blacklight 7.12.0 → 7.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +109 -0
  3. data/.rubocop.yml +3 -0
  4. data/README.md +1 -1
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/blacklight/blacklight.js +4 -2
  7. data/app/components/blacklight/constraints_component.rb +14 -6
  8. data/app/components/blacklight/document/thumbnail_component.html.erb +1 -1
  9. data/app/components/blacklight/document/thumbnail_component.rb +1 -1
  10. data/app/components/blacklight/document_component.html.erb +1 -0
  11. data/app/components/blacklight/document_component.rb +14 -1
  12. data/app/components/blacklight/facet_field_component.html.erb +1 -0
  13. data/app/components/blacklight/facet_field_pagination_component.html.erb +4 -4
  14. data/app/components/blacklight/facet_field_pagination_component.rb +0 -4
  15. data/app/components/blacklight/hidden_search_state_component.rb +54 -0
  16. data/app/components/blacklight/search_bar_component.html.erb +10 -8
  17. data/app/components/blacklight/search_bar_component.rb +14 -1
  18. data/app/controllers/concerns/blacklight/catalog.rb +3 -3
  19. data/app/controllers/concerns/blacklight/search_context.rb +2 -2
  20. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  21. data/app/helpers/blacklight/blacklight_helper_behavior.rb +1 -1
  22. data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
  23. data/app/helpers/blacklight/configuration_helper_behavior.rb +3 -9
  24. data/app/helpers/blacklight/facets_helper_behavior.rb +8 -2
  25. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +2 -38
  26. data/app/helpers/blacklight/icon_helper_behavior.rb +1 -1
  27. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +7 -5
  28. data/app/helpers/blacklight/render_partials_helper_behavior.rb +2 -2
  29. data/app/javascript/blacklight/button_focus.js +1 -0
  30. data/app/javascript/blacklight/modal.js +10 -4
  31. data/app/presenters/blacklight/document_presenter.rb +4 -0
  32. data/app/presenters/blacklight/facet_item_presenter.rb +7 -3
  33. data/app/presenters/blacklight/index_presenter.rb +2 -2
  34. data/app/presenters/blacklight/rendering/link_to_facet.rb +3 -1
  35. data/app/presenters/blacklight/show_presenter.rb +0 -4
  36. data/app/services/blacklight/search_service.rb +13 -11
  37. data/app/values/blacklight/types.rb +1 -1
  38. data/app/views/bookmarks/_tools.html.erb +1 -1
  39. data/app/views/catalog/_search_form.html.erb +1 -1
  40. data/app/views/catalog/index.json.jbuilder +3 -1
  41. data/blacklight.gemspec +5 -4
  42. data/lib/blacklight/configuration/facet_field.rb +7 -0
  43. data/lib/blacklight/configuration/fields.rb +1 -1
  44. data/lib/blacklight/configuration/search_field.rb +5 -0
  45. data/lib/blacklight/configuration/tool_config.rb +4 -0
  46. data/lib/blacklight/configuration/view_config.rb +12 -0
  47. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  48. data/lib/blacklight/search_builder.rb +13 -23
  49. data/lib/blacklight/search_state.rb +82 -70
  50. data/lib/blacklight/search_state/filter_field.rb +122 -0
  51. data/lib/blacklight/solr/repository.rb +3 -3
  52. data/lib/blacklight/solr/response.rb +1 -1
  53. data/lib/blacklight/solr/search_builder_behavior.rb +71 -51
  54. data/package.json +5 -1
  55. data/spec/components/blacklight/constraint_layout_component_spec.rb +1 -1
  56. data/spec/components/blacklight/document_component_spec.rb +17 -0
  57. data/spec/components/blacklight/hidden_search_state_component_spec.rb +24 -0
  58. data/spec/features/facets_spec.rb +2 -17
  59. data/spec/features/search_filters_spec.rb +0 -20
  60. data/spec/features/search_spec.rb +0 -5
  61. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +1 -2
  62. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +1 -0
  63. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -0
  64. data/spec/lib/blacklight/configuration/view_config_spec.rb +15 -0
  65. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +9 -0
  66. data/spec/lib/blacklight/search_state/filter_field_spec.rb +125 -0
  67. data/spec/lib/blacklight/search_state_spec.rb +132 -3
  68. data/spec/models/blacklight/configuration_spec.rb +8 -0
  69. data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
  70. data/spec/models/blacklight/solr/search_builder_spec.rb +32 -2
  71. data/spec/spec_helper.rb +8 -3
  72. data/spec/test_app_templates/Gemfile.extra +1 -1
  73. data/spec/views/catalog/_document.html.erb_spec.rb +1 -0
  74. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +2 -0
  75. data/tasks/blacklight.rake +3 -3
  76. metadata +50 -29
  77. data/.npmignore +0 -23
  78. data/.travis.yml +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 795afb3fdb4a13aa033d1b37180537e51ebfd53ab8f0ef894d05b6370b1c1238
