katalyst-tables 3.0.0.beta1 → 3.0.0

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -2
  3. data/README.md +56 -190
  4. data/app/assets/builds/katalyst/tables.esm.js +17 -47
  5. data/app/assets/builds/katalyst/tables.js +17 -47
  6. data/app/assets/builds/katalyst/tables.min.js +1 -1
  7. data/app/assets/builds/katalyst/tables.min.js.map +1 -1
  8. data/app/components/concerns/katalyst/tables/has_table_content.rb +17 -8
  9. data/app/components/concerns/katalyst/tables/identifiable.rb +51 -0
  10. data/app/components/concerns/katalyst/tables/orderable.rb +35 -105
  11. data/app/components/concerns/katalyst/tables/selectable.rb +18 -75
  12. data/app/components/concerns/katalyst/tables/sortable.rb +51 -17
  13. data/app/components/katalyst/table_component.html.erb +4 -4
  14. data/app/components/katalyst/table_component.rb +271 -53
  15. data/app/components/katalyst/tables/body_row_component.html.erb +5 -0
  16. data/app/components/katalyst/tables/body_row_component.rb +4 -31
  17. data/app/components/katalyst/tables/cell_component.rb +85 -0
  18. data/app/components/katalyst/tables/{body → cells}/boolean_component.rb +8 -2
  19. data/app/components/katalyst/tables/{body → cells}/currency_component.rb +7 -7
  20. data/app/components/katalyst/tables/{body → cells}/date_component.rb +12 -9
  21. data/app/components/katalyst/tables/{body → cells}/date_time_component.rb +13 -10
  22. data/app/components/katalyst/tables/{body → cells}/number_component.rb +5 -5
  23. data/app/components/katalyst/tables/cells/ordinal_component.rb +44 -0
  24. data/app/components/katalyst/tables/{body → cells}/rich_text_component.rb +8 -5
  25. data/app/components/katalyst/tables/cells/select_component.rb +39 -0
  26. data/app/components/katalyst/tables/data.rb +30 -0
  27. data/app/components/katalyst/tables/header_row_component.html.erb +5 -0
  28. data/app/components/katalyst/tables/header_row_component.rb +4 -25
  29. data/app/components/katalyst/tables/label.rb +37 -0
  30. data/app/components/katalyst/tables/orderable/form_component.rb +38 -0
  31. data/app/components/katalyst/tables/selectable/form_component.html.erb +3 -3
  32. data/app/components/katalyst/tables/selectable/form_component.rb +8 -11
  33. data/app/controllers/concerns/katalyst/tables/backend.rb +2 -28
  34. data/app/helpers/katalyst/tables/frontend.rb +48 -2
  35. data/app/javascript/tables/application.js +0 -5
  36. data/app/javascript/tables/orderable/form_controller.js +8 -6
  37. data/app/javascript/tables/orderable/item_controller.js +9 -0
  38. data/app/models/concerns/katalyst/tables/collection/core.rb +6 -1
  39. data/app/models/concerns/katalyst/tables/collection/sorting.rb +85 -17
  40. data/app/models/katalyst/tables/collection/array.rb +38 -0
  41. data/app/models/katalyst/tables/collection/base.rb +4 -0
  42. data/config/locales/tables.en.yml +0 -6
  43. data/lib/katalyst/tables/config.rb +23 -0
  44. data/lib/katalyst/tables.rb +9 -0
  45. metadata +22 -29
  46. data/app/components/concerns/katalyst/tables/body/typed_columns.rb +0 -132
  47. data/app/components/concerns/katalyst/tables/configurable_component.rb +0 -52
  48. data/app/components/concerns/katalyst/tables/header/typed_columns.rb +0 -179
  49. data/app/components/katalyst/tables/body/attachment_component.rb +0 -58
  50. data/app/components/katalyst/tables/body/link_component.rb +0 -40
  51. data/app/components/katalyst/tables/body_cell_component.rb +0 -55
  52. data/app/components/katalyst/tables/header/attachment_component.rb +0 -15
  53. data/app/components/katalyst/tables/header/boolean_component.rb +0 -15
  54. data/app/components/katalyst/tables/header/currency_component.rb +0 -15
  55. data/app/components/katalyst/tables/header/date_component.rb +0 -15
  56. data/app/components/katalyst/tables/header/date_time_component.rb +0 -15
  57. data/app/components/katalyst/tables/header/link_component.rb +0 -15
  58. data/app/components/katalyst/tables/header/number_component.rb +0 -15
  59. data/app/components/katalyst/tables/header/rich_text_component.rb +0 -15
  60. data/app/components/katalyst/tables/header_cell_component.rb +0 -97
  61. data/app/helpers/katalyst/tables/frontend/helper.rb +0 -31
  62. data/app/javascript/tables/turbo/collection_controller.js +0 -38
  63. data/app/models/katalyst/tables/collection/sort_form.rb +0 -120
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Katalyst
4
+ module Tables
5
+ module Collection
6
+ # Entry point for creating a collection from an array for use with table components.
7
+ class Array
8
+ include Core
9
+ include Filtering
10
+
11
+ def self.with_params(params)
12
+ new.with_params(params)
13
+ end
14
+
15
+ def model
16
+ items.first&.class || ActiveRecord::Base
17
+ end
18
+
19
+ def model_name
20
+ @model_name ||= items.first&.model_name || ActiveModel::Name.new(Object, nil, "record")
21
+ end
22
+
23
+ def with_params(params)
24
+ # test support
25
+ params = ActionController::Parameters.new(params) unless params.is_a?(ActionController::Parameters)
26
+
27
+ self.attributes = params.permit(self.class.permitted_params)
28
+
29
+ self
30
+ end
31
+
32
+ def inspect
33
+ "#<#{self.class.name} @attributes=#{attributes.inspect} @model_name=\"#{model_name}\" @count=#{items&.count}>"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -34,6 +34,10 @@ module Katalyst
34
34
  new.with_params(params)
