blacklight 7.13.2 → 7.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +23 -3
  3. data/README.md +0 -2
  4. data/VERSION +1 -1
  5. data/app/assets/javascripts/blacklight/blacklight.js +4 -2
  6. data/app/assets/stylesheets/blacklight/_header.scss +0 -5
  7. data/app/assets/stylesheets/blacklight/_icons.scss +5 -1
  8. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -1
  9. data/app/components/blacklight/advanced_search_form_component.html.erb +46 -0
  10. data/app/components/blacklight/advanced_search_form_component.rb +75 -0
  11. data/app/components/blacklight/constraint_component.html.erb +1 -1
  12. data/app/components/blacklight/constraint_layout_component.html.erb +1 -1
  13. data/app/components/blacklight/constraints_component.rb +42 -17
  14. data/app/components/blacklight/document/thumbnail_component.html.erb +2 -2
  15. data/app/components/blacklight/document/thumbnail_component.rb +5 -2
  16. data/app/components/blacklight/document_component.rb +7 -2
  17. data/app/components/blacklight/document_metadata_component.rb +1 -1
  18. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +23 -0
  19. data/app/components/blacklight/facet_field_checkboxes_component.rb +24 -0
  20. data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +6 -0
  21. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +29 -0
  22. data/app/components/blacklight/facet_field_list_component.html.erb +1 -0
  23. data/app/components/blacklight/facet_field_pagination_component.rb +1 -1
  24. data/app/components/blacklight/facet_item_component.rb +4 -2
  25. data/app/components/blacklight/hidden_search_state_component.rb +54 -0
  26. data/app/components/blacklight/search_bar_component.html.erb +4 -0
  27. data/app/components/blacklight/search_bar_component.rb +4 -2
  28. data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
  29. data/app/controllers/concerns/blacklight/catalog.rb +6 -0
  30. data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
  31. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  32. data/app/helpers/blacklight/facets_helper_behavior.rb +1 -1
  33. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +2 -38
  34. data/app/helpers/blacklight/icon_helper_behavior.rb +1 -1
  35. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
  36. data/app/javascript/blacklight/button_focus.js +1 -0
  37. data/app/javascript/blacklight/modal.js +10 -4
  38. data/app/models/concerns/blacklight/suggest/response.rb +1 -1
  39. data/app/presenters/blacklight/clause_presenter.rb +37 -0
  40. data/app/presenters/blacklight/document_presenter.rb +5 -1
  41. data/app/presenters/blacklight/facet_field_presenter.rb +4 -0
  42. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +45 -0
  43. data/app/presenters/blacklight/facet_item_presenter.rb +32 -20
  44. data/app/presenters/blacklight/field_presenter.rb +1 -1
  45. data/app/presenters/blacklight/inclusive_facet_item_presenter.rb +16 -0
  46. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  47. data/app/presenters/blacklight/search_bar_presenter.rb +4 -0
  48. data/app/views/bookmarks/_tools.html.erb +1 -1
  49. data/app/views/catalog/_advanced_search_form.html.erb +7 -0
  50. data/app/views/catalog/_advanced_search_help.html.erb +24 -0
  51. data/app/views/catalog/_search_form.html.erb +1 -0
  52. data/app/views/catalog/_zero_results.html.erb +1 -1
  53. data/app/views/catalog/advanced_search.html.erb +17 -0
  54. data/blacklight.gemspec +5 -4
  55. data/config/i18n-tasks.yml +1 -0
  56. data/config/locales/blacklight.en.yml +17 -0
  57. data/lib/blacklight/configuration.rb +2 -1
  58. data/lib/blacklight/configuration/field.rb +1 -1
  59. data/lib/blacklight/configuration/sort_field.rb +1 -1
  60. data/lib/blacklight/open_struct_with_hash_access.rb +18 -1
  61. data/lib/blacklight/routes/searchable.rb +1 -0
  62. data/lib/blacklight/search_builder.rb +2 -0
  63. data/lib/blacklight/search_state.rb +5 -1
  64. data/lib/blacklight/search_state/filter_field.rb +17 -7
  65. data/lib/blacklight/solr/repository.rb +11 -2
  66. data/lib/blacklight/solr/search_builder_behavior.rb +87 -23
  67. data/package.json +1 -1
  68. data/spec/components/blacklight/advanced_search_form_component_spec.rb +51 -0
  69. data/spec/components/blacklight/constraint_layout_component_spec.rb +1 -1
  70. data/spec/components/blacklight/document_component_spec.rb +17 -0
  71. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +55 -0
  72. data/spec/components/blacklight/facet_field_list_component_spec.rb +39 -4
  73. data/spec/components/blacklight/hidden_search_state_component_spec.rb +24 -0
  74. data/spec/controllers/catalog_controller_spec.rb +9 -0
  75. data/spec/features/advanced_search_spec.rb +67 -0
  76. data/spec/features/bookmarks_spec.rb +1 -9
  77. data/spec/features/facets_spec.rb +2 -17
  78. data/spec/features/search_filters_spec.rb +0 -20
  79. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +1 -0
  80. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -0
  81. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +8 -0
  82. data/spec/lib/blacklight/search_state/filter_field_spec.rb +65 -0
  83. data/spec/models/blacklight/solr/repository_spec.rb +12 -0
  84. data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
  85. data/spec/models/blacklight/solr/search_builder_spec.rb +28 -0
  86. data/spec/presenters/blacklight/clause_presenter_spec.rb +34 -0
  87. data/spec/presenters/blacklight/document_presenter_spec.rb +13 -0
  88. data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +41 -0
  89. data/spec/spec_helper.rb +8 -3
  90. data/spec/test_app_templates/Gemfile.extra +1 -1
  91. data/spec/views/catalog/_document.html.erb_spec.rb +1 -0
  92. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +2 -0
  93. metadata +66 -27
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class FacetFieldCheckboxesComponent < ::ViewComponent::Base
5
+ def initialize(facet_field:, layout: nil)
6
+ @facet_field = facet_field
7
+ @layout = layout == false ? FacetFieldNoLayoutComponent : Blacklight::FacetFieldComponent
8
+ end
9
+
10
+ def render?
11
+ presenters.any?
12
+ end
13
+
14
+ def presenters
15
+ return [] unless @facet_field.paginator
16
+
17
+ return to_enum(:presenters) unless block_given?
18
+
19
+ @facet_field.paginator.items.each do |item|
20
+ yield Blacklight::FacetItemPresenter.new(item, @facet_field.facet_field, @view_context, @facet_field.key, @facet_field.search_state)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ <div class="inclusive_or card card-body bg-light mb-3">
2
+ <h5><%= t('blacklight.advanced_search.any_of') %></h5>
3
+ <ul class="list-unstyled facet-values">
4
+ <%= @view_context.render(Blacklight::FacetItemComponent.with_collection(presenters.to_a)) %>
5
+ </ul>
6
+ </div>
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class FacetFieldInclusiveConstraintComponent < ::ViewComponent::Base
5
+ with_collection_parameter :facet_field
6
+
7
+ def initialize(facet_field:, values: nil)
8
+ @facet_field = facet_field
9
+ @values = values
10
+ end
11
+
12
+ def values
13
+ @values ||= @facet_field.values.find { |v| v.is_a? Array }
14
+ @values || []
15
+ end
16
+
17
+ def render?
18
+ values.present?
19
+ end
20
+
21
+ def presenters
22
+ return to_enum(:presenters) unless block_given?
23
+
24
+ values.each do |item|
25
+ yield Blacklight::FacetGroupedItemPresenter.new(values, item, @facet_field.facet_field, @view_context, @facet_field.key, @facet_field.search_state)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,6 +3,7 @@
3
3
  <%= @facet_field.label %>
