plutonium 0.50.0 → 0.51.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/.claude/skills/plutonium/SKILL.md +85 -102
- data/.claude/skills/plutonium-app/SKILL.md +572 -0
- data/.claude/skills/plutonium-auth/SKILL.md +163 -300
- data/.claude/skills/plutonium-behavior/SKILL.md +838 -0
- data/.claude/skills/plutonium-resource/SKILL.md +1176 -0
- data/.claude/skills/plutonium-tenancy/SKILL.md +655 -0
- data/.claude/skills/plutonium-testing/SKILL.md +6 -5
- data/.claude/skills/plutonium-ui/SKILL.md +900 -0
- data/CHANGELOG.md +27 -2
- data/Rakefile +2 -1
- data/app/assets/plutonium.css +1 -11
- data/app/assets/plutonium.js +1009 -1214
- data/app/assets/plutonium.js.map +3 -3
- data/app/assets/plutonium.min.js +52 -51
- data/app/assets/plutonium.min.js.map +3 -3
- data/docs/.vitepress/config.ts +37 -27
- data/docs/getting-started/index.md +22 -29
- data/docs/getting-started/installation.md +37 -80
- data/docs/getting-started/tutorial/index.md +4 -5
- data/docs/guides/adding-resources.md +66 -377
- data/docs/guides/authentication.md +94 -463
- data/docs/guides/authorization.md +124 -370
- data/docs/guides/creating-packages.md +94 -296
- data/docs/guides/custom-actions.md +121 -441
- data/docs/guides/index.md +22 -42
- data/docs/guides/multi-tenancy.md +116 -187
- data/docs/guides/nested-resources.md +103 -431
- data/docs/guides/search-filtering.md +123 -240
- data/docs/guides/testing.md +5 -4
- data/docs/guides/theming.md +157 -407
- data/docs/guides/troubleshooting.md +5 -3
- data/docs/guides/user-invites.md +106 -425
- data/docs/guides/user-profile.md +76 -243
- data/docs/index.md +1 -1
- data/docs/reference/app/generators.md +517 -0
- data/docs/reference/app/index.md +158 -0
- data/docs/reference/app/packages.md +146 -0
- data/docs/reference/app/portals.md +377 -0
- data/docs/reference/auth/accounts.md +230 -0
- data/docs/reference/auth/index.md +88 -0
- data/docs/reference/auth/profile.md +185 -0
- data/docs/reference/behavior/controllers.md +395 -0
- data/docs/reference/behavior/index.md +22 -0
- data/docs/reference/behavior/interactions.md +341 -0
- data/docs/reference/behavior/policies.md +417 -0
- data/docs/reference/index.md +56 -49
- data/docs/reference/resource/actions.md +423 -0
- data/docs/reference/resource/definition.md +508 -0
- data/docs/reference/resource/index.md +50 -0
- data/docs/reference/resource/model.md +348 -0
- data/docs/reference/resource/query.md +305 -0
- data/docs/reference/tenancy/entity-scoping.md +361 -0
- data/docs/reference/tenancy/index.md +36 -0
- data/docs/reference/tenancy/invites.md +393 -0
- data/docs/reference/tenancy/nested-resources.md +267 -0
- data/docs/reference/testing/index.md +287 -0
- data/docs/reference/ui/assets.md +400 -0
- data/docs/reference/ui/components.md +165 -0
- data/docs/reference/ui/displays.md +104 -0
- data/docs/reference/ui/forms.md +284 -0
- data/docs/reference/ui/index.md +30 -0
- data/docs/reference/ui/layouts.md +106 -0
- data/docs/reference/ui/pages.md +189 -0
- data/docs/reference/ui/tables.md +117 -0
- data/docs/superpowers/specs/2026-05-09-typeahead-endpoint-design.md +203 -0
- data/docs/superpowers/specs/2026-05-12-skill-compaction-design.md +99 -0
- data/docs/superpowers/specs/2026-05-13-docs-restructure-design.md +186 -0
- data/gemfiles/rails_7.gemfile.lock +1 -1
- data/gemfiles/rails_8.0.gemfile.lock +1 -1
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/generators/pu/core/update/update_generator.rb +0 -20
- data/lib/generators/pu/invites/install_generator.rb +1 -0
- data/lib/plutonium/definition/base.rb +1 -1
- data/lib/plutonium/definition/{views.rb → index_views.rb} +21 -20
- data/lib/plutonium/helpers/turbo_helper.rb +11 -0
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +14 -0
- data/lib/plutonium/resource/controller.rb +1 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +19 -1
- data/lib/plutonium/resource/controllers/typeahead.rb +180 -0
- data/lib/plutonium/resource/policy.rb +7 -0
- data/lib/plutonium/routing/mapper_extensions.rb +15 -0
- data/lib/plutonium/ui/component/methods.rb +4 -0
- data/lib/plutonium/ui/form/base.rb +6 -2
- data/lib/plutonium/ui/form/components/json.rb +58 -0
- data/lib/plutonium/ui/form/components/resource_select.rb +62 -8
- data/lib/plutonium/ui/form/components/secure_association.rb +98 -22
- data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
- data/lib/plutonium/ui/form/resource.rb +0 -4
- data/lib/plutonium/ui/grid/resource.rb +1 -1
- data/lib/plutonium/ui/layout/base.rb +1 -0
- data/lib/plutonium/ui/page/base.rb +0 -7
- data/lib/plutonium/ui/page/index.rb +4 -4
- data/lib/plutonium/ui/table/resource.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +8 -0
- data/lib/tasks/release.rake +15 -1
- data/package.json +10 -10
- data/src/css/slim_select.css +4 -0
- data/src/js/controllers/slim_select_controller.js +61 -0
- data/src/js/turbo/turbo_actions.js +33 -0
- data/yarn.lock +553 -543
- metadata +44 -33
- data/.claude/skills/plutonium-assets/SKILL.md +0 -512
- data/.claude/skills/plutonium-controller/SKILL.md +0 -396
- data/.claude/skills/plutonium-create-resource/SKILL.md +0 -303
- data/.claude/skills/plutonium-definition/SKILL.md +0 -1223
- data/.claude/skills/plutonium-entity-scoping/SKILL.md +0 -317
- data/.claude/skills/plutonium-forms/SKILL.md +0 -465
- data/.claude/skills/plutonium-installation/SKILL.md +0 -331
- data/.claude/skills/plutonium-interaction/SKILL.md +0 -413
- data/.claude/skills/plutonium-invites/SKILL.md +0 -408
- data/.claude/skills/plutonium-model/SKILL.md +0 -440
- data/.claude/skills/plutonium-nested-resources/SKILL.md +0 -360
- data/.claude/skills/plutonium-package/SKILL.md +0 -198
- data/.claude/skills/plutonium-policy/SKILL.md +0 -456
- data/.claude/skills/plutonium-portal/SKILL.md +0 -410
- data/.claude/skills/plutonium-views/SKILL.md +0 -651
- data/docs/reference/assets/index.md +0 -496
- data/docs/reference/controller/index.md +0 -412
- data/docs/reference/definition/actions.md +0 -462
- data/docs/reference/definition/fields.md +0 -383
- data/docs/reference/definition/index.md +0 -326
- data/docs/reference/definition/query.md +0 -351
- data/docs/reference/generators/index.md +0 -648
- data/docs/reference/interaction/index.md +0 -449
- data/docs/reference/model/features.md +0 -248
- data/docs/reference/model/index.md +0 -218
- data/docs/reference/policy/index.md +0 -456
- data/docs/reference/portal/index.md +0 -379
- data/docs/reference/views/forms.md +0 -411
- data/docs/reference/views/index.md +0 -544
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
# Definition Actions
|
|
2
|
-
|
|
3
|
-
Complete reference for custom actions in definitions.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Actions add buttons beyond standard CRUD operations. Two types:
|
|
8
|
-
|
|
9
|
-
1. **Simple Actions** - Navigate to URLs
|
|
10
|
-
2. **Interactive Actions** - Execute Interactions with optional user input
|
|
11
|
-
|
|
12
|
-
## Action Types
|
|
13
|
-
|
|
14
|
-
| Type | Shows In | Use Case |
|
|
15
|
-
|------|----------|----------|
|
|
16
|
-
| `resource_action` | Index page | Import, Export, Create |
|
|
17
|
-
| `record_action` | Show page | Edit, Delete, Archive |
|
|
18
|
-
| `collection_record_action` | Table rows | Quick actions per row |
|
|
19
|
-
| `bulk_action` | Selected records | Bulk operations |
|
|
20
|
-
|
|
21
|
-
## Simple Actions
|
|
22
|
-
|
|
23
|
-
Simple actions link to existing routes. The target route must already exist.
|
|
24
|
-
|
|
25
|
-
```ruby
|
|
26
|
-
class PostDefinition < Plutonium::Resource::Definition
|
|
27
|
-
# Link to external URL
|
|
28
|
-
action :documentation,
|
|
29
|
-
label: "Documentation",
|
|
30
|
-
route_options: {url: "https://docs.example.com"},
|
|
31
|
-
icon: Phlex::TablerIcons::Book,
|
|
32
|
-
resource_action: true
|
|
33
|
-
|
|
34
|
-
# Link to custom controller action
|
|
35
|
-
action :reports,
|
|
36
|
-
route_options: {action: :reports},
|
|
37
|
-
icon: Phlex::TablerIcons::ChartBar,
|
|
38
|
-
resource_action: true
|
|
39
|
-
end
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
::: warning Always Name Custom Routes
|
|
43
|
-
When adding custom routes for actions, always use the `as:` option:
|
|
44
|
-
|
|
45
|
-
```ruby
|
|
46
|
-
resources :posts do
|
|
47
|
-
collection do
|
|
48
|
-
get :reports, as: :reports # Named route required!
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
This ensures `resource_url_for` can generate correct URLs, especially for nested resources.
|
|
54
|
-
:::
|
|
55
|
-
|
|
56
|
-
**Note:** For custom operations with business logic, use **Interactive Actions** with an Interaction class.
|
|
57
|
-
|
|
58
|
-
## Interactive Actions
|
|
59
|
-
|
|
60
|
-
```ruby
|
|
61
|
-
class PostDefinition < Plutonium::Resource::Definition
|
|
62
|
-
action :publish,
|
|
63
|
-
interaction: PublishInteraction,
|
|
64
|
-
icon: Phlex::TablerIcons::Send
|
|
65
|
-
|
|
66
|
-
action :archive,
|
|
67
|
-
interaction: ArchiveInteraction,
|
|
68
|
-
color: :danger,
|
|
69
|
-
category: :danger,
|
|
70
|
-
position: 1000,
|
|
71
|
-
confirmation: "Are you sure?"
|
|
72
|
-
end
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Action Options
|
|
76
|
-
|
|
77
|
-
```ruby
|
|
78
|
-
action :name,
|
|
79
|
-
# Display
|
|
80
|
-
label: "Custom Label", # Button text (default: name.titleize)
|
|
81
|
-
description: "What it does", # Tooltip/description
|
|
82
|
-
icon: Phlex::TablerIcons::Star, # Icon component
|
|
83
|
-
|
|
84
|
-
# Styling
|
|
85
|
-
color: :danger, # :primary, :secondary, :danger
|
|
86
|
-
|
|
87
|
-
# Visibility (boolean flags)
|
|
88
|
-
resource_action: true, # Show on index page
|
|
89
|
-
record_action: true, # Show on show page
|
|
90
|
-
collection_record_action: true, # Show in table rows
|
|
91
|
-
bulk_action: true, # For selected records
|
|
92
|
-
|
|
93
|
-
# Grouping
|
|
94
|
-
category: :primary, # :primary, :secondary, :danger
|
|
95
|
-
position: 50, # Order (lower = first)
|
|
96
|
-
|
|
97
|
-
# Behavior
|
|
98
|
-
confirmation: "Are you sure?", # Confirmation dialog
|
|
99
|
-
turbo_frame: "_top", # Turbo frame target
|
|
100
|
-
return_to: "/custom/path", # Override return URL
|
|
101
|
-
route_options: {action: :foo}, # Route configuration
|
|
102
|
-
|
|
103
|
-
# Dialog chrome (for interactive actions with a form)
|
|
104
|
-
modal: :slideover # :centered (default) or :slideover
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### `Action#with(...)`
|
|
108
|
-
|
|
109
|
-
Action records are frozen value objects. To derive a variant — typically inside `customize_actions` — call `existing.with(...)` for a new copy with overrides applied:
|
|
110
|
-
|
|
111
|
-
```ruby
|
|
112
|
-
def customize_actions
|
|
113
|
-
defined_actions[:edit] = defined_actions[:edit].with(turbo_frame: "_top")
|
|
114
|
-
end
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Route Options
|
|
118
|
-
|
|
119
|
-
Configure how the action's URL is generated:
|
|
120
|
-
|
|
121
|
-
```ruby
|
|
122
|
-
# Simple route to controller action
|
|
123
|
-
action :preview,
|
|
124
|
-
route_options: {action: :preview},
|
|
125
|
-
record_action: true
|
|
126
|
-
|
|
127
|
-
# With HTTP method
|
|
128
|
-
action :archive,
|
|
129
|
-
route_options: {method: :post, action: :archive},
|
|
130
|
-
record_action: true
|
|
131
|
-
|
|
132
|
-
# External URL
|
|
133
|
-
action :docs,
|
|
134
|
-
route_options: {url: "https://docs.example.com"},
|
|
135
|
-
resource_action: true
|
|
136
|
-
|
|
137
|
-
# Custom URL resolver
|
|
138
|
-
action :create_deployment,
|
|
139
|
-
route_options: Plutonium::Action::RouteOptions.new(
|
|
140
|
-
url_resolver: ->(subject) {
|
|
141
|
-
resource_url_for(Deployment, action: :new, parent: subject)
|
|
142
|
-
}
|
|
143
|
-
),
|
|
144
|
-
record_action: true
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Built-in CRUD Actions
|
|
148
|
-
|
|
149
|
-
These are defined by default:
|
|
150
|
-
|
|
151
|
-
```ruby
|
|
152
|
-
action :new,
|
|
153
|
-
route_options: {action: :new},
|
|
154
|
-
resource_action: true,
|
|
155
|
-
category: :primary,
|
|
156
|
-
icon: Phlex::TablerIcons::Plus,
|
|
157
|
-
position: 10
|
|
158
|
-
|
|
159
|
-
action :show,
|
|
160
|
-
route_options: {action: :show},
|
|
161
|
-
collection_record_action: true,
|
|
162
|
-
icon: Phlex::TablerIcons::Eye,
|
|
163
|
-
position: 10
|
|
164
|
-
|
|
165
|
-
action :edit,
|
|
166
|
-
route_options: {action: :edit},
|
|
167
|
-
record_action: true,
|
|
168
|
-
collection_record_action: true,
|
|
169
|
-
icon: Phlex::TablerIcons::Edit,
|
|
170
|
-
position: 20
|
|
171
|
-
|
|
172
|
-
action :destroy,
|
|
173
|
-
route_options: {method: :delete},
|
|
174
|
-
record_action: true,
|
|
175
|
-
collection_record_action: true,
|
|
176
|
-
category: :danger,
|
|
177
|
-
icon: Phlex::TablerIcons::Trash,
|
|
178
|
-
position: 100,
|
|
179
|
-
confirmation: "Are you sure?",
|
|
180
|
-
turbo_frame: "_top"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Customizing Built-in Actions
|
|
184
|
-
|
|
185
|
-
Override in your definition:
|
|
186
|
-
|
|
187
|
-
```ruby
|
|
188
|
-
class PostDefinition < Plutonium::Resource::Definition
|
|
189
|
-
# Customize delete confirmation
|
|
190
|
-
action :destroy,
|
|
191
|
-
confirmation: "This will permanently delete the post and all comments.",
|
|
192
|
-
route_options: {method: :delete},
|
|
193
|
-
record_action: true,
|
|
194
|
-
collection_record_action: true,
|
|
195
|
-
category: :danger,
|
|
196
|
-
icon: Phlex::TablerIcons::Trash,
|
|
197
|
-
position: 100,
|
|
198
|
-
turbo_frame: "_top"
|
|
199
|
-
end
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## Authorization
|
|
203
|
-
|
|
204
|
-
Actions are authorized via policies:
|
|
205
|
-
|
|
206
|
-
```ruby
|
|
207
|
-
# app/policies/post_policy.rb
|
|
208
|
-
class PostPolicy < Plutonium::Resource::Policy
|
|
209
|
-
def publish?
|
|
210
|
-
user.admin? || record.author == user
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def archive?
|
|
214
|
-
user.admin?
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
The action only appears if the policy method returns `true`.
|
|
220
|
-
|
|
221
|
-
## Immediate vs Form Actions
|
|
222
|
-
|
|
223
|
-
**Immediate** - Executes without showing a form (when interaction has no extra inputs):
|
|
224
|
-
|
|
225
|
-
```ruby
|
|
226
|
-
class ArchiveInteraction < Plutonium::Resource::Interaction
|
|
227
|
-
attribute :resource # Only resource, no other inputs
|
|
228
|
-
# No input declarations
|
|
229
|
-
|
|
230
|
-
def execute
|
|
231
|
-
resource.archived!
|
|
232
|
-
succeed(resource)
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
**Form** - Shows a form first (when interaction has additional inputs):
|
|
238
|
-
|
|
239
|
-
```ruby
|
|
240
|
-
class InviteUserInteraction < Plutonium::Resource::Interaction
|
|
241
|
-
attribute :resource
|
|
242
|
-
attribute :email
|
|
243
|
-
attribute :role
|
|
244
|
-
|
|
245
|
-
input :email
|
|
246
|
-
input :role, as: :select, choices: %w[admin member]
|
|
247
|
-
# Has inputs = shows form first
|
|
248
|
-
end
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## Interaction Reference
|
|
252
|
-
|
|
253
|
-
### Basic Structure
|
|
254
|
-
|
|
255
|
-
```ruby
|
|
256
|
-
class PublishInteraction < Plutonium::Resource::Interaction
|
|
257
|
-
presents label: "Publish",
|
|
258
|
-
icon: Phlex::TablerIcons::Send,
|
|
259
|
-
description: "Make this post public"
|
|
260
|
-
|
|
261
|
-
attribute :resource # The record being acted upon
|
|
262
|
-
|
|
263
|
-
private
|
|
264
|
-
|
|
265
|
-
def execute
|
|
266
|
-
resource.update!(published: true, published_at: Time.current)
|
|
267
|
-
succeed(resource).with_message("Published!")
|
|
268
|
-
rescue ActiveRecord::RecordInvalid => e
|
|
269
|
-
failed(e.record.errors)
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### With User Input
|
|
275
|
-
|
|
276
|
-
```ruby
|
|
277
|
-
class InviteUserInteraction < Plutonium::Resource::Interaction
|
|
278
|
-
presents label: "Invite User", icon: Phlex::TablerIcons::Mail
|
|
279
|
-
|
|
280
|
-
attribute :resource # The company
|
|
281
|
-
attribute :email
|
|
282
|
-
attribute :role
|
|
283
|
-
|
|
284
|
-
input :email, as: :email
|
|
285
|
-
input :role, as: :select, choices: %w[admin member viewer]
|
|
286
|
-
|
|
287
|
-
validates :email, presence: true, format: {with: URI::MailTo::EMAIL_REGEXP}
|
|
288
|
-
validates :role, presence: true
|
|
289
|
-
|
|
290
|
-
private
|
|
291
|
-
|
|
292
|
-
def execute
|
|
293
|
-
UserInvite.create!(
|
|
294
|
-
company: resource,
|
|
295
|
-
email: email,
|
|
296
|
-
role: role
|
|
297
|
-
)
|
|
298
|
-
succeed(resource).with_message("Invitation sent to #{email}.")
|
|
299
|
-
rescue ActiveRecord::RecordInvalid => e
|
|
300
|
-
failed(e.record.errors)
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### Bulk Action
|
|
306
|
-
|
|
307
|
-
Bulk actions operate on multiple selected records. When registered, the resource table automatically shows:
|
|
308
|
-
- **Selection checkboxes** in each row
|
|
309
|
-
- **Bulk actions toolbar** that appears when records are selected
|
|
310
|
-
|
|
311
|
-
```ruby
|
|
312
|
-
class BulkArchiveInteraction < Plutonium::Resource::Interaction
|
|
313
|
-
presents label: "Archive Selected", icon: Phlex::TablerIcons::Archive
|
|
314
|
-
|
|
315
|
-
attribute :resources # Array of records (note: plural)
|
|
316
|
-
|
|
317
|
-
private
|
|
318
|
-
|
|
319
|
-
def execute
|
|
320
|
-
count = 0
|
|
321
|
-
resources.each do |record|
|
|
322
|
-
record.archived!
|
|
323
|
-
count += 1
|
|
324
|
-
end
|
|
325
|
-
succeed(resources).with_message("#{count} records archived.")
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
Register in definition:
|
|
331
|
-
|
|
332
|
-
```ruby
|
|
333
|
-
class PostDefinition < ResourceDefinition
|
|
334
|
-
action :bulk_archive, interaction: BulkArchiveInteraction
|
|
335
|
-
# bulk_action: true is automatically inferred from `resources` attribute
|
|
336
|
-
end
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
Add the policy method (checked per-record):
|
|
340
|
-
|
|
341
|
-
```ruby
|
|
342
|
-
class PostPolicy < ResourcePolicy
|
|
343
|
-
def bulk_archive?
|
|
344
|
-
# Can use record attributes - checked for each selected record
|
|
345
|
-
user.admin? || record.author == user
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
::: tip Bulk Action Authorization
|
|
351
|
-
Bulk actions use **per-record authorization**:
|
|
352
|
-
- Policy method (e.g., `bulk_archive?`) is checked for **each selected record** - you can use `record` attributes
|
|
353
|
-
- Backend rejects the entire request if any record fails authorization
|
|
354
|
-
- UI only shows actions that **all** selected records support
|
|
355
|
-
:::
|
|
356
|
-
|
|
357
|
-
### Resource Action (No Record)
|
|
358
|
-
|
|
359
|
-
```ruby
|
|
360
|
-
class ImportInteraction < Plutonium::Resource::Interaction
|
|
361
|
-
presents label: "Import CSV", icon: Phlex::TablerIcons::Upload
|
|
362
|
-
|
|
363
|
-
# No :resource or :resources = resource action
|
|
364
|
-
attribute :file
|
|
365
|
-
|
|
366
|
-
input :file, as: :file
|
|
367
|
-
|
|
368
|
-
validates :file, presence: true
|
|
369
|
-
|
|
370
|
-
private
|
|
371
|
-
|
|
372
|
-
def execute
|
|
373
|
-
# Import logic...
|
|
374
|
-
succeed(nil).with_message("Import completed.")
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
## Interaction Responses
|
|
380
|
-
|
|
381
|
-
```ruby
|
|
382
|
-
def execute
|
|
383
|
-
# Success with message (redirects to resource automatically)
|
|
384
|
-
succeed(resource).with_message("Done!")
|
|
385
|
-
|
|
386
|
-
# Success with custom redirect (only if different from default)
|
|
387
|
-
succeed(resource)
|
|
388
|
-
.with_redirect_response(custom_dashboard_path)
|
|
389
|
-
.with_message("Redirecting...")
|
|
390
|
-
|
|
391
|
-
# Failure with field errors
|
|
392
|
-
failed(resource.errors)
|
|
393
|
-
|
|
394
|
-
# Failure with custom message
|
|
395
|
-
failed("Something went wrong")
|
|
396
|
-
end
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
::: tip Automatic Redirect
|
|
400
|
-
Redirect is automatic on success. You can use `with_redirect_response` for a different destination.
|
|
401
|
-
:::
|
|
402
|
-
|
|
403
|
-
## Inherited Actions
|
|
404
|
-
|
|
405
|
-
Actions defined in `ResourceDefinition` are inherited by all definitions:
|
|
406
|
-
|
|
407
|
-
```ruby
|
|
408
|
-
# app/definitions/resource_definition.rb
|
|
409
|
-
class ResourceDefinition < Plutonium::Resource::Definition
|
|
410
|
-
action :archive,
|
|
411
|
-
interaction: ArchiveInteraction,
|
|
412
|
-
color: :danger,
|
|
413
|
-
position: 1000
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
# All definitions inherit the archive action automatically
|
|
417
|
-
class PostDefinition < ResourceDefinition
|
|
418
|
-
end
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
## Portal-Specific Actions
|
|
422
|
-
|
|
423
|
-
Override actions for a specific portal:
|
|
424
|
-
|
|
425
|
-
```ruby
|
|
426
|
-
# packages/admin_portal/app/definitions/admin_portal/post_definition.rb
|
|
427
|
-
class AdminPortal::PostDefinition < ::PostDefinition
|
|
428
|
-
# Add admin-only actions
|
|
429
|
-
action :feature, interaction: FeaturePostInteraction
|
|
430
|
-
action :bulk_publish, interaction: BulkPublishInteraction
|
|
431
|
-
end
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
## Common Patterns
|
|
435
|
-
|
|
436
|
-
### Archive/Restore
|
|
437
|
-
|
|
438
|
-
```ruby
|
|
439
|
-
action :archive,
|
|
440
|
-
interaction: ArchiveInteraction,
|
|
441
|
-
record_action: true,
|
|
442
|
-
color: :danger
|
|
443
|
-
|
|
444
|
-
action :restore,
|
|
445
|
-
interaction: RestoreInteraction,
|
|
446
|
-
record_action: true
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
### Export
|
|
450
|
-
|
|
451
|
-
```ruby
|
|
452
|
-
action :export,
|
|
453
|
-
interaction: ExportInteraction,
|
|
454
|
-
resource_action: true,
|
|
455
|
-
icon: Phlex::TablerIcons::Download
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
## Related
|
|
459
|
-
|
|
460
|
-
- [Definition Reference](./index)
|
|
461
|
-
- [Fields Reference](./fields)
|
|
462
|
-
- [Query Reference](./query)
|