35
35
  end
36
36
 
37
+ def model
38
+ items.model
39
+ end
40
+
37
41
  def model_name
38
42
  @model_name ||= items.model_name.dup.tap do |name|
39
43
  name.param_key = ""
@@ -1,10 +1,4 @@
1
1
  en:
2
- time:
3
- formats:
4
- table: "%e %B %Y, %l:%M%P"
5
- date:
6
- formats:
7
- table: "%e %B %Y"
8
2
  katalyst:
9
3
  tables:
10
4
  orderable:
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/configurable"
4
+
5
+ module Katalyst
6
+ module Tables
7
+ class Config
8
+ include ActiveSupport::Configurable
9
+
10
+ config_accessor(:component_extensions) do
11
+ %w[
12
+ Katalyst::Tables::Identifiable
13
+ Katalyst::Tables::Orderable
14
+ Katalyst::Tables::Selectable
15
+ Katalyst::Tables::Sortable
16
+ ]
17
+ end
18
+
19
+ config_accessor(:date_format) { :default }
20
+ config_accessor(:datetime_format) { :default }
21
+ end
22
+ end
23
+ end
@@ -3,10 +3,19 @@
3
3
  require "view_component"
4
4
  require "katalyst/html_attributes"
5
5
 
6
+ require_relative "tables/config"
6
7
  require_relative "tables/engine"
7
8
 
8
9
  module Katalyst
9
10
  module Tables
10
11
  class Error < StandardError; end
12
+
13
+ def self.config
14
+ @config ||= Config.new
15
+ end
16
+
17
+ def self.configure
18
+ yield config
19
+ end
11
20
  end
12
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-tables
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-03 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katalyst-html-attributes
@@ -63,63 +63,56 @@ files:
63
63
  - app/assets/stylesheets/katalyst/tables/typed-columns/_datetime.scss
64
64
  - app/assets/stylesheets/katalyst/tables/typed-columns/_index.scss
65
65
  - app/assets/stylesheets/katalyst/tables/typed-columns/_number.scss
66
- - app/components/concerns/katalyst/tables/body/typed_columns.rb
67
- - app/components/concerns/katalyst/tables/configurable_component.rb
68
66
  - app/components/concerns/katalyst/tables/has_table_content.rb
