Commit 2ac8da6ca9b6e28203831fcbaddfc16c7609ce78
Exists in
master
and in
110 other branches
Merge branch 'master' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM
Showing
4 changed files
with
1920 additions
and
1826 deletions
Show diff stats
js/.eslintrc.yml
... | ... | @@ -10,6 +10,11 @@ rules: |
10 | 10 | semi: [error, always] |
11 | 11 | max-len: [error, code: 120] |
12 | 12 | max-lines: [warn, 600] |
13 | + max-params: [warn, 3] | |
14 | + complexity: [warn, 20] | |
15 | + no-ternary: off | |
16 | + no-plusplus: off | |
17 | + multiline-ternary: off | |
13 | 18 | linebreak-style: [error, unix] |
14 | 19 | quotes: [error, single] |
15 | 20 | strict: [error, global] |
... | ... | @@ -26,6 +31,9 @@ rules: |
26 | 31 | id-length: off |
27 | 32 | no-magic-numbers: off |
28 | 33 | no-invalid-this: off |
34 | + no-extra-parens: [error, all, nestedBinaryExpressions: false] | |
35 | + camelcase: warn | |
36 | + max-depth: warn | |
29 | 37 | |
30 | 38 | # ES3/5 compatibility: |
31 | 39 | prefer-template: off |
... | ... | @@ -33,3 +41,4 @@ rules: |
33 | 41 | prefer-arrow-callback: off |
34 | 42 | object-shorthand: off |
35 | 43 | prefer-rest-params: off |
44 | + prefer-destructuring: off | |
... | ... |
js/app/models/AmdaNode.js
js/app/models/InteractiveNode.js
1 | -/** | |
1 | +/** | |
2 | 2 | * Project : AMDA-NG4 |
3 | 3 | * Name : InteractiveNode.js |
4 | 4 | * @class amdaModel.InteractiveNode |
... | ... | @@ -8,760 +8,881 @@ |
8 | 8 | * @version $Id: InteractiveNode.js 2683 2014-12-02 10:58:53Z elena $ |
9 | 9 | */ |
10 | 10 | |
11 | +/* global amdaUI, AmdaAction, myDesktopApp, amdaPlotObj, amdaModel*/ | |
12 | + | |
11 | 13 | Ext.define('amdaModel.InteractiveNode', { |
12 | - extend: 'amdaModel.AmdaNode', | |
13 | - | |
14 | - requires: [ | |
15 | - 'amdaPlotObj.PlotRequestObject' | |
16 | - ], | |
17 | - | |
18 | - fields: [ | |
19 | - {name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false}, | |
20 | - {name: 'objectDataModel', type: 'string', persist: false}, | |
21 | - {name: 'object', type: 'object', persist: false}, | |
22 | - {name: 'moduleId', type: 'string', persist: false}, | |
23 | - {name: 'filtered', type: 'boolean', defaultValue: false, persist: false}, | |
24 | - {name: 'disable', type: 'boolean', defaultValue: false, persist: false} | |
25 | - ], | |
26 | - | |
27 | - statics: { | |
28 | - preloadNodes : function(node,onready) | |
29 | - { | |
30 | - var me = this; | |
31 | - | |
32 | - var nodesToLoad = new Array(); | |
33 | - nodesToLoad.push(node); | |
34 | - this.preloadTreeNode(node, nodesToLoad, function (node) | |
35 | - { | |
36 | - var isFinish = true; | |
37 | - nodesToLoad.forEach(function (element, index, array) | |
38 | - { | |
39 | - if (!element.isLoaded()) | |
40 | - isFinish = false; | |
41 | - }); | |
42 | - if (isFinish && onready) | |
43 | - onready.call(); | |
44 | - }); | |
45 | - }, | |
46 | - | |
47 | - preloadTreeNode : function(node, nodesToLoad, onloaded) | |
48 | - { | |
49 | - var me = this; | |
50 | - | |
51 | - if (node.isLoaded()) | |
52 | - { | |
53 | - node.eachChild(function(n) | |
54 | - { | |
55 | - if (!n.isLoaded() && !n.isLeaf()) | |
56 | - { | |
57 | - nodesToLoad.push(n); | |
58 | - me.preloadTreeNode(n,nodesToLoad,onloaded); | |
59 | - } | |
60 | - }); | |
61 | - | |
62 | - if (onloaded) | |
63 | - onloaded.call(me,node); | |
64 | - return; | |
65 | - } | |
66 | - | |
67 | - node.store.load({ | |
68 | - node : node, | |
69 | - callback : function(records, operation, successful) | |
70 | - { | |
71 | - records.forEach(function (record) | |
72 | - { | |
73 | - if (!record.isLoaded() && !record.isLeaf()) | |
74 | - { | |
75 | - nodesToLoad.push(record); | |
76 | - me.preloadTreeNode(record,nodesToLoad,onloaded); | |
77 | - } | |
78 | - }); | |
79 | - if (onloaded) | |
80 | - onloaded.call(me,node); | |
81 | - } | |
82 | - }); | |
83 | - } | |
84 | - }, | |
85 | - | |
86 | - onReady : null, | |
87 | - | |
88 | - constructor : function(config) | |
89 | - { | |
90 | - this.callParent(arguments); | |
91 | - this.set('nodeType',this.self.nodeType); | |
92 | - this.set('ownerTreeId',amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
93 | - if (this.get('id')) { // TODO why sometimes (delete in remote interoper tree) this.get('id') = undefined ? | |
94 | - // if id of this node have root category suffix | |
95 | - if (Ext.util.Format.substr(this.get('id'), -(amdaUI.ExplorerUI.CAT_SUFFIX.length), this.get('id').length) === amdaUI.ExplorerUI.CAT_SUFFIX) | |
96 | - { | |
97 | - // set the expanded property to true | |
98 | - this.set('expanded',true); | |
99 | - } | |
100 | - } | |
101 | - }, | |
102 | - | |
103 | -/** | |
104 | -* this method is overriden into ExecutableNode to return true | |
105 | -*/ | |
106 | - isExecutable: function() | |
107 | - { | |
108 | - return false; | |
109 | - }, | |
14 | + extend: 'amdaModel.AmdaNode', | |
110 | 15 | |
111 | -/** | |
112 | -* open Module with THIS NODE | |
113 | -*/ | |
114 | - editInModule : function (contextNode, onReady) | |
115 | - { | |
116 | - // set the contextNode of this node | |
117 | - this.set('contextNode',contextNode); | |
118 | - // parameter module | |
119 | - var me = this; | |
120 | - myDesktopApp.getLoadedModule(this.get('moduleId'),true, function (module) { | |
121 | - // If the node to edit is not already linked to this module | |
122 | - if (module.getLinkedNode() != me) | |
123 | - { | |
124 | - // set relative node into parameter Module | |
125 | - module.setLinkedNode(me); | |
126 | - if (contextNode==null) | |
127 | - { | |
128 | - // set the root node as contextNode | |
129 | - contextNode = me.getRootNode(); | |
130 | - } | |
131 | - module.setContextNode(contextNode); | |
132 | - | |
133 | - } else if (module.getLinkedNode() != null){ | |
134 | - //TODO the node to edit is already edited | |
135 | - // myDesktopApp.warningMsg('This object is being edited'); | |
136 | - //Sol1: msg alert: "warning this node is already edited! If you want to get the original, please press the 'reset' button"->'OK' | |
137 | - //Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your modification?"->'Confirm','Cancel' | |
138 | - } | |
139 | - // Opening parameter window | |
140 | - module.createWindow(onReady); | |
141 | - }); | |
142 | - }, | |
16 | + requires: ['amdaPlotObj.PlotRequestObject'], | |
17 | + | |
18 | + fields: [ | |
19 | + { | |
20 | + name: 'contextNode', | |
21 | + type: 'amdaModel.AmdaNode', | |
22 | + persist: false | |
23 | + }, | |
24 | + { | |
25 | + name: 'objectDataModel', | |
26 | + type: 'string', | |
27 | + persist: false | |
28 | + }, | |
29 | + { | |
30 | + name: 'object', | |
31 | + type: 'object', | |
32 | + persist: false | |
33 | + }, | |
34 | + { | |
35 | + name: 'moduleId', | |
36 | + type: 'string', | |
37 | + persist: false | |
38 | + }, | |
39 | + { | |
40 | + name: 'filtered', | |
41 | + type: 'boolean', | |
42 | + defaultValue: false, | |
43 | + persist: false | |
44 | + }, | |
45 | + { | |
46 | + name: 'disable', | |
47 | + type: 'boolean', | |
48 | + defaultValue: false, | |
49 | + persist: false | |
50 | + } | |
51 | + ], | |
143 | 52 | |
144 | -/** | |
145 | -* Method to rename the workspace node | |
146 | -*/ | |
147 | - rename: function(value,callBackFn) | |
148 | - { | |
149 | - var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value, parent : this.parentNode.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')}; | |
150 | - AmdaAction.renameObject(dataToSend, callBackFn); | |
151 | - }, | |
152 | - | |
153 | -/** | |
154 | -* Method to rename the workspace node when D&D | |
155 | -*/ | |
156 | - renameDD: function(parentId, callBackFn) | |
157 | - { | |
158 | - var dataToSend = {id : this.get('id'), old_name: this.get('name'), name: this.get('name'), parent : parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')}; | |
159 | - AmdaAction.renameObject(dataToSend, callBackFn); | |
160 | - }, | |
161 | - | |
162 | -/** | |
163 | -* validation method on name (used in module forms) | |
164 | -* @param name the name to validate | |
165 | -* @returns | |
166 | -*/ | |
167 | - isValidName : function(name, callBackFn) | |
168 | - { | |
169 | - var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isLeaf()}; | |
170 | - AmdaAction.validNameObject(dataToSend, callBackFn); | |
171 | - }, | |
53 | + statics: { | |
54 | + preloadNodes: function (node, onready) { | |
55 | + var nodesToLoad; | |
172 | 56 | |
173 | -/** | |
174 | -* Method to persist modifications of an AmdaObject by Server side and update the workspace | |
175 | -* node linked to a Module | |
176 | -*/ | |
177 | - update : function(opt) | |
178 | - { | |
179 | - AmdaAction.modifyObject(this.get('object').getJsonValues(true), function(res,e){ | |
180 | - | |
181 | - if(e.status) { | |
182 | - if (res.id) { | |
183 | - if (!this.get('contextNode')) { | |
184 | - // set the root node of 'Derived Parameters' tree as contextNode | |
185 | - this.set('contextNode',this.getRootNode()); | |
186 | - } | |
187 | - this.get('contextNode').expand(false,false); | |
188 | - this.myGetOwnerTree().getSelectionModel().select(this); | |
189 | - | |
190 | - if (opt) | |
191 | - { | |
192 | - var scope = opt.scope ? opt.scope : this; | |
193 | - if (opt.callback) | |
194 | - opt.callback.call(scope,'update'); | |
195 | - } | |
196 | - | |
197 | - Ext.Msg.alert('Complete', 'Object '+this.get('object').get('name')+' has been modified'); | |
198 | - // fix the modifications for object | |
199 | - this.get('object').commit(); | |
200 | - | |
201 | - if (res.info) { | |
202 | - this.set('info',res.info); | |
203 | - } | |
204 | - | |
205 | - // myDataParam special update | |
206 | - this.specialUpdate(res, false); | |
207 | - | |
208 | - // reload object into the view of corresponding Module | |
209 | - var me = this; | |
210 | - myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { | |
211 | - module.getUiContent().setObject(me.get('object')); | |
212 | - }); | |
213 | - } | |
214 | - else { | |
215 | - //TODO proper error message handling | |
216 | - // error code from server; but e.status==true | |
217 | - // revert all modifications since last load or commit | |
218 | - this.get('object').reject(); | |
219 | - myDesktopApp.errorMsg(res.error); | |
220 | - } | |
221 | - } | |
222 | - else { | |
223 | - // revert all modifications since last load or commit | |
224 | - this.get('object').reject(); | |
225 | - myDesktopApp.errorMsg(e.message); | |
226 | - } | |
227 | - },this); | |
228 | - }, | |
57 | + nodesToLoad = []; | |
58 | + nodesToLoad.push(node); | |
59 | + this.preloadTreeNode(node, nodesToLoad, function () { | |
60 | + var isFinish = true; | |
61 | + nodesToLoad.forEach(function (element) { | |
62 | + if (!element.isLoaded()) { | |
63 | + isFinish = false; | |
64 | + } | |
65 | + }); | |
66 | + if (isFinish && onready) { | |
67 | + onready.call(); | |
68 | + } | |
69 | + }); | |
70 | + }, | |
229 | 71 | |
230 | -/** | |
231 | -* Method to create a new AmdaObject by server side and create the workspace node linked to a Module | |
232 | -* under its contextNode or the root node corresponding to this nodeType category | |
233 | -*/ | |
234 | - create : function(opt) | |
235 | - { | |
236 | - if (!this.get('contextNode') || (this.get('contextNode').data.id == 'sharedtimeTable-treeRootNode') || (this.get('contextNode').data.id == 'sharedcatalog-treeRootNode')) { | |
237 | - // set the root node of 'Derived Parameters' tree as contextNode | |
238 | - this.set('contextNode',this.getRootNode()); | |
239 | - } | |
240 | - // call the Ext.Direct method to create parameter | |
241 | - AmdaAction.createObject(this.get('object').getJsonValues(false), this.get('contextNode').get('id'), function(res,e){ | |
242 | - //success | |
243 | - if(e.status) | |
244 | - { | |
245 | - // if correct response received | |
246 | - if (res.id) { //if (res.id || res.error == 'NAME_EXISTS') { | |
247 | - // 'save as' case ; delete old node if it exists | |
248 | - if (this.toRename) | |
249 | - { | |
250 | - this.toRename = false; | |
251 | - var myRoot = this.getRootNode(); | |
252 | - // search the same named node to override | |
253 | - var updateNode = myRoot.findChild('text',this.get('object').get('name'),true); | |
254 | - // destroy the overrided node | |
255 | - updateNode.parentNode.removeChild(updateNode);//TODO ??if destroy==true => too many recursions.... | |
256 | - updateNode.destroy(); | |
257 | - } | |
258 | - // set text of this node | |
259 | - this.set('text',this.get('object').get('name')); | |
260 | - //set id of this node | |
261 | - this.set('id',res.id); | |
262 | - this.internalId = res.id; | |
263 | - // set id of node's object | |
264 | - this.get('object').set('id',res.id); | |
265 | - | |
266 | - if (res.created){ | |
267 | - // set the created date | |
268 | - this.get('object').set('created',res.created); | |
269 | - } | |
270 | - | |
271 | - if (res.info){ | |
272 | - // set the tooltip | |
273 | - this.set('info',res.info); | |
274 | - } | |
275 | - //set globalStart & global Stop to be used for time selection | |
276 | - this.specialUpdate(res, true); | |
277 | - | |
278 | - //TODO do we need this commission ??? | |
279 | - // fix the modifications for object | |
280 | - this.get('object').commit(); | |
281 | - // if ownerTree panel is not active | |
282 | - if (this.myGetOwnerTree().ownerCt.getActiveTab()!==this.myGetOwnerTree()) | |
283 | - { | |
284 | - // set ownerTree panel as the active tab - to enable selection of this node his ownerTree must have a view | |
285 | - this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree()); | |
286 | - } | |
287 | - | |
288 | - Ext.Msg.alert('Complete', 'New object '+this.get('object').get('name')+' has been created'); | |
289 | - // expand the contextNode | |
290 | - this.get('contextNode').expand(false, function() | |
291 | - { | |
292 | - if (!this.get('contextNode').findChild('text',this.get('text'))) { | |
293 | - // create node in tree as child of contextNode | |
294 | - this.get('contextNode').appendChild(this); | |
295 | - } | |
296 | - // select the new node | |
297 | - this.myGetOwnerTree().getSelectionModel().select(this); | |
298 | - if (opt) | |
299 | - { | |
300 | - var scope = opt.scope ? opt.scope : this; | |
301 | - if (opt.callback) | |
302 | - opt.callback.call(scope,'create'); | |
303 | - } | |
304 | - }, this); | |
305 | - } | |
306 | - // error code from server; but e.status==true | |
307 | - else { | |
308 | - myDesktopApp.errorMsg(res.error); | |
309 | - // revert all modifications since last load or commit | |
310 | - this.get('object').reject(); | |
311 | - } | |
312 | - } | |
313 | - // failure: e.status == false | |
314 | - else { | |
315 | - // revert all modifications since last load or commit | |
316 | - this.get('object').reject(); | |
317 | - //TODO: this.destroy(); | |
318 | - myDesktopApp.errorMsg(e.message); | |
319 | - } | |
320 | - },this); | |
321 | - }, | |
322 | - | |
323 | - specialUpdate : function() {}, | |
324 | -/** | |
325 | -* Generic part of Context Menu | |
326 | -* | |
327 | -*/ | |
328 | - allMenuItems : function() { | |
329 | - var src = this.self.objectName; | |
330 | - var menuItems = | |
331 | - [ { | |
332 | - fnId : 'root-createLeaf', | |
333 | - text : 'Create '+ src | |
334 | - }, { | |
335 | - fnId : 'root-createDir', | |
336 | - text : 'Create Folder' | |
337 | - }, { | |
338 | - fnId : 'dire-createLeaf', | |
339 | - text : 'Create ' + src | |
340 | - }, { | |
341 | - fnId : 'dire-createDir', | |
342 | - text : 'Create Folder' | |
343 | - }, { | |
344 | - fnId : 'dire-renameNode', | |
345 | - text : 'Rename Folder' | |
346 | - }, { | |
347 | - fnId : 'dire-deleteNode', | |
348 | - text : 'Delete Folder' | |
349 | - }, { | |
350 | - fnId : 'leaf-editLeaf', | |
351 | - text : 'Edit ' + src | |
352 | - }, { | |
353 | - fnId : 'leaf-renameNode', | |
354 | - text : 'Rename ' + src | |
355 | - }, { | |
356 | - fnId : 'leaf-deleteNode', | |
357 | - text : 'Delete '+ src | |
358 | - } ]; | |
359 | - return menuItems; | |
360 | - }, | |
361 | - | |
362 | - allMenuMultiItems : function() { | |
363 | - var menuMulti = [ | |
364 | - { | |
365 | - fnId : 'mult-deleteMulti', | |
366 | - text : 'Delete selected ' + this.self.objectName + 's' | |
367 | - } | |
368 | - ]; | |
369 | - return menuMulti; | |
370 | - }, | |
371 | - | |
372 | - getAllContextMenuItems: function(){ | |
373 | - return this.allMenuItems(); | |
374 | - }, | |
375 | - | |
376 | - getMultiContextMenuItems: function(){ | |
377 | - return this.allMenuMultiItems(); | |
378 | - }, | |
379 | - | |
380 | -/** | |
381 | -* default implementation | |
382 | -* no menu display if there's no override of this function | |
383 | -*/ | |
384 | - getMultiContextMenuItems: function(){ | |
385 | - return null; | |
386 | - }, | |
387 | - | |
388 | -/** | |
389 | -* Context Menu Actions | |
390 | -* | |
391 | -*/ | |
392 | - onMenuItemClick : function(menu,item,event) { | |
393 | - // fnId parsing : | |
394 | - var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); | |
395 | - | |
396 | - switch (fnId) { | |
397 | - case 'deleteNode': | |
398 | - this.deleteNode(); | |
399 | - break; | |
400 | - case 'createDir': | |
401 | - this.createDir(); | |
402 | - break; | |
403 | - case 'createLeaf': | |
404 | - this.createLeaf(this); | |
405 | - break; | |
406 | - case 'renameNode': | |
407 | - this.renameNode(); | |
408 | - break; | |
409 | - case 'editLeaf': | |
410 | - this.editLeaf(); | |
411 | - break; | |
412 | - case 'deleteMulti': | |
413 | - this.deleteMulti(); | |
414 | - break; | |
415 | - case 'plotParam': | |
416 | - this.createPlot(this); | |
417 | - break; | |
418 | - case 'downParam': | |
419 | - this.createDownload(this); | |
420 | - break; | |
421 | - default: | |
422 | - break; | |
423 | - } // switch end | |
424 | - }, | |
425 | - | |
426 | - getTimeFromNode: function(node) { | |
427 | - var startString = new String(node.get('globalStart')); | |
428 | - var stopString = new String(node.get('globalStop')); | |
429 | - | |
430 | - var startDate = new Date(startString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | |
431 | - var stopDate = new Date(stopString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | |
432 | - | |
433 | - if (stopDate - startDate > 86400000 ) { | |
434 | - var startTime = Ext.Date.add(stopDate, Ext.Date.DAY, -1); | |
435 | - // var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s')}; | |
436 | - var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d'), stop: Ext.Date.format(stopDate, 'Y/m/d')}; | |
437 | - } | |
438 | - else { | |
439 | - var timeObj = {start: node.get('globalStart'), stop: node.get('globalStop')}; | |
440 | - } | |
441 | - return timeObj; | |
442 | - }, | |
443 | - | |
444 | - createPlot: function(node) | |
445 | - { | |
446 | - if (node.get('disable')) return; | |
447 | - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) { | |
448 | - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.plot.id)) { | |
449 | - var request = Ext.create(amdaPlotObj.PlotRequestObject.$className); | |
450 | - var newNode = Ext.create(amdaModel.PlotNode.$className, { object : request }); | |
451 | - // edit newNode into Plot Module with node as contextNode | |
452 | - newNode.editInModule(); | |
453 | - if((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | |
454 | - module.getUiContent().setTimeFromData(node.getTimeFromNode(node)); | |
455 | - } | |
456 | - } | |
457 | - module.getUiContent().addParameter(node); | |
458 | - }); | |
459 | - }, | |
460 | - | |
461 | - createDownload: function(node) | |
462 | - { | |
463 | - if (node.get('disable')) return; | |
464 | - | |
465 | - if (node.get('notyet')) { | |
466 | - myDesktopApp.warningMsg('Sorry! access to this parameter is restricted.'); | |
467 | - return; | |
468 | - } | |
469 | - | |
470 | - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) { | |
471 | - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.download.id)) { | |
472 | - var request = Ext.create(amdaModel.Download.$className); | |
473 | - amdaModel.DownloadNode.set('object',request); | |
474 | - // singleton! | |
475 | - amdaModel.DownloadNode.editInModule(); | |
476 | - if ((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | |
477 | - module.getUiContent().setTimeFromData(node.getTimeFromNode(node)); | |
478 | - } | |
479 | - } | |
480 | - var paramName; | |
481 | - var components = null; | |
482 | - switch (node.$className) { | |
483 | - case 'amdaModel.AliasNode' : | |
484 | - paramName = "#"+node.get('text'); | |
485 | - break; | |
486 | - case 'amdaModel.DerivedParamNode' : | |
487 | - paramName = "ws_"+node.get('text'); | |
488 | - break; | |
489 | - case 'amdaModel.MyDataParamNode' : | |
490 | - paramName = 'wsd_'+node.get('text'); | |
491 | - break; | |
492 | - default : | |
493 | - if (node.get('alias')!= "" ) | |
494 | - paramName = "#"+node.get('alias'); | |
495 | - else | |
496 | - paramName = node.get('id'); | |
497 | - } | |
498 | -// var component_info = node.get('component_info'); | |
499 | -// if (component_info && component_info.parentId) { | |
500 | -// //It's a component | |
501 | -// paramName = component_info.parentId; | |
502 | -// components = []; | |
503 | -// if (component_info.index1) | |
504 | -// components['index1'] = component_info.index1; | |
505 | -// if (component_info.index2) | |
506 | -// components['index2'] = component_info.index2; | |
507 | -// } | |
508 | - module.addParam(paramName,true,node.get('needsArgs'),components); | |
509 | - }); | |
510 | - }, | |
511 | - | |
512 | - deleteNode: function() { | |
513 | - // if the target is a directory | |
514 | - if (!this.isLeaf()) { | |
515 | - // determine if this directory is empty before launching the delete confirmation method | |
516 | - this.isNotEmptyDir(this.confirmDirectoryDeletion); | |
517 | - // else (the target is a leaf) | |
518 | - } else { | |
519 | - // no confirmation prompt for leaves | |
520 | - this.confirmDirectoryDeletion(false); | |
521 | - } | |
522 | - }, | |
523 | - | |
524 | -/** | |
525 | -* this method return if node has Childs even if it was not already loaded | |
526 | -*/ | |
527 | - isNotEmptyDir : function(callbackFn) { | |
528 | - var hasChilds; | |
529 | - // if node not already loaded | |
530 | - if (!this.isLoaded()){ | |
531 | - // call directFunction to load this node | |
532 | - AmdaAction.getTree({node:this.get('id'),nodeType:this.get('nodeType')},function(res,e){ | |
533 | - callbackFn.call(this,res.length>0?true:false); | |
534 | - },this); | |
535 | - } | |
536 | - else { | |
537 | - callbackFn.call(this,this.hasChildNodes()); | |
538 | - } | |
539 | - }, | |
540 | - | |
541 | -/** | |
542 | -* this method is used to display a confirmation message | |
543 | -*/ | |
544 | - confirmDirectoryDeletion : function(isNotEmptyDir) | |
545 | - { | |
546 | - // if this is a non-empty directory | |
547 | - if (isNotEmptyDir) { | |
548 | - // Prompt to the user if he also wants to delete its content | |
549 | - Ext.Msg.confirm('non-empty directory', 'The target is a non-empty directory!<br>Do you want to continue and also delete its content?', function(btn, text){ | |
550 | - if (btn == 'yes'){ | |
551 | - // do delete | |
552 | - this.realDelete(); | |
553 | - } | |
554 | - },this); | |
555 | - } | |
556 | - else { | |
557 | - this.realDelete(); | |
558 | - } | |
559 | - }, | |
560 | - | |
561 | -/* | |
562 | -* Call the extDirect method to delete parameter | |
563 | -* Callback method needed to execute node deletion in tree if id in result or to show error msg | |
564 | -*/ | |
565 | - realDelete : function() | |
566 | - { | |
567 | - AmdaAction.deleteObject({id: this.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')}, function(res,e){ | |
568 | - //TODO proper errors handling | |
569 | - // node deletion in tree | |
570 | - if (res) { // if success | |
571 | - if (res.id) { | |
572 | - //Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK}); | |
573 | - if (this.parentNode) { | |
574 | - if (this.isLeaf()){ | |
575 | - var moduleId = this.get('moduleId'); | |
576 | - // if really interactive node | |
577 | - if (moduleId) { | |
578 | - var me = this; | |
579 | - myDesktopApp.getLoadedModule(moduleId, true, function (module) { | |
580 | - var editedNode = module.getLinkedNode(); | |
581 | - // file node is not linked directly to the module | |
582 | - var isThisFile = false; | |
583 | - | |
584 | - if (editedNode && editedNode.$className == 'amdaModel.MyDataParamNode') | |
585 | - if (editedNode.get('fileObject').get('fileName') == me.get('text')) | |
586 | - isThisFile = true; | |
587 | - | |
588 | - if (me.$className == 'amdaModel.DerivedParamNode') | |
589 | - { | |
590 | - var obj = { | |
591 | - paramId : 'ws_'+me.get('text') | |
592 | - }; | |
593 | - AmdaAction.compilParamDelete(obj); | |
594 | - } | |
595 | - | |
596 | - if (editedNode === me || isThisFile){ | |
597 | - var newNode = Ext.ModelManager.create({leaf : true}, me.$className); | |
598 | - // several tabs could be connected to one node | |
599 | - if (moduleId === myDesktopApp.dynamicModules.plot.id) { | |
600 | - var linkedNodes = module.linkedNodes; | |
601 | - | |
602 | - if (linkedNodes) { | |
603 | - linkedNodes.each(function(key, value){ | |
604 | - if (value === me) { | |
605 | - linkedNodes.replace(key,newNode); | |
606 | - var tabPanel = module.getUiContent().tabPanel.items.getByKey(key); | |
607 | - tabPanel.setObject(Ext.create(amdaModel.Plot.$className, {})); | |
608 | - } | |
609 | - }, me); | |
610 | - } | |
611 | - } | |
612 | - newNode.editInModule(); | |
613 | - } | |
614 | - }); | |
615 | - } | |
616 | - } | |
617 | - //update mask info in myData | |
618 | - if (res.maskDesc && !res.maskDeleted) { | |
619 | - this.parentNode.set('info', res.maskDesc); | |
620 | - this.updateMyDataParam(res.mask, res.maskDesc); | |
621 | - } | |
622 | - this.remove(); | |
623 | - } | |
624 | - //TODO Several special node-dependent actions - to move to node functions.. | |
625 | - // nodes of another nodeType to be deleted as they depend on deleted node | |
626 | - if (res.params) { | |
627 | - this.deleteDependence(res.params); | |
628 | - //TODO reset | |
629 | - } | |
630 | - // mask was deleted or updated - to update mydata tree | |
631 | - if (res.maskDeleted) { | |
632 | - this.updateMyData(); | |
633 | - } | |
634 | - } | |
635 | - else { | |
636 | - myDesktopApp.warningMsg(res.error); | |
637 | - } | |
638 | - } | |
639 | - else { | |
640 | - myDesktopApp.errorMsg(e.message); | |
641 | - } | |
642 | - }, this); | |
643 | - }, | |
644 | - | |
645 | -/* | |
646 | -* Delete musti selection | |
647 | -*/ | |
648 | - deleteMulti: function() | |
649 | - { | |
650 | - var selection = this.myGetOwnerTree().getSelectionModel().selected.items; | |
651 | - alert(selection.length +' to delete!'); | |
652 | - Ext.Array.each(selection,function(item,index,allItems){ | |
653 | - item.deleteNode(); | |
654 | - }) | |
655 | - }, | |
656 | - | |
657 | -/* | |
658 | -* Create Folder | |
659 | -*/ | |
660 | - createDir: function() { | |
661 | - var me = this; | |
662 | - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), | |
663 | - function() | |
664 | - { | |
665 | - var newNode = Ext.create(me.$className, | |
666 | - { | |
667 | - leaf : false, nodeType : me.get('nodeType'), | |
668 | - text : amdaModel.AmdaNode.NEW_DIR_NAME, | |
669 | - children : [] | |
670 | - }); | |
671 | - | |
672 | - // insert the new node as a child of node | |
673 | - newNode = me.insertChild(0, newNode); | |
674 | - // start text edition on this new directory node | |
675 | - me.expand(false); | |
676 | - newNode.expand(false); | |
677 | - | |
678 | - // select the new node | |
679 | - me.myGetOwnerTree().getSelectionModel().select(newNode); | |
680 | - // call the renameNode method for this new node | |
681 | - newNode.renameNode(); | |
682 | - }); | |
683 | - }, | |
684 | - | |
685 | -/* | |
686 | -* | |
687 | -*/ | |
688 | - createLeaf: function(contextNode) { | |
689 | - // create new node with the same type than the contextNode | |
690 | - var newNode = Ext.create(contextNode.$className, {leaf : true}); | |
691 | - | |
692 | - // load the rootNode and recursively all its child nodes | |
693 | - amdaModel.InteractiveNode.preloadNodes(contextNode.getRootNode(), | |
694 | - function() | |
695 | - { | |
696 | - // edit newNode into Parameter Module with node as contextNode | |
697 | - newNode.editInModule(contextNode); | |
698 | - }); | |
699 | - }, | |
700 | - | |
701 | - renameNode: function() | |
702 | - { | |
703 | - if (this.myGetOwnerTree()) | |
704 | - { | |
705 | - // load the rootNode and recursively all its child nodes if not already loaded | |
706 | - var me = this; | |
707 | - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), | |
708 | - function() | |
709 | - { | |
710 | - // fire the edition event on tree | |
711 | - me.myGetOwnerTree().fireEvent('edition',me.myGetOwnerTree().view, me.myGetOwnerTree().getSelectionModel().selected.items[0]); | |
712 | - }); | |
713 | - } | |
714 | - else | |
715 | - { | |
716 | - myDesktopApp.errorMsg('tree is undefined'); | |
717 | - } | |
718 | - }, | |
719 | - | |
720 | -/* | |
721 | -* load the rootNode and recursively all its child nodes | |
722 | -* to know all names of DerivedParameters | |
723 | -*/ | |
724 | - editLeaf: function(onReady) | |
725 | - { | |
726 | - var me = this; | |
727 | - amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), | |
728 | - function() | |
729 | - { | |
730 | - if (me.get('object')) | |
731 | - { | |
732 | - // launch edition of parameter into parameter module | |
733 | - me.editInModule(null, onReady); | |
734 | - } | |
735 | - else | |
736 | - { | |
737 | - // call the ext method to get the details of parameter | |
738 | - // the edition of real parameter is done into callback method getObjectCallback | |
739 | - if (onReady) | |
740 | - me.onReady = onReady; | |
741 | - | |
742 | - AmdaAction.getObject(me.get('id'), me.get('nodeType'), me.getObjectCallback, me); | |
743 | - } | |
744 | - }); | |
745 | - }, | |
746 | - | |
747 | -/* | |
748 | -* | |
749 | -*/ | |
750 | - getObjectCallback : function(result,remoteEvent) | |
751 | - { | |
752 | - var t = remoteEvent.getTransaction(); | |
753 | - | |
754 | - if (result) { | |
755 | - var paramObj = Ext.create(this.get('objectDataModel'), result); | |
756 | - // set parameter into node | |
757 | - this.set('object',paramObj); | |
758 | - // Edition of parameter into parameter Module | |
759 | - this.editInModule(null, this.onReady); | |
760 | - } | |
761 | - else { | |
762 | - // EXCEPTION : parameter not found !? | |
763 | - myDesktopApp.errorMsg(t.action + "." + t.method + " : No parameter '" | |
764 | - + this.get('name') + "' found!"); | |
765 | - } | |
766 | - } | |
72 | + preloadTreeNode: function (node, nodesToLoad, onloaded) { | |
73 | + var me = this; | |
74 | + | |
75 | + if (node.isLoaded()) { | |
76 | + node.eachChild(function (n) { | |
77 | + if (!n.isLoaded() && !n.isLeaf()) { | |
78 | + nodesToLoad.push(n); | |
79 | + me.preloadTreeNode(n, nodesToLoad, onloaded); | |
80 | + } | |
81 | + }); | |
82 | + | |
83 | + if (onloaded) { | |
84 | + onloaded.call(me, node); | |
85 | + } | |
86 | + return; | |
87 | + } | |
88 | + | |
89 | + node.store.load({ | |
90 | + node: node, | |
91 | + callback: function (records) { | |
92 | + records.forEach(function (record) { | |
93 | + if (!record.isLoaded() && !record.isLeaf()) { | |
94 | + nodesToLoad.push(record); | |
95 | + me.preloadTreeNode(record, nodesToLoad, onloaded); | |
96 | + } | |
97 | + }); | |
98 | + if (onloaded) { | |
99 | + onloaded.call(me, node); | |
100 | + } | |
101 | + } | |
102 | + }); | |
103 | + } | |
104 | + }, | |
105 | + | |
106 | + onReady: null, | |
107 | + | |
108 | + constructor: function (config) { | |
109 | + var suffix; | |
110 | + this.callParent(arguments); | |
111 | + this.set('nodeType', this.self.nodeType); | |
112 | + this.set('ownerTreeId', amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
113 | + // TODO why sometimes (delete in remote interoper tree) this.get('id') = undefined ? | |
114 | + if (this.get('id')) { | |
115 | + // If id of this node have root category suffix | |
116 | + suffix = amdaUI.ExplorerUI.CAT_SUFFIX; | |
117 | + if (Ext.util.Format.substr(this.get('id'), -suffix.length, this.get('id').length) === suffix) { | |
118 | + // Set the expanded property to true | |
119 | + this.set('expanded', true); | |
120 | + } | |
121 | + } | |
122 | + }, | |
123 | + | |
124 | + /** | |
125 | + * This method is overriden into ExecutableNode to return true | |
126 | + * @returns {boolean} true if node is executable | |
127 | + */ | |
128 | + isExecutable: function () { | |
129 | + return false; | |
130 | + }, | |
131 | + | |
132 | + /** | |
133 | + * Open Module with THIS NODE | |
134 | + * @param {object} contextNode Context node | |
135 | + * @param {function} onReady onRady callback function | |
136 | + * @returns {void} | |
137 | + */ | |
138 | + editInModule: function (contextNode, onReady) { | |
139 | + var me = this; | |
140 | + // Set the contextNode of this node | |
141 | + this.set('contextNode', contextNode); | |
142 | + // Parameter module | |
143 | + myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { | |
144 | + // If the node to edit is not already linked to this module | |
145 | + if (module.getLinkedNode() != me) { | |
146 | + // Set relative node into parameter Module | |
147 | + module.setLinkedNode(me); | |
148 | + if (contextNode == null) { | |
149 | + // Set the root node as contextNode | |
150 | + contextNode = me.getRootNode(); | |
151 | + } | |
152 | + module.setContextNode(contextNode); | |
153 | + | |
154 | + } else if (module.getLinkedNode() != null) { | |
155 | + | |
156 | + /* | |
157 | + * TODO the node to edit is already edited | |
158 | + * myDesktopApp.warningMsg('This object is being edited'); | |
159 | + * Sol1: msg alert: "warning this node is already edited! If you want to get the original, | |
160 | + * please press the 'reset' button"->'OK' | |
161 | + * Sol2: msg with user choice: "warning this node is already edited! Would you confirm this action and lost your | |
162 | + * modification?"->'Confirm','Cancel' | |
163 | + */ | |
164 | + } | |
165 | + // Opening parameter window | |
166 | + module.createWindow(onReady); | |
167 | + }); | |
168 | + }, | |
169 | + | |
170 | + /** | |
171 | + * Method to rename the workspace node | |
172 | + * @param {string} value The new name | |
173 | + * @param {function} callBackFn Callback function | |
174 | + * @returns {void} | |
175 | + */ | |
176 | + rename: function (value, callBackFn) { | |
177 | + var dataToSend = { | |
178 | + id: this.get('id'), | |
179 | + old_name: this.modified.text, | |
180 | + name: value, | |
181 | + parent: this.data.parentId, | |
182 | + leaf: this.isLeaf(), | |
183 | + nodeType: this.get('nodeType') | |
184 | + }; | |
185 | + AmdaAction.renameObject(dataToSend, callBackFn); | |
186 | + }, | |
187 | + | |
188 | + /** | |
189 | + * Method to rename the workspace node when D&D | |
190 | + * @param {string} parentId The parent ID | |
191 | + * @param {function} callBackFn callback function | |
192 | + * @returns {void} | |
193 | + */ | |
194 | + renameDD: function (parentId, callBackFn) { | |
195 | + var dataToSend = { | |
196 | + id: this.get('id'), | |
197 | + old_name: this.get('name'), | |
198 | + name: this.get('name'), | |
199 | + parent: parentId, | |
200 | + leaf: this.isLeaf(), | |
201 | + nodeType: this.get('nodeType') | |
202 | + }; | |
203 | + AmdaAction.renameObject(dataToSend, callBackFn); | |
204 | + }, | |
205 | + | |
206 | + /** | |
207 | + * Validation method on name (used in module forms) | |
208 | + * @param {string} name the name to validate | |
209 | + * @param {function} callBackFn Callback function | |
210 | + * @returns {void} | |
211 | + */ | |
212 | + isValidName: function (name, callBackFn) { | |
213 | + var dataToSend = { | |
214 | + name: name, | |
215 | + nodeType: this.get('nodeType'), | |
216 | + leaf: this.isLeaf() | |
217 | + }; | |
218 | + AmdaAction.validNameObject(dataToSend, callBackFn); | |
219 | + }, | |
220 | + | |
221 | + /** | |
222 | + * Method to persist modifications of an AmdaObject by Server side and update the workspace node linked to a Module | |
223 | + * @param {object} opt ... | |
224 | + * @returns {void} | |
225 | + */ | |
226 | + update: function (opt) { | |
227 | + AmdaAction.modifyObject(this.get('object').getJsonValues(true), function (res, e) { | |
228 | + | |
229 | + if (e.status) { | |
230 | + if (res.id) { | |
231 | + if (!this.get('contextNode')) { | |
232 | + // Set the root node of 'Derived Parameters' tree as contextNode | |
233 | + this.set('contextNode', this.getRootNode()); | |
234 | + } | |
235 | + this.get('contextNode').expand(false, false); | |
236 | + this.myGetOwnerTree().getSelectionModel().select(this); | |
237 | + | |
238 | + if (opt && opt.callback) { | |
239 | + opt.callback.call(opt.scope ? opt.scope : this, 'update'); | |
240 | + } | |
241 | + | |
242 | + Ext.Msg.alert('Complete', 'Object ' + this.get('object').get('name') + ' has been modified'); | |
243 | + // Fix the modifications for object | |
244 | + this.get('object').commit(); | |
245 | + | |
246 | + if (res.info) { | |
247 | + this.set('info', res.info); | |
248 | + } | |
249 | + | |
250 | + if (this.get('nodeType') == 'myDataParam') { | |
251 | + if (res.isSpectra) { | |
252 | + this.set('iconCls', 'icon-spectra'); | |
253 | + } else if (res.size > 1) { | |
254 | + this.set('iconCls', 'icon-unknowntype'); | |
255 | + } | |
256 | + } | |
257 | + | |
258 | + // Update my data on possibble mask change | |
259 | + if (res.updateMyData) { | |
260 | + this.updateMyData(); | |
261 | + this.updateMask(res.mask); | |
262 | + } | |
263 | + // Reload object into the view of corresponding Module | |
264 | + var me = this; | |
265 | + myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { | |
266 | + module.getUiContent().setObject(me.get('object')); | |
267 | + }); | |
268 | + } else { | |
269 | + | |
270 | + /* | |
271 | + *TODO proper error message handling | |
272 | + * error code from server; but e.status==true | |
273 | + * revert all modifications since last load or commit | |
274 | + */ | |
275 | + this.get('object').reject(); | |
276 | + myDesktopApp.errorMsg(res.error); | |
277 | + } | |
278 | + } else { | |
279 | + // Revert all modifications since last load or commit | |
280 | + this.get('object').reject(); | |
281 | + myDesktopApp.errorMsg(e.message); | |
282 | + } | |
283 | + }, this); | |
284 | + }, | |
285 | + | |
286 | + /** | |
287 | + * Method to create a new AmdaObject by server side and create the workspace node linked to a Module under its | |
288 | + * contextNode or the root node corresponding to this nodeType category. | |
289 | + * @param {object} opt ... | |
290 | + * @returns {void} | |
291 | + */ | |
292 | + create: function (opt) { | |
293 | + var contextId; | |
294 | + if (!this.get('contextNode') || this.get('contextNode').data.id == 'sharedtimeTable-treeRootNode' || | |
295 | + this.get('contextNode').data.id == 'sharedcatalog-treeRootNode') { | |
296 | + // Set the root node of 'Derived Parameters' tree as contextNode | |
297 | + this.set('contextNode', this.getRootNode()); | |
298 | + } | |
299 | + // Call the Ext.Direct method to create parameter | |
300 | + contextId = this.get('contextNode').get('id'); | |
301 | + AmdaAction.createObject(this.get('object').getJsonValues(false), contextId, function (res, e) { | |
302 | + var myRoot, updateNode; | |
303 | + // Success | |
304 | + if (e.status) { | |
305 | + // If correct response received | |
306 | + if (res.id) { | |
307 | + // If (res.id || res.error == 'NAME_EXISTS') { | |
308 | + if (this.toRename) { | |
309 | + // 'save as' case ; delete old node if it exists | |
310 | + this.toRename = false; | |
311 | + myRoot = this.getRootNode(); | |
312 | + // Search the same named node to override | |
313 | + updateNode = myRoot.findChild('text', this.get('object').get('name'), true); | |
314 | + // Destroy the overrided node | |
315 | + updateNode.parentNode.removeChild(updateNode); | |
316 | + // TODO ??if destroy==true => too many recursions.... | |
317 | + updateNode.destroy(); | |
318 | + } | |
319 | + // Set text of this node | |
320 | + this.set('text', this.get('object').get('name')); | |
321 | + // Set id of this node | |
322 | + this.set('id', res.id); | |
323 | + this.internalId = res.id; | |
324 | + // Set id of node's object | |
325 | + this.get('object').set('id', res.id); | |
326 | + | |
327 | + if (res.created) { | |
328 | + // Set the created date | |
329 | + this.get('object').set('created', res.created); | |
330 | + } | |
331 | + | |
332 | + if (res.info) { | |
333 | + // Set the tooltip | |
334 | + this.set('info', res.info); | |
335 | + // Set globalStart & global Stop to be used for time selection | |
336 | + if (this.get('nodeType') == 'myDataParam') { | |
337 | + var startStop = res.info.split('<br/>'); | |
338 | + this.set('globalStart', startStop[1].substr(0, 19)); | |
339 | + this.set('globalStop', startStop[1].substr(20)); | |
340 | + | |
341 | + if (res.mask) { | |
342 | + this.set('linkedMask', res.mask); | |
343 | + } | |
344 | + if (res.size) { | |
345 | + this.set('size', res.size); | |
346 | + } | |
347 | + | |
348 | + if (res.isSpectra) { | |
349 | + this.set('iconCls', 'icon-spectra'); | |
350 | + } else if (res.size > 1) { | |
351 | + this.set('iconCls', 'icon-unknowntype'); | |
352 | + } | |
353 | + } | |
354 | + } | |
355 | + | |
356 | + /* | |
357 | + *TODO do we need this commission ??? | |
358 | + * fix the modifications for object | |
359 | + */ | |
360 | + this.get('object').commit(); | |
361 | + // If ownerTree panel is not active | |
362 | + if (this.myGetOwnerTree().ownerCt.getActiveTab() !== this.myGetOwnerTree()) { | |
363 | + // Set ownerTree panel as the active tab - to enable selection of this node his ownerTree must have a view | |
364 | + this.myGetOwnerTree().ownerCt.setActiveTab(this.myGetOwnerTree()); | |
365 | + } | |
366 | + | |
367 | + Ext.Msg.alert('Complete', 'New object ' + this.get('object').get('name') + ' has been created'); | |
368 | + // Expand the contextNode | |
369 | + this.get('contextNode').expand(false, function () { | |
370 | + if (!this.get('contextNode').findChild('text', this.get('text'))) { | |
371 | + // Create node in tree as child of contextNode | |
372 | + this.get('contextNode').appendChild(this); | |
373 | + } | |
374 | + // Select the new node | |
375 | + this.myGetOwnerTree().getSelectionModel().select(this); | |
376 | + if (opt && opt.callback) { | |
377 | + opt.callback.call(opt.scope ? opt.scope : this, 'create'); | |
378 | + } | |
379 | + }, this); | |
380 | + | |
381 | + /* | |
382 | + * MyDataParamNode - update MyData subtree | |
383 | + *TODO put this in mydataparamnode | |
384 | + */ | |
385 | + if (res.updateMyData) { | |
386 | + this.updateMyData(); | |
387 | + this.updateMask(res.mask); | |
388 | + } | |
389 | + | |
390 | + } | |
391 | + // Error code from server; but e.status==true | |
392 | + else { | |
393 | + myDesktopApp.errorMsg(res.error); | |
394 | + // Revert all modifications since last load or commit | |
395 | + this.get('object').reject(); | |
396 | + } | |
397 | + } | |
398 | + // Failure: e.status == false | |
399 | + else { | |
400 | + // Revert all modifications since last load or commit | |
401 | + this.get('object').reject(); | |
402 | + // TODO: this.destroy(); | |
403 | + myDesktopApp.errorMsg(e.message); | |
404 | + } | |
405 | + }, this); | |
406 | + }, | |
407 | + | |
408 | + /** | |
409 | + * Generic part of Context Menu | |
410 | + * @returns {*[]|*} Menu items | |
411 | + */ | |
412 | + allMenuItems: function () { | |
413 | + var menuItems, src; | |
414 | + | |
415 | + src = this.self.objectName; | |
416 | + menuItems = [ | |
417 | + { | |
418 | + fnId: 'root-createLeaf', | |
419 | + text: 'Create ' + src | |
420 | + }, | |
421 | + { | |
422 | + fnId: 'root-createDir', | |
423 | + text: 'Create Folder' | |
424 | + }, | |
425 | + { | |
426 | + fnId: 'dire-createLeaf', | |
427 | + text: 'Create ' + src | |
428 | + }, | |
429 | + { | |
430 | + fnId: 'dire-createDir', | |
431 | + text: 'Create Folder' | |
432 | + }, | |
433 | + { | |
434 | + fnId: 'dire-renameNode', | |
435 | + text: 'Rename Folder' | |
436 | + }, | |
437 | + { | |
438 | + fnId: 'dire-deleteNode', | |
439 | + text: 'Delete Folder' | |
440 | + }, | |
441 | + { | |
442 | + fnId: 'leaf-editLeaf', | |
443 | + text: 'Edit ' + src | |
444 | + }, | |
445 | + { | |
446 | + fnId: 'leaf-renameNode', | |
447 | + text: 'Rename ' + src | |
448 | + }, | |
449 | + { | |
450 | + fnId: 'leaf-deleteNode', | |
451 | + text: 'Delete ' + src | |
452 | + } | |
453 | + ]; | |
454 | + return menuItems; | |
455 | + }, | |
456 | + | |
457 | + allMenuMultiItems: function () { | |
458 | + return [ | |
459 | + { | |
460 | + fnId: 'mult-deleteMulti', | |
461 | + text: 'Delete selected ' + this.self.objectName + 's' | |
462 | + } | |
463 | + ]; | |
464 | + }, | |
465 | + | |
466 | + getAllContextMenuItems: function () { | |
467 | + return this.allMenuItems(); | |
468 | + }, | |
469 | + | |
470 | + getMultiContextMenuItems: function () { | |
471 | + return this.allMenuMultiItems(); | |
472 | + }, | |
473 | + | |
474 | + // FIXME: duplicate declaration โ โ | |
475 | + | |
476 | + /** | |
477 | + * Default implementation: no menu display if there's no override of this function | |
478 | + * @returns {null} Items | |
479 | + */ | |
480 | + getMultiContextMenuItems: function () { | |
481 | + return null; | |
482 | + }, | |
483 | + | |
484 | + /** | |
485 | + * Context Menu Actions | |
486 | + * @param {object} menu The menu | |
487 | + * @param {object} item the item | |
488 | + * @returns {void} | |
489 | + */ | |
490 | + onMenuItemClick: function (menu, item) { | |
491 | + // FnId parsing : | |
492 | + var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); | |
493 | + | |
494 | + switch (fnId) { | |
495 | + case 'deleteNode': | |
496 | + this.deleteNode(); | |
497 | + break; | |
498 | + case 'createDir': | |
499 | + this.createDir(); | |
500 | + break; | |
501 | + case 'createLeaf': | |
502 | + this.createLeaf(this); | |
503 | + break; | |
504 | + case 'renameNode': | |
505 | + this.renameNode(false); | |
506 | + break; | |
507 | + case 'editLeaf': | |
508 | + this.editLeaf(); | |
509 | + break; | |
510 | + case 'deleteMulti': | |
511 | + this.deleteMulti(); | |
512 | + break; | |
513 | + case 'plotParam': | |
514 | + this.createPlot(this); | |
515 | + break; | |
516 | + case 'downParam': | |
517 | + this.createDownload(this); | |
518 | + break; | |
519 | + default: | |
520 | + break; | |
521 | + } | |
522 | + }, | |
523 | + | |
524 | + getTimeFromNode: function (node) { | |
525 | + var startDate, stopDate, timeObj; | |
526 | + startDate = new Date(String(node.get('globalStart')).replace(/-/g, '/').replace(/[T|Z]/g, ' ')); | |
527 | + stopDate = new Date(String(node.get('globalStop')).replace(/-/g, '/').replace(/[T|Z]/g, ' ')); | |
528 | + | |
529 | + if (stopDate - startDate > 86400000) { | |
530 | + // 'timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s')}; | |
531 | + timeObj = { | |
532 | + start: Ext.Date.format(Ext.Date.add(stopDate, Ext.Date.DAY, -1), 'Y/m/d'), | |
533 | + stop: Ext.Date.format(stopDate, 'Y/m/d') | |
534 | + }; | |
535 | + } else { | |
536 | + timeObj = { | |
537 | + start: node.get('globalStart'), | |
538 | + stop: node.get('globalStop') | |
539 | + }; | |
540 | + } | |
541 | + return timeObj; | |
542 | + }, | |
543 | + | |
544 | + createPlot: function (node) { | |
545 | + if (node.get('disable')) { | |
546 | + return; | |
547 | + } | |
548 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) { | |
549 | + if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.plot.id)) { | |
550 | + var request = Ext.create(amdaPlotObj.PlotRequestObject.$className); | |
551 | + var newNode = Ext.create(amdaModel.PlotNode.$className, {object: request}); | |
552 | + // Edit newNode into Plot Module with node as contextNode | |
553 | + newNode.editInModule(); | |
554 | + if (node.get('globalStart') != null && node.get('globalStop') != null && | |
555 | + node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | |
556 | + module.getUiContent().setTimeFromData(node.getTimeFromNode(node)); | |
557 | + } | |
558 | + } | |
559 | + module.getUiContent().addParameter(node); | |
560 | + }); | |
561 | + }, | |
562 | + | |
563 | + createDownload: function (node) { | |
564 | + if (node.get('disable')) { | |
565 | + return; | |
566 | + } | |
567 | + | |
568 | + if (node.get('notyet')) { | |
569 | + myDesktopApp.warningMsg('Sorry! access to this parameter is restricted.'); | |
570 | + return; | |
571 | + } | |
572 | + | |
573 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.download.id, true, function (module) { | |
574 | + var paramName, request; | |
575 | + if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.download.id)) { | |
576 | + request = Ext.create(amdaModel.Download.$className); | |
577 | + amdaModel.DownloadNode.set('object', request); | |
578 | + // Singleton! | |
579 | + amdaModel.DownloadNode.editInModule(); | |
580 | + if (node.get('globalStart') != null && node.get('globalStop') != null && | |
581 | + node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | |
582 | + module.getUiContent().setTimeFromData(node.getTimeFromNode(node)); | |
583 | + } | |
584 | + } | |
585 | + switch (node.$className) { | |
586 | + case 'amdaModel.AliasNode': | |
587 | + paramName = '#' + node.get('text'); | |
588 | + break; | |
589 | + case 'amdaModel.DerivedParamNode': | |
590 | + paramName = 'ws_' + node.get('text'); | |
591 | + break; | |
592 | + case 'amdaModel.MyDataParamNode': | |
593 | + paramName = 'wsd_' + node.get('text'); | |
594 | + break; | |
595 | + default: | |
596 | + if (node.get('alias') != '') { | |
597 | + paramName = '#' + node.get('alias'); | |
598 | + } else { | |
599 | + paramName = node.get('id'); | |
600 | + } | |
601 | + } | |
602 | + | |
603 | + /* | |
604 | + * Var component_info = node.get('component_info'); | |
605 | + * If (component_info && component_info.parentId) { | |
606 | + * // It's a component | |
607 | + * ParamName = component_info.parentId; | |
608 | + * Components = []; | |
609 | + * If (component_info.index1) | |
610 | + * Components['index1'] = component_info.index1; | |
611 | + * If (component_info.index2) | |
612 | + * Components['index2'] = component_info.index2; | |
613 | + * } | |
614 | + */ | |
615 | + module.addParam(paramName, true, node.get('needsArgs'), null); | |
616 | + }); | |
617 | + }, | |
618 | + | |
619 | + deleteNode: function () { | |
620 | + // If the target is a directory | |
621 | + if (this.isLeaf()) { | |
622 | + // No confirmation prompt for leaves | |
623 | + this.confirmDirectoryDeletion(false); | |
624 | + } else { | |
625 | + // Determine if this directory is empty before launching the delete confirmation method | |
626 | + this.isNotEmptyDir(this.confirmDirectoryDeletion); | |
627 | + // Else (the target is a leaf) | |
628 | + } | |
629 | + }, | |
630 | + | |
631 | + /** | |
632 | + * This method return if node has Childs even if it was not already loaded | |
633 | + * @param {function} callbackFn Callback function | |
634 | + * @returns {void} | |
635 | + */ | |
636 | + isNotEmptyDir: function (callbackFn) { | |
637 | + // If node not already loaded | |
638 | + if (this.isLoaded()) { | |
639 | + callbackFn.call(this, this.hasChildNodes()); | |
640 | + } else { | |
641 | + // Call directFunction to load this node | |
642 | + AmdaAction.getTree({ | |
643 | + node: this.get('id'), | |
644 | + nodeType: this.get('nodeType') | |
645 | + }, function (res) { | |
646 | + callbackFn.call(this, res.length > 0); | |
647 | + }, this); | |
648 | + } | |
649 | + }, | |
650 | + | |
651 | + /** | |
652 | + * This method is used to display a confirmation message | |
653 | + * @param {boolean} isNotEmptyDir true if the directory is not empty. | |
654 | + * @returns {void} | |
655 | + */ | |
656 | + confirmDirectoryDeletion: function (isNotEmptyDir) { | |
657 | + var ConfirmMsg = 'The target is a non-empty directory!<br>Do you want to continue and also delete its content?'; | |
658 | + // If this is a non-empty directory | |
659 | + if (isNotEmptyDir) { | |
660 | + // Prompt to the user if he also wants to delete its content | |
661 | + Ext.Msg.confirm('non-empty directory', ConfirmMsg, function (btn, text) { | |
662 | + if (btn == 'yes') { | |
663 | + // Do delete | |
664 | + this.realDelete(); | |
665 | + } | |
666 | + }, this); | |
667 | + } else { | |
668 | + this.realDelete(); | |
669 | + } | |
670 | + }, | |
671 | + | |
672 | + /* | |
673 | + * Call the extDirect method to delete parameter | |
674 | + * Callback method needed to execute node deletion in tree if id in result or to show error msg | |
675 | + */ | |
676 | + realDelete: function () { | |
677 | + AmdaAction.deleteObject({ | |
678 | + id: this.get('id'), | |
679 | + leaf: this.isLeaf(), | |
680 | + nodeType: this.get('nodeType') | |
681 | + }, function (res, e) { | |
682 | + var me, moduleId; | |
683 | + me = this; | |
684 | + | |
685 | + // Node deletion in tree - TODO proper errors handling | |
686 | + | |
687 | + // If success | |
688 | + if (res) { | |
689 | + if (res.id) { | |
690 | + | |
691 | + /* | |
692 | + * Ext.Msg.show({ | |
693 | + * title:'Warning', | |
694 | + * msg: 'Requests with parameter '+node.data.text+' are deleted', | |
695 | + * icon: Ext.MessageBox.ERROR, | |
696 | + * buttons: Ext.Msg.OK | |
697 | + * }); | |
698 | + */ | |
699 | + if (this.parentNode) { | |
700 | + if (this.isLeaf()) { | |
701 | + moduleId = this.get('moduleId'); | |
702 | + // If really interactive node | |
703 | + if (moduleId) { | |
704 | + myDesktopApp.getLoadedModule(moduleId, true, function (module) { | |
705 | + var editedNode, isThisFile, linkedNodes, newNode, tabPanel; | |
706 | + editedNode = module.getLinkedNode(); | |
707 | + // File node is not linked directly to the module | |
708 | + isThisFile = false; | |
709 | + | |
710 | + if (editedNode && editedNode.$className == 'amdaModel.MyDataParamNode') { | |
711 | + if (editedNode.get('fileObject').get('fileName') == me.get('text')) { | |
712 | + isThisFile = true; | |
713 | + } | |
714 | + } | |
715 | + | |
716 | + if (me.$className == 'amdaModel.DerivedParamNode') { | |
717 | + AmdaAction.compilParamDelete({paramId: 'ws_' + me.get('text')}); | |
718 | + } | |
719 | + | |
720 | + if (editedNode === me || isThisFile) { | |
721 | + newNode = Ext.ModelManager.create({leaf: true}, me.$className); | |
722 | + // Several tabs could be connected to one node | |
723 | + if (moduleId === myDesktopApp.dynamicModules.plot.id) { | |
724 | + linkedNodes = module.linkedNodes; | |
725 | + | |
726 | + if (linkedNodes) { | |
727 | + linkedNodes.each(function (key, value) { | |
728 | + if (value === me) { | |
729 | + linkedNodes.replace(key, newNode); | |
730 | + tabPanel = module.getUiContent().tabPanel.items.getByKey(key); | |
731 | + tabPanel.setObject(Ext.create(amdaModel.Plot.$className, {})); | |
732 | + } | |
733 | + }, me); | |
734 | + } | |
735 | + } | |
736 | + newNode.editInModule(); | |
737 | + } | |
738 | + }); | |
739 | + } | |
740 | + } | |
741 | + // Update mask info in myData | |
742 | + if (res.maskDesc && !res.maskDeleted) { | |
743 | + this.parentNode.set('info', res.maskDesc); | |
744 | + this.updateMyDataParam(res.mask, res.maskDesc); | |
745 | + } | |
746 | + this.remove(); | |
747 | + } | |
748 | + | |
749 | + /* | |
750 | + *TODO Several special node-dependent actions - to move to node functions.. | |
751 | + * nodes of another nodeType to be deleted as they depend on deleted node | |
752 | + */ | |
753 | + if (res.params) { | |
754 | + this.deleteDependence(res.params); | |
755 | + // TODO reset | |
756 | + } | |
757 | + // Mask was deleted or updated - to update mydata tree | |
758 | + if (res.maskDeleted) { | |
759 | + this.updateMyData(); | |
760 | + } | |
761 | + } else { | |
762 | + myDesktopApp.warningMsg(res.error); | |
763 | + } | |
764 | + } else { | |
765 | + myDesktopApp.errorMsg(e.message); | |
766 | + } | |
767 | + }, this); | |
768 | + }, | |
769 | + | |
770 | + /** | |
771 | + * Delete multi selection | |
772 | + * @returns {void} | |
773 | + */ | |
774 | + deleteMulti: function () { | |
775 | + var selection = this.myGetOwnerTree().getSelectionModel().selected.items; | |
776 | + Ext.alert(selection.length + ' to delete!'); | |
777 | + Ext.Array.each(selection, function (item, index, allItems) { | |
778 | + item.deleteNode(); | |
779 | + }); | |
780 | + }, | |
781 | + | |
782 | + /** | |
783 | + * Create Folder | |
784 | + * @returns {void} | |
785 | + */ | |
786 | + createDir: function () { | |
787 | + var me = this; | |
788 | + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () { | |
789 | + var newNode = Ext.create(me.$className, | |
790 | + { | |
791 | + leaf: false, | |
792 | + nodeType: me.get('nodeType'), | |
793 | + text: amdaModel.AmdaNode.NEW_DIR_NAME, | |
794 | + children: [], | |
795 | + parentId: me.get('id') | |
796 | + }); | |
797 | + | |
798 | + // Insert the new node as a child of node | |
799 | + me.insertChild(0, newNode); | |
800 | + // Start text edition on this new directory node | |
801 | + me.expand(false); | |
802 | + newNode.expand(false); | |
803 | + | |
804 | + // Select the new node | |
805 | + me.myGetOwnerTree().getSelectionModel().select(newNode); | |
806 | + // Call the renameNode method for this new node | |
807 | + newNode.renameNode(true); | |
808 | + }); | |
809 | + }, | |
810 | + | |
811 | + /* | |
812 | + * | |
813 | + */ | |
814 | + createLeaf: function (contextNode) { | |
815 | + // Create new node with the same type than the contextNode | |
816 | + var newNode = Ext.create(contextNode.$className, {leaf: true}); | |
817 | + | |
818 | + // Load the rootNode and recursively all its child nodes | |
819 | + amdaModel.InteractiveNode.preloadNodes(contextNode.getRootNode(), function () { | |
820 | + // Edit newNode into Parameter Module with node as contextNode | |
821 | + newNode.editInModule(contextNode); | |
822 | + }); | |
823 | + }, | |
824 | + | |
825 | + renameNode: function (deleteOnFailure) { | |
826 | + var item, me; | |
827 | + me = this; | |
828 | + if (this.myGetOwnerTree()) { | |
829 | + // Load the rootNode and recursively all its child nodes if not already loaded | |
830 | + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () { | |
831 | + // Fire the edition event on tree | |
832 | + item = me.myGetOwnerTree().getSelectionModel().selected.items[0]; | |
833 | + item.deleteOnFailure = deleteOnFailure; | |
834 | + me.myGetOwnerTree().fireEvent('edition', me.myGetOwnerTree().view, item); | |
835 | + }); | |
836 | + } else { | |
837 | + myDesktopApp.errorMsg('tree is undefined'); | |
838 | + } | |
839 | + }, | |
840 | + | |
841 | + /** | |
842 | + * Load the rootNode and recursively all its child nodes to know all names of DerivedParameters | |
843 | + * @param {function} onReady On ready callback function | |
844 | + * @returns {void} | |
845 | + */ | |
846 | + editLeaf: function (onReady) { | |
847 | + var me = this; | |
848 | + amdaModel.InteractiveNode.preloadNodes(this.getRootNode(), function () { | |
849 | + if (me.get('object')) { | |
850 | + // Launch edition of parameter into parameter module | |
851 | + me.editInModule(null, onReady); | |
852 | + } else { | |
853 | + | |
854 | + /* | |
855 | + * Call the ext method to get the details of parameter | |
856 | + * the edition of real parameter is done into callback method getObjectCallback | |
857 | + */ | |
858 | + if (onReady) { | |
859 | + me.onReady = onReady; | |
860 | + } | |
861 | + | |
862 | + AmdaAction.getObject(me.get('id'), me.get('nodeType'), me.getObjectCallback, me); | |
863 | + } | |
864 | + }); | |
865 | + }, | |
866 | + | |
867 | + /** | |
868 | + * Get object callback | |
869 | + * @param {object} result The result | |
870 | + * @param {object} remoteEvent ... | |
871 | + * @returns {void} | |
872 | + */ | |
873 | + getObjectCallback: function (result, remoteEvent) { | |
874 | + var t = remoteEvent.getTransaction(); | |
875 | + | |
876 | + if (result) { | |
877 | + var paramObj = Ext.create(this.get('objectDataModel'), result); | |
878 | + // Set parameter into node | |
879 | + this.set('object', paramObj); | |
880 | + // Edition of parameter into parameter Module | |
881 | + this.editInModule(null, this.onReady); | |
882 | + } else { | |
883 | + // EXCEPTION : parameter not found !? | |
884 | + myDesktopApp.errorMsg(t.action + '.' + t.method + ' : No parameter \'' + | |
885 | + this.get('name') + '\' found!'); | |
886 | + } | |
887 | + } | |
767 | 888 | }); |
... | ... |
js/app/views/ExplorerUI.js
1 | 1 | /** |
2 | 2 | * Project : AMDA-NG4 |
3 | 3 | * Name : ExplorerUI.js |
4 | - * @class amdaUI.ExplorerUI | |
4 | + * @class amdaUI.ExplorerUI | |
5 | 5 | * @extends Ext.tab.Panel |
6 | 6 | * @class amdaUI.TreeToolColumn |
7 | 7 | * @extends Ext.tree.Column |
... | ... | @@ -11,1085 +11,1049 @@ |
11 | 11 | * @author CDA |
12 | 12 | */ |
13 | 13 | |
14 | +/* global AmdaAction, amdaModel, myDesktopApp, amdaUI, MyTreeEditor */ | |
15 | + | |
14 | 16 | Ext.define('amdaUI.TreeToolColumn', { |
15 | - extend: 'Ext.tree.Column', | |
16 | - alias: 'widget.treetoolcolumn', | |
17 | - | |
18 | - /** | |
19 | - * Add more tools here. These will be on the prototype for all TreeToolColumns | |
20 | - */ | |
21 | - tools: { | |
22 | - 'info': 'js/resources/images/16x16/info_mini.png' | |
23 | - }, | |
24 | - | |
25 | - initComponent: function() | |
26 | - { | |
27 | - var me = this; | |
28 | - me.addEvents('toolclick'); | |
29 | - me.callParent(); | |
30 | - me.on('toolclick', me.toolHandler, me); | |
31 | - }, | |
32 | - | |
33 | - renderer: function(value, metaData, record, rowIdx, colIdx, store, view) | |
34 | - { | |
35 | - var toolCol = view.getHeaderAtIndex(colIdx); | |
36 | - | |
37 | - if (!toolCol.toolIsVisible(record)) return value; | |
38 | - | |
39 | - var toolId = 'tool-' + rowIdx + '-' + colIdx, | |
40 | - toolImg = toolCol.tools[toolCol.tool], | |
41 | - imgHtml = Ext.DomHelper.markup({ | |
42 | - id : toolId, | |
43 | - tag : 'img', | |
44 | - tooltype: toolCol.tool, | |
45 | - src : toolImg, | |
46 | - style : 'cursor:hand;' | |
47 | - }); | |
48 | - | |
49 | - return value + ' ' + imgHtml; | |
50 | - }, | |
51 | - | |
52 | - processEvent: function(type, view, cell, recordIndex, cellIndex, e) | |
53 | - { | |
54 | - if(type === "click" && e.target.tagName === "IMG") | |
55 | - { | |
56 | - var tooltype = e.target.getAttribute("tooltype"); | |
57 | - if(tooltype) | |
58 | - return this.fireEvent("toolclick", view, cell, recordIndex, cellIndex, e); | |
59 | - } | |
60 | - return this.fireEvent.apply(this, arguments); | |
61 | - }, | |
62 | - | |
63 | - /** | |
64 | - * Override this when you add columns to the tree... see example below | |
65 | - */ | |
66 | -// toolHandler: function() { | |
67 | -// alert("override this"); | |
68 | -// }, | |
69 | - | |
70 | - toolIsVisible : function(record) { | |
71 | - return false; | |
72 | - } | |
17 | + extend: 'Ext.tree.Column', | |
18 | + alias: 'widget.treetoolcolumn', | |
19 | + | |
20 | + /** | |
21 | + * Add more tools here. These will be on the prototype for all TreeToolColumns | |
22 | + */ | |
23 | + tools: {info: 'js/resources/images/16x16/info_mini.png'}, | |
24 | + | |
25 | + initComponent: function () { | |
26 | + var me = this; | |
27 | + | |
28 | + me.addEvents('toolclick'); | |
29 | + me.callParent(); | |
30 | + me.on('toolclick', me.toolHandler, me); | |
31 | + }, | |
32 | + | |
33 | + renderer: function (value, metaData, record, rowIdx, colIdx, store, view) { | |
34 | + var imgHtml, | |
35 | + toolCol = view.getHeaderAtIndex(colIdx); | |
36 | + | |
37 | + if (!toolCol.toolIsVisible(record)) { | |
38 | + return value; | |
39 | + } | |
40 | + | |
41 | + imgHtml = Ext.DomHelper.markup({ | |
42 | + id: 'tool-' + rowIdx + '-' + colIdx, | |
43 | + tag: 'img', | |
44 | + tooltype: toolCol.tool, | |
45 | + src: toolCol.tools[toolCol.tool], | |
46 | + style: 'cursor:hand;' | |
47 | + }); | |
48 | + | |
49 | + return value + ' ' + imgHtml; | |
50 | + }, | |
51 | + | |
52 | + processEvent: function (type, view, cell, recordIndex, cellIndex, e) { | |
53 | + var toolType; | |
54 | + | |
55 | + if (type === 'click' && e.target.tagName === 'IMG') { | |
56 | + toolType = e.target.getAttribute('tooltype'); | |
57 | + if (toolType) { | |
58 | + return this.fireEvent('toolclick', view, cell, recordIndex, cellIndex, e); | |
59 | + } | |
60 | + } | |
61 | + return this.fireEvent.apply(this, arguments); | |
62 | + }, | |
63 | + | |
64 | + /** | |
65 | + * Override this when you add columns to the tree... see example below: | |
66 | + * | |
67 | + * ToolHandler: function() { | |
68 | + * Alert("override this"); | |
69 | + * } | |
70 | + * | |
71 | + * @returns {boolean} False | |
72 | + */ | |
73 | + toolIsVisible: function () { | |
74 | + return false; | |
75 | + } | |
73 | 76 | }); |
74 | 77 | |
75 | 78 | |
76 | 79 | // ExplorerUI |
77 | 80 | Ext.define('amdaUI.ExplorerUI', { |
78 | - extend: 'Ext.tab.Panel', | |
79 | - alias : 'widget.panelExplorer', | |
80 | - | |
81 | - statics: | |
82 | - { | |
83 | - RESRC_TAB : { | |
84 | - TREE_ID:'resourcesTree', | |
85 | - TREE_TYPE:'resources' | |
86 | - }, | |
87 | - OPE_TAB : { | |
88 | - TREE_ID:'operationsTree', | |
89 | - TREE_TYPE:'operations' | |
90 | - }, | |
91 | - JOB_TAB : { | |
92 | - TREE_ID:'jobsTree', | |
93 | - TREE_TYPE:'jobs' | |
94 | - }, | |
95 | - | |
96 | - CAT_SUFFIX: '-treeBase', | |
97 | - ROOT_SUFFIX: '-treeRootNode', | |
98 | - SUB_ROOT_SUFFIX : 'RootNode', | |
99 | - | |
100 | - ITEM_KIND_BASE : 'base', | |
101 | - ITEM_KIND_ROOT : 'root', | |
102 | - ITEM_KIND_LEAF : 'leaf', | |
103 | - ITEM_KIND_DIRE : 'dire', | |
104 | - ITEM_KIND_PARA : 'para', | |
105 | - ITEM_KIND_MISS : 'miss' | |
106 | - }, | |
107 | - | |
108 | - initComponent : function (config) | |
109 | - { | |
110 | - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
111 | - | |
112 | - var myConf = { | |
113 | - split : true, | |
114 | - width : '100%', | |
115 | - height : '100%', | |
116 | - autoScroll : true, | |
117 | - border : true, | |
118 | - header : false, | |
119 | - defaults : { | |
120 | - // applied to each contained panel | |
121 | - containerScroll : true | |
122 | - }, | |
123 | - stateful: true, | |
124 | - //stateId: 'tp1', | |
125 | - stateEvents: ['tabchange'], | |
126 | - getState: function() { | |
127 | - return { | |
128 | - activeTab: this.items.findIndex('id',this.getActiveTab().id) | |
129 | - }; | |
130 | - }, | |
131 | - applyState: function(s) { | |
132 | - this.setActiveTab(s.activeTab); | |
133 | - }, | |
134 | - items: [ | |
135 | - this.initTree(amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE), | |
136 | - this.initTree(amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE), | |
137 | - this.initTree(amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE) | |
138 | - ], | |
139 | - tbar : [ | |
140 | - { | |
141 | - xtype : 'combo', | |
142 | - fieldLabel: 'Filter', | |
143 | - labelWidth: 25, | |
144 | - width: 140, | |
145 | - store: explorerModule.filtersStore, | |
146 | - queryMode: 'local', | |
147 | - displayField: 'name', | |
148 | - valueField: 'id', | |
149 | - listeners : { | |
150 | - scope : this, | |
151 | - select: function(combo, records) { | |
152 | - AmdaAction.setCrtFilterId({id : records[0].get('id')}, | |
153 | - function (result, e) | |
154 | - { | |
155 | - var t = e.getTransaction(); | |
156 | - if (e.status) | |
157 | - { | |
158 | - if (result) | |
159 | - { | |
160 | - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
161 | - if (explorerModule) | |
162 | - explorerModule.setCrtFilter(); | |
163 | - } | |
164 | - else | |
165 | - Ext.Msg.show( { | |
166 | - title : 'Filter', | |
167 | - msg : 'Cannot apply filter', | |
168 | - modal : true, | |
169 | - icon : Ext.Msg.ERROR, | |
170 | - buttons : Ext.Msg.OK | |
171 | - }); | |
172 | - } | |
173 | - else | |
174 | - { | |
175 | - // FAILURE | |
176 | - Ext.Msg.show({title:'Error System', msg: e.message, icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK}); | |
177 | - } | |
178 | - },this); | |
179 | - } | |
180 | - } | |
181 | - }, | |
182 | - { | |
183 | - text: '', | |
184 | - iconCls : 'icon-parameters', | |
185 | - tooltip: { text: 'Edit Filter', align: 'bl-tl' }, | |
186 | - handler: function(t){ | |
187 | - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.filters.id, true, function (module) { | |
188 | - module.createWindow(); | |
189 | - }); | |
190 | - } | |
191 | - }, | |
192 | - { | |
193 | - text: '', | |
194 | - iconCls : 'icon-remover', | |
195 | - tooltip: { text: 'Reset Filter', align: 'bl-tl' }, | |
196 | - handler: function(t){ | |
197 | - var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
198 | - explorerModule.resetFilter(); | |
199 | - } | |
200 | - }, '-', | |
201 | - { | |
202 | - xtype: 'displayfield', | |
203 | - fieldLabel: 'SortBy', | |
204 | - width: 40 | |
205 | - }, | |
206 | - { | |
207 | - text: 'Name', | |
208 | - scope : this, | |
209 | - tooltip: { text: 'Sort out AMDA DataBase Data by Mission Name', align: 'bl-tl' }, | |
210 | - pressed: true, | |
211 | - enableToggle : true, | |
212 | - toggleGroup: 'sorting', | |
213 | - handler: function(){ | |
214 | - var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
215 | - tree.getStore().sort([ | |
216 | - { sorterFn: function(o1, o2){ | |
217 | - if (o1.get('nodeType') !== 'localParam') | |
218 | - return; | |
219 | - | |
220 | - return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1; | |
221 | - } | |
222 | - }]); | |
223 | - this.updateFilter(); | |
224 | - } | |
225 | - }, | |
226 | - { | |
227 | - text: 'Target', | |
228 | - scope : this, | |
229 | - tooltip: {text: 'Sort out AMDA DataBase Data by Mission Main Target', align: 'bl-tl'}, | |
230 | - enableToggle : true, | |
231 | - toggleGroup: 'sorting', | |
232 | - handler: function(){ | |
233 | - var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
234 | - tree.getStore().sort([{ property : 'rank' }]); | |
235 | - this.updateFilter(); | |
236 | - } | |
237 | - }] | |
238 | - }; | |
239 | - Ext.apply (this , Ext.apply (arguments, myConf)); | |
240 | - this.callParent(arguments); | |
241 | - }, | |
242 | - | |
243 | - initTree : function(treeType) | |
244 | - { | |
245 | - switch (treeType) | |
246 | - { | |
247 | - case amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE: | |
248 | - treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID; | |
249 | - break; | |
250 | - case amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE: | |
251 | - treeId = amdaUI.ExplorerUI.OPE_TAB.TREE_ID; | |
252 | - break; | |
253 | - case amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE: | |
254 | - treeId = amdaUI.ExplorerUI.JOB_TAB.TREE_ID; | |
255 | - break; | |
256 | - default: | |
257 | - treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID; | |
258 | - break; | |
259 | - } | |
260 | - | |
261 | - var store = Ext.create('Ext.data.TreeStore', { | |
262 | - root: { | |
263 | - expanded: true, | |
264 | - nodeType : treeType | |
265 | - }, | |
266 | - model: 'amdaModel.AmdaNode', | |
267 | - sorters:[{ direction: 'ASC' , | |
268 | - sorterFn: function(o1, o2){ | |
269 | - | |
270 | - if (o1.get('nodeType') == 'localParam' || o1.get('nodeType') == 'myData') { | |
271 | - return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1; | |
272 | - } | |
273 | - | |
274 | - return; | |
275 | - } | |
276 | - }], | |
277 | - listeners: { | |
278 | - beforeload: function(store, operation){ | |
279 | - store.proxy.extraParams = { | |
280 | - nodeType: operation.node.get('nodeType') | |
281 | - }; | |
282 | - } | |
283 | - } | |
284 | - }); | |
285 | - | |
286 | - var menu = new Ext.menu.Menu(); | |
287 | - | |
288 | - var tree = Ext.create('Ext.tree.Panel', { | |
289 | - id : treeId, | |
290 | - title: treeType, | |
291 | - store: store, | |
292 | - rootVisible: false, | |
293 | - animate: false, | |
294 | - hideHeaders : true, | |
295 | - selModel: Ext.create('Ext.selection.TreeModel', { | |
296 | - // ignoreRightMouseSelection: true, | |
297 | - mode: 'MULTI' | |
298 | - }), | |
299 | - viewConfig: | |
300 | - { | |
301 | - plugins: | |
302 | - { | |
303 | - ptype: 'treeviewdragdrop', | |
304 | - enableDrag:true, | |
305 | - enableDrop:true, | |
306 | - //TODO - BRE - Wait a fix for drag&drop issue | |
307 | - ddGroup:'explorerTree', | |
308 | - pluginId : 'ddplugin', | |
309 | - | |
310 | - isValidDropPoint : function (node, position, dragZone, e, data) | |
311 | - { | |
312 | - if (!node || !data.item) { | |
313 | - return false; | |
314 | - } | |
315 | - var view = this.view, | |
316 | - targetNode = view.getRecord(node), | |
317 | - draggedRecords = data.records, | |
318 | - dataLength = draggedRecords.length, | |
319 | - ln = draggedRecords.length, | |
320 | - i, record; | |
321 | - | |
322 | - // No drop position, or dragged records: invalid drop point | |
323 | - if (!(targetNode && position && dataLength)) { | |
324 | - return false; | |
325 | - } | |
326 | - // If the targetNode is within the folder we are dragging | |
327 | - for (i = 0; i < ln; i++) { | |
328 | - record = draggedRecords[i]; | |
329 | - if (record.isNode && record.contains(targetNode)) { | |
330 | - return false; | |
331 | - } | |
332 | - } | |
333 | - // Respect the allowDrop field on Tree nodes | |
334 | - if (position === 'append' && targetNode.get('allowDrop') === false) { | |
335 | - return false; | |
336 | - } | |
337 | - else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) { | |
338 | - return false; | |
339 | - } | |
340 | - // If the target record is in the dragged dataset, then invalid drop | |
341 | - if (Ext.Array.contains(draggedRecords, targetNode)) { | |
342 | - return false; | |
343 | - } | |
344 | - // | |
345 | - if (dataLength > 1) | |
346 | - return false; | |
347 | - | |
348 | - var draggedRecord = draggedRecords[0]; | |
349 | - // | |
350 | - switch (targetNode.data.nodeType) | |
351 | - { | |
352 | - case 'localParam' : | |
353 | - case 'remoteParam' : | |
354 | - case 'remoteSimuParam' : | |
355 | - case 'myData' : | |
356 | - return false; | |
357 | - default : | |
358 | - if (draggedRecord.data.id == targetNode.data.nodeType+'-treeRootNode') | |
359 | - return false; | |
360 | - if ((position == 'before') && (targetNode.data.id == targetNode.data.nodeType+'-treeRootNode')) | |
361 | - return false; | |
362 | - return (draggedRecord.data.nodeType == targetNode.data.nodeType); | |
363 | - } | |
364 | - return false; | |
365 | - }, | |
366 | - onViewRender : function(view) | |
367 | - { | |
368 | - var me = this; | |
369 | - | |
370 | - view.on('itemupdate', function(record,index,node,opts) | |
371 | - { | |
372 | - var forceHide = false; | |
373 | - var crtRec = record.parentNode; | |
374 | - while (crtRec && !forceHide) | |
375 | - { | |
376 | - if (crtRec.get('filtered')) | |
377 | - forceHide = crtRec.get('filtered'); | |
378 | - crtRec = crtRec.parentNode; | |
379 | - } | |
380 | - tree.setNodesVisibility(record,forceHide); | |
381 | - tree.applyDisableToNode(record); | |
382 | - }); | |
383 | - | |
384 | - view.on('itemadd', function(records,index,node,opts) | |
385 | - { | |
386 | - Ext.each(records,function (rec) | |
387 | - { | |
388 | - tree.applyFilterToNode(rec); | |
389 | - tree.applyDisableToNode(rec); | |
390 | - }); | |
391 | - }); | |
392 | - | |
393 | - view.on('afteritemexpand', function(record,index,node,opts) | |
394 | - { | |
395 | - var forceHide = false; | |
396 | - var crtRec = record.parentNode; | |
397 | - while (crtRec && !forceHide) | |
398 | - { | |
399 | - if (crtRec.get('filtered')) | |
400 | - forceHide = crtRec.get('filtered'); | |
401 | - crtRec = crtRec.parentNode; | |
402 | - | |
403 | - } | |
404 | - tree.setNodesVisibility(record,forceHide); | |
405 | - tree.applyDisableToNode(record); | |
406 | - }); | |
407 | - | |
408 | - if (me.enableDrag) | |
409 | - { | |
410 | - me.dragZone = Ext.create('Ext.tree.ViewDragZone', { | |
411 | - view: view, | |
412 | - ddGroup: me.dragGroup || me.ddGroup, | |
413 | - dragText: me.dragText, | |
414 | - repairHighlightColor: me.nodeHighlightColor, | |
415 | - repairHighlight: me.nodeHighlightOnRepair | |
416 | - }); | |
417 | - } | |
418 | - | |
419 | - if (me.enableDrop) | |
420 | - { | |
421 | - me.dropZone = Ext.create('Ext.tree.ViewDropZone', { | |
422 | - view: view, | |
423 | - ddGroup: me.dropGroup || me.ddGroup, | |
424 | - allowContainerDrops: me.allowContainerDrops, | |
425 | - appendOnly: me.appendOnly, | |
426 | - allowParentInserts: me.allowParentInserts, | |
427 | - expandDelay: me.expandDelay, | |
428 | - dropHighlightColor: me.nodeHighlightColor, | |
429 | - dropHighlight: me.nodeHighlightOnDrop, | |
430 | - isValidDropPoint : me.isValidDropPoint | |
431 | - }); | |
432 | - } | |
433 | - } | |
434 | - }, | |
435 | - listeners : | |
436 | - { | |
437 | - beforedrop : function(node, data, overModel, dropPosition) | |
438 | - { | |
439 | - var parentId; | |
440 | - switch(dropPosition) | |
441 | - { | |
442 | - case 'append' : | |
443 | - if (overModel.isLeaf()) | |
444 | - parentId = overModel.parentNode.get('id'); | |
445 | - else | |
446 | - parentId = overModel.get('id'); | |
447 | - | |
448 | - if(!overModel.isExpanded() && overModel.isExpandable()) { | |
449 | - myDesktopApp.warningMsg('Please open the folder before node adding'); | |
450 | - return false; | |
451 | - } | |
452 | - break; | |
453 | - case 'before' : | |
454 | - case 'after' : | |
455 | - parentId = overModel.parentNode.get('id'); | |
456 | - break; | |
457 | - } | |
458 | - | |
459 | - Ext.each(data.records, function(rec) | |
460 | - { | |
461 | - rec.renameDD(parentId,function(result) | |
462 | - { | |
463 | - if (result) | |
464 | - { | |
465 | - if (!result.id) | |
466 | - { | |
467 | - Ext.Msg.show({ | |
468 | - title : 'Drop is impossible', | |
469 | - msg : result.error, | |
470 | - buttons : Ext.Msg.OK, | |
471 | - icon : Ext.MessageBox.WARNING | |
472 | - }); | |
473 | - | |
474 | - return false; | |
475 | - } | |
476 | - } | |
477 | - else | |
478 | - { | |
479 | - Ext.Msg.show({ | |
480 | - title : 'Drop is impossible', | |
481 | - msg : 'Cannot connect to the server', | |
482 | - buttons : Ext.Msg.OK, | |
483 | - icon : Ext.MessageBox.WARNING | |
484 | - }); | |
485 | - | |
486 | - return false; | |
487 | - } | |
488 | - | |
489 | - return true; | |
490 | - }); | |
491 | - }); | |
492 | - } | |
493 | - } | |
494 | - }, | |
495 | - listeners: | |
496 | - { | |
497 | - itemmouseenter: function(view, record, item){ | |
498 | - if(record.get('isParameter')){ | |
499 | - var el = Ext.get(item), | |
500 | - td = el.down('td > div'); | |
501 | - td.setStyle('cursor', 'crosshair'); | |
502 | - } | |
503 | - else | |
504 | - { | |
505 | - var el = Ext.get(item), | |
506 | - td = el.down('td > div'); | |
507 | - td.setStyle('cursor', 'pointer'); | |
508 | - } | |
509 | - }, | |
510 | - | |
511 | - itemcontextmenu: function(view, rec, item, index, e){ | |
512 | - // Add record to selection model | |
513 | - view.ownerCt.getSelectionModel().select(rec); | |
514 | - | |
515 | - // block other events | |
516 | - e.stopEvent(); | |
517 | - | |
518 | - // clear menu items | |
519 | - menu.removeAll(); | |
520 | - var menuItems; | |
521 | - | |
522 | - // if it's a single selection | |
523 | - if (view.ownerCt.getSelectionModel().selected.length === 1) { | |
524 | - // get items menu corresponding to right clicked record | |
525 | - menuItems = rec.getContextMenuItems(this); | |
526 | - | |
527 | - } else if (view.ownerCt.getSelectionModel().selected.length > 1) { | |
528 | - // get items menu corresponding to right clicked record | |
529 | - menuItems = rec.getContextMenuMultiItems(this); | |
530 | - } | |
531 | - // if there's at least one item menu | |
532 | - if (menuItems && menuItems.length){ | |
533 | - // add the items | |
534 | - menu.add(menuItems); | |
535 | - // add listener on right clicked record | |
536 | - var onRecordClick = function (menu, item, e, eOpts) | |
537 | - { | |
538 | - if (this.myGetOwnerTree().getSelectionModel().isSelected(this)) { | |
539 | - //Dispatch click event to the record | |
540 | - this.onMenuItemClick(menu,item,e); | |
541 | - } | |
542 | - //Remove old click listener | |
543 | - menu.removeListener('click',onRecordClick,this); | |
544 | - }; | |
545 | - | |
546 | - menu.addListener('click',onRecordClick,rec); | |
547 | - // then show menu | |
548 | - menu.showAt(e.getXY()); | |
549 | - } | |
550 | - }, | |
551 | - | |
552 | - itemdblclick: function(view, record, item, index, event){ | |
553 | - event.stopEvent(); | |
554 | - // first check if it is for SAVE-START-STOP plugin... | |
555 | - if (Ext.PluginManager.getCount() > 0 && | |
556 | - record.get('nodeType') == amdaModel.TimeTableNode.nodeType && record.isLeaf()) { | |
557 | - var zmgr = myDesktopApp.desktop.getDesktopZIndexManager(); | |
558 | - var winActive = zmgr.getActive(); | |
559 | - var winId = winActive.getId(); | |
560 | - if (winId == 'explorer-win') { | |
561 | - zmgr.eachTopDown(function(win) { | |
562 | - var id = win.getId(); | |
563 | - if (id !== 'explorer-win') { | |
564 | - winId = id; | |
565 | - return false; | |
566 | - } | |
567 | - }); | |
568 | - } | |
569 | - } | |
570 | - | |
571 | - if (record.get('nodeType') == 'remoteParam' && !record.isLeaf() | |
572 | - && !record.get('isParameter')) { | |
573 | - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) { | |
574 | - module.createWindow(record.getBaseId()); | |
575 | - }); | |
576 | - } | |
577 | - | |
578 | - if (record.isLeaf() || record.data.isParameter) | |
579 | - switch (record.get('nodeType')) | |
580 | - { | |
581 | - case 'myData' : | |
582 | - case 'myDataParam' : | |
583 | - case 'derivedParam' : | |
584 | - case 'timeTable' : | |
585 | - case 'sharedtimeTable' : | |
586 | - case 'sharedcatalog' : | |
587 | - case 'catalog' : | |
588 | - case 'request' : | |
589 | - case 'condition' : | |
590 | - record.editLeaf(); | |
591 | - break; | |
592 | - case 'localParam' : | |
593 | - case 'remoteParam': | |
594 | - case 'remoteSimuParam': | |
595 | - record.createAlias(record); | |
596 | - break; | |
597 | - case 'bkgWorks' : | |
598 | - if (!record.get('object')) { | |
599 | - AmdaAction.getObject(record.get('id'), record.get('nodeType'), record.getObjectCallback, record); | |
600 | - } | |
601 | - else { | |
602 | - if (record.get('status') == 'done') { | |
603 | - var isInteractive = false; | |
604 | - var isNewTab = true; | |
605 | - record.editNode(isNewTab, isInteractive); | |
606 | - } | |
607 | - else { | |
608 | - myDesktopApp.infoMsg('Job Status: ' + record.get('status')); | |
609 | - } | |
610 | - } | |
611 | - break; | |
612 | - } | |
613 | - }, | |
614 | - | |
615 | - beforeselect: function(view,node,index,options){ | |
616 | - // if there's at least one node already selected | |
617 | - if(view.selected.length | |
618 | - //AND (the node which is beeing selected has a different nodeType than the first selected node OR the first selected node isn't a leaf | |
619 | - && ( node.get('nodeType')!== view.selected.items[0].get('nodeType') || !view.selected.items[0].isLeaf()) | |
620 | - // OR the node which is beeing selected has no nodeType OR it isn't a leaf OR | |
621 | - || !node.get('nodeType') || !node.isLeaf() | |
622 | - ){ | |
623 | - // clear old selection | |
624 | - view.deselectAll(); | |
625 | - } | |
626 | - }, | |
627 | - | |
628 | - afterrender: function(comp){ | |
629 | - var view = comp.getView(); | |
630 | - view.tip = Ext.create('Ext.tip.ToolTip', { | |
631 | - // The overall target element. | |
632 | - target: view.el, | |
633 | - // Each grid row causes its own seperate show and hide. | |
634 | - delegate: view.itemSelector, | |
635 | - dismissDelay : 0, | |
636 | - // showDelay: 100, | |
637 | - // anchor: 'left', | |
638 | - // Moving within the row should not hide the tip. | |
639 | - trackMouse: true, | |
640 | - autoRender: true, | |
641 | - listeners: { | |
642 | - // Change content dynamically depending on which element triggered the show. | |
643 | - beforeshow: function updateTipBody(tip) { | |
644 | - if (view.getRecord(tip.triggerElement)) { | |
645 | - var info = view.getRecord(tip.triggerElement).get('info'); | |
646 | - if (!info || info == '') { | |
647 | - tip.addCls('hide'); | |
648 | - } | |
649 | - else { | |
650 | - tip.removeCls('hide'); | |
651 | - tip.update(info); | |
652 | - } | |
653 | - } | |
654 | - } | |
655 | - } | |
656 | - }); | |
657 | - }, | |
658 | - // if remote base is empty - open interoperability module | |
659 | - itemexpand: function(node) { | |
660 | - if ( node.get('nodeType') == amdaModel.RemoteParamNode.nodeType | |
661 | - && node.getDepth() == 3 && !node.hasChildNodes()) { | |
662 | - node.addData(); | |
663 | - } | |
664 | - }, | |
665 | - scope: this | |
666 | - }, | |
667 | - | |
668 | - hideHeaders: true, | |
669 | - // must define a column with a field to enable editor | |
670 | - columns: [{ | |
671 | - xtype : 'treetoolcolumn', | |
672 | - text : 'Name', | |
673 | - flex : 1, | |
674 | - dataIndex: 'text', | |
675 | - tool: 'info', // this references the "tools" object on the prototype | |
676 | - toolHandler: function(view, cell, recordIndex, cellIndex, e) { | |
677 | - var tooltype = e.target.getAttribute("tooltype"); | |
678 | - var record = view.store.getAt(recordIndex); | |
679 | - switch (tooltype) | |
680 | - { | |
681 | - case 'info' : | |
682 | - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.info.id, true, function (module) { | |
683 | - module.createWindow(record.get('help'), record.get('text')); | |
684 | - }); | |
685 | - break; | |
686 | - } | |
687 | - }, | |
688 | - toolIsVisible : function(record) { | |
689 | - | |
690 | - switch (record.get('nodeType')) | |
691 | - { | |
692 | - case 'localParam' : | |
693 | - case 'remoteParam' : | |
694 | - case 'remoteSimuParam' : | |
695 | - | |
696 | - return record.get('help') != ''; | |
697 | - } | |
698 | - return false; | |
699 | - }, | |
700 | - field: { | |
701 | - validFlag: false, | |
702 | - validator : function(value) { | |
703 | - // get explorerModule | |
704 | - var explModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
705 | - var explUI = explModule.getUiContent(); | |
706 | - var activeTreePanel = explUI.getActiveTab(); | |
707 | - | |
708 | - var editedNode = activeTreePanel.getSelectionModel().selected.items[0]; | |
709 | - if (editedNode) { | |
710 | - if (!editedNode.get('id') && value === amdaModel.AmdaNode.NEW_DIR_NAME){ | |
711 | - return false; | |
712 | - } else { | |
713 | - return this.validFlag; | |
714 | - } | |
715 | - } else { | |
716 | - return true; | |
717 | - } | |
718 | - }, | |
719 | - listeners: { | |
720 | - change : function( field, newValue, oldValue, eOpts ) | |
721 | - { | |
722 | - var explModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
723 | - var explUI = explModule.getUiContent(); | |
724 | - var activeTreePanel = explUI.getActiveTab(); | |
725 | - | |
726 | - var editedNode = activeTreePanel.getSelectionModel().selected.items[0]; | |
727 | - if (editedNode) { | |
728 | - editedNode.isValidName(newValue, function (res) { | |
729 | - if (!res) | |
730 | - { | |
731 | - field.validFlag = 'Error during object validation'; | |
732 | - field.validate(); | |
733 | - return; | |
734 | - } | |
735 | - if (!res.valid) | |
736 | - { | |
737 | - if (res.error) | |
738 | - { | |
739 | - field.validFlag = res.error; | |
740 | - field.validate(); | |
741 | - return; | |
742 | - } | |
743 | - else | |
744 | - { | |
745 | - field.validFlag = 'Invalid object name'; | |
746 | - field.validate(); | |
747 | - return; | |
748 | - } | |
749 | - } | |
750 | - | |
751 | - field.validFlag = true; | |
752 | - field.validate(); | |
753 | - }); | |
754 | - } | |
755 | - } | |
756 | - }, | |
757 | - scope: this | |
758 | - } | |
759 | - }], | |
760 | - //add our custom editor plugin | |
761 | - plugins: [ new MyTreeEditor({ | |
762 | - pluginId: 'treeEditor', | |
763 | - listeners: { | |
764 | - 'canceledit' : function(editor, context) { | |
765 | - if (editor && editor.startValue===amdaModel.AmdaNode.NEW_DIR_NAME) { | |
766 | - context.record.remove(true); | |
767 | - } | |
768 | - } | |
769 | - } | |
770 | - })], | |
771 | - | |
772 | - setNodesVisibility : function(node,forceHide) | |
773 | - { | |
774 | - var isFiltered = node.get('filtered'); | |
775 | - | |
776 | - for (var i = 0; i < node.childNodes.length; i++) | |
777 | - this.setNodesVisibility(node.childNodes[i],forceHide || isFiltered); | |
778 | - | |
779 | - this.setNodeVisibility(node,!(forceHide || isFiltered)); | |
780 | - }, | |
781 | - | |
782 | - setNodeVisibility : function(node,isVisible) | |
783 | - { | |
784 | - var record = store.getNodeById(node.internalId); | |
785 | - var viewNode = Ext.fly(tree.getView().getNode(record)); | |
786 | - if (viewNode) | |
787 | - { | |
788 | - viewNode.setVisibilityMode(Ext.Element.DISPLAY); | |
789 | - if (isVisible) | |
790 | - { | |
791 | - viewNode.show(); | |
792 | - this.applyDisableToNode(record); | |
793 | - } | |
794 | - else | |
795 | - viewNode.hide(); | |
796 | - } | |
797 | - }, | |
798 | - | |
799 | - applyFilterToNode : function(node) | |
800 | - { | |
801 | - if (!node) | |
802 | - return; | |
803 | - | |
804 | - var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter; | |
805 | - | |
806 | - switch (node.get('nodeType')) | |
807 | - { | |
808 | - case 'localParam' : | |
809 | - if (!filter || !filter['param']) | |
810 | - { | |
811 | - //no filter applied | |
812 | - node.set('filtered',false); | |
813 | - return; | |
814 | - } | |
815 | - var pos = node.get('depth') - 3; //depth from local param root node | |
816 | - if (pos < 0 || pos > 2) | |
817 | - { | |
818 | - node.set('filtered',false); | |
819 | - return; | |
820 | - } | |
821 | - var isFiltered = true; | |
822 | - for (var i = 0; i < filter['param'].length; i++) | |
823 | - { | |
824 | - s = filter['param'][i].split(';'); | |
825 | - if (node.get('id') == s[pos]) | |
826 | - { | |
827 | - isFiltered = false; | |
828 | - break; | |
829 | - } | |
830 | - } | |
831 | - node.set('filtered',isFiltered); | |
832 | - break; | |
833 | - | |
834 | - case 'remoteSimuParam' : | |
835 | - if (!filter || !filter['simu'] ) | |
836 | - { | |
837 | - //no filter applied | |
838 | - node.set('filtered',false); | |
839 | - return; | |
840 | - } | |
841 | - var pos = node.get('depth') - 3; //depth from remote param root node | |
842 | - | |
843 | - if (pos < 0 || pos > 5) | |
844 | - { | |
845 | - node.set('filtered',false); | |
846 | - return; | |
847 | - } | |
848 | - var isFiltered = true; | |
849 | - | |
850 | - for (var i = 0; i < filter['simu'].length; i++) | |
851 | - { | |
852 | - s = filter['simu'][i].split(';'); | |
853 | - | |
854 | - if (node.get('id') == s[pos]) | |
855 | - { | |
856 | - isFiltered = false; | |
857 | - break; | |
858 | - } | |
859 | - } | |
860 | - node.set('filtered',isFiltered); | |
861 | - break; | |
862 | - /*case 'alias' : | |
863 | - if (!this.localParamFilter.result || this.localParamFilter.id == "" || | |
864 | - !node.isLeaf()) | |
865 | - { | |
866 | - //no filter applied | |
867 | - node.set('filtered',false); | |
868 | - return; | |
869 | - } | |
870 | - var crtParam = node.get('id'); | |
871 | - crtParam = crtParam.replace('alias_',''); | |
872 | - crtParam = crtParam.replace(/_/g,':'); | |
873 | - var isFiltered = true; | |
874 | - for (var i = 0; i < this.localParamFilter.result.length; i++) | |
875 | - { | |
876 | - s = this.localParamFilter.result[i].split(';'); | |
877 | - console.log(s[2]); | |
878 | - if (crtParam == s[2]) | |
879 | - { | |
880 | - isFiltered = false; | |
881 | - break; | |
882 | - } | |
883 | - } | |
884 | - node.set('filtered',isFiltered); | |
885 | - break;*/ | |
886 | - default : | |
887 | - return; | |
888 | - } | |
889 | - }, | |
890 | - | |
891 | - applyFilterToNodes : function(node) | |
892 | - { | |
893 | - node.eachChild(function (child){ | |
894 | - tree.applyFilterToNodes(child); | |
895 | - }); | |
896 | - tree.applyFilterToNode(node); | |
897 | - }, | |
898 | - | |
899 | - applyDisableToNode : function(node) | |
900 | - { | |
901 | - var crtNode = node; | |
902 | - var disable = false; | |
903 | - | |
904 | - do | |
905 | - { | |
906 | - if (crtNode.get('disable')) | |
907 | - { | |
908 | - disable = true; | |
909 | - break; | |
910 | - } | |
911 | - crtNode = crtNode.parentNode; | |
912 | - } while (crtNode); | |
913 | - | |
914 | - | |
915 | - var viewNode = Ext.fly(tree.getView().getNode(node)); | |
916 | - if (disable) | |
917 | - { | |
918 | - node.set('disable',true); | |
919 | - viewNode.setStyle('opacity',0.5); | |
920 | - } | |
921 | - } | |
922 | - }); | |
923 | - | |
924 | - tree.addEvents('edition'); | |
925 | - | |
926 | - return tree; | |
927 | - }, | |
928 | - | |
929 | - updateFilter : function() | |
930 | - { | |
931 | - var filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter; | |
932 | - | |
933 | - var keys = []; | |
934 | - for (var f in filter) { | |
935 | - if (hasOwnProperty.call(filter, f)) | |
936 | - keys.push(f); | |
937 | - } | |
938 | - | |
939 | - var tree = this.query('#'+amdaUI.ExplorerUI.RESRC_TAB.TREE_ID)[0]; | |
940 | - tree.getView().refresh(); | |
941 | - | |
942 | - for (var i = 0; i < keys.length; i++) | |
943 | - { | |
944 | - if (keys[i] == "_empty_") | |
945 | - continue; | |
946 | - | |
947 | - switch (keys[i]) | |
948 | - { | |
949 | - case 'param' : | |
950 | - //apply filter to local datasets | |
951 | - var localNode = tree.getRootNode().findChild('id','myLocalData-treeRootNode',true); | |
952 | - tree.applyFilterToNodes(localNode); | |
953 | - tree.setNodesVisibility(localNode,false); | |
954 | - tree.applyDisableToNode(localNode); | |
955 | - | |
956 | - //apply filter to aliases | |
957 | - var aliasNode = tree.getRootNode().findChild('id','alias-treeRootNode',true); | |
958 | - tree.applyFilterToNodes(aliasNode); | |
959 | - tree.setNodesVisibility(aliasNode,false); | |
960 | - tree.applyDisableToNode(aliasNode); | |
961 | - break; | |
962 | - | |
963 | - case 'simu' : | |
964 | - //apply filter to simulation datasets (in remote data) | |
965 | - var remoteNode = tree.getRootNode().findChild('id','myRemoteSimuData-treeRootNode',true); | |
966 | - tree.applyFilterToNodes(remoteNode); | |
967 | - tree.setNodesVisibility(remoteNode,false); | |
968 | - tree.applyDisableToNode(remoteNode); | |
969 | - break; | |
970 | - } | |
971 | - } | |
972 | - | |
973 | - this.dockedItems.getAt(1).items.items[0].select(filter['name']); | |
974 | - } | |
81 | + | |
82 | + extend: 'Ext.tab.Panel', | |
83 | + alias: 'widget.panelExplorer', | |
84 | + | |
85 | + statics: { | |
86 | + RESRC_TAB: { | |
87 | + TREE_ID: 'resourcesTree', | |
88 | + TREE_TYPE: 'resources' | |
89 | + }, | |
90 | + OPE_TAB: { | |
91 | + TREE_ID: 'operationsTree', | |
92 | + TREE_TYPE: 'operations' | |
93 | + }, | |
94 | + JOB_TAB: { | |
95 | + TREE_ID: 'jobsTree', | |
96 | + TREE_TYPE: 'jobs' | |
97 | + }, | |
98 | + | |
99 | + CAT_SUFFIX: '-treeBase', | |
100 | + ROOT_SUFFIX: '-treeRootNode', | |
101 | + SUB_ROOT_SUFFIX: 'RootNode', | |
102 | + | |
103 | + ITEM_KIND_BASE: 'base', | |
104 | + ITEM_KIND_ROOT: 'root', | |
105 | + ITEM_KIND_LEAF: 'leaf', | |
106 | + ITEM_KIND_DIRE: 'dire', | |
107 | + ITEM_KIND_PARA: 'para', | |
108 | + ITEM_KIND_MISS: 'miss' | |
109 | + }, | |
110 | + | |
111 | + initComponent: function (config) { | |
112 | + var explorerModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id), | |
113 | + myConf; | |
114 | + | |
115 | + myConf = { | |
116 | + split: true, | |
117 | + width: '100%', | |
118 | + height: '100%', | |
119 | + autoScroll: true, | |
120 | + border: true, | |
121 | + header: false, | |
122 | + defaults: { | |
123 | + // Applied to each contained panel | |
124 | + containerScroll: true | |
125 | + }, | |
126 | + stateful: true, | |
127 | + // StateId: 'tp1', | |
128 | + stateEvents: ['tabchange'], | |
129 | + getState: function () { | |
130 | + return {activeTab: this.items.findIndex('id', this.getActiveTab().id)}; | |
131 | + }, | |
132 | + applyState: function (s) { | |
133 | + this.setActiveTab(s.activeTab); | |
134 | + }, | |
135 | + items: [ | |
136 | + this.initTree(amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE), | |
137 | + this.initTree(amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE), | |
138 | + this.initTree(amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE) | |
139 | + ], | |
140 | + tbar: [ | |
141 | + { | |
142 | + xtype: 'combo', | |
143 | + fieldLabel: 'Filter', | |
144 | + labelWidth: 25, | |
145 | + width: 140, | |
146 | + store: explorerModule.filtersStore, | |
147 | + queryMode: 'local', | |
148 | + displayField: 'name', | |
149 | + valueField: 'id', | |
150 | + listeners: { | |
151 | + scope: this, | |
152 | + select: function (combo, records) { | |
153 | + AmdaAction.setCrtFilterId({id: records[0].get('id')}, function (result, e) { | |
154 | + if (e.status) { | |
155 | + if (result && explorerModule) { | |
156 | + explorerModule.setCrtFilter(); | |
157 | + } else { | |
158 | + Ext.Msg.show({ | |
159 | + title: 'Filter', | |
160 | + msg: 'Cannot apply filter', | |
161 | + modal: true, | |
162 | + icon: Ext.Msg.ERROR, | |
163 | + buttons: Ext.Msg.OK | |
164 | + }); | |
165 | + } | |
166 | + } else { | |
167 | + // FAILURE | |
168 | + Ext.Msg.show({ | |
169 | + title: 'Error System', | |
170 | + msg: e.message, | |
171 | + icon: Ext.MessageBox.ERROR, | |
172 | + buttons: Ext.Msg.OK | |
173 | + }); | |
174 | + } | |
175 | + }, this); | |
176 | + } | |
177 | + } | |
178 | + }, | |
179 | + { | |
180 | + text: '', | |
181 | + iconCls: 'icon-parameters', | |
182 | + tooltip: { | |
183 | + text: 'Edit Filter', | |
184 | + align: 'bl-tl' | |
185 | + }, | |
186 | + handler: function () { | |
187 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.filters.id, true, function (module) { | |
188 | + module.createWindow(); | |
189 | + }); | |
190 | + } | |
191 | + }, | |
192 | + { | |
193 | + text: '', | |
194 | + iconCls: 'icon-remover', | |
195 | + tooltip: { | |
196 | + text: 'Reset Filter', | |
197 | + align: 'bl-tl' | |
198 | + }, | |
199 | + handler: function () { | |
200 | + explorerModule.resetFilter(); | |
201 | + } | |
202 | + }, | |
203 | + '-', | |
204 | + { | |
205 | + xtype: 'displayfield', | |
206 | + fieldLabel: 'SortBy', | |
207 | + width: 40 | |
208 | + }, | |
209 | + { | |
210 | + text: 'Name', | |
211 | + scope: this, | |
212 | + tooltip: { | |
213 | + text: 'Sort out AMDA DataBase Data by Mission Name', | |
214 | + align: 'bl-tl' | |
215 | + }, | |
216 | + pressed: true, | |
217 | + enableToggle: true, | |
218 | + toggleGroup: 'sorting', | |
219 | + handler: function () { | |
220 | + var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
221 | + tree.getStore().sort([ | |
222 | + { | |
223 | + sorterFn: function (o1, o2) { | |
224 | + if (o1.get('nodeType') !== 'localParam') { | |
225 | + return; | |
226 | + } | |
227 | + | |
228 | + return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1; | |
229 | + } | |
230 | + } | |
231 | + ]); | |
232 | + this.updateFilter(); | |
233 | + } | |
234 | + }, | |
235 | + { | |
236 | + text: 'Target', | |
237 | + scope: this, | |
238 | + tooltip: { | |
239 | + text: 'Sort out AMDA DataBase Data by Mission Main Target', | |
240 | + align: 'bl-tl' | |
241 | + }, | |
242 | + enableToggle: true, | |
243 | + toggleGroup: 'sorting', | |
244 | + handler: function () { | |
245 | + var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); | |
246 | + tree.getStore().sort([{property: 'rank'}]); | |
247 | + this.updateFilter(); | |
248 | + } | |
249 | + } | |
250 | + ] | |
251 | + }; | |
252 | + Ext.apply(this, Ext.apply(arguments, myConf)); | |
253 | + this.callParent(arguments); | |
254 | + }, | |
255 | + | |
256 | + initTree: function (treeType) { | |
257 | + var menu, store, tree, treeId; | |
258 | + switch (treeType) { | |
259 | + case amdaUI.ExplorerUI.RESRC_TAB.TREE_TYPE: | |
260 | + treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID; | |
261 | + break; | |
262 | + case amdaUI.ExplorerUI.OPE_TAB.TREE_TYPE: | |
263 | + treeId = amdaUI.ExplorerUI.OPE_TAB.TREE_ID; | |
264 | + break; | |
265 | + case amdaUI.ExplorerUI.JOB_TAB.TREE_TYPE: | |
266 | + treeId = amdaUI.ExplorerUI.JOB_TAB.TREE_ID; | |
267 | + break; | |
268 | + default: | |
269 | + treeId = amdaUI.ExplorerUI.RESRC_TAB.TREE_ID; | |
270 | + break; | |
271 | + } | |
272 | + | |
273 | + store = Ext.create('Ext.data.TreeStore', { | |
274 | + root: { | |
275 | + expanded: true, | |
276 | + nodeType: treeType | |
277 | + }, | |
278 | + model: 'amdaModel.AmdaNode', | |
279 | + sorters: [ | |
280 | + { | |
281 | + direction: 'ASC', | |
282 | + sorterFn: function (o1, o2) { | |
283 | + if (o1.get('nodeType') !== 'localParam') { | |
284 | + return; | |
285 | + } | |
286 | + | |
287 | + return o1.get('text').toUpperCase() < o2.get('text').toUpperCase() ? -1 : 1; | |
288 | + } | |
289 | + } | |
290 | + ], | |
291 | + listeners: { | |
292 | + beforeload: function (_store, operation) { | |
293 | + _store.proxy.extraParams = {nodeType: operation.node.get('nodeType')}; | |
294 | + } | |
295 | + } | |
296 | + }); | |
297 | + | |
298 | + menu = new Ext.menu.Menu(); | |
299 | + | |
300 | + tree = Ext.create('Ext.tree.Panel', { | |
301 | + id: treeId, | |
302 | + title: treeType, | |
303 | + store: store, | |
304 | + rootVisible: false, | |
305 | + animate: false, | |
306 | + hideHeaders: true, | |
307 | + selModel: Ext.create('Ext.selection.TreeModel', { | |
308 | + // IgnoreRightMouseSelection: true, | |
309 | + mode: 'MULTI' | |
310 | + }), | |
311 | + viewConfig: { | |
312 | + plugins: { | |
313 | + ptype: 'treeviewdragdrop', | |
314 | + enableDrag: true, | |
315 | + enableDrop: true, | |
316 | + // TODO - BRE - Wait a fix for drag&drop issue | |
317 | + ddGroup: 'explorerTree', | |
318 | + pluginId: 'ddplugin', | |
319 | + | |
320 | + isValidDropPoint: function (node, position, dragZone, e, data) { | |
321 | + if (!node || !data.item) { | |
322 | + return false; | |
323 | + } | |
324 | + var view = this.view, | |
325 | + targetNode = view.getRecord(node), | |
326 | + draggedRecords = data.records, | |
327 | + dataLength = draggedRecords.length, | |
328 | + ln = draggedRecords.length, | |
329 | + i, record; | |
330 | + | |
331 | + // No drop position, or dragged records: invalid drop point | |
332 | + if (!(targetNode && position && dataLength)) { | |
333 | + return false; | |
334 | + } | |
335 | + // If the targetNode is within the folder we are dragging | |
336 | + for (i = 0; i < ln; i++) { | |
337 | + record = draggedRecords[i]; | |
338 | + if (record.isNode && record.contains(targetNode)) { | |
339 | + return false; | |
340 | + } | |
341 | + } | |
342 | + // Respect the allowDrop field on Tree nodes | |
343 | + if (position === 'append' && targetNode.get('allowDrop') === false) { | |
344 | + return false; | |
345 | + } else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) { | |
346 | + return false; | |
347 | + } | |
348 | + // If the target record is in the dragged dataset, then invalid drop | |
349 | + if (Ext.Array.contains(draggedRecords, targetNode)) { | |
350 | + return false; | |
351 | + } | |
352 | + // | |
353 | + if (dataLength > 1) { | |
354 | + return false; | |
355 | + } | |
356 | + | |
357 | + var draggedRecord = draggedRecords[0]; | |
358 | + // | |
359 | + switch (targetNode.data.nodeType) { | |
360 | + case 'localParam': | |
361 | + case 'remoteParam': | |
362 | + case 'remoteSimuParam': | |
363 | + case 'myData': | |
364 | + return false; | |
365 | + default: | |
366 | + if (draggedRecord.data.id == targetNode.data.nodeType + '-treeRootNode') { | |
367 | + return false; | |
368 | + } | |
369 | + if (position == 'before' && targetNode.data.id == targetNode.data.nodeType + '-treeRootNode') { | |
370 | + return false; | |
371 | + } | |
372 | + return draggedRecord.data.nodeType == targetNode.data.nodeType; | |
373 | + } | |
374 | + return false; | |
375 | + }, | |
376 | + onViewRender: function (view) { | |
377 | + var me = this; | |
378 | + | |
379 | + view.on('itemupdate', function (record) { | |
380 | + var forceHide = false, | |
381 | + crtRec = record.parentNode; | |
382 | + | |
383 | + while (crtRec && !forceHide) { | |
384 | + if (crtRec.get('filtered')) { | |
385 | + forceHide = crtRec.get('filtered'); | |
386 | + } | |
387 | + crtRec = crtRec.parentNode; | |
388 | + } | |
389 | + tree.setNodesVisibility(record, forceHide); | |
390 | + tree.applyDisableToNode(record); | |
391 | + }); | |
392 | + | |
393 | + view.on('itemadd', function (records) { | |
394 | + Ext.each(records, function (rec) { | |
395 | + tree.applyFilterToNode(rec); | |
396 | + tree.applyDisableToNode(rec); | |
397 | + }); | |
398 | + }); | |
399 | + | |
400 | + view.on('afteritemexpand', function (record) { | |
401 | + var crtRec, forceHide; | |
402 | + forceHide = false; | |
403 | + crtRec = record.parentNode; | |
404 | + while (crtRec && !forceHide) { | |
405 | + if (crtRec.get('filtered')) { | |
406 | + forceHide = crtRec.get('filtered'); | |
407 | + } | |
408 | + crtRec = crtRec.parentNode; | |
409 | + | |
410 | + } | |
411 | + tree.setNodesVisibility(record, forceHide); | |
412 | + tree.applyDisableToNode(record); | |
413 | + }); | |
414 | + | |
415 | + if (me.enableDrag) { | |
416 | + me.dragZone = Ext.create('Ext.tree.ViewDragZone', { | |
417 | + view: view, | |
418 | + ddGroup: me.dragGroup || me.ddGroup, | |
419 | + dragText: me.dragText, | |
420 | + repairHighlightColor: me.nodeHighlightColor, | |
421 | + repairHighlight: me.nodeHighlightOnRepair | |
422 | + }); | |
423 | + } | |
424 | + | |
425 | + if (me.enableDrop) { | |
426 | + me.dropZone = Ext.create('Ext.tree.ViewDropZone', { | |
427 | + view: view, | |
428 | + ddGroup: me.dropGroup || me.ddGroup, | |
429 | + allowContainerDrops: me.allowContainerDrops, | |
430 | + appendOnly: me.appendOnly, | |
431 | + allowParentInserts: me.allowParentInserts, | |
432 | + expandDelay: me.expandDelay, | |
433 | + dropHighlightColor: me.nodeHighlightColor, | |
434 | + dropHighlight: me.nodeHighlightOnDrop, | |
435 | + isValidDropPoint: me.isValidDropPoint | |
436 | + }); | |
437 | + } | |
438 | + } | |
439 | + }, | |
440 | + listeners: { | |
441 | + beforedrop: function (node, data, overModel, dropPosition) { | |
442 | + var parentId; | |
443 | + switch (dropPosition) { | |
444 | + case 'append': | |
445 | + if (overModel.isLeaf()) { | |
446 | + parentId = overModel.parentNode.get('id'); | |
447 | + } else { | |
448 | + parentId = overModel.get('id'); | |
449 | + } | |
450 | + | |
451 | + if (!overModel.isExpanded() && overModel.isExpandable()) { | |
452 | + myDesktopApp.warningMsg('Please open the folder before node adding'); | |
453 | + return false; | |
454 | + } | |
455 | + break; | |
456 | + case 'before': | |
457 | + case 'after': | |
458 | + parentId = overModel.parentNode.get('id'); | |
459 | + break; | |
460 | + default: | |
461 | + break; | |
462 | + } | |
463 | + | |
464 | + Ext.each(data.records, function (rec) { | |
465 | + rec.renameDD(parentId, function (result) { | |
466 | + if (result) { | |
467 | + if (!result.id) { | |
468 | + Ext.Msg.show({ | |
469 | + title: 'Drop is impossible', | |
470 | + msg: result.error, | |
471 | + buttons: Ext.Msg.OK, | |
472 | + icon: Ext.MessageBox.WARNING | |
473 | + }); | |
474 | + | |
475 | + return false; | |
476 | + } | |
477 | + } else { | |
478 | + Ext.Msg.show({ | |
479 | + title: 'Drop is impossible', | |
480 | + msg: 'Cannot connect to the server', | |
481 | + buttons: Ext.Msg.OK, | |
482 | + icon: Ext.MessageBox.WARNING | |
483 | + }); | |
484 | + | |
485 | + return false; | |
486 | + } | |
487 | + | |
488 | + return true; | |
489 | + }); | |
490 | + }); | |
491 | + } | |
492 | + } | |
493 | + }, | |
494 | + listeners: { | |
495 | + itemmouseenter: function (view, record, item) { | |
496 | + Ext.get(item).down('td > div').setStyle('cursor', record.get('isParameter') ? 'pointer' : 'crosshair'); | |
497 | + }, | |
498 | + | |
499 | + itemcontextmenu: function (view, rec, item, index, e) { | |
500 | + var menuItems; | |
501 | + | |
502 | + // Add record to selection model | |
503 | + view.ownerCt.getSelectionModel().select(rec); | |
504 | + | |
505 | + // Block other events | |
506 | + e.stopEvent(); | |
507 | + | |
508 | + // Clear menu items | |
509 | + menu.removeAll(); | |
510 | + | |
511 | + // If it's a single selection | |
512 | + if (view.ownerCt.getSelectionModel().selected.length === 1) { | |
513 | + // Get items menu corresponding to right clicked record | |
514 | + menuItems = rec.getContextMenuItems(this); | |
515 | + | |
516 | + } else if (view.ownerCt.getSelectionModel().selected.length > 1) { | |
517 | + // Get items menu corresponding to right clicked record | |
518 | + menuItems = rec.getContextMenuMultiItems(this); | |
519 | + } | |
520 | + // If there's at least one item menu | |
521 | + if (menuItems && menuItems.length) { | |
522 | + // Add the items | |
523 | + menu.add(menuItems); | |
524 | + | |
525 | + // Add listener on right clicked record | |
526 | + var onRecordClick = function (menu, item, e) { | |
527 | + if (this.myGetOwnerTree().getSelectionModel().isSelected(this)) { | |
528 | + // Dispatch click event to the record | |
529 | + this.onMenuItemClick(menu, item, e); | |
530 | + } | |
531 | + // Remove old click listener | |
532 | + menu.removeListener('click', onRecordClick, this); | |
533 | + }; | |
534 | + | |
535 | + menu.addListener('click', onRecordClick, rec); | |
536 | + // Then show menu | |
537 | + menu.showAt(e.getXY()); | |
538 | + } | |
539 | + }, | |
540 | + | |
541 | + itemdblclick: function (view, record, item, index, event) { | |
542 | + var zmgr, winId; | |
543 | + | |
544 | + event.stopEvent(); | |
545 | + // First check if it is for SAVE-START-STOP plugin... | |
546 | + if (Ext.PluginManager.getCount() > 0 && | |
547 | + record.get('nodeType') == amdaModel.TimeTableNode.nodeType && record.isLeaf()) { | |
548 | + zmgr = myDesktopApp.desktop.getDesktopZIndexManager(); | |
549 | + winId = zmgr.getActive().getId(); | |
550 | + if (winId == 'explorer-win') { | |
551 | + zmgr.eachTopDown(function (win) { | |
552 | + var id = win.getId(); | |
553 | + if (id !== 'explorer-win') { | |
554 | + winId = id; | |
555 | + return false; | |
556 | + } | |
557 | + }); | |
558 | + } | |
559 | + } | |
560 | + | |
561 | + if (record.get('nodeType') == 'remoteParam' && !record.isLeaf() && | |
562 | + !record.get('isParameter')) { | |
563 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) { | |
564 | + module.createWindow(record.getBaseId()); | |
565 | + }); | |
566 | + } | |
567 | + | |
568 | + if (record.isLeaf() || record.data.isParameter) { | |
569 | + switch (record.get('nodeType')) { | |
570 | + case 'myData': | |
571 | + case 'myDataParam': | |
572 | + case 'derivedParam': | |
573 | + case 'timeTable': | |
574 | + case 'sharedtimeTable': | |
575 | + case 'sharedcatalog': | |
576 | + case 'catalog': | |
577 | + case 'request': | |
578 | + case 'condition': | |
579 | + record.editLeaf(); | |
580 | + break; | |
581 | + case 'localParam': | |
582 | + case 'remoteParam': | |
583 | + case 'remoteSimuParam': | |
584 | + record.createAlias(record); | |
585 | + break; | |
586 | + case 'bkgWorks': | |
587 | + if (!record.get('object')) { | |
588 | + AmdaAction.getObject(record.get('id'), record.get('nodeType'), record.getObjectCallback, record); | |
589 | + } else if (record.get('status') == 'done') { | |
590 | + // IsInteractive = true, isNewTab = false | |
591 | + record.editNode(true, false); | |
592 | + } else { | |
593 | + myDesktopApp.infoMsg('Job Status: ' + record.get('status')); | |
594 | + } | |
595 | + break; | |
596 | + default: | |
597 | + break; | |
598 | + } | |
599 | + } | |
600 | + }, | |
601 | + | |
602 | + beforeselect: function (view, node) { | |
603 | + // If there's at least one node already selected | |
604 | + if (view.selected.length && | |
605 | + // AND (the node which is beeing selected has a different nodeType than the first selected node OR the first selected node isn't a leaf | |
606 | + (node.get('nodeType') !== view.selected.items[0].get('nodeType') || !view.selected.items[0].isLeaf()) || | |
607 | + // OR the node which is beeing selected has no nodeType OR it isn't a leaf OR | |
608 | + !node.get('nodeType') || !node.isLeaf() | |
609 | + ) { | |
610 | + // Clear old selection | |
611 | + view.deselectAll(); | |
612 | + } | |
613 | + }, | |
614 | + | |
615 | + afterrender: function (comp) { | |
616 | + var view = comp.getView(); | |
617 | + view.tip = Ext.create('Ext.tip.ToolTip', { | |
618 | + // The overall target element. | |
619 | + target: view.el, | |
620 | + // Each grid row causes its own seperate show and hide. | |
621 | + delegate: view.itemSelector, | |
622 | + dismissDelay: 0, | |
623 | + | |
624 | + /* | |
625 | + * ShowDelay: 100, | |
626 | + * anchor: 'left', | |
627 | + * Moving within the row should not hide the tip. | |
628 | + */ | |
629 | + trackMouse: true, | |
630 | + autoRender: true, | |
631 | + listeners: { | |
632 | + // Change content dynamically depending on which element triggered the show. | |
633 | + beforeshow: function updateTipBody (tip) { | |
634 | + var info; | |
635 | + if (view.getRecord(tip.triggerElement)) { | |
636 | + info = view.getRecord(tip.triggerElement).get('info'); | |
637 | + if (!info || info == '') { | |
638 | + tip.addCls('hide'); | |
639 | + } else { | |
640 | + tip.removeCls('hide'); | |
641 | + tip.update(info); | |
642 | + } | |
643 | + } | |
644 | + } | |
645 | + } | |
646 | + }); | |
647 | + }, | |
648 | + // If remote base is empty - open interoperability module | |
649 | + itemexpand: function (node) { | |
650 | + if (node.get('nodeType') == amdaModel.RemoteParamNode.nodeType && | |
651 | + node.getDepth() == 3 && !node.hasChildNodes()) { | |
652 | + node.addData(); | |
653 | + } | |
654 | + }, | |
655 | + scope: this | |
656 | + }, | |
657 | + | |
658 | + // Must define a column with a field to enable editor | |
659 | + columns: [ | |
660 | + { | |
661 | + xtype: 'treetoolcolumn', | |
662 | + text: 'Name', | |
663 | + flex: 1, | |
664 | + dataIndex: 'text', | |
665 | + // This references the "tools" object on the prototype | |
666 | + tool: 'info', | |
667 | + toolHandler: function (view, cell, recordIndex, cellIndex, e) { | |
668 | + var record = view.store.getAt(recordIndex); | |
669 | + switch (e.target.getAttribute('tooltype')) { | |
670 | + case 'info': | |
671 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.info.id, true, function (module) { | |
672 | + module.createWindow(record.get('help'), record.get('text')); | |
673 | + }); | |
674 | + break; | |
675 | + default: | |
676 | + break; | |
677 | + } | |
678 | + }, | |
679 | + toolIsVisible: function (record) { | |
680 | + | |
681 | + switch (record.get('nodeType')) { | |
682 | + case 'localParam': | |
683 | + case 'remoteParam': | |
684 | + case 'remoteSimuParam': | |
685 | + return record.get('help') != ''; | |
686 | + default: | |
687 | + break; | |
688 | + } | |
689 | + return false; | |
690 | + }, | |
691 | + field: { | |
692 | + validFlag: true, | |
693 | + listeners: { | |
694 | + change: function (field, newValue) { | |
695 | + var editedNode, explModule; | |
696 | + | |
697 | + explModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id); | |
698 | + editedNode = explModule.getUiContent().getActiveTab().getSelectionModel().selected.items[0]; | |
699 | + | |
700 | + if (editedNode) { | |
701 | + editedNode.isValidName(newValue, function (res) { | |
702 | + var validFlag = true; | |
703 | + if (newValue === amdaModel.AmdaNode.NEW_DIR_NAME) { | |
704 | + validFlag = 'Field is not modified'; | |
705 | + } else if (!res) { | |
706 | + validFlag = 'Error during object validation'; | |
707 | + } else if (!res.valid) { | |
708 | + if (res.error) { | |
709 | + validFlag = res.error; | |
710 | + } else { | |
711 | + validFlag = 'Invalid object name'; | |
712 | + } | |
713 | + } | |
714 | + if (validFlag !== true) { | |
715 | + field.markInvalid(validFlag); | |
716 | + } | |
717 | + field.validFlag = validFlag; | |
718 | + }); | |
719 | + } | |
720 | + } | |
721 | + }, | |
722 | + scope: this | |
723 | + } | |
724 | + } | |
725 | + ], | |
726 | + // Add our custom editor plugin | |
727 | + plugins: [ | |
728 | + new MyTreeEditor({ | |
729 | + pluginId: 'treeEditor', | |
730 | + listeners: { | |
731 | + beforeedit: function (editor, e) { | |
732 | + e.column.field.fireEvent('change', e.column.field, e.value, ''); | |
733 | + }, | |
734 | + validateedit: function (editor, e) { | |
735 | + if (e.column.field.validFlag !== true) { | |
736 | + if (e.record.deleteOnFailure) { | |
737 | + e.record.remove(true); | |
738 | + } else { | |
739 | + return false; | |
740 | + } | |
741 | + } | |
742 | + return true; | |
743 | + } | |
744 | + }, | |
745 | + scope: this | |
746 | + }) | |
747 | + ], | |
748 | + | |
749 | + setNodesVisibility: function (node, forceHide) { | |
750 | + var isFiltered = node.get('filtered'); | |
751 | + | |
752 | + for (var i = 0; i < node.childNodes.length; i++) { | |
753 | + this.setNodesVisibility(node.childNodes[i], forceHide || isFiltered); | |
754 | + } | |
755 | + | |
756 | + this.setNodeVisibility(node, !(forceHide || isFiltered)); | |
757 | + }, | |
758 | + | |
759 | + setNodeVisibility: function (node, isVisible) { | |
760 | + var record = store.getNodeById(node.internalId); | |
761 | + var viewNode = Ext.fly(tree.getView().getNode(record)); | |
762 | + if (viewNode) { | |
763 | + viewNode.setVisibilityMode(Ext.Element.DISPLAY); | |
764 | + if (isVisible) { | |
765 | + viewNode.show(); | |
766 | + this.applyDisableToNode(record); | |
767 | + } else { | |
768 | + viewNode.hide(); | |
769 | + } | |
770 | + } | |
771 | + }, | |
772 | + | |
773 | + applyFilterToNode: function (node) { | |
774 | + var filter, isFiltered, pos; | |
775 | + | |
776 | + if (!node) { | |
777 | + return; | |
778 | + } | |
779 | + | |
780 | + filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter; | |
781 | + | |
782 | + switch (node.get('nodeType')) { | |
783 | + case 'localParam': | |
784 | + if (!filter || !filter.param) { | |
785 | + // No filter applied | |
786 | + node.set('filtered', false); | |
787 | + return; | |
788 | + } | |
789 | + // Depth from local param root node | |
790 | + pos = node.get('depth') - 3; | |
791 | + if (pos < 0 || pos > 2) { | |
792 | + node.set('filtered', false); | |
793 | + return; | |
794 | + } | |
795 | + isFiltered = true; | |
796 | + for (var i = 0; i < filter.param.length; i++) { | |
797 | + if (node.get('id') == filter.param[i].split(';')[pos]) { | |
798 | + isFiltered = false; | |
799 | + break; | |
800 | + } | |
801 | + } | |
802 | + node.set('filtered', isFiltered); | |
803 | + break; | |
804 | + | |
805 | + case 'remoteSimuParam': | |
806 | + if (!filter || !filter.simu) { | |
807 | + // No filter applied | |
808 | + node.set('filtered', false); | |
809 | + return; | |
810 | + } | |
811 | + // Depth from remote param root node | |
812 | + pos = node.get('depth') - 3; | |
813 | + if (pos < 0 || pos > 5) { | |
814 | + node.set('filtered', false); | |
815 | + return; | |
816 | + } | |
817 | + isFiltered = true; | |
818 | + for (var i = 0; i < filter.simu.length; i++) { | |
819 | + if (node.get('id') == filter.simu[i].split(';')[pos]) { | |
820 | + isFiltered = false; | |
821 | + break; | |
822 | + } | |
823 | + } | |
824 | + node.set('filtered', isFiltered); | |
825 | + break; | |
826 | + | |
827 | + /* | |
828 | + * Case 'alias': | |
829 | + * if (!this.localParamFilter.result || this.localParamFilter.id == "" || !node.isLeaf()) { | |
830 | + * // No filter applied | |
831 | + * node.set('filtered',false); | |
832 | + * return; | |
833 | + * } | |
834 | + * var crtParam = node.get('id'); | |
835 | + * crtParam = crtParam.replace('alias_',''); | |
836 | + * crtParam = crtParam.replace(/_/g,':'); | |
837 | + * var isFiltered = true; | |
838 | + * for (var i = 0; i < this.localParamFilter.result.length; i++) { | |
839 | + * s = this.localParamFilter.result[i].split(';'); | |
840 | + * console.log(s[2]); | |
841 | + * if (crtParam == s[2]) { | |
842 | + * isFiltered = false; | |
843 | + * break; | |
844 | + * } | |
845 | + * } | |
846 | + * node.set('filtered',isFiltered); | |
847 | + * break; | |
848 | + */ | |
849 | + default: | |
850 | + | |
851 | + } | |
852 | + }, | |
853 | + | |
854 | + applyFilterToNodes: function (node) { | |
855 | + node.eachChild(function (child) { | |
856 | + tree.applyFilterToNodes(child); | |
857 | + }); | |
858 | + tree.applyFilterToNode(node); | |
859 | + }, | |
860 | + | |
861 | + applyDisableToNode: function (node) { | |
862 | + var crtNode, disable, viewNode; | |
863 | + | |
864 | + crtNode = node; | |
865 | + disable = false; | |
866 | + | |
867 | + do { | |
868 | + if (crtNode.get('disable')) { | |
869 | + disable = true; | |
870 | + break; | |
871 | + } | |
872 | + crtNode = crtNode.parentNode; | |
873 | + } while (crtNode); | |
874 | + | |
875 | + | |
876 | + viewNode = Ext.fly(tree.getView().getNode(node)); | |
877 | + if (disable) { | |
878 | + node.set('disable', true); | |
879 | + viewNode.setStyle('opacity', 0.5); | |
880 | + } | |
881 | + } | |
882 | + }); | |
883 | + | |
884 | + tree.addEvents('edition'); | |
885 | + | |
886 | + return tree; | |
887 | + }, | |
888 | + | |
889 | + updateFilter: function () { | |
890 | + var aliasNode, filter, keys, localNode, remoteNode, tree; | |
891 | + | |
892 | + filter = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id).filter; | |
893 | + | |
894 | + keys = []; | |
895 | + for (var f in filter) { | |
896 | + if (hasOwnProperty.call(filter, f)) { | |
897 | + keys.push(f); | |
898 | + } | |
899 | + } | |
900 | + | |
901 | + tree = this.query('#' + amdaUI.ExplorerUI.RESRC_TAB.TREE_ID)[0]; | |
902 | + tree.getView().refresh(); | |
903 | + | |
904 | + for (var i = 0; i < keys.length; i++) { | |
905 | + if (keys[i] == '_empty_') { | |
906 | + continue; | |
907 | + } | |
908 | + | |
909 | + switch (keys[i]) { | |
910 | + case 'param': | |
911 | + // Apply filter to local datasets | |
912 | + localNode = tree.getRootNode().findChild('id', 'myLocalData-treeRootNode', true); | |
913 | + tree.applyFilterToNodes(localNode); | |
914 | + tree.setNodesVisibility(localNode, false); | |
915 | + tree.applyDisableToNode(localNode); | |
916 | + | |
917 | + // Apply filter to aliases | |
918 | + aliasNode = tree.getRootNode().findChild('id', 'alias-treeRootNode', true); | |
919 | + tree.applyFilterToNodes(aliasNode); | |
920 | + tree.setNodesVisibility(aliasNode, false); | |
921 | + tree.applyDisableToNode(aliasNode); | |
922 | + break; | |
923 | + | |
924 | + case 'simu': | |
925 | + // Apply filter to simulation datasets (in remote data) | |
926 | + remoteNode = tree.getRootNode().findChild('id', 'myRemoteSimuData-treeRootNode', true); | |
927 | + tree.applyFilterToNodes(remoteNode); | |
928 | + tree.setNodesVisibility(remoteNode, false); | |
929 | + tree.applyDisableToNode(remoteNode); | |
930 | + break; | |
931 | + default: | |
932 | + break; | |
933 | + } | |
934 | + } | |
935 | + | |
936 | + this.dockedItems.getAt(1).items.items[0].select(filter.name); | |
937 | + } | |
975 | 938 | }); |
976 | 939 | |
977 | 940 | // MyTreeEditor |
978 | -Ext.define( 'MyTreeEditor', { | |
979 | - extend: 'Ext.grid.plugin.CellEditing', | |
980 | - alias: 'editing.treeeditor', | |
981 | - | |
982 | - // initialization method of plugin | |
983 | - init: function(cmp) { | |
984 | - var me = this; | |
985 | - me.hostCmp = cmp; | |
986 | - // on parent event | |
987 | - me.hostCmp.on({ | |
988 | - // on edition event | |
989 | - edition : { | |
990 | - delay: 50, | |
991 | - fn : function(view, record, item, index, e){ | |
992 | - view.getHeaderAtIndex(0).field.validFlag = 'Not modified'; | |
993 | - // call the start edition method | |
994 | - me.startEdit(record, view.getHeaderAtIndex(0)); | |
995 | - }, | |
996 | - scope: me | |
997 | - } | |
998 | - }); | |
999 | - me.callParent(arguments); | |
1000 | - }, | |
1001 | - | |
1002 | - /** | |
1003 | - * Cancel any active editing. | |
1004 | - */ | |
1005 | - cancelEdit: function() { | |
1006 | - var me = this, | |
1007 | - activeEd = me.getActiveEditor(), | |
1008 | - viewEl = me.grid.getView().getEl(me.getActiveColumn()); | |
1009 | - | |
1010 | - me.setActiveEditor(null); | |
1011 | - me.setActiveColumn(null); | |
1012 | - me.setActiveRecord(null); | |
1013 | - if (activeEd) { | |
1014 | - activeEd.cancelEdit(); | |
1015 | - viewEl.focus(); | |
1016 | - this.fireEvent('canceledit', activeEd, me.context); | |
1017 | - } | |
1018 | - }, | |
1019 | - | |
1020 | - /** | |
1021 | - * overwrite the initEditTriggers to disable edition on click/dblclick | |
1022 | - * and to add custom | |
1023 | - */ | |
1024 | - initEditTriggers: function() | |
1025 | - { | |
1026 | - var me = this, | |
1027 | - view = me.view; | |
1028 | - | |
1029 | - me.on({ | |
1030 | - edit: function(editor,event){ | |
1031 | - // if there is a modification | |
1032 | - if (event.originalValue !== event.value) { | |
1033 | - // delegate rename action on model | |
1034 | - event.record.rename(event.value,function(result){ | |
1035 | - // if a result has been returned : success | |
1036 | - if(result) { | |
1037 | - // delegate commit action to delete modification flag | |
1038 | - event.record.commit(); | |
1039 | - var rec = event.record.data; | |
1040 | - // in case of directory | |
1041 | - if (!rec.leaf){ | |
1042 | - // set folder's ID returned by server | |
1043 | - rec.id = result.id; | |
1044 | - } | |
1045 | - } else { // in case of transaction error | |
1046 | - // reset originalValue | |
1047 | - event.record.value = event.originalValue; | |
1048 | - event.record.get('text') = event.originalValue; | |
1049 | - event.record.commit(); | |
1050 | - } | |
1051 | - }); | |
1052 | - } | |
1053 | - } | |
1054 | - }); | |
1055 | - | |
1056 | - // enable Enter key and Esc Key | |
1057 | - view.on('render', function() { | |
1058 | - me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { | |
1059 | - enter: me.onEnterKey, | |
1060 | - esc: me.onEscKey, | |
1061 | - scope: me | |
1062 | - }); | |
1063 | - }, me, { single: true }); | |
1064 | - }, | |
1065 | - //overwrite the getEditing context because we do not need the rowId | |
1066 | - getEditingContext: function(record, columnHeader) { | |
1067 | - var me = this, | |
1068 | - grid = me.grid, | |
1069 | - store = grid.store, | |
1070 | - colIdx, | |
1071 | - view = grid.getView(), | |
1072 | - value; | |
1073 | - | |
1074 | - // getting colIdx and real columnHeader | |
1075 | - if (Ext.isNumber(columnHeader)) { | |
1076 | - colIdx = columnHeader; | |
1077 | - columnHeader = grid.headerCt.getHeaderAtIndex(colIdx); | |
1078 | - } else { | |
1079 | - colIdx = columnHeader.getIndex(); | |
1080 | - } | |
1081 | - // getting current value | |
1082 | - value = record.get(columnHeader.dataIndex); | |
1083 | - | |
1084 | - // return editing context | |
1085 | - return { | |
1086 | - grid: grid, | |
1087 | - record: record, | |
1088 | - field: columnHeader.dataIndex, | |
1089 | - value: value, | |
1090 | - column: columnHeader, | |
1091 | - colIdx: colIdx, | |
1092 | - view: columnHeader.getOwnerHeaderCt().view | |
1093 | - }; | |
1094 | - } | |
941 | +Ext.define('MyTreeEditor', { | |
942 | + extend: 'Ext.grid.plugin.CellEditing', | |
943 | + alias: 'editing.treeeditor', | |
944 | + | |
945 | + // Initialization method of plugin | |
946 | + init: function (cmp) { | |
947 | + var me = this; | |
948 | + me.hostCmp = cmp; | |
949 | + // On parent event | |
950 | + me.hostCmp.on({ | |
951 | + // On edition event | |
952 | + edition: { | |
953 | + delay: 50, | |
954 | + fn: function (view, record, item, index, e) { | |
955 | + | |
956 | + /* | |
957 | + * View.getHeaderAtIndex(0).field.validFlag = 'Not modified'; | |
958 | + * call the start edition method | |
959 | + */ | |
960 | + me.startEdit(record, view.getHeaderAtIndex(0)); | |
961 | + }, | |
962 | + scope: me | |
963 | + } | |
964 | + }); | |
965 | + me.callParent(arguments); | |
966 | + }, | |
967 | + | |
968 | + /** | |
969 | + * Cancel any active editing. | |
970 | + * @returns {void} | |
971 | + */ | |
972 | + cancelEdit: function () { | |
973 | + var me = this, | |
974 | + activeEd = me.getActiveEditor(), | |
975 | + viewEl = me.grid.getView().getEl(me.getActiveColumn()); | |
976 | + | |
977 | + me.setActiveEditor(null); | |
978 | + me.setActiveColumn(null); | |
979 | + me.setActiveRecord(null); | |
980 | + if (activeEd) { | |
981 | + activeEd.cancelEdit(); | |
982 | + viewEl.focus(); | |
983 | + this.fireEvent('canceledit', activeEd, me.context); | |
984 | + } | |
985 | + }, | |
986 | + | |
987 | + /** | |
988 | + * Overwrite the initEditTriggers to disable edition on click/dblclick and to add custom | |
989 | + * @returns {void} | |
990 | + */ | |
991 | + initEditTriggers: function () { | |
992 | + var me = this, | |
993 | + view = me.view; | |
994 | + | |
995 | + me.on({ | |
996 | + edit: function (editor, event) { | |
997 | + // If there is a modification | |
998 | + if (event.originalValue !== event.value) { | |
999 | + // Delegate rename action on model | |
1000 | + event.record.rename(event.value, function (result) { | |
1001 | + // If a result has been returned : success | |
1002 | + if (result) { | |
1003 | + // Delegate commit action to delete modification flag | |
1004 | + event.record.commit(); | |
1005 | + var rec = event.record.data; | |
1006 | + // In case of directory | |
1007 | + if (!rec.leaf) { | |
1008 | + // Set folder's ID returned by server | |
1009 | + rec.id = result.id; | |
1010 | + } | |
1011 | + } else { | |
1012 | + // In case of transaction error, reset originalValue | |
1013 | + event.record.value = event.originalValue; | |
1014 | + event.record.set('text', event.originalValue); | |
1015 | + event.record.commit(); | |
1016 | + } | |
1017 | + }); | |
1018 | + } | |
1019 | + } | |
1020 | + }); | |
1021 | + | |
1022 | + // Enable Enter key and Esc Key | |
1023 | + view.on('render', function () { | |
1024 | + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { | |
1025 | + enter: me.onEnterKey, | |
1026 | + esc: me.onEscKey, | |
1027 | + scope: me | |
1028 | + }); | |
1029 | + }, me, {single: true}); | |
1030 | + }, | |
1031 | + // Overwrite the getEditing context because we do not need the rowId | |
1032 | + getEditingContext: function (record, columnHeader) { | |
1033 | + var me = this, | |
1034 | + grid = me.grid, | |
1035 | + colIdx, | |
1036 | + value; | |
1037 | + | |
1038 | + // Getting colIdx and real columnHeader | |
1039 | + if (Ext.isNumber(columnHeader)) { | |
1040 | + colIdx = columnHeader; | |
1041 | + columnHeader = grid.headerCt.getHeaderAtIndex(colIdx); | |
1042 | + } else { | |
1043 | + colIdx = columnHeader.getIndex(); | |
1044 | + } | |
1045 | + // Getting current value | |
1046 | + value = record.get(columnHeader.dataIndex); | |
1047 | + | |
1048 | + // Return editing context | |
1049 | + return { | |
1050 | + grid: grid, | |
1051 | + record: record, | |
1052 | + field: columnHeader.dataIndex, | |
1053 | + value: value, | |
1054 | + column: columnHeader, | |
1055 | + colIdx: colIdx, | |
1056 | + view: columnHeader.getOwnerHeaderCt().view | |
1057 | + }; | |
1058 | + } | |
1095 | 1059 | }); |
... | ... |