]> git.argeo.org Git - gpl/argeo-slc.git/blob - server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/LauncherApplet.js
Handle the folders drag'n'drop (dynamic nodes must be loaded, however).
[gpl/argeo-slc.git] / server / org.argeo.slc.ria / src / argeo-ria-lib / slc / class / org / argeo / slc / ria / LauncherApplet.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.LauncherApplet",
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 this.COMMON_FORM_HEADER_LABEL = "Choose Agent";
15 this.CHOOSE_AGENT_LABEL = "Agent Uuid";
16 this.CHOOSE_FORM_PART_LABEL = "Test Type";
17 },
18
19 properties :
20 {
21 /**
22 * The viewPane inside which this applet is added.
23 */
24 view : {
25 init : null
26 },
27 viewSelection : {
28 nullable:false,
29 check:"org.argeo.ria.components.ViewSelection"
30 },
31 instanceId : {init:""},
32 instanceLabel : {init:""},
33 /**
34 * Commands definition, see {@link org.argeo.ria.event.CommandsManager#definitions}
35 */
36 commands : {
37 init : {
38 "submitform" : {
39 label : "Execute",
40 icon : "resource/slc/media-playback-start.png",
41 shortcut : "Control+e",
42 enabled : true,
43 menu : "Launcher",
44 toolbar : "launcher",
45 callback : function(e){
46 this.submitForm();
47 },
48 command : null
49 },
50 "reloadagents" : {
51 label : "Reload Agents",
52 icon : "resource/slc/view-refresh.png",
53 shortcut : "Control+r",
54 enabled : true,
55 menu : "Launcher",
56 toolbar : "launcher",
57 callback : function(e){
58 var req = org.argeo.slc.ria.SlcApi.getListAgentsService("agents");
59 req.send();
60 },
61 command : null
62 }
63 }
64 },
65 /**
66 * A map containing all currently registered agents.
67 */
68 registeredTopics : {
69 init : {},
70 check : "Map",
71 event : "changeRegisteredTopics"
72 }
73 },
74
75 members :
76 {
77 /**
78 * Called at applet creation. Just registers viewPane.
79 * @param viewPane {org.argeo.ria.components.ViewPane} The viewPane.
80 */
81 init : function(viewPane){
82 this.setView(viewPane);
83 this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId()));
84 this._createLayout();
85 this._createForm();
86 this._amqClient = org.argeo.ria.remote.JmsClient.getInstance();
87 this._amqClient.startPolling();
88 },
89
90 /**
91 *
92 */
93 load : function(){
94 this.getView().setViewTitle("Execution Launcher");
95 this.addListener("changeRegisteredTopics", function(event){
96 //this._refreshTopicsSubscriptions(event);
97 this._feedSelector(event);
98 }, this);
99 var reloadHandler = function(message){
100 // Delay reload to be sure the jms was first integrated by the db, then ask the db.
101 qx.event.Timer.once(function(){
102 org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadagents").execute();
103 }, this, 1000);
104 }
105 this._amqClient.addListener("agentregister", "topic://agent.register", reloadHandler, this);
106 this._amqClient.addListener("agentunregister", "topic://agent.unregister", reloadHandler, this);
107 reloadHandler();
108 },
109
110 addScroll : function(){
111 return false;
112 },
113
114 close : function(){
115 this._amqClient.removeListener("agentregister", "topic://agent.register");
116 this._amqClient.removeListener("agentunregister", "topic://agent.unregister");
117
118 this.setRegisteredTopics({});
119 this._amqClient.stopPolling();
120 },
121
122 /**
123 * Creates the main applet layout.
124 */
125 _createLayout : function(){
126 this.formPane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
127 this.scroll = new qx.ui.container.Scroll(this.formPane);
128 this.formPane.setPadding(10);
129 this.add(this.scroll, {edge:'center'});
130
131 },
132
133 /**
134 * Creates the form.
135 */
136 _createForm : function(){
137 this.fields = {};
138 this.hiddenFields = {};
139 this.freeFields = [];
140
141 var execButtonPane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
142 var execButton = new qx.ui.form.Button(
143 "Execute",
144 "resource/slc/media-playback-start-32.png"
145 )
146 execButton.addListener("click", function(){
147 this.submitForm();
148 }, this);
149 execButtonPane.setPadding(10, 80);
150 execButtonPane.add(execButton, {edge:"center"});
151 this.formPane.add(execButtonPane);
152
153 this.agentSelector = new qx.ui.form.SelectBox();
154 var serviceManager = org.argeo.ria.remote.RequestManager.getInstance();
155 serviceManager.addListener("reload", function(reloadEvent){
156 if(reloadEvent.getDataType()!= "agents") return ;
157 var xmlDoc = reloadEvent.getContent();
158 var nodes = org.argeo.ria.util.Element.selectNodes(xmlDoc, "//slc:slc-agent-descriptor");
159 var newTopics = {};
160 for(var i=0;i<nodes.length;i++){
161 var uuid = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "@uuid");
162 var host = org.argeo.ria.util.Element.getSingleNodeText(nodes[i], "slc:host");
163 newTopics[uuid] = host+" ("+uuid+")";
164 }
165 this.setRegisteredTopics(newTopics);
166 }, this);
167
168 var commonForm = {pane:this.formPane};
169 this._addFormHeader(commonForm, this.COMMON_FORM_HEADER_LABEL);
170 this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_AGENT_LABEL), this.agentSelector);
171 this._createFormVariableParts();
172 if(!this.parts) return;
173 if(qx.lang.Object.getLength(this.parts) > 1){
174 // Add chooser
175 this.partChooser = new qx.ui.form.SelectBox();
176 for(var key in this.parts){
177 this.partChooser.add(new qx.ui.form.ListItem(this.parts[key].label, null, key));
178 }
179 this._addFormEntry(commonForm, new qx.ui.basic.Label(this.CHOOSE_FORM_PART_LABEL), this.partChooser);
180 this.partChooser.addListener("changeValue", function(ev){
181 this._showSelectedPart(ev.getData());
182 }, this);
183 }
184 this._showSelectedPart(qx.lang.Object.getKeys(this.parts)[0]);
185 },
186
187 /**
188 * Show a form part given its id.
189 * @param partId {String} The part id
190 */
191 _showSelectedPart : function(partId){
192 if(!this.parts) return;
193 if(!this.partsContainer){
194 this.partsContainer = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
195 this.formPane.add(this.partsContainer);
196 }
197 for(var i in this.parts){
198 var formObject = this.parts[i];
199 if(!formObject.added){
200 this.partsContainer.add(formObject.pane, {top:0, left:0});
201 formObject.added = true;
202 }
203 formObject.pane.hide();
204 }
205 if(this.parts[partId]){
206 this.parts[partId].pane.show();
207 }
208 },
209
210 /**
211 * Init a form part : creates a pane, a set of fields, etc.
212 * @param formId {String} A unique ID
213 * @param label {String} A label
214 * @return {Map} The form part.
215 */
216 _initFormPart : function(formId, label){
217 if(!this.parts) this.parts = {};
218 var formObject = {};
219 formObject.hiddenFields = {};
220 formObject.freeFields = [];
221 formObject.fields = {};
222 formObject.id = formId;
223 formObject.label = label;
224 this.parts[formId] = formObject;
225 formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));
226 return formObject;
227 },
228
229 /**
230 * To be overriden by this class children.
231 */
232 _createFormVariableParts : function(){
233 var standard = this._initFormPart("standard", "Canonical");
234 this._createStandardForm(standard);
235 var simple = this._initFormPart("simple", "SLC Sample");
236 this._createSimpleForm(simple);
237 },
238
239 /**
240 * Creates a form for SLC demo
241 * @param formObject {Map} The form part
242 */
243 _createSimpleForm : function(formObject){
244
245 this._addFormInputText(formObject, "ant.file", "File", "Category1/SubCategory2/build.xml");
246 var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
247 moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
248 moreButton.setCursor("pointer");
249 moreButton.addListener("click", function(){
250 this._addFormInputText(formObject);
251 }, this);
252 this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
253 this._addFormInputText(formObject);
254 this._addFormInputText(formObject);
255
256 },
257
258 /**
259 * Create a canonical form.
260 * @param formObject {Map} The form part
261 */
262 _createStandardForm : function(formObject){
263
264 this._addFormHeader(formObject, "Set Execution Parameters");
265 this._addFormInputText(formObject, "status", "Status", "STARTED");
266 this._addFormInputText(formObject, "host", "Host", "localhost");
267 this._addFormInputText(formObject, "user", "User", "user");
268
269 var moreButton = new qx.ui.basic.Image("resource/slc/list-add.png");
270 moreButton.setToolTip(new qx.ui.tooltip.ToolTip("Add a parameter"));
271 moreButton.setCursor("pointer");
272 moreButton.addListener("click", function(){
273 this._addFormInputText(formObject);
274 }, this);
275 this._addFormHeader(formObject, "Add optionnal parameters", moreButton);
276 this._addFormInputText(formObject);
277 this._addFormInputText(formObject);
278 },
279
280 /**
281 * Add an hidden field to the form
282 * @param formObject {Map} The form part
283 * @param fieldName {String} Name
284 * @param fieldValue {String} Value
285 */
286 _addFormHiddenField : function(formObject, fieldName, fieldValue){
287 formObject.hiddenFields[fieldName] = fieldValue;
288 },
289
290 /**
291 * Creates a simple label/input form entry.
292 * @param formObject {Map} The form part
293 * @param fieldName {String} Name
294 * @param fieldLabel {String} Label of the field
295 * @param defaultValue {String} The default value
296 * @param choiceValues {Map} An map of values
297 */
298 _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, choiceValues){
299 var labelElement;
300 if(choiceValues){
301 var fieldElement = new qx.ui.form.SelectBox();
302 for(var key in choiceValues){
303 fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));
304 }
305 }else{
306 var fieldElement = new qx.ui.form.TextField();
307 }
308 if(defaultValue){
309 fieldElement.setValue(defaultValue);
310 }
311 if(fieldName && fieldLabel){
312 labelElement = new qx.ui.basic.Label(fieldLabel);
313 formObject.fields[fieldName] = fieldElement;
314 }else{
315 labelElement = new qx.ui.form.TextField();
316 formObject.freeFields.push({
317 labelEl:labelElement,
318 valueEl:fieldElement
319 });
320 }
321 this._addFormEntry(formObject, labelElement, fieldElement);
322 },
323
324 /**
325 * Add an header
326 * @param formObject {Map} The form part
327 * @param content {Mixed} Content to add.
328 * @param additionnalButton {Mixed} Any widget to add on the east.
329 */
330 _addFormHeader : function(formObject, content, additionnalButton){
331 var header = new qx.ui.basic.Label('<b>'+content+'</b>');
332 header.setRich(true);
333 if(!additionnalButton){
334 header.setPaddingTop(10);
335 formObject.pane.add(header);
336 }else{
337 var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());
338 pane.setPaddingTop(10);
339 pane.setPaddingRight(10);
340 pane.add(header, {edge:'center'});
341 pane.add(additionnalButton, {edge:'east'});
342 formObject.pane.add(pane);
343 }
344 },
345
346 /**
347 * Adds a label/input like entry in the form.
348 * @param formObject {Map} The form part
349 * @param labelElement {Object} Either a label or an input
350 * @param fieldElement {Object} Any form input.
351 */
352 _addFormEntry : function(formObject, labelElement, fieldElement){
353 var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));
354 labelElement.setWidth(100);
355 labelElement.setTextAlign("right");
356 entryPane.add(labelElement);
357 entryPane.add(new qx.ui.basic.Label(':'));
358 fieldElement.setWidth(150);
359 entryPane.add(fieldElement);
360 formObject.pane.add(entryPane);
361 },
362
363 /*
364 _refreshTopicsSubscriptions : function(changeTopicsEvent){
365 var oldTopics = changeTopicsEvent.getOldData() || {};
366 var newTopics = changeTopicsEvent.getData();
367 var removed = [];
368 var added = [];
369 for(var key in oldTopics){
370 if(!newTopics[key]) {
371 //this._removeAmqListener(key);
372 }
373 }
374 for(var key in newTopics){
375 if(!oldTopics[key]) {
376 //this._addAmqListener(key);
377 }
378 }
379 },
380 */
381
382 /**
383 * Refresh the selector when the topics are updated.
384 * @param changeTopicsEvent {qx.event.type.DataEvent} The reload event.
385 */
386 _feedSelector : function(changeTopicsEvent){
387 var topics = changeTopicsEvent.getData();
388 this.agentSelector.removeAll();
389 var emptyItem = new qx.ui.form.ListItem("", null, "");
390 this.agentSelector.add(emptyItem);
391 this.agentSelector.setSelected(emptyItem);
392 for(var key in topics){
393 var listItem = new qx.ui.form.ListItem(topics[key], null, key);
394 this.agentSelector.add(listItem);
395 }
396 },
397
398 /*
399 _addAmqListener: function(uuid){
400 this._amqClient.addListener("slcExec", "topic://agent."+uuid+".newExecution", function(response){
401 var message = org.argeo.ria.util.Element.selectSingleNode(response, "slc:slc-execution");
402 var slcExec = new org.argeo.slc.ria.SlcExecutionMessage(message.getAttribute("uuid"));
403 slcExec.fromXml(message);
404 this.logModel.addRows([
405 [new Date().toString(), slcExec.getHost()+' ('+slcExec.getUuid()+')', slcExec.getStatus()]
406 ]);
407 }, this);
408 },
409
410 _removeAmqListener : function(uuid){
411 this._amqClient.removeListener("slcExec", "topic://agent."+uuid+".newExecution");
412 },
413 */
414
415 /**
416 * Make an SlcExecutionMessage from the currently displayed form.
417 * @param crtPartId {String} The form part currently displayed
418 * @param slcExec {org.argeo.slc.ria.SlcExecutionMessage} The message to fill.
419 * @param fields {Map} The fields of the form
420 * @param hiddenFields {Map} The hidden ones
421 * @param freeFields {Array} The free fields.
422 */
423 _prepareSlcExecutionMessage : function(crtPartId, slcExec, fields, hiddenFields, freeFields){
424 if(crtPartId == "standard"){
425 slcExec.setStatus(fields.status.getValue());
426 slcExec.setHost(fields.host.getValue());
427 slcExec.setUser(fields.user.getValue());
428 }else{
429 slcExec.addAttribute("ant.file", fields["ant.file"].getValue());
430 }
431 for(var i=0;i<freeFields.length;i++){
432 var fF = freeFields[i];
433 if(fF.labelEl.getValue() != "" && fF.valueEl.getValue() != ""){
434 slcExec.addAttribute(fF.labelEl.getValue(), fF.valueEl.getValue());
435 }
436 }
437 },
438
439 /**
440 * Called when the user clicks the "Execute" button.
441 */
442 submitForm : function(){
443 var currentUuid = this.agentSelector.getValue();
444 if(!currentUuid) return;
445 var slcExec = new org.argeo.slc.ria.SlcExecutionMessage();
446
447 var fields = {};
448 var hiddenFields = {};
449 var freeFields = {};
450 var crtPartId = "";
451 if(this.parts){
452 if(this.partChooser){
453 crtPartId = this.partChooser.getValue();
454 }else{
455 crtPartId = qx.lang.Object.getKeys(this.parts)[0];
456 }
457 var crtPart = this.parts[crtPartId];
458 fields = crtPart.fields;
459 hiddenFields = crtPart.hiddenFields;
460 freeFields = crtPart.freeFields;
461 }
462
463 this._prepareSlcExecutionMessage(crtPartId, slcExec, fields, hiddenFields, freeFields);
464
465 this._amqClient.sendMessage(
466 "topic://agent.newExecution",
467 slcExec.toXml(),
468 {"slc-agentId":currentUuid}
469 );
470 // Force logs refresh right now!
471 qx.event.Timer.once(function(){
472 var command = org.argeo.ria.event.CommandsManager.getInstance().getCommandById("reloadlogs");
473 if(command){
474 command.execute();
475 }
476 }, this, 2000);
477 }
478
479 }
480 });