katalyst-tables 2.6.0.beta → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +1 -23
- data/app/assets/stylesheets/katalyst/tables/_index.scss +1 -0
- data/app/assets/stylesheets/katalyst/tables/_ordinal.scss +38 -0
- data/app/assets/stylesheets/katalyst/tables/_table.scss +123 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_boolean.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_currency.scss +5 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_date.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_datetime.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_index.scss +5 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_number.scss +5 -0
- data/app/components/concerns/katalyst/tables/body/typed_columns.rb +132 -0
- data/app/components/concerns/katalyst/tables/has_table_content.rb +1 -1
- data/app/components/concerns/katalyst/tables/header/typed_columns.rb +179 -0
- data/app/components/concerns/katalyst/tables/orderable.rb +1 -1
- data/app/components/concerns/katalyst/tables/selectable.rb +2 -1
- data/app/components/katalyst/table_component.rb +13 -1
- data/app/components/katalyst/tables/body/attachment_component.rb +58 -0
- data/app/components/katalyst/tables/body/boolean_component.rb +14 -0
- data/app/components/katalyst/tables/body/currency_component.rb +29 -0
- data/app/components/katalyst/tables/body/date_component.rb +64 -0
- data/app/components/katalyst/tables/body/date_time_component.rb +57 -0
- data/app/components/katalyst/tables/body/link_component.rb +40 -0
- data/app/components/katalyst/tables/body/number_component.rb +22 -0
- data/app/components/katalyst/tables/body/rich_text_component.rb +18 -0
- data/app/components/katalyst/tables/body_cell_component.rb +9 -1
- data/app/components/katalyst/tables/body_row_component.rb +9 -2
- data/app/components/katalyst/tables/empty_caption_component.rb +1 -1
- data/app/components/katalyst/tables/header/attachment_component.rb +15 -0
- data/app/components/katalyst/tables/header/boolean_component.rb +15 -0
- data/app/components/katalyst/tables/header/currency_component.rb +15 -0
- data/app/components/katalyst/tables/header/date_component.rb +15 -0
- data/app/components/katalyst/tables/header/date_time_component.rb +15 -0
- data/app/components/katalyst/tables/header/link_component.rb +15 -0
- data/app/components/katalyst/tables/header/number_component.rb +15 -0
- data/app/components/katalyst/tables/header/rich_text_component.rb +15 -0
- data/app/components/katalyst/tables/header_cell_component.rb +35 -3
- data/app/components/katalyst/tables/header_row_component.rb +3 -2
- data/app/components/katalyst/tables/selectable/form_component.html.erb +4 -2
- data/app/controllers/concerns/katalyst/tables/backend.rb +2 -2
- data/app/helpers/katalyst/tables/frontend.rb +2 -2
- data/app/models/concerns/katalyst/tables/collection/pagination.rb +8 -1
- data/app/models/concerns/katalyst/tables/collection/sorting.rb +3 -3
- data/app/models/katalyst/tables/collection/sort_form.rb +26 -8
- data/config/locales/tables.en.yml +6 -0
- metadata +33 -9
- data/app/components/concerns/katalyst/tables/turbo_replaceable.rb +0 -79
- data/app/components/katalyst/turbo/pagy_nav_component.rb +0 -23
- data/app/components/katalyst/turbo/table_component.rb +0 -45
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Body
|
8
|
+
# Shows an attachment
|
9
|
+
#
|
10
|
+
# The value is expected to be an ActiveStorage attachment
|
11
|
+
#
|
12
|
+
# If it is representable, shows as a image tag using a default variant named :thumb.
|
13
|
+
#
|
14
|
+
# Otherwise shows as a link to download.
|
15
|
+
class AttachmentComponent < BodyCellComponent
|
16
|
+
def initialize(table, record, attribute, variant: :thumb, **options)
|
17
|
+
super(table, record, attribute, **options)
|
18
|
+
|
19
|
+
@variant = variant
|
20
|
+
end
|
21
|
+
|
22
|
+
def rendered_value
|
23
|
+
representation
|
24
|
+
end
|
25
|
+
|
26
|
+
def representation
|
27
|
+
if value.try(:variable?) && named_variant.present?
|
28
|
+
image_tag(value.variant(@variant))
|
29
|
+
elsif value.try(:attached?)
|
30
|
+
filename.to_s
|
31
|
+
else
|
32
|
+
""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def filename
|
37
|
+
value.blob.filename
|
38
|
+
end
|
39
|
+
|
40
|
+
# Utility for accessing the path Rails provides for retrieving the
|
41
|
+
# attachment for use in cells. Example:
|
42
|
+
# <% row.attachment :file do |cell| %>
|
43
|
+
# <%= link_to "Download", cell.internal_path %>
|
44
|
+
# <% end %>
|
45
|
+
def internal_path
|
46
|
+
rails_blob_path(value, disposition: :attachment)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Find the reflective variant by name (i.e. :thumb by default)
|
52
|
+
def named_variant
|
53
|
+
object.attachment_reflections[@attribute.to_s].named_variants[@variant.to_sym]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Body
|
8
|
+
# Formats the value as a money value
|
9
|
+
#
|
10
|
+
# The value is expected to be in cents.
|
11
|
+
# Adds a class to the cell to allow for custom styling
|
12
|
+
class CurrencyComponent < BodyCellComponent
|
13
|
+
def initialize(table, record, attribute, options: {}, **html_attributes)
|
14
|
+
super(table, record, attribute, **html_attributes)
|
15
|
+
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def rendered_value
|
20
|
+
value.present? ? number_to_currency(value / 100.0, @options) : ""
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_html_attributes
|
24
|
+
super.merge_html(class: "type-currency")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
module Body
|
6
|
+
# Formats the value as a date
|
7
|
+
# @param format [String] date format, defaults to :table
|
8
|
+
# @param relative [Boolean] if true, the date may be(if within 5 days) shown as a relative date
|
9
|
+
class DateComponent < BodyCellComponent
|
10
|
+
def initialize(table, record, attribute, format: :table, relative: true, **options)
|
11
|
+
super(table, record, attribute, **options)
|
12
|
+
|
13
|
+
@format = format
|
14
|
+
@relative = relative
|
15
|
+
end
|
16
|
+
|
17
|
+
def value
|
18
|
+
super&.to_date
|
19
|
+
end
|
20
|
+
|
21
|
+
def rendered_value
|
22
|
+
@relative ? relative_time : absolute_time
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def absolute_time
|
28
|
+
value.present? ? I18n.l(value, format: @format) : ""
|
29
|
+
end
|
30
|
+
|
31
|
+
def relative_time
|
32
|
+
if value.blank?
|
33
|
+
""
|
34
|
+
else
|
35
|
+
days_ago_in_words(value)&.capitalize || absolute_time
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_html_attributes
|
40
|
+
@relative && value.present? && days_ago_in_words(value).present? ? { title: absolute_time } : {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def days_ago_in_words(value)
|
44
|
+
from_time = value.to_time
|
45
|
+
to_time = Date.current.to_time
|
46
|
+
distance_in_days = ((to_time - from_time) / (24.0 * 60.0 * 60.0)).round
|
47
|
+
|
48
|
+
case distance_in_days
|
49
|
+
when 0
|
50
|
+
"today"
|
51
|
+
when 1
|
52
|
+
"yesterday"
|
53
|
+
when -1
|
54
|
+
"tomorrow"
|
55
|
+
when 2..5
|
56
|
+
"#{distance_in_days} days ago"
|
57
|
+
when -5..-2
|
58
|
+
"#{distance_in_days.abs} days from now"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
module Body
|
6
|
+
# Formats the value as a datetime
|
7
|
+
# @param format [String] datetime format, defaults to :admin
|
8
|
+
# @param relative [Boolean] if true, the datetime may be(if today) shown as a relative date/time
|
9
|
+
class DateTimeComponent < BodyCellComponent
|
10
|
+
include ActionView::Helpers::DateHelper
|
11
|
+
|
12
|
+
def initialize(table, record, attribute, format: :table, relative: true, **options)
|
13
|
+
super(table, record, attribute, **options)
|
14
|
+
|
15
|
+
@format = format
|
16
|
+
@relative = relative
|
17
|
+
end
|
18
|
+
|
19
|
+
def value
|
20
|
+
super&.to_datetime
|
21
|
+
end
|
22
|
+
|
23
|
+
def rendered_value
|
24
|
+
@relative ? relative_time : absolute_time
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def absolute_time
|
30
|
+
value.present? ? I18n.l(value, format: @format) : ""
|
31
|
+
end
|
32
|
+
|
33
|
+
def today?
|
34
|
+
value&.to_date == Date.current
|
35
|
+
end
|
36
|
+
|
37
|
+
def relative_time
|
38
|
+
return "" if value.blank?
|
39
|
+
|
40
|
+
if today?
|
41
|
+
if value > DateTime.current
|
42
|
+
"#{distance_of_time_in_words(value, DateTime.current)} from now".capitalize
|
43
|
+
else
|
44
|
+
"#{distance_of_time_in_words(value, DateTime.current)} ago".capitalize
|
45
|
+
end
|
46
|
+
else
|
47
|
+
absolute_time
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_html_attributes
|
52
|
+
@relative && today? ? { title: absolute_time } : {}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Body
|
8
|
+
# Displays a link to the record
|
9
|
+
# The link text is the value of the attribute
|
10
|
+
# @see Koi::Tables::BodyRowComponent#link
|
11
|
+
class LinkComponent < BodyCellComponent
|
12
|
+
def initialize(table, record, attribute, url:, link: {}, **options)
|
13
|
+
super(table, record, attribute, **options)
|
14
|
+
|
15
|
+
@url = url
|
16
|
+
@link_options = link
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
content # ensure content is set before rendering options
|
21
|
+
|
22
|
+
link = content.present? && url.present? ? link_to(content, url, @link_options) : content.to_s
|
23
|
+
content_tag(@type, link, **html_attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
case @url
|
28
|
+
when Symbol
|
29
|
+
# helpers are not available until the component is rendered
|
30
|
+
@url = helpers.public_send(@url, record)
|
31
|
+
when Proc
|
32
|
+
@url = @url.call(record)
|
33
|
+
else
|
34
|
+
@url
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Body
|
8
|
+
# Formats the value as a number
|
9
|
+
#
|
10
|
+
# Adds a class to the cell to allow for custom styling
|
11
|
+
class NumberComponent < BodyCellComponent
|
12
|
+
def rendered_value
|
13
|
+
value.present? ? number_to_human(value) : ""
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_html_attributes
|
17
|
+
super.merge_html(class: "type-number")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Body
|
8
|
+
# Displays the plain text for rich text content
|
9
|
+
#
|
10
|
+
# Adds a title attribute to allow for hover over display of the full content
|
11
|
+
class RichTextComponent < BodyCellComponent
|
12
|
+
def default_html_attributes
|
13
|
+
{ title: value.to_plain_text }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -18,7 +18,7 @@ module Katalyst
|
|
18
18
|
|
19
19
|
def before_render
|
20
20
|
# fallback if no content block is given
|
21
|
-
with_content(
|
21
|
+
with_content(rendered_value) unless content?
|
22
22
|
end
|
23
23
|
|
24
24
|
def call
|
@@ -36,6 +36,14 @@ module Katalyst
|
|
36
36
|
@record.public_send(@attribute)
|
37
37
|
end
|
38
38
|
|
39
|
+
def rendered_value
|
40
|
+
value.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
value.to_s
|
45
|
+
end
|
46
|
+
|
39
47
|
def inspect
|
40
48
|
"#<#{self.class.name} attribute: #{@attribute.inspect}, value: #{value.inspect}>"
|
41
49
|
end
|
@@ -4,6 +4,7 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
class BodyRowComponent < ViewComponent::Base # :nodoc:
|
6
6
|
include Katalyst::HtmlAttributes
|
7
|
+
include Body::TypedColumns
|
7
8
|
|
8
9
|
renders_many :columns, ->(component) { component }
|
9
10
|
|
@@ -24,8 +25,8 @@ module Katalyst
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def cell(attribute,
|
28
|
-
with_column(@table.body_cell_component.new(@table, @record, attribute, **
|
28
|
+
def cell(attribute, **, &)
|
29
|
+
with_column(@table.body_cell_component.new(@table, @record, attribute, **), &)
|
29
30
|
end
|
30
31
|
|
31
32
|
def header?
|
@@ -36,6 +37,12 @@ module Katalyst
|
|
36
37
|
true
|
37
38
|
end
|
38
39
|
|
40
|
+
def default_html_attributes
|
41
|
+
return {} unless @table.generate_ids?
|
42
|
+
|
43
|
+
{ id: dom_id(@record) }
|
44
|
+
end
|
45
|
+
|
39
46
|
def inspect
|
40
47
|
"#<#{self.class.name} record: #{record.inspect}>"
|
41
48
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class AttachmentComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-attachment")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class BooleanComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-boolean")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class CurrencyComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-currency")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class DateComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-date")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class DateTimeComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-datetime")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class LinkComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-link")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class NumberComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-number")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
5
|
+
module Katalyst
|
6
|
+
module Tables
|
7
|
+
module Header
|
8
|
+
class RichTextComponent < HeaderCellComponent
|
9
|
+
def default_html_attributes
|
10
|
+
super.merge_html(class: "type-rich-text")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
+
|
3
5
|
module Katalyst
|
4
6
|
module Tables
|
5
7
|
class HeaderCellComponent < ViewComponent::Base # :nodoc:
|
@@ -9,19 +11,20 @@ module Katalyst
|
|
9
11
|
|
10
12
|
delegate :object_name, :collection, :sorting, to: :@table
|
11
13
|
|
12
|
-
def initialize(table, attribute, label: nil, link: {}, **html_attributes)
|
14
|
+
def initialize(table, attribute, label: nil, link: {}, width: nil, **html_attributes)
|
13
15
|
super(**html_attributes)
|
14
16
|
|
15
17
|
@table = table
|
16
18
|
@attribute = attribute
|
17
19
|
@value = label
|
20
|
+
@width = width
|
18
21
|
@link_attributes = link
|
19
22
|
end
|
20
23
|
|
21
24
|
def call
|
22
25
|
tag.th(**html_attributes) do
|
23
26
|
if sortable?(@attribute)
|
24
|
-
link_to(value, sort_url(@attribute),
|
27
|
+
link_to(value, sort_url(@attribute), **link_attributes)
|
25
28
|
else
|
26
29
|
value
|
27
30
|
end
|
@@ -47,7 +50,7 @@ module Katalyst
|
|
47
50
|
end
|
48
51
|
|
49
52
|
def inspect
|
50
|
-
"#<#{self.class.name} attribute: #{@attribute.inspect}, value: #{value.inspect}>"
|
53
|
+
"#<#{self.class.name} attribute: #{@attribute.inspect}, value: #{@value.inspect}>"
|
51
54
|
end
|
52
55
|
|
53
56
|
# Backwards compatibility with tables 1.0
|
@@ -55,7 +58,36 @@ module Katalyst
|
|
55
58
|
|
56
59
|
private
|
57
60
|
|
61
|
+
def width_class
|
62
|
+
case @width
|
63
|
+
when :xs
|
64
|
+
"width-xs"
|
65
|
+
when :s
|
66
|
+
"width-s"
|
67
|
+
when :m
|
68
|
+
"width-m"
|
69
|
+
when :l
|
70
|
+
"width-l"
|
71
|
+
else
|
72
|
+
""
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def link_attributes
|
77
|
+
{ data: { turbo_action: "replace" } }.merge_html(@link_attributes)
|
78
|
+
end
|
79
|
+
|
58
80
|
def default_html_attributes
|
81
|
+
sort_data.merge(width_data)
|
82
|
+
end
|
83
|
+
|
84
|
+
def width_data
|
85
|
+
return {} unless @width
|
86
|
+
|
87
|
+
{ class: width_class }
|
88
|
+
end
|
89
|
+
|
90
|
+
def sort_data
|
59
91
|
return {} unless sorting&.supports?(collection, @attribute)
|
60
92
|
|
61
93
|
{ data: { sort: sorting.status(@attribute) } }
|
@@ -4,6 +4,7 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
class HeaderRowComponent < ViewComponent::Base # :nodoc:
|
6
6
|
include Katalyst::HtmlAttributes
|
7
|
+
include Header::TypedColumns
|
7
8
|
|
8
9
|
renders_many :columns, ->(component) { component }
|
9
10
|
|
@@ -24,8 +25,8 @@ module Katalyst
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def cell(attribute,
|
28
|
-
with_column(@table.header_cell_component.new(@table, attribute, link: @link_attributes, **
|
28
|
+
def cell(attribute, **, &)
|
29
|
+
with_column(@table.header_cell_component.new(@table, attribute, link: @link_attributes, **), &)
|
29
30
|
end
|
30
31
|
|
31
32
|
def header?
|
@@ -1,7 +1,9 @@
|
|
1
1
|
<%= form_with(method: :patch,
|
2
|
-
id
|
2
|
+
id:,
|
3
3
|
class: "tables--selection--form",
|
4
|
-
data: { controller:
|
4
|
+
data: { controller: form_controller,
|
5
|
+
turbo_action: "replace",
|
6
|
+
turbo_permanent: "" },
|
5
7
|
html: { hidden: "" }) do |form| %>
|
6
8
|
<p class="tables--selection--summary">
|
7
9
|
<span data-<%= form_target("count") %>>0</span>
|
@@ -21,8 +21,8 @@ module Katalyst
|
|
21
21
|
column, direction = params[:sort]&.split
|
22
22
|
direction = "asc" unless SortForm::DIRECTIONS.include?(direction)
|
23
23
|
|
24
|
-
SortForm.new(column
|
25
|
-
direction:
|
24
|
+
SortForm.new(column:,
|
25
|
+
direction:)
|
26
26
|
.apply(collection)
|
27
27
|
end
|
28
28
|
|
@@ -4,9 +4,9 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
# View Helper for generating HTML tables. Include in your ApplicationHelper, or similar.
|
6
6
|
module Frontend
|
7
|
-
def table_with(collection:, component: nil,
|
7
|
+
def table_with(collection:, component: nil, **, &)
|
8
8
|
component ||= default_table_component_class
|
9
|
-
render(component.new(collection
|
9
|
+
render(component.new(collection:, **), &)
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -35,7 +35,14 @@ module Katalyst
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def paginate_options
|
38
|
-
@paginate.is_a?(Hash) ? @paginate : {}
|
38
|
+
opts = @paginate.is_a?(Hash) ? @paginate : {}
|
39
|
+
opts = opts.dup
|
40
|
+
opts[:anchor_string] ||= anchor_string
|
41
|
+
opts
|
42
|
+
end
|
43
|
+
|
44
|
+
def anchor_string
|
45
|
+
"data-turbo-action=\"replace\""
|
39
46
|
end
|
40
47
|
|
41
48
|
class Paginate # :nodoc:
|
@@ -22,16 +22,16 @@ module Katalyst
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def initialize(sorting: config.sorting, **options)
|
25
|
-
@sorting = SortForm.parse(sorting) if sorting
|
25
|
+
@sorting = SortForm.parse(sorting, default: sorting) if sorting
|
26
26
|
|
27
|
-
super(sort: sorting, **options) # set default sort based on config
|
27
|
+
super(sort: @sorting.to_param, **options) # set default sort based on config
|
28
28
|
end
|
29
29
|
|
30
30
|
def sort=(value)
|
31
31
|
return unless @sorting
|
32
32
|
|
33
33
|
# update internal proxy
|
34
|
-
@sorting = SortForm.parse(value, default:
|
34
|
+
@sorting = SortForm.parse(value, default: @sorting.default)
|
35
35
|
|
36
36
|
# update attribute based on normalized value
|
37
37
|
super(@sorting.to_param)
|