From f9c8b272c6badfa4731e9c3e9e257e1348a93e60 Mon Sep 17 00:00:00 2001 From: elena <ebudnik@irap.omp.eu> Date: Fri, 25 Sep 2015 15:26:17 +0200 Subject: [PATCH] edit catalog --- js/app/controllers/CatalogModule.js | 16 ++++++++++++++-- js/app/controllers/InteractiveModule.js | 99 +++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------- js/app/views/CatalogUI.js | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------- php/classes/AmdaAction.php | 19 ++++++++++++++----- php/classes/CatalogCacheMgr.php | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- php/classes/CatalogMgr.php | 33 ++++++++++++++++++++++++++++++++- 6 files changed, 362 insertions(+), 146 deletions(-) diff --git a/js/app/controllers/CatalogModule.js b/js/app/controllers/CatalogModule.js index 046a5ad..2605d70 100644 --- a/js/app/controllers/CatalogModule.js +++ b/js/app/controllers/CatalogModule.js @@ -15,6 +15,7 @@ Ext.define('amdaDesktop.CatalogModule', { ], contentId : 'catalogUI', + isOperationOnShow : true, /** * @cfg {String} data models @@ -30,6 +31,17 @@ Ext.define('amdaDesktop.CatalogModule', { height: 700, uiType : 'panelCatalog', helpTitle : 'Help on Catalog Module', - helpFile : 'catalogHelp' - + helpFile : 'catalogHelp', + + operationOnShow: function() { + var obj = this.linkedNode.get('object'); + if (obj && obj.get('id') == '' && !obj.get('fromPlugin')) { + Ext.Msg.prompt('Define Parameters', 'Please enter parameters number:', function(btn, text){ + if (btn == 'ok'){ + AmdaAction.initTTCache(this.getUiContent().isCatalog, text, this.getUiContent().onAfterInit, this.getUiContent()); + } + }, this); + } + + } }); diff --git a/js/app/controllers/InteractiveModule.js b/js/app/controllers/InteractiveModule.js index e6ba79e..fd41a1a 100644 --- a/js/app/controllers/InteractiveModule.js +++ b/js/app/controllers/InteractiveModule.js @@ -5,13 +5,7 @@ * @extends amdaDesktop.AmdaModule * @brief Generic Interactive Module controller definition * @author CDA - * @version $Id: InteractiveModule.js 2109 2014-02-19 17:47:37Z elena $ - ******************************************************************************* - * FT Id : Date : Name - Description - ******************************************************************************* - * : :08/06/2011: CDA - Migration extjs4 - * : :09/06/2011: elena - generic Interactive modules methods: init(), createWindow(), - * createLinkedNode(), createObject() now are defined here + * @version $Id: InteractiveModule.js 2109 2014-02-19 17:47:37Z elena $ */ Ext.define('amdaDesktop.InteractiveModule', { @@ -82,65 +76,70 @@ Ext.define('amdaDesktop.InteractiveModule', { ], items : [ { - xtype : this.uiType, - object : this.linkedNode.get('object'), - id : this.contentId + xtype : this.uiType, + object : this.linkedNode.get('object'), + id : this.contentId } ] }); this.closed = false; win.on({ - scope: this, - // on window activation event - activate: function(){ - // order to pin this Module with WsExplorer - this.pin(); - }, - // on window closing event - beforeclose: function (win, eOpts) { - - this.saveState(); - - var isDirty = this.getUiContent().fclose(); - - if (!this.closed && isDirty) { - Ext.Msg.confirm('Close', 'Current window has been modified.\nDo you want to close the window ?' , function (btn, text){ - if (btn == 'yes'){ - // mark this.closed as true before the call to close() as that will fire the beforeclose event again - this.closed = true; - win.close(); - } + scope: this, + // on window activation event + activate: function(){ + // order to pin this Module with WsExplorer + this.pin(); + }, + // on window closing event + beforeclose: function (win, eOpts) { + + this.saveState(); + + var isDirty = this.getUiContent().fclose(); + + if (!this.closed && isDirty) { + Ext.Msg.confirm('Close', 'Current window has been modified.\nDo you want to close the window ?' , function (btn, text){ + if (btn == 'yes'){ + // mark this.closed as true before the call to close() as that will fire the beforeclose event again + this.closed = true; + win.close(); + } },this); - } else if (!isDirty) { - this.closed = true; - } + } else if (!isDirty) { + this.closed = true; + } - if (this.closed) { - //remove object from linkedNode in order to minimize used memory - this.linkedNode.set('object',''); - // unlink Node - this.setLinkedNode(null); - // order to unpin this Module from WsExplorer - this.unpin(); - } + if (this.closed) { + //remove object from linkedNode in order to minimize used memory + this.linkedNode.set('object',''); + // unlink Node + this.setLinkedNode(null); + // order to unpin this Module from WsExplorer + this.unpin(); + } - // Don't automatically close if the form is dirty, let the call to this.close() within the confirm box close the window. - return this.closed; - }, - minimize: function (win, eOpts) { + // Don't automatically close if the form is dirty, let the call to this.close() within the confirm box close the window. + return this.closed; + }, + minimize: function (win, eOpts) { // Save form if (this.getUiContent().formPanel) - this.getUiContent().formPanel.getForm().updateRecord(this.linkedNode.get('object')); + this.getUiContent().formPanel.getForm().updateRecord(this.linkedNode.get('object')); else - this.getUiContent().items.getAt(0).getForm().updateRecord(this.linkedNode.get('object')); + this.getUiContent().items.getAt(0).getForm().updateRecord(this.linkedNode.get('object')); // Save grids this.getUiContent().updateObject(); - } + }, + show: function() { + // configuration of empty catalog + if (this.isOperationOnShow) + this.operationOnShow(); + } }); - } else { - this.getUiContent().setObject(this.linkedNode.get('object')); + // second arg 'true' is used in CatalogUI to mark if Grid Reconfiguration is needed + this.getUiContent().setObject(this.linkedNode.get('object'), true); } win.show(); }, diff --git a/js/app/views/CatalogUI.js b/js/app/views/CatalogUI.js index 1f3da5c..51c4384 100644 --- a/js/app/views/CatalogUI.js +++ b/js/app/views/CatalogUI.js @@ -10,21 +10,28 @@ Ext.define('amdaUI.CatalogUI', { extend: 'Ext.container.Container', alias: 'widget.panelCatalog', - + + requires: [ + 'Ext.grid.plugin.BufferedRenderer' + ], + isCatalog : true, + constructor: function(config) { this.init(config); - this.callParent(arguments);; + this.callParent(arguments); + this.toReconfigure = true; if (this.object) this.loadObject(); }, - setObject : function (object) - { - // set object - this.object = object; - + setObject : function (object, toReconfigure) + { + if (toReconfigure) + this.toReconfigure = true; + // set object + this.object = object; // load object into view this.loadObject(); }, @@ -77,44 +84,38 @@ Ext.define('amdaUI.CatalogUI', { this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals')); }, - /** - * load object catalog into this view - */ - loadObject : function() - { - // load object into form - this.formPanel.getForm().loadRecord(this.object); + + + onAfterInit: function(result, e) { - this.status = null; - var me = this; - var onAfterInit = function(result, e) - { - if (!result || !result.success) - { - if (result.message) - myDesktopApp.errorMsg(result.message); - else - myDesktopApp.errorMsg('Unknown error during catalog cache initialisation'); - return; - } - + if (!result || !result.success) + { + if (result.message) + myDesktopApp.errorMsg(result.message); + else + myDesktopApp.errorMsg('Unknown error during catalog cache initialisation'); + return; + } + + if (me.toReconfigure) + { var fields = [], columns = [], i = 3, width, index; var fieldsConfig = [{ name : 'start' },{ name : 'stop' },{ name: 'cacheId', type : 'int'}, { name: 'isNew', type : 'boolean', defaultValue: false }, - { name: 'isModified', type : 'boolean', defaultValue: false} + { name: 'isModified', type : 'boolean', defaultValue: false} ]; for (var j = 0; j < 5; j++) fields[j] = Ext.create('Ext.data.Field', fieldsConfig[j]); - columns[0] = Ext.create('Ext.grid.column.RowNumberer'); + columns[0] = Ext.create('Ext.grid.column.RowNumberer'); columns[1] = Ext.create('Ext.grid.column.Column', { text: 'Start Time', sortable : false, dataIndex: 'start', - width : 120, menuDisabled: true }); + width : 120, menuDisabled: true, editor : { xtype:'datefield', allowBlank:false, hideTrigger: true, format : 'Y-m-d\\TH:i:s'}}); columns[2] = Ext.create('Ext.grid.column.Column', { text: 'Stop Time', sortable : false, dataIndex: 'stop', - width : 120, menuDisabled: true }); + width : 120, menuDisabled: true, editor : { xtype:'datefield', allowBlank:false, hideTrigger: true, format : 'Y-m-d\\TH:i:s'}}); Ext.Array.each(result.parameters, function(obj) { @@ -122,12 +123,12 @@ Ext.define('amdaUI.CatalogUI', { fields[i+2] = Ext.create('Ext.data.Field',{ name : index }); width = 50. * parseInt(obj.size); columns[i] = Ext.create('Ext.grid.column.Column', { text: obj.name, sortable : false, dataIndex: index, - width : width, menuDisabled: true }); + width : width, menuDisabled: true, editor: 'textfield' }); i++; }); - - - + + + var store = Ext.create('Ext.data.Store', { fields: fields, autoDestroy: false, @@ -161,11 +162,11 @@ Ext.define('amdaUI.CatalogUI', { // this.fireEvent("refresh"); } } - }); - + }); + me.TTGrid.reconfigure(store, columns); - - me.TTGrid.getSelectionModel().deselectAll(); + } + me.TTGrid.getSelectionModel().deselectAll(); // // // clear filters // me.TTGrid.getStore().clearFilter(true); @@ -173,41 +174,50 @@ Ext.define('amdaUI.CatalogUI', { // //clear sort // me.TTGrid.getStore().sorters.clear(); // //me.TTGrid.getStore().sorters = new Ext.util.MixedCollection(); - // + //set cache token to the Catalog object - me.object.set('cacheToken', result.token); - me.setParamInfo(result.parameters); - - me.TTGrid.getStore().load(); + me.object.set('cacheToken', result.token); + me.setParamInfo(result.parameters); + + me.TTGrid.getStore().load(); - me.status = result.status; - }; - + me.status = result.status; + }, + + /** + * load object catalog into this view + */ + loadObject : function() + { + // load object into form + this.formPanel.getForm().loadRecord(this.object); + + this.status = null; + if (this.object.get('fromPlugin')) { if (this.object.get('objFormat') && this.object.get('objFormat') != '') { //From uploaded file - //AmdaAction.initTTCacheFromUploadedFile(this.object.get('objName'), this.object.get('objFormat'), onAfterInit); + //AmdaAction.initTTCacheFromUploadedFile(this.object.get('objName'), this.object.get('objFormat'), this.onAfterInit, this); } else { - //From tmp object (ie Search result) - AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, onAfterInit); + //From tmp object (ie Statistics result) + AmdaAction.initTTCacheFromTmpObject(this.object.get('folderId'), this.object.get('objName'), this.isCatalog, this.onAfterInit, this); } } else { - var typeTT = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id).linkedNode.data.nodeType; + // var typeTT = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id).linkedNode.data.nodeType; if (this.object.get('id') == '') - { - //Init empty cache - AmdaAction.initTTCache(this.isCatalog, onAfterInit); + { + } else { //From existing TT file - AmdaAction.initTTCacheFromTT(this.object.get('id'), 'catalog', onAfterInit); + AmdaAction.initTTCacheFromTT(this.object.get('id'), 'catalog', this.onAfterInit, this); } } }, @@ -221,8 +231,9 @@ Ext.define('amdaUI.CatalogUI', { */ saveProcess : function(toRename) { - var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); - + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); + // store / columns are the same - not needed to reconfigure grid + this.toReconfigure = false; // if the name has been modified this is a creation if (this.fclose()) { @@ -245,13 +256,26 @@ Ext.define('amdaUI.CatalogUI', { } module.linkedNode.create({callback : function() {module.linkedNode.update();}, scope : this}); } else { - //update + //update module.linkedNode.update(); } + } }, /** + * overwrite metod called by Save button + */ + overwriteProcess : function(btn) + { + if (btn == 'cancel') return; + + this.fieldName.clearInvalid(); + this.saveProcess(true); + + }, + + /** * Check if changes were made before closing window * @return true if changes */ @@ -263,8 +287,7 @@ Ext.define('amdaUI.CatalogUI', { var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0); return isDirty; }, - - + init : function (config) { this.object = config.object; @@ -282,39 +305,97 @@ Ext.define('amdaUI.CatalogUI', { return this.validFlag; } }); - + + var cellEditing = Ext.create('Ext.grid.plugin.CellEditing',{ +// clicksToEdit: 2, + onEditComplete : function(ed, value, startValue) { + var me = this, + activeColumn = me.getActiveColumn(), + context = me.context, + record; + + if (activeColumn) { + record = context.record; + + me.setActiveEditor(null); + me.setActiveColumn(null); + me.setActiveRecord(null); + + context.value = value; + if (!me.validateEdit()) { + me.editing = false; + return; + } + + // Only update the record if the new value is different than the + // startValue. When the view refreshes its el will gain focus + if (!record.isEqual(value, startValue)) { + var obj = {}; + + obj['cacheId'] = record.get('cacheId'); + obj['isCatalog'] = true; + obj[activeColumn.dataIndex] = value; + + //Interval is modified on the server side + me.editing = true; + + AmdaAction.modifyTTCacheInterval(obj, function (result, e) { + + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); + if (module) + module.getUiContent().status = result.status; + context.grid.getSelectionModel().deselectAll(); + context.store.reload({ + callback : function(records, options, success) { + context.view.bufferedRenderer.scrollTo(context.rowIdx, true, function() { + me.fireEvent('edit', me, context); + me.editing = false; + }, me); + } + }); + }, this); + } + else + me.editing = false; + } + } + }); this.TTGrid = Ext.create('Ext.grid.Panel', { height: 530, columns: [ ], frame: true, + columnLines: true, + // selType: 'cellmodel', + plugins: [ cellEditing, { ptype : 'bufferedrenderer'} ], dockedItems: [{ xtype: 'toolbar', items: [{ iconCls: 'icon-add', scope: this, handler: function(){ - alert('NOT IMPLEMENTED YET'); - // cellEditing.cancelEdit(); - // - // var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0]; - // var row = 0; - // if (selection) - // row = store.indexOf(selection) + 1; - // this.TTGrid.getSelectionModel().deselectAll(); - // - // var me = this; - // AmdaAction.addTTCacheInterval({'index' : row}, function (result, e) { - // this.status = result.status; - // this.TTGrid.getStore().reload({ - // callback : function(records, options, success) { - // me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function() { - // me.TTGrid.getView().select(row); - // cellEditing.startEditByPosition({row: row, column: 1}); - // }, me); - // } - // }); - // }, this); + + cellEditing.cancelEdit(); + var store = this.TTGrid.getStore(); + + var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0]; + var row = 0; + if (selection) + row = store.indexOf(selection) + 1; + this.TTGrid.getSelectionModel().deselectAll(); + + var me = this; + AmdaAction.addTTCacheInterval({'index' : row, 'isCatalog' : true}, function (result, e) { + this.status = result.status; + this.TTGrid.getStore().reload({ + callback : function(records, options, success) { + me.TTGrid.getView().bufferedRenderer.scrollTo(row, false, function() { + me.TTGrid.getView().select(row); + cellEditing.startEditByPosition({row: row, column: 1}); + }, me); + } + }); + }, this); } },{ iconCls: 'icon-delete', @@ -325,8 +406,7 @@ Ext.define('amdaUI.CatalogUI', { var selection = this.TTGrid.getView().getSelectionModel().getSelection()[0]; if (selection) { - var rowId = selection.get('cacheId'); - console.log(selection); + var rowId = selection.get('cacheId'); this.TTGrid.getSelectionModel().deselectAll(); AmdaAction.removeTTCacheIntervalFromId(rowId, this.isCatalog, function (result, e) { this.status = result.status; @@ -458,7 +538,7 @@ Ext.define('amdaUI.CatalogUI', { myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.visu.id, true, function (module) { - //temporary linked node - as Visu module is 'pseud' intercative - no 'save', no 'execute' + //temporary linked node - as Visu module is 'pseudo' interactive - no 'save', no 'execute' var temporaryNode = Ext.create('amdaModel.CatalogNode', { leaf : true }); diff --git a/php/classes/AmdaAction.php b/php/classes/AmdaAction.php index 5fd734c..11b8c04 100644 --- a/php/classes/AmdaAction.php +++ b/php/classes/AmdaAction.php @@ -937,12 +937,12 @@ class AmdaAction { return $result; } - public function initTTCache($isCatalog = false) + public function initTTCache($isCatalog = false, $nparams) { if (!$isCatalog) $cacheMgr = new TimeTableCacheMgr(); else $cacheMgr = new CatalogCacheMgr(); - return $cacheMgr->initTTCache(); + return $cacheMgr->initTTCache($nparams); } @@ -1002,7 +1002,9 @@ class AmdaAction { public function addTTCacheInterval($o) { - $cacheMgr = new TimeTableCacheMgr(); + if ($o->isCatalog) $cacheMgr = new CatalogCacheMgr(); + else $cacheMgr = new TimeTableCacheMgr(); + return $cacheMgr->addInterval($o->index, $o->start, $o->stop); } @@ -1010,13 +1012,20 @@ class AmdaAction { { if ($isCatalog) $cacheMgr = new CatalogCacheMgr(); else $cacheMgr = new TimeTableCacheMgr(); - + return $cacheMgr->removeIntervalFromId($id); } public function modifyTTCacheInterval($o) { - $cacheMgr = new TimeTableCacheMgr(); + if ($o->isCatalog) { + + $cacheMgr = new CatalogCacheMgr(); + return $cacheMgr->modifyIntervalFromId($o); + + } + else $cacheMgr = new TimeTableCacheMgr(); + return $cacheMgr->modifyIntervalFromId($o->cacheId, $o->start, $o->stop); } diff --git a/php/classes/CatalogCacheMgr.php b/php/classes/CatalogCacheMgr.php index 765d441..d482cbb 100644 --- a/php/classes/CatalogCacheMgr.php +++ b/php/classes/CatalogCacheMgr.php @@ -226,12 +226,42 @@ class CatalogCacheObject extends TimeTableCacheObject return true; } + + public function modifyIntervalFromId($obj) { + + foreach ($this->intervals as $interval) + { + if ($interval->getId() == $obj->cacheId) + { + foreach((array)$obj as $key => $val) { + + if ($key == 'start') + $interval->setStartFromISO($val); + else if ($key == 'stop') + $interval->setStopFromISO($val); + else { + if (strpos($key, 'param') === false) + continue; + $params = $interval->getParams(); + $paramIndex = (int)substr($key,5); + $params[$paramIndex-2] = $val; + $interval->setParams($params); + } + } + $interval->setIsModified(true); + $this->isModified = true; + return true; + } + } + + return false; + } } class CatalogCacheMgr extends TimeTableCacheMgr { - protected static $cache_file = "cacheCat"; + protected static $cache_file = "cacheCat"; protected $ttMgr = null; protected $cache = null; @@ -298,7 +328,7 @@ class CatalogCacheMgr extends TimeTableCacheMgr } $paramHeaders = $intervals_res['parameters']; - + $this->cache->setParamsNumber(count($paramHeaders)); $this->cache->setParamsSizes($paramHeaders); unset($intervals_res); @@ -350,6 +380,61 @@ class CatalogCacheMgr extends TimeTableCacheMgr $this->cache->reset(); return $this->ttMgr->saveIntervals($id, $intervals, $action); - } + } + + public function addInterval($index, $start, $stop, $params) { + if (!$this->loadFromFile()) + return array('success' => false, 'message' => 'Cannot load cache file'); + + if (!isset($index)) + $index = 0; + + if (!isset($start)) + $start = date('Y-m-d\TH:i:s'); + + if (!isset($stop)) + $stop = date('Y-m-d\TH:i:s'); + + if (!isset($params)) + $params = []; + + $this->cache->addInterval($start, $stop, $params, true, $index); + + //$this->cache->updateIndexes(); + + $this->saveToFile(); + + return array('success' => true, 'index' => $index, 'status' => $this->cache->getStatus()); + } + + public function modifyIntervalFromId($obj) { + if (!$this->loadFromFile()) + return array('success' => false, 'message' => 'Cannot load cache file'); + + $this->cache->modifyIntervalFromId($obj); + + $this->saveToFile(); + + return array('success' => true, 'status' => $this->cache->getStatus()); + } + + public function initTTCache($nparams) { + //Create new cache + $this->cache = new CatalogCacheObject(); + $this->cache->setParamsNumber((int)$nparams); + $paramHeaders = array(); + + for ($i = 0; $i < (int)$nparams; $i++) { + $paramHeaders[$i]['id'] = 'id_'.(string)($i+1); + $paramHeaders[$i]['name'] = 'param_'.(string)($i+1); + $paramHeaders[$i]['size'] = 1; + $paramHeaders[$i]['type'] = 'Float'; + + } + $this->cache->setParamsSizes($paramHeaders); + //Save cache file + return array('success' => $this->saveToFile(), 'token' => $this->cache->getToken(), + 'status' => $this->cache->getStatus(), 'parameters' => $paramHeaders); + } } ?> \ No newline at end of file diff --git a/php/classes/CatalogMgr.php b/php/classes/CatalogMgr.php index f422f12..8de4a17 100644 --- a/php/classes/CatalogMgr.php +++ b/php/classes/CatalogMgr.php @@ -379,6 +379,37 @@ class CatalogMgr extends TimeTableMgr { ); } - + +// public function modifyObject($p) { +// $folder = $this->getObjectFolder($p->id); +// +// //Copy TT in a tempory file +// $ttFilePath = USERTTDIR.$p->id.'.xml'; +// $tmpFileExist = FALSE; +// if (file_exists($ttFilePath)) +// $tmpFileExist = copy($ttFilePath,$ttFilePath.".tmp"); +// +// //Delete TT +// $this->deleteObject($p); +// +// //Save modifications +// try { +// $result = $this->createObject($p, $folder); +// if ($result['error']) +// throw new Exception($result['error']); +// if ($tmpFileExist) +// unlink($ttFilePath.".tmp"); +// return array('id' => $p->id, 'info' => $result['nbIntervals'].' intervals' ); +// } +// catch (Exception $e) { +// //Restore TT file +// if ($tmpFileExist) +// { +// copy($ttFilePath.".tmp", $ttFilePath); +// unlink($ttFilePath.".tmp"); +// } +// return array ('error' => $e->getMessage()); +// } +// } } ?> -- libgit2 0.21.2