Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract a Spotlight::TabPanelComponent for building bootstrap tab panels #2784

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/components/spotlight/tab_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= tag.div role: 'tabpanel', class: @classes.join(' '), id: @id, data: @data do %>
<%= content %>
<% end %>
30 changes: 30 additions & 0 deletions app/components/spotlight/tab_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Spotlight
# Component for a single tab panel pane, with responsibility for also building
# out the tab panel's control
class TabComponent < ViewComponent::Base
def initialize(id:, label:, active: false, label_data: {})
super

@id = id
@label = label
@active = active
@classes = ['tab-pane', ('active' if active)].compact
@label_data = label_data
end

def render_label
tag.li role: 'presentation', class: 'nav-item' do
link_to @label,
"##{@id}",
aria: {
controls: @id
},
role: 'tab',
data: { toggle: 'tab' }.merge(@label_data),
class: ['nav-link', ('active' if @active)].compact.join(' ')
end
end
end
end
19 changes: 19 additions & 0 deletions app/components/spotlight/tab_panel_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<% tabs_content = capture do %>
<ul class="nav nav-tabs" role="tablist">
<% tabs.each do |tab| %>
<%= tab.render_label %>
<% end %>
</ul>
<% end %>

<%= tabs_content if @tab_position == :outside %>

<div role="tabpanel">
<%= tabs_content if @tab_position == :inside %>

<div class="tab-content">
<% tabs.each do |tab| %>
<%= tab %>
<% end %>
</div>
</div>
13 changes: 13 additions & 0 deletions app/components/spotlight/tab_panel_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Spotlight
# Component for building out a basic tabbed interface
class TabPanelComponent < ViewComponent::Base
renders_many :tabs, Spotlight::TabComponent

def initialize(tab_position: :inside)
super
@tab_position = tab_position
end
end
end
79 changes: 29 additions & 50 deletions app/views/spotlight/appearances/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,9 @@
</ul>
</div>
<% end %>
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<% if current_exhibit.themes.many? %>
<li role="presentation" class="nav-item">
<a href="#site-theme" aria-controls="site-theme" role="tab" data-toggle="tab" class="nav-link active"><%= t(:'.site_theme.heading') %></a>
</li>
<% end %>

<li role="presentation" class="nav-item">
<a href="#site-masthead" aria-controls="site-masthead" role="tab" data-toggle="tab" class="nav-link <%= 'active' unless current_exhibit.themes.many? %>"><%= t(:'.site_masthead.heading') %></a>
</li>

<li role="presentation" class="nav-item">
<a href="#site-thumbnail" aria-controls="site-thumbnail" role="tab" data-toggle="tab" class="nav-link"><%= t(:'.site_thumbnail.heading') %></a>
</li>

<li role="presentation" class="nav-item">
<a href="#main-menu" aria-controls="main-menu" role="tab" data-toggle="tab" class="nav-link"><%= t(:'.main_navigation.menu') %></a>
</li>
</ul>
<div class="tab-content">
<% if current_exhibit.themes.many? %>
<div role="tabpanel" class="tab-pane active" id="site-theme">
<%= render Spotlight::TabPanelComponent.new do |component| %>
<% if current_exhibit.themes.many? %>
<% component.tab(id: 'site-theme', active: true, label: t(:'.site_theme.heading')) do %>
<p class="instructions"><%= t(:'.site_theme.help') %></p>
<%= f.form_group :theme, label: { text: t(:'.site_theme.label') } do %>
<% current_exhibit.themes.each do |theme| %>
Expand All @@ -48,37 +28,36 @@
</div>
<% end %>
<% end %>
</div>
<% end %>
<% end %>

<div role="tabpanel" class="tab-pane <%= 'active' unless current_exhibit.themes.many? %>" id="site-masthead">
<p class="instructions"><%= t(:'.site_masthead.help') %></p>
<%= f.fields_for(:masthead, current_exhibit.masthead || current_exhibit.build_masthead) do |m| %>
<%= render '/spotlight/featured_images/form', f: m, initial_crop_selection: Spotlight::Engine.config.masthead_initial_crop_selection, crop_type: :masthead %>
<% end %>
</div>
<% component.tab(id: 'site-masthead', active: !current_exhibit.themes.many?, label: t(:'.site_masthead.heading')) do %>
<p class="instructions"><%= t(:'.site_masthead.help') %></p>
<%= f.fields_for(:masthead, current_exhibit.masthead || current_exhibit.build_masthead) do |m| %>
<%= render '/spotlight/featured_images/form', f: m, initial_crop_selection: Spotlight::Engine.config.masthead_initial_crop_selection, crop_type: :masthead %>
<% end %>
<% end %>

