plutonium 0.33.1 → 0.34.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/# Plutonium: The pre-alpha demo.md +4 -2
- data/.claude/skills/assets/SKILL.md +416 -0
- data/.claude/skills/connect-resource/SKILL.md +112 -0
- data/.claude/skills/controller/SKILL.md +302 -0
- data/.claude/skills/create-resource/SKILL.md +240 -0
- data/.claude/skills/definition/SKILL.md +218 -0
- data/.claude/skills/definition-actions/SKILL.md +386 -0
- data/.claude/skills/definition-fields/SKILL.md +474 -0
- data/.claude/skills/definition-query/SKILL.md +334 -0
- data/.claude/skills/forms/SKILL.md +439 -0
- data/.claude/skills/installation/SKILL.md +300 -0
- data/.claude/skills/interaction/SKILL.md +382 -0
- data/.claude/skills/model/SKILL.md +267 -0
- data/.claude/skills/model-features/SKILL.md +286 -0
- data/.claude/skills/nested-resources/SKILL.md +274 -0
- data/.claude/skills/package/SKILL.md +191 -0
- data/.claude/skills/policy/SKILL.md +352 -0
- data/.claude/skills/portal/SKILL.md +400 -0
- data/.claude/skills/resource/SKILL.md +281 -0
- data/.claude/skills/rodauth/SKILL.md +452 -0
- data/.claude/skills/views/SKILL.md +563 -0
- data/Appraisals +46 -4
- data/CHANGELOG.md +32 -1
- data/app/assets/plutonium.css +2 -2
- data/config/brakeman.ignore +239 -0
- data/config/initializers/action_policy.rb +1 -1
- data/docs/.vitepress/config.ts +132 -47
- data/docs/concepts/architecture.md +226 -0
- data/docs/concepts/auto-detection.md +254 -0
- data/docs/concepts/index.md +61 -0
- data/docs/concepts/packages-portals.md +304 -0
- data/docs/concepts/resources.md +224 -0
- data/docs/cookbook/blog.md +412 -0
- data/docs/cookbook/index.md +289 -0
- data/docs/cookbook/saas.md +481 -0
- data/docs/getting-started/index.md +56 -0
- data/docs/getting-started/installation.md +146 -0
- data/docs/getting-started/tutorial/01-setup.md +118 -0
- data/docs/getting-started/tutorial/02-first-resource.md +180 -0
- data/docs/getting-started/tutorial/03-authentication.md +246 -0
- data/docs/getting-started/tutorial/04-authorization.md +170 -0
- data/docs/getting-started/tutorial/05-custom-actions.md +202 -0
- data/docs/getting-started/tutorial/06-nested-resources.md +147 -0
- data/docs/getting-started/tutorial/07-customizing-ui.md +254 -0
- data/docs/getting-started/tutorial/index.md +64 -0
- data/docs/guides/adding-resources.md +420 -0
- data/docs/guides/authentication.md +551 -0
- data/docs/guides/authorization.md +468 -0
- data/docs/guides/creating-packages.md +380 -0
- data/docs/guides/custom-actions.md +523 -0
- data/docs/guides/index.md +45 -0
- data/docs/guides/multi-tenancy.md +302 -0
- data/docs/guides/nested-resources.md +411 -0
- data/docs/guides/search-filtering.md +266 -0
- data/docs/guides/theming.md +321 -0
- data/docs/index.md +67 -26
- data/docs/public/CLAUDE.md +64 -21
- data/docs/reference/assets/index.md +496 -0
- data/docs/reference/controller/index.md +363 -0
- data/docs/reference/definition/actions.md +400 -0
- data/docs/reference/definition/fields.md +350 -0
- data/docs/reference/definition/index.md +252 -0
- data/docs/reference/definition/query.md +342 -0
- data/docs/reference/generators/index.md +469 -0
- data/docs/reference/index.md +49 -0
- data/docs/reference/interaction/index.md +445 -0
- data/docs/reference/model/features.md +248 -0
- data/docs/reference/model/index.md +219 -0
- data/docs/reference/policy/index.md +385 -0
- data/docs/reference/portal/index.md +382 -0
- data/docs/reference/views/forms.md +396 -0
- data/docs/reference/views/index.md +479 -0
- data/gemfiles/rails_7.gemfile +9 -2
- data/gemfiles/rails_7.gemfile.lock +146 -111
- data/gemfiles/rails_8.0.gemfile +20 -0
- data/gemfiles/rails_8.0.gemfile.lock +417 -0
- data/gemfiles/rails_8.1.gemfile +20 -0
- data/gemfiles/rails_8.1.gemfile.lock +419 -0
- data/lib/generators/pu/gem/dotenv/templates/.env +2 -0
- data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -1
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +13 -16
- data/lib/generators/pu/pkg/portal/USAGE +65 -0
- data/lib/generators/pu/pkg/portal/portal_generator.rb +22 -9
- data/lib/generators/pu/res/conn/USAGE +71 -0
- data/lib/generators/pu/res/model/USAGE +106 -110
- data/lib/generators/pu/res/model/templates/model.rb.tt +6 -2
- data/lib/generators/pu/res/scaffold/USAGE +85 -0
- data/lib/generators/pu/rodauth/install_generator.rb +2 -6
- data/lib/generators/pu/rodauth/templates/config/initializers/url_options.rb +17 -0
- data/lib/generators/pu/skills/sync/USAGE +14 -0
- data/lib/generators/pu/skills/sync/sync_generator.rb +66 -0
- data/lib/plutonium/action_policy/sti_policy_lookup.rb +1 -1
- data/lib/plutonium/core/controller.rb +2 -2
- data/lib/plutonium/interaction/base.rb +1 -0
- data/lib/plutonium/package/engine.rb +2 -2
- data/lib/plutonium/query/adhoc_block.rb +6 -2
- data/lib/plutonium/query/model_scope.rb +1 -1
- data/lib/plutonium/railtie.rb +4 -0
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +1 -1
- data/lib/plutonium/resource/query_object.rb +38 -8
- data/lib/plutonium/ui/table/components/scopes_bar.rb +39 -34
- data/lib/plutonium/version.rb +1 -1
- data/lib/tasks/release.rake +19 -4
- data/package.json +1 -1
- metadata +76 -39
- data/brakeman.ignore +0 -28
- data/docs/api-examples.md +0 -49
- data/docs/guide/claude-code-guide.md +0 -74
- data/docs/guide/deep-dive/authorization.md +0 -189
- data/docs/guide/deep-dive/multitenancy.md +0 -256
- data/docs/guide/deep-dive/resources.md +0 -390
- data/docs/guide/getting-started/01-installation.md +0 -165
- data/docs/guide/index.md +0 -28
- data/docs/guide/introduction/01-what-is-plutonium.md +0 -211
- data/docs/guide/introduction/02-core-concepts.md +0 -440
- data/docs/guide/tutorial/01-project-setup.md +0 -75
- data/docs/guide/tutorial/02-creating-a-feature-package.md +0 -45
- data/docs/guide/tutorial/03-defining-resources.md +0 -90
- data/docs/guide/tutorial/04-creating-a-portal.md +0 -101
- data/docs/guide/tutorial/05-customizing-the-ui.md +0 -128
- data/docs/guide/tutorial/06-adding-custom-actions.md +0 -101
- data/docs/guide/tutorial/07-implementing-authorization.md +0 -90
- data/docs/markdown-examples.md +0 -85
- data/docs/modules/action.md +0 -244
- data/docs/modules/authentication.md +0 -236
- data/docs/modules/configuration.md +0 -599
- data/docs/modules/controller.md +0 -443
- data/docs/modules/core.md +0 -316
- data/docs/modules/definition.md +0 -1308
- data/docs/modules/display.md +0 -759
- data/docs/modules/form.md +0 -495
- data/docs/modules/generator.md +0 -400
- data/docs/modules/index.md +0 -167
- data/docs/modules/interaction.md +0 -642
- data/docs/modules/package.md +0 -151
- data/docs/modules/policy.md +0 -176
- data/docs/modules/portal.md +0 -710
- data/docs/modules/query.md +0 -297
- data/docs/modules/resource_record.md +0 -618
- data/docs/modules/routing.md +0 -690
- data/docs/modules/table.md +0 -301
- data/docs/modules/ui.md +0 -631
|
@@ -0,0 +1,400 @@
|
|
|
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
|
+
**Note:** For custom operations with business logic, use **Interactive Actions** with an Interaction class.
|
|
43
|
+
|
|
44
|
+
## Interactive Actions
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
class PostDefinition < Plutonium::Resource::Definition
|
|
48
|
+
action :publish,
|
|
49
|
+
interaction: PublishInteraction,
|
|
50
|
+
icon: Phlex::TablerIcons::Send
|
|
51
|
+
|
|
52
|
+
action :archive,
|
|
53
|
+
interaction: ArchiveInteraction,
|
|
54
|
+
color: :danger,
|
|
55
|
+
category: :danger,
|
|
56
|
+
position: 1000,
|
|
57
|
+
confirmation: "Are you sure?"
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Action Options
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
action :name,
|
|
65
|
+
# Display
|
|
66
|
+
label: "Custom Label", # Button text (default: name.titleize)
|
|
67
|
+
description: "What it does", # Tooltip/description
|
|
68
|
+
icon: Phlex::TablerIcons::Star, # Icon component
|
|
69
|
+
|
|
70
|
+
# Styling
|
|
71
|
+
color: :danger, # :primary, :secondary, :danger
|
|
72
|
+
|
|
73
|
+
# Visibility (boolean flags)
|
|
74
|
+
resource_action: true, # Show on index page
|
|
75
|
+
record_action: true, # Show on show page
|
|
76
|
+
collection_record_action: true, # Show in table rows
|
|
77
|
+
bulk_action: true, # For selected records
|
|
78
|
+
|
|
79
|
+
# Grouping
|
|
80
|
+
category: :primary, # :primary, :secondary, :danger
|
|
81
|
+
position: 50, # Order (lower = first)
|
|
82
|
+
|
|
83
|
+
# Behavior
|
|
84
|
+
confirmation: "Are you sure?", # Confirmation dialog
|
|
85
|
+
turbo_frame: "_top", # Turbo frame target
|
|
86
|
+
return_to: "/custom/path", # Override return URL
|
|
87
|
+
route_options: {action: :foo} # Route configuration
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Route Options
|
|
91
|
+
|
|
92
|
+
Configure how the action's URL is generated:
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# Simple route to controller action
|
|
96
|
+
action :preview,
|
|
97
|
+
route_options: {action: :preview},
|
|
98
|
+
record_action: true
|
|
99
|
+
|
|
100
|
+
# With HTTP method
|
|
101
|
+
action :archive,
|
|
102
|
+
route_options: {method: :post, action: :archive},
|
|
103
|
+
record_action: true
|
|
104
|
+
|
|
105
|
+
# External URL
|
|
106
|
+
action :docs,
|
|
107
|
+
route_options: {url: "https://docs.example.com"},
|
|
108
|
+
resource_action: true
|
|
109
|
+
|
|
110
|
+
# Custom URL resolver
|
|
111
|
+
action :create_deployment,
|
|
112
|
+
route_options: Plutonium::Action::RouteOptions.new(
|
|
113
|
+
url_resolver: ->(subject) {
|
|
114
|
+
resource_url_for(Deployment, action: :new, parent: subject)
|
|
115
|
+
}
|
|
116
|
+
),
|
|
117
|
+
record_action: true
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Built-in CRUD Actions
|
|
121
|
+
|
|
122
|
+
These are defined by default:
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
action :new,
|
|
126
|
+
route_options: {action: :new},
|
|
127
|
+
resource_action: true,
|
|
128
|
+
category: :primary,
|
|
129
|
+
icon: Phlex::TablerIcons::Plus,
|
|
130
|
+
position: 10
|
|
131
|
+
|
|
132
|
+
action :show,
|
|
133
|
+
route_options: {action: :show},
|
|
134
|
+
collection_record_action: true,
|
|
135
|
+
icon: Phlex::TablerIcons::Eye,
|
|
136
|
+
position: 10
|
|
137
|
+
|
|
138
|
+
action :edit,
|
|
139
|
+
route_options: {action: :edit},
|
|
140
|
+
record_action: true,
|
|
141
|
+
collection_record_action: true,
|
|
142
|
+
icon: Phlex::TablerIcons::Edit,
|
|
143
|
+
position: 20
|
|
144
|
+
|
|
145
|
+
action :destroy,
|
|
146
|
+
route_options: {method: :delete},
|
|
147
|
+
record_action: true,
|
|
148
|
+
collection_record_action: true,
|
|
149
|
+
category: :danger,
|
|
150
|
+
icon: Phlex::TablerIcons::Trash,
|
|
151
|
+
position: 100,
|
|
152
|
+
confirmation: "Are you sure?",
|
|
153
|
+
turbo_frame: "_top"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Customizing Built-in Actions
|
|
157
|
+
|
|
158
|
+
Override in your definition:
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
class PostDefinition < Plutonium::Resource::Definition
|
|
162
|
+
# Customize delete confirmation
|
|
163
|
+
action :destroy,
|
|
164
|
+
confirmation: "This will permanently delete the post and all comments.",
|
|
165
|
+
route_options: {method: :delete},
|
|
166
|
+
record_action: true,
|
|
167
|
+
collection_record_action: true,
|
|
168
|
+
category: :danger,
|
|
169
|
+
icon: Phlex::TablerIcons::Trash,
|
|
170
|
+
position: 100,
|
|
171
|
+
turbo_frame: "_top"
|
|
172
|
+
end
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Authorization
|
|
176
|
+
|
|
177
|
+
Actions are authorized via policies:
|
|
178
|
+
|
|
179
|
+
```ruby
|
|
180
|
+
# app/policies/post_policy.rb
|
|
181
|
+
class PostPolicy < Plutonium::Resource::Policy
|
|
182
|
+
def publish?
|
|
183
|
+
user.admin? || record.author == user
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def archive?
|
|
187
|
+
user.admin?
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The action only appears if the policy method returns `true`.
|
|
193
|
+
|
|
194
|
+
## Immediate vs Form Actions
|
|
195
|
+
|
|
196
|
+
**Immediate** - Executes without showing a form (when interaction has no extra inputs):
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
class ArchiveInteraction < Plutonium::Resource::Interaction
|
|
200
|
+
attribute :resource # Only resource, no other inputs
|
|
201
|
+
# No input declarations
|
|
202
|
+
|
|
203
|
+
def execute
|
|
204
|
+
resource.archived!
|
|
205
|
+
succeed(resource)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Form** - Shows a form first (when interaction has additional inputs):
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
class InviteUserInteraction < Plutonium::Resource::Interaction
|
|
214
|
+
attribute :resource
|
|
215
|
+
attribute :email
|
|
216
|
+
attribute :role
|
|
217
|
+
|
|
218
|
+
input :email
|
|
219
|
+
input :role, as: :select, choices: %w[admin member]
|
|
220
|
+
# Has inputs = shows form first
|
|
221
|
+
end
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Interaction Reference
|
|
225
|
+
|
|
226
|
+
### Basic Structure
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
class PublishInteraction < Plutonium::Resource::Interaction
|
|
230
|
+
presents label: "Publish",
|
|
231
|
+
icon: Phlex::TablerIcons::Send,
|
|
232
|
+
description: "Make this post public"
|
|
233
|
+
|
|
234
|
+
attribute :resource # The record being acted upon
|
|
235
|
+
|
|
236
|
+
private
|
|
237
|
+
|
|
238
|
+
def execute
|
|
239
|
+
resource.update!(published: true, published_at: Time.current)
|
|
240
|
+
succeed(resource).with_message("Published!")
|
|
241
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
242
|
+
failed(e.record.errors)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### With User Input
|
|
248
|
+
|
|
249
|
+
```ruby
|
|
250
|
+
class InviteUserInteraction < Plutonium::Resource::Interaction
|
|
251
|
+
presents label: "Invite User", icon: Phlex::TablerIcons::Mail
|
|
252
|
+
|
|
253
|
+
attribute :resource # The company
|
|
254
|
+
attribute :email
|
|
255
|
+
attribute :role
|
|
256
|
+
|
|
257
|
+
input :email, as: :email
|
|
258
|
+
input :role, as: :select, choices: %w[admin member viewer]
|
|
259
|
+
|
|
260
|
+
validates :email, presence: true, format: {with: URI::MailTo::EMAIL_REGEXP}
|
|
261
|
+
validates :role, presence: true
|
|
262
|
+
|
|
263
|
+
private
|
|
264
|
+
|
|
265
|
+
def execute
|
|
266
|
+
UserInvite.create!(
|
|
267
|
+
company: resource,
|
|
268
|
+
email: email,
|
|
269
|
+
role: role
|
|
270
|
+
)
|
|
271
|
+
succeed(resource).with_message("Invitation sent to #{email}.")
|
|
272
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
273
|
+
failed(e.record.errors)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Bulk Action
|
|
279
|
+
|
|
280
|
+
```ruby
|
|
281
|
+
class BulkArchiveInteraction < Plutonium::Resource::Interaction
|
|
282
|
+
presents label: "Archive Selected", icon: Phlex::TablerIcons::Archive
|
|
283
|
+
|
|
284
|
+
attribute :resources # Array of records (note: plural)
|
|
285
|
+
|
|
286
|
+
private
|
|
287
|
+
|
|
288
|
+
def execute
|
|
289
|
+
count = 0
|
|
290
|
+
resources.each do |record|
|
|
291
|
+
record.archived!
|
|
292
|
+
count += 1
|
|
293
|
+
end
|
|
294
|
+
succeed(resources).with_message("#{count} records archived.")
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Resource Action (No Record)
|
|
300
|
+
|
|
301
|
+
```ruby
|
|
302
|
+
class ImportInteraction < Plutonium::Resource::Interaction
|
|
303
|
+
presents label: "Import CSV", icon: Phlex::TablerIcons::Upload
|
|
304
|
+
|
|
305
|
+
# No :resource or :resources = resource action
|
|
306
|
+
attribute :file
|
|
307
|
+
|
|
308
|
+
input :file, as: :file
|
|
309
|
+
|
|
310
|
+
validates :file, presence: true
|
|
311
|
+
|
|
312
|
+
private
|
|
313
|
+
|
|
314
|
+
def execute
|
|
315
|
+
# Import logic...
|
|
316
|
+
succeed(nil).with_message("Import completed.")
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Interaction Responses
|
|
322
|
+
|
|
323
|
+
```ruby
|
|
324
|
+
def execute
|
|
325
|
+
# Success with message
|
|
326
|
+
succeed(resource).with_message("Done!")
|
|
327
|
+
|
|
328
|
+
# Success with redirect
|
|
329
|
+
succeed(resource)
|
|
330
|
+
.with_redirect_response(resource_url_for(resource))
|
|
331
|
+
.with_message("Redirecting...")
|
|
332
|
+
|
|
333
|
+
# Failure with field errors
|
|
334
|
+
failed(resource.errors)
|
|
335
|
+
|
|
336
|
+
# Failure with custom message
|
|
337
|
+
failed("Something went wrong")
|
|
338
|
+
end
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Inherited Actions
|
|
342
|
+
|
|
343
|
+
Actions defined in `ResourceDefinition` are inherited by all definitions:
|
|
344
|
+
|
|
345
|
+
```ruby
|
|
346
|
+
# app/definitions/resource_definition.rb
|
|
347
|
+
class ResourceDefinition < Plutonium::Resource::Definition
|
|
348
|
+
action :archive,
|
|
349
|
+
interaction: ArchiveInteraction,
|
|
350
|
+
color: :danger,
|
|
351
|
+
position: 1000
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# All definitions inherit the archive action automatically
|
|
355
|
+
class PostDefinition < ResourceDefinition
|
|
356
|
+
end
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Portal-Specific Actions
|
|
360
|
+
|
|
361
|
+
Override actions for a specific portal:
|
|
362
|
+
|
|
363
|
+
```ruby
|
|
364
|
+
# packages/admin_portal/app/definitions/admin_portal/post_definition.rb
|
|
365
|
+
class AdminPortal::PostDefinition < ::PostDefinition
|
|
366
|
+
# Add admin-only actions
|
|
367
|
+
action :feature, interaction: FeaturePostInteraction
|
|
368
|
+
action :bulk_publish, interaction: BulkPublishInteraction
|
|
369
|
+
end
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## Common Patterns
|
|
373
|
+
|
|
374
|
+
### Archive/Restore
|
|
375
|
+
|
|
376
|
+
```ruby
|
|
377
|
+
action :archive,
|
|
378
|
+
interaction: ArchiveInteraction,
|
|
379
|
+
record_action: true,
|
|
380
|
+
color: :danger
|
|
381
|
+
|
|
382
|
+
action :restore,
|
|
383
|
+
interaction: RestoreInteraction,
|
|
384
|
+
record_action: true
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Export
|
|
388
|
+
|
|
389
|
+
```ruby
|
|
390
|
+
action :export,
|
|
391
|
+
interaction: ExportInteraction,
|
|
392
|
+
resource_action: true,
|
|
393
|
+
icon: Phlex::TablerIcons::Download
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Related
|
|
397
|
+
|
|
398
|
+
- [Definition Reference](./index)
|
|
399
|
+
- [Fields Reference](./fields)
|
|
400
|
+
- [Query Reference](./query)
|