From 0607e6adfa2dec9e92312303bfa1f11273eda39d Mon Sep 17 00:00:00 2001 From: Alex Arnaud Date: Wed, 7 Apr 2021 13:20:53 +0000 Subject: [PATCH] Bug 20388: Elasticsearch - Ability to add search fields from UI MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Test plan: - apply this patch, - check that SearchEngine system preference is set to Elasticsearch, - go to Admin > Search engine configuration, - on the search fields tab, fill a new line at the bottom of the table (name, label, type) - click on the "Add" button and save, - check that the new search field has been saved, - also test field deletions, - check that you can't delete already mapped fields. Signed-off-by: Nicolas Legrand Signed-off-by: Séverine QUEUNE Signed-off-by: Nick Clemens Signed-off-by: Björn Nylén Signed-off-by: Julian Maurice Signed-off-by: Michal Denar Signed-off-by: Michal Denar Signed-off-by: Michaela Sieber Signed-off-by: David Schmidt Signed-off-by: Nick Clemens Signed-off-by: Katrin Fischer --- Koha/SearchField.pm | 12 +++++ admin/searchengine/elasticsearch/mappings.pl | 11 ++-- .../searchengine/elasticsearch/mappings.tt | 51 ++++++++++++++++++- .../prog/js/elasticsearch-mappings.js | 50 +++++++++++++++++- t/db_dependent/Koha/SearchField.t | 31 ++++++++++- 5 files changed, 148 insertions(+), 7 deletions(-) diff --git a/Koha/SearchField.pm b/Koha/SearchField.pm index 32fa405430..be7b094f9b 100644 --- a/Koha/SearchField.pm +++ b/Koha/SearchField.pm @@ -68,6 +68,18 @@ sub search_marc_maps { return $marc_map_fields; } +=head3 is_mapped + +my $is_mapped = $search_field->is_mapped + +=cut + +sub is_mapped { + my ( $self ) = @_; + + return $self->search_marc_maps()->count ? 1 : 0; +} + =head3 is_mapped_biblios my $is_mapped_biblios = $search_field->is_mapped_biblios diff --git a/admin/searchengine/elasticsearch/mappings.pl b/admin/searchengine/elasticsearch/mappings.pl index dc2fa3149e..9d0ae806e2 100755 --- a/admin/searchengine/elasticsearch/mappings.pl +++ b/admin/searchengine/elasticsearch/mappings.pl @@ -109,6 +109,8 @@ if ( $op eq 'cud-edit' ) { eval { + Koha::SearchFields->search()->delete; + for my $i ( 0 .. scalar(@field_name) - 1 ) { my $field_name = $field_name[$i]; my $field_label = $field_label[$i]; @@ -117,9 +119,11 @@ if ( $op eq 'cud-edit' ) { my $field_staff_client = $field_staff_client[$i]; my $field_opac = $field_opac[$i]; - my $search_field = Koha::SearchFields->find( { name => $field_name }, { key => 'name' } ); - $search_field->label($field_label); - $search_field->type($field_type); + my $search_field = Koha::SearchFields->find_or_create({ + name => $field_name, + label => $field_label, + type => $field_type, + }); if (!length($field_weight)) { $search_field->weight(undef); @@ -285,6 +289,7 @@ my @all_search_fields; while ( my $search_field = $search_fields->next ) { my $search_field_unblessed = $search_field->unblessed; $search_field_unblessed->{mapped_biblios} = 1 if $search_field->is_mapped_biblios; + $search_field_unblessed->{is_mapped} = $search_field->is_mapped; $search_field_unblessed->{aliases} = $search_fields_aliases->{$search_field_unblessed->{name}}; push @all_search_fields, $search_field_unblessed; } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt index 5975c70596..fb25bed28e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt @@ -133,7 +133,7 @@ a.add, a.delete { [% WRAPPER tab_panels %] [% WRAPPER tab_panel tabname="search_fields" bt_active= 1 %] - +
@@ -142,11 +142,13 @@ a.add, a.delete { + + @@ -253,9 +255,56 @@ a.add, a.delete { [% END %] + [% END %] + + + + + + + + + + + +
NameType Weight Searchable 
  Staff interface OPAC 
+ [% IF search_field.is_mapped %] + Delete + [% ELSE %] + Delete + [% END %] +
+ + + + + + + + + + + + Add
[% END %] [% FOREACH index IN indexes %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js b/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js index b40fec0f45..db67f7fd53 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js +++ b/koha-tmpl/intranet-tmpl/prog/js/elasticsearch-mappings.js @@ -14,6 +14,7 @@ function clone_line(line) { $(new_line).find("select").each(function () { var attr = $(this).attr('name'); var val = $(line).find('[data-id="' + attr + '"]').val(); + $(this).find('option').removeAttr('selected'); $(this).find('option[value="' + val + '"]').attr("selected", "selected"); }); return new_line; @@ -46,7 +47,7 @@ $(document).ready(function () { tableInit( oldtabid, newtabid ); }); - $('.delete').click(function () { + $(document).on('click', '.delete', function() { if ($(this).hasClass('mandatory') && $(".mandatory[data-field_name=" + $(this).attr('data-field_name') + "]").length < 2) { alert( __("This field is mandatory and must have at least one mapping") ); return; @@ -54,6 +55,25 @@ $(document).ready(function () { var table = $(this).closest('table'); let dt = $(table).DataTable(); dt.row( $(this).closest('tr') ).remove().draw(); + $(this).parents('tr').remove(); + var line = $(this).closest("tr"); + + var name; + // We clicked delete button on search fields tab. + if (name = $(line).find('input[name="search_field_name"]').val()) { + // Prevent user from using a search field for a mapping + // after removing it without saving. + $('select[data-id="mapping_search_field_name"]').each(function( index, element) { + $(element).find('option[value="' + name + '"]').remove(); + }); + } + + var search_field_name = $(line).find('input[name="mapping_search_field_name"]').val(); + var mappings = $('input[name="mapping_search_field_name"][type="hidden"][value="' + search_field_name + '"]'); + if (mappings.length == 0) { + var search_field_line = $('input[name="search_field_name"][value="' + search_field_name + '"]').closest("tr"); + $(search_field_line).find('a.btn-default').removeClass('disabled'); + } } }); @@ -65,10 +85,16 @@ $(document).ready(function () { var marc_field = $(line).find('input[data-id="mapping_marc_field"]').val(); if (marc_field.length > 0) { var new_line = clone_line(line); + var search_field_name = $(line).find('select[data-id="mapping_search_field_name"] option:selected').text(); new_line.appendTo($('table[data-index_name="' + index_name + '"]>tbody')); let dt = $('#' + table_id).DataTable(); dt.row.add(new_line).draw(); + var search_field_line = $('input[name="search_field_name"][value="' + search_field_name + '"]').closest("tr"); + $(search_field_line).find('a.btn-default').addClass('disabled'); + + clean_line(line); + $(table).on( 'click', '.delete', function () { var table = $(this).closest('table'); let dt = $(table).DataTable(); @@ -99,4 +125,26 @@ $(document).ready(function () { }); return true; }); + + $('.add-search-field').click(function() { + var table = $(this).closest('table'); + var line = $(this).closest("tr"); + var name = $(line).find('input[data-id="search_field_name"]').val(); + let already_exist = 0; + + if ( $('input[name="search_field_name"][value="' + name + '"]').val() ) { + already_exist = 1; + } + + if (already_exist) { + alert("SearchField "+ name + " already exist"); + } else { + var label = $(line).find('input[data-id="search_field_label"]').val(); + if ( name.length > 0 && label.length > 0 ) { + var new_line = clone_line( line ); + new_line.appendTo(table.find('tbody')); + clean_line(line); + } + } + }); }); diff --git a/t/db_dependent/Koha/SearchField.t b/t/db_dependent/Koha/SearchField.t index 8212d18064..d2394fcc87 100755 --- a/t/db_dependent/Koha/SearchField.t +++ b/t/db_dependent/Koha/SearchField.t @@ -19,10 +19,11 @@ use Modern::Perl; -use Test::More tests => 10; +use Test::More tests => 12; use Koha::Database; use Koha::SearchFields; +use Koha::SearchMarcMaps; use t::lib::Mocks; use t::lib::TestBuilder; @@ -38,6 +39,32 @@ my $sf = $builder->build({ source => 'SearchField', }); +my $search_field = Koha::SearchFields->find($sf->{id}); +ok(!$search_field->is_mapped, 'Search field 1 is not mapped'); + +my $auth_smm = $builder->build({ + source => 'SearchMarcMap', + value => { + index_name => 'authorities', + marc_type => 'marc21', + marc_field => '200abde' + } +}); + +my $auth_smtf = $builder->build({ + source => 'SearchMarcToField', + value => { + search_marc_map_id => $auth_smm->{id}, + search_field_id => $sf->{id} + } +}); + +$search_field = Koha::SearchFields->find($sf->{id}); +ok($search_field->is_mapped, 'Search field 1 is mapped'); + +Koha::SearchMarcMaps->search({})->delete; +$schema->resultset('SearchMarcToField')->search({})->delete; + my $smm = $builder->build({ source => 'SearchMarcMap', value => { @@ -72,7 +99,7 @@ my $smtf2 = $builder->build({ } }); -my $search_field = Koha::SearchFields->find($sf->{id}); +$search_field = Koha::SearchFields->find($sf->{id}); my $marc_maps = $search_field->search_marc_maps; my $marc_map = $marc_maps->next; is($marc_maps->count, 1, 'search_marc_maps should return 1 marc map'); -- 2.39.5