plutonium 0.34.1 → 0.35.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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium/skill.md +53 -0
  3. data/.claude/skills/{assets → plutonium-assets}/SKILL.md +13 -8
  4. data/.claude/skills/{connect-resource → plutonium-connect-resource}/SKILL.md +1 -1
  5. data/.claude/skills/{controller → plutonium-controller}/SKILL.md +27 -13
  6. data/.claude/skills/{create-resource → plutonium-create-resource}/SKILL.md +1 -1
  7. data/.claude/skills/{definition → plutonium-definition}/SKILL.md +10 -10
  8. data/.claude/skills/{definition-actions → plutonium-definition-actions}/SKILL.md +34 -9
  9. data/.claude/skills/{definition-fields → plutonium-definition-fields}/SKILL.md +38 -10
  10. data/.claude/skills/plutonium-definition-query/SKILL.md +356 -0
  11. data/.claude/skills/{forms → plutonium-forms}/SKILL.md +6 -6
  12. data/.claude/skills/{installation → plutonium-installation}/SKILL.md +9 -9
  13. data/.claude/skills/{interaction → plutonium-interaction}/SKILL.md +20 -19
  14. data/.claude/skills/{model → plutonium-model}/SKILL.md +3 -3
  15. data/.claude/skills/{model-features → plutonium-model-features}/SKILL.md +3 -3
  16. data/.claude/skills/{nested-resources → plutonium-nested-resources}/SKILL.md +5 -5
  17. data/.claude/skills/{package → plutonium-package}/SKILL.md +7 -8
  18. data/.claude/skills/{policy → plutonium-policy}/SKILL.md +26 -4
  19. data/.claude/skills/{portal → plutonium-portal}/SKILL.md +33 -31
  20. data/.claude/skills/{resource → plutonium-resource}/SKILL.md +27 -27
  21. data/.claude/skills/{rodauth → plutonium-rodauth}/SKILL.md +5 -5
  22. data/.claude/skills/plutonium-theming/SKILL.md +424 -0
  23. data/.claude/skills/{views → plutonium-views}/SKILL.md +7 -7
  24. data/CHANGELOG.md +52 -0
  25. data/CLAUDE.md +215 -0
  26. data/CONTRIBUTING.md +72 -18
  27. data/README.md +100 -19
  28. data/app/assets/plutonium.css +1 -11
  29. data/app/assets/plutonium.js +1685 -1146
  30. data/app/assets/plutonium.js.map +4 -4
  31. data/app/assets/plutonium.min.js +70 -70
  32. data/app/assets/plutonium.min.js.map +4 -4
  33. data/app/views/resource/interactive_bulk_action.html.erb +1 -5
  34. data/app/views/rodauth/_email_auth_request_form.html.erb +1 -1
  35. data/app/views/rodauth/_login_form.html.erb +15 -55
  36. data/app/views/rodauth/_login_form_footer.html.erb +2 -2
  37. data/app/views/rodauth/_password_visibility.html.erb +2 -8
  38. data/app/views/rodauth/add_recovery_codes.html.erb +2 -2
  39. data/app/views/rodauth/change_login.html.erb +36 -19
  40. data/app/views/rodauth/change_password.html.erb +34 -10
  41. data/app/views/rodauth/close_account.html.erb +12 -4
  42. data/app/views/rodauth/confirm_password.html.erb +19 -17
  43. data/app/views/rodauth/create_account.html.erb +30 -109
  44. data/app/views/rodauth/email_auth.html.erb +1 -1
  45. data/app/views/rodauth/logout.html.erb +4 -4
  46. data/app/views/rodauth/otp_auth.html.erb +13 -4
  47. data/app/views/rodauth/otp_disable.html.erb +12 -4
  48. data/app/views/rodauth/otp_setup.html.erb +29 -12
  49. data/app/views/rodauth/otp_unlock.html.erb +19 -10
  50. data/app/views/rodauth/otp_unlock_not_available.html.erb +7 -7
  51. data/app/views/rodauth/recovery_auth.html.erb +12 -4
  52. data/app/views/rodauth/recovery_codes.html.erb +12 -4
  53. data/app/views/rodauth/remember.html.erb +7 -7
  54. data/app/views/rodauth/reset_password.html.erb +23 -7
  55. data/app/views/rodauth/reset_password_request.html.erb +14 -10
  56. data/app/views/rodauth/sms_auth.html.erb +13 -4
  57. data/app/views/rodauth/sms_confirm.html.erb +13 -4
  58. data/app/views/rodauth/sms_disable.html.erb +12 -4
  59. data/app/views/rodauth/sms_request.html.erb +1 -1
  60. data/app/views/rodauth/sms_setup.html.erb +23 -7
  61. data/app/views/rodauth/two_factor_auth.html.erb +2 -2
  62. data/app/views/rodauth/two_factor_disable.html.erb +12 -4
  63. data/app/views/rodauth/two_factor_manage.html.erb +7 -7
  64. data/app/views/rodauth/unlock_account.html.erb +13 -5
  65. data/app/views/rodauth/unlock_account_request.html.erb +2 -2
  66. data/app/views/rodauth/verify_account.html.erb +25 -7
  67. data/app/views/rodauth/verify_account_resend.html.erb +14 -10
  68. data/app/views/rodauth/verify_login_change.html.erb +1 -1
  69. data/app/views/rodauth/webauthn_auth.html.erb +1 -1
  70. data/app/views/rodauth/webauthn_remove.html.erb +18 -8
  71. data/app/views/rodauth/webauthn_setup.html.erb +12 -4
  72. data/docs/.vitepress/config.ts +15 -26
  73. data/docs/.vitepress/theme/custom.css +388 -29
  74. data/docs/getting-started/index.md +1 -1
  75. data/docs/getting-started/tutorial/02-first-resource.md +9 -0
  76. data/docs/getting-started/tutorial/06-nested-resources.md +2 -2
  77. data/docs/getting-started/tutorial/07-author-portal.md +191 -0
  78. data/docs/getting-started/tutorial/{07-customizing-ui.md → 08-customizing-ui.md} +7 -7
  79. data/docs/getting-started/tutorial/index.md +5 -2
  80. data/docs/guides/authorization.md +33 -0
  81. data/docs/guides/creating-packages.md +12 -16
  82. data/docs/guides/custom-actions.md +36 -0
  83. data/docs/guides/search-filtering.md +121 -42
  84. data/docs/guides/theming.md +232 -36
  85. data/docs/index.md +203 -57
  86. data/docs/public/og-image.png +0 -0
  87. data/docs/reference/controller/index.md +14 -16
  88. data/docs/reference/definition/actions.md +38 -3
  89. data/docs/reference/definition/fields.md +3 -3
  90. data/docs/reference/definition/index.md +2 -2
  91. data/docs/reference/generators/index.md +0 -1
  92. data/docs/reference/interaction/index.md +14 -10
  93. data/docs/reference/model/index.md +0 -1
  94. data/docs/reference/portal/index.md +13 -27
  95. data/gemfiles/rails_7.gemfile.lock +1 -1
  96. data/gemfiles/rails_8.0.gemfile.lock +1 -1
  97. data/gemfiles/rails_8.1.gemfile.lock +1 -1
  98. data/lib/generators/pu/pkg/portal/portal_generator.rb +0 -2
  99. data/lib/generators/pu/pkg/portal/templates/app/views/package/dashboard/index.html.erb +28 -72
  100. data/lib/plutonium/action/interactive.rb +2 -2
  101. data/lib/plutonium/core/controller.rb +2 -1
  102. data/lib/plutonium/definition/actions.rb +2 -2
  103. data/lib/plutonium/lib/deep_freezer.rb +3 -7
  104. data/lib/plutonium/query/filter.rb +14 -0
  105. data/lib/plutonium/query/filters/association.rb +49 -0
  106. data/lib/plutonium/query/filters/boolean.rb +35 -0
  107. data/lib/plutonium/query/filters/date.rb +97 -0
  108. data/lib/plutonium/query/filters/date_range.rb +58 -0
  109. data/lib/plutonium/query/filters/select.rb +55 -0
  110. data/lib/plutonium/resource/controllers/crud_actions.rb +24 -6
  111. data/lib/plutonium/resource/controllers/interactive_actions.rb +76 -58
  112. data/lib/plutonium/resource/controllers/queryable.rb +4 -2
  113. data/lib/plutonium/resource/query_object.rb +1 -1
  114. data/lib/plutonium/ui/action_button.rb +23 -65
  115. data/lib/plutonium/ui/actions_dropdown.rb +103 -0
  116. data/lib/plutonium/ui/block.rb +1 -1
  117. data/lib/plutonium/ui/breadcrumbs.rb +12 -19
  118. data/lib/plutonium/ui/color_mode_selector.rb +1 -1
  119. data/lib/plutonium/ui/component/kit.rb +6 -0
  120. data/lib/plutonium/ui/component_classes.rb +102 -0
  121. data/lib/plutonium/ui/display/base.rb +15 -0
  122. data/lib/plutonium/ui/display/components/attachment.rb +6 -5
  123. data/lib/plutonium/ui/display/components/boolean.rb +23 -0
  124. data/lib/plutonium/ui/display/components/color.rb +23 -0
  125. data/lib/plutonium/ui/display/resource.rb +1 -1
  126. data/lib/plutonium/ui/display/theme.rb +29 -15
  127. data/lib/plutonium/ui/empty_card.rb +3 -3
  128. data/lib/plutonium/ui/form/base.rb +20 -0
  129. data/lib/plutonium/ui/form/components/key_value_store.rb +11 -11
  130. data/lib/plutonium/ui/form/components/resource_select.rb +31 -0
  131. data/lib/plutonium/ui/form/components/secure_association.rb +1 -2
  132. data/lib/plutonium/ui/form/components/uppy.rb +5 -4
  133. data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +4 -4
  134. data/lib/plutonium/ui/form/interaction.rb +17 -1
  135. data/lib/plutonium/ui/form/query.rb +133 -80
  136. data/lib/plutonium/ui/form/theme.rb +50 -35
  137. data/lib/plutonium/ui/frame_navigator_panel.rb +2 -2
  138. data/lib/plutonium/ui/layout/base.rb +1 -1
  139. data/lib/plutonium/ui/layout/header.rb +4 -7
  140. data/lib/plutonium/ui/layout/rodauth_layout.rb +7 -7
  141. data/lib/plutonium/ui/layout/sidebar.rb +1 -1
  142. data/lib/plutonium/ui/nav_grid_menu.rb +7 -6
  143. data/lib/plutonium/ui/nav_user.rb +9 -8
  144. data/lib/plutonium/ui/page/interactive_action.rb +5 -5
  145. data/lib/plutonium/ui/page_header.rb +29 -10
  146. data/lib/plutonium/ui/panel.rb +4 -4
  147. data/lib/plutonium/ui/sidebar_menu.rb +8 -8
  148. data/lib/plutonium/ui/skeleton_table.rb +7 -8
  149. data/lib/plutonium/ui/tab_list.rb +5 -5
  150. data/lib/plutonium/ui/table/base.rb +3 -0
  151. data/lib/plutonium/ui/table/components/attachment.rb +4 -3
  152. data/lib/plutonium/ui/table/components/bulk_actions_toolbar.rb +82 -0
  153. data/lib/plutonium/ui/table/components/pagy_info.rb +2 -2
  154. data/lib/plutonium/ui/table/components/pagy_pagination.rb +13 -8
  155. data/lib/plutonium/ui/table/components/row_actions_dropdown.rb +101 -0
  156. data/lib/plutonium/ui/table/components/scopes_bar.rb +2 -2
  157. data/lib/plutonium/ui/table/components/selection_column.rb +100 -0
  158. data/lib/plutonium/ui/table/display_theme.rb +6 -6
  159. data/lib/plutonium/ui/table/resource.rb +93 -52
  160. data/lib/plutonium/ui/table/theme.rb +28 -15
  161. data/lib/plutonium/version.rb +1 -1
  162. data/package.json +2 -2
  163. data/plutonium.gemspec +5 -4
  164. data/src/css/components.css +471 -0
  165. data/src/css/intl_tel_input.css +2 -2
  166. data/src/css/plutonium.css +2 -0
  167. data/src/css/tokens.css +149 -0
  168. data/src/js/controllers/bulk_actions_controller.js +109 -0
  169. data/src/js/controllers/filter_panel_controller.js +35 -0
  170. data/src/js/controllers/register_controllers.js +5 -1
  171. data/src/js/controllers/resource_drop_down_controller.js +25 -1
  172. data/src/js/controllers/slim_select_controller.js +6 -2
  173. data/src/js/turbo/turbo_actions.js +1 -1
  174. metadata +52 -39
  175. data/.claude/skills/definition-query/SKILL.md +0 -334
  176. data/docs/concepts/architecture.md +0 -226
  177. data/docs/concepts/auto-detection.md +0 -254
  178. data/docs/concepts/index.md +0 -61
  179. data/docs/concepts/packages-portals.md +0 -304
  180. data/docs/concepts/resources.md +0 -224
  181. data/docs/cookbook/blog.md +0 -411
  182. data/docs/cookbook/index.md +0 -289
  183. data/docs/cookbook/saas.md +0 -481
  184. data/docs/public/CLAUDE.md +0 -578
  185. data/lib/generators/pu/pkg/portal/templates/app/controllers/resource_controller.rb.tt +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 928572413dcc6ef2e0d2e7ad258ccd1728d1d6ace9ae921abe6ae9eba89733f3
