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