]>
git.argeo.org Git - gpl/argeo-slc.git/blob - server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/FlowsSelectorView.js
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"
33 * Commands definition, see
34 * {@link org.argeo.ria.event.CommandsManager#definitions}
39 label
: "Add to batch",
40 icon
: "org.argeo.slc.ria/list-add.png",
45 callback : function(e
) {
46 if (this.tree
.isSelectionEmpty()) {
49 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
50 if(!batchView
) return;
51 selection
= this.tree
.getSelection();
52 if (selection
.length
> 1) {
53 for (var i
= 0; i
< selection
.length
; i
++) {
55 batchView
.addFlowToBatch(selection
[i
], null, true);
63 batchView
.addFlowToBatch(selection
[0], null);
69 selectionChange : function(viewId
, selection
) {
70 if (viewId
!= "form:tree")
72 if (!selection
|| selection
.length
!= 1)
74 var item
= selection
[0];
75 this.setEnabled(false);
76 switch (item
.classname
) {
77 case "qx.ui.tree.TreeFile" :
78 this.setEnabled(true);
80 case "org.argeo.ria.components.PersistentTreeFolder" :
81 if (item
.getTree() && item
.getTree().getRoot() == item
)
83 this.setEnabled(true);
85 case "org.argeo.ria.components.DynamicTreeFolder" :
86 if (item
.getTree() && item
.getTree().getRoot() == item
)
88 if (item
.getState() == "loaded")
89 this.setEnabled(true);
96 label
: "Toggle 'Preferred Host'",
97 icon
: "ria/bookmark.png",
102 callback : function(e
) {
103 if (this.tree
.isSelectionEmpty()) {
106 var selection
= this.tree
.getSelection();
107 if(selection
.length
!= 1) return;
108 var agentNode
= selection
[0];
109 if(!agentNode
.getUserData("agentHost")) return;
110 this.togglePreferredHost(agentNode
);
112 selectionChange : function(viewId
, selection
) {
113 if (viewId
!= "form:tree")
115 if (!selection
|| selection
.length
!= 1)
117 var item
= selection
[0];
118 this.setEnabled(false);
119 if(item
.getUserData("agentHost")){
120 this.setEnabled(true);
126 label
: "Reload Agents",
127 icon
: "org.argeo.slc.ria/view-refresh.png",
128 shortcut
: "control+h",
132 callback : function(e
) {
133 this.rootNode
.reload();
138 label
: "Reload Node",
139 icon
: "org.argeo.slc.ria/view-refresh.png",
144 callback : function(e
) {
145 if (this.tree
.isSelectionEmpty()) { return; }
146 var selected
= this.tree
.getSelection()[0];
147 if (selected
.classname
== "org.argeo.ria.components.DynamicTreeFolder") {
148 if (selected
.getUserData("moduleData")) {
149 // It's a "module" node, first trigger the
150 // reloadBundle.service
151 selected
.setUserData("dataModel", {});
152 selected
.setEnabled(false);
153 selected
.setOpen(false);
154 var moduleData
= selected
155 .getUserData("moduleData");
156 var bundleService
= org
.argeo
.slc
.ria
.SlcApi
157 .getReloadBundleService(
160 bundleService
.addListener("completed",
162 selected
.setEnabled(true);
163 selected
.setOpen(true);
166 // bundleService.send();
167 // Do not send, not implemented yet, false timer
169 qx
.event
.Timer
.once(function(response
) {
170 selected
.setEnabled(true);
171 selected
.setOpen(true);
179 selectionChange : function(viewId
, selection
) {
180 if (viewId
!= "form:tree")
184 if (selection
.length
> 1) {
185 this.setEnabled(false);
188 var item
= selection
[0];
189 if (!qx
.Class
.isSubClassOf(qx
.Class
190 .getByName(item
.classname
),
191 qx
.ui
.tree
.AbstractTreeItem
))
193 this.setEnabled(false);
194 if (qx
.Class
.isSubClassOf(qx
.Class
195 .getByName(item
.classname
),
196 org
.argeo
.ria
.components
.DynamicTreeFolder
)) {
197 this.setEnabled(true);
209 "flowSelector.preferred.hosts" : {
210 label
: "Preferred Hosts (Execution View)",
216 * Static loader for the "agent" level (first level)
219 * {org.argeo.ria.components.PersistentTreeFolder} The root Tree Folder.
221 agentLoader : function(folder
) {
223 var preferredHosts
= org
.argeo
.ria
.session
.MPrefHolder
.loadRiaPreferenceValue("flowSelector.preferred.hosts");
224 if(preferredHosts
&& preferredHosts
!=""){
225 preferredHosts
= preferredHosts
.split(",");
227 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListAgentsService("agents");
229 if(folder
.getState() == "loaded" && folder
.getUserData("agentsMap")){
230 // Diff loading, just add new nodes.
231 agents
= folder
.getUserData("agentsMap");
234 req
.addListener("completed", function(response
) {
235 var xmlDoc
= response
.getContent();
236 var nodes
= org
.argeo
.ria
.util
.Element
.selectNodes(xmlDoc
,
237 "/slc:object-list/slc:slc-agent-descriptor");
238 var modulesLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.modulesLoader
;
240 for (var i
= 0; i
< nodes
.length
; i
++) {
241 var uuid
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "@uuid");
242 var host
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "slc:host");
244 newAgents
[uuid
] = host
;
248 if(newAgents
) newAgents
[uuid
] = host
;
249 var agentFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
250 host
, modulesLoader
, "Loading Modules...", folder
.getDragData());
251 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(agentFolder
, uuid
);
252 agentFolder
.setPersistentTreeID(folder
.getPersistentTreeID()+"_"+uuid
);
253 agentFolder
.setUserData("agentHost", host
); // Used by bookmark system
254 agentFolder
.setUserData("agentUuid", uuid
);
255 if(preferredHosts
&& preferredHosts
instanceof Array
&& qx
.lang
.Array
.contains(preferredHosts
, host
)){
256 folder
.addAtBegin(agentFolder
);
257 agentFolder
.setIcon("org.argeo.slc.ria/computer_bookmarked.png");
259 folder
.add(agentFolder
);
260 agentFolder
.setIcon("org.argeo.slc.ria/computer.png");
264 // Make sure some agents should not be removed
265 for(var agentKey
in agents
){
266 if(!newAgents
[agentKey
]){
267 var node
= org
.argeo
.slc
.ria
.FlowsSelectorView
.findAgentNodeById(folder
, agentKey
);
268 if(node
) folder
.remove(node
);
269 delete agents
[agentKey
];
270 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
271 if(batchView
) batchView
.clearBatchForAgentId(agentKey
);
275 folder
.setUserData("agentsMap", agents
);
276 folder
.setLoaded(true);
277 folder
.getTree().fireEvent("changeSelection");
279 req
.addListener("failed", function(response
) {
280 folder
.setLoaded(true);
287 * Loader for the "modules" level : takes any tree folder, currently the
291 * {org.argeo.ria.components.PersistentTreeFolder} The root folder
293 modulesLoader : function(folder
) {
294 var agentId
= folder
.getUserData("agentUuid");
295 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListModulesService(agentId
);
296 req
.addListener("completed", function(response
) {
297 var descriptors
= org
.argeo
.ria
.util
.Element
.selectNodes(
298 response
.getContent(),
299 "slc:object-list/" + org
.argeo
.slc
.ria
.execution
.Module
.XPATH_ROOT
);
301 for (var i
= 0; i
< descriptors
.length
; i
++) {
302 var tmpModule
= new org
.argeo
.slc
.ria
.execution
.Module();
304 tmpModule
.setXmlNode(descriptors
[i
]);
306 qx
.log
.Logger
.error(e
);
308 var name
= tmpModule
.getName();
309 var version
= tmpModule
.getVersion();
312 mods
[name
].push(tmpModule
);
314 var flowLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.flowLoader
;
315 for (var key
in mods
) {
316 for (var i
= 0; i
< mods
[key
].length
; i
++) {
317 var module
= mods
[key
][i
];
318 var versionFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
319 module
.getLabel(), flowLoader
,
320 "Loading Flows", folder
.getDragData());
321 versionFolder
.setUserData("moduleData", {
323 version
: module
.getVersion()
325 versionFolder
.setIcon("org.argeo.slc.ria/archive.png");
326 versionFolder
.setUserData("agentUuid", agentId
);
327 var sep
= (module
.getDescription()!=""?" - ":"");
328 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(versionFolder
, key
+ ' (' + module
.getVersion() + ')'+sep
+module
.getDescription());
329 // Warning, we must add it AFTER setting the user data,
330 // because of the persistent loading mechanism.
331 folder
.add(versionFolder
);
334 folder
.setLoaded(true);
335 folder
.getTree().fireEvent("changeSelection");
337 req
.addListener("failed", function(response
) {
338 folder
.setLoaded(true);
344 * Loader for the "flow" level : takes a folder containing "moduleData"
345 * and create its children.
348 * {org.argeo.ria.components.PersistentTreeFolder} A Tree folder containing in the
349 * key "moduleData" of its user data a map containing the
350 * keys {name,version}
352 flowLoader : function(folder
) {
353 var moduleData
= folder
.getUserData("moduleData");
354 var agentUuid
= folder
.getUserData("agentUuid");
356 var req
= org
.argeo
.slc
.ria
.SlcApi
357 .getLoadExecutionDescriptorService(agentUuid
,
358 moduleData
.name
, moduleData
.version
);
359 req
.addListener("completed", function(response
) {
360 var executionModule
= new org
.argeo
.slc
.ria
.execution
.Module();
362 executionModule
.setXmlNode(response
.getContent());
366 var execFlows
= executionModule
.getExecutionFlows();
367 for (var key
in execFlows
) {
368 var file
= new qx
.ui
.tree
.TreeFile(key
);
369 if(execFlows
[key
].getDescription() != ""){
370 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(file
, execFlows
[key
].getDescription());
372 file
.setIcon("org.argeo.slc.ria/system.png");
373 var path
= execFlows
[key
].getPath();
374 file
.setUserData("executionModule", executionModule
);
375 file
.setUserData("executionFlow", execFlows
[key
]);
376 file
.setUserData("agentUuid", agentUuid
);
377 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachNodeByPath(folder
, path
, file
, {
378 agentUuid
: folder
.getUserData("agentUuid")
380 folder
.appendDragData(file
);
382 folder
.setLoaded(true);
383 folder
.getTree().fireEvent("changeSelection");
385 req
.addListener("failed", function(response
) {
386 folder
.setLoaded(true);
391 attachToolTip : function(nodeItem
, description
){
392 var tt
= new qx
.ui
.tooltip
.ToolTip(description
);
393 tt
.setShowTimeout(0);
394 nodeItem
.setToolTip(tt
);
398 * Parse a string path and search if there is a root node.
401 * {org.argeo.ria.components.DynamicTreeFolder} The parent
402 * node (containing data model)
404 * {String} The path of the node to attach.
406 * {qx.ui.tree.TreeFile} The leaf node
408 * {Map} User data to attach at all levels.
410 attachNodeByPath : function(rootNode
, path
, childNode
, userData
) {
411 if (!path
|| path
== "" || path
== "/") {
412 rootNode
.add(childNode
);
415 var model
= rootNode
.getUserData("dataModel");
418 rootNode
.setUserData("dataModel", model
);
420 var parts
= path
.split("/");
421 var keys
= qx
.lang
.Object
.getKeys(model
);
423 var crtFolder
= rootNode
;
424 for (var i
= 0; i
< parts
.length
; i
++) {
427 crtPath
+= "/" + parts
[i
];
428 if (!model
[crtPath
]) {
429 var virtualFolder
= new org
.argeo
.ria
.components
.PersistentTreeFolder(parts
[i
]);
430 if (userData
&& qx
.lang
.Object
.getLength(userData
)) {
431 for (var key
in userData
) {
432 virtualFolder
.setUserData(key
, userData
[key
]);
435 rootNode
.appendDragData(virtualFolder
);
436 model
[crtPath
] = virtualFolder
;
437 crtFolder
.add(virtualFolder
);
438 crtFolder
= virtualFolder
;
440 crtFolder
= model
[crtPath
];
443 crtFolder
.add(childNode
);
446 findAgentNodeById : function(node
, agentId
){
447 var nodeAgents
= node
.getItems();
448 for(var i
=0;i
<nodeAgents
.length
;i
++){
449 if(nodeAgents
[i
].getUserData("agentUuid") == agentId
){
450 return nodeAgents
[i
];
458 * Called at applet creation. Just registers viewPane.
461 * {org.argeo.ria.components.ViewPane} The viewPane.
463 init : function(viewPane
) {
464 this.setView(viewPane
);
465 this.setViewSelection(new org
.argeo
.ria
.components
.ViewSelection(viewPane
.getViewId()));
466 this.remoteNotifier
= new org
.argeo
.ria
.remote
.RemoteNotifier(
467 "/org.argeo.slc.webapp/", "pollEvent.service",
468 "addEventListener.service", "removeEventListener.service");
469 this.remoteNotifier
.setEventParamName("slc_eventType");
470 this.remoteNotifier
.setEventXPath("/slc:slc-event");
472 .setEventTypeXPath('slc:headers/slc:header[@name="slc_eventType"]');
474 .setEventDataXPath('slc:headers/slc:header[@name="slc_agentId"]');
475 this.remoteNotifier
.setAnswerStatusXPath("slc:execution-answer/slc:status");
476 this.remoteNotifier
.startPolling();
477 this.UIBus
= org
.argeo
.ria
.event
.UIBus
.getInstance();
478 this.UIBus
.registerNotifier(this.remoteNotifier
);
485 this._createLayout();
486 this.getView().setViewTitle("Available Scripts");
487 this.UIBus
.addListener("agentRegistered", this._addAgentHandler
, this);
488 this.UIBus
.addListener("agentUnregistered", this._removeAgentHandler
, this);
491 _addAgentHandler : function(agentId
){
492 this.rootNode
.load();
495 _removeAgentHandler : function(agentId
){
496 var treeNode
= this.self(arguments
).findAgentNodeById(this.rootNode
, agentId
);
498 this.rootNode
.remove(treeNode
);
500 var agentsMap
= this.getAgentsMap();
501 if(agentsMap
[agentId
]){
502 delete agentsMap
[agentId
];
504 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
506 batchView
.clearBatchForAgentId(agentId
);
510 addScroll : function() {
515 this.UIBus
.removeListener("agentRegistered", this._addAgentHandler
, this);
516 this.UIBus
.removeListener("agentUnregistered", this._removeAgentHandler
, this);
517 this.remoteNotifier
.stopPolling();
522 * @param agentNode {qx.ui.tree.AbstractTreeItem}
524 togglePreferredHost : function(agentNode
){
525 var hostName
= agentNode
.getUserData("agentHost");
526 var pref
= this.getRiaPreferenceValue("flowSelector.preferred.hosts");
529 prefArray
= pref
.split(",");
531 if(qx
.lang
.Array
.contains(prefArray
, hostName
)){
532 qx
.lang
.Array
.remove(prefArray
, hostName
);
533 agentNode
.setIcon("org.argeo.slc.ria/computer.png");
535 prefArray
.push(hostName
);
536 agentNode
.setIcon("org.argeo.slc.ria/computer_bookmarked.png");
537 var parent
= agentNode
.getParent();
538 parent
.remove(agentNode
);
539 parent
.addAtBegin(agentNode
);
541 this.setRiaPreferenceValue("flowSelector.preferred.hosts", prefArray
.join(","));
545 * Creates the main applet layout.
547 _createLayout : function() {
549 this.tree
= new qx
.ui
.tree
.Tree();
550 this.tree
.setDecorator(null);
551 this.tree
.setSelectionMode("multi");
563 this.rootNode
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
564 "Tests", this.self(arguments
).agentLoader
,
565 "Loading Agents", dragData
);
566 this.tree
.setRoot(this.rootNode
);
567 this.tree
.setHideRoot(true);
568 this.rootNode
.setPersistentTreeID("org.argeo.slc.ria.FlowsSelector")
569 this.rootNode
.setOpen(true);
570 this.tree
.setContextMenu(org
.argeo
.ria
.event
.CommandsManager
571 .getInstance().createMenuFromIds(["addtobatch",
572 "reloadtree", "preferredHost"]));
574 this.tree
.addListener("changeSelection", function(e
) {
575 var viewSelection
= this.getViewSelection();
576 viewSelection
.setViewId("form:tree");
577 viewSelection
.clear();
578 var sel
= this.tree
.getSortedSelection();
579 for (var i
= 0; i
< sel
.length
; i
++) {
580 viewSelection
.addNode(sel
[i
]);
588 getAgentsMap : function(){
589 return this.rootNode
.getUserData("agentsMap");