Skip to content

Commit

Permalink
Merge pull request #2443 from projectblacklight/viewcomponents-slots-v2
Browse files Browse the repository at this point in the history
Support ViewComponent slots v2 API
  • Loading branch information
jcoyne authored Apr 17, 2021
2 parents 5a394f9 + 0a12aa6 commit 7c11785
Show file tree
Hide file tree
Showing 43 changed files with 448 additions and 192 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Naming/MethodParameterName:
AllowedNames:
- id
- q
- as

Naming/PredicateName:
ForbiddenPrefixes:
Expand Down Expand Up @@ -122,3 +123,6 @@ Style/RedundantRegexpEscape:

Style/SlicingWithRange:
Enabled: true

Rails/ContentTag:
Enabled: false
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<% if constraints.present? %>
<div class="constraints well search_history">
<h4><%= t 'blacklight.advanced_search.form.search_context' %></h4>
<%= constraints %>
<% constraints.each do |constraint| %>
<%= constraint %>
<% end %>
</div>
<% end %>

Expand All @@ -15,7 +17,9 @@
</h2>

<div id="advanced_search">
<%= search_field_controls %>
<% search_field_controls.each do |control| %>
<%= control %>
<% end %>
</div>
</div>

Expand All @@ -24,7 +28,9 @@

<div id="advanced_search_facets" class="limit_input">
<div class="advanced-facet-limits panel-group">
<%= search_filter_controls %>
<% search_filter_controls.each do |control| %>
<%= control %>
<% end %>
</div>
</div>
</div>
Expand Down
83 changes: 48 additions & 35 deletions app/components/blacklight/advanced_search_form_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,79 @@

module Blacklight
class AdvancedSearchFormComponent < SearchBarComponent
with_content_areas :constraints, :search_field_controls, :search_filter_controls
include Blacklight::ContentAreasShim

renders_many :constraints
renders_many :search_field_controls
renders_many :search_filter_controls, (lambda do |config:, display_facet:, presenter: nil, component: nil, **kwargs|
presenter ||= (config.presenter || Blacklight::FacetFieldPresenter).new(config, display_facet, @view_context)
component = component || config.advanced_search_component || Blacklight::FacetFieldCheckboxesComponent

component.new(facet_field: presenter, **kwargs)
end)

def initialize(response:, **options)
super(**options)
@response = response
end

def before_render
initialize_search_field_controls if search_field_controls.blank?
initialize_search_filter_controls if search_filter_controls.blank?
initialize_constraints if constraints.blank?
end

def default_operator_menu
options_with_labels = [:must, :should].index_by { |op| t(op, scope: 'blacklight.advanced_search.op') }
select_tag(:op, options_for_select(options_with_labels, params[:op]), class: 'input-small')
end

# Rubocop is just wrong here, so...:
# rubocop:disable Rails/ContentTag
def search_field_controls
@search_field_controls || safe_join(search_fields.values.map.with_index do |field, i|
fields_for('clause[]', i, include_id: false) do |f|
content_tag(:div, class: 'form-group advanced-search-field row') do
f.label(:query, field.display_label('search'), class: "col-sm-3 col-form-label") +
content_tag(:div, class: 'col-sm-9') do
f.hidden_field(:field, value: field.key) +
f.text_field(:query, value: query_for_search_clause(field.key), class: 'form-control')
def sort_fields_select
options = sort_fields.values.map { |field_config| [@view_context.sort_field_label(field_config.key), field_config.key] }
select_tag(:sort, options_for_select(options, params[:sort]), class: "form-control sort-select")
end

private

def initialize_search_field_controls
search_fields.values.each.with_index do |field, i|
search_field_control do
fields_for('clause[]', i, include_id: false) do |f|
content_tag(:div, class: 'form-group advanced-search-field row') do
f.label(:query, field.display_label('search'), class: "col-sm-3 col-form-label") +
content_tag(:div, class: 'col-sm-9') do
f.hidden_field(:field, value: field.key) +
f.text_field(:query, value: query_for_search_clause(field.key), class: 'form-control')
end
end
end
end
end, "\n")
end
# rubocop:enable Rails/ContentTag

def query_for_search_clause(key)
field = (@params[:clause] || {}).values.find { |value| value['field'].to_s == key.to_s }

field&.dig('query')
end
end

def search_filter_controls
return @search_filter_controls if @search_filter_controls

def initialize_search_filter_controls
fields = blacklight_config.facet_fields.select { |_k, v| v.include_in_advanced_search || v.include_in_advanced_search.nil? }

safe_join(fields.map do |_k, config|
fields.each do |_k, config|
display_facet = @response.aggregations[config.field]

presenter = (config.presenter || Blacklight::FacetFieldPresenter).new(config, display_facet, @view_context)
component = config.advanced_search_component || Blacklight::FacetFieldCheckboxesComponent
@view_context.render(component.new(facet_field: presenter))
end, "\n")
search_filter_control(config: config, display_facet: display_facet)
end
end

