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