Bug 34112: Replace fa.fa-pencil-alt with fa-solid.fa-pencil in edit buttons
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / admin / marc-overlay-rules.tt
1 [% USE raw %]
2 [% USE To %]
3 [% USE Asset %]
4 [% SET footerjs = 1 %]
5 [% USE Koha %]
6 [% USE KohaSpan %]
7 [% PROCESS 'i18n.inc' %]
8 [% INCLUDE 'doc-head-open.inc' %]
9 <title>MARC overlay rules &rsaquo; Koha &rsaquo; Administration</title>
10 [% INCLUDE 'doc-head-close.inc' %]
11
12 <style>
13     .required {
14         background-color: #C00;
15     }
16 </style>
17
18 </head>
19 <body id="admin_marc-overlay-rules" class="admin">
20 [% WRAPPER 'header.inc' %]
21     [% INCLUDE 'cat-search.inc' %]
22 [% END %]
23
24 [% WRAPPER 'sub-header.inc' %]
25     [% WRAPPER breadcrumbs %]
26         [% WRAPPER breadcrumb_item %]
27             <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
28         [% END %]
29         [% WRAPPER breadcrumb_item %]
30             <a href="#" aria-current="page">
31                 <span>MARC overlay rules</span>
32             </a>
33         [% END %]
34     [% END #/ WRAPPER breadcrumbs %]
35 [% END #/ WRAPPER sub-header.inc %]
36
37     <div class="main container-fluid">
38         <div class="row">
39             <div class="col-sm-10 col-sm-push-2">
40
41                 <h1>Manage MARC overlay rules</h1>
42
43                 [% FOR m IN messages %]
44                 <div class="dialog [% m.type | html %]">
45                     [% SWITCH m.code %]
46                     [% CASE 'invalid_tag_regexp' %]
47                       <span>Invalid regular expression "[% m.tag | html %]".</span>
48                     [% CASE 'invalid_control_field_actions' %]
49                       <span>Invalid combination of actions for tag [% m.tag | html %]. Control field rules do not allow "Appended: Append" and "Removed: Skip".</span>
50                     [% CASE %]
51                       <span>[% m.code | html %]</span>
52                     [% END %]
53                 </div>
54                 [% END %]
55
56                 [% UNLESS Koha.Preference( 'MARCOverlayRules' ) %]
57                 [% SET pref_MARCOverlayRules_link = '<a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=MARCOverlayRules">MARCOverlayRules</a>' %]
58                 <div class="dialog message">
59                     The [%  pref_MARCOverlayRules_link | $raw | $KohaSpan %] preference is not set, don't forget to enable it for rules to take effect.
60                 </div>
61                 [% END %]
62                 [% IF removeConfirm %]
63                 <div class="dialog alert">
64                     <h3>Remove rule?</h3>
65                     <p>Are you sure you want to remove the selected rule(s)?</p>
66
67                     <form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="GET">
68                         <button type="submit" class="deny"><i class="fa fa-fw fa-times"></i> No, do not remove</button>
69                     </form>
70                     <button type="button" class="approve" id="doremove"><i class="fa fa-fw fa-check"></i> Yes, remove</button>
71                 </div>
72                 [% END %]
73
74                 <div class="page-section">
75                 <form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="POST" id="marc-overlay-rules-form">
76                     <table id="marc-overlay-rules">
77                         <thead><tr>
78                             <th>Rule</th>
79                             <th>Module</th>
80                             <th>[% tp('noun', 'Filter') | html %]</th>
81                             <th>Tag</th>
82                             <th>Preset</th>
83                             <th>Added <i id="info_added" data-toggle="tooltip" title="If a field matching the rule tag only exists in the incoming record" data-placement="right" class="fa fa-info-circle"></i></th>
84                             <th>Appended <i id="info_appended" data-toggle="tooltip" title="If the original record has one or more fields matching with the rule tag, but one or more fields matching the rule tag differ in the incoming record" data-placement="right" class="fa fa-info-circle"></i></th>
85                             <th>Removed <i id="info_removed" data-toggle="tooltip" title="If the original record has a field matching the rule tag, but the matching field is not in the incoming record" data-placement="right" class="fa fa-info-circle"></i></th>
86                             <th>Deleted <i id="info_deleted" data-toggle="tooltip" title="If the original record has fields matching the rule tag, but no fields with this are found in the incoming record" data-placement="right" class="fa fa-info-circle"></i></th>
87                             <th>Actions</th>
88                             <th>&nbsp;</th>
89                         </tr></thead>
90                         [% UNLESS edit %]
91                         <tfoot>
92                             <tr class="rule-new">
93                                 <th>&nbsp;</th>
94                                 <th>
95                                     <select name="module">
96                                         <option value="source">Source</option>
97                                         <option value="categorycode">User category</option>
98                                         <option value="userid">Username</option>
99                                     </select>
100                                 </th>
101                                 <th id="filter-container"></th>
102                                 <th><input type="text" size="5" name="tag"/></th>
103                                 <th>
104                                     <select name="preset">
105                                         <option value="" selected>Custom</option>
106                                         <option value="Protect">Protect</option>
107                                         <option value="Overwrite">Overwrite</option>
108                                         <option value="Add new">Add new</option>
109                                         <option value="Add and append">Add and append</option>
110                                         <option value="Protect from deletion">Protect from deletion</option>
111                                     </select>
112                                 </th>
113                                 <th class="rule-operation-action-edit">
114                                     <select name="add">
115                                         <option value="0">Skip</option>
116                                         <option value="1">Add</option>
117                                     </select>
118                                 </th>
119                                 <th class="rule-operation-action-edit">
120                                     <select name="append">
121                                         <option value="0">Skip</option>
122                                         <option value="1">Append</option>
123                                     </select>
124                                 </th>
125                                 <th class="rule-operation-action-edit">
126                                     <select name="remove">
127                                         <option value="0">Skip</option>
128                                         <option value="1">Remove</option>
129                                     </select>
130                                 </th>
131                                 <th class="rule-operation-action-edit">
132                                     <select name="delete">
133                                         <option value="0">Skip</option>
134                                         <option value="1">Delete</option>
135                                     </select>
136                                 </th>
137                                 <th><button class="btn btn-default btn-xs" title="Add" id="add"><i class="fa fa-plus"></i> Add rule</button></th>
138                                 <th><button id="btn_batchremove" disabled="disabled" class="btn btn-default btn-xs" title="Batch remove"><i class="fa fa-trash-can"></i> Delete selected</button></th>
139                             </tr>
140                         </tfoot>
141                         [% END %]
142                         <tbody>
143                             [% FOREACH rule IN rules %]
144                                 <tr id="[% rule.id | html %]" class="rule[% IF rule.edit %]-edit[% END %]">
145                                 [% IF rule.edit %]
146                                     <td>[% rule.id | html %]</td>
147                                     <td>
148                                         <select name="module">
149                                             [% IF rule.module == "source" %]
150                                                 <option value="source" selected="selected">Source</option>
151                                             [% ELSE %]
152                                                 <option value="source">Source</option>
153                                             [% END %]
154                                             [% IF rule.module == "categorycode" %]
155                                                 <option value="categorycode" selected="selected">User category</option>
156                                             [% ELSE %]
157                                                 <option value="categorycode">User category</option>
158                                             [% END %]
159                                             [% IF rule.module == "userid" %]
160                                                 <option value="userid" selected="selected">Username</option>
161                                             [% ELSE %]
162                                                 <option value="userid">Username</option>
163                                             [% END %]
164                                         </select>
165                                     </td>
166                                     <td id="filter-container" data-filter="[% rule.filter | html %]"></td>
167                                     <td><input type="text" size="3" name="tag" value="[% rule.tag | html %]"/></td>
168                                     <th>
169                                         <select name="preset">
170                                             <option value="" selected>Custom</option>
171                                             <option value="Protect">Protect</option>
172                                             <option value="Overwrite">Overwrite</option>
173                                             <option value="Add new">Add new</option>
174                                             <option value="Add and append">Add and append</option>
175                                             <option value="Protect from deletion">Protect from deletion</option>
176                                         </select>
177                                     </th>
178                                     <td class="rule-operation-action-edit">
179                                         <select name="add">
180                                             [% IF rule.add %]
181                                                 <option value="0">Skip</option>
182                                                 <option value="1" selected="selected">Add</option>
183                                             [% ELSE %]
184                                                 <option value="0" selected="selected">Skip</option>
185                                                 <option value="1">Add</option>
186                                             [% END %]
187                                         </select>
188                                     </td>
189                                     <td class="rule-operation-action-edit">
190                                         <select name="append">
191                                             [% IF rule.append %]
192                                                 <option value="0">Skip</option>
193                                                 <option value="1" selected="selected">Append</option>
194                                             [% ELSE %]
195                                                 <option value="0" selected="selected">Skip</option>
196                                                 <option value="1">Append</option>
197                                             [% END %]
198                                         </select>
199                                     </td>
200                                     <td class="rule-operation-action-edit">
201                                         <select name="remove">
202                                             [% IF rule.remove %]
203                                                 <option value="0">Skip</option>
204                                                 <option value="1" selected="selected">Remove</option>
205                                             [% ELSE %]
206                                                 <option value="0" selected="selected">Skip</option>
207                                                 <option value="1">Remove</option>
208                                             [% END %]
209                                         </select>
210                                     </td>
211                                     <td class="rule-operation-action-edit">
212                                         <select name="delete">
213                                             [% IF rule.delete %]
214                                                 <option value="0">Skip</option>
215                                                 <option value="1" selected="selected">Delete</option>
216                                             [% ELSE %]
217                                                 <option value="0" selected="selected">Skip</option>
218                                                 <option value="1">Delete</option>
219                                             [% END %]
220                                         </select>
221                                     </td>
222                                     <td class="actions">
223                                         <button class="btn btn-default btn-xs" title="Save" id="doedit" value="[% rule.id | html %]"><i class="fa fa-check"></i> Save</button>
224                                         <button type="submit" class="btn btn-default btn-xs" title="Cancel" ><i class="fa fa-times"></i> Cancel</button>
225                                     </td>
226                                     <td></td>
227                                 [% ELSE %]
228                                     <td>[% rule.id | html %]</td>
229                                     <td class="rule-module">[% rule.module | html %]</td>
230                                     <td class="rule-filter">[% rule.filter | html %]</td>
231                                     <td>[% rule.tag | html %]</td>
232                                     <td class="rule-preset"></td>
233                                     <td class="rule-operation-action" data-operation="add">[% IF rule.add %]Add[% ELSE %]Skip[% END %]</td>
234                                     <td class="rule-operation-action" data-operation="append">[% IF rule.append %]Append[% ELSE %]Skip[% END %]</td>
235                                     <td class="rule-operation-action" data-operation="remove">[% IF rule.remove %]Remove[% ELSE %]Skip[% END %]</td>
236                                     <td class="rule-operation-action" data-operation="delete">[% IF rule.delete %]Delete[% ELSE %]Skip[% END %]</td>
237                                     <td class="actions">
238                                         <a href="?op=remove&id=[% rule.id | uri %]" title="Delete" class="btn btn-default btn-xs"><i class="fa fa-trash-can"></i> Delete</a>
239                                         <a href="?op=edit&id=[% rule.id | uri %]" title="Edit" class="btn btn-default btn-xs"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit</a>
240                                     </td>
241                                     <td>
242                                         [% IF rule.removemarked %]
243                                             <input type="checkbox" name="batchremove" value="[% rule.id | html %]" checked="checked"/>
244                                         [% ELSE %]
245                                             <input type="checkbox" name="batchremove" value="[% rule.id | html %]"/>
246                                         [% END %]
247                                     </td>
248                                 [% END %]
249                                 </tr>
250                             [% END %]
251                         </tbody>
252                     </table>
253                 </form>
254                 </div> <!-- /.page-section -->
255
256                 <form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="post">
257                     <input type="hidden" name="op" value="redo-matching" />
258                 </form>
259
260             </div><!-- /.col-sm-10.col-sm-push-2 -->
261
262             <div class="col-sm-2 col-sm-pull-10">
263                 <aside>
264                     [% INCLUDE 'admin-menu.inc' %]
265                 </aside>
266             </div>
267
268         </div><!-- /.row -->
269     </div><!-- /main container-fluid -->
270
271 [% MACRO jsinclude BLOCK %]
272     [% Asset.js("js/admin-menu.js") | $raw %]
273     [% INCLUDE 'datatables.inc' %]
274
275     <script>
276     $(document).ready(function(){
277         function doSubmit(op, id) {
278             $('<input type="hidden"/>')
279             .attr('name', 'op')
280             .attr('value', op)
281             .appendTo('#marc-overlay-rules-form');
282
283             if(id) {
284                 $('<input type="hidden"/>')
285                 .attr('name', 'id')
286                 .attr('value', id)
287                 .appendTo('#marc-overlay-rules-form');
288             }
289
290             var valid = true;
291             if (op == 'add' || op == 'edit') {
292                 var validate = [
293                     $('#marc-overlay-rules-form input[name="filter"]'),
294                     $('#marc-overlay-rules-form input[name="tag"]')
295                 ];
296                 for(var i = 0; i < validate.length; i++) {
297                     if (validate[i].length) {
298                         if(validate[i].val().length == 0) {
299                             validate[i].addClass('required');
300                             valid = false;
301                         } else {
302                             validate[i].removeClass('required');
303                         }
304                     }
305                 }
306             }
307
308             if (valid) {
309                 $('#marc-overlay-rules-form').submit();
310             }
311
312             return valid;
313         }
314
315         $('#doremove').on('click', function(){
316             doSubmit('doremove');
317         });
318         $('#doedit').on('click', function(){
319             doSubmit('doedit', $("#doedit").attr('value'));
320         });
321         $('#add').on('click', function(){
322             doSubmit('add');
323             return false;
324         });
325         $('#btn_batchremove').on('click', function(){
326             doSubmit('remove');
327         });
328
329         /* Disable batch remove unless one or more checkboxes are checked */
330         $('input[name="batchremove"]').change(function() {
331             if($('input[name="batchremove"]:checked').length > 0) {
332                 $('#btn_batchremove').removeAttr('disabled');
333             } else {
334                 $('#btn_batchremove').attr('disabled', 'disabled');
335             }
336         });
337
338         $.fn.dataTable.ext.order['dom-input'] = function (settings, col) {
339             return this.api().column(col, { order: 'index' }).nodes()
340                 .map(function (td, i) {
341                     if($('input', td).val() != undefined) {
342                         return $('input', td).val();
343                     } else if($('select', td).val() != undefined) {
344                         return $('option[selected="selected"]', td).val();
345                     } else {
346                         return $(td).html();
347                     }
348                 });
349         }
350
351         $('#marc-overlay-rules').dataTable($.extend(true, {}, dataTablesDefaults, {
352             "aoColumns": [
353                 {"bSearchable": false, "bSortable": false},
354                 {"sSortDataType": "dom-input"},
355                 {"sSortDataType": "dom-input"},
356                 {"bSearchable": false, "sSortDataType": "dom-input"},
357                 {"bSearchable": false, "sSortDataType": "dom-input"},
358                 {"bSearchable": false, "sSortDataType": "dom-input"},
359                 {"bSearchable": false, "sSortDataType": "dom-input"},
360                 {"bSearchable": false, "sSortDataType": "dom-input"},
361                 {"bSearchable": false, "sSortDataType": "dom-input"},
362                 {"bSearchable": false, "bSortable": false},
363                 {"bSearchable": false, "bSortable": false}
364             ],
365             "pagingType": "simple"
366         }));
367
368         var overlay_rules_presets = {};
369         overlay_rules_presets[_("Protect")] = {
370           'add': 0,
371           'append': 0,
372           'remove': 0,
373           'delete': 0
374         };
375         overlay_rules_presets[_("Overwrite")] = {
376           'add': 1,
377           'append': 1,
378           'remove': 1,
379           'delete': 1
380         };
381         overlay_rules_presets[_("Add new")] = {
382           'add': 1,
383           'append': 0,
384           'remove': 0,
385           'delete': 0
386         };
387         overlay_rules_presets[_("Add and append")] = {
388           'add': 1,
389           'append': 1,
390           'remove': 0,
391           'delete': 0
392         };
393         overlay_rules_presets[_("Protect from deletion")] = {
394           'add': 1,
395           'append': 1,
396           'remove': 1,
397           'delete': 0
398         };
399
400         var overlay_rules_label_to_value = {};
401         overlay_rules_label_to_value[_("Add")] = 1;
402         overlay_rules_label_to_value[_("Append")] = 1;
403         overlay_rules_label_to_value[_("Remove")] = 1;
404         overlay_rules_label_to_value[_("Delete")] = 1;
405         overlay_rules_label_to_value[_("Skip")] = 0;
406
407         function hash_config(config) {
408           return JSON.stringify(config, Object.keys(config).sort());
409         }
410
411         var overlay_rules_preset_map = {};
412         $.each(overlay_rules_presets, function(preset, config) {
413           overlay_rules_preset_map[hash_config(config)] = preset;
414         });
415
416         function operations_config_overlay_rule_preset(config) {
417           return overlay_rules_preset_map[hash_config(config)] || '';
418         }
419
420         /* Set preset values according to operation config */
421         $('.rule').each(function() {
422           var $this = $(this);
423           var operations_config = {};
424           $('.rule-operation-action', $this).each(function() {
425             var $operation = $(this);
426             operations_config[$operation.data('operation')] = overlay_rules_label_to_value[$operation.text()];
427           });
428           $('.rule-preset', $this).text(
429             operations_config_overlay_rule_preset(operations_config) || _("Custom")
430           );
431         });
432
433         /* Listen to operations config changes and set presets accordingly */
434         $('.rule-operation-action-edit select').change(function() {
435           var operations_config = {};
436           var $parent_row = $(this).closest('tr');
437           $('.rule-operation-action-edit select', $parent_row).each(function() {
438             var $this = $(this);
439             operations_config[$this.attr('name')] = parseInt($this.val());
440           });
441           $('select[name="preset"]', $parent_row).val(
442               operations_config_overlay_rule_preset(operations_config)
443           );
444         });
445
446         /* Listen to preset changes and set operations config accordingly */
447         $('select[name="preset"]').change(function() {
448           var $this = $(this);
449           var $parent_row = $this.closest('tr');
450           var preset = $this.val();
451           if (preset) {
452             $.each(overlay_rules_presets[preset], function(operation, action) {
453               $('select[name="' + operation + '"]', $parent_row).val(action);
454             });
455           }
456         });
457
458         var categories = [% To.json( categories ) | $raw %];
459         // Add * => * to this array of objects, and *reduce* it to one object
460         // Note: This allows displaying a sorted list of categories later, but we still depend on an object!
461         categories.unshift({ categorycode: '*', description: '*'});
462         categories = categories.reduce( ( a,c ) => ( { ...a, [c.categorycode]: c.description } ), {} );
463
464         var module_filter_options = {
465         source: {
466             '*': '*',
467             batchmod: _("Batch record modification"),
468             intranet: _("Staff interface MARC editor"),
469             batchimport: _("Staged MARC import"),
470             z3950: _("Z39.50"),
471             /* bulkmarcimport: _("bulkmarcimport.pl"), */
472             import_lexile: _("import_lexile.pl")
473         },
474
475             categorycode: categories,
476         };
477
478         //Kind of hack: Replace filter value with label when one exist
479         $('.rule-module').each(function() {
480           var $this = $(this);
481           var module = $this.text();
482           if (module in module_filter_options) {
483             let $filter = $this.siblings('.rule-filter');
484             if ($filter.text() in module_filter_options[module]) {
485               $filter.text(module_filter_options[module][$filter.text()]);
486             }
487           }
488         });
489
490         var $filter_container = $('#filter-container');
491
492         /* Listen to module changes and set filter input accordingly */
493         $('select[name="module"]').change(function() {
494           var $this = $(this);
495           var module_name = $this.val();
496
497           /* Remove current element if any */
498           $filter_container.empty();
499
500           var filter_elem = null;
501           if (module_name in module_filter_options) {
502             // Create select element
503             filter_elem = document.createElement('select');
504             for (var filter_value in module_filter_options[module_name]) {
505               var option = document.createElement('option');
506               option.value = filter_value;
507               option.text = module_filter_options[module_name][filter_value];
508               filter_elem.appendChild(option);
509             }
510           }
511           else {
512             // Create text input element
513             filter_elem = document.createElement('input');
514             filter_elem.type = 'text';
515             filter_elem.setAttribute('size', 5);
516           }
517           filter_elem.name = 'filter';
518           filter_elem.id = 'filter';
519           $filter_container.append(filter_elem);
520         }).change(); // Trigger change
521
522         // Hack: set value if editing rule
523         if ($filter_container.data('filter')) {
524           $('#filter').val($filter_container.data('filter'));
525         }
526
527     });
528     </script>
529 [% END %]
530 [% INCLUDE 'intranet-bottom.inc' %]