katalyst-tables 3.5.1 → 3.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3814f29f662d5198c08b423d4f7ac76a07e327588f601fcc163adaa239f7b842
4
- data.tar.gz: 24c1a6a392a570cd2338b1d3501a8d6a10c3f96f0d445aafb64b0fa541764e06
3
+ metadata.gz: 5402c4de7c04e40f7586c7ab01498e17a085b16c630a556eecbd5ddf7557fc08
4
+ data.tar.gz: 52de56d41efe1dc78a47e43891db23bcca41feccb285f450e4fb45e5810d51f0
5
5
  SHA512:
6
- metadata.gz: ec8aeebe3f1470b3cc1f0d15802cabf82365d91646b70ea9dabbbb1ad7fca2cde1d983014bbb84bdfd6af0ad3a0fd85305ae33e00de38ed789b105ce5f6b7aae
7
- data.tar.gz: 7b630dde2814a741df30c2dac1c5e21ed23a6137a588413044172ba8b658287462fb7a860d961d8f489ad4be1fe4207b4aab203419bfc2c7ed65cfc6a1437965
6
+ metadata.gz: 107ebb571430631da2083805322b3734d0a1ef5ca9f4bbf43433e0e32658ea3fec5ad8bb94e8cf768978e2b1d9224f755f81d0e32b69e59737425f23c5f9c68f
7
+ data.tar.gz: c43331d1a1fc21587f0cd5a874a5adbf34813b94eae3007586418b3c440876ec00a8e810aa19eb2d15eb52b55f4c37280dee8992f8e86e95ae826094bfc5ad74
data/README.md CHANGED
@@ -1,267 +1,10 @@
1
- # Katalyst::Tables
1
+ # Katalyst Tables
2
2
 
3
- Tools for building HTML tables from ActiveRecord collections.
3
+ A library for viewing and interacting with database tables in Ruby on Rails.
4
4
 
5
- ## Installation
5
+ ## Documentation
6
6
 
