]> git.sur5r.net Git - bacula/bacula/commitdiff
baculum: Jobs working refresh in realtime and add new tray bar
authorMarcin Haba <marcin.haba@bacula.pl>
Mon, 30 Mar 2015 00:33:39 +0000 (02:33 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Mon, 30 Mar 2015 00:33:39 +0000 (02:33 +0200)
18 files changed:
gui/baculum/protected/JavaScript/slide-window.js
gui/baculum/protected/Lang/en/messages.mo
gui/baculum/protected/Lang/en/messages.po
gui/baculum/protected/Lang/pl/messages.mo
gui/baculum/protected/Lang/pl/messages.po
gui/baculum/protected/Pages/Home.page
gui/baculum/protected/Pages/Monitor.php [new file with mode: 0644]
gui/baculum/protected/Pages/config.xml
gui/baculum/protected/Portlets/JobConfiguration.php
gui/baculum/protected/Portlets/JobConfiguration.tpl
gui/baculum/protected/Portlets/JobList.tpl
gui/baculum/protected/Portlets/JobRunConfiguration.tpl
gui/baculum/protected/Portlets/TrayBar.php [new file with mode: 0644]
gui/baculum/protected/Portlets/TrayBar.tpl [new file with mode: 0644]
gui/baculum/protected/application.xml
gui/baculum/themes/Baculum-v1/check-icon.png [new file with mode: 0644]
gui/baculum/themes/Baculum-v1/gearwheel-icon.png [new file with mode: 0644]
gui/baculum/themes/Baculum-v1/style.css

index 9e3f499f8790561619ce0278edef1022877df56f..44e1545828edb2763780a1c36a04ffa4f4bbffd8 100644 (file)
@@ -138,6 +138,10 @@ var SlideWindowClass = Class.create({
                        }.bind(this)
                });
        },