4
4
  <% end %>
5
5
  <% component.with(:body) do %>
6
+ <%= @view_context.render(Blacklight::FacetFieldInclusiveConstraintComponent.new(facet_field: @facet_field)) %>
6
7
  <ul class="facet-values list-unstyled">
7
8
  <%= render_facet_limit_list @facet_field.paginator, @facet_field.key %>
8
9
  </ul>
@@ -7,7 +7,7 @@ module Blacklight
7
7
  end
8
8
 
9
9
  def sort_facet_url(sort)
10
- @facet_field.paginator.params_for_resort_url(sort, @facet_fieldsearch_state.to_h)
10
+ @facet_field.paginator.params_for_resort_url(sort, @facet_field.search_state.to_h)
11
11
  end
12
12
 
13
13
  def param_name
@@ -86,8 +86,8 @@ module Blacklight
86
86
  tag.span(@label, class: "selected") +
87
87
  # remove link
88
88
  link_to(@href, class: "remove") do
89
- tag.span('✖', class: "remove-icon") +
90
- tag.span('[remove]', class: 'sr-only')
89
+ tag.span('✖', class: "remove-icon", aria: { hidden: true }) +
90
+ tag.span(@view_context.t(:'blacklight.search.facets.selected.remove'), class: 'sr-only')
91
91
  end
