Skip to content

Commit

Permalink
Summary table
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanCornthwaiteKatalyst committed Jun 14, 2024
1 parent cf386d4 commit c9c43d5
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 119 deletions.
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
katalyst-koi (4.7.3)
katalyst-koi (4.8.0)
bcrypt
importmap-rails
katalyst-content
Expand Down Expand Up @@ -212,7 +212,7 @@ GEM
base64
katalyst-basic-auth (0.5.0)
rack
katalyst-content (2.4.0)
katalyst-content (2.4.1)
active_storage_validations
katalyst-html-attributes
katalyst-kpop
Expand All @@ -231,7 +231,7 @@ GEM
katalyst-kpop
katalyst-tables
view_component
katalyst-tables (3.0.0)
katalyst-tables (3.1.0)
katalyst-html-attributes
view_component
language_server-protocol (3.17.0.3)
Expand Down
85 changes: 85 additions & 0 deletions app/components/concerns/koi/tables/cells.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# frozen_string_literal: true

module Koi
module Tables
module Cells
# Generates a column that links to the record's show page (by default).
#
# @param column [Symbol] the column's name, called as a method on the record
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param url [Symbol|String|Proc] arguments for url_For, defaults to the record
# @param link [Hash] options to be passed to the link_to helper
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to alter the cell content
#
# If a block is provided, it will be called with the link cell component as an argument.
# @yieldparam cell [Katalyst::Tables::Cells::LinkComponent] the cell component
#
# @return [void]
#
# @example Render a column containing the record's title, linked to its show page
# <% row.link :title %> # => <td><a href="/admin/post/15">About us</a></td>
# @example Render a column containing the record's title, linked to its edit page
# <% row.link :title, url: :edit_admin_post_path do |cell| %>
# Edit <%= cell %>
# <% end %>
# # => <td><a href="/admin/post/15/edit">Edit About us</a></td>
def link(column, label: nil, heading: false, url: [:admin, record], link: {}, **, &)
with_cell(Tables::Cells::LinkComponent.new(
collection:, row:, column:, record:, label:, heading:, url:, link:, **,
), &)
end

# Generates a column from an enum value rendered as a tag.
# The target attribute must be defined as an `enum` in the model.
#
# @param column [Symbol] the column's name, called as a method on the record.
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to wrap the cell content
#
# When rendering an enum value, the component will check for translations
# using the key `active_record.attributes.[model]/[column].[value]`,
# e.g. `active_record.attributes.banner/status.published`.
#
# If a block is provided, it will be called with the cell component as an argument.
# @yieldparam cell [Katalyst::Tables::CellComponent] the cell component
#
# @return [void]
#
# @example Render a generic text column for any value that supports `to_s`
# <% row.enum :status %>
# <%# label => <th>Status</th> %>
# <%# data => <td class="type-enum"><span data-enum="status" data-value="published">Published</span></td> %>
def enum(column, label: nil, heading: false, **, &)
with_cell(Tables::Cells::EnumComponent.new(
collection:, row:, column:, record:, label:, heading:, **,
), &)
end

# Generates a column that renders an ActiveStorage attachment as a downloadable link.
#
# @param column [Symbol] the column's name, called as a method on the record
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param variant [Symbol] the variant to use when rendering the image (default :thumb)
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to alter the cell content
#
# If a block is provided, it will be called with the attachment cell component as an argument.
# @yieldparam cell [Katalyst::Tables::Cells::AttachmentComponent] the cell component
#
# @return [void]
#
# @example Render a column containing a download link to the record's background image
# <% row.attachment :background %> # => <td><a href="...">background.png</a></td>
def attachment(column, label: nil, heading: false, variant: :thumb, **, &)
with_cell(Tables::Cells::AttachmentComponent.new(
collection:, row:, column:, record:, label:, heading:, variant:, **,
), &)
end
end
end
end
7 changes: 7 additions & 0 deletions app/components/koi/summary_table_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Koi
class SummaryTableComponent < Katalyst::SummaryTableComponent
include Tables::Cells
end
end
7 changes: 7 additions & 0 deletions app/components/koi/table_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Koi
class TableComponent < Katalyst::TableComponent
include Tables::Cells
end
end
80 changes: 2 additions & 78 deletions app/components/koi/tables/table_component.rb
Original file line number Diff line number Diff line change
@@ -1,85 +1,9 @@
# frozen_string_literal: true