4
- data.tar.gz: f94b0167a48c070d0425d5d1f42364d03786a83834b1071f791b70dfb72db421
3
+ metadata.gz: 81218e96d42c461a2bc5b61da7e338683b372547745ebbc177fe53ee2b5fa800
4
+ data.tar.gz: 960e4e769e69d71e7e081f873d1b1bfe0f4c1aaae1b155c453e83446abbe0f8d
5
5
  SHA512:
6
- metadata.gz: be38ab566496a59200dbb0dfe728ae85dc7c3d9fdbfb031b7501e9ac96b4fe69139618c7077fb7ea363aafa59388aee89681903d9c4223611044c59101ab17b6
7
- data.tar.gz: a1d51393fe914ddecb1b339c36a0a2d4fd8f69cc995291e4d383fdeeae815419ce1f564854e3b4aace31d119ca1eddaa687ed7d87fce7e30b1fa8db07f98ae4d
6
+ metadata.gz: 3ce18e3627917b3dbb7564352101bb0bd55e6a78c0bcd7fdad75e923620830f407597fc4d140659207f3346e789a74ec5d035d176520b496c6d7c4e0efa421d9
7
+ data.tar.gz: 5215e2e874ebdfb05bbdd997f75f68178ae7e73f81abcd47e0f0d2be771d4f2a37762fbaaec522811341bd9b4a6aafbe61e2b8a5e189b0cd68745694915cc97a
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: plutonium
3
+ description: High-level guide for working with Plutonium applications - read this first
4
+ ---
5
+
6
+ # Plutonium Development Guide
7
+
8
+ Read this first when working on a Plutonium application.
9
+
10
+ ## Core Rules
11
+
12
+ 1. **Always use generators** - Never manually create resources, packages, or portals
13
+ 2. **Check relevant skills first** - Each concept has a dedicated skill with details
14
+ 3. **Definitions over controllers** - UI customization belongs in definitions, not controllers
15
+ 4. **Policies for authorization** - All permission logic goes in policies
16
+
17
+ ## Key Generators
18
+
19
+ ```bash
20
+ rails g pu:res:scaffold Post title:string --dest=main_app # Create resource
21
+ rails g pu:res:conn Post --dest=admin_portal # Connect to portal
22
+ rails g pu:pkg:package blogging # Create feature package
23
+ rails g pu:pkg:portal admin_portal # Create portal
24
+ ```
25
+
26
+ Always specify `--dest` to avoid interactive prompts.
27
+
28
+ ## Resource Architecture
29
+
30
+ A resource has four layers:
31
+
32
+ | Layer | Purpose | Customize when... |
33
+ |-------|---------|-------------------|
34
+ | Model | Data, validations, associations | Adding business logic |
35
+ | Definition | UI - fields, actions, filters | Changing how things look/behave |
36
+ | Policy | Authorization - who can do what | Restricting access |
37
+ | Controller | Request handling | Rarely - use hooks if needed |
38
+
39
+ ## Skill Reference
40
+
41
+ | Topic | Skill |
42
+ |-------|-------|
43
+ | Creating resources | `plutonium-create-resource` |
44
+ | Connecting to portals | `plutonium-connect-resource` |
45
+ | Field configuration | `plutonium-definition-fields` |
46
+ | Actions & interactions | `plutonium-definition-actions` |
47
+ | Search, filters, scopes | `plutonium-definition-query` |
48
+ | Authorization | `plutonium-policy` |
49
+ | Custom views | `plutonium-views` |
50
+ | Custom forms | `plutonium-forms` |
51
+ | Nested resources | `plutonium-nested-resources` |
52
+ | Packages & portals | `plutonium-package`, `plutonium-portal` |
53
+ | Authentication | `plutonium-rodauth` |
@@ -1,12 +1,14 @@
1
1
  ---
