]>
git.argeo.org Git - gpl/argeo-slc.git/blob - server/org.argeo.slc.ria/src/main/webapp/argeo-ria-lib/slc/class/org/argeo/slc/ria/NewLauncherApplet.js
2 * A simple Hello World applet for documentation purpose.
3 * The only associated command is the "Close" command.
5 qx
.Class
.define("org.argeo.slc.ria.NewLauncherApplet",
7 extend
: qx
.ui
.container
.Composite
,
8 implement
: [org
.argeo
.ria
.components
.IView
],
10 construct : function(){
12 this.setLayout(new qx
.ui
.layout
.Dock());
18 * The viewPane inside which this applet is added.
25 check
:"org.argeo.ria.components.ViewSelection"
27 instanceId
: {init
:""},
28 instanceLabel
: {init
:""},
30 * A boolean registering whether the SpecEditor must autoOpen or not when a spec is added to the Batch.
37 * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
42 label
: "Execute Batch On...",
43 icon
: "resource/slc/media-playback-start.png",
48 callback : function(e
){},
50 submenuCallback : function(commandId
){
51 //alert("Execute Batch on Agent "+commandId);
52 this.executeBatchOnAgent(commandId
);
57 label
: "Add to batch",
58 icon
: "resource/slc/list-add.png",
63 callback : function(e
){
64 this._addFlowToBatch();
66 selectionChange : function(viewId
, selection
){
67 if(viewId
!= "form:tree") return;
68 if(!selection
|| selection
.length
!= 1) return;
69 var item
= selection
[0];
70 this.setEnabled(false);
71 if(qx
.Class
.isSubClassOf(qx
.Class
.getByName(item
.classname
), qx
.ui
.tree
.TreeFile
)){
72 this.setEnabled(true);
80 icon
: "resource/slc/document-open.png",
84 toggleInitialState
: true,
87 callback : function(event
){
88 var state
= event
.getTarget().getUserData("slc.command.toggleState");
89 this.setAutoOpen(state
);
93 "editexecutionspecs" : {
94 label
: "Edit Execution Specs",
95 icon
: "resource/slc/document-open.png",
100 callback : function(e
){
101 var sel
= this.list
.getSortedSelection();
103 var specEditor
= new org
.argeo
.slc
.ria
.execution
.SpecEditor(item
.getUserData("batchEntrySpec"));
104 specEditor
.attachAndShow();
106 selectionChange : function(viewId
, selection
){
107 if(viewId
!= "form:list") return;
108 this.setEnabled(false);
109 if((selection
&& selection
.length
== 1)) this.setEnabled(true);
113 "removefrombatch" : {
114 label
: "Remove from batch",
115 icon
: "resource/slc/edit-delete.png",
120 callback : function(e
){
121 var sel
= this.list
.getSortedSelection();
122 var modal
= new org
.argeo
.ria
.components
.Modal("Confirm", null);
123 modal
.addConfirm("Are you sure you want to remove<br> the selected test" + (sel
.length
>1?"s":"") + " from the Batch?");
124 modal
.addListener("ok", function(){
125 for(var i
=0;i
<sel
.length
;i
++){
126 this.list
.remove(sel
[i
]);
129 modal
.attachAndShow();
131 selectionChange : function(viewId
, selection
){
132 if(viewId
!= "form:list") return;
133 this.setEnabled(false);
134 if((selection
&& selection
.length
> 0)) this.setEnabled(true);
139 label
: "Reload Agents",
140 icon
: "resource/slc/view-refresh.png",
141 shortcut
: "Control+r",
144 toolbar
: "launcher",
145 callback : function(e
){
146 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListAgentsService("agents");
153 icon
: "resource/slc/view-refresh.png",
154 shortcut
: "Control+m",
157 toolbar
: "launcher",
158 callback : function(e
){
159 var selected
= this.tree
.getSelectedItem();
160 if(selected
.classname
== "org.argeo.ria.components.DynamicTreeFolder"){
161 if(selected
.getUserData("moduleData")){
162 // It's a "module" node, first trigger the reloadBundle.service
163 selected
.setUserData("dataModel", {});
164 selected
.setEnabled(false);
165 selected
.setOpen(false);
166 var moduleData
= selected
.getUserData("moduleData");
167 var bundleService
= org
.argeo
.slc
.ria
.SlcApi
.getReloadBundleService(moduleData
.name
, moduleData
.version
);
168 bundleService
.addListener("completed", function(response
){
169 selected
.setEnabled(true);
170 selected
.setOpen(true);
173 //bundleService.send();
174 //Do not send, not implemented yet, false timer instead.
175 qx
.event
.Timer
.once(function(response
){
176 selected
.setEnabled(true);
177 selected
.setOpen(true);
185 selectionChange : function(viewId
, selection
){
186 if(viewId
!= "form:tree") return;
187 if(!selection
|| selection
.length
!= 1) return;
188 var item
= selection
[0];
189 if(!qx
.Class
.isSubClassOf(qx
.Class
.getByName(item
.classname
), qx
.ui
.tree
.AbstractTreeItem
)) return;
190 this.setEnabled(false);
191 if(qx
.Class
.isSubClassOf(qx
.Class
.getByName(item
.classname
), org
.argeo
.ria
.components
.DynamicTreeFolder
)){
192 this.setEnabled(true);
200 * A map containing all currently registered agents.
205 event
: "changeRegisteredTopics"
211 * Loader for the "flow" level : takes a folder containing "moduleData" and create its children.
212 * @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}
214 flowLoader : function(folder
){
215 var moduleData
= folder
.getUserData("moduleData");
216 //var pathStub = ["", "/test/toto/zobi", "loop"];
219 var req
= org
.argeo
.slc
.ria
.SlcApi
.getLoadExecutionDescriptorService(moduleData
.name
, moduleData
.version
);
220 req
.addListener("completed", function(response
){
221 var executionModule
= new org
.argeo
.slc
.ria
.execution
.Module();
222 executionModule
.setXmlNode(response
.getContent());
223 var execFlows
= executionModule
.getExecutionFlows();
224 for(var key
in execFlows
){
225 var file
= new qx
.ui
.tree
.TreeFile(key
);
226 var path
= execFlows
[key
].getPath();
227 //path = pathStub[indexStub];
229 file
.setUserData("executionModule", executionModule
);
230 file
.setUserData("executionFlow", execFlows
[key
]);
231 org
.argeo
.slc
.ria
.NewLauncherApplet
.attachNodeByPath(folder
, path
, file
);
232 folder
.appendDragData(file
);
234 folder
.setLoaded(true);
240 * Loader for the "modules" level : takes any tree folder, currently the root folder.
241 * @param folder {qx.ui.tree.TreeFolder} The root folder
243 modulesLoader : function(folder
){
244 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListModulesService();
245 req
.addListener("completed", function(response
){
246 var descriptors
= org
.argeo
.ria
.util
.Element
.selectNodes(response
.getContent(), "slc:object-list/slc:execution-module-descriptor");
248 for(var i
=0;i
<descriptors
.length
; i
++){
249 var name
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(descriptors
[i
], "slc:name");
250 var version
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(descriptors
[i
], "slc:version");
251 if(!mods
[name
]) mods
[name
] = [];
252 mods
[name
].push(version
);
254 var flowLoader
= org
.argeo
.slc
.ria
.NewLauncherApplet
.flowLoader
;
255 for(var key
in mods
){
256 for(var i
=0;i
<mods
[key
].length
;i
++){
257 var versionFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
258 key
+ ' ('+mods
[key
][i
]+')',
263 folder
.add(versionFolder
);
264 versionFolder
.setUserData("moduleData", {name
:key
, version
:mods
[key
][i
]});
266 folder
.setLoaded(true);
273 * Parse a string path and search if there is a root node.
274 * @param rootNode {qx.ui.tree.AbstractTreeItem} The parent node (containing data model)
275 * @param path {String} The path of the node to attach.
277 attachNodeByPath : function(rootNode
, path
, childNode
){
278 if(!path
|| path
=="" || path
== "/" ){
279 rootNode
.add(childNode
);
282 var model
= rootNode
.getUserData("dataModel");
285 rootNode
.setUserData("dataModel", model
);
287 var parts
= path
.split("/");
288 var keys
= qx
.lang
.Object
.getKeys(model
);
290 var crtFolder
= rootNode
;
291 for(var i
=0;i
<parts
.length
;i
++){
292 if(parts
[i
] == "") continue;
294 if(!model
[parts
[i
]]) {
295 var virtualFolder
= new qx
.ui
.tree
.TreeFolder(parts
[i
]);
296 model
[parts
[i
]] = virtualFolder
;
297 crtFolder
.add(virtualFolder
);
298 crtFolder
= virtualFolder
;
300 crtFolder
= model
[parts
[i
]];
303 crtFolder
.add(childNode
);
310 * Called at applet creation. Just registers viewPane.
311 * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
313 init : function(viewPane
){
314 this.setView(viewPane
);
315 this.setViewSelection(new org
.argeo
.ria
.components
.ViewSelection(viewPane
.getViewId()));
316 this._amqClient
= org
.argeo
.ria
.remote
.JmsClient
.getInstance();
317 this._amqClient
.uri
= "/org.argeo.slc.webapp/amq";
318 this._amqClient
.startPolling();
325 this._createLayout();
326 this.getView().setViewTitle("Execution Launcher");
327 org
.argeo
.ria
.remote
.RequestManager
.getInstance().addListener("reload", function(reloadEvent
){
328 if(reloadEvent
.getDataType()!= "agents") return ;
329 var xmlDoc
= reloadEvent
.getContent();
330 var nodes
= org
.argeo
.ria
.util
.Element
.selectNodes(xmlDoc
, "//slc:slc-agent-descriptor");
332 for(var i
=0;i
<nodes
.length
;i
++){
333 var uuid
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "@uuid");
334 var host
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "slc:host");
335 newTopics
[uuid
] = host
+" ("+uuid
+")";
337 this.setRegisteredTopics(newTopics
);
339 this.addListener("changeRegisteredTopics", function(event
){
340 //this._refreshTopicsSubscriptions(event);
341 this._feedSelector(event
);
343 var reloadHandler = function(message
){
344 // Delay reload to be sure the jms was first integrated by the db, then ask the db.
345 qx
.event
.Timer
.once(function(){
346 org
.argeo
.ria
.event
.CommandsManager
.getInstance().getCommandById("reloadagents").execute();
349 this._amqClient
.addListener("agentregister", "topic://agent.register", reloadHandler
, this);
350 this._amqClient
.addListener("agentunregister", "topic://agent.unregister", reloadHandler
, this);
354 addScroll : function(){
359 this._amqClient
.removeListener("agentregister", "topic://agent.register");
360 this._amqClient
.removeListener("agentunregister", "topic://agent.unregister");
361 this._amqClient
.removeListener("modulesResponse", "topic://modulesManager.response");
362 this.setRegisteredTopics({});
363 this._amqClient
.stopPolling();
367 * Creates the main applet layout.
369 _createLayout : function(){
371 var splitPane
= new qx
.ui
.splitpane
.Pane("vertical");
372 splitPane
.setDecorator(null);
375 this.formPane
= new qx
.ui
.container
.Composite(new qx
.ui
.layout
.VBox(5));
376 this.scroll
= new qx
.ui
.container
.Scroll(this.formPane
);
377 this.formPane
.setPadding(10);
379 this.tree
= new qx
.ui
.tree
.Tree();
380 this.tree
.setDecorator(null);
388 var root
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
390 this.self(arguments
).modulesLoader
,
394 this.tree
.setRoot(root
);
396 this.tree
.setContextMenu(org
.argeo
.ria
.event
.CommandsManager
.getInstance().createMenuFromIds(["addtobatch", "reloadtree"]));
398 this.tree
.addListener("changeSelection", function(e
){
399 var viewSelection
= this.getViewSelection();
400 viewSelection
.setViewId("form:tree");
401 viewSelection
.clear();
402 var sel
= this.tree
.getSortedSelection();
403 for(var i
=0;i
<sel
.length
;i
++){
404 viewSelection
.addNode(sel
[i
]);
408 this.listPane
= new qx
.ui
.container
.Composite(new qx
.ui
.layout
.Dock());
409 var listToolBar
= new qx
.ui
.toolbar
.ToolBar();
410 var toolGroup
= new qx
.ui
.toolbar
.Part();
411 listToolBar
.add(toolGroup
);
413 var execButton
= this.getCommands()["submitform"].command
.getToolbarButton();
414 toolGroup
.add(execButton
);
416 listToolBar
.addSpacer();
417 listToolBar
.setPaddingRight(4);
418 var delButton
= this.getCommands()["removefrombatch"].command
.getToolbarButton();
419 var formButton
= this.getCommands()["editexecutionspecs"].command
.getToolbarButton();
420 delButton
.setShow("icon");
421 formButton
.setShow("icon");
422 listToolBar
.add(formButton
);
423 listToolBar
.add(delButton
);
425 this.listPane
.add(listToolBar
, {edge
:"north"});
427 var indicator
= new qx
.ui
.core
.Widget();
428 indicator
.setDecorator(new qx
.ui
.decoration
.Single().set({top
:[1,"solid","#33508D"]}));
429 indicator
.setHeight(0);
430 indicator
.setOpacity(0.5);
431 indicator
.setZIndex(100);
432 indicator
.setLayoutProperties({left
:-1000,top
:-1000});
433 org
.argeo
.ria
.Application
.INSTANCE
.getRoot().add(indicator
);
436 this.list
= new qx
.ui
.form
.List();
437 this.list
.setDecorator(null);
438 this.list
.setSelectionMode("multi");
439 this.list
.setDroppable(true);
440 this.list
.setDraggable(true);
441 this.list
.setContextMenu(org
.argeo
.ria
.event
.CommandsManager
.getInstance().createMenuFromIds(["editexecutionspecs", "removefrombatch"]));
444 this.list
.addListener("dragstart", function(e
){
445 e
.addType(["items"]);
446 e
.addAction(["move"]);
448 this.list
.addListener("dragend", function(e
){
449 indicator
.setDomPosition(-1000,-1000);
451 this.list
.addListener("dragover", function(e
){
452 var orig
= e
.getOriginalTarget();
453 var origCoords
= orig
.getContainerLocation();
454 indicator
.setWidth(orig
.getBounds().width
);
455 indicator
.setDomPosition(origCoords
.left
, origCoords
.bottom
);
457 this.list
.addListener("drag", function(e
){
458 var orig
= e
.getOriginalTarget();
459 var origCoords
= orig
.getContainerLocation();
460 indicator
.setWidth(orig
.getBounds().width
);
461 indicator
.setDomPosition(origCoords
.left
, origCoords
.bottom
);
464 this.list
.addListener("drop", function(e
){
465 var target
= e
.getRelatedTarget();
466 var afterItem
= e
.getOriginalTarget();
467 indicator
.setDomPosition(-1000,-1000);
468 if(afterItem
.classname
!= "qx.ui.form.ListItem") afterItem
= null;
470 target
= this.list
.getSortedSelection()[0];
472 this._addFlowToBatch(target
, afterItem
);
474 this.listPane
.add(this.list
, {edge
:"center"});
476 this.list
.addListener("changeSelection", function(e
){
477 var viewSelection
= this.getViewSelection();
478 viewSelection
.setViewId("form:list");
479 viewSelection
.clear();
480 var listSel
= this.list
.getSortedSelection();
481 for(var i
=0;i
<listSel
.length
;i
++){
482 viewSelection
.addNode(listSel
[i
]);
486 splitPane
.add(this.tree
, 0);
487 splitPane
.add(this.listPane
, 1);
491 * Adds a given ExecutionFlow to the batch
492 * @param target {mixed} The dropped target, can be a TreeFile (add) or a ListItem (reorder).
493 * @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.
495 _addFlowToBatch : function(target
, after
){
496 //this.debug(target);
498 target
= this.tree
.getSelectedItem();
500 }else if(target
.classname
== "qx.ui.form.ListItem"){
502 if(after
== "first") this.list
.addAt(target
, 0);
503 else this.list
.addAfter(target
, after
);
506 var executionModule
= target
.getUserData("executionModule");
507 var executionFlow
= target
.getUserData("executionFlow");
508 var batchEntry
= new org
.argeo
.slc
.ria
.execution
.BatchEntrySpec(executionModule
, executionFlow
);
509 var label
= batchEntry
.getLabel();
510 var icon
= target
.getIcon();
511 var item
= new qx
.ui
.form
.ListItem(label
, icon
);
512 item
.addListener("dblclick", function(e
){
513 this.getCommands()["editexecutionspecs"].command
.execute();
515 item
.setUserData("batchEntrySpec", batchEntry
);
516 item
.setPaddingTop(1);
517 item
.setPaddingBottom(2);
519 if(after
== "first") this.list
.addAt(item
, 0);
520 else this.list
.addAfter(item
, after
);
524 this.list
.select(item
);
525 if(this.getAutoOpen()){
526 this.getCommands()["editexecutionspecs"].command
.execute();
531 * Refresh the selector when the topics are updated.
532 * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
534 _feedSelector : function(changeTopicsEvent
){
535 var topics
= changeTopicsEvent
.getData();
536 var command
= this.getCommands()["submitform"].command
;
537 command
.setEnabled(false);
539 for(var key
in topics
){
540 var submenu
= {"label":topics
[key
],"icon":"resource/slc/mime-xsl.png", "commandId":key
};
545 menu
.push({"label":"Fake Agent", "icon":"resource/slc/mime-xsl.png", "commandId":"fake_agent_uuid"});
547 command
.clearMenus();
548 command
.setMenu(menu
);
549 if(menu
.length
) command
.setEnabled(true);
554 * Called at execution
555 * @param agentUuid {String} The id of the target agent
557 executeBatchOnAgent : function(agentUuid
){
558 var selection
= this.list
.getChildren();
559 if(!selection
.length
) return;
560 var slcExecMessage
= new org
.argeo
.slc
.ria
.execution
.Message();
561 for(var i
=0;i
<selection
.length
;i
++){
562 var batchEntrySpec
= selection
[i
].getUserData("batchEntrySpec");
563 slcExecMessage
.addBatchEntrySpec(batchEntrySpec
);
565 this._amqClient
.sendMessage(
566 "topic://agent.newExecution",
567 slcExecMessage
.toXml(),
568 {"slc-agentId":agentUuid
}
570 // Force logs refresh right now!
571 qx
.event
.Timer
.once(function(){
572 var command
= org
.argeo
.ria
.event
.CommandsManager
.getInstance().getCommandById("reloadlogs");