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.
- checksums.yaml +4 -4
- data/.claude/skills/plutonium-auth/SKILL.md +7 -1
- data/.claude/skills/plutonium-behavior/SKILL.md +4 -0
- data/.claude/skills/plutonium-resource/SKILL.md +49 -0
- data/CHANGELOG.md +16 -0
- data/app/assets/plutonium.css +1 -1
- data/docs/.vitepress/config.ts +1 -0
- data/docs/reference/auth/accounts.md +7 -0
- data/docs/reference/resource/actions.md +3 -0
- data/docs/reference/resource/definition.md +129 -0
- data/docs/reference/resource/export.md +94 -0
- data/docs/reference/ui/forms.md +51 -21
- data/docs/superpowers/plans/2026-06-14-form-sectioning.md +917 -0
- data/docs/superpowers/plans/2026-06-14-form-sectioning.md.tasks.json +40 -0
- data/docs/superpowers/specs/2026-06-12-export-csv-default-action-design.md +306 -0
- data/docs/superpowers/specs/2026-06-14-form-sectioning-design.md +237 -0
- data/gemfiles/rails_7.gemfile.lock +3 -1
- data/gemfiles/rails_8.0.gemfile.lock +3 -1
- data/gemfiles/rails_8.1.gemfile.lock +3 -1
- data/lib/generators/pu/lite/solid_errors/solid_errors_generator.rb +3 -3
- data/lib/generators/pu/rodauth/admin_generator.rb +5 -2
- data/lib/generators/pu/rodauth/migration_generator.rb +1 -1
- data/lib/generators/pu/rodauth/templates/app/interactions/resend_admin_interaction.rb.tt +18 -0
- data/lib/generators/pu/rodauth/views_generator.rb +1 -1
- data/lib/plutonium/definition/base.rb +4 -0
- data/lib/plutonium/definition/form_layout.rb +144 -0
- data/lib/plutonium/interaction/base.rb +1 -0
- data/lib/plutonium/package/engine.rb +17 -7
- data/lib/plutonium/query/filter.rb +4 -1
- data/lib/plutonium/query/filters/association.rb +1 -2
- data/lib/plutonium/resource/controller.rb +1 -0
- data/lib/plutonium/resource/controllers/export_csv.rb +162 -0
- data/lib/plutonium/resource/controllers/queryable.rb +1 -0
- data/lib/plutonium/resource/policy.rb +21 -0
- data/lib/plutonium/routing/mapper_extensions.rb +13 -0
- data/lib/plutonium/ui/export_button.rb +86 -0
- data/lib/plutonium/ui/form/components/section.rb +58 -0
- data/lib/plutonium/ui/form/resource.rb +85 -7
- data/lib/plutonium/ui/table/components/toolbar.rb +9 -2
- data/lib/plutonium/ui/table/resource.rb +18 -1
- data/lib/plutonium/version.rb +1 -1
- data/package.json +1 -1
- data/plutonium.gemspec +1 -0
- data/src/css/slim_select.css +11 -2
- metadata +26 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plutonium
|
|
4
|
+
module UI
|
|
5
|
+
module Form
|
|
6
|
+
module Components
|
|
7
|
+
# Renders a form section's chrome (heading/description, optional native
|
|
8
|
+
# <details> collapsible, and a fields grid) and yields to a block that
|
|
9
|
+
# renders the section's fields (the form supplies render_resource_field).
|
|
10
|
+
class Section < Plutonium::UI::Component::Base
|
|
11
|
+
def initialize(resolved, grid_class:)
|
|
12
|
+
@section = resolved.section
|
|
13
|
+
@grid_class = grid_class
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
SECTION_CLASS = "space-y-4 border-t border-[var(--pu-border-muted)] pt-6 first:border-t-0 first:pt-0"
|
|
17
|
+
HEADING_CLASS = "text-base font-semibold text-[var(--pu-text)]"
|
|
18
|
+
SUMMARY_CLASS = "#{HEADING_CLASS} cursor-pointer select-none"
|
|
19
|
+
DESCRIPTION_CLASS = "text-sm text-[var(--pu-text-muted)]"
|
|
20
|
+
|
|
21
|
+
def view_template(&fields_block)
|
|
22
|
+
if @section.collapsible?
|
|
23
|
+
details(open: !@section.collapsed?, class: SECTION_CLASS) do
|
|
24
|
+
summary(class: SUMMARY_CLASS) { heading_text }
|
|
25
|
+
describe
|
|
26
|
+
grid(&fields_block)
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
div(class: SECTION_CLASS) do
|
|
30
|
+
header_block
|
|
31
|
+
grid(&fields_block)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def header_block
|
|
39
|
+
return if @section.ungrouped? && @section.options[:label].nil?
|
|
40
|
+
h3(class: HEADING_CLASS) { heading_text }
|
|
41
|
+
describe
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def heading_text = @section.label
|
|
45
|
+
|
|
46
|
+
def describe
|
|
47
|
+
return unless @section.description
|
|
48
|
+
p(class: DESCRIPTION_CLASS) { @section.description }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def grid(&fields_block)
|
|
52
|
+
div(class: @grid_class, &fields_block)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -98,11 +98,81 @@ module Plutonium
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def render_fields
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
sections = resolve_form_layout
|
|
102
|
+
if sections.nil?
|
|
103
|
+
fields_wrapper {
|
|
104
|
+
resource_fields.each { |name| render_resource_field name }
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
else
|
|
107
|
+
sections.each { |rs| render_form_section(rs) }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Resolve the whole form layout for THIS render, in one pass: drop
|
|
112
|
+
# condition-hidden sections and evaluate any proc-valued options, all in
|
|
113
|
+
# the form instance context (where `object`, `current_user`, `params` and
|
|
114
|
+
# helpers live — same context as input/section `condition:`). Returns nil
|
|
115
|
+
# when no form_layout is declared (caller falls back to a single grid).
|
|
116
|
+
def resolve_form_layout
|
|
117
|
+
sections = resource_definition.resolve_form_sections(resource_fields)
|
|
118
|
+
return nil if sections.nil?
|
|
119
|
+
|
|
120
|
+
sections.filter_map do |resolved|
|
|
121
|
+
section = resolved.section
|
|
122
|
+
condition = section.condition
|
|
123
|
+
next if condition && !instance_exec(&condition)
|
|
124
|
+
|
|
125
|
+
# `columns` stays a validated literal; everything else may be a proc.
|
|
126
|
+
options = section.options.to_h do |key, value|
|
|
127
|
+
[key, (key != :condition && value.is_a?(Proc)) ? instance_exec(&value) : value]
|
|
128
|
+
end
|
|
129
|
+
Plutonium::Definition::FormLayout::ResolvedSection.new(
|
|
130
|
+
section: Plutonium::Definition::FormLayout::Section.new(
|
|
131
|
+
key: section.key, fields: section.fields, options: options.freeze
|
|
132
|
+
),
|
|
133
|
+
fields: resolved.fields
|
|
134
|
+
)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Pure presentation — the section is already resolved (visible, options
|
|
139
|
+
# evaluated) by resolve_form_layout.
|
|
140
|
+
def render_form_section(resolved)
|
|
141
|
+
section = resolved.section
|
|
142
|
+
render Plutonium::UI::Form::Components::Section.new(
|
|
143
|
+
resolved, grid_class: section_grid_class(section.columns)
|
|
144
|
+
) do
|
|
145
|
+
# Inside a multi-column section, let fields flow into the grid cells
|
|
146
|
+
# instead of forcing each to span the full row (see col-span default
|
|
147
|
+
# in render_simple_resource_field).
|
|
148
|
+
previous = @section_columns
|
|
149
|
+
@section_columns = section.columns
|
|
150
|
+
begin
|
|
151
|
+
resolved.fields.each { |name| render_resource_field name }
|
|
152
|
+
ensure
|
|
153
|
+
@section_columns = previous
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# True while rendering fields inside a section that declared an explicit
|
|
159
|
+
# column count > 1. Such fields default to a single grid cell rather than
|
|
160
|
+
# `col-span-full`, so the section's grid actually lays out in columns.
|
|
161
|
+
def in_multi_column_section?
|
|
162
|
+
@section_columns.to_i > 1
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# nil → the form's default responsive grid; an Integer overrides columns.
|
|
166
|
+
def section_grid_class(columns)
|
|
167
|
+
return themed(:fields_wrapper, nil) if columns.nil?
|
|
168
|
+
|
|
169
|
+
base = "grid gap-6 grid-flow-row-dense grid-cols-1"
|
|
170
|
+
case columns.to_i
|
|
171
|
+
when 1 then base
|
|
172
|
+
when 2 then "#{base} md:grid-cols-2"
|
|
173
|
+
when 3 then "#{base} md:grid-cols-2 lg:grid-cols-3"
|
|
174
|
+
else "#{base} md:grid-cols-2 2xl:grid-cols-#{columns.to_i}"
|
|
175
|
+
end
|
|
106
176
|
end
|
|
107
177
|
|
|
108
178
|
def render_actions
|
|
@@ -232,10 +302,18 @@ module Plutonium
|
|
|
232
302
|
end
|
|
233
303
|
else
|
|
234
304
|
wrapper_options = input_options[:wrapper] || {}
|
|
305
|
+
# Only supply a default column span when the field hasn't declared its
|
|
306
|
+
# own (via `wrapper: {class: "col-span-..."}`). A field-level col-span
|
|
307
|
+
# ALWAYS wins — including inside a section with `columns:` — so authors
|
|
308
|
+
# can opt a single field back to full width in a multi-column section,
|
|
309
|
+
# or vice versa.
|
|
310
|
+
# TODO: remove the string check once theming supports class merges.
|
|
235
311
|
if !wrapper_options[:class] || !wrapper_options[:class].include?("col-span")
|
|
236
|
-
#
|
|
237
|
-
#
|
|
238
|
-
|
|
312
|
+
# In a multi-column section the field flows into a single grid cell
|
|
313
|
+
# (no col-span), so the declared `columns:` actually takes effect.
|
|
314
|
+
# Everywhere else fields span the full row.
|
|
315
|
+
default_span = in_multi_column_section? ? nil : "col-span-full"
|
|
316
|
+
wrapper_options[:class] = tokens(default_span, wrapper_options[:class])
|
|
239
317
|
end
|
|
240
318
|
|
|
241
319
|
render form.field(name, **field_options).wrapped(
|
|
@@ -8,7 +8,7 @@ module Plutonium
|
|
|
8
8
|
# inline search, and column config / overflow icon buttons into a single
|
|
9
9
|
# tight strip rendered above the table when shell == :modern.
|
|
10
10
|
class Toolbar < Plutonium::UI::Component::Base
|
|
11
|
-
def initialize(query:, search_url:, search_param: :q, search_value: nil, views: [:table], current_view: :table, view_cookie_name: nil, view_cookie_path: "/")
|
|
11
|
+
def initialize(query:, search_url:, search_param: :q, search_value: nil, views: [:table], current_view: :table, view_cookie_name: nil, view_cookie_path: "/", export: nil)
|
|
12
12
|
@query = query
|
|
13
13
|
@search_url = search_url
|
|
14
14
|
@search_param = search_param
|
|
@@ -17,10 +17,11 @@ module Plutonium
|
|
|
17
17
|
@current_view = current_view
|
|
18
18
|
@view_cookie_name = view_cookie_name
|
|
19
19
|
@view_cookie_path = view_cookie_path
|
|
20
|
+
@export = export
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def render?
|
|
23
|
-
@views.size > 1 || has_filters? || has_search?
|
|
24
|
+
@views.size > 1 || has_filters? || has_search? || @export.present?
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def view_template
|
|
@@ -29,11 +30,17 @@ module Plutonium
|
|
|
29
30
|
render switcher
|
|
30
31
|
render_divider if switcher.render?
|
|
31
32
|
render_filter_button
|
|
33
|
+
render_export_button if @export
|
|
32
34
|
div(class: "flex-1")
|
|
33
35
|
render_search if has_search?
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
39
|
+
# Export split button, rendered just after the Filter button.
|
|
40
|
+
def render_export_button
|
|
41
|
+
render Plutonium::UI::ExportButton.new(**@export)
|
|
42
|
+
end
|
|
43
|
+
|
|
37
44
|
private
|
|
38
45
|
|
|
39
46
|
def has_filters?
|
|
@@ -47,10 +47,27 @@ module Plutonium
|
|
|
47
47
|
views: resource_definition.defined_index_views,
|
|
48
48
|
current_view: :table,
|
|
49
49
|
view_cookie_name: Plutonium::UI::Page::Index.view_cookie_name(resource_class),
|
|
50
|
-
view_cookie_path: Plutonium::UI::Page::Index.view_cookie_path(request)
|
|
50
|
+
view_cookie_path: Plutonium::UI::Page::Index.view_cookie_path(request),
|
|
51
|
+
export: export_toolbar_config
|
|
51
52
|
)
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
# Export split-button config, or nil when the policy forbids export.
|
|
56
|
+
# The primary link carries the current query (selected scope + filters
|
|
57
|
+
# + search); "Export all" carries `?all=1`.
|
|
58
|
+
def export_toolbar_config
|
|
59
|
+
return nil unless current_policy.allowed_to?(:export_csv?)
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
scoped_url: resource_url_for(resource_class, action: :export_csv, **export_query_params),
|
|
63
|
+
all_url: resource_url_for(resource_class, action: :export_csv, all: 1)
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def export_query_params
|
|
68
|
+
params[:q].present? ? {q: params[:q].to_unsafe_h} : {}
|
|
69
|
+
end
|
|
70
|
+
|
|
54
71
|
def render_filter_pills
|
|
55
72
|
TableFilterPills(query: current_query_object, total_count: pagy_instance&.count)
|
|
56
73
|
end
|
data/lib/plutonium/version.rb
CHANGED
data/package.json
CHANGED
data/plutonium.gemspec
CHANGED
|
@@ -51,6 +51,7 @@ Gem::Specification.new do |spec|
|
|
|
51
51
|
|
|
52
52
|
spec.add_dependency "zeitwerk"
|
|
53
53
|
spec.add_dependency "rails", ">= 7.2"
|
|
54
|
+
spec.add_dependency "csv" # CSV export; no longer a default gem on Ruby 3.4+
|
|
54
55
|
spec.add_dependency "listen", "~> 3.8"
|
|
55
56
|
spec.add_dependency "pagy", "~> 43.0"
|
|
56
57
|
spec.add_dependency "rabl", "~> 0.17.0" # TODO: what to do with RABL
|
data/src/css/slim_select.css
CHANGED
|
@@ -43,9 +43,11 @@
|
|
|
43
43
|
border-radius: var(--pu-radius-md);
|
|
44
44
|
color: var(--pu-text);
|
|
45
45
|
}
|
|
46
|
+
|
|
46
47
|
.ss-main:hover {
|
|
47
48
|
border-color: var(--pu-border-strong);
|
|
48
49
|
}
|
|
50
|
+
|
|
49
51
|
.ss-main:focus,
|
|
50
52
|
.ss-main[aria-expanded="true"] {
|
|
51
53
|
border-color: var(--pu-input-focus-ring);
|
|
@@ -196,9 +198,11 @@
|
|
|
196
198
|
font-size: inherit;
|
|
197
199
|
line-height: inherit;
|
|
198
200
|
}
|
|
201
|
+
|
|
199
202
|
.ss-content .ss-search input::placeholder {
|
|
200
203
|
color: var(--pu-input-placeholder);
|
|
201
204
|
}
|
|
205
|
+
|
|
202
206
|
.ss-content .ss-search input:focus {
|
|
203
207
|
border-color: var(--pu-input-focus-ring);
|
|
204
208
|
box-shadow: 0 0 0 3px theme(colors.primary.500 / 15%);
|
|
@@ -225,7 +229,7 @@
|
|
|
225
229
|
|
|
226
230
|
/* List */
|
|
227
231
|
.ss-content .ss-list {
|
|
228
|
-
@apply flex-auto h-auto overflow-x-hidden overflow-y-auto;
|
|
232
|
+
@apply flex-auto h-auto overflow-x-hidden overflow-y-auto mb-2;
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
.ss-content .ss-list .ss-error {
|
|
@@ -345,10 +349,12 @@
|
|
|
345
349
|
.ss-main.ss-invalid {
|
|
346
350
|
@apply border-danger-500 bg-danger-50/50 text-danger-900;
|
|
347
351
|
}
|
|
352
|
+
|
|
348
353
|
.ss-main.ss-invalid:focus,
|
|
349
354
|
.ss-main.ss-invalid[aria-expanded="true"] {
|
|
350
355
|
box-shadow: 0 0 0 3px theme(colors.danger.500 / 15%);
|
|
351
356
|
}
|
|
357
|
+
|
|
352
358
|
.dark .ss-main.ss-invalid {
|
|
353
359
|
@apply bg-danger-950/20 border-danger-500/70 text-danger-200;
|
|
354
360
|
}
|
|
@@ -360,10 +366,12 @@
|
|
|
360
366
|
.ss-main.ss-valid {
|
|
361
367
|
@apply border-success-500 bg-success-50/50 text-success-900;
|
|
362
368
|
}
|
|
369
|
+
|
|
363
370
|
.ss-main.ss-valid:focus,
|
|
364
371
|
.ss-main.ss-valid[aria-expanded="true"] {
|
|
365
372
|
box-shadow: 0 0 0 3px theme(colors.success.500 / 15%);
|
|
366
373
|
}
|
|
374
|
+
|
|
367
375
|
.dark .ss-main.ss-valid {
|
|
368
376
|
@apply bg-success-950/20 border-success-500/70 text-success-200;
|
|
369
377
|
}
|
|
@@ -385,7 +393,8 @@
|
|
|
385
393
|
width: 100% !important;
|
|
386
394
|
border-radius: 0 !important;
|
|
387
395
|
margin: 0 !important;
|
|
388
|
-
pointer-events: none !important;
|
|
396
|
+
pointer-events: none !important;
|
|
397
|
+
/* Disabled by default */
|
|
389
398
|
}
|
|
390
399
|
|
|
391
400
|
/* When active (dropdown is expanded), enable pointer events */
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plutonium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.60.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stefan Froelich
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-06-
|
|
10
|
+
date: 2026-06-14 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: zeitwerk
|
|
@@ -37,6 +37,20 @@ dependencies:
|
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '7.2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: csv
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
40
54
|
- !ruby/object:Gem::Dependency
|
|
41
55
|
name: listen
|
|
42
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -641,6 +655,7 @@ files:
|
|
|
641
655
|
- docs/reference/index.md
|
|
642
656
|
- docs/reference/resource/actions.md
|
|
643
657
|
- docs/reference/resource/definition.md
|
|
658
|
+
- docs/reference/resource/export.md
|
|
644
659
|
- docs/reference/resource/index.md
|
|
645
660
|
- docs/reference/resource/model.md
|
|
646
661
|
- docs/reference/resource/query.md
|
|
@@ -670,6 +685,8 @@ files:
|
|
|
670
685
|
- docs/superpowers/plans/2026-06-02-structured-inputs.md.tasks.json
|
|
671
686
|
- docs/superpowers/plans/2026-06-04-sqlite-tune-maintenance-generators.md
|
|
672
687
|
- docs/superpowers/plans/2026-06-04-sqlite-tune-maintenance-generators.md.tasks.json
|
|
688
|
+
- docs/superpowers/plans/2026-06-14-form-sectioning.md
|
|
689
|
+
- docs/superpowers/plans/2026-06-14-form-sectioning.md.tasks.json
|
|
673
690
|
- docs/superpowers/specs/2026-04-08-plutonium-skills-overhaul-design.md
|
|
674
691
|
- docs/superpowers/specs/2026-04-14-plutonium-testing-design.md
|
|
675
692
|
- docs/superpowers/specs/2026-05-07-ui-layout-overhaul-design.md
|
|
@@ -680,6 +697,8 @@ files:
|
|
|
680
697
|
- docs/superpowers/specs/2026-05-29-avatar-component-design.md
|
|
681
698
|
- docs/superpowers/specs/2026-06-01-structured-inputs-design.md
|
|
682
699
|
- docs/superpowers/specs/2026-06-04-sqlite-tune-maintenance-generators-design.md
|
|
700
|
+
- docs/superpowers/specs/2026-06-12-export-csv-default-action-design.md
|
|
701
|
+
- docs/superpowers/specs/2026-06-14-form-sectioning-design.md
|
|
683
702
|
- esbuild.config.js
|
|
684
703
|
- exe/pug
|
|
685
704
|
- gemfiles/rails_7.gemfile
|
|
@@ -888,6 +907,7 @@ files:
|
|
|
888
907
|
- lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt
|
|
889
908
|
- lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt
|
|
890
909
|
- lib/generators/pu/rodauth/templates/app/interactions/invite_admin_interaction.rb.tt
|
|
910
|
+
- lib/generators/pu/rodauth/templates/app/interactions/resend_admin_interaction.rb.tt
|
|
891
911
|
- lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt
|
|
892
912
|
- lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt
|
|
893
913
|
- lib/generators/pu/rodauth/templates/app/models/account.rb.tt
|
|
@@ -979,6 +999,7 @@ files:
|
|
|
979
999
|
- lib/plutonium/definition/base.rb
|
|
980
1000
|
- lib/plutonium/definition/config_attr.rb
|
|
981
1001
|
- lib/plutonium/definition/defineable_props.rb
|
|
1002
|
+
- lib/plutonium/definition/form_layout.rb
|
|
982
1003
|
- lib/plutonium/definition/index_views.rb
|
|
983
1004
|
- lib/plutonium/definition/inheritable_config_attr.rb
|
|
984
1005
|
- lib/plutonium/definition/metadata.rb
|
|
@@ -1045,6 +1066,7 @@ files:
|
|
|
1045
1066
|
- lib/plutonium/resource/controllers/crud_actions.rb
|
|
1046
1067
|
- lib/plutonium/resource/controllers/crud_actions/index_action.rb
|
|
1047
1068
|
- lib/plutonium/resource/controllers/defineable.rb
|
|
1069
|
+
- lib/plutonium/resource/controllers/export_csv.rb
|
|
1048
1070
|
- lib/plutonium/resource/controllers/interactive_actions.rb
|
|
1049
1071
|
- lib/plutonium/resource/controllers/presentable.rb
|
|
1050
1072
|
- lib/plutonium/resource/controllers/queryable.rb
|
|
@@ -1105,6 +1127,7 @@ files:
|
|
|
1105
1127
|
- lib/plutonium/ui/dyna_frame/content.rb
|
|
1106
1128
|
- lib/plutonium/ui/dyna_frame/host.rb
|
|
1107
1129
|
- lib/plutonium/ui/empty_card.rb
|
|
1130
|
+
- lib/plutonium/ui/export_button.rb
|
|
1108
1131
|
- lib/plutonium/ui/form/base.rb
|
|
1109
1132
|
- lib/plutonium/ui/form/components/easymde.rb
|
|
1110
1133
|
- lib/plutonium/ui/form/components/flatpickr.rb
|
|
@@ -1113,6 +1136,7 @@ files:
|
|
|
1113
1136
|
- lib/plutonium/ui/form/components/json.rb
|
|
1114
1137
|
- lib/plutonium/ui/form/components/key_value_store.rb
|
|
1115
1138
|
- lib/plutonium/ui/form/components/resource_select.rb
|
|
1139
|
+
- lib/plutonium/ui/form/components/section.rb
|
|
1116
1140
|
- lib/plutonium/ui/form/components/secure_association.rb
|
|
1117
1141
|
- lib/plutonium/ui/form/components/secure_polymorphic_association.rb
|
|
1118
1142
|
- lib/plutonium/ui/form/components/sticky_footer.rb
|