69
- - app/components/concerns/katalyst/tables/header/typed_columns.rb
67
+ - app/components/concerns/katalyst/tables/identifiable.rb
70
68
  - app/components/concerns/katalyst/tables/orderable.rb
71
69
  - app/components/concerns/katalyst/tables/row_renderer.rb
72
70
  - app/components/concerns/katalyst/tables/selectable.rb
73
71
  - app/components/concerns/katalyst/tables/sortable.rb
74
72
  - app/components/katalyst/table_component.html.erb
75
73
  - app/components/katalyst/table_component.rb
76
- - app/components/katalyst/tables/body/attachment_component.rb
77
- - app/components/katalyst/tables/body/boolean_component.rb
78
- - app/components/katalyst/tables/body/currency_component.rb
79
- - app/components/katalyst/tables/body/date_component.rb
80
- - app/components/katalyst/tables/body/date_time_component.rb
81
- - app/components/katalyst/tables/body/link_component.rb
82
- - app/components/katalyst/tables/body/number_component.rb
83
- - app/components/katalyst/tables/body/rich_text_component.rb
84
- - app/components/katalyst/tables/body_cell_component.rb
74
+ - app/components/katalyst/tables/body_row_component.html.erb
85
75
  - app/components/katalyst/tables/body_row_component.rb
76
+ - app/components/katalyst/tables/cell_component.rb
77
+ - app/components/katalyst/tables/cells/boolean_component.rb
78
+ - app/components/katalyst/tables/cells/currency_component.rb
79
+ - app/components/katalyst/tables/cells/date_component.rb
80
+ - app/components/katalyst/tables/cells/date_time_component.rb
81
+ - app/components/katalyst/tables/cells/number_component.rb
82
+ - app/components/katalyst/tables/cells/ordinal_component.rb
83
+ - app/components/katalyst/tables/cells/rich_text_component.rb
84
+ - app/components/katalyst/tables/cells/select_component.rb
85
+ - app/components/katalyst/tables/data.rb
86
86
  - app/components/katalyst/tables/empty_caption_component.html.erb
87
87
  - app/components/katalyst/tables/empty_caption_component.rb
88
- - app/components/katalyst/tables/header/attachment_component.rb
89
- - app/components/katalyst/tables/header/boolean_component.rb
90
- - app/components/katalyst/tables/header/currency_component.rb
91
- - app/components/katalyst/tables/header/date_component.rb
92
- - app/components/katalyst/tables/header/date_time_component.rb
93
- - app/components/katalyst/tables/header/link_component.rb
94
- - app/components/katalyst/tables/header/number_component.rb
95
- - app/components/katalyst/tables/header/rich_text_component.rb
96
- - app/components/katalyst/tables/header_cell_component.rb
88
+ - app/components/katalyst/tables/header_row_component.html.erb
97
89
  - app/components/katalyst/tables/header_row_component.rb
90
+ - app/components/katalyst/tables/label.rb
91
+ - app/components/katalyst/tables/orderable/form_component.rb
98
92
  - app/components/katalyst/tables/pagy_nav_component.rb
99
93
  - app/components/katalyst/tables/selectable/form_component.html.erb
100
94
  - app/components/katalyst/tables/selectable/form_component.rb
101
95
  - app/controllers/concerns/katalyst/tables/backend.rb
102
96
  - app/helpers/katalyst/tables/frontend.rb
103
- - app/helpers/katalyst/tables/frontend/helper.rb
104
97
  - app/javascript/tables/application.js
105
98
  - app/javascript/tables/orderable/form_controller.js
106
99
  - app/javascript/tables/orderable/item_controller.js
107
100
  - app/javascript/tables/orderable/list_controller.js
108
101
  - app/javascript/tables/selection/form_controller.js
109
102
  - app/javascript/tables/selection/item_controller.js
110
- - app/javascript/tables/turbo/collection_controller.js
111
103
  - app/models/concerns/katalyst/tables/collection/core.rb
112
104
  - app/models/concerns/katalyst/tables/collection/filtering.rb
113
105
  - app/models/concerns/katalyst/tables/collection/has_params.rb
114
106
  - app/models/concerns/katalyst/tables/collection/pagination.rb
115
107
  - app/models/concerns/katalyst/tables/collection/reducers.rb
