From: Marcin Haba Date: Sun, 1 Nov 2020 04:42:04 +0000 (+0100) Subject: baculum: Add graphs to job view page X-Git-Tag: Release-9.6.7~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0fa11011c261cd228ae11c9c6980bcb25c7fe7fb;p=thirdparty%2Fbacula.git baculum: Add graphs to job view page There also have been changed: - Fix selecting pool for copy or migrate jobs running from job history page by 'Run job again' job button - Unified getting information about job from show job output - Improved pie graphs look --- diff --git a/gui/baculum/protected/Web/Class/JobInfo.php b/gui/baculum/protected/Web/Class/JobInfo.php new file mode 100644 index 000000000..5da6ba8d4 --- /dev/null +++ b/gui/baculum/protected/Web/Class/JobInfo.php @@ -0,0 +1,72 @@ + + * @category Module + * @package Baculum Web + */ +class JobInfo extends WebModule { + + const RESOURCE_PATTERN = '/(?P\S+(?=:))?:?(\s+((?P\S+)=(?P[\s\S]*?(?=\s\S+=.+|$))))/'; + + public function parseResourceDirectives(array $show_out) { + $result = []; + $resource = []; + $res = null; + for ($i = 1; $i < count($show_out); $i++) { + if (preg_match_all(self::RESOURCE_PATTERN, $show_out[$i], $match) > 0) { + if (!empty($match['resource'][0])) { + if (count($resource) == 1) { + /** + * Check key to not overwrite already existing resource + * because in some cases there can be for example two + * Autochanger resources: one from Pool and second from NextPool. + */ + if (!key_exists($res, $result)) { + $result = array_merge($result, $resource); + } + $resource = []; + } + $res = strtolower($match['resource'][0]); + } + if (!key_exists($res, $resource)) { + $resource[$res] = []; + } + for ($j = 0; $j < count($match['directive']); $j++) { + $directive = strtolower($match['directive'][$j]); + $value = $match['value'][$j]; + $resource[$res][$directive] = $value; + } + } + } + if (count($resource) == 1) { + $result = array_merge($result, $resource); + } + return $result; + } +} +?> diff --git a/gui/baculum/protected/Web/JavaScript/graph.js b/gui/baculum/protected/Web/JavaScript/graph.js index 9e6063299..e4655ea6f 100644 --- a/gui/baculum/protected/Web/JavaScript/graph.js +++ b/gui/baculum/protected/Web/JavaScript/graph.js @@ -1238,13 +1238,14 @@ var GraphPieClass = jQuery.klass({ series: null, pie: null, graph_options: { - colors: ['#63c422', '#d70808', '#FFFF66', 'orange', 'blue'], + colors: ['#63c422', '#d70808', '#FFFF66', 'orange', '#2980B9'], HtmlText: false, fontColor: '#000000', grid: { verticalLines : false, horizontalLines : false, outlineWidth: 0, + color: 'black' }, xaxis: { showLabels : false,}, yaxis: { showLabels : false }, @@ -1253,7 +1254,6 @@ var GraphPieClass = jQuery.klass({ explode : 6, labelFormatter: PieGraph.pie_label_formatter, shadowSize: 4, - fillOpacity: 1, sizeRatio: 0.77 }, mouse: { @@ -1268,9 +1268,10 @@ var GraphPieClass = jQuery.klass({ margin: 0 } }, - initialize: function(jobs, container_id) { - this.jobs = jobs; - this.container = document.getElementById(container_id); + initialize: function(prop) { + this.jobs = prop.jobs; + this.title = prop.hasOwnProperty('title') ? prop.title : null; + this.container = document.getElementById(prop.container_id); this.series = this.prepare_series(); this.draw_grah(); }, @@ -1284,14 +1285,21 @@ var GraphPieClass = jQuery.klass({ jobs_count = this.jobs[label].length; serie = { data: [[0, jobs_count]], - label: label + ' (' + jobs_count.toString() + ')' + label: label + ' (' + jobs_count.toString() + ')', + pie: { + explode: 12 + } } series.push(serie); } return series; }, draw_grah: function() { - this.pie = Flotr.draw(this.container, this.series, this.graph_options); + var graph_options = $.extend({}, this.graph_options); + if (this.title) { + graph_options.title = this.title; + } + this.pie = Flotr.draw(this.container, this.series, graph_options); } }); diff --git a/gui/baculum/protected/Web/JavaScript/misc.js b/gui/baculum/protected/Web/JavaScript/misc.js index 1bca58b07..2f429f1ff 100644 --- a/gui/baculum/protected/Web/JavaScript/misc.js +++ b/gui/baculum/protected/Web/JavaScript/misc.js @@ -797,7 +797,10 @@ var Dashboard = { if (this.pie != null) { this.pie.pie.destroy(); } - this.pie = new GraphPieClass(this.stats.jobs_summary, this.ids.pie_summary); + this.pie = new GraphPieClass({ + jobs: this.stats.jobs_summary, + container_id: this.ids.pie_summary + }); } } diff --git a/gui/baculum/protected/Web/Lang/en/messages.mo b/gui/baculum/protected/Web/Lang/en/messages.mo index 9a2a56d63..6d79dd373 100644 Binary files a/gui/baculum/protected/Web/Lang/en/messages.mo and b/gui/baculum/protected/Web/Lang/en/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/en/messages.po b/gui/baculum/protected/Web/Lang/en/messages.po index 11ee4e799..9992452e5 100644 --- a/gui/baculum/protected/Web/Lang/en/messages.po +++ b/gui/baculum/protected/Web/Lang/en/messages.po @@ -3082,3 +3082,6 @@ msgstr "saved" msgid "deleted" msgstr "deleted" + +msgid "last %days days" +msgstr "last %days days" diff --git a/gui/baculum/protected/Web/Lang/ja/messages.mo b/gui/baculum/protected/Web/Lang/ja/messages.mo index 1bc58cd09..9f73d7e32 100644 Binary files a/gui/baculum/protected/Web/Lang/ja/messages.mo and b/gui/baculum/protected/Web/Lang/ja/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/ja/messages.po b/gui/baculum/protected/Web/Lang/ja/messages.po index 72415e820..da88b94b5 100644 --- a/gui/baculum/protected/Web/Lang/ja/messages.po +++ b/gui/baculum/protected/Web/Lang/ja/messages.po @@ -3168,3 +3168,6 @@ msgstr "saved" msgid "deleted" msgstr "deleted" + +msgid "last %days days" +msgstr "last %days days" diff --git a/gui/baculum/protected/Web/Lang/pl/messages.mo b/gui/baculum/protected/Web/Lang/pl/messages.mo index 12b8c083d..c9aeb04ec 100644 Binary files a/gui/baculum/protected/Web/Lang/pl/messages.mo and b/gui/baculum/protected/Web/Lang/pl/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/pl/messages.po b/gui/baculum/protected/Web/Lang/pl/messages.po index 5b593d85f..23e644bef 100644 --- a/gui/baculum/protected/Web/Lang/pl/messages.po +++ b/gui/baculum/protected/Web/Lang/pl/messages.po @@ -3093,3 +3093,6 @@ msgstr "zapisany" msgid "deleted" msgstr "skasowany" + +msgid "last %days days" +msgstr "ostatnie %days dni" diff --git a/gui/baculum/protected/Web/Lang/pt/messages.mo b/gui/baculum/protected/Web/Lang/pt/messages.mo index da0155da4..ac649390b 100644 Binary files a/gui/baculum/protected/Web/Lang/pt/messages.mo and b/gui/baculum/protected/Web/Lang/pt/messages.mo differ diff --git a/gui/baculum/protected/Web/Lang/pt/messages.po b/gui/baculum/protected/Web/Lang/pt/messages.po index 2154506f1..c0bee3ad9 100644 --- a/gui/baculum/protected/Web/Lang/pt/messages.po +++ b/gui/baculum/protected/Web/Lang/pt/messages.po @@ -3092,3 +3092,6 @@ msgstr "saved" msgid "deleted" msgstr "deleted" + +msgid "last %days days" +msgstr "last %days days" diff --git a/gui/baculum/protected/Web/Pages/JobHistoryList.php b/gui/baculum/protected/Web/Pages/JobHistoryList.php index ffd20d02c..6fba287fb 100644 --- a/gui/baculum/protected/Web/Pages/JobHistoryList.php +++ b/gui/baculum/protected/Web/Pages/JobHistoryList.php @@ -36,6 +36,8 @@ class JobHistoryList extends BaculumWebPage { const USE_CACHE = true; + const DEFAULT_JOB_PRIORITY = 10; + public function loadRunJobModal($sender, $param) { $this->RunJobModal->loadData(); } @@ -54,26 +56,35 @@ class JobHistoryList extends BaculumWebPage { $level = trim($jobdata->level); $params['level'] = !empty($level) ? $level : 'F'; // Admin job has empty level $job_show = $this->getModule('api')->get( - array('jobs', $jobid, 'show'), null, true, self::USE_CACHE + ['jobs', $jobid, 'show'], + null, + true, + self::USE_CACHE )->output; + $job_info = $this->getModule('job_info')->parseResourceDirectives($job_show); if ($jobdata->filesetid > 0) { $params['filesetid'] = $jobdata->filesetid; } else { - $params['fileset'] = RunJob::getResourceName('fileset', $job_show); + $params['fileset'] = key_exists('fileset', $job_info) ? $job_info['fileset']['name'] : ''; } $params['clientid'] = $jobdata->clientid; - $params['storage'] = RunJob::getResourceName('storage', $job_show); - if (empty($params['storage'])) { - $params['storage'] = RunJob::getResourceName('autochanger', $job_show); - } - if ($jobdata->poolid > 0) { + $storage = key_exists('storage', $job_info) ? $job_info['storage']['name'] : null; + $autochanger = key_exists('autochanger', $job_info) ? $job_info['autochanger']['name'] : null; + $params['storage'] = $storage ?: $autochanger; + + /** + * For 'c' type (Copy Job) and 'g' type (Migration Job) the in job table in poolid property is written + * write pool, not read pool. Here in 'pool' property is set read pool and from this reason for 'c' + * and 'g' types the pool cannot be taken from job table. + */ + if ($jobdata->poolid > 0 && $jobdata->type != 'c' && $jobdata->type != 'g') { $params['poolid'] = $jobdata->poolid; } else { - $params['pool'] = RunJob::getResourceName('pool', $job_show); + $params['pool'] = key_exists('pool', $job_info) ? $job_info['pool']['name'] : ''; } - $job_attr = RunJob::getJobAttr($job_show); - $params['priority'] = key_exists('priority', $job_attr) ? $job_attr['priority'] : 10; - $params['accurate'] = (key_exists('accurate', $job_attr) && $job_attr['accurate'] == 1); + $params['priority'] = key_exists('job', $job_info) ? $job_info['job']['priority'] : self::DEFAULT_JOB_PRIORITY; + $accurate = key_exists('job', $job_info) && key_exists('accurate', $job_info['job']) ? $job_info['job']['accurate'] : 0; + $params['accurate'] = ($accurate == 1); $result = $this->getModule('api')->create(array('jobs', 'run'), $params); if ($result->error === 0) { diff --git a/gui/baculum/protected/Web/Pages/JobHistoryView.php b/gui/baculum/protected/Web/Pages/JobHistoryView.php index b9cadaad8..0d9f9eefa 100644 --- a/gui/baculum/protected/Web/Pages/JobHistoryView.php +++ b/gui/baculum/protected/Web/Pages/JobHistoryView.php @@ -42,14 +42,13 @@ class JobHistoryView extends BaculumWebPage { const JOB_LEVEL = 'JobLevel'; const JOB_TYPE = 'JobType'; const CLIENTID = 'ClientId'; + const JOB_INFO = 'JobInfo'; const USE_CACHE = true; const SORT_ASC = 0; const SORT_DESC = 1; - const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i'; - public $is_running = false; public $allow_graph_mode = false; public $allow_list_files_mode = false; @@ -91,9 +90,15 @@ class JobHistoryView extends BaculumWebPage { public function onInit($param) { parent::onInit($param); + $this->JobConfig->attachEventHandler('OnSave', [$this, 'reloadJobInfo']); + $job_name = $this->getJobName(); $this->RunJobModal->setJobId($this->getJobId()); - $this->RunJobModal->setJobName($this->getJobName()); + $this->RunJobModal->setJobName($job_name); $this->FileList->setJobId($this->getJobId()); + if ($this->IsCallBack || $this->IsPostBack) { + return; + } + $this->setJobInfo($job_name); } public function onLoad($param) { @@ -276,6 +281,45 @@ class JobHistoryView extends BaculumWebPage { return $this->getViewState(self::JOB_LEVEL); } + /** + * Set job information from show job output. + * + * @return none + */ + public function setJobInfo($job_name) { + $job_show = $this->getModule('api')->get( + array('jobs', 'show', '?name='. rawurlencode($job_name)), + null, + true, + false + ); + if ($job_show->error == 0) { + $job_info = $this->getModule('job_info')->parseResourceDirectives($job_show->output); + $this->setViewState(self::JOB_INFO, $job_info); + } + } + + /** + * Get job information. + * + * @return array job information + */ + public function getJobInfo() { + return $this->getViewState(self::JOB_INFO, []); + } + + + /** + * Reload job information. + * + * @param mixed $param save event parameter + * @return none + */ + public function reloadJobInfo($param) { + $job_name = $this->getJobName(); + $this->setJobInfo($job_name); + } + /** * Refresh job log page and load latest logs. * @@ -340,41 +384,27 @@ class JobHistoryView extends BaculumWebPage { } } - public 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; - } - public function loadFileSetConfig($sender, $param) { if (!empty($_SESSION['dir'])) { - $jobshow = $this->getModule('api')->get(array( - 'jobs', $this->getJobId(), 'show' - ))->output; - $fileset = $this->getResourceName('fileset', $jobshow); - $this->FileSetConfig->setComponentName($_SESSION['dir']); - $this->FileSetConfig->setResourceName($fileset); - $this->FileSetConfig->setLoadValues(true); - $this->FileSetConfig->raiseEvent('OnDirectiveListLoad', $this, null); + $job_info = $this->getJobInfo(); + if (key_exists('fileset', $job_info)) { + $this->FileSetConfig->setComponentName($_SESSION['dir']); + $this->FileSetConfig->setResourceName($job_info['fileset']['name']); + $this->FileSetConfig->setLoadValues(true); + $this->FileSetConfig->raiseEvent('OnDirectiveListLoad', $this, null); + } } } public function loadScheduleConfig($sender, $param) { if (!empty($_SESSION['dir'])) { - $jobshow = $this->getModule('api')->get(array( - 'jobs', $this->getJobId(), 'show' - ))->output; - $schedule = $this->getResourceName('schedule', $jobshow); - $this->ScheduleConfig->setComponentName($_SESSION['dir']); - $this->ScheduleConfig->setResourceName($schedule); - $this->ScheduleConfig->setLoadValues(true); - $this->ScheduleConfig->raiseEvent('OnDirectiveListLoad', $this, null); + $job_info = $this->getJobInfo(); + if (key_exists('schedule', $job_info)) { + $this->ScheduleConfig->setComponentName($_SESSION['dir']); + $this->ScheduleConfig->setResourceName($job_info['schedule']['name']); + $this->ScheduleConfig->setLoadValues(true); + $this->ScheduleConfig->raiseEvent('OnDirectiveListLoad', $this, null); + } } } diff --git a/gui/baculum/protected/Web/Pages/JobView.page b/gui/baculum/protected/Web/Pages/JobView.page index d390fab0c..8499094f1 100644 --- a/gui/baculum/protected/Web/Pages/JobView.page +++ b/gui/baculum/protected/Web/Pages/JobView.page @@ -41,13 +41,318 @@
<%=Prado::localize('Run job')%>   +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gui/baculum/protected/Web/Pages/JobView.php b/gui/baculum/protected/Web/Pages/JobView.php index d323f6519..470d386f5 100644 --- a/gui/baculum/protected/Web/Pages/JobView.php +++ b/gui/baculum/protected/Web/Pages/JobView.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2019 Kern Sibbald + * Copyright (C) 2013-2020 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -35,18 +35,11 @@ Prado::using('Application.Web.Class.BaculumWebPage'); class JobView extends BaculumWebPage { const JOB_NAME = 'JobName'; - - const USE_CACHE = true; - - const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i'; - - private $jobdata; - public $is_running = false; - public $fileset; - public $schedule; + const JOB_INFO = 'JobInfo'; public function onInit($param) { parent::onInit($param); + $this->JobConfig->attachEventHandler('OnSave', [$this, 'reloadJobInfo']); if ($this->IsCallBack || $this->IsPostBack) { return; } @@ -58,6 +51,7 @@ class JobView extends BaculumWebPage { $this->setJobName($job_name); $this->Schedules->setJob($job_name); $this->Schedules->setDays(90); + $this->setJobInfo($job_name); } /** @@ -78,6 +72,45 @@ class JobView extends BaculumWebPage { return $this->getViewState(self::JOB_NAME); } + /** + * Set job information from show job output. + * + * @return none + */ + public function setJobInfo($job_name) { + $job_show = $this->getModule('api')->get( + array('jobs', 'show', '?name='. rawurlencode($job_name)), + null, + true, + false + ); + if ($job_show->error == 0) { + $job_info = $this->getModule('job_info')->parseResourceDirectives($job_show->output); + $this->setViewState(self::JOB_INFO, $job_info); + } + } + + /** + * Get job information. + * + * @return array job information + */ + public function getJobInfo() { + return $this->getViewState(self::JOB_INFO, []); + } + + /** + * Reload job information. + * + * @param mixed $param save event parameter + * @return none + */ + public function reloadJobInfo($param) { + if ($this->Request->contains('job')) { + $this->setJobInfo($this->Request['job']); + } + } + public function loadRunJobModal($sender, $param) { $this->RunJobModal->loadData(); } @@ -91,41 +124,29 @@ class JobView extends BaculumWebPage { } } - public 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; - } - public function loadFileSetConfig($sender, $param) { if (!empty($_SESSION['dir'])) { - $jobshow = $this->getModule('api')->get(array( - 'jobs', 'show', '?name=' . rawurlencode($this->getJobName()) - ))->output; - $fileset = $this->getResourceName('fileset', $jobshow); - $this->FileSetConfig->setComponentName($_SESSION['dir']); - $this->FileSetConfig->setResourceName($fileset); - $this->FileSetConfig->setLoadValues(true); - $this->FileSetConfig->raiseEvent('OnDirectiveListLoad', $this, null); + $job_info = $this->getJobInfo(); + if (key_exists('fileset', $job_info)) { + $this->FileSetConfig->setComponentName($_SESSION['dir']); + $this->FileSetConfig->setResourceName($job_info['fileset']['name']); + $this->FileSetConfig->setLoadValues(true); + $this->FileSetConfig->raiseEvent('OnDirectiveListLoad', $this, null); + } } } public function loadScheduleConfig($sender, $param) { if (!empty($_SESSION['dir'])) { - $jobshow = $this->getModule('api')->get(array( - 'jobs', 'show', '?name=' . rawurlencode($this->getJobName()) - ))->output; - $schedule = $this->getResourceName('schedule', $jobshow); - $this->ScheduleConfig->setComponentName($_SESSION['dir']); - $this->ScheduleConfig->setResourceName($schedule); - $this->ScheduleConfig->setLoadValues(true); - $this->ScheduleConfig->raiseEvent('OnDirectiveListLoad', $this, null); + $job_info = $this->getJobInfo(); + if (key_exists('schedule', $job_info)) { + $this->ScheduleConfig->setComponentName($_SESSION['dir']); + $this->ScheduleConfig->setResourceName($job_info['schedule']['name']); + $this->ScheduleConfig->setLoadValues(true); + $this->ScheduleConfig->raiseEvent('OnDirectiveListLoad', $this, null); + } else { + $this->ScheduleConfig->unloadDirectives(); + } } } diff --git a/gui/baculum/protected/Web/Pages/config.xml b/gui/baculum/protected/Web/Pages/config.xml index 5a9b90eb6..242e85334 100644 --- a/gui/baculum/protected/Web/Pages/config.xml +++ b/gui/baculum/protected/Web/Pages/config.xml @@ -25,5 +25,7 @@ + + diff --git a/gui/baculum/protected/Web/Portlets/RunJob.php b/gui/baculum/protected/Web/Portlets/RunJob.php index 006e25594..1e3a0aaf0 100644 --- a/gui/baculum/protected/Web/Portlets/RunJob.php +++ b/gui/baculum/protected/Web/Portlets/RunJob.php @@ -44,10 +44,6 @@ class RunJob extends Portlets { const USE_CACHE = true; - const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i'; - const JOB_SHOW_PATTERN = '/^Job:\sname=(?P.+)\sJobType=\d+\slevel=(?P\w+)?\sPriority=(?P\d+)/i'; - const ACCURATE_PATTERN = '/^\s+Accurate=(?P\d)/i'; - const DEFAULT_JOB_PRIORITY = 10; public $job_to_verify = array('C', 'O', 'd', 'A'); @@ -58,15 +54,36 @@ class RunJob extends Portlets { $jobid = $this->getJobId(); $jobname = $this->getJobName(); $jobdata = null; + $job_info = []; + if ($jobid > 0) { - $jobdata = $this->getModule('api')->get(array('jobs', $jobid), null, true, self::USE_CACHE)->output; + $jobdata = $this->getModule('api')->get( + ['jobs', $jobid], + null, + true, + self::USE_CACHE + ); + if ($jobdata->error == 0) { + $jobname = $jobdata->name; + } + } + + if (!empty($jobname)) { $job_show = $this->getModule('api')->get( - array('jobs', 'show', '?name='. rawurlencode($jobdata->name)), + ['jobs', 'show', '?name='. rawurlencode($jobname)], null, true, self::USE_CACHE - )->output; - $jobdata->storage = $this->getResourceName('(?:storage|autochanger)', $job_show); + ); + if ($job_show->error == 0) { + $job_info = $this->getModule('job_info')->parseResourceDirectives($job_show->output); + } + } + + if ($jobid > 0) { + $storage = key_exists('storage', $job_info) ? $job_info['storage']['name'] : null; + $autochanger = key_exists('autochanger', $job_info) ? $job_info['autochanger']['name'] : null; + $jobdata->storage = $storage ?: $autochanger; $this->getPage()->getCallbackClient()->show('run_job_storage_from_config_info'); } elseif (!empty($jobname)) { $jobdata = new stdClass; @@ -78,17 +95,23 @@ class RunJob extends Portlets { )->output; $levels = $this->getModule('misc')->getJobLevels(); $levels_flip = array_flip($levels); - $job_attr = $this->getJobAttr($job_show); - if (!empty($job_attr['level'])) { - $jobdata->level = $levels_flip[$job_attr['level']]; + if (key_exists('job', $job_info) && !empty($job_info['job']['level'])) { + $jobdata->level = $levels_flip[$job_info['job']['level']]; } - $jobdata->client = $this->getResourceName('client', $job_show); - $jobdata->fileset = $this->getResourceName('fileset', $job_show); - $jobdata->pool = $this->getResourceName('pool', $job_show); - $jobdata->storage = $this->getResourceName('(?:storage|autochanger)', $job_show); - $jobdata->priorjobid = $job_attr['priority']; - $jobdata->accurate = (key_exists('accurate', $job_attr) && $job_attr['accurate'] == 1); + $client = key_exists('client', $job_info) ? $job_info['client']['name'] : null; + $fileset = key_exists('fileset', $job_info) ? $job_info['fileset']['name'] : null; + $pool = key_exists('pool', $job_info) ? $job_info['pool']['name'] : null; + $storage = key_exists('storage', $job_info) ? $job_info['storage']['name'] : null; + $autochanger = key_exists('autochanger', $job_info) ? $job_info['autochanger']['name'] : null; + $priority = key_exists('job', $job_info) ? $job_info['job']['priority'] : self::DEFAULT_JOB_PRIORITY; + $accurate = key_exists('job', $job_info) && key_exists('accurate', $job_info['job']) ? $job_info['job']['accurate'] : 0; + $jobdata->client = $client; + $jobdata->fileset = $fileset; + $jobdata->pool = $pool; + $jobdata->storage = $storage ?: $autochanger; + $jobdata->priorjobid = $priority; + $jobdata->accurate = ($accurate == 1); } else { $jobs = array(); $job_list = $this->getModule('api')->get(array('jobs', 'resnames'), null, true, self::USE_CACHE)->output; @@ -280,35 +303,6 @@ class RunJob extends Portlets { return $verifyVals; } - public 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; - } - - public function getJobAttr($jobshow) { - $attr = array(); - for ($i = 0; $i < count($jobshow); $i++) { - if (preg_match(self::JOB_SHOW_PATTERN, $jobshow[$i], $match) === 1) { - $attr['jobname'] = $match['jobname']; - $attr['level'] = $match['level']; - $attr['priority'] = $match['priority']; - } - if (preg_match(self::ACCURATE_PATTERN, $jobshow[$i], $match) === 1) { - $attr['accurate'] = $match['accurate']; - break; - } - } - return $attr; - } - - public function estimate($sender, $param) { $params = array(); $jobid = $this->getJobId(); diff --git a/gui/baculum/themes/Baculum-v2/css/baculum.css b/gui/baculum/themes/Baculum-v2/css/baculum.css index c8a6550f8..1da9320d3 100644 --- a/gui/baculum/themes/Baculum-v2/css/baculum.css +++ b/gui/baculum/themes/Baculum-v2/css/baculum.css @@ -8,10 +8,6 @@ z-index: 0; } -#jobs_summary_graph canvas:nth-child(2) { - position: static !important; -} - .monospace { font-family: "Courier New", Courier, monospace !important; } @@ -432,3 +428,13 @@ table.component td:nth-of-type(1) { .field_invalid { border: 1px solid red !important; } + +#job_graph_container { + display: flex; + flex-wrap: wrap; +} + +#job_graph_container > div { + width: 420px; + margin: 10px; +}