5 [% PROCESS 'i18n.inc' %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>[% FILTER collapse %]
10 [% tx("Details of job #{job_id}", { job_id = job.id }) | html %] ›
12 [% t("Jobs") | html %] ›
13 [% t("Administration") | html %] ›
14 [% t("Koha") | html %]
17 [% INCLUDE 'doc-head-close.inc' %]
20 <body id="admin_background_jobs" class="admin">
21 [% WRAPPER 'header.inc' %]
22 [% INCLUDE 'prefs-admin-search.inc' %]
25 [% WRAPPER 'sub-header.inc' %]
26 [% WRAPPER breadcrumbs %]
27 [% IF CAN_user_parameters_manage_background_jobs %]
28 [% WRAPPER breadcrumb_item %]
29 <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
32 [% WRAPPER breadcrumb_item %]
33 <a href="/cgi-bin/koha/admin/background_jobs.pl">Jobs</a>
35 [% WRAPPER breadcrumb_item bc_active= 1 %]
36 <span>Details of job #[% job.id | html %]</span>
39 [% WRAPPER breadcrumb_item bc_active= 1 %]
44 [% WRAPPER breadcrumb_item bc_active= 1 %]
45 <span>Administration</span>
48 [% END #/ WRAPPER breadcrumbs %]
49 [% END #/ WRAPPER sub-header.inc %]
51 <div class="main container-fluid">
53 <div class="col-sm-10 col-sm-push-2">
55 [% INCLUDE 'messages.inc' %]
57 [% FOR m IN messages %]
58 <div class="dialog message">
60 [% CASE 'cannot_view_job' %]
61 <div><i class="fa fa-exclamation error"></i>Insufficient permission to see this job.</div>
69 <h1>Details of job #[% job.id | html %]</h1>
71 [% PROCESS "background_jobs/${job.type}.inc" %]
73 <div id="job_details" style="display:none">
74 <fieldset class="rows">
76 <li><span class="label">Job ID: </span>[% job.id | html %]</li>
78 <label for="job_status">Status: </label>
79 <span id="job_status_description"></span>
81 <li><label for="job_progress">Progress: </label>[% job.progress || 0 | html %] / [% job.size | html %]</li>
83 <label for="job_type">Type: </label>
84 <span id="job_type_description"></span>
87 <label for="job_enqueued_on">Queued: </label>
88 [% job.enqueued_on | $KohaDates with_hours = 1 %]
91 <label for="job_started_on">Started: </label>
92 [% job.started_on | $KohaDates with_hours = 1 %]
95 <label for="job_ended_on">Ended: </label>
96 [% job.ended_on | $KohaDates with_hours = 1 %]
100 <div class="page-section">
102 [% IF job.status != 'new' %][% PROCESS 'report' %][% END %]
104 <div class="page-section">
105 <h2>Detailed messages</h2>
106 [% IF job.status != 'new' %][% PROCESS 'detail' %][% END %]
108 </div> <!-- /#job_details -->
110 [% IF CAN_user_parameters_manage_background_jobs %]
111 <fieldset class="action">
112 <a href="/cgi-bin/koha/admin/background_jobs.pl">Return to the job list</a>
117 [% IF op == 'list' %]
122 <input type="checkbox" id="only_current" checked />
123 <label for="only_current">Current jobs only</label>
127 <input type="checkbox" id="include_last_hour" checked />
128 <label for="include_last_hour">Only include jobs enqueued in the last hour</label>
131 <div class="page-section">
132 <table id="table_jobs">
136 <th data-filter="job_statuses">Status</th>
138 <th data-filter="job_types">Type</th>
142 <th class="noExport">Actions</th>
150 </div> <!-- /.col-sm-10.col-sm-push-2 -->
152 <div class="col-sm-2 col-sm-pull-10">
154 [% INCLUDE 'admin-menu.inc' %]
156 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
157 </div> <!-- /.row -->
159 [% MACRO jsinclude BLOCK %]
160 [% Asset.js("js/admin-menu.js") | $raw %]
161 [% INCLUDE 'js-date-format.inc' %]
162 [% INCLUDE 'datatables.inc' %]
164 const job_statuses = [
165 {'_id': 'new', '_str': _("New")},
166 {'_id': 'cancelled', '_str': _("Cancelled")},
167 {'_id': 'finished', '_str': _("Finished")},
168 {'_id': 'started', '_str': _("Started")},
169 {'_id': 'running', '_str': _("Running")},
170 {'_id': 'failed', '_str': _("Failed")},
172 function get_job_status (status) {
173 let status_lib = job_statuses.find( s => s._id == status );
175 return status_lib._str;
182 '_id': 'batch_biblio_record_modification',
183 '_str': _("Batch bibliographic record modification")
186 '_id': 'batch_biblio_record_deletion',
187 '_str': _("Batch bibliographic record deletion")
190 '_id': 'batch_authority_record_modification',
191 '_str': _("Batch authority record modification")
194 '_id': 'batch_authority_record_deletion',
195 '_str': _("Batch authority record deletion")
198 '_id': 'batch_item_record_modification',
199 '_str': _("Batch item record modification")
202 '_id': 'batch_item_record_deletion',
203 '_str': _("Batch item record deletion")
206 '_id': 'erm_sushi_harvester',
207 '_str': _("ERM Usage Statistics SUSHI Harvester")
210 '_id': 'batch_hold_cancel',
211 '_str': _("Batch hold cancellation")
214 '_id': 'pseudonymize_statistic',
215 '_str': _("Pseudonymize statistic")
218 '_id': 'create_eholdings_from_biblios',
219 '_str': _("Create eHolding titles")
222 '_id': 'update_elastic_index',
223 '_str': _("Update Elasticsearch index")
226 '_id': 'update_holds_queue_for_biblios',
227 '_str': _("Holds queue update")
230 '_id': 'stage_marc_for_import',
231 '_str': _("Staged MARC records for import")
234 '_id': 'marc_import_commit_batch',
235 '_str': _("Import MARC records")
238 '_id': 'marc_import_revert_batch',
239 '_str': _("Revert import MARC records")
242 '_id': 'import_from_kbart_file',
243 '_str': _("Import titles from a KBART file")
247 function get_job_type (job_type) {
248 let job_type_lib = job_types.find( t => t._id == job_type );
249 if ( job_type_lib ) {
250 return job_type_lib._str;
252 return _("Unknown job type '%s'").format(job_type);
255 $(document).ready(function() {
256 [% IF op == 'view' %]
257 $("#job_status_description").html( get_job_status("[% job.status | html %]") );
258 $("#job_type_description").html( get_job_type("[% job.type | html %]") );
259 $("#job_details").show();
262 let additional_filters = {
263 enqueued_on: function(){
264 let now = new Date();
265 if ( $("#include_last_hour").is(":checked") ) {
266 now.setHours(now.getHours() - 1);
267 return { ">": now.toISOString() };
269 return { "<": now.toISOString() };
274 let only_current_filter = function(){
275 if ( $("#only_current").is(":checked") ) {
276 return 'only_current=1';
278 return 'only_current=0';
282 let jobs_table = $("#table_jobs").kohaTable({
284 "url": "/api/v1/jobs?" + only_current_filter()
286 "order": [[ 1, "desc" ]],
297 "render": function(data, type, row, meta) {
298 return get_job_status(row.status).escapeHtml();
302 "data": "progress,size",
305 "render": function(data, type, row, meta) {
306 return "%s/%s".format(row.progress, row.size).escapeHtml();
313 "render": function(data, type, row, meta) {
314 return get_job_type(row.type).escapeHtml();
318 "data": "enqueued_date",
321 "render": function(data, type, row, meta) {
322 return $datetime(row.enqueued_date);
326 "data": "started_date",
329 "render": function(data, type, row, meta) {
330 return $datetime(row.started_date);
334 "data": "ended_date",
337 "render": function(data, type, row, meta) {
338 return $datetime(row.ended_date);
342 "data": function( row, type, val, meta ) {
343 var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/background_jobs.pl?op=view&id='+ encodeURIComponent(row.job_id) +'"><i class="fa-solid fa-eye aria-hidden="true"></i> '+_("View")+'</a>'+"\n";
344 if ( row.status == 'new' || row.status == 'started' ) {
345 result += '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/background_jobs.pl?op=cancel&id='+ encodeURIComponent(row.job_id) +'"><i class="fa fa-trash-can" aria-hidden="true"></i> '+_("Cancel")+'</a>';
353 }, null, 1, additional_filters);
355 $("#include_last_hour").on("change", function(){
356 jobs_table.DataTable().draw();
360 $("#only_current").on("change", function(){
361 jobs_table.DataTable().ajax.url("/api/v1/jobs?" + only_current_filter()).load();
366 [% IF op == 'view' %]
371 [% INCLUDE 'intranet-bottom.inc' %]