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