plutonium 0.15.5 → 0.15.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +1 -1
  3. data/app/assets/plutonium.ico +0 -0
  4. data/app/assets/plutonium.js +25 -11
  5. data/app/assets/plutonium.js.map +2 -2
  6. data/app/assets/plutonium.min.js +4 -4
  7. data/app/assets/plutonium.min.js.map +3 -3
  8. data/app/assets/plutonium.png +0 -0
  9. data/app/views/layouts/rodauth.html.erb +2 -2
  10. data/docs/.vitepress/config.ts +61 -0
  11. data/docs/.vitepress/theme/custom.css +61 -0
  12. data/docs/.vitepress/theme/index.ts +4 -0
  13. data/docs/api-examples.md +49 -0
  14. data/docs/guide/getting-started/authorization.md +296 -0
  15. data/docs/guide/getting-started/core-concepts.md +432 -0
  16. data/docs/guide/getting-started/index.md +18 -0
  17. data/docs/guide/getting-started/installation.md +270 -0
  18. data/docs/guide/getting-started/resources.md +250 -0
  19. data/docs/guide/what-is-plutonium.md +211 -0
  20. data/docs/index.md +43 -0
  21. data/docs/markdown-examples.md +85 -0
  22. data/docs/public/android-chrome-192x192.png +0 -0
  23. data/docs/public/android-chrome-512x512.png +0 -0
  24. data/docs/public/apple-touch-icon.png +0 -0
  25. data/docs/public/favicon-16x16.png +0 -0
  26. data/docs/public/favicon-32x32.png +0 -0
  27. data/docs/public/favicon.ico +0 -0
  28. data/docs/public/plutonium.png +0 -0
  29. data/docs/public/site.webmanifest +1 -0
  30. data/docs/public/templates/plutonium.rb +29 -0
  31. data/lib/generators/pu/core/assets/assets_generator.rb +2 -3
  32. data/lib/generators/pu/core/assets/templates/tailwind.config.js +2 -2
  33. data/lib/generators/pu/core/install/install_generator.rb +9 -1
  34. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -1
  35. data/lib/generators/pu/eject/layout/layout_generator.rb +3 -3
  36. data/lib/generators/pu/eject/shell/shell_generator.rb +3 -3
  37. data/lib/generators/pu/gem/dotenv/dotenv_generator.rb +1 -1
  38. data/lib/generators/pu/gem/letter_opener/letter_opener_generator.rb +21 -0
  39. data/lib/generators/pu/gem/redis/redis_generator.rb +0 -2
  40. data/lib/generators/pu/gem/standard/standard_generator.rb +19 -0
  41. data/lib/generators/pu/lib/plutonium_generators/generator.rb +1 -1
  42. data/lib/generators/pu/res/conn/conn_generator.rb +1 -1
  43. data/lib/plutonium/core/controllers/authorizable.rb +1 -1
  44. data/lib/plutonium/definition/actions.rb +6 -2
  45. data/lib/plutonium/definition/base.rb +1 -0
  46. data/lib/plutonium/definition/nested_inputs.rb +19 -0
  47. data/lib/plutonium/railtie.rb +0 -10
  48. data/lib/plutonium/resource/controller.rb +1 -1
  49. data/lib/plutonium/resource/controllers/crud_actions.rb +1 -1
  50. data/lib/plutonium/resource/controllers/interactive_actions.rb +1 -1
  51. data/lib/plutonium/resource/controllers/presentable.rb +1 -5
  52. data/lib/plutonium/resource/policy.rb +4 -5
  53. data/lib/plutonium/resource/register.rb +3 -0
  54. data/lib/plutonium/ui/action_button.rb +34 -19
  55. data/lib/plutonium/ui/block.rb +13 -0
  56. data/lib/plutonium/ui/component/kit.rb +10 -0
  57. data/lib/plutonium/ui/display/resource.rb +29 -11
  58. data/lib/plutonium/ui/display/theme.rb +1 -1
  59. data/lib/plutonium/ui/dyna_frame/content.rb +2 -2
  60. data/lib/plutonium/ui/dyna_frame/host.rb +20 -0
  61. data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +282 -0
  62. data/lib/plutonium/ui/form/resource.rb +40 -29
  63. data/lib/plutonium/ui/form/theme.rb +1 -1
  64. data/lib/plutonium/ui/frame_navigator_panel.rb +53 -0
  65. data/lib/plutonium/ui/panel.rb +63 -0
  66. data/lib/plutonium/ui/skeleton_table.rb +29 -0
  67. data/lib/plutonium/ui/table/components/search_bar.rb +1 -1
  68. data/lib/plutonium/ui/table/resource.rb +1 -1
  69. data/lib/plutonium/version.rb +1 -1
  70. data/package-lock.json +5767 -1851
  71. data/package.json +10 -4
  72. data/src/js/controllers/frame_navigator_controller.js +25 -8
  73. data/src/js/controllers/nested_resource_form_fields_controller.js +2 -2
  74. data/src/js/core.js +0 -1
  75. data/tailwind.options.js +89 -11
  76. metadata +36 -12
  77. data/app/assets/plutonium-original.png +0 -0
  78. data/app/assets/plutonium-white.png +0 -0
  79. data/lib/generators/pu/gem/redis/templates/.keep +0 -0
  80. data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
  81. data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
  82. /data/{templates → docs/public/templates}/base.rb +0 -0
