Commit 7139db83d09623a3d5e44a883098e08980db7dcb

Authored by Benjamin Renard
2 parents 0ace2f9a 6d5299c8
Exists in special-params

Merge branch 'amdadev' into special-params

Showing 45 changed files with 1588 additions and 1150 deletions   Show diff stats
generic_data/Functions/functions.xml
... ... @@ -109,7 +109,11 @@
109 109 <info_brief>Shifts parameter by T secs back (T &lt; 0) and forth (T &gt; 0))</info_brief>
110 110 <new_kernel>#timeShift</new_kernel>
111 111 </function>
112   -
  112 + <function name="filter()" args="3" kind="filter" group="space">
  113 + <default_args>,6,100</default_args>
  114 + <info_brief>Remove Spikes: filter(param, factor,nPoints)</info_brief>
  115 + <new_kernel>#filter</new_kernel>
  116 + </function>
113 117 <function name="vAlfven(,)" args="2" kind="physics" group="space">
114 118 <prompt_param>density[cm^⁻3], b_magnitude[nT]</prompt_param>
115 119 <info_brief>Alfven velocity Valfven(density[cm^⁻3], b_magnitude[nT])</info_brief>
... ... @@ -274,4 +278,5 @@
274 278 <info_brief>Square root</info_brief>
275 279 <new_kernel>sqrt</new_kernel>
276 280 </function>
  281 +
277 282 </functions>
... ...
generic_data/operations.json
1 1 {"nodes": [
2 2 {"nodeType" : "request", "text" : "Plot", "id" : "request-treeRootNode"} ,
3   - {"nodeType" : "condition","text" : "Data Mining","id" : "condition-treeRootNode" }
  3 + {"nodeType" : "download", "text" : "Download", "id" : "download-treeRootNode"} ,
  4 + {"nodeType" : "condition","text" : "Data Mining","id" : "condition-treeRootNode" },
  5 + {"nodeType" : "statistic","text" : "Statistic","id" : "statistic-treeRootNode" }
4 6 ]}
... ...
js/app/controllers/DownloadModule.js
... ... @@ -22,7 +22,6 @@ Ext.define(&#39;amdaDesktop.DownloadModule&#39;, {
22 22 * @cfg {String} data models
23 23 * @required
24 24 */
25   - objectDataModel : 'amdaModel.Download',
26 25 nodeDataModel : 'amdaModel.DownloadNode',
27 26  
28 27 /**
... ... @@ -30,21 +29,11 @@ Ext.define(&#39;amdaDesktop.DownloadModule&#39;, {
30 29 * @required
31 30 */
32 31 width: 600,
33   - height: 600,
  32 + height: 620,
34 33 uiType : 'panelDownload',
35 34 helpTitle : 'Help on Download Module',
36 35 helpFile : 'downloadHelp',
37 36  
38   - /**
39   - * @override
40   - */
41   - createWindow : function() {
42   - if (!this.linkedNode){
43   - this.setLinkedNode(amdaModel.DownloadNode);
44   - }
45   - this.callParent(arguments);
46   - },
47   -
48 37 saveState: function() {
49 38 var uiContent = this.getUiContent();
50 39 var form = uiContent.down('form').getForm();
... ... @@ -56,5 +45,26 @@ Ext.define(&#39;amdaDesktop.DownloadModule&#39;, {
56 45 getState : function() {
57 46 // return Ext.state.Manager.get(this.id + '_form');
58 47 return Ext.state.Manager.get('timeinterval');
  48 + },
  49 +
  50 + addParameter: function(paramNode) {
  51 + var me = this;
  52 + var desktop = this.app.getDesktop();
  53 + var win = desktop.getWindow(this.id);
  54 + if (win) {
  55 + me.getUiContent().addParameter(paramNode, false);
  56 + win.show();
  57 + }
  58 + else {
  59 + this.createWindow(function () {
  60 + me.getUiContent().addParameter(paramNode, true);
  61 + });
  62 + }
  63 + },
  64 +
  65 + editFromJsonData: function(jsonData) {
  66 + this.createLinkedNode();
  67 + this.createObject(jsonData);
  68 + this.createWindow();
59 69 }
60   -});
61 70 \ No newline at end of file
  71 +});
