]> git.argeo.org Git - gpl/argeo-slc.git/blob - server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/NewLauncherApplet.js
Do not set wrong content-type
[gpl/argeo-slc.git] / server / org.argeo.slc.ria / src / argeo-ria-lib / slc / class / org / argeo / slc / ria / NewLauncherApplet.js
1 /**
2 * A simple Hello World applet for documentation purpose.
3 * The only associated command is the "Close" command.
4 */
5 qx.Class.define("org.argeo.slc.ria.NewLauncherApplet",
6 {
7 extend : qx.ui.container.Composite,
8 implement : [org.argeo.ria.components.IView],
9
10 construct : function(){
11 this.base(arguments);
12 this.setLayout(new qx.ui.layout.Dock());
13 },
14
15 properties :
16 {
17 /**
18 * The viewPane inside which this applet is added.
19 */
20 view : {
21 init : null
22 },
23 viewSelection : {
24 nullable:false,
25 check:"org.argeo.ria.components.ViewSelection"
26 },
27 instanceId : {init:""},
28 instanceLabel : {init:""},
29 /**
30 * A boolean registering whether the SpecEditor must autoOpen or not when a spec is added to the Batch.
31 */
32 autoOpen : {
33 init : true,
34 check : "Boolean"
35 },
36 batchAgentId : {
37 init : null,
38 nullable : true,
39 check : "String",
40 event : "changeBatchAgentId"
41 },
42 /**
43 * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
44 */
45 commands : {
46 init : {
47 "submitform" : {
48 label : "Execute Batch",
49 icon : "resource/slc/media-playback-start.png",
50 shortcut : null,
51 enabled : false,
52 menu : "Launcher",
53 toolbar : "launcher",
54 callback : function(e){
55 if(this.getBatchAgentId()){
56 this.executeBatchOnAgent(this.getBatchAgentId());
57 }
58 },
59 command : null
60 },
61 "addtobatch" : {
62 label : "Add to batch",
63 icon : "resource/slc/list-add.png",
64 shortcut : null,
65 enabled : true,
66 menu : null,
67 toolbar : null,
68 callback : function(e){
69 this._addFlowToBatch();
70 },
71 selectionChange : function(viewId, selection){
72 if(viewId != "form:tree") return;
73 if(!selection || selection.length != 1) return;
74 var item = selection[0];
75 this.setEnabled(false);
76 switch(item.classname){
77 case "qx.ui.tree.TreeFile" :
78 this.setEnabled(true);
79 break;
80 case "qx.ui.tree.TreeFolder" :
81 if(item.getTree().getRoot() == item) break;
82 this.setEnabled(true);
83 break;
84 case "org.argeo.ria.components.DynamicTreeFolder":
85 if(item.getTree().getRoot() == item) break;
86 if(item.getState() == "loaded") this.setEnabled(true);
87 break;
88 }
89 },
90 command : null
91 },
92 "toggleopenonadd" : {
93 label : "Auto Open",
94 icon : "resource/slc/document-open.png",
95 shortcut : null,
96 enabled : true,
97 toggle : true,
98 toggleInitialState : true,
99 menu : "Launcher",
100 toolbar : "launcher",
101 callback : function(event){
102 var state = event.getTarget().getUserData("slc.command.toggleState");
103 this.setAutoOpen(state);
104 },
105 command : null
106 },
107 "editexecutionspecs" : {
108 label : "Edit Execution Specs",
109 icon : "resource/slc/document-open.png",
110 shortcut : null,
111 enabled : false,
112 menu : "Launcher",
113 toolbar : null,
114 callback : function(e){
115 var sel = this.list.getSortedSelection();
116 var spec = sel[0].getUserData("batchEntrySpec");
117 if(spec.hasEditableValues()){
118 var specEditor = new org.argeo.slc.ria.execution.SpecEditor(spec);
119 specEditor.attachAndShow();
120 }
121 },
122 selectionChange : function(viewId, selection){
123 if(viewId != "form:list") return;
124 this.setEnabled(false);
125 if((selection && selection.length == 1)) {
126 var selectedItemSpec = selection[0].getUserData("batchEntrySpec");
127 if(selectedItemSpec.hasEditableValues()){
128 this.setEnabled(true);
129 }
130 }
131 },
132 command : null
133 },
134 "removefrombatch" : {
135 label : "Remove from batch",
136 icon : "resource/slc/edit-delete.png",
137 shortcut : null,
138 enabled : false,
139 menu : "Launcher",
140 toolbar : null,
141 callback : function(e){
142 var sel = this.list.getSortedSelection();
143 var modal = new org.argeo.ria.components.Modal("Confirm", null);
144 modal.addConfirm("Are you sure you want to remove<br> the selected test" + (sel.length>1?"s":"") + " from the Batch?");
145 modal.addListener("ok", function(){
146 for(var i=0;i<sel.length;i++){
147 this.list.remove(sel[i]);
148 }
149 if(!this.list.hasChildren()){
150 this.setBatchAgentId(null);
151 }
152 }, this);
153 modal.attachAndShow();
154 },
155 selectionChange : function(viewId, selection){
156 if(viewId != "form:list") return;
157 this.setEnabled(false);
158 if((selection && selection.length > 0)) this.setEnabled(true);
159 },
160 command : null
161 },
162 "reloadtree" : {
163 label : "Reload",
164 icon : "resource/slc/view-refresh.png",
165 shortcut : "Control+m",
166 enabled : false,
167 menu : "Launcher",
168 toolbar : "launcher",
169 callback : function(e){
170 var selected = this.tree.getSelection()[0];
171 if(selected.classname == "org.argeo.ria.components.DynamicTreeFolder"){
172 if(selected.getUserData("moduleData")){
173 // It's a "module" node, first trigger the reloadBundle.service
174 selected.setUserData("dataModel", {});
175 selected.setEnabled(false);
176 selected.setOpen(false);
177 var moduleData = selected.getUserData("moduleData");
178 var bundleService = org.argeo.slc.ria.SlcApi.getReloadBundleService(moduleData.name, moduleData.version);
179 bundleService.addListener("completed", function(response){
180 selected.setEnabled(true);
181 selected.setOpen(true);
182 selected.reload();
183 }, this);
184 //bundleService.send();
185 //Do not send, not implemented yet, false timer instead.
186 qx.event.Timer.once(function(response){
187 selected.setEnabled(true);
188 selected.setOpen(true);
189 selected.reload();
190 }, this, 2000);
191 }else{
192 selected.reload();
193 }
194 }
195 },
196 selectionChange : function(viewId, selection){
197 if(viewId != "form:tree") return;
198 if(!selection) return;
199 if(selection.length > 1){
200 this.setEnabled(false);
201 return;
202 }
203 var item = selection[0];
204 if(!qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.AbstractTreeItem)) return;
205 this.setEnabled(false);
206 if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), org.argeo.ria.components.DynamicTreeFolder)){
207 this.setEnabled(true);
208 }
209 },
210 command : null
211 }
212 }
213 }
214 },
215
216 statics : {
217 /**
218 * Static loader for the "agent" level (first level)
219 * @param folder {qx.ui.tree.TreeFolder} The root Tree Folder.
220 */
221 agentLoader : function(folder){
222
223 var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
224 var agents = {};
225 req.addListener("completed", function(response){
226 var xmlDoc = response.getContent();
227 var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
228 //var newTopics = {};
229 var modulesLoader = org.argeo.slc.ria.NewLauncherApplet.modulesLoader;
230 for(var i=0;i<nodes.length;i++){
231 var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
232 var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
233 agents[uuid] = host;
234 var agentFolder = new org.argeo.ria.components.DynamicTreeFolder(
235 host + ' ('+uuid+')',
236 modulesLoader,
237 "Loading Modules...",
238 folder.getDragData()
239 );
240 agentFolder.setUserData("agentUuid", uuid);
241 agentFolder.setIcon("resource/slc/mime-xsl-22.png");
242 folder.add(agentFolder);
243 }
244 folder.setUserData("agentsMap", agents);
245 folder.setLoaded(true);
246 });
247 req.addListener("failed", function(response){folder.setLoaded(true);});
248 req.send();
249
250 },
251
252 /**
253 * Loader for the "modules" level : takes any tree folder, currently the root folder.
254 * @param folder {qx.ui.tree.TreeFolder} The root folder
255 */
256 modulesLoader : function(folder){
257 var agentId = folder.getUserData("agentUuid");
258 var req = org.argeo.slc.ria.SlcApi.getListModulesService(agentId);
259 req.addListener("completed", function(response){
260 var descriptors = org.argeo.ria.util.Element.selectNodes(response.getContent(), "slc:object-list/slc:execution-module-descriptor");
261 var mods = {};
262 for(var i=0;i<descriptors.length; i++){
263 var name = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:name");
264 var version = org.argeo.ria.util.Element.getSingleNodeText(descriptors[i], "slc:version");
265 if(!mods[name]) mods[name] = [];
266 mods[name].push(version);
267 }
268 var flowLoader = org.argeo.slc.ria.NewLauncherApplet.flowLoader;
269 for(var key in mods){
270 for(var i=0;i<mods[key].length;i++){
271 var versionFolder = new org.argeo.ria.components.DynamicTreeFolder(
272 key + ' ('+mods[key][i]+')',
273 flowLoader,
274 "Loading Flows",
275 folder.getDragData()
276 );
277 folder.add(versionFolder);
278 versionFolder.setUserData("moduleData", {name:key, version:mods[key][i]});
279 versionFolder.setUserData("agentUuid", agentId);
280 }
281 folder.setLoaded(true);
282 }
283 });
284 req.addListener("failed", function(response){folder.setLoaded(true);});
285 req.send();
286 },
287
288 /**
289 * Loader for the "flow" level : takes a folder containing "moduleData" and create its children.
290 * @param folder {qx.ui.tree.TreeFolder} A Tree folder containing in the key "moduleData" of its user data a map containing the keys {name,version}
291 */
292 flowLoader : function(folder){
293 var moduleData = folder.getUserData("moduleData");
294 var agentUuid = folder.getUserData("agentUuid");
295 //var pathStub = ["", "/test/toto/zobi", "loop"];
296 //var indexStub = 0;
297
298 var req = org.argeo.slc.ria.SlcApi.getLoadExecutionDescriptorService(agentUuid,moduleData.name, moduleData.version);
299 req.addListener("completed", function(response){
300 var executionModule = new org.argeo.slc.ria.execution.Module();
301 try{
302 executionModule.setXmlNode(response.getContent());
303 }catch(e){
304 this.error(e);
305 }
306 var execFlows = executionModule.getExecutionFlows();
307 for(var key in execFlows){
308 var file = new qx.ui.tree.TreeFile(key);
309 var path = execFlows[key].getPath();
310 //path = pathStub[indexStub];
311 //indexStub ++;
312 file.setUserData("executionModule", executionModule);
313 file.setUserData("executionFlow", execFlows[key]);
314 file.setUserData("agentUuid", agentUuid);
315 org.argeo.slc.ria.NewLauncherApplet.attachNodeByPath(
316 folder,
317 path,
318 file,
319 {agentUuid:folder.getUserData("agentUuid")}
320 );
321 folder.appendDragData(file);
322 }
323 folder.setLoaded(true);
324 });
325 req.addListener("failed", function(response){folder.setLoaded(true);});
326 req.send();
327 },
328
329 /**
330 * Parse a string path and search if there is a root node.
331 * @param rootNode {org.argeo.ria.components.DynamicTreeFolder} The parent node (containing data model)
332 * @param path {String} The path of the node to attach.
333 * @param childNode {qx.ui.tree.TreeFile} The leaf node
334 * @param userData {Map} User data to attach at all levels.
335 */
336 attachNodeByPath : function(rootNode, path, childNode, userData){
337 if(!path || path=="" || path == "/" ){
338 rootNode.add(childNode);
339 return;
340 }
341 var model = rootNode.getUserData("dataModel");
342 if(!model){
343 model = {};
344 rootNode.setUserData("dataModel", model);
345 }
346 var parts = path.split("/");
347 var keys = qx.lang.Object.getKeys(model);
348 var crtPath = "/";
349 var crtFolder = rootNode;
350 for(var i=0;i<parts.length;i++){
351 if(parts[i] == "") continue;
352 crtPath += parts[i];
353 if(!model[parts[i]]) {
354 var virtualFolder = new qx.ui.tree.TreeFolder(parts[i]);
355 if(userData && qx.lang.Object.getLength(userData)){
356 for(var key in userData){ virtualFolder.setUserData(key, userData[key]); }
357 }
358 rootNode.appendDragData(virtualFolder);
359 model[parts[i]] = virtualFolder;
360 crtFolder.add(virtualFolder);
361 crtFolder = virtualFolder;
362 }else{
363 crtFolder = model[parts[i]];
364 }
365 }
366 crtFolder.add(childNode);
367 }
368 },
369
370 members :
371 {
372 /**
373 * Called at applet creation. Just registers viewPane.
374 * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
375 */
376 init : function(viewPane){
377 this.setView(viewPane);
378 this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
379 this.remoteNotifier = new org.argeo.ria.remote.RemoteNotifier(
380 "/org.argeo.slc.webapp/",
381 "pollEvent.service",
382 "addEventListener.service",
383 "removeEventListener.service"
384 );
385 this.remoteNotifier.setEventParamName("slc_eventType");
386 this.remoteNotifier.setEventXPath("/slc:slc-event");
387 this.remoteNotifier.setEventTypeXPath('slc:headers/slc:header[@name="slc_eventType"]');
388 this.remoteNotifier.setEventDataXPath('slc:headers/slc:header[@name="slc_agentId"]');
389 this.remoteNotifier.startPolling();
390 this.UIBus = org.argeo.ria.event.UIBus.getInstance();
391 this.UIBus.registerNotifier(this.remoteNotifier);
392
393 this._emptyAgentString = "Empty Batch";
394 this._crtAgentString = "Target Agent : ";
395 },
396
397 /**
398 *
399 */
400 load : function(){
401 this._createLayout();
402 this.getView().setViewTitle("Execution Launcher");
403 this.reloadHandler = function(message){
404 this.rootNode.reload();
405 }
406 this.UIBus.addListener("agentRegistered", this.reloadHandler, this);
407 this.UIBus.addListener("agentUnregistered", this.reloadHandler, this);
408 },
409
410 addScroll : function(){
411 return false;
412 },
413
414 close : function(){
415 this.UIBus.removeListener("agentRegistered", this.reloadHandler, this);
416 this.UIBus.removeListener("agentUnregistered", this.reloadHandler, this);
417 this.remoteNotifier.stopPolling();
418 },
419
420 /**
421 * Creates the main applet layout.
422 */
423 _createLayout : function(){
424
425 var splitPane = new qx.ui.splitpane.Pane("vertical");
426 splitPane.setDecorator(null);
427 this.add(splitPane);
428
429 this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
430 this.scroll = new qx.ui.container.Scroll(this.formPane);
431 this.formPane.setPadding(10);
432
433 this.tree = new qx.ui.tree.Tree();
434 this.tree.setDecorator(null);
435 this.tree.setSelectionMode("multi");
436 var dragData = {
437 "file" : {
438 "type" : ["items"],
439 "action":["move"]
440 },
441 "folder" : {
442 "type" : ["items"],
443 "action":["move"]
444 }
445 };
446
447 this.rootNode = new org.argeo.ria.components.DynamicTreeFolder(
448 "Tests",
449 this.self(arguments).agentLoader,
450 "Loading Agents",
451 dragData
452 );
453 this.tree.setRoot(this.rootNode);
454 this.rootNode.setOpen(true);
455 this.tree.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["addtobatch", "reloadtree"]));
456
457 this.tree.addListener("changeSelection", function(e){
458 var viewSelection = this.getViewSelection();
459 viewSelection.setViewId("form:tree");
460 viewSelection.clear();
461 var sel = this.tree.getSortedSelection();
462 for(var i=0;i<sel.length;i++){
463 viewSelection.addNode(sel[i]);
464 }
465 }, this);
466
467 this.listPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
468 var listToolBar = new qx.ui.toolbar.ToolBar();
469 var toolGroup = new qx.ui.toolbar.Part();
470 listToolBar.add(toolGroup);
471
472 this.batchLabel = new qx.ui.basic.Atom(this._emptyAgentString, "resource/slc/mime-xsl-22.png");
473 this.batchLabel.setPadding(6);
474 toolGroup.add(this.batchLabel);
475 this.addListener("changeBatchAgentId", function(event){
476 var value = event.getData();
477 if(value == null){
478 this.batchLabel.setLabel(this._emptyAgentString);
479 }else{
480 var agentsList = this.rootNode.getUserData("agentsMap");
481 this.batchLabel.setLabel(this._crtAgentString + agentsList[value]);
482 }
483 }, this);
484
485 listToolBar.addSpacer();
486 listToolBar.setPaddingRight(4);
487 var execButton = this.getCommands()["submitform"].command.getToolbarButton();
488 var delButton = this.getCommands()["removefrombatch"].command.getToolbarButton();
489 var formButton = this.getCommands()["editexecutionspecs"].command.getToolbarButton();
490 execButton.setShow("icon");
491 delButton.setShow("icon");
492 formButton.setShow("icon");
493 listToolBar.add(execButton);
494 listToolBar.add(new qx.ui.toolbar.Separator());
495 listToolBar.add(formButton);
496 listToolBar.add(delButton);
497
498 this.listPane.add(listToolBar, {edge:"north"});
499
500 var indicator = new qx.ui.core.Widget();
501 indicator.setDecorator(new qx.ui.decoration.Single().set({top:[1,"solid","#33508D"]}));
502 indicator.setHeight(0);
503 indicator.setOpacity(0.5);
504 indicator.setZIndex(100);
505 indicator.setLayoutProperties({left:-1000,top:-1000});
506 org.argeo.ria.Application.INSTANCE.getRoot().add(indicator);
507
508
509 this.list = new qx.ui.form.List();
510 this.list.setDecorator(null);
511 this.list.setSelectionMode("multi");
512 this.list.setDroppable(true);
513 this.list.setDraggable(true);
514 this.list.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["editexecutionspecs", "removefrombatch"]));
515
516
517 this.list.addListener("dragstart", function(e){
518 e.addType(["items"]);
519 e.addAction(["move"]);
520 },this);
521 this.list.addListener("dragend", function(e){
522 indicator.setDomPosition(-1000,-1000);
523 });
524 this.list.addListener("dragover", function(e){
525 var orig = e.getOriginalTarget();
526 var origCoords = orig.getContainerLocation();
527 indicator.setWidth(orig.getBounds().width);
528 indicator.setDomPosition(origCoords.left, origCoords.bottom);
529 });
530 this.list.addListener("drag", function(e){
531 var orig = e.getOriginalTarget();
532 var origCoords = orig.getContainerLocation();
533 indicator.setWidth(orig.getBounds().width);
534 indicator.setDomPosition(origCoords.left, origCoords.bottom);
535 });
536
537 this.list.addListener("drop", function(e){
538 var target = e.getRelatedTarget();
539 var afterItem = e.getOriginalTarget();
540 indicator.setDomPosition(-1000,-1000);
541 if(afterItem.classname != "qx.ui.form.ListItem") afterItem = null;
542 if(!target){
543 target = this.list.getSortedSelection()[0];
544 this._addFlowToBatch(target, afterItem);
545 }else{
546 this._addFlowToBatch(null, afterItem);
547 }
548 }, this);
549 this.listPane.add(this.list, {edge:"center"});
550
551 this.list.addListener("changeSelection", function(e){
552 var viewSelection = this.getViewSelection();
553 viewSelection.setViewId("form:list");
554 viewSelection.clear();
555 var listSel = this.list.getSortedSelection();
556 for(var i=0;i<listSel.length;i++){
557 viewSelection.addNode(listSel[i]);
558 }
559 }, this);
560
561 listChangeListener = function(){
562 var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("submitform");
563 command.setEnabled(this.list.hasChildren());
564 };
565 this.list.addListener("addItem", listChangeListener, this);
566 this.list.addListener("removeItem", listChangeListener, this);
567
568 splitPane.add(this.tree, 0);
569 splitPane.add(this.listPane, 1);
570 },
571
572 /**
573 * Adds a given ExecutionFlow to the batch
574 * @param target {mixed} The dropped target, can be a TreeFile (add) or a ListItem (reorder).
575 * @param after {qx.ui.form.ListItem} Optional list item : if set, the flow will be added as a new list item positionned after this one.
576 */
577 _addFlowToBatch : function(target, after, skipAutoOpen){
578 if(target && target.classname == "qx.ui.form.ListItem"){
579 if(!after) return;
580 if(after == "first") this.list.addAt(target, 0);
581 else this.list.addAfter(target, after);
582 return;
583 }
584 if(!target){
585 if(this.tree.isSelectionEmpty()){
586 return;
587 }
588 selection = this.tree.getSelection();
589 if(selection.length > 1){
590 for(var i=0;i<selection.length;i++){
591 this._addFlowToBatch(selection[i], null, true);
592 }
593 return;
594 }else{
595 target = selection[0];
596 }
597 }
598
599 // Folder case
600 if(qx.Class.isSubClassOf(qx.Class.getByName(target.classname), qx.ui.tree.TreeFolder)){
601 var allChildren = target.getItems(true);
602 for(var i=0;i<allChildren.length;i++){
603 if(allChildren[i].getUserData("executionFlow")){
604 this._addFlowToBatch(allChildren[i], null, true);
605 }
606 }
607 return;
608 }
609
610 // Check agent Uuid against current batch agent Id.
611 var agentUuid = target.getUserData("agentUuid");
612 if(!this.getBatchAgentId()){
613 this.setBatchAgentId(agentUuid);
614 }else if(this.getBatchAgentId() != agentUuid){
615 var modal = new org.argeo.ria.components.Modal("Wrong Agent!", null, "Batch can contain tests only of the same agent!");
616 modal.attachAndShow();
617 return;
618 }
619
620 var executionModule = target.getUserData("executionModule");
621 var executionFlow = target.getUserData("executionFlow");
622 var batchEntry = new org.argeo.slc.ria.execution.BatchEntrySpec(executionModule, executionFlow);
623 var label = batchEntry.getLabel();
624 var icon = target.getIcon() || "resource/slc/office-document.png";
625 var item = new qx.ui.form.ListItem(label, icon);
626 item.addListener("dblclick", function(e){
627 this.getCommands()["editexecutionspecs"].command.execute();
628 }, this);
629 item.setUserData("batchEntrySpec", batchEntry);
630 item.setPaddingTop(1);
631 item.setPaddingBottom(2);
632 if(after){
633 if(after == "first") this.list.addAt(item, 0);
634 else this.list.addAfter(item, after);
635 }else{
636 this.list.add(item);
637 }
638 this.list.select(item);
639 if(this.getAutoOpen() && !skipAutoOpen){
640 this.getCommands()["editexecutionspecs"].command.execute();
641 }
642 },
643
644 /**
645 * Called at execution
646 * @param agentUuid {String} The id of the target agent
647 */
648 executeBatchOnAgent : function(agentUuid){
649 var selection = this.list.getChildren();
650 if(!selection.length) return;
651 var slcExecMessage = new org.argeo.slc.ria.execution.Message();
652 for(var i=0;i<selection.length;i++){
653 var batchEntrySpec = selection[i].getUserData("batchEntrySpec");
654 slcExecMessage.addBatchEntrySpec(batchEntrySpec);
655 }
656 console.log(slcExecMessage.toXml());
657 var req = org.argeo.slc.ria.SlcApi.getNewSlcExecutionService(agentUuid, slcExecMessage.toXml());
658 req.send();
659 // Force logs refresh right now!
660 qx.event.Timer.once(function(){
661 var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
662 if(command){
663 command.execute();
664 }
665 }, this, 2000);
666 }
667
668 }
669 });