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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -2
- data/README.md +56 -190
- 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/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 -75
- 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 +271 -53
- data/app/components/katalyst/tables/body_row_component.html.erb +5 -0
- data/app/components/katalyst/tables/body_row_component.rb +4 -31
- data/app/components/katalyst/tables/cell_component.rb +85 -0
- data/app/components/katalyst/tables/{body → cells}/boolean_component.rb +8 -2
- data/app/components/katalyst/tables/{body → cells}/currency_component.rb +7 -7
- data/app/components/katalyst/tables/{body → cells}/date_component.rb +12 -9
- data/app/components/katalyst/tables/{body → cells}/date_time_component.rb +13 -10
- data/app/components/katalyst/tables/{body → cells}/number_component.rb +5 -5
- data/app/components/katalyst/tables/cells/ordinal_component.rb +44 -0
- data/app/components/katalyst/tables/{body → cells}/rich_text_component.rb +8 -5
- 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/header_row_component.html.erb +5 -0
- data/app/components/katalyst/tables/header_row_component.rb +4 -25
- 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 +3 -3
- 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/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/config/locales/tables.en.yml +0 -6
- data/lib/katalyst/tables/config.rb +23 -0
- data/lib/katalyst/tables.rb +9 -0
- metadata +22 -29
- data/app/components/concerns/katalyst/tables/body/typed_columns.rb +0 -132
- data/app/components/concerns/katalyst/tables/configurable_component.rb +0 -52
- data/app/components/concerns/katalyst/tables/header/typed_columns.rb +0 -179
- data/app/components/katalyst/tables/body/attachment_component.rb +0 -58
- data/app/components/katalyst/tables/body/link_component.rb +0 -40
- data/app/components/katalyst/tables/body_cell_component.rb +0 -55
- data/app/components/katalyst/tables/header/attachment_component.rb +0 -15
- data/app/components/katalyst/tables/header/boolean_component.rb +0 -15
- data/app/components/katalyst/tables/header/currency_component.rb +0 -15
- data/app/components/katalyst/tables/header/date_component.rb +0 -15
- data/app/components/katalyst/tables/header/date_time_component.rb +0 -15
- data/app/components/katalyst/tables/header/link_component.rb +0 -15
- data/app/components/katalyst/tables/header/number_component.rb +0 -15
- data/app/components/katalyst/tables/header/rich_text_component.rb +0 -15
- data/app/components/katalyst/tables/header_cell_component.rb +0 -97
- 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 -120
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
-
|
5
3
|
module Katalyst
|
6
4
|
module Tables
|
7
|
-
module
|
5
|
+
module Cells
|
8
6
|
# Formats the value as a number
|
9
7
|
#
|
10
8
|
# Adds a class to the cell to allow for custom styling
|
11
|
-
class NumberComponent <
|
9
|
+
class NumberComponent < CellComponent
|
12
10
|
def rendered_value
|
13
11
|
value.present? ? number_to_human(value) : ""
|
14
12
|
end
|
15
13
|
|
14
|
+
private
|
15
|
+
|
16
16
|
def default_html_attributes
|
17
|
-
|
17
|
+
{ class: "type-number" }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
module Cells
|
6
|
+
class OrdinalComponent < CellComponent
|
7
|
+
def initialize(primary_key:, **)
|
8
|
+
super(**)
|
9
|
+
|
10
|
+
@primary_key = primary_key
|
11
|
+
end
|
12
|
+
|
13
|
+
def rendered_value
|
14
|
+
t("katalyst.tables.orderable.value")
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def default_html_attributes
|
20
|
+
if @row.header?
|
21
|
+
{ class: "ordinal" }
|
22
|
+
else
|
23
|
+
{
|
24
|
+
class: "ordinal",
|
25
|
+
data: {
|
26
|
+
controller: Orderable::ITEM_CONTROLLER,
|
27
|
+
"#{Orderable::ITEM_CONTROLLER}-params-value": params.to_json,
|
28
|
+
},
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def params
|
34
|
+
{
|
35
|
+
id_name: @primary_key,
|
36
|
+
id_value: record.public_send(@primary_key),
|
37
|
+
index_name: column,
|
38
|
+
index_value: record.public_send(column),
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,16 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
using Katalyst::HtmlAttributes::HasHtmlAttributes
|
4
|
-
|
5
3
|
module Katalyst
|
6
4
|
module Tables
|
7
|
-
module
|
5
|
+
module Cells
|
8
6
|
# Displays the plain text for rich text content
|
9
7
|
#
|
10
8
|
# Adds a title attribute to allow for hover over display of the full content
|
11
|
-
class RichTextComponent <
|
9
|
+
class RichTextComponent < CellComponent
|
10
|
+
private
|
11
|
+
|
12
12
|
def default_html_attributes
|
13
|
-
{
|
13
|
+
{
|
14
|
+
class: "type-rich-text",
|
15
|
+
title: (value.to_plain_text unless row.header?),
|
16
|
+
}
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
module Cells
|
6
|
+
class SelectComponent < CellComponent
|
7
|
+
def initialize(params:, form_id:, **)
|
8
|
+
super(**)
|
9
|
+
|
10
|
+
@params = params
|
11
|
+
@form_id = form_id
|
12
|
+
end
|
13
|
+
|
14
|
+
def rendered_value
|
15
|
+
tag.input(type: :checkbox)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def default_html_attributes
|
21
|
+
if @row.header?
|
22
|
+
{ class: "selection" }
|
23
|
+
else
|
24
|
+
{
|
25
|
+
class: "selection",
|
26
|
+
data: {
|
27
|
+
controller: Selectable::ITEM_CONTROLLER,
|
28
|
+
"#{Selectable::ITEM_CONTROLLER}-params-value" => @params.to_json,
|
29
|
+
"#{Selectable::ITEM_CONTROLLER}-#{Selectable::FORM_CONTROLLER}-outlet" => "##{@form_id}",
|
30
|
+
action: "change->#{Selectable::ITEM_CONTROLLER}#change",
|
31
|
+
turbo_permanent: "",
|
32
|
+
},
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
class Data
|
6
|
+
def initialize(record:, column:)
|
7
|
+
@record = record
|
8
|
+
@column = column
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
return @value if defined?(@value)
|
13
|
+
|
14
|
+
@value = @record&.public_send(@column)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
ActionView::OutputBuffer.new.tap do |output|
|
19
|
+
output << value.to_s
|
20
|
+
end.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
alias to_s call
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
"#<#{self.class.name} column: #{@column.inspect}, value: #{value.inspect}>"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -4,29 +4,11 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
class HeaderRowComponent < ViewComponent::Base # :nodoc:
|
6
6
|
include Katalyst::HtmlAttributes
|
7
|
-
include Header::TypedColumns
|
8
7
|
|
9
|
-
renders_many :
|
8
|
+
renders_many :cells, ->(cell) { cell }
|
10
9
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
@table = table
|
15
|
-
@link_attributes = link
|
16
|
-
end
|
17
|
-
|
18
|
-
def call
|
19
|
-
content # generate content before rendering
|
20
|
-
|
21
|
-
tag.tr(**html_attributes) do
|
22
|
-
columns.each do |column|
|
23
|
-
concat(column.to_s)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def cell(attribute, **, &)
|
29
|
-
with_column(@table.header_cell_component.new(@table, attribute, link: @link_attributes, **), &)
|
10
|
+
def before_render
|
11
|
+
content # ensure content is rendered so html_attributes can be set
|
30
12
|
end
|
31
13
|
|
32
14
|
def header?
|
@@ -38,11 +20,8 @@ module Katalyst
|
|
38
20
|
end
|
39
21
|
|
40
22
|
def inspect
|
41
|
-
"#<#{self.class.name}
|
23
|
+
"#<#{self.class.name}>"
|
42
24
|
end
|
43
|
-
|
44
|
-
# Backwards compatibility with tables 1.0
|
45
|
-
alias_method :options, :html_attributes=
|
46
25
|
end
|
47
26
|
end
|
48
27
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
class Label
|
6
|
+
def initialize(collection:, column:, label: nil)
|
7
|
+
@collection = collection
|
8
|
+
@column = column
|
9
|
+
@label = label
|
10
|
+
end
|
11
|
+
|
12
|
+
def value
|
13
|
+
return @value if defined?(@value)
|
14
|
+
|
15
|
+
@value = if !@label.nil?
|
16
|
+
@label
|
17
|
+
elsif @collection.model.present?
|
18
|
+
@collection.model.human_attribute_name(@column)
|
19
|
+
else
|
20
|
+
@column.to_s.humanize.capitalize
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def call
|
25
|
+
ActionView::OutputBuffer.new.tap do |output|
|
26
|
+
output << value.to_s
|
27
|
+
end.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
alias to_s call
|
31
|
+
|
32
|
+
def inspect
|
33
|
+
"#<#{self.class.name} column: #{@column.inspect} value: #{value.inspect}>"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Tables
|
5
|
+
module Orderable
|
6
|
+
class FormComponent < ViewComponent::Base # :nodoc:
|
7
|
+
include Katalyst::Tables::Identifiable::Defaults
|
8
|
+
|
9
|
+
attr_reader :id, :url
|
10
|
+
|
11
|
+
# @param collection [Katalyst::Tables::Collection::Core] the collection to render
|
12
|
+
# @param url [String] the url to submit the form to (e.g. <resources>_order_path)
|
13
|
+
# @param id [String] the id of the form element (defaults to <resources>_order_form)
|
14
|
+
# @param scope [String] the base scope to use for form inputs (defaults to order[<resources>])
|
15
|
+
def initialize(collection:, url:, id: nil, scope: nil)
|
16
|
+
super
|
17
|
+
|
18
|
+
@id = id || Orderable.default_form_id(collection)
|
19
|
+
@url = url
|
20
|
+
@scope = scope || Orderable.default_scope(collection)
|
21
|
+
end
|
22
|
+
|
23
|
+
def call
|
24
|
+
form_with(id:, url:, method: :patch, data: {
|
25
|
+
controller: FORM_CONTROLLER,
|
26
|
+
"#{FORM_CONTROLLER}-scope-value": @scope,
|
27
|
+
}) do |form|
|
28
|
+
form.button(hidden: "")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def inspect
|
33
|
+
"#<#{self.class.name} id: #{id.inspect}, url: #{url.inspect}>"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -4,11 +4,11 @@
|
|
4
4
|
data: { controller: form_controller,
|
5
5
|
turbo_action: "replace",
|
6
6
|
turbo_permanent: "" },
|
7
|
-
html: { hidden: "" }) do |form| %>
|
7
|
+
html: { action: false, hidden: "" }) do |form| %>
|
8
8
|
<p class="tables--selection--summary">
|
9
9
|
<span data-<%= form_target("count") %>>0</span>
|
10
|
-
<span data-<%= form_target("singular") %> hidden><%= @
|
11
|
-
<span data-<%= form_target("plural") %>><%= @
|
10
|
+
<span data-<%= form_target("singular") %> hidden><%= @collection.model_name.singular %></span>
|
11
|
+
<span data-<%= form_target("plural") %>><%= @collection.model_name.plural %></span>
|
12
12
|
selected
|
13
13
|
</p>
|
14
14
|
<%= content %>
|
@@ -4,24 +4,21 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
module Selectable
|
6
6
|
class FormComponent < ViewComponent::Base # :nodoc:
|
7
|
+
include Katalyst::Tables::Identifiable::Defaults
|
8
|
+
|
7
9
|
attr_reader :id, :primary_key
|
8
10
|
|
9
|
-
|
11
|
+
# @param collection [Katalyst::Tables::Collection::Core] the collection to render
|
12
|
+
# @param id [String] the id of the form element (defaults to <resources>_selection_form)
|
13
|
+
# @param primary_key [String] the primary key of the record in the collection (defaults to :id)
|
14
|
+
def initialize(collection:,
|
10
15
|
id: nil,
|
11
16
|
primary_key: :id)
|
12
17
|
super
|
13
18
|
|
14
|
-
@
|
15
|
-
@id = id
|
19
|
+
@collection = collection
|
20
|
+
@id = id || Selectable.default_form_id(collection)
|
16
21
|
@primary_key = primary_key
|
17
|
-
|
18
|
-
if @id.nil?
|
19
|
-
table_id = table.try(:id)
|
20
|
-
|
21
|
-
raise ArgumentError, "Table selection requires an id" if table_id.nil?
|
22
|
-
|
23
|
-
@id = "#{table_id}_selection"
|
24
|
-
end
|
25
22
|
end
|
26
23
|
|
27
24
|
def inspect
|
@@ -2,35 +2,10 @@
|
|
2
2
|
|
3
3
|
module Katalyst
|
4
4
|
module Tables
|
5
|
-
#
|
6
|
-
# in a table view using Katalyst::Tables::Frontend.
|
7
|
-
#
|
8
|
-
# Provides `table_sort` for sorting based on column interactions (sort param).
|
5
|
+
# Configuration for controllers to specify which TableComponent should be used in associated views.
|
9
6
|
module Backend
|
10
7
|
extend ActiveSupport::Concern
|
11
8
|
|
12
|
-
# @deprecated backwards compatibility
|
13
|
-
class SortForm < Katalyst::Tables::Collection::SortForm
|
14
|
-
end
|
15
|
-
|
16
|
-
# Sort the given collection by params[:sort], which is set when a user
|
17
|
-
# interacts with a column header in a frontend table view.
|
18
|
-
#
|
19
|
-
# @return [[SortForm, ActiveRecord::Relation]]
|
20
|
-
def table_sort(collection)
|
21
|
-
column, direction = params[:sort]&.split
|
22
|
-
direction = "asc" unless SortForm::DIRECTIONS.include?(direction)
|
23
|
-
|
24
|
-
SortForm.new(column:,
|
25
|
-
direction:)
|
26
|
-
.apply(collection)
|
27
|
-
end
|
28
|
-
|
29
|
-
def self_referred?
|
30
|
-
request.referer.present? && URI.parse(request.referer).path == request.path
|
31
|
-
end
|
32
|
-
alias self_refered? self_referred?
|
33
|
-
|
34
9
|
included do
|
35
10
|
class_attribute :_default_table_component, instance_accessor: false
|
36
11
|
end
|
@@ -39,8 +14,7 @@ module Katalyst
|
|
39
14
|
# Set the table component to be used as the default for all tables
|
40
15
|
# in the views rendered by this controller and its subclasses.
|
41
16
|
#
|
42
|
-
#
|
43
|
-
# * <tt>component</tt> - Default table component, an instance of +Katalyst::TableComponent+
|
17
|
+
# @param component [Class] the table component class to use
|
44
18
|
def default_table_component(component)
|
45
19
|
self._default_table_component = component
|
46
20
|
end
|
@@ -4,9 +4,55 @@ module Katalyst
|
|
4
4
|
module Tables
|
5
5
|
# View Helper for generating HTML tables. Include in your ApplicationHelper, or similar.
|
6
6
|
module Frontend
|
7
|
-
|
7
|
+
# Construct a new table component. This entry point supports a large number
|
8
|
+
# of options for customizing the table. The most common options are:
|
9
|
+
# @param collection [Katalyst::Tables::Collection::Core] the collection to render
|
10
|
+
# @param header [Boolean] whether to render the header row (defaults to true, supports options)
|
11
|
+
# @param caption [Boolean Hash] whether to render the caption (defaults to true, supports options)
|
12
|
+
# @param generate_ids [Boolean] whether to generate dom ids for the table and rows
|
13
|
+
#
|
14
|
+
# Blocks will receive the table in row-rendering mode (with row and record defined):
|
15
|
+
# @yieldparam [Katalyst::TableComponent] the row component to render
|
16
|
+
# @yieldparam [Object, nil] the object to render, or nil for header rows
|
17
|
+
#
|
18
|
+
# If no block is provided when the table is rendered then the table will look for a row partial:
|
19
|
+
# @param object_name [Symbol] the name of the object to use for partial rendering
|
20
|
+
# (defaults to collection.model_name.i18n_key)
|
21
|
+
# @param partial [String] the name of the partial to use for rendering each row
|
22
|
+
# (defaults to to_partial_path on the object)
|
23
|
+
# @param as [Symbol] the name of the local variable to use for rendering each row
|
24
|
+
# (defaults to collection.model_name.param_key)
|
25
|
+
#
|
26
|
+
# In addition to these options, standard HTML attributes can be passed which will be added to the table tag.
|
27
|
+
def table_with(collection:,
|
28
|
+
component: nil,
|
29
|
+
header: true,
|
30
|
+
caption: true,
|
31
|
+
generate_ids: false,
|
32
|
+
object_name: nil,
|
33
|
+
partial: nil,
|
34
|
+
as: nil,
|
35
|
+
**,
|
36
|
+
&)
|
8
37
|
component ||= default_table_component_class
|
9
|
-
|
38
|
+
component = component.new(collection:, header:, caption:, generate_ids:, object_name:, partial:, as:, **)
|
39
|
+
|
40
|
+
render(component, &)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param collection [Katalyst::Tables::Collection::Core] the collection to render
|
44
|
+
# @param url [String] the url to submit the form to (e.g. <resources>_order_path)
|
45
|
+
# @param id [String] the id of the form element (defaults to <resources>_order_form)
|
46
|
+
# @param scope [String] the base scope to use for form inputs (defaults to order[<resources>])
|
47
|
+
def table_orderable_with(collection:, url:, id: nil, scope: nil, &)
|
48
|
+
render(Orderable::FormComponent.new(collection:, url:, id:, scope:))
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param collection [Katalyst::Tables::Collection::Core] the collection to render
|
52
|
+
# @param id [String] the id of the form element (defaults to <resources>_selection_form)
|
53
|
+
# @param primary_key [String] the primary key of the record in the collection (defaults to :id)
|
54
|
+
def table_selection_with(collection:, id: nil, primary_key: :id, &)
|
55
|
+
render(Selectable::FormComponent.new(collection:, id:, primary_key:), &)
|
10
56
|
end
|
11
57
|
|
12
58
|
private
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import TurboCollectionController from "./turbo/collection_controller";
|
2
1
|
import OrderableItemController from "./orderable/item_controller";
|
3
2
|
import OrderableListController from "./orderable/list_controller";
|
4
3
|
import OrderableFormController from "./orderable/form_controller";
|
@@ -6,10 +5,6 @@ import SelectionFormController from "./selection/form_controller";
|
|
6
5
|
import SelectionItemController from "./selection/item_controller";
|
7
6
|
|
8
7
|
const Definitions = [
|
9
|
-
{
|
10
|
-
identifier: "tables--turbo--collection",
|
11
|
-
controllerConstructor: TurboCollectionController,
|
12
|
-
},
|
13
8
|
{
|
14
9
|
identifier: "tables--orderable--item",
|
15
10
|
controllerConstructor: OrderableItemController,
|
@@ -1,13 +1,15 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
3
|
export default class OrderableFormController extends Controller {
|
4
|
+
static values = { scope: String };
|
5
|
+
|
4
6
|
add(item) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
);
|
7
|
+
item.params(this.scopeValue).forEach(({ name, value }) => {
|
8
|
+
this.element.insertAdjacentHTML(
|
9
|
+
"beforeend",
|
10
|
+
`<input type="hidden" name="${name}" value="${value}" data-generated>`,
|
11
|
+
);
|
12
|
+
});
|
11
13
|
}
|
12
14
|
|
13
15
|
submit() {
|
@@ -48,6 +48,15 @@ export default class OrderableRowController extends Controller {
|
|
48
48
|
this.index = index;
|
49
49
|
}
|
50
50
|
|
51
|
+
/** Retrieve params for use in the form */
|
52
|
+
params(scope) {
|
53
|
+
const { id_name, id_value, index_name } = this.paramsValue;
|
54
|
+
return [
|
55
|
+
{ name: `${scope}[${id_value}][${id_name}]`, value: this.id },
|
56
|
+
{ name: `${scope}[${id_value}][${index_name}]`, value: this.index },
|
57
|
+
];
|
58
|
+
}
|
59
|
+
|
51
60
|
/**
|
52
61
|
* Restore any visual changes made during drag and remove the drag state.
|
53
62
|
*/
|
@@ -18,7 +18,7 @@ module Katalyst
|
|
18
18
|
def permitted_params
|
19
19
|
_default_attributes.to_h.each_with_object([]) do |(k, v), h|
|
20
20
|
h << case v
|
21
|
-
when Array
|
21
|
+
when ::Array
|
22
22
|
{ k => [] }
|
23
23
|
else
|
24
24
|
k
|
@@ -39,6 +39,11 @@ module Katalyst
|
|
39
39
|
clear_changes_information
|
40
40
|
end
|
41
41
|
|
42
|
+
# Collections that do not include Sorting are never sortable.
|
43
|
+
def sortable?
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
42
47
|
def apply(items)
|
43
48
|
@items = items
|
44
49
|
reducers.build do |_|
|
@@ -14,27 +14,88 @@ module Katalyst
|
|
14
14
|
module Sorting
|
15
15
|
extend ActiveSupport::Concern
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
DIRECTIONS = %w[asc desc].freeze
|
18
|
+
|
19
|
+
module SortParams
|
20
|
+
refine Hash do
|
21
|
+
def to_param
|
22
|
+
"#{self[:column]} #{self[:direction]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
refine String do
|
27
|
+
def to_param
|
28
|
+
to_h.to_param
|
29
|
+
end
|
20
30
|
|
31
|
+
def to_h
|
32
|
+
column, direction = split(/[ +]/, 2)
|
33
|
+
|
34
|
+
direction = "asc" unless DIRECTIONS.include?(direction)
|
35
|
+
{ column:, direction: }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
using SortParams
|
41
|
+
|
42
|
+
included do
|
21
43
|
attribute :sort, :string
|
44
|
+
|
45
|
+
attr_reader :default_sort
|
22
46
|
end
|
23
47
|
|
24
48
|
def initialize(sorting: config.sorting, **options)
|
25
|
-
@
|
49
|
+
@default_sort = sorting.to_param if sorting.present?
|
50
|
+
|
51
|
+
super(sort: @default_sort, **options) # set default sort based on config
|
52
|
+
end
|
26
53
|
|
27
|
-
|
54
|
+
def default_sort?
|
55
|
+
sort == @default_sort
|
28
56
|
end
|
29
57
|
|
58
|
+
# Returns true if the collection supports sorting on the given column.
|
59
|
+
# A column supports sorting if it is a database column or if
|
60
|
+
# the collection responds to `order_by_#{column}(direction)`.
|
61
|
+
#
|
62
|
+
# @param column [String, Symbol]
|
63
|
+
# @return [true, false]
|
64
|
+
def sortable?(column = nil)
|
65
|
+
if column.nil?
|
66
|
+
@default_sort.present?
|
67
|
+
else
|
68
|
+
items.respond_to?(:"order_by_#{column}") || items.model.has_attribute?(column.to_s)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set the current sort behaviour of the collection.
|
73
|
+
#
|
74
|
+
# @param value [String, Hash] "column direction", or { column:, direction: }
|
30
75
|
def sort=(value)
|
31
|
-
|
76
|
+
super(value.to_param) if @default_sort
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the current sort behaviour of the given column, for use as a
|
80
|
+
# column heading class in the table view.
|
81
|
+
#
|
82
|
+
# @param column [String, Symbol] the table column as defined in table_with
|
83
|
+
# @return [String] the current sort behaviour of the given column
|
84
|
+
def sort_status(column)
|
85
|
+
current, direction = sort.to_h.values_at(:column, :direction)
|
86
|
+
direction if column.to_s == current
|
87
|
+
end
|
32
88
|
|
33
|
-
|
34
|
-
|
89
|
+
# Calculates the sort parameter to apply when the given column is toggled.
|
90
|
+
#
|
91
|
+
# @param column [String, Symbol]
|
92
|
+
# @return [String]
|
93
|
+
def toggle_sort(column)
|
94
|
+
current, direction = sort.to_h.values_at(:column, :direction)
|
35
95
|
|
36
|
-
#
|
37
|
-
|
96
|
+
return "#{column} asc" unless column.to_s == current
|
97
|
+
|
98
|
+
direction == "asc" ? "#{column} desc" : "#{column} asc"
|
38
99
|
end
|
39
100
|
|
40
101
|
class Sort # :nodoc:
|
@@ -44,15 +105,22 @@ module Katalyst
|
|
44
105
|
@app = app
|
45
106
|
end
|
46
107
|
|
108
|
+
using SortParams
|
109
|
+
|
47
110
|
def call(collection)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
111
|
+
collection = @app.call(collection)
|
112
|
+
|
113
|
+
column, direction = collection.sort.to_h.values_at(:column, :direction)
|
114
|
+
|
115
|
+
return collection if column.nil?
|
116
|
+
|
117
|
+
if collection.items.respond_to?(:"order_by_#{column}")
|
118
|
+
collection.items = collection.items.reorder(nil).public_send(:"order_by_#{column}", direction.to_sym)
|
119
|
+
elsif collection.items.model.has_attribute?(column)
|
120
|
+
collection.items = collection.items.reorder(column => direction)
|
121
|
+
end
|
52
122
|
|
53
|
-
|
54
|
-
def params
|
55
|
-
@collection.attributes
|
123
|
+
collection
|
56
124
|
end
|
57
125
|
end
|
58
126
|
end
|