blacklight 7.14.1 → 7.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/VERSION +1 -1
  4. data/app/assets/stylesheets/blacklight/_icons.scss +5 -1
  5. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -0
  6. data/app/components/blacklight/advanced_search_form_component.html.erb +52 -0
  7. data/app/components/blacklight/advanced_search_form_component.rb +88 -0
  8. data/app/components/blacklight/constraint_component.html.erb +1 -1
  9. data/app/components/blacklight/constraint_layout_component.html.erb +1 -1
  10. data/app/components/blacklight/constraints_component.html.erb +19 -3
  11. data/app/components/blacklight/constraints_component.rb +41 -18
  12. data/app/components/blacklight/content_areas_shim.rb +12 -0
  13. data/app/components/blacklight/document/action_component.html.erb +1 -1
  14. data/app/components/blacklight/document/action_component.rb +6 -1
  15. data/app/components/blacklight/document/actions_component.html.erb +3 -5
  16. data/app/components/blacklight/document/actions_component.rb +16 -2
  17. data/app/components/blacklight/document/thumbnail_component.html.erb +1 -1
  18. data/app/components/blacklight/document/thumbnail_component.rb +4 -1
  19. data/app/components/blacklight/document_component.html.erb +4 -7
  20. data/app/components/blacklight/document_component.rb +73 -68
  21. data/app/components/blacklight/document_metadata_component.html.erb +2 -2
  22. data/app/components/blacklight/document_metadata_component.rb +13 -2
  23. data/app/components/blacklight/document_title_component.html.erb +17 -0
  24. data/app/components/blacklight/document_title_component.rb +59 -0
  25. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +23 -0
  26. data/app/components/blacklight/facet_field_checkboxes_component.rb +24 -0
  27. data/app/components/blacklight/facet_field_component.rb +4 -1
  28. data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +6 -0
  29. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +29 -0
  30. data/app/components/blacklight/facet_field_list_component.html.erb +3 -2
  31. data/app/components/blacklight/facet_field_no_layout_component.rb +4 -1
  32. data/app/components/blacklight/facet_field_pagination_component.rb +1 -1
  33. data/app/components/blacklight/facet_item_component.rb +4 -2
  34. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  35. data/app/components/blacklight/metadata_field_layout_component.html.erb +3 -1
  36. data/app/components/blacklight/metadata_field_layout_component.rb +26 -1
  37. data/app/components/blacklight/response/view_type_button_component.html.erb +4 -0
  38. data/app/components/blacklight/response/view_type_button_component.rb +36 -0
  39. data/app/components/blacklight/response/view_type_component.html.erb +2 -5
  40. data/app/components/blacklight/response/view_type_component.rb +9 -13
  41. data/app/components/blacklight/search_bar_component.html.erb +4 -0
  42. data/app/components/blacklight/search_bar_component.rb +13 -4
  43. data/app/components/blacklight/system/dropdown_component.html.erb +4 -7
  44. data/app/components/blacklight/system/dropdown_component.rb +24 -0
  45. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  46. data/app/components/blacklight/system/flash_message_component.rb +7 -1
  47. data/app/components/blacklight/system/modal_component.rb +7 -1
  48. data/app/controllers/concerns/blacklight/catalog.rb +7 -1
  49. data/app/helpers/blacklight/blacklight_helper_behavior.rb +3 -4
  50. data/app/helpers/blacklight/component_helper_behavior.rb +2 -2
  51. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  52. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
  53. data/app/presenters/blacklight/clause_presenter.rb +37 -0
  54. data/app/presenters/blacklight/document_presenter.rb +13 -5
  55. data/app/presenters/blacklight/facet_field_presenter.rb +4 -0
  56. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +45 -0
  57. data/app/presenters/blacklight/facet_item_presenter.rb +32 -20
  58. data/app/presenters/blacklight/inclusive_facet_item_presenter.rb +16 -0
  59. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  60. data/app/presenters/blacklight/search_bar_presenter.rb +4 -0
  61. data/app/services/blacklight/search_service.rb +1 -1
  62. data/app/views/bookmarks/_tools.html.erb +1 -1
  63. data/app/views/catalog/_advanced_search_form.html.erb +7 -0
  64. data/app/views/catalog/_advanced_search_help.html.erb +24 -0
  65. data/app/views/catalog/_citation.html.erb +1 -1
  66. data/app/views/catalog/_document.html.erb +2 -2
  67. data/app/views/catalog/_facet_layout.html.erb +2 -2
  68. data/app/views/catalog/_search_form.html.erb +1 -0
  69. data/app/views/catalog/_show_main_content.html.erb +3 -3
  70. data/app/views/catalog/advanced_search.html.erb +17 -0
  71. data/app/views/catalog/email.html.erb +2 -2
  72. data/app/views/catalog/email_success.html.erb +1 -1
  73. data/app/views/catalog/facet.html.erb +3 -3
  74. data/app/views/catalog/sms.html.erb +2 -2
  75. data/app/views/catalog/sms_success.html.erb +1 -1
  76. data/blacklight.gemspec +2 -2
  77. data/config/i18n-tasks.yml +1 -0
  78. data/config/locales/blacklight.de.yml +2 -2
  79. data/config/locales/blacklight.en.yml +17 -0
  80. data/lib/blacklight/configuration.rb +52 -6
  81. data/lib/blacklight/configuration/view_config.rb +16 -5
  82. data/lib/blacklight/engine.rb +3 -1
  83. data/lib/blacklight/open_struct_with_hash_access.rb +22 -1
  84. data/lib/blacklight/routes/searchable.rb +1 -0
  85. data/lib/blacklight/search_builder.rb +2 -0
  86. data/lib/blacklight/search_state.rb +7 -3
  87. data/lib/blacklight/search_state/filter_field.rb +17 -7
  88. data/lib/blacklight/solr/facet_paginator.rb +2 -0
  89. data/lib/blacklight/solr/repository.rb +11 -2
  90. data/lib/blacklight/solr/request.rb +31 -0
  91. data/lib/blacklight/solr/response.rb +2 -16
  92. data/lib/blacklight/solr/response/facets.rb +76 -22
  93. data/lib/blacklight/solr/response/params.rb +104 -0
  94. data/lib/blacklight/solr/search_builder_behavior.rb +126 -32
  95. data/lib/generators/blacklight/assets_generator.rb +6 -2
  96. data/lib/generators/blacklight/user_generator.rb +1 -1
  97. data/spec/components/blacklight/advanced_search_form_component_spec.rb +51 -0
  98. data/spec/components/blacklight/document_component_spec.rb +18 -3
  99. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +55 -0
  100. data/spec/components/blacklight/facet_field_list_component_spec.rb +39 -4
  101. data/spec/controllers/catalog_controller_spec.rb +9 -0
  102. data/spec/features/advanced_search_spec.rb +67 -0
  103. data/spec/lib/blacklight/configuration/view_config_spec.rb +1 -1
  104. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +20 -0
  105. data/spec/lib/blacklight/search_state/filter_field_spec.rb +65 -0
  106. data/spec/models/blacklight/configuration_spec.rb +64 -0
  107. data/spec/models/blacklight/solr/facet_paginator_spec.rb +4 -0
  108. data/spec/models/blacklight/solr/repository_spec.rb +12 -0
  109. data/spec/models/blacklight/solr/request_spec.rb +62 -29
  110. data/spec/models/blacklight/solr/response/facets_spec.rb +109 -0
  111. data/spec/models/blacklight/solr/response_spec.rb +10 -0
  112. data/spec/models/blacklight/solr/search_builder_spec.rb +77 -0
  113. data/spec/presenters/blacklight/clause_presenter_spec.rb +34 -0
  114. data/spec/presenters/blacklight/document_presenter_spec.rb +13 -0
  115. data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +41 -0
  116. data/spec/views/catalog/index.atom.builder_spec.rb +1 -1
  117. metadata +37 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0fa09c963759adb956f189243824f10d2c16ee518849c33ed0e6343240dec93