<div role="tabpanel" class="tab-pane" id="site-thumbnail">
<p class="instructions"><%= t(:'.site_thumbnail.help') %></p>
<%= f.fields_for(:thumbnail, current_exhibit.thumbnail || current_exhibit.build_thumbnail) do |m| %>
<%= render '/spotlight/featured_images/form', f: m, initial_crop_selection: Spotlight::Engine.config.thumbnail_initial_crop_selection, crop_type: :thumbnail %>
<% end %>
</div>
<% component.tab(id: 'site-thumbnail', label: t(:'.site_thumbnail.heading')) do %>
<p class="instructions"><%= t(:'.site_thumbnail.help') %></p>
<%= f.fields_for(:thumbnail, current_exhibit.thumbnail || current_exhibit.build_thumbnail) do |m| %>
<%= render '/spotlight/featured_images/form', f: m, initial_crop_selection: Spotlight::Engine.config.thumbnail_initial_crop_selection, crop_type: :thumbnail %>
<% end %>
<% end %>

<div role="tabpanel" class="tab-pane" id="main-menu">
<%= field_set_tag do %>
<p class="instructions"><%= t(:'.main_navigation.help') %></p>
<div class="card-group dd main_navigation_admin col-sm-7" id="nested-navigation" data-behavior="nestable" data-max-depth="1">
<ol class="dd-list">
<%= f.fields_for :main_navigations do |label| %>
<%= render layout: 'spotlight/shared/dd3_item', locals: { id: label.object.nav_type, field: label, label: label.object.label_or_default, default_value: label.object.default_label, enabled_method: :display } do; end %>
<% end %>
</ol>
</div>
<% end %>
</div>
</div>
</div>
<% component.tab(id: 'main-menu', label: t(:'.main_navigation.menu')) do %>
<%= field_set_tag do %>
<p class="instructions"><%= t(:'.main_navigation.help') %></p>
<div class="card-group dd main_navigation_admin col-sm-7" id="nested-navigation" data-behavior="nestable" data-max-depth="1">
<ol class="dd-list">
<%= f.fields_for :main_navigations do |label| %>
<%= render layout: 'spotlight/shared/dd3_item', locals: { id: label.object.nav_type, field: label, label: label.object.label_or_default, default_value: label.object.default_label, enabled_method: :display } do; end %>
<% end %>
</ol>
</div>
<% end %>
<% end %>
<% end %>

<div class="form-actions">
<div class="primary-actions">
Expand Down
36 changes: 11 additions & 25 deletions app/views/spotlight/bulk_updates/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,16 @@
<%= render 'progress_panel' %>
</div>

<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="nav-item">
<a href="#overview" aria-controls="overview" role="tab" data-toggle="tab" class="nav-link active"><%= t(:'.overview.heading') %></a>
</li>
<li role="presentation" class="nav-item">
<a href="#download" aria-controls="download" role="tab" data-toggle="tab" class="nav-link"><%= t(:'.download.heading') %></a>
</li>
<li role="presentation" class="nav-item">
<a href="#upload" aria-controls="upload" role="tab" data-toggle="tab" class="nav-link"><%= t(:'.upload.heading') %></a>
</li>
</ul>
<%= render Spotlight::TabPanelComponent.new do |component| %>
<% component.tab(id: 'overview', label: t(:'.overview.heading'), active: true) do %>
<%= render 'overview' %>
<% end %>

<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="overview">
<%= render 'overview' %>
</div>
<% component.tab(id: 'download', label: t(:'.download.heading')) do %>
<%= render 'download' %>
<% end %>

<div role="tabpanel" class="tab-pane" id="download">
<%= render 'download' %>
</div>

