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