92
92
  end + render_facet_count(classes: ["selected"])
93
93
  end
@@ -103,6 +103,8 @@ module Blacklight
103
103
  def render_facet_count(options = {})
104
104
  return @view_context.render_facet_count(@hits, options) unless @view_context.method(:render_facet_count).owner == Blacklight::FacetsHelperBehavior || explicit_component_configuration?
105
105
 
106
+ return '' if @hits.blank?
107
+
106
108
  classes = (options[:classes] || []) << "facet-count"
107
109
  tag.span(t('blacklight.search.facets.count', number: number_with_delimiter(@hits)), class: classes)
108
110
  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
@@ -29,3 +29,7 @@
29
29
  </span>
30
30
  </div>
31
31
  <% end %>
32
+
33
+ <% if presenter.advanced_search_enabled? %>
34
+ <%= link_to t('blacklight.advanced_search.more_options'), @advanced_search_url, class: 'advanced_search btn btn-secondary'%>
35
+ <% end %>
@@ -6,12 +6,14 @@ module Blacklight
6
6
 
7
7
  # rubocop:disable Metrics/ParameterLists
8
8
  def initialize(
9
- url:, params:, classes: ['search-query-form'], presenter: nil,
10
- prefix: '', method: 'GET', q: nil, query_param: :q,
9
+ url:, advanced_search_url: nil, params:,
10
+ classes: ['search-query-form'], presenter: nil, prefix: '',
11
+ method: 'GET', q: nil, query_param: :q,
11
12
  search_field: nil, search_fields: [], autocomplete_path: nil,
12
13
  autofocus: nil, i18n: { scope: 'blacklight.search.form' }
13
14
  )
14
15
  @url = url
16
+ @advanced_search_url = advanced_search_url
15
17
  @q = q || params[:q]
16
18
  @query_param = query_param
17
19
  @search_field = search_field || params[:search_field]
@@ -25,7 +25,7 @@ module Blacklight::Bookmarks
25
25
  def action_documents
26
26
  bookmarks = token_or_current_or_guest_user.bookmarks
27
27
  bookmark_ids = bookmarks.collect { |b| b.document_id.to_s }
28
- search_service.fetch(bookmark_ids)
28
+ search_service.fetch(bookmark_ids, rows: bookmark_ids.count)
29
29
  end
30
30
 
31
31
  def action_success_redirect_path
@@ -56,6 +56,12 @@ module Blacklight::Catalog
56
56
  end
57
57
  end
58
58
 
59
+ def advanced_search
60
+ empty_service = search_service_class.new(config: blacklight_config, user_params: {}, **search_service_context)
61
+
62
+ (@response, _deprecated_document_list) = empty_service.search_results
63
+ end
64
+
59
65
  # get a single document from the index
60
66
  def raw
61
67
  raise(ActionController::RoutingError, 'Not Found') unless blacklight_config.raw_endpoint.enabled
@@ -10,7 +10,7 @@ module Blacklight
10
10
  deprecation_deprecate :document_action_label
11
11
 
12
12
  # @deprecated
13
- def document_action_path action_opts, url_opts = nil
13
+ def document_action_path action_opts, url_opts = {}
14
14
  if action_opts.path
15
15
  send(action_opts.path, url_opts)
16
16
  elsif url_opts[:id].class.respond_to?(:model_name)
@@ -189,7 +189,7 @@ module Blacklight::ConfigurationHelperBehavior
189
189
 
190
190
  field = fields.first if document.nil?
191
191
  field ||= fields.find { |f| document.has? f }
192
- field &&= field.try(:to_sym)
192
+ field &&= field&.to_sym
193
193
 
194
194
  field
195
195
  end
@@ -198,7 +198,7 @@ module Blacklight::ConfigurationHelperBehavior
198
198
  ##
199
199
  # Default sort field
200
200
  def default_sort_field
201
- (active_sort_fields.find { |_k, config| config.respond_to?(:default) && config.default } || active_sort_fields.first).try(:last)
201
+ (active_sort_fields.find { |_k, config| config.respond_to?(:default) && config.default } || active_sort_fields.first)&.last
202
202
  end
