plutonium 0.15.4 → 0.15.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +1 -1
  3. data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
  4. data/app/views/resource/_resource_table.html.erb +0 -321
  5. data/lib/plutonium/definition/base.rb +8 -0
  6. data/lib/plutonium/definition/defineable_props.rb +1 -1
  7. data/lib/plutonium/definition/presentable.rb +71 -0
  8. data/lib/plutonium/interaction/README.md +1 -1
  9. data/lib/plutonium/interaction/base.rb +6 -6
  10. data/lib/plutonium/lib/deep_freezer.rb +31 -0
  11. data/lib/plutonium/query/adhoc_block.rb +19 -0
  12. data/lib/plutonium/query/base.rb +29 -0
  13. data/lib/plutonium/query/filter.rb +12 -0
  14. data/lib/plutonium/query/filters/text.rb +77 -0
  15. data/lib/plutonium/query/model_scope.rb +19 -0
  16. data/lib/plutonium/resource/controller.rb +0 -3
  17. data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
  18. data/lib/plutonium/resource/controllers/crud_actions.rb +2 -5
  19. data/lib/plutonium/resource/controllers/defineable.rb +0 -2
  20. data/lib/plutonium/resource/controllers/queryable.rb +36 -20
  21. data/lib/plutonium/resource/policy.rb +1 -1
  22. data/lib/plutonium/resource/query_object.rb +61 -147
  23. data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
  24. data/lib/plutonium/ui/component/methods.rb +1 -1
  25. data/lib/plutonium/ui/display/resource.rb +19 -15
  26. data/lib/plutonium/ui/form/query.rb +171 -0
  27. data/lib/plutonium/ui/form/resource.rb +21 -17
  28. data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
  29. data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
  30. data/lib/plutonium/ui/table/resource.rb +10 -9
  31. data/lib/plutonium/version.rb +1 -1
  32. data/package-lock.json +2 -2
  33. data/package.json +1 -1
  34. metadata +12 -4
  35. data/lib/plutonium/interaction/concerns/presentable.rb +0 -73
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Plutonium
4
+ module UI
5
+ module Form
6
+ class Query < Base
7
+ attr_reader :query_object
8
+
9
+ def initialize(*, query_object:, page_size:, attributes: {}, **options, &)
10
+ options[:as] = :q
11
+ options[:method] = :get
12
+ attributes.deep_merge!(
13
+ id: :search_form,
14
+ class!: "space-y-2 mb-4",
15
+ controller: "form",
16
+ data: {controller: "form", turbo_frame: nil}
17
+ )
18
+ super(*, attributes:, **options, &)
19
+
20
+ @query_object = query_object
21
+ @page_size = page_size
22
+ end
23
+
24
+ def form_template
25
+ render_fields
26
+ end
27
+
28
+ private
29
+
30
+ def render_fields
31
+ render_search_fields
32
+ render_filter_fields
33
+ div hidden: true do # workaround the fact that input array does not accept other attributes for now
34
+ input(name: "limit", value: @page_size, type: :hidden, hidden: true) if @page_size
35
+ render_sort_fields
36
+ render_scope_fields
37
+ end
38
+ end
39
+
40
+ def render_sort_fields
41
+ # q[sort_fields][]=name&q[sort_fields][]=created_at
42
+ field :sort_fields do |name|
43
+ render name.input_array_tag do |array|
44
+ render array.input_tag(type: :hidden, hidden: true)
45
+ end
46
+ end
47
+ # q[sort_directions][created_at]=ASC&q[sort_directions][name]=ASC&
48
+ nest_one :sort_directions do |nested|
49
+ query_object.sort_definitions.each do |filter_name, definition|
50
+ nested.field(filter_name) do |f|
51
+ render f.input_tag(type: :hidden, hidden: true)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def render_scope_fields
58
+ # q[scope]=&
59
+ return if query_object.scope_definitions.blank?
60
+
61
+ render field(:scope).input_tag(type: :hidden, hidden: true)
62
+ end
63
+
64
+ def render_search_fields
65
+ # q[search]=&
66
+ return unless query_object.search_filter
67
+
68
+ search_query = query_object.search_query
69
+ div(class: "relative") do
70
+ div(class: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none") do
71
+ svg(
72
+ class: "w-5 h-5 text-gray-500 dark:text-gray-400",
73
+ aria_hidden: "true",
74
+ fill: "currentColor",
75
+ viewbox: "0 0 20 20",
76
+ xmlns: "http://www.w3.org/2000/svg"
77
+ ) do |s|
78
+ s.path(
79
+ fill_rule: "evenodd",
80
+ d:
81
+ "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
82
+ clip_rule: "evenodd"
83
+ )
84
+ end
85
+ end
86
+ render field(:search, value: search_query)
87
+ .placeholder("Search...")
88
+ .input_tag(
89
+ value: search_query,
90
+ class: "block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500",
91
+ data: {
92
+ action: "form#submit",
93
+ turbo_permanent: true
94
+ }
95
+ )
96
+ end
97
+ end
98
+
99
+ def render_filter_fields
100
+ div(class: "flex flex-wrap items-center gap-4") do
101
+ span(class: "text-sm font-medium text-gray-900 dark:text-white") { "Filters:" }
102
+ div(class: "flex flex-wrap items-center gap-4 mr-auto") do
103
+ div class: "flex flex-wrap items-center gap-4" do
104
+ query_object.filter_definitions.each do |filter_name, definition|
105
+ nest_one filter_name do |nested|
106
+ definition.defined_inputs.each do |input_name, _|
107
+ render_defined_field nested, definition, input_name
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ div(class: "flex flex-wrap items-center gap-2") do
114
+ actions_wrapper do
115
+ render field(:submit).submit_button_tag(
116
+ name: nil,
117
+ class!: "inline-flex items-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
118
+ ) do
119
+ render Phlex::TablerIcons::Filter.new(class: "w-4 h-4 mr-2")
120
+ plain "Apply Filters"
121
+ end
122
+
123
+ render field(:reset).submit_button_tag(
124
+ name: nil,
125
+ type: :reset,
126
+ class!: "inline-flex items-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-4 py-2 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
127
+ ) do
128
+ render Phlex::TablerIcons::X.new(class: "w-4 h-4 mr-2")
129
+ plain "Clear Filters"
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ def form_action
137
+ # query forms post to the same page
138
+ nil
139
+ end
140
+
141
+ def render_defined_field(nested, resource_definition, name)
142
+ # field :name, as: :string
143
+ # input :name, as: :string
144
+ # input :description, class: "col-span-full"
145
+ # input :age, tag: {class: "max-h-fit"}
146
+ # input :dob do |f|
147
+ # f.date_tag
148
+ # end
149
+
150
+ field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options] : {}
151
+
152
+ input_definition = resource_definition.defined_inputs[name] || {}
153
+ input_options = input_definition[:options] || {}
154
+
155
+ tag = field_options[:as] || input_options[:as]
156
+ tag_attributes = input_options[:tag] || {}
157
+ tag_block = input_definition[:block] || ->(f) {
158
+ tag ||= f.inferred_field_component
159
+ f.send(:"#{tag}_tag", **tag_attributes, class: tokens(tag_attributes[:class], "flex-1"))
160
+ }
161
+
162
+ field_options = field_options.except(:as)
163
+ nested.field(name, **field_options) do |f|
164
+ f.placeholder(f.label) unless f.placeholder
165
+ render tag_block.call(f)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -34,32 +34,36 @@ module Plutonium
34
34
  end
35
35
 
36
36
  def render_resource_field(name)
37
- # input :name, as: :string
38
- # input :description, class: "col-span-full"
39
- # input :age, field: {class: "max-h-fit"}
40
- # input :dob do |f|
41
- # f.date_tag
42
- # end
43
-
44
37
  when_permitted(name) do
38
+ # field :name, as: :string
39
+ # input :name, as: :string
40
+ # input :description, class: "col-span-full"
41
+ # input :age, tag: {class: "max-h-fit"}
42
+ # input :dob do |f|
43
+ # f.date_tag
44
+ # end
45
+
46
+ field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options] : {}
47
+
45
48
  input_definition = resource_definition.defined_inputs[name] || {}
46
49
  input_options = input_definition[:options] || {}
47
- input_field_as = input_options.delete(:as)
48
50
 
49
- input_field_options = input_options.delete(:field) || {}
50
- input_block = input_definition[:block] || ->(f) {
51
- input_field_as ||= f.inferred_field_component
52
- f.send(:"#{input_field_as}_tag", **input_field_options)
51
+ tag = field_options[:as] || input_options[:as]
52
+ tag_attributes = input_options[:tag] || {}
53
+ tag_block = input_definition[:block] || ->(f) {
54
+ tag ||= f.inferred_field_component
55
+ f.send(:"#{tag}_tag", **tag_attributes)
53
56
  }
54
57
 
55
- field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options] : {}
56
- if !input_options[:class] || !input_options[:class].include?("col-span")
58
+ field_options = field_options.except(:as)
59
+ wrapper_options = input_options.except(:tag, :as)
60
+ if !wrapper_options[:class] || wrapper_options[:class].include?("col-span")
57
61
  # temp hack to allow col span overrides