<div role="tabpanel" class="tab-pane" id="upload">
<%= render 'upload' %>
</div>
</div>
</div>
<% component.tab(id: 'upload', label: t(:'.upload.heading')) do %>
<%= render 'upload' %>
<% end %>
<% end %>
14 changes: 6 additions & 8 deletions app/views/spotlight/exhibits/_delete.html.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<div role="tabpanel" class="tab-pane" id="delete">
<div class="alert alert-danger">
<h2 class="alert-heading h4"><%= t(:".heading") %></h2>
<div class="row">
<p class='col-9'><%= t(:".warning_html", export_link: link_to(t(:'spotlight.exhibits.export.download'), spotlight.edit_exhibit_path(current_exhibit, anchor: 'export'))) %></p>
<div class='col-3'>
<%= delete_link current_exhibit, class: 'btn btn-secondary' %>
</div>
<div class="alert alert-danger">
<h2 class="alert-heading h4"><%= t(:".heading") %></h2>
<div class="row">
<p class='col-9'><%= t(:".warning_html", export_link: link_to(t(:'spotlight.exhibits.export.download'), spotlight.edit_exhibit_path(current_exhibit, anchor: 'export'))) %></p>
<div class='col-3'>
<%= delete_link current_exhibit, class: 'btn btn-secondary' %>
</div>
</div>
</div>
10 changes: 4 additions & 6 deletions app/views/spotlight/exhibits/_export.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<div role="tabpanel" class="tab-pane <%= 'active' if @tab == 'export' %>" id="export">
<div class="row col-md-12">
<p class="instructions"><%= t :'.instructions' %></p>
<div class="primary-actions">
<%= link_to t(:'.download'), get_exhibit_path(current_exhibit, format: 'json'), class: 'btn btn-primary' %>
</div>
<div class="row col-md-12">
<p class="instructions"><%= t :'.instructions' %></p>
<div class="primary-actions">
<%= link_to t(:'.download'), get_exhibit_path(current_exhibit, format: 'json'), class: 'btn btn-primary' %>
</div>
</div>
26 changes: 12 additions & 14 deletions app/views/spotlight/exhibits/_import.html.erb
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
<div role="tabpanel" class="tab-pane <%= 'active' if @tab == 'import' %>" id="import">
<%= bootstrap_form_for [:import, current_exhibit], html: { class: 'clearfix', multipart: true } do |f| %>
<div class="row col-md-12">
<p class="instructions"><%= t :'.instructions' %></p>
<div class="form-group">
<%= file_field_tag :file, class: 'form-control' %>
<%= hidden_field_tag :tab, 'import' %>
</div>
<div class="form-actions">
<div class="primary-actions">
<%= f.submit t(:'.button'), class: 'btn btn-primary' %>
</div>
<%= bootstrap_form_for [:import, current_exhibit], html: { class: 'clearfix', multipart: true } do |f| %>
<div class="row col-md-12">
<p class="instructions"><%= t :'.instructions' %></p>
<div class="form-group">
<%= file_field_tag :file, class: 'form-control' %>
<%= hidden_field_tag :tab, 'import' %>
</div>
<div class="form-actions">
<div class="primary-actions">
<%= f.submit t(:'.button'), class: 'btn btn-primary' %>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
100 changes: 49 additions & 51 deletions app/views/spotlight/exhibits/_languages.html.erb
Original file line number Diff line number Diff line change
@@ -1,59 +1,57 @@
<div role="tabpanel" class="tab-pane <%= 'active' if @tab == 'language' %>" id="language">
<p class="instructions"><%= t :'spotlight.exhibits.languages.selection_instructions' %></p>
<p class="instructions"><%= t :'spotlight.exhibits.languages.selection_instructions' %></p>

<%= bootstrap_form_for [current_exhibit, Spotlight::Language.new], layout: :horizontal, html: { class: 'row' }, label_col: "col-sm-3", control_col: "col-sm-9" do |f| %>
<div class='col-sm-6'>
<%= f.select('locale', add_exhibit_language_dropdown_options, prompt: t('.selection_prompt')) %>
<%= hidden_field_tag :tab, 'language' %>
</div>
<div class='col-sm-6'>
<%= f.submit nil, class: 'btn btn-primary' %>
</div>
<% end %>
<%= bootstrap_form_for [current_exhibit, Spotlight::Language.new], layout: :horizontal, html: { class: 'row' }, label_col: "col-sm-3", control_col: "col-sm-9" do |f| %>
<div class='col-sm-6'>
<%= f.select('locale', add_exhibit_language_dropdown_options, prompt: t('.selection_prompt')) %>
<%= hidden_field_tag :tab, 'language' %>
</div>
<div class='col-sm-6'>
<%= f.submit nil, class: 'btn btn-primary' %>
</div>
<% end %>