4
- data.tar.gz: 61d5a9c3f582555de951e49a1912ad7a4feceb16f2635f1650eafa7a2200be39
3
+ metadata.gz: 1e26542ca54e79594290b86c0506e4bc3a26a225d84e17537893381b4ad2c421
4
+ data.tar.gz: c812f19a30e663a1350888600307e7ba1b089b8794570eeadb38f89a6de57d27
5
5
  SHA512:
6
- metadata.gz: 9ed401d79a83ca244fd44f3d5ecc08e45a57ec69d76e84265dec12b450594e228906a3db51eb7d2c38560e5ed6a3d643c0ecf16eea9941eb0830cbc64f88294c
7
- data.tar.gz: 90388ff2eab28a18cf4810769995b18143badd8c325b00ad075dbef243d5b3b074de5bb7442c65f6905f009485feca10452ff7b9c4d749b453e7b28da2a3a21d
6
+ metadata.gz: 8f167c42362e5372a681777ce1cd1a72bf6ca9f5762098686bc6bb8872f59afd3f110312d15c1436320b511df272281ddb04be6cf9c10620535389aa87c91169
7
+ data.tar.gz: 9ae4c4178d7eff8eb4656d03353fe4fb2cd4f66e32fffdebd8645275f213b26aadd9c8204c2feba9f6479160ad925ba220ce6e1ec59bff42f9ca298dfd7cbb5c
data/.rubocop.yml CHANGED
@@ -57,6 +57,7 @@ Naming/MethodParameterName:
57
57
  AllowedNames:
