From f792a3de2c4c89f113466ebc70d564eeb48c59e2 Mon Sep 17 00:00:00 2001 From: elena <ebudnik@irap.omp.eu> Date: Thu, 9 Jul 2015 14:26:21 +0200 Subject: [PATCH] catalog ihm --- generic_data/jobs.json | 7 +++++-- generic_data/resources.json | 6 ++++++ js/app/AmdaApp.js | 26 +++++++++++++------------- js/app/controllers/CatalogModule.js | 35 +++++++++++++++++++++++++++++++++++ js/app/controllers/ExplorerModule.js | 5 +++-- js/app/models/Catalog.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ js/app/models/CatalogNode.js | 28 ++++++++++++++++++++++++++++ js/app/stores/ExplorerReader.js | 2 ++ js/app/views/CatalogUI.js | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 559 insertions(+), 17 deletions(-) create mode 100644 js/app/controllers/CatalogModule.js create mode 100644 js/app/models/Catalog.js create mode 100644 js/app/models/CatalogNode.js create mode 100644 js/app/views/CatalogUI.js diff --git a/generic_data/jobs.json b/generic_data/jobs.json index ee48f3b..107be9a 100644 --- a/generic_data/jobs.json +++ b/generic_data/jobs.json @@ -2,12 +2,15 @@ {"nodeType" : "bkgWorks", "text" : "Finished Jobs / Results", "id" : "result-treeRootNode", "children" : [{"nodeType" : "bkgWorks","text" : "Plot","id" : "resPlot-treeRootNode" }, {"nodeType" : "bkgWorks","text" : "Download","id" : "resDown-treeRootNode"}, - {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "resSearch-treeRootNode"} + {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "resSearch-treeRootNode"}, + {"nodeType" : "bkgWorks","text" : "Catalog","id" : "resCatalog-treeRootNode"} ] }, {"nodeType" : "bkgWorks", "text" : "Jobs in Progress", "id" : "bkgjobs-treeRootNode", "children" : [{"nodeType" : "bkgWorks","text" : "Plot","id" : "bkgPlot-treeRootNode" }, {"nodeType" : "bkgWorks","text" : "Download","id" : "bkgDown-treeRootNode"}, - {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"}] + {"nodeType" : "bkgWorks","text" : "Data Mining","id" : "bkgSearch-treeRootNode"}, + {"nodeType" : "bkgWorks","text" : "Catalog","id" : "bkgCatalog-treeRootNode"} + ] } ]} diff --git a/generic_data/resources.json b/generic_data/resources.json index 959e071..f82b41d 100644 --- a/generic_data/resources.json +++ b/generic_data/resources.json @@ -14,5 +14,11 @@ { "nodeType" : "sharedtimeTable", "text" : "Shared Time Tables", "id" : "sharedtimeTable-treeRootNode"} ] }, + {"nodeType" : "","text" : "Catalogs","id" : "catalog-treeBase", + "children" : [ + { "nodeType" : "catalog", "text" : "My Catalogs", "id" : "catalog-treeRootNode"}, + { "nodeType" : "sharedCatalog", "text" : "Shared Catalogs", "id" : "sharedCatalog-treeRootNode"} + ] + }, {"nodeType" : "myData","text" : "My Files", "id" : "myData-treeRootNode"} ]} diff --git a/js/app/AmdaApp.js b/js/app/AmdaApp.js index f9a7f1d..cdde7c9 100755 --- a/js/app/AmdaApp.js +++ b/js/app/AmdaApp.js @@ -5,20 +5,13 @@ * @extends Ext.ux.desktop.App * @brief Main class defining Amda Desktop and its Modules * @author Ext JS Library 4.0 Copyright(c) 2006-2011 Sencha Inc. licensing@sencha.com - * @version $Id: AmdaApp.js 2932 2015-06-02 09:35:47Z elena $ - * @todo Load/Unload Modules on need - ******************************************************************************* - * FT Id : Date : Name - Description - ******************************************************************************* - * : :07/06/2011: elena - First Modifs for Amda Application */ Ext.define('amdaApp.AmdaApp', { extend: 'Ext.ux.desktop.App', - requires: [ - + requires: [ 'Ext.window.MessageBox', 'Ext.ux.desktop.ShortcutModel', 'amdaUI.SampToolBarUI', @@ -27,6 +20,13 @@ Ext.define('amdaApp.AmdaApp', { ], dynamicModules: { + catalog : { + id : 'catalog-win', + icon : 'icon-catalog', + title : 'Generate/Edit catalogs', + source : 'amdaDesktop.CatalogModule', + useLauncher : true + }, param : { id : 'param-win', icon : 'icon-parameters', @@ -49,24 +49,24 @@ Ext.define('amdaApp.AmdaApp', { useLauncher : true }, plot : { - id : 'plot-win', + id : 'plot-win', icon : 'icon-plot', title : 'Plot Manager', source : 'amdaDesktop.PlotModule', useLauncher : true }, search : { - id : 'search-win', + id : 'search-win', icon : 'icon-search', title : 'Data Mining', source : 'amdaDesktop.SearchModule', useLauncher : true }, download : { - id : 'down-win', + id : 'down-win', icon : 'icon-download', title : 'Download data', - source : 'amdaDesktop.DownloadModule', + source : 'amdaDesktop.DownloadModule', useLauncher : true }, upload : { @@ -279,7 +279,7 @@ Ext.define('amdaApp.AmdaApp', { { name: 'Upload data', iconCls: 'mydata', module: 'up-win'}, { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' }, { name: 'TimeTables operations', iconCls: 'operations', module: 'ttsOpe-win' }, - // { name: 'Generate/Edit catalogs', iconCls: 'catalog', module: 'catalog-win'}, + { name: 'Generate/Edit catalogs', iconCls: 'catalog', module: 'catalog-win'}, // { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'}, { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' } ] diff --git a/js/app/controllers/CatalogModule.js b/js/app/controllers/CatalogModule.js new file mode 100644 index 0000000..046a5ad --- /dev/null +++ b/js/app/controllers/CatalogModule.js @@ -0,0 +1,35 @@ +/** + * Project AMDA-NG + * Name CatalogModule.js + * @class amdaDesktop.CatalogModule + * @extends amdaDesktop.InteractiveModule + * @brief Catalog Module controller definition + * @author elena + */ + +Ext.define('amdaDesktop.CatalogModule', { + extend: 'amdaDesktop.InteractiveModule', + + requires: [ + 'amdaUI.CatalogUI' + ], + + contentId : 'catalogUI', + + /** + * @cfg {String} data models + * @required + */ + nodeDataModel : 'amdaModel.CatalogNode', + + /** + * @cfg {String} window definitions + * @required + */ + width : 800, + height: 700, + uiType : 'panelCatalog', + helpTitle : 'Help on Catalog Module', + helpFile : 'catalogHelp' + +}); diff --git a/js/app/controllers/ExplorerModule.js b/js/app/controllers/ExplorerModule.js index d66a356..16182a6 100644 --- a/js/app/controllers/ExplorerModule.js +++ b/js/app/controllers/ExplorerModule.js @@ -1,11 +1,10 @@ /** - * Project : AMDA-NG4 + * Project : AMDA-NG * Name : ExplorerModule.js * @class amdaDesktop.ExplorerModule * @extends amdaDesktop.AmdaModule * @brief Explorer Module controller definition * @author CDA - * @version $Id: ExplorerModule.js 2239 2014-03-26 12:31:32Z elena $ */ Ext.define('amdaDesktop.ExplorerModule', { @@ -23,6 +22,7 @@ Ext.define('amdaDesktop.ExplorerModule', { 'amdaModel.RemoteSimuParamNode', 'amdaModel.AliasNode', 'amdaModel.TimeTableNode', + 'amdaModel.CatalogNode', 'amdaModel.sharedTimeTableNode', 'amdaModel.MyDataParamNode', 'amdaModel.MyDataNode', @@ -35,6 +35,7 @@ Ext.define('amdaDesktop.ExplorerModule', { 'amdaModel.Plot', 'amdaModel.Download', 'amdaModel.TimeTable', + 'amdaModel.Catalog', 'amdaModel.FileObject', 'amdaModel.FileParamObject', 'amdaModel.FilterInfo' diff --git a/js/app/models/Catalog.js b/js/app/models/Catalog.js new file mode 100644 index 0000000..f43acb7 --- /dev/null +++ b/js/app/models/Catalog.js @@ -0,0 +1,52 @@ +/** + * Project : AMDA-NG + * Name : Catalog.js + * Description : Catalog Object Definition + * @class amdaModel.Catalog + * @extends amdaModel.TimeTable + * @author elena + */ + + + +Ext.define('amdaModel.Catalog', { + + extend: 'amdaModel.TimeTable', + + fields : [ + { name: 'parameter' }, + { name: 'timeTables' }//, +// { name: 'timesrc', type: 'string', defaultValue : "TimeTable" } + ], + + getJsonValues : function (hasId) { + var values = new Object(); + if (hasId) { + values.id = this.get('id'); + } + + values.timesrc = 'TimeTable'; + values.name = this.get('name'); + values.created = this.get('created'); + + if (this.get('description').match(/[a-z,0-9]/gi) != null) { + values.description = this.get('description'); + } +// if (this.get('history').match(/[a-z,0-9]/gi) != null) { +// values.history = this.get('history'); +// } + values.objName = this.get('objName'); + values.objFormat = this.get('objFormat'); + values.folderId = this.get('folderId'); + values.nbIntervals = this.get('nbIntervals'); + values.cacheToken = this.get('cacheToken'); + values.parameter = this.get('parameter'); + values.timeTables = this.get('timetable'); + values.leaf = true; + values.nodeType = amdaModel.CatalogNode.nodeType; + return values; + } + + + +}); \ No newline at end of file diff --git a/js/app/models/CatalogNode.js b/js/app/models/CatalogNode.js new file mode 100644 index 0000000..3108f74 --- /dev/null +++ b/js/app/models/CatalogNode.js @@ -0,0 +1,28 @@ +/** + * Project : AMDA-NG + * Name : CatalogNode.js + * @class amdaModel.CatalogNode + * @extends amdaModel.TimeTableNode + * @brief Basic Model of Node corresponding to a amda catalog + * @author elena + */ + +Ext.define('amdaModel.CatalogNode', { + + extend: 'amdaModel.ExecutableNode', + + statics: { + nodeType: 'catalog', + objectName: 'Catalog' + }, + + constructor : function(config){// + this.callParent(arguments); + this.set('nodeType',amdaModel.CatalogNode.nodeType); + this.set('moduleId',myDesktopApp.dynamicModules.catalog.id); + this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); + this.set('objectDataModel',amdaModel.Catalog.$className); + if (this.get('leaf')) this.set('iconCls', 'icon-catalog'); + } + +}); diff --git a/js/app/stores/ExplorerReader.js b/js/app/stores/ExplorerReader.js index f6a0e12..5d26e04 100644 --- a/js/app/stores/ExplorerReader.js +++ b/js/app/stores/ExplorerReader.js @@ -37,6 +37,8 @@ Ext.define('amdaReader.ExplorerReader', { return amdaModel.AliasNode; case 'timeTable' : return amdaModel.TimeTableNode; + case 'catalog' : + return amdaModel.CatalogNode; case 'sharedtimeTable' : return amdaModel.sharedTimeTableNode; case 'condition' : diff --git a/js/app/views/CatalogUI.js b/js/app/views/CatalogUI.js new file mode 100644 index 0000000..8dd1286 --- /dev/null +++ b/js/app/views/CatalogUI.js @@ -0,0 +1,415 @@ +/** + * Project AMDA-NG + * Name CatalogUI.js + * @class amdaUI.catalogUI + * @extends Ext.container.Container + * @brief Catalog Module UI definition (View) + * @author elena + */ + +Ext.define('amdaUI.CatalogUI', { + extend: 'Ext.container.Container', + alias: 'widget.panelCatalog', + + requires : [ +// 'amdaModel.Function' + ], + + statics : { +// functionStore : null + }, + + constructor: function(config) { + this.init(config); + this.callParent(arguments); + // if (this.object) this.loadObject(); + }, + + addParam : function(ParamName,isLeaf) + { + var r = Ext.create('amdaModel.AmdaObject', { name: ParamName }); + this.paramGrid.getStore().add(r); + this.paramGrid.getSelectionModel().select(this.paramGrid.getStore().getCount()-1); + }, + + addTT : function(TTname,TTid) + { + Ext.define('tempObject', { + extend: 'Ext.data.Model', + fields: [ + {name: 'name', type: 'string'}, + {name: 'hidden_id', type: 'string'} + ]}); + var r = Ext.create('tempObject', { name:TTname, hidden_id : TTid }); + this.ttGrid.getStore().add(r); + this.ttGrid.getSelectionModel().select(this.paramGrid.getStore().getCount()-1); + + }, + + generateCatalog : function(){ + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); + if (module) + module.linkedNode.execute(); + }, + + /** + * update this.object from form + */ + + updateObject : function(){ + // get the basic form of the left + var basicForm = this.formPanel.items.items[0].getForm(); + + var formValues = basicForm.getValues(); + this.object.set('name',formValues.name); + this.object.set('description',formValues.description); + + var recs = this.paramGrid.getStore().getNewRecords(); + var paramArr = new Array(); + Ext.Array.each(recs, function(rec, index,allItems){ + var obj = new Object(); + obj.param = rec.get('name'); + obj.function = rec.get('function'); + paramArr.push(obj); + }); + this.object.set('parameter', paramArr); + + // hidden_id - if real 'id' - getNewRecords (and other getRecords) methods doesn't work + var tts = this.ttGrid.getStore().getNewRecords(); + var ttArr = new Array(); + Ext.Array.each(tts, function(rec, index, allItems){ + var obj = new Object(); + obj.id = rec.get('hidden_id'); + ttArr.push(obj); + }); + this.object.set('timetable', ttArr); + + var updateStatus = true; + + return updateStatus; + }, + + init : function (config) { + +// var functions = Ext.create('Ext.data.Store', { +// fields: ['id', 'name'], +// data : [ +// {"id":"min", "name":"MIN"}, +// {"id":"max", "name":"MAX"}, +// {"id":"mean","name":"MEAN"} +// ] +// }); + + this.fieldName = new Ext.form.field.Text({ + fieldLabel: 'Name*', + allowBlank : false, + stripCharsRe: /(^\s+|\s+$)/g, + emptyText: 'Please no spaces!', + name: 'name', + anchor: '100%', + validateOnChange: false, + validateOnBlur: false, + validFlag: false, + validator : function() { + return this.validFlag; + } + }); + + var ttStore = Ext.create('Ext.data.Store', + { + fields: [ 'name', 'hidden_id'] + }); + + this.ttGrid = Ext.create('Ext.grid.Panel', { + title: 'Select Time Table', + height: 100, + store : ttStore, + columns: [ + { xtype: 'rownumberer' }, + { header: "Time Table Name", dataIndex: 'name', flex:1, sortable : false, menuDisabled: true }, + { menuDisabled: true, width: 30, renderer: function() + { + return '<div class="icon-remover" style="width: 15px; height: 15px;"></div>'; + } + } + ], + listeners : { + render : function(o,op) { + var me = this; + var el = me.getEl(); + var dropTarget = Ext.create('Ext.dd.DropTarget', el, { + ddGroup: 'explorerTree', + notifyOver : function(ddSource, e, data) + { + if ((data.records[0].get('nodeType') == 'timeTable' || data.records[0].get('nodeType') == 'sharedtimeTable') && (data.records[0].get('leaf'))) + { + this.valid = true; + return this.dropAllowed; + } + this.valid = false; + return this.dropNotAllowed; + }, + notifyDrop : function(ddSource, e, data) + { + if (!this.valid) return false; + + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); + if (module) + { + module.getUiContent().addTT(data.records[0].get('text'),data.records[0].get('id')); + } + return true; + } + }); + }, + + cellclick : function(grid, cell, cellIndex, record){ + if (cellIndex == 2) + grid.getStore().remove(record); + } + } + }); + + var store = Ext.create('Ext.data.Store', + { + fields: ['name', 'function'] + }); + + this.paramGrid = Ext.create('Ext.grid.Panel', { + title: 'Select Parameter & Apply Function', + selType : 'rowmodel', + height: 200, + store : store, + columns: [ + { xtype: 'rownumberer' }, + { header: 'parameter', dataIndex: 'name', menuDisabled : true, sortable : false }, + { header: 'function', dataIndex: 'function', menuDisabled : true, sortable : false, + editor: { + xtype: 'combo', queryMode : 'local', +// emptyText : 'please click to select function', + store: [ 'min', 'max', 'mean' ], + triggerAction: 'all', +// lazyInit: false, + listeners: { + focus: function(obj) { + obj.expand(); + } + } + }, + renderer: function(v) + { + if(v != null && v.length > 0 ) + return v; + else + return 'click to select'; + } + }, + { menuDisabled : true, width: 30, renderer: function(){ + return '<div class="icon-remover" style="width: 15px; height: 15px;"></div>'; + } + } + ], + plugins: [ + Ext.create('Ext.grid.plugin.CellEditing', { + clicksToEdit: 1 + }) + ], + listeners : + { + render : function(o,op) + { + var me = this; + var el = me.body.dom; + var dropTarget = Ext.create('Ext.dd.DropTarget', el, { + ddGroup: 'explorerTree', + notifyOver : function(ddSource, e, data) + { + if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet')) { + this.valid = false; + return this.dropNotAllowed; + } + if (((data.records[0].data.nodeType == 'localParam') || + (data.records[0].data.nodeType == 'remoteParam') || + (data.records[0].data.nodeType == 'remoteSimuParam') || + (data.records[0].data.nodeType == 'derivedParam') || + (data.records[0].data.nodeType == 'myDataParam') || + (data.records[0].data.nodeType == 'alias'))&& + (data.records[0].isLeaf() || data.records[0].data.isParameter) && + !data.records[0].data.disable) + { + this.valid = true; + return this.dropAllowed; + } + + this.valid = false; + return this.dropNotAllowed; + }, + notifyDrop : function(ddSource, e, data) + { + if (!this.valid) + return false; + var nameToSent; + switch (data.records[0].data.nodeType) + { + case 'localParam' : + case 'remoteParam': + case 'remoteSimuParam': + nameToSent = data.records[0].get('id'); + if (data.records[0].get('alias')!= "" ) + var nameToSent = "#"+data.records[0].get('alias'); + break; + case 'alias' : + nameToSent = "#"+data.records[0].get('text'); + break; + case 'derivedParam' : + nameToSent = "ws_"+data.records[0].get('text'); + break; + case 'myDataParam' : + nameToSent = "wsd_"+data.records[0].get('text'); + break; + default : + return false; + } + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id); + if (module) + { + if (data.records[0].get('needsArgs') && !data.records[0].get('isSpectra')) { + module.getUiContent().fireEvent('openParamEditor',nameToSent); + } + else { + module.addParam(nameToSent,true); + } + } + return true; + } + }); + }, + cellclick : function(grid, cell, cellIndex, record){ + if (cellIndex == 3) + grid.getStore().remove(record); + } + } + }); + + this.catalogGrid = Ext.create('Ext.grid.Panel', { + title: 'Catalog', + height: 500, + columns: [ + { text: '', dataIndex: '' } + + ] + }); + + this.formPanel = Ext.create('Ext.form.Panel', { + height: 550, + width: 800, + layout: 'border', + defaults: { layout: 'fit', border: false }, + fieldDefaults: { labelWidth: 80, labelAlign : 'top' }, + items: [ + { + xtype: 'form', + region: 'center', + flex: 1, + buttonAlign: 'left', + bodyStyle: {background : '#dfe8f6'}, + padding: '5 5 5 5', + layout: {type: 'vbox', pack: 'start', align: 'stretch'}, + items : [ + this.fieldName, + { + xtype: 'fieldcontainer', + layout: 'hbox', + items: [ + { + xtype:'datefield', fieldLabel:'Creation date', + name: 'created', disabled: true, + hideTrigger: true, format: 'Y/m/d H:i:s' + }, + { xtype: 'splitter' }, + { xtype:'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true} + ] + }, + { + xtype: 'textarea', + name: 'description', + fieldLabel: 'Description', +// anchor: '100% 50%' + }, + + this.paramGrid, + this.ttGrid + ], + fbar:[ + { + type: 'button', + text: 'Generate Catalog', + scope : this, + handler: function(button){ + // update object with user's values + // if the return is true (object had been updated) + // if(this.updateObject()){ + this.updateObject(); + this.generateCatalog(); + // } + } + }, + { + type: 'button', + text: 'Reset' + } + ] + }, { + xtype: 'form', + region: 'east', + bodyStyle: {background : '#dfe8f6'}, + padding: '5 5 5 5', + flex: 2, + items : [ + this.catalogGrid + ], + fbar:[ + { + type: 'button', + text: 'Save' + },{ + type: 'button', + text: 'Share', + disabled: true + }, + { + type: 'button', + text: 'Visualize' + } + ] + } + ] + }); + + + + var myConf = { + layout: 'border', + items: [ + this.formPanel, + { + xtype: 'panel', + region: 'south', + title: 'Information', + collapsible: true, + height: 100, + autoHide: false, + bodyStyle: 'padding:5px', + iconCls: 'icon-information', + loader: { + autoLoad: true, + url: helpDir+'downloadHOWTO' + } + } + ] + }; + + Ext.apply (this, Ext.apply(arguments, myConf)); + } + +}); -- libgit2 0.21.2