]> git.sur5r.net Git - bacula/bacula/commitdiff
baculum: Add run job again button and small improvements
authorMarcin Haba <marcin.haba@bacula.pl>
Fri, 11 Dec 2015 07:56:58 +0000 (08:56 +0100)
committerMarcin Haba <marcin.haba@bacula.pl>
Fri, 11 Dec 2015 07:56:58 +0000 (08:56 +0100)
18 files changed:
gui/baculum/protected/JavaScript/slide-window.js
gui/baculum/protected/Pages/API/FileSets.php
gui/baculum/protected/Pages/API/JobRun.php
gui/baculum/protected/Pages/API/JobShow.php [new file with mode: 0644]
gui/baculum/protected/Pages/API/JobsShow.php [new file with mode: 0644]
gui/baculum/protected/Pages/Home.page
gui/baculum/protected/Portlets/ClientList.tpl
gui/baculum/protected/Portlets/JobConfiguration.php
gui/baculum/protected/Portlets/JobList.php
gui/baculum/protected/Portlets/JobList.tpl
gui/baculum/protected/Portlets/JobRunList.tpl
gui/baculum/protected/Portlets/PoolList.tpl
gui/baculum/protected/Portlets/StorageList.tpl
gui/baculum/protected/application.xml
gui/baculum/themes/Baculum-v1/loader-alter.gif [new file with mode: 0644]
gui/baculum/themes/Baculum-v1/loader.gif [new file with mode: 0644]
gui/baculum/themes/Baculum-v1/play.png [new file with mode: 0644]
gui/baculum/themes/Baculum-v1/style.css