58
58
  - id
59
59
  - q
60
+ - as
60
61
 
61
62
  Naming/PredicateName:
62
63
  ForbiddenPrefixes:
@@ -122,3 +123,6 @@ Style/RedundantRegexpEscape:
122
123
 
123
124
  Style/SlicingWithRange:
124
125
  Enabled: true
126
+
127
+ Rails/ContentTag:
128
+ Enabled: false
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.14.1
1
+ 7.17.0
@@ -14,8 +14,12 @@
14
14
 
15
15
  .btn.btn-icon {
16
16
  padding: $btn-padding-y;
17
-
17
+
18
18
  &.btn-sm {
19
19
  padding: $btn-padding-y-sm;
20
20
  }
21
21
  }
22
+
23
+ .remove-icon {
24
+ font-family: $remove-icon-font-family;
25
+ }
@@ -5,3 +5,8 @@ $logo-image: image_url('blacklight/logo.png') !default;
5
5
  /* label (field names) */
6
6
  $field_name_color: $text-muted !default;
7
7
  $zindex-typeahead: $zindex-dropdown;
8
+
9
+ // the default bootstrap font-family list includes "Segoe UI Emoji", which, on windows
10
+ // renders our remove icon as an emoji-sized x instead of what we see on all other platforms...
11
+ // so, for now (until we replace it with an SVG icon or something), we get to override bootstrap:
12
+ $remove-icon-font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif !default;
@@ -0,0 +1,52 @@
1
+ <% if constraints.present? %>
2
+ <div class="constraints well search_history">
3
+ <h4><%= t 'blacklight.advanced_search.form.search_context' %></h4>
4
+ <% constraints.each do |constraint| %>
5
+ <%= constraint %>
6
+ <% end %>
7
+ </div>
8
+ <% end %>
9
+
10
+ <%= form_tag @url, method: @method, class: @classes.join(' '), role: 'search', 'aria-label' => t('blacklight.search.form.submit') do %>
11
+ <%= render_hash_as_hidden_fields(@params) %>
12
+
13
+ <div class="input-criteria">
14
+ <div class="query-criteria">
15
+ <h2 class="query-criteria-heading">
16
+ <%= t('blacklight.advanced_search.form.query_criteria_heading_html', select_menu: default_operator_menu) %>
17
+ </h2>
18
+
19
+ <div id="advanced_search">
20
+ <% search_field_controls.each do |control| %>
21
+ <%= control %>
22
+ <% end %>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="limit-criteria">
27
+ <h2 class="limit-criteria-heading"><%= t('blacklight.advanced_search.form.limit_criteria_heading_html')%></h2>
28
+
29
+ <div id="advanced_search_facets" class="limit_input">
30
+ <div class="advanced-facet-limits panel-group">
31
+ <% search_filter_controls.each do |control| %>
32
+ <%= control %>
33
+ <% end %>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+
39
+ <%= content_tag :h2, t('blacklight.advanced_search.form.sort_label') %>
40
+ <div class="form-group row">
41
+ <div class="col-sm-offset-3 col-sm-4">
42
+ <%= sort_fields_select %>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="form-group row">
47
+ <div class="submit-buttons col-sm-offset-3 col-sm-9">
48
+ <%= submit_tag t('blacklight.advanced_search.form.search_btn_html'), class: 'btn btn-primary advanced-search-submit', id: "advanced-search-submit" %>
49
+ <%= button_tag t('blacklight.advanced_search.form.start_over_html'), type: 'reset', class: 'btn btn-link advanced-search-start-over' %>
50
+ </div>
51
+ </div>
52
+ <% end %>
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ class AdvancedSearchFormComponent < SearchBarComponent
5
+ include Blacklight::ContentAreasShim
6
+
7
+ renders_many :constraints
8
+ renders_many :search_field_controls
9
+ renders_many :search_filter_controls, (lambda do |config:, display_facet:, presenter: nil, component: nil, **kwargs|
10
+ presenter ||= (config.presenter || Blacklight::FacetFieldPresenter).new(config, display_facet, @view_context)
11
+ component = component || config.advanced_search_component || Blacklight::FacetFieldCheckboxesComponent
12
+
13
+ component.new(facet_field: presenter, **kwargs)
14
+ end)
15
+
16
+ def initialize(response:, **options)
17
+ super(**options)
18
+ @response = response
19
+ end
20
+
21
+ def before_render
22
+ initialize_search_field_controls if search_field_controls.blank?
23
+ initialize_search_filter_controls if search_filter_controls.blank?
24
+ initialize_constraints if constraints.blank?
25
+ end
26
+
27
+ def default_operator_menu
28
+ options_with_labels = [:must, :should].index_by { |op| t(op, scope: 'blacklight.advanced_search.op') }
29
+ select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
30
+ end
31
+
32
+ def sort_fields_select
33
+ options = sort_fields.values.map { |field_config| [@view_context.sort_field_label(field_config.key), field_config.key] }
34
+ select_tag(:sort, options_for_select(options, params[:sort]), class: "form-control sort-select")
35
+ end
36
+
37
+ private
38
+
39
+ def initialize_search_field_controls
40
+ search_fields.values.each.with_index do |field, i|
41
+ search_field_control do
42
+ fields_for('clause[]', i, include_id: false) do |f|
43
+ content_tag(:div, class: 'form-group advanced-search-field row') do
44
+ f.label(:query, field.display_label('search'), class: "col-sm-3 col-form-label") +
45
+ content_tag(:div, class: 'col-sm-9') do
46
+ f.hidden_field(:field, value: field.key) +
47
+ f.text_field(:query, value: query_for_search_clause(field.key), class: 'form-control')
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def initialize_search_filter_controls
56
+ fields = blacklight_config.facet_fields.select { |_k, v| v.include_in_advanced_search || v.include_in_advanced_search.nil? }
57
+
58
+ fields.each do |_k, config|
59
+ display_facet = @response.aggregations[config.field]
60
+ search_filter_control(config: config, display_facet: display_facet)
61
+ end
62
+ end
63
+
64
+ def initialize_constraints
65
+ constraint do
66
+ params = @view_context.search_state.params_for_search.except :page, :f_inclusive, :q, :search_field, :op, :index, :sort
67
+
68
+ params.except!(*search_fields.map { |_key, field_def| field_def[:key] })
69
+
70
+ @view_context.render_search_to_s(params)
71
+ end
72
+ end
73
+
74
+ def query_for_search_clause(key)
75
+ field = (@params[:clause] || {}).values.find { |value| value['field'].to_s == key.to_s }
76
+
77
+ field&.dig('query')
78
+ end
79
+
80
+ def search_fields
81
+ blacklight_config.search_fields.select { |_k, v| v.include_in_advanced_search || v.include_in_advanced_search.nil? }
82
+ end
83
+
84
+ def sort_fields
85
+ blacklight_config.sort_fields.select { |_k, v| v.include_in_advanced_search || v.include_in_advanced_search.nil? }
86
+ end
87
+ end
88
+ end
@@ -1,5 +1,5 @@
1
1
  <%= render(@layout.new(
2
- classes: (Array(@classes) + ["filter-#{@facet_item_presenter.facet_config.key.parameterize}"]).join(' '),
2
+ classes: (Array(@classes) + ["filter-#{@facet_item_presenter.key.parameterize}"]).join(' '),
3
3
  label: @facet_item_presenter.field_label,
4
4
  value: @facet_item_presenter.label,
5
5
  remove_path: @facet_item_presenter.remove_href)) %>