7
- Add this line to your application's Gemfile:
8
-
9
- ```ruby
10
- gem "katalyst-tables"
11
- ```
12
-
13
- And then execute:
14
-
15
- $ bundle install
16
-
17
- Add the Gem's javascript and CSS to your build pipeline. This assumes that
18
- you're using `rails-dartsass` and `importmaps` to manage your assets.
19
-
20
- ```javascript
21
- // app/javascript/controllers/application.js
22
- import { application } from "controllers/application";
23
- import tables from "@katalyst/tables";
24
- application.load(tables);
25
- ```
26
-
27
- ```scss
28
- // app/assets/stylesheets/application.scss
29
- @use "@katalyst/tables";
30
- ```
31
-
32
- ## Usage
33
-
34
- This gem provides entry points for backend and frontend concerns:
35
- * `Katalyst::TableComponent` can be used render encapsulated tables,
36
- * `Katalyst::SummaryTableComponent` can be used render a record using the table syntax,
37
- * `Katalyst::Tables::Frontend` provides `table_with` for inline table generation,
38
- * `Katalyst::Tables::Collection::Base` provides a default entry point for
39
- building collections in your controller actions
40
- * `Katalyst::Tables::Collection::Query` provides build-in query parsing and filtering
41
- based on the attributes defined in your collection.
42
-
43
- ### Frontend
44
-
45
- Add `include Katalyst::Tables::Frontend` to your `ApplicationHelper` or similar.
46
-
47
- You can use the `table_with` helper to generate a table inline in your view without explicitly interacting with the
48
- table component. This is the preferred approach when creating tables. However, if the table is complex or you need to
49
- reuse it, you should consider moving the definition of the row into a partial.
50
-
51
- ```erb
52
- <%= table_with collection: @people do |row, person| %>
53
- <% row.text :name do |cell| %>
54
- <%= link_to cell.value, [:edit, person] %>
55
- <% end %>
56
- <% row.text :email %>
57
- <% end %>
58
- ```
59
-
60
- By not providing a block to the `table_with` call, the gem will look for a partial called `_person.html+row.erb` to
61
- render each row:
62
-
63
- ```erb
64
- <%# locals: { row:, person: nil } %>
65
- <% row.text :name do |cell| %>
66
- <%= link_to cell.value, [:edit, person] %>
67
- <% end %>
68
- <% row.text :email %>
69
- ```
70
-
71
- The table will call your block / partial once per row and accumulate the cells
72
- you generate into rows, including a header row:
73
-
74
- ```html
75
-
76
- <table>
77
- <thead>
78
- <tr>
79
- <th>Name</th>
80
- <th>Email</th>
81
- </tr>
82
- </thead>
83
- <tbody>
84
- <tr>
85
- <td><a href="/people/1/edit">Alice</a></td>
86
- <td>alice@acme.org</td>
87
- </tr>
88
- <tr>
89
- <td><a href="/people/2/edit">Bob</a></td>
90
- <td>bob@acme.org</td>
91
- </tr>
92
- </tbody>
93
- </table>
94
- ```
95
-
96
- You can customize the partial and/or the name of the resource in a similar style
97
- to view partials:
98
-
99
- ```erb
100
- <%= table_with(collection: @employees, as: :person, partial: "person") %>
101
- ```
102
-
103
- ### HTML Attributes
104
-
105
- You can add custom attributes on table, row, and cell tags.
106
-
107
- The table tag takes attributes passed to `table_with` helper, similar to `form_with`:
108
-
109
- ```erb
110
- <%= table_with(collection: @people, id: "people-table")
111
- ```
112
-
113
- Cells support the same approach:
114
-
115
- ```erb
116
- <%= row.text :name, class: "name" %>
117
- ```
118
-
119
- Rows do not get called directly, so instead you can assign to `html_attributes` on the row builder to customize row tag
120
- generation.
121
-
122
- ```erb
123
- <% row.update_html_attributes(id: person.id) if row.body? %>
124
- ```
125
-
126
- Note: because the row builder gets called to generate the header row, you may need to guard calls that access the
127
- `person` directly as shown in the previous example. You could also check whether `person` is present.
128
-
129
- ### Headers
130
-
131
- Tables will automatically generate a header row for you by calling your row partial or provided block with no object.
132
- During this call, `row.header?` is true, `row.body?` is false, and the object (`person`) is nil.
133
-
134
- All cells generated in the table header iteration will automatically be header cells, but you can also make header cells
135
- in your body rows by passing `heading: true` when you generate the cell.
136
-
137
- ```erb
138
- <% row.number :id, heading: true %>
139
- ```
140
-
141
- The table header cells default to showing the capitalized column name, but you can customize this in one of two ways:
142
-
143
- * Set the value inline
144
- ```erb
145
- <% row.number :id, label: "ID" %>
146
- ```
147
- * Define a translation for the attribute
148
- ```yml
149
- # en.yml
150
- activerecord:
151
- attributes:
152
- person:
153
- id: "ID"
154
- ```
155
-
156
- Note: if the cell is given a block, it is not called during the header pass. This
157
- is because the block is assumed to be for generating data for the body, not the
158
- header. We suggest you set `label` instead.
159
-
160
- #### Cell values
161
-
162
- If you do not provide a value when you call the cell builder, the attribute you
163
- provide will be retrieved from the current item and the result will be rendered in
164
- the table cell. This is often all you need to do, but if you do want to customise
165
- the value you can pass a block instead:
166
-
167
- ```erb
168
- <% row.text :status do %>
169
- <%= person.password.present? ? "Active" : "Invited" %>
170
- <% end %>
171
- ```
172
-
173
- In the context of the block you have access the cell component if you simply
174
- want to extend the default behaviour:
175
-
176
- ```erb
177
- <%# @type [Katalyst::Tables::CellComponent] cell %>
178
- <% row.text :name do |cell| %>
179
- <%= link_to cell, person %>
180
- <% end %>
181
- ```
182
-
183
- You can also update `html_attributes` on the cell builder, similar to the row
184
- builder, see `katalyst-html-attributes` for details.
185
-
186
- ## Collections
187
-
188
- The `Katalyst::Tables::Collection::Base` class provides a convenient way to
189
- manage collections in your controller actions. It is designed to be used with
190
- Pagy for pagination and provides built-in sorting when used with ActiveRecord
191
- collections. Sorting and Pagination are off by default, you can either set them
192
- on creation or create a custom `Collection` class that sets them on by default:
193
-
194
- ```ruby
195
- # in #index
196
- Katalyst::Tables::Collection::Base.new(sorting: "name asc", pagination: true)
197
- # or as a nested class in your controller
198
- class Collection < Katalyst::Tables::Collection::Base
199
- config.sorting = "name asc" # requires models have a name attribute
200
- config.pagination = true
201
- end
202
- ```
203
-
204
- Collections can be passed directly to `table_with` method and it will automatically
205
- detect features such as sorting and generate the appropriate table header links.
206
-
207
- ```erb
208
- <%= table_with(collection:) %>
209
- ```
210
-
211
- ### Query
212
-
213
- Include `Katalyst::Tables::Collection::Query` into your collection to add automatic
214
- query parsing and filtering based on the configured attributes. For example:
215
-
216
- ```ruby
217
- class Collection < Katalyst::Tables::Collection::Base
218
- include Katalyst::Tables::Collection::Query
219
-
220
- attribute :first_name, :string
221
- attribute :created_at, :date
222
- end
223
- ```
224
-
225
- With this definition and a text-input named `query`, your users can write tagged
226
- query expressions such as `first_name:Aaron` or `created_at:>2024-01-01` and these
227
- will be automatically parsed and applied to the collection attribute, and the collection
228
- will automatically generate and apply ActiveRecord conditions to filter the given scope.
229
-
230
- There's also a frontend utility, `table_query_with(collection:)` that will generate the form
231
- and show a modal that helps users to interact with the query interface. More details available
232
- in the [query](docs/query.md) documentation.
233
-
234
- ## Summary tables
235
- You can use the `Katalyst::SummaryTableComponent` to render a single record utilizing all the functionality from the
236
- `Katalyst::TableComponent`.
237
-
238
- ```erb
239
- <%= summary_table_with model: @person do |row| %>
240
- <% row.text :name %>
241
- <% row.text :email %>
242
- <% end %>
243
- ```
244
-
245
- ## Extensions
246
-
247
- The following extensions are available and activated by default:
248
-
249
- * [Filtering](docs/filtering.md) - adds automatic collection filtering based on attributes
250
- * [Query](docs/query.md) - adds human-friendly text filtering that populates collection attributes
251
- * [Identifiable](docs/identifiable.md) - adds default dom ids to the table and data rows.
252
- * [Orderable](docs/orderable.md) - adds bulk-update for 'ordinal' columns via dragging rows in the table.
253
- * [Pagination](docs/pagination.md) - handles paginating of data in the collection.
254
- * [Selectable](docs/selectable.md) - adds bulk-action support for rows in the table.
255
- * [Sortable](docs/sortable.md) - table column headers that can be sorted will be wrapped in links.
256
- * [Customization](docs/customization.md) - customize the table and cell rendering.
257
-
258
- You can disable extensions by altering the `Katalyst::Tables.config.component_extensions` before initialization.
259
-
260
- ## Development
261
-
262
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests.
263
-
264
- To install this gem onto your local machine, run `bundle exec rake install`.
7
+ See [katalyst.github.io/tables](https://katalyst.github.io/tables/) for documentation.
265
8
 
266
9
  ## Contributing
267
10
 
@@ -269,4 +12,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/kataly
269
12
 
270
13
  ## License
271
14
 
272
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
15
+ Katalyst Tables is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -96,10 +96,12 @@
96
96
  }
