]> git.sur5r.net Git - bacula/bacula/commitdiff
baculum: Show jobs for client
authorMarcin Haba <marcin.haba@bacula.pl>
Sat, 12 Mar 2016 01:33:19 +0000 (02:33 +0100)
committerKern Sibbald <kern@sibbald.com>
Tue, 31 May 2016 06:20:28 +0000 (08:20 +0200)
12 files changed:
gui/baculum/protected/Class/JobManager.php
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/Lang/pt/messages.mo
gui/baculum/protected/Lang/pt/messages.po
gui/baculum/protected/Pages/API/JobsForClient.php [new file with mode: 0644]
gui/baculum/protected/Portlets/ClientConfiguration.php
gui/baculum/protected/Portlets/ClientConfiguration.tpl
gui/baculum/protected/Portlets/ClientList.tpl
gui/baculum/protected/application.xml

index f08a27001b6016596f09d6184aa0a9f0a177634b..078efeea00ce4ac9067d5198c280a1b1bba68905 100644 (file)
@@ -131,5 +131,21 @@ class JobManager extends TModule {
                return JobRecord::finder()->findAllBySql($sql);
        }
 
+       /**
+        * Get jobs for given client.
+        *
+        * @param string $clientid client identifier
+        * @param array $allowed_jobs jobs allowed to show
+        * @return array jobs for specific client
+        */
+       public function getJobsForClient($clientid, $allowed_jobs = array()) {
+               $jobs_criteria = '';
+               if (count($allowed_jobs) > 0) {
+                       $jobs_sql = implode("', '", $allowed_jobs);
+                       $jobs_criteria = " AND Job.Name IN ('" . $jobs_sql . "')";
+               }
+               $sql = "SELECT DISTINCT Job.* FROM Client, Job WHERE Client.ClientId='$clientid' AND Client.ClientId=Job.ClientId $jobs_criteria";
+               return JobRecord::finder()->findAllBySql($sql);
+       }
 }
 ?>
index 5fc682c7ea10c41ed624c79ae0377c94da642390..5479eef48c7230c6be0dcb20212e3d6ff94d09fe 100644 (file)
Binary files a/gui/baculum/protected/Lang/en/messages.mo and b/gui/baculum/protected/Lang/en/messages.mo differ
index 3b630625d77c349d67e6469d5cf192f4ef32983c..a3b2b2d37d2a9df96b9291479acfe0c744422c96 100644 (file)
@@ -1142,3 +1142,9 @@ msgstr "Jobs on Volume"
 msgid "No jobs on the volume."
 msgstr "No jobs on the volume."
 
+msgid "Jobs for Client"
+msgstr "Jobs for Client"
+
+msgid "No jobs for the client."
+msgstr "No jobs for the client."
+
index 7b2fe042425bd7a416099080fe27f25ec150b643..dd0d0b32618d7735c9f6c9d5ea2d5c7ac724ea08 100644 (file)
Binary files a/gui/baculum/protected/Lang/pl/messages.mo and b/gui/baculum/protected/Lang/pl/messages.mo differ
index 6b6f6c04f03dd6cd85905418b5c221db999d5db1..96d70df014a10617ec2d30af484f5025aefb1062 100644 (file)
@@ -1143,3 +1143,9 @@ msgstr "Zadania na volumenie"
 msgid "No jobs on the volume."
 msgstr "Na wolumenie nie ma żadnych zadań."
 
+msgid "Jobs for Client"
+msgstr "Zadania dla klienta"
+
+msgid "No jobs for the client."
+msgstr "Nie ma żadnych zadań dla klienta."
+
index 73e8e97cac9d677ef35a3e7d4984e21a4c946200..8791c99bdc43893f851cc78abad5428506928d40 100644 (file)
Binary files a/gui/baculum/protected/Lang/pt/messages.mo and b/gui/baculum/protected/Lang/pt/messages.mo differ
index 75c6eedc527dd2e813eed913ddc03fd68347c1b5..759db72637c1c6e217414050db3671baff936e82 100644 (file)
@@ -1145,3 +1145,9 @@ msgstr "Jobs on Volume"
 msgid "No jobs on the volume."
 msgstr "No jobs on the volume."
 
+msgid "Jobs for Client"
+msgstr "Jobs for Client"
+
+msgid "No jobs for the client."
+msgstr "No jobs for the client."
+
diff --git a/gui/baculum/protected/Pages/API/JobsForClient.php b/gui/baculum/protected/Pages/API/JobsForClient.php
new file mode 100644 (file)
index 0000000..ff027be
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2016 Kern Sibbald
+ *
+ * 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 JobsForClient extends BaculumAPI {
+       public function get() {
+               $allowed = array();
+               $clientid = intval($this->Request['id']);
+               $error = false;
+               if (!is_null($this->user)) {
+                       $allowed_jobs = $this->getModule('bconsole')->bconsoleCommand($this->director, array('.jobs'), $this->user);
+                       if ($allowed_jobs->exitcode === 0) {
+                               $allowed = $allowed_jobs->output;
+                       } else {
+                               $error = true;
+                               $this->output = $allowed_jobs->output;
+                               $this->error = $allowed_jobs->exitcode;
+                       }
+               }
+
+               if ($error === false) {
+                       $jobs = $this->getModule('job')->getJobsForClient($clientid, $allowed);
+                       $this->output = $jobs;
+                       $this->error = JobError::ERROR_NO_ERRORS;
+               }
+       }
+}
+?>
index 1b9ed6b76dc36c484c0decd0b4a607647b53dded..f3dd43c43b3e636b334f0dcfd082c960a5b413b8 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 Prado::using('System.Web.UI.ActiveControls.TActiveCustomValidator');
+Prado::using('System.Web.UI.ActiveControls.TActiveDataGrid');
 Prado::using('Application.Portlets.Portlets');
 
 class ClientConfiguration extends Portlets {
@@ -41,6 +42,10 @@ class ClientConfiguration extends Portlets {
                $this->FileRetention->Text = intval($client->fileretention / 86400); // conversion to days
                $this->JobRetention->Text = intval($client->jobretention / 86400); // conversion to days
                $this->AutoPrune->Checked = $client->autoprune == 1;
+
+               $jobs_for_client = $this->Application->getModule('api')->get(array('clients', 'jobs', $client->clientid))->output;
+               $this->JobsForClient->DataSource = $this->Application->getModule('misc')->objectToArray($jobs_for_client);
+               $this->JobsForClient->dataBind();
        }
 
        public function status($sender, $param) {
@@ -69,5 +74,10 @@ class ClientConfiguration extends Portlets {
                $isValid = preg_match('/^\d+$/', $this->JobRetention->Text) && $this->JobRetention->Text >= 0;
                $param->setIsValid($isValid);
        }
+
+       public function openJob($sender, $param) {
+               $jobid = $param->CallbackParameter;
+               $this->getPage()->JobConfiguration->configure($jobid);
+       }
 }
 ?>
index fd13e844790f42866ce9b66ebc6979974df9c962..8a0ac8c78baa5e744610f7db4c2becf7e997ed40 100644 (file)
@@ -5,6 +5,7 @@
                <com:TActiveLabel ID="ClientDescription" CssClass="description" />
                <span class="text tab tab_active" rel="client_actions_tab"><%[ Actions ]%></span>
                <span class="text tab" rel="client_console_tab"><%[ Console status ]%></span>
+               <span class="text tab" rel="client_jobs_tab"><%[ Jobs for Client ]%></span>
                <hr class="tabs" />
                <div id="client_actions_tab">
                        <com:TValidationSummary
                                <com:TActiveTextBox ID="ShowClient" TextMode="MultiLine" CssClass="textbox-auto" Style="height: 440px" ReadOnly="true" />
                        </div>
                </div>
+               <div id="client_jobs_tab" style="display: none">
+                       <div style="max-height: 444px; overflow-y: auto;">
+                               <com:TActiveDataGrid
+                                       ID="JobsForClient"
+                                       EnableViewState="false"
+                                       AutoGenerateColumns="false"
+                                       AllowSorting="false"
+                                       CellPadding="5px"
+                                       CssClass="window-section-detail"
+                                       ItemStyle.CssClass="slide-window-element"
+                                       AlternatingItemStyle.CssClass="slide-window-element-alternating"
+                                       >
+                                       <com:TActiveBoundColumn HeaderText="ID" DataField="jobid" />
+                                       <com:TActiveTemplateColumn HeaderText="<%[ Job name ]%>" SortExpression="name">
+                                               <prop:ItemTemplate>
+                                                       <div title="<%=$this->getParent()->Data['name']%>"><%=$this->getPage()->JobWindow->formatJobName($this->getParent()->Data['name'])%></div>
+                                                       <input type="hidden" name="<%=$this->getParent()->ClientID%>" value="<%=$this->getParent()->Data['jobid']%>" />
+                                               </prop:ItemTemplate>
+                                       </com:TActiveTemplateColumn>
+                                       <com:TActiveTemplateColumn>
+                                               <prop:HeaderText>
+                                                       <span title="<%=Prado::localize('Type')%>" style="cursor: help">T</span>
+                                               </prop:HeaderText>
+                                               <prop:ItemTemplate>
+                                                       <%=$this->getParent()->Data['type']%>
+                                               </prop:ItemTemplate>
+                                       </com:TActiveTemplateColumn>
+                                       <com:TActiveTemplateColumn>
+                                               <prop:HeaderText>
+                                                       <span title="<%=Prado::localize('Level')%>" style="cursor: help">L</span>
+                                               </prop:HeaderText>
+                                               <prop:ItemTemplate>
+                                                       <%=$this->getParent()->Data['level']%>
+                                               </prop:ItemTemplate>
+                                       </com:TActiveTemplateColumn>
+                                       <com:TActiveTemplateColumn HeaderText="<%[ Job status ]%>" SortExpression="jobstatus">
+                                               <prop:ItemTemplate>
+                                                       <div class="job-status-<%=$this->getPage()->JobWindow->getJobStatusLetter($this->getParent()->Data)%>" title="<%=$this->getPage()->JobWindow->getJobStatusDescription($this->getParent()->Data)%>"><%=$this->getPage()->JobWindow->getJobStatusValue($this->getParent()->Data)%></div>
+                                               </prop:ItemTemplate>
+                                       </com:TActiveTemplateColumn>
+                                       <com:TActiveTemplateColumn HeaderText="<%[ Size ]%>" SortExpression="jobbytes">
+                                               <prop:ItemTemplate>
+                                                       <div class="size" rel="<%=$this->getParent()->Data['jobbytes']%>"><%=$this->getParent()->Data['jobbytes']%></div>
+                                               </prop:ItemTemplate>
+                                       </com:TActiveTemplateColumn>
+                                       <com:TActiveBoundColumn SortExpression="jobfiles" HeaderText="<%[ Files ]%>" DataField="jobfiles" />
+                                       <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>
+                       </div>
+                       <p class="center bold" id="no_jobs_for_client" style="display: none"><%[ No jobs for the client. ]%></p>
+                       <script type="text/javascript">
+                               var bind_jobs_for_client_action = function() {
+                                       var grid_id = '<%=$this->JobsForClient->ClientID%>';
+                                       var no_jobs_msg_id = 'no_jobs_for_client';
+                                       if (!document.getElementById(grid_id)) {
+                                               $(no_jobs_msg_id).show();
+                                               return;
+                                       }
+                                       $(no_jobs_msg_id).hide();
+                                       SlideWindow.makeSortable(grid_id);
+                                       var odd_rows = ['#' + grid_id, 'tr.' + SlideWindow.elements.contentItems].join(' ');
+                                       var even_rows = ['#' + grid_id, 'tr.' + SlideWindow.elements.contentAlternatingItems].join(' ');
+                                       var callback = <%=$this->OpenJobCall->ActiveControl->Javascript%>;
+                                       $$(odd_rows, even_rows).each(function(el) {
+                                               el.observe('click', function(e) {
+                                                       var el = $(e.srcElement||e.target);
+                                                       if (el) {
+                                                               el = el.up('tr').down('input[type=hidden]')
+                                                               var val = el.getValue();
+                                                               callback.ActiveControl.CallbackParameter = val;
+                                                               callback.dispatch();
+                                                               ConfigurationWindow.getObj('ClientWindow').progress(true);
+                                                       }
+                                               }.bind(this));
+                                       }.bind(this));
+                                       SlideWindow.sortTable(grid_id, 0, true);
+                               }.bind(this);
+                       </script>
+                       <com:TCallback ID="OpenJobCall" OnCallback="openJob">
+                               <prop:ClientSide.OnComplete>
+                                       ConfigurationWindow.getObj('ClientWindow').progress(false);
+                                       ConfigurationWindow.getObj('JobWindow').switchTabByNo(2);
+                                       ConfigurationWindow.getObj('JobWindow').show();
+                               </prop:ClientSide.OnComplete>
+                       </com:TCallback>
+               </div>
        </com:TActivePanel>
 </com:TContent>
index 59388ab0a4a8d2d298cb1a19f6570911e7d9e05d..cc021407a31d55fe3873eb01c151584346869fa9 100644 (file)
@@ -47,6 +47,8 @@
        <com:TCallback ID="DataElementCall" OnCallback="Page.ClientWindow.configure">
                <prop:ClientSide.OnComplete>
                        ConfigurationWindow.getObj('ClientWindow').show();
+                       Formatters.set_formatters();
+                       bind_jobs_for_client_action();
                        ConfigurationWindow.getObj('ClientWindow').progress(false);
                </prop:ClientSide.OnComplete>
        </com:TCallback>
index 38cf9708941bffa835bd9d945fb1efd406748364..dcfd01cc962ccf3abede62f8f708ec982b9518ba 100644 (file)
@@ -27,6 +27,7 @@
                        <url ServiceParameter="API.ClientsShow" pattern="clients/show/" />
                        <url ServiceParameter="API.ClientShow" pattern="clients/show/{id}/" parameters.id="\d+" />
                        <url ServiceParameter="API.ClientStatus" pattern="clients/status/{id}/" parameters.id="\d+" />
+                       <url ServiceParameter="API.JobsForClient" pattern="clients/jobs/{id}/" parameters.id="\d+" />
                        <!-- END Clients (file daemons) -->
                        <!-- START Storages (storage daemons) -->
                        <url ServiceParameter="API.Storages" pattern="storages/" />