@@ -9,7 +9,7 @@
9
9
  </span>
10
10
  <% if @remove_path.present? %>
11
11
  <%= link_to(@remove_path, class: 'btn btn-outline-secondary remove') do %>
12
- <span class="remove-icon">✖</span>
12
+ <span class="remove-icon" aria-hidden="true">✖</span>
13
13
  <span class="sr-only">
14
14
  <%= if @label.blank?
15
15
  t('blacklight.search.filters.remove.value', value: @value)
@@ -4,7 +4,23 @@
4
4
  <%= link_to t('blacklight.search.start_over'), start_over_path, class: "catalog_startOverLink btn btn-primary" %>
5
5
 
6
6
  <span class="constraints-label sr-only"><%= t('blacklight.search.filters.title') %></span>
7
- <%= query_constraints_area || query_constraints %>
8
- <%= facet_constraints_area || facet_constraints %>
9
- <%= additional_constraints %>
7
+ <% if query_constraints_area.present? %>
8
+ <% query_constraints_area.each do |constraint| %>
9
+ <%= constraint %>
10
+ <% end %>
11
+ <% else %>
12
+ <%= query_constraints %>
13
+ <% end %>
14
+
15
+ <% if facet_constraints_area.present? %>
16
+ <% facet_constraints_area.each do |constraint| %>
17
+ <%= constraint %>
18
+ <% end %>
19
+ <% else %>
20
+ <%= facet_constraints %>
21
+ <% end %>
22
+
23
+ <% additional_constraints.each do |constraints| %>
24
+ <%= constraints %>
25
+ <% end %>
10
26
  <% end %>