# @deprecated prefer Koi::TableComponent
module Koi
module Tables
class TableComponent < Katalyst::TableComponent
# Generates a column that links to the record's show page (by default).
#
# @param column [Symbol] the column's name, called as a method on the record
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param url [Symbol|String|Proc] arguments for url_For, defaults to the record
# @param link [Hash] options to be passed to the link_to helper
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to alter the cell content
#
# If a block is provided, it will be called with the link cell component as an argument.
# @yieldparam cell [Katalyst::Tables::Cells::LinkComponent] the cell component
#
# @return [void]
#
# @example Render a column containing the record's title, linked to its show page
# <% row.link :title %> # => <td><a href="/admin/post/15">About us</a></td>
# @example Render a column containing the record's title, linked to its edit page
# <% row.link :title, url: :edit_admin_post_path do |cell| %>
# Edit <%= cell %>
# <% end %>
# # => <td><a href="/admin/post/15/edit">Edit About us</a></td>
def link(column, label: nil, heading: false, url: [:admin, record], link: {}, **, &)
with_cell(Tables::Cells::LinkComponent.new(
collection:, row:, column:, record:, label:, heading:, url:, link:, **,
), &)
end

# Generates a column from an enum value rendered as a tag.
# The target attribute must be defined as an `enum` in the model.
#
# @param column [Symbol] the column's name, called as a method on the record.
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to wrap the cell content
#
# When rendering an enum value, the component will check for translations
# using the key `active_record.attributes.[model]/[column].[value]`,
# e.g. `active_record.attributes.banner/status.published`.
#
# If a block is provided, it will be called with the cell component as an argument.
# @yieldparam cell [Katalyst::Tables::CellComponent] the cell component
#
# @return [void]
#
# @example Render a generic text column for any value that supports `to_s`
# <% row.enum :status %>
# <%# label => <th>Status</th> %>
# <%# data => <td class="type-enum"><span data-enum="status" data-value="published">Published</span></td> %>
def enum(column, label: nil, heading: false, **, &)
with_cell(Tables::Cells::EnumComponent.new(
collection:, row:, column:, record:, label:, heading:, **,
), &)
end

# Generates a column that renders an ActiveStorage attachment as a downloadable link.
#
# @param column [Symbol] the column's name, called as a method on the record
# @param label [String|nil] the label to use for the column header
# @param heading [boolean] if true, data cells will use `th` tags
# @param variant [Symbol] the variant to use when rendering the image (default :thumb)
# @param ** [Hash] HTML attributes to be added to column cells
# @param & [Proc] optional block to alter the cell content
#
# If a block is provided, it will be called with the attachment cell component as an argument.
# @yieldparam cell [Katalyst::Tables::Cells::AttachmentComponent] the cell component
#
# @return [void]
#
# @example Render a column containing a download link to the record's background image
# <% row.attachment :background %> # => <td><a href="...">background.png</a></td>
def attachment(column, label: nil, heading: false, variant: :thumb, **, &)
with_cell(Tables::Cells::AttachmentComponent.new(
collection:, row:, column:, record:, label:, heading:, variant:, **,
), &)
end
class TableComponent < ::Koi::TableComponent
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def authenticate_local_admins(value)
include ::Pagy::Backend

default_form_builder "Koi::FormBuilder"
default_table_component Koi::Tables::TableComponent
default_table_component Koi::TableComponent
default_summary_table_component Koi::SummaryTableComponent

helper Katalyst::GOVUK::Formbuilder::Frontend
helper Katalyst::Navigation::FrontendHelper
Expand Down
2 changes: 1 addition & 1 deletion katalyst-koi.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "katalyst-koi"
s.version = "4.7.3"
s.version = "4.8.0"
s.authors = ["Katalyst Interactive"]
s.email = ["[email protected]"]

Expand Down
21 changes: 2 additions & 19 deletions lib/generators/koi/admin_views/admin_views_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,6 @@ def govuk_input_for(attribute)
end
end

