]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.webapp/src/main/webapp/argeo-ria-lib/slc/class/org/argeo/slc/ria/NewLauncherApplet.js
Improve ant
[gpl/argeo-slc.git] / org.argeo.slc.webapp / src / main / webapp / 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 autoOpen : {
30 init : true,
31 check : "Boolean"
32 },
33 /**
34 * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
35 */
36 commands : {
37 init : {
38 "submitform" : {
39 label : "Execute Batch On...",
40 icon : "resource/slc/media-playback-start.png",
41 shortcut : null,
42 enabled : true,
43 menu : "Launcher",
44 toolbar : null,
45 callback : function(e){},
46 submenu : [],
47 submenuCallback : function(commandId){
48 //alert("Execute Batch on Agent "+commandId);
49 this.executeBatchOnAgent(commandId);
50 },
51 command : null
52 },
53 "addtobatch" : {
54 label : "Add to batch",
55 icon : "resource/slc/list-add.png",
56 shortcut : null,
57 enabled : true,
58 menu : null,
59 toolbar : null,
60 callback : function(e){
61 this._addFlowToBatch();
62 },
63 selectionChange : function(viewId, selection){
64 if(viewId != "form:tree") return;
65 if(!selection || selection.length != 1) return;
66 var item = selection[0];
67 this.setEnabled(false);
68 if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.TreeFile)){
69 this.setEnabled(true);
70 }
71
72 },
73 command : null
74 },
75 "toggleopenonadd" : {
76 label : "Auto Open",
77 icon : "resource/slc/document-open.png",
78 shortcut : null,
79 enabled : true,
80 toggle : true,
81 toggleInitialState : true,
82 menu : "Launcher",
83 toolbar : "launcher",
84 callback : function(event){
85 var state = event.getTarget().getUserData("slc.command.toggleState");
86 this.setAutoOpen(state);
87 },
88 command : null
89 },
90 "editexecutionspecs" : {
91 label : "Edit Execution Specs",
92 icon : "resource/slc/document-open.png",
93 shortcut : null,
94 enabled : false,
95 menu : "Launcher",
96 toolbar : null,
97 callback : function(e){
98 var sel = this.list.getSortedSelection();
99 var item = sel[0];
100 var specEditor = new org.argeo.slc.ria.execution.SpecEditor(item.getUserData("batchEntrySpec"));
101 specEditor.attachAndShow();
102 },
103 selectionChange : function(viewId, selection){
104 if(viewId != "form:list") return;
105 this.setEnabled(false);
106 if((selection && selection.length == 1)) this.setEnabled(true);
107 },
108 command : null
109 },
110 "removefrombatch" : {
111 label : "Remove from batch",
112 icon : "resource/slc/edit-delete.png",
113 shortcut : null,
114 enabled : false,
115 menu : "Launcher",
116 toolbar : null,
117 callback : function(e){
118 var sel = this.list.getSortedSelection();
119 var modal = new org.argeo.ria.components.Modal("Confirm", null);
120 modal.addConfirm("Are you sure you want to remove<br> the selected test" + (sel.length>1?"s":"") + " from the Batch?");
121 modal.addListener("ok", function(){
122 for(var i=0;i<sel.length;i++){
123 this.list.remove(sel[i]);
124 }
125 }, this);
126 modal.attachAndShow();
127 },
128 selectionChange : function(viewId, selection){
129 if(viewId != "form:list") return;
130 this.setEnabled(false);
131 if((selection && selection.length > 0)) this.setEnabled(true);
132 },
133 command : null
134 },
135 "reloadagents" : {
136 label : "Reload Agents",
137 icon : "resource/slc/view-refresh.png",
138 shortcut : "Control+r",
139 enabled : true,
140 menu : "Launcher",
141 toolbar : "launcher",
142 callback : function(e){
143 var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
144 req.send();
145 },
146 command : null
147 },
148 "reloadtree" : {
149 label : "Reload",
150 icon : "resource/slc/view-refresh.png",
151 shortcut : "Control+m",
152 enabled : false,
153 menu : "Launcher",
154 toolbar : "launcher",
155 callback : function(e){
156 var selected = this.tree.getSelectedItem();
157 if(selected.classname == "org.argeo.ria.components.DynamicTreeFolder"){
158 selected.reload();
159 }
160 },
161 selectionChange : function(viewId, selection){
162 if(viewId != "form:tree") return;
163 if(!selection || selection.length != 1) return;
164 var item = selection[0];
165 if(!qx.Class.isSubClassOf(qx.Class.getByName(item.classname), qx.ui.tree.AbstractTreeItem)) return;
166 this.setEnabled(false);
167 if(qx.Class.isSubClassOf(qx.Class.getByName(item.classname), org.argeo.ria.components.DynamicTreeFolder)){
168 this.setEnabled(true);
169 }
170 },
171 command : null
172 }
173 }
174 },
175 /**
176 * A map containing all currently registered agents.
177 */
178 registeredTopics : {
179 init : {},
180 check : "Map",
181 event : "changeRegisteredTopics"
182 }
183 },
184
185 statics : {
186 flowLoader : function(folder){
187 var moduleData = folder.getUserData("moduleData");
188 var req = org.argeo.ria.remote.RequestManager.getInstance().getRequest("../argeo-ria-src/stub.xml", "GET", "application/xml");
189 req.addListener("completed", function(response){
190 var executionModule = new org.argeo.slc.ria.execution.Module();
191 executionModule.setXmlNode(response.getContent());
192 //
193 // ARTIFIALLY REPLACE MODULE NAME / VERSION, FOR TESTS PURPOSES
194 //
195 executionModule.setName(moduleData.name);
196 executionModule.setVersion(moduleData.version);
197 // END
198 var execFlows = executionModule.getExecutionFlows();
199 for(var key in execFlows){
200 var file = new qx.ui.tree.TreeFile(key);
201 file.setUserData("executionModule", executionModule);
202 file.setUserData("executionFlow", execFlows[key]);
203 folder.add(file);
204 }
205 folder.setLoaded(true);
206 });
207 req.send();
208 },
209
210 modulesLoader : function(folder){
211 // Call service, and parse
212 var mods = {
213 "Module 1":["ver1.1", "ver1.2", "ver1.3"],
214 "Module 2":["ver2.1", "ver2.2", "ver2.3", "ver2.4"],
215 "Module 3":["ver3.1", "ver3.2"]
216 };
217 var flowLoader = org.argeo.slc.ria.NewLauncherApplet.flowLoader;
218 for(var key in mods){
219 var moduleFolder = new qx.ui.tree.TreeFolder(key);
220 folder.add(moduleFolder);
221 for(var i=0;i<mods[key].length;i++){
222 var versionFolder = new org.argeo.ria.components.DynamicTreeFolder(
223 mods[key][i],
224 flowLoader,
225 "Loading Flows",
226 folder.getDragData()
227 );
228 moduleFolder.add(versionFolder);
229 versionFolder.setUserData("moduleData", {name:key, version:mods[key][i]});
230 }
231 folder.setLoaded(true);
232 }
233 }
234 },
235
236 members :
237 {
238 /**
239 * Called at applet creation. Just registers viewPane.
240 * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
241 */
242 init : function(viewPane){
243 this.setView(viewPane);
244 this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
245 this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
246 this._amqClient.startPolling();
247 },
248
249 /**
250 *
251 */
252 load : function(){
253 this._createLayout();
254 this.getView().setViewTitle("Execution Launcher");
255 org.argeo.ria.remote.RequestManager.getInstance().addListener("reload", function(reloadEvent){
256 if(reloadEvent.getDataType()!= "agents") return ;
257 var xmlDoc = reloadEvent.getContent();
258 var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
259 var newTopics = {};
260 for(var i=0;i<nodes.length;i++){
261 var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
262 var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
263 newTopics[uuid] = host+" ("+uuid+")";
264 }
265 this.setRegisteredTopics(newTopics);
266 }, this);
267 this.addListener("changeRegisteredTopics", function(event){
268 //this._refreshTopicsSubscriptions(event);
269 this._feedSelector(event);
270 }, this);
271 var reloadHandler = function(message){
272 // Delay reload to be sure the jms was first integrated by the db, then ask the db.
273 qx.event.Timer.once(function(){
274 org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
275 }, this, 1000);
276 }
277 this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
278 this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
279 reloadHandler();
280
281 this._amqClient.addListener("modulesResponse", "modulesManager.response", function(message){
282 this.info(message);
283 }, this);
284 },
285
286 addScroll : function(){
287 return false;
288 },
289
290 close : function(){
291 this._amqClient.removeListener("agentregister", "topic://agent.register");
292 this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
293 this._amqClient.removeListener("modulesResponse", "topic://modulesManager.response");
294 this.setRegisteredTopics({});
295 this._amqClient.stopPolling();
296 },
297
298 /**
299 * Creates the main applet layout.
300 */
301 _createLayout : function(){
302
303 var splitPane = new qx.ui.splitpane.Pane("vertical");
304 splitPane.setDecorator(null);
305 this.add(splitPane);
306
307 this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
308 this.scroll = new qx.ui.container.Scroll(this.formPane);
309 this.formPane.setPadding(10);
310
311 this.tree = new qx.ui.tree.Tree();
312 this.tree.setDecorator(null);
313 var dragData = {
314 "file" : {
315 "type" : ["items"],
316 "action":["move"]
317 }
318 };
319
320 var root = new org.argeo.ria.components.DynamicTreeFolder(
321 "All Tests",
322 this.self(arguments).modulesLoader,
323 "Loading Modules",
324 dragData
325 );
326 this.tree.setRoot(root);
327 root.setOpen(true);
328 this.tree.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["addtobatch", "reloadtree"]));
329
330 this.tree.addListener("changeSelection", function(e){
331 var viewSelection = this.getViewSelection();
332 viewSelection.setViewId("form:tree");
333 viewSelection.clear();
334 var sel = this.tree.getSortedSelection();
335 for(var i=0;i<sel.length;i++){
336 viewSelection.addNode(sel[i]);
337 }
338 }, this);
339
340 this.listPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
341 var listToolBar = new qx.ui.toolbar.ToolBar();
342 var toolGroup = new qx.ui.toolbar.Part();
343 listToolBar.add(toolGroup);
344
345 var execButton = this.getCommands()["submitform"].command.getToolbarButton();
346 toolGroup.add(execButton);
347
348 listToolBar.addSpacer();
349 listToolBar.setPaddingRight(4);
350 var delButton = this.getCommands()["removefrombatch"].command.getToolbarButton();
351 var formButton = this.getCommands()["editexecutionspecs"].command.getToolbarButton();
352 delButton.setShow("icon");
353 formButton.setShow("icon");
354 listToolBar.add(formButton);
355 listToolBar.add(delButton);
356
357 this.listPane.add(listToolBar, {edge:"north"});
358
359 var indicator = new qx.ui.core.Widget();
360 indicator.setDecorator(new qx.ui.decoration.Single().set({top:[1,"solid","#33508D"]}));
361 indicator.setHeight(0);
362 indicator.setOpacity(0.5);
363 indicator.setZIndex(100);
364 indicator.setLayoutProperties({left:-1000,top:-1000});
365 org.argeo.ria.Application.INSTANCE.getRoot().add(indicator);
366
367
368 this.list = new qx.ui.form.List();
369 this.list.setDecorator(null);
370 this.list.setSelectionMode("multi");
371 this.list.setDroppable(true);
372 this.list.setDraggable(true);
373 this.list.setContextMenu(org.argeo.ria.event.CommandsManager.getInstance().createMenuFromIds(["editexecutionspecs", "removefrombatch"]));
374
375
376 this.list.addListener("dragstart", function(e){
377 e.addType(["items"]);
378 e.addAction(["move"]);
379 },this);
380 this.list.addListener("dragend", function(e){
381 indicator.setDomPosition(-1000,-1000);
382 });
383 this.list.addListener("dragover", function(e){
384 var orig = e.getOriginalTarget();
385 var origCoords = orig.getContainerLocation();
386 indicator.setWidth(orig.getBounds().width);
387 indicator.setDomPosition(origCoords.left, origCoords.bottom);
388 });
389 this.list.addListener("drag", function(e){
390 var orig = e.getOriginalTarget();
391 var origCoords = orig.getContainerLocation();
392 indicator.setWidth(orig.getBounds().width);
393 indicator.setDomPosition(origCoords.left, origCoords.bottom);
394 });
395
396 this.list.addListener("drop", function(e){
397 var target = e.getRelatedTarget();
398 var afterItem = e.getOriginalTarget();
399 indicator.setDomPosition(-1000,-1000);
400 if(afterItem.classname != "qx.ui.form.ListItem") afterItem = null;
401 if(!target){
402 target = this.list.getSortedSelection()[0];
403 }
404 this._addFlowToBatch(target, afterItem);
405 }, this);
406 this.listPane.add(this.list, {edge:"center"});
407
408 this.list.addListener("changeSelection", function(e){
409 var viewSelection = this.getViewSelection();
410 viewSelection.setViewId("form:list");
411 viewSelection.clear();
412 var listSel = this.list.getSortedSelection();
413 for(var i=0;i<listSel.length;i++){
414 viewSelection.addNode(listSel[i]);
415 }
416 }, this);
417
418 splitPane.add(this.tree, 0);
419 splitPane.add(this.listPane, 1);
420 },
421
422 _addFlowToBatch : function(target, after){
423 this.debug(target);
424 if(!target){
425 target = this.tree.getSelectedItem();
426 if(!target) return;
427 }else if(target.classname == "qx.ui.form.ListItem"){
428 if(!after) return;
429 if(after == "first") this.list.addAt(target, 0);
430 else this.list.addAfter(target, after);
431 return;
432 }
433 var executionModule = target.getUserData("executionModule");
434 var executionFlow = target.getUserData("executionFlow");
435 var batchEntry = new org.argeo.slc.ria.execution.BatchEntrySpec(executionModule, executionFlow);
436 var label = batchEntry.getLabel();
437 var icon = target.getIcon();
438 var item = new qx.ui.form.ListItem(label, icon);
439 item.setUserData("batchEntrySpec", batchEntry);
440 item.setPaddingTop(1);
441 item.setPaddingBottom(2);
442 if(after){
443 if(after == "first") this.list.addAt(item, 0);
444 else this.list.addAfter(item, after);
445 }else{
446 this.list.add(item);
447 }
448 this.list.select(item);
449 if(this.getAutoOpen()){
450 this.getCommands()["editexecutionspecs"].command.execute();
451 }
452 },
453
454 /**
455 * Refresh the selector when the topics are updated.
456 * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
457 */
458 _feedSelector : function(changeTopicsEvent){
459 var topics = changeTopicsEvent.getData();
460 var command = this.getCommands()["submitform"].command;
461 command.setEnabled(false);
462 var menu = [];
463 for(var key in topics){
464 var submenu = {"label":topics[key],"icon":"resource/slc/mime-xsl.png", "commandId":key};
465 menu.push(submenu);
466 }
467 // FAKE!!
468 if(!menu.length){
469 menu.push({"label":"Fake Agent", "icon":"resource/slc/mime-xsl.png", "commandId":"fake_agent_uuid"});
470 }
471 command.clearMenus();
472 command.setMenu(menu);
473 if(menu.length) command.setEnabled(true);
474 },
475
476 currentBatchToXml : function(){
477 var selection = this.list.getChildren();
478 var xmlString = "";
479 for(var i=0;i<selection.length;i++){
480 var batchEntrySpec = selection[i].getUserData("batchEntrySpec");
481 xmlString += batchEntrySpec.toXml();
482 }
483 return xmlString;
484 },
485
486 executeBatchOnAgent : function(agentUuid){
487 var xmlString = agentUuid + this.currentBatchToXml();
488 alert(xmlString);
489 },
490
491 /**
492 * Make an SlcExecutionMessage from the currently displayed form.
493 * @param crtPartId {String} The form part currently displayed
494 * @param slcExec {org.argeo.slc.ria.SlcExecutionMessage} The message to fill.
495 * @param fields {Map} The fields of the form
496 * @param hiddenFields {Map} The hidden ones
497 * @param freeFields {Array} The free fields.
498 */
499 _prepareSlcExecutionMessage : function(crtPartId, slcExec, fields, hiddenFields, freeFields){
500 if(crtPartId == "standard"){
501 slcExec.setStatus(fields.status.getValue());
502 slcExec.setHost(fields.host.getValue());
503 slcExec.setUser(fields.user.getValue());
504 }else{
505 slcExec.addAttribute("ant.file", fields["ant.file"].getValue());
506 }
507 for(var i=0;i<freeFields.length;i++){
508 var fF = freeFields[i];
509 if(fF.labelEl.getValue() != "" && fF.valueEl.getValue() != ""){
510 slcExec.addAttribute(fF.labelEl.getValue(), fF.valueEl.getValue());
511 }
512 }
513 },
514
515 /**
516 * Called when the user clicks the "Execute" button.
517 */
518 submitForm : function(){
519 var currentUuid = this.agentSelector.getValue();
520 if(!currentUuid) return;
521 var slcExec = new org.argeo.slc.ria.SlcExecutionMessage();
522
523 var fields = {};
524 var hiddenFields = {};
525 var freeFields = {};
526 var crtPartId = "";
527 if(this.parts){
528 if(this.partChooser){
529 crtPartId = this.partChooser.getValue();
530 }else{
531 crtPartId = qx.lang.Object.getKeys(this.parts)[0];
532 }
533 var crtPart = this.parts[crtPartId];
534 fields = crtPart.fields;
535 hiddenFields = crtPart.hiddenFields;
536 freeFields = crtPart.freeFields;
537 }
538
539 this._prepareSlcExecutionMessage(crtPartId, slcExec, fields, hiddenFields, freeFields);
540
541 this._amqClient.sendMessage(
542 "topic://agent.newExecution",
543 slcExec.toXml(),
544 {"slc-agentId":currentUuid}
545 );
546 // Force logs refresh right now!
547 qx.event.Timer.once(function(){
548 var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
549 if(command){
550 command.execute();
551 }
552 }, this, 2000);
553 }
554
555 }
556 });