@@ -2,7 +2,11 @@
2
2
 
3
3
  module Blacklight
4
4
  class ConstraintsComponent < ::ViewComponent::Base
5
- with_content_areas :query_constraints_area, :facet_constraints_area, :additional_constraints
5
+ include Blacklight::ContentAreasShim
6
+
7
+ renders_many :query_constraints_area
8
+ renders_many :facet_constraints_area
9
+ renders_many :additional_constraints
6
10
 
7
11
  def initialize(search_state:,
8
12
  id: 'appliedParams', classes: 'clearfix constraints-container',
@@ -15,23 +19,25 @@ module Blacklight
15
19
  end
16
20
 
17
21
  def query_constraints
18
- return if @search_state.query_param.blank?
19
-
20
22
  Deprecation.silence(Blacklight::RenderConstraintsHelperBehavior) do
21
- @view_context.render(
22
- @query_constraint_component.new(
23
- search_state: @search_state,
24
- value: @search_state.query_param,
25
- label: label,
26
- remove_path: @view_context.remove_constraint_url(@search_state),
27
- classes: 'query'
23
+ if @search_state.query_param.present?
24
+ @view_context.render(
25
+ @query_constraint_component.new(
26
+ search_state: @search_state,
27
+ value: @search_state.query_param,
28
+ label: label,
29
+ remove_path: @view_context.remove_constraint_url(@search_state),
30
+ classes: 'query'
31
+ )
28
32
  )
29
- )
30
- end
33
+ else
34
+ ''.html_safe
35
+ end
36
+ end + @view_context.render(@facet_constraint_component.with_collection(clause_presenters.to_a))
31
37
  end
32
38
 
33
39
  def facet_constraints
34
- @view_context.render(@facet_constraint_component.with_collection(facet_item_presenters))
40
+ @view_context.render(@facet_constraint_component.with_collection(facet_item_presenters.to_a))
35
41
  end
36
42
 
37
43
  def start_over_path
@@ -53,21 +59,38 @@ module Blacklight
53
59
  end
54
60
 
55
61
  def facet_item_presenters
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)
62
+ return to_enum(:facet_item_presenters) unless block_given?
59
63
 
60
- Array(values).map do |val|
64
+ Deprecation.silence(Blacklight::SearchState) do
65
+ @search_state.filters.map do |facet|
66
+ facet.values.map do |val|
61
67
  next if val.blank? # skip empty string
62
68
 
63
- facet_item_presenter(facet_config, val, facet)
69
+ if val.is_a?(Array)
70
+ yield inclusive_facet_item_presenter(facet.config, val, facet.key) if val.any?(&:present?)
71
+ else
72
+ yield facet_item_presenter(facet.config, val, facet.key)
73
+ end
64
74
  end
65
75
  end
66
76
  end
67
77
  end
68
78
 
79
+ def clause_presenters
80
+ return to_enum(:clause_presenters) unless block_given?
81
+
82
+ @search_state.clause_params.each do |key, clause|
83
+ field_config = @view_context.blacklight_config.search_fields[clause[:field]]
84
+ yield Blacklight::ClausePresenter.new(key, clause, field_config, @view_context)
85
+ end
86
+ end
87
+
69
88
  def facet_item_presenter(facet_config, facet_item, facet_field)
70
89
  Blacklight::FacetItemPresenter.new(facet_item, facet_config, @view_context, facet_field)
71
90
  end
91
+
92
+ def inclusive_facet_item_presenter(facet_config, facet_item, facet_field)
93
+ Blacklight::InclusiveFacetItemPresenter.new(facet_item, facet_config, @view_context, facet_field)
94
+ end
72
95
  end
73
96
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Blacklight
4
+ # Shim to support ViewComponent v2 slots using the content_areas API for backwards compatibility
5
+ module ContentAreasShim
6
+ # Shim the `with` helper to write content into slots instead
7
+ def with(slot_name, *args, **kwargs, &block)
8
+ Deprecation.warn('ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
9
+ public_send(slot_name, *args, **kwargs, &block)
10
+ end
11
+ end
12
+ end
@@ -2,7 +2,7 @@
2
2
  <%= link_to label,
3
3
  url,
4
4
  id: @id,
5
- class: 'nav-link',
5
+ class: @link_classes,
6
6
  data: {}.merge(({ blacklight_modal: "trigger" } if @action.modal != false) || {}) %>
7
7
  <% else %>
8
8
  <%= @view_context.render(partial: @action.partial || @action.name.to_s, locals: { document: @document, document_action_config: @action }.merge(@options)) %>
@@ -7,12 +7,13 @@ module Blacklight
7
7
  with_collection_parameter :action
8
8
 
9
9
  # @param [Blacklight::Document] document
10
- def initialize(document:, action:, options: {}, url_opts: {}, id: nil)
10
+ def initialize(document:, action:, options: {}, url_opts: {}, id: nil, link_classes: 'nav-link')
11
11
  @document = document
12
12
  @action = action
13
13
  @options = options
14
14
  @url_opts = url_opts
15
15
  @id = id || @action.fetch(:id, "#{@action.name}Link")
16
+ @link_classes = link_classes
16
17
  end
17
18
 
18
19
  def using_default_document_action?
@@ -33,6 +34,10 @@ module Blacklight
33
34
  @view_context.document_action_path(@action, @url_opts.merge(({ id: @document } if @document) || {}))
34
35
  end
35
36
  end
37
+
38
+ def key
39
+ @action.key
40
+ end
36
41
  end
37
42
  end
38
43
  end
@@ -1,13 +1,11 @@
1
1
  <%= content_tag @tag, class: @classes do %>
2
- <% @actions.each do |action| %>
3
- <% result = capture { @view_context.render((action.component || Blacklight::Document::ActionComponent).new(action: action, document: @document, options: @options, url_opts: @url_opts)) } %>
4
-
2
+ <% actions.each do |action| %>
5
3
  <% if @wrapping_tag %>
6
4
  <%= content_tag(@wrapping_tag, class: Array(@wrapping_classes) + [action.key]) do %>
7
- <%= result %>
5
+ <%= action %>
8
6
  <% end %>
9
7
  <% else %>
10
- <%= result %>
8
+ <%= action %>
11
9
  <% end %>
12
10
  <% end %>
13
11
  <% end %>
@@ -4,9 +4,14 @@ module Blacklight
4
4
  module Document
5
5
  # Render a bookmark widget to bookmark / unbookmark a document
6
6
  class ActionsComponent < ::ViewComponent::Base
7
+ renders_many :actions, (lambda do |action:, component: nil, **kwargs|
8
+ component ||= action.component || Blacklight::Document::ActionComponent
9
+ component.new(action: action, document: @document, options: @options, url_opts: @url_opts, link_classes: @link_classes, **kwargs)
10
+ end)
11
+
7
12
  # @param [Blacklight::Document] document
8
13
  # rubocop:disable Metrics/ParameterLists
9
- def initialize(document: nil, actions: [], options: {}, url_opts: nil, tag: :div, classes: 'index-document-functions', wrapping_tag: nil, wrapping_classes: nil)
14
+ def initialize(document: nil, actions: [], options: {}, url_opts: nil, tag: :div, classes: 'index-document-functions', wrapping_tag: nil, wrapping_classes: nil, link_classes: 'nav-link')
10
15
  @document = document
11
16
  @actions = actions
12
17
  @tag = tag
@@ -15,11 +20,20 @@ module Blacklight
15
20
  @url_opts = url_opts
16
21
  @wrapping_tag = wrapping_tag
17
22
  @wrapping_classes = wrapping_classes
23
+ @link_classes = link_classes
18
24
  end
19
25
  # rubocop:enable Metrics/ParameterLists
20
26
 
27
+ def before_render
28
+ return if actions.present?
29
+
30
+ @actions.each do |a|
31
+ action(component: a.component, action: a)
32
+ end
33
+ end
34
+
21
35
  def render?
22
- @actions.any?
36
+ actions.present?
23
37
  end
24
38
  end
25
39
  end