diff --git a/Gemfile.lock b/Gemfile.lock
index 2f8ee88c..d9023dd2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- katalyst-koi (4.7.3)
+ katalyst-koi (4.8.0)
bcrypt
importmap-rails
katalyst-content
@@ -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
@@ -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)
diff --git a/app/components/concerns/koi/tables/cells.rb b/app/components/concerns/koi/tables/cells.rb
new file mode 100644
index 00000000..d12fa190
--- /dev/null
+++ b/app/components/concerns/koi/tables/cells.rb
@@ -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 %> # =>
About us |
+ # @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 %>
+ # # => Edit About us |
+ 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 => Status | %>
+ # <%# data => Published | %>
+ 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 %> # => background.png |
+ 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
diff --git a/app/components/koi/summary_table_component.rb b/app/components/koi/summary_table_component.rb
new file mode 100644
index 00000000..4b29b57e
--- /dev/null
+++ b/app/components/koi/summary_table_component.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Koi
+ class SummaryTableComponent < Katalyst::SummaryTableComponent
+ include Tables::Cells
+ end
+end
diff --git a/app/components/koi/table_component.rb b/app/components/koi/table_component.rb
new file mode 100644
index 00000000..ceb96f9f
--- /dev/null
+++ b/app/components/koi/table_component.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Koi
+ class TableComponent < Katalyst::TableComponent
+ include Tables::Cells
+ end
+end
diff --git a/app/components/koi/tables/table_component.rb b/app/components/koi/tables/table_component.rb
index e34f0c06..b3a3f8d0 100644
--- a/app/components/koi/tables/table_component.rb
+++ b/app/components/koi/tables/table_component.rb
@@ -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 %> # => About us |
- # @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 %>
- # # => Edit About us |
- 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 => Status | %>
- # <%# data => Published | %>
- 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 %> # => background.png |
- 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
diff --git a/app/controllers/concerns/koi/controller/is_admin_controller.rb b/app/controllers/concerns/koi/controller/is_admin_controller.rb
index 023cbf79..40a3eaf9 100644
--- a/app/controllers/concerns/koi/controller/is_admin_controller.rb
+++ b/app/controllers/concerns/koi/controller/is_admin_controller.rb
@@ -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
diff --git a/katalyst-koi.gemspec b/katalyst-koi.gemspec
index 4894711a..4fb013a0 100644
--- a/katalyst-koi.gemspec
+++ b/katalyst-koi.gemspec
@@ -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 = ["developers@katalyst.com.au"]
diff --git a/lib/generators/koi/admin_views/admin_views_generator.rb b/lib/generators/koi/admin_views/admin_views_generator.rb
index 619329c4..582297e7 100644
--- a/lib/generators/koi/admin_views/admin_views_generator.rb
+++ b/lib/generators/koi/admin_views/admin_views_generator.rb
@@ -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
@@ -89,6 +70,8 @@ def index_attribute_for(attribute)
end
end
+ alias_method :summary_attribute_for, :index_attribute_for
+
def index_attributes
attributes
end
diff --git a/lib/generators/koi/admin_views/templates/show.html.erb.tt b/lib/generators/koi/admin_views/templates/show.html.erb.tt
index b95684ff..7257831c 100644
--- a/lib/generators/koi/admin_views/templates/show.html.erb.tt
+++ b/lib/generators/koi/admin_views/templates/show.html.erb.tt
@@ -4,10 +4,14 @@
Summary
-<%%= 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 %>
diff --git a/spec/components/koi/tables/cells/attachment_component_spec.rb b/spec/components/koi/tables/cells/attachment_component_spec.rb
index 850b1694..53e89c8e 100644
--- a/spec/components/koi/tables/cells/attachment_component_spec.rb
+++ b/spec/components/koi/tables/cells/attachment_component_spec.rb
@@ -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") }
diff --git a/spec/components/koi/tables/cells/enum_component_spec.rb b/spec/components/koi/tables/cells/enum_component_spec.rb
index b436de78..63228f5a 100644
--- a/spec/components/koi/tables/cells/enum_component_spec.rb
+++ b/spec/components/koi/tables/cells/enum_component_spec.rb
@@ -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") }
diff --git a/spec/components/koi/tables/cells/link_component_spec.rb b/spec/components/koi/tables/cells/link_component_spec.rb
index 8730f6bb..be9e7900 100644
--- a/spec/components/koi/tables/cells/link_component_spec.rb
+++ b/spec/components/koi/tables/cells/link_component_spec.rb
@@ -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") }
diff --git a/spec/generators/koi/admin_views_generator_spec.rb b/spec/generators/koi/admin_views_generator_spec.rb
index 662e8233..68328cb2 100644
--- a/spec/generators/koi/admin_views_generator_spec.rb
+++ b/spec/generators/koi/admin_views_generator_spec.rb
@@ -39,11 +39,11 @@
end
it { is_expected.to contain "
Summary
" }
- 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
diff --git a/spec/views/admin/posts/index.html.erb_spec.rb b/spec/views/admin/posts/index.html.erb_spec.rb
index 7f733623..e8022b66 100644
--- a/spec/views/admin/posts/index.html.erb_spec.rb
+++ b/spec/views/admin/posts/index.html.erb_spec.rb
@@ -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
diff --git a/spec/views/admin/posts/show.html.erb_spec.rb b/spec/views/admin/posts/show.html.erb_spec.rb
index a2c98208..8b19053c 100644
--- a/spec/views/admin/posts/show.html.erb_spec.rb
+++ b/spec/views/admin/posts/show.html.erb_spec.rb
@@ -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