+
+       isWindowOpen: function() {
+               return !(this.window.style.display === 'none');
+       },
        
        resetSize : function() {
                if(this.isConfigurationOpen()) {
index 5b75739980b5aaad03e2be27292fb2e34ecab2d3..6bf2bb9bfb3f8fefb8e70eb3e12abbcf62138142 100644 (file)
Binary files a/gui/baculum/protected/Lang/en/messages.mo and b/gui/baculum/protected/Lang/en/messages.mo differ
index a2457c489571184d78b239923cb38286ed370476..22242be45d63941017f1d0fb91463945819891f2 100644 (file)
@@ -1003,3 +1003,10 @@ msgstr "Verify by JobId"
 
 msgid "Verify option:"
 msgstr "Verify option:"
+
+msgid "Running jobs:"
+msgstr "Running jobs:"
+
+msgid "Finished jobs:"
+msgstr "Finished jobs:"
+
index f05d48bc1e07b6ed7189fb3aa96334fabe209bcf..417ecba3fa3ba78d2888d7dfc2863eba3c75e3f8 100644 (file)
Binary files a/gui/baculum/protected/Lang/pl/messages.mo and b/gui/baculum/protected/Lang/pl/messages.mo differ
index b0d5575c49e373819b3042d067f54f518e54c3a5..9cccbab7d396eaf5cf91a97694a9d1a635cb468e 100644 (file)
@@ -1005,3 +1005,9 @@ msgstr "Weryfikuj na podstawie JobId"
 msgid "Verify option:"
 msgstr "Opcja weryfikacji:"
 
+msgid "Running jobs:"
+msgstr "Uruchomione zadania:"
+
+msgid "Finished jobs:"
+msgstr "Zakończone zadania:"
+
index 6660973a4f89b6c1f08528362f6cafe0ffe31db6..75341c00e855d0d6346afd9d759ad5e5cd465183 100644 (file)
@@ -9,6 +9,7 @@
                        <com:TActiveLinkButton ID="Workspace" Text="<%[ Workspace ]%>" Attributes.onclick="PanelWindow.show('container');" />
                        <com:TActiveLinkButton ID="Graphs" Text="<%[ Graphs ]%>" Attributes.onclick="PanelWindow.show('graphs');" />
                </div>
+               <com:Application.Portlets.TrayBar ID="TrayBar" />
        </div>
        <div id="container">
                <div id="menu-left">
        </div>
        <div id="bottom"></div>
        <script type="text/javascript">
+               var oMonitor;
                document.observe("dom:loaded", function() {
                        <%=(!is_null($this->openWindow) ?
                                '$("' . $this->openWindow . '").click(); window.history.pushState("", "", "/");'
diff --git a/gui/baculum/protected/Pages/Monitor.php b/gui/baculum/protected/Pages/Monitor.php
new file mode 100644 (file)
index 0000000..59b495d
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Bacula® - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2015 Marcin Haba
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The main 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.
+ *
+ * Bacula® is a registered trademark of Kern Sibbald.
+ */
+
+class Monitor extends BaculumPage {
+       public function onInit($param) {
+               parent::onInit($param);
+               $_SESSION['monitor_data'] = array('jobs' => array(), 'running_jobs' => array(), 'terminated_jobs' => array());
+               $_SESSION['monitor_data']['jobs'] = $this->Application->getModule('api')->get(array('jobs'))->output;
+
+               $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates();
+
+               for ($i = 0; $i < count($_SESSION['monitor_data']['jobs']); $i++) {
+                       if (in_array($_SESSION['monitor_data']['jobs'][$i]->jobstatus, $runningJobStates)) {
+                               $_SESSION['monitor_data']['running_jobs'][] = $_SESSION['monitor_data']['jobs'][$i];
+                       } else {
+                               $_SESSION['monitor_data']['terminated_jobs'][] = $_SESSION['monitor_data']['jobs'][$i];
+                       }
+               }
+               echo json_encode($_SESSION['monitor_data']);
+               exit();
+       }
+}
+
+?>
index 18bd4b30ec02af4220053612511c217ad386bcc7..246b9b7ec208608d5966b61c8324357a0a6d6ec9 100644 (file)
@@ -2,7 +2,7 @@
 <configuration>
   <authorization>
     <allow pages="BaculumError,Requirements" users="*" />
-    <allow pages="Home,RestoreWizard,API.*" roles="admin,user" />
+    <allow pages="Home,RestoreWizard,API.*,Monitor" roles="admin,user" />
     <allow pages="ConfigurationWizard" roles="admin" />
     <deny users="*" />
   </authorization>
index 81d3a3348ddda126fe91b10fbde6e7a7326db027..8e92ce197f4d8d35cbdacea6ddb61fd2f0685709 100644 (file)
@@ -17,6 +17,7 @@
  * Bacula® is a registered trademark of Kern Sibbald.
  */
 
+Prado::using('System.Web.UI.ActiveControls.TActiveHiddenField');
 Prado::using('System.Web.UI.ActiveControls.TActivePanel');
 Prado::using('Application.Portlets.Portlets');
 
@@ -108,10 +109,19 @@ class JobConfiguration extends Portlets {
 
                $this->Priority->Text = ($jobdata->priorjobid == 0) ? self::DEFAULT_JOB_PRIORITY : $jobdata->priorjobid;
                $this->DeleteButton->Visible = true;
-               $this->CancelButton->Visible = in_array($jobdata->jobstatus, $runningJobStates);
+               $this->CancelButton->Visible = $this->RefreshStart->Value = in_array($jobdata->jobstatus, $runningJobStates);
        }
 
        public function status($sender, $param) {
+               $refreshStart = false;
+               for ($i = 0; $i < count($_SESSION['monitor_data']['running_jobs']); $i++) {
+                       if ($_SESSION['monitor_data']['running_jobs'][$i]->jobid == $this->JobID->Text) {
+                               $refreshStart = true;
+                               break;
+                       }
+               }
+               $this->RefreshStart->Value = $refreshStart;
+
                $joblog = $this->Application->getModule('api')->get(array('joblog', $this->JobID->Text))->output;
                $this->Estimation->Text = is_array($joblog) ? implode(PHP_EOL, $joblog) : Prado::localize("Output for selected job is not available yet or you do not have enabled logging job logs to catalog database. For watching job log there is need to add to the job Messages resource next directive: console = all, !skipped, !saved");
        }
index 1052462f13f31e6d1627208c962ff1061135b902..1f9141a3a02d4b191a812d5d5677b3a6852e7626 100644 (file)
                <com:TCallback ID="ReloadJobs" OnCallback="Page.JobWindow.prepareData" ClientSide.OnComplete="SlideWindow.getObj('JobWindow').setLoadRequest();" />
                <script type="text/javascript">
                        var job_callback_func = function() {
-                               var mainForm = Prado.Validation.getForm();
-                               var callback = <%=$this->ReloadJobs->ActiveControl->Javascript%>;
-                               if (Prado.Validation.managers[mainForm].getValidatorsWithError('JobGroup').length == 0) {
-                                       SlideWindow.getObj('JobWindow').markAllChecked(false);
-                                       callback.dispatch();
+                               /*
+                                * Check if Job list window is open and if any checkbox from actions is not checked.
+                                * If yes, then is possible to refresh Job list window.
+                                */
+                               if(SlideWindow.getObj('JobWindow').isWindowOpen() === true && SlideWindow.getObj('JobWindow').areActionsOpen() === false) {
+                                       var mainForm = Prado.Validation.getForm();
+                                       var callback = <%=$this->ReloadJobs->ActiveControl->Javascript%>;
+                                       if (Prado.Validation.managers[mainForm].getValidatorsWithError('JobGroup').length == 0) {
+                                               SlideWindow.getObj('JobWindow').markAllChecked(false);
+                                               callback.dispatch();
+                                       }
                                }
                        }
                </script>
                        <com:BActiveButton ID="Status" Text="<%[ Job status ]%>" CausesValidation="false" OnClick="status" ClientSide.OnSuccess="ConfigurationWindow.getObj('JobWindow').progress(false);job_callback_func();" CssClass="bbutton" />
                        <com:TActiveLabel ID="DeleteButton"><com:BActiveButton ID="Delete" Text="<%[ Delete job ]%>" CausesValidation="false" OnClick="delete" ClientSide.OnSuccess="ConfigurationWindow.getObj('JobWindow').progress(false);job_callback_func();" CssClass="bbutton" /> </com:TActiveLabel>
                        <com:TActiveLabel ID="CancelButton"><com:BActiveButton ID="Cancel" Text="<%[ Cancel job ]%>" CausesValidation="false" OnClick="cancel" ClientSide.OnSuccess="ConfigurationWindow.getObj('JobWindow').progress(false);job_callback_func();" CssClass="bbutton" /> </com:TActiveLabel>
-                       <com:BActiveButton ID="Run" Text="<%[ Run job again ]%>" ValidationGroup="JobGroup" CausesValidation="true" OnClick="run_again" ClientSide.OnSuccess="ConfigurationWindow.getObj('JobWindow').progress(false);job_callback_func();"/>
+                       <com:BActiveButton ID="Run" Text="<%[ Run job again ]%>" ValidationGroup="JobGroup" CausesValidation="true" OnClick="run_again" ClientSide.OnSuccess="ConfigurationWindow.getObj('JobWindow').progress(false);job_callback_func();oMonitor();"/>
                </div>
+               <com:TCallback ID="RefreshStatus" OnCallback="status" ClientSide.OnComplete="status_callback_timeout = setTimeout('status_callback_func()', 10000);" />
+               <script type="text/javascript">
+                       var status_callback_timeout;
+                       var status_prev = false;
+                       var status_callback_func = function() {
+                               if(status_callback_timeout) {
+                                       clearTimeout(status_callback_timeout);
+                               }
+                               if($('<%=$this->getID()%>configuration').visible() && ($('<%=$this->RefreshStart->ClientID%>').value === 'true' || status_prev === true)) {
+                                       status_prev = ($('<%=$this->RefreshStart->ClientID%>').value === 'true');
+                                       var callback = <%=$this->RefreshStatus->ActiveControl->Javascript%>;
+                                       oMonitor();
+                                       callback.dispatch();
+                               } else {
+                                       status_prev = false;
+                               }
+                       }
+               </script>
+               <com:TActiveHiddenField ID="RefreshStart" />
                <div class="text small"><%[ Console status ]%></div>
                <div class="field-full" style="min-height: 166px">
                        <com:TActiveTextBox ID="Estimation" TextMode="MultiLine" CssClass="textbox-auto" Style="height: 145px" ReadOnly="true" />
index d7ccc5dd7d6042a3c76ae63fe4b79bceffba4422..7e20d226e957876c524d4858f50283d67c3a88a8 100644 (file)
@@ -65,6 +65,7 @@
                <prop:ClientSide.OnComplete>
                        ConfigurationWindow.getObj('JobWindow').show();
                        ConfigurationWindow.getObj('JobWindow').progress(false);
+                       status_callback_func();
                </prop:ClientSide.OnComplete>
        </com:TCallback>
 </com:TContent>
index e0500c994da1ec0a17393b3e055dcaff2a0d90d3..44e948a155d3cd382eca5d9b00933ea393b885a7 100644 (file)
                        <div class="field"><com:TActiveCheckBox ID="Accurate" AutoPostBack="false" /></div>
                </com:TPanel>
                <com:TPanel ID="EstimateLine" CssClass="button">
-                       <com:Application.Portlets.BActiveButton ID="Estimate" Text="<%[ Estimate job ]%>" OnClick="estimate"  ClientSide.OnSuccess="ConfigurationWindow.getObj('JobRunWindow').progress(false);jobrun_callback_func();" />
+                       <com:Application.Portlets.BActiveButton ID="Estimate" Text="<%[ Estimate job ]%>" OnClick="estimate"  ClientSide.OnSuccess="ConfigurationWindow.getObj('JobRunWindow').progress(false);jobrun_callback_func();oMonitor();" />
                </com:TPanel>
        </com:TActivePanel>
 </com:TContent>
diff --git a/gui/baculum/protected/Portlets/TrayBar.php b/gui/baculum/protected/Portlets/TrayBar.php
new file mode 100644 (file)
index 0000000..8a19981
--- /dev/null
@@ -0,0 +1,25 @@
+
+<?php
+/**
+ * Bacula® - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2015 Marcin Haba
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The main 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.
+ *
+ * Bacula® is a registered trademark of Kern Sibbald.
+ */
+
+Prado::using('Application.Portlets.Portlets');
+
+class TrayBar extends Portlets {
+
+}
diff --git a/gui/baculum/protected/Portlets/TrayBar.tpl b/gui/baculum/protected/Portlets/TrayBar.tpl
new file mode 100644 (file)
index 0000000..7fedf0b
--- /dev/null
@@ -0,0 +1,32 @@
+<div id="tray_bar">
+       <img src="<%=$this->getPage()->getTheme()->getBaseUrl()%>/gearwheel-icon.png" alt="<%[ Running jobs: ]%>" /> <%[ Running jobs: ]%> <span class="bold" id="running_jobs"></span>
+       <img src="<%=$this->getPage()->getTheme()->getBaseUrl()%>/check-icon.png" alt="<%[ Finished jobs: ]%>" /> <%[ Finished jobs: ]%> <span class="bold" id="finished_jobs"></span>
+</div>
+<script type="text/javascript">
+       var oMonitor;
+       var default_refresh_interval = 60000;
+       var default_fast_refresh_interval = 10000;
+       var timeout_handler;
+       document.observe("dom:loaded", function() {
+               oMonitor = function() {
+                       return new Ajax.Request('<%=$this->Service->constructUrl("Monitor")%>', {
+                               onSuccess: function(response) {
+                                       if (timeout_handler) {
+                                               clearTimeout(timeout_handler);
+                                       }
+                                       var jobs = (response.responseText).evalJSON();
+                                       if (jobs.running_jobs.length > 0) {
+                                               refreshInterval = default_fast_refresh_interval;
+                                       } else {
+                                               refreshInterval = default_refresh_interval;
+                                       }
+                                       job_callback_func();
+                                       $('running_jobs').update(jobs.running_jobs.length);
+                                       $('finished_jobs').update(jobs.terminated_jobs.length);
+                                       timeout_handler = setTimeout("oMonitor()", refreshInterval);
+                               }
+                       });
+               };
+               oMonitor();
+       });
+       </script>
index bf154c9bd424776079f6fb5539768d047ea80f31..d6438c8e46de2388cbe18751726779e4074da85b 100644 (file)
@@ -14,6 +14,7 @@
                        <url ServiceParameter="ConfigurationWizard" pattern="wizard/" />
                        <url ServiceParameter="RestoreWizard" pattern="restore/" />
                        <url ServiceParameter="BaculumError" pattern="message/{error}/" parameters.error="\d+" />
+                       <url ServiceParameter="Monitor" pattern="monitor/" />
                        <!-- START Directors -->
                        <url ServiceParameter="API.Directors" pattern="directors/" />
                        <!-- END Directors -->
diff --git a/gui/baculum/themes/Baculum-v1/check-icon.png b/gui/baculum/themes/Baculum-v1/check-icon.png
new file mode 100644 (file)
index 0000000..004d3b5
Binary files /dev/null and b/gui/baculum/themes/Baculum-v1/check-icon.png differ
diff --git a/gui/baculum/themes/Baculum-v1/gearwheel-icon.png b/gui/baculum/themes/Baculum-v1/gearwheel-icon.png
new file mode 100644 (file)
index 0000000..f410812
Binary files /dev/null and b/gui/baculum/themes/Baculum-v1/gearwheel-icon.png differ
index 28867b6b11d9864482693d27e485dd2b5f1b4aef..09a41ac597bae3c1a9b0f1ded1d971d75dcbe716 100644 (file)
@@ -113,7 +113,7 @@ a:hover {
        z-index: 100;
 }
 
-#directors, #panel_switcher {
+#directors, #panel_switcher, #tray_bar {
        float: right;
        font-size: 12px;
 }
@@ -129,6 +129,20 @@ a:hover {
        font-weight: bold;
 }
 
+#tray_bar {
+       margin: 2px 30px 2px 0;
+}
+
+#tray_bar img {
+       float: none;
+       margin: 0;
+       padding: auto 12px;
+}
+
+#tray_bar span{
+       font-size: 14px;
+}
+
 div.configuration {
        width: 45%;
        height: 575px;