plutonium 0.68.0 → 0.70.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-async-interactions/SKILL.md +41 -2
- data/.claude/skills/plutonium-resource/SKILL.md +13 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +37 -0
- data/CLAUDE.md +11 -0
- data/SECURITY.md +1 -1
- data/app/assets/plutonium.css +3 -1
- data/app/assets/plutonium.png +0 -0
- data/config/locales/en/async.yml +11 -1
- data/config/locales/en/ui.yml +3 -0
- data/docs/blog/introducing-plutonium-dashboards.md +4 -4
- data/docs/blog/the-slowest-query-is-the-count.md +109 -0
- data/docs/guides/performance.md +14 -0
- data/docs/public/favicon-16x16.png +0 -0
- data/docs/public/favicon-32x32.png +0 -0
- data/docs/public/images/blog/i18n-es-admin.png +0 -0
- data/docs/public/images/blog/pagination-capped.png +0 -0
- data/docs/public/images/blog/pagination-countless.png +0 -0
- data/docs/public/images/components/avatar.png +0 -0
- data/docs/public/images/guides/custom-actions-bulk.png +0 -0
- data/docs/public/images/guides/dashboard-card-error.png +0 -0
- data/docs/public/images/guides/dashboard-loading.png +0 -0
- data/docs/public/images/guides/dashboard-overview.png +0 -0
- data/docs/public/images/guides/dashboard-sidebar.png +0 -0
- data/docs/public/images/guides/kanban-after-move.png +0 -0
- data/docs/public/images/guides/kanban-board-light.png +0 -0
- data/docs/public/images/guides/kanban-board.png +0 -0
- data/docs/public/images/guides/kanban-show-centered-modal.png +0 -0
- data/docs/public/images/guides/kanban-wip-toast.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/guides/wizards-chooser.png +0 -0
- data/docs/public/images/guides/wizards-completed.png +0 -0
- data/docs/public/images/guides/wizards-index-action.png +0 -0
- data/docs/public/images/guides/wizards-repeater.png +0 -0
- data/docs/public/images/guides/wizards-review.png +0 -0
- data/docs/public/images/guides/wizards-step.png +0 -0
- data/docs/public/images/home/tour-actions.png +0 -0
- data/docs/public/images/home/tour-async.png +0 -0
- data/docs/public/images/home/tour-kanban.png +0 -0
- data/docs/public/images/home/tour-tenancy.png +0 -0
- data/docs/public/images/home/tour-wizard.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/reference/async-progress-page.png +0 -0
- data/docs/public/images/reference/async-running-banner.png +0 -0
- data/docs/public/images/reference/structured-inputs-removed.png +0 -0
- data/docs/public/images/reference/structured-inputs.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/public/og-image.png +0 -0
- data/docs/public/plutonium.png +0 -0
- data/docs/public/tutorial/plutonium-association-panel.png +0 -0
- data/docs/public/tutorial/plutonium-dashboard.png +0 -0
- data/docs/public/tutorial/plutonium-login-page.png +0 -0
- data/docs/public/tutorial/plutonium-nested-form.png +0 -0
- data/docs/public/tutorial/plutonium-posts-dashboard-customized.png +0 -0
- data/docs/public/tutorial/plutonium-posts-dashboard.png +0 -0
- data/docs/public/tutorial/plutonium-posts-detail-customized.png +0 -0
- data/docs/public/tutorial/plutonium-posts-detail.png +0 -0
- data/docs/public/tutorial/plutonium-publish-post.png +0 -0
- data/docs/reference/behavior/async-interactions.md +62 -5
- data/docs/reference/configuration.md +1 -0
- data/docs/reference/generators/lite.md +30 -6
- data/docs/reference/i18n.md +2 -2
- data/docs/reference/resource/definition.md +35 -0
- data/docs/reference/ui/layouts.md +13 -0
- data/docs/superpowers/plans/2026-10-15-async-run-pre-check.md +1056 -0
- data/docs/superpowers/plans/2026-10-15-async-run-pre-check.md.tasks.json +49 -0
- data/docs/superpowers/specs/2026-10-15-async-run-pre-check-design.md +208 -0
- data/gemfiles/rails_7.gemfile.lock +5 -5
- data/gemfiles/rails_8.0.gemfile.lock +3 -3
- data/gemfiles/rails_8.1.gemfile.lock +3 -3
- data/lib/generators/pu/lite/maintenance/maintenance_generator.rb +20 -1
- data/lib/generators/pu/lite/maintenance/templates/app/jobs/sqlite_maintenance_job.rb.tt +18 -1
- data/lib/plutonium/configuration.rb +17 -0
- data/lib/plutonium/definition/base.rb +22 -0
- data/lib/plutonium/definition/presentable.rb +4 -1
- data/lib/plutonium/interaction/async/configuration.rb +15 -0
- data/lib/plutonium/interaction/async/context.rb +12 -2
- data/lib/plutonium/interaction/async/executor.rb +54 -0
- data/lib/plutonium/interaction/async/run.rb +128 -14
- data/lib/plutonium/interaction/async/run_definition.rb +5 -4
- data/lib/plutonium/interaction/async/run_policy.rb +5 -5
- data/lib/plutonium/interaction/response/redirect.rb +19 -7
- data/lib/plutonium/pagination.rb +35 -0
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +27 -1
- data/lib/plutonium/ui/breadcrumbs.rb +26 -8
- data/lib/plutonium/ui/grid/card.rb +11 -2
- data/lib/plutonium/ui/grid/resource.rb +2 -2
- data/lib/plutonium/ui/interaction/async/run_progress.rb +25 -11
- data/lib/plutonium/ui/interaction/async/running_banner.rb +21 -5
- data/lib/plutonium/ui/layout/base.rb +0 -9
- data/lib/plutonium/ui/layout/icon_rail.rb +42 -4
- data/lib/plutonium/ui/page/index.rb +23 -4
- data/lib/plutonium/ui/table/components/filter_pills.rb +8 -2
- data/lib/plutonium/ui/table/components/pagy_info.rb +30 -10
- data/lib/plutonium/ui/table/resource.rb +2 -2
- data/lib/plutonium/version.rb +1 -1
- data/package.json +1 -1
- data/plutonium.gemspec +3 -1
- data/src/css/components.css +12 -1
- data/src/css/font_awesome.css +2328 -0
- data/src/css/plutonium.css +1 -0
- metadata +11 -7
- data/docs/public/images/blog/dashboards-card-error.png +0 -0
- data/docs/public/images/blog/dashboards-loading.png +0 -0
- data/docs/public/images/blog/dashboards-overview.png +0 -0
- data/docs/public/images/blog/dashboards-sidebar.png +0 -0
|
@@ -855,6 +855,41 @@ All three inherit to subclasses, so a portal-specific definition keeps its paren
|
|
|
855
855
|
- **Interactions** (`Plutonium::Interaction::Base`) support the same settings, for interactive actions rendered as standalone pages.
|
|
856
856
|
- **Wizards are configured separately**, via `Plutonium.configuration.wizards.width`. It defaults to `:md` independently of `default_page_width`, so widening resource pages leaves wizard steps where they are. Set both if you want them to match.
|
|
857
857
|
|
|
858
|
+
## Pagination count
|
|
859
|
+
|
|
860
|
+
The index page shows its total ("Displaying Posts 1-20 of 13,742 in total") and links every page, which takes a `COUNT(*)` on each load. On a table with millions of rows that count can take seconds. `pagination` sets how much counting a resource does:
|
|
861
|
+
|
|
862
|
+
```ruby
|
|
863
|
+
# config/initializers/plutonium.rb
|
|
864
|
+
Plutonium.configure { |config| config.pagination = {count: :exact} } # the default
|
|
865
|
+
|
|
866
|
+
class TransactionDefinition < ResourceDefinition
|
|
867
|
+
pagination count: 10_000
|
|
868
|
+
end
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
| `count:` | Query | Total shown | Page links |
|
|
872
|
+
|---|---|---|---|
|
|
873
|
+
| `:exact` | `SELECT COUNT(*) FROM ...` | the exact total | every page |
|
|
874
|
+
| an Integer | `SELECT COUNT(*) FROM (SELECT 1 FROM ... LIMIT 10001)` | exact up to the cap, then "10000+" | up to the page holding row 10,000 |
|
|
875
|
+
| `false` | none: fetches one extra row to tell whether a next page exists | the page's range only, without "of N" | previous/next, plus the pages visited so far |
|
|
876
|
+
|
|
877
|
+
A cap makes the count cheap when many rows match, because the subquery stops after `cap + 1` of them. It does not help a filter that matches few rows: the database still scans until it has found them all, so give that filter's column an index.
|
|
878
|
+
|
|
879
|
+
Any other value raises `ArgumentError` at declaration. The setting inherits to subclasses, so a portal-specific definition keeps its parent's choice unless it sets its own.
|
|
880
|
+
|
|
881
|
+
To choose per request, for example no count only while no filter is applied, override `pagination_count` in the controller. It returns the same values:
|
|
882
|
+
|
|
883
|
+
```ruby
|
|
884
|
+
class TransactionsController < ResourceController
|
|
885
|
+
private
|
|
886
|
+
|
|
887
|
+
def pagination_count
|
|
888
|
+
current_query_object.active_filter_descriptions.empty? ? false : 10_000
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
```
|
|
892
|
+
|
|
858
893
|
## File uploads
|
|
859
894
|
|
|
860
895
|
```ruby
|
|
@@ -109,6 +109,19 @@ The sidebar/icon-rail navigation is built with `Phlexi::Menu::Builder` in the ej
|
|
|
109
109
|
) %>
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
### Links pinned above the footer
|
|
113
|
+
|
|
114
|
+
`footer_menu:` takes a second `Phlexi::Menu::Builder` whose items render between the scrolling nav and the pin button, so they stay in view however long the nav gets. Items render the same way as the main menu's:
|
|
115
|
+
|
|
116
|
+
```erb
|
|
117
|
+
<%= render Plutonium::UI::Layout::IconRail.new(
|
|
118
|
+
menu: main_menu,
|
|
119
|
+
footer_menu: Phlexi::Menu::Builder.new do |m|
|
|
120
|
+
m.item "Settings", url: settings_path, icon: Phlex::TablerIcons::Settings
|
|
121
|
+
end
|
|
122
|
+
) %>
|
|
123
|
+
```
|
|
124
|
+
|
|
112
125
|
### Per-item link attributes
|
|
113
126
|
|
|
114
127
|
Any extra options you pass to `item` are spread straight onto the rendered `<a>`, so a menu entry can opt into `target`, `rel`, `data-*`, `aria-*`, etc. Useful for items that open in their own tab or drive a Stimulus/Turbo behavior:
|