116
108
  - app/models/concerns/katalyst/tables/collection/sorting.rb
109
+ - app/models/katalyst/tables/collection/array.rb
117
110
  - app/models/katalyst/tables/collection/base.rb
118
111
  - app/models/katalyst/tables/collection/filter.rb
119
- - app/models/katalyst/tables/collection/sort_form.rb
120
112
  - config/importmap.rb
121
113
  - config/locales/tables.en.yml
122
114
  - lib/katalyst/tables.rb
115
+ - lib/katalyst/tables/config.rb
123
116
  - lib/katalyst/tables/engine.rb
124
117
  homepage: https://github.com/katalyst/tables
125
118
  licenses:
@@ -130,7 +123,7 @@ metadata:
130
123
  homepage_uri: https://github.com/katalyst/tables
131
124
  source_code_uri: https://github.com/katalyst/tables
132
125
  changelog_uri: https://github.com/katalyst/tables/blobs/main/CHANGELOG.md
133
- post_install_message:
126
+ post_install_message:
134
127
  rdoc_options: []
135
128
  require_paths:
136
129
  - lib
@@ -146,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
139
  version: '0'
147
140
  requirements: []
148
141
  rubygems_version: 3.5.9
149
- signing_key:
142
+ signing_key:
150
143
  specification_version: 4
151
144
  summary: HTML table generator for Rails views
