-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
49190fb
commit aecb45b
Showing
8 changed files
with
348 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# frozen_string_literal: true | ||
|
||
module Koi | ||
module Tables | ||
module Cells | ||
# Shows an attachment | ||
# | ||
# The value is expected to be an ActiveStorage attachment | ||
# | ||
# If it is representable, shows as a image tag using the specified variant. | ||
# | ||
# Otherwise shows as a link to download. | ||
class AttachmentComponent < Katalyst::Tables::CellComponent | ||
def initialize(variant:, **) | ||
super(**) | ||
|
||
@variant = variant | ||
end | ||
|
||
def rendered_value | ||
representation | ||
end | ||
|
||
def representation | ||
if value.try(:variable?) && named_variant.present? | ||
image_tag(value.variant(@variant)) | ||
elsif value.try(:attached?) | ||
filename.to_s | ||
else | ||
"" | ||
end | ||
end | ||
|
||
def filename | ||
value.blob.filename | ||
end | ||
|
||
# Utility for accessing the path Rails provides for retrieving the | ||
# attachment for use in cells. Example: | ||
# <% row.attachment :file do |cell| %> | ||
# <%= link_to "Download", cell.internal_path %> | ||
# <% end %> | ||
def internal_path | ||
rails_blob_path(value, disposition: :attachment) | ||
end | ||
|
||
private | ||
|
||
def default_html_attributes | ||
{ class: "type-attachment" } | ||
end | ||
|
||
# Find the reflective variant by name (i.e. :thumb by default) | ||
def named_variant | ||
record.attachment_reflections[@column.to_s].named_variants[@variant.to_sym] | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# frozen_string_literal: true | ||
|
||
module Koi | ||
module Tables | ||
module Cells | ||
# Displays a link to the record | ||
# The link text is the value of the attribute | ||
class LinkComponent < Katalyst::Tables::CellComponent | ||
define_html_attribute_methods :link_attributes | ||
|
||
def initialize(url:, link:, **) | ||
super(**) | ||
|
||
@url = url | ||
|
||
self.link_attributes = link | ||
end | ||
|
||
def rendered_value | ||
link_to(value, url, **link_attributes) | ||
end | ||
|
||
def url | ||
case @url | ||
when Symbol | ||
# helpers are not available until the component is rendered | ||
@url = helpers.public_send(@url, record) | ||
when Proc | ||
@url = @url.call(record) | ||
else | ||
@url | ||
end | ||
end | ||
|
||
private | ||
|
||
def default_html_attributes | ||
{ class: "type-link" } | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
spec/components/koi/tables/cells/attachment_component_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe Koi::Tables::Cells::AttachmentComponent do | ||
let(:table) { Koi::Tables::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") } | ||
let(:data) { rendered.at_css("tbody td") } | ||
|
||
it "renders column header" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-attachment">Image</th> | ||
HTML | ||
end | ||
|
||
it "renders column data" do | ||
expect(data).to have_css("td.type-attachment img[src*='dummy.png']") | ||
end | ||
|
||
context "with html_options" do | ||
let(:rendered) { render_inline(table) { |row| row.attachment(:image, **Test::HTML_ATTRIBUTES) } } | ||
|
||
it "renders header with html_options" do | ||
expect(label).to match_html(<<~HTML) | ||
<th id="ID" class="type-attachment CLASS" style="style" data-foo="bar" aria-label="LABEL">Image</th> | ||
HTML | ||
end | ||
|
||
it "renders data with html_options" do | ||
expect(data).to have_css("td.type-attachment.CLASS[data-foo=bar] img[src*='dummy.png']") | ||
end | ||
end | ||
|
||
context "when given a label" do | ||
let(:rendered) { render_inline(table) { |row| row.attachment(:image, label: "LABEL") } } | ||
|
||
it "renders header with label" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-attachment">LABEL</th> | ||
HTML | ||
end | ||
|
||
it "renders data without label" do | ||
expect(data).to have_css("td.type-attachment img[src*='dummy.png']") | ||
end | ||
end | ||
|
||
context "when given an empty label" do | ||
let(:rendered) { render_inline(table) { |row| row.attachment(:image, label: "") } } | ||
|
||
it "renders header with an empty label" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-attachment"></th> | ||
HTML | ||
end | ||
end | ||
|
||
context "with nil data value" do | ||
let(:collection) { build_list(:banner, 1) } | ||
|
||
it "renders data as falsey" do | ||
expect(data).to match_html(<<~HTML) | ||
<td class="type-attachment"></td> | ||
HTML | ||
end | ||
end | ||
|
||
context "when given a block" do | ||
let(:rendered) { render_inline(table) { |row| row.attachment(:image) { |cell| cell.tag.span(cell) } } } | ||
|
||
it "renders the default header" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-attachment">Image</th> | ||
HTML | ||
end | ||
|
||
it "renders the custom data" do | ||
expect(data).to have_css("td.type-attachment > span > img[src*='dummy.png']") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe Koi::Tables::Cells::LinkComponent do | ||
let(:table) { Koi::Tables::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") } | ||
let(:data) { rendered.at_css("tbody td") } | ||
|
||
it "renders column header" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-link">Name</th> | ||
HTML | ||
end | ||
|
||
it "renders column data" do | ||
expect(data).to match_html(<<~HTML) | ||
<td class="type-link"><a href="/admin/posts/#{collection.first.id}">#{collection.first.name}</a></td> | ||
HTML | ||
end | ||
|
||
context "with html_options" do | ||
let(:rendered) { render_inline(table) { |row| row.link(:name, **Test::HTML_ATTRIBUTES) } } | ||
|
||
it "renders header with html_options" do | ||
expect(label).to match_html(<<~HTML) | ||
<th id="ID" class="type-link CLASS" style="style" data-foo="bar" aria-label="LABEL">Name</th> | ||
HTML | ||
end | ||
|
||
it "renders data with html_options" do | ||
expect(data).to match_html(<<~HTML) | ||
<td id="ID" class="type-link CLASS" style="style" data-foo="bar" aria-label="LABEL"><a href="/admin/posts/#{collection.first.id}">#{collection.first.name}</a></td> | ||
HTML | ||
end | ||
end | ||
|
||
context "when given a label" do | ||
let(:rendered) { render_inline(table) { |row| row.link(:name, label: "LABEL") } } | ||
|
||
it "renders header with label" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-link">LABEL</th> | ||
HTML | ||
end | ||
|
||
it "renders data without label" do | ||
expect(data).to match_html(<<~HTML) | ||
<td class="type-link"><a href="/admin/posts/#{collection.first.id}">#{collection.first.name}</a></td> | ||
HTML | ||
end | ||
end | ||
|
||
context "when given an empty label" do | ||
let(:rendered) { render_inline(table) { |row| row.link(:name, label: "") } } | ||
|
||
it "renders header with an empty label" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-link"></th> | ||
HTML | ||
end | ||
end | ||
|
||
context "with nil data value" do | ||
let(:rendered) { render_inline(table) { |row| row.link(:name) } } | ||
let(:collection) { create_list(:post, 1, name: nil) } | ||
|
||
it "renders data as url" do | ||
expect(data).to match_html(<<~HTML) | ||
<td class="type-link"><a href="/admin/posts/#{collection.first.id}">/admin/posts/#{collection.first.id}</a></td> | ||
HTML | ||
end | ||
end | ||
|
||
context "when given a block" do | ||
let(:rendered) { render_inline(table) { |row| row.link(:name) { |cell| cell.tag.span(cell) } } } | ||
|
||
it "renders the default header" do | ||
expect(label).to match_html(<<~HTML) | ||
<th class="type-link">Name</th> | ||
HTML | ||
end | ||
|
||
it "renders the custom data" do | ||
expect(data).to match_html(<<~HTML) | ||
<td class="type-link"><span><a href="/admin/posts/#{collection.first.id}">#{collection.first.name}</a></span></td> | ||
HTML | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rack/request" | ||
require "rails_helper" | ||
|
||
module Test | ||
HTML_ATTRIBUTES = { | ||
id: "ID", | ||
class: "CLASS", | ||
html: { style: "style" }, | ||
data: { foo: "bar" }, | ||
aria: { label: "LABEL" }, | ||
}.freeze | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters