plutonium 0.15.6 → 0.15.8
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/core/assets/templates/tailwind.config.js +11 -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/extra/colorized_logger/colorized_logger_generator.rb +21 -0
- data/lib/generators/pu/extra/colorized_logger/templates/config/initializers/colorized_logger.rb +22 -0
- 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/core/controllers/authorizable.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 +13 -9
- data/lib/plutonium/resource/controllers/authorizable.rb +2 -2
- data/lib/plutonium/resource/controllers/interactive_actions.rb +1 -1
- data/lib/plutonium/resource/controllers/presentable.rb +15 -8
- 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 +285 -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/package-lock.json +2 -2
- data/package.json +1 -1
- data/src/js/controllers/frame_navigator_controller.js +25 -8
- data/src/js/controllers/nested_resource_form_fields_controller.js +2 -2
- data/tailwind.config.js +11 -1
- data/tailwind.options.js +7 -1
- metadata +13 -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' )
|
@@ -1,12 +1,22 @@
|
|
1
1
|
const { execSync } = require('child_process');
|
2
2
|
const plutoniumGemPath = execSync("bundle show plutonium").toString().trim();
|
3
3
|
const plutoniumTailwindConfig = require(`${plutoniumGemPath}/tailwind.options.js`)
|
4
|
+
const tailwindPlugin = require('tailwindcss/plugin')
|
4
5
|
|
5
6
|
module.exports = {
|
6
7
|
darkMode: plutoniumTailwindConfig.darkMode,
|
7
8
|
plugins: [
|
8
9
|
// add plugins here
|
9
|
-
].concat(plutoniumTailwindConfig.plugins.map((plugin)
|
10
|
+
].concat(plutoniumTailwindConfig.plugins.map(function (plugin) {
|
11
|
+
switch (typeof plugin) {
|
12
|
+
case "function":
|
13
|
+
return tailwindPlugin(plugin)
|
14
|
+
case "string":
|
15
|
+
return require(plugin)
|
16
|
+
default:
|
17
|
+
throw Error(`unsupported plugin: ${plugin}: ${(typeof plugin)}`)
|
18
|
+
}
|
19
|
+
})),
|
10
20
|
theme: plutoniumTailwindConfig.theme,
|
11
21
|
content: [
|
12
22
|
`${__dirname}/app/**/*.rb`,
|
@@ -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)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../lib/plutonium_generators"
|
4
|
+
|
5
|
+
module Pu
|
6
|
+
module Extra
|
7
|
+
class ColorizedLoggerGenerator < Rails::Generators::Base
|
8
|
+
include PlutoniumGenerators::Generator
|
9
|
+
|
10
|
+
source_root File.expand_path("templates", __dir__)
|
11
|
+
|
12
|
+
desc "Set up a colorized logger"
|
13
|
+
|
14
|
+
def start
|
15
|
+
copy_file "config/initializers/colorized_logger.rb"
|
16
|
+
rescue => e
|
17
|
+
exception "#{self.class} failed:", e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/generators/pu/extra/colorized_logger/templates/config/initializers/colorized_logger.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
return unless Rails.env.development?
|
4
|
+
|
5
|
+
# Taken from https://gist.github.com/kyrylo/3d90f7a656d1a0accf244b8f1d25999b?permalink_comment_id=5264120#gistcomment-5264120
|
6
|
+
|
7
|
+
module ColorizedLogger
|
8
|
+
%i[debug info warn error fatal unknown].each do |level|
|
9
|
+
color = case level
|
10
|
+
when :debug then "\e[0;36m" # Cyan text
|
11
|
+
when :info then "\e[0;32m" # Green text
|
12
|
+
when :warn then "\e[1;33m" # Yellow text
|
13
|
+
when :error, :fatal then "\e[1;31m" # Red text
|
14
|
+
else "\e[0m" # Terminal default
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method(level) do |progname = nil, &block|
|
18
|
+
super(color + (progname || (block && block.call)).to_s + "\e[0m")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
Rails.logger.extend(ColorizedLogger)
|
@@ -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
|
@@ -34,7 +34,7 @@ module Plutonium
|
|
34
34
|
# Gets the resource class for the controller
|
35
35
|
# @return [ActiveRecord::Base] The resource class
|
36
36
|
def resource_class
|
37
|
-
return @resource_class if @resource_class
|
37
|
+
return @resource_class if @resource_class
|
38
38
|
|
39
39
|
name.to_s.gsub(/^#{current_package}::/, "").gsub(/Controller$/, "").classify.constantize
|
40
40
|
rescue NameError
|
@@ -52,14 +52,14 @@ module Plutonium
|
|
52
52
|
# Returns the resource record based on path parameters
|
53
53
|
# @return [ActiveRecord::Base, nil] The resource record
|
54
54
|
def resource_record
|
55
|
-
@resource_record ||= current_authorized_scope.from_path_param(params[:id]).first! if params[:id]
|
55
|
+
@resource_record ||= current_authorized_scope.from_path_param(params[:id]).first! if params[:id]
|
56
56
|
@resource_record
|
57
57
|
end
|
58
58
|
|
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
|
@@ -125,19 +125,23 @@ module Plutonium
|
|
125
125
|
# Applies submitted resource params if they have been passed
|
126
126
|
def maybe_apply_submitted_resource_params!
|
127
127
|
ensure_get_request
|
128
|
-
resource_record.attributes = submitted_resource_params if params[resource_param_key]
|
128
|
+
resource_record.attributes = submitted_resource_params if params[resource_param_key]
|
129
129
|
end
|
130
130
|
|
131
131
|
# Returns the current parent based on path parameters
|
132
132
|
# @return [ActiveRecord::Base, nil] The current parent
|
133
133
|
def current_parent
|
134
|
-
return unless parent_route_param
|
134
|
+
return unless parent_route_param
|
135
135
|
|
136
136
|
@current_parent ||= begin
|
137
137
|
parent_route_key = parent_route_param.to_s.gsub(/_id$/, "").to_sym
|
138
138
|
parent_class = current_engine.resource_register.route_key_lookup[parent_route_key]
|
139
|
-
parent_scope =
|
140
|
-
|
139
|
+
parent_scope = if scoped_to_entity?
|
140
|
+
parent_class.associated_with(current_scoped_entity)
|
141
|
+
else
|
142
|
+
parent_class.all
|
143
|
+
end
|
144
|
+
parent_scope = parent_scope.from_path_param(params[parent_route_param])
|
141
145
|
current_parent = parent_scope.first!
|
142
146
|
authorize! current_parent, to: :read?
|
143
147
|
current_parent
|
@@ -153,7 +157,7 @@ module Plutonium
|
|
153
157
|
# Returns the parent input parameter
|
154
158
|
# @return [Symbol, nil] The parent input parameter
|
155
159
|
def parent_input_param
|
156
|
-
return unless current_parent
|
160
|
+
return unless current_parent
|
157
161
|
|
158
162
|
resource_class.reflect_on_all_associations(:belongs_to).find { |assoc| assoc.klass.name == current_parent.class.name }&.name&.to_sym
|
159
163
|
end
|
@@ -182,7 +186,7 @@ module Plutonium
|
|
182
186
|
# Overrides parent parameters
|
183
187
|
# @param [Hash] input_params The input parameters
|
184
188
|
def override_parent_params(input_params)
|
185
|
-
if current_parent
|
189
|
+
if current_parent
|
186
190
|
if input_params.key?(parent_input_param) || resource_class.method_defined?(:"#{parent_input_param}=")
|
187
191
|
input_params[parent_input_param] = current_parent
|
188
192
|
end
|
@@ -112,7 +112,7 @@ module Plutonium
|
|
112
112
|
#
|
113
113
|
# @return [Hash] default context for the current resource's policy
|
114
114
|
def current_policy_context
|
115
|
-
{
|
115
|
+
{entity_scope: current_parent || entity_scope_for_authorize}
|
116
116
|
end
|
117
117
|
|
118
118
|
# Authorizes the current action for the given record of the current resource
|
@@ -130,7 +130,7 @@ module Plutonium
|
|
130
130
|
#
|
131
131
|
# @return [Array<Symbol>] the list of permitted attributes for the current action
|
132
132
|
def permitted_attributes
|
133
|
-
@permitted_attributes ||= current_policy.send_with_report(:"permitted_attributes_for_#{action_name}")
|
133
|
+
@permitted_attributes ||= current_policy.send_with_report(:"permitted_attributes_for_#{action_name}").freeze
|
134
134
|
end
|
135
135
|
|
136
136
|
# Returns the list of permitted associations for the current resource
|
@@ -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,6 @@ module Plutonium
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
helper_method :presentable_attributes, :present_associations?
|
9
8
|
helper_method :build_form, :build_detail, :build_collection
|
10
9
|
end
|
11
10
|
|
@@ -14,12 +13,24 @@ module Plutonium
|
|
14
13
|
def presentable_attributes
|
15
14
|
@presentable_attributes ||= begin
|
16
15
|
presentable_attributes = permitted_attributes
|
17
|
-
|
18
|
-
|
16
|
+
if current_parent
|
17
|
+
presentable_attributes -= [parent_input_param, :"#{parent_input_param}_id"]
|
18
|
+
elsif scoped_to_entity?
|
19
|
+
presentable_attributes -= [scoped_entity_param_key, :"#{scoped_entity_param_key}_id"]
|
20
|
+
end
|
19
21
|
presentable_attributes
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
25
|
+
def submittable_attributes
|
26
|
+
@submittable_attributes ||= begin
|
27
|
+
submittable_attributes = permitted_attributes
|
28
|
+
submittable_attributes -= [parent_input_param, :"#{parent_input_param}_id"] if current_parent
|
29
|
+
submittable_attributes -= [scoped_entity_param_key, :"#{scoped_entity_param_key}_id"] if scoped_to_entity?
|
30
|
+
submittable_attributes
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
23
34
|
def build_collection
|
24
35
|
current_definition.collection_class.new(@resource_records, resource_fields: presentable_attributes, resource_definition: current_definition)
|
25
36
|
end
|
@@ -29,11 +40,7 @@ module Plutonium
|
|
29
40
|
end
|
30
41
|
|
31
42
|
def build_form(record = resource_record)
|
32
|
-
current_definition.form_class.new(record, resource_fields:
|
33
|
-
end
|
34
|
-
|
35
|
-
def present_associations?
|
36
|
-
current_parent.nil?
|
43
|
+
current_definition.form_class.new(record, resource_fields: submittable_attributes, resource_definition: current_definition)
|
37
44
|
end
|
38
45
|
end
|
39
46
|
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, class: 'dyna', &)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|