4
- data.tar.gz: 003ccd0c42c44636d463df31c141a7b9b6ab1276bab6d771d1637d2eb7ff17fc
3
+ metadata.gz: 125e5713e43315d9fdbae35677048bb1a1bb9830970f8ff43101ecaed9979385
4
+ data.tar.gz: 34d83a1474edd010642bc2ddf9f72a5409dd66f80bd28f3e6576fafdaa119475
5
5
  SHA512:
6
- metadata.gz: 1e9cdd317ae4535217bc98930c09095ca8aaebe01124863b6a507a2c9bfbd4851a18d72f139bbb6c2f152094e1cb3cf3462eea26747f3212dc484c24603f6ec4
7
- data.tar.gz: a7f142dbaaabff9a9477d116ccd283ab67b2e72fb6d5f0c0482b495ed57f69486aa73f3ef6f67b31f0d00316d1dfb0b61fffaae08ebd1208aebae18a495c9746
6
+ metadata.gz: ab411c9cd2690a01b3d61fa1c8f602b910686b920e26ac638eddfb08e4b43af86d6beca036509056f510a2d56041059dadcfa0ee92cccedcbe238bfe5d7abc4b
7
+ data.tar.gz: ed2cea2667023dbe7720c4939f4dc4b3cd98d26be0e7a1bc89dba416d0b077bf3792b810fe9e479ef5890f2cad3b3003154822778722b5528051df106f570e51
@@ -0,0 +1,109 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: CI
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ lint:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: 2.7
25
+ - name: Install dependencies
26
+ run: bundle install
27
+ - name: Run linter
28
+ run: bundle exec rake rubocop
29
+ test:
30
+ runs-on: ubuntu-latest
31
+ strategy:
32
+ matrix:
33
+ ruby: [2.7, 3.0]
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - name: Set up Ruby
37
+ uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ - name: Install dependencies
41
+ run: bundle install
42
+ - name: Run tests
43
+ run: bundle exec rake ci
44
+ env:
45
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
46
+ test_rails6_0:
47
+ runs-on: ubuntu-latest
48
+ strategy:
49
+ matrix:
50
+ ruby: [2.6]
51
+ steps:
52
+ - uses: actions/checkout@v2
53
+ - name: Set up Ruby
54
+ uses: ruby/setup-ruby@v1
55
+ with:
56
+ ruby-version: ${{ matrix.ruby }}
57
+ - name: Install dependencies
58
+ run: bundle install
59
+ env:
60
+ RAILS_VERSION: 6.0.3.4
61
+ - name: Run tests
62
+ run: bundle exec rake ci
63
+ env:
64
+ RAILS_VERSION: 6.0.3.4
65
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
66
+ test_rails5_2:
67
+ runs-on: ubuntu-latest
68
+ strategy:
69
+ matrix:
70
+ ruby: [2.5]
71
+ steps:
72
+ - uses: actions/checkout@v2
73
+ - name: Set up Ruby
74
+ uses: ruby/setup-ruby@v1
75
+ with:
76
+ ruby-version: ${{ matrix.ruby }}
77
+ - name: Install dependencies
78
+ run: bundle install
79
+ env:
80
+ RAILS_VERSION: 5.2.4.2
81
+ - name: Run tests
82
+ run: bundle exec rake ci
83
+ env:
84
+ RAILS_VERSION: 5.2.4.2
85
+ ENGINE_CART_RAILS_OPTIONS: '--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test'
86
+ api_test:
87
+ runs-on: ubuntu-latest
88
+ strategy:
89
+ matrix:
90
+ ruby: [2.7]
91
+ steps:
92
+ - uses: actions/checkout@v2
93
+ - name: Set up Ruby
94
+ uses: ruby/setup-ruby@v1
95
+ with:
96
+ ruby-version: ${{ matrix.ruby }}
97
+ - name: Install dependencies
98
+ run: bundle install
99
+ - name: Run tests
100
+ run: bundle exec rake ci
101
+ env:
102
+ BLACKLIGHT_API_TEST: true
103
+ ENGINE_CART_RAILS_OPTIONS: '--api --skip-git --skip-bundle --skip-listen --skip-spring --skip-yarn --skip-keeps --skip-action-cable --skip-coffee --skip-test'
104
+ docker_build:
105
+ runs-on: ubuntu-latest
106
+ steps:
107
+ - uses: actions/checkout@v2
108
+ - name: Build docker image
109
+ run: docker-compose build app
@@ -37,6 +37,8 @@ Metrics/BlockLength:
37
37
  Metrics/ClassLength:
