]>
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
755fc1d0eca7472f315714dcff097013c4eaf2d1
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
.setState("loading");
143 this.rootNode
.load();
148 label
: "Reload Node",
149 icon
: "org/argeo/slc/ria/view-refresh.png",
154 callback : function(e
) {
155 if (this.tree
.isSelectionEmpty()) { return; }
156 var selected
= this.tree
.getSelection()[0];
157 if (selected
.classname
== "org.argeo.ria.components.DynamicTreeFolder") {
158 if (selected
.getUserData("moduleData")) {
159 // It's a "module" node, first trigger the
160 // reloadBundle.service
161 selected
.setUserData("dataModel", {});
162 selected
.setEnabled(false);
163 selected
.setOpen(false);
164 var moduleData
= selected
165 .getUserData("moduleData");
166 var bundleService
= org
.argeo
.slc
.ria
.SlcApi
167 .getReloadBundleService(
170 bundleService
.addListener("completed",
172 selected
.setEnabled(true);
173 selected
.setOpen(true);
176 // bundleService.send();
177 // Do not send, not implemented yet, false timer
179 qx
.event
.Timer
.once(function(response
) {
180 selected
.setEnabled(true);
181 selected
.setOpen(true);
189 selectionChange : function(viewId
, selection
) {
190 if (viewId
!= "form:tree")
194 if (selection
.length
> 1) {
195 this.setEnabled(false);
198 var item
= selection
[0];
199 if (!qx
.Class
.isSubClassOf(qx
.Class
200 .getByName(item
.classname
),
201 qx
.ui
.tree
.AbstractTreeItem
))
203 this.setEnabled(false);
204 if (qx
.Class
.isSubClassOf(qx
.Class
205 .getByName(item
.classname
),
206 org
.argeo
.ria
.components
.DynamicTreeFolder
)) {
207 this.setEnabled(true);
219 "flowSelector.preferred.hosts" : {
220 label
: "Preferred Hosts (Execution View)",
226 * Static loader for the "agent" level (first level)
229 * {org.argeo.ria.components.PersistentTreeFolder} The root Tree Folder.
231 agentLoader : function(folder
) {
233 var preferredHosts
= org
.argeo
.ria
.session
.MPrefHolder
.loadRiaPreferenceValue("flowSelector.preferred.hosts");
234 if(preferredHosts
&& preferredHosts
!=""){
235 preferredHosts
= preferredHosts
.split(",");
237 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListAgentsService("agents");
239 if(folder
.getUserData("agentsMap")){
240 // Diff loading, just add new nodes.
241 agents
= folder
.getUserData("agentsMap");
244 req
.addListener("completed", function(response
) {
245 var xmlDoc
= response
.getContent();
246 var nodes
= org
.argeo
.ria
.util
.Element
.selectNodes(xmlDoc
,
247 "/slc:object-list/slc:slc-agent-descriptor");
248 var modulesLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.modulesLoader
;
250 for (var i
= 0; i
< nodes
.length
; i
++) {
251 var uuid
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "@uuid");
252 var host
= org
.argeo
.ria
.util
.Element
.getSingleNodeText(nodes
[i
], "slc:host");
254 newAgents
[uuid
] = host
;
258 if(newAgents
) newAgents
[uuid
] = host
;
259 var agentFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
260 host
, modulesLoader
, "Loading Modules...", folder
.getDragData());
261 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(agentFolder
, uuid
);
262 agentFolder
.setPersistentTreeID(folder
.getPersistentTreeID()+"_"+uuid
);
263 agentFolder
.setUserData("agentHost", host
); // Used by bookmark system
264 agentFolder
.setUserData("agentUuid", uuid
);
265 if(preferredHosts
&& preferredHosts
instanceof Array
&& qx
.lang
.Array
.contains(preferredHosts
, host
)){
266 folder
.addAtBegin(agentFolder
);
267 agentFolder
.setIcon("org/argeo/slc/ria/computer_bookmarked.png");
269 folder
.add(agentFolder
);
270 agentFolder
.setIcon("org/argeo/slc/ria/computer.png");
274 // Make sure some agents should not be removed
275 for(var agentKey
in agents
){
276 if(!newAgents
[agentKey
]){
277 var node
= org
.argeo
.slc
.ria
.FlowsSelectorView
.findAgentNodeById(folder
, agentKey
);
278 if(node
) folder
.remove(node
);
279 delete agents
[agentKey
];
280 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
281 if(batchView
) batchView
.clearBatchForAgentId(agentKey
);
285 folder
.setUserData("agentsMap", agents
);
286 folder
.setLoaded(true);
287 folder
.getTree().fireDataEvent("changeSelection", folder
.getTree().getSelection());
289 req
.addListener("failed", function(response
) {
290 folder
.setLoaded(true);
297 * Loader for the "modules" level : takes any tree folder, currently the
301 * {org.argeo.ria.components.PersistentTreeFolder} The root folder
303 modulesLoader : function(folder
) {
304 var agentId
= folder
.getUserData("agentUuid");
305 var req
= org
.argeo
.slc
.ria
.SlcApi
.getListModulesService(agentId
);
306 req
.addListener("completed", function(response
) {
307 var descriptors
= org
.argeo
.ria
.util
.Element
.selectNodes(
308 response
.getContent(),
309 "slc:object-list/" + org
.argeo
.slc
.ria
.execution
.Module
.XPATH_ROOT
);
311 for (var i
= 0; i
< descriptors
.length
; i
++) {
312 var tmpModule
= new org
.argeo
.slc
.ria
.execution
.Module();
314 tmpModule
.setXmlNode(descriptors
[i
]);
316 qx
.log
.Logger
.error(e
);
318 var name
= tmpModule
.getName();
319 var version
= tmpModule
.getVersion();
322 mods
[name
].push(tmpModule
);
324 var flowLoader
= org
.argeo
.slc
.ria
.FlowsSelectorView
.flowLoader
;
325 for (var key
in mods
) {
326 for (var i
= 0; i
< mods
[key
].length
; i
++) {
327 var module
= mods
[key
][i
];
328 var versionFolder
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
329 module
.getLabel(), flowLoader
,
330 "Loading Flows", folder
.getDragData());
331 versionFolder
.setUserData("moduleData", {
333 version
: module
.getVersion()
335 versionFolder
.setIcon("org/argeo/slc/ria/archive.png");
336 versionFolder
.setUserData("agentUuid", agentId
);
337 var sep
= (module
.getDescription()!=""?" - ":"");
338 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(versionFolder
, key
+ ' (' + module
.getVersion() + ')'+sep
+module
.getDescription());
339 // Warning, we must add it AFTER setting the user data,
340 // because of the persistent loading mechanism.
341 folder
.add(versionFolder
);
344 folder
.setLoaded(true);
345 folder
.getTree().fireDataEvent("changeSelection", folder
.getTree().getSelection());
347 req
.addListener("failed", function(response
) {
348 folder
.setLoaded(true);
354 * Loader for the "flow" level : takes a folder containing "moduleData"
355 * and create its children.
358 * {org.argeo.ria.components.PersistentTreeFolder} A Tree folder containing in the
359 * key "moduleData" of its user data a map containing the
360 * keys {name,version}
362 flowLoader : function(folder
) {
363 var moduleData
= folder
.getUserData("moduleData");
364 var agentUuid
= folder
.getUserData("agentUuid");
366 var req
= org
.argeo
.slc
.ria
.SlcApi
367 .getLoadExecutionDescriptorService(agentUuid
,
368 moduleData
.name
, moduleData
.version
);
369 req
.addListener("completed", function(response
) {
370 var executionModule
= new org
.argeo
.slc
.ria
.execution
.Module();
372 executionModule
.setXmlNode(response
.getContent());
376 var execFlows
= executionModule
.getExecutionFlows();
377 for (var key
in execFlows
) {
378 var path
= execFlows
[key
].getPath();
379 var name
= execFlows
[key
].getName();
382 if(name
&& name
.indexOf(sep
)>-1 && !path
){
383 // Use given name to build the path.
384 // split dirname and basename
385 var parts
= name
.split(sep
);
386 var basename
= parts
.pop();
387 var dirname
= parts
.join("/");
389 nodeLabel
= basename
;
391 var file
= new qx
.ui
.tree
.TreeFile(nodeLabel
);
392 if(execFlows
[key
].getDescription() != ""){
393 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachToolTip(file
, execFlows
[key
].getDescription());
395 file
.setIcon("org/argeo/slc/ria/system.png");
396 file
.setUserData("executionModule", executionModule
);
397 file
.setUserData("executionFlow", execFlows
[key
]);
398 file
.setUserData("agentUuid", agentUuid
);
399 org
.argeo
.slc
.ria
.FlowsSelectorView
.attachNodeByPath(folder
, path
, file
, {
400 agentUuid
: folder
.getUserData("agentUuid")
402 folder
.appendDragData(file
);
404 folder
.setLoaded(true);
405 folder
.getTree().fireDataEvent("changeSelection", folder
.getTree().getSelection());
407 req
.addListener("failed", function(response
) {
408 folder
.setLoaded(true);
413 attachToolTip : function(nodeItem
, description
){
414 var tt
= new qx
.ui
.tooltip
.ToolTip(description
);
415 tt
.setShowTimeout(0);
416 nodeItem
.setToolTip(tt
);
420 * Parse a string path and search if there is a root node.
423 * {org.argeo.ria.components.DynamicTreeFolder} The parent
424 * node (containing data model)
426 * {String} The path of the node to attach.
428 * {qx.ui.tree.TreeFile} The leaf node
430 * {Map} User data to attach at all levels.
432 attachNodeByPath : function(rootNode
, path
, childNode
, userData
) {
433 if (!path
|| path
== "" || path
== "/") {
434 rootNode
.add(childNode
);
437 var model
= rootNode
.getUserData("dataModel");
440 rootNode
.setUserData("dataModel", model
);
442 var parts
= path
.split("/");
443 var keys
= qx
.lang
.Object
.getKeys(model
);
445 var crtFolder
= rootNode
;
446 for (var i
= 0; i
< parts
.length
; i
++) {
449 crtPath
+= "/" + parts
[i
];
450 if (!model
[crtPath
]) {
451 var virtualFolder
= new org
.argeo
.ria
.components
.PersistentTreeFolder(parts
[i
]);
452 if (userData
&& qx
.lang
.Object
.getLength(userData
)) {
453 for (var key
in userData
) {
454 virtualFolder
.setUserData(key
, userData
[key
]);
457 rootNode
.appendDragData(virtualFolder
);
458 model
[crtPath
] = virtualFolder
;
459 crtFolder
.add(virtualFolder
);
460 crtFolder
= virtualFolder
;
462 crtFolder
= model
[crtPath
];
465 crtFolder
.add(childNode
);
468 findAgentNodeById : function(node
, agentId
){
469 var nodeAgents
= node
.getItems();
470 for(var i
=0;i
<nodeAgents
.length
;i
++){
471 if(nodeAgents
[i
].getUserData("agentUuid") == agentId
){
472 return nodeAgents
[i
];
480 * Called at applet creation. Just registers viewPane.
483 * {org.argeo.ria.components.ViewPane} The viewPane.
485 init : function(viewPane
) {
486 this.setView(viewPane
);
487 this.setViewSelection(new org
.argeo
.ria
.components
.ViewSelection(viewPane
.getViewId()));
488 this.remoteNotifier
= new org
.argeo
.ria
.remote
.RemoteNotifier(
489 "/org.argeo.slc.webapp/", "pollEvent.service",
490 "addEventListener.service", "removeEventListener.service");
491 this.remoteNotifier
.setEventParamName("slc_eventType");
492 this.remoteNotifier
.setEventXPath("/slc:slc-event");
494 .setEventTypeXPath('slc:headers/slc:header[@name="slc_eventType"]');
496 .setEventDataXPath('slc:headers/slc:header[@name="slc_agentId"]');
497 this.remoteNotifier
.setAnswerStatusXPath("slc:execution-answer/slc:status");
498 this.remoteNotifier
.startPolling();
499 this.UIBus
= org
.argeo
.ria
.event
.UIBus
.getInstance();
500 this.UIBus
.registerNotifier(this.remoteNotifier
);
507 this._createLayout();
508 this.getView().setViewTitle("Available Scripts");
509 this.UIBus
.addListener("agentRegistered", this._addAgentHandler
, this);
510 this.UIBus
.addListener("agentUnregistered", this._removeAgentHandler
, this);
513 _addAgentHandler : function(agentId
){
514 this.rootNode
.load();
517 _removeAgentHandler : function(agentId
){
518 var treeNode
= this.self(arguments
).findAgentNodeById(this.rootNode
, agentId
);
520 this.rootNode
.remove(treeNode
);
522 var agentsMap
= this.getAgentsMap();
523 if(agentsMap
[agentId
]){
524 delete agentsMap
[agentId
];
526 var batchView
= org
.argeo
.ria
.components
.ViewsManager
.getInstance().getViewPaneById("batch").getContent();
528 batchView
.clearBatchForAgentId(agentId
);
532 addScroll : function() {
537 this.UIBus
.removeListener("agentRegistered", this._addAgentHandler
, this);
538 this.UIBus
.removeListener("agentUnregistered", this._removeAgentHandler
, this);
539 this.remoteNotifier
.stopPolling();
544 * @param agentNode {qx.ui.tree.AbstractTreeItem}
546 togglePreferredHost : function(agentNode
){
547 var hostName
= agentNode
.getUserData("agentHost");
548 var pref
= this.getRiaPreferenceValue("flowSelector.preferred.hosts");
551 prefArray
= pref
.split(",");
553 if(qx
.lang
.Array
.contains(prefArray
, hostName
)){
554 qx
.lang
.Array
.remove(prefArray
, hostName
);
555 agentNode
.setIcon("org/argeo/slc/ria/computer.png");
557 prefArray
.push(hostName
);
558 agentNode
.setIcon("org/argeo/slc/ria/computer_bookmarked.png");
559 var parent
= agentNode
.getParent();
560 parent
.remove(agentNode
);
561 parent
.addAtBegin(agentNode
);
563 this.setRiaPreferenceValue("flowSelector.preferred.hosts", prefArray
.join(","));
567 * Creates the main applet layout.
569 _createLayout : function() {
571 this.tree
= new qx
.ui
.tree
.Tree();
572 this.tree
.setDecorator(null);
573 this.tree
.setSelectionMode("multi");
585 this.rootNode
= new org
.argeo
.ria
.components
.DynamicTreeFolder(
586 "Tests", this.self(arguments
).agentLoader
,
587 "Loading Agents", dragData
);
588 this.tree
.setRoot(this.rootNode
);
589 this.tree
.setHideRoot(true);
590 this.rootNode
.setPersistentTreeID("org/argeo/slc/ria.FlowsSelector")
591 this.rootNode
.setOpen(true);
592 this.tree
.setContextMenu(org
.argeo
.ria
.event
.CommandsManager
593 .getInstance().createMenuFromIds(["addtobatch",
594 "reloadtree", "preferredHost"]));
596 this.tree
.addListener("changeSelection", function(e
) {
597 var viewSelection
= this.getViewSelection();
598 viewSelection
.setViewId("form:tree");
599 viewSelection
.clear();
600 var sel
= this.tree
.getSortedSelection();
601 for (var i
= 0; i
< sel
.length
; i
++) {
602 viewSelection
.addNode(sel
[i
]);
606 this.tree
.addListener("dblclick", function(e
){
607 var sel
= this.tree
.getSortedSelection();
608 if(sel
&& sel
.length
!=1) return;
610 if(origin
.classname
== "qx.ui.tree.TreeFile"){
611 this.setExecuteAfterAdd(true);
612 this.getCommands()["addtobatch"].command
.execute();
619 getAgentsMap : function(){
620 return this.rootNode
.getUserData("agentsMap");