Jonathan Druart
e08629b68b
To be nicer with translators. Update the PO files for whichever languages will show how this is useful. Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net> Rebased-by: Victor Grousset/tuxayo <victor@tuxayo.net> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
526 lines
25 KiB
Text
526 lines
25 KiB
Text
[% USE raw %]
|
|
[% USE Asset %]
|
|
[% SET footerjs = 1 %]
|
|
[% USE Koha %]
|
|
[% USE KohaSpan %]
|
|
[% INCLUDE 'doc-head-open.inc' %]
|
|
<title>MARC overlay rules › Koha › Administration</title>
|
|
[% INCLUDE 'doc-head-close.inc' %]
|
|
|
|
<style>
|
|
.required {
|
|
background-color: #C00;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body id="admin_marc-overlay-rules" class="admin">
|
|
[% INCLUDE 'header.inc' %]
|
|
[% INCLUDE 'cat-search.inc' %]
|
|
|
|
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
|
|
<ol>
|
|
<li>
|
|
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
|
|
</li>
|
|
<li>
|
|
<a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" aria-current="page">
|
|
MARC overlay rules
|
|
</a>
|
|
</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<div class="main container-fluid">
|
|
<div class="row">
|
|
<div class="col-sm-10 col-sm-push-2">
|
|
|
|
<h1>Manage MARC overlay rules</h1>
|
|
|
|
[% FOR m IN messages %]
|
|
<div class="dialog [% m.type | html %]">
|
|
[% SWITCH m.code %]
|
|
[% CASE 'invalid_tag_regexp' %]
|
|
<span>Invalid regular expression "[% m.tag | html %]".</span>
|
|
[% CASE 'invalid_control_field_actions' %]
|
|
<span>Invalid combination of actions for tag [% m.tag | html %]. Control field rules do not allow "Appended: Append" and "Removed: Skip".</span>
|
|
[% CASE %]
|
|
<span>[% m.code | html %]</span>
|
|
[% END %]
|
|
</div>
|
|
[% END %]
|
|
|
|
[% UNLESS Koha.Preference( 'MARCOverlayRules' ) %]
|
|
[% SET pref_MARCOverlayRules_link = '<a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=MARCOverlayRules">MARCOverlayRules</a>' %]
|
|
<div class="dialog message">
|
|
The [% pref_MARCOverlayRules_link | $raw | $KohaSpan %] preference is not set, don't forget to enable it for rules to take effect.
|
|
</div>
|
|
[% END %]
|
|
[% IF removeConfirm %]
|
|
<div class="dialog alert">
|
|
<h3>Remove rule?</h3>
|
|
<p>Are you sure you want to remove the selected rule(s)?</p>
|
|
|
|
<form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="GET">
|
|
<button type="submit" class="deny"><i class="fa fa-fw fa-remove"></i> No, do not remove</button>
|
|
</form>
|
|
<button type="button" class="approve" id="doremove"><i class="fa fa-fw fa-check"></i> Yes, remove</button>
|
|
</div>
|
|
[% END %]
|
|
|
|
<form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="POST" id="marc-overlay-rules-form">
|
|
<table id="marc-overlay-rules">
|
|
<thead><tr>
|
|
<th>Rule</th>
|
|
<th>Module</th>
|
|
<th>Filter</th>
|
|
<th>Tag</th>
|
|
<th>Preset</th>
|
|
<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>
|
|
<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>
|
|
<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>
|
|
<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>
|
|
<th>Actions</th>
|
|
<th> </th>
|
|
</tr></thead>
|
|
[% UNLESS edit %]
|
|
<tfoot>
|
|
<tr class="rule-new">
|
|
<th> </th>
|
|
<th>
|
|
<select name="module">
|
|
<option value="source">Source</option>
|
|
<option value="categorycode">User category</option>
|
|
<option value="userid">Username</option>
|
|
</select>
|
|
</th>
|
|
<th id="filter-container"></th>
|
|
<th><input type="text" size="5" name="tag"/></th>
|
|
<th>
|
|
<select name="preset">
|
|
<option value="" selected>Custom</option>
|
|
<option value="Protect">Protect</option>
|
|
<option value="Overwrite">Overwrite</option>
|
|
<option value="Add new">Add new</option>
|
|
<option value="Add and append">Add and append</option>
|
|
<option value="Protect from deletion">Protect from deletion</option>
|
|
</select>
|
|
</th>
|
|
<th class="rule-operation-action-edit">
|
|
<select name="add">
|
|
<option value="0">Skip</option>
|
|
<option value="1">Add</option>
|
|
</select>
|
|
</th>
|
|
<th class="rule-operation-action-edit">
|
|
<select name="append">
|
|
<option value="0">Skip</option>
|
|
<option value="1">Append</option>
|
|
</select>
|
|
</th>
|
|
<th class="rule-operation-action-edit">
|
|
<select name="remove">
|
|
<option value="0">Skip</option>
|
|
<option value="1">Remove</option>
|
|
</select>
|
|
</th>
|
|
<th class="rule-operation-action-edit">
|
|
<select name="delete">
|
|
<option value="0">Skip</option>
|
|
<option value="1">Delete</option>
|
|
</select>
|
|
</th>
|
|
<th><button class="btn btn-default btn-xs" title="Add" id="add"><i class="fa fa-plus"></i> Add rule</button></th>
|
|
<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>
|
|
</tr>
|
|
</tfoot>
|
|
[% END %]
|
|
<tbody>
|
|
[% FOREACH rule IN rules %]
|
|
<tr id="[% rule.id | html %]" class="rule[% IF rule.edit %]-edit[% END %]">
|
|
[% IF rule.edit %]
|
|
<td>[% rule.id | html %]</td>
|
|
<td>
|
|
<select name="module">
|
|
[% IF rule.module == "source" %]
|
|
<option value="source" selected="selected">Source</option>
|
|
[% ELSE %]
|
|
<option value="source">Source</option>
|
|
[% END %]
|
|
[% IF rule.module == "categorycode" %]
|
|
<option value="categorycode" selected="selected">User category</option>
|
|
[% ELSE %]
|
|
<option value="categorycode">User category</option>
|
|
[% END %]
|
|
[% IF rule.module == "userid" %]
|
|
<option value="userid" selected="selected">Username</option>
|
|
[% ELSE %]
|
|
<option value="userid">Username</option>
|
|
[% END %]
|
|
</select>
|
|
</td>
|
|
<td id="filter-container" data-filter="[% rule.filter | html %]"></td>
|
|
<td><input type="text" size="3" name="tag" value="[% rule.tag | html %]"/></td>
|
|
<th>
|
|
<select name="preset">
|
|
<option value="" selected>Custom</option>
|
|
<option value="Protect">Protect</option>
|
|
<option value="Overwrite">Overwrite</option>
|
|
<option value="Add new">Add new</option>
|
|
<option value="Add and append">Add and append</option>
|
|
<option value="Protect from deletion">Protect from deletion</option>
|
|
</select>
|
|
</th>
|
|
<td class="rule-operation-action-edit">
|
|
<select name="add">
|
|
[% IF rule.add %]
|
|
<option value="0">Skip</option>
|
|
<option value="1" selected="selected">Add</option>
|
|
[% ELSE %]
|
|
<option value="0" selected="selected">Skip</option>
|
|
<option value="1">Add</option>
|
|
[% END %]
|
|
</select>
|
|
</td>
|
|
<td class="rule-operation-action-edit">
|
|
<select name="append">
|
|
[% IF rule.append %]
|
|
<option value="0">Skip</option>
|
|
<option value="1" selected="selected">Append</option>
|
|
[% ELSE %]
|
|
<option value="0" selected="selected">Skip</option>
|
|
<option value="1">Append</option>
|
|
[% END %]
|
|
</select>
|
|
</td>
|
|
<td class="rule-operation-action-edit">
|
|
<select name="remove">
|
|
[% IF rule.remove %]
|
|
<option value="0">Skip</option>
|
|
<option value="1" selected="selected">Remove</option>
|
|
[% ELSE %]
|
|
<option value="0" selected="selected">Skip</option>
|
|
<option value="1">Remove</option>
|
|
[% END %]
|
|
</select>
|
|
</td>
|
|
<td class="rule-operation-action-edit">
|
|
<select name="delete">
|
|
[% IF rule.delete %]
|
|
<option value="0">Skip</option>
|
|
<option value="1" selected="selected">Delete</option>
|
|
[% ELSE %]
|
|
<option value="0" selected="selected">Skip</option>
|
|
<option value="1">Delete</option>
|
|
[% END %]
|
|
</select>
|
|
</td>
|
|
<td class="actions">
|
|
<button class="btn btn-default btn-xs" title="Save" id="doedit" value="[% rule.id | html %]"><i class="fa fa-check"></i> Save</button>
|
|
<button type="submit" class="btn btn-default btn-xs" title="Cancel" ><i class="fa fa-times"></i> Cancel</button>
|
|
</td>
|
|
<td></td>
|
|
[% ELSE %]
|
|
<td>[% rule.id | html %]</td>
|
|
<td class="rule-module">[% rule.module | html %]</td>
|
|
<td class="rule-filter">[% rule.filter | html %]</td>
|
|
<td>[% rule.tag | html %]</td>
|
|
<td class="rule-preset"></td>
|
|
<td class="rule-operation-action" data-operation="add">[% IF rule.add %]Add[% ELSE %]Skip[% END %]</td>
|
|
<td class="rule-operation-action" data-operation="append">[% IF rule.append %]Append[% ELSE %]Skip[% END %]</td>
|
|
<td class="rule-operation-action" data-operation="remove">[% IF rule.remove %]Remove[% ELSE %]Skip[% END %]</td>
|
|
<td class="rule-operation-action" data-operation="delete">[% IF rule.delete %]Delete[% ELSE %]Skip[% END %]</td>
|
|
<td class="actions">
|
|
<a href="?op=remove&id=[% rule.id | uri %]" title="Delete" class="btn btn-default btn-xs"><i class="fa fa-trash"></i> Delete</a>
|
|
<a href="?op=edit&id=[% rule.id | uri %]" title="Edit" class="btn btn-default btn-xs"><i class="fa fa-pencil"></i> Edit</a>
|
|
</td>
|
|
<td>
|
|
[% IF rule.removemarked %]
|
|
<input type="checkbox" name="batchremove" value="[% rule.id | html %]" checked="checked"/>
|
|
[% ELSE %]
|
|
<input type="checkbox" name="batchremove" value="[% rule.id | html %]"/>
|
|
[% END %]
|
|
</td>
|
|
[% END %]
|
|
</tr>
|
|
[% END %]
|
|
</tbody>
|
|
</table>
|
|
</form>
|
|
|
|
<form action="/cgi-bin/koha/admin/marc-overlay-rules.pl" method="post">
|
|
<input type="hidden" name="op" value="redo-matching" />
|
|
</form>
|
|
|
|
</div><!-- /.col-sm-10.col-sm-push-2 -->
|
|
|
|
<div class="col-sm-2 col-sm-pull-10">
|
|
<aside>
|
|
[% INCLUDE 'admin-menu.inc' %]
|
|
</aside>
|
|
</div>
|
|
|
|
</div><!-- /.row -->
|
|
</div><!-- /main container-fluid -->
|
|
|
|
[% MACRO jsinclude BLOCK %]
|
|
[% Asset.js("js/admin-menu.js") | $raw %]
|
|
[% INCLUDE 'datatables.inc' %]
|
|
|
|
<script>
|
|
$(document).ready(function(){
|
|
function doSubmit(op, id) {
|
|
$('<input type="hidden"/>')
|
|
.attr('name', 'op')
|
|
.attr('value', op)
|
|
.appendTo('#marc-overlay-rules-form');
|
|
|
|
if(id) {
|
|
$('<input type="hidden"/>')
|
|
.attr('name', 'id')
|
|
.attr('value', id)
|
|
.appendTo('#marc-overlay-rules-form');
|
|
}
|
|
|
|
var valid = true;
|
|
if (op == 'add' || op == 'edit') {
|
|
var validate = [
|
|
$('#marc-overlay-rules-form input[name="filter"]'),
|
|
$('#marc-overlay-rules-form input[name="tag"]')
|
|
];
|
|
for(var i = 0; i < validate.length; i++) {
|
|
if (validate[i].length) {
|
|
if(validate[i].val().length == 0) {
|
|
validate[i].addClass('required');
|
|
valid = false;
|
|
} else {
|
|
validate[i].removeClass('required');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (valid) {
|
|
$('#marc-overlay-rules-form').submit();
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
$('#doremove').on('click', function(){
|
|
doSubmit('doremove');
|
|
});
|
|
$('#doedit').on('click', function(){
|
|
doSubmit('doedit', $("#doedit").attr('value'));
|
|
});
|
|
$('#add').on('click', function(){
|
|
doSubmit('add');
|
|
return false;
|
|
});
|
|
$('#btn_batchremove').on('click', function(){
|
|
doSubmit('remove');
|
|
});
|
|
|
|
/* Disable batch remove unless one or more checkboxes are checked */
|
|
$('input[name="batchremove"]').change(function() {
|
|
if($('input[name="batchremove"]:checked').length > 0) {
|
|
$('#btn_batchremove').removeAttr('disabled');
|
|
} else {
|
|
$('#btn_batchremove').attr('disabled', 'disabled');
|
|
}
|
|
});
|
|
|
|
$.fn.dataTable.ext.order['dom-input'] = function (settings, col) {
|
|
return this.api().column(col, { order: 'index' }).nodes()
|
|
.map(function (td, i) {
|
|
if($('input', td).val() != undefined) {
|
|
return $('input', td).val();
|
|
} else if($('select', td).val() != undefined) {
|
|
return $('option[selected="selected"]', td).val();
|
|
} else {
|
|
return $(td).html();
|
|
}
|
|
});
|
|
}
|
|
|
|
$('#marc-overlay-rules').dataTable($.extend(true, {}, dataTablesDefaults, {
|
|
"aoColumns": [
|
|
{"bSearchable": false, "bSortable": false},
|
|
{"sSortDataType": "dom-input"},
|
|
{"sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "sSortDataType": "dom-input"},
|
|
{"bSearchable": false, "bSortable": false},
|
|
{"bSearchable": false, "bSortable": false}
|
|
],
|
|
"pagingType": "simple"
|
|
}));
|
|
|
|
var overlay_rules_presets = {};
|
|
overlay_rules_presets[_("Protect")] = {
|
|
'add': 0,
|
|
'append': 0,
|
|
'remove': 0,
|
|
'delete': 0
|
|
};
|
|
overlay_rules_presets[_("Overwrite")] = {
|
|
'add': 1,
|
|
'append': 1,
|
|
'remove': 1,
|
|
'delete': 1
|
|
};
|
|
overlay_rules_presets[_("Add new")] = {
|
|
'add': 1,
|
|
'append': 0,
|
|
'remove': 0,
|
|
'delete': 0
|
|
};
|
|
overlay_rules_presets[_("Add and append")] = {
|
|
'add': 1,
|
|
'append': 1,
|
|
'remove': 0,
|
|
'delete': 0
|
|
};
|
|
overlay_rules_presets[_("Protect from deletion")] = {
|
|
'add': 1,
|
|
'append': 1,
|
|
'remove': 1,
|
|
'delete': 0
|
|
};
|
|
|
|
var overlay_rules_label_to_value = {};
|
|
overlay_rules_label_to_value[_("Add")] = 1;
|
|
overlay_rules_label_to_value[_("Append")] = 1;
|
|
overlay_rules_label_to_value[_("Remove")] = 1;
|
|
overlay_rules_label_to_value[_("Delete")] = 1;
|
|
overlay_rules_label_to_value[_("Skip")] = 0;
|
|
|
|
function hash_config(config) {
|
|
return JSON.stringify(config, Object.keys(config).sort());
|
|
}
|
|
|
|
var overlay_rules_preset_map = {};
|
|
$.each(overlay_rules_presets, function(preset, config) {
|
|
overlay_rules_preset_map[hash_config(config)] = preset;
|
|
});
|
|
|
|
function operations_config_overlay_rule_preset(config) {
|
|
return overlay_rules_preset_map[hash_config(config)] || '';
|
|
}
|
|
|
|
/* Set preset values according to operation config */
|
|
$('.rule').each(function() {
|
|
var $this = $(this);
|
|
var operations_config = {};
|
|
$('.rule-operation-action', $this).each(function() {
|
|
var $operation = $(this);
|
|
operations_config[$operation.data('operation')] = overlay_rules_label_to_value[$operation.text()];
|
|
});
|
|
$('.rule-preset', $this).text(
|
|
operations_config_overlay_rule_preset(operations_config) || _("Custom")
|
|
);
|
|
});
|
|
|
|
/* Listen to operations config changes and set presets accordingly */
|
|
$('.rule-operation-action-edit select').change(function() {
|
|
var operations_config = {};
|
|
var $parent_row = $(this).closest('tr');
|
|
$('.rule-operation-action-edit select', $parent_row).each(function() {
|
|
var $this = $(this);
|
|
operations_config[$this.attr('name')] = parseInt($this.val());
|
|
});
|
|
$('select[name="preset"]', $parent_row).val(
|
|
operations_config_overlay_rule_preset(operations_config)
|
|
);
|
|
});
|
|
|
|
/* Listen to preset changes and set operations config accordingly */
|
|
$('select[name="preset"]').change(function() {
|
|
var $this = $(this);
|
|
var $parent_row = $this.closest('tr');
|
|
var preset = $this.val();
|
|
if (preset) {
|
|
$.each(overlay_rules_presets[preset], function(operation, action) {
|
|
$('select[name="' + operation + '"]', $parent_row).val(action);
|
|
});
|
|
}
|
|
});
|
|
|
|
var module_filter_options = {
|
|
source: {
|
|
'*': '*',
|
|
batchmod: _("Batch record modification"),
|
|
intranet: _("Staff client MARC editor"),
|
|
batchimport: _("Staged MARC import"),
|
|
z3950: _("Z39.50"),
|
|
/* bulkmarcimport: _("bulkmarcimport.pl"), */
|
|
import_lexile: _("import_lexile.pl")
|
|
},
|
|
categorycode: {
|
|
'*': '*',
|
|
[% FOREACH categorycode IN categorycodes %]
|
|
[% categorycode.categorycode | html %]: "[% categorycode.description | html %]",
|
|
[% END %]
|
|
}
|
|
};
|
|
|
|
//Kind of hack: Replace filter value with label when one exist
|
|
$('.rule-module').each(function() {
|
|
var $this = $(this);
|
|
var module = $this.text();
|
|
if (module in module_filter_options) {
|
|
let $filter = $this.siblings('.rule-filter');
|
|
if ($filter.text() in module_filter_options[module]) {
|
|
$filter.text(module_filter_options[module][$filter.text()]);
|
|
}
|
|
}
|
|
});
|
|
|
|
var $filter_container = $('#filter-container');
|
|
|
|
/* Listen to module changes and set filter input accordingly */
|
|
$('select[name="module"]').change(function() {
|
|
var $this = $(this);
|
|
var module_name = $this.val();
|
|
|
|
/* Remove current element if any */
|
|
$filter_container.empty();
|
|
|
|
var filter_elem = null;
|
|
if (module_name in module_filter_options) {
|
|
// Create select element
|
|
filter_elem = document.createElement('select');
|
|
for (var filter_value in module_filter_options[module_name]) {
|
|
var option = document.createElement('option');
|
|
option.value = filter_value;
|
|
option.text = module_filter_options[module_name][filter_value];
|
|
filter_elem.appendChild(option);
|
|
}
|
|
}
|
|
else {
|
|
// Create text input element
|
|
filter_elem = document.createElement('input');
|
|
filter_elem.type = 'text';
|
|
filter_elem.setAttribute('size', 5);
|
|
}
|
|
filter_elem.name = 'filter';
|
|
filter_elem.id = 'filter';
|
|
$filter_container.append(filter_elem);
|
|
}).change(); // Trigger change
|
|
|
|
// Hack: set value if editing rule
|
|
if ($filter_container.data('filter')) {
|
|
$('#filter').val($filter_container.data('filter'));
|
|
}
|
|
|
|
});
|
|
</script>
|
|
[% END %]
|
|
[% INCLUDE 'intranet-bottom.inc' %]
|