]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add status schedule page
authorMarcin Haba <marcin.haba@bacula.pl>
Thu, 2 May 2019 07:49:10 +0000 (09:49 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Thu, 2 May 2019 09:11:23 +0000 (11:11 +0200)
18 files changed:
gui/baculum/protected/Common/Class/BClientScript.php
gui/baculum/protected/Web/JavaScript/misc.js
gui/baculum/protected/Web/Lang/en/messages.mo
gui/baculum/protected/Web/Lang/en/messages.po
gui/baculum/protected/Web/Lang/ja/messages.mo
gui/baculum/protected/Web/Lang/ja/messages.po
gui/baculum/protected/Web/Lang/pl/messages.mo
gui/baculum/protected/Web/Lang/pl/messages.po
gui/baculum/protected/Web/Lang/pt/messages.mo
gui/baculum/protected/Web/Lang/pt/messages.po
gui/baculum/protected/Web/Pages/JobView.page
gui/baculum/protected/Web/Pages/JobView.php
gui/baculum/protected/Web/Pages/ScheduleList.page
gui/baculum/protected/Web/Pages/ScheduleStatusList.php [new file with mode: 0644]
gui/baculum/protected/Web/Pages/ScheduleStatusList.tpl [new file with mode: 0644]
gui/baculum/protected/Web/Portlets/StatusSchedule.php [new file with mode: 0644]
gui/baculum/protected/Web/Portlets/StatusSchedule.tpl [new file with mode: 0644]
gui/baculum/protected/Web/endpoints.xml

index 216d7dfd6a36394d3fbecef7c409f5c79581f474..6836fe06747b0526f2f828c23c5f55070d81adc0 100644 (file)
@@ -24,7 +24,7 @@ Prado::using('System.Web.UI.WebControls.TClientScript');
 
 class BClientScript extends TClientScript {
 
-       const SCRIPTS_VERSION = 2;
+       const SCRIPTS_VERSION = 3;
 
        public function getScriptUrl()
        {
index bb7360d9c6b1c1c80e42c06cbf11e1b771759050..aa74d594b3e24c74ff8c6536d92fe4c855385894 100644 (file)
@@ -80,6 +80,18 @@ var Units = {
                }
                var ret = {value: time_seconds, format: f};
                return ret;
+       },
+       format_date: function(timestamp) {
+               if (typeof(timestamp) === 'string') {
+                       timestamp = parseInt(timestamp, 10);
+               }
+               if (timestamp < 9999999999) {
+                       timestamp *= 1000;
+               }
+               var d = new Date(timestamp);
+               var date = [d.getFullYear(), ('0' + (d.getMonth()+1)).slice(-2), ('0' + d.getDate()).slice(-2)].join('-');
+               var time = [d.getHours(), ('0' + d.getMinutes()).slice(-2), ('0' + d.getSeconds()).slice(-2)].join(':');
+               return (date + ' ' + time);
        }
 }
 
index 5c643256f7ff9309f65cbdccac5385974bae12fd..c4080111522ddf0d127186ddd4386b0071547374 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/en/messages.mo and b/gui/baculum/protected/Web/Lang/en/messages.mo differ
index bfc857393fcc43b71a5e5f31b4a3766d28e45a0c..0bf5a0ba30ca1f1b4cf14dc81b73f5104e29bb0e 100644 (file)
@@ -1993,3 +1993,39 @@ msgstr "Plugins"
 
 msgid "Add plugin"
 msgstr "Add plugin"
+
+msgid "Job schedules"
+msgstr "Job schedules"
+
+msgid "Priority"
+msgstr "Priority"
+
+msgid "Scheduled"
+msgstr "Scheduled"
+
+msgid "FileSet"
+msgstr "FileSet"
+
+msgid "Filters:"
+msgstr "Filters:"
+
+msgid "Date from:"
+msgstr "Date from:"
+
+msgid "Days:"
+msgstr "Days:"
+
+msgid "Apply filters"
+msgstr "Apply filters"
+
+msgid "You must enter an integer."
+msgstr "You must enter an integer."
+
+msgid "Invalid date format."
+msgstr "Invalid date format."
+
+msgid "Input must be between 1 and 1000."
+msgstr "Input must be between 1 and 1000."
+
+msgid "Schedule status"
+msgstr "Schedule status"
index 1845bf2946045e58aa6157e8f2f983749e5ee42c..b71ad3bde945495b73cc0ce3203641da7e6b3427 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/ja/messages.mo and b/gui/baculum/protected/Web/Lang/ja/messages.mo differ
index 3600886f8d51c6a8876fa6058ebf7fcd982b1087..e9765e27a7da5a0cecc2723ed9fbc9f2cd9c4a7e 100644 (file)
@@ -2094,3 +2094,39 @@ msgstr "Add plugin"
 
 msgid "Plugins"
 msgstr "Plugins"
+
+msgid "Job schedules"
+msgstr "Job schedules"
+
+msgid "Priority"
+msgstr "Priority"
+
+msgid "Scheduled"
+msgstr "Scheduled"
+
+msgid "FileSet"
+msgstr "FileSet"
+
+msgid "Filters:"
+msgstr "Filters:"
+
+msgid "Date from:"
+msgstr "Date from:"
+
+msgid "Days:"
+msgstr "Days:"
+
+msgid "Apply filters"
+msgstr "Apply filters"
+
+msgid "You must enter an integer."
+msgstr "You must enter an integer."
+
+msgid "Invalid date format."
+msgstr "Invalid date format."
+
+msgid "Input must be between 1 and 1000."
+msgstr "Input must be between 1 and 1000."
+
+msgid "Schedule status"
+msgstr "Schedule status"
index 7c49bdcfb1ad2cb6a7480f709b1126dec4f6205e..281a5935e52836cd9c13d52529b56c584d8ef688 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pl/messages.mo and b/gui/baculum/protected/Web/Lang/pl/messages.mo differ
index 6d27962060daf65e7841c29f7ea60a9e8a227dde..e0eed90f309870a09b3d3f38920fa2b40c155e1b 100644 (file)
@@ -2000,3 +2000,39 @@ msgstr "Dodaj wtyczkę"
 
 msgid "Plugins"
 msgstr "Wtyczki"
+
+msgid "Job schedules"
+msgstr "Harmonogramy zadania"
+
+msgid "Priority"
+msgstr "Priorytet"
+
+msgid "Scheduled"
+msgstr "Zaplanowane"
+
+msgid "FileSet"
+msgstr "FileSet"
+
+msgid "Filters:"
+msgstr "Filtry:"
+
+msgid "Date from:"
+msgstr "Data od:"
+
+msgid "Days:"
+msgstr "Dni:"
+
+msgid "Apply filters"
+msgstr "Zastosuj filtry"
+
+msgid "You must enter an integer."
+msgstr "Musisz wprowadzić liczbę całkowitą."
+
+msgid "Invalid date format."
+msgstr "Niepoprawny format daty."
+
+msgid "Input must be between 1 and 1000."
+msgstr "Pole musi mieć wartość z zakresu 1-1000."
+
+msgid "Schedule status"
+msgstr "Status harmonogramu zadań"
index 40febb44d9afd5ed14a87b87b6866d07e5683b2a..fb7d7d7412b718d100880caed39c110a347d6488 100644 (file)
Binary files a/gui/baculum/protected/Web/Lang/pt/messages.mo and b/gui/baculum/protected/Web/Lang/pt/messages.mo differ
index 0fc278262ec1e789a2bf32568ee970fb6629a808..50bb4272f47b6e768abde4feef68a00364406ec0 100644 (file)
@@ -2008,3 +2008,39 @@ msgstr "Plugin"
 
 msgid "Plugins"
 msgstr "Plugins"
+
+msgid "Job schedules"
+msgstr "Job schedules"
+
+msgid "Priority"
+msgstr "Priority"
+
+msgid "Scheduled"
+msgstr "Scheduled"
+
+msgid "FileSet"
+msgstr "FileSet"
+
+msgid "Filters:"
+msgstr "Filters:"
+
+msgid "Date from:"
+msgstr "Date from:"
+
+msgid "Days:"
+msgstr "Days:"
+
+msgid "Apply filters"
+msgstr "Apply filters"
+
+msgid "You must enter an integer."
+msgstr "You must enter an integer."
+
+msgid "Invalid date format."
+msgstr "Invalid date format."
+
+msgid "Input must be between 1 and 1000."
+msgstr "Input must be between 1 and 1000."
+
+msgid "Schedule status"
+msgstr "Schedule status"
index 99045a6827fd741586d746e34e70c20f5cb60820..a79f5c1a887c41f04823009626a0d50860efc153 100644 (file)
                        OnClick="loadScheduleConfig"
                        CommandParameter="show"
                />
+               <com:TActiveLinkButton
+                       CssClass="w3-bar-item w3-button tab_btn"
+                       Text="<%[ Job schedules ]%>"
+                       OnCallback="loadSchedules"
+                       CommandParameter="show"
+                       Attributes.onclick="W3Tabs.open(this.id, 'job_schedules'); clear_node('#job_config div.directive_field'); clear_node('#fileset_config div.directive_field'); clear_node('#schedule_config  div.directive_field');"
+               />
        </div>
        <div class="w3-container tab_item" id="job_actions">
                <com:TActiveLinkButton
@@ -71,4 +78,9 @@
                        ShowCancelButton="false"
                />
        </div>
+       <div class="w3-container tab_item" id="job_schedules" style="display: none">
+               <com:Application.Web.Portlets.StatusSchedule
+                       ID="Schedules"
+               />
+       </div>
 </com:TContent>
index 78e17293e415860f332b47008446a06ddbe4ee3e..559753b7d5e7a42fae77b22aad1ba925834ce04f 100644 (file)
@@ -49,6 +49,8 @@ class JobView extends BaculumWebPage {
                }
                $this->RunJobModal->setJobName($job_name);
                $this->setJobName($job_name);
+               $this->Schedules->setJob($job_name);
+               $this->Schedules->setDays(90);
        }
 
        /**
@@ -119,5 +121,9 @@ class JobView extends BaculumWebPage {
                        $this->ScheduleConfig->raiseEvent('OnDirectiveListLoad', $this, null);
                }
        }
+
+       public function loadSchedules($sender, $param) {
+               $this->Schedules->loadSchedules();
+       }
 }
 ?>
index d3b2946348ef9bd8d476d60147edcc341ac9287e..0f3552321e21f5e99b0b14ad569c89c1757155e4 100644 (file)
@@ -8,6 +8,7 @@
        </header>
        <div class="w3-margin-left w3-margin-bottom">
                <button type="button" class="w3-button w3-green<%=empty($_SESSION['dir']) ? ' hide': ''%>" onclick="document.location.href='<%=$this->Service->constructUrl('NewResource', array('component_type' => 'dir', 'component_name' => $_SESSION['dir'], 'resource_type' => 'Schedule'))%>';"><i class="fa fa-plus"></i> &nbsp;<%[ Add schedule ]%></button>
+               <button type="button" class="w3-button w3-green" onclick="document.location.href='<%=$this->Service->constructUrl('ScheduleStatusList')%>';"><i class="fa fa-clock"></i> &nbsp;<%[ Schedule status ]%></button>
        </div>
        <div class="w3-container">
                        <table id="schedule_list" class="w3-table w3-striped w3-hoverable w3-white w3-margin-bottom">
diff --git a/gui/baculum/protected/Web/Pages/ScheduleStatusList.php b/gui/baculum/protected/Web/Pages/ScheduleStatusList.php
new file mode 100644 (file)
index 0000000..f10733b
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2019 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.
+ */
+
+Prado::using('Application.Web.Class.BaculumWebPage');
+
+class ScheduleStatusList extends BaculumWebPage {
+}
+?>
diff --git a/gui/baculum/protected/Web/Pages/ScheduleStatusList.tpl b/gui/baculum/protected/Web/Pages/ScheduleStatusList.tpl
new file mode 100644 (file)
index 0000000..d98a56c
--- /dev/null
@@ -0,0 +1,7 @@
+<%@ MasterClass="Application.Web.Layouts.Main" Theme="Baculum-v2"%>
+<com:TContent ID="Main">
+       <com:Application.Web.Portlets.StatusSchedule
+               ShowClientFilter="true"
+               ShowScheduleFilter="true"
+       />
+</com:TContent>
diff --git a/gui/baculum/protected/Web/Portlets/StatusSchedule.php b/gui/baculum/protected/Web/Portlets/StatusSchedule.php
new file mode 100644 (file)
index 0000000..81b6e91
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum   - Bacula web interface
+ *
+ * Copyright (C) 2013-2019 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.
+ */
+
+Prado::using('System.Web.UI.JuiControls.TJuiDatePicker');
+Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton');
+Prado::using('Application.Web.Portlets.Portlets');
+
+class StatusSchedule extends Portlets {
+
+       const JOB = 'Job';
+       const CLIENT = 'Client';
+       const SCHEDULE = 'Schedule';
+       const DAYS = 'Days';
+       const LIMIT = 'Limit';
+       const TIME = 'Time';
+       const SHOW_CLIENT_FILTER = 'ShowClientFilter';
+       const SHOW_SCHEDULE_FILTER = 'ShowScheduleFilter';
+
+       public $schedules = array();
+
+       public function onLoad($param) {
+               parent::onLoad($param);
+               if ($this->getPage()->IsCallBack || $this->getPage()->IsPostBack) {
+                       return;
+               }
+               $this->loadSchedules();
+               $this->DatePicker->setDate(date('Y-m-d'));
+
+               if ($this->getShowClientFilter()) {
+                       $clients = $this->getClients();
+                       $this->Client->DataSource = array_combine($clients, $clients);
+                       $this->Client->dataBind();
+               } else {
+                       $this->Client->Visible = false;
+               }
+
+               if ($this->getShowScheduleFilter()) {
+                       $schedules = $this->getSchedules();
+                       $this->Schedule->DataSource = array_combine($schedules, $schedules);
+                       $this->Schedule->dataBind();
+               } else {
+                       $this->Schedule->Visible = false;
+               }
+       }
+
+       public function loadSchedules() {
+               $query = array();
+               $job = $this->getJob();
+               if (!empty($job)) {
+                       $query[] = 'job=' . rawurlencode($job);
+               }
+               $client = $this->getClient();
+               if (!empty($client)) {
+                       $query[] = 'client=' . rawurlencode($client);
+               }
+               $schedule = $this->getSchedule();
+               if (!empty($schedule)) {
+                       $query[] = 'schedule=' . rawurlencode($schedule);
+               }
+               $days = $this->getDays();
+               if (!empty($days)) {
+                       $query[] = 'days=' . $days;
+               }
+               $limit = $this->getLimit();
+               if (!empty($limit)) {
+                       $query[] = 'limit=' . $limit;
+               }
+               $time = $this->getTime();
+               if (!empty($time)) {
+                       $query[] = 'time=' . rawurlencode($time);
+               }
+               $params = array('schedules', 'status');
+               if (count($query) > 0) {
+                       $params[] = '?' . implode('&', $query);
+               }
+
+               $result = $this->getModule('api')->get($params);
+               if ($result->error === 0) {
+                       $schedules = $result->output;
+                       if ($this->getPage()->IsCallBack) {
+                               $this->getpage()->getcallbackclient()->callclientfunction(
+                                       'set_job_schedule_data',
+                                       json_encode($schedules)
+                               );
+                               $this->getpage()->getcallbackclient()->callclientfunction(
+                                       'init_job_schedule'
+                               );
+                       } else {
+                               $this->schedules = $schedules;
+                       }
+               }
+       }
+
+       public function getClients() {
+               $clients = array('');
+               $result = $this->getModule('api')->get(array('clients'));
+               if ($result->error === 0) {
+                       for ($i = 0; $i < count($result->output); $i++) {
+                               $clients[] = $result->output[$i]->name;
+                       }
+               }
+               return $clients;
+       }
+
+       public function getSchedules() {
+               $schedules = array();
+               $result = $this->getModule('api')->get(array('schedules', 'resnames'));
+               if ($result->error === 0) {
+                       $schedules = $result->output;
+                       array_unshift($schedules, '');
+               }
+               return $schedules;
+       }
+
+       public function applyFilters($sender, $param) {
+               $time = $this->DatePicker->getDate() . ' 00:00:00';
+               $this->setTime($time);
+
+               $days = intval($this->Days->Text);
+               $this->setDays($days);
+
+               if ($this->getShowClientFilter()) {
+                       $this->setClient($this->Client->SelectedValue);
+               }
+
+               if ($this->getShowScheduleFilter()) {
+                       $this->setSchedule($this->Schedule->SelectedValue);
+               }
+
+               $this->loadSchedules();
+       }
+
+       public function setJob($job) {
+               $this->setViewState(self::JOB, $job);
+       }
+
+       public function getJob() {
+               return $this->getViewState(self::JOB);
+       }
+
+
+       public function setClient($client) {
+               $this->setViewState(self::CLIENT, $client);
+       }
+
+       public function getClient() {
+               return $this->getViewState(self::CLIENT);
+       }
+
+       public function setSchedule($schedule) {
+               $this->setViewState(self::SCHEDULE, $schedule);
+       }
+
+       public function getSchedule() {
+               return $this->getViewState(self::SCHEDULE);
+       }
+
+       public function setDays($days) {
+               $this->setViewState(self::DAYS, $days);
+       }
+
+       public function getDays() {
+               return $this->getViewState(self::DAYS);
+       }
+
+       public function setLimit($limit) {
+               $this->setViewState(self::LIMIT, $limit);
+       }
+
+       public function getLimit() {
+               return $this->getViewState(self::LIMIT);
+       }
+
+       public function setTime($time) {
+               $this->setViewState(self::TIME, $time);
+       }
+
+       public function getTime() {
+               return $this->getViewState(self::TIME);
+       }
+
+       public function setShowClientFilter($show) {
+               $show = TPropertyValue::ensureBoolean($show);
+               $this->setViewState(self::SHOW_CLIENT_FILTER, $show);
+       }
+
+       public function getShowClientFilter() {
+               return $this->getViewState(self::SHOW_CLIENT_FILTER, false);
+       }
+
+       public function setShowScheduleFilter($show) {
+               $show = TPropertyValue::ensureBoolean($show);
+               $this->setViewState(self::SHOW_SCHEDULE_FILTER, $show);
+       }
+
+       public function getShowScheduleFilter() {
+               return $this->getViewState(self::SHOW_SCHEDULE_FILTER, false);
+       }
+}
+?>
diff --git a/gui/baculum/protected/Web/Portlets/StatusSchedule.tpl b/gui/baculum/protected/Web/Portlets/StatusSchedule.tpl
new file mode 100644 (file)
index 0000000..883d599
--- /dev/null
@@ -0,0 +1,191 @@
+<!-- Header -->
+<header class="w3-container">
+       <h5>
+               <b><i class="fa fa-clock"></i> <%[ Schedule status ]%></b>
+       </h5>
+</header>
+<div class="w3-container">
+       <div class="w3-card-4 w3-padding w3-margin-bottom">
+               <strong><%[ Filters: ]%></strong>
+                <%[ Date from: ]%> <com:TJuiDatePicker
+                       ID="DatePicker"
+                       Options.dateFormat="yy-mm-dd"
+                       Options.changeYear="true",
+                       Options.changeMonth="true"
+                       Options.showAnim="fold"
+                       Style.Width="100px"
+                       />
+               <com:TRequiredFieldValidator
+                       ValidationGroup="ScheduleFilters"
+                       ControlToValidate="DatePicker"
+                       Text="<%[ Field required. ]%>"
+                       Display="Dynamic"
+               />
+               <com:TRegularExpressionValidator
+                       ValidationGroup="ScheduleFilters"
+                       ControlToValidate="DatePicker"
+                       RegularExpression="\d{4}-\d{2}-\d{2}"
+                       Text="<%[ Invalid date format. ]%>"
+                       Display="Dynamic"
+               />
+               <%[ Days: ]%> <com:TTextBox
+                       ID="Days"
+                       Style.Width="50px"
+                       Text="90"
+               />
+               <com:TRequiredFieldValidator
+                       ValidationGroup="ScheduleFilters"
+                       ControlToValidate="Days"
+                       Text="<%[ Field required. ]%>"
+                       Display="Dynamic"
+               />
+               <com:TDataTypeValidator
+                       ValidationGroup="ScheduleFilters"
+                       ControlToValidate="Days"
+                       DataType="Integer"
+                       Text="<%[ You must enter an integer. ]%>"
+                       Display="Dynamic"
+               />
+               <com:TRangeValidator
+                       ValidationGroup="ScheduleFilters"
+                       ControlToValidate="Days"
+                       DataType="Integer"
+                       MinValue="1"
+                       MaxValue="1000"
+                       Text="<%[ Input must be between 1 and 1000. ]%>"
+                       Display="Dynamic"
+               />
+               <com:TLabel
+                       ID="ClientLabel"
+                       ForControl="Client"
+                       Text="<%[ Client: ]%>"
+               /> <com:TDropDownList
+                       ID="Client"
+                       Style.Width="150px"
+               />
+               <com:TLabel
+                       ID="ScheduleLabel"
+                       ForControl="Schedule"
+                       Text="<%[ Schedule: ]%>"
+               />
+                <com:TDropDownList
+                       ID="Schedule"
+                       Style.Width="150px"
+               />
+               <com:TActiveLinkButton
+                       ID="ApplyFilter"
+                       CausesValidation="true"
+                       ValidationGroup="ScheduleFilters"
+                       CssClass="w3-green w3-button w3-margin-left"
+                       OnClick="applyFilters"
+               >
+                       <i class="fa fa-check"></i> &nbsp;<%[ Apply filters ]%>
+               </com:TActiveLinkButton>
+       </div>
+       <table id="schedule_list" class="w3-table w3-striped w3-hoverable w3-white w3-margin-bottom" style="width: 100%">
+               <thead>
+                       <tr>
+                               <th></th>
+                               <th><%[ Level ]%></th>
+                               <th><%[ Type ]%></th>
+                               <th><%[ Priority ]%></th>
+                               <th><%[ Scheduled ]%></th>
+                               <%=empty($this->getJob()) ? '<th>' . Prado::localize('Job name') . '</th>': ''%>
+                               <th><%[ Client ]%></th>
+                               <th><%[ FileSet ]%></th>
+                               <th><%[ Schedule ]%></th>
+                       </tr>
+               </thead>
+               <tbody id="schedule_list_body">
+               </tbody>
+       </table>
+</div>
+<script type="text/javascript">
+var oJobScheduleList = {
+       table: null,
+       data: <%=json_encode($this->schedules)%>,
+       ids: {
+               schedule_list: 'schedule_list',
+               schedule_list_body: 'schedule_list_body'
+       },
+       init: function() {
+               this.set_table();
+       },
+       set_data(data) {
+               data = JSON.parse(data);
+               this.data = data;
+       },
+       get_data(data) {
+               return this.data;
+       },
+       set_table: function() {
+               this.table = $('#' + this.ids.schedule_list).DataTable({
+                       data: this.get_data(),
+                       deferRender: true,
+                       columns: [
+                               {
+                                       className: 'details-control',
+                                       orderable: false,
+                                       data: null,
+                                       defaultContent: '<button type="button" class="w3-button w3-blue"><i class="fa fa-angle-down"></i></button>'
+                               },
+                               {
+                                       data: 'level',
+                                       render: function(data, type, row) {
+                                               var ret;
+                                               if (!data) {
+                                                       ret = '-';
+                                               } else {
+                                                       ret = JobLevel.get_level(data);
+                                               }
+                                               return ret;
+                                       }
+                               },
+                               {
+                                       data: 'type',
+                                       render: function(data, type, row) {
+                                               return JobType.get_type(data);
+                                       }
+                               },
+                               {data: 'priority'},
+                               {
+                                       data: 'schedtime_epoch',
+                                       render: function(data, type, row) {
+                                               return Units.format_date(data);
+                                       }
+                               },
+                               <%=empty($this->getJob()) ? '{data: "name"},' : ''%>
+                               {data: 'client'},
+                               {data: 'fileset'},
+                               {data: 'schedule'}
+                       ],
+                       responsive: {
+                               details: {
+                                       type: 'column'
+                               }
+                       },
+                       columnDefs: [{
+                               className: 'control',
+                               orderable: false,
+                               targets: 0
+                       },
+                       {
+                               className: "dt-center",
+                               targets: [ 1, 3 ]
+                       }],
+                       order: [4, 'asc']
+               });
+       }
+};
+
+function set_job_schedule_data(data) {
+       oJobScheduleList.set_data(data);
+}
+function init_job_schedule() {
+       if (oJobScheduleList.table) {
+               oJobScheduleList.table.destroy();
+       }
+       oJobScheduleList.init();
+}
+<%=count($this->schedules) > 0 ? 'init_job_schedule();' : ''%>
+</script>
index 4a2d2729a915cd6c3ae9b5ec37495d07868f2943..26684cbc70f66787d01ddd3d7dab86c433a923e9 100644 (file)
@@ -20,6 +20,7 @@
        <url ServiceParameter="FileSetList" pattern="web/fileset/" />
        <url ServiceParameter="FileSetView" pattern="web/fileset/{fileset}/" parameters.fileset="[a-zA-Z0-9:.\-_ ]+" />
        <url ServiceParameter="ScheduleList" pattern="web/schedule/" />
+       <url ServiceParameter="ScheduleStatusList" pattern="web/schedule/status/" />
        <url ServiceParameter="ScheduleView" pattern="web/schedule/{schedule}/" parameters.schedule="[a-zA-Z0-9:.\-_ ]+" />
        <url ServiceParameter="Graphs" pattern="web/graphs/" />
        <url ServiceParameter="Console" pattern="web/console/" />