58
62
  # TODO: remove once we complete theming, which will support merges
59
- input_options[:class] = tokens("col-span-full", input_options[:class])
63
+ wrapper_options[:class] = tokens("col-span-full", wrapper_options[:class])
60
64
  end
61
- render field(name, **field_options).wrapped(**input_options) do |f|
62
- render input_block.call(f)
65
+ render field(name, **field_options).wrapped(**wrapper_options) do |f|
66
+ render tag_block.call(f)
63
67
  end
64
68
  end
65
69
  end
@@ -124,7 +124,7 @@ module Plutonium
124
124
 
125
125
  private
126
126
 
127
- def current_scope = resource_query_params[:scope]
127
+ def current_scope = raw_resource_query_params[:scope]
128
128
 
129
129
  def render?
130
130
  current_query_object.scope_definitions.present?
@@ -6,150 +6,17 @@ module Plutonium
6
6
  module Components
7
7
  class SearchBar < Plutonium::UI::Component::Base
8
8
  def view_template
9
- original_attributes = Phlex::HTML::EVENT_ATTRIBUTES
10
- temp_attributes = Phlex::HTML::EVENT_ATTRIBUTES.dup
11
- temp_attributes.delete("oninput")
12
- temp_attributes.delete("onclick")
13
- Phlex::HTML.const_set(:EVENT_ATTRIBUTES, temp_attributes)
14
-
15
- div(
16
- class:
17
- # "p-4 bg-white border border-gray-200 rounded-lg dark:bg-gray-800 dark:border-gray-700 space-y-2 mb-4"
18
- "space-y-2 mb-4"
19
- ) do
20
- search_query = current_query_object.search_query
21
- query_params = resource_query_params
22
- render Phlexi::Form(:q, attributes: {class!: nil, data: {controller: "form", turbo_frame: nil}}) {
23
- div(class: "relative") do
24
- div(class: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none") do
25
- svg(
26
- class: "w-5 h-5 text-gray-500 dark:text-gray-400",
27
- aria_hidden: "true",
28
- fill: "currentColor",
29
- viewbox: "0 0 20 20",
30
- xmlns: "http://www.w3.org/2000/svg"
31
- ) do |s|
32
- s.path(
33
- fill_rule: "evenodd",
34
- d:
35
- "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
36
- clip_rule: "evenodd"
37
- )
38
- end
39
- end
40
- render field(:search, value: search_query)
41
- .placeholder("Search...")
42
- .input_tag(
43
- id: "search",
44
- value: search_query,
45
- class: "block w-full p-2 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500",
46
- data: {
47
- action: "form#submit",
48
- turbo_permanent: true
49
- }
50
- )
51
-
52
- render field(:scope, value: query_params[:scope]).input_tag(type: :hidden)
53
- render field(:sort_fields, value: query_params[:sort_fields]).input_array_tag do |f|
54
- render f.input_tag(type: :hidden)
55
- end
56
- nest_one(:sort_directions) do |directions|
57
- query_params[:sort_directions]&.each do |name, value|
58
- render directions.field(name, value:).input_tag(hidden: true)
59
- end
60
- end
61
- end
62
- }
63
-
64
- # div(class: "flex flex-wrap items-center gap-4") do
65
- # span(class: "text-sm font-medium text-gray-900 dark:text-white") do
66
- # "Filters:"
67
- # end
68
- # select(
69
- # id: "category-filter",
70
- # class:
71
- # "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
72
- # ) do
73
- # option(selected: "selected", value: "") { "All Categories" }
74
- # option(value: "technology") { "Technology" }
75
- # option(value: "science") { "Science" }
76
- # option(value: "health") { "Health" }
77
- # end
78
- # div(class: "flex items-center space-x-2") do
79
- # input(
80
- # type: "date",
81
- # id: "start-date",
82
- # class:
83
- # "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
84
- # )
85
- # span(class: "text-gray-500 dark:text-gray-400") { "to" }
86
- # input(
87
- # type: "date",
88
- # id: "end-date",
89
- # class:
90
- # "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
91
- # )
92
- # end
93
- # select(
94
- # id: "author-filter",
95
- # class:
96
- # "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
97
- # ) do
98
- # option(selected: "selected", value: "") { "All Authors" }
99
- # option(value: "john-doe") { "John Doe" }
100
- # option(value: "jane-smith") { "Jane Smith" }
101
- # end
102
- # button(
103
- # onclick: "applyFilters()",
104
- # class:
105
- # "inline-flex items-center text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-primary-600 dark:hover:bg-primary-700 focus:outline-none dark:focus:ring-primary-800"
106
- # ) do
107
- # svg(
108
- # class: "w-4 h-4 mr-2",
109
- # fill: "currentColor",
110
- # viewbox: "0 0 20 20",
111
- # xmlns: "http://www.w3.org/2000/svg"
112
- # ) do |s|
113
- # s.path(
114
- # fill_rule: "evenodd",
115
- # d:
116
- # "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z",
117
- # clip_rule: "evenodd"
118
- # )
119
- # end
120
- # plain " Apply Filters "
121
- # end
122
- # button(
123
- # onclick: "clearFilters()",
124
- # class:
125
- # "inline-flex items-center text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg text-sm px-4 py-2 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700"
126
- # ) do
127
- # svg(
128
- # class: "w-4 h-4 mr-2",
129
- # fill: "currentColor",
130
- # viewbox: "0 0 20 20",
131
- # xmlns: "http://www.w3.org/2000/svg"
132
- # ) do |s|
133
- # s.path(
134
- # fill_rule: "evenodd",
135
- # d:
136
- # "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",
137
- # clip_rule: "evenodd"
138
- # )
139
- # end
140
- # plain " Clear Filters "
141
- # end
142
- # end
143
- end
144
- ensure
145
- # TODO: remove this once Phlex adds support for SafeValues
146
- Phlex::HTML.const_set(:EVENT_ATTRIBUTES, original_attributes)
9
+ render current_definition.query_form.new(
10
+ raw_resource_query_params,
11
+ query_object: current_query_object,
12
+ page_size: request.parameters[:limit]
13
+ )
147
14
  end
148
15
 
149
16
  private
150
17
 
151
18
  def render?
152
- current_query_object.search_filter.present? && current_policy.allowed_to?(:search?)
19
+ current_query_object.filter_definitions.present? && current_policy.allowed_to?(:search?)
153
20
  end
154
21
  end
155
22
  end
@@ -53,19 +53,20 @@ module Plutonium
53
53
 
54
54
  column_definition = resource_definition.defined_columns[name] || {}
55
55
  column_display_options = column_definition[:options] || {}
56
- display_field_as = column_display_options.delete(:as)
57
- align_field_to = column_display_options.delete(:align)
58
56
 
59
- display_block = column_definition[:block] || ->(wrapped_object, key) {
57
+ display_tag = column_display_options[:as]
58
+ display_tag_options = column_display_options.except(:as, :align)
59
+ display_tag_block = column_definition[:block] || ->(wrapped_object, key) {
60
60
  f = wrapped_object.field(key)
61
- display_field_as ||= f.inferred_field_component
62
- f.send(:"#{display_field_as}_tag", **column_display_options)
61
+ display_tag ||= f.inferred_field_component
62
+ f.send(:"#{display_tag}_tag", **display_tag_options)
63
63
  }
64
64
 
65
- field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options] : {}
66
- field_options[:as] = display_field_as
67
- field_options[:align] = align_field_to if align_field_to
68
- table.column name, **field_options, sort_params: current_query_object.sort_params_for(name), &display_block
65
+ # align_field_to = column_display_options.slice(:align)
66
+ field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options].dup : {}
67
+ field_options = field_options.merge(**column_display_options.slice(:align))
68
+ # field_options[:align] = align_field_to if align_field_to
69
+ table.column name, **field_options, sort_params: current_query_object.sort_params_for(name), &display_tag_block
69
70
  end
