plutonium 0.58.1 → 0.60.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/plutonium-auth/SKILL.md +7 -1
  3. data/.claude/skills/plutonium-behavior/SKILL.md +4 -0
  4. data/.claude/skills/plutonium-resource/SKILL.md +49 -0
  5. data/CHANGELOG.md +16 -0
  6. data/app/assets/plutonium.css +1 -1
  7. data/docs/.vitepress/config.ts +1 -0
  8. data/docs/reference/auth/accounts.md +7 -0
  9. data/docs/reference/resource/actions.md +3 -0
  10. data/docs/reference/resource/definition.md +129 -0
  11. data/docs/reference/resource/export.md +94 -0
  12. data/docs/reference/ui/forms.md +51 -21
  13. data/docs/superpowers/plans/2026-06-14-form-sectioning.md +917 -0
  14. data/docs/superpowers/plans/2026-06-14-form-sectioning.md.tasks.json +40 -0
  15. data/docs/superpowers/specs/2026-06-12-export-csv-default-action-design.md +306 -0
  16. data/docs/superpowers/specs/2026-06-14-form-sectioning-design.md +237 -0
  17. data/gemfiles/rails_7.gemfile.lock +3 -1
  18. data/gemfiles/rails_8.0.gemfile.lock +3 -1
  19. data/gemfiles/rails_8.1.gemfile.lock +3 -1
  20. data/lib/generators/pu/lite/solid_errors/solid_errors_generator.rb +3 -3
  21. data/lib/generators/pu/rodauth/admin_generator.rb +5 -2
  22. data/lib/generators/pu/rodauth/migration_generator.rb +1 -1
  23. data/lib/generators/pu/rodauth/templates/app/interactions/resend_admin_interaction.rb.tt +18 -0
  24. data/lib/generators/pu/rodauth/views_generator.rb +1 -1
  25. data/lib/plutonium/definition/base.rb +4 -0
  26. data/lib/plutonium/definition/form_layout.rb +144 -0
  27. data/lib/plutonium/interaction/base.rb +1 -0
  28. data/lib/plutonium/package/engine.rb +17 -7
  29. data/lib/plutonium/query/filter.rb +4 -1
  30. data/lib/plutonium/query/filters/association.rb +1 -2
  31. data/lib/plutonium/resource/controller.rb +1 -0
  32. data/lib/plutonium/resource/controllers/export_csv.rb +162 -0
  33. data/lib/plutonium/resource/controllers/queryable.rb +1 -0
  34. data/lib/plutonium/resource/policy.rb +21 -0
  35. data/lib/plutonium/routing/mapper_extensions.rb +13 -0
  36. data/lib/plutonium/ui/export_button.rb +86 -0
  37. data/lib/plutonium/ui/form/components/section.rb +58 -0
  38. data/lib/plutonium/ui/form/resource.rb +85 -7
  39. data/lib/plutonium/ui/table/components/toolbar.rb +9 -2
  40. data/lib/plutonium/ui/table/resource.rb +18 -1
  41. data/lib/plutonium/version.rb +1 -1
  42. data/package.json +1 -1
  43. data/plutonium.gemspec +1 -0
  44. data/src/css/slim_select.css +11 -2
  45. metadata +26 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4aacffd8e85ac820827b65cc219e00cded934d37d879756ea808a8f9ba86fc26
4
- data.tar.gz: bc6d63a46c46f0f01b2351590b36ee54108a29372c4f9aa1d0d3922ab014f334
3
+ metadata.gz: 3fa2b8cea268efcf47ef9f1d599f0899ad89c86fb63b3bc7faa8451da9ddae14
4
+ data.tar.gz: 4c10a0e528713d73ab87012443ac6b1032c633487cf57b231bc1d956061b6aa0
5
5
  SHA512:
6
- metadata.gz: d29f628a11fdff4163c3430d225912902d07481fef1bc23bdacb23390cda5a063a604a3432929938a1c37bf7afc04aea643f1c0400d99478be62314d3ec8be89
7
- data.tar.gz: 52b66cfe37dde6f57dcb2cda8d8ab9369e585d0f8847d4af0e35b78f3af4bd5bad20a6c0de2840c872bc37fe34b45343538001308bd822c5f3bbc399b44e2b1b
6
+ metadata.gz: fdd98d0175ac22901548a4eb9dd82b52877aaec986dad07b635999a5b2a6bcccc52cc4b3034c85c3199657cd1c8c6dc496d6a8e9463b9f7de783fc504d8aa992
7
+ data.tar.gz: d59318593eb59b0976fb4a15f78b7a05a83c891ff0c2fb768610ee7ed8e6073f91812a6828b43ed19503d6b906431eb6b41b11cb5f1048c39cb2e638a277c9a5
@@ -70,7 +70,7 @@ rails generate pu:rodauth:account user [options]
70
70
 
71
71
  ### Admin account — `pu:rodauth:admin`
72
72
 
73
- Pre-configured secure admin with multi-phase login, required TOTP, recovery codes, lockout, active session tracking, audit logging, role-based access, invite interaction, and **no public signup**.
73
+ Pre-configured secure admin with multi-phase login, required TOTP, recovery codes, lockout, active session tracking, audit logging, role-based access, invite + resend-invite interactions, and **no public signup**.
74
74
 
75
75
  ```bash
76
76
  rails generate pu:rodauth:admin admin
@@ -89,6 +89,12 @@ rails generate pu:rodauth:admin admin --extra-attributes=name:string,department:
89
89
  enum :role, super_admin: 0, admin: 1
90
90
  ```
91
91
 
