View | Details | Raw Unified | Return to bug 19482
Collapse All | Expand All

(-)a/Koha/SearchEngine/Elasticsearch.pm (-1 / +1 lines)
Lines 355-361 sub reset_elasticsearch_mappings { Link Here
355
    while ( my ( $index_name, $fields ) = each %$indexes ) {
355
    while ( my ( $index_name, $fields ) = each %$indexes ) {
356
        while ( my ( $field_name, $data ) = each %$fields ) {
356
        while ( my ( $field_name, $data ) = each %$fields ) {
357
357
358
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight staff_client opac facet_order /;
358
            my %sf_params = map { $_ => $data->{$_} } grep { exists $data->{$_} } qw/ type label weight staff_client opac facet_order mandatory/;
359
359
360
            # Set default values
360
            # Set default values
361
            $sf_params{staff_client} //= 1;
361
            $sf_params{staff_client} //= 1;
(-)a/admin/searchengine/elasticsearch/mappings.pl (-1 / +8 lines)
Lines 133-138 if ( $op eq 'edit' ) { Link Here
133
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
133
        my @facetable_fields = Koha::SearchEngine::Elasticsearch->get_facetable_fields();
134
        my @facetable_field_names = map { $_->name } @facetable_fields;
134
        my @facetable_field_names = map { $_->name } @facetable_fields;
135
135
136
        my $mandatory_before = Koha::SearchFields->search({mandatory=>1})->count;
137
        my $mandatory_after  = 0;
138
        my %seen_fields;
136
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
139
        for my $i ( 0 .. scalar(@index_name) - 1 ) {
137
            my $index_name          = $index_name[$i];
140
            my $index_name          = $index_name[$i];
138
            my $search_field_name   = $search_field_name[$i];
141
            my $search_field_name   = $search_field_name[$i];
Lines 144-149 if ( $op eq 'edit' ) { Link Here
144
            my $mapping_search      = $mapping_search[$i];
147
            my $mapping_search      = $mapping_search[$i];
145
148
146
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
149
            my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' });
150
            $mandatory_after++ if $search_field->mandatory && !defined $seen_fields{$search_field_name};
151
            $seen_fields{$search_field_name} = 1;
147
            # TODO Check mapping format
152
            # TODO Check mapping format
148
            my $marc_field = Koha::SearchMarcMaps->find_or_create({
153
            my $marc_field = Koha::SearchMarcMaps->find_or_create({
149
                index_name => $index_name,
154
                index_name => $index_name,
Lines 157-164 if ( $op eq 'edit' ) { Link Here
157
                search => $mapping_search
162
                search => $mapping_search
158
            });
163
            });
159
        }
164
        }
165
        push @messages, { type => 'error', code => 'missing_mandatory_fields' } if $mandatory_after < $mandatory_before;
160
    };
166
    };
161
    if ($@) {
167
    if ($@ || @messages) {
162
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
168
        push @messages, { type => 'error', code => 'error_on_update', message => $@, };
163
        $schema->storage->txn_rollback;
169
        $schema->storage->txn_rollback;
164
    } else {
170
    } else {
Lines 237-242 for my $index_name (@index_names) { Link Here
237
            search_field_name  => $name,
243
            search_field_name  => $name,
238
            search_field_label => $s->label,
244
            search_field_label => $s->label,
239
            search_field_type  => $s->type,
245
            search_field_type  => $s->type,
246
            search_field_mandatory  => $s->mandatory,
240
            marc_field         => $s->get_column('marc_field'),
247
            marc_field         => $s->get_column('marc_field'),
241
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
248
            sort               => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc"
242
            suggestible        => $s->get_column('suggestible'),
249
            suggestible        => $s->get_column('suggestible'),
(-)a/admin/searchengine/elasticsearch/mappings.yaml (+2 lines)
Lines 2233-2238 biblios: Link Here
2233
        sort: 1
2233
        sort: 1
2234
        suggestible: ''
2234
        suggestible: ''
2235
    type: sum
2235
    type: sum
2236
    mandatory: 1
2236
  itemnumber:
2237
  itemnumber:
2237
    label: itemnumber
2238
    label: itemnumber
2238
    mappings:
2239
    mappings:
Lines 4196-4201 biblios: Link Here
4196
        sort: ~
4197
        sort: ~
4197
        suggestible: ''
4198
        suggestible: ''
4198
    type: string
4199
    type: string
4200
    mandatory: 1
4199
  title-abbreviated:
4201
  title-abbreviated:
4200
    label: title-abbreviated
4202
    label: title-abbreviated
4201
    mappings:
4203
    mappings:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt (-107 / +151 lines)
Lines 29-35 Link Here
29
    $(document).ready(function() {
29
    $(document).ready(function() {
30
        $("#tabs").tabs();
30
        $("#tabs").tabs();
31
        $('.delete').click(function() {
31
        $('.delete').click(function() {
32
            $(this).parents('tr').remove();
32
            if( $(this).hasClass('mandatory') && $(".mandatory[data-field_name="+$(this).attr('data-field_name')+"]").length < 2 ){
33
                alert("This field is mandatory and must have at least one mapping");
34
                return;
35
            } else {
36
                $(this).parents('tr').remove();
37
            }
33
        });
38
        });
34
39
35
        $("table.mappings").tableDnD( {
40
        $("table.mappings").tableDnD( {
Lines 87-92 a.add, a.delete { Link Here
87
          [% tx("(search field {field_name} with mapping {marc_field}.)", { field_name = m.values.field_name, marc_field = m.values.marc_field }) | html %]
92
          [% tx("(search field {field_name} with mapping {marc_field}.)", { field_name = m.values.field_name, marc_field = m.values.marc_field }) | html %]
88
        [% CASE 'invalid_field_weight' %]
93
        [% CASE 'invalid_field_weight' %]
89
          [% tx("Invalid field weight '{weight}', must be a positive decimal number.", { weight = m.weight }) | html %]
94
          [% tx("Invalid field weight '{weight}', must be a positive decimal number.", { weight = m.weight }) | html %]
95
        [% CASE 'missing_mandatory_fields' %]
96
          [% t("You attempted to delete all mappings for a required index, you must leave at least one mapping") | $raw %]
90
        [% CASE 'error_on_update_es_mappings' %]
97
        [% CASE 'error_on_update_es_mappings' %]
91
          [% tx("An error occurred when updating Elasticsearch index mappings: {message}.", { message = m.message }) | html %]
98
          [% tx("An error occurred when updating Elasticsearch index mappings: {message}.", { message = m.message }) | html %]
92
        [% CASE 'reindex_required' %]
99
        [% CASE 'reindex_required' %]
Lines 176-227 a.add, a.delete { Link Here
176
                </thead>
183
                </thead>
177
                <tbody>
184
                <tbody>
178
                  [% FOREACH search_field IN all_search_fields %]
185
                  [% FOREACH search_field IN all_search_fields %]
186
                      [% IF search_field.mandatory %]
187
                          [% SET is_readonly = "readonly" %]
188
                      [% ELSE %]
189
                          [% SET is_readonly = "" %]
190
                      [% END %]
179
                    <tr>
191
                    <tr>
180
                      <td>
192
                      <td>
181
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" />
193
                        <input type="text" name="search_field_name" value="[% search_field.name | html %]" [% is_readonly %]/>
182
                      </td>
194
                      </td>
183
                      <td>
195
                      <td>
184
                        <input type="text" name="search_field_label" value="[% search_field.label | html %]" />
196
                        <input type="text" name="search_field_label" value="[% search_field.label | html %]" [% is_readonly %]/>
185
                      </td>
186
                      <td>
197
                      <td>
187
                        <select name="search_field_type">
198
                        [% IF is_readonly %]
188
                          <option value=""></option>
199
                            <input type="hidden" name="search_field_type" value="[% search_field.type | html %]" />
189
                          [% IF search_field.type == "string" %]
200
                            <select name="search_field_type" disabled>
190
                            <option value="string" selected="selected">String</option>
201
                        [% ELSE %]
191
                          [% ELSE %]
202
                            <select name="search_field_type">
192
                            <option value="string">String</option>
203
                              <option value=""></option>
193
                          [% END %]
204
                              [% IF search_field.type == "string" %]
194
                          [% IF search_field.type == "date" %]
205
                                <option value="string" selected="selected">String</option>
195
                            <option value="date" selected="selected">Date</option>
206
                              [% ELSE %]
196
                          [% ELSE %]
207
                                <option value="string">String</option>
197
                            <option value="date">Date</option>
208
                              [% END %]
198
                          [% END %]
209
                              [% IF search_field.type == "date" %]
199
                          [% IF search_field.type == "number" %]
210
                                <option value="date" selected="selected">Date</option>
200
                            <option value="number" selected="selected">Number</option>
211
                              [% ELSE %]
201
                          [% ELSE %]
212
                                <option value="date">Date</option>
202
                            <option value="number">Number</option>
213
                              [% END %]
203
                          [% END %]
214
                              [% IF search_field.type == "number" %]
204
                          [% IF search_field.type == "boolean" %]
215
                                <option value="number" selected="selected">Number</option>
205
                            <option value="boolean" selected="selected">Boolean</option>
216
                              [% ELSE %]
206
                          [% ELSE %]
217
                                <option value="number">Number</option>
207
                            <option value="boolean">Boolean</option>
218
                              [% END %]
208
                          [% END %]
219
                              [% IF search_field.type == "boolean" %]
209
                          [% IF search_field.type == "sum" %]
220
                                <option value="boolean" selected="selected">Boolean</option>
210
                            <option value="sum" selected="selected">Sum</option>
221
                              [% ELSE %]
211
                          [% ELSE %]
222
                                <option value="boolean">Boolean</option>
212
                            <option value="sum">Sum</option>
223
                              [% END %]
213
                          [% END %]
224
                              [% IF search_field.type == "sum" %]
214
                          [% IF search_field.type == "isbn" %]
225
                                <option value="sum" selected="selected">Sum</option>
215
                            <option value="isbn" selected="selected">ISBN</option>
226
                              [% ELSE %]
216
                          [% ELSE %]
227
                                <option value="sum">Sum</option>
217
                            <option value="isbn">ISBN</option>
228
                              [% END %]
218
                          [% END %]
229
                              [% IF search_field.type == "isbn" %]
219
                          [% IF search_field.type == "stdno" %]
230
                                <option value="isbn" selected="selected">ISBN</option>
220
                            <option value="stdno" selected="selected">Std. Number</option>
231
                              [% ELSE %]
221
                          [% ELSE %]
232
                                <option value="isbn">ISBN</option>
222
                            <option value="stdno">Std. Number</option>
233
                              [% END %]
223
                          [% END %]
234
                              [% IF search_field.type == "stdno" %]
224
                        </select>
235
                                <option value="stdno" selected="selected">Std. Number</option>
236
                              [% ELSE %]
237
                                <option value="stdno">Std. Number</option>
238
                              [% END %]
239
                            </select>
240
                        [% END %]
225
                      </td>
241
                      </td>
226
                      <td>
242
                      <td>
227
                        <select name="search_field_staff_client">
243
                        <select name="search_field_staff_client">
Lines 273-346 a.add, a.delete { Link Here
273
                      </thead>
289
                      </thead>
274
                      <tbody>
290
                      <tbody>
275
                        [% FOREACH mapping IN index.mappings %]
291
                        [% FOREACH mapping IN index.mappings %]
276
                          <tr>
292
                            [% IF mapping.search_field_mandatory && mapping.search_field_label != loop.next.search_field_label && mapping.search_field_label != loop.prev.search_field_label %]
277
                            <td>
293
                              <tr>
278
                              <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
294
                                <td>
279
                              <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
295
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
280
                              [% mapping.search_field_label | html %]
296
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
281
                            </td>
297
                                  [% mapping.search_field_label | html %]
282
                            <td>
298
                                </td>
283
                              <select name="mapping_sort">
299
                                <td>
284
                                [% IF mapping.sort == 'undef' %]
300
                                  <input type="hidden" name="mapping_sort" value="[% mapping.sort | html %]" readonly />[% IF mapping.sort == 'undef' %]Undef[% ELSE %][% mapping.sort | html %][% END %]
285
                                  <option value="undef" selected="selected">Undef</option>
301
                                </td>
286
                                [% ELSE %]
302
                                <td>
287
                                  <option value="undef">Undef</option>
303
                                  <input type="hidden" name="mapping_facet" value="[% mapping.facet | html %]" readonly />[% IF mapping.facet == 1 %]Yes[% ELSE %]No[% END %]
288
                                [% END %]
304
                                </td>
289
                                [% IF mapping.sort == 0 %]
305
                                <td>
290
                                  <option value="0" selected="selected">0</option>
306
                                  <input type="hidden" name="mapping_suggestible" value="[% mapping.suggestible | html %]" readonly />[% IF mapping.suggestible == 1 %]Yes[% ELSE %]No[% END %]
291
                                [% ELSE %]
307
                                </td>
292
                                  <option value="0">0</option>
308
                                <td>
293
                                [% END %]
309
                                  <input type="hidden" name="mapping_search" value="[% mapping.search | html %]" readonly />[% IF mapping.search == 1 %]Yes[% ELSE %]No[% END %]
294
                                [% IF  mapping.sort == 1 %]
310
                                </td>
295
                                  <option value="1" selected="selected">1</option>
311
                                <td>
296
                                [% ELSE %]
312
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
297
                                  <option value="1">1</option>
313
                                </td>
298
                                [% END %]
314
                              </tr>
299
                              </select>
315
                            [% ELSE %]
300
                            </td>
316
                              <tr>
301
                            <td>
317
                                <td>
302
                              [% IF mapping.is_facetable %]
318
                                  <input type="hidden" name="mapping_index_name" value="[% index.index_name | html %]" />
303
                                <select name="mapping_facet">
319
                                  <input type="hidden" name="mapping_search_field_name" value="[% mapping.search_field_name | html %]">
304
                                  [% IF mapping.facet %]
320
                                  [% mapping.search_field_label | html %]
305
                                    <option value="0">No</option>
321
                                </td>
306
                                    <option value="1" selected="selected">Yes</option>
322
                                <td>
323
                                  <select name="mapping_sort">
324
                                    [% IF mapping.sort == 'undef' %]
325
                                      <option value="undef" selected="selected">Undef</option>
326
                                    [% ELSE %]
327
                                      <option value="undef">Undef</option>
328
                                    [% END %]
329
                                    [% IF mapping.sort == 0 %]
330
                                      <option value="0" selected="selected">0</option>
331
                                    [% ELSE %]
332
                                      <option value="0">0</option>
333
                                    [% END %]
334
                                    [% IF  mapping.sort == 1 %]
335
                                      <option value="1" selected="selected">1</option>
336
                                    [% ELSE %]
337
                                      <option value="1">1</option>
338
                                    [% END %]
339
                                  </select>
340
                                </td>
341
                                <td>
342
                                  [% IF mapping.is_facetable %]
343
                                    <select name="mapping_facet">
344
                                      [% IF mapping.facet %]
345
                                        <option value="0">No</option>
346
                                        <option value="1" selected="selected">Yes</option>
347
                                      [% ELSE %]
348
                                        <option value="0" selected="selected">No</option>
349
                                        <option value="1">Yes</option>
350
                                      [% END %]
351
                                    </select>
307
                                  [% ELSE %]
352
                                  [% ELSE %]
308
                                    <option value="0" selected="selected">No</option>
353
                                    <input type="hidden" name="mapping_facet" value="0" />
309
                                    <option value="1">Yes</option>
354
                                    No
310
                                  [% END %]
355
                                  [% END %]
311
                                </select>
356
                                </td>
312
                              [% ELSE %]
357
                                <td>
313
                                <input type="hidden" name="mapping_facet" value="0" />
358
                                  <select name="mapping_suggestible">
314
                                No
359
                                    [% IF mapping.suggestible %]
315
                              [% END %]
360
                                      <option value="0">No</option>
316
                            </td>
361
                                      <option value="1" selected="selected">Yes</option>
317
                            <td>
362
                                    [% ELSE %]
318
                              <select name="mapping_suggestible">
363
                                      <option value="0" selected="selected">No</option>
319
                                [% IF mapping.suggestible %]
364
                                      <option value="1">Yes</option>
320
                                  <option value="0">No</option>
365
                                    [% END %]
321
                                  <option value="1" selected="selected">Yes</option>
366
                                  </select>
322
                                [% ELSE %]
367
                                </td>
323
                                  <option value="0" selected="selected">No</option>
368
                                <td>
324
                                  <option value="1">Yes</option>
369
                                  <select name="mapping_search">
325
                                [% END %]
370
                                    [% IF mapping.search %]
326
                              </select>
371
                                      <option value="0">No</option>
327
                            </td>
372
                                      <option value="1" selected="selected">Yes</option>
328
                            <td>
373
                                    [% ELSE %]
329
                              <select name="mapping_search">
374
                                      <option value="0" selected="selected">No</option>
330
                                [% IF mapping.search %]
375
                                      <option value="1">Yes</option>
331
                                  <option value="0">No</option>
376
                                    [% END %]
332
                                  <option value="1" selected="selected">Yes</option>
377
                                  </select>
378
                                </td>
379
                                <td>
380
                                    <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
381
                                </td>
382
                                [% IF mapping.search_field_mandatory %]
383
                                    <td><a class="btn btn-default btn-xs delete mandatory" data-field_name="[% mapping.search_field_name %]" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
333
                                [% ELSE %]
384
                                [% ELSE %]
334
                                  <option value="0" selected="selected">No</option>
385
                                    <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
335
                                  <option value="1">Yes</option>
336
                                [% END %]
386
                                [% END %]
337
                              </select>
387
                              </tr>
338
                            </td>
388
                            [% END %]
339
                            <td>
340
                                <input name="mapping_marc_field" type="text" value="[% mapping.marc_field | html %]" />
341
                            </td>
342
                            <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td>
343
                          </tr>
344
                        [% END %]
389
                        [% END %]
345
                      </tbody>
390
                      </tbody>
346
                      <tfoot>
391
                      <tfoot>
347
- 

Return to bug 19482