<h2 class="mt-4"><%= t :'spotlight.exhibits.languages.current_header' %></h2>
<h2 class="mt-4"><%= t :'spotlight.exhibits.languages.current_header' %></h2>

<% if current_exhibit.languages.any? && current_exhibit.languages.last.persisted? %>
<p class="instructions"><%= t :'spotlight.exhibits.languages.current_instructions' %></p>
<% if current_exhibit.languages.any? && current_exhibit.languages.last.persisted? %>
<p class="instructions"><%= t :'spotlight.exhibits.languages.current_instructions' %></p>

<%= bootstrap_form_for current_exhibit, layout: :horizontal do |f| %>
<div class="row">
<div class="col-md-8">
<table class="table table-striped">
<thead>
<tr>
<th scope="col"><%= t('.table_heading.language') %></th>
<th scope="col" class='text-center'><%= t('.table_heading.public') %></th>
<th scope="col" class='text-center'><%= t('.table_heading.action') %></th>
</tr>
</thead>
<tbody>
<% current_exhibit.languages.each do |language| %>
<%= f.fields_for :languages, language do |languages| %>
<tr>
<td><%= t("locales.#{language.locale}") %></td>
<td class='text-center'>
<div class='checkbox'>
<%= languages.label :public, class: 'sr-only' %>
<%= languages.check_box_without_bootstrap :public %>
</div>
</td>
<td class='text-center'><%= link_to t('.remove'), exhibit_language_path(current_exhibit, language), method: :delete, data: { confirm: t('.modal.confirm') }, class: 'btn btn-sm btn-danger' %></td>
</tr>
<% end %>
<%= bootstrap_form_for current_exhibit, layout: :horizontal do |f| %>
<div class="row">
<div class="col-md-8">
<table class="table table-striped">
<thead>
<tr>
<th scope="col"><%= t('.table_heading.language') %></th>
<th scope="col" class='text-center'><%= t('.table_heading.public') %></th>
<th scope="col" class='text-center'><%= t('.table_heading.action') %></th>
</tr>
</thead>
<tbody>
<% current_exhibit.languages.each do |language| %>
<%= f.fields_for :languages, language do |languages| %>
<tr>
<td><%= t("locales.#{language.locale}") %></td>
<td class='text-center'>
<div class='checkbox'>
<%= languages.label :public, class: 'sr-only' %>
<%= languages.check_box_without_bootstrap :public %>
</div>
</td>
<td class='text-center'><%= link_to t('.remove'), exhibit_language_path(current_exhibit, language), method: :delete, data: { confirm: t('.modal.confirm') }, class: 'btn btn-sm btn-danger' %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% end %>
</tbody>
</table>
</div>
<div class="form-actions">
<div class="primary-actions">
<%= hidden_field_tag :tab, 'language' %>
<%= f.submit nil, class: 'btn btn-primary' %>
</div>
</div>
<div class="form-actions">
<div class="primary-actions">
<%= hidden_field_tag :tab, 'language' %>
<%= f.submit nil, class: 'btn btn-primary' %>
</div>
<% end %>
<% else %>
<p><%= t('.no_languages_help_text') %></p>
</div>
<% end %>
</div>
<% else %>
<p><%= t('.no_languages_help_text') %></p>
<% end %>
11 changes: 11 additions & 0 deletions app/views/spotlight/exhibits/_public_exhibits.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<%= render 'tags', tags: @exhibits.published.all_tags %>
<%= render 'exhibits', exhibits: @published_exhibits %>

<% if @published_exhibits.total_count > @published_exhibits.size %>
<nav class="d-flex justify-content-center">
<ul class="pagination">
<li class="page-item"><%= link_to_previous_page @published_exhibits, t('views.pagination.previous').html_safe, class: 'page-link' %></li>
<li class="page-item"><%= link_to_next_page @published_exhibits, t('views.pagination.next').html_safe, class: 'page-link' %></li>
</ul>
</nav>
<% end %>
Loading