Binary file
@@ -12,8 +12,8 @@
12
12
  <%= yield %>
13
13
  </div>
14
14
  </div>
15
- <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
15
+ <div class="mt-4 flex items-center font-medium text-secondary-600 dark:text-secondary-400 hover:underline">
16
16
  <%= render_icon "outline/home" %>
17
- <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
17
+ <%= link_to "Home", root_path, class: "font-medium text-secondary-600 dark:text-secondary-400" %>
18
18
  </div>
19
19
  <% end %>
@@ -0,0 +1,61 @@
1
+ import { defineConfig } from "vitepress"
2
+ import { withMermaid } from "vitepress-plugin-mermaid";
3
+
4
+ const base = "/plutonium-core/"
5
+
6
+ // https://vitepress.dev/reference/site-config
7
+ export default defineConfig(withMermaid({
8
+ base: base,
9
+ title: "Plutonium",
10
+ description: "The Ultimate Rapid Application Development Toolkit (RADKit) for Rails",
11
+ head: [["link", { rel: "icon", href: `${base}favicon.ico` }]],
12
+ themeConfig: {
13
+ // https://vitepress.dev/reference/default-theme-config
14
+ logo: "/plutonium.png",
15
+ search: {
16
+ provider: 'local'
17
+ },
18
+ nav: [
19
+ { text: "Home", link: "/" },
20
+ { text: "Guide", link: "/guide/getting-started" }
21
+ ],
22
+ sidebar: {
23
+ '/guide/': [
24
+
25
+ {
26
+ text: "Introduction",
27
+ items: [
28
+ { text: "What is Plutonium?", link: "/guide/what-is-plutonium" },
29
+ ]
30
+ },
31
+ {
32
+ text: "Getting Started",
33
+ items: [
34
+ { text: "Overview", link: "/guide/getting-started/" },
35
+ { text: "Installation", link: "/guide/getting-started/installation" },
36
+ { text: "Core Concepts", link: "/guide/getting-started/core-concepts" },
37
+ { text: "Resources", link: "/guide/getting-started/resources" },
38
+ { text: "Authorization", link: "/guide/getting-started/authorization" },
39
+ ]
40
+ },
41
+ // { text: "Quick Start", link: "/installation" },
42
+
43
+ // {
44
+ // text: "Examples",
45
+ // items: [
46
+ // { text: "Markdown Examples", link: "/installation" },
47
+ // { text: "Runtime API Examples", link: "/api-examples" }
48
+ // ]
49
+ // }
50
+ ]
51
+ },
52
+ socialLinks: [
53
+ { icon: "github", link: "https://github.com/radioactive-labs/plutonium-core" }
54
+ ],
55
+ footer: {
56
+ message: 'Released under the MIT License.',
57
+ copyright: 'Copyright © 2024-present Stefan Froelich'
58
+ }
59
+ },
60
+ cleanUrls: true,
61
+ }))
@@ -0,0 +1,61 @@
1
+ /*
2
+
3
+ Primary Colors:
4
+
5
+ Coral/Orange Red: #FF4D4D (for main CTAs and primary elements)
6
+ Deep Turquoise: #00CED1 (for secondary elements)
7
+ Deep Blue: #1E3D59 (for text and accents)
8
+
9
+ Accent Colors:
10
+
11
+ Soft Pink: #FF9EAA (for highlights)
12
+ Light Blue: #B8E3E9 (for backgrounds)
13
+ White: #FFFFFF (for contrast and readability)
14
+
15
+ */
16
+
17
+ :root {
18
+ /* Primary Brand Colors - Inspired by the vibrant gradient */
19
+ --vp-c-brand-1: #FF4D4D;
20
+ /* Vibrant coral red */
21
+ --vp-c-brand-2: #FF6B4A;
22
+ /* Lighter coral */
23
+ --vp-c-brand-3: #FF8347;
24
+ /* Soft orange */
25
+ --vp-c-brand-soft: rgba(255, 77, 77, 0.14);
26
+
27
+ /* Accent Colors */
28
+ --vp-c-accent-1: #00CED1;
29
+ /* Turquoise */
30
+ --vp-c-accent-2: #1E90FF;
31
+ /* Bright blue */
32
+ --vp-c-accent-3: #4169E1;
33
+ /* Royal blue */
34
+ --vp-c-accent-soft: rgba(0, 206, 209, 0.14);
35
+
36
+ /* Custom Background Gradients */
37
+ --vp-home-hero-name-background: linear-gradient(120deg,
38
+ #FF4D4D 30%,
39
+ #00CED1);
40
+
41
+ /* Updating existing color references */
42
+ --vp-c-tip-1: var(--vp-c-accent-1);
43
+ --vp-c-tip-2: var(--vp-c-accent-2);
44
+ --vp-c-tip-3: var(--vp-c-accent-3);
45
+ --vp-c-tip-soft: var(--vp-c-accent-soft);
46
+ }
47
+
48
+ .dark {
49
+ /* Dark mode adjustments */
50
+ --vp-c-brand-1: #FF6B4A;
51
+ /* Slightly lighter coral for dark mode */
52
+ --vp-c-brand-2: #FF4D4D;
53
+ --vp-c-brand-3: #FF3333;
54
+ --vp-c-brand-soft: rgba(255, 107, 74, 0.16);
55
+
56
+ --vp-c-accent-1: #40E0E3;
57
+ /* Brighter turquoise for dark mode */
58
+ --vp-c-accent-2: #45A3FF;
59
+ --vp-c-accent-3: #6182E3;
60
+ --vp-c-accent-soft: rgba(64, 224, 227, 0.16);
61
+ }
@@ -0,0 +1,4 @@
1
+ import DefaultTheme from "vitepress/theme"
2
+ import "./custom.css"
3
+
4
+ export default DefaultTheme
@@ -0,0 +1,49 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Runtime API Examples
6
+
7
+ This page demonstrates usage of some of the runtime APIs provided by VitePress.
8
+
9
+ The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files:
10
+
11
+ ```md
12
+ <script setup>
13
+ import { useData } from 'vitepress'
14
+
15
+ const { theme, page, frontmatter } = useData()
16
+ </script>
17
+
18
+ ## Results
19
+
20
+ ### Theme Data
21
+ <pre>{{ theme }}</pre>
22
+
23
+ ### Page Data
24
+ <pre>{{ page }}</pre>
25
+
26
+ ### Page Frontmatter
27
+ <pre>{{ frontmatter }}</pre>
28
+ ```
29
+
30
+ <script setup>
31
+ import { useData } from 'vitepress'
32
+
33
+ const { site, theme, page, frontmatter } = useData()
34
+ </script>
35
+
36
+ ## Results
37
+
38
+ ### Theme Data
39
+ <pre>{{ theme }}</pre>
40
+
41
+ ### Page Data
42
+ <pre>{{ page }}</pre>
43
+
44
+ ### Page Frontmatter
45
+ <pre>{{ frontmatter }}</pre>
46
+
47
+ ## More
48
+
49
+ Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata).
@@ -0,0 +1,296 @@
1
+ # Authorization and Access Control
2
+
3
+ Plutonium provides a robust authorization system built on top of [Action Policy](https://actionpolicy.evilmartians.io/), offering fine-grained access control, resource scoping, and entity-based authorization.
4
+
5
+ ## Overview
6
+
7
+ Authorization in Plutonium operates at multiple levels:
8
+ - Resource-level policies
9
+ - Action-based permissions
10
+ - Entity-based scoping
11
+ - Attribute-level access control
12
+
13
+ ## Basic Policy Definition
14
+
15
+ Every resource in Plutonium requires a policy. Here's a basic example:
16
+
17
+ ```ruby
18
+ class BlogPolicy < ResourcePolicy
19
+ # Core CRUD Permissions
20
+
21
+ def create?
22
+ # All authenticated users can create blogs
23
+ true
24
+ end
25
+
26
+ def read?
27
+ # Allow anyone to read blogs
28
+ true
29
+ end
30
+
31
+ def update?
32
+ # Allow only the blog owner to update
33
+ owner?
34
+ end
35
+
36
+ def destroy?
37
+ # Allow only the blog owner or admins to destroy
38
+ owner? || user.admin?
39
+ end
40
+
41
+ # Attribute Control
42
+
43
+ def permitted_attributes_for_create
44
+ [:title, :content, :category]
45
+ end
46
+
47
+ def permitted_attributes_for_read
48
+ [:title, :content, :category, :created_at, :updated_at, :user_id]
49
+ end
50
+
51
+ def permitted_attributes_for_update
52
+ [:title, :content, :category]
53
+ end
54
+
55
+ # Association Access
56
+
57
+ def permitted_associations
58
+ [:comments]
59
+ end
60
+
61
+ private
62
+
63
+ def owner?
64
+ record.user_id == user.id
65
+ end
66
+ end
67
+ ```
68
+
69
+ ## Default Behaviors in Plutonium Policies
70
+
71
+ ::: info Overview
72
+ Plutonium's Policy system implements a secure-by-default pattern with clear inheritance chains for both permissions and attribute access.
73
+ :::
74
+
75
+ ### Permission Defaults
76
+
77
+ Permission methods follow two key patterns: core permissions that default to `false`, and derived permissions that inherit from core ones.
78
+
79
+ #### Core Permission Chain
80
+
81
+ ```mermaid
82
+ graph TD
83
+ subgraph Core Permissions
84
+ A[create? ❌] --> B[update? ❌]
85
+ A --> C[destroy? ❌]
86
+ D[read? ❌] --> E[index? ❌]
87
+ D --> F[show? ❌]
88
+ end
89
+ ```
90
+
91
+ ::: warning Security First
92
+ All core permissions (`create?` and `read?`) default to `false`. You must explicitly override these to grant access.
93
+ ```ruby
94
+ # Default implementations
95
+ def create?
96
+ false
97
+ end
98
+
99
+ def read?
100
+ false
101
+ end
102
+ ```
103
+ :::
104
+
105
+ #### Permission Inheritance
106
+
107
+ ::: code-group
108
+ ```ruby [Action Methods]
109
+ def update?
110
+ create? # Inherits from create?
111
+ end
112
+
113
+ def destroy?
114
+ create? # Inherits from create?
115
+ end
116
+
117
+ def index?
118
+ read? # Inherits from read?
119
+ end
120
+
121
+ def show?
122
+ read? # Inherits from read?
123
+ end
124
+ ```
125
+
126
+ ```ruby [Helper Methods]
127
+ def new?
128
+ create? # Matches create?
129
+ end
130
+
131
+ def edit?
132
+ update? # Matches update?
133
+ end
134
+
135
+ def search?
136
+ index? # Matches index?
137
+ end
138
+ ```
139
+ :::
140
+
141
+ ### Attribute Permission Defaults
142
+
143
+ Attribute permissions also follow an inheritance pattern, but with auto-detection in development:
144
+
145
+ ::: details Inheritance Chain
146
+ ```mermaid
147
+ graph TD
148
+ subgraph Core Attributes
149
+ A[permitted_attributes_for_create] --> B[permitted_attributes_for_update]
150
+ C[permitted_attributes_for_read] --> D[permitted_attributes_for_show]
151
+ C --> E[permitted_attributes_for_index]
152
+ end
153
+ ```
154
+ :::
155
+
156
+ #### Core Implementation Details
157
+
158
+ ::: code-group
159
+ ```ruby [Create Attributes]
160
+ def permitted_attributes_for_create
161
+ # Auto-detects fields but excludes system columns
162
+ autodetect_permitted_fields(:permitted_attributes_for_create) - [
163
+ resource_class.primary_key.to_sym,
164
+ :created_at,
165
+ :updated_at
166
+ ]
167
+ end
168
+ ```
169
+
170
+ ```ruby [Read Attributes]
171
+ def permitted_attributes_for_read
172
+ # Auto-detects all fields
173
+ autodetect_permitted_fields(:permitted_attributes_for_read)
174
+ end
175
+ ```
176
+
177
+ ```ruby [Update Attributes]
178
+ def permitted_attributes_for_update
179
+ # Inherits from create
180
+ permitted_attributes_for_create
181
+ end
182
+ ```
183
+ :::
184
+
185
+ ::: danger Auto-detection Warning
186
+ The default attribute detection:
187
+ - Only works in development
188
+ - Raises errors in other environments
189
+ - Shows warning messages
190
+ - Must be overridden in production
191
+ :::
192
+
193
+ ### Association Defaults
194
+
195
+ By default, no associations are permitted:
196
+
197
+ ```ruby
198
+ def permitted_associations
199
+ [] # Must be explicitly defined
200
+ end
201
+ ```
202
+
203
+ ### Context Object Defaults
204
+
205
+ Two built-in authorization contexts:
206
+
207
+ ::: code-group
208
+ ```ruby [Required Context]
209
+ # User must be present
210
+ authorize :user, allow_nil: false
211
+ ```
212
+
213
+ ```ruby [Optional Context]
214
+ # Entity scope is optional
215
+ authorize :entity_scope, allow_nil: true
216
+ ```
217
+ :::
218
+
219
+ #### Default Scoping Behavior
220
+
221
+ When an entity scope exists, records are automatically filtered:
222
+
223
+ ```ruby
224
+ relation_scope do |relation|
225
+ next relation unless entity_scope
226
+ relation.associated_with(entity_scope)
227
+ end
228
+ ```
229
+
230
+ #### Adding Custom Contexts
231
+
232
+ You can add additional authorization contexts:
233
+
234
+ ::: code-group
235
+ ```ruby [Policy]
236
+ class BlogPolicy < ResourcePolicy
237
+ authorize :ability, allow_nil: true
238
+
239
+ def promote?
240
+ user.admin? && ability&.can?(:promote, record)
241
+ end
242
+ end
243
+ ```
244
+
245
+ ```ruby [Controller]
246
+ class BlogsController < ResourceController
247
+ authorize :ability, through: :current_ability
248
+
249
+ private
250
+
251
+ def current_ability
252
+ @current_ability ||= Ability.new(current_user)
253
+ end
254
+ end
255
+ ```
256
+ :::
257
+
258
+ ## Quick Reference
259
+
260
+ | Method Type | Default | Inherits From |
261
+ |------------|---------|---------------|
262
+ | create? | false | - |
263
+ | read? | false | - |
264
+ | update? | false | create? |
265
+ | destroy? | false | create? |
266
+ | index? | false | read? |
267
+ | show? | false | read? |
268
+ | attributes_for_create | auto* | - |
269
+ | attributes_for_read | auto* | - |
270
+ | attributes_for_update | auto* | create |
271
+ | associations | [] | - |
272
+
273
+ ::: warning
274
+ \*Auto-detection only works in development
275
+ :::
276
+
277
+ ## Security Best Practices
278
+
279
+ ### 1. Never Skip Authorization
280
+
281
+ Plutonium controllers automatically verify authorization:
282
+
283
+ ```ruby
284
+ class BlogsController < ResourceController
285
+ def show
286
+ # This will raise an error if you forget to authorize
287
+ # authorize! resource_record
288
+ render :show
289
+ end
290
+ end
291
+ ```
292
+
293
+ ## Related Resources
294
+
295
+ - [Action Policy Documentation](https://actionpolicy.evilmartians.io/)
296
+ - [Rails Security Guide](https://guides.rubyonrails.org/security.html)