2
- name: assets
3
- description: Plutonium assets and theming - TailwindCSS configuration, custom styling, and component themes
2
+ name: plutonium-assets
3
+ description: Plutonium asset setup - TailwindCSS configuration, Stimulus controllers, and Phlexi component themes
4
4
  ---
5
5
 
6
- # Plutonium Assets & Theming
6
+ # Plutonium Assets & Setup
7
7
 
8
8
  Plutonium uses TailwindCSS 4 for styling with a customizable theme system for components.
9
9
 
10
+ > **Note:** For CSS design tokens (`--pu-*` variables) and component classes (`.pu-btn`, `.pu-input`, etc.), see the `plutonium-theming` skill.
11
+
10
12
  ## Asset Configuration
11
13
 
12
14
  Configure assets in the initializer:
@@ -154,9 +156,11 @@ Plutonium includes a color mode selector component that handles this automatical
154
156
  - International telephone input styles
155
157
  - Flatpickr (date picker) styles
156
158
 
157
- ## Component Themes
159
+ ## Component Themes (Phlexi)
160
+
161
+ Plutonium components use a theme system based on Phlexi for customizing Form, Display, and Table components. Each component type has a theme class with named style tokens.
158
162
 
159
- Plutonium components use a theme system based on Phlexi. Each component type has a theme class with named style tokens.
163
+ > **Note:** This is different from the CSS design token system (`.pu-*` classes). For pre-built component classes, see `plutonium-theming`.
160
164
 