index e8b1325c716497ace5c21a313e35579d12653d13..b857b7392aa55f8fd1f1585df6cfb998c8ceabaa 100644 (file)
@@ -12,6 +12,7 @@ var SlideWindowClass = Class.create({
        options: null,
        configurationObj: null,
        loadRequest : null,
+       actionsRequest: null,
        repeaterEl: null,
        gridEl: null,
        checked: [],
@@ -29,16 +30,19 @@ var SlideWindowClass = Class.create({
        },
 
        elements : {
-               containerSuffix : '-slide-window-container',
-               configurationWindows : 'div.configuration',
+               content: 'div.slide-window-content',
+               containerSuffix: '-slide-window-container',
+               containerProgressSuffix: '-slide-window-progress',
+               configurationWindows: 'div.configuration',
                configurationProgress: 'div.configuration-progress',
-               contentItems : 'slide-window-element',
-               contentAlternatingItems : 'slide-window-element-alternating',
-               toolsButtonSuffix : '-slide-window-tools',
-               optionsButtonSuffix : '-slide-window-options',
-               actionsSuffix : '-slide-window-actions',
-               toolbarSuffix : '-slide-window-toolbar',
-               titleSuffix : '-slide-window-title'
+               contentItems: 'slide-window-element',
+               contentAlternatingItems: 'slide-window-element-alternating',
+               toolsButtonSuffix: '-slide-window-tools',
+               optionsButtonSuffix: '-slide-window-options',
+               actionsSuffix: '-slide-window-actions',
+               toolbarSuffix: '-slide-window-toolbar',
+               titleSuffix: '-slide-window-title',
+               actionsButton : 'actions_btn'
        },
 
        initialize: function(windowId, data) {
@@ -128,8 +132,28 @@ var SlideWindowClass = Class.create({
                this.options.observe('click', function() {
                        this.toggleToolbar();
                }.bind(this));
+
+               this.setActionsBtnEvents();
+       },
+
+       setActionsBtnEvents: function() {
+               var actions_btn_container = this.window.getElementsByClassName(this.elements.actionsButton);
+               if (actions_btn_container.length === 1) {
+                       var actions_btn = actions_btn_container[0].getElementsByTagName('INPUT');
+                       if (actions_btn.length === 1) {
+                               actions_btn[0].addEventListener('mouseup', function(e) {
+                                       var row = this.getGridRowUnderCursor(e);
+                                       var el = $(row).down('input[type=hidden]');
+                                       if(el) {
+                                               var val = el.getValue();
+                                               this.actionsRequest.ActiveControl.CallbackParameter = val;
+                                               this.actionsRequest.dispatch();
+                                       }
+                               }.bind(this));
+                       }
+               }
        },
-       
+
        openWindow : function() {
                this.hideOtherWindows();
                Effect.toggle(this.window, 'slide', { duration: 0.3, afterFinish : function() {
@@ -148,7 +172,16 @@ var SlideWindowClass = Class.create({
        isWindowOpen: function() {
                return !(this.window.style.display === 'none');
        },
-       
+
+       showProgress: function(show) {
+               var progress = $(this.windowId + this.elements.containerProgressSuffix);
+               if (show === true) {
+                       progress.setStyle({display: 'block'});
+               } else if (show === false) {
+                       progress.hide();
+               }
+       },
+
        resetSize : function() {
                if(this.isConfigurationOpen()) {
                        if(this.isFullSize()) {
@@ -210,10 +243,14 @@ var SlideWindowClass = Class.create({
                this.configurationObj = obj;
        },
 
-       setWindowElementsEvent: function(repeaterEl, gridEl, requestObj) {
-               this.repeaterEl = repeaterEl;
-               this.gridEl = gridEl;
-               this.loadRequest = requestObj;
+       setWindowElementsEvent: function(opts) {
+               this.repeaterEl = opts.repeater_id;
+               this.gridEl = opts.grid_id;
+               this.loadRequest = opts.request_obj;
+               if (opts.hasOwnProperty('actions_obj')) {
+                       this.actionsRequest = opts.actions_obj;
+               }
+               this.showProgress(false);
                this.markAllChecked(false);
                this.setLoadRequest();
                this.postWindowOpen();
@@ -228,6 +265,15 @@ var SlideWindowClass = Class.create({
                        dataList = $(this.repeaterEl + '_Container').select('div.slide-window-element');
                }
 
+               var set_callback_parameter = function(element) {
+                       var el = $(element).down('input[type=hidden]')
+                       if(el) {
+                               var val = el.getValue();
+                               this.loadRequest.ActiveControl.CallbackParameter = val;
+                               this.loadRequest.dispatch();
+                               this.configurationObj.openConfigurationWindow(this);
+                       }
+               }.bind(this);
                dataList.each(function(tr) {
                        $(tr).observe('click', function(index, clickedEl) {
                                var target = clickedEl.target || clickedEl.srcElement;
@@ -236,14 +282,7 @@ var SlideWindowClass = Class.create({
                                if(clicked && clicked.hasAttribute('type') && clicked.readAttribute('type') == 'checkbox') {
                                        return;
                                }
-
-                               var el = $(tr).down('input[type=hidden]')
-                               if(el) {
-                                       var val = el.getValue();
-                                       this.loadRequest.ActiveControl.CallbackParameter = val;
-                                       this.loadRequest.dispatch();
-                                       this.configurationObj.openConfigurationWindow(this);
-                               }
+                               set_callback_parameter(tr);
                        }.bind(this, tr));
                }.bind(this));
        },
@@ -445,6 +484,48 @@ var SlideWindowClass = Class.create({
        postWindowOpen: function() {
                this.setActions();
                this.setElementsCount();
+               this.setOptionsBtn();
+       },
+       setOptionsBtn: function() {
+               var options_btn = this.window.getElementsByClassName(this.elements.actionsButton);
+               var table_window = $(this.windowId + this.elements.containerSuffix).down(this.elements.content);
+               if (options_btn.length === 1) {
+                       options_btn = options_btn[0];
+                       table_window.stopObserving('mouseover');
+                       table_window.observe('mouseover', function(e) {
+                               var el = this.getGridRowUnderCursor(e);
+                               if (el && (el.className == this.elements.contentItems || el.className == this.elements.contentAlternatingItems)) {
+                                       el.style.backgroundColor = '#aeb2b6';
+                                       options_btn.setStyle({display: ''});
+                                       var scroll_y = document.viewport.getScrollOffsets().top;
+                                       var y = (el.viewportOffset().top + scroll_y - 57).toString() + 'px';
+                                       options_btn.setStyle({top: y});
+                               } else {
+                                       options_btn.setStyle({display: 'none'});
+                               }
+                       }.bind(this));
+                       table_window.stopObserving('mouseout');
+                       table_window.observe('mouseout', function(e) {
+                               table_window.select('TR').forEach(function(el) {
+                                       el.style.backgroundColor = '';
+                               });;
+                               options_btn.setStyle({display: 'none'});
+                       });
+               }
+       },
+       getGridRowUnderCursor: function(e) {
+               var x = e.clientX - 100;
+               var y = e.clientY;
+               var element_mouse_is_over = document.elementFromPoint(x, y);
+               var el;
+               var el_over = $(element_mouse_is_over);
+               if (el_over && el_over.nodeName != 'TR') {
+                       el = el_over.down('tr');
+                       if (!el) {
+                               el = el_over.up('tr');
+                       }
+               }
+               return el;
        }
 });
 
@@ -452,7 +533,7 @@ var SlideWindow = new SlideWindowClass()
 
 document.observe("dom:loaded", function() {
        if(Prototype.Browser.IE  || Prototype.Browser.Gecko || Prototype.Browser.WebKit) {
-               $$('input[type=checkbox], input[type=submit], input[type=radio], a').each(function(el) {
+               $$('input[type=checkbox], input[type=submit], input[type=radio], input[type=image], a').each(function(el) {
                        el.observe('focus', function() {
                                el.blur();
                        }.bind(el));
index 5f2ce3f1d0bfe515fd2f9e3b6ac3db2b573c0ed2..b5275c140de0f57ad3b1bd532c8572fd66941c74 100644 (file)
@@ -43,4 +43,4 @@ class FileSets extends BaculumAPI {
                }
        }
 }
-?>
\ No newline at end of file
+?>
index a9c950faa341993190863d6689f540ad44f38e8e..e895bf48c3d36e78ee23afdeb59c9b520bc7cf53 100644 (file)
@@ -48,7 +48,20 @@ class JobRun extends BaculumAPI {
                                                if(!is_null($storage)) {
                                                        if(!is_null($pool)) {
                                                                $joblevels  = $this->getModule('misc')->getJobLevels();
-                                                               $run = $this->getModule('bconsole')->bconsoleCommand($this->director, array('run', 'job="' . $job . '"', 'level="' . $joblevels[$level] . '"', 'fileset="' . $fileset . '"', 'client="' . $client->name . '"', 'storage="' . $storage->name . '"', 'pool="' . $pool->name . '"' , 'priority="' . $priority . '"',  $jobid , $verifyjob, 'yes'), $this->user);
+                                                               $command = array(
+                                                                       'run',
+                                                                       'job="' . $job . '"',
+                                                                       'level="' . $joblevels[$level] . '"',
+                                                                       'fileset="' . $fileset . '"',
+                                                                       'client="' . $client->name . '"',
+                                                                       'storage="' . $storage->name . '"',
+                                                                       'pool="' . $pool->name . '"' ,
+                                                                       'priority="' . $priority . '"',
+                                                                       $jobid,
+                                                                       $verifyjob,
+                                                                       'yes'
+                                                               );
+                                                               $run = $this->getModule('bconsole')->bconsoleCommand($this->director, $command, $this->user);
                                                                $this->output = $run->output;
                                                                $this->error = (integer)$run->exitcode;
                                                        } else {
diff --git a/gui/baculum/protected/Pages/API/JobShow.php b/gui/baculum/protected/Pages/API/JobShow.php
new file mode 100644 (file)
index 0000000..fddd516
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2015 Marcin Haba
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+class JobShow extends BaculumAPI {
+       public function get() {
+               $jobid = intval($this->Request['id']);
+               $job = $this->getModule('job')->getJobById($jobid);
+               if(!is_null($job)) {
+                       $jobShow = $this->getModule('bconsole')->bconsoleCommand($this->director, array('show', 'job="' . $job->name . '"'), $this->user);
+                       $this->output = $jobShow->output;
+                       $this->error = (integer)$jobShow->exitcode;
+               } else {
+                       $this->output = JobError::MSG_ERROR_JOB_DOES_NOT_EXISTS;
+                       $this->error = JobError::ERROR_JOB_DOES_NOT_EXISTS;
+               }
+       }
+}
+
+?>
diff --git a/gui/baculum/protected/Pages/API/JobsShow.php b/gui/baculum/protected/Pages/API/JobsShow.php
new file mode 100644 (file)
index 0000000..9880679
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2015 Marcin Haba
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+class JobsShow extends BaculumAPI {
+
+       public function get() {
+               $jobs = $this->getModule('bconsole')->bconsoleCommand($this->director, array('show', 'jobs'), $this->user);
+               $this->output = $jobs->output;
+               $this->error = (integer)$jobs->exitcode;
+       }
+}
+
+?>
index 4aef694f0ed8a9e7cc685b306adf1052a75227e8..f0f5b9880f6bf744f2c471f048e6011bbf9ead9c 100644 (file)
        </div>
        <div id="container">
                <div id="menu-left">
-                       <com:TActiveButton ID="StorageBtn" CssClass="storage-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Storage Daemons')%>', '<%=Prado::localize('Configuration of storage daemons.')%>');" ClientSide.OnLoading="$('StorageWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('StorageWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('StorageWindow').setWindowElementsEvent('<%=$this->StorageWindow->Repeater->ClientID%>', '<%=$this->StorageWindow->DataGrid->ClientID%>', <%=$this->StorageWindow->DataElementCall->ActiveControl->Javascript%>);" />
-                       <com:TActiveButton ID="ClientBtn" CssClass="client-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Clients')%>', '<%=Prado::localize('Configuration of clients daemons.')%>');" ClientSide.OnLoading="$('ClientWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('ClientWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('ClientWindow').setWindowElementsEvent('<%=$this->ClientWindow->Repeater->ClientID%>', '<%=$this->ClientWindow->DataGrid->ClientID%>', <%=$this->ClientWindow->DataElementCall->ActiveControl->Javascript%>);" />
-                       <com:TActiveButton ID="MediaBtn" CssClass="media-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Volumes')%>', '<%=Prado::localize('Management of volumes.')%>');" ClientSide.OnLoading="$('VolumeWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('VolumeWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('VolumeWindow').setWindowElementsEvent('<%=$this->VolumeWindow->Repeater->ClientID%>', '<%=$this->VolumeWindow->DataGrid->ClientID%>', <%=$this->VolumeWindow->DataElementCall->ActiveControl->Javascript%>);" />
-
-                       <com:TActiveButton ID="PoolBtn" CssClass="pool-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Pools')%>', '<%=Prado::localize('Management of volumes pools.')%>');" ClientSide.OnLoading="$('PoolWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('PoolWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('PoolWindow').setWindowElementsEvent('<%=$this->PoolWindow->Repeater->ClientID%>', '<%=$this->PoolWindow->DataGrid->ClientID%>', <%=$this->PoolWindow->DataElementCall->ActiveControl->Javascript%>);" />
-                       <com:TActiveButton ID="JobBtn" CssClass="job-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Jobs')%>', '<%=Prado::localize('Jobs settings.')%>');" ClientSide.OnLoading="$('JobWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('JobWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('JobWindow').setWindowElementsEvent('<%=$this->JobWindow->Repeater->ClientID%>', '<%=$this->JobWindow->DataGrid->ClientID%>', <%=$this->JobWindow->DataElementCall->ActiveControl->Javascript%>);" />
-                       <com:TActiveButton ID="JobRunBtn" CssClass="jobrun-btn" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Run job')%>', '<%=Prado::localize('Starting jobs.')%>');" ClientSide.OnLoading="$('JobRunWindow-slide-window-progress').setStyle({'display': 'block'});" ClientSide.OnComplete="$('JobRunWindow-slide-window-progress').setStyle({'display': 'none'});SlideWindow.getObj('JobRunWindow').setWindowElementsEvent('<%=$this->JobRunWindow->Repeater->ClientID%>', '<%=$this->JobRunWindow->DataGrid->ClientID%>', <%=$this->JobRunWindow->DataElementCall->ActiveControl->Javascript%>);" />
-                       <com:TActiveButton CssClass="restore-btn" OnClick="restore" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Restore')%>', '<%=Prado::localize('Restore wizard.')%>');" />
-                       <com:TActiveButton ID="SettingsWizardBtn" CssClass="setting-btn" OnClick="configuration" Attributes.onmouseover="javascript:showTip(this, '<%=Prado::localize('Settings')%>', '<%=Prado::localize('Management settings wizard.')%>');" />
+                       <com:TActiveButton ID="StorageBtn" CssClass="storage-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Storage Daemons')%>',
+                                               '<%=Prado::localize('Configuration of storage daemons.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('StorageWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('StorageWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->StorageWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->StorageWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->StorageWindow->DataElementCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="ClientBtn" CssClass="client-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Clients')%>',
+                                               '<%=Prado::localize('Configuration of clients daemons.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('ClientWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('ClientWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->ClientWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->ClientWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->ClientWindow->DataElementCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="MediaBtn" CssClass="media-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Volumes')%>',
+                                               '<%=Prado::localize('Management of volumes.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('VolumeWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('VolumeWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->VolumeWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->VolumeWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->VolumeWindow->DataElementCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="PoolBtn" CssClass="pool-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Pools')%>',
+                                               '<%=Prado::localize('Management of volumes pools.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('PoolWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('PoolWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->PoolWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->PoolWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->PoolWindow->DataElementCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="JobBtn" CssClass="job-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Jobs')%>',
+                                               '<%=Prado::localize('Jobs settings.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('JobWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('JobWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->JobWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->JobWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->JobWindow->DataElementCall->ActiveControl->Javascript%>,
+                                               actions_obj: <%=$this->JobWindow->RunJobCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="JobRunBtn" CssClass="jobrun-btn">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Run job')%>',
+                                               '<%=Prado::localize('Starting jobs.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                               <prop:ClientSide.OnLoading>
+                                       SlideWindow.getObj('JobRunWindow').showProgress(true);
+                               </prop:ClientSide.OnLoading>
+                               <prop:ClientSide.OnComplete>
+                                       SlideWindow.getObj('JobRunWindow').setWindowElementsEvent({
+                                               repeater_id: '<%=$this->JobRunWindow->Repeater->ClientID%>',
+                                               grid_id: '<%=$this->JobRunWindow->DataGrid->ClientID%>',
+                                               request_obj: <%=$this->JobRunWindow->DataElementCall->ActiveControl->Javascript%>
+                                       });
+                               </prop:ClientSide.OnComplete>
+                       </com:TActiveButton>
+                       <com:TActiveButton CssClass="restore-btn" OnClick="restore">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Restore')%>',
+                                               '<%=Prado::localize('Restore wizard.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                       </com:TActiveButton>
+                       <com:TActiveButton ID="SettingsWizardBtn" CssClass="setting-btn" OnClick="configuration">
+                               <prop:Attributes.onmouseover>
+                                       showTip(
+                                               this,
+                                               '<%=Prado::localize('Settings')%>',
+                                               '<%=Prado::localize('Management settings wizard.')%>'
+                                       );
+                               </prop:Attributes.onmouseover>
+                       </com:TActiveButton>
                </div>
                <com:TActivePanel ID="Content">
                        <div id="content">
index eb5b85b9af30deb7d298b24c7021f72d845caa0b..5ee46995ca310d35a696a9263f046f41a10ce265 100644 (file)
@@ -17,7 +17,7 @@
                        AllowSorting="false"
                        OnSortCommand="sortDataGrid"
                        CellPadding="5px"
-                       CssClass="window-section-detail"
+                       CssClass="window-section-detail-smallrow"
                        ItemStyle.CssClass="slide-window-element"
                        AlternatingItemStyle.CssClass="slide-window-element-alternating"
                >
index 0be1ad5c71cee34d59cfff2ee3111b1d8fa06db2..35c3c0fd09104696bbb64bc5dc4f1ccea3f62b6d 100644 (file)
@@ -28,6 +28,7 @@ class JobConfiguration extends Portlets {
 
        const DEFAULT_JOB_PRIORITY = 10;
 
+       const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i';
 
        public $jobToVerify = array('C', 'O', 'd');
 
@@ -100,12 +101,21 @@ class JobConfiguration extends Portlets {
                $this->Pool->SelectedValue = $jobdata->poolid;
                $this->Pool->dataBind();
 
-               $storages = $this->Application->getModule('api')->get(array('storages'))->output;
+               $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid))->output;
+               $storageShow = $this->getResourceName('storage', $jobshow);
                $storagesList = array();
+               $selectedStorageId = null;
+               $storages = $this->Application->getModule('api')->get(array('storages'))->output;
                foreach($storages as $storage) {
+                       if ($storage->name == $storageShow) {
+                               $selectedStorageId = $storage->storageid;
+                       }
                        $storagesList[$storage->storageid] = $storage->name;
                }
                $this->Storage->dataSource = $storagesList;
+               if (!is_null($selectedStorageId)) {
+                       $this->Storage->SelectedValue = $selectedStorageId;
+               }
                $this->Storage->dataBind();
 
                $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates();
@@ -150,26 +160,41 @@ class JobConfiguration extends Portlets {
                if($this->PriorityValidator->IsValid === false) {
                        return false;
                }
+
                $params = array();
-               $params['id'] = $this->JobID->Text;
-               $params['level'] = $this->Level->SelectedValue;
-               $params['fileset'] = $this->FileSet->SelectedValue;
-               $params['clientid'] = $this->Client->SelectedValue;
-               $params['storageid'] = $this->Storage->SelectedValue;
-               $params['poolid'] = $this->Pool->SelectedValue;
-               $params['priority'] = $this->Priority->Text;
-
-               if (in_array($this->Level->SelectedItem->Value, $this->jobToVerify)) {
-                       $verifyVals = $this->getVerifyVals();
-                       if ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobname']) {
-                               $params['verifyjob'] = $this->JobToVerifyJobName->SelectedValue;
-                       } elseif ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) {
-                               $params['jobid'] = $this->JobToVerifyJobId->Text;
+               if (is_null($sender) && is_numeric($param)) {
+                       $jobdata = $this->Application->getModule('api')->get(array('jobs', $param))->output;
+                       $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid))->output;
+                       $params['id'] = $jobdata->jobid;
+                       $params['level'] = $jobdata->level;
+                       $params['fileset'] = $this->getResourceName('fileset', $jobshow);
+                       $params['clientid'] = $jobdata->clientid;
+                       $storage = $this->getResourceName('storage', $jobshow);
+                       $params['storageid'] = $this->getStorageByName($storage)->storageid;
+                       $pool = $this->getResourceName('pool', $jobshow);
+                       $params['poolid'] = $this->getPoolByName($pool)->poolid;
+               } else {
+                       $params['id'] = $this->JobID->Text;
+                       $params['level'] = $this->Level->SelectedValue;
+                       $params['fileset'] = $this->FileSet->SelectedValue;
+                       $params['clientid'] = $this->Client->SelectedValue;
+                       $params['storageid'] = $this->Storage->SelectedValue;
+                       $params['poolid'] = $this->Pool->SelectedValue;
+                       $params['priority'] = $this->Priority->Text;
+
+                       if (in_array($this->Level->SelectedItem->Value, $this->jobToVerify)) {
+                               $verifyVals = $this->getVerifyVals();
+                               if ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobname']) {
+                                       $params['verifyjob'] = $this->JobToVerifyJobName->SelectedValue;
+                               } elseif ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) {
+                                       $params['jobid'] = $this->JobToVerifyJobId->Text;
+                               }
                        }
                }
-
                $result = $this->Application->getModule('api')->create(array('jobs', 'run'), $params)->output;
-               $this->Estimation->Text = implode(PHP_EOL, $result);
+               if (!is_null($sender) || !is_numeric($param)) {
+                       $this->Estimation->Text = implode(PHP_EOL, $result);
+               }
        }
 
        public function estimate($sender, $param) {
@@ -204,5 +229,41 @@ class JobConfiguration extends Portlets {
                $verifyVals = array_combine($verifyOpt, $verifyOpt);
                return $verifyVals;
        }
+
+       private function getResourceName($resource, $jobshow) {
+               $resource_name = null;
+               $pattern = str_replace('%resource', $resource, self::RESOURCE_SHOW_PATTERN);
+               for ($i = 0; $i < count($jobshow); $i++) {
+                       if (preg_match($pattern, $jobshow[$i], $match) === 1) {
+                               $resource_name = $match[1];
+                               break;
+                       }
+               }
+               return $resource_name;
+       }
+
+       private function getPoolByName($name) {
+               $pool = null;
+               $pools = $this->Application->getModule('api')->get(array('pools'))->output;
+               for ($i = 0; $i < count($pools); $i++) {
+                       if ($pools[$i]->name == $name) {
+                               $pool = $pools[$i];
+                               break;
+                       }
+               }
+               return $pool;
+       }
+
+       private function getStorageByName($name) {
+               $storage = null;
+               $storages = $this->Application->getModule('api')->get(array('storages'))->output;
+               for ($i = 0; $i < count($storages); $i++) {
+                       if ($storages[$i]->name == $name) {
+                               $storage = $storages[$i];
+                               break;
+                       }
+               }
+               return $storage;
+       }
 }
 ?>
index ded04a7ba12e70cee636dfb0df8b245b5ec50d74..3e5e7994ac0f41f76b0b3d04731e73a22f96a57e 100644 (file)
@@ -22,7 +22,6 @@
 
 Prado::using('System.Web.UI.ActiveControls.TActiveDataGrid');
 Prado::using('System.Web.UI.ActiveControls.TActiveRepeater');
-Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton');
 Prado::using('System.Web.UI.ActiveControls.TActivePanel');
 Prado::using('System.Web.UI.ActiveControls.TCallback');
 Prado::using('Application.Portlets.ISlideWindow');
@@ -35,6 +34,7 @@ class JobList extends Portlets implements ISlideWindow {
        public $windowTitle;
        public $jobLevels;
        public $jobStates;
+       public $runningJobStates;
        public $jobTypes;
 
        public function setID($id) {
@@ -63,15 +63,21 @@ class JobList extends Portlets implements ISlideWindow {
 
        public function onLoad($param) {
                parent::onLoad($param);
-               $this->prepareData();
+               $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run', 'RunJobAgain');
+               if($this->Page->IsPostBack || $this->Page->IsCallBack) {
+                       if(in_array($this->getPage()->CallBackEventTarget->ID, $allowedButtons)) {
+                               $this->prepareData();
+                       }
+               }
                $misc = $this->Application->getModule('misc');
                $this->jobLevels = $misc->getJobLevels();
                $this->jobStates = $misc->getJobState();
                $this->jobTypes = $misc->getJobType();
+               $this->runningJobStates = $misc->getRunningJobStates();
        }
 
        public function prepareData($forceReload = false) {
-               $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run');
+               $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run', 'RunJobAgain');
                if($this->Page->IsPostBack || $this->Page->IsCallBack || $forceReload) {
                        if(in_array($this->getPage()->CallBackEventTarget->ID, $allowedButtons) || $forceReload) {
                                $params = $this->getUrlParams('jobs', $this->getPage()->JobWindow->ID);
@@ -106,6 +112,12 @@ class JobList extends Portlets implements ISlideWindow {
                }
        }
 
+       public function run_again($sender, $param) {
+               if($this->Page->IsCallBack) {
+                       $this->getPage()->JobConfiguration->run_again(null, $param->CallbackParameter);
+               }
+       }
+
        public function executeAction($action) {
                $params = explode(';', $this->CheckedValues->Value);
                $commands = array();
index 7e20d226e957876c524d4858f50283d67c3a88a8..54b24f965e766cd9607686bcef1f56aa3ceab80e 100644 (file)
                                <div class="job-status-<%=isset($this->getParent()->Data['jobstatus']) ? $this->getParent()->Data['jobstatus'] : ''%>" title="<%=isset($this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['description']) ? $this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['description'] : ''%>"><%=isset($this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['value']) ? $this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['value'] : ''%></div>
                        </prop:ItemTemplate>
                </com:TActiveTemplateColumn>
-               <com:TActiveBoundColumn
-                       SortExpression="endtime"
-                       HeaderText="<%[ End time ]%>"
-                       DataField="endtime"
-               />
+               <com:TActiveTemplateColumn HeaderText="<%[ End time ]%>" SortExpression="endtime">
+                       <prop:ItemTemplate>
+                               <%=$this->getParent()->Data['endtime']%>
+                               <%=in_array($this->getParent()->Data['jobstatus'], $this->getPage()->JobWindow->runningJobStates) ? '<img src="' . $this->getPage()->getTheme()->getBaseUrl() . '/loader-alter.gif" />' : ''%>
+                       </prop:ItemTemplate>
+               </com:TActiveTemplateColumn>
        </com:TActiveDataGrid>
        <com:TActiveHiddenField ID="CheckedValues" />
        </com:TActivePanel>
                        status_callback_func();
                </prop:ClientSide.OnComplete>
        </com:TCallback>
+       <com:TCallback ID="RunJobCall" OnCallback="Page.JobWindow.run_again">
+               <prop:ClientSide.OnLoading>
+                       var img_btn = $('run_job_again_btn');
+                       var img_src_path = img_btn.readAttribute('src').replace(/[^\/]+\S$/, '');
+                       img_btn.writeAttribute('disabled', 'disabled');
+                       img_btn.writeAttribute('src', img_src_path + 'loader.gif');
+               </prop:ClientSide.OnLoading>
+               <prop:ClientSide.OnComplete>
+                       var img_btn = $('run_job_again_btn');
+                       var img_src_path = img_btn.readAttribute('src').replace(/[^\/]+\S$/, '');
+                       img_btn.writeAttribute('src', img_src_path + 'play.png');
+                       img_btn.removeAttribute('disabled');
+                       status_callback_func();
+                       oMonitor();
+               </prop:ClientSide.OnComplete>
+       </com:TCallback>
+       <div class="actions_btn" style="display: none">
+               <input type="image" id="run_job_again_btn" title="<%[ Run job again ]%>" src="<%=$this->getPage()->getTheme()->getBaseUrl()%>/play.png" onclick="return false" />
+       </div>
 </com:TContent>
index ec4255e100d5c55b16610947cd19d44cd6305f38..32659d798a6842510c1e510897e2b35ee83eaa27 100644 (file)
@@ -20,7 +20,7 @@
                AllowSorting="false"
                OnSortCommand="sortDataGrid"
                CellPadding="5px"
-               CssClass="window-section-detail"
+               CssClass="window-section-detail-smallrow"
                ItemStyle.CssClass="slide-window-element"
                AlternatingItemStyle.CssClass="slide-window-element-alternating"
        >
index fa147f84d387c6ead3adc62f4b7c8dfc5020bfa1..d0193a144758209d6d789da43d50e3ad868d7b4c 100644 (file)
@@ -18,7 +18,7 @@
                        AllowSorting="false"
                        OnSortCommand="sortDataGrid"
                        CellPadding="5px"
-                       CssClass="window-section-detail"
+                       CssClass="window-section-detail-smallrow"
                        ItemStyle.CssClass="slide-window-element"
                        AlternatingItemStyle.CssClass="slide-window-element-alternating"
                >
index cf0649bfa2907f19122610d5c871acd747aead72..54a71925a26f4ba633bb93dc75c73a783f76b515 100644 (file)
@@ -17,7 +17,7 @@
                        AllowSorting="false"
                        OnSortCommand="sortDataGrid"
                        CellPadding="5px"
-                       CssClass="window-section-detail"
+                       CssClass="window-section-detail-smallrow"
                        ItemStyle.CssClass="slide-window-element"
                        AlternatingItemStyle.CssClass="slide-window-element-alternating"
                >
index 116597d0f4e0542ca973dbe34f957f81f1d8b99d..99e3f67717db2356b5405015a2041b70c576b981 100644 (file)
@@ -63,6 +63,8 @@
                        <url ServiceParameter="API.JobEstimate" pattern="jobs/estimate/" />
                        <url ServiceParameter="API.JobRun" pattern="jobs/run/" />
                        <url ServiceParameter="API.JobCancel" pattern="jobs/cancel/{id}/" parameters.id="\d+"/>
+                       <url ServiceParameter="API.JobsShow" pattern="jobs/show/" />
+                       <url ServiceParameter="API.JobShow" pattern="jobs/show/{id}/" parameters.id="\d+" />
                        <url ServiceParameter="API.RestoreRun" pattern="jobs/restore/" />
                        <!-- END Jobs -->
                        <!-- START BVFS -->
diff --git a/gui/baculum/themes/Baculum-v1/loader-alter.gif b/gui/baculum/themes/Baculum-v1/loader-alter.gif
new file mode 100644 (file)
index 0000000..87dd7fa
Binary files /dev/null and b/gui/baculum/themes/Baculum-v1/loader-alter.gif differ
diff --git a/gui/baculum/themes/Baculum-v1/loader.gif b/gui/baculum/themes/Baculum-v1/loader.gif
new file mode 100644 (file)
index 0000000..00662c6
Binary files /dev/null and b/gui/baculum/themes/Baculum-v1/loader.gif differ
diff --git a/gui/baculum/themes/Baculum-v1/play.png b/gui/baculum/themes/Baculum-v1/play.png
new file mode 100644 (file)
index 0000000..91d2059
Binary files /dev/null and b/gui/baculum/themes/Baculum-v1/play.png differ
index 1135fc81ed7ca5316bc070df4d0b106b25cfd183..7c8d41ace817fee54a4b540b08d7d6695067a503 100644 (file)
@@ -191,6 +191,16 @@ div.slide-window-progress {
        display: none;
 }
 
+div.actions_btn {
+       position: absolute;
+       width: 35px;
+       height: 35px;
+       right: 22px;
+       top: 0px;
+       margin: 3px 0;
+       text-align: right;
+}
+
 #console {
        clear: left;
        min-width: 973px;
@@ -385,7 +395,7 @@ input.bbutton {
        display: inline-block;
        width: auto;
        margin: 5px 8px;
-       padding: 0 18px;
+       padding: 0 16px;
        min-width: 65px;
        border-radius: 4px;
        border: 1px solid #8f2626;
@@ -394,7 +404,7 @@ input.bbutton {
 }
 
 input.bbutton:hover {
-       padding: 0 18px;
+       padding: 0 16px;
        box-shadow: inset 0 0 3px #faeded;
        background: #ff7474;
        border: 1px solid #8f2626;
@@ -446,27 +456,36 @@ tr.slide-window-element-alternating {
 tr.slide-window-element td, tr.slide-window-element-alternating td {
        font-style: italic;
        word-break: break-all;
+       line-height: 30px;
 }
+
 tr.slide-window-element:hover, tr.slide-window-element-alternating:hover {
        float: none;
        cursor: pointer;
 }
 
-tr.slide-window-element:hover td, tr.slide-window-element-alternating:hover td{
+tr.slide-window-element:hover td, tr.slide-window-element-alternating:hover td {
        background-color: #aeb2b6;
 }
 
-table.window-section-detail, table.file-browser-detail {
+tr.slide-window-element img, tr.slide-window-element-alternating img {
+       float: right;
+}
+
+table.window-section-detail, table.window-section-detail-smallrow, table.file-browser-detail {
        background-color: rgba(0,0,0,0.5);
        width: 100%;
        font-size: 10px;
        font-weight: normal;
 }
 
-table.window-section-detail th, table.file-browser-detail th {
+table.window-section-detail th, table.window-section-detail-smallrow th, table.file-browser-detail th {
        background-color: black;
        color: white;
 }
+table.window-section-detail-smallrow td {
+       line-height: 15px;
+}
 
 table.file-browser-detail {
        border-spacing: 0;
@@ -677,7 +696,7 @@ div.status-bar-detail-append, div.status-bar-detail-full, div.status-bar-detail-
 
 div.job-status-C, div.job-status-R, div.job-status-B, div.job-status-T, div.job-status-W, div.job-status-E, div.job-status-e, div.job-status-f, div.job-status-D, div.job-status-A, div.job-status-I, div.job-status-F, div.job-status-S, div.job-status-m, div.job-status-M, div.job-status-s, div.job-status-j, div.job-status-c, div.job-status-d, div.job-status-t, div.job-status-p, div.job-status-i, div.job-status-a, div.job-status-l, div.job-status-L {
        border: 1px solid black;
-       min-width: 80px;
+       min-width: 52px;
        height: 20px;
        line-height: 20px;
        font-size: 9px;