Bug 34788: Add a background job to import a KBART file
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / admin / background_jobs.tt
1 [% USE raw %]
2 [% USE KohaDates %]
3 [% USE Asset %]
4 [% USE KohaDates %]
5 [% PROCESS 'i18n.inc' %]
6 [% SET footerjs = 1 %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>[% FILTER collapse %]
9     [% IF op == 'view' %]
10         [% tx("Details of job #{job_id}", { job_id = job.id }) | html %] &rsaquo;
11     [% END %]
12     [% t("Jobs") | html %] &rsaquo;
13     [% t("Administration") | html %] &rsaquo;
14     [% t("Koha") | html %]
15 [% END %]</title>
16
17 [% INCLUDE 'doc-head-close.inc' %]
18 </head>
19
20 <body id="admin_background_jobs" class="admin">
21 [% WRAPPER 'header.inc' %]
22     [% INCLUDE 'prefs-admin-search.inc' %]
23 [% END %]
24
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>
30             [% END %]
31             [% IF op == 'view' %]
32                 [% WRAPPER breadcrumb_item %]
33                     <a href="/cgi-bin/koha/admin/background_jobs.pl">Jobs</a>
34                 [% END %]
35                 [% WRAPPER breadcrumb_item bc_active= 1 %]
36                     <span>Details of job #[% job.id | html %]</span>
37                 [% END %]
38             [% ELSE %]
39                 [% WRAPPER breadcrumb_item bc_active= 1 %]
40                     <span>Jobs</span>
41                 [% END %]
42             [% END %]
43         [% ELSE %]
44             [% WRAPPER breadcrumb_item bc_active= 1 %]
45                 <span>Administration</span>
46             [% END %]
47         [% END %]
48     [% END #/ WRAPPER breadcrumbs %]
49 [% END #/ WRAPPER sub-header.inc %]
50
51 <div class="main container-fluid">
52     <div class="row">
53         <div class="col-sm-10 col-sm-push-2">
54             <main>
55                 [% INCLUDE 'messages.inc' %]
56
57 [% FOR m IN messages %]
58     <div class="dialog message">
59         [% SWITCH m.code %]
60         [% CASE 'cannot_view_job' %]
61             <div><i class="fa fa-exclamation error"></i>Insufficient permission to see this job.</div>
62         [% CASE %]
63             [% m.code | html %]
64         [% END %]
65     </div>
66 [% END %]
67
68 [% IF op == 'view' %]
69     <h1>Details of job #[% job.id | html %]</h1>
70
71     [% PROCESS "background_jobs/${job.type}.inc" %]
72
73     <div id="job_details" style="display:none">
74         <fieldset class="rows">
75             <ol>
76                 <li><span class="label">Job ID: </span>[% job.id | html %]</li>
77                 <li>
78                     <label for="job_status">Status: </label>
79                     <span id="job_status_description"></span>
80                 </li>
81                 <li><label for="job_progress">Progress: </label>[% job.progress || 0 | html %] / [% job.size | html %]</li>
82                 <li>
83                     <label for="job_type">Type: </label>
84                     <span id="job_type_description"></span>
85                 </li>
86                 <li>
87                     <label for="job_enqueued_on">Queued: </label>
88                     [% job.enqueued_on | $KohaDates with_hours = 1 %]
89                 </li>
90                 <li>
91                     <label for="job_started_on">Started: </label>
92                     [% job.started_on | $KohaDates with_hours = 1 %]
93                 </li>
94                 <li>
95                     <label for="job_ended_on">Ended: </label>
96                     [% job.ended_on | $KohaDates with_hours = 1 %]
97                 </li>
98             </ol>
99         </fieldset>
100         <div class="page-section">
101             <h2>Report</h2>
102             [% IF job.status != 'new' %][% PROCESS 'report' %][% END %]
103         </div>
104         <div class="page-section">
105             <h2>Detailed messages</h2>
106             [% IF job.status != 'new' %][% PROCESS 'detail' %][% END %]
107         </div>
108     </div> <!-- /#job_details -->
109
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>
113         </fieldset>
114     [% END %]
115 [% END %]
116
117 [% IF op == 'list' %]
118
119     <h1>Jobs</h1>
120
121     <div>
122         <input type="checkbox" id="only_current" checked />
123         <label for="only_current">Current jobs only</label>
124     </div>
125
126     <div>
127         <input type="checkbox" id="include_last_hour" checked />
128         <label for="include_last_hour">Only include jobs enqueued in the last hour</label>
129     </div>
130
131     <div class="page-section">
132         <table id="table_jobs">
133             <thead>
134                 <tr>
135                     <th>Job ID</th>
136                     <th data-filter="job_statuses">Status</th>
137                     <th>Progress</th>
138                     <th data-filter="job_types">Type</th>
139                     <th>Queued</th>
140                     <th>Started</th>
141                     <th>Ended</th>
142                     <th class="noExport">Actions</th>
143                 </tr>
144             </thead>
145         </table>
146     </div>
147 [% END %]
148
149             </main>
150         </div> <!-- /.col-sm-10.col-sm-push-2 -->
151
152         <div class="col-sm-2 col-sm-pull-10">
153             <aside>
154                 [% INCLUDE 'admin-menu.inc' %]
155             </aside>
156         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
157      </div> <!-- /.row -->
158
159 [% MACRO jsinclude BLOCK %]
160     [% Asset.js("js/admin-menu.js") | $raw %]
161     [% INCLUDE 'js-date-format.inc' %]
162     [% INCLUDE 'datatables.inc' %]
163     <script>
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")},
171         ];
172         function get_job_status (status) {
173             let status_lib = job_statuses.find( s => s._id == status );
174             if (status_lib) {
175                 return status_lib._str;
176             }
177             return status;
178         }
179
180         const job_types = [
181             {
182                 '_id': 'batch_biblio_record_modification',
183                 '_str': _("Batch bibliographic record modification")
184             },
185             {
186                 '_id': 'batch_biblio_record_deletion',
187                 '_str': _("Batch bibliographic record deletion")
188             },
189             {
190                 '_id': 'batch_authority_record_modification',
191                 '_str': _("Batch authority record modification")
192             },
193             {
194                 '_id': 'batch_authority_record_deletion',
195                 '_str': _("Batch authority record deletion")
196             },
197             {
198                 '_id': 'batch_item_record_modification',
199                 '_str': _("Batch item record modification")
200             },
201             {
202                 '_id': 'batch_item_record_deletion',
203                 '_str': _("Batch item record deletion")
204             },
205             {
206                 '_id': 'erm_sushi_harvester',
207                 '_str': _("ERM Usage Statistics SUSHI Harvester")
208             },
209             {
210                 '_id': 'batch_hold_cancel',
211                 '_str': _("Batch hold cancellation")
212             },
213             {
214                 '_id': 'pseudonymize_statistic',
215                 '_str': _("Pseudonymize statistic")
216             },
217             {
218                 '_id': 'create_eholdings_from_biblios',
219                 '_str': _("Create eHolding titles")
220             },
221             {
222                 '_id': 'update_elastic_index',
223                 '_str': _("Update Elasticsearch index")
224             },
225             {
226                 '_id': 'update_holds_queue_for_biblios',
227                 '_str': _("Holds queue update")
228             },
229             {
230                 '_id': 'stage_marc_for_import',
231                 '_str': _("Staged MARC records for import")
232             },
233             {
234                 '_id': 'marc_import_commit_batch',
235                 '_str': _("Import MARC records")
236             },
237             {
238                 '_id': 'marc_import_revert_batch',
239                 '_str': _("Revert import MARC records")
240             },
241             {
242                 '_id': 'import_from_kbart_file',
243                 '_str': _("Import titles from a KBART file")
244             },
245         ];
246
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;
251             }
252             return _("Unknown job type '%s'").format(job_type);
253         }
254
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();
260             [% END %]
261
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() };
268                     } else {
269                         return { "<": now.toISOString() };
270                     }
271                 }
272             };
273
274             let only_current_filter = function(){
275                 if ( $("#only_current").is(":checked") ) {
276                     return 'only_current=1';
277                 } else {
278                     return 'only_current=0';
279                 }
280             }
281
282             let jobs_table = $("#table_jobs").kohaTable({
283                 "ajax": {
284                     "url": "/api/v1/jobs?" + only_current_filter()
285                 },
286                 "order": [[ 1, "desc" ]],
287                 "columns": [
288                     {
289                         "data": "job_id",
290                         "searchable": true,
291                         "orderable": true
292                     },
293                     {
294                         "data": "status",
295                         "searchable": true,
296                         "orderable": true,
297                         "render": function(data, type, row, meta) {
298                             return get_job_status(row.status).escapeHtml();
299                         }
300                     },
301                     {
302                         "data": "progress,size",
303                         "searchable": false,
304                         "orderable": true,
305                         "render": function(data, type, row, meta) {
306                             return "%s/%s".format(row.progress, row.size).escapeHtml();
307                         }
308                     },
309                     {
310                         "data": "type",
311                         "searchable": true,
312                         "orderable": true,
313                         "render": function(data, type, row, meta) {
314                             return get_job_type(row.type).escapeHtml();
315                         }
316                     },
317                     {
318                         "data": "enqueued_date",
319                         "searchable": true,
320                         "orderable": true,
321                         "render": function(data, type, row, meta) {
322                             return $datetime(row.enqueued_date);
323                         }
324                     },
325                     {
326                         "data": "started_date",
327                         "searchable": true,
328                         "orderable": true,
329                         "render": function(data, type, row, meta) {
330                             return $datetime(row.started_date);
331                         }
332                     },
333                     {
334                         "data": "ended_date",
335                         "searchable": true,
336                         "orderable": true,
337                         "render": function(data, type, row, meta) {
338                             return $datetime(row.ended_date);
339                         }
340                     },
341                     {
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&amp;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&amp;id='+ encodeURIComponent(row.job_id) +'"><i class="fa fa-trash-can" aria-hidden="true"></i> '+_("Cancel")+'</a>';
346                             }
347                             return result;
348                         },
349                         "searchable": false,
350                         "orderable": false
351                     }
352                 ]
353             }, null, 1, additional_filters);
354
355             $("#include_last_hour").on("change", function(){
356                 jobs_table.DataTable().draw();
357                 return false;
358             });
359
360             $("#only_current").on("change", function(){
361                 jobs_table.DataTable().ajax.url("/api/v1/jobs?" + only_current_filter()).load();
362                 return false;
363             });
364         });
365     </script>
366     [% IF op == 'view' %]
367         [% PROCESS 'js' %]
368     [% END %]
369 [% END %]
370
371 [% INCLUDE 'intranet-bottom.inc' %]