plutonium 0.15.0 → 0.15.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/views/resource/_interactive_action_form.html.erb +1 -0
- data/app/views/resource/{interactive_resource_collection_action.html.erb → interactive_bulk_action.html.erb} +1 -1
- data/app/views/resource/interactive_record_action.html.erb +1 -0
- data/app/views/resource/{interactive_resource_record_action.html.erb → interactive_resource_action.html.erb} +1 -1
- data/lib/plutonium/action/base.rb +6 -3
- data/lib/plutonium/action/interactive.rb +16 -9
- data/lib/plutonium/definition/base.rb +8 -1
- data/lib/plutonium/definition/sorting.rb +15 -0
- data/lib/plutonium/interaction/README.md +34 -1
- data/lib/plutonium/interaction/base.rb +38 -7
- data/lib/plutonium/interaction/concerns/presentable.rb +24 -12
- data/lib/plutonium/interaction/outcome.rb +77 -55
- data/lib/plutonium/interaction/response/base.rb +3 -1
- data/lib/plutonium/interaction/response/failure.rb +18 -0
- data/lib/plutonium/interaction/response/file.rb +20 -0
- data/lib/plutonium/interaction/response/redirect.rb +1 -11
- data/lib/plutonium/interaction/response/render.rb +1 -9
- data/lib/plutonium/resource/controllers/authorizable.rb +29 -5
- data/lib/plutonium/resource/controllers/interactive_actions.rb +171 -130
- data/lib/plutonium/resource/controllers/queryable.rb +2 -2
- data/lib/plutonium/resource/interaction.rb +1 -3
- data/lib/plutonium/resource/query_object.rb +2 -2
- data/lib/plutonium/routing/mapper_extensions.rb +9 -9
- data/lib/plutonium/ui/action_button.rb +4 -3
- data/lib/plutonium/ui/component/methods.rb +1 -0
- data/lib/plutonium/ui/display/theme.rb +4 -3
- data/lib/plutonium/ui/form/interaction.rb +35 -0
- data/lib/plutonium/ui/form/resource.rb +1 -1
- data/lib/plutonium/ui/page/interactive_action.rb +23 -0
- data/lib/plutonium/ui/table/components/search_bar.rb +1 -1
- data/lib/plutonium/ui/table/display_theme.rb +2 -2
- data/lib/plutonium/ui/table/resource.rb +11 -5
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +1 -0
- metadata +11 -21
- data/app/views/resource/_interactive_resource_action_form.html.erb +0 -45
- data/app/views/resource/interactive_resource_recordless_action.html.erb +0 -5
- data/gemfiles/rails_7.gemfile.lock +0 -339
@@ -26,7 +26,6 @@ module Plutonium
|
|
26
26
|
class ActionMissingCurrentAuthorizedScope < ActionPolicy::UnauthorizedAction; end
|
27
27
|
|
28
28
|
included do
|
29
|
-
verify_authorized
|
30
29
|
after_action :verify_authorize_current
|
31
30
|
after_action :verify_current_authorized_scope, except: %i[new create]
|
32
31
|
|
@@ -35,28 +34,53 @@ module Plutonium
|
|
35
34
|
attr_writer :authorize_current_count
|
36
35
|
attr_writer :current_authorized_scope_count
|
37
36
|
|
37
|
+
attr_reader :verify_authorize_current_skipped
|
38
|
+
attr_reader :verify_current_authorized_scope_skipped
|
39
|
+
|
38
40
|
protected :authorize_current_count=, :authorize_current_count
|
39
41
|
protected :current_authorized_scope_count=, :current_authorized_scope_count
|
40
42
|
end
|
41
43
|
|
44
|
+
class_methods do
|
45
|
+
# Skips verify_authorize_current after_action callback.
|
46
|
+
def skip_verify_authorize_current(**options)
|
47
|
+
skip_after_action :verify_authorize_current, options
|
48
|
+
end
|
49
|
+
|
50
|
+
# Skips verify_current_authorized_scope after_action callback.
|
51
|
+
def skip_verify_current_authorized_scope(**options)
|
52
|
+
skip_after_action :verify_current_authorized_scope, options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
42
56
|
private
|
43
57
|
|
58
|
+
def skip_verify_authorize_current!
|
59
|
+
@verify_authorize_current_skipped = true
|
60
|
+
end
|
61
|
+
|
62
|
+
def skip_verify_current_authorized_scope!
|
63
|
+
@verify_current_authorized_scope_skipped = true
|
64
|
+
end
|
65
|
+
|
44
66
|
# Verifies that authorize_current has been called
|
45
67
|
#
|
46
68
|
# @raise [ActionMissingAuthorizeCurrent] if authorize_current hasn't been called
|
47
69
|
def verify_authorize_current
|
48
|
-
return if
|
70
|
+
return if verify_authorize_current_skipped
|
71
|
+
return if authorize_current_count > 0
|
49
72
|
|
50
|
-
raise ActionMissingAuthorizeCurrent.new(controller_path, action_name)
|
73
|
+
raise ActionMissingAuthorizeCurrent.new(controller_path, action_name)
|
51
74
|
end
|
52
75
|
|
53
76
|
# Verifies that current_authorized_scope has been called
|
54
77
|
#
|
55
78
|
# @raise [ActionMissingCurrentAuthorizedScope] if current_authorized_scope hasn't been called
|
56
79
|
def verify_current_authorized_scope
|
57
|
-
return if
|
80
|
+
return if current_authorized_scope_count
|
81
|
+
return if current_authorized_scope_count > 0
|
58
82
|
|
59
|
-
raise ActionMissingCurrentAuthorizedScope.new(controller_path, action_name)
|
83
|
+
raise ActionMissingCurrentAuthorizedScope.new(controller_path, action_name)
|
60
84
|
end
|
61
85
|
|
62
86
|
# @return [Integer] the number of times authorize_current has been called
|
@@ -7,169 +7,178 @@ module Plutonium
|
|
7
7
|
included do
|
8
8
|
helper_method :current_interactive_action
|
9
9
|
|
10
|
-
before_action :
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
before_action :validate_interactive_action!, only: %i[
|
11
|
+
interactive_record_action commit_interactive_record_action
|
12
|
+
interactive_bulk_action commit_interactive_bulk_action
|
13
|
+
interactive_resource_action commit_interactive_resource_action
|
14
14
|
]
|
15
15
|
|
16
|
-
before_action :
|
17
|
-
|
16
|
+
before_action :authorize_interactive_record_action!, only: %i[
|
17
|
+
interactive_record_action commit_interactive_record_action
|
18
18
|
]
|
19
19
|
|
20
20
|
before_action :authorize_interactive_resource_action!, only: %i[
|
21
|
-
|
22
|
-
|
21
|
+
interactive_bulk_action commit_interactive_bulk_action
|
22
|
+
interactive_resource_action commit_interactive_resource_action
|
23
23
|
]
|
24
24
|
end
|
25
25
|
|
26
|
-
# GET /resources/1/
|
27
|
-
def
|
28
|
-
|
26
|
+
# GET /resources/1/record_actions/:interactive_action
|
27
|
+
def interactive_record_action
|
28
|
+
build_interactive_record_action_interaction
|
29
29
|
|
30
30
|
if helpers.current_turbo_frame == "modal"
|
31
31
|
render layout: false
|
32
32
|
else
|
33
|
-
render :
|
33
|
+
render :interactive_record_action
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
# POST /resources/1/
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
]
|
37
|
+
# POST /resources/1/record_actions/:interactive_action
|
38
|
+
def commit_interactive_record_action
|
39
|
+
build_interactive_record_action_interaction
|
40
|
+
|
41
|
+
outcome = @interaction.call
|
42
|
+
if outcome.success?
|
43
|
+
outcome.to_response.process(self) do |value|
|
44
|
+
respond_to do |format|
|
45
|
+
return_url = redirect_url_after_action_on(resource_record)
|
46
|
+
format.any { redirect_to return_url, status: :see_other }
|
47
|
+
if helpers.current_turbo_frame == "modal"
|
48
|
+
format.turbo_stream do
|
49
|
+
render turbo_stream: [
|
50
|
+
turbo_stream.redirect(return_url)
|
51
|
+
]
|
52
|
+
end
|
54
53
|
end
|
55
54
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
end
|
56
|
+
else
|
57
|
+
outcome.to_response.process(self) do
|
58
|
+
respond_to do |format|
|
59
|
+
format.html do
|
60
|
+
render :interactive_record_action, status: :unprocessable_entity
|
61
|
+
end
|
62
|
+
format.any do
|
63
|
+
@errors = @interaction.errors
|
64
|
+
render "errors", status: :unprocessable_entity
|
65
|
+
end
|
66
|
+
if helpers.current_turbo_frame == "modal"
|
67
|
+
format.turbo_stream do
|
68
|
+
render turbo_stream: [
|
69
|
+
turbo_stream.replace(:modal, partial: "interactive_action_form")
|
70
|
+
]
|
71
|
+
end
|
68
72
|
end
|
69
73
|
end
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
74
|
-
# GET /resources/
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
@interaction = current_interactive_action.interaction.new((params[:interaction] || {}).except(:resources))
|
78
|
+
# GET /resources/resource_actions/:interactive_action
|
79
|
+
def interactive_resource_action
|
80
|
+
skip_verify_current_authorized_scope!
|
81
|
+
build_interactive_resource_action_interaction
|
79
82
|
|
80
83
|
if helpers.current_turbo_frame == "modal"
|
81
84
|
render layout: false
|
82
85
|
else
|
83
|
-
render :
|
86
|
+
render :interactive_resource_action
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
87
|
-
# POST /resources/
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
90
|
+
# POST /resources/resource_actions/:interactive_action
|
91
|
+
def commit_interactive_resource_action
|
92
|
+
skip_verify_current_authorized_scope!
|
93
|
+
build_interactive_resource_action_interaction
|
94
|
+
|
95
|
+
outcome = @interaction.call
|
96
|
+
if outcome.success?
|
97
|
+
outcome.to_response.process(self) do |value|
|
98
|
+
respond_to do |format|
|
99
|
+
return_url = redirect_url_after_action_on(resource_class)
|
100
|
+
format.any { redirect_to return_url, status: :see_other }
|
101
|
+
if helpers.current_turbo_frame == "modal"
|
102
|
+
format.turbo_stream do
|
103
|
+
render turbo_stream: [
|
104
|
+
turbo_stream.redirect(return_url)
|
105
|
+
]
|
106
|
+
end
|
104
107
|
end
|
105
108
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
109
|
+
end
|
110
|
+
else
|
111
|
+
outcome.to_response.process(self) do
|
112
|
+
respond_to do |format|
|
113
|
+
format.html do
|
114
|
+
render :interactive_record_action, status: :unprocessable_entity
|
115
|
+
end
|
116
|
+
format.any do
|
117
|
+
@errors = @interaction.errors
|
118
|
+
render "errors", status: :unprocessable_entity
|
119
|
+
end
|
120
|
+
if helpers.current_turbo_frame == "modal"
|
121
|
+
format.turbo_stream do
|
122
|
+
render turbo_stream: [
|
123
|
+
turbo_stream.replace(:modal, partial: "interactive_action_form")
|
124
|
+
]
|
125
|
+
end
|
118
126
|
end
|
119
127
|
end
|
120
128
|
end
|
121
129
|
end
|
122
130
|
end
|
123
131
|
|
124
|
-
# GET /resources/
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
# GET /resources/bulk_actions/:interactive_action?ids[]=1&ids[]=2
|
133
|
+
def interactive_bulk_action
|
134
|
+
raise NotImplementedError
|
135
|
+
# # TODO: ensure that the selected list matches the returned value
|
136
|
+
# interactive_bulk
|
137
|
+
# @interaction = current_interactive_action.interaction.new((params[:interaction] || {}).except(:resources))
|
138
|
+
|
139
|
+
# if helpers.current_turbo_frame == "modal"
|
140
|
+
# render layout: false
|
141
|
+
# else
|
142
|
+
# render :interactive_bulk_action
|
143
|
+
# end
|
135
144
|
end
|
136
145
|
|
137
|
-
# POST /resources/
|
138
|
-
def
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
146
|
+
# POST /resources/bulk_actions/:interactive_action?ids[]=1&ids[]=2
|
147
|
+
def commit_interactive_bulk_action
|
148
|
+
raise NotImplementedError
|
149
|
+
# respond_to do |format|
|
150
|
+
# inputs = interaction_params.merge(resources: interactive_bulk)
|
151
|
+
# @interaction = current_interactive_action.interaction.run(inputs)
|
152
|
+
|
153
|
+
# if @interaction.valid?
|
154
|
+
# collection_count = interactive_bulk.size
|
155
|
+
|
156
|
+
# flash[:notice] = "TODO:#{current_interactive_action} #{collection_count} #{resource_class.model_name.human.pluralize(collection_count)} successfully updated."
|
157
|
+
|
158
|
+
# format.html { redirect_to resource_url_for(resource_class) }
|
159
|
+
# if helpers.current_turbo_frame == "modal"
|
160
|
+
# format.turbo_stream do
|
161
|
+
# render turbo_stream: [
|
162
|
+
# turbo_stream.redirect(resource_url_for(resource_class))
|
163
|
+
# ]
|
164
|
+
# end
|
165
|
+
# end
|
166
|
+
# else
|
167
|
+
# format.html do
|
168
|
+
# render :interactive_bulk_action, status: :unprocessable_entity
|
169
|
+
# end
|
170
|
+
# format.any do
|
171
|
+
# @errors = @interaction.errors
|
172
|
+
# render "errors", status: :unprocessable_entity
|
173
|
+
# end
|
174
|
+
|
175
|
+
# if helpers.current_turbo_frame == "modal"
|
176
|
+
# format.turbo_stream do
|
177
|
+
# render turbo_stream: turbo_stream.replace(:modal, partial: "interactive_bulk_action_form")
|
178
|
+
# end
|
179
|
+
# end
|
180
|
+
# end
|
181
|
+
# end
|
173
182
|
end
|
174
183
|
|
175
184
|
private
|
@@ -179,17 +188,19 @@ module Plutonium
|
|
179
188
|
end
|
180
189
|
|
181
190
|
def interactive_resource_actions
|
182
|
-
@interactive_resource_actions ||=
|
191
|
+
@interactive_resource_actions ||= current_definition
|
192
|
+
.defined_actions
|
193
|
+
.select { |k, v| v.is_a?(Plutonium::Action::Interactive) }
|
183
194
|
end
|
184
195
|
|
185
|
-
def
|
196
|
+
def validate_interactive_action!
|
186
197
|
interactive_resource_action = params[:interactive_action]&.to_sym
|
187
198
|
unless interactive_resource_actions.key?(interactive_resource_action)
|
188
199
|
raise ::AbstractController::ActionNotFound, "Unknown action '#{interactive_resource_action}'"
|
189
200
|
end
|
190
201
|
end
|
191
202
|
|
192
|
-
def
|
203
|
+
def authorize_interactive_record_action!
|
193
204
|
interactive_resource_action = params[:interactive_action]&.to_sym
|
194
205
|
authorize_current! resource_record, to: :"#{interactive_resource_action}?"
|
195
206
|
end
|
@@ -199,13 +210,43 @@ module Plutonium
|
|
199
210
|
authorize_current! resource_class, to: :"#{interactive_resource_action}?"
|
200
211
|
end
|
201
212
|
|
202
|
-
def
|
203
|
-
@
|
213
|
+
def interactive_bulk
|
214
|
+
@interactive_bulk ||= current_authorized_scope.from_path_param(params.require(:ids))
|
215
|
+
end
|
216
|
+
|
217
|
+
def build_interactive_record_action_interaction
|
218
|
+
@interaction = current_interactive_action.interaction.new
|
219
|
+
@interaction.attributes = interaction_params.merge(resource: resource_record)
|
220
|
+
@interaction
|
221
|
+
end
|
222
|
+
|
223
|
+
def build_interactive_resource_action_interaction
|
224
|
+
@interaction = current_interactive_action.interaction.new
|
225
|
+
@interaction.attributes = interaction_params
|
226
|
+
@interaction
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns the submitted resource parameters
|
230
|
+
# @return [Hash] The submitted resource parameters
|
231
|
+
def submitted_interaction_params
|
232
|
+
@submitted_interaction_params ||= current_interactive_action
|
233
|
+
.interaction
|
234
|
+
.build_form(nil)
|
235
|
+
.extract_input(params)[:interaction]
|
236
|
+
end
|
237
|
+
|
238
|
+
def redirect_url_after_action_on(resource_record_or_resource_class)
|
239
|
+
if (return_to = url_from(params[:return_to]))
|
240
|
+
return return_to
|
241
|
+
end
|
242
|
+
|
243
|
+
resource_url_for(resource_record_or_resource_class)
|
204
244
|
end
|
205
245
|
|
246
|
+
# Returns the resource parameters, including scoped and parent parameters
|
247
|
+
# @return [Hash] The resource parameters
|
206
248
|
def interaction_params
|
207
|
-
|
208
|
-
(params[:interaction] || {}).except(:resource, :resources)
|
249
|
+
@interaction_params ||= submitted_interaction_params.except(:resource, :resources)
|
209
250
|
end
|
210
251
|
end
|
211
252
|
end
|
@@ -24,11 +24,11 @@ module Plutonium
|
|
24
24
|
end
|
25
25
|
|
26
26
|
current_definition.defined_scopes.each do |key, value|
|
27
|
-
query_object.define_scope key, value[:block]
|
27
|
+
query_object.define_scope key, value[:block], **value[:options]
|
28
28
|
end
|
29
29
|
|
30
30
|
current_definition.defined_sorts.each do |key, value|
|
31
|
-
query_object.define_sorter key, value[:block]
|
31
|
+
query_object.define_sorter key, value[:block], **value[:options]
|
32
32
|
end
|
33
33
|
|
34
34
|
query_object
|
@@ -138,9 +138,9 @@ module Plutonium
|
|
138
138
|
#
|
139
139
|
# @param name [Symbol] The name of the sort.
|
140
140
|
# @param body [Proc, nil] The body of the sort.
|
141
|
-
def define_sorter(name, body = nil)
|
141
|
+
def define_sorter(name, body = nil, using: nil)
|
142
142
|
if body.nil?
|
143
|
-
sort_field = determine_sort_field(name)
|
143
|
+
sort_field = using || determine_sort_field(name)
|
144
144
|
body = ->(scope, direction:) { scope.order(sort_field => direction) }
|
145
145
|
end
|
146
146
|
|
@@ -90,9 +90,9 @@ module Plutonium
|
|
90
90
|
# @return [void]
|
91
91
|
def define_member_interactive_actions
|
92
92
|
member do
|
93
|
-
get "record_actions/:interactive_action", action: :
|
94
|
-
as: :
|
95
|
-
post "record_actions/:interactive_action", action: :
|
93
|
+
get "record_actions/:interactive_action", action: :interactive_record_action,
|
94
|
+
as: :record_action
|
95
|
+
post "record_actions/:interactive_action", action: :commit_interactive_record_action
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -101,13 +101,13 @@ module Plutonium
|
|
101
101
|
# @return [void]
|
102
102
|
def define_collection_interactive_actions
|
103
103
|
collection do
|
104
|
-
get "
|
105
|
-
as: :
|
106
|
-
post "
|
104
|
+
get "bulk_actions/:interactive_action", action: :interactive_bulk_action,
|
105
|
+
as: :bulk_action
|
106
|
+
post "bulk_actions/:interactive_action", action: :commit_interactive_bulk_action
|
107
107
|
|
108
|
-
get "
|
109
|
-
as: :
|
110
|
-
post "
|
108
|
+
get "resource_actions/:interactive_action", action: :interactive_resource_action,
|
109
|
+
as: :resource_action
|
110
|
+
post "resource_actions/:interactive_action", action: :commit_interactive_resource_action
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -40,6 +40,7 @@ module Plutonium
|
|
40
40
|
class: "inline-block",
|
41
41
|
form: {
|
42
42
|
data: {
|
43
|
+
turbo: @action.turbo,
|
43
44
|
turbo_confirm: @action.confirmation,
|
44
45
|
turbo_frame: @action.turbo_frame
|
45
46
|
}
|
@@ -55,7 +56,7 @@ module Plutonium
|
|
55
56
|
if @action.icon
|
56
57
|
render @action.icon.new(class: icon_classes)
|
57
58
|
end
|
58
|
-
span { @action.label }
|
59
|
+
span { @action.label }
|
59
60
|
end
|
60
61
|
|
61
62
|
def button_classes
|
@@ -69,7 +70,7 @@ module Plutonium
|
|
69
70
|
|
70
71
|
def base_classes
|
71
72
|
if @variant == :table
|
72
|
-
"inline-flex items-center justify-center
|
73
|
+
"inline-flex items-center justify-center py-1 px-2 rounded-lg focus:outline-none focus:ring-2"
|
73
74
|
else
|
74
75
|
"flex items-center justify-center px-4 py-2 text-sm font-medium rounded-lg focus:outline-none focus:ring-4"
|
75
76
|
end
|
@@ -77,7 +78,7 @@ module Plutonium
|
|
77
78
|
|
78
79
|
def icon_classes
|
79
80
|
if @variant == :table
|
80
|
-
"h-4 w-4"
|
81
|
+
"h-4 w-4 mr-1"
|
81
82
|
else
|
82
83
|
"h-3.5 w-3.5 mr-2 -ml-1"
|
83
84
|
end
|
@@ -7,17 +7,18 @@ module Plutonium
|
|
7
7
|
def self.theme
|
8
8
|
super.merge({
|
9
9
|
base: "relative bg-white dark:bg-gray-800 shadow-md sm:rounded-lg my-3",
|
10
|
+
value_wrapper: "max-h-[300px] overflow-y-auto",
|
10
11
|
fields_wrapper: "p-6 grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-4 gap-6 gap-y-10 grid-flow-row-dense",
|
11
12
|
label: "text-base font-bold text-gray-500 dark:text-gray-400 mb-1",
|
12
13
|
description: "text-sm text-gray-400 dark:text-gray-500",
|
13
14
|
placeholder: "text-md text-gray-500 dark:text-gray-300 mb-1 italic",
|
14
|
-
string: "
|
15
|
-
text: "
|
15
|
+
string: "text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
16
|
+
text: "text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
16
17
|
link: "text-primary-600 dark:text-primary-500 whitespace-pre-line",
|
17
18
|
color: "flex items-center text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
18
19
|
color_indicator: "w-10 h-10 rounded-full mr-2", # max-h-fit
|
19
20
|
email: "flex items-center text-md text-primary-600 dark:text-primary-500 mb-1 whitespace-pre-line",
|
20
|
-
json: "
|
21
|
+
json: "text-sm text-gray-900 dark:text-white mb-1 whitespace-pre font-mono shadow-inner p-4",
|
21
22
|
prefixed_icon: "w-8 h-8 mr-2"
|
22
23
|
})
|
23
24
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Form
|
6
|
+
class Interaction < Resource
|
7
|
+
def initialize(interaction, *, **options, &)
|
8
|
+
options[:key] = :interaction
|
9
|
+
options[:resource_fields] = interaction.attribute_names.map(&:to_sym) - %i[resource resources]
|
10
|
+
options[:resource_definition] = interaction
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def form_action
|
18
|
+
# interactive action forms post to the same page
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize_attributes
|
23
|
+
super
|
24
|
+
attributes.fetch(:data_turbo) { attributes[:data_turbo] = object.turbo.to_s }
|
25
|
+
end
|
26
|
+
|
27
|
+
def submit_button(*, **)
|
28
|
+
super(*, **) do
|
29
|
+
object.label
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Page
|
6
|
+
class InteractiveAction < Base
|
7
|
+
private
|
8
|
+
|
9
|
+
def page_title
|
10
|
+
current_interactive_action.label || super
|
11
|
+
end
|
12
|
+
|
13
|
+
def page_description
|
14
|
+
current_interactive_action.description || super
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_default_content
|
18
|
+
render "interactive_action_form"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|