1<?php 2 3/** 4 * 5 * bareos-webui - Bareos Web-Frontend 6 * 7 * @link https://github.com/bareos/bareos for the canonical source repository 8 * @copyright Copyright (c) 2013-2017 Bareos GmbH & Co. KG (http://www.bareos.org/) 9 * @license GNU Affero General Public License (http://www.gnu.org/licenses/) 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Affero General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Affero General Public License for more details. 20 * 21 * You should have received a copy of the GNU Affero General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 * 24 */ 25 26$title = 'Jobs'; 27$this->headTitle($title); 28 29?> 30 31<ul class="nav nav-tabs"> 32 <li class="active"><a href="<?php echo $this->url('job', array('action'=>'index')); ?>"><?php echo $this->translate('Show'); ?></a></li> 33 <li><a href="<?php echo $this->url('job', array('action'=>'actions')); ?>"><?php echo $this->translate('Actions'); ?></a></li> 34 <li><a href="<?php echo $this->url('job', array('action'=>'run')); ?>"><?php echo $this->translate('Run'); ?></a></li> 35</ul> 36 37<br /> 38 39<?php if($this->acl_alert) : echo $this->ACLAlert($this->invalid_commands); elseif(!$this->acl_alert) : ?> 40 41<div class="row"> 42 43<div class="col-md-2"> 44 <?php echo $this->formRow($form->get('jobname')); ?> 45</div> 46 47<div class="col-md-2"> 48 <?php echo $this->formRow($form->get('period')); ?> 49</div> 50 51<div class="col-md-2"> 52 <?php echo $this->formRow($form->get('status')); ?> 53</div> 54 55</div> 56 57<br /> 58 59<div class="row"> 60 61<div class="col-md-12"> 62 63<div class="panel panel-default"> 64 65<div class="panel-heading"> 66<h3 class="panel-title"><?php echo $this->translate('Job list'); ?></h3> 67</div> 68 69<div class="panel-body"> 70 71<table class="table table-no-bordered table-hover" id="jobtable"> 72 73<thead class="bg-primary"> 74 <th><?php echo $this->translate("Job ID"); ?></th> 75 <th><?php echo $this->translate("Job name"); ?></th> 76 <th><?php echo $this->translate("Client"); ?></th> 77 <th><?php echo $this->translate("Type"); ?></th> 78 <th><?php echo $this->translate("Level"); ?></th> 79 <th><?php echo $this->translate("Files"); ?></th> 80 <th><?php echo $this->translate("Bytes"); ?></th> 81 <th><?php echo $this->translate("Errors"); ?></th> 82 <th><?php echo $this->translate("Status"); ?></th> 83 <th><?php echo $this->translate("Actions"); ?></th> 84</thead> 85 86</table> 87 88</div> 89</div> 90</div> 91</div> 92 93<?php 94 echo $this->headScript()->prependFile($this->basePath() . '/js/custom-functions.js'); 95 echo $this->headLink()->prependStylesheet($this->basePath() . '/css/bootstrap-table.min.css'); 96 echo $this->headScript()->prependFile($this->basePath() . '/js/bootstrap-table-locale-all.min.js'); 97 echo $this->headScript()->prependFile($this->basePath() . '/js/bootstrap-table-cookie.min.js'); 98 echo $this->headScript()->prependFile($this->basePath() . '/js/bootstrap-table.min.js'); 99?> 100 101<!-- modal-001 start --> 102<div id="modal-001" class="modal fade modal-001" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel"> 103 <div class="modal-dialog modal-md"> 104 <div class="modal-content"> 105 <div class="modal-header"> 106 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> 107 <h4 class="modal-title" id="myModalLabel"><?php echo $this->translate("Failed to retrieve data from Bareos director"); ?></h4> 108 </div> 109 <div class="modal-body"> 110 <p><?php echo $this->translate("Please try to reduce the amount of data to display, e.g. reduce time period."); ?></p> 111 <p><?php echo $this->translate("Error message received from director:"); ?></p> 112 <p class="text-danger"><?php echo $this->translate("Failed to send result as json. Maybe the result message is too long?"); ?></p> 113 </div> 114 <div class="modal-footer"> 115 <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo $this->translate("Close"); ?></button> 116 </div> 117 </div> 118 </div> 119</div> 120<!-- modal-001 end --> 121 122<!-- modal-002 start --> 123<div id="modal-002" class="modal fade modal-002" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel"> 124 <div class="modal-dialog modal-md"> 125 <div class="modal-content"> 126 <div class="modal-header"> 127 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 128 <span aria-hidden="true">×</span> 129 </button> 130 <h4 class="modal-title" id="myModalLabel">Director message</h4> 131 </div> 132 <div class="modal-body"> 133 <p><?php echo str_replace(array("\n","\r"), "<br />", $this->result); ?></p> 134 </div> 135 <div class="modal-footer"> 136 <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo $this->translate("Close"); ?></button> 137 </div> 138 </div> 139 </div> 140</div> 141<!-- modal-002 end --> 142 143<script> 144 145 var jobtable = null; 146 147 function detailFormatter(index, row) { 148 var html = []; 149 html.push('<div class="container-fluid">'); 150 html.push('<table class="table table-bordered">'); 151 html.push('<tr>'); 152 html.push('<th><?php echo addslashes($this->translate("Fileset")); ?></th>'); 153 html.push('<td><a href="<?php echo $this->basePath() . '/fileset/details/'; ?>' + row.filesetid + '">' + row.fileset +'</a></td>'); 154 html.push('</tr>'); 155 html.push('<tr>'); 156 html.push('<th><?php echo addslashes($this->translate("Pool")); ?></th>'); 157 html.push('<td><a href="<?php echo $this->basePath() . '/pool/details/'; ?>' + row.poolname + '">' + row.poolname + '</a></td>'); 158 html.push('</tr>'); 159 html.push('<tr>'); 160 html.push('<th><?php echo addslashes($this->translate("Scheduled")); ?></th>'); 161 html.push('<td>' + row.schedtime + '</td>'); 162 html.push('</tr>'); 163 html.push('<tr>'); 164 html.push('<th><?php echo $this->translate("Start"); ?></th>'); 165 html.push('<td>' + row.starttime + '</td>'); 166 html.push('</tr>'); 167 html.push('<tr>'); 168 html.push('<th><?php echo $this->translate("End"); ?></th>'); 169 html.push('<td>' + row.endtime + '</td>'); 170 html.push('</tr>'); 171 html.push('</table>'); 172 html.push('</div>'); 173 return html.join(''); 174 } 175 176 function getJobs() { 177 jobtable = $('#jobtable').bootstrapTable({ 178 locale: '<?php echo str_replace('_','-', $_SESSION['bareos']['locale']); ?>', 179 cookie: <?php echo $_SESSION['bareos']['dt_statesave']; ?>, 180 cookieIdTable: 'dashboard_table_jobs_last_status', 181 url: '<?php echo $this->url('job', array('action' => 'getData'), null) . '?data=jobs&jobname='.$this->jobname.'&status='.$this->status.'&period='.$this->period; ?>', 182 method: 'get', 183 dataType: 'json', 184 pagination : true, 185 sidePagination: 'client', 186 pageList: [ <?php echo $_SESSION['bareos']['dt_lengthmenu']; ?> ], 187 pageSize: <?php echo $_SESSION['bareos']['dt_pagelength']; ?>, 188 search: true, 189 showPaginationSwitch: true, 190 showColumns: true, 191 showRefresh: true, 192 sortName: 'jobid', 193 sortOrder: 'desc', 194 detailView: true, 195 detailFormatter: 'detailFormatter', 196 columns: [ 197 { 198 field: 'jobid', 199 sortable: true, 200 formatter: function(value) { 201 return '<a href="<?php echo $this->basePath() . '/job/details/'; ?>'+value+'" title="<?php echo $this->translate("View Job Details"); ?>">'+value+'</a>'; 202 } 203 }, 204 { 205 field: 'name', 206 sortable: true, 207 formatter: function(value) { 208 return '<a href="<?php echo $this->basePath() . '/job/index?jobname='; ?>'+value+'">'+value+'</a>'; 209 } 210 }, 211 { 212 field: 'client', 213 sortable: true, 214 formatter: function(value) { 215 return '<a href="<?php echo $this->basePath() . '/client/details/'; ?>'+value+'">'+value+'</a>'; 216 } 217 }, 218 { 219 field: 'type', 220 sortable: true, 221 formatter: function(value) { 222 return formatJobType(value); 223 } 224 }, 225 { 226 field: 'level', 227 sortable: true, 228 formatter: function(value) { 229 return formatJobLevel(value); 230 } 231 }, 232 { 233 field: 'jobfiles', 234 sortable: true, 235 }, 236 { 237 field: 'jobbytes', 238 sortable: true, 239 formatter: function(value) { 240 return formatBytes(value); 241 } 242 }, 243 { 244 field: 'joberrors', 245 sortable: true, 246 }, 247 { 248 field: 'jobstatus', 249 sortable: true, 250 formatter: function(value) { 251 return formatJobStatus(value); 252 } 253 }, 254 { 255 field: 'action', 256 formatter: function(value, row, index) { 257 switch(row.jobstatus) { 258 case 'T': 259 case 'W': 260 switch(row.type) { 261 case 'B': 262 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath() . '/job/index?action=rerun&jobid='; ?>'+row.jobid+'" title="<?php echo $this->translate("Rerun"); ?>" id="btn-1"><span class="glyphicon glyphicon-repeat"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath(); ?>/restore/?mergefilesets=1&mergejobs=1&client='+row.client+'&jobid='+row.jobid+'" title="<?php echo $this->translate("Restore"); ?>" id="btn-1"><span class="glyphicon glyphicon-import"></span></a>'; 263 case 'C': 264 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath(); ?>/restore/?mergefilesets=1&mergejobs=1&client='+row.client+'&jobid='+row.jobid+'" title="<?php echo $this->translate("Restore"); ?>" id="btn-1"><span class="glyphicon glyphicon-import"></span></a>'; 265 } 266 case 'E': 267 case 'e': 268 case 'f': 269 case 'A': 270 switch(row.type) { 271 case 'B': 272 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath() . '/job/index?action=rerun&jobid='; ?>'+row.jobid+'" title="<?php echo $this->translate("Rerun"); ?>" id="btn-1"><span class="glyphicon glyphicon-repeat"></span></a>'; 273 } 274 case 'F': 275 case 'S': 276 case 'm': 277 case 'M': 278 case 's': 279 case 'j': 280 case 'c': 281 case 'd': 282 case 't': 283 case 'p': 284 case 'q': 285 case 'C': 286 case 'R': 287 case 'l': 288 switch(row.type) { 289 case 'R': 290 switch(row.jobstatus) { 291 case 'R': 292 case 'l': 293 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath() . '/job/cancel/'; ?>'+row.jobid+'" title="<?php echo $this->translate("Cancel"); ?>" id="btn-1"><span class="glyphicon glyphicon-trash"></span></a>'; 294 default: 295 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> '; 296 } 297 case 'B': 298 case 'C': 299 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> <a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath() . '/job/cancel/'; ?>'+row.jobid+'" title="<?php echo $this->translate("Cancel"); ?>" id="btn-1"><span class="glyphicon glyphicon-trash"></span></a>'; 300 default: 301 return '<a class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="top" href="<?php echo $this->basePath();?>/job/details/'+row.jobid+'" title="<?php echo $this->translate("View Job Details"); ?>" id="btn-0"><span class="glyphicon glyphicon-search"></span></a> '; 302 } 303 default: 304 return ''; 305 } 306 } 307 } 308 ] 309 }); 310 } 311 312 function updateQueryParams(k, v) { 313 var p = []; 314 var params = []; 315 316 p['jobname'] = '<?php echo $this->jobname; ?>'; 317 p['status'] = '<?php echo $this->status; ?>'; 318 p['period'] = '<?php echo $this->period; ?>'; 319 320 if(k == 'status' && v == 'running') { 321 p['period'] = 'all'; 322 } 323 else if(k == 'status' && v == 'waiting') { 324 p['period'] = 'all'; 325 } 326 327 p[k] = v; 328 329 for(key in p) { 330 params.push(key + "=" + p[key]); 331 } 332 333 return params.join('&'); 334 } 335 336 $(document).ready(function() { 337 setDtTextDomain('<?php echo $this->basePath() . '/js/locale'; ?>'); 338 setDtLocale('<?php echo $_SESSION['bareos']['locale']; ?>'); 339 340 var result = '<?php echo str_replace(array("\n","\r"), "", $this->result); ?>'; 341 342 if(result.length > 0) { 343 $("#modal-002").modal(); 344 } 345 346 getJobs(); 347 348 $('#jobname').change(function(event) { 349 window.location.href = window.location.pathname + '?' + updateQueryParams('jobname', this.value); 350 }); 351 352 $('#period').change(function(event) { 353 window.location.href = window.location.pathname + '?' + updateQueryParams('period', this.value); 354 }); 355 356 $('#status').change(function(event) { 357 window.location.href = window.location.pathname + '?' + updateQueryParams('status', this.value); 358 }); 359 360 $('#jobtable').on('load-error.bs.table', function(status, res) { 361 $("#modal-001").modal(); 362 }); 363 364 }); 365 366</script> 367 368<?php endif; ?> 369