161
165
  ### Form Theme
162
166
 
@@ -411,6 +415,7 @@ theme: {
411
415
 
412
416
  ## Related Skills
413
417
 
414
- - `views` - Layout customization
415
- - `forms` - Form theming
416
- - `installation` - Initial setup
418
+ - `plutonium-theming` - CSS design tokens and component classes (`.pu-*`)
419
+ - `plutonium-views` - Layout customization
420
+ - `plutonium-forms` - Form theming
421
+ - `plutonium-installation` - Initial setup
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: connect-resource
2
+ name: plutonium-connect-resource
3
3
  description: Connect existing resources to portals for web access
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: controller
2
+ name: plutonium-controller
3
3
  description: Plutonium resource controllers - CRUD actions, customization, and integration
4
4
  ---
5
5
 
@@ -269,16 +269,30 @@ end
269
269
 
270
270
  ## Portal-Specific Controllers
271
271
 
272
- Each portal can have its own controller override:
272
+ Each portal can have its own controller override. Portal controllers inherit from the feature package's controller:
273
273
 
274
274
  ```ruby
275
275
  # packages/admin_portal/app/controllers/admin_portal/posts_controller.rb
276
- module AdminPortal
277
- class PostsController < ResourceController
278
- private
276
+ class AdminPortal::PostsController < ::PostsController
277
+ include AdminPortal::Concerns::Controller
278
+
279
+ private
280
+
281
+ def preferred_action_after_submit
282
+ "index" # Admin prefers list view
283
+ end
284
+ end
285
+ ```
286
+
287
+ Controllers are auto-created if not defined. When accessing a portal resource, Plutonium dynamically creates the controller by inheriting from the feature package's controller.
279
288
 
280
- def preferred_action_after_submit
281
- "index" # Admin prefers list view
289
+ For non-resource portal pages (dashboard, settings), inherit from `PlutoniumController`:
290
+
291
+ ```ruby
292
+ module AdminPortal
293
+ class DashboardController < PlutoniumController
294
+ def index
295
+ # Dashboard home
282
296
  end
283
297
  end
284
298
  end
@@ -294,9 +308,9 @@ end
294
308
 
295
309
  ## Related Skills
296
310
 
297
- - `resource` - How controllers fit in the resource architecture
298
- - `policy` - Authorization (used by controllers)
299
- - `definition-actions` - Interactive actions (preferred over custom controller actions)
300
- - `views` - Custom page, form, display, and table classes
301
- - `nested-resources` - Parent/child routes and scoping
302
- - `model` - Resource models
311
+ - `plutonium-resource` - How controllers fit in the resource architecture
312
+ - `plutonium-policy` - Authorization (used by controllers)
313
+ - `plutonium-definition-actions` - Interactive actions (preferred over custom controller actions)
314
+ - `plutonium-views` - Custom page, form, display, and table classes
315
+ - `plutonium-nested-resources` - Parent/child routes and scoping
316
+ - `plutonium-model` - Resource models
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: create-resource
2
+ name: plutonium-create-resource
3
3
  description: Generate Plutonium resources with models, migrations, controllers, policies, and definitions
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: definition
2
+ name: plutonium-definition
3
3
  description: Overview of Plutonium resource definitions - structure, inheritance, and best practices
4
4
  ---
5
5
 
@@ -21,7 +21,7 @@ Resource definitions configure **HOW** resources are rendered and interacted wit
21
21
  ```ruby
22
22
  class PostDefinition < Plutonium::Resource::Definition
23
23
  # Fields, inputs, displays, columns (see definition-fields skill)
24
- field :content, as: :rich_text
24
+ field :content, as: :markdown
25
25
  input :title, hint: "Be descriptive"
26
26
  display :content, as: :markdown
27
27
  column :title, align: :center
@@ -52,7 +52,7 @@ end
52
52
  # app/definitions/post_definition.rb (resource-specific - created by scaffold)
53
53
  class PostDefinition < ResourceDefinition
54
54
  scope :published
55
- input :content, as: :rich_text
55
+ input :content, as: :markdown
56
56
  end
57
57
  ```
58
58
 
@@ -79,7 +79,7 @@ This lets you:
79
79
 
80
80
  | Layer | Purpose | Example |
81
81
  |-------|---------|---------|
82
- | **Definition** | HOW fields render | `input :content, as: :rich_text` |
82
+ | **Definition** | HOW fields render | `input :content, as: :markdown` |
83
83
  | **Policy** | WHAT is visible/editable | `permitted_attributes_for_read` |
84
84
  | **Interaction** | Business logic | `resource.update!(state: :archived)` |
85
85
 
@@ -99,7 +99,7 @@ Plutonium automatically detects from your model:
99
99
  ```ruby
100
100
  class PostDefinition < ResourceDefinition
101
101
  # 1. Override auto-detected type
102
- field :content, as: :rich_text # text -> rich_text
102
+ field :content, as: :markdown # text -> rich_text
103
103
  input :published_at, as: :date # datetime -> date only
104
104
 
105
105
  # 2. Add custom options
@@ -125,7 +125,7 @@ class PostDefinition < ResourceDefinition
125
125
  # No field declarations needed - all auto-detected!
126
126
 
127
127
  # Only customize what you need:
128
- input :content, as: :rich_text
128
+ input :content, as: :markdown
129
129
  display :content, as: :markdown
130
130
 
131
131
  scope :published
@@ -212,7 +212,7 @@ end
212
212
 
213
213
  ## Related Skills
214
214
 
215
- - `definition-fields` - Fields, inputs, displays, columns
216
- - `definition-actions` - Actions and interactions
217
- - `definition-query` - Search, filters, scopes, sorting
218
- - `views` - Custom page, form, display, and table classes
215
+ - `plutonium-definition-fields` - Fields, inputs, displays, columns
216
+ - `plutonium-definition-actions` - Actions and interactions
217
+ - `plutonium-definition-query` - Search, filters, scopes, sorting
218
+ - `plutonium-views` - Custom page, form, display, and table classes
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: definition-actions
2
+ name: plutonium-definition-actions
3
3
  description: Add custom actions and interactions to Plutonium resources
4
4
  ---
5
5
 
@@ -145,7 +145,12 @@ end
145
145
 
146
146
  ### Bulk Action (Multiple Records)
147
147
 
148
+ Bulk actions operate on multiple selected records at once. When a definition has bulk actions, the resource table automatically shows:
149
+ - **Selection checkboxes** in each row
150
+ - **Bulk actions toolbar** that appears when records are selected
151
+
148
152
  ```ruby
153
+ # 1. Create the interaction (note: plural `resources` attribute)
149
154
  class BulkArchiveInteraction < Plutonium::Resource::Interaction
150
155
  presents label: "Archive Selected", icon: Phlex::TablerIcons::Archive
151
156
 
@@ -162,8 +167,26 @@ class BulkArchiveInteraction < Plutonium::Resource::Interaction
162
167
  failed("Bulk archive failed: #{error.message}")
163
168
  end
164
169
  end
170
+
171
+ # 2. Register the action in the definition
172
+ class PostDefinition < ResourceDefinition
173
+ action :bulk_archive, interaction: BulkArchiveInteraction
174
+ # bulk_action: true is automatically inferred from `resources` attribute
175
+ end
176
+
177
+ # 3. Add policy method
178
+ class PostPolicy < ResourcePolicy
179
+ def bulk_archive?
180
+ create? # Or whatever permission level is appropriate
181
+ end
182
+ end
165
183
  ```
166
184
 
185
+ **Authorization for bulk actions:**
186
+ - Policy method (e.g., `bulk_archive?`) is checked **per record** - the backend fails the entire request if any selected record is not authorized
187
+ - Records are fetched via `current_authorized_scope` - only records the user can access are included
188
+ - The UI only shows action buttons that **all** selected records support (intersection of allowed actions)
189
+
167
190
  ### Resource Action (No Record)
168
191
 
169
192
  ```ruby
@@ -188,12 +211,12 @@ end
188
211
 
189
212
  ```ruby
190
213
  def execute
191
- # Success with message
214
+ # Success with message (redirects to resource automatically)
192
215
  succeed(resource).with_message("Done!")
193
216
 
194
- # Success with redirect
217
+ # Success with custom redirect (only if different from default)
195
218
  succeed(resource)
196
- .with_redirect_response(resource_url_for(resource))
219
+ .with_redirect_response(custom_dashboard_path)
197
220
  .with_message("Redirecting...")
198
221
 
199
222
  # Failure with field errors
@@ -207,6 +230,8 @@ def execute
207
230
  end
208
231
  ```
209
232
 
233
+ **Note:** Redirect is automatic on success. Only use `with_redirect_response` for a different destination.
234
+
210
235
  ## Interaction Context
211
236
 
212
237
  Inside an interaction:
@@ -379,8 +404,8 @@ end
379
404
 
380
405
  ## Related Skills
381
406
 
382
- - `definition` - Overview and structure
383
- - `definition-fields` - Fields, inputs, displays
384
- - `definition-query` - Search, filters, scopes
385
- - `interaction` - Writing interaction classes
386
- - `policy` - Controlling action access
407
+ - `plutonium-definition` - Overview and structure
408
+ - `plutonium-definition-fields` - Fields, inputs, displays
409
+ - `plutonium-definition-query` - Search, filters, scopes
410
+ - `plutonium-interaction` - Writing interaction classes
411
+ - `plutonium-policy` - Controlling action access
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: definition-fields
2
+ name: plutonium-definition-fields
3
3
  description: Configure how resource fields are rendered in forms, show pages, and tables
4
4
  ---
5
5
 
@@ -21,7 +21,7 @@ Configure how fields are rendered using `field`, `input`, `display`, and `column
21
21
  ```ruby
22
22
  class PostDefinition < ResourceDefinition
23
23
  # field - changes type everywhere
24
- field :content, as: :rich_text
24
+ field :content, as: :markdown
25
25
 
26
26
  # input - form-specific
27
27
  input :title,
@@ -48,7 +48,7 @@ end
48
48
  | Category | Types |
49
49
  |----------|-------|
50
50
  | **Text** | `:string`, `:text`, `:email`, `:url`, `:tel`, `:password` |
51
- | **Rich Text** | `:rich_text`, `:markdown` |
51
+ | **Rich Text** | `:markdown` (EasyMDE editor) |
52
52
  | **Numeric** | `:number`, `:integer`, `:decimal`, `:range` |
53
53
  | **Boolean** | `:boolean` |
54
54
  | **Date/Time** | `:date`, `:time`, `:datetime` |
@@ -311,7 +311,9 @@ input :color_picker, as: ColorPickerComponent
311
311
  display :chart, as: ChartComponent
312
312
  ```
313
313
 
314
- ## Column Alignment
314
+ ## Column Options
315
+
316
+ ### Alignment
315
317
 
316
318
  ```ruby
317
319
  column :title, align: :start # Left (default)
@@ -319,6 +321,32 @@ column :status, align: :center # Center
319
321
  column :amount, align: :end # Right
320
322
  ```
321
323
 
324
+ ### Custom Column Rendering
325
+
326
+ Use a block to customize how a column value is displayed. The block receives the raw record:
327
+
328
+ ```ruby
329
+ column :price do |record|
330
+ "$#{"%.2f" % record.price}" if record.price
331
+ end
332
+
333
+ column :status do |record|
334
+ case record.status
335
+ when 'active' then "✓ Active"
336
+ when 'pending' then "⏳ Pending"
337
+ else record.status.humanize
338
+ end
339
+ end
340
+
341
+ column :description do |record|
342
+ record.description&.truncate(50)
343
+ end
344
+
345
+ column :author do |record|
346
+ record.author&.name || "Unknown"
347
+ end
348
+ ```
349
+
322
350
  ## Nested Inputs
323
351
 
324
352
  Render inline forms for associated records. Requires `accepts_nested_attributes_for` on the model.
@@ -425,7 +453,7 @@ input :documents, as: :uppy,
425
453
  ### Rich Text Content
426
454
 
427
455
  ```ruby
428
- field :content, as: :rich_text # Form: rich editor
456
+ field :content, as: :markdown # Form: rich editor
429
457
  display :content, as: :markdown # Show: rendered markdown
430
458
  ```
431
459
 
@@ -467,8 +495,8 @@ Inside `condition` procs and `input` blocks:
467
495
 
468
496
  ## Related Skills
469
497
 
470
- - `definition` - Overview and structure
471
- - `definition-actions` - Actions and interactions
472
- - `definition-query` - Search, filters, scopes
473
- - `forms` - Custom form templates and field builders
474
- - `views` - Custom page and display templates
498
+ - `plutonium-definition` - Overview and structure
499
+ - `plutonium-definition-actions` - Actions and interactions
500
+ - `plutonium-definition-query` - Search, filters, scopes
501
+ - `plutonium-forms` - Custom form templates and field builders
502
+ - `plutonium-views` - Custom page and display templates