]>
git.argeo.org Git - gpl/argeo-slc.git/blob - FlowsSelectorView.js
d15b71a1d265a3310c0cdbb57f97580d422f182c
5 qx
.Class
.define("org.argeo.slc.ria.FlowsSelectorView", {
6 extend
: qx
.ui
.container
.Composite
,
7 implement
: [org
.argeo
.ria
.components
.IView
],
8 include
: [org
.argeo
.ria
.session
.MPrefHolder
],
10 construct : function() {
12 this.setLayout(new qx
.ui
.layout
.Dock());
17 * The viewPane inside which this applet is added.
24 check
: "org.argeo.ria.components.ViewSelection"
37 * Commands definition, see
38 * {@link org.argeo.ria.event.CommandsManager#definitions}
43 label
: "Add to batch",
44 icon
: "org.argeo.slc.ria/list-add.png",
49 callback : function(e
) {
50 if (this.tree
.isSelectionEmpty()) {
53 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
54 if(!batchView
) return;
55 selection
= this.tree
.getSelection();
56 if (selection
.length
> 1) {
57 for (var i
= 0; i
< selection
.length
; i
++) {
59 batchView
.addFlowToBatch(selection
[i
], null, true);
67 batchView
.addFlowToBatch(selection
[0], null);
72 if(this.getExecuteAfterAdd() && batchView
.getCommands()){
73 batchView
.setForceClearPreference(true);
74 batchView
.getCommands()["submitform"].command
.execute();
76 this.setExecuteAfterAdd(false);
78 selectionChange : function(viewId
, selection
) {
79 if (viewId
!= "form:tree")
81 if (!selection
|| selection
.length
!= 1)
83 var item
= selection
[0];
84 this.setEnabled(false);
85 switch (item
.classname
) {
86 case "qx.ui.tree.TreeFile" :
87 this.setEnabled(true);
89 case "org.argeo.ria.components.PersistentTreeFolder" :
90 if (item
.getTree() && item
.getTree().getRoot() == item
)
92 this.setEnabled(true);
94 case "org.argeo.ria.components.DynamicTreeFolder" :
95 if (item
.getTree() && item
.getTree().getRoot() == item
)
97 if (item
.getState() == "loaded")
98 this.setEnabled(true);
105 label
: "Toggle 'Preferred Host'",
106 icon
: "ria/bookmark.png",
111 callback : function(e
) {
112 if (this.tree
.isSelectionEmpty()) {
115 var selection
= this.tree
.getSelection();
116 if(selection
.length
!= 1) return;
117 var agentNode
= selection
[0];
118 if(!agentNode
.getUserData("agentHost")) return;
119 this.togglePreferredHost(agentNode
);
121 selectionChange : function(viewId
, selection
) {
122 if (viewId
!= "form:tree")
124 if (!selection
|| selection
.length
!= 1)
126 var item
= selection
[0];
127 this.setEnabled(false);
128 if(item
.getUserData("agentHost")){
129 this.setEnabled(true);
135 label
: "Reload Agents",
136 icon
: "org.argeo.slc.ria/view-refresh.png",
137 shortcut
: "control+h",
141 callback : function(e
) {
142 this.rootNode
.reload();
147 label
: "Reload Node",
148 icon
: "org.argeo.slc.ria/view-refresh.png",
153 callback : function(e
) {
154 if (this.tree
.isSelectionEmpty()) { return; }
155 var selected
= this.tree
.getSelection()[0];
156 if (selected
.classname
== "org.argeo.ria.components.DynamicTreeFolder") {
157 if (selected
.getUserData("moduleData")) {
158 // It's a "module" node, first trigger the
159 // reloadBundle.service
160 selected
.setUserData("dataModel", {});
161 selected
.setEnabled(false);
162 selected
.setOpen(false);
163 var moduleData
= selected
164 .getUserData("moduleData");
165 var bundleService
= org
.argeo
.slc
.ria
.SlcApi
166 .getReloadBundleService(
169 bundleService
.addListener("completed",
171 selected
.setEnabled(true);
172 selected
.setOpen(true);
175 // bundleService.send();
176 // Do not send, not implemented yet, false timer
178 qx
.event
.Timer
.once(function(response
) {
179 selected
.setEnabled(true);
180 selected
.setOpen(true);
188 selectionChange : function(viewId
, selection
) {
189 if (viewId
!= "form:tree")
193 if (selection
.length
> 1) {
194 this.setEnabled(false);
197 var item
= selection
[0];
198 if (!qx
.Class
.isSubClassOf(qx
.Class
199 .getByName(item
.classname
),
200 qx
.ui
.tree
.AbstractTreeItem
))
202 this.setEnabled(false);
203 if (qx
.Class
.isSubClassOf(qx
.Class
204 .getByName(item
.classname
),
205 org
.argeo
.ria
.components
.DynamicTreeFolder
)) {
206 this.setEnabled(true);
218 "flowSelector.preferred.hosts" : {
219 label
: "Preferred Hosts (Execution View)",
225 * Static loader for the "agent" level (first level)
228 * {org.argeo.ria.components.PersistentTreeFolder} The root Tree Folder.
230 agentLoader : function(folder
) {
232 var preferredHosts
= org
.argeo
.ria
.session
.MPrefHolder
.loadRiaPreferenceValue("flowSelector.preferred.hosts");
233 if(preferredHosts
&& preferredHosts
!=""){
234 preferredHosts
= preferredHosts
.split(",");
236 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListAgentsService("agents");
238 if(folder
.getState() == "loaded" && folder
.getUserData("agentsMap")){
239 // Diff loading, just add new nodes.
240 agents
= folder
.getUserData("agentsMap");
243 req
.addListener("completed", function(response
) {
244 var xmlDoc
= response
.getContent();
245 var nodes
= org
.argeo
.ria
.util
.Element
.selectNodes(xmlDoc
,
246 "/slc:object-list/slc:slc-agent-descriptor");
247 var modulesLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.modulesLoader
;
249 for (var i
= 0; i
< nodes
.length
; i
++) {
250 var uuid
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "@uuid");
251 var host
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "slc:host");
253 newAgents
[uuid
] = host
;
257 if(newAgents
) newAgents
[uuid
] = host
;
258 var agentFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
259 host
, modulesLoader
, "Loading Modules...", folder
.getDragData());
260 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(agentFolder
, uuid
);
261 agentFolder
.setPersistentTreeID(folder
.getPersistentTreeID()+"_"+uuid
);
262 agentFolder
.setUserData("agentHost", host
); // Used by bookmark system
263 agentFolder
.setUserData("agentUuid", uuid
);
264 if(preferredHosts
&& preferredHosts
instanceof Array
&& qx
.lang
.Array
.contains(preferredHosts
, host
)){
265 folder
.addAtBegin(agentFolder
);
266 agentFolder
.setIcon("org.argeo.slc.ria/computer_bookmarked.png");
268 folder
.add(agentFolder
);
269 agentFolder
.setIcon("org.argeo.slc.ria/computer.png");
273 // Make sure some agents should not be removed
274 for(var agentKey
in agents
){
275 if(!newAgents
[agentKey
]){
276 var node
= org
.argeo
.slc
.ria
.FlowsSelectorView
.findAgentNodeById(folder
, agentKey
);
277 if(node
) folder
.remove(node
);
278 delete agents
[agentKey
];
279 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
280 if(batchView
) batchView
.clearBatchForAgentId(agentKey
);
284 folder
.setUserData("agentsMap", agents
);
285 folder
.setLoaded(true);
286 folder
.getTree().fireEvent("changeSelection");
288 req
.addListener("failed", function(response
) {
289 folder
.setLoaded(true);
296 * Loader for the "modules" level : takes any tree folder, currently the
300 * {org.argeo.ria.components.PersistentTreeFolder} The root folder
302 modulesLoader : function(folder
) {
303 var agentId
= folder
.getUserData("agentUuid");
304 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListModulesService(agentId
);
305 req
.addListener("completed", function(response
) {
306 var descriptors
= org
.argeo
.ria
.util
.Element
.selectNodes(
307 response
.getContent(),
308 "slc:object-list/" + org
.argeo
.slc
.ria
.execution
.Module
.XPATH_ROOT
);
310 for (var i
= 0; i
< descriptors
.length
; i
++) {
311 var tmpModule
= new org
.argeo
.slc
.ria
.execution
.Module();
313 tmpModule
.setXmlNode(descriptors
[i
]);
315 qx
.log
.Logger
.error(e
);
317 var name
= tmpModule
.getName();
318 var version
= tmpModule
.getVersion();
321 mods
[name
].push(tmpModule
);
323 var flowLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.flowLoader
;
324 for (var key
in mods
) {
325 for (var i
= 0; i
< mods
[key
].length
; i
++) {
326 var module
= mods
[key
][i
];
327 var versionFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
328 module
.getLabel(), flowLoader
,
329 "Loading Flows", folder
.getDragData());
330 versionFolder
.setUserData("moduleData", {
332 version
: module
.getVersion()
334 versionFolder
.setIcon("org.argeo.slc.ria/archive.png");
335 versionFolder
.setUserData("agentUuid", agentId
);
336 var sep
= (module
.getDescription()!=""?" - ":"");
337 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(versionFolder
, key
+ ' (' + module
.getVersion() + ')'+sep
+module
.getDescription());
338 // Warning, we must add it AFTER setting the user data,
339 // because of the persistent loading mechanism.
340 folder
.add(versionFolder
);
343 folder
.setLoaded(true);
344 folder
.getTree().fireEvent("changeSelection");
346 req
.addListener("failed", function(response
) {
347 folder
.setLoaded(true);
353 * Loader for the "flow" level : takes a folder containing "moduleData"
354 * and create its children.
357 * {org.argeo.ria.components.PersistentTreeFolder} A Tree folder containing in the
358 * key "moduleData" of its user data a map containing the
359 * keys {name,version}
361 flowLoader : function(folder
) {
362 var moduleData
= folder
.getUserData("moduleData");
363 var agentUuid
= folder
.getUserData("agentUuid");
365 var req
= org
.argeo
.slc
.ria
.SlcApi
366 .getLoadExecutionDescriptorService(agentUuid
,
367 moduleData
.name
, moduleData
.version
);
368 req
.addListener("completed", function(response
) {
369 var executionModule
= new org
.argeo
.slc
.ria
.execution
.Module();
371 executionModule
.setXmlNode(response
.getContent());
375 var execFlows
= executionModule
.getExecutionFlows();
376 for (var key
in execFlows
) {
377 var path
= execFlows
[key
].getPath();
378 var name
= execFlows
[key
].getName();
381 if(name
&& name
.indexOf(sep
)>-1 && !path
){
382 // Use given name to build the path.
383 // split dirname and basename
384 var parts
= name
.split(sep
);
385 var basename
= parts
.pop();
386 var dirname
= parts
.join("/");
388 nodeLabel
= basename
;
390 var file
= new qx
.ui
.tree
.TreeFile(nodeLabel
);
391 if(execFlows
[key
].getDescription() != ""){
392 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(file
, execFlows
[key
].getDescription());
394 file
.setIcon("org.argeo.slc.ria/system.png");
395 file
.setUserData("executionModule", executionModule
);
396 file
.setUserData("executionFlow", execFlows
[key
]);
397 file
.setUserData("agentUuid", agentUuid
);
398 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachNodeByPath(folder
, path
, file
, {
399 agentUuid
: folder
.getUserData("agentUuid")
401 folder
.appendDragData(file
);
403 folder
.setLoaded(true);
404 folder
.getTree().fireEvent("changeSelection");
406 req
.addListener("failed", function(response
) {
407 folder
.setLoaded(true);
412 attachToolTip : function(nodeItem
, description
){
413 var tt
= new qx
.ui
.tooltip
.ToolTip(description
);
414 tt
.setShowTimeout(0);
415 nodeItem
.setToolTip(tt
);
419 * Parse a string path and search if there is a root node.
422 * {org.argeo.ria.components.DynamicTreeFolder} The parent
423 * node (containing data model)
425 * {String} The path of the node to attach.
427 * {qx.ui.tree.TreeFile} The leaf node
429 * {Map} User data to attach at all levels.
431 attachNodeByPath : function(rootNode
, path
, childNode
, userData
) {
432 if (!path
|| path
== "" || path
== "/") {
433 rootNode
.add(childNode
);
436 var model
= rootNode
.getUserData("dataModel");
439 rootNode
.setUserData("dataModel", model
);
441 var parts
= path
.split("/");
442 var keys
= qx
.lang
.Object
.getKeys(model
);
444 var crtFolder
= rootNode
;
445 for (var i
= 0; i
< parts
.length
; i
++) {
448 crtPath
+= "/" + parts
[i
];
449 if (!model
[crtPath
]) {
450 var virtualFolder
= new org
.argeo
.ria
.components
.PersistentTreeFolder(parts
[i
]);
451 if (userData
&& qx
.lang
.Object
.getLength(userData
)) {
452 for (var key
in userData
) {
453 virtualFolder
.setUserData(key
, userData
[key
]);
456 rootNode
.appendDragData(virtualFolder
);
457 model
[crtPath
] = virtualFolder
;
458 crtFolder
.add(virtualFolder
);
459 crtFolder
= virtualFolder
;
461 crtFolder
= model
[crtPath
];
464 crtFolder
.add(childNode
);
467 findAgentNodeById : function(node
, agentId
){
468 var nodeAgents
= node
.getItems();
469 for(var i
=0;i
<nodeAgents
.length
;i
++){
470 if(nodeAgents
[i
].getUserData("agentUuid") == agentId
){
471 return nodeAgents
[i
];
479 * Called at applet creation. Just registers viewPane.
482 * {org.argeo.ria.components.ViewPane} The viewPane.
484 init : function(viewPane
) {
485 this.setView(viewPane
);
486 this.setViewSelection(new org
.argeo
.ria
.components
.ViewSelection(viewPane
.getViewId()));
487 this.remoteNotifier
= new org
.argeo
.ria
.remote
.RemoteNotifier(
488 "/org.argeo.slc.webapp/", "pollEvent.service",
489 "addEventListener.service", "removeEventListener.service");
490 this.remoteNotifier
.setEventParamName("slc_eventType");
491 this.remoteNotifier
.setEventXPath("/slc:slc-event");
493 .setEventTypeXPath('slc:headers/slc:header[@name="slc_eventType"]');
495 .setEventDataXPath('slc:headers/slc:header[@name="slc_agentId"]');
496 this.remoteNotifier
.setAnswerStatusXPath("slc:execution-answer/slc:status");
497 this.remoteNotifier
.startPolling();
498 this.UIBus
= org
.argeo
.ria
.event
.UIBus
.getInstance();
499 this.UIBus
.registerNotifier(this.remoteNotifier
);
506 this._createLayout();
507 this.getView().setViewTitle("Available Scripts");
508 this.UIBus
.addListener("agentRegistered", this._addAgentHandler
, this);
509 this.UIBus
.addListener("agentUnregistered", this._removeAgentHandler
, this);
512 _addAgentHandler : function(agentId
){
513 this.rootNode
.load();
516 _removeAgentHandler : function(agentId
){
517 var treeNode
= this.self(arguments
).findAgentNodeById(this.rootNode
, agentId
);
519 this.rootNode
.remove(treeNode
);
521 var agentsMap
= this.getAgentsMap();
522 if(agentsMap
[agentId
]){
523 delete agentsMap
[agentId
];
525 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
527 batchView
.clearBatchForAgentId(agentId
);
531 addScroll : function() {
536 this.UIBus
.removeListener("agentRegistered", this._addAgentHandler
, this);
537 this.UIBus
.removeListener("agentUnregistered", this._removeAgentHandler
, this);
538 this.remoteNotifier
.stopPolling();
543 * @param agentNode {qx.ui.tree.AbstractTreeItem}
545 togglePreferredHost : function(agentNode
){
546 var hostName
= agentNode
.getUserData("agentHost");
547 var pref
= this.getRiaPreferenceValue("flowSelector.preferred.hosts");
550 prefArray
= pref
.split(",");
552 if(qx
.lang
.Array
.contains(prefArray
, hostName
)){
553 qx
.lang
.Array
.remove(prefArray
, hostName
);
554 agentNode
.setIcon("org.argeo.slc.ria/computer.png");
556 prefArray
.push(hostName
);
557 agentNode
.setIcon("org.argeo.slc.ria/computer_bookmarked.png");
558 var parent
= agentNode
.getParent();
559 parent
.remove(agentNode
);
560 parent
.addAtBegin(agentNode
);
562 this.setRiaPreferenceValue("flowSelector.preferred.hosts", prefArray
.join(","));
566 * Creates the main applet layout.
568 _createLayout : function() {
570 this.tree
= new qx
.ui
.tree
.Tree();
571 this.tree
.setDecorator(null);
572 this.tree
.setSelectionMode("multi");
584 this.rootNode
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
585 "Tests", this.self(arguments
).agentLoader
,
586 "Loading Agents", dragData
);
587 this.tree
.setRoot(this.rootNode
);
588 this.tree
.setHideRoot(true);
589 this.rootNode
.setPersistentTreeID("org.argeo.slc.ria.FlowsSelector")
590 this.rootNode
.setOpen(true);
591 this.tree
.setContextMenu(org
.argeo
.ria
.event
.CommandsManager
592 .getInstance().createMenuFromIds(["addtobatch",
593 "reloadtree", "preferredHost"]));
595 this.tree
.addListener("changeSelection", function(e
) {
596 var viewSelection
= this.getViewSelection();
597 viewSelection
.setViewId("form:tree");
598 viewSelection
.clear();
599 var sel
= this.tree
.getSortedSelection();
600 for (var i
= 0; i
< sel
.length
; i
++) {
601 viewSelection
.addNode(sel
[i
]);
605 this.tree
.addListener("dblclick", function(e
){
606 var sel
= this.tree
.getSortedSelection();
607 if(sel
&& sel
.length
!=1) return;
609 if(origin
.classname
== "qx.ui.tree.TreeFile"){
610 this.setExecuteAfterAdd(true);
611 this.getCommands()["addtobatch"].command
.execute();
618 getAgentsMap : function(){
619 return this.rootNode
.getUserData("agentsMap");