def summary_attribute_for(attribute)
case attribute.type
when :integer
%(<% dl.number :#{attribute.name} %>)
when :boolean
%(<% dl.boolean :#{attribute.name} %>)
when :date
%(<% dl.date :#{attribute.name} %>)
when :datetime
%(<% dl.datetime :#{attribute.name} %>)
when :rich_text
%(<% dl.rich_text :#{attribute.name} %>)
when :attachment
%(<% dl.attachment :#{attribute.name} %>)
else
%(<% dl.text :#{attribute.name} %>)
end
end

def index_attribute_for(attribute)
case attribute.type
when :integer
Expand All @@ -89,6 +70,8 @@ def index_attribute_for(attribute)
end
end

alias_method :summary_attribute_for, :index_attribute_for

def index_attributes
attributes
end
Expand Down
10 changes: 7 additions & 3 deletions lib/generators/koi/admin_views/templates/show.html.erb.tt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

<h2>Summary</h2>

<%%= render Koi::SummaryListComponent.new(model: <%= singular_name %>) do |dl| %>
<%- attributes.each do |attribute| -%>
<%%= summary_table_with(model: <%= singular_name %>) do |row| %>
<%- attributes.each_with_index do |attribute, index| -%>
<%- if index.zero? -%>
<%% row.link :<%= attribute.name %> %>
<%- else -%>
<%= summary_attribute_for attribute %>
<%- end -%>
<%- end -%>
<%- end -%>
<%% end %>

<div class="actions">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "rails_helper"

RSpec.describe Koi::Tables::Cells::AttachmentComponent do
let(:table) { Koi::Tables::TableComponent.new(collection:) }
let(:table) { Koi::TableComponent.new(collection:) }
let(:collection) { create_list(:banner, 1, :with_image) }
let(:rendered) { render_inline(table) { |row| row.attachment(:image) } }
let(:label) { rendered.at_css("thead th") }
Expand Down
2 changes: 1 addition & 1 deletion spec/components/koi/tables/cells/enum_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "rails_helper"

RSpec.describe Koi::Tables::Cells::EnumComponent do
let(:table) { Koi::Tables::TableComponent.new(collection:) }
let(:table) { Koi::TableComponent.new(collection:) }
let(:collection) { create_list(:banner, 1, status: "published") }
let(:rendered) { render_inline(table) { |row, _post| row.enum(:status) } }
let(:label) { rendered.at_css("thead th") }
Expand Down
2 changes: 1 addition & 1 deletion spec/components/koi/tables/cells/link_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "rails_helper"

RSpec.describe Koi::Tables::Cells::LinkComponent do
let(:table) { Koi::Tables::TableComponent.new(collection:) }
let(:table) { Koi::TableComponent.new(collection:) }
let(:collection) { create_list(:post, 1) }
let(:rendered) { render_inline(table) { |row, _post| row.link(:name) } }
let(:label) { rendered.at_css("thead th") }
Expand Down
12 changes: 6 additions & 6 deletions spec/generators/koi/admin_views_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@
end

it { is_expected.to contain "<h2>Summary</h2>" }
it { is_expected.to contain "<%= render Koi::SummaryListComponent.new(model: test) do |dl| %>" }
it { is_expected.to contain "<% dl.text :title %>" }
it { is_expected.to contain "<% dl.rich_text :description %>" }
it { is_expected.to contain "<% dl.number :ordinal %>" }
it { is_expected.to contain "<% dl.datetime :archived_at %>" }
it { is_expected.to contain "<% dl.boolean :active %>" }
it { is_expected.to contain "<%= summary_table_with(model: test) do |row| %>" }
it { is_expected.to contain "<% row.link :title %>" }
it { is_expected.to contain "<% row.rich_text :description %>" }
it { is_expected.to contain "<% row.number :ordinal %>" }
it { is_expected.to contain "<% row.datetime :archived_at %>" }
it { is_expected.to contain "<% row.boolean :active %>" }
end
end
2 changes: 1 addition & 1 deletion spec/views/admin/posts/index.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Workaround for https://github.com/rspec/rspec-rails/issues/2729
view.lookup_context.prefixes.prepend "admin/posts"

allow(view).to receive(:default_table_component_class).and_return(Koi::Tables::TableComponent)
allow(view).to receive(:default_table_component_class).and_return(Koi::TableComponent)

render locals: { collection: }
end
Expand Down
8 changes: 4 additions & 4 deletions spec/views/admin/posts/show.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
render template: "admin/posts/show", locals: { post: }
end

it { expect(rendered).to have_css("dt", text: "Name") }
it { expect(rendered).to have_css("dd", text: post.name) }
it { expect(rendered).to have_css("dt", text: "Title") }
it { expect(rendered).to have_css("dd", text: post.title) }
it { expect(rendered).to have_css("th", text: "Name") }
it { expect(rendered).to have_css("td", text: post.name) }
it { expect(rendered).to have_css("th", text: "Title") }
it { expect(rendered).to have_css("td", text: post.title) }
end

0 comments on commit c9c43d5

Please sign in to comment.