Commit 2b2bb2638d2c40cb2b34fcba6d5704fc040dd2ae

Authored by Hacene SI HADJ MOHAND
2 parents 6d20bc66 0e6edc02

Merge branch 'develop' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM into develop

generic_data/operations.json
1 1 {"nodes": [
2 2 {"nodeType" : "request", "text" : "Plot", "id" : "request-treeRootNode"} ,
3 3 {"nodeType" : "download", "text" : "Download", "id" : "download-treeRootNode"} ,
4   - {"nodeType" : "condition","text" : "Data Mining","id" : "condition-treeRootNode" }
  4 + {"nodeType" : "condition","text" : "Data Mining","id" : "condition-treeRootNode" },
  5 + {"nodeType" : "statistic","text" : "Statistic","id" : "statistic-treeRootNode" }
5 6 ]}
... ...
js/app/controllers/ExplorerModule.js
... ... @@ -48,7 +48,7 @@ Ext.define('amdaDesktop.ExplorerModule',
48 48 'amdaModel.Download',
49 49 'amdaModel.TimeTable',
50 50 'amdaModel.Catalog',
51   - 'amdaModel.Stats',
  51 + 'amdaModel.Statistic',
52 52 'amdaModel.FileObject',
53 53 'amdaModel.FileParamObject',
54 54 'amdaModel.FilterInfo'
... ...
js/app/controllers/InteractiveModule.js
... ... @@ -141,6 +141,7 @@ Ext.define('amdaDesktop.InteractiveModule', {
141 141 // this.operationOnShow();
142 142 if (onShowEvent)
143 143 onShowEvent();
  144 + onShowEvent = null; // use onShowEvent only once after window creation (cf. #9510)
144 145 }
145 146 });
146 147 } else {
... ...
js/app/controllers/JobsMgr.js
... ... @@ -94,7 +94,7 @@ Ext.define('amdaDesktop.JobsMgr', {
94 94 case 'download':
95 95 type = 'Download '
96 96 break
97   - case 'statistics':
  97 + case 'statistic':
98 98 type = 'Statistics '
99 99 break
100 100 default:
... ... @@ -161,7 +161,7 @@ Ext.define('amdaDesktop.JobsMgr', {
161 161 resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.DOWNLOAD, true)
162 162 jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.DOWNLOAD, true)
163 163 break
164   - case 'statistics':
  164 + case 'statistic':
165 165 resRootNode = root.findChild('id', bkgJob.RES_ROOT_NODE.STATISTICS, true)
166 166 jobRootNode = root.findChild('id', bkgJob.JOB_ROOT_NODE.STATISTICS, true)
167 167 break
... ...
js/app/controllers/StatisticsModule.js
... ... @@ -21,25 +21,16 @@ Ext.define('amdaDesktop.StatisticsModule', {
21 21 * @required
22 22 */
23 23 nodeDataModel : 'amdaModel.StatisticsNode',
24   - objectDataModel : 'amdaModel.Stats',
  24 + objectDataModel : 'amdaModel.Statistic',
25 25 /**
26 26 * @cfg {String} window definitions
27 27 * @required
28 28 */
29 29 width : 550,
30   - height: 550,
  30 + height: 600,
31 31 uiType : 'panelStatistics',
32 32 helpTitle : 'Help on Statistics Module',
33 33 helpFile : 'statisticsHelp',
34   - /**
35   - * @override
36   - */
37   - createWindow : function() {
38   - if (!this.linkedNode){
39   - this.setLinkedNode(amdaModel.StatisticsNode);
40   - }
41   - this.callParent(arguments);
42   - },
43 34  
44 35 saveState: function() {
45 36 var uiContent = this.getUiContent();
... ...
js/app/models/AmdaTimeObject.js
... ... @@ -12,12 +12,17 @@
12 12  
13 13  
14 14 Ext.define('amdaModel.TTobject', {
15   - extend: 'amdaModel.AmdaObject',
  15 + extend: 'amdaModel.AmdaObject',
  16 +
  17 + fields : [
  18 + {name: 'nodeType', type: 'string'}
  19 + ],
16 20  
17 21 getJsonValues : function () {
18 22 var values = new Object();
19 23 values.timeTableName = this.get('name');
20 24 values.id = this.get('id');
  25 + values.nodeType = this.get('nodeType');
21 26 return values;
22 27 }
23 28 });
... ...
js/app/models/BkgJobNode.js
... ... @@ -18,7 +18,7 @@ Ext.define('amdaModel.BkgJobNode', {
18 18 PLOT: 'request',//'plot',
19 19 CONDITION: 'condition',
20 20 DOWNLOAD: 'download',
21   - STATISTICS: 'statistics'
  21 + STATISTICS: 'statistic'
22 22 },
23 23 JOB_ROOT_NODE: {
24 24 PLOT: 'bkgPlot-treeRootNode',
... ... @@ -179,7 +179,7 @@ Ext.define('amdaModel.BkgJobNode', {
179 179 case 'condition' : var type = 'Data Mining '; break;
180 180 case 'request' : var type = 'Plot '; break;
181 181 case 'download' : var type = 'Download '; break;
182   - case 'statistics' : var type = 'Statistics '; break;
  182 + case 'statistic' : var type = 'Statistics '; break;
183 183 default: var type = 'unknown';
184 184 }
185 185  
... ... @@ -228,8 +228,8 @@ Ext.define('amdaModel.BkgJobNode', {
228 228 resultId : result.result,
229 229 folderId : result.folder});
230 230 break;
231   - case 'statistics' :
232   - obj = Ext.create('amdaModel.Stats',
  231 + case 'statistic' :
  232 + obj = Ext.create('amdaModel.Statistic',
233 233 {name: result.name,
234 234 resultId : result.result,
235 235 folderId : result.folder});
... ... @@ -325,7 +325,7 @@ Ext.define('amdaModel.BkgJobNode', {
325 325 case 'condition' : var type = 'Data Mining '; break;
326 326 case 'request' : var type = 'Plot '; break;
327 327 case 'download' : var type = 'Download '; break;
328   - case 'statistics' : var type = 'Statistics '; break;
  328 + case 'statistic' : var type = 'Statistics '; break;
329 329 default: var type = 'unknown';
330 330 }
331 331 myDesktopApp.infoMsg('Your request is still running and has been assigned the name '+this.get('text')+' -- Check Jobs in Progress');
... ...
js/app/models/Download.js
... ... @@ -77,7 +77,8 @@ Ext.define('amdaModel.Download', {
77 77 {name: 'fileformat', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.fileformat},
78 78 {name: 'fileformatTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.fileformatTT},
79 79 {name: 'compression', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filecompress},
80   - {name: 'compressionTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filecompressTT}
  80 + {name: 'compressionTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filecompressTT},
  81 + {name: 'last_update', type: 'int', defaultValue: 0}
81 82 ],
82 83  
83 84 associations : [
... ...
js/app/models/ExecutableNode.js
... ... @@ -11,7 +11,7 @@
11 11 Ext.define('amdaModel.ExecutableNode', {
12 12 extend: 'amdaModel.InteractiveNode',
13 13  
14   - fields: [ 'jobNode', 'resultModel'],
  14 + fields: [ 'jobNode', 'resultModel' ],
15 15  
16 16 statics: { jobTreeLoaded : false },
17 17  
... ...
js/app/models/InteractiveNode.js
... ... @@ -19,7 +19,8 @@ Ext.define('amdaModel.InteractiveNode', {
19 19 {name: 'filtered', type: 'boolean', defaultValue: false, persist: false},
20 20 {name: 'needsArgs', type:'boolean', defaultValue: false},
21 21 {name: 'predefinedArgs', type:'boolean', defaultValue: false},
22   - {name: 'disable', type: 'boolean', defaultValue: false, persist: false}
  22 + {name: 'disable', type: 'boolean', defaultValue: false, persist: false},
  23 + {name: 'last_update', type: 'int', defaultValue: 0}
23 24 ],
24 25  
25 26 statics: {
... ... @@ -206,6 +207,7 @@ Ext.define('amdaModel.InteractiveNode', {
206 207 }
207 208  
208 209 if (res.last_update) {
  210 + this.set('last_update', res.last_update);
209 211 this.get('object').set('last_update', res.last_update);
210 212 }
211 213  
... ... @@ -288,6 +290,7 @@ Ext.define('amdaModel.InteractiveNode', {
288 290  
289 291 var reloadObject = false;
290 292 if (res.last_update) {
  293 + this.set('last_update', res.last_update);
291 294 this.get('object').set('last_update', res.last_update);
292 295 reloadObject = true;
293 296 }
... ...
js/app/models/Statistic.js 0 โ†’ 100644
... ... @@ -0,0 +1,119 @@
  1 +/**
  2 + * Project : AMDA-NG
  3 + * Name : Statistic.js
  4 + * Description : Statistics Object Definition
  5 + * @class amdaModel.Statistic
  6 + * @extends amdaModel.AmdaTimeObject
  7 + * @author elena
  8 + */
  9 +
  10 +Ext.define('amdaModel.Statistic', {
  11 + extend: 'amdaModel.AmdaTimeObject',
  12 +
  13 + requires: [
  14 + "amdaModel.StatisticParam"
  15 + ],
  16 +
  17 + fields : [
  18 + {name: 'type', type: 'string', defaultValue: 'Statistic'},
  19 + {name: 'description', type: 'string'},
  20 + {name: 'last_update', type: 'int', defaultValue: 0}
  21 + ],
  22 +
  23 + associations : [
  24 + {
  25 + type : 'hasMany',
  26 + model : 'amdaModel.StatisticParam',
  27 + name : 'params'
  28 + }
  29 + ],
  30 +
  31 + constructor: function(){
  32 + var me = this;
  33 + me.callParent(arguments);
  34 + if ((arguments.length > 0) && arguments[0])
  35 + {
  36 + if (arguments[0].parameter)
  37 + me.loadParams(arguments[0].parameter);
  38 + }
  39 + this.dirty = false;
  40 + },
  41 +
  42 + loadParams: function(params)
  43 + {
  44 + /* Compatability mode */
  45 + Ext.each(params, function(param, index) {
  46 + if (param.hasOwnProperty('is-init')) {
  47 + return;
  48 + }
  49 + params[index]['dim1-sum-type'] = param['dim1-is-range'] ? 1 : 0;
  50 + params[index]['dim1-min-value'] = param['dim1-min-range'];
  51 + params[index]['dim1-max-value'] = param['dim1-max-range'];
  52 + params[index]['dim2-sum-type'] = param['dim2-is-range'] ? 1 : 0;
  53 + params[index]['dim2-min-value'] = param['dim2-min-range'];
  54 + params[index]['dim2-max-value'] = param['dim2-max-range'];
  55 + params[index]['is-init'] = true;
  56 + });
  57 + this.params().loadData(params);
  58 + },
  59 +
  60 + isDirty : function() {
  61 + if (this.dirty)
  62 + return true;
  63 +
  64 + var d = false;
  65 +
  66 + this.params().each(function (param, index) {
  67 + if (param.dirty)
  68 + d = true;
  69 + });
  70 + return d;
  71 + },
  72 +
  73 + getJsonValues : function ()
  74 + {
  75 + var values = new Object();
  76 + values.nodeType = 'statistic';
  77 + values.type = this.get('type');
  78 + values.name = this.get('name');
  79 + values.timesrc = this.get('timesrc');
  80 + values.description = this.get('description');
  81 +
  82 + // if there's at least one parameter
  83 + values.parameter = [];
  84 + this.params().each(function (param, index) {
  85 + values.parameter[index] = param.getJsonValues();
  86 + });
  87 +
  88 + if (values.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0])
  89 + {
  90 + // get complete timeTables collection
  91 + var timeTables = this.get('timeTables');
  92 + // init an empty array for timeTables
  93 + values.timeTables=[];
  94 + // for each interval record
  95 + Ext.Array.each(timeTables, function(item, index, all)
  96 + {
  97 + if (!item.$className) {
  98 + values.timeTables[index] = {timeTableName : item.timeTableName, id : item.id};
  99 + }
  100 + // get Json simplified value
  101 + else {
  102 + values.timeTables[index] = item.getJsonValues();
  103 + }
  104 + });
  105 + } else
  106 + {
  107 + values.startDate = this.get('startDate');
  108 + values.stopDate = this.get('stopDate');
  109 + values.durationDay = this.get('durationDay');
  110 + values.durationHour = this.get('durationHour');
  111 + values.durationMin = this.get('durationMin');
  112 + values.durationSec = this.get('durationSec');
  113 + }
  114 +
  115 + values.leaf = true;
  116 +
  117 + return values;
  118 + }
  119 +});
... ...
js/app/models/StatisticParam.js 0 โ†’ 100644
... ... @@ -0,0 +1,30 @@
  1 +/**
  2 + * Projectย  : AMDA-NG
  3 + * Name : StatisticParam.js
  4 + * Description : Statistic Param Business Object Definition
  5 + * @class amdaModel.StatisticParam
  6 + * @extends amdaModel.RequestParamObject
  7 + *
  8 + * @author benjamin
  9 + * @version $Id: StatisticParam.js 2068 2021-05-20 11:27:38Z benjamin $
  10 + ******************************************************************************
  11 + * FT Id : Date : Name - Description
  12 + ******************************************************************************
  13 + * : :20/05/2021: benjamin โ€“ creation
  14 + */
  15 +
  16 +
  17 +Ext.define('amdaModel.StatisticParam', {
  18 + extend: 'amdaModel.RequestParamObject',
  19 +
  20 + fields : [
  21 + {name: 'function', type: 'string', defaultValue: ''}
  22 + ],
  23 +
  24 + getJsonValues : function ()
  25 + {
  26 + var values = this.callParent(arguments);
  27 + values['function'] = this.get('function');
  28 + return values;
  29 + }
  30 +});
... ...
js/app/models/StatisticsNode.js
... ... @@ -10,22 +10,15 @@
10 10 Ext.define('amdaModel.StatisticsNode', {
11 11  
12 12 extend: 'amdaModel.ExecutableNode',
13   -
14   - singleton: true,
  13 +
  14 + statics: {
  15 + nodeType: 'statistic',
  16 + objectName: 'Statistic'
  17 + },
15 18  
16   - fields: [
17   - {name: 'object', type: 'object'},
18   - {name: 'moduleId', type: 'string', defaultValue:'statistics-win'},
19   - {name: 'nodeType', type: 'string', defaultValue: 'statistics'},
20   - {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Stats'},
21   - {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
22   - ],
23   -
24   - constructor: function(config) {
25   - this.callParent(arguments);
26   - this.set('nodeType','statistics');
27   - },
28   - isExecutable: function(){
29   - return true;
  19 + constructor: function(config) {
  20 + this.callParent(arguments);
  21 + this.set('moduleId',myDesktopApp.dynamicModules.statistics.id);
  22 + this.set('objectDataModel',amdaModel.Statistic.$className);
30 23 }
31 24 });
... ...
js/app/models/Stats.js deleted
... ... @@ -1,82 +0,0 @@
1   -/**
2   - * Project : AMDA-NG
3   - * Name : Stats.js
4   - * Description : Statistics Object Definition
5   - * @class amdaModel.Stats
6   - * @extends amdaModel.TimeTable
7   - * @author elena
8   - */
9   -
10   -Ext.define('amdaModel.Stats', {
11   - extend: 'amdaModel.AmdaTimeObject',
12   -
13   - fields : [
14   - { name: 'parameter' } ,
15   - { name: 'description' }
16   - ],
17   -
18   - getJsonValues : function (hasId)
19   - {
20   - var values = new Object();
21   - if (hasId) {
22   - values.id = this.get('id');
23   - }
24   -
25   - values.timesrc = this.get('timesrc');
26   - values.name = this.get('name');
27   -
28   -// if (this.get('description').match(/[a-z,0-9]/gi) != null) {
29   -// values.description = this.get('description');
30   -// }
31   -// if (this.get('history').match(/[a-z,0-9]/gi) != null) {
32   -// values.history = this.get('history');
33   -// }
34   - values.objName = this.get('objName');
35   - values.objFormat = this.get('objFormat');
36   -
37   -// values.cacheToken = this.get('cacheToken');
38   - values.parameter = this.get('parameter');
39   -
40   - // if there's at least one parameter
41   -// if (this.get('parameter') && this.get('parameter').length)
42   -// {
43   -// var list = this.get('parameter');
44   -// values.parameter=[];
45   -// Ext.each(list, function(item, index){
46   -// values.parameter[index] = item.getJsonValues();
47   -// });
48   -// }
49   -
50   - if (values.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0])
51   - {
52   - // get complete timeTables collection
53   - var timeTables = this.get('timeTables');
54   - // init an empty array for timeTables
55   - values.timeTables=[];
56   - // for each interval record
57   - Ext.Array.each(timeTables, function(item, index, all)
58   - {
59   - if (!item.$className) {
60   - values.timeTables[index] = {timeTableName : item.timeTableName, id : item.id};
61   - }
62   - // get Json simplified value
63   - else {
64   - values.timeTables[index] = item.getJsonValues();
65   - }
66   - });
67   - } else
68   - {
69   - values.startDate = this.get('startDate');
70   - values.stopDate = this.get('stopDate');
71   - values.durationDay = this.get('durationDay');
72   - values.durationHour = this.get('durationHour');
73   - values.durationMin = this.get('durationMin');
74   - values.durationSec = this.get('durationSec');
75   - }
76   -
77   - values.leaf = true;
78   - values.nodeType = 'statistics';
79   -
80   - return values;
81   - }
82   -});
js/app/models/TimeTableNode.js
... ... @@ -135,7 +135,7 @@ Ext.define('amdaModel.TimeTableNode', {
135 135 var me = this;
136 136 myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.tt_op.id, true, function (module) {
137 137 module.createWindow();
138   - module.getUiContent().addTT(me.get('text'), me.get('id'));
  138 + module.getUiContent().addTT(me.get('text'), me.get('id'), me.get('nodeType'));
139 139 });
140 140 },
141 141  
... ...
js/app/stores/ExplorerReader.js
... ... @@ -48,7 +48,9 @@ Ext.define('amdaReader.ExplorerReader', {
48 48 case 'request' :
49 49 return amdaModel.PlotNode;
50 50 case 'download' :
51   - return amdaModel.DownloadNode;
  51 + return amdaModel.DownloadNode;
  52 + case 'statistic' :
  53 + return amdaModel.StatisticsNode;
52 54 case 'bkgWorks' :
53 55 return amdaModel.BkgJobNode;
54 56 default:
... ...
js/app/views/ExplorerUI.js
... ... @@ -544,7 +544,10 @@ Ext.define('amdaUI.ExplorerUI', {
544 544 menu.removeListener('click',onRecordClick,this);
545 545 };
546 546  
547   - menu.addListener('click',onRecordClick,rec);
  547 + if (!menu.hasListener('click')) {
  548 + // set click listener on menu only once (cf. #9510)
  549 + menu.addListener('click',onRecordClick,rec);
  550 + }
548 551 // then show menu
549 552 menu.showAt(e.getXY());
550 553 }
... ... @@ -589,6 +592,7 @@ Ext.define('amdaUI.ExplorerUI', {
589 592 case 'request' :
590 593 case 'condition' :
591 594 case 'download':
  595 + case 'statistic':
592 596 record.editLeaf();
593 597 break;
594 598 case 'localParam' :
... ... @@ -645,6 +649,13 @@ Ext.define('amdaUI.ExplorerUI', {
645 649 beforeshow: function updateTipBody(tip) {
646 650 if (view.getRecord(tip.triggerElement)) {
647 651 var info = view.getRecord(tip.triggerElement).get('info');
  652 + var last_update = view.getRecord(tip.triggerElement).get('last_update');
  653 + if (last_update && (last_update > 0)) {
  654 + if (info && (info != '')) {
  655 + info += '<br/>';
  656 + }
  657 + info += '<b>Last modification: </b>' + Ext.Date.format(new Date(last_update * 1000), "Y-m-d H:i:s");
  658 + }
648 659 if (!info || info == '') {
649 660 tip.addCls('hide');
650 661 }
... ...
js/app/views/StatisticsUI.js
... ... @@ -13,18 +13,11 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
13 13 alias: 'widget.panelStatistics',
14 14  
15 15 requires: [
16   - //'amdaModel.Function'
17 16 'amdaUI.TimeSelectorUI',
18 17 'amdaUI.ParamArgumentsPlug',
19   - 'amdaModel.DownloadParam',
20   - 'amdaModel.RequestParamObject'
  18 + 'amdaModel.StatisticParam'
21 19 ],
22 20  
23   - statics:
24   - {
25   - // functionStore : null
26   - },
27   -
28 21 constructor: function (config)
29 22 {
30 23 this.init(config);
... ... @@ -41,7 +34,15 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
41 34 // load object into form
42 35 var basicForm = this.formPanel.items.items[1].getForm();
43 36 basicForm.loadRecord(this.object);
  37 + // set object's TTs into the timeselector
  38 + this.timeSelector.setTTTab(this.object.get('timeTables'));
  39 + // set parameters
  40 + this.paramGrid.reconfigure(this.object.params());
  41 + },
44 42  
  43 + setObject: function (obj) {
  44 + this.object = obj;
  45 + this.loadObject();
45 46 },
46 47  
47 48 onApplyParameterArgs: function (parentUI, paramObject)
... ... @@ -67,7 +68,7 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
67 68 }
68 69 }
69 70  
70   - var r = Ext.create('amdaModel.DownloadParam', paramObj);
  71 + var r = Ext.create('amdaModel.StatisticParam', paramObj);
71 72 this.paramGrid.getStore().add(r);
72 73 this.paramGrid.getSelectionModel().select(this.paramGrid.getStore().getCount() - 1);
73 74 // var pos = this.paramGrid.store.getCount();
... ... @@ -86,6 +87,88 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
86 87 paramArgsPlug.show('statistics-param-arguments-plugin', record);
87 88 },
88 89  
  90 + saveRequest : function()
  91 + {
  92 + var me = this;
  93 +
  94 + if (!this.updateObject()) {
  95 + return;
  96 + }
  97 +
  98 + var statisticModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.statistics.id);
  99 +
  100 + if ((this.object.get('id') != '') && (statisticModule.linkedNode.get('text') == this.object.get('name'))) {
  101 + this.saveProcess(false);
  102 + return;
  103 + }
  104 +
  105 + statisticModule.linkedNode.isValidName(this.fieldName.getValue(), function (res) {
  106 + if (!res)
  107 + {
  108 + me.fieldName.validFlag = 'Error during object validation';
  109 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  110 + me.fieldName.validate();
  111 + return;
  112 + }
  113 +
  114 + if (!res.valid)
  115 + {
  116 + if (res.error)
  117 + {
  118 + if (res.error.search('subtree') != -1) {
  119 + Ext.MessageBox.show({title:'Warning',
  120 + msg: res.error+'<br/>Do you want to overwrite it?',
  121 + width: 300,
  122 + buttons: Ext.MessageBox.OKCANCEL,
  123 + fn : function(btn) {
  124 + if (btn == 'cancel') return;
  125 + this.fieldName.clearInvalid();
  126 + this.saveProcess(true);
  127 + },
  128 + icon: Ext.MessageBox.WARNING,
  129 + scope : me
  130 + });
  131 + me.fieldName.validFlag = true;
  132 + }
  133 + else
  134 + me.fieldName.validFlag = res.error;
  135 + }
  136 + else
  137 + {
  138 + me.fieldName.validFlag = 'Invalid object name';
  139 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  140 + }
  141 + me.fieldName.validate();
  142 + return;
  143 + }
  144 +
  145 + me.fieldName.validFlag = true;
  146 + me.fieldName.validate();
  147 + me.saveProcess(false);
  148 + });
  149 + },
  150 +
  151 + saveProcess: function(toRename) {
  152 + var statisticModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.statistics.id);
  153 + if (this.object.isModified('name')) {
  154 + if (this.object.get('id'))
  155 + {
  156 + var contextNode = statisticModule.linkedNode.parentNode;
  157 + statisticModule.createLinkedNode();
  158 + statisticModule.linkedNode.set('contextNode',contextNode);
  159 + statisticModule.createObject(this.object.getJsonValues());
  160 + var statisticObj = statisticModule.linkedNode.get('object');
  161 + this.object = statisticObj;
  162 + if (toRename) statisticModule.linkedNode.toRename = true;
  163 + }
  164 + statisticModule.linkedNode.create();
  165 + }
  166 + else {
  167 + statisticModule.linkedNode.set('contextNode',statisticModule.contextNode);
  168 + statisticModule.linkedNode.update();
  169 + }
  170 + },
  171 +
89 172 addTT: function (TTname, TTid)
90 173 {
91 174 this.timeSelector.addTT(TTname, TTid);
... ... @@ -181,7 +264,7 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
181 264 init: function (config)
182 265 {
183 266 this.fieldName = new Ext.form.field.Text({
184   - fieldLabel: 'Catalog Name',
  267 + fieldLabel: 'Request Name',
185 268 allowBlank: false,
186 269 stripCharsRe: /(^\s+|\s+$)/g,
187 270 emptyText: 'Please no spaces!',
... ... @@ -195,25 +278,15 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
195 278 }
196 279 });
197 280  
198   - var ttStore = Ext.create('Ext.data.Store',
199   - {
200   - fields: ['name', 'hidden_id']
201   - });
202   -
203 281 this.timeSelector = new amdaUI.TimeSelectorUI({id: 'statisticsTimeSelector', flex: 1});
204 282  
205   - var store = Ext.create('Ext.data.Store',
206   - {
207   - fields: ['name', 'function']
208   - });
209   -
210 283 this.paramGrid = Ext.create('Ext.grid.Panel',
211 284 {
212 285 title: 'Select Parameter & Apply Function',
213 286 selType: 'rowmodel',
214 287 flex: 2,
215 288 // height :250,
216   - store: store,
  289 + store: Ext.create('Ext.data.Store', {model: 'amdaModel.StatisticParam'}),
217 290 columns: [
218 291 {xtype: 'rownumberer'},
219 292 {
... ... @@ -408,7 +481,7 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
408 481 items: [this.paramGrid],
409 482 fbar: [{
410 483 type: 'button',
411   - text: 'Generate Catalog',
  484 + text: 'Generate',
412 485 scope: this,
413 486 handler: function ()
414 487 {
... ... @@ -428,7 +501,16 @@ Ext.define(&#39;amdaUI.StatisticsUI&#39;,
428 501 this.paramGrid.store.removeAll();
429 502 this.timeSelector.TTGrid.store.removeAll();
430 503 }
431   - }]
  504 + },
  505 + {
  506 + text: 'Save',
  507 + id: 'save-statistic',
  508 + scope: this,
  509 + handler: function () {
  510 + this.saveRequest();
  511 + }
  512 + }
  513 + ]
432 514 },
433 515 {
434 516 xtype: 'form',
... ...
js/app/views/TabResultUI.js
... ... @@ -31,7 +31,7 @@ Ext.define(&#39;amdaUI.TabResultUI&#39;, {
31 31 break;
32 32 case 'download': var title = 'Download Results';
33 33 break;
34   - case 'statistics': var title = 'Statistics Results';
  34 + case 'statistic': var title = 'Statistics Results';
35 35 break;
36 36 default:
37 37 }
... ... @@ -319,7 +319,7 @@ Ext.define(&#39;amdaUI.ResultItem&#39;, {
319 319 case 'condition' :
320 320 Ext.apply(this, configTT);
321 321 break;
322   - case 'statistics' :
  322 + case 'statistic' :
323 323 Ext.apply(this, configCat);
324 324 break;
325 325 case 'request' :
... ...
js/app/views/TimeTableOperationUI.js
... ... @@ -17,13 +17,13 @@ Ext.define(&#39;amdaUI.TimeTableOperationUI&#39;, {
17 17 this.callParent(arguments);
18 18 },
19 19  
20   - addTT : function(newTTName,newTTid) {
  20 + addTT : function(newTTName,newTTid,nodeType) {
21 21 // search for an existing record in store with this unique name
22 22 var existingIndex = this.TTGrid.store.findExact( 'name', newTTName);
23 23 // if no corresponding TT found
24 24 if (existingIndex == -1){
25 25 // adding the time table to the TTGrid of TT download
26   - var r = Ext.create('amdaModel.TTobject', { id: newTTid, name: newTTName });
  26 + var r = Ext.create('amdaModel.TTobject', { id: newTTid, name: newTTName, nodeType: nodeType});
27 27 this.TTGrid.store.insert(this.TTGrid.store.getCount(),r);
28 28 }
29 29 },
... ... @@ -125,7 +125,7 @@ Ext.define(&#39;amdaUI.TimeTableOperationUI&#39;, {
125 125 var timeTableOperationModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.tt_op.id);
126 126 if (!timeTableOperationModule)
127 127 return false;
128   - timeTableOperationModule.getUiContent().addTT(data.records[0].get('text'),data.records[0].get('id'));
  128 + timeTableOperationModule.getUiContent().addTT(data.records[0].get('text'),data.records[0].get('id'), data.records[0].get('nodeType'));
129 129 return true;
130 130 }
131 131 });
... ... @@ -173,7 +173,7 @@ Ext.define(&#39;amdaUI.TimeTableOperationUI&#39;, {
173 173 var ttids = [];
174 174 var name= "";
175 175 Ext.each(tts, function(tt, index) {
176   - ttids[index] = tt.data.id;
  176 + ttids[index] = {'id': tt.data.id, 'nodeType' : tt.data.nodeType};
177 177 name = name + tt.data.name + " ";
178 178 });
179 179 // Time table's name and history field
... ... @@ -235,7 +235,7 @@ Ext.define(&#39;amdaUI.TimeTableOperationUI&#39;, {
235 235 var tts = this.TTGrid.getStore().data.items;
236 236 var ttids = [];
237 237 Ext.each(tts, function(tt, index) {
238   - ttids[index] = tt.data.id;
  238 + ttids[index] = {'id': tt.data.id, 'nodeType': tt.data.nodeType};
239 239 });
240 240 // Time table's name and history field
241 241 var newTabName = tts[0].data.name + "_I_" + tts[1].data.name;
... ...
php/classes/AmdaAction.php
... ... @@ -10,7 +10,7 @@ class AmdaAction
10 10 'remoteSimuParam' => 'RemoteParams.xml', 'derivedParam' => 'WsParams.xml', 'myDataParam' => 'WsParams.xml',
11 11 'timeTable' => 'Tt.xml', 'catalog' => 'Tt.xml', 'alias' => 'Alias.xml',
12 12 'myData' => 'Files.xml',
13   - 'request' => 'Request.xml', 'condition' => 'Request.xml', 'download' => 'Request.xml',
  13 + 'request' => 'Request.xml', 'condition' => 'Request.xml', 'download' => 'Request.xml', 'statistic' => 'Request.xml',
14 14 'bkgWorks' => 'jobs.xml');
15 15  
16 16 private $user, $amdaStat;
... ... @@ -152,6 +152,7 @@ class AmdaAction
152 152 $isSimulation = false;
153 153 $rank = null;
154 154 $skip = FALSE;
  155 + $last_update = 0;
155 156  
156 157 switch ($nodeType)
157 158 {
... ... @@ -172,8 +173,13 @@ class AmdaAction
172 173 case 'download':
173 174 case 'condition':
174 175 case 'request':
  176 + case 'statistic':
175 177 $objectMgr = new RequestMgr($nodeType);
176 178 $info = $objectMgr->getObjectInfo($id);
  179 + $obj_info = $objectMgr->getObject($id);
  180 + if (!empty($obj_info) && !empty($obj_info->last_update)) {
  181 + $last_update = $obj_info->last_update;
  182 + }
177 183 break;
178 184  
179 185 case 'timeTable':
... ... @@ -357,7 +363,7 @@ class AmdaAction
357 363 $info .= "<br/><b>Plot Only!!!</b>";
358 364 }
359 365  
360   - $childrenToReturn[] = array('text' => $name, 'id' => $id,'nodeType' => $nodeType, 'info' => $info,
  366 + $childrenToReturn[] = array('text' => $name, 'id' => $id,'nodeType' => $nodeType, 'info' => $info, 'last_update' => $last_update,
361 367 'leaf' => false, 'help' => $help, 'disable' => $disable, 'rank' => $rank, 'timeRestriction' => $timeRestriction);
362 368 }
363 369 break;
... ... @@ -577,7 +583,7 @@ class AmdaAction
577 583 $childrenToReturn[] = array('text' => $name, 'id' => $id, 'nodeType' => $nodeType, 'info' => $info,
578 584 'help' => $help, 'leaf' => $isLeaf, 'isParameter' => $isParameter, 'dim_1' => $dim_1, 'dim_2' => $dim_2,
579 585 'component_info' => isset($component_info) ? $component_info : NULL,
580   - 'iconCls' => isset($iconCls) ? $iconCls : NULL );
  586 + 'iconCls' => isset($iconCls) ? $iconCls : NULL, 'last_update' => $last_update );
581 587 }
582 588 }
583 589 // if $childrenToReturn we have to return []
... ... @@ -735,6 +741,7 @@ class AmdaAction
735 741 case 'condition' :
736 742 case 'request' :
737 743 case 'download' :
  744 + case 'statistic':
738 745 $objectMgr = new RequestMgr($nodeType);
739 746 break;
740 747 case 'bkgWorks' :
... ... @@ -769,6 +776,7 @@ class AmdaAction
769 776 case 'condition' :
770 777 case 'request' :
771 778 case 'download' :
  779 + case 'statistic' :
772 780 $objectMgr = new RequestMgr($obj->nodeType);
773 781 break;
774 782 case 'alias' :
... ... @@ -808,6 +816,7 @@ class AmdaAction
808 816 case 'condition' :
809 817 case 'request' :
810 818 case 'download' :
  819 + case 'statistic' :
811 820 $objectMgr = new RequestMgr($obj->nodeType);
812 821 break;
813 822 case 'alias' :
... ... @@ -842,6 +851,7 @@ class AmdaAction
842 851 case 'condition' :
843 852 case 'request' :
844 853 case 'download' :
  854 + case 'statistic' :
845 855 $objectMgr = new RequestMgr($obj->nodeType);
846 856 break;
847 857 case 'alias' :
... ... @@ -873,6 +883,7 @@ class AmdaAction
873 883 case 'condition' :
874 884 case 'request' :
875 885 case 'download' :
  886 + case 'statistic' :
876 887 $objectMgr = new RequestMgr($obj->nodeType);
877 888 break;
878 889 default:
... ... @@ -900,6 +911,7 @@ class AmdaAction
900 911 case 'condition' :
901 912 case 'request' :
902 913 case 'download' :
  914 + case 'statistic' :
903 915 $objectMgr = new RequestMgr($obj->nodeType);
904 916 break;
905 917 default:
... ...
php/classes/AmdaStats.php
... ... @@ -7,13 +7,13 @@
7 7 class AmdaStats {
8 8  
9 9 public $statXml;
10   - public $tasks = array('plot', 'mining', 'print', 'statistics');
  10 + public $tasks = array('plot', 'mining', 'print', 'statistic');
11 11 public $tasksWs = array('ws_print', 'ws_plot');
12 12 public $tasksAdd = array('ttoper', 'samp', 'upload', 'create', 'images');
13 13 public $usersToExclude = array('bouchemit');
14 14 public $success = true;
15 15 private $user = null;
16   - private $task = array('request'=>'plot','condition'=>'mining', 'download'=>'print','statistics'=>'statistics',
  16 + private $task = array('request'=>'plot','condition'=>'mining', 'download'=>'print','statistic'=>'statistics',
17 17 'getparameter'=>'ws_print', 'getdataset' => 'ws_print', 'getorbites' => 'ws_print', 'getplot' => 'ws_plot');
18 18  
19 19 public function __construct($user) {
... ...
php/classes/RequestMgr.php
... ... @@ -9,7 +9,7 @@ class RequestMgr extends AmdaObjectMgr
9 9 public $obj;
10 10 protected $type;
11 11 protected $jobXml, $jobXmlName;
12   - protected $types = array('request', 'download', 'condition');
  12 + protected $types = array('request', 'download', 'condition', 'statistic');
13 13  
14 14 function __construct($type)
15 15 {
... ... @@ -38,6 +38,10 @@ class RequestMgr extends AmdaObjectMgr
38 38 {
39 39 $this->id_prefix = 'down_';
40 40 }
  41 + else if ($type == 'statistic')
  42 + {
  43 + $this->id_prefix = 'stat_';
  44 + }
41 45 else
42 46 {
43 47 $this->id_prefix = 'cond_';
... ... @@ -298,7 +302,7 @@ class RequestMgr extends AmdaObjectMgr
298 302 if (count($argsTab) > 0) $args[] = $argsTab;
299 303  
300 304 break;
301   - case 'statistics' :
  305 + case 'statistic' :
302 306 return array('success' => true);
303 307 break;
304 308 default :
... ... @@ -421,6 +425,32 @@ class RequestMgr extends AmdaObjectMgr
421 425 $info .= "Empty";
422 426 }
423 427 break;
  428 + case 'statistic':
  429 + $info .= "Statistic: ";
  430 + $functions_list = array();
  431 + if (!empty($obj->parameter)) {
  432 + foreach ($obj->parameter as $param) {
  433 + if (!array_key_exists($param->function, $functions_list)) {
  434 + $functions_list[$param->function] = array();
  435 + }
  436 + if (!in_array($param->paramid, $functions_list[$param->function])) {
  437 + $functions_list[$param->function][] = $param->paramid;
  438 + }
  439 + }
  440 + if (!empty($functions_list)) {
  441 + foreach ($functions_list as $func => $params) {
  442 + $info .= "<br/>";
  443 + $info .= "<b>" . $func . ":</b> " . implode(', ', $params);
  444 + }
  445 + }
  446 + else {
  447 + $info .= "Empty";
  448 + }
  449 + }
  450 + else {
  451 + $info .= "Empty";
  452 + }
  453 + break;
424 454 default:
425 455 $info .= "<b>ERROR:</b> Unknown request type";
426 456 }
... ...
php/classes/TimeTableMgr.php
... ... @@ -359,7 +359,7 @@ class TimeTableMgr extends AmdaObjectMgr
359 359  
360 360 $intervals = 0;
361 361 for ($iId = 0; $iId < count($obj->ids); $iId++) {
362   - $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]);
  362 + $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
363 363 for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
364 364 $interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
365 365 $interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
... ... @@ -559,7 +559,7 @@ class TimeTableMgr extends AmdaObjectMgr
559 559 {
560 560 $intervals = 0;
561 561 for ($iId = 0; $iId < count($obj->ids); $iId++) {
562   - $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]);
  562 + $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
563 563 for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
564 564 $interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
565 565 $interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
... ...