plutonium 0.37.0 → 0.39.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-controller/SKILL.md +38 -2
- data/.claude/skills/plutonium-definition-actions/SKILL.md +13 -0
- data/.claude/skills/plutonium-definition-fields/SKILL.md +33 -0
- data/.claude/skills/plutonium-nested-resources/SKILL.md +85 -23
- data/.claude/skills/plutonium-policy/SKILL.md +93 -6
- data/CHANGELOG.md +42 -0
- data/CLAUDE.md +8 -10
- data/CONTRIBUTING.md +6 -8
- data/Rakefile +16 -1
- data/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.js +9371 -11492
- data/app/assets/plutonium.js.map +4 -4
- data/app/assets/plutonium.min.js +55 -55
- data/app/assets/plutonium.min.js.map +4 -4
- data/docs/guides/custom-actions.md +14 -0
- data/docs/guides/index.md +5 -0
- data/docs/guides/nested-resources.md +139 -32
- data/docs/guides/troubleshooting.md +82 -0
- data/docs/og-image.html +84 -0
- data/docs/public/og-image.png +0 -0
- data/docs/reference/controller/index.md +6 -2
- data/docs/reference/definition/actions.md +14 -0
- data/docs/reference/definition/fields.md +33 -0
- data/docs/reference/model/index.md +1 -1
- data/docs/reference/policy/index.md +77 -6
- data/gemfiles/rails_7.gemfile.lock +5 -5
- data/gemfiles/rails_8.0.gemfile.lock +5 -5
- data/gemfiles/rails_8.1.gemfile.lock +5 -5
- data/lib/generators/pu/rodauth/install_generator.rb +7 -11
- data/lib/generators/pu/rodauth/templates/app/rodauth/rodauth_plugin.rb.tt +3 -5
- data/lib/plutonium/auth/sequel_adapter.rb +76 -0
- data/lib/plutonium/core/controller.rb +143 -19
- data/lib/plutonium/core/controllers/association_resolver.rb +86 -0
- data/lib/plutonium/helpers/display_helper.rb +12 -0
- data/lib/plutonium/query/filters/association.rb +25 -3
- data/lib/plutonium/resource/controller.rb +91 -9
- data/lib/plutonium/resource/controllers/authorizable.rb +17 -4
- data/lib/plutonium/resource/controllers/crud_actions.rb +7 -5
- data/lib/plutonium/resource/controllers/interactive_actions.rb +9 -0
- data/lib/plutonium/resource/controllers/presentable.rb +15 -11
- data/lib/plutonium/resource/policy.rb +85 -2
- data/lib/plutonium/resource/record/routes.rb +31 -1
- data/lib/plutonium/routing/mapper_extensions.rb +49 -10
- data/lib/plutonium/routing/route_set_extensions.rb +3 -0
- data/lib/plutonium/ui/action_button.rb +72 -11
- data/lib/plutonium/ui/actions_dropdown.rb +3 -25
- data/lib/plutonium/ui/breadcrumbs.rb +2 -2
- data/lib/plutonium/ui/component/methods.rb +10 -3
- data/lib/plutonium/ui/display/resource.rb +5 -2
- data/lib/plutonium/ui/form/base.rb +1 -1
- data/lib/plutonium/ui/form/components/key_value_store.rb +17 -5
- data/lib/plutonium/ui/form/interaction.rb +5 -5
- data/lib/plutonium/ui/form/query.rb +1 -1
- data/lib/plutonium/ui/form/resource.rb +1 -1
- data/lib/plutonium/ui/layout/base.rb +1 -1
- data/lib/plutonium/ui/layout/basic_layout.rb +2 -2
- data/lib/plutonium/ui/layout/resource_layout.rb +2 -2
- data/lib/plutonium/ui/layout/rodauth_layout.rb +2 -2
- data/lib/plutonium/ui/page/index.rb +1 -1
- data/lib/plutonium/ui/page/interactive_action.rb +1 -1
- data/lib/plutonium/ui/table/components/row_actions_dropdown.rb +3 -25
- data/lib/plutonium/version.rb +1 -1
- data/lib/tasks/release.rake +1 -1
- data/package.json +6 -5
- data/plutonium.gemspec +2 -2
- data/src/js/controllers/key_value_store_controller.js +6 -0
- data/src/js/controllers/resource_drop_down_controller.js +3 -3
- data/yarn.lock +1465 -693
- metadata +10 -7
- data/app/javascript/controllers/key_value_store_controller.js +0 -119
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plutonium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.39.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stefan Froelich
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: zeitwerk
|
|
@@ -184,14 +184,14 @@ dependencies:
|
|
|
184
184
|
requirements:
|
|
185
185
|
- - ">="
|
|
186
186
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: 0.
|
|
187
|
+
version: 0.14.1
|
|
188
188
|
type: :runtime
|
|
189
189
|
prerelease: false
|
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
191
|
requirements:
|
|
192
192
|
- - ">="
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: 0.
|
|
194
|
+
version: 0.14.1
|
|
195
195
|
- !ruby/object:Gem::Dependency
|
|
196
196
|
name: phlexi-table
|
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -226,14 +226,14 @@ dependencies:
|
|
|
226
226
|
requirements:
|
|
227
227
|
- - ">="
|
|
228
228
|
- !ruby/object:Gem::Version
|
|
229
|
-
version: 0.4.
|
|
229
|
+
version: 0.4.1
|
|
230
230
|
type: :runtime
|
|
231
231
|
prerelease: false
|
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
|
233
233
|
requirements:
|
|
234
234
|
- - ">="
|
|
235
235
|
- !ruby/object:Gem::Version
|
|
236
|
-
version: 0.4.
|
|
236
|
+
version: 0.4.1
|
|
237
237
|
- !ruby/object:Gem::Dependency
|
|
238
238
|
name: tailwind_merge
|
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -444,7 +444,6 @@ files:
|
|
|
444
444
|
- app/assets/plutonium.min.js
|
|
445
445
|
- app/assets/plutonium.min.js.map
|
|
446
446
|
- app/assets/plutonium.png
|
|
447
|
-
- app/javascript/controllers/key_value_store_controller.js
|
|
448
447
|
- app/views/layouts/resource.html.erb
|
|
449
448
|
- app/views/layouts/rodauth.html.erb
|
|
450
449
|
- app/views/plutonium/_flash.html.erb
|
|
@@ -541,7 +540,9 @@ files:
|
|
|
541
540
|
- docs/guides/nested-resources.md
|
|
542
541
|
- docs/guides/search-filtering.md
|
|
543
542
|
- docs/guides/theming.md
|
|
543
|
+
- docs/guides/troubleshooting.md
|
|
544
544
|
- docs/index.md
|
|
545
|
+
- docs/og-image.html
|
|
545
546
|
- docs/public/android-chrome-192x192.png
|
|
546
547
|
- docs/public/android-chrome-512x512.png
|
|
547
548
|
- docs/public/apple-touch-icon.png
|
|
@@ -776,9 +777,11 @@ files:
|
|
|
776
777
|
- lib/plutonium/auth.rb
|
|
777
778
|
- lib/plutonium/auth/public.rb
|
|
778
779
|
- lib/plutonium/auth/rodauth.rb
|
|
780
|
+
- lib/plutonium/auth/sequel_adapter.rb
|
|
779
781
|
- lib/plutonium/configuration.rb
|
|
780
782
|
- lib/plutonium/core/.DS_Store
|
|
781
783
|
- lib/plutonium/core/controller.rb
|
|
784
|
+
- lib/plutonium/core/controllers/association_resolver.rb
|
|
782
785
|
- lib/plutonium/core/controllers/authorizable.rb
|
|
783
786
|
- lib/plutonium/core/controllers/bootable.rb
|
|
784
787
|
- lib/plutonium/core/controllers/entity_scoping.rb
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { Controller } from "@hotwired/stimulus"
|
|
2
|
-
|
|
3
|
-
// Connects to data-controller="key-value-store"
|
|
4
|
-
export default class extends Controller {
|
|
5
|
-
static targets = ["container", "pair", "template", "addButton", "keyInput", "valueInput"]
|
|
6
|
-
static values = { limit: Number }
|
|
7
|
-
|
|
8
|
-
connect() {
|
|
9
|
-
this.updateIndices()
|
|
10
|
-
this.updateAddButtonState()
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
addPair(event) {
|
|
14
|
-
event.preventDefault()
|
|
15
|
-
|
|
16
|
-
if (this.pairTargets.length >= this.limitValue) {
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const template = this.templateTarget
|
|
21
|
-
const newPair = template.content.cloneNode(true)
|
|
22
|
-
const index = this.pairTargets.length
|
|
23
|
-
|
|
24
|
-
// Update the template placeholders with actual indices
|
|
25
|
-
this.updatePairIndices(newPair, index)
|
|
26
|
-
|
|
27
|
-
this.containerTarget.appendChild(newPair)
|
|
28
|
-
this.updateIndices()
|
|
29
|
-
this.updateAddButtonState()
|
|
30
|
-
|
|
31
|
-
// Focus on the key input of the new pair
|
|
32
|
-
const newKeyInput = this.containerTarget.lastElementChild.querySelector('[data-key-value-store-target="keyInput"]')
|
|
33
|
-
if (newKeyInput) {
|
|
34
|
-
newKeyInput.focus()
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
removePair(event) {
|
|
39
|
-
event.preventDefault()
|
|
40
|
-
|
|
41
|
-
const pair = event.target.closest('[data-key-value-store-target="pair"]')
|
|
42
|
-
if (pair) {
|
|
43
|
-
pair.remove()
|
|
44
|
-
this.updateIndices()
|
|
45
|
-
this.updateAddButtonState()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
updateIndices() {
|
|
50
|
-
this.pairTargets.forEach((pair, index) => {
|
|
51
|
-
const keyInput = pair.querySelector('[data-key-value-store-target="keyInput"]')
|
|
52
|
-
const valueInput = pair.querySelector('[data-key-value-store-target="valueInput"]')
|
|
53
|
-
|
|
54
|
-
if (keyInput) {
|
|
55
|
-
// Update name attribute
|
|
56
|
-
keyInput.name = keyInput.name.replace(/\[\d+\]/, `[${index}]`)
|
|
57
|
-
// Update id attribute for Turbo compatibility
|
|
58
|
-
keyInput.id = keyInput.id.replace(/_\d+_/, `_${index}_`)
|
|
59
|
-
}
|
|
60
|
-
if (valueInput) {
|
|
61
|
-
// Update name attribute
|
|
62
|
-
valueInput.name = valueInput.name.replace(/\[\d+\]/, `[${index}]`)
|
|
63
|
-
// Update id attribute for Turbo compatibility
|
|
64
|
-
valueInput.id = valueInput.id.replace(/_\d+_/, `_${index}_`)
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
updatePairIndices(element, index) {
|
|
70
|
-
const inputs = element.querySelectorAll('input')
|
|
71
|
-
inputs.forEach(input => {
|
|
72
|
-
if (input.name) {
|
|
73
|
-
input.name = input.name.replace('__INDEX__', index)
|
|
74
|
-
}
|
|
75
|
-
if (input.id) {
|
|
76
|
-
input.id = input.id.replace('___INDEX___', `_${index}_`)
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
updateAddButtonState() {
|
|
82
|
-
const addButton = this.addButtonTarget
|
|
83
|
-
if (this.pairTargets.length >= this.limitValue) {
|
|
84
|
-
addButton.disabled = true
|
|
85
|
-
addButton.classList.add('opacity-50', 'cursor-not-allowed')
|
|
86
|
-
} else {
|
|
87
|
-
addButton.disabled = false
|
|
88
|
-
addButton.classList.remove('opacity-50', 'cursor-not-allowed')
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Serialize the current key-value pairs to JSON
|
|
93
|
-
toJSON() {
|
|
94
|
-
const pairs = {}
|
|
95
|
-
this.pairTargets.forEach(pair => {
|
|
96
|
-
const keyInput = pair.querySelector('[data-key-value-store-target="keyInput"]')
|
|
97
|
-
const valueInput = pair.querySelector('[data-key-value-store-target="valueInput"]')
|
|
98
|
-
|
|
99
|
-
if (keyInput && valueInput && keyInput.value.trim()) {
|
|
100
|
-
pairs[keyInput.value.trim()] = valueInput.value
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
return JSON.stringify(pairs)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Get the current key-value pairs as an object
|
|
107
|
-
toObject() {
|
|
108
|
-
const pairs = {}
|
|
109
|
-
this.pairTargets.forEach(pair => {
|
|
110
|
-
const keyInput = pair.querySelector('[data-key-value-store-target="keyInput"]')
|
|
111
|
-
const valueInput = pair.querySelector('[data-key-value-store-target="valueInput"]')
|
|
112
|
-
|
|
113
|
-
if (keyInput && valueInput && keyInput.value.trim()) {
|
|
114
|
-
pairs[keyInput.value.trim()] = valueInput.value
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
return pairs
|
|
118
|
-
}
|
|
119
|
-
}
|