38
38
  Exclude:
39
39
  - "lib/blacklight/configuration.rb"
40
+ - "lib/blacklight/search_builder.rb"
41
+ - "lib/blacklight/search_state.rb"
40
42
 
41
43
  Layout/LineLength:
42
44
  Max: 200
@@ -46,6 +48,7 @@ Layout/LineLength:
46
48
  Metrics/ModuleLength:
47
49
  Exclude:
48
50
  - 'app/controllers/concerns/blacklight/catalog.rb'
51
+ - 'lib/blacklight/solr/search_builder_behavior.rb'
49
52
 
50
53
  Naming/HeredocDelimiterNaming:
51
54
  Enabled: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Blacklight
2
2
 
3
- [![Build Status](https://travis-ci.org/projectblacklight/blacklight.png?branch=master)](https://travis-ci.org/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Test Coverage](https://api.codeclimate.com/v1/badges/83fd270492c136594e59/test_coverage)](https://codeclimate.com/github/projectblacklight/blacklight/test_coverage)
3
+ [![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=master)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Test Coverage](https://api.codeclimate.com/v1/badges/83fd270492c136594e59/test_coverage)](https://codeclimate.com/github/projectblacklight/blacklight/test_coverage)
4
4
 
5
5
  Blacklight is an open source Solr user interface discovery platform.
6
6
  You can use Blacklight to enable searching and browsing of your collections.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.12.0
1
+ 7.14.0
@@ -99,6 +99,7 @@ Blacklight.onLoad(function () {
99
99
  Blacklight.onLoad(function () {
100
100
  // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
101
101
  // Safari both do not set focus to a button on button click.
102
+ // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
102
103
  document.querySelectorAll('button.collapse-toggle').forEach(button => {
103
104
  button.addEventListener('click', () => {
104
105
  event.target.focus();
@@ -349,8 +350,9 @@ Blacklight.modal.modalCloseSelector = '[data-blacklight-modal~=close]'; // Calle
349
350
  // to show to user in modal. Right now called only for extreme
350
351
  // network errors.
351
352
 
352
- Blacklight.modal.onFailure = function (data) {
353
- var contents = '<div class="modal-header">' + '<div class="modal-title">Network Error</div>' + '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button>';
353
+ Blacklight.modal.onFailure = function (jqXHR, textStatus, errorThrown) {
354
+ console.error('Server error:', this.url, jqXHR.status, errorThrown);
355
+ var contents = '<div class="modal-header">' + '<div class="modal-title">There was a problem with your request.</div>' + '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' + ' <span aria-hidden="true">&times;</span>' + '</button></div>' + ' <div class="modal-body"><p>Expected a successful response from the server, but got an error</p>' + '<pre>' + this.type + ' ' + this.url + "\n" + jqXHR.status + ': ' + errorThrown + '</pre></div>';
354
356
  $(Blacklight.modal.modalSelector).find('.modal-content').html(contents);
355
357
  $(Blacklight.modal.modalSelector).modal('show');
356
358
  };
@@ -22,7 +22,7 @@ module Blacklight
22
22
  @query_constraint_component.new(
23
23
  search_state: @search_state,
24
24
  value: @search_state.query_param,
25
- label: @view_context.constraint_query_label(@search_state.params),
25
+ label: label,
26
26
  remove_path: @view_context.remove_constraint_url(@search_state),
27
27
  classes: 'query'
28
28
  )
@@ -46,14 +46,22 @@ module Blacklight
46
46
 
47
47
  private
48
48
 
49
+ def label
50
+ Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
51
+ @view_context.constraint_query_label(@search_state.params)
52
+ end
53
+ end
54
+
49
55
  def facet_item_presenters
50
- @search_state.filter_params.each_pair.flat_map do |facet, values|
51
- facet_config = @view_context.facet_configuration_for_field(facet)
56
+ Deprecation.silence(Blacklight::SearchState) do
57
+ @search_state.filter_params.each_pair.flat_map do |facet, values|
58
+ facet_config = @view_context.facet_configuration_for_field(facet)
52
59
 
53
- Array(values).map do |val|
54
- next if val.blank? # skip empty string
60
+ Array(values).map do |val|
61
+ next if val.blank? # skip empty string
55
62
 
56
- facet_item_presenter(facet_config, val, facet)
63
+ facet_item_presenter(facet_config, val, facet)
64
+ end
57
65
  end
58
66
  end
59
67
  end
@@ -6,7 +6,7 @@
6
6
  <% warn_about_deprecated_behavior %>
7
7
  <%= value %>
8
8
  <% else %>
9
- <%= @view_context.link_to_document(@presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
9
+ <%= helpers.link_to_document(@presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
10
10
  <% end %>
11
11
  </div>
12
12
  <% end %>
@@ -10,7 +10,7 @@ module Blacklight
10
10
  def initialize(presenter:, counter:)
11
11
  @presenter = presenter
12
12
  @counter = counter
13
- @use_thumbnail_tag = @presenter.thumbnail != Blacklight::ThumbnailPresenter
13
+ @use_thumbnail_tag = !@presenter.thumbnail.instance_of?(Blacklight::ThumbnailPresenter)
14
14
  end
15
15
 
16
16
  def render?
@@ -19,6 +19,7 @@
19
19
  <%= actions %>
20
20
  </header>
21
21
 
22
+ <%= embed %>
22
23
  <%= content %>
23
24
  <%= metadata %>
24
25
  </div>
@@ -6,7 +6,7 @@ module Blacklight
6
6
  # the accessors below.
7
7
  with_content_areas :header, :body, :footer,
8
8
  :before_title, :title, :after_title,
9
- :actions, :metadata, :thumbnail,
9
+ :actions, :embed, :metadata, :thumbnail,
10
10
  :partials
11
11
  with_collection_parameter :document
12
12
 
@@ -25,6 +25,7 @@ module Blacklight
25
25
  def initialize(document: nil, presenter: nil,
26
26
  id: nil, classes: [], component: :article, title_component: :h4,
27
27
  metadata_component: Blacklight::DocumentMetadataComponent,
28
+ embed_component: nil,
28
29
  counter: nil, document_counter: nil, counter_offset: 0,
29
30
  show: false)
30
31
  if presenter.nil? && document.nil?
@@ -39,8 +40,10 @@ module Blacklight
39
40
  @id = id || ('document' if show)
40
41
  @classes = classes
41
42
 
43
+ @embed_component = embed_component
42
44
  @metadata_component = metadata_component
43
45
 
46
+ @document_counter = document_counter
44
47
  @counter = counter
45
48
  @counter ||= document_counter + 1 + counter_offset if document_counter.present?
46
49
 
@@ -101,6 +104,16 @@ module Blacklight
101
104
  @before_title || counter
102
105
  end
103
106
 
107
+ def embed
108
+ return @embed if @embed
109
+
110
+ component = @embed_component || presenter.view_config.embed_component
111
+
112
+ return unless component
113
+
114
+ @view_context.render(component.new(document: @document, presenter: presenter, document_counter: @document_counter))
115
+ end
116
+
104
117
  private
105
118
 
106
119
  def counter
@@ -1,6 +1,7 @@
1
1
  <div class="card facet-limit blacklight-<%= @facet_field.key %> <%= 'facet-limit-active' if @facet_field.active? %>">
2
2
  <h3 class="card-header p-0 facet-field-heading" id="<%= @facet_field.html_id %>-header">
3
3
  <button
4
+ type="button"
4
5
  class="btn btn-block p-2 text-left collapse-toggle <%= "collapsed" if @facet_field.collapsed? %>"
5
6
  data-toggle="collapse"
6
7
  data-target="#<%= @facet_field.html_id %>"
@@ -1,9 +1,9 @@
1
1
  <div class="prev_next_links btn-group">
2
- <%= link_to_previous_page @facet_field.paginator, raw(t('views.pagination.previous')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
2
+ <%= @view_context.link_to_previous_page @facet_field.paginator, raw(t('views.pagination.previous')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
3
3
  <%= content_tag :span, raw(t('views.pagination.previous')), class: 'disabled btn' %>
4
4
  <% end %>
5
5
 
6
- <%= link_to_next_page @facet_field.paginator, raw(t('views.pagination.next')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
6
+ <%= @view_context.link_to_next_page @facet_field.paginator, raw(t('views.pagination.next')), params: @facet_field.search_state.to_h, param_name: param_name, class: 'btn btn-link', data: { blacklight_modal: "preserve" } do %>
7
7
  <%= content_tag :span, raw(t('views.pagination.next')), class: 'disabled btn' %>
8
8
  <% end %>
9
9
  </div>
@@ -11,9 +11,9 @@
11
11
  <div class="sort-options btn-group">
12
12
  <% if @facet_field.paginator.sort == 'index' -%>
13
13
  <span class="active az btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.index') %></span>
14
- <%= link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
14
+ <%= @view_context.link_to(t('blacklight.search.facets.sort.count'), sort_facet_url('count'), class: "sort_change numeric btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
15
15
  <% elsif @facet_field.paginator.sort == 'count' -%>
16
- <%= link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
16
+ <%= @view_context.link_to(t('blacklight.search.facets.sort.index'), sort_facet_url('index'), class: "sort_change az btn btn-outline-secondary", data: { blacklight_modal: "preserve" }) %>
17
17
  <span class="active numeric btn btn-outline-secondary"><%= t('blacklight.search.facets.sort.count') %></span>
18
18
  <% end -%>
19
19
  </div>
@@ -6,10 +6,6 @@ module Blacklight
6
6
  @facet_field = facet_field
7
7
  end
8
8
 
9
- def render?
10
- @facet_field.facet_field.index_range&.any?
11
- end
12
-
13
9
  def sort_facet_url(sort)
14
10
  @facet_field.paginator.params_for_resort_url(sort, @facet_fieldsearch_state.to_h)
15
11
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ # Writes out zero or more <input type="hidden"> elements, completely
5
+ # representing a hash passed in using Rails-style request parameters
6
+ # for hashes nested with arrays and other hashes.
7
+ class HiddenSearchStateComponent < ::ViewComponent::Base
8
+ # @param [Hash] hash
9
+ def initialize(params:)
10
+ Deprecation.warn(self, "Passing page as a parameter to HiddenSearchStateComponent is deprecated and will not be supported in Blacklight 8") if params.key?(:page)
11
+ @params = params.except(:utf8)
12
+ end
13
+
14
+ def call
15
+ hidden_fields = []
16
+ flatten_hash(@params).each do |name, value|
17
+ value = Array.wrap(value)
18
+ value.each do |v|
19
+ hidden_fields << hidden_field_tag(name, v.to_s, id: nil)
20
+ end
21
+ end
22
+
23
+ safe_join(hidden_fields, "\n")
24
+ end
25
+
26
+ private
27
+
28
+ def flatten_hash(hash = params, ancestor_names = [])
29
+ flat_hash = {}
30
+ hash.each do |k, v|
31
+ names = Array.new(ancestor_names)
32
+ names << k
33
+ if v.is_a?(Hash)
34
+ flat_hash.merge!(flatten_hash(v, names))
35
+ else
36
+ key = flat_hash_key(names)
37
+ key += "[]" if v.is_a?(Array)
38
+ flat_hash[key] = v
39
+ end
40
+ end
41
+
42
+ flat_hash
43
+ end
44
+
45
+ def flat_hash_key(names)
46
+ names = Array.new(names)
47
+ name = names.shift.to_s.dup
48
+ names.each do |n|
49
+ name << "[#{n}]"
50
+ end
51
+ name
52
+ end
53
+ end
54
+ end
@@ -1,27 +1,29 @@
1
- <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => t('blacklight.search.form.submit') do %>
1
+ <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => scoped_t('submit') do %>
2
2
  <%= render_hash_as_hidden_fields(@params) %>
3
3
  <% if @search_fields.length > 1 %>
4
- <label for="search_field" class="sr-only"><%= t('blacklight.search.form.search_field.label') %></label>
4
+ <label for="search_field" class="sr-only"><%= scoped_t('search_field.label') %></label>
5
5
  <% end %>
6
6
  <div class="input-group">
7
+ <%= prepend %>
8
+
7
9
  <% if @search_fields.length > 1 %>
8
10
  <%= select_tag(:search_field,
9
11
  options_for_select(@search_fields, h(@search_field)),
10
- title: t('blacklight.search.form.search_field.title'),
12
+ title: scoped_t('search_field.title'),
11
13
  id: "#{@prefix}search_field",
12
14
  class: "custom-select search-field") %>
13
15
  <% elsif @search_fields.length == 1 %>
14
16
  <%= hidden_field_tag :search_field, @search_fields.first.last %>
15
17
  <% end %>
16
18
 
17
- <label for="<%= @prefix %>q" class="sr-only"><%= t('blacklight.search.form.search.label') %></label>
18
- <%= text_field_tag :q, @q, placeholder: t('blacklight.search.form.search.placeholder'), class: "search-q q form-control rounded-#{@search_fields.length > 1 ? '0' : 'left'}", id: "#{@prefix}q", autocomplete: autocomplete_path.present? ? "off" : "", autofocus: @autofocus, data: { autocomplete_enabled: autocomplete_path.present?, autocomplete_path: autocomplete_path } %>
19
-
20
- <%= content %>
19
+ <label for="<%= @prefix %><%= @query_param %>" class="sr-only"><%= scoped_t('search.label') %></label>
20
+ <%= text_field_tag @query_param, @q, placeholder: scoped_t('search.placeholder'), class: "search-q q form-control rounded-#{@search_fields.length > 1 ? '0' : 'left'}", id: "#{@prefix}q", autocomplete: autocomplete_path.present? ? "off" : "", autofocus: @autofocus, data: { autocomplete_enabled: autocomplete_path.present?, autocomplete_path: autocomplete_path } %>
21
21
 
22
22
  <span class="input-group-append">
23
+ <%= append %>
24
+
23
25
  <button type="submit" class="btn btn-primary search-btn" id="<%= @prefix %>search">
24
- <span class="submit-search-text"><%= t('blacklight.search.form.submit') %></span>
26
+ <span class="submit-search-text"><%= scoped_t('submit') %></span>
25
27
  <%= blacklight_icon :search, aria_hidden: true %>
26
28
  </button>
27
29
  </span>
@@ -2,10 +2,18 @@
2
2
 
3
3
  module Blacklight
4
4
  class SearchBarComponent < ::ViewComponent::Base
5
+ with_content_areas :append, :prepend
6
+
5
7
  # rubocop:disable Metrics/ParameterLists
6
- def initialize(url:, params:, classes: ['search-query-form'], presenter: nil, prefix: '', method: 'GET', q: nil, search_field: nil, search_fields: [], autocomplete_path: nil, autofocus: nil)
8
+ def initialize(
9
+ url:, params:, classes: ['search-query-form'], presenter: nil,
10
+ prefix: '', method: 'GET', q: nil, query_param: :q,
11
+ search_field: nil, search_fields: [], autocomplete_path: nil,
12
+ autofocus: nil, i18n: { scope: 'blacklight.search.form' }
13
+ )
7
14
  @url = url
8
15
  @q = q || params[:q]
16
+ @query_param = query_param
9
17
  @search_field = search_field || params[:search_field]
10
18
  @params = params.except(:q, :search_field, :utf8, :page)
11
19
  @prefix = prefix
@@ -15,6 +23,7 @@ module Blacklight
15
23
  @autocomplete_path = autocomplete_path
16
24
  @autofocus = autofocus
17
25
  @search_fields = search_fields
26
+ @i18n = i18n
18
27
  end
19
28
  # rubocop:enable Metrics/ParameterLists
20
29
 
@@ -47,5 +56,9 @@ module Blacklight
47
56
  @view_context.render_hash_as_hidden_fields(*args)
48
57
  end
49
58
  end
59
+
60
+ def scoped_t(key, **args)
61
+ t(key, default: t(key, scope: 'blacklight.search.form'), **@i18n, **args)
62
+ end
50
63
  end
51
64
  end