katalyst-tables 3.0.0.beta1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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