152
145
  test_files: []
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Katalyst
4
- module Tables
5
- module Body
6
- module TypedColumns
7
- extend ActiveSupport::Concern
8
-
9
- # Generates a column from boolean values rendered as "Yes" or "No".
10
- #
11
- # @param method [Symbol] the method to call on the record
12
- # @param attributes [Hash] HTML attributes to be added to the cell
13
- # @param block [Proc] optional block to alter the cell content
14
- # @return [void]
15
- #
16
- # @example Render a boolean column indicating whether the record is active
17
- # <% row.boolean :active %> # => <td>Yes</td>
18
- def boolean(method, **attributes, &)
19
- with_column(Body::BooleanComponent.new(@table, @record, method, **attributes), &)
20
- end
21
-
22
- # Generates a column from date values rendered using I18n.l.
23
- # The default format is :admin, but it can be overridden.
24
- #
25
- # @param method [Symbol] the method to call on the record
26
- # @param format [Symbol] the I18n date format to use when rendering
27
- # @param attributes [Hash] HTML attributes to be added to the cell tag
28
- # @param block [Proc] optional block to alter the cell content
29
- # @return [void]
30
- #
31
- # @example Render a date column describing when the record was created
32
- # <% row.date :created_at %> # => <td>29 Feb 2024</td>
33
- def date(method, format: :table, **attributes, &)
34
- with_column(Body::DateComponent.new(@table, @record, method, format:, **attributes), &)
35
- end
36
-
37
- # Generates a column from datetime values rendered using I18n.l.
38
- # The default format is :admin, but it can be overridden.
39
- #
40
- # @param method [Symbol] the method to call on the record
41
- # @param format [Symbol] the I18n datetime format to use when rendering
42
- # @param attributes [Hash] HTML attributes to be added to the cell tag
43
- # @param block [Proc] optional block to alter the cell content
44
- # @return [void]
45
- #
46
- # @example Render a datetime column describing when the record was created
47
- # <% row.datetime :created_at %> # => <td>29 Feb 2024, 5:00pm</td>
48
- def datetime(method, format: :table, **attributes, &)
49
- with_column(Body::DateTimeComponent.new(@table, @record, method, format:, **attributes), &)
50
- end
51
-
52
- # Generates a column from numeric values formatted appropriately.
53
- #
54
- # @param method [Symbol] the method to call on the record
55
- # @param attributes [Hash] HTML attributes to be added to the cell tag
56
- # @param block [Proc] optional block to alter the cell content
57
- # @return [void]
58
- #
59
- # @example Render the number of comments on a post
60
- # <% row.number :comment_count %> # => <td>0</td>
61
- def number(method, **attributes, &)
62
- with_column(Body::NumberComponent.new(@table, @record, method, **attributes), &)
63
- end
64
-
65
- # Generates a column from numeric values rendered using `number_to_currency`.
66
- #
67
- # @param method [Symbol] the method to call on the record
68
- # @param options [Hash] options to be passed to `number_to_currency`
69
- # @param attributes [Hash] HTML attributes to be added to the cell tag
70
- # @param block [Proc] optional block to alter the cell content
71
- # @return [void]
72
- #
73
- # @example Render a currency column for the price of a product
74
- # <% row.currency :price %> # => <td>$3.50</td>
75
- def currency(method, options: {}, **attributes, &)
76
- with_column(Body::CurrencyComponent.new(@table, @record, method, options:, **attributes), &)
77
- end
78
-
79
- # Generates a column containing HTML markup.
80
- #
81
- # @param method [Symbol] the method to call on the record
82
- # @param attributes [Hash] HTML attributes to be added to the cell tag
83
- # @param block [Proc] optional block to alter the cell content
84
- # @return [void]
85
- #
86
- # @note This method assumes that the method returns HTML-safe content.
87
- # If the content is not HTML-safe, it will be escaped.
88
- #
89
- # @example Render a description column containing HTML markup
90
- # <% row.rich_text :description %> # => <td><em>Emphasis</em></td>
91
- def rich_text(method, **attributes, &)
92
- with_column(Body::RichTextComponent.new(@table, @record, method, **attributes), &)
93
- end
94
-
95
- # Generates a column that links to the record's show page (by default).
96
- #
97
- # @param method [Symbol] the method to call on the record
98
- # @param link [Hash] options to be passed to the link_to helper
99
- # @option opts [Hash, Array, String, Symbol] :url ([:admin, object]) options for url_for,
100
- # or a symbol to be passed to the route helper
101
- # @param attributes [Hash] HTML attributes to be added to the cell tag
102
- # @param block [Proc] optional block to alter the cell content
103
- # @return [void]
104
- #
105
- # @example Render a column containing the record's title, linked to its show page
106
- # <% row.link :title %> # => <td><a href="/admin/post/15">About us</a></td>
107
- # @example Render a column containing the record's title, linked to its edit page
108
- # <% row.link :title, url: :edit_admin_post_path do |cell| %>
109
- # Edit <%= cell %>
110
- # <% end %>
111
- # # => <td><a href="/admin/post/15/edit">Edit About us</a></td>
112
- def link(method, url: @record, link: {}, **attributes, &)
113
- with_column(Body::LinkComponent.new(@table, @record, method, url:, link:, **attributes), &)
114
- end
115
-
116
- # Generates a column that renders an ActiveStorage attachment as a downloadable link.
117
- #
118
- # @param method [Symbol] the method to call on the record
119
- # @param variant [Symbol] the variant to use when rendering the image (default :thumb)
120
- # @param attributes [Hash] HTML attributes to be added to the cell tag
121
- # @param block [Proc] optional block to alter the cell content
122
- # @return [void]
123
- #
124
- # @example Render a column containing a download link to the record's background image
125
- # <% row.attachment :background %> # => <td><a href="...">background.png</a></td>
126
- def attachment(method, variant: :thumb, **attributes, &)
127
- with_column(Body::AttachmentComponent.new(@table, @record, method, variant:, **attributes), &)
128
- end
129
- end
130
- end
131
- end
132
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Katalyst
4
- module Tables
5
- module ConfigurableComponent # :nodoc:
6
- extend ActiveSupport::Concern
7
-
8
- include ActiveSupport::Configurable
9
-
10
- included do
11
- # Workaround: ViewComponent::Base.config is incompatible with ActiveSupport::Configurable
12
- @_config = Class.new(ActiveSupport::Configurable::Configuration).new
13
- end
14
-
15
- class_methods do
16
- # Define a configurable sub-component.
17
- # Sub-components are cached on the table instance. We want to allow run
18
- # time mixins for tables so that we can extend tables with cross-cutting
19
- # concerns that affect multiple sub-components by including the concern
20
- # into the top-level table class. We achieve this by subclassing the
21
- # component as soon as it is created so that when a mixin is added to
22
- # the table class, it can immediately retrieve and modify the
23
- # sub-component class as well without needing to worry about affecting
24
- # other tables.
25
- def config_component(name, component_name: "#{name}_component", default: nil) # rubocop:disable Metrics/MethodLength
26
- config_accessor(name)
27
- config.public_send(:"#{name}=", default)
28
- define_method(component_name) do
29
- return instance_variable_get(:"@#{component_name}") if instance_variable_defined?(:"@#{component_name}")
30
-
31
- klass = config.public_send(name)
32
- component = klass ? self.class.const_get(klass) : nil
33
-
34
- # subclass to allow table-specific extensions
35
- if component
36
- component = Class.new(component)
37
- component.extend(HiddenSubcomponent)
38
- end
39
-
40
- instance_variable_set(:"@#{component_name}", component) if component
41
- end
42
- end
43
- end
44
-
45
- # View Component uses `name` to resolve the template path, so we need to
46
- # hide the subclass from the template resolver.
47
- module HiddenSubcomponent
48
- delegate :name, to: :superclass
49
- end
50
- end
51
- end
52
- end
@@ -1,179 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Katalyst
4
- module Tables
5
- module Header
6
- module TypedColumns
7
- extend ActiveSupport::Concern
8
-
9
- # Renders a boolean column header
10
- # @param method [Symbol] the method to call on the record to get the value
11
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
12
- # @option attributes [String] :label (nil) The label options to display in the header
13
- # @option attributes [Hash] :link ({}) The link options for the sorting link
14
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
15
- #
16
- # @example Render a boolean column header
17
- # <% row.boolean :active %> # => <th>Active</th>
18
- #
19
- # @example Render a boolean column header with a custom label
20
- # <% row.boolean :active, label: "Published" %> # => <th>Published</th>
21
- #
22
- # @example Render a boolean column header with small width
23
- # <% row.boolean :active, width: :s %>
24
- # => <th class="width-s">Active</th>
25
- #
26
- def boolean(method, **attributes, &)
27
- with_column(Header::BooleanComponent.new(@table, method, link: @link_attributes, **attributes), &)
28
- end
29
-
30
- # Renders a date column header
31
- # @param method [Symbol] the method to call on the record to get the value
32
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
33
- # @option attributes [String] :label (nil) The label options to display in the header
34
- # @option attributes [Hash] :link ({}) The link options for the sorting link
35
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
36
- #
37
- # @example Render a date column header
38
- # <% row.date :published_on %> # => <th>Published on</th>
39
- #
40
- # @example Render a date column header with a custom label
41
- # <% row.date :published_on, label: "Date" %> # => <th>Date</th>
42
- #
43
- # @example Render a boolean column header with small width
44
- # <% row.date :published_on, width: :s %>
45
- # => <th class="width-s">Published on</th>
46
- #
47
- def date(method, **attributes, &)
48
- with_column(Header::DateComponent.new(@table, method, link: @link_attributes, **attributes), &)
49
- end
50
-
51
- # Renders a datetime column header
52
- # @param method [Symbol] the method to call on the record to get the value
53
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
54
- # @option attributes [String] :label (nil) The label options to display in the header
55
- # @option attributes [Hash] :link ({}) The link options for the sorting link
56
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
57
- #
58
- # @example Render a datetime column header
59
- # <% row.datetime :created_at %> # => <th>Created at</th>
60
- #
61
- # @example Render a datetime column header with a custom label
62
- # <% row.datetime :created_at, label: "Published at" %> # => <th>Published at</th>
63
- #
64
- # @example Render a boolean column header with small width
65
- # <% row.datetime :created_at, width: :s %>
66
- # => <th class="width-s">Created at</th>
67
- #
68
- def datetime(method, **attributes, &)
69
- with_column(Header::DateTimeComponent.new(@table, method, link: @link_attributes, **attributes), &)
70
- end
71
-
72
- # Renders a number column header
73
- # @param method [Symbol] the method to call on the record to get the value
74
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
75
- # @option attributes [String] :label (nil) The label options to display in the header
76
- # @option attributes [Hash] :link ({}) The link options for the sorting link
77
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
78
- #
79
- # @example Render a number column header
80
- # <% row.number :comment_count %> # => <th>Comments</th>
81
- #
82
- # @example Render a number column header with a custom label
83
- # <% row.number :comment_count, label: "Comments" %> # => <th>Comments</th>
84
- #
85
- # @example Render a boolean column header with small width
86
- # <% row.number :comment_count, width: :s %>
87
- # => <th class="width-s">Comments</th>
88
- #
89
- def number(method, **attributes, &)
90
- with_column(Header::NumberComponent.new(@table, method, link: @link_attributes, **attributes), &)
91
- end
92
-
93
- # Renders a currency column header
94
- # @param method [Symbol] the method to call on the record to get the value
95
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
96
- # @option attributes [String] :label (nil) The label options to display in the header
97
- # @option attributes [Hash] :link ({}) The link options for the sorting link
98
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
99
- #
100
- # @example Render a currency column header
101
- # <% row.currency :price %> # => <th>Price</th>
102
- #
103
- # @example Render a currency column header with a custom label
104
- # <% row.currency :price, label: "Amount($)" %> # => <th>Amount($)</th>
105
- #
106
- # @example Render a boolean column header with small width
107
- # <% row.currency :price, width: :s %>
108
- # => <th class="width-s">Price</th>
109
- #
110
- def currency(method, **attributes, &)
111
- with_column(Header::CurrencyComponent.new(@table, method, link: @link_attributes, **attributes), &)
112
- end
113
-
114
- # Renders a rich text column header
115
- # @param method [Symbol] the method to call on the record to get the value
116
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
117
- # @option attributes [String] :label (nil) The label options to display in the header
118
- # @option attributes [Hash] :link ({}) The link options for the sorting link
119
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
120
- #
121
- # @example Render a rich text header
122
- # <% row.rich_text :content %> # => <th>Content</th>
123
- #
124
- # @example Render a rich text column header with a custom label
125
- # <% row.currency :content, label: "Content!" %> # => <th>Content!</th>
126
- #
127
- # @example Render a boolean column header with small width
128
- # <% row.currency :content, width: :s %>
129
- # => <th class="width-s">Content</th>
130
- #
131
- def rich_text(method, **attributes, &)
132
- with_column(Header::RichTextComponent.new(@table, method, link: @link_attributes, **attributes), &)
133
- end
134
-
135
- # Renders a link column header
136
- # @param method [Symbol] the method to call on the record to get the value
137
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
138
- # @option attributes [String] :label (nil) The label options to display in the header
139
- # @option attributes [Hash] :link ({}) The link options for the sorting link
140
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
141
- #
142
- # @example Render a link column header
143
- # <% row.link :link %> # => <th>Link</th>
144
- #
145
- # @example Render a link column header with a custom label
146
- # <% row.link :link, label: "Post" %> # => <th>Post</th>
147
- #
148
- # @example Render a boolean column header with small width
149
- # <% row.link :link, width: :s %>
150
- # => <th class="width-s">Link</th>
151
- #
152
- def link(method, **attributes, &)
153
- with_column(Header::LinkComponent.new(@table, method, link: @link_attributes, **attributes), &)
154
- end
155
-
156
- # Renders a attachment column header
157
- # @param method [Symbol] the method to call on the record to get the value
158
- # @param attributes [Hash] additional arguments are applied as html attributes to the th element
159
- # @option attributes [String] :label (nil) The label options to display in the header
160
- # @option attributes [Hash] :link ({}) The link options for the sorting link
161
- # @option attributes [String] :width (nil) The width of the column, can be +:xs+, +:s+, +:m+, +:l+ or nil
162
- #
163
- # @example Render a attachment column header
164
- # <% row.attachment :attachment %> # => <th>Attachment</th>
165
- #
166
- # @example Render a attachment column header with a custom label
167
- # <% row.attachment :attachment, label: "Document" %> # => <th>Document</th>
168
- #
169
- # @example Render a boolean column header with small width
170
- # <% row.attachment :attachment, width: :s %>
171
- # => <th class="width-s">Attachment</th>
172
- #
173
- def attachment(method, **attributes, &)
174
- with_column(Header::AttachmentComponent.new(@table, method, link: @link_attributes, **attributes), &)
175
- end
176
- end
177
- end
178
- end
179
- end
@@ -1,58 +0,0 @@
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