]> git.argeo.org Git - gpl/argeo-slc.git/blob - server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/BatchView.js
Bases for monitoring perspective
[gpl/argeo-slc.git] / server / org.argeo.slc.ria / src / argeo-ria-lib / slc / class / org / argeo / slc / ria / BatchView.js
1 /**
2 * Applet for the batch manager
3 */
4 qx.Class.define("org.argeo.slc.ria.BatchView",
5 {
6 extend : qx.ui.container.Composite,
7 implement : [org.argeo.ria.components.IView],
8 include : [org.argeo.ria.session.MPrefHolder],
9 statics : {
10 riaPreferences : {
11 "slc.batch.delete.confirm" : {
12 label : "Confirm on batch deletion",
13 type : "boolean",
14 defaultValue : true
15 },
16 "slc.batch.autoclear" : {
17 label : "Autoclear batch on execution",
18 type : "boolean",
19 defaultValue : false
20 }
21 }
22 },
23 properties :
24 {
25 /**
26 * The commands definition Map that will be automatically added and wired to the menubar and toolbar.
27 * See {@link org.argeo.ria.event.CommandsManager#definitions} for the keys to use for defining commands.
28 */
29 commands : {
30 init : {
31 "submitform" : {
32 label : "Execute Batch",
33 icon : "org.argeo.slc.ria/media-playback-start.png",
34 shortcut : null,
35 enabled : false,
36 menu : "Launcher",
37 toolbar : "batch",
38 callback : function(e) {
39 var batchAgentId = this.getBatchAgentId();
40 if (!batchAgentId) {
41 return;
42 }
43 var prefName = "slc.batch.autoclear";
44 var prefValue = this.getRiaPreferenceValue(prefName);
45 if(prefValue !== null){
46 this.executeBatchOnAgent(batchAgentId, prefValue);
47 return;
48 }
49 var modal = new org.argeo.ria.components.Modal("Clear?", null);
50 modal.addYesNoReminder("Do you want to clear the batch automatically after execution?", prefName);
51 modal.addListener("cancel", function(e){
52 this.executeBatchOnAgent(batchAgentId, false);
53 }, this);
54 modal.addListener("ok", function(e){
55 this.executeBatchOnAgent(batchAgentId, true);
56 }, this);
57 modal.attachAndShow();
58 },
59 command : null
60 },
61 /*
62 "toggleopenonadd" : {
63 label : "Auto edit on Add",
64 icon : "org.argeo.slc.ria/document-open.png",
65 shortcut : null,
66 enabled : true,
67 toggle : true,
68 toggleInitialState : true,
69 menu : "Launcher",
70 toolbar : "launcher",
71 callback : function(event) {
72 var state = event.getTarget().getUserData("slc.command.toggleState");
73 this.setAutoOpen(state);
74 },
75 command : null
76 },
77 "editexecutionspecs" : {
78 label : "Edit Execution Specs",
79 icon : "org.argeo.slc.ria/document-open.png",
80 shortcut : null,
81 enabled : false,
82 menu : "Launcher",
83 toolbar : "batch",
84 callback : function(e) {
85 var sel = this.list.getSortedSelection();
86 var spec = sel[0].getUserData("batchEntrySpec");
87 if (spec.hasEditableValues()) {
88 var specEditor = new org.argeo.slc.ria.execution.SpecEditor(spec);
89 specEditor.attachAndShow();
90 }
91 },
92 selectionChange : function(viewId, selection) {
93 if (viewId != "batch:list")
94 return;
95 this.setEnabled(false);
96 if ((selection && selection.length == 1)) {
97 var selectedItemSpec = selection[0].getUserData("batchEntrySpec");
98 if (selectedItemSpec.hasEditableValues()) {
99 this.setEnabled(true);
100 }
101 }
102 },
103 command : null
104 },
105 */
106 "removefrombatch" : {
107 label : "Remove from batch",
108 icon : "org.argeo.slc.ria/edit-delete.png",
109 shortcut : null,
110 enabled : false,
111 menu : "Launcher",
112 toolbar : "batch",
113 callback : function(e) {
114 var sel = this.list.getSortedSelection();
115 var confirmPref = this.getRiaPreferenceValue("slc.batch.delete.confirm");
116 this.debug(confirmPref);
117 var execution = function() {
118 for (var i = 0; i < sel.length; i++) {
119 this.list.remove(sel[i]);
120 }
121 if (!this.list.hasChildren()) {
122 this.setBatchAgentId(null);
123 }
124 }
125 if(confirmPref){
126 var modal = new org.argeo.ria.components.Modal("Confirm", null);
127 modal.addConfirm("Are you sure you want to remove<br> the selected test"
128 + (sel.length > 1 ? "s" : "")
129 + " from the Batch?");
130 modal.addListener("ok", execution, this);
131 modal.attachAndShow();
132 }else{
133 execution = qx.lang.Function.bind(execution, this);
134 execution();
135 }
136 },
137 selectionChange : function(viewId, selection) {
138 if (viewId != "batch:list")
139 return;
140 this.setEnabled(false);
141 if ((selection && selection.length > 0))
142 this.setEnabled(true);
143 },
144 command : null
145 },
146 "clearbatch" : {
147 label : "Clear batch",
148 icon : "org.argeo.slc.ria/user-trash-full.png",
149 shortcut : null,
150 enabled : true,
151 menu : "Launcher",
152 toolbar : "batch",
153 callback : function(e) {
154 if(!this.list.hasChildren()) return;
155 this.list.selectAll();
156 this.getCommands()["removefrombatch"].command.execute();
157 },
158 selectionChange : function(viewId, selection) {
159 },
160 command : null
161 }
162 }
163 },
164 view : {
165 init : null
166 },
167 viewSelection : {
168 nullable:false,
169 check:"org.argeo.ria.components.ViewSelection"
170 },
171 instanceId : {init:""},
172 instanceLabel : {init:""},
173 /**
174 * A boolean registering whether the SpecEditor must autoOpen or not
175 * when a spec is added to the Batch.
176 */
177 autoOpen : {
178 init : true,
179 check : "Boolean"
180 },
181 batchAgentId : {
182 init : null,
183 nullable : true,
184 check : "String",
185 event : "changeBatchAgentId"
186 }
187 },
188
189 construct : function(){
190 this.base(arguments);
191 this.setLayout(new qx.ui.layout.Dock());
192 },
193
194 members : {
195 /**
196 * The implementation should contain the GUI initialisation.
197 * This is the role of the manager to actually add the graphical component to the pane,
198 * so it's not necessary to do it here.
199 * @param viewPane {org.argeo.ria.components.ViewPane} The pane manager
200 * @param data {Mixed} Any object or data passed by the initiator of the view
201 * @return {Boolean}
202 */
203 init : function(viewPane, data){
204 this.setView(viewPane);
205 this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
206 this._emptyAgentString = "Empty Batch (Drop scripts here)";
207 this._crtAgentString = "Batch Execution on Agent ";
208
209 },
210 /**
211 * The implementation should contain the real data loading (i.o. query...)
212 * @return {Boolean}
213 */
214 load : function(){
215 this._createLayout();
216 this.getView().setViewTitle(this._emptyAgentString);
217 //this.getView().setViewTitle("");
218 },
219
220 /**
221 * Creates the main applet layout.
222 */
223 _createLayout : function() {
224 this.listPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
225 this.addListener("changeBatchAgentId", function(event) {
226 var value = event.getData();
227 if (value == null) {
228 this.getView().setViewTitle(this._emptyAgentString);
229 } else {
230 var selectorView = org.argeo.ria.components.ViewsManager.getInstance().getViewPaneById("selector").getContent();
231 if(selectorView){
232 var agentsMap = selectorView.getAgentsMap();
233 this.getView().setViewTitle(this._crtAgentString + "'" + agentsMap[value] + "'");
234 }
235 }
236 }, this);
237
238 var indicator = new qx.ui.core.Widget();
239 indicator.setDecorator(new qx.ui.decoration.Single().set({
240 top : [1, "solid", "#33508D"]
241 }));
242 indicator.setHeight(0);
243 indicator.setOpacity(0.5);
244 indicator.setZIndex(100);
245 indicator.setLayoutProperties({
246 left : -1000,
247 top : -1000
248 });
249 org.argeo.ria.Application.INSTANCE.getRoot().add(indicator);
250
251 this.list = new qx.ui.form.List();
252 this.list.setDecorator(null);
253 this.list.setSelectionMode("multi");
254 this.list.setDroppable(true);
255 this.list.setDraggable(true);
256 this.list.setContextMenu(org.argeo.ria.event.CommandsManager
257 .getInstance().createMenuFromIds(["removefrombatch"]));
258
259 this.list.addListener("dragstart", function(e) {
260 e.addType(["items"]);
261 e.addAction(["move"]);
262 }, this);
263 this.list.addListener("dragend", function(e) {
264 indicator.setDomPosition(-1000, -1000);
265 });
266 this.list.addListener("dragover", function(e) {
267 var orig = e.getOriginalTarget();
268 var origCoords = orig.getContainerLocation();
269 indicator.setWidth(orig.getBounds().width);
270 indicator.setDomPosition(origCoords.left,
271 origCoords.bottom);
272 });
273 this.list.addListener("drag", function(e) {
274 var orig = e.getOriginalTarget();
275 var origCoords = orig.getContainerLocation();
276 indicator.setWidth(orig.getBounds().width);
277 indicator.setDomPosition(origCoords.left,
278 origCoords.bottom);
279 });
280
281 this.list.addListener("drop", function(e) {
282 var target = e.getRelatedTarget();
283 var afterItem = e.getOriginalTarget();
284 indicator.setDomPosition(-1000, -1000);
285 if (afterItem.classname != "qx.ui.form.ListItem")
286 afterItem = null;
287 if (!target) {
288 target = this.list.getSortedSelection()[0];
289 this.addFlowToBatch(target, afterItem);
290 } else {
291 org.argeo.ria.event.CommandsManager.getInstance().executeCommand("addtobatch");
292 }
293 }, this);
294 this.listPane.add(this.list, {
295 edge : "center"
296 });
297
298 this.list.addListener("changeSelection", function(e) {
299 var viewSelection = this.getViewSelection();
300 viewSelection.setViewId("batch:list");
301 viewSelection.clear();
302 var listSel = this.list.getSortedSelection();
303 for (var i = 0; i < listSel.length; i++) {
304 viewSelection.addNode(listSel[i]);
305 }
306 }, this);
307
308 this.dropDecorator = new qx.ui.decoration.Background();
309 this.dropDecorator.set({
310 backgroundImage : "org.argeo.slc.ria/drophere.gif",
311 backgroundRepeat : "no-repeat"
312 });
313
314
315 listChangeListener = function() {
316 var command = org.argeo.ria.event.CommandsManager.getInstance()
317 .getCommandById("submitform");
318 command.setEnabled(this.list.hasChildren());
319 var command2 = org.argeo.ria.event.CommandsManager.getInstance()
320 .getCommandById("clearbatch");
321 command2.setEnabled(this.list.hasChildren());
322 this.list.setDecorator((this.list.hasChildren()?null:this.dropDecorator));
323 };
324 this.list.addListener("addItem", listChangeListener, this);
325 this.list.addListener("removeItem", listChangeListener, this);
326
327 this.list.setDecorator(this.dropDecorator);
328
329 this.add(this.listPane);
330 },
331
332
333 /**
334 * Adds a given ExecutionFlow to the batch
335 *
336 * @param target
337 * {mixed} The dropped target, can be a TreeFile (add) or a
338 * ListItem (reorder).
339 * @param after
340 * {qx.ui.form.ListItem} Optional list item : if set, the
341 * flow will be added as a new list item positionned after
342 * this one.
343 * @param skipAutoOpen
344 * {boolean} Whether the formular should open or not.
345 */
346 addFlowToBatch : function(target, after, skipAutoOpen) {
347 if (target && target.classname == "qx.ui.form.ListItem") {
348 if (!after)
349 return;
350 if (after == "first")
351 this.list.addAt(target, 0);
352 else
353 this.list.addAfter(target, after);
354 return;
355 }
356
357 // Folder case
358 if (qx.Class.isSubClassOf(qx.Class.getByName(target.classname),
359 qx.ui.tree.TreeFolder)) {
360 var allChildren = target.getItems(true);
361 for (var i = 0; i < allChildren.length; i++) {
362 if (allChildren[i].getUserData("executionFlow")) {
363 try{
364 this.addFlowToBatch(allChildren[i], null, true);
365 }catch(e){
366 return;
367 }
368 }
369 }
370 return;
371 }
372
373 // Check agent Uuid against current batch agent Id.
374 var agentUuid = target.getUserData("agentUuid");
375 if (!this.getBatchAgentId()) {
376 this.setBatchAgentId(agentUuid);
377 } else if (this.getBatchAgentId() != agentUuid) {
378 this.error("Batch can contain tests only of the same agent!");
379 throw new Error("Batch can contain tests only of the same agent!");
380 }
381
382 var executionModule = target.getUserData("executionModule");
383 var executionFlow = target.getUserData("executionFlow");
384 var batchEntry = new org.argeo.slc.ria.execution.BatchEntrySpec(
385 executionModule, executionFlow);
386 var label = batchEntry.getLabel();
387 var icon = target.getIcon() || "org.argeo.slc.ria/office-document.png";
388 var item = new qx.ui.form.ListItem(label, icon);
389 /*
390 item.addListener("dblclick", function(e) {
391 this.getCommands()["editexecutionspecs"].command
392 .execute();
393 }, this);
394 */
395 item.setUserData("batchEntrySpec", batchEntry);
396 item.setPaddingTop(1);
397 item.setPaddingBottom(2);
398 if (after) {
399 if (after == "first")
400 this.list.addAt(item, 0);
401 else
402 this.list.addAfter(item, after);
403 } else {
404 this.list.add(item);
405 }
406 this.list.select(item);
407 /*
408 if (this.getAutoOpen() && !skipAutoOpen) {
409 this.getCommands()["editexecutionspecs"].command.execute();
410 }
411 */
412 },
413
414 /**
415 * Called at execution
416 *
417 * @param agentUuid
418 * {String} The id of the target agent
419 */
420 executeBatchOnAgent : function(agentUuid, clearBatch) {
421 var selection = this.list.getChildren();
422 if (!selection.length)
423 return;
424 var slcExecMessage = new org.argeo.slc.ria.execution.Message();
425 for (var i = 0; i < selection.length; i++) {
426 var batchEntrySpec = selection[i].getUserData("batchEntrySpec");
427 slcExecMessage.addBatchEntrySpec(batchEntrySpec);
428 }
429 try{
430 var xmlMessage = slcExecMessage.toXml();
431 var req = org.argeo.slc.ria.SlcApi.getNewSlcExecutionService(
432 agentUuid, xmlMessage);
433 req.send();
434 // Force logs refresh right now!
435 qx.event.Timer.once(function() {
436 var command = org.argeo.ria.event.CommandsManager
437 .getInstance().getCommandById("reloadlogs");
438 if (command) {
439 command.execute();
440 }
441 }, this, 2000);
442 if(clearBatch){
443 req.addListener("completed", function(e){
444 this.list.removeAll();
445 }, this);
446 }
447 }catch(e){
448 this.error(e);
449 }
450 },
451
452 clearBatchForAgentId : function(agentId){
453 if(this.getBatchAgentId() == agentId){
454 this.list.removeAll();
455 this.setBatchAgentId(null);
456 }
457 },
458
459 /**
460 * Whether this component is already contained in a scroller (return false) or not (return true).
461 * @return {Boolean}
462 */
463 addScroll : function(){return false;},
464 /**
465 * Called at destruction time
466 * Perform all the clean operations (stopping polling queries, etc.)
467 */
468 close : function(){return true;}
469 }
470
471
472 });