203
203
 
204
204
  ##
@@ -180,7 +180,7 @@ module Blacklight::FacetsHelperBehavior
180
180
  # @return [String]
181
181
  def facet_partial_name(display_facet = nil)
182
182
  config = facet_configuration_for_field(display_facet.name)
183
- name = config.try(:partial)
183
+ name = config.partial
184
184
  name ||= "facet_pivot" if config.pivot
185
185
  name || "facet_limit"
186
186
  end
@@ -21,43 +21,7 @@ module Blacklight::HashAsHiddenFieldsHelperBehavior
21
21
  # @param [Hash] hash
22
22
  # @return [String]
23
23
  def render_hash_as_hidden_fields(hash)
24
- hidden_fields = []
25
- flatten_hash(hash).each do |name, value|
26
- value = Array.wrap(value)
27
- value.each do |v|
28
- hidden_fields << hidden_field_tag(name, v.to_s, id: nil)
29
- end
30
- end
31
-
32
- safe_join(hidden_fields, "\n")
33
- end
34
- deprecation_deprecate render_hash_as_hidden_fields: 'Moving to a private method of Blacklight::SearchBarComponent'
35
-
36
- private
37
-
38
- def flatten_hash(hash = params, ancestor_names = [])
39
- flat_hash = {}
40
- hash.each do |k, v|
41
- names = Array.new(ancestor_names)
42
- names << k
43
- if v.is_a?(Hash)
44
- flat_hash.merge!(flatten_hash(v, names))
45
- else
46
- key = flat_hash_key(names)
47
- key += "[]" if v.is_a?(Array)
48
- flat_hash[key] = v
49
- end
50
- end
51
-
52
- flat_hash
53
- end
54
-
55
- def flat_hash_key(names)
56
- names = Array.new(names)
57
- name = names.shift.to_s.dup
58
- names.each do |n|
59
- name << "[#{n}]"
60
- end
61
- name
24
+ render Blacklight::HiddenSearchStateComponent.new(params: hash)
62
25
  end
26
+ deprecation_deprecate render_hash_as_hidden_fields: 'Use Blacklight::HiddenSearchStateComponent instead'
63
27
  end
@@ -12,7 +12,7 @@ module Blacklight::IconHelperBehavior
12
12
  def blacklight_icon(icon_name, options = {})
13
13
  Rails.cache.fetch([:blacklight_icons, icon_name, options]) do
14
14
  icon = Blacklight::Icon.new(icon_name, **options)
15
- tag.span(icon.svg.html_safe, icon.options)
15
+ tag.span(icon.svg.html_safe, **icon.options)
16
16
  end
17
17
  end
18
18
  end
@@ -88,8 +88,8 @@ module Blacklight::RenderConstraintsHelperBehavior
88
88
  return "".html_safe if search_state.filter_params.blank?
89
89
 
90
90
  Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
