katalyst-tables 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +7 -1
- data/app/assets/javascripts/controllers/tables/orderable/form_controller.js +20 -0
- data/app/assets/javascripts/controllers/tables/orderable/item_controller.js +8 -0
- data/app/assets/javascripts/controllers/tables/orderable/list_controller.js +73 -0
- data/app/assets/javascripts/controllers/tables/turbo_collection_controller.js +1 -1
- data/app/components/concerns/katalyst/tables/configurable_component.rb +24 -3
- data/app/components/concerns/katalyst/tables/has_html_attributes.rb +36 -20
- data/app/components/concerns/katalyst/tables/orderable.rb +113 -0
- data/app/components/katalyst/table_component.html.erb +13 -0
- data/app/components/katalyst/table_component.rb +16 -28
- data/app/components/katalyst/tables/body_cell_component.rb +4 -0
- data/app/components/katalyst/tables/body_row_component.rb +4 -0
- data/app/components/katalyst/tables/empty_caption_component.rb +5 -1
- data/app/components/katalyst/tables/header_cell_component.rb +5 -1
- data/app/components/katalyst/tables/header_row_component.rb +4 -0
- data/app/components/katalyst/tables/pagy_nav_component.rb +4 -0
- data/app/components/katalyst/turbo/table_component.rb +5 -5
- data/config/locales/tables.en.yml +6 -0
- data/lib/katalyst/tables/backend.rb +2 -2
- data/lib/katalyst/tables/version.rb +1 -1
- data/lib/katalyst/tables.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc97f1a686a28e4542c65f076afde15d61523726efb4dcaa3586e6c945121c13
|
4
|
+
data.tar.gz: 10eee025b9e0daee5d3aeda7a78625e6491d91d02f99bf831092072845276185
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a7e06d525551918f60e7b9a225f4ddb34bb3eeaeaecde37e817d0c61ade348f52e290235b21e84bedc72c92615f81e1226a10305242ff3e95e33fbb47a21878
|
7
|
+
data.tar.gz: 2d23b372c056506b054c02165e7191eb73d00f76df054e0d70eafbd88d6979126a3803c11bef29889f9095f644c7e40b30396da8d48580239978a7c9ee795019
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -287,6 +287,12 @@ def index
|
|
287
287
|
end
|
288
288
|
```
|
289
289
|
|
290
|
+
## Extensions
|
291
|
+
|
292
|
+
The following extensions are available:
|
293
|
+
|
294
|
+
* [Orderable](docs/orderable.md) - adds bulk-update for 'ordinal' columns via dragging rows in the table.
|
295
|
+
|
290
296
|
## Customization
|
291
297
|
|
292
298
|
A common pattern we use is to have a cell at the end of the table for actions. For example:
|
@@ -334,7 +340,7 @@ class ActionTableComponent < Katalyst::TableComponent
|
|
334
340
|
config.body_row = "ActionBodyRow"
|
335
341
|
config.body_cell = "ActionBodyCell"
|
336
342
|
|
337
|
-
def
|
343
|
+
def default_html_attributes
|
338
344
|
{ class: "action-table" }
|
339
345
|
end
|
340
346
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class OrderableFormController extends Controller {
|
4
|
+
add(name, value) {
|
5
|
+
this.element.insertAdjacentHTML(
|
6
|
+
"beforeend",
|
7
|
+
`<input type="hidden" name="${name}" value="${value}" data-generated>`,
|
8
|
+
);
|
9
|
+
}
|
10
|
+
|
11
|
+
submit() {
|
12
|
+
this.element.requestSubmit();
|
13
|
+
}
|
14
|
+
|
15
|
+
clear() {
|
16
|
+
this.element
|
17
|
+
.querySelectorAll("input[data-generated]")
|
18
|
+
.forEach((input) => input.remove());
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class OrderableListController extends Controller {
|
4
|
+
static outlets = ["tables--orderable--item", "tables--orderable--form"];
|
5
|
+
|
6
|
+
dragstart(event) {
|
7
|
+
if (this.element !== event.target.parentElement) return;
|
8
|
+
|
9
|
+
const target = event.target;
|
10
|
+
event.dataTransfer.effectAllowed = "move";
|
11
|
+
|
12
|
+
// update element style after drag has begun
|
13
|
+
setTimeout(() => (target.dataset.dragging = ""));
|
14
|
+
}
|
15
|
+
|
16
|
+
dragover(event) {
|
17
|
+
if (!this.dragItem) return;
|
18
|
+
|
19
|
+
swap(this.dropTarget(event.target), this.dragItem);
|
20
|
+
|
21
|
+
event.preventDefault();
|
22
|
+
return true;
|
23
|
+
}
|
24
|
+
|
25
|
+
dragenter(event) {
|
26
|
+
event.preventDefault();
|
27
|
+
}
|
28
|
+
|
29
|
+
drop(event) {
|
30
|
+
if (!this.dragItem) return;
|
31
|
+
|
32
|
+
event.preventDefault();
|
33
|
+
delete this.dragItem.dataset.dragging;
|
34
|
+
|
35
|
+
this.update();
|
36
|
+
}
|
37
|
+
|
38
|
+
update() {
|
39
|
+
// clear any existing inputs to prevent duplicates
|
40
|
+
this.tablesOrderableFormOutlet.clear();
|
41
|
+
|
42
|
+
// insert any items that have changed position
|
43
|
+
this.tablesOrderableItemOutlets.forEach((item, index) => {
|
44
|
+
if (item.valueValue !== index) {
|
45
|
+
this.tablesOrderableFormOutlet.add(item.nameValue, index);
|
46
|
+
}
|
47
|
+
});
|
48
|
+
|
49
|
+
this.tablesOrderableFormOutlet.submit();
|
50
|
+
}
|
51
|
+
|
52
|
+
get dragItem() {
|
53
|
+
return this.element.querySelector("[data-dragging]");
|
54
|
+
}
|
55
|
+
|
56
|
+
dropTarget($e) {
|
57
|
+
while ($e && $e.parentElement !== this.element) {
|
58
|
+
$e = $e.parentElement;
|
59
|
+
}
|
60
|
+
return $e;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
function swap(target, item) {
|
65
|
+
if (target && target !== item) {
|
66
|
+
const positionComparison = target.compareDocumentPosition(item);
|
67
|
+
if (positionComparison & Node.DOCUMENT_POSITION_FOLLOWING) {
|
68
|
+
target.insertAdjacentElement("beforebegin", item);
|
69
|
+
} else if (positionComparison & Node.DOCUMENT_POSITION_PRECEDING) {
|
70
|
+
target.insertAdjacentElement("afterend", item);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
@@ -14,18 +14,39 @@ module Katalyst
|
|
14
14
|
|
15
15
|
class_methods do
|
16
16
|
# Define a configurable sub-component.
|
17
|
-
|
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
|
18
26
|
config_accessor(name)
|
19
27
|
config.public_send("#{name}=", default)
|
20
28
|
define_method(component_name) do
|
21
|
-
instance_variable_get("@#{component_name}") if instance_variable_defined?("@#{component_name}")
|
29
|
+
return instance_variable_get("@#{component_name}") if instance_variable_defined?("@#{component_name}")
|
22
30
|
|
23
31
|
klass = config.public_send(name)
|
24
|
-
component = self.class.const_get(klass)
|
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
|
+
|
25
40
|
instance_variable_set("@#{component_name}", component) if component
|
26
41
|
end
|
27
42
|
end
|
28
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
|
29
50
|
end
|
30
51
|
end
|
31
52
|
end
|
@@ -4,41 +4,57 @@ require "html_attributes_utils"
|
|
4
4
|
|
5
5
|
module Katalyst
|
6
6
|
module Tables
|
7
|
-
|
7
|
+
# Adds HTML attributes to a component.
|
8
|
+
# Accepts HTML attributes from the constructor or via `html_attributes=`.
|
9
|
+
# These are merged with the default attributes defined in the component.
|
10
|
+
# Adds support for custom html attributes for other tags, e.g.:
|
11
|
+
# define_html_attribute_methods :table_attributes, default: {}
|
12
|
+
# tag.table(**table_attributes)
|
13
|
+
module HasHtmlAttributes
|
8
14
|
extend ActiveSupport::Concern
|
9
15
|
|
10
16
|
using HTMLAttributesUtils
|
11
17
|
|
12
|
-
|
18
|
+
MERGEABLE_ATTRIBUTES = [
|
13
19
|
*HTMLAttributesUtils::DEFAULT_MERGEABLE_ATTRIBUTES,
|
14
20
|
%i[data controller],
|
15
|
-
%i[data action]
|
21
|
+
%i[data action],
|
16
22
|
].freeze
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
refine Hash do
|
25
|
+
def merge_html(attributes)
|
26
|
+
deep_merge_html_attributes(attributes, mergeable_attributes: MERGEABLE_ATTRIBUTES)
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
class_methods do
|
31
|
+
using HasHtmlAttributes
|
32
|
+
|
33
|
+
def define_html_attribute_methods(name, default: {})
|
34
|
+
define_method("default_#{name}") { default }
|
35
|
+
private("default_#{name}")
|
29
36
|
|
30
|
-
|
31
|
-
|
37
|
+
define_method(name) do
|
38
|
+
send("default_#{name}").merge_html(instance_variable_get("@#{name}") || {})
|
39
|
+
end
|
32
40
|
|
33
|
-
|
41
|
+
define_method("#{name}=") do |options|
|
42
|
+
instance_variable_set("@#{name}", options.slice(:id, :aria, :class, :data).merge(options.fetch(:html, {})))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
included do
|
48
|
+
define_html_attribute_methods :html_attributes, default: {}
|
34
49
|
|
35
|
-
|
36
|
-
|
37
|
-
.deep_merge_html_attributes(@html_attributes, mergeable_attributes: DEFAULT_MERGEABLE_ATTRIBUTES)
|
50
|
+
# Backwards compatibility with tables 1.0
|
51
|
+
alias_method :options, :html_attributes=
|
38
52
|
end
|
39
53
|
|
40
|
-
def
|
41
|
-
|
54
|
+
def initialize(**options)
|
55
|
+
super(**options.except(:id, :aria, :class, :data, :html))
|
56
|
+
|
57
|
+
self.html_attributes = options
|
42
58
|
end
|
43
59
|
end
|
44
60
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
# Adds drag and drop ordering to a table.
|
6
|
+
# See [documentation](/docs/orderable.md) for more details.
|
7
|
+
module Orderable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
FORM_CONTROLLER = "tables--orderable--form"
|
11
|
+
ITEM_CONTROLLER = "tables--orderable--item"
|
12
|
+
LIST_CONTROLLER = "tables--orderable--list"
|
13
|
+
|
14
|
+
using HasHtmlAttributes
|
15
|
+
|
16
|
+
# Enhance a given table component class with orderable support.
|
17
|
+
# Supports extension via `included` and `extended` hooks.
|
18
|
+
def self.make_orderable(table_class)
|
19
|
+
# Add `orderable` columns to row components
|
20
|
+
table_class.header_row_component.include(HeaderRow)
|
21
|
+
table_class.body_row_component.include(BodyRow)
|
22
|
+
|
23
|
+
# Add `orderable` slot to table component
|
24
|
+
table_class.config_component :orderable, default: "FormComponent"
|
25
|
+
table_class.renders_one(:orderable, lambda do |**attrs|
|
26
|
+
orderable_component.new(table: self, **attrs)
|
27
|
+
end)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Support for inclusion in a table component class
|
31
|
+
included do
|
32
|
+
Orderable.make_orderable(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Support for extending a table component instance
|
36
|
+
def self.extended(table)
|
37
|
+
Orderable.make_orderable(table.class)
|
38
|
+
end
|
39
|
+
|
40
|
+
def tbody_attributes
|
41
|
+
return super unless orderable?
|
42
|
+
|
43
|
+
super.merge_html(
|
44
|
+
{ data: { controller: LIST_CONTROLLER,
|
45
|
+
action: <<~ACTIONS.squish,
|
46
|
+
dragstart->#{LIST_CONTROLLER}#dragstart
|
47
|
+
dragenter->#{LIST_CONTROLLER}#dragenter
|
48
|
+
dragover->#{LIST_CONTROLLER}#dragover
|
49
|
+
drop->#{LIST_CONTROLLER}#drop
|
50
|
+
ACTIONS
|
51
|
+
"#{LIST_CONTROLLER}-#{FORM_CONTROLLER}-outlet" => "##{orderable.id}",
|
52
|
+
"#{LIST_CONTROLLER}-#{ITEM_CONTROLLER}-outlet" => "td.ordinal" } },
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
module HeaderRow # :nodoc:
|
57
|
+
def ordinal(attribute = :ordinal, **)
|
58
|
+
cell(attribute, class: "ordinal", label: "")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module BodyRow # :nodoc:
|
63
|
+
def ordinal(attribute = :ordinal, id: :id)
|
64
|
+
name = @table.orderable.record_scope(@record, id, attribute)
|
65
|
+
value = @record.public_send(attribute)
|
66
|
+
cell(attribute, class: "ordinal", data: {
|
67
|
+
controller: ITEM_CONTROLLER,
|
68
|
+
"#{ITEM_CONTROLLER}-name-value" => name,
|
69
|
+
"#{ITEM_CONTROLLER}-value-value" => value,
|
70
|
+
}) { t("katalyst.tables.orderable.value") }
|
71
|
+
end
|
72
|
+
|
73
|
+
def html_attributes
|
74
|
+
super.merge_html(
|
75
|
+
{
|
76
|
+
draggable: "true",
|
77
|
+
},
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class FormComponent < ViewComponent::Base # :nodoc:
|
83
|
+
attr_reader :id, :url, :scope
|
84
|
+
|
85
|
+
def initialize(table:,
|
86
|
+
url:,
|
87
|
+
id: "#{table.id}-orderable-form",
|
88
|
+
scope: "order[#{table.collection.model_name.plural}]")
|
89
|
+
super
|
90
|
+
|
91
|
+
@table = table
|
92
|
+
@id = id
|
93
|
+
@url = url
|
94
|
+
@scope = scope
|
95
|
+
end
|
96
|
+
|
97
|
+
def record_scope(record, id, attribute)
|
98
|
+
"#{scope}[#{record.public_send(id)}][#{attribute}]"
|
99
|
+
end
|
100
|
+
|
101
|
+
def call
|
102
|
+
form_with(id: id, url: url, method: :patch, data: { controller: FORM_CONTROLLER }) do |form|
|
103
|
+
form.button(hidden: "")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def inspect
|
108
|
+
"#<#{self.class.name} id: #{id.inspect}, url: #{url.inspect}, scope: #{scope.inspect}>"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= tag.table(**html_attributes) do %>
|
2
|
+
<%= render caption if caption? %>
|
3
|
+
<% if header? %>
|
4
|
+
<%= tag.thead(**thead_attributes) do %>
|
5
|
+
<%= header_row.render_in(view_context, &row_proc) %>
|
6
|
+
<% end %>
|
7
|
+
<% end %>
|
8
|
+
<%= tag.tbody(**tbody_attributes) do %>
|
9
|
+
<% collection.each do |record| %>
|
10
|
+
<%= body_row(record).render_in(view_context) { |r| row_proc.call(r, record) } %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
@@ -54,43 +54,24 @@ module Katalyst
|
|
54
54
|
super(**html_attributes)
|
55
55
|
end
|
56
56
|
|
57
|
-
def
|
58
|
-
|
59
|
-
concat(caption)
|
60
|
-
concat(thead)
|
61
|
-
concat(tbody)
|
62
|
-
end
|
57
|
+
def caption?
|
58
|
+
@caption.present?
|
63
59
|
end
|
64
60
|
|
65
61
|
def caption
|
66
|
-
caption_component&.new(self)
|
62
|
+
caption_component&.new(self)
|
67
63
|
end
|
68
64
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
tag.thead do
|
73
|
-
concat(render_header)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def tbody
|
78
|
-
tag.tbody do
|
79
|
-
collection.each do |record|
|
80
|
-
concat(render_row(record))
|
81
|
-
end
|
82
|
-
end
|
65
|
+
def header?
|
66
|
+
@header.present?
|
83
67
|
end
|
84
68
|
|
85
|
-
def
|
86
|
-
|
87
|
-
header_row_component.new(self, **@header_options).render_in(view_context, &row_proc)
|
69
|
+
def header_row
|
70
|
+
header_row_component.new(self, **@header_options)
|
88
71
|
end
|
89
72
|
|
90
|
-
def
|
91
|
-
body_row_component.new(self, record)
|
92
|
-
row_proc.call(row, record)
|
93
|
-
end
|
73
|
+
def body_row(record)
|
74
|
+
body_row_component.new(self, record)
|
94
75
|
end
|
95
76
|
|
96
77
|
def sorting
|
@@ -98,5 +79,12 @@ module Katalyst
|
|
98
79
|
|
99
80
|
collection.sorting if collection.respond_to?(:sorting)
|
100
81
|
end
|
82
|
+
|
83
|
+
def inspect
|
84
|
+
"#<#{self.class.name} collection: #{collection.inspect}>"
|
85
|
+
end
|
86
|
+
|
87
|
+
define_html_attribute_methods(:thead_attributes)
|
88
|
+
define_html_attribute_methods(:tbody_attributes)
|
101
89
|
end
|
102
90
|
end
|
@@ -46,9 +46,13 @@ module Katalyst
|
|
46
46
|
@attribute.to_s.humanize.capitalize
|
47
47
|
end
|
48
48
|
|
49
|
+
def inspect
|
50
|
+
"#<#{self.class.name} attribute: #{@attribute.inspect}, value: #{value.inspect}>"
|
51
|
+
end
|
52
|
+
|
49
53
|
private
|
50
54
|
|
51
|
-
def
|
55
|
+
def default_html_attributes
|
52
56
|
return {} unless sorting&.supports?(collection, @attribute)
|
53
57
|
|
54
58
|
{ data: { sort: sorting.status(@attribute) } }
|
@@ -23,13 +23,13 @@ module Katalyst
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
def
|
26
|
+
def default_html_attributes
|
27
27
|
{
|
28
28
|
data: {
|
29
|
-
controller:
|
30
|
-
tables__turbo_collection_url_value:
|
31
|
-
tables__turbo_collection_sort_value: collection.sort
|
32
|
-
}
|
29
|
+
controller: "tables--turbo-collection",
|
30
|
+
tables__turbo_collection_url_value: current_path,
|
31
|
+
tables__turbo_collection_sort_value: collection.sort,
|
32
|
+
},
|
33
33
|
}
|
34
34
|
end
|
35
35
|
|
@@ -22,9 +22,9 @@ module Katalyst
|
|
22
22
|
column, direction = params[:sort]&.split(" ")
|
23
23
|
direction = "asc" unless SortForm::DIRECTIONS.include?(direction)
|
24
24
|
|
25
|
-
SortForm.new(column:
|
25
|
+
SortForm.new(column: column,
|
26
26
|
direction: direction)
|
27
|
-
|
27
|
+
.apply(collection)
|
28
28
|
end
|
29
29
|
|
30
30
|
def self_referred?
|
data/lib/katalyst/tables.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative "tables/engine"
|
|
7
7
|
require_relative "tables/frontend"
|
8
8
|
require_relative "tables/version"
|
9
9
|
|
10
|
-
require_relative "tables/engine" if Object.const_defined?(
|
10
|
+
require_relative "tables/engine" if Object.const_defined?(:Rails)
|
11
11
|
|
12
12
|
module Katalyst
|
13
13
|
module Tables
|
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: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katalyst Interactive
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: html-attributes-utils
|
@@ -50,12 +50,17 @@ files:
|
|
50
50
|
- LICENSE.txt
|
51
51
|
- README.md
|
52
52
|
- app/assets/config/katalyst-tables.js
|
53
|
+
- app/assets/javascripts/controllers/tables/orderable/form_controller.js
|
54
|
+
- app/assets/javascripts/controllers/tables/orderable/item_controller.js
|
55
|
+
- app/assets/javascripts/controllers/tables/orderable/list_controller.js
|
53
56
|
- app/assets/javascripts/controllers/tables/turbo_collection_controller.js
|
54
57
|
- app/components/concerns/katalyst/tables/configurable_component.rb
|
55
58
|
- app/components/concerns/katalyst/tables/has_html_attributes.rb
|
56
59
|
- app/components/concerns/katalyst/tables/has_table_content.rb
|
60
|
+
- app/components/concerns/katalyst/tables/orderable.rb
|
57
61
|
- app/components/concerns/katalyst/tables/sortable.rb
|
58
62
|
- app/components/concerns/katalyst/tables/turbo_replaceable.rb
|
63
|
+
- app/components/katalyst/table_component.html.erb
|
59
64
|
- app/components/katalyst/table_component.rb
|
60
65
|
- app/components/katalyst/tables/body_cell_component.rb
|
61
66
|
- app/components/katalyst/tables/body_row_component.rb
|
@@ -72,6 +77,7 @@ files:
|
|
72
77
|
- app/models/concerns/katalyst/tables/collection/sorting.rb
|
73
78
|
- app/models/katalyst/tables/collection.rb
|
74
79
|
- config/importmap.rb
|
80
|
+
- config/locales/tables.en.yml
|
75
81
|
- lib/katalyst/tables.rb
|
76
82
|
- lib/katalyst/tables/backend.rb
|
77
83
|
- lib/katalyst/tables/backend/sort_form.rb
|