70
71
 
71
72
  table.actions do |wrapped_object|
@@ -1,5 +1,5 @@
1
1
  module Plutonium
2
- VERSION = "0.15.4"
2
+ VERSION = "0.15.5"
3
3
  NEXT_MAJOR_VERSION = VERSION.split(".").tap { |v|
4
4
  v[1] = v[1].to_i + 1
5
5
  v[2] = 0
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@radioactive-labs/plutonium",
9
- "version": "0.1.3",
9
+ "version": "0.1.5",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@hotwired/stimulus": "^3.2.2",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Core assets for the Plutonium gem",
5
5
  "type": "module",
6
6
  "main": "src/js/core.js",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plutonium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.4
4
+ version: 0.15.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-06 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -1256,6 +1256,7 @@ files:
1256
1256
  - lib/plutonium/definition/base.rb
1257
1257
  - lib/plutonium/definition/config_attr.rb
1258
1258
  - lib/plutonium/definition/defineable_props.rb
1259
+ - lib/plutonium/definition/presentable.rb
1259
1260
  - lib/plutonium/definition/search.rb
1260
1261
  - lib/plutonium/definition/sorting.rb
1261
1262
  - lib/plutonium/engine.rb
@@ -1275,7 +1276,6 @@ files:
1275
1276
  - lib/plutonium/icons.rb
1276
1277
  - lib/plutonium/interaction/README.md
1277
1278
  - lib/plutonium/interaction/base.rb
1278
- - lib/plutonium/interaction/concerns/presentable.rb
1279
1279
  - lib/plutonium/interaction/concerns/workflow_dsl.rb
1280
1280
  - lib/plutonium/interaction/outcome.rb
1281
1281
  - lib/plutonium/interaction/response/base.rb
@@ -1286,6 +1286,7 @@ files:
1286
1286
  - lib/plutonium/interaction/response/render.rb
1287
1287
  - lib/plutonium/lib/after_commit.rb
1288
1288
  - lib/plutonium/lib/bit_flags.rb
1289
+ - lib/plutonium/lib/deep_freezer.rb
1289
1290
  - lib/plutonium/lib/overlayed_hash.rb
1290
1291
  - lib/plutonium/lib/smart_cache.rb
1291
1292
  - lib/plutonium/models/has_cents.rb
@@ -1295,13 +1296,18 @@ files:
1295
1296
  - lib/plutonium/portal/engine.rb
1296
1297
  - lib/plutonium/preserved__/field.rb.bk
1297
1298
  - lib/plutonium/preserved__/input.rb.bk
1299
+ - lib/plutonium/query/adhoc_block.rb
1300
+ - lib/plutonium/query/base.rb
1301
+ - lib/plutonium/query/filter.rb
1302
+ - lib/plutonium/query/filters/text.rb
1303
+ - lib/plutonium/query/model_scope.rb
1298
1304
  - lib/plutonium/railtie.rb
1299
- - lib/plutonium/refinements/parameter_refinements.rb
1300
1305
  - lib/plutonium/reloader.rb
1301
1306
  - lib/plutonium/resource/context.rb
1302
1307
  - lib/plutonium/resource/controller.rb
1303
1308
  - lib/plutonium/resource/controllers/authorizable.rb
1304
1309
  - lib/plutonium/resource/controllers/crud_actions.rb
1310
+ - lib/plutonium/resource/controllers/crud_actions/index_action.rb
1305
1311
  - lib/plutonium/resource/controllers/defineable.rb
1306
1312
  - lib/plutonium/resource/controllers/interactive_actions.rb
1307
1313
  - lib/plutonium/resource/controllers/presentable.rb
@@ -1319,6 +1325,7 @@ files:
1319
1325
  - lib/plutonium/routing/route_set_extensions.rb
1320
1326
  - lib/plutonium/simple_form/attachment_component.rb
1321
1327
  - lib/plutonium/simple_form/input_group_component.rb
1328
+ - lib/plutonium/support/parameters.rb
1322
1329
  - lib/plutonium/ui.rb
1323
1330
  - lib/plutonium/ui/action_button.rb
1324
1331
  - lib/plutonium/ui/breadcrumbs.rb
@@ -1334,6 +1341,7 @@ files:
1334
1341
  - lib/plutonium/ui/empty_card.rb
1335
1342
  - lib/plutonium/ui/form/base.rb
1336
1343
  - lib/plutonium/ui/form/interaction.rb
1344
+ - lib/plutonium/ui/form/query.rb
1337
1345
  - lib/plutonium/ui/form/resource.rb
1338
1346
  - lib/plutonium/ui/form/theme.rb
1339
1347
  - lib/plutonium/ui/page/base.rb
@@ -1,73 +0,0 @@
1
- module Plutonium
2
- module Interaction
3
- module Concerns
4
- # Provides presentation-related functionality for interactions.
5
- #
6
- # This module allows interactions to define metadata such as labels, icons,
7
- # and descriptions, which can be used for UI generation or documentation.
8
- #
9
- # @example
10
- # class MyInteraction < Plutonium::Interaction::Base
11
- # include Plutonium::Interaction::Concerns::Presentable
12
- #
13
- # presents label: "My Interaction",
14
- # icon: "star",
15
- # description: "Does something awesome"
16
- #
17
- # # ... rest of the interaction
18
- # end
19
- module Presentable
20
- extend ActiveSupport::Concern
21
-
22
- included do
23
- class_attribute :presentation_metadata, default: {}
24
- end
25
-
26
- class_methods do
27
- # Defines presentation metadata for the interaction.
28
- #
29
- # @param options [Hash] The presentation options.
30
- # @option options [String] :label The label for the interaction.
31
- # @option options [String] :icon The icon for the interaction.
32
- # @option options [String] :description The description of the interaction.
33
- def presents(**options)
34
- self.presentation_metadata = options
35
- end
36
-
37
- # Returns the label for the interaction.
38
- #
39
- # @return [String] The label defined in the presentation metadata or a default generated from the class name.
40
- def label
41
- presentation_metadata[:label] || name.demodulize.titleize
42
- end
43
-
44
- # Returns the icon for the interaction.
45
- #
46
- # @return [String, nil] The icon defined in the presentation metadata.
47
- def icon
48
- presentation_metadata[:icon]
49
- end
50
-
51
- # Returns the description for the interaction.
52
- #
53
- # @return [String, nil] The description defined in the presentation metadata.
54
- def description
55
- presentation_metadata[:description]
56
- end
57
- end
58
-
59
- def label
60
- self.class.label
61
- end
62
-
63
- def icon
64
- self.class.icon
65
- end
66
-
67
- def description
68
- self.class.description
69
- end
70
- end
71
- end
72
- end
73
- end