91
- safe_join(search_state.filter_params.each_pair.map do |facet, values|
92
- render_filter_element(facet, values, search_state)
91
+ safe_join(search_state.filters.map do |field|
92
+ render_filter_element(field.key, field.values, search_state)
93
93
  end, "\n")
94
94
  end
95
95
  end
@@ -1,6 +1,7 @@
1
1
  Blacklight.onLoad(function() {
2
2
  // Button clicks should change focus. As of 10/3/19, Firefox for Mac and
3
3
  // Safari both do not set focus to a button on button click.
4
+ // See https://zellwk.com/blog/inconsistent-button-behavior/ for background information
4
5
  document.querySelectorAll('button.collapse-toggle').forEach((button) => {
5
6
  button.addEventListener('click', () => {
6
7
  event.target.focus();
@@ -101,12 +101,18 @@ Blacklight.modal.modalCloseSelector = '[data-blacklight-modal~=close]';
101
101
  // Called on fatal failure of ajax load, function returns content
102
102
  // to show to user in modal. Right now called only for extreme
103
103
  // network errors.
104
- Blacklight.modal.onFailure = function(data) {
105
- var contents = '<div class="modal-header">' +
106
- '<div class="modal-title">Network Error</div>' +
104
+ Blacklight.modal.onFailure = function(jqXHR, textStatus, errorThrown) {
105
+ console.error('Server error:', this.url, jqXHR.status, errorThrown);
106
+
107
+ var contents = '<div class="modal-header">' +
108
+ '<div class="modal-title">There was a problem with your request.</div>' +
107
109
  '<button type="button" class="blacklight-modal-close close" data-dismiss="modal" aria-label="Close">' +
108
110
  ' <span aria-hidden="true">&times;</span>' +
109
- '</button>';
111
+ '</button></div>' +
112
+ ' <div class="modal-body"><p>Expected a successful response from the server, but got an error</p>' +
113
+ '<pre>' +
114
+ this.type + ' ' + this.url + "\n" + jqXHR.status + ': ' + errorThrown +
115
+ '</pre></div>';
110
116
  $(Blacklight.modal.modalSelector).find('.modal-content').html(contents);
111
117
  $(Blacklight.modal.modalSelector).modal('show');
112
118
  }
@@ -22,7 +22,7 @@ module Blacklight
22
22
  # present
23
23
  # @return [Array]
24
24
  def suggestions
25
- (response.try(:[], suggest_path).try(:[], suggester_name).try(:[], request_params[:q]).try(:[], 'suggestions') || []).uniq
25
+ (response.dig(suggest_path, suggester_name, request_params[:q], 'suggestions') || []).uniq
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class ClausePresenter
5
+ attr_reader :key, :user_parameters, :field_config, :view_context, :search_state
6
+
7
+ def initialize(key, user_parameters, field_config, view_context, search_state = view_context.search_state)
8
+ @key = key
9
+ @user_parameters = user_parameters
10
+ @field_config = field_config
11
+ @view_context = view_context
12
+ @search_state = search_state
13
+ end
14
+
15
+ def field_label
16
+ field_config.display_label('search')
17
+ end
18
+
19
+ ##
20
+ # Get the displayable version of a facet's value
21
+ #
22
+ # @return [String]
23
+ def label
24
+ user_parameters[:query]
25
+ end
26
+
27
+ def remove_href(path = search_state)
28
+ view_context.search_action_path(path.reset_search(clause: path.clause_params.except(key)))
29
+ end
30
+
31
+ private
32
+
33
+ def facet_field_presenter
34
+ @facet_field_presenter ||= view_context.facet_field_presenter(facet_config, {})
35
+ end
36
+ end
37
+ end
@@ -97,8 +97,12 @@ module Blacklight
97
97
  field_presenter(field_config, options).render
98
98
  end
99
99
 
100
+ def thumbnail_presenter_class
101
+ view_config.thumbnail_presenter || thumbnail_presenter
102
+ end
103
+
100
104
  def thumbnail
101
- @thumbnail ||= thumbnail_presenter.new(document, view_context, view_config)
105
+ @thumbnail ||= thumbnail_presenter_class.new(document, view_context, view_config)
102
106
  end
103
107
 
104
108
  ##
@@ -40,6 +40,10 @@ module Blacklight
40
40
  view_context.facet_field_label(key)
41
41
  end
42
42
 
43
+ def values
44
+ search_state&.filter(facet_field)&.values || []
45
+ end
46
+
43
47
  # @private
44
48
  # @deprecated
45
49
  def html_id
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class FacetGroupedItemPresenter < Blacklight::FacetItemPresenter
5
+ attr_reader :group
6
+
7
+ delegate :key, to: :facet_config
8
+
9
+ def initialize(group, facet_item, facet_config, view_context, facet_field, search_state = view_context.search_state)
10
+ @group = group
11
+ @facet_item = facet_item
12
+ @facet_config = facet_config
13
+ @view_context = view_context
14
+ @facet_field = facet_field
15
+ @search_state = search_state
16
+ end
17
+
18
+ ##
19
+ # Check if the query parameters have the given facet field with the
20
+ # given value.
21
+ def selected?
22
+ group.include?(facet_item)
23
+ end
24
+
25
+ # @private
26
+ def remove_href(path = search_state)
27
+ new_state = path.filter(facet_config).remove(group)
28
+ new_state = new_state.filter(facet_config).add(group - [facet_item])
29
+
30
+ view_context.search_action_path(new_state)
31
+ end
32
+
33
+ # @private
34
+ def add_href(_path_options = {})
35
+ if facet_config.url_method
36
+ return view_context.public_send(facet_config.url_method, facet_config.key, facet_item)
37
+ end
38
+
39
+ new_state = search_state.filter(facet_config).remove(@group)
40
+ new_state = new_state.filter(facet_config).add(@group + [facet_item])
41
+
42
+ view_context.search_action_path(new_state)
43
+ end
44
+ end
45
+ end