def constraints
params = @view_context.search_state.params_for_search.except :page, :f_inclusive, :q, :search_field, :op, :index, :sort
def initialize_constraints
constraint do
params = @view_context.search_state.params_for_search.except :page, :f_inclusive, :q, :search_field, :op, :index, :sort

params.except!(*search_fields.map { |_key, field_def| field_def[:key] })
params.except!(*search_fields.map { |_key, field_def| field_def[:key] })

@view_context.render_search_to_s(params)
@view_context.render_search_to_s(params)
end
end

def sort_fields_select
options = sort_fields.values.map { |field_config| [@view_context.sort_field_label(field_config.key), field_config.key] }
select_tag(:sort, options_for_select(options, params[:sort]), class: "form-control sort-select")
def query_for_search_clause(key)
field = (@params[:clause] || {}).values.find { |value| value['field'].to_s == key.to_s }

field&.dig('query')
end

def search_fields
Expand Down
22 changes: 19 additions & 3 deletions app/components/blacklight/constraints_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,23 @@
<%= link_to t('blacklight.search.start_over'), start_over_path, class: "catalog_startOverLink btn btn-primary" %>

<span class="constraints-label sr-only"><%= t('blacklight.search.filters.title') %></span>
<%= query_constraints_area || query_constraints %>
<%= facet_constraints_area || facet_constraints %>
<%= additional_constraints %>
<% if query_constraints_area.present? %>
<% query_constraints_area.each do |constraint| %>
<%= constraint %>
<% end %>
<% else %>
<%= query_constraints %>
<% end %>

<% if facet_constraints_area.present? %>
<% facet_constraints_area.each do |constraint| %>
<%= constraint %>
<% end %>
<% else %>
<%= facet_constraints %>
<% end %>

<% additional_constraints.each do |constraints| %>
<%= constraints %>
<% end %>
<% end %>
6 changes: 5 additions & 1 deletion app/components/blacklight/constraints_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

module Blacklight
class ConstraintsComponent < ::ViewComponent::Base
with_content_areas :query_constraints_area, :facet_constraints_area, :additional_constraints
include Blacklight::ContentAreasShim

renders_many :query_constraints_area
renders_many :facet_constraints_area
renders_many :additional_constraints

def initialize(search_state:,
id: 'appliedParams', classes: 'clearfix constraints-container',
Expand Down
12 changes: 12 additions & 0 deletions app/components/blacklight/content_areas_shim.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Blacklight
# Shim to support ViewComponent v2 slots using the content_areas API for backwards compatibility
module ContentAreasShim
# Shim the `with` helper to write content into slots instead
def with(slot_name, *args, **kwargs, &block)
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.')
public_send(slot_name, *args, **kwargs, &block)
end
end
end
4 changes: 4 additions & 0 deletions app/components/blacklight/document/action_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def url
@view_context.document_action_path(@action, @url_opts.merge(({ id: @document } if @document) || {}))
end
end

def key
@action.key
end
end
end
end
8 changes: 3 additions & 5 deletions app/components/blacklight/document/actions_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<%= content_tag @tag, class: @classes do %>
<% @actions.each do |action| %>
<% result = capture { @view_context.render((action.component || Blacklight::Document::ActionComponent).new(action: action, document: @document, options: @options, url_opts: @url_opts, link_classes: @link_classes)) } %>

<% actions.each do |action| %>
<% if @wrapping_tag %>
<%= content_tag(@wrapping_tag, class: Array(@wrapping_classes) + [action.key]) do %>
<%= result %>
<%= action %>
<% end %>
<% else %>
<%= result %>
<%= action %>
<% end %>
<% end %>
<% end %>
15 changes: 14 additions & 1 deletion app/components/blacklight/document/actions_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ module Blacklight
module Document
# Render a bookmark widget to bookmark / unbookmark a document
class ActionsComponent < ::ViewComponent::Base
renders_many :actions, (lambda do |action:, component: nil, **kwargs|
component ||= action.component || Blacklight::Document::ActionComponent
component.new(action: action, document: @document, options: @options, url_opts: @url_opts, link_classes: @link_classes, **kwargs)
end)

# @param [Blacklight::Document] document
# rubocop:disable Metrics/ParameterLists
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')
Expand All @@ -19,8 +24,16 @@ def initialize(document: nil, actions: [], options: {}, url_opts: nil, tag: :div
end
# rubocop:enable Metrics/ParameterLists

def before_render
return if actions.present?

@actions.each do |a|
action(component: a.component, action: a)
end
end

def render?
@actions.any?
actions.present?
end
end
end
Expand Down
11 changes: 4 additions & 7 deletions app/components/blacklight/document_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@
<%= body %>
<% else %>
<div class="document-main-section">
<header class="documentHeader row">
<%= content_tag @title_component, class: 'index_title document-title-heading' do %>
<%= before_title %><%= title %><%= after_title %>
<% end %>
<%= actions %>
</header>

<%= title %>
<%= embed %>
<%= content %>
<%= metadata %>
<% metadata_sections.each do |section| %>
<%= section %>
<% end %>
</div>

<%= thumbnail %>
Expand Down
Loading

0 comments on commit 7c11785

Please sign in to comment.