katalyst-tables 2.6.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/README.md +57 -213
- data/app/assets/builds/katalyst/tables.esm.js +17 -47
- data/app/assets/builds/katalyst/tables.js +17 -47
- data/app/assets/builds/katalyst/tables.min.js +1 -1
- data/app/assets/builds/katalyst/tables.min.js.map +1 -1
- data/app/assets/stylesheets/katalyst/tables/_index.scss +1 -0
- data/app/assets/stylesheets/katalyst/tables/_ordinal.scss +38 -0
- data/app/assets/stylesheets/katalyst/tables/_table.scss +123 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_boolean.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_currency.scss +5 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_date.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_datetime.scss +4 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_index.scss +5 -0
- data/app/assets/stylesheets/katalyst/tables/typed-columns/_number.scss +5 -0
- data/app/components/concerns/katalyst/tables/has_table_content.rb +17 -8
- data/app/components/concerns/katalyst/tables/identifiable.rb +51 -0
- data/app/components/concerns/katalyst/tables/orderable.rb +35 -105
- data/app/components/concerns/katalyst/tables/selectable.rb +18 -74
- data/app/components/concerns/katalyst/tables/sortable.rb +51 -17
- data/app/components/katalyst/table_component.html.erb +4 -4
- data/app/components/katalyst/table_component.rb +277 -47
- data/app/components/katalyst/tables/body_row_component.html.erb +5 -0
- data/app/components/katalyst/tables/body_row_component.rb +4 -24
- data/app/components/katalyst/tables/cell_component.rb +85 -0
- data/app/components/katalyst/tables/cells/boolean_component.rb +20 -0
- data/app/components/katalyst/tables/cells/currency_component.rb +29 -0
- data/app/components/katalyst/tables/cells/date_component.rb +67 -0
- data/app/components/katalyst/tables/cells/date_time_component.rb +60 -0
- data/app/components/katalyst/tables/cells/number_component.rb +22 -0
- data/app/components/katalyst/tables/cells/ordinal_component.rb +44 -0
- data/app/components/katalyst/tables/cells/rich_text_component.rb +21 -0
- data/app/components/katalyst/tables/cells/select_component.rb +39 -0
- data/app/components/katalyst/tables/data.rb +30 -0
- data/app/components/katalyst/tables/empty_caption_component.rb +1 -1
- data/app/components/katalyst/tables/header_row_component.html.erb +5 -0
- data/app/components/katalyst/tables/header_row_component.rb +4 -24
- data/app/components/katalyst/tables/label.rb +37 -0
- data/app/components/katalyst/tables/orderable/form_component.rb +38 -0
- data/app/components/katalyst/tables/selectable/form_component.html.erb +6 -4
- data/app/components/katalyst/tables/selectable/form_component.rb +8 -11
- data/app/controllers/concerns/katalyst/tables/backend.rb +2 -28
- data/app/helpers/katalyst/tables/frontend.rb +48 -2
- data/app/javascript/tables/application.js +0 -5
- data/app/javascript/tables/orderable/form_controller.js +8 -6
- data/app/javascript/tables/orderable/item_controller.js +9 -0
- data/app/models/concerns/katalyst/tables/collection/core.rb +6 -1
- data/app/models/concerns/katalyst/tables/collection/pagination.rb +8 -1
- data/app/models/concerns/katalyst/tables/collection/sorting.rb +85 -17
- data/app/models/katalyst/tables/collection/array.rb +38 -0
- data/app/models/katalyst/tables/collection/base.rb +4 -0
- data/lib/katalyst/tables/config.rb +23 -0
- data/lib/katalyst/tables.rb +9 -0
- metadata +32 -15
- data/app/components/concerns/katalyst/tables/configurable_component.rb +0 -52
- data/app/components/concerns/katalyst/tables/turbo_replaceable.rb +0 -79
- data/app/components/katalyst/tables/body_cell_component.rb +0 -47
- data/app/components/katalyst/tables/header_cell_component.rb +0 -65
- data/app/components/katalyst/turbo/pagy_nav_component.rb +0 -23
- data/app/components/katalyst/turbo/table_component.rb +0 -45
- data/app/helpers/katalyst/tables/frontend/helper.rb +0 -31
- data/app/javascript/tables/turbo/collection_controller.js +0 -38
- data/app/models/katalyst/tables/collection/sort_form.rb +0 -102
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Tables
|
5
|
-
class HeaderCellComponent < ViewComponent::Base # :nodoc:
|
6
|
-
include Frontend::Helper
|
7
|
-
include Katalyst::HtmlAttributes
|
8
|
-
include Sortable
|
9
|
-
|
10
|
-
delegate :object_name, :collection, :sorting, to: :@table
|
11
|
-
|
12
|
-
def initialize(table, attribute, label: nil, link: {}, **html_attributes)
|
13
|
-
super(**html_attributes)
|
14
|
-
|
15
|
-
@table = table
|
16
|
-
@attribute = attribute
|
17
|
-
@value = label
|
18
|
-
@link_attributes = link
|
19
|
-
end
|
20
|
-
|
21
|
-
def call
|
22
|
-
tag.th(**html_attributes) do
|
23
|
-
if sortable?(@attribute)
|
24
|
-
link_to(value, sort_url(@attribute), **@link_attributes)
|
25
|
-
else
|
26
|
-
value
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def value
|
32
|
-
if !@value.nil?
|
33
|
-
@value
|
34
|
-
elsif object_name.present?
|
35
|
-
translation
|
36
|
-
else
|
37
|
-
default_value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def translation(key = "activerecord.attributes.#{object_name}.#{@attribute}")
|
42
|
-
translate(key, default: default_value)
|
43
|
-
end
|
44
|
-
|
45
|
-
def default_value
|
46
|
-
@attribute.to_s.humanize.capitalize
|
47
|
-
end
|
48
|
-
|
49
|
-
def inspect
|
50
|
-
"#<#{self.class.name} attribute: #{@attribute.inspect}, value: #{value.inspect}>"
|
51
|
-
end
|
52
|
-
|
53
|
-
# Backwards compatibility with tables 1.0
|
54
|
-
alias_method :options, :html_attributes=
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def default_html_attributes
|
59
|
-
return {} unless sorting&.supports?(collection, @attribute)
|
60
|
-
|
61
|
-
{ data: { sort: sorting.status(@attribute) } }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Turbo
|
5
|
-
class PagyNavComponent < Tables::PagyNavComponent # :nodoc:
|
6
|
-
include Tables::TurboReplaceable
|
7
|
-
|
8
|
-
def initialize(id:, **options)
|
9
|
-
super(id:, **options)
|
10
|
-
end
|
11
|
-
|
12
|
-
def id
|
13
|
-
pagy_options[:id]
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def pagy_options
|
19
|
-
super.merge(anchor_string: "data-turbo-stream")
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Turbo
|
5
|
-
# Renders a table that uses turbo stream replacement when sorting or
|
6
|
-
# paginating.
|
7
|
-
class TableComponent < ::Katalyst::TableComponent
|
8
|
-
include Tables::TurboReplaceable
|
9
|
-
|
10
|
-
attr_reader :id
|
11
|
-
|
12
|
-
def initialize(collection:, id:, header: true, **options)
|
13
|
-
header = if header.is_a?(Hash)
|
14
|
-
default_header_options.merge(header)
|
15
|
-
elsif header
|
16
|
-
default_header_options
|
17
|
-
end
|
18
|
-
|
19
|
-
@id = id
|
20
|
-
|
21
|
-
super(collection:, header:, id:, **options)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def default_html_attributes
|
27
|
-
{
|
28
|
-
data: {
|
29
|
-
controller: "tables--turbo--collection",
|
30
|
-
tables__turbo__collection_query_value: current_query,
|
31
|
-
tables__turbo__collection_sort_value: collection.sort,
|
32
|
-
},
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
def current_query
|
37
|
-
Rack::Utils.build_nested_query(collection.to_params)
|
38
|
-
end
|
39
|
-
|
40
|
-
def default_header_options
|
41
|
-
{ link: { data: { turbo_stream: "" } } }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Tables
|
5
|
-
module Frontend
|
6
|
-
# @deprecated Use {Katalyst::TableComponent} instead.
|
7
|
-
module Helper # :nodoc:
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
# Generates a url for applying/toggling sort for the given column.
|
11
|
-
#
|
12
|
-
# @param sort [String, nil] sort parameter to apply, or nil to remove sorting
|
13
|
-
# @return [String] URL for toggling column sorting
|
14
|
-
# @deprecated Use {Katalyst::TablesComponent} instead.
|
15
|
-
def sort_url_for(sort: nil, default: nil)
|
16
|
-
# Implementation inspired by pagy's `pagy_url_for` helper.
|
17
|
-
# Preserve any existing GET parameters
|
18
|
-
# CAUTION: these parameters are not sanitised
|
19
|
-
params = if sort && !sort.eql?(default)
|
20
|
-
request.GET.merge("sort" => sort).except("page")
|
21
|
-
else
|
22
|
-
request.GET.except("page", "sort")
|
23
|
-
end
|
24
|
-
query_string = params.empty? ? "" : "?#{Rack::Utils.build_nested_query(params)}"
|
25
|
-
|
26
|
-
"#{request.path}#{query_string}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
import { Controller } from "@hotwired/stimulus";
|
2
|
-
import { Turbo } from "@hotwired/turbo-rails";
|
3
|
-
|
4
|
-
export default class TurboCollectionController extends Controller {
|
5
|
-
static values = {
|
6
|
-
query: String,
|
7
|
-
sort: String,
|
8
|
-
};
|
9
|
-
|
10
|
-
queryValueChanged(query) {
|
11
|
-
Turbo.navigator.history.replace(this.#url(query));
|
12
|
-
}
|
13
|
-
|
14
|
-
sortValueChanged(sort) {
|
15
|
-
document.querySelectorAll(this.#sortSelector).forEach((input) => {
|
16
|
-
if (input) input.value = sort;
|
17
|
-
});
|
18
|
-
}
|
19
|
-
|
20
|
-
get #sortSelector() {
|
21
|
-
return "input[name='sort']";
|
22
|
-
}
|
23
|
-
|
24
|
-
#url(query) {
|
25
|
-
const frame = this.element.closest("turbo-frame");
|
26
|
-
let url;
|
27
|
-
|
28
|
-
if (frame) {
|
29
|
-
url = new URL(frame.baseURI);
|
30
|
-
} else {
|
31
|
-
url = new URL(window.location.href);
|
32
|
-
}
|
33
|
-
|
34
|
-
url.search = query;
|
35
|
-
|
36
|
-
return url;
|
37
|
-
}
|
38
|
-
}
|
@@ -1,102 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Tables
|
5
|
-
module Collection
|
6
|
-
# A FormObject (model) representing the sort state of controller for a given
|
7
|
-
# collection/parameter.
|
8
|
-
class SortForm
|
9
|
-
DIRECTIONS = %w[asc desc].freeze
|
10
|
-
|
11
|
-
attr_accessor :column, :direction, :default
|
12
|
-
|
13
|
-
def self.parse(param, default: nil)
|
14
|
-
column, direction = param.to_s.split
|
15
|
-
direction = "asc" unless DIRECTIONS.include?(direction)
|
16
|
-
|
17
|
-
default = SortForm.parse(default).to_param if default.present?
|
18
|
-
|
19
|
-
SortForm.new(column:, direction:, default:)
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize(column: nil, direction: nil, default: nil)
|
23
|
-
self.column = column
|
24
|
-
self.direction = direction
|
25
|
-
self.default = default
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_param
|
29
|
-
"#{column} #{direction}"
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns true if the given collection supports sorting on the given
|
33
|
-
# column. A column supports sorting if it is a database column or if
|
34
|
-
# the collection responds to `order_by_#{column}(direction)`.
|
35
|
-
#
|
36
|
-
# @param collection [ActiveRecord::Relation]
|
37
|
-
# @param column [String, Symbol]
|
38
|
-
# @return [true, false]
|
39
|
-
def supports?(collection, column)
|
40
|
-
scope_for(collection).respond_to?(:"order_by_#{column}") ||
|
41
|
-
model_for(collection).has_attribute?(column.to_s)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns the current sort behaviour of the given column, for use as a
|
45
|
-
# column heading class in the table view.
|
46
|
-
#
|
47
|
-
# @param column [String, Symbol] the table column as defined in table_with
|
48
|
-
# @return [String] the current sort behaviour of the given column
|
49
|
-
def status(column)
|
50
|
-
direction if column.to_s == self.column
|
51
|
-
end
|
52
|
-
|
53
|
-
# Calculates the sort parameter to apply when the given column is toggled.
|
54
|
-
#
|
55
|
-
# @param column [String, Symbol]
|
56
|
-
# @return [String]
|
57
|
-
def toggle(column)
|
58
|
-
return "#{column} asc" unless column.to_s == self.column
|
59
|
-
|
60
|
-
case direction
|
61
|
-
when "asc"
|
62
|
-
"#{column} desc"
|
63
|
-
when "desc"
|
64
|
-
"#{column} asc"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Apply the constructed sort ordering to the collection.
|
69
|
-
#
|
70
|
-
# @param collection [ActiveRecord::Relation]
|
71
|
-
# @return [Array(SortForm, ActiveRecord::Relation)]
|
72
|
-
def apply(collection)
|
73
|
-
return [self, collection] if column.nil?
|
74
|
-
|
75
|
-
if collection.respond_to?(:"order_by_#{column}")
|
76
|
-
collection = collection.reorder(nil).public_send(:"order_by_#{column}", direction.to_sym)
|
77
|
-
elsif collection.model.has_attribute?(column)
|
78
|
-
collection = collection.reorder(column => direction)
|
79
|
-
else
|
80
|
-
clear!
|
81
|
-
end
|
82
|
-
|
83
|
-
[self, collection]
|
84
|
-
end
|
85
|
-
|
86
|
-
private
|
87
|
-
|
88
|
-
def clear!
|
89
|
-
self.column = self.direction = nil
|
90
|
-
end
|
91
|
-
|
92
|
-
def scope_for(collection)
|
93
|
-
collection.is_a?(Core) ? collection.items : collection
|
94
|
-
end
|
95
|
-
|
96
|
-
def model_for(collection)
|
97
|
-
scope_for(collection).model
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|