97
97
  }
98
98
 
99
- .footer {
99
+ footer {
100
100
  grid-area: footer;
101
101
  display: flex;
102
- justify-content: flex-end;
103
- padding-block: 1rem;
102
+ justify-content: flex-start;
103
+ padding-inline: 1rem;
104
+ padding-block: 0.5rem;
105
+ border-top: 1px solid #d3d3d3;
104
106
  }
105
107
  }
@@ -7,7 +7,11 @@ module Katalyst
7
7
  # Expect to see NoMethodError failures if pagy is not available
8
8
  "Pagy::Frontend".safe_constantize&.tap { |pagy| include(pagy) }
9
9
 
10
- attr_reader :pagy_options
10
+ def self.pagy_legacy?
11
+ Pagy::VERSION.scan(/\d+/).first.to_i <= 8
12
+ end
13
+
14
+ delegate :pagy_legacy?, to: :class
11
15
 
12
16
  def initialize(collection: nil, pagy: nil, **pagy_options)
13
17
  super()
@@ -24,9 +28,19 @@ module Katalyst
24
28
  pagy_nav(@pagy, **pagy_options).html_safe # rubocop:disable Rails/OutputSafety
25
29
  end
26
30
 
31
+ def pagy_options
32
+ default_pagy_options.merge(@pagy_options)
33
+ end
34
+
27
35
  def inspect
28
36
  "#<#{self.class.name} pagy: #{@pagy.inspect}>"
29
37
  end