... ...
js/app/controllers/ExplorerModule.js
... ... @@ -49,7 +49,7 @@ Ext.define(&#39;amdaDesktop.ExplorerModule&#39;,
49 49 'amdaModel.Download',
50 50 'amdaModel.TimeTable',
51 51 'amdaModel.Catalog',
52   - 'amdaModel.Stats',
  52 + 'amdaModel.Statistic',
53 53 'amdaModel.FileObject',
54 54 'amdaModel.FileParamObject',
55 55 'amdaModel.FilterInfo'
... ...
js/app/controllers/InteractiveModule.js
... ... @@ -141,6 +141,7 @@ Ext.define(&#39;amdaDesktop.InteractiveModule&#39;, {
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(&#39;amdaDesktop.JobsMgr&#39;, {
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(&#39;amdaDesktop.JobsMgr&#39;, {
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/PlotModule.js
... ... @@ -300,5 +300,30 @@ Ext.define(&#39;amdaDesktop.PlotModule&#39;, {
300 300  
301 301 isMultiPlot : function() {
302 302 return this.multiPlotWin && !this.multiPlotWin.isHidden();
  303 + },
  304 +
  305 + editInDownloadModule: function(plotNode) {
  306 + var plotValues = plotNode.get('object').getJsonValues();
  307 + var downloadValues = new Object();
  308 + downloadValues.timesrc = plotValues.timesrc;
  309 + downloadValues.startDate = plotValues.startDate;
  310 + downloadValues.stopDate = plotValues.stopDate;
  311 + downloadValues.durationDay = plotValues.durationDay;
  312 + downloadValues.durationHour = plotValues.durationHour;
  313 + downloadValues.durationMin = plotValues.durationMin;
  314 + downloadValues.durationSec = plotValues.durationSec;
  315 + if (plotValues.timeTables)
  316 + downloadValues.timeTables = plotValues.timeTables;
  317 + downloadValues.list = [];
  318 + plotNode.get('object').panels().each(function (panel) {
  319 + panel.params().each(function (param) {
  320 + paramObj = param.getJsonValues();
  321 + paramObj.id = "";
  322 + downloadValues.list.push(paramObj);
  323 + });
  324 + });
  325 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) {
  326 + module.editFromJsonData(downloadValues);
  327 + });
303 328 }
304 329 });
... ...
js/app/controllers/StatisticsModule.js
... ... @@ -21,25 +21,16 @@ Ext.define(&#39;amdaDesktop.StatisticsModule&#39;, {
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(&#39;amdaModel.BkgJobNode&#39;, {
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(&#39;amdaModel.BkgJobNode&#39;, {
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(&#39;amdaModel.BkgJobNode&#39;, {
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(&#39;amdaModel.BkgJobNode&#39;, {
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');
... ... @@ -395,97 +395,5 @@ Ext.define(&#39;amdaModel.BkgJobNode&#39;, {
395 395 this.set('rootNode',this.myGetOwnerTree().getRootNode().findChild( 'id', rootNodeId, true));
396 396 }
397 397 return this.get('rootNode');
398   - },
399   -
400   - /**
401   - * @override amdaModel.ExecutableNode.execute PNG (interactive session only!!!)
402   - */
403   - execute : function(arguments)
404   - {
405   - // Not needed to send the whole request
406   - // var jsonObj = this.get('object').getJsonValues(true);
407   - //TODO append jsonObj.action at server side => history!!!
408   - var jsonObj = {};
409   - var isMulti = arguments[0];
410   - jsonObj.action = {name:arguments[1],arg1:arguments[2],arg2:arguments[3]};
411   - //AKKA replace resultID by folderId
412   - jsonObj.folderId = this.get('object').get('folderId');
413   - //jsonObj.resultId = this.get('object').get('resultFolder');
414   -
415   - this.action = jsonObj.action.name;
416   -
417   - // this.set('tabId', jsonObj.tabId);
418   -
419   - // Node exists already, interactive Session
420   - var isInteractive = true;
421   - var isNewTab = false;
422   -
423   - loadMask.show(this.get('object').get('tabId'));
424   - AmdaAction.execute({nodeType : this.get('nodeType')}, jsonObj, function(res,e)
425   - {
426   - loadMask.hide();
427   - //AKKA - Rework of the result treatment for the integration with the new kernel
428   - if (!e.status)
429   - {
430   - myDesktopApp.errorMsg('Internal error during request');
431   - return;
432   - }
433   - if (!res.success)
434   - {
435   - myDesktopApp.errorMsg(res.message);
436   - return;
437   - }
438   - // NO background jobs for PNG !!!!! Timeout KILL
439   - if (res.status == amdaModel.BkgJobNode.STATUS_LIST.DONE)
440   - {
441   - this.updateNode(res);
442   - this.updateObject(res);
443   - this.editNode(isNewTab, isInteractive);
444   - }
445   - else
446   - {
447   - myDesktopApp.warningMsg(res.message);
448   - // keep this for case of Background Job
449   - /* var id = res.id;
450   - var text = 'job_' + res.pid;
451   - var status = amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS;
452   - var newobj = Ext.create('amdaModel.Plot',
453   - { resultId : id, name : res.rawname, resultId: res.rawname});
454   - var newNode = Ext.create(this.$className, { id : id, pid : res.pid, text : text, jobType : 'request',
455   - leaf : true, status : status, rawname : res.rawname, object : newobj});
456   - newNode.createJobNode(false);
457   - */
458   - }
459   - }, this);
460   - },
461   -
462   - updateNode : function(res)
463   - {
464   - var windowId = 'plot' + this.get('tabId')+'-win';
465   - var win = myDesktopApp.getDesktop().getWindow(windowId);
466   - //TODO if it is possible to close window before getting result?
467   - if (!win)
468   - myDesktopApp.errorMsg('You have closed window!!!');
469   - else
470   - {
471   - var panelResult = win.items.items[0];
472   - panelResult.setObjectIntoNode();
473   - }
474   - },
475   -
476   - updateObject : function(res)
477   - {
478   - var object = this.get('object');
479   - object.set('outputName', res.name);
480   - object.set('resultId', res.result);
481   - object.set('startDate', res.startDate);
482   - object.set('stopDate', res.stopDate);
483   -
484   - if (object.get('timesrc') == amdaModel.AmdaTimeObject.inputTimeSrc[0] && this.action != 'zoom')
485   - {
486   - object.set('intervalN', res.intervalN);
487   - object.set('totalN', res.totalN);
488   - object.set('ttName', res.tableName);
489   - }
490   - }
  398 + }
491 399 });
... ...
js/app/models/Catalog.js
... ... @@ -43,6 +43,14 @@ Ext.define(&#39;amdaModel.Catalog&#39;, {
43 43 values.parameters = this.get('parameters');
44 44 values.leaf = true;
45 45 values.nodeType = amdaModel.CatalogNode.nodeType;
  46 +
  47 + if (this.get('contact').match(/[a-z,0-9]/gi) != null) {
  48 + values.contact = this.get('contact');
  49 + }
  50 + values.surveyStart = this.get('surveyStart');
  51 + values.surveyStop = this.get('surveyStop');
  52 +
  53 +
46 54 return values;
47 55 }
48 56  
... ...
js/app/models/Download.js
... ... @@ -7,30 +7,131 @@
7 7 * @author myriam
8 8 * @version $Id: Download.js 2068 2014-02-06 11:27:38Z elena $
9 9 */
10   -
  10 +
  11 +
  12 +Ext.define('amdaModel.DownloadConfig', {
  13 + singleton: true,
  14 +
  15 + defaultValues : {
  16 + timeformat: 'YYYY-MM-DDThh:mm:ss',
  17 + timeformatTT: 'YYYY-MM-DDThh:mm:ss',
  18 + fileformat: 'ASCII',
  19 + fileformatTT: 'text',
  20 + filecompress: 'tar+gzip',
  21 + filecompressTT: 'tar+gzip',
  22 + filestructure: '2'
  23 + },
  24 +
  25 + timeformatData: [
  26 + ['YYYY-MM-DDThh:mm:ss', 'YYYY-MM-DDThh:mm:ss.ms', 'ISO format with msecs'],
  27 + ['DD Time', 'YYYYDOYhhmmssms', 'Day-Of-Year, 1 Jan : DOY = 0'],
  28 + ['Timestamp', 'Seconds from 1970', 'Total of seconds from the Unix Epoch on January 1st, 1970 at UTC.'],
  29 + ['YYYY MM DD hh mm ss', 'YYYY MM DD hh mm ss ms', 'date with spaces'],
  30 + ['Timestamp-with-milliseconds', 'Seconds from 1970 with ms', 'Total of seconds from the Unix Epoch with milliseconds.']
  31 + ],
  32 + fileformatData: [
  33 + ['ASCII', 'ASCII'],
  34 + ['vot', 'VOTable'],
  35 + ['cdf', 'CDF'],
  36 + ['json', 'JSON']
  37 + ],
  38 + fileformatTTData: [
  39 + ['text', 'plain text'],
  40 + ['vot', 'VOTable'],
  41 + ['space', 'HPEvent']
  42 + ],
  43 + filecompressData: [
  44 + ['zip', 'zip'],
  45 + ['tar+gzip', 'tar+gzip']
  46 + ],
  47 + filecompressTTData: [
  48 + ['zip', 'zip'],
  49 + ['tar+gzip', 'tar+gzip'],
  50 + ['none', 'none']
  51 + ],
  52 + filestructureData: [
  53 + ['0', 'All In One File'],
  54 + ['1', 'One File Per Time Interval'],
  55 + ['2', 'One File Per Param/Interval']
  56 + ]
  57 +});
11 58  
12 59 Ext.define('amdaModel.Download', {
13 60 extend: 'amdaModel.AmdaTimeObject',
14   -
  61 +
  62 + requires: [
  63 + "amdaModel.DownloadParam"
  64 + ],
  65 +
15 66 fields : [
16 67 {name: 'type', type: 'string', defaultValue: 'Download'},
17 68 {name: 'downloadSrc', type: 'string'},
18   - {name: 'list', defaultValue: null }, // array of parameters
19   - {name: 'timeformat', type: 'string'},
20   - {name: 'timeformatTT', type: 'string'},
21   - {name: 'structure', type: 'string'},
  69 + {name: 'timeformat', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.timeformat},
  70 + {name: 'timeformatTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.timeformatTT},
  71 + {name: 'filestructure', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filestructure},
22 72 {name: 'refparamSampling', type: 'boolean', defaultValue: false},
23 73 {name: 'separateInfoFile', type: 'boolean', defaultValue: false},
24   - {name: 'sampling', type: 'int', defaultValue: '600'},
  74 + {name: 'sampling', type: 'float', defaultValue: '600'},
25 75 {name: 'scientificformat', type: 'boolean', defaultValue: true},
26 76 {name: 'fileprefix', type: 'string'},
27   - {name: 'fileformat', type: 'string'},
28   - {name: 'fileformatTT', type: 'string'},
29   - {name: 'compression', type: 'string'},
30   - {name: 'compressionTT', type: 'string'}
  77 + {name: 'fileformat', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.fileformat},
  78 + {name: 'fileformatTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.fileformatTT},
  79 + {name: 'compression', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filecompress},
  80 + {name: 'compressionTT', type: 'string', defaultValue: amdaModel.DownloadConfig.defaultValues.filecompressTT},
  81 + {name: 'last_update', type: 'int', defaultValue: 0}
  82 + ],
  83 +
  84 + associations : [
  85 + {
  86 + type : 'hasMany',
  87 + model : 'amdaModel.DownloadParam',
  88 + name : 'params'
  89 + }
31 90 ],
32 91  
33   - propertiesToCopy : 'id,name,downloadSrc,refparamSampling,separateInfoFile,sampling,scientificformat,list,timeformat,timeformatTT,structure,fileprefix,fileformat,fileformatTT,compression,compressionTT',
  92 + propertiesToCopy : 'id,name,downloadSrc,refparamSampling,separateInfoFile,sampling,scientificformat,list,timeformat,timeformatTT,filestructure,fileprefix,fileformat,fileformatTT,compression,compressionTT',
  93 +
  94 + constructor: function(){
  95 + var me = this;
  96 + me.callParent(arguments);
  97 + if ((arguments.length > 0) && arguments[0])
  98 + {
  99 + if (arguments[0].list)
  100 + me.loadParams(arguments[0].list);
  101 + }
  102 + this.dirty = false;
  103 + },
  104 +
  105 + loadParams: function(params)
  106 + {
  107 + /* Compatability mode */
  108 + Ext.each(params, function(param, index) {
  109 + if (param.hasOwnProperty('is-init')) {
  110 + return;
  111 + }
  112 + params[index]['dim1-sum-type'] = param['dim1-is-range'] ? 1 : 0;
  113 + params[index]['dim1-min-value'] = param['dim1-min-range'];
  114 + params[index]['dim1-max-value'] = param['dim1-max-range'];
  115 + params[index]['dim2-sum-type'] = param['dim2-is-range'] ? 1 : 0;
  116 + params[index]['dim2-min-value'] = param['dim2-min-range'];
  117 + params[index]['dim2-max-value'] = param['dim2-max-range'];
  118 + params[index]['is-init'] = true;
  119 + });
  120 + this.params().loadData(params);
  121 + },
  122 +
  123 + isDirty : function() {
  124 + if (this.dirty)
  125 + return true;
  126 +
  127 + var d = false;
  128 +
  129 + this.params().each(function (param, index) {
  130 + if (param.dirty)
  131 + d = true;
  132 + });
  133 + return d;
  134 + },
34 135  
35 136 getJsonValues : function(){
36 137  
... ... @@ -38,9 +139,10 @@ Ext.define(&#39;amdaModel.Download&#39;, {
38 139 myValues.nodeType = 'download';//amdaModel.DownloadNode.nodeType;
39 140 myValues.type = this.get('type');
40 141 myValues.downloadSrc = this.get('downloadSrc');
  142 + myValues.name = this.get('name');
41 143 //Data download
42 144 if (myValues.downloadSrc === '0') { // Data download
43   - myValues.structure = this.get('structure');
  145 + myValues.filestructure = this.get('filestructure');
44 146 myValues.refparamSampling = this.get('refparamSampling');
45 147 myValues.separateInfoFile = this.get('separateInfoFile');
46 148 myValues.scientificformat = this.get('scientificformat');
... ... @@ -74,13 +176,10 @@ Ext.define(&#39;amdaModel.Download&#39;, {
74 176 }
75 177  
76 178 // if there's at least one parameter
77   - if (this.get('list') && this.get('list').length) {
78   - var list = this.get('list');
79   - myValues.list=[];
80   - Ext.each(list, function(item, index){
81   - myValues.list[index] = item.getJsonValues();
82   - });
83   - }
  179 + myValues.list = []
  180 + this.params().each(function (param, index) {
  181 + myValues.list[index] = param.getJsonValues();
  182 + });
84 183 myValues.fileformat = this.get('fileformat');
85 184 myValues.timeformat = this.get('timeformat');
86 185 myValues.compression = this.get('compression');
... ...
js/app/models/DownloadNode.js
... ... @@ -2,7 +2,7 @@
2 2 * Project : AMDA-NG4
3 3 * Name : DownloadNode.js
4 4 * @class amdaModel.DownloadNode
5   - * @extends Ext.data.Model
  5 + * @extends amdaModel.ExecutableNode
6 6 * @brief Basic Model of Node corresponding to a download request
7 7 * @author Myriam
8 8 * @version $Id: DownloadNode.js 2949 2015-06-23 10:25:59Z elena $
... ... @@ -10,70 +10,24 @@
10 10  
11 11 Ext.define('amdaModel.DownloadNode', {
12 12  
13   - extend: 'Ext.data.Model',
14   - singleton: true,
  13 + extend: 'amdaModel.ExecutableNode',
  14 +
  15 + statics: {
  16 + nodeType: 'download',
  17 + objectName: 'Download'
  18 + },
15 19  
16   - fields:[{name : 'downloadType', type : 'string'},
17   - {name: 'object', type: 'object'},
18   - {name: 'realLinkedNode', type: 'amdaModel.AmdaNode'},
19   - {name: 'moduleId', type: 'string', defaultValue:'down-win'},
20   - {name: 'nodeType', type: 'string', defaultValue: 'download'},
21   - {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Download'},
22   - {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
23   - ],
24   -
25   - isExecutable: function(){
26   - return true;
27   - },
28   -
29   - getObjectCallback : function(result,remoteEvent){
30   - var t = remoteEvent.getTransaction();
31   - if (result) {
32   - var paramObj = Ext.create(this.get('objectDataModel'), result);
33   - // set parameter into node
34   - this.set('object', paramObj);
35   - var downObject = amdaModel.DownloadNode.decodeObject();
36   - // Edition ;
37   - amdaModel.DownloadNode.set('object',Ext.create('amdaModel.Download',downObject));
38   - amdaModel.DownloadNode.editInModule();
39   - }
40   - else {
41   - myDesktopApp.errorMsg(t.action + "." + t.method + " : No parameter '"
42   - +this.get('name')+"' found!");
43   - // EXCEPTION : parameter not found !?
44   - }
45   - },
46   -
47   - editInModule : function () {
48   - var me = this;
49   - myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) {
50   - // If the node to edit is not already linked to this module
51   - if (module.getLinkedNode() != me) {
52   - // set relative node into parameter Module
53   - module.setLinkedNode(me);
54   - }
55   - else {// the node to edit is already edited
56   - //TODO: TBD : message to user
57   - //Sol1: msg alert: "warning this node is already edited! If you want to get the original, please press the 'reset' button"->'OK'
58   - //Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your modification?"->'Confirm','Cancel'
59   - }
60   - // Opening parameter window
61   - module.createWindow();
62   - });
63   - },
  20 + constructor : function(config) {
  21 + this.callParent(arguments);
  22 + this.set('moduleId',myDesktopApp.dynamicModules.download.id);
  23 + this.set('objectDataModel',amdaModel.Download.$className);
  24 + },
64 25  
65 26 decodeObject: function(obj) {
66 27 var myValues = new Object();
67 28 myValues.list=[];
68 29  
69   - if (!obj) {
70   - var fullObject = this.get('realLinkedNode').get('object');
71   - }
72   - else {
73   - var fullObject = obj;
74   - }
75   -
76   - fullObject.panels().each(function (panel) {
  30 + obj.panels().each(function (panel) {
77 31 panel.params().each(function (param) {
78 32 var myParam = new Object();
79 33 myParam.paramid = param.get('paramid');
... ... @@ -98,13 +52,13 @@ Ext.define(&#39;amdaModel.DownloadNode&#39;, {
98 52 alert('Parameter '+ myParam.paramid + ' is PlotOnly');
99 53 });
100 54 });
101   - myValues.timesrc = fullObject.get('timesrc');
  55 + myValues.timesrc = obj.get('timesrc');
102 56 // if there's at least one timeTable name into 'timeTables' collection
103 57 if (myValues.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0]
104   - && fullObject.get('timeTables')
105   - && fullObject.get('timeTables').length){
  58 + && obj.get('timeTables')
  59 + && obj.get('timeTables').length){
106 60 // get complete timeTables collection
107   - var timeTables = fullObject.get('timeTables');
  61 + var timeTables = obj.get('timeTables');
108 62 // init an empty array for timeTables
109 63 myValues.timeTables=[];
110 64 // for each interval record
... ... @@ -119,150 +73,15 @@ Ext.define(&#39;amdaModel.DownloadNode&#39;, {
119 73 });
120 74 }
121 75 else {
122   - myValues.startDate = fullObject.get('startDate');
123   - myValues.stopDate = fullObject.get('stopDate');
124   - myValues.durationDay = fullObject.get('durationDay');
125   - myValues.durationHour = fullObject.get('durationHour');
126   - myValues.durationMin = fullObject.get('durationMin');
127   - myValues.durationSec = fullObject.get('durationSec');
  76 + myValues.startDate = obj.get('startDate');
  77 + myValues.stopDate = obj.get('stopDate');
  78 + myValues.durationDay = obj.get('durationDay');
  79 + myValues.durationHour = obj.get('durationHour');
  80 + myValues.durationMin = obj.get('durationMin');
  81 + myValues.durationSec = obj.get('durationSec');
128 82 }
129 83  
130   - myValues.name = fullObject.get('name');
  84 + myValues.name = obj.get('name');
131 85 return myValues;
132   - },
133   -
134   - encodeObject: function() {
135   - },
136   -
137   - loadJobTree : function(sendToSamp, clientId) {
138   - //TBD - BRE - fix code duplication with ExecutableNode if possible
139   - var rootNode = Ext.getCmp(amdaUI.ExplorerUI.JOB_TAB.TREE_ID).getRootNode();
140   - var me = this;
141   - amdaModel.InteractiveNode.preloadNodes(rootNode,
142   - function()
143   - {
144   - amdaModel.InteractiveNode.jobTreeLoaded = true;
145   - me.realExecute(sendToSamp, clientId);
146   - });
147   - },
148   -
149   - execute : function(sendToSamp, clientId) {
150   -
151   - if (!amdaModel.ExecutableNode.jobTreeLoaded) this.loadJobTree(sendToSamp, clientId);
152   - else this.realExecute(sendToSamp, clientId);
153   - },
154   -
155   -/**
156   -* Method to execute this node
157   -*/
158   - realExecute : function(sendToSamp, clientId) {
159   - var jsonObject = this.get('object').getJsonValues();
160   - if (!jsonObject.list && !jsonObject.images) {
161   - myDesktopApp.warningMsg('Please select at least one Parameter (Get Data) or one Time Table (Get Time Table)');
162   - return;
163   - }
164   -
165   - if (sendToSamp) {
166   - jsonObject.sendToSamp = true;
167   - }
168   -
169   - loadMask.show();
170   - AmdaAction.execute({nodeType : this.get('nodeType')}, jsonObject, function(res,e)
171   - {
172   - loadMask.hide();
173   -
174   - //AKKA - Rework of the result treatment for the integration with the new kernel
175   - if (!e.status)
176   - {
177   - myDesktopApp.errorMsg('Internal error during download request');
178   - return;
179   - }
180   -
181   - if (!res.success)
182   - {
183   - myDesktopApp.errorMsg(res.message);
184   - return;
185   - }
186   - //TBD if such condition is OK ?
187   - if (!res.id && res.download) {
188   - if (res.sendToSamp) {
189   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
190   - Ext.Array.each(res.download, function(download) {
191   - module.sendVOTable(download, clientId ? clientId : 'hub');
192   - });
193   - });
194   - return;
195   - } else if (res.compression) {
196   - window.location.href = res.download;
197   - }
198   - else {
199   - window.open(res.download, '_blank');
200   - }
201   - return;
202   - }
203   -
204   - if (logExecTime && res.exectime && (res.exectime != 0)) {
205   - console.log("CMD EXEC TIME FOR "+res.id+" = "+res.exectime+"ms");
206   - }
207   -
208   - var newobj = this.createJobObject(res);
209   - var newNode = Ext.create(this.get('jobNode'),
210   - {
211   - id : res.id,
212   - info : res.info,
213   - jobType : this.get('nodeType'),
214   - processId : res.id,
215   - text : res.name,
216   - status : res.status,
217   - stop : res.stop,
218   - leaf : true,
219   - object : newobj
220   -
221   - });
222   -
223   - // new Tab
224   - switch (res.status)
225   - {
226   - case amdaModel.BkgJobNode.STATUS_LIST.DONE :
227   - if (!res.sendToSamp) {
228   - // New tab, non-interactive session
229   - var isInteractive = false;
230   - var isNewTab = true;
231   - newNode.createJobNode(true);
232   - newNode.editNode(isNewTab, isInteractive);
233   - }
234   - else {
235   - var files = res.result.split(",");
236   - Ext.each(files, function(file) {
237   - var href = 'data/'+sessionID+'/RES/'+ res.folder + '/' + file;
238   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
239   - module.sendVOTable(href, clientId ? clientId : 'hub');
240   - });
241   - });
242   - }
243   - break;
244   - case amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS :
245   - newNode.createJobNode(false);
246   - break;
247   - default:
248   - newNode.createJobNode(true);
249   - }
250   - }, this );
251   - },
252   -
253   - createJobObject: function(res) {
254   -
255   - var obj = this.get('object').getJsonValues();
256   - //TODO text, name, outputName - if all is needed
257   - //new object to attach to new bkgJobNode
258   - //TODO Ext.clone()
259   -
260   - var newobj = Ext.copyTo({}, obj, this.get('object').propertiesToCopy);
261   - newobj.id = res.id;
262   - newobj.resultId = res.result;
263   - newobj.folderId = res.folder;
264   - newobj = Ext.create(this.get('object').$className, newobj);
265   -
266   - return newobj;
267   - }
  86 + }
268 87 });
... ...
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  
... ... @@ -22,35 +22,41 @@ Ext.define(&#39;amdaModel.ExecutableNode&#39;, {
22 22 this.set('jobNode', 'amdaModel.BkgJobNode');
23 23 },
24 24  
25   - loadJobTree : function()
  25 + loadJobTree : function(opts)
26 26 {
27 27 var rootNode = Ext.getCmp(amdaUI.ExplorerUI.JOB_TAB.TREE_ID).getRootNode();
28 28 var me = this;
29 29 amdaModel.InteractiveNode.preloadNodes(rootNode, function(){
30 30 amdaModel.ExecutableNode.jobTreeLoaded = true;
31   - me.realExecute();
  31 + me.realExecute(opts);
32 32 });
33 33 },
34 34  
35   - execute : function(isDirty)
  35 + execute : function(opts)
36 36 {
37 37 if (!amdaModel.ExecutableNode.jobTreeLoaded)
38   - this.loadJobTree();
  38 + this.loadJobTree(opts);
39 39 else
40   - this.realExecute();
  40 + this.realExecute(opts);
41 41 },
42 42  
43 43 /**
44 44 * Method to execute this node
45 45 */
46   - realExecute : function()
  46 + realExecute : function(opts)
47 47 {
48 48 var isInteractivePlot = (this.get('nodeType') == 'request') && (this.get('object').get('file-output') == 'INTERACTIVE') || (this.get('nodeType') == 'multiplot');
  49 +
  50 + var jsonObject = this.get('object').getJsonValues();
  51 + if (opts && opts.sendToSamp) {
  52 + jsonObject.sendToSamp = true;
  53 + opts.clientId = opts.clientId ? opts.clientId : 'hub';
  54 + }
49 55  
50 56 if (!loadMask.isMasked())
51 57 loadMask.show(isInteractivePlot);
52 58  
53   - AmdaAction.execute({nodeType : this.get('nodeType')}, this.get('object').getJsonValues(true),
  59 + AmdaAction.execute({nodeType : this.get('nodeType')}, jsonObject,
54 60 function(res,e)
55 61 {
56 62 loadMask.hide();
... ... @@ -74,7 +80,36 @@ Ext.define(&#39;amdaModel.ExecutableNode&#39;, {
74 80 module.updateInteractiveSession(res, true);
75 81 });
76 82 }
  83 + else if (!res.id && res.download) {
  84 + //Download TT / Cat
  85 + if (res.sendToSamp) {
  86 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
  87 + Ext.Array.each(res.download, function(download) {
  88 + module.sendVOTable(download, opts.clientId);
  89 + });
  90 + });
  91 + return;
  92 + } else if (res.compression) {
  93 + window.location.href = res.download;
  94 + }
  95 + else {
  96 + window.open(res.download, '_blank');
  97 + }
  98 + return;
  99 + }
77 100 else {
  101 + if (res.sendToSamp) {
  102 + // Send to SAMP from Download UI
  103 + var files = res.result.split(",");
  104 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
  105 + Ext.each(files, function(file) {
  106 + var href = 'data/'+sessionID+'/RES/'+ res.folder + '/' + file;
  107 + module.sendVOTable(href, opts.clientId);
  108 + });
  109 + });
  110 + return;
  111 + }
  112 +
78 113 if (logExecTime && res.exectime && (res.exectime != 0)) {
79 114 console.log("CMD EXEC TIME FOR "+res.id+" = "+res.exectime+"ms");
80 115 }
... ... @@ -96,7 +131,7 @@ Ext.define(&#39;amdaModel.ExecutableNode&#39;, {
96 131  
97 132 newNode.get('object').on('execute', function() {
98 133 // Then call the node creation method
99   - this.execute(arguments);
  134 + this.execute(opts);
100 135 }, newNode);
101 136  
102 137 switch (res.status)
... ...
js/app/models/InteractiveNode.js
... ... @@ -19,7 +19,8 @@ Ext.define(&#39;amdaModel.InteractiveNode&#39;, {
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(&#39;amdaModel.InteractiveNode&#39;, {
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(&#39;amdaModel.InteractiveNode&#39;, {
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 }
... ... @@ -487,78 +490,7 @@ Ext.define(&#39;amdaModel.InteractiveNode&#39;, {
487 490 createDownload: function(node)
488 491 {
489 492 myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) {
490   - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.download.id)) {
491   - var request = Ext.create(amdaModel.Download.$className);
492   - amdaModel.DownloadNode.set('object',request);
493   - // singleton!
494   - amdaModel.DownloadNode.editInModule();
495   - if ((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) {
496   - module.getUiContent().setTimeFromData(node.getTimeFromNode(node));
497   - }
498   - }
499   - var paramName;
500   - var components = null;
501   - switch (node.$className) {
502   - case 'amdaModel.AliasNode' :
503   - paramName = "#"+node.get('text');
504   - break;
505   - case 'amdaModel.DerivedParamComponentNode' :
506   -
507   - paramId = node.get('text');
508   - var parentId = paramId.substr(0, paramId.length - 3);
509   - paramName= "ws_" + parentId;
510   - var regExp = /\(([\d]+)\)/;
511   - var component_index = regExp.exec(paramId);
512   - if (component_index)
513   - {
514   - components = [];
515   - components['index1'] = component_index[1];
516   - }
517   - break;
518   - case 'amdaModel.MyDataParamComponentNode' :
519   - paramId = node.get('text');
520   - var parentId = paramId.substr(0, paramId.length - 3);
521   - paramName= "wsd_" + parentId;
522   - var regExp = /\(([\d]+)\)/;
523   - var component_index = regExp.exec(paramId);
524   - if (component_index)
525   - {
526   - components = [];
527   - components['index1'] = component_index[1];
528   - }
529   - break;
530   - case 'amdaModel.DerivedParamNode' :
531   - paramName = "ws_"+node.get('text');
532   - break;
533   - case 'amdaModel.MyDataParamNode' :
534   - paramName = 'wsd_'+node.get('text');
535   - break;
536   - default :
537   - if (node.get('alias')!= "" )
538   - paramName = "#"+node.get('alias');
539   - else
540   - paramName = node.get('id');
541   - }
542   - var component_info = node.get('component_info');
543   - var predefinedArgs = node.get('predefinedArgs');
544   - if (component_info && component_info.parentId) {
545   - //It's a component
546   - paramName = component_info.parentId;
547   - components = [];
548   - if (component_info.index1)
549   - components['index1'] = component_info.index1;
550   - if (component_info.index2)
551   - components['index2'] = component_info.index2;
552   - predefinedArgs = node.parentNode.get('predefinedArgs');
553   - }
554   - if (predefinedArgs) {
555   - module.parseTemplatedParam(paramName, function(param_info) {
556   - module.addParam(param_info.paramid, true, node.get('needsArgs'), components, param_info.template_args);
557   - });
558   - }
559   - else {
560   - module.addParam(paramName,true,node.get('needsArgs'),components);
561   - }
  493 + module.addParameter(node);
562 494 });
563 495 },
564 496  
... ...
js/app/models/PlotObjects/PlotBaseSerieObject.js
... ... @@ -11,182 +11,191 @@
11 11 ******************************************************************************
12 12 * : :14/09/2015: BRE - file creation
13 13 */
14   -
15   -
  14 +
  15 +
16 16 Ext.define('amdaPlotObj.PlotBaseSerieObject', {
17   - extend: 'Ext.data.Model',
18   -
19   - requires: [
20   - 'amdaPlotObj.PlotObjectConfig'
21   - ],
22   -
23   - fields : [
24   - {name: 'serie-yaxis', type: 'string'},
25   - {name: 'serie-resolution', type: 'int'},
26   - {name: 'serie-lines-activated', type: 'boolean'},
27   - {name: 'serie-lines-style', type: 'string'},
28   - {name: 'serie-lines-width', type: 'float'},
29   - {name: 'serie-lines-color', type: 'string'},
30   - {name: 'serie-symbols-activated', type: 'boolean'},
31   - {name: 'serie-symbols-type', type: 'string'},
32   - {name: 'serie-symbols-size', type: 'float'},
33   - {name: 'serie-symbols-color', type: 'string'},
34   - {name: 'serie-colored-param', type: 'string'},
35   - {name: 'serie-value-min', type: 'float', useNull:true},
36   - {name: 'serie-value-max', type: 'float', useNull:true},
37   -
38   - //Time tick
39   - {name: 'serie-timetick-activated', type: 'boolean'},
40   - {name: 'serie-timetick-type', type: 'string'},
41   - {name: 'serie-timetick-step', type: 'float'},
42   - {name: 'serie-timetick-nbmajor', type: 'int'},
43   - {name: 'serie-timetick-nbminor', type: 'int'},
44   - {name: 'serie-timetick-color', type: 'string'},
45   - {name: 'serie-timetick-symbols-type', type: 'string'},
46   - {name: 'serie-timetick-symbols-size', type: 'float'},
47   - {name: 'serie-timetick-symbols-color', type: 'string'},
48   - {name: 'serie-timetick-firstsymbols-activated', type: 'boolean'},
49   - {name: 'serie-timetick-firstsymbols-type', type: 'string'},
50   - {name: 'serie-timetick-firstsymbols-size', type: 'float'},
51   - {name: 'serie-timetick-firstsymbols-color', type: 'string'},
52   - {name: 'serie-timetick-font-activated', type: 'boolean'},
53   - {name: 'serie-timetick-font-name', type: 'string'},
54   - {name: 'serie-timetick-font-size', type: 'int'},
55   - {name: 'serie-timetick-font-bold', type: 'boolean'},
56   - {name: 'serie-timetick-font-italic', type: 'boolean'},
57   -
58   - //Interval tick
59   - {name: 'serie-intervaltick-activated', type: 'boolean'},
60   - {name: 'serie-intervaltick-mode', type: 'string'},
61   - {name: 'serie-intervaltick-color', type: 'string'},
62   - {name: 'serie-intervaltick-symbols-type', type: 'string'},
63   - {name: 'serie-intervaltick-symbols-size', type: 'float'},
64   - {name: 'serie-intervaltick-symbols-color', type: 'string'},
65   - {name: 'serie-intervaltick-font-activated', type: 'boolean'},
66   - {name: 'serie-intervaltick-font-name', type: 'string'},
67   - {name: 'serie-intervaltick-font-size', type: 'int'},
68   - {name: 'serie-intervaltick-font-bold', type: 'boolean'},
69   - {name: 'serie-intervaltick-font-italic', type: 'boolean'},
  17 + extend: 'Ext.data.Model',
  18 +
  19 + requires: [
  20 + 'amdaPlotObj.PlotObjectConfig'
70 21 ],
71   -
72   - constructor: function(){
  22 +
  23 + fields: [
  24 + {name: 'serie-yaxis', type: 'string'},
  25 + {name: 'serie-resolution', type: 'int'},
  26 + {name: 'serie-lines-activated', type: 'boolean'},
  27 + {name: 'serie-lines-style', type: 'string'},
  28 + {name: 'serie-lines-width', type: 'float'},
  29 + {name: 'serie-lines-color', type: 'string'},
  30 + {name: 'serie-symbols-activated', type: 'boolean'},
  31 + {name: 'serie-symbols-type', type: 'string'},
  32 + {name: 'serie-symbols-size', type: 'float'},
  33 + {name: 'serie-symbols-color', type: 'string'},
  34 + {name: 'serie-colored-param', type: 'string'},
  35 + {name: 'serie-value-min', type: 'float', useNull: true},
  36 + {name: 'serie-value-max', type: 'float', useNull: true},
  37 +
  38 + //Time tick
  39 + {name: 'serie-timetick-activated', type: 'boolean'},
  40 + {name: 'serie-timetick-type', type: 'string'},
  41 + {name: 'serie-timetick-step', type: 'float'},
  42 + {name: 'serie-timetick-nbmajor', type: 'int'},
  43 + {name: 'serie-timetick-nbminor', type: 'int'},
  44 + {name: 'serie-timetick-color', type: 'string'},
  45 + {name: 'serie-timetick-symbols-type', type: 'string'},
  46 + {name: 'serie-timetick-symbols-size', type: 'float'},
  47 + {name: 'serie-timetick-symbols-color', type: 'string'},
  48 + {name: 'serie-timetick-firstsymbols-activated', type: 'boolean'},
  49 + {name: 'serie-timetick-firstsymbols-type', type: 'string'},
  50 + {name: 'serie-timetick-firstsymbols-size', type: 'float'},
  51 + {name: 'serie-timetick-firstsymbols-color', type: 'string'},
  52 + {name: 'serie-timetick-font-activated', type: 'boolean'},
  53 + {name: 'serie-timetick-font-name', type: 'string'},
  54 + {name: 'serie-timetick-font-size', type: 'int'},
  55 + {name: 'serie-timetick-font-bold', type: 'boolean'},
  56 + {name: 'serie-timetick-font-italic', type: 'boolean'},
  57 +
  58 + //Interval tick
  59 + {name: 'serie-intervaltick-activated', type: 'boolean'},
  60 + {name: 'serie-intervaltick-mode', type: 'string'},
  61 + {name: 'serie-intervaltick-color', type: 'string'},
  62 + {name: 'serie-intervaltick-symbols-type', type: 'string'},
  63 + {name: 'serie-intervaltick-symbols-size', type: 'float'},
  64 + {name: 'serie-intervaltick-symbols-color', type: 'string'},
  65 + {name: 'serie-intervaltick-font-activated', type: 'boolean'},
  66 + {name: 'serie-intervaltick-font-name', type: 'string'},
  67 + {name: 'serie-intervaltick-font-size', type: 'int'},
  68 + {name: 'serie-intervaltick-font-bold', type: 'boolean'},
  69 + {name: 'serie-intervaltick-font-italic', type: 'boolean'},
  70 + //Filtering
  71 + {name: 'filtering-activated', type: 'boolean'},
  72 + {name:'filtering-level', type:'int'}
  73 + ],
  74 +
  75 + constructor: function () {
73 76 var me = this;
74 77 me.callParent(arguments);
75 78 if ((arguments.length > 0) && arguments[0])
76 79 {
77   - }
78   - else
  80 + } else
79 81 {
80   - //new object, set default fields values
81   - me.setDefaultValues();
  82 + //new object, set default fields values
  83 + me.setDefaultValues();
82 84 }
83 85 this.dirty = false;
84 86 },
85   -
86   - setDefaultValues: function()
  87 +
  88 + setDefaultValues: function ()
87 89 {
88   - this.set('serie-yaxis', amdaPlotObj.PlotObjectConfig.defaultValues.serie.yAxis);
89   - this.set('serie-resolution', amdaPlotObj.PlotObjectConfig.defaultValues.serie.resolution);
90   - this.set('serie-lines-activated', true);
91   - this.set('serie-lines-style', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.style);
92   - this.set('serie-lines-width', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.width);
93   - this.set('serie-lines-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.color);
94   - this.set('serie-symbols-activated', false);
95   - this.set('serie-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.type);
96   - this.set('serie-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.size);
97   - this.set('serie-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.color);
98   - this.set('serie-colored-param', '');
99   -
100   - this.set('serie-timetick-activated', false);
101   - this.set('serie-timetick-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.type);
102   - this.set('serie-timetick-step', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.step);
103   - this.set('serie-timetick-nbmajor', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.nbmajor);
104   - this.set('serie-timetick-nbminor', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.nbminor);
105   - this.set('serie-timetick-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.color);
106   - this.set('serie-timetick-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.type);
107   - this.set('serie-timetick-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.size);
108   - this.set('serie-timetick-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.color);
109   - this.set('serie-timetick-firstsymbols-activated', true);
110   - this.set('serie-timetick-firstsymbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.type);
111   - this.set('serie-timetick-firstsymbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.size);
112   - this.set('serie-timetick-firstsymbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.color);
113   - this.set('serie-timetick-font-activated', false);
  90 + this.set('serie-yaxis', amdaPlotObj.PlotObjectConfig.defaultValues.serie.yAxis);
  91 + this.set('serie-resolution', amdaPlotObj.PlotObjectConfig.defaultValues.serie.resolution);
  92 + this.set('serie-lines-activated', true);
  93 + this.set('serie-lines-style', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.style);
  94 + this.set('serie-lines-width', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.width);
  95 + this.set('serie-lines-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.lines.color);
  96 + this.set('serie-symbols-activated', false);
  97 + this.set('serie-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.type);
  98 + this.set('serie-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.size);
  99 + this.set('serie-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.symbols.color);
  100 + this.set('serie-colored-param', '');
  101 +
  102 + this.set('serie-timetick-activated', false);
  103 + this.set('serie-timetick-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.type);
  104 + this.set('serie-timetick-step', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.step);
  105 + this.set('serie-timetick-nbmajor', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.nbmajor);
  106 + this.set('serie-timetick-nbminor', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.nbminor);
  107 + this.set('serie-timetick-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.color);
  108 + this.set('serie-timetick-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.type);
  109 + this.set('serie-timetick-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.size);
  110 + this.set('serie-timetick-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.symbols.color);
  111 + this.set('serie-timetick-firstsymbols-activated', true);
  112 + this.set('serie-timetick-firstsymbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.type);
  113 + this.set('serie-timetick-firstsymbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.size);
  114 + this.set('serie-timetick-firstsymbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.firstsymbols.color);
  115 + this.set('serie-timetick-font-activated', false);
114 116 this.set('serie-timetick-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.font.name);
115 117 this.set('serie-timetick-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.timetick.font.size);
116 118 this.set('serie-timetick-font-bold', false);
117 119 this.set('serie-timetick-font-italic', false);
118   -
119   - this.set('serie-intervaltick-activated', false);
120   - this.set('serie-intervaltick-mode', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.mode);
121   - this.set('serie-intervaltick-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.color);
122   - this.set('serie-intervaltick-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.type);
123   - this.set('serie-intervaltick-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.size);
124   - this.set('serie-intervaltick-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.color);
125   - this.set('serie-intervaltick-font-activated', false);
126   - this.set('serie-intervaltick-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.font.name);
127   - this.set('serie-intervaltick-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.font.size);
128   - this.set('serie-intervaltick-font-bold', false);
129   - this.set('serie-intervaltick-font-italic', false);
  120 +
  121 + this.set('serie-intervaltick-activated', false);
  122 + this.set('serie-intervaltick-mode', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.mode);
  123 + this.set('serie-intervaltick-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.color);
  124 + this.set('serie-intervaltick-symbols-type', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.type);
  125 + this.set('serie-intervaltick-symbols-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.size);
  126 + this.set('serie-intervaltick-symbols-color', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.symbols.color);
  127 + this.set('serie-intervaltick-font-activated', false);
  128 + this.set('serie-intervaltick-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.font.name);
  129 + this.set('serie-intervaltick-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.serie.intervaltick.font.size);
  130 + this.set('serie-intervaltick-font-bold', false);
  131 + this.set('serie-intervaltick-font-italic', false);
  132 +
  133 + // filtering
  134 + this.set( 'filtering-activated', false);
  135 + this.set('filtering-level', amdaPlotObj.PlotObjectConfig.defaultValues.filtering.level);
130 136 },
131   -
132   - loadFromData : function(drawData)
  137 +
  138 + loadFromData: function (drawData)
133 139 {
134   - Ext.Object.each(drawData, function(key, value) {
135   - if (key == 'type')
136   - return;
137   - this.set(key, value);
138   - }, this);
  140 + Ext.Object.each(drawData, function (key, value) {
  141 + if (key == 'type')
  142 + return;
  143 + this.set(key, value);
  144 + }, this);
139 145 },
140   -
141   - getJsonValues : function()
  146 +
  147 + getJsonValues: function ()
142 148 {
143   - var serieValues = new Object();
144   -
145   - serieValues['serie-yaxis'] = this.get('serie-yaxis');
146   - serieValues['serie-resolution'] = this.get('serie-resolution');
147   - serieValues['serie-lines-activated'] = this.get('serie-lines-activated');
148   - serieValues['serie-lines-style'] = this.get('serie-lines-style');
149   - serieValues['serie-lines-width'] = this.get('serie-lines-width');
150   - serieValues['serie-lines-color'] = this.get('serie-lines-color');
151   - serieValues['serie-symbols-activated'] = this.get('serie-symbols-activated');
152   - serieValues['serie-symbols-type'] = this.get('serie-symbols-type');
153   - serieValues['serie-symbols-size'] = this.get('serie-symbols-size');
154   - serieValues['serie-symbols-color'] = this.get('serie-symbols-color');
155   - serieValues['serie-colored-param'] = this.get('serie-colored-param');
156   - serieValues['serie-value-min'] = this.get('serie-value-min');
157   - serieValues['serie-value-max'] = this.get('serie-value-max');
158   -
159   - serieValues['serie-timetick-activated'] = this.get('serie-timetick-activated');
160   - serieValues['serie-timetick-type'] = this.get('serie-timetick-type');
161   - serieValues['serie-timetick-step'] = this.get('serie-timetick-step');
162   - serieValues['serie-timetick-nbmajor'] = this.get('serie-timetick-nbmajor');
163   - serieValues['serie-timetick-nbminor'] = this.get('serie-timetick-nbminor');
164   - serieValues['serie-timetick-color'] = this.get('serie-timetick-color');
165   - serieValues['serie-timetick-symbols-type'] = this.get('serie-timetick-symbols-type');
166   - serieValues['serie-timetick-symbols-size'] = this.get('serie-timetick-symbols-size');
167   - serieValues['serie-timetick-symbols-color'] = this.get('serie-timetick-symbols-color');
168   - serieValues['serie-timetick-firstsymbols-activated'] = this.get('serie-timetick-firstsymbols-activated');
169   - serieValues['serie-timetick-firstsymbols-type'] = this.get('serie-timetick-firstsymbols-type');
170   - serieValues['serie-timetick-firstsymbols-size'] = this.get('serie-timetick-firstsymbols-size');
171   - serieValues['serie-timetick-firstsymbols-color'] = this.get('serie-timetick-firstsymbols-color');
172   - serieValues['serie-timetick-font-activated'] = this.get('serie-timetick-font-activated');
173   - serieValues['serie-timetick-font-name'] = this.get('serie-timetick-font-name');
174   - serieValues['serie-timetick-font-size'] = this.get('serie-timetick-font-size');
175   - serieValues['serie-timetick-font-bold'] = this.get('serie-timetick-font-bold');
176   - serieValues['serie-timetick-font-italic'] = this.get('serie-timetick-font-italic');
177   -
178   - serieValues['serie-intervaltick-activated'] = this.get('serie-intervaltick-activated');
179   - serieValues['serie-intervaltick-mode'] = this.get('serie-intervaltick-mode');
180   - serieValues['serie-intervaltick-color'] = this.get('serie-intervaltick-color');
181   - serieValues['serie-intervaltick-symbols-type'] = this.get('serie-intervaltick-symbols-type');
182   - serieValues['serie-intervaltick-symbols-size'] = this.get('serie-intervaltick-symbols-size');
183   - serieValues['serie-intervaltick-symbols-color'] = this.get('serie-intervaltick-symbols-color');
184   - serieValues['serie-intervaltick-font-activated'] = this.get('serie-intervaltick-font-activated');
185   - serieValues['serie-intervaltick-font-name'] = this.get('serie-intervaltick-font-name');
186   - serieValues['serie-intervaltick-font-size'] = this.get('serie-intervaltick-font-size');
187   - serieValues['serie-intervaltick-font-bold'] = this.get('serie-intervaltick-font-bold');
188   - serieValues['serie-intervaltick-font-italic'] = this.get('serie-intervaltick-font-italic');
189   -
190   - return serieValues;
  149 + var serieValues = new Object();
  150 +
  151 + serieValues['serie-yaxis'] = this.get('serie-yaxis');
  152 + serieValues['serie-resolution'] = this.get('serie-resolution');
  153 + serieValues['serie-lines-activated'] = this.get('serie-lines-activated');
  154 + serieValues['serie-lines-style'] = this.get('serie-lines-style');
  155 + serieValues['serie-lines-width'] = this.get('serie-lines-width');
  156 + serieValues['serie-lines-color'] = this.get('serie-lines-color');
  157 + serieValues['serie-symbols-activated'] = this.get('serie-symbols-activated');
  158 + serieValues['serie-symbols-type'] = this.get('serie-symbols-type');
  159 + serieValues['serie-symbols-size'] = this.get('serie-symbols-size');
  160 + serieValues['serie-symbols-color'] = this.get('serie-symbols-color');
  161 + serieValues['serie-colored-param'] = this.get('serie-colored-param');
  162 + serieValues['serie-value-min'] = this.get('serie-value-min');
  163 + serieValues['serie-value-max'] = this.get('serie-value-max');
  164 +
  165 + serieValues['serie-timetick-activated'] = this.get('serie-timetick-activated');
  166 + serieValues['serie-timetick-type'] = this.get('serie-timetick-type');
  167 + serieValues['serie-timetick-step'] = this.get('serie-timetick-step');
  168 + serieValues['serie-timetick-nbmajor'] = this.get('serie-timetick-nbmajor');
  169 + serieValues['serie-timetick-nbminor'] = this.get('serie-timetick-nbminor');
  170 + serieValues['serie-timetick-color'] = this.get('serie-timetick-color');
  171 + serieValues['serie-timetick-symbols-type'] = this.get('serie-timetick-symbols-type');
  172 + serieValues['serie-timetick-symbols-size'] = this.get('serie-timetick-symbols-size');
  173 + serieValues['serie-timetick-symbols-color'] = this.get('serie-timetick-symbols-color');
  174 + serieValues['serie-timetick-firstsymbols-activated'] = this.get('serie-timetick-firstsymbols-activated');
  175 + serieValues['serie-timetick-firstsymbols-type'] = this.get('serie-timetick-firstsymbols-type');
  176 + serieValues['serie-timetick-firstsymbols-size'] = this.get('serie-timetick-firstsymbols-size');
  177 + serieValues['serie-timetick-firstsymbols-color'] = this.get('serie-timetick-firstsymbols-color');
  178 + serieValues['serie-timetick-font-activated'] = this.get('serie-timetick-font-activated');
  179 + serieValues['serie-timetick-font-name'] = this.get('serie-timetick-font-name');
  180 + serieValues['serie-timetick-font-size'] = this.get('serie-timetick-font-size');
  181 + serieValues['serie-timetick-font-bold'] = this.get('serie-timetick-font-bold');
  182 + serieValues['serie-timetick-font-italic'] = this.get('serie-timetick-font-italic');
  183 +
  184 + serieValues['serie-intervaltick-activated'] = this.get('serie-intervaltick-activated');
  185 + serieValues['serie-intervaltick-mode'] = this.get('serie-intervaltick-mode');
  186 + serieValues['serie-intervaltick-color'] = this.get('serie-intervaltick-color');
  187 + serieValues['serie-intervaltick-symbols-type'] = this.get('serie-intervaltick-symbols-type');
  188 + serieValues['serie-intervaltick-symbols-size'] = this.get('serie-intervaltick-symbols-size');
  189 + serieValues['serie-intervaltick-symbols-color'] = this.get('serie-intervaltick-symbols-color');
  190 + serieValues['serie-intervaltick-font-activated'] = this.get('serie-intervaltick-font-activated');
  191 + serieValues['serie-intervaltick-font-name'] = this.get('serie-intervaltick-font-name');
  192 + serieValues['serie-intervaltick-font-size'] = this.get('serie-intervaltick-font-size');
  193 + serieValues['serie-intervaltick-font-bold'] = this.get('serie-intervaltick-font-bold');
  194 + serieValues['serie-intervaltick-font-italic'] = this.get('serie-intervaltick-font-italic');
  195 +
  196 + serieValues['filtering-activated'] = this.get('filtering-activated');
  197 + serieValues['filtering-level'] = this.get('filtering-level');
  198 +
  199 + return serieValues;
191 200 }
192 201 });
... ...
js/app/models/PlotObjects/PlotObjectConfig.js
... ... @@ -137,7 +137,8 @@ Ext.define(&#39;amdaPlotObj.PlotObjectConfig&#39;, {
137 137 color : 'auto'
138 138 }
139 139 },
140   - projection : 'XY'
  140 + projection : 'XY',
  141 +
141 142 },
142 143 spectro : {
143 144 yAxis : 'y-left',
... ... @@ -200,7 +201,10 @@ Ext.define(&#39;amdaPlotObj.PlotObjectConfig&#39;, {
200 201 type : 'serie-constant',
201 202 greaterColor : 'none',
202 203 lessColor : 'none'
203   - }
  204 + },
  205 + filtering:{
  206 + level:1
  207 + }
204 208 },
205 209  
206 210 getValueByKey : function(dataList, key)
... ... @@ -478,6 +482,12 @@ Ext.define(&#39;amdaPlotObj.PlotObjectConfig&#39;, {
478 482 {'key' : 'linear', 'value' : 'Linear'},
479 483 {'key' : 'log', 'value' : 'Logarithmic'}
480 484 ],
  485 +
  486 + availableFilteringLevel : [
  487 + {'key' : 1, 'value' : 'Low'},
  488 + {'key' : 2, 'value' : 'Medium'},
  489 + {'key' : 3, 'value' : 'Strong'}
  490 + ],
481 491  
482 492 getParamConfig : function(paramId, onParamConfigLoaded) {
483 493 AmdaAction.getParamPlotInit({"paramId" : paramId}, function (result, e) {
... ...
js/app/models/PlotObjects/PlotParamObject.js
... ... @@ -71,8 +71,8 @@ Ext.define(&#39;amdaPlotObj.PlotParamObject&#39;, {
71 71 {
72 72 case 'serie' :
73 73 return new amdaPlotObj.PlotSerieObject(data);
74   - case 'orbit-serie' :
75   - return new amdaPlotObj.PlotOrbitSerieObject(data);
  74 + case 'orbit-serie' :
  75 + return new amdaPlotObj.PlotOrbitSerieObject(data);
76 76 case 'spectro' :
77 77 return new amdaPlotObj.PlotSpectroObject(data);
78 78 case 'status-bar' :
... ...
js/app/models/PlotObjects/PlotSpectroObject.js
... ... @@ -26,7 +26,10 @@ Ext.define(&#39;amdaPlotObj.PlotSpectroObject&#39;, {
26 26 {name: 'spectro-value-min', type: 'float', useNull:true},
27 27 {name: 'spectro-value-max', type: 'float', useNull:true},
28 28 {name: 'spectro-log0-as-min', type: 'boolean'},
29   - {name: 'spectro-normalization', type: 'string'}
  29 + {name: 'spectro-normalization', type: 'string'},
  30 + //Filtering
  31 + {name: 'filtering-activated', type: 'boolean'},
  32 + {name:'filtering-level', type:'int'}
30 33 ],
31 34  
32 35 constructor: function(){
... ... @@ -58,6 +61,9 @@ Ext.define(&#39;amdaPlotObj.PlotSpectroObject&#39;, {
58 61 this.set('spectro-resolution', amdaPlotObj.PlotObjectConfig.defaultValues.spectro.resolution);
59 62 this.set('spectro-log0-as-min', false);
60 63 this.set('spectro-normalization', "none");
  64 + // filtering
  65 + this.set( 'filtering-activated', false);
  66 + this.set('filtering-level', amdaPlotObj.PlotObjectConfig.defaultValues.filtering.level);
61 67 },
62 68  
63 69 getJsonValues : function()
... ... @@ -70,6 +76,8 @@ Ext.define(&#39;amdaPlotObj.PlotSpectroObject&#39;, {
70 76 spectroValues['spectro-value-max'] = this.get('spectro-value-max');
71 77 spectroValues['spectro-log0-as-min'] = this.get('spectro-log0-as-min');
72 78 spectroValues['spectro-normalization'] = this.get('spectro-normalization');
  79 + spectroValues['filtering-activated'] = this.get('filtering-activated');
  80 + spectroValues['filtering-level'] = this.get('filtering-level');
73 81 return spectroValues;
74 82 }
75 83 });
... ...
js/app/models/RequestParamObject.js
... ... @@ -63,7 +63,7 @@ Ext.define(&#39;amdaModel.RequestParamObject&#39;, {
63 63 /* Field for arguments of a templated parameter */
64 64 {name: 'template_args', type: 'auto', defaultValue: null},
65 65 /* ?? */
66   - {name: 'plotonly', type: 'bool', defaultValue: false}
  66 + {name: 'plotonly', type: 'bool', defaultValue: false},
67 67 ],
68 68  
69 69 getDimSum : function(dim) {
... ... @@ -141,21 +141,21 @@ Ext.define(&#39;amdaModel.RequestParamObject&#39;, {
141 141  
142 142 paramValues['dim1-index'] = this.get('dim1-index');
143 143 paramValues['dim1-sum-type'] = this.get('dim1-sum-type');
144   - paramValues['dim1-min-value'] = this.get('dim1-min-value');
145   - paramValues['dim1-max-value'] = this.get('dim1-max-value');
146   - paramValues['dim1-min-index'] = this.get('dim1-min-index');
147   - paramValues['dim1-max-index'] = this.get('dim1-max-index');
  144 + paramValues['dim1-min-value'] = this.get('dim1-min-value');
  145 + paramValues['dim1-max-value'] = this.get('dim1-max-value');
  146 + paramValues['dim1-min-index'] = this.get('dim1-min-index');
  147 + paramValues['dim1-max-index'] = this.get('dim1-max-index');
148 148  
149 149 paramValues['dim2-index'] = this.get('dim2-index');
150 150 paramValues['dim2-sum-type'] = this.get('dim2-sum-type');
151   - paramValues['dim2-min-value'] = this.get('dim2-min-value');
152   - paramValues['dim2-max-value'] = this.get('dim2-max-value');
153   - paramValues['dim2-min-index'] = this.get('dim2-min-index');
154   - paramValues['dim2-max-index'] = this.get('dim2-max-index');
  151 + paramValues['dim2-min-value'] = this.get('dim2-min-value');
  152 + paramValues['dim2-max-value'] = this.get('dim2-max-value');
  153 + paramValues['dim2-min-index'] = this.get('dim2-min-index');
  154 + paramValues['dim2-max-index'] = this.get('dim2-max-index');
155 155  
156   - paramValues['type'] = this.get('type');
157   - paramValues['is-init'] = this.get('is-init');
158   -
  156 + paramValues['type'] = this.get('type');
  157 + paramValues['is-init'] = this.get('is-init');
  158 +
159 159 if (this.get('template_args') != null) {
160 160 paramValues['template_args'] = new Object();
161 161 Ext.Object.each(this.get('template_args'), function (argKey, argValue) {
... ...
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,24 +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: 'downloadType', type : 'string'},
18   - {name: 'object', type: 'object'},
19   - {name: 'realLinkedNode', type: 'amdaModel.AmdaNode'},
20   - {name: 'moduleId', type: 'string', defaultValue:'statistics-win'},
21   - {name: 'nodeType', type: 'string', defaultValue: 'statistics'},
22   - {name: 'objectDataModel', type: 'string', defaultValue:'amdaModel.Stats'},
23   - {name: 'jobNode', type: 'string', defaultValue: 'amdaModel.BkgJobNode'}
24   - ],
25   -
26   - constructor: function(config) {
27   - this.callParent(arguments);
28   - this.set('nodeType','statistics');
29   - },
30   - isExecutable: function(){
31   - 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);
32 23 }
33 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/TimeTable.js
... ... @@ -134,6 +134,9 @@ Ext.define(&#39;amdaModel.TimeTable&#39;, {
134 134 {name: 'fromPlugin', type: 'boolean', defaultValue: false},
135 135 {name: 'created', type: 'date'},
136 136 {name: 'description', type: 'string'},
  137 + {name: 'contact', type: 'string', defaultValue:sessionID},
  138 + {name: 'surveyStart', type: 'date'},
  139 + {name: 'surveyStop', type: 'date'},
137 140 {name: 'history', type: 'string'},
138 141 {name: 'nbIntervals', type: 'int'},
139 142 {name: 'objName', type: 'string', defaultValue: ""},
... ... @@ -178,12 +181,18 @@ Ext.define(&#39;amdaModel.TimeTable&#39;, {
178 181 }
179 182 values.objName = this.get('objName');
180 183 values.objFormat = this.get('objFormat');
181   - values.folderId = this.get('folderId');
  184 + values.folderId = this.get('folderId');
182 185 values.nbIntervals = this.get('nbIntervals');
183 186 values.cacheToken = this.get('cacheToken');
184 187  
185 188 values.leaf = true;
186 189 values.nodeType = amdaModel.TimeTableNode.nodeType;
  190 +
  191 + if (this.get('contact').match(/[a-z,0-9]/gi) != null) {
  192 + values.contact = this.get('contact');
  193 + }
  194 + values.surveyStart = this.get('surveyStart');
  195 + values.surveyStop = this.get('surveyStop');
187 196 return values;
188 197 }
189 198  
... ...
js/app/models/TimeTableNode.js
... ... @@ -135,7 +135,7 @@ Ext.define(&#39;amdaModel.TimeTableNode&#39;, {
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/AmdaTreeReader.js
... ... @@ -77,4 +77,4 @@ Ext.define(&#39;amdaReader.AmdaTreeReader&#39;, {
77 77 * @abstract This method has to be overriden in subclasses
78 78 */
79 79 getType: function(node){}
80   -});
81 80 \ No newline at end of file
  81 +});
... ...
js/app/stores/ExplorerReader.js
... ... @@ -48,7 +48,11 @@ Ext.define(&#39;amdaReader.ExplorerReader&#39;, {
48 48 case 'condition' :
49 49 return amdaModel.SearchNode;
50 50 case 'request' :
51   - return amdaModel.PlotNode;
  51 + return amdaModel.PlotNode;
  52 + case 'download' :
  53 + return amdaModel.DownloadNode;
  54 + case 'statistic' :
  55 + return amdaModel.StatisticsNode;
52 56 case 'bkgWorks' :
53 57 return amdaModel.BkgJobNode;
54 58 default:
... ...
js/app/views/AstroImagesUI.js
... ... @@ -38,7 +38,8 @@ Ext.define(&#39;amdaUI.AstroImagesUI&#39;, {
38 38 extend: 'Ext.form.Panel',
39 39  
40 40 requires: [
41   - 'amdaUI.SendToSampButtonUI'
  41 + 'amdaUI.SendToSampButtonUI',
  42 + 'amdaModel.DownloadNode'
42 43 ],
43 44  
44 45 //
... ... @@ -318,9 +319,13 @@ Ext.define(&#39;amdaUI.AstroImagesUI&#39;, {
318 319 obj.set('compression','zip');
319 320 obj.set('list',imageList);
320 321 obj.set('downloadSrc',2);
321   -
322   - amdaModel.DownloadNode.set('object',obj);
323   - amdaModel.DownloadNode.execute();
  322 +
  323 + var downloadNode = Ext.create('amdaModel.DownloadNode', {
  324 + leaf : true,
  325 + });
  326 +
  327 + downloadNode.set('object',obj);
  328 + downloadNode.execute();
324 329 },
325 330  
326 331 getAdditionalRequestConfig : function(panelId)
... ...
js/app/views/CalculatorUI.js
... ... @@ -592,6 +592,7 @@ Ext.define(&#39;amdaUI.CalculatorUI&#39;, {
592 592 this.createFunctionBtns('ModelFunctions', 'Models', '#calc_tab_func_id');
593 593 this.createFunctionBtns('AmdaFunctions', 'TimeShift', '#calc_tab_func_id');
594 594 this.createFunctionBtns('FramesFunctions', 'Frames', '#calc_tab_func_id');
  595 + this.createFunctionBtns('FilterFunctions', 'Filter', '#calc_tab_func_id');
595 596 amdaUI.CalculatorUI.functionStore.clearFilter();
596 597  
597 598 // group stat
... ... @@ -699,6 +700,10 @@ Ext.define(&#39;amdaUI.CalculatorUI&#39;, {
699 700 amdaUI.CalculatorUI.functionStore.filter('kind', 'frames');
700 701 width = .45;
701 702 break;
  703 + case 'FilterFunctions' :
  704 + amdaUI.CalculatorUI.functionStore.filter('kind', 'filter');
  705 + width = .45;
  706 + break;
702 707 }
703 708  
704 709 var crtTab = funcTab[0].add(
... ...
js/app/views/CatalogUI.js
... ... @@ -22,6 +22,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
22 22 ],
23 23  
24 24 isCatalog: true,
  25 + activeField : null,
25 26 statics: {
26 27 COL_TO_HIDE_DURATION: 'colToHideDuration'
27 28 },
... ... @@ -79,7 +80,6 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
79 80 // get the basic form
80 81 var basicForm = this.formPanel.getForm();
81 82 var updateStatus = true;
82   -
83 83 var fieldsWithoutName = basicForm.getFields().items;
84 84 Ext.Array.each(fieldsWithoutName, function (item, index, allItems) {
85 85 if (item !== this.fieldName) {
... ... @@ -148,6 +148,58 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
148 148 return;
149 149 }
150 150 },
  151 + updateSurveyDates : function(ttObj){
  152 + var starts = [];
  153 + var stops= [];
  154 + if (this.TTGrid.getStore().getTotalCount() <= 0)
  155 + return;
  156 + reqObj = {
  157 + 'typeTT': 'catalog',
  158 + }
  159 + AmdaAction.readCacheIntervals(reqObj, function(result, e)
  160 + {
  161 + if (!result) {
  162 + myDesktopApp.errorMsg(e.message);
  163 + Ext.defer(function () {
  164 + Ext.Msg.toFront()
  165 + }, 10);
  166 +
  167 + return;
  168 + } else if (!result.success)
  169 + {
  170 + if (result.message)
  171 + myDesktopApp.errorMsg(result.message);
  172 + else
  173 + myDesktopApp.errorMsg('Unknown error during catalog survey dates update');
  174 +
  175 + Ext.defer(function () {
  176 + Ext.Msg.toFront()
  177 + }, 10);
  178 +
  179 + return;
  180 + }
  181 + Ext.Array.each(result.intervals, function (item, index) {
  182 + starts[index] = (item.start);
  183 + stops[index] = (item.stop);
  184 + });
  185 + if(starts.length !== 0 || stops.length !== 0) {
  186 +
  187 + starts.sort();
  188 + stops.sort();
  189 + s = new Date(starts[0]);
  190 + e = new Date(stops[stops.length - 1]);
  191 + if(! ttObj.get('surveyStart') ){
  192 + ttObj.set('surveyStart', s);
  193 + this.status.isModified = true;
  194 + }
  195 + if(! ttObj.get('surveyStop') ){
  196 + ttObj.set('surveyStop', e);
  197 + this.status.isModified = true;
  198 + }
  199 + }
  200 + });
  201 + },
  202 +
151 203 createTT: function (catId) {
152 204 var ttObj = Ext.create('amdaModel.TimeTable');
153 205 var timeTabNode = Ext.create('amdaModel.TimeTableNode', {leaf: true});
... ... @@ -156,6 +208,8 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
156 208 date = Ext.Date.format(creatDate, 'Y-m-d\\TH:i:s');
157 209 descr = 'Generated by CDPP/Amda Catalog Module \n' + 'From Catalog: ' + this.object.get('name') + '\nOn: ' + date + '\n';
158 210 ttObj.set('description', descr + this.object.get('description'));
  211 + ttObj.set('contact', this.object.get('contact'));
  212 + //this.updateSurveyDates(ttObj);
159 213 timeTabNode.set('object', ttObj);
160 214 var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
161 215 var ttRootNode = explorerTree.getRootNode().findChild('id', 'timeTable-treeRootNode', true);
... ... @@ -482,7 +536,14 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
482 536 xtype: 'gridcolumn',
483 537 width: pramColumnWidth * parseInt(obj.size),
484 538 editor: 'textfield',
485   - filter: {type: 'string'}
  539 + renderer :function(value){
  540 + var renderedVal = value;
  541 + if(value.toLowerCase().startsWith("http://") ||value.toLowerCase().startsWith("https://")) {
  542 + renderedVal = '<a href="' + value + '" target="_blank">' + value +'</a>';
  543 + }
  544 + return renderedVal;
  545 + },
  546 + filter: {type: 'string'}
486 547 });
487 548 break;
488 549 case 3: //int
... ... @@ -626,6 +687,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
626 687 var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.catalog.id);
627 688 // store / columns are the same - not needed to reconfigure grid
628 689 this.toReconfigure = false;
  690 + this.updateSurveyDates(this.object);
629 691  
630 692 // if save shared catalog
631 693 if (module.contextNode && (module.contextNode.get('id') == 'sharedcatalog-treeRootNode'))
... ... @@ -684,8 +746,8 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
684 746 if (this.TTGrid.getStore().getTotalCount() > 0)
685 747 {
686 748 // update TimeTable object which the content of form
687   - basicForm.updateRecord(this.object);
688 749  
  750 + basicForm.updateRecord(this.object);
689 751 var me = this;
690 752 this.checkIntervalsStatusForSave(function () {
691 753 //Name validation
... ... @@ -757,7 +819,32 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
757 819 var isDirty = this.formPanel.getForm().isDirty() || (this.status.isModified) || (this.status.nbModified > 0) || (this.status.nbNew > 0);
758 820 return isDirty;
759 821 },
760   -
  822 + onChangeStartField: function(field, newValue, oldValue){
  823 + if (field.isValid()) {
  824 + if (field.isValid() && this.activeField == 'surveyStart') {
  825 + // launch the update of duration fields
  826 + var form = this.findParentByType('form').getForm();
  827 + var stop = form.findField('surveyStop').setMinValue(newValue);
  828 + var start = form.findField('surveyStart').getValue();
  829 + var stop = form.findField('surveyStop').getValue();
  830 + if (stop <= start) {
  831 + form.findField('surveyStart').markInvalid('Start Time must be before Stop Time');
  832 + }
  833 + }
  834 + }
  835 + },
  836 + onChangeStopField: function(field, newValue, oldValue)
  837 + {
  838 + if (field.isValid() && this.activeField =='surveyStop' ) {
  839 + // launch the update of duration fields
  840 + var form = this.findParentByType('form').getForm();
  841 + var start = form.findField('surveyStart').getValue();
  842 + var stop =form.findField('surveyStop').getValue();
  843 + if ( stop <= start ) {
  844 + field.markInvalid('Stop Time must be after Start Time');
  845 + }
  846 + }
  847 + },
761 848 init: function (config)
762 849 {
763 850 this.object = config.object;
... ... @@ -947,14 +1034,61 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
947 1034 ]
948 1035 },
949 1036 {
  1037 + xtype:'fieldset',
  1038 + columnWidth: 0.5,
  1039 + title: 'Survey Period',
  1040 + collapsible: true,
  1041 + defaultType: 'datefield',
  1042 + defaults: {anchor: '100%'},
  1043 + layout: 'anchor',
  1044 + items :[{
  1045 + fieldLabel: 'Start Time',
  1046 + name: 'surveyStart',
  1047 + emptyText: 'YYYY/MM/DDThh:mm:ss',
  1048 + format: 'Y-m-d\\TH:i:s',
  1049 + enforceMaxLength: true,
  1050 + maxLength: 19,
  1051 + labelWidth: 60,
  1052 + labelAlign: 'left',
  1053 + listeners: {
  1054 + change: this.onChangeStartField,
  1055 + focus: function(field) {
  1056 + this.activeField = 'surveyStart';
  1057 + },
  1058 + }
  1059 + }, {
  1060 + fieldLabel: 'Stop Time',
  1061 + name: 'surveyStop',
  1062 + emptyText: 'YYYY/MM/DDThh:mm:ss',
  1063 + format: 'Y-m-d\\TH:i:s',
  1064 + labelAlign: 'left',
  1065 + enforceMaxLength: true,
  1066 + maxLength: 19,
  1067 + labelWidth: 60,
  1068 + align: 'left',
  1069 + listeners: {
  1070 + change: this.onChangeStopField,
  1071 + focus: function(field) {
  1072 + this.activeField = 'surveyStop';
  1073 + },
  1074 + }
  1075 + }]
  1076 + },
  1077 + {
  1078 + xtype: 'textarea',
  1079 + name: 'contact',
  1080 + fieldLabel: 'Contact',
  1081 + height:50
  1082 + },
  1083 + {
950 1084 xtype: 'textarea',
951 1085 name: 'description',
952 1086 fieldLabel: 'Description',
953   - height: 200
  1087 + height: 150
954 1088 },
955 1089 {
956 1090 xtype: 'component',
957   - height: 90
  1091 + height: 20
958 1092 }],
959 1093 dockedItems: [
960 1094 {
... ...
js/app/views/DownloadUI.js
... ... @@ -16,25 +16,11 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
16 16 'amdaUI.TimeSelectorUI',
17 17 'amdaUI.ParamArgumentsPlug',
18 18 'amdaUI.SendToSampButtonUI',
  19 + 'amdaModel.Download',
19 20 'amdaModel.DownloadParam',
20 21 'amdaModel.RequestParamObject'
21 22 ],
22 23  
23   - //Old kernel time formats
24   - //timeformatData : [['Y-m-dTH:i:s', 'YYYY-MM-DDThh:mm:ss'], ['Y m d H i s', 'YYYY MM DD hh mm ss'], ['d m Y H i s', 'DD MM YYYY hh mm ss'], ['Y z H i s', 'YYYY DDD hh mm ss']],
25   - //New kernel time formats
26   - timeformatData: [['YYYY-MM-DDThh:mm:ss', 'YYYY-MM-DDThh:mm:ss.ms', 'ISO format with msecs'],
27   - ['DD Time', 'YYYYDOYhhmmssms', 'Day-Of-Year, 1 Jan : DOY = 0'],
28   - ['Timestamp', 'Seconds from 1970', 'Total of seconds from the Unix Epoch on January 1st, 1970 at UTC.'],
29   - ['YYYY MM DD hh mm ss', 'YYYY MM DD hh mm ss ms', 'date with spaces'],
30   - ['Timestamp-with-milliseconds', 'Seconds from 1970 with ms', 'Total of seconds from the Unix Epoch with milliseconds.']],
31   - timeformatTTData: [['Y-m-dTH:i:s', 'YYYY-MM-DDThh:mm:ss']],
32   - fileformatData: [['ASCII', 'ASCII'], ['vot', 'VOTable'], ['cdf', 'CDF'], ['json', 'JSON']],
33   - fileformatTTData: [['text', 'plain text'], ['vot', 'VOTable']],
34   - filecompressData: [['zip', 'zip'], ['tar+gzip', 'tar+gzip']],
35   - filecompressTT: [['zip', 'zip'], ['tar+gzip', 'tar+gzip'], ['none', 'none']],
36   - filestructureData: [['0', 'All In One File'], ['1', 'One File Per Time Interval'], ['2', 'One File Per Param/Interval']],
37   -
38 24 constructor: function (config) {
39 25 this.init(config);
40 26 this.callParent(arguments);
... ... @@ -47,6 +33,91 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
47 33 paramArgsPlug.onApply = this.onApplyParameterArgs;
48 34 },
49 35  
  36 + saveRequest: function()
  37 + {
  38 + var me = this;
  39 +
  40 + if (!this.updateObject()) {
  41 + return;
  42 + }
  43 +
  44 + var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
  45 + if (!downloadModule) {
  46 + return;
  47 + }
  48 +
  49 + if ((this.object.get('id') != '') && (downloadModule.linkedNode.get('text') == this.object.get('name'))) {
  50 + this.saveProcess(false);
  51 + return;
  52 + }
  53 +
  54 + downloadModule.linkedNode.isValidName(this.fieldName.getValue(), function (res) {
  55 + if (!res)
  56 + {
  57 + me.fieldName.validFlag = 'Error during object validation';
  58 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  59 + me.fieldName.validate();
  60 + return;
  61 + }
  62 +
  63 + if (!res.valid)
  64 + {
  65 + if (res.error)
  66 + {
  67 + if (res.error.search('subtree') != -1) {
  68 + Ext.MessageBox.show({title:'Warning',
  69 + msg: res.error+'<br/>Do you want to overwrite it?',
  70 + width: 300,
  71 + buttons: Ext.MessageBox.OKCANCEL,
  72 + fn : function(btn) {
  73 + if (btn == 'cancel') return;
  74 + this.fieldName.clearInvalid();
  75 + this.saveProcess(true);
  76 + },
  77 + icon: Ext.MessageBox.WARNING,
  78 + scope : me
  79 + });
  80 + me.fieldName.validFlag = true;
  81 + }
  82 + else
  83 + me.fieldName.validFlag = res.error;
  84 + }
  85 + else
  86 + {
  87 + me.fieldName.validFlag = 'Invalid object name';
  88 + myDesktopApp.errorMsg(me.fieldName.validFlag);
  89 + }
  90 + me.fieldName.validate();
  91 + return;
  92 + }
  93 +
  94 + me.fieldName.validFlag = true;
  95 + me.fieldName.validate();
  96 + me.saveProcess(false);
  97 + });
  98 + },
  99 +
  100 + saveProcess: function(toRename) {
  101 + var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
  102 + if (this.object.isModified('name')) {
  103 + if (this.object.get('id'))
  104 + {
  105 + var contextNode = downloadModule.linkedNode.parentNode;
  106 + downloadModule.createLinkedNode();
  107 + downloadModule.linkedNode.set('contextNode',contextNode);
  108 + downloadModule.createObject(this.object.getJsonValues());
  109 + var downloadObj = downloadModule.linkedNode.get('object');
  110 + this.object = downloadObj;
  111 + if (toRename) downloadModule.linkedNode.toRename = true;
  112 + }
  113 + downloadModule.linkedNode.create();
  114 + }
  115 + else {
  116 + downloadModule.linkedNode.set('contextNode',downloadModule.contextNode);
  117 + downloadModule.linkedNode.update();
  118 + }
  119 + },
  120 +
50 121 addTT: function (newTTName, newTTid)
51 122 {
52 123 var tabPanel = this.formPanel.down();
... ... @@ -92,6 +163,14 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
92 163 this.timeSelector.intervalSel.updateDuration();
93 164 },
94 165  
  166 + addParameter: function(paramNode, updateTime)
  167 + {
  168 + if (this.doNotifyDrop(paramNode)) {
  169 + return this.doParamDrop(paramNode);
  170 + }
  171 + return false;
  172 + },
  173 +
95 174 addParam: function (paramId, isLeaf, needArgs, components, predefined_args)
96 175 {
97 176 // adding the parameter to the paramGrid
... ... @@ -123,44 +202,6 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
123 202 this.editParameterArgs(r);
124 203 },
125 204  
126   - addParams: function (arrayParams)
127   - {
128   - var arrayRec = new Array();
129   - var index = 1;
130   -
131   - if (arrayParams)
132   - {
133   - Ext.Array.each(arrayParams, function (item) {
134   - if (Ext.isObject(item)) {
135   - // handel case of derived parameters
136   - var patt_ws = new RegExp("ws_");
137   - var patt_wsd = new RegExp("wsd_");
138   - if (typeof paramId !== 'undefined' && ! patt_ws.test(item.paramid) && ! patt_wsd.test(item.paramid))
139   - {
140   - // for Parameter Name in Download Module
141   - var paramObj = amdaModel.RequestParamObject.getEmptyObj();
142   - paramObj.paramid = paramId;
143   - paramObj['dim1-index'] = item.get('dim1');
144   - paramObj['dim2-index'] = item.get('dim2');
145   -
146   - var r = Ext.create('amdaModel.DownloadParam', paramObj);
147   - } else
148   - {
149   - //for download from get Data in Plot module
150   - var r = Ext.create('amdaModel.DownloadParam', item);
151   - }
152   -
153   - } else {
154   - // for Download By Request in Operations menu
155   - //TODO BRE - Components selection
156   - var r = Ext.create('amdaModel.DownloadParam', {paramid: item});
157   - }
158   - arrayRec.push(r);
159   - });
160   - }
161   - this.paramGrid.getStore().loadData(arrayRec);
162   - },
163   -
164 205 // parameter name -> alias
165 206 updateConstruct: function (oldval, newval) {
166 207 var index = this.paramGrid.store.findExact('name', oldval);
... ... @@ -192,16 +233,16 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
192 233 {
193 234 var timeformat = values.timeformat;
194 235 var timeSource = this.timeSelector.getActiveTimeSource();
195   - var structure = values.filestructure;
  236 + var filestructure = values.filestructure;
196 237 var sampling = values.sampling ? values.sampling : 600;
197   - var refparamSampling = values.refparamsampling == 'on';
  238 + var refparamSampling = values.refparamSampling == 'on';
198 239 var fileprefix = values.fileprefix ? values.fileprefix : '';
199 240 var fileformat = values.fileformat;
200 241 var compression = values.compression;
201 242  
202 243 var fieldsWithoutName = basicForm.getFields().items;
203 244 Ext.Array.each(fieldsWithoutName, function (item, index, allItems) {
204   - if (!item.isValid()) {
  245 + if ((item.name != 'name') && !item.isValid()) {
205 246 if ((timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) &&
206 247 ((item.name == 'startDate') || (item.name == 'stopDate') || (item.name == 'duration'))) {
207 248 updateStatus = true;
... ... @@ -220,18 +261,23 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
220 261 updateStatus = false;
221 262 }
222 263  
  264 + if (updateStatus && (this.object.params().count() == 0))
  265 + {
  266 + myDesktopApp.warningMsg('You must define at least one parameter to download');
  267 + updateStatus = false;
  268 + }
  269 +
223 270 if (updateStatus)
224 271 {
225 272 /// real object update
226 273 // update TimeTable object with the content of form
227 274 basicForm.updateRecord(this.object);
  275 +
228 276 this.object.set('timesrc', timeSource);
229 277 // set valid intervals into TimeTable object
230 278 if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0])
231 279 this.object.set('timeTables', this.timeSelector.TTGrid.getStore().data.items);
232   - // set parameters
233   - this.object.set('list', this.paramGrid.getStore().data.items);
234   - this.object.set('structure', structure);
  280 + this.object.set('filestructure', filestructure);
235 281 this.object.set('refparamSampling', refparamSampling);
236 282 this.object.set('sampling', sampling);
237 283 this.object.set('fileprefix', fileprefix);
... ... @@ -243,10 +289,14 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
243 289 //TT download
244 290 else
245 291 {
246   - var timeformat = values.timeformatTT;
  292 + var timeformat = values.timeformatTT ? values.timeformatTT :amdaModel.DownloadConfig.defaultValues.timeformatTT;
247 293 var compression = values.compressionTT;
248 294 var fileformat = values.fileformatTT;
249   - if (compression === 'none'
  295 + if (this.TTGrid.getStore().count() == 0) {
  296 + myDesktopApp.warningMsg('You must define at least one TimeTable or Catalog to download');
  297 + updateStatus = false;
  298 + }
  299 + else if (compression === 'none'
250 300 && this.TTGrid.getStore().count() > 1) {
251 301 myDesktopApp.warningMsg('You are going to download several time tables - select the Compression please');
252 302 updateStatus = false;
... ... @@ -266,31 +316,16 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
266 316 * load this.object into form
267 317 */
268 318 loadObject: function () {
269   -
270   - if (!this.object.get('timeformat'))
271   - this.object.set('timeformat', this.timeformatData[0][0]);
272   -
273   - if (!this.object.get('timeformatTT'))
274   - this.object.set('timeformatTT', this.timeformatData[0][0]);
275   -
276   - if (!this.object.get('fileformat'))
277   - this.object.set('fileformat', this.fileformatData[0][0]);
278   -
279   - if (!this.object.get('fileformatTT'))
280   - this.object.set('fileformatTT', this.fileformatTTData[0][0]);
281   -
282   - if (!this.object.get('compression'))
283   - this.object.set('compression', this.filecompressData[1][0]);
284   -
285   - if (!this.object.get('compressionTT'))
286   - this.object.set('compressionTT', this.filecompressData[1][0]);
287   -
288 319 // load object into form
289 320 this.formPanel.getForm().loadRecord(this.object);
290 321 // set object's TTs into the timeselector
291 322 this.addTTs(this.object.get('timeTables'));
292   - // set parameters
293   - this.addParams(this.object.get('list'));
  323 + // set parameters
  324 + this.paramGrid.reconfigure(this.object.params());
  325 + //this.paramGrid.getStore().loadData(this.object.params().data.items);
  326 + // select "Parameters" tab
  327 + var tabPanel = this.formPanel.down();
  328 + tabPanel.setActiveTab(0);
294 329 },
295 330  
296 331 /**
... ... @@ -299,7 +334,7 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
299 334 doDownload: function (sendToSamp, clientId) {
300 335 var downloadModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
301 336 if (downloadModule)
302   - downloadModule.linkedNode.execute(sendToSamp, clientId);
  337 + downloadModule.linkedNode.execute({'sendToSamp': (sendToSamp == true), 'clientId': clientId});
303 338 },
304 339  
305 340 actionItem: function (grid, cell, cellIndex, record, row, recordIndex, e) {
... ... @@ -328,7 +363,7 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
328 363 if (!this.formPanel)
329 364 return;
330 365  
331   - var refParamCheck = this.formPanel.getForm().findField('refparamsampling');
  366 + var refParamCheck = this.formPanel.getForm().findField('refparamSampling');
332 367 var samplingField = this.formPanel.getForm().findField('sampling');
333 368  
334 369 if (samplingField && newValue !== oldValue) {
... ... @@ -336,6 +371,21 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
336 371 samplingField.setDisabled((newValue == 2) || refParamCheck.getValue());
337 372 }
338 373 },
  374 + onTTFileFormatChange: function (combo, newValue, oldValue) {
  375 + if (!this.formPanel)
  376 + return;
  377 +
  378 + var refTimeFormatField = this.formPanel.getForm().findField('timeformatTT');
  379 +
  380 + if (refTimeFormatField && newValue !== oldValue) {
  381 + if (newValue === 'space' ){
  382 + refTimeFormatField.setValue('YYYY-MM-DDThh:mm:ss');
  383 + refTimeFormatField.setDisabled(true);
  384 + }else{
  385 + refTimeFormatField.setDisabled(false);
  386 + }
  387 + }
  388 + },
339 389  
340 390 onRefParamSamplingChange: function (check, newValue, oldValue) {
341 391 if (!this.formPanel)
... ... @@ -355,12 +405,128 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
355 405 }
356 406 },
357 407  
  408 + doNotifyDrop: function(record)
  409 + {
  410 + if (record.get('nodeType') == 'localParam' && record.get('notyet'))
  411 + {
  412 + return false;
  413 + }
  414 + if (((record.get('nodeType') == 'localParam') ||
  415 + (record.get('nodeType') == 'remoteParam') ||
  416 + (record.get('nodeType') == 'remoteSimuParam') ||
  417 + (record.get('nodeType') == 'derivedParam') ||
  418 + (record.get('nodeType') == 'myDataParam') ||
  419 + (record.get('nodeType') == 'alias')) &&
  420 + (record.isLeaf() || record.get('isParameter')) &&
  421 + !record.get('disable'))
  422 + {
  423 + return true;
  424 + }
  425 +
  426 + return false;
  427 + },
  428 +
  429 + doParamDrop: function(record)
  430 + {
  431 + var idToSent;
  432 + var components = null;
  433 + var predefinedArgs = record.get('predefinedArgs');
  434 + switch (record.get('nodeType'))
  435 + {
  436 + case 'localParam' :
  437 + case 'remoteParam':
  438 + case 'remoteSimuParam':
  439 + idToSent = record.get('id');
  440 + if (record.get('alias') != "")
  441 + idToSent = "#" + record.get('alias');
  442 + var component_info = record.get('component_info');
  443 + if (component_info && component_info.parentId)
  444 + {
  445 + if (component_info.index1 || component_info.index2)
  446 + {
  447 + idToSent = component_info.parentId;
  448 + components = [];
  449 + if (component_info.index1)
  450 + components['index1'] = component_info.index1;
  451 + if (component_info.index2)
  452 + components['index2'] = component_info.index2;
  453 + predefinedArgs = record.parentNode.get('predefinedArgs');
  454 + }
  455 + if (record.get('needsArgs'))
  456 + {
  457 + idToSent = component_info.parentId;
  458 + if (component_info.index1)
  459 + {
  460 + components = [];
  461 + components['index1'] = component_info.index1;
  462 + }
  463 + }
  464 + }
  465 + break;
  466 + case 'alias' :
  467 + idToSent = "#" + record.get('text');
  468 + break;
  469 + case 'derivedParam' :
  470 + if (record.modelName == 'amdaModel.DerivedParamComponentNode')
  471 + {
  472 + paramId = record.get('text');
  473 + var parentId = paramId.substr(0, paramId.length - 3);
  474 + idToSent = "ws_" + parentId;
  475 + var regExp = /\(([\d]+)\)/;
  476 + var component_index = regExp.exec(paramId);
  477 + if (component_index)
  478 + {
  479 + components = [];
  480 + components['index1'] = component_index[1];
  481 + }
  482 + }
  483 + else {
  484 + idToSent = "ws_" + record.get('text');
  485 + }
  486 + break;
  487 + case 'myDataParam' :
  488 + if (record.modelName == 'amdaModel.MyDataParamComponentNode')
  489 + {
  490 + paramId = record.get('text');
  491 + var parentId = paramId.substr(0, paramId.length - 3);
  492 + idToSent = "wsd_" + parentId;
  493 + var regExp = /\(([\d]+)\)/;
  494 + var component_index = regExp.exec(paramId);
  495 + if (component_index)
  496 + {
  497 + components = [];
  498 + components['index1'] = component_index[1];
  499 + }
  500 + }
  501 + else {
  502 + idToSent = "wsd_" + record.get('text');
  503 + }
  504 + break;
  505 + default :
  506 + return false;
  507 + }
  508 +
  509 + var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
  510 + if (downModule) {
  511 + if (predefinedArgs) {
  512 + downModule.parseTemplatedParam(idToSent, function(param_info) {
  513 + downModule.addParam(param_info.paramid, record.get('leaf'), record.get('needsArgs'), components, param_info.template_args);
  514 + });
  515 + }
  516 + else {
  517 + downModule.addParam(idToSent, record.get('leaf'), record.get('needsArgs'), components);
  518 + return true;
  519 + }
  520 + }
  521 + return true;
  522 + },
  523 +
358 524 /**
359 525 * Check if changes were made before closing window
360 526 * @return false
361 527 */
362 528 fclose: function () {
363   - return false;
  529 + return this.object.isDirty();
364 530 },
365 531  
366 532 init: function (config) {
... ... @@ -368,6 +534,23 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
368 534  
369 535 this.timeSelector = new amdaUI.TimeSelectorUI({id: 'downloadTimeSelector', flex: 1});
370 536  
  537 + this.fieldName = new Ext.form.field.Text({
  538 + labelAlign: 'left',
  539 + labelWidth: 90,
  540 + fieldLabel: 'Request Name',
  541 + name : 'name',
  542 + allowBlank : false,
  543 + stripCharsRe: /(^\s+|\s+$)/g,
  544 + validateOnChange: false,
  545 + validateOnBlur: false,
  546 + validFlag: false,
  547 + validator : function()
  548 + {
  549 + return this.validFlag;
  550 + }
  551 + });
  552 +
  553 + var downloadCont = this;
371 554 this.paramGrid = Ext.create('Ext.grid.Panel', {
372 555 flex: 2,
373 556 store: Ext.create('Ext.data.Store', {model: 'amdaModel.DownloadParam'}),
... ... @@ -401,129 +584,23 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
401 584 {
402 585 var me = this;
403 586 var el = me.body.dom;
404   - var dropTarget = Ext.create('Ext.dd.DropTarget', el, {
  587 + me.dropTarget = Ext.create('Ext.dd.DropTarget', el, {
405 588 ddGroup: 'explorerTree',
406 589 notifyEnter: function (ddSource, e, data) { },
407 590 notifyOver: function (ddSource, e, data)
408 591 {
409   - if (data.records[0].data.nodeType == 'localParam' && data.records[0].get('notyet'))
410   - {
  592 + if (!downloadCont.doNotifyDrop(data.records[0])) {
411 593 this.valid = false;
412 594 return this.dropNotAllowed;
413 595 }
414   - if (((data.records[0].data.nodeType == 'localParam') ||
415   - (data.records[0].data.nodeType == 'remoteParam') ||
416   - (data.records[0].data.nodeType == 'remoteSimuParam') ||
417   - (data.records[0].data.nodeType == 'derivedParam') ||
418   - (data.records[0].data.nodeType == 'myDataParam') ||
419   - (data.records[0].data.nodeType == 'alias')) &&
420   - (data.records[0].isLeaf() || data.records[0].data.isParameter) &&
421   - !data.records[0].data.disable)
422   - {
423   - this.valid = true;
424   - return this.dropAllowed;
425   - }
426   -
427   - this.valid = false;
428   - return this.dropNotAllowed;
  596 + this.valid = true;
  597 + return this.dropAllowed;
429 598 },
430 599 notifyDrop: function (ddSource, e, data)
431 600 {
432 601 if (!this.valid)
433 602 return false;
434   - var idToSent;
435   - var components = null;
436   - var predefinedArgs = data.records[0].get('predefinedArgs');
437   - switch (data.records[0].data.nodeType)
438   - {
439   - case 'localParam' :
440   - case 'remoteParam':
441   - case 'remoteSimuParam':
442   - idToSent = data.records[0].get('id');
443   - if (data.records[0].get('alias') != "")
444   - idToSent = "#" + data.records[0].get('alias');
445   - var component_info = data.records[0].get('component_info');
446   - if (component_info && component_info.parentId)
447   - {
448   - if (component_info.index1 || component_info.index2)
449   - {
450   - idToSent = component_info.parentId;
451   - components = [];
452   - if (component_info.index1)
453   - components['index1'] = component_info.index1;
454   - if (component_info.index2)
455   - components['index2'] = component_info.index2;
456   - predefinedArgs = data.records[0].parentNode.get('predefinedArgs');
457   - }
458   - if (data.records[0].get('needsArgs'))
459   - {
460   - idToSent = component_info.parentId;
461   - if (component_info.index1)
462   - {
463   - components = [];
464   - components['index1'] = component_info.index1;
465   - }
466   - }
467   - }
468   - break;
469   - case 'alias' :
470   - idToSent = "#" + data.records[0].get('text');
471   - break;
472   - case 'derivedParam' :
473   - if (data.records[0].modelName == 'amdaModel.DerivedParamComponentNode')
474   - {
475   - paramId = data.records[0].get('text');
476   - var parentId = paramId.substr(0, paramId.length - 3);
477   - idToSent = "ws_" + parentId;
478   - var regExp = /\(([\d]+)\)/;
479   - var component_index = regExp.exec(paramId);
480   - if (component_index)
481   - {
482   - components = [];
483   - components['index1'] = component_index[1];
484   - }
485   - break;
486   - } else
487   - {
488   - idToSent = "ws_" + data.records[0].get('text');
489   - }
490   - break;
491   - case 'myDataParam' :
492   - if (data.records[0].modelName == 'amdaModel.MyDataParamComponentNode')
493   - {
494   - paramId = data.records[0].get('text');
495   - var parentId = paramId.substr(0, paramId.length - 3);
496   - idToSent = "wsd_" + parentId;
497   - var regExp = /\(([\d]+)\)/;
498   - var component_index = regExp.exec(paramId);
499   - if (component_index)
500   - {
501   - components = [];
502   - components['index1'] = component_index[1];
503   - }
504   - break;
505   - }
506   - else{
507   - idToSent = "wsd_" + data.records[0].get('text');
508   - }
509   - break;
510   - default :
511   - return false;
512   - }
513   - var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
514   - if (downModule) {
515   -
516   - if (predefinedArgs) {
517   - downModule.parseTemplatedParam(idToSent, function(param_info) {
518   - downModule.addParam(param_info.paramid, data.records[0].get('leaf'), data.records[0].get('needsArgs'), components, param_info.template_args);
519   - });
520   - }
521   - else {
522   - downModule.addParam(idToSent, data.records[0].get('leaf'), data.records[0].get('needsArgs'), components);
523   - return true;
524   - }
525   - }
526   - return true;
  603 + return downloadCont.doParamDrop(data.records[0]);
527 604 }
528 605 });
529 606 }
... ... @@ -587,11 +664,9 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
587 664  
588 665 var storeTimeFormat = new Ext.data.ArrayStore({
589 666 fields: ['id', 'name', 'qtip'],
590   - data: this.timeformatData
  667 + data: amdaModel.DownloadConfig.timeformatData
591 668 });
592   -
593   - this.paramPanel = {
594   - xtype: 'container',
  669 + this.paramPanel = new Ext.container.Container({
595 670 title: 'Parameters',
596 671 layout: {
597 672 type: 'hbox',
... ... @@ -607,12 +682,7 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
607 682 align: 'stretch'
608 683 },
609 684 items: [
610   - {
611   - xtype: 'textfield',
612   - fieldLabel: 'Request Name',
613   - disabled: true,
614   - name: 'name'
615   - },
  685 + this.fieldName,
616 686 {
617 687 xtype: 'splitter',
618 688 flex: 0.05
... ... @@ -647,14 +717,12 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
647 717 '<li class="x-boundlist-item" data-qtip="{qtip}">{name}</li>',
648 718 '</tpl>'
649 719 ]
650   - },
651   - value: storeTimeFormat.first()
  720 + }
652 721 },
653 722 {
654 723 fieldLabel: 'File Structure',
655 724 name: 'filestructure',
656   - store: this.filestructureData,
657   - value: this.filestructureData[2],
  725 + store: amdaModel.DownloadConfig.filestructureData,
658 726 listeners: {
659 727 change: {fn: this.onFileStructureChange},
660 728 scope: this
... ... @@ -669,7 +737,7 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
669 737 {
670 738 xtype: 'checkbox', boxLabel: 'Use first param. as reference for sampling',
671 739 boxLabelAlign: 'before',
672   - name: 'refparamsampling', checked: false, disabled: true,
  740 + name: 'refparamSampling', checked: false, disabled: true,
673 741 listeners: {
674 742 change: {fn: this.onRefParamSamplingChange},
675 743 scope: this
... ... @@ -694,19 +762,17 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
694 762 {
695 763 fieldLabel: 'File Format',
696 764 name: 'fileformat',
697   - store: this.fileformatData,
698   - value: this.fileformatData[0]
  765 + store: amdaModel.DownloadConfig.fileformatData
699 766 },
700 767 {
701 768 fieldLabel: 'Compression',
702 769 name: 'compression',
703   - store: this.filecompressData,
704   - value: this.filecompressData[0]
  770 + store: amdaModel.DownloadConfig.filecompressData
705 771 },
706 772 this.timeSelector
707 773 ]
708 774 }
709   - ]};
  775 + ]});
710 776  
711 777 this.ttPanel =
712 778 {
... ... @@ -745,20 +811,21 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
745 811 '<li class="x-boundlist-item" data-qtip="{qtip}">{name}</li>',
746 812 '</tpl>'
747 813 ]
748   - },
749   - value: storeTimeFormat.first()
  814 + }
750 815 },
751 816 {
752 817 fieldLabel: 'File Format ',
753 818 name: 'fileformatTT',
754   - store: this.fileformatTTData,
755   - value: this.fileformatTTData[0]
  819 + store: amdaModel.DownloadConfig.fileformatTTData,
  820 + listeners: {
  821 + change: {fn: this.onTTFileFormatChange},
  822 + scope: this
  823 + }
756 824 },
757 825 {
758 826 fieldLabel: 'Compression ',
759 827 name: 'compressionTT',
760   - store: this.filecompressTT,
761   - value: this.filecompressTT[0]
  828 + store: amdaModel.DownloadConfig.filecompressTTData
762 829 }
763 830 ]}
764 831 ]
... ... @@ -780,8 +847,16 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
780 847 items: [
781 848 this.paramPanel,
782 849 this.ttPanel
783   - ]
784   - }],
  850 + ],
  851 + listeners: {
  852 + tabchange: function(tabPanel, newCard, oldCard, eOpts) {
  853 + var saveBtn = this.down('#save-download');
  854 + saveBtn.setDisabled(newCard != this.paramPanel);
  855 + },
  856 + scope: this
  857 + }
  858 + },
  859 + ],
785 860 fbar: [
786 861 {
787 862 text: 'Download',
... ... @@ -798,17 +873,19 @@ Ext.define(&#39;amdaUI.DownloadUI&#39;, {
798 873 text: 'Reset',
799 874 scope: this,
800 875 handler: function () {
801   - this.formPanel.getForm().reset();
802   - var tabPanel = this.formPanel.down();
803   - var downloadSrc = tabPanel.items.indexOf(tabPanel.getActiveTab());
804   - if (downloadSrc === 0) {
805   - // reset parameters and Time Tables in Get Data
806   - this.paramGrid.store.removeAll();
807   - this.timeSelector.TTGrid.store.removeAll();
808   - } else {
809   - // reset Time Tables in Get time Table
810   - this.TTGrid.store.removeAll();
811   - }
  876 + var downModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id);
  877 + downModule.createLinkedNode();
  878 + var obj = null;
  879 + downModule.createObject(obj);
  880 + this.setObject(downModule.linkedNode.get('object'));
  881 + }
  882 + },
  883 + {
  884 + text: 'Save',
  885 + id: 'save-download',
  886 + scope: this,
  887 + handler: function () {
  888 + this.saveRequest();
812 889 }
813 890 },
814 891 '->',
... ...
js/app/views/ExplorerUI.js
... ... @@ -544,7 +544,10 @@ Ext.define(&#39;amdaUI.ExplorerUI&#39;, {
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 }
... ... @@ -588,6 +591,8 @@ Ext.define(&#39;amdaUI.ExplorerUI&#39;, {
588 591 case 'catalog' :
589 592 case 'request' :
590 593 case 'condition' :
  594 + case 'download':
  595 + case 'statistic':
591 596 record.editLeaf();
592 597 break;
593 598 case 'localParam' :
... ... @@ -644,6 +649,13 @@ Ext.define(&#39;amdaUI.ExplorerUI&#39;, {
644 649 beforeshow: function updateTipBody(tip) {
645 650 if (view.getRecord(tip.triggerElement)) {
646 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 + }
647 659 if (!info || info == '') {
648 660 tip.addCls('hide');
649 661 }
... ...
js/app/views/PlotComponents/PlotBaseSerieForm.js
... ... @@ -81,6 +81,11 @@ Ext.define(&#39;amdaPlotComp.PlotBaseSerieForm&#39;, {
81 81 this.addStandardFloat2('serie-value-max', 'Max value', -Number.MAX_VALUE, Number.MAX_VALUE, true)
82 82 ];
83 83 },
  84 + getFilteringItems: function(){
  85 + return[
  86 + this.addStandardCombo('filtering-level', 'Level', amdaPlotObj.PlotObjectConfig.availableFilteringLevel)
  87 + ];
  88 + },
84 89  
85 90 getFormItems: function() {
86 91 var me = this;
... ... @@ -93,13 +98,14 @@ Ext.define(&#39;amdaPlotComp.PlotBaseSerieForm&#39;, {
93 98 me.object.set('serie-yaxis', value);
94 99 me.crtTree.refresh();
95 100 }),
96   - myDesktopApp.addAmdaInfo('MinMaxThreshold','vertical-align:bottom'),
  101 + myDesktopApp.addAmdaInfo('MinMaxThreshold','vertical-align:bottom'),
97 102 this.addStandardFieldSet('Min/Max thresholds', '', this.getValuesRangeItems()),
98 103 this.addStandardParamDropTarget('serie-colored-param', 'Colored Parameter'),
99 104 this.addStandardFieldSet('Lines', 'serie-lines-activated', this.addStandardLineItems('serie-lines')),
100 105 this.addStandardFieldSet('Symbols', 'serie-symbols-activated', this.addStandardSymbolsItems('serie-symbols')),
101 106 this.addStandardFieldSet('Time ticks', 'serie-timetick-activated', this.getTimeTickItems()),
102   - this.addStandardFieldSet('Interval ticks', 'serie-intervaltick-activated', this.getIntervalTickItems())
  107 + this.addStandardFieldSet('Interval ticks', 'serie-intervaltick-activated', this.getIntervalTickItems()),
  108 + this.addStandardFieldSet('Filtering ( ! Experimental ! )', 'filtering-activated', this.getFilteringItems())
103 109 ];
104 110 }
105 111 });
... ...
js/app/views/PlotComponents/PlotPanelForm.js
... ... @@ -132,7 +132,7 @@ Ext.define(&#39;amdaPlotComp.PlotPanelForm&#39;, {
132 132 this.addStandardCheck('panel-scatter-isotropic', 'Orthonormal scale', function(name, value, oldValue) {
133 133 me.object.set('panel-scatter-isotropic', value);
134 134 me.crtTree.refresh();
135   - }, 'When this option is selected, a unit on the X-axis appears with the same size as a unit on the Y-axis'),
  135 + }, 'When this option is selected, X-axis and Y-axis appear with the same scale in the panel'),
136 136 this.addStandardText('panel-epoch-centertimeid', 'Epoch Center Time Id', function(name, value, oldValue) {
137 137 me.object.set('panel-epoch-centertimeid', value);
138 138 me.crtTree.refresh();
... ...
js/app/views/PlotComponents/PlotSpectroForm.js
... ... @@ -22,6 +22,11 @@ Ext.define(&#39;amdaPlotComp.PlotSpectroForm&#39;, {
22 22 this.addStandardFloat2('spectro-value-max', 'Max value', -Number.MAX_VALUE, Number.MAX_VALUE, true)
23 23 ];
24 24 },
  25 + getFilteringItems: function(){
  26 + return[
  27 + this.addStandardCombo('filtering-level', 'Level', amdaPlotObj.PlotObjectConfig.availableFilteringLevel)
  28 + ];
  29 + },
25 30  
26 31 getFormItems: function() {
27 32 var me = this;
... ... @@ -43,7 +48,8 @@ Ext.define(&#39;amdaPlotComp.PlotSpectroForm&#39;, {
43 48 {
44 49 me.object.set('spectro-normalization', value);
45 50 }
46   - })
  51 + }),
  52 + this.addStandardFieldSet('Filtering ( ! Experimental ! )', 'filtering-activated', this.getFilteringItems())
47 53 ];
48 54 }
49 55 });
... ...
js/app/views/PlotComponents/PlotTabContent.js
... ... @@ -167,9 +167,8 @@ Ext.define(&#39;amdaPlotComp.PlotTabContent&#39;, {
167 167 },
168 168  
169 169 getDataProcess : function() {
170   - var downObject = amdaModel.DownloadNode.decodeObject(this.plotNode.get('object'));
171   - amdaModel.DownloadNode.set('object',Ext.create('amdaModel.Download',downObject));
172   - amdaModel.DownloadNode.editInModule();
  170 + var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id);
  171 + plotModule.editInDownloadModule(this.plotNode);
173 172 },
174 173  
175 174 isValidRequest : function(acceptEmptyTTList = true) {
... ...
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/RemoteDataCenter/ImpexParamManager.php
... ... @@ -380,7 +380,7 @@ class ImpexParamManager
380 380 $obj = (object)array(
381 381 "nodeType" => "download",
382 382 "downloadSrc" => "0",
383   - "structure" => 2,
  383 + "filestructure" => 2,
384 384 "refparamSampling" => false,
385 385 "sampling" => 60,
386 386 "timesrc" => "Interval",
... ...
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',
  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;
... ... @@ -155,6 +155,7 @@ class AmdaAction
155 155 $isSimulation = false;
156 156 $rank = null;
157 157 $skip = FALSE;
  158 + $last_update = 0;
158 159  
159 160 switch ($nodeType)
160 161 {
... ... @@ -172,21 +173,17 @@ class AmdaAction
172 173 ];
173 174 break;
174 175  
  176 + case 'download':
175 177 case 'condition':
176   - $objectMgr = new RequestMgr($nodeType);
177   - $info = $objectMgr->getObject($id)->expression;
178   - break;
179   -
180 178 case 'request':
181   - $objectMgr = new RequestMgr($nodeType);
182   - $objplot = $objectMgr->getObject($id);
183   - if (isset($objplot->name)) {
184   - $info = $objplot->name;
185   - }
186   - else {
187   - $info = $id;
188   - }
189   - break;
  179 + case 'statistic':
  180 + $objectMgr = new RequestMgr($nodeType);
  181 + $info = $objectMgr->getObjectInfo($id);
  182 + $obj_info = $objectMgr->getObject($id);
  183 + if (!empty($obj_info) && !empty($obj_info->last_update)) {
  184 + $last_update = $obj_info->last_update;
  185 + }
  186 + break;
190 187  
191 188 case 'timeTable':
192 189 case 'catalog':
... ... @@ -376,7 +373,7 @@ class AmdaAction
376 373 $info .= "<br/><b>Plot Only!!!</b>";
377 374 }
378 375  
379   - $childrenToReturn[] = array('text' => $name, 'id' => $id,'nodeType' => $nodeType, 'info' => $info,
  376 + $childrenToReturn[] = array('text' => $name, 'id' => $id,'nodeType' => $nodeType, 'info' => $info, 'last_update' => $last_update,
380 377 'leaf' => false, 'help' => $help, 'disable' => $disable, 'rank' => $rank, 'timeRestriction' => $timeRestriction);
381 378 }
382 379 break;
... ... @@ -596,7 +593,7 @@ class AmdaAction
596 593 $childrenToReturn[] = array('text' => $name, 'id' => $id, 'nodeType' => $nodeType, 'info' => $info,
597 594 'help' => $help, 'leaf' => $isLeaf, 'isParameter' => $isParameter, 'dim_1' => $dim_1, 'dim_2' => $dim_2,
598 595 'component_info' => isset($component_info) ? $component_info : NULL,
599   - 'iconCls' => isset($iconCls) ? $iconCls : NULL );
  596 + 'iconCls' => isset($iconCls) ? $iconCls : NULL, 'last_update' => $last_update );
600 597 }
601 598 }
602 599 // if $childrenToReturn we have to return []
... ... @@ -753,6 +750,8 @@ class AmdaAction
753 750 break;
754 751 case 'condition' :
755 752 case 'request' :
  753 + case 'download' :
  754 + case 'statistic':
756 755 $objectMgr = new RequestMgr($nodeType);
757 756 break;
758 757 case 'bkgWorks' :
... ... @@ -786,6 +785,8 @@ class AmdaAction
786 785 break;
787 786 case 'condition' :
788 787 case 'request' :
  788 + case 'download' :
  789 + case 'statistic' :
789 790 $objectMgr = new RequestMgr($obj->nodeType);
790 791 break;
791 792 case 'alias' :
... ... @@ -824,6 +825,8 @@ class AmdaAction
824 825 break;
825 826 case 'condition' :
826 827 case 'request' :
  828 + case 'download' :
  829 + case 'statistic' :
827 830 $objectMgr = new RequestMgr($obj->nodeType);
828 831 break;
829 832 case 'alias' :
... ... @@ -857,6 +860,8 @@ class AmdaAction
857 860 break;
858 861 case 'condition' :
859 862 case 'request' :
  863 + case 'download' :
  864 + case 'statistic' :
860 865 $objectMgr = new RequestMgr($obj->nodeType);
861 866 break;
862 867 case 'alias' :
... ... @@ -887,6 +892,8 @@ class AmdaAction
887 892 break;
888 893 case 'condition' :
889 894 case 'request' :
  895 + case 'download' :
  896 + case 'statistic' :
890 897 $objectMgr = new RequestMgr($obj->nodeType);
891 898 break;
892 899 default:
... ... @@ -913,6 +920,8 @@ class AmdaAction
913 920 break;
914 921 case 'condition' :
915 922 case 'request' :
  923 + case 'download' :
  924 + case 'statistic' :
916 925 $objectMgr = new RequestMgr($obj->nodeType);
917 926 break;
918 927 default:
... ...
php/classes/AmdaStats.php
... ... @@ -6,103 +6,150 @@
6 6  
7 7 class AmdaStats {
8 8  
9   - public $statXml;
  9 + public $statsFilePath;
10 10 public $tasks = array('plot', 'mining', 'print', 'statistics');
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) {
20   -
21   - $this->statXml = new DomDocument('1.0','UTF-8');
22   - $this->statXml->preserveWhiteSpace = false;
23   - $this->statXml->formatOutput = true;
24   -
25   - if (!defined("StatsXml")){
26   - $thisYear = date("Y");
27   - if (!$user){
28   - // general - to read
29   - // define('StatsXml',DATAPATH.'Statistics/Stats.xml');
30   - define("StatsXml",DATAPATH."Statistics/Stats$thisYear.xml");
31   - // if (file_exists(StatsXml)) unlink(StatsXml);
32   - }
33   - else {
34   - // individual - to write
35   - // define("StatsXml", USERPATH."/".$user."/Stats.xml");
36   - define("StatsXml", USERPATH.$user."/Stats$thisYear.xml");
37   - $this->user = $user;
38   - }
  20 + if (!is_dir(DATAPATH.'Statistics')) {
  21 + if (!mkdir(DATAPATH.'Statistics', 0775)) $this->success = false; //return -1;
  22 + if (!chgrp(DATAPATH.'Statistics', APACHE_USER)) $this->success = false; // return -1;
39 23 }
40 24  
41   - if (!file_exists(StatsXml)) {
42   - if (!is_dir(DATAPATH.'Statistics')) {
43   - if (!mkdir(DATAPATH.'Statistics', 0775)) $this->success = false; //return -1;
44   - if (!chgrp(DATAPATH.'Statistics', APACHE_USER)) $this->success = false; // return -1;
45   - }
  25 + $this->statsFilePath = $this->getStatsFilePath($user);
  26 + }
46 27  
47   - $status = $this->generateXml();
48   - if (!$status) {
49   - error_log('Cannot create Stats.xml: Fatal Error '.$user,1,email);
50   - $this->success = false;
51   - }
  28 + public function addTask($user, $task, $vars) {
  29 + $this->concurrentAccessGuestFile(array($this,'_addTask'),array('user' => $user, 'task' => $task, 'vars' => $vars));
  30 + }
  31 +
  32 + public function getModulesStat($start, $stop, $update) {
  33 + return $this->concurrentAccessGuestFile(array($this,'_getModulesStat'), array('start' => $start, 'stop' => $stop, 'update' => $update));
  34 + }
  35 +
  36 + public function mergeXml($year) {
  37 + return $this->concurrentAccessGuestFile(array($this,'_mergeXml'), array('year' => $year));
  38 + }
  39 +
  40 + public function getDataStat($index, $start, $stop, $update) {
  41 + return $this->concurrentAccessGuestFile(array($this,'_getDataStat'), array('index' => $index, 'start', $start, 'stop' => $stop, 'update' => $update));
  42 + }
  43 +
  44 + public function mergeStats($inXml) {
  45 + return $this->concurrentAccessGuestFile(array($this,'_mergeStats'), array('inXml' => $inXml));
  46 + }
  47 +
  48 + private function getStatsFilePath($user) {
  49 + $thisYear = date("Y");
  50 + if (empty($user)){
  51 + return DATAPATH."Statistics/Stats$thisYear.xml";
52 52 }
53   - else {
54   - $status = $this->statXml->load(StatsXml);
55   - if (!$status) {
56   - $status = $this->generateXml();
57   - $msg = $status ? 'Cannot load Stats.xml. New Stats.xml was created' :
58   - 'Cannot load Stats.xml. Cannot create Stats.xml: Fatal Error ';
59   -
60   - error_log($msg.$user,1,email);
61   -
62   - if (!$status)
63   - $this->success = false;
  53 + return USERPATH.$user."/Stats$thisYear.xml";
  54 + }
  55 +
  56 + private function concurrentAccessGuestFile($callback, $options) {
  57 + $lockFile = $this->statsFilePath.".lockfile";
  58 +
  59 + $fp = fopen($lockFile, "w+");
  60 +
  61 + if ($fp === false) {
  62 + return false;
  63 + }
  64 +
  65 + $res = true;
  66 +
  67 + if (flock($fp, LOCK_EX))
  68 + {
  69 + $newFile = FALSE;
  70 + if (!file_exists($this->statsFilePath)) {
  71 + $res = $this->_generateXml();
64 72 }
65   - else {
66   - $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs);
67   - $newTask = FALSE;
68   - foreach ($allTasks as $task) {
69   - $items = $this->statXml->getElementsByTagName($task);
70   - if ($items->length == 0) {
71   - //add missing task
72   - $element = $this->statXml->createElement("$task");
73   - $this->statXml->documentElement->appendChild($element);
74   - $newTask = TRUE;
  73 +
  74 + if ($res) {
  75 + $dom = new DomDocument("1.0","UTF-8");
  76 + $dom->preserveWhiteSpace = false;
  77 + $dom->formatOutput = true;
  78 + $res = $dom->load($this->statsFilePath);
  79 + if (!$newFile) {
  80 + // add missing tasks if needed
  81 + $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs);
  82 + $newTask = FALSE;
  83 + foreach ($allTasks as $task) {
  84 + $items = $dom->getElementsByTagName($task);
  85 + if ($items->length == 0) {
  86 + //add missing task
  87 + $element = $dom->createElement("$task");
  88 + $dom->documentElement->appendChild($element);
  89 + $newTask = TRUE;
  90 + }
75 91 }
  92 + if ($newTask) {
  93 + $dom->save($this->statsFilePath);
  94 + }
76 95 }
77   - if ($newTask) {
78   - $this->statXml->save(StatsXml);
  96 + if ($res) {
  97 + $func_res = call_user_func($callback,$dom, $options);
79 98 }
80 99 }
81   - }
  100 + }
  101 + else
  102 + $res = false;
  103 +
  104 + fclose($fp);
  105 +
  106 + if ($res)
  107 + return $func_res;
  108 +
  109 + return false;
  110 + }
  111 +
  112 + private function _generateXml() {
  113 + $dom = new DomDocument("1.0","UTF-8");
  114 + $dom->preserveWhiteSpace = false;
  115 + $dom->formatOutput = true;
  116 +
  117 + $rootElement = $dom->createElement('stats');
  118 +
  119 + $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs);
  120 +
  121 + foreach ($allTasks as $task) {
  122 + $element = $dom->createElement("$task");
  123 + $rootElement->appendChild($element);
  124 + }
  125 +
  126 + $dom->appendChild($rootElement);
  127 +
  128 + return $dom->save($this->statsFilePath);
82 129 }
83 130  
84 131 /*
85 132 * Merge individual User Stats.xml into one generique Stats.xml
86 133 */
87   - public function mergeXml($year) {
  134 + private function _mergeXml($dom, $options) {
88 135 // long procedure
89 136 ini_set('max_execution_time', 600);
90 137  
91 138 $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs);
92 139  
93 140 $userDoc = new DomDocument("1.0");
94   - if ($year == null) $year = date("Y");
  141 + if ($options['year'] == null) $options['year'] = date("Y");
95 142  
96 143 $users=glob(USERPATH."*");
97 144 foreach ($users as $user) {
98   - $userXmlPath = $user."/Stats$year.xml";
  145 + $userXmlPath = $user."/Stats".$options['year'].".xml";
99 146  
100 147 if (!file_exists($userXmlPath)) continue;
101 148  
102 149 $userDoc->load($userXmlPath);
103 150  
104 151 foreach ($allTasks as $task) {
105   - $globalTaskItems = $this->statXml->getElementsByTagName($task);
  152 + $globalTaskItems = $dom->getElementsByTagName($task);
106 153 if ($globalTaskItems->length == 0)
107 154 continue;
108 155 $globalTaskItem = $globalTaskItems->item(0);
... ... @@ -113,7 +160,7 @@ class AmdaStats {
113 160 $userItems = $userTaskItem->getElementsByTagName("item");
114 161 if ($userItems->length > 0) {
115 162 foreach ($userItems as $userItem) {
116   - $globalItem = $this->statXml->importNode($userItem, true);
  163 + $globalItem = $dom->importNode($userItem, true);
117 164 $globalTaskItem->appendChild($globalItem);
118 165 }
119 166 }
... ... @@ -121,98 +168,79 @@ class AmdaStats {
121 168 }
122 169  
123 170 // write task statistics as json
124   - $this->getModulesStat(null,null,true);
  171 + $this->_getModulesStat($dom, array('start' => null, 'stop' => null, 'update' => TRUE));
125 172 // write data statistics as json
126   - $this->getDataStat(0,null,null,true);
  173 + $this->_getDataStat($dom, array('index' => 0, 'start', null, 'stop' => null, 'update' => true));
127 174  
128   - return $this->statXml->save(StatsXml);
  175 + return $dom->save($this->statsFilePath);
129 176 }
130 177  
131   - private function generateXml() {
132   -
133   - $rootElement = $this->statXml->createElement('stats');
134   -
135   - $allTasks = array_merge($this->tasks, $this->tasksAdd, $this->tasksWs);
136   -
137   - foreach ($allTasks as $task) {
138   - $element = $this->statXml->createElement("$task");
139   - $rootElement->appendChild($element);
140   - }
141   -
142   - $this->statXml->appendChild($rootElement);
143   -
144   - return $this->statXml->save(StatsXml);
145   - }
146   -
147   - public function addTask($user, $task, $vars) {
148   -
149   -// if (!$this->user) {
150   -// error_log('User is null', 1, email);
151   -// return;
152   -// }
153   - if ($task == 'killplot')
154   - return;
  178 + private function _addTask($dom, $options) {
  179 + if ($options['task'] == 'killplot')
  180 + return FALSE;
155 181  
156   - if ($vars)
157   - $realTask = $this->task[$task];
  182 + if ($options['vars'])
  183 + $realTask = $this->task[$options['task']];
158 184 else
159   - $realTask = $task;
  185 + $realTask = $options['task'];
160 186  
161   - if (!in_array($user, $this->usersToExclude)) {
162   - $taskElementNode = $this->statXml->getElementsByTagName("$realTask");
  187 + if (!in_array($options['user'], $this->usersToExclude)) {
  188 + $taskElementNode = $dom->getElementsByTagName("$realTask");
163 189  
164 190 if ($taskElementNode->length < 1)
165 191 return;
166 192  
167 193 $taskElement = $taskElementNode->item(0);
168 194 if (is_object($taskElement)) {
169   - $newTask = $this->statXml->createElement('item');
  195 + $newTask = $dom->createElement('item');
170 196 $newTask->setAttribute('date', date('Y-m-d'));
171   - $newTask->setAttribute('user', $user);
  197 + $newTask->setAttribute('user', $options['user']);
172 198  
173   - if ($vars) {
  199 + if ($options['vars']) {
174 200 $ID = array();
175 201  
176   - foreach ($vars as $var) {
  202 + foreach ($options['vars'] as $var) {
177 203 $ID[] = $var;
178 204 }
179 205  
180 206 $ID = array_unique($ID);
181 207  
182 208 foreach ($ID as $id) {
183   - $datasetElement = $this->statXml->createElement('dataset', $id);
  209 + $datasetElement = $dom->createElement('dataset', $id);
184 210 $newTask->appendChild($datasetElement);
185 211 }
186 212 }
187 213  
188 214 $taskElement->appendChild($newTask);
189   - $this->statXml->save(StatsXml);
  215 + return $dom->save($this->statsFilePath);
190 216 }
191 217 else
192   - error_log('Check Stats.xml - no task element '.$task, 1, email);
  218 + error_log('Check Stats.xml - no task element '.$options['task'], 1, email);
193 219 }
  220 +
  221 + return FALSE;
194 222 }
195 223  
196 224 /*
197 225 * Show Statistics
198 226 */
199   - public function getModulesStat($start, $stop, $update){
  227 + private function _getModulesStat($dom, $options){
200 228  
201   - if (!$update && file_exists(DATAPATH.'Statistics/tasks.json')) {
202   - return file_get_contents(DATAPATH.'Statistics/tasks.json');
  229 + if (!$options['update'] && file_exists(DATAPATH.'Statistics/tasks.json')) {
  230 + return file_get_contents(DATAPATH.'Statistics/tasks.json');
203 231 }
204 232  
205 233 $taskArray = array();
206 234  
207 235 foreach (array_merge($this->tasks,$this->tasksAdd, $this->tasksWs) as $task) {
208   - $taskItems = $this->statXml->getElementsByTagName($task);
  236 + $taskItems = $dom->getElementsByTagName($task);
209 237 if ($taskItems->length < 1)
210 238 return;
211 239 $theTask = $taskItems->item(0);
212 240 $items = $theTask->getElementsByTagName('item');
213 241 $hints = $items->length;
214 242  
215   - $startStop = $this->getStartStop($items, $start, $stop);
  243 + $startStop = $this->getStartStop($items, $options['start'], $options['stop']);
216 244  
217 245 $taskArray[] = array('task' => $task, 'number' => $hints,
218 246 'start' => $startStop[0], 'stop' => $startStop[1]);
... ... @@ -228,9 +256,9 @@ class AmdaStats {
228 256 /*
229 257 * Show Statistics
230 258 */
231   - public function getDataStat($index, $start, $stop, $update){
  259 + private function _getDataStat($dom, $options){
232 260  
233   - if (!$update && file_exists(DATAPATH.'Statistics/data.json')) {
  261 + if (!$options['update'] && file_exists(DATAPATH.'Statistics/data.json')) {
234 262 $GENERALarray = json_decode(file_get_contents(DATAPATH.'Statistics/data.json'));
235 263 }
236 264 else {
... ... @@ -243,7 +271,7 @@ class AmdaStats {
243 271 $dataTasks = array_merge($this->tasks, $this->tasksWs);
244 272  
245 273 foreach ($dataTasks as $task) {
246   - $taskItems = $this->statXml->getElementsByTagName($task);
  274 + $taskItems = $dom->getElementsByTagName($task);
247 275 if ($taskItems->length < 1)
248 276 continue;
249 277 $theTask = $taskItems->item(0);
... ... @@ -258,10 +286,15 @@ class AmdaStats {
258 286 foreach ($VIs as $VI) {
259 287 $id = $VI->nodeValue;
260 288 if ($id) {
261   -
  289 + if (!in_array($id, $usersArray)) {
  290 + $usersArray[$id] = array();
  291 + }
  292 + if (!in_array($user, $usersArray[$id])) {
  293 + $usersArray[$id][$user] = 0;
  294 + }
262 295 $usersArray[$id][$user]++;
263 296  
264   - if ($TASKarray[$id]) {
  297 + if (array_key_exists($id, $TASKarray)) {
265 298 $TASKarray[$id]++;
266 299 $TOTALarray[$id]++;
267 300 if ($STARTarray[$id] > $time)
... ... @@ -270,7 +303,7 @@ class AmdaStats {
270 303 $STOParray[$id] = $time;
271 304 }
272 305 else {
273   - if (!$TOTALarray[$id]) {
  306 + if (!array_key_exists($id,$TOTALarray)) {
274 307 $STARTarray[$id] = $time;
275 308 $STOParray[$id] = $time;
276 309 $TOTALarray[$id] = 1;
... ... @@ -298,17 +331,20 @@ class AmdaStats {
298 331 foreach ($TOTALarray as $key => $value) {
299 332 $viStart = $STARTarray[$key];
300 333 $viStop = $STOParray[$key];
301   - $plot = $VIarray['plot'][$key];
302   - $mining = $VIarray['mining'][$key];
303   - $print = $VIarray['print'][$key];
304   - $stat = $VIarray['statistics'][$key];
  334 + $plot = (empty($VIarray['plot']) || empty($VIarray['plot'][$key])) ? 0 : $VIarray['plot'][$key];
  335 + $mining = (empty($VIarray['mining']) || empty($VIarray['mining'][$key])) ? 0 : $VIarray['mining'][$key];
  336 + $print = (empty($VIarray['print']) || empty($VIarray['print'][$key])) ? 0 : $VIarray['print'][$key];
  337 + $stat = (empty($VIarray['statistics']) || empty($VIarray['statistics'][$key])) ? 0 : $VIarray['statistics'][$key];
  338 + $ws_print = (empty($VIarray['ws_print']) || empty($VIarray['ws_print'][$key])) ? 0 : $VIarray['ws_print'][$key];
  339 + $ws_plot = (empty($VIarray['ws_plot']) || empty($VIarray['ws_plot'][$key])) ? 0 : $VIarray['ws_plot'][$key];
305 340 $uniqueUsers = count($usersArray[$key]);
306 341  
307 342 if ($key != 'undefined')
308 343 {
309 344 $GENERALarray[] = array('id' => $key, 'number' => $value, 'percent' => $value,
310 345 'plot' => $plot, 'mining' => $mining,
311   - 'print' => $print,'statistics' => $stat,
  346 + 'print' => $print,'statistics' => $stat,
  347 + 'ws_print' => $ws_print, 'ws_plot' => $ws_plot,
312 348 'start' => $viStart, 'stop' => $viStop, 'unique' => $uniqueUsers);
313 349  
314 350 $Ntotal += $value;
... ... @@ -325,8 +361,8 @@ class AmdaStats {
325 361  
326 362 $Nmax = count($GENERALarray);
327 363  
328   - $length = $index + 20 > $Nmax ? $Nmax - $index + 1 : 20;
329   - $objToReturn = array('stats' => array_reverse(array_slice($GENERALarray, $index, $length)));
  364 + $length = $options['index'] + 20 > $Nmax ? $Nmax - $options['index'] + 1 : 20;
  365 + $objToReturn = array('stats' => array_reverse(array_slice($GENERALarray, $options['index'], $length)));
330 366  
331 367 file_put_contents(DATAPATH.'Statistics/data.json',json_encode($GENERALarray));
332 368  
... ... @@ -355,32 +391,29 @@ class AmdaStats {
355 391 return array(min($date), max($date));
356 392 }
357 393  
358   - public function mergeStats($inXml) {
  394 + private function _mergeStats($dom, $options) {
359 395  
360   - if (!file_exists(StatsXml)) return 0;
361   - if (!file_exists($inXml)) return 0;
  396 + if (!file_exists($options['inXml'])) return 0;
362 397  
363 398 $tags = array_merge($this->tasks,$this->tasksAdd, $this->tasksWs);
364 399  
365   - $doc1 = new DomDocument("1.0");
366 400 $doc2 = new DomDocument("1.0");
367 401  
368   - if (!$doc1->load(StatsXml)) return 0;
369   - if (!$doc2->load($inXml)) return 0;
  402 + if (!$doc2->load($options['inXml'])) return 0;
370 403  
371 404 foreach ($tags as $tag){
372   - $tag1 = $doc1->getElementsByTagName($tag)->item(0);
  405 + $tag1 = $dom->getElementsByTagName($tag)->item(0);
373 406 $tag2 = $doc2->getElementsByTagName($tag)->item(0);
374 407 $items2 = $tag2->getElementsByTagName("item");
375 408 if ($items2->length > 0) {
376 409 foreach ($items2 as $item2) {
377   - $item1 = $doc1->importNode($item2, true);
  410 + $item1 = $dom->importNode($item2, true);
378 411 $tag1->appendChild($item1);
379 412 }
380 413 }
381 414 }
382 415  
383   - return $doc1->save(StatsXml);
  416 + return $dom->save($this->statsFilePath);
384 417 }
385 418 }
386 419 ?>
... ...
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', 'condition');
  12 + protected $types = array('request', 'download', 'condition', 'statistic');
13 13  
14 14 function __construct($type)
15 15 {
... ... @@ -34,6 +34,14 @@ class RequestMgr extends AmdaObjectMgr
34 34 {
35 35 $this->id_prefix = 'req_';
36 36 }
  37 + else if ($type == 'download' )
  38 + {
  39 + $this->id_prefix = 'down_';
  40 + }
  41 + else if ($type == 'statistic')
  42 + {
  43 + $this->id_prefix = 'stat_';
  44 + }
37 45 else
38 46 {
39 47 $this->id_prefix = 'cond_';
... ... @@ -173,17 +181,14 @@ class RequestMgr extends AmdaObjectMgr
173 181 if ($this->type == 'condition')
174 182 {
175 183 $p->expression = $this->resetAlias($p->expression);
176   - $info = $p->expression;
177 184 }
178 185 else if ($this->type == 'request')
179 186 {
180   - $info = '';
181 187 for ($i=0; $i < count($p->children); $i++)
182 188 {
183 189 for ($j=0; $j < count($p->children[$i]->children); $j++)
184 190 {
185 191 $p->children[$i]->children[$j]->name = $this->resetAlias($p->children[$i]->children[$j]->name);
186   - $info = $info.' '.$p->children[$i]->children[$j]->name;
187 192 }
188 193 }
189 194 }
... ... @@ -201,7 +206,7 @@ class RequestMgr extends AmdaObjectMgr
201 206  
202 207 $this -> addToContent($p, $folder);
203 208  
204   - return array('id' => $this->id, 'info' => $info, 'last_update' => $p->last_update) + $additional;
  209 + return array('id' => $this->id, 'info' => $this->getObjectInfo($p->id), 'last_update' => $p->last_update) + $additional;
205 210 }
206 211  
207 212 public static function checkRequest($obj)
... ... @@ -297,7 +302,7 @@ class RequestMgr extends AmdaObjectMgr
297 302 if (count($argsTab) > 0) $args[] = $argsTab;
298 303  
299 304 break;
300   - case 'statistics' :
  305 + case 'statistic' :
301 306 return array('success' => true);
302 307 break;
303 308 default :
... ... @@ -351,5 +356,113 @@ class RequestMgr extends AmdaObjectMgr
351 356  
352 357 return array('success' => true);
353 358 }
  359 +
  360 + public function getObjectInfo($id) {
  361 + $info = "Request ID: ".$id."<br/>";
  362 +
  363 + if (!file_exists(USERREQDIR.$id)) {
  364 + $info .= "<b>ERROR:</b> Cannot retrieve request definition file";
  365 + return $info;
  366 + }
  367 +
  368 + $obj = json_decode(file_get_contents(USERREQDIR.$id));
  369 + if (empty($obj)) {
  370 + $info .= "<b>ERROR:</b> Cannot load request definition file";
  371 + return $info;
  372 + }
  373 +
  374 + switch ($this->type) {
  375 + case 'request':
  376 + $info .= "Plot: ";
  377 + $panels_list = array();
  378 + if (!empty($obj->panels)) {
  379 + foreach ($obj->panels as $p) {
  380 + $panel_info = "Panel #".$p->{"panel-index"}.": ";
  381 + if (empty($p->params)) {
  382 + $panel_info .= "Empty";
  383 + }
  384 + else {
  385 + $params_list = array();
  386 + if (!empty($p->params)) {
  387 + foreach ($p->params as $p) {
  388 + if (!in_array($p->paramid, $params_list))
  389 + $params_list[] = $p->paramid;
  390 + }
  391 + }
  392 + if (!empty($params_list)) {
  393 + $panel_info .= implode(', ', $params_list);
  394 + }
  395 + else {
  396 + $panel_info .= "Empty";
  397 + }
  398 + }
  399 + $panels_list[] = $panel_info;
  400 + }
  401 + }
  402 + if (!empty($panels_list)) {
  403 + $info .= '<br/>'.implode('<br/>', $panels_list);
  404 + }
  405 + else {
  406 + $info .= "Empty";
  407 + }
  408 + break;
  409 + case 'condition':
  410 + $info .= "Data Mining: ".htmlspecialchars($obj->expression);
  411 + break;
  412 + case 'download':
  413 + $info .= "Download: ";
  414 + $params_list = array();
  415 + if (!empty($obj->list)) {
  416 + foreach ($obj->list as $p) {
  417 + if (!in_array($p->paramid, $params_list))
  418 + $params_list[] = $p->paramid;
  419 + }
  420 + }
  421 + if (!empty($params_list)) {
  422 + $info .= implode(', ',$params_list);
  423 + }
  424 + else {
  425 + $info .= "Empty";
  426 + }
  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;
  454 + default:
  455 + $info .= "<b>ERROR:</b> Unknown request type";
  456 + }
  457 +
  458 + return $info;
  459 + }
  460 +
  461 + function modifyObject($p)
  462 + {
  463 + $result = parent::modifyObject($p);
  464 + $result["info"] = $this->getObjectInfo($p->id);
  465 + return $result;
  466 + }
354 467 }
355 468 ?>
... ...
php/classes/TimeTableMgr.php
... ... @@ -87,10 +87,29 @@ class TimeTableMgr extends AmdaObjectMgr
87 87 if ($attribute->tagName != 'intervals') {
88 88 $attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
89 89 } else {
90   - $nbInt++;
  90 +
  91 + // get 'surveyStart' and
  92 + if($attributesToReturn['surveyStart'] == "" || $attributesToReturn['surveyStop'] == "" ){
  93 + if($nbInt == 0){
  94 + foreach ($attribute->childNodes as $ch ){
  95 + if($ch->tagName == 'start') $start = $ch->nodeValue;
  96 + if($ch->tagName == 'stop') $stop = $ch->nodeValue;
  97 + }
  98 + }else{
  99 + foreach ($attribute->childNodes as $ch ){
  100 + if($ch->tagName == 'start' && $start > $ch->nodeValue) $start = $ch->nodeValue;
  101 + if($ch->tagName == 'stop' && $stop < $ch->nodeValue) $stop = $ch->nodeValue;
  102 + }
  103 + }
  104 + }
  105 + $nbInt++;
91 106 }
92 107 }
93 108 }
  109 + if($attributesToReturn['surveyStart'] == "")
  110 + $attributesToReturn['surveyStart'] = $start;
  111 + if($attributesToReturn['surveyStop'] == "" )
  112 + $attributesToReturn['surveyStop'] = $stop;
94 113 $attributesToReturn['nbIntervals'] = $nbInt;
95 114  
96 115 return $attributesToReturn;
... ... @@ -359,7 +378,7 @@ class TimeTableMgr extends AmdaObjectMgr
359 378  
360 379 $intervals = 0;
361 380 for ($iId = 0; $iId < count($obj->ids); $iId++) {
362   - $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]);
  381 + $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
363 382 for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
364 383 $interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
365 384 $interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
... ... @@ -559,7 +578,7 @@ class TimeTableMgr extends AmdaObjectMgr
559 578 {
560 579 $intervals = 0;
561 580 for ($iId = 0; $iId < count($obj->ids); $iId++) {
562   - $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]);
  581 + $table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
563 582 for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
564 583 $interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
565 584 $interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
... ...