|
13 |
dojo.require("umc.widgets.ContainerForm"); |
13 |
dojo.require("umc.widgets.ContainerForm"); |
14 |
dojo.require("umc.widgets.Grid"); |
14 |
dojo.require("umc.widgets.Grid"); |
15 |
dojo.require("umc.widgets.TabbedModule"); |
15 |
dojo.require("umc.widgets.TabbedModule"); |
|
|
16 |
dojo.require("umc.widgets.StandbyMixin"); |
17 |
dojo.require("umc.modules._join.Form"); |
16 |
dojo.require("dojox.string.sprintf"); |
18 |
dojo.require("dojox.string.sprintf"); |
17 |
dojo.require("dojox.layout.TableContainer"); |
|
|
18 |
|
19 |
|
19 |
// Inheriting from umc.widgets.TabbedModule so any pages being added |
20 |
// Inheriting from umc.widgets.TabbedModule so any pages being added |
20 |
// will become tabs automatically. |
21 |
// will become tabs automatically. |
|
22 |
|
23 |
|
23 |
_page: null, // umc.widgets.Page |
24 |
_page: null, // umc.widgets.Page |
24 |
_content: null, // umc.widgets.ExpandingTitlePane |
25 |
_content: null, // umc.widgets.ExpandingTitlePane |
25 |
_split: null, // dijit.layout.BorderContainer |
26 |
// _split: null, // dijit.layout.BorderContainer |
26 |
_grid: null, // umc.widgets.Grid |
27 |
_grid: null, // umc.widgets.Grid |
27 |
_infotext: null, |
28 |
_infotext: null, |
28 |
|
29 |
|
|
60 |
_switch_log_display: function(code) { |
61 |
_switch_log_display: function(code) { |
61 |
if (code == 'hide') |
62 |
if (code == 'hide') |
62 |
{ |
63 |
{ |
63 |
this._split.removeChild(this._logview); |
64 |
this._content.removeChild(this._logview); |
64 |
this._bottom.addChild(this._b_show); |
65 |
this._bottom.addChild(this._b_show); |
65 |
this._bottom.removeChild(this._b_hide); |
66 |
this._bottom.removeChild(this._b_hide); |
66 |
this._bottom.removeChild(this._b_full); |
67 |
this._bottom.removeChild(this._b_full); |
|
86 |
this._refresh_log(true); |
87 |
this._refresh_log(true); |
87 |
this._bottom.addChild(this._b_hide); |
88 |
this._bottom.addChild(this._b_hide); |
88 |
this._bottom.addChild(this._b_full); |
89 |
this._bottom.addChild(this._b_full); |
89 |
this._split.addChild(this._logview); |
90 |
this._content.addChild(this._logview); |
90 |
this._logview.addChild(this._logtext); |
91 |
this._logview.addChild(this._logtext); |
91 |
} |
92 |
} |
92 |
|
93 |
|
|
106 |
{ |
107 |
{ |
107 |
// show grid with join status, else.... |
108 |
// show grid with join status, else.... |
108 |
this._infotext.set('content',this._("This system joined on %s",result)); |
109 |
this._infotext.set('content',this._("This system joined on %s",result)); |
109 |
this._split.removeChild(this._joinpane); |
110 |
this._content.removeChild(this._joinpane); |
110 |
this._split.addChild(this._grid); |
111 |
this._content.addChild(this._grid); |
111 |
this._reload_grid(); // force grid reload |
112 |
this._reload_grid(); // force grid reload |
112 |
} |
113 |
} |
113 |
else |
114 |
else |
114 |
{ |
115 |
{ |
115 |
// show affordance to join, nothing more. |
116 |
// show affordance to join, nothing more. |
116 |
this._infotext.set('content',this._("This system has not been joined yet.")); |
117 |
this._infotext.set('content',this._("This system has not been joined yet.")); |
117 |
this._split.removeChild(this._grid); |
118 |
this._content.removeChild(this._grid); |
118 |
this._split.addChild(this._joinpane); |
119 |
this._content.addChild(this._joinpane); |
119 |
} |
120 |
} |
120 |
} |
121 |
} |
121 |
})); |
122 |
}), |
|
|
123 |
dojo.hitch(this, function(result) { |
124 |
console.error("check_join_status ERROR " + result.message); |
125 |
}) |
126 |
); |
122 |
}, |
127 |
}, |
123 |
|
128 |
|
124 |
// Asynchronously invokes reload of the log lines display. Before fetching real data, |
129 |
// Asynchronously invokes reload of the log lines display. Before fetching real data, |
|
160 |
}).then(dojo.hitch(this,function(result) { |
165 |
}).then(dojo.hitch(this,function(result) { |
161 |
var txt = dojox.string.sprintf("<u><b>%s</b></u><br/>\n",this._("Join Protocol")); |
166 |
var txt = dojox.string.sprintf("<u><b>%s</b></u><br/>\n",this._("Join Protocol")); |
162 |
|
167 |
|
163 |
// this is for debugging so we can see the refresh |
|
|
164 |
//var txt = dojox.string.sprintf("<u><b>%s [%d]</b></u><br/>\n",this._("Join Protocol"),this._proto_gen); |
165 |
//this._proto_gen++; |
166 |
|
167 |
if (this._logcount) |
168 |
if (this._logcount) |
168 |
{ |
169 |
{ |
169 |
var tmp = this._("last {logcount} lines"); |
170 |
var tmp = this._("last {logcount} lines"); |
|
188 |
// Establish refresh every second. We keep the last instance of our 'Deferred' |
189 |
// Establish refresh every second. We keep the last instance of our 'Deferred' |
189 |
// as an instance member this._refresh_job, thus avoiding to have more than one |
190 |
// as an instance member this._refresh_job, thus avoiding to have more than one |
190 |
// refresh running at any time. |
191 |
// refresh running at any time. |
191 |
if (! this._refresh_job) |
192 |
// |
|
|
193 |
// Added here: if this._refresh_time is set to zero we stop the timer. |
194 |
if ((! this._refresh_job) && (this._refresh_time)) |
192 |
{ |
195 |
{ |
193 |
var deferred = new dojo.Deferred(); |
196 |
var deferred = new dojo.Deferred(); |
194 |
this._refresh_job = deferred; |
197 |
this._refresh_job = deferred; |
|
239 |
this.moduleStore.query({ |
242 |
this.moduleStore.query({ |
240 |
scope: 'running' |
243 |
scope: 'running' |
241 |
}).then(dojo.hitch(this, function(result) { |
244 |
}).then(dojo.hitch(this, function(result) { |
242 |
if (result != this._job_running) |
245 |
try |
243 |
{ |
246 |
{ |
244 |
this._job_running = result; |
247 |
if (result != this._job_running) |
245 |
this._check_join_status(); // switch between join form and script grid |
|
|
246 |
this._reload_grid(); // redo the status query for the grid, effectively triggering |
247 |
// _check_grid_status() on 'fetchComplete' |
248 |
} |
249 |
// for first display: if none of the two widgets (script grid or join form) |
250 |
// is displayed AND we run into a running job we have to do two things: |
251 |
// (1) show a header text that explains the situation |
252 |
// (2) switch log display on. |
253 |
if (this._job_running) |
254 |
{ |
255 |
var txt = this._infotext.get('content'); |
256 |
if (txt == '') |
257 |
{ |
248 |
{ |
258 |
this._infotext.set('content',this._("Currently some join scripts are running. You may watch the log file until they are finished.")); |
249 |
this._job_running = result; |
259 |
this._switch_log_display('show'); |
250 |
if (! result) |
|
|
251 |
{ |
252 |
this._joinform.standby(false); |
253 |
} |
254 |
this._check_join_status(); // switch between join form and script grid |
255 |
this._reload_grid(); // redo the status query for the grid, effectively triggering |
256 |
// _check_grid_status() on 'fetchComplete' |
260 |
} |
257 |
} |
|
|
258 |
// for first display: if none of the two widgets (script grid or join form) |
259 |
// is displayed AND we run into a running job we have to do two things: |
260 |
// (1) show a header text that explains the situation |
261 |
// (2) switch log display on. |
262 |
if (this._job_running) |
263 |
{ |
264 |
var txt = this._infotext.get('content'); |
265 |
if (txt == '') |
266 |
{ |
267 |
this._infotext.set('content',this._("Currently some join scripts are running. You may watch the log file until they are finished.")); |
268 |
this._switch_log_display('show'); |
269 |
} |
270 |
} |
261 |
} |
271 |
} |
262 |
})); |
272 |
catch(error) |
|
|
273 |
{ |
274 |
console.error('job_polling_loop ERROR: ' + error.message); |
275 |
} |
276 |
}), |
277 |
dojo.hitch(this, function(result) { |
278 |
this._joinform.standby(false); |
279 |
this._grid.standby(false); |
280 |
}) |
281 |
); |
263 |
|
282 |
|
264 |
// We should have exactly one such job. If one is underway, we don't |
283 |
// We should have exactly one such job. If one is underway, we don't |
265 |
// step on its feet. Otherwise, we start a new one. |
284 |
// step on its feet. Otherwise, we start a new one. |
|
354 |
{ |
373 |
{ |
355 |
if (runnable) |
374 |
if (runnable) |
356 |
{ |
375 |
{ |
357 |
this._footers[0].set('content',this._('%d scripts are due to be run',runnable)); |
376 |
var due = this._('%d scripts are due to be run.',runnable); |
|
|
377 |
if (runnable == 1) |
378 |
{ |
379 |
due = this._("One script is due to be run."); |
380 |
} |
381 |
this._footers[0].set('content',due); |
382 |
|
358 |
this._multi_action.set('label',this._('run all')); |
383 |
this._multi_action.set('label',this._('run all')); |
359 |
this._footers[1].addChild(this._multi_action); |
384 |
this._footers[1].addChild(this._multi_action); |
360 |
} |
385 |
} |
|
393 |
{ |
418 |
{ |
394 |
this._job_running = true; |
419 |
this._job_running = true; |
395 |
|
420 |
|
396 |
this._footers[0].set('content',this._('%d join scripts are currently running',list.length)); |
421 |
if (list.length == 1) |
|
|
422 |
{ |
423 |
this._footers[0].set('content',this._("One join script is currently running")); |
424 |
} |
425 |
else |
426 |
{ |
427 |
this._footers[0].set('content',this._('%d join scripts are currently running',list.length)); |
428 |
} |
397 |
this._footers[1].removeChild(this._multi_action); |
429 |
this._footers[1].removeChild(this._multi_action); |
398 |
|
430 |
|
399 |
this.umcpCommand('join/run',{scripts: list}).then(dojo.hitch(this, function(data) { |
431 |
this.umcpCommand('join/run',{scripts: list}).then(dojo.hitch(this, function(data) { |
|
432 |
// Trying to give the user a chance to resize the grid <-> logview ratio. |
464 |
// Trying to give the user a chance to resize the grid <-> logview ratio. |
433 |
// Even a simple BorderContainer is able to do that: just give some of its |
465 |
// Even a simple BorderContainer is able to do that: just give some of its |
434 |
// children a 'splitter: true' property. |
466 |
// children a 'splitter: true' property. |
435 |
this._split = new dijit.layout.BorderContainer({ |
467 |
// this._split = new dijit.layout.BorderContainer({ |
436 |
}); |
468 |
// }); |
437 |
this._content.addChild(this._split); |
469 |
// this._content.addChild(this._split); |
438 |
|
470 |
|
439 |
this._grid = new umc.widgets.Grid({ |
471 |
this._grid = new umc.widgets.Grid({ |
440 |
region: 'center', |
472 |
region: 'center', |
441 |
moduleStore: this.moduleStore, |
473 |
moduleStore: this.moduleStore, |
442 |
//query: {scope: 'scripts'}, |
474 |
//query: {scope: 'scripts'}, |
443 |
actions: {}, |
475 |
actions: |
|
|
476 |
[ |
477 |
{ |
478 |
name: 'run', |
479 |
label: this._( 'Execute' ), |
480 |
description: this._( 'Execute this join script' ), |
481 |
isContextAction: true, |
482 |
isStandardAction: true, |
483 |
canExecute: dojo.hitch(this, function(values) { |
484 |
// Knowledge is in the Python module! |
485 |
return (values['action'] == 'run'); |
486 |
}), |
487 |
callback: dojo.hitch(this, function(id) { |
488 |
if (dojo.isArray(id)) |
489 |
{ |
490 |
id = id[0]; |
491 |
} |
492 |
this._run_scripts([id]); |
493 |
}) |
494 |
} |
495 |
], |
444 |
columns: |
496 |
columns: |
445 |
[ |
497 |
[ |
446 |
{ |
498 |
{ |
447 |
name: 'script', |
499 |
name: 'script', |
448 |
label: this._("Script (package)"), |
500 |
label: this._("Script (package)"), |
449 |
description: this._("Script name (the same as the package it belongs to)"), |
501 |
description: this._("Script name (the same as the package it belongs to)"), |
450 |
editable: false, |
502 |
editable: false |
451 |
width: '40%' |
503 |
// width: '50%' |
452 |
}, |
504 |
}, |
453 |
{ |
505 |
{ |
454 |
name: 'current', |
506 |
name: 'current', |
455 |
label: this._("Current version"), |
507 |
label: this._("Current version"), |
456 |
description: this._("Latest script version ready for execution"), |
508 |
description: this._("Latest script version ready for execution"), |
457 |
editable: false, |
509 |
editable: false, |
458 |
width: '14%' |
510 |
width: 'adjust' |
459 |
}, |
511 |
}, |
460 |
{ |
512 |
{ |
461 |
name: 'last', |
513 |
name: 'last', |
462 |
label: this._("Last version"), |
514 |
label: this._("Last version"), |
463 |
description: this._("Latest script version that was executed successfully"), |
515 |
description: this._("Latest script version that was executed successfully"), |
464 |
editable: false, |
516 |
editable: false, |
465 |
width: '14%' |
517 |
width: 'adjust' |
466 |
}, |
518 |
}, |
467 |
// Status column. Currently only text. |
519 |
// Status column. Currently only text. |
468 |
{ |
520 |
{ |
|
471 |
description: this._("Status of this package"), |
523 |
description: this._("Status of this package"), |
472 |
editable: false, |
524 |
editable: false, |
473 |
width: '12%' |
525 |
width: '12%' |
474 |
// iconField: 'icon' // deactivated (for now) |
|
|
475 |
}, |
476 |
// Action field |
477 |
{ |
478 |
name: 'action', |
479 |
label: this._("Action"), |
480 |
description: this._("Run this script if it's due or never run"), |
481 |
sortable: false, |
482 |
editable: false, |
483 |
width: '10%', |
484 |
// We turn the value of the field into an action button that will |
485 |
// invoke the script named by the 'script' field of this row |
486 |
formatter: dojo.hitch(this, function(key, rowIndex) { |
487 |
// key = the value of the field, in our case empty or 'run' |
488 |
// rowIndex = needed to retrieve the script name |
489 |
try |
490 |
{ |
491 |
if (key != '') |
492 |
{ |
493 |
var tmp = this._grid.getRowValues(rowIndex); |
494 |
var script = tmp.script; |
495 |
return new umc.widgets.Button({ |
496 |
label: key, |
497 |
// FIXME style this button by a reasonable CSS class or such. |
498 |
style: 'border:outset 1px;background-color:#A0A0A0;margin:0px;padding:0px;', |
499 |
//'class': 'umcSubmitButton', // doesn't work, unfortunately. |
500 |
onClick: dojo.hitch(this, function() { |
501 |
this._run_scripts([script]); |
502 |
}) |
503 |
}); |
504 |
} |
505 |
return ''; |
506 |
} |
507 |
catch(err) |
508 |
{ |
509 |
return ''; |
510 |
} |
511 |
}) |
512 |
} |
526 |
} |
513 |
] |
527 |
] |
514 |
}); |
528 |
}); |
|
655 |
scrollable: false, |
669 |
scrollable: false, |
656 |
style: 'border:none;' |
670 |
style: 'border:none;' |
657 |
}); |
671 |
}); |
658 |
this._split.addChild(info); |
672 |
this._content.addChild(info); |
659 |
|
673 |
|
660 |
this._infotext = new umc.widgets.Text({ |
674 |
this._infotext = new umc.widgets.Text({ |
661 |
style: 'border:none;margin:.2em;', |
675 |
style: 'border:none;margin:.2em;', |
662 |
content: '', |
676 |
content: '' |
663 |
}); |
677 |
}); |
664 |
info.addChild(this._infotext); |
678 |
info.addChild(this._infotext); |
665 |
|
679 |
|
|
668 |
// password and for starting the join process. This form is prepared here and stored |
682 |
// password and for starting the join process. This form is prepared here and stored |
669 |
// into the this._joinpane variable. The _check_join_status() method will decide |
683 |
// into the this._joinpane variable. The _check_join_status() method will decide |
670 |
// which view is to show. |
684 |
// which view is to show. |
671 |
this._joinpane = new dojox.layout.TableContainer({ |
685 |
this._joinpane = new umc.widgets.ContainerWidget({ |
672 |
region: 'center', |
686 |
region: 'center', |
673 |
cols: 1, |
687 |
scrollable: true |
674 |
style: 'width:50%;', |
|
|
675 |
showLabels: false |
676 |
}); |
688 |
}); |
677 |
this._joinform = new umc.widgets.Form({ |
689 |
var buttons = |
678 |
scrollable: true, |
690 |
[ |
679 |
buttons: |
691 |
{ |
680 |
[ |
692 |
type: 'submit', |
681 |
{ |
693 |
'default': true, |
682 |
type: 'submit', |
694 |
label: this._("Start Join"), |
683 |
label: this._("Start Join"), |
695 |
onClick: dojo.hitch(this, function() { |
684 |
onClick: dojo.hitch(this, function() { |
696 |
this._joinform.standby(true); |
685 |
//this._joinform.standby(true); |
697 |
this._switch_log_display('show'); |
686 |
this._switch_log_display('show'); |
698 |
this.umcpCommand('join/join',{ |
687 |
this.umcpCommand('join/join',{ |
699 |
host: this._joinform._widgets['host'].value, |
688 |
host: this._joinform._widgets['host'].value, |
700 |
user: this._joinform._widgets['user'].value, |
689 |
user: this._joinform._widgets['user'].value, |
701 |
pass: this._joinform._widgets['pass'].value |
690 |
pass: this._joinform._widgets['pass'].value |
702 |
}).then(dojo.hitch(this, function(data) { |
691 |
}).then(dojo.hitch(this, function(data) { |
703 |
var result = dojo.getObject('result', false, data); |
692 |
var result = dojo.getObject('result', false, data); |
704 |
if (result != '') |
693 |
if (result != '') |
705 |
{ |
694 |
{ |
706 |
this._joinform.standby(false); |
695 |
// Note result is already localized |
707 |
// Note result is already localized |
696 |
umc.dialog.alert(this._("Can't start join: ") + result); |
708 |
umc.dialog.alert(this._("Can't start join: ") + result); |
697 |
this._check_join_status(); // sets meaningful messages |
709 |
this._check_join_status(); // sets meaningful messages |
698 |
} |
710 |
} |
699 |
else |
711 |
else |
700 |
{ |
712 |
{ |
701 |
// Job is started. Now wait for its completion. |
713 |
// Job is started. Now wait for its completion. |
702 |
this._job_polling_loop(true); |
714 |
this._job_polling_loop(true); |
703 |
} |
715 |
} |
704 |
})); |
716 |
})); |
705 |
}) |
717 |
}) |
706 |
} |
718 |
} |
707 |
], |
719 |
]; |
708 |
widgets: |
720 |
var widgets = |
709 |
[ |
721 |
[ |
710 |
{ |
722 |
{ |
711 |
type: 'Text', |
723 |
type: 'Text', |
712 |
name: 'text', |
724 |
name: 'text', |
713 |
style: 'margin-top:1em;margin-bottom:1em;', |
725 |
style: 'margin-top:1em;margin-bottom:1em;', |
714 |
content: this._("Please enter the required information below and click the 'Start Join' button. This will join your system into the domain.") |
726 |
content: this._("Please enter the required information below and click the 'Start Join' button. This will join your system into the domain.") |
715 |
}, |
727 |
}, |
716 |
{ |
728 |
{ |
717 |
type: 'TextBox', |
729 |
type: 'TextBox', |
718 |
name: 'host', |
730 |
name: 'host', |
719 |
value: '', |
731 |
value: '', |
720 |
label: this._('DC Hostname'), |
732 |
label: this._('DC Hostname'), |
721 |
description: this._('The hostname of the DC Master of the domain') |
733 |
description: this._('The hostname of the DC Master of the domain') |
722 |
}, |
734 |
}, |
723 |
{ |
735 |
{ |
724 |
type: 'TextBox', |
736 |
type: 'TextBox', |
725 |
name: 'user', |
737 |
name: 'user', |
726 |
value: 'Administrator', |
738 |
value: 'Administrator', |
727 |
label: this._('Username'), |
739 |
label: this._('Username'), |
728 |
description: this._('The username of the Domain Administrator') |
740 |
description: this._('The username of the Domain Administrator') |
729 |
}, |
741 |
}, |
730 |
{ |
742 |
{ |
731 |
type: 'PasswordBox', |
743 |
type: 'PasswordBox', |
732 |
name: 'pass', |
744 |
name: 'pass', |
733 |
value: '', |
745 |
value: '', |
734 |
label: this._( 'Password' ), |
746 |
label: this._( 'Password' ), |
735 |
description: this._( 'Password of the Domain Administrator' ) |
747 |
description: this._( 'Password of the Domain Administrator' ) |
736 |
} |
748 |
} |
737 |
] |
749 |
]; |
|
|
750 |
this._joinform = new umc.modules._join.Form({ |
751 |
buttons: buttons, |
752 |
widgets: widgets |
738 |
}); |
753 |
}); |
739 |
this._joinpane.addChild(this._joinform); |
754 |
this._joinpane.addChild(this._joinform); |
740 |
|
755 |
|
|
745 |
this._job_polling_loop(true); |
760 |
this._job_polling_loop(true); |
746 |
|
761 |
|
747 |
this._page.startup(); // start event loop and data gathering |
762 |
this._page.startup(); // start event loop and data gathering |
|
|
763 |
}, |
764 |
|
765 |
uninitialize: function() { |
748 |
|
766 |
|
749 |
} |
767 |
this.inherited(arguments); |
|
|
768 |
this._refresh_time = 0; |
769 |
|
750 |
}); |
770 |
}); |