38
+
39
+ private
40
+
41
+ def default_pagy_options
42
+ pagy_legacy? ? {} : { anchor_string: 'data-turbo-action="replace"' }
43
+ end
30
44
  end
31
45
  end
32
46
  end
@@ -22,6 +22,12 @@ module Katalyst
22
22
  collection.suggestions.each do |suggestion|
23
23
  with_suggestion(suggestion:)
24
24
  end
25
+
26
+ unless footer?
27
+ with_footer do
28
+ link_to("Search syntax", "https://katalyst.github.io/tables/users/queries")
29
+ end
30
+ end
25
31
  end
26
32
 
27
33
  private
@@ -8,6 +8,7 @@ module Katalyst
8
8
 
9
9
  included do
10
10
  class_attribute :_default_table_component, instance_accessor: false
11
+ class_attribute :_default_table_pagination_component, instance_accessor: false
11
12
  class_attribute :_default_table_query_component, instance_accessor: false
12
13
  class_attribute :_default_summary_table_component, instance_accessor: false
13
14
  end
@@ -21,6 +22,14 @@ module Katalyst
21
22
  self._default_table_component = component
22
23
  end
23
24
 
25
+ # Set the table pagination component to be used as the default for all tables
26
+ # in the views rendered by this controller and its subclasses.
27
+ #
28
+ # @param component [Class] the table pagination component class to use
29
+ def default_table_pagination_component(component)
30
+ self._default_table_pagination_component = component
31
+ end
32
+
24
33
  # Set the table query component to be used as the default for all tables
25
34
  # in the views rendered by this controller and its subclasses.
26
35
  #
@@ -44,6 +53,11 @@ module Katalyst
44
53
  self.class._default_table_component
45
54
  end
46
55
 
56
+ # Default table pagination component for this controller
57
+ def default_table_pagination_component
58
+ self.class._default_table_pagination_component
59
+ end
60
+
47
61
  # Default table query component for this controller
48
62
  def default_table_query_component
49
63
  self.class._default_table_query_component
@@ -55,6 +55,14 @@ module Katalyst
55
55
  render(Selectable::FormComponent.new(collection:, id:, primary_key:), &)
56
56
  end
57
57
 
58
+ # Construct pagination navigation for the current page. Defaults to pagy_nav.
59
+ #
60
+ # @param collection [Katalyst::Tables::Collection::Core] the collection to render
61
+ def table_pagination_with(collection:, **)
62
+ component ||= default_table_pagination_component_class
63
+ render(component.new(collection:, **))
64
+ end
65
+
58
66
  # Construct a new query interface for filtering the current page.
59
67
  #
60
68
  # @param collection [Katalyst::Tables::Collection::Core] the collection to render
@@ -85,6 +93,11 @@ module Katalyst
85
93
  component.respond_to?(:constantize) ? component.constantize : component
86
94
  end
87
95
 
96
+ def default_table_pagination_component_class
97
+ component = controller.try(:default_table_pagination_component) || PagyNavComponent
98
+ component.respond_to?(:constantize) ? component.constantize : component
99
+ end
100
+
88
101
  def default_table_query_component_class
89
102
  component = controller.try(:default_table_query_component) || QueryComponent
90
103
  component.respond_to?(:constantize) ? component.constantize : component
@@ -37,12 +37,12 @@ module Katalyst
37
37
  def paginate_options
38
38
  opts = @paginate.is_a?(Hash) ? @paginate : {}
39
39
  opts = opts.dup
40
- opts[:anchor_string] ||= anchor_string
41
- opts
42
- end
43
40
 
44
- def anchor_string
45
- "data-turbo-action=\"replace\""
41
+ if PagyNavComponent.pagy_legacy?
42
+ opts[:anchor_string] ||= "data-turbo-action=\"replace\""
43
+ end
44
+
45
+ opts
46
46
  end
47
47
 
48
48
  class Paginate # :nodoc:
@@ -57,7 +57,7 @@ module Katalyst
57
57
  def call(collection)
58
58
  @collection = @app.call(collection)
59
59
  if collection.paginate?
60
- @collection.pagination, @collection.items = pagy(@collection.items, collection.paginate_options.dup)
60
+ @collection.pagination, @collection.items = pagy(@collection.items, **collection.paginate_options)
61
61
  end
62
62
  @collection
63
63
  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.5.1
4
+ version: 3.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-18 00:00:00.000000000 Z
11
+ date: 2024-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: katalyst-html-attributes