plutonium 0.50.0 → 0.52.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 +574 -0
- data/.claude/skills/plutonium-auth/SKILL.md +167 -302
- 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 +674 -0
- data/.claude/skills/plutonium-testing/SKILL.md +9 -6
- data/.claude/skills/plutonium-ui/SKILL.md +900 -0
- data/CHANGELOG.md +44 -2
- data/Rakefile +2 -1
- data/app/assets/plutonium.css +1 -11
- data/app/assets/plutonium.js +1010 -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 +38 -29
- data/docs/.vitepress/theme/components/HomeAudienceSplit.vue +53 -0
- data/docs/.vitepress/theme/components/HomeCta.vue +108 -0
- data/docs/.vitepress/theme/components/HomeHero.vue +70 -0
- data/docs/.vitepress/theme/components/HomeInTheBox.vue +74 -0
- data/docs/.vitepress/theme/components/HomePillars.vue +42 -0
- data/docs/.vitepress/theme/components/HomeStopWriting.vue +49 -0
- data/docs/.vitepress/theme/components/HomeWalkthrough.vue +111 -0
- data/docs/.vitepress/theme/components/SectionLanding.vue +115 -0
- data/docs/.vitepress/theme/custom.css +144 -0
- data/docs/.vitepress/theme/index.ts +58 -1
- data/docs/getting-started/index.md +33 -57
- data/docs/getting-started/installation.md +37 -80
- data/docs/getting-started/tutorial/02-first-resource.md +17 -8
- data/docs/getting-started/tutorial/03-authentication.md +31 -23
- data/docs/getting-started/tutorial/05-custom-actions.md +9 -4
- data/docs/getting-started/tutorial/06-nested-resources.md +7 -1
- data/docs/getting-started/tutorial/07-author-portal.md +8 -0
- data/docs/getting-started/tutorial/08-customizing-ui.md +4 -0
- data/docs/getting-started/tutorial/index.md +4 -5
- data/docs/guides/adding-resources.md +66 -377
- data/docs/guides/authentication.md +98 -462
- data/docs/guides/authorization.md +124 -370
- data/docs/guides/creating-packages.md +93 -298
- data/docs/guides/custom-actions.md +126 -441
- data/docs/guides/customizing-ui.md +258 -0
- data/docs/guides/index.md +49 -52
- data/docs/guides/multi-tenancy.md +123 -186
- data/docs/guides/nested-resources.md +137 -396
- data/docs/guides/search-filtering.md +127 -238
- data/docs/guides/testing.md +10 -5
- data/docs/guides/theming.md +168 -405
- data/docs/guides/troubleshooting.md +5 -3
- data/docs/guides/user-invites.md +112 -425
- data/docs/guides/user-profile.md +82 -241
- data/docs/index.md +10 -219
- data/docs/public/asciinema/home-scaffold.cast +305 -0
- data/docs/public/images/guides/custom-actions-bulk.png +0 -0
- data/docs/public/images/guides/multi-tenancy-dashboard.png +0 -0
- data/docs/public/images/guides/multi-tenancy-welcome.png +0 -0
- data/docs/public/images/guides/nested-inputs.png +0 -0
- data/docs/public/images/guides/nested-resources-tab.png +0 -0
- data/docs/public/images/guides/search-filtering-index.png +0 -0
- data/docs/public/images/guides/search-filtering-panel.png +0 -0
- data/docs/public/images/guides/theming-after.png +0 -0
- data/docs/public/images/guides/theming-before.png +0 -0
- data/docs/public/images/guides/user-invites-landing.png +0 -0
- data/docs/public/images/guides/user-profile-edit.png +0 -0
- data/docs/public/images/guides/user-profile-show.png +0 -0
- data/docs/public/images/home-index.png +0 -0
- data/docs/public/images/home-new.png +0 -0
- data/docs/public/images/home-show.png +0 -0
- data/docs/public/images/tutorial/02-empty-index.png +0 -0
- data/docs/public/images/tutorial/02-index-with-posts.png +0 -0
- data/docs/public/images/tutorial/02-new-form-modal.png +0 -0
- data/docs/public/images/tutorial/02-new-form.png +0 -0
- data/docs/public/images/tutorial/03-create-account.png +0 -0
- data/docs/public/images/tutorial/03-login.png +0 -0
- data/docs/public/images/tutorial/04-admin-index.png +0 -0
- data/docs/public/images/tutorial/05-actions-menu.png +0 -0
- data/docs/public/images/tutorial/05-row-actions.png +0 -0
- data/docs/public/images/tutorial/06-comments-tab.png +0 -0
- data/docs/public/images/tutorial/06-post-with-comments.png +0 -0
- data/docs/public/images/tutorial/07-author-dashboard.png +0 -0
- data/docs/public/images/tutorial/07-author-portal.png +0 -0
- data/docs/public/images/tutorial/08-customized-index.png +0 -0
- 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 +229 -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 +67 -48
- 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 +368 -0
- data/docs/reference/tenancy/index.md +36 -0
- data/docs/reference/tenancy/invites.md +400 -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 +121 -0
- data/docs/superpowers/plans/2026-05-15-public-pages-overhaul.md +1648 -0
- data/docs/superpowers/plans/2026-05-15-public-pages-overhaul.md.tasks.json +109 -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/docs/superpowers/specs/2026-05-15-public-pages-overhaul-design.md +263 -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/assets/assets_generator.rb +10 -0
- data/lib/generators/pu/core/update/update_generator.rb +0 -20
- data/lib/generators/pu/invites/install_generator.rb +45 -0
- data/lib/generators/pu/invites/templates/packages/invites/app/controllers/invites/user_invitations_controller.rb.tt +1 -0
- data/lib/generators/pu/profile/conn_generator.rb +2 -2
- data/lib/generators/pu/res/conn/conn_generator.rb +33 -6
- data/lib/generators/pu/res/model/templates/model.rb.tt +4 -0
- data/lib/generators/pu/rodauth/account_generator.rb +2 -1
- data/lib/generators/pu/rodauth/admin_generator.rb +0 -2
- data/lib/generators/pu/rodauth/migration_generator.rb +0 -2
- data/lib/generators/pu/rodauth/views_generator.rb +0 -2
- data/lib/generators/pu/saas/membership/USAGE +4 -1
- data/lib/generators/pu/saas/setup_generator.rb +16 -4
- data/lib/generators/pu/saas/welcome/templates/app/controllers/welcome_controller.rb.tt +1 -1
- 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 +30 -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 +23 -5
- data/lib/plutonium/resource/controllers/interactive_actions.rb +3 -3
- 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 +5 -0
- data/lib/plutonium/ui/form/base.rb +23 -3
- 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 +103 -22
- data/lib/plutonium/ui/form/concerns/typeahead_attributes.rb +83 -0
- data/lib/plutonium/ui/form/interaction.rb +1 -1
- data/lib/plutonium/ui/form/resource.rb +0 -4
- data/lib/plutonium/ui/form/theme.rb +1 -1
- 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/edit.rb +1 -1
- data/lib/plutonium/ui/page/index.rb +4 -4
- data/lib/plutonium/ui/page/new.rb +1 -1
- data/lib/plutonium/ui/table/components/filter_form.rb +12 -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 +13 -10
- data/src/css/slim_select.css +4 -0
- data/src/js/controllers/form_controller.js +5 -4
- data/src/js/controllers/slim_select_controller.js +61 -0
- data/src/js/turbo/turbo_actions.js +33 -0
- data/yarn.lock +661 -544
- metadata +86 -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
|
@@ -12,23 +12,27 @@ Rodauth is a Ruby authentication framework that Plutonium uses for:
|
|
|
12
12
|
|
|
13
13
|
Plutonium integrates Rodauth seamlessly with its portal system.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Installing Rodauth
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Run the Plutonium Rodauth installer once per app — it creates the Rodauth app, plugin, and initializer:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
rails generate pu:rodauth:install
|
|
21
|
-
rails db:migrate
|
|
22
21
|
```
|
|
23
22
|
|
|
23
|
+
(No migration is needed yet; the account-type generator below creates its own tables.)
|
|
24
|
+
|
|
24
25
|
## Creating an Account Type
|
|
25
26
|
|
|
26
|
-
Plutonium supports multiple account types. For
|
|
27
|
+
Plutonium supports multiple account types. For admins, use the dedicated `pu:rodauth:admin` generator — it's a preset on top of `pu:rodauth:account` that enables 2FA, lockout, audit logging, and disables public signup:
|
|
27
28
|
|
|
28
29
|
```bash
|
|
29
30
|
rails generate pu:rodauth:admin admin
|
|
31
|
+
rails db:migrate
|
|
30
32
|
```
|
|
31
33
|
|
|
34
|
+
For self-service user accounts, the corresponding command is `rails generate pu:rodauth:account user`.
|
|
35
|
+
|
|
32
36
|
This creates:
|
|
33
37
|
|
|
34
38
|
### Account Model (`app/models/admin.rb`)
|
|
@@ -57,30 +61,28 @@ end
|
|
|
57
61
|
|
|
58
62
|
The generator also creates migrations for the account table and authentication features.
|
|
59
63
|
|
|
60
|
-
##
|
|
64
|
+
## Gating the Portal with Authentication
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
In [Chapter 2](./02-first-resource) you generated the admin portal with `--public`. Now that you have an `admin` Rodauth account, swap the portal over to require login. The fastest way is to re-run the portal generator with `--auth=admin --force`:
|
|
63
67
|
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
module AdminPortal
|
|
67
|
-
module Concerns
|
|
68
|
-
module Controller
|
|
69
|
-
extend ActiveSupport::Concern
|
|
70
|
-
include Plutonium::Portal::Controller
|
|
71
|
-
include Plutonium::Auth::Rodauth(:admin)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
68
|
+
```bash
|
|
69
|
+
rails generate pu:pkg:portal admin --auth=admin --force
|
|
75
70
|
```
|
|
76
71
|
|
|
77
|
-
This
|
|
72
|
+
This updates two files:
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
- `packages/admin_portal/app/controllers/admin_portal/concerns/controller.rb` — swaps `include Plutonium::Auth::Public` for `include Plutonium::Auth::Rodauth(:admin)`, giving you `current_user`, `logout_url`, and `profile_url` helpers throughout the portal.
|
|
75
|
+
- `packages/admin_portal/config/routes.rb` — wraps the engine mount in a routes-level constraint:
|
|
80
76
|
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
```ruby
|
|
78
|
+
constraints Rodauth::Rails.authenticate(:admin) do
|
|
79
|
+
mount AdminPortal::Engine, at: "/admin"
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The routes constraint is what actually gates access — unauthenticated requests to `/admin/*` are redirected to `/admins/login` before they hit any controller or policy.
|
|
84
|
+
|
|
85
|
+
(If you prefer not to regenerate, you can apply both edits by hand — they're shown above.)
|
|
84
86
|
|
|
85
87
|
## Testing Authentication
|
|
86
88
|
|
|
@@ -90,7 +92,13 @@ Restart your server:
|
|
|
90
92
|
bin/dev
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
Visit `http://localhost:3000/admin/blogging/posts`. You'll be redirected to the login page
|
|
95
|
+
Visit `http://localhost:3000/admin/blogging/posts`. You'll be redirected to the login page:
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
The "Create a New Account" link goes to the same Rodauth-rendered account creation form:
|
|
100
|
+
|
|
101
|
+

|
|
94
102
|
|
|
95
103
|
### Creating an Admin Account
|
|
96
104
|
|
|
@@ -79,10 +79,15 @@ end
|
|
|
79
79
|
|
|
80
80
|
## Testing the Action
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
Open any unpublished post and click **Actions** in the top-right — the "Publish Post" item appears with its Tabler icon:
|
|
83
|
+
|
|
84
|
+

|
|
85
|
+
|
|
86
|
+
It also shows on each table row's `⋮` menu — same action, available wherever the record is rendered:
|
|
87
|
+
|
|
88
|
+

|
|
89
|
+
|
|
90
|
+
Click "Publish Post" and the post is updated; the flash banner confirms success.
|
|
86
91
|
|
|
87
92
|
## Actions with User Input
|
|
88
93
|
|
|
@@ -69,7 +69,13 @@ class Blogging::PostPolicy < Blogging::ResourcePolicy
|
|
|
69
69
|
end
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
The
|
|
72
|
+
The post show page now has tabs — **Details** and **Comments** — driven by the associations you permit:
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
Clicking **Comments** opens the nested index for that post — a complete sub-resource view with its own paginated table, "New" button, and row actions:
|
|
77
|
+
|
|
78
|
+

|
|
73
79
|
|
|
74
80
|
## Comment Policy
|
|
75
81
|
|
|
@@ -168,6 +168,14 @@ Now you have two portals:
|
|
|
168
168
|
| Admin | `/admin` | Admin | All posts |
|
|
169
169
|
| Author | `/author` | User | Own posts only |
|
|
170
170
|
|
|
171
|
+
Log in at `/users/login` with the user account and you land on the Author Portal dashboard — the same chrome as the Admin Portal but mounted at `/author`, gated by `Rodauth::Rails.authenticate(:user)`:
|
|
172
|
+
|
|
173
|
+

|
|
174
|
+
|
|
175
|
+
The posts list lives at `/author/blogging/posts` — same `Blogging::Post` resource, different portal context (and once you add the scoping policy below, scoped to the logged-in author):
|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
|
|
171
179
|
### Test the difference:
|
|
172
180
|
|
|
173
181
|
1. **Create an Admin account** at `/admin/register`
|
|
@@ -117,6 +117,10 @@ class Blogging::PostDefinition < Blogging::ResourceDefinition
|
|
|
117
117
|
end
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
The default "Posts" heading becomes your branded title and description:
|
|
121
|
+
|
|
122
|
+

|
|
123
|
+
|
|
120
124
|
For more advanced customization, you can create custom page classes that inherit from Plutonium's page components:
|
|
121
125
|
|
|
122
126
|
```ruby
|
|
@@ -55,13 +55,12 @@ Create a second portal with different access levels for content authors.
|
|
|
55
55
|
### [8. Customizing the UI](./08-customizing-ui)
|
|
56
56
|
Customize forms, tables, and views to match your requirements.
|
|
57
57
|
|
|
58
|
-
## Getting
|
|
58
|
+
## Getting help
|
|
59
59
|
|
|
60
60
|
If you get stuck:
|
|
61
|
-
- Check the [Guides](/guides/) for detailed explanations
|
|
62
|
-
- Browse the [Reference Documentation](/reference/) for API details
|
|
63
|
-
- Visit our [GitHub Issues](https://github.com/radioactive-labs/plutonium-core/issues)
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
- Check the [Guides](/guides/) for task-oriented walkthroughs.
|
|
63
|
+
- Browse the [Reference](/reference/) for full API surface — [App](/reference/app/), [Resource](/reference/resource/), [Behavior](/reference/behavior/), [UI](/reference/ui/), [Auth](/reference/auth/), [Tenancy](/reference/tenancy/), [Testing](/reference/testing/).
|
|
64
|
+
- Visit [GitHub Issues](https://github.com/radioactive-labs/plutonium-core/issues).
|
|
66
65
|
|
|
67
66
|
[Begin Chapter 1: Project Setup →](./01-setup)
|