92
+ **Invite + resend actions.** The admin resource gets two actions:
93
+ - **Invite** — invite a new admin by email; they set their password via the verification link.
94
+ - **Resend invitation** — re-send that verification email, shown only for admins who haven't verified yet.
95
+
96
+ This is Rodauth account verification — distinct from the tenancy invitation system (see [[plutonium-tenancy]]).
97
+
92
98
  Rake task for direct admin creation (namespace is `rodauth`, task name is the account name):
93
99
 
94
100
  ```bash
@@ -375,6 +375,9 @@ end
375
375
  | `new?` | `create?` | Rarely needed |
376
376
  | `edit?` | `update?` | Rarely needed |
377
377
  | `search?` | `index?` | Search-specific rules |
378
+ | `typeahead?` | `index?` | Autocomplete-specific rules |
379
+
380
+ `export_csv?` is the exception — it defaults to `false` (not derived) so CSV export is strictly opt-in. Override it to `true` (or `index?`) to enable the built-in export. The exported column set is `permitted_attributes_for_export` (defaults to `permitted_attributes_for_index`). See [[plutonium-resource]] → CSV Export.
378
381
 
379
382
  ### Custom actions
380
383
 
@@ -423,6 +426,7 @@ end
423
426
  | `permitted_attributes_for_show` | `permitted_attributes_for_read` |
424
427
  | `permitted_attributes_for_new` | `permitted_attributes_for_create` |
425
428
  | `permitted_attributes_for_edit` | `permitted_attributes_for_update` |
429
+ | `permitted_attributes_for_export` | `permitted_attributes_for_index` (CSV export columns; primary key is always prepended) |
426
430
 
427
431
  ### Per-action override
428
432
 
@@ -1290,6 +1290,55 @@ end
1290
1290
  - **Immediate** — interaction has only `:resource` (or `:resources`) and no other inputs. Shows an auto-generated browser confirmation (`"#{label}?"`, e.g. `"Archive?"`) on click, then runs. Pass `confirmation: "Custom message"` to override, or `confirmation: false` to skip.
1291
1291
  - **Form** — interaction declares extra `attribute`/`input` beyond `:resource`/`:resources`. Renders a modal form first; no auto-confirmation (the form itself is the confirmation step).
1292
1292
 
1293
+ ## CSV Export (built-in)
1294
+
1295
+ Every resource has a streamed CSV export, **disabled by default**. It is not declared
1296
+ with `action :export_csv` — it's a policy-gated capability with its own split button.
1297
+ The route (`GET /<resources>/export_csv`) is auto-mounted; the button appears on the
1298
+ index page once the policy permits it. Enable it by overriding one policy method:
1299
+
1300
+ ```ruby
1301
+ class PostPolicy < ResourcePolicy
1302
+ def export_csv? = true # or `index?` to mirror list access
1303
+ end
1304
+ ```
1305
+
1306
+ **Two exports** (split button in the index toolbar, after Filter):
1307
+ - **Export** (primary) — the current view: selected scope + filters + search (the
1308
+ index's `?q`), all matching rows (not just the visible page). File: `posts_<date>.csv`.
1309
+ - **Export all** (dropdown) — the entire authorized scope, ignoring scope/filters/
1310
+ search (`?all=1`). File: `posts_all_<date>.csv`.
1311
+
1312
+ Both stream via `find_each` (memory-safe on large tables; primary-key order, so the
1313
+ file does not preserve the index sort).
1314
+
1315
+ - **Columns** = `permitted_attributes_for_export` (defaults to the index columns),
1316
+ with the **primary key always first**. Override to tailor:
1317
+
1318
+ ```ruby
1319
+ def permitted_attributes_for_export = [:title, :author, :total, :created_at]
1320
+ ```
1321
+
1322
+ - **Per-field output** — customize a cell's value and header in the definition with
1323
+ the `export` DSL (parallels `display`/`column`):
1324
+
1325
+ ```ruby
1326
+ class PostDefinition < ResourceDefinition
1327
+ export :author, label: "Author email", &->(post) { post.author.email }
1328
+ export :total, &->(post) { post.total.format }
1329
+ end
1330
+ ```
1331
+
1332
+ - **Without** an `export` block a column is read off the record: scalars as-is,
1333
+ associations as their `display_name_of` label (e.g. `User #5`, not `#<User:…>`). A
1334
+ computed/virtual column with no real method **needs** an `export` block (a `label:`-only
1335
+ `export` doesn't supply a value) — otherwise the cell renders `<<invalid column>>`.
1336
+ - **CSV/formula injection** is neutralized automatically (cells starting with `= + - @` or
1337
+ tab/CR get a leading `'`).
1338
+
1339
+ The button opens in a new tab (so the streamed download bypasses Turbo). Full reference:
1340
+ `docs/reference/resource/export.md`.
1341
+
1293
1342
  ---
1294
1343
 
1295
1344
  ## Related Skills
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [0.60.0] - 2026-06-14
2
+
3
+ ### 🚀 Features
4
+
5
+ - *(generators)* Add resend-invite action to rodauth admin
6
+ - *(forms)* Form sectioning DSL (form_layout / section / ungrouped) (#61)
7
+ ## [0.59.0] - 2026-06-13
8
+
9
+ ### 🚀 Features
10
+
11
+ - *(resource)* Add built-in policy-gated CSV export
12
+
13
+ ### 🐛 Bug Fixes
14
+
15
+ - *(generators)* Configure solid_errors reading connection and env lookup
16
+ - *(query)* Resolve association filter class via resource_class reflection
1
17
  ## [0.58.1] - 2026-06-10
2
18
 
3
19
  ### 🐛 Bug Fixes