plutonium 0.15.6 → 0.15.7
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/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.js +25 -11
- data/app/assets/plutonium.js.map +2 -2
- data/app/assets/plutonium.min.js +4 -4
- data/app/assets/plutonium.min.js.map +3 -3
- data/app/views/layouts/rodauth.html.erb +2 -2
- data/docs/guide/getting-started/installation.md +2 -1
- data/docs/guide/getting-started/resources.md +8 -12
- data/docs/public/templates/plutonium.rb +8 -0
- data/lib/generators/pu/core/assets/assets_generator.rb +1 -1
- data/lib/generators/pu/eject/layout/layout_generator.rb +3 -3
- data/lib/generators/pu/eject/shell/shell_generator.rb +3 -3
- data/lib/generators/pu/gem/dotenv/dotenv_generator.rb +1 -1
- data/lib/generators/pu/gem/letter_opener/letter_opener_generator.rb +21 -0
- data/lib/generators/pu/gem/redis/redis_generator.rb +0 -2
- data/lib/generators/pu/gem/standard/standard_generator.rb +19 -0
- data/lib/generators/pu/lib/plutonium_generators/generator.rb +1 -1
- data/lib/generators/pu/res/conn/conn_generator.rb +1 -1
- data/lib/plutonium/definition/actions.rb +6 -2
- data/lib/plutonium/definition/base.rb +1 -0
- data/lib/plutonium/definition/nested_inputs.rb +19 -0
- data/lib/plutonium/resource/controller.rb +1 -1
- data/lib/plutonium/resource/controllers/interactive_actions.rb +1 -1
- data/lib/plutonium/resource/controllers/presentable.rb +1 -5
- data/lib/plutonium/ui/block.rb +13 -0
- data/lib/plutonium/ui/component/kit.rb +10 -0
- data/lib/plutonium/ui/display/resource.rb +29 -11
- data/lib/plutonium/ui/display/theme.rb +1 -1
- data/lib/plutonium/ui/dyna_frame/content.rb +2 -2
- data/lib/plutonium/ui/dyna_frame/host.rb +20 -0
- data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +282 -0
- data/lib/plutonium/ui/form/resource.rb +39 -29
- data/lib/plutonium/ui/form/theme.rb +1 -1
- data/lib/plutonium/ui/frame_navigator_panel.rb +53 -0
- data/lib/plutonium/ui/panel.rb +63 -0
- data/lib/plutonium/ui/skeleton_table.rb +29 -0
- data/lib/plutonium/ui/table/resource.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/src/js/controllers/frame_navigator_controller.js +25 -8
- data/src/js/controllers/nested_resource_form_fields_controller.js +2 -2
- metadata +11 -3
- data/lib/generators/pu/gem/redis/templates/.keep +0 -0
@@ -12,8 +12,8 @@
|
|
12
12
|
<%= yield %>
|
13
13
|
</div>
|
14
14
|
</div>
|
15
|
-
<div class="mt-4 flex items-center font-medium text-
|
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-
|
17
|
+
<%= link_to "Home", root_path, class: "font-medium text-secondary-600 dark:text-secondary-400" %>
|
18
18
|
</div>
|
19
19
|
<% end %>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
::: tip VERSION REQUIREMENTS
|
4
4
|
- Ruby 3.2.2 or higher
|
5
5
|
- Rails 7.1 or higher
|
6
|
+
- Node.js and Yarn
|
6
7
|
:::
|
7
8
|
|
8
9
|
## Quick Start
|
@@ -151,7 +152,7 @@ bin/importmap pin @radioactive-labs/plutonium
|
|
151
152
|
```
|
152
153
|
|
153
154
|
```bash [esbuild]
|
154
|
-
|
155
|
+
yarn add @radioactive-labs/plutonium
|
155
156
|
```
|
156
157
|
:::
|
157
158
|
|
@@ -17,7 +17,8 @@ Resources are the core building blocks of a Plutonium application. A resource re
|
|
17
17
|
The fastest way to create a resource is using the scaffold generator:
|
18
18
|
|
19
19
|
```bash
|
20
|
-
rails generate pu:res:scaffold Blog user:belongs_to
|
20
|
+
rails generate pu:res:scaffold Blog user:belongs_to \
|
21
|
+
title:string content:text 'published_at:datetime?'
|
21
22
|
```
|
22
23
|
|
23
24
|
This generates several files, including:
|
@@ -40,11 +41,11 @@ class BlogPolicy < Plutonium::Resource::Policy
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def permitted_attributes_for_create
|
43
|
-
%i[user title content
|
44
|
+
%i[user title content published_at]
|
44
45
|
end
|
45
46
|
|
46
47
|
def permitted_attributes_for_read
|
47
|
-
%i[user title content
|
48
|
+
%i[user title content published_at]
|
48
49
|
end
|
49
50
|
end
|
50
51
|
```
|
@@ -83,12 +84,12 @@ end
|
|
83
84
|
class BlogDefinition < Plutonium::Resource::Definition
|
84
85
|
# Customize how fields are displayed
|
85
86
|
display :title, class: "col-span-full"
|
86
|
-
display :content do |f|
|
87
|
+
display :content, class: "col-span-full" do |f|
|
87
88
|
f.text_tag class: "prose dark:prose-invert"
|
88
89
|
end
|
89
90
|
|
90
91
|
# Custom column display in tables
|
91
|
-
column :
|
92
|
+
column :published_at, align: :end
|
92
93
|
end
|
93
94
|
```
|
94
95
|
:::
|
@@ -140,7 +141,6 @@ module Blogs
|
|
140
141
|
|
141
142
|
def execute
|
142
143
|
if resource.update(
|
143
|
-
state: "published",
|
144
144
|
published_at: publish_date
|
145
145
|
)
|
146
146
|
succeed(resource)
|
@@ -175,20 +175,16 @@ class BlogDefinition < Plutonium::Resource::Definition
|
|
175
175
|
end
|
176
176
|
|
177
177
|
# Add filters
|
178
|
-
filter :state,
|
179
|
-
with: SelectFilter,
|
180
|
-
choices: %w[draft published]
|
181
|
-
|
182
178
|
filter :published_at,
|
183
179
|
with: DateFilter,
|
184
180
|
predicate: :gteq
|
185
181
|
|
186
182
|
# Add scopes
|
187
183
|
scope :published do |scope|
|
188
|
-
where(
|
184
|
+
scope.where.not(published_at: nil)
|
189
185
|
end
|
190
186
|
scope :draft do |scope|
|
191
|
-
where(
|
187
|
+
scope.where(published_at: nil)
|
192
188
|
end
|
193
189
|
|
194
190
|
# Configure sorting
|
@@ -15,6 +15,14 @@ after_bundle do
|
|
15
15
|
git add: "."
|
16
16
|
git commit: %( -m 'add annotate' )
|
17
17
|
|
18
|
+
generate "pu:gem:standard"
|
19
|
+
git add: "."
|
20
|
+
git commit: %( -m 'add standardrb' )
|
21
|
+
|
22
|
+
generate "pu:gem:letter_opener"
|
23
|
+
git add: "."
|
24
|
+
git commit: %( -m 'add letter_opener' )
|
25
|
+
|
18
26
|
generate "pu:core:assets"
|
19
27
|
git add: "."
|
20
28
|
git commit: %( -m 'integrate assets' )
|
@@ -15,7 +15,7 @@ module Pu
|
|
15
15
|
class_option :rodauth, type: :boolean
|
16
16
|
|
17
17
|
def start
|
18
|
-
destination_dir = (
|
18
|
+
destination_dir = (destination_portal == "main_app") ? "app/views/" : "packages/#{destination_portal}/app/views/"
|
19
19
|
[
|
20
20
|
"layouts/resource.html.erb"
|
21
21
|
].each do |file|
|
@@ -27,8 +27,8 @@ module Pu
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def
|
31
|
-
@
|
30
|
+
def destination_portal
|
31
|
+
@destination_portal || select_portal(options[:dest], msg: "Select destination portal")
|
32
32
|
end
|
33
33
|
|
34
34
|
def copy_file(source_path, destination_path)
|
@@ -14,7 +14,7 @@ module Pu
|
|
14
14
|
class_option :dest, type: :string
|
15
15
|
|
16
16
|
def start
|
17
|
-
destination_dir = (
|
17
|
+
destination_dir = (destination_portal == "main_app") ? "app/views/" : "packages/#{destination_portal}/app/views"
|
18
18
|
[
|
19
19
|
"plutonium/_resource_header.html.erb",
|
20
20
|
"plutonium/_resource_sidebar.html.erb"
|
@@ -27,8 +27,8 @@ module Pu
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def
|
31
|
-
@
|
30
|
+
def destination_portal
|
31
|
+
@destination_portal || select_portal(options[:dest], msg: "Select destination portal")
|
32
32
|
end
|
33
33
|
|
34
34
|
def copy_file(source_path, destination_path)
|
@@ -21,7 +21,7 @@ module Pu
|
|
21
21
|
|
22
22
|
gitignore "!/.env.template", "!/.env.local.template", "!/.env"
|
23
23
|
|
24
|
-
insert_into_file "Gemfile", "\ngem \"dotenv\", :
|
24
|
+
insert_into_file "Gemfile", "\ngem \"dotenv\", groups: %i[development test]\n", after: /^gem ["']rails["'].*\n/
|
25
25
|
bundle!
|
26
26
|
end
|
27
27
|
rescue => e
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../lib/plutonium_generators"
|
4
|
+
|
5
|
+
module Pu
|
6
|
+
module Gem
|
7
|
+
class LetterOpenerGenerator < Rails::Generators::Base
|
8
|
+
include PlutoniumGenerators::Generator
|
9
|
+
|
10
|
+
desc "Set up letter_opener"
|
11
|
+
|
12
|
+
def start
|
13
|
+
bundle "letter_opener", group: :development
|
14
|
+
environment "config.action_mailer.delivery_method = :letter_opener", env: :development
|
15
|
+
environment "config.action_mailer.perform_deliveries = true", env: :development
|
16
|
+
rescue => e
|
17
|
+
exception "#{self.class} failed:", e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../lib/plutonium_generators"
|
4
|
+
|
5
|
+
module Pu
|
6
|
+
module Gem
|
7
|
+
class StandardGenerator < Rails::Generators::Base
|
8
|
+
include PlutoniumGenerators::Generator
|
9
|
+
|
10
|
+
desc "Set up standardrb"
|
11
|
+
|
12
|
+
def start
|
13
|
+
bundle "standardrb"
|
14
|
+
rescue => e
|
15
|
+
exception "#{self.class} failed:", e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -22,7 +22,7 @@ module Pu
|
|
22
22
|
error "No resources found" if available_resources.blank?
|
23
23
|
selected_resources = prompt.multi_select("Select resources", available_resources)
|
24
24
|
|
25
|
-
@app_namespace =
|
25
|
+
@app_namespace = select_portal.camelize
|
26
26
|
|
27
27
|
selected_resources.each do |resource|
|
28
28
|
@resource_class = resource
|
@@ -14,8 +14,12 @@ module Plutonium
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def action(name, **)
|
18
|
-
instance_defined_actions[name] =
|
17
|
+
def action(name, interaction: nil, **)
|
18
|
+
instance_defined_actions[name] = if interaction
|
19
|
+
Plutonium::Action::Interactive::Factory.create(name, interaction:, **)
|
20
|
+
else
|
21
|
+
Plutonium::Action::Simple.new(name, **)
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
def defined_actions
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Definition
|
3
|
+
module NestedInputs
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
defineable_prop :nested_input
|
8
|
+
|
9
|
+
# def self.nested_input(name, with: nil, **)
|
10
|
+
# defined_nested_inputs[name] = {}
|
11
|
+
# end
|
12
|
+
|
13
|
+
# def nested_input(name, with: nil, **)
|
14
|
+
# instance_defined_nested_inputs[name] = {}
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -59,7 +59,7 @@ module Plutonium
|
|
59
59
|
# Returns the submitted resource parameters
|
60
60
|
# @return [Hash] The submitted resource parameters
|
61
61
|
def submitted_resource_params
|
62
|
-
@submitted_resource_params ||= build_form(resource_class.new).extract_input(params)[resource_param_key.to_sym]
|
62
|
+
@submitted_resource_params ||= build_form(resource_class.new).extract_input(params, view_context:)[resource_param_key.to_sym]
|
63
63
|
end
|
64
64
|
|
65
65
|
# Returns the resource parameters, including scoped and parent parameters
|
@@ -232,7 +232,7 @@ module Plutonium
|
|
232
232
|
@submitted_interaction_params ||= current_interactive_action
|
233
233
|
.interaction
|
234
234
|
.build_form(nil)
|
235
|
-
.extract_input(params)[:interaction]
|
235
|
+
.extract_input(params, view_context:)[:interaction]
|
236
236
|
end
|
237
237
|
|
238
238
|
def redirect_url_after_action_on(resource_record_or_resource_class)
|
@@ -5,7 +5,7 @@ module Plutonium
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
helper_method :presentable_attributes
|
8
|
+
helper_method :presentable_attributes
|
9
9
|
helper_method :build_form, :build_detail, :build_collection
|
10
10
|
end
|
11
11
|
|
@@ -31,10 +31,6 @@ module Plutonium
|
|
31
31
|
def build_form(record = resource_record)
|
32
32
|
current_definition.form_class.new(record, resource_fields: presentable_attributes, resource_definition: current_definition)
|
33
33
|
end
|
34
|
-
|
35
|
-
def present_associations?
|
36
|
-
current_parent.nil?
|
37
|
-
end
|
38
34
|
end
|
39
35
|
end
|
40
36
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module UI
|
3
|
+
class Block < Plutonium::UI::Component::Base
|
4
|
+
def view_template(&)
|
5
|
+
raise ArgumentError, "Block requires a content block" unless block_given?
|
6
|
+
|
7
|
+
div class: "relative bg-white dark:bg-gray-800 shadow-md sm:rounded-lg my-3" do
|
8
|
+
yield
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -10,6 +10,16 @@ module Plutonium
|
|
10
10
|
|
11
11
|
def Breadcrumbs(...) = render Plutonium::UI::Breadcrumbs.new(...)
|
12
12
|
|
13
|
+
def SkeletonTable(...) = render Plutonium::UI::SkeletonTable.new(...)
|
14
|
+
|
15
|
+
def Block(...) = render Plutonium::UI::Block.new(...)
|
16
|
+
|
17
|
+
def Panel(...) = render Plutonium::UI::Panel.new(...)
|
18
|
+
|
19
|
+
def FrameNavigatorPanel(...) = render Plutonium::UI::FrameNavigatorPanel.new(...)
|
20
|
+
|
21
|
+
def DynaFrameHost(...) = render Plutonium::UI::DynaFrame::Host.new(...)
|
22
|
+
|
13
23
|
def DynaFrameContent(...) = render Plutonium::UI::DynaFrame::Content.new(...)
|
14
24
|
|
15
25
|
def PageHeader(...) = render Plutonium::UI::PageHeader.new(...)
|
@@ -21,19 +21,37 @@ module Plutonium
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def render_fields
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
Block do
|
25
|
+
fields_wrapper do
|
26
|
+
resource_fields.each do |name|
|
27
|
+
render_resource_field name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
29
31
|
end
|
30
32
|
|
31
33
|
def render_associations
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
resource_associations.each do |name|
|
35
|
+
reflection = object.class.reflect_on_association name
|
36
|
+
|
37
|
+
if !reflection
|
38
|
+
raise ArgumentError,
|
39
|
+
"unknown association #{object.class}##{name} defined in #permitted_associations"
|
40
|
+
elsif !registered_resources.include?(reflection.klass)
|
41
|
+
raise ArgumentError,
|
42
|
+
"#{object.class}##{name} defined in #permitted_associations, but #{reflection.klass} is not a registered resource"
|
43
|
+
end
|
44
|
+
|
45
|
+
title = object.class.human_attribute_name(name)
|
46
|
+
src = case reflection.macro
|
47
|
+
when :belongs_to
|
48
|
+
associated = object.public_send name
|
49
|
+
resource_url_for(associated, parent: nil) if associated
|
50
|
+
when :has_many
|
51
|
+
resource_url_for(reflection.klass, parent: object)
|
52
|
+
end
|
53
|
+
FrameNavigatorPanel(title:, src:) if src
|
54
|
+
end
|
37
55
|
end
|
38
56
|
|
39
57
|
def render_resource_field(name)
|
@@ -73,7 +91,7 @@ module Plutonium
|
|
73
91
|
end
|
74
92
|
|
75
93
|
def present_associations?
|
76
|
-
|
94
|
+
current_turbo_frame.nil?
|
77
95
|
end
|
78
96
|
end
|
79
97
|
end
|
@@ -6,7 +6,7 @@ module Plutonium
|
|
6
6
|
class Theme < Phlexi::Display::Theme
|
7
7
|
def self.theme
|
8
8
|
super.merge({
|
9
|
-
base: "
|
9
|
+
base: "",
|
10
10
|
value_wrapper: "max-h-[300px] overflow-y-auto",
|
11
11
|
fields_wrapper: "p-6 grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-4 gap-6 gap-y-10 grid-flow-row-dense",
|
12
12
|
label: "text-base font-bold text-gray-500 dark:text-gray-400 mb-1",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module UI
|
3
|
+
module DynaFrame
|
4
|
+
class Host < Plutonium::UI::Component::Base
|
5
|
+
include Phlex::Rails::Helpers::TurboFrameTag
|
6
|
+
|
7
|
+
def initialize(src:, loading:, id: SecureRandom.hex, **attributes)
|
8
|
+
@id = id
|
9
|
+
@src = src
|
10
|
+
@loading = loading
|
11
|
+
@attributes = attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
def view_template(&)
|
15
|
+
turbo_frame_tag(@id, src: @src, loading: @loading, **@attributes, &)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|