plutonium 0.14.0 → 0.15.0.pre.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README copy.md +1 -1
- data/README.md +1 -1
- data/app/assets/plutonium.css +1 -1
- data/app/views/{application → plutonium}/_resource_header.html copy.erb +1 -1
- data/app/views/{application → plutonium}/_resource_header.html.erb +1 -1
- data/app/views/{application → plutonium}/_resource_sidebar.html.erb +2 -0
- data/app/views/resource/_resource_details.html.erb +1 -36
- data/app/views/resource/_resource_form.html.erb +1 -5
- data/app/views/resource/_resource_table.html.erb +315 -85
- data/app/views/resource/edit.html.erb +1 -5
- data/app/views/resource/index.html.erb +1 -5
- data/app/views/resource/new.html.erb +1 -5
- data/app/views/resource/show.html.erb +1 -5
- data/config/initializers/pagy.rb +1 -0
- data/config/initializers/rabl.rb +27 -20
- data/gemfiles/rails_7.gemfile.lock +5 -1
- data/lib/generators/pu/core/assets/assets_generator.rb +2 -2
- data/lib/generators/pu/core/install/install_generator.rb +0 -3
- data/lib/generators/pu/core/install/templates/app/controllers/plutonium_controller.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/controllers/resource_controller.rb.tt +21 -1
- data/lib/generators/pu/core/install/templates/app/definitions/resource_definition.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/models/resource_record.rb.tt +0 -2
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +5 -2
- data/lib/generators/pu/eject/shell/shell_generator.rb +2 -2
- data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +19 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/logger.rb +1 -1
- data/lib/generators/pu/lib/plutonium_generators/generator.rb +5 -3
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +26 -2
- data/lib/generators/pu/pkg/{feature/feature_generator.rb → package/package_generator.rb} +4 -4
- data/lib/generators/pu/pkg/{feature → package}/templates/app/controllers/resource_controller.rb.tt +0 -2
- data/lib/generators/pu/pkg/package/templates/app/definitions/resource_definition.rb.tt +4 -0
- data/lib/generators/pu/pkg/package/templates/app/query_objects/resource_query_object.rb.tt +4 -0
- data/lib/generators/pu/pkg/{app/app_generator.rb → portal/portal_generator.rb} +10 -8
- data/lib/generators/pu/pkg/{app → portal}/templates/app/controllers/concerns/controller.rb.tt +3 -7
- data/lib/generators/pu/pkg/{app → portal}/templates/app/controllers/dashboard_controller.rb.tt +1 -1
- data/lib/generators/pu/pkg/portal/templates/app/controllers/plutonium_controller.rb.tt +5 -0
- data/lib/generators/pu/pkg/{app/templates/app/controllers/controller.rb.tt → portal/templates/app/controllers/resource_controller.rb.tt} +1 -1
- data/lib/generators/pu/pkg/portal/templates/app/definitions/resource_definition.rb.tt +4 -0
- data/lib/generators/pu/pkg/{app → portal}/templates/app/views/package/dashboard/index.html.erb +2 -1
- data/lib/generators/pu/res/conn/conn_generator.rb +78 -3
- data/lib/generators/pu/res/conn/templates/app/controllers/resource_controller.rb.tt +1 -1
- data/lib/generators/pu/res/conn/templates/app/definitions/resource_definition.rb.tt +3 -0
- data/lib/generators/pu/res/conn/templates/app/policies/resource_policy.rb.tt +29 -1
- data/lib/generators/pu/res/conn/templates/app/presenters/resource_presenter.rb.tt +1 -1
- data/lib/generators/pu/res/conn/templates/app/query_objects/resource_query_object.rb.tt +1 -1
- data/lib/generators/pu/res/model/model_generator.rb +0 -7
- data/lib/generators/pu/res/model/templates/model.rb.tt +4 -1
- data/lib/generators/pu/res/scaffold/scaffold_generator.rb +22 -4
- data/lib/generators/pu/res/scaffold/templates/controller.rb.tt +0 -1
- data/lib/generators/pu/res/scaffold/templates/definition.rb.tt +4 -0
- data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +2 -2
- data/lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt +1 -1
- data/lib/generators/pu/rodauth/templates/app/rodauth/account_rodauth_plugin.rb.tt +270 -0
- data/lib/plutonium/action/README.md +0 -0
- data/lib/plutonium/action/base.rb +103 -0
- data/lib/plutonium/action/interactive.rb +117 -0
- data/lib/plutonium/action/route_options.rb +65 -0
- data/lib/plutonium/action/simple.rb +8 -0
- data/lib/plutonium/auth.rb +1 -1
- data/lib/plutonium/configuration.rb +130 -0
- data/lib/plutonium/core/actions/collection.rb +1 -1
- data/lib/plutonium/core/associations/renderers/factory.rb +3 -1
- data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +1 -1
- data/lib/plutonium/core/autodiscovery/input_discoverer.rb +1 -1
- data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +1 -1
- data/lib/plutonium/core/controller.rb +110 -0
- data/lib/plutonium/core/controllers/authorizable.rb +12 -35
- data/lib/plutonium/core/controllers/bootable.rb +38 -7
- data/lib/plutonium/core/controllers/entity_scoping.rb +6 -2
- data/lib/plutonium/core/fields/renderers/association_renderer.rb +1 -1
- data/lib/plutonium/core/ui/collection.rb +1 -1
- data/lib/plutonium/core/ui/detail.rb +1 -1
- data/lib/plutonium/core/ui/form.rb +1 -1
- data/lib/plutonium/definition/actions.rb +50 -0
- data/lib/plutonium/definition/base.rb +92 -0
- data/lib/plutonium/definition/config_attr.rb +30 -0
- data/lib/plutonium/definition/defineable_props.rb +96 -0
- data/lib/plutonium/definition/search.rb +21 -0
- data/lib/plutonium/engine/validator.rb +30 -0
- data/lib/plutonium/engine.rb +25 -0
- data/lib/plutonium/helpers/assets_helper.rb +73 -20
- data/lib/plutonium/helpers/form_helper.rb +1 -3
- data/lib/plutonium/interaction/README.md +369 -0
- data/lib/plutonium/interaction/base.rb +75 -0
- data/lib/plutonium/interaction/concerns/presentable.rb +61 -0
- data/lib/plutonium/interaction/concerns/workflow_dsl.rb +82 -0
- data/lib/plutonium/interaction/outcome.rb +129 -0
- data/lib/plutonium/interaction/response/base.rb +63 -0
- data/lib/plutonium/interaction/response/null.rb +33 -0
- data/lib/plutonium/interaction/response/redirect.rb +30 -0
- data/lib/plutonium/interaction/response/render.rb +28 -0
- data/lib/plutonium/lib/bit_flags.rb +70 -9
- data/lib/plutonium/lib/overlayed_hash.rb +86 -0
- data/lib/plutonium/lib/smart_cache.rb +171 -0
- data/lib/plutonium/models/has_cents.rb +170 -0
- data/lib/plutonium/{pkg/base.rb → package/engine.rb} +10 -2
- data/lib/plutonium/{application → portal}/controller.rb +3 -11
- data/lib/plutonium/{application → portal}/dynamic_controllers.rb +4 -4
- data/lib/plutonium/portal/engine.rb +15 -0
- data/lib/plutonium/railtie.rb +35 -15
- data/lib/plutonium/reloader.rb +71 -29
- data/lib/plutonium/resource/controller.rb +51 -34
- data/lib/plutonium/resource/controllers/authorizable.rb +128 -0
- data/lib/plutonium/{core → resource}/controllers/crud_actions.rb +23 -22
- data/lib/plutonium/resource/controllers/defineable.rb +26 -0
- data/lib/plutonium/{core → resource}/controllers/interactive_actions.rb +12 -12
- data/lib/plutonium/resource/controllers/presentable.rb +41 -0
- data/lib/plutonium/resource/controllers/queryable.rb +44 -0
- data/lib/plutonium/resource/definition.rb +6 -0
- data/lib/plutonium/resource/policy.rb +25 -13
- data/lib/plutonium/resource/query_object.rb +50 -51
- data/lib/plutonium/resource/record.rb +6 -89
- data/lib/plutonium/resource/register.rb +82 -0
- data/lib/plutonium/routing/mapper_extensions.rb +1 -1
- data/lib/plutonium/routing/resource_registration.rb +1 -1
- data/lib/plutonium/routing/route_set_extensions.rb +6 -18
- data/lib/plutonium/ui/action_button.rb +125 -0
- data/lib/plutonium/ui/breadcrumbs.rb +163 -0
- data/lib/plutonium/ui/component/base.rb +13 -0
- data/lib/plutonium/ui/component/behaviour.rb +38 -0
- data/lib/plutonium/ui/component/kit.rb +31 -0
- data/lib/plutonium/ui/component/methods.rb +54 -0
- data/lib/plutonium/ui/display/base.rb +25 -0
- data/lib/plutonium/ui/display/component/association.rb +26 -0
- data/lib/plutonium/ui/display/resource.rb +77 -0
- data/lib/plutonium/ui/display/theme.rb +27 -0
- data/lib/plutonium/ui/dyna_frame/content.rb +20 -0
- data/lib/plutonium/ui/empty_card.rb +20 -0
- data/lib/plutonium/ui/form/base.rb +37 -0
- data/lib/plutonium/ui/form/resource.rb +75 -0
- data/lib/plutonium/ui/form/theme.rb +42 -0
- data/lib/plutonium/ui/page/base.rb +112 -0
- data/lib/plutonium/ui/page/edit.rb +23 -0
- data/lib/plutonium/ui/page/index.rb +27 -0
- data/lib/plutonium/ui/page/new.rb +23 -0
- data/lib/plutonium/ui/page/show.rb +27 -0
- data/lib/plutonium/ui/page_header.rb +49 -0
- data/lib/plutonium/ui/table/base.rb +13 -0
- data/lib/plutonium/ui/table/components/pagy_info.rb +70 -0
- data/lib/plutonium/ui/table/components/pagy_page_info.rb +70 -0
- data/lib/plutonium/ui/table/components/pagy_pagination.rb +105 -0
- data/lib/plutonium/ui/table/components/scopes_bar.rb +136 -0
- data/lib/plutonium/ui/table/components/search_bar.rb +158 -0
- data/lib/plutonium/ui/table/display_theme.rb +21 -0
- data/lib/plutonium/ui/table/resource.rb +98 -0
- data/lib/plutonium/ui/table/theme.rb +35 -0
- data/lib/plutonium/ui.rb +9 -0
- data/lib/plutonium/version.rb +5 -1
- data/lib/plutonium.rb +53 -26
- data/package-lock.json +19 -22
- data/package.json +4 -4
- data/sig/.keep +0 -0
- data/src/css/plutonium.css +15 -0
- data/tailwind.options.js +11 -3
- metadata +220 -81
- data/lib/generators/pu/core/install/templates/app/presenters/resource_presenter.rb.tt +0 -2
- data/lib/generators/pu/core/install/templates/app/query_objects/resource_query_object.rb.tt +0 -2
- data/lib/generators/pu/pkg/feature/templates/app/query_objects/resource_query_object.rb.tt +0 -4
- data/lib/plutonium/concerns/resource_validatable.rb +0 -34
- data/lib/plutonium/config.rb +0 -9
- data/lib/plutonium/core/controllers/base.rb +0 -101
- data/lib/plutonium/core/controllers/presentable.rb +0 -65
- data/lib/plutonium/core/controllers/queryable.rb +0 -28
- data/lib/plutonium/pkg/app.rb +0 -35
- data/lib/plutonium/pkg/concerns/resource_validatable.rb +0 -36
- data/lib/plutonium/pkg/feature.rb +0 -18
- data/lib/plutonium/policy/initializer.rb +0 -22
- data/lib/plutonium/policy/scope.rb +0 -19
- data/lib/plutonium/pundit/context.rb +0 -18
- data/lib/plutonium/pundit/policy_finder.rb +0 -25
- data/lib/plutonium/resource/policy_context.rb +0 -5
- data/lib/plutonium/resource_register.rb +0 -83
- data/lib/plutonium/smart_cache.rb +0 -151
- data/sig/plutonium.rbs +0 -12
- /data/app/views/{application → plutonium}/_flash.html.erb +0 -0
- /data/app/views/{application → plutonium}/_flash_alerts.html.erb +0 -0
- /data/app/views/{application → plutonium}/_flash_toasts.html.erb +0 -0
- /data/lib/generators/pu/pkg/{app/templates/app/views/package → package/templates}/.keep +0 -0
- /data/lib/generators/pu/pkg/{feature → package}/templates/app/interactions/resource_interaction.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{feature → package}/templates/app/models/resource_record.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{feature → package}/templates/app/policies/resource_policy.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{feature → package}/templates/app/presenters/resource_presenter.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{feature → package}/templates/lib/engine.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{app → portal}/templates/app/policies/resource_policy.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{app → portal}/templates/app/presenters/resource_presenter.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{app → portal}/templates/app/query_objects/resource_query_object.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{feature/templates → portal/templates/app/views/package}/.keep +0 -0
- /data/lib/generators/pu/pkg/{app → portal}/templates/config/routes.rb.tt +0 -0
- /data/lib/generators/pu/pkg/{app → portal}/templates/lib/engine.rb.tt +0 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
class ActionButton < Plutonium::UI::Component::Base
|
6
|
+
include Phlex::Rails::Helpers::LinkTo
|
7
|
+
include Phlex::Rails::Helpers::ButtonTo
|
8
|
+
|
9
|
+
def initialize(action, url:, variant: :default)
|
10
|
+
@action = action
|
11
|
+
@url = url
|
12
|
+
@variant = variant
|
13
|
+
end
|
14
|
+
|
15
|
+
def view_template
|
16
|
+
if @action.route_options.method == :get
|
17
|
+
render_link
|
18
|
+
else
|
19
|
+
render_button
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def render_link
|
26
|
+
link_to(
|
27
|
+
@url,
|
28
|
+
class: button_classes,
|
29
|
+
data: {turbo_frame: @action.turbo_frame}
|
30
|
+
) do
|
31
|
+
render_button_content
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_button
|
36
|
+
button_to(
|
37
|
+
@url,
|
38
|
+
method: @action.route_options.method,
|
39
|
+
name: :return_to, value: request.original_url,
|
40
|
+
class: "inline-block",
|
41
|
+
form: {
|
42
|
+
data: {
|
43
|
+
turbo_confirm: @action.confirmation,
|
44
|
+
turbo_frame: @action.turbo_frame
|
45
|
+
}
|
46
|
+
}
|
47
|
+
) do
|
48
|
+
span(class: button_classes) do
|
49
|
+
render_button_content
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_button_content
|
55
|
+
if @action.icon
|
56
|
+
render @action.icon.new(class: icon_classes)
|
57
|
+
end
|
58
|
+
span { @action.label } unless @variant == :table
|
59
|
+
end
|
60
|
+
|
61
|
+
def button_classes
|
62
|
+
tokens(
|
63
|
+
base_classes,
|
64
|
+
color_classes,
|
65
|
+
size_classes,
|
66
|
+
-> { @action.icon && @variant != :table } => "space-x-1"
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def base_classes
|
71
|
+
if @variant == :table
|
72
|
+
"inline-flex items-center justify-center p-1 rounded-lg focus:outline-none focus:ring-2"
|
73
|
+
else
|
74
|
+
"flex items-center justify-center px-4 py-2 text-sm font-medium rounded-lg focus:outline-none focus:ring-4"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def icon_classes
|
79
|
+
if @variant == :table
|
80
|
+
"h-4 w-4"
|
81
|
+
else
|
82
|
+
"h-3.5 w-3.5 mr-2 -ml-1"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def size_classes
|
87
|
+
(@variant == :table) ? "text-xs" : "text-sm"
|
88
|
+
end
|
89
|
+
|
90
|
+
def color_classes
|
91
|
+
case @action.color || @action.category.to_sym
|
92
|
+
when :primary
|
93
|
+
table_variant_class(
|
94
|
+
"bg-primary-100 text-primary-700 hover:bg-primary-200 focus:ring-primary-300 dark:bg-primary-700 dark:text-primary-100 dark:hover:bg-primary-600 dark:focus:ring-primary-600",
|
95
|
+
"bg-primary-700 text-white hover:bg-primary-800 focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800"
|
96
|
+
)
|
97
|
+
when :warning
|
98
|
+
table_variant_class(
|
99
|
+
"bg-yellow-100 text-yellow-700 hover:bg-yellow-200 focus:ring-yellow-300 dark:bg-yellow-700 dark:text-yellow-100 dark:hover:bg-yellow-600 dark:focus:ring-yellow-600",
|
100
|
+
"bg-yellow-400 text-white hover:bg-yellow-500 focus:ring-yellow-300 dark:bg-yellow-600 dark:hover:bg-yellow-700 dark:focus:ring-yellow-800"
|
101
|
+
)
|
102
|
+
when :danger
|
103
|
+
table_variant_class(
|
104
|
+
"bg-red-100 text-red-700 hover:bg-red-200 focus:ring-red-300 dark:bg-red-700 dark:text-red-100 dark:hover:bg-red-600 dark:focus:ring-red-600",
|
105
|
+
"bg-red-700 text-white hover:bg-red-800 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900"
|
106
|
+
)
|
107
|
+
when :success
|
108
|
+
table_variant_class(
|
109
|
+
"bg-green-100 text-green-700 hover:bg-green-200 focus:ring-green-300 dark:bg-green-700 dark:text-green-100 dark:hover:bg-green-600 dark:focus:ring-green-600",
|
110
|
+
"bg-green-700 text-white hover:bg-green-800 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800"
|
111
|
+
)
|
112
|
+
else
|
113
|
+
table_variant_class(
|
114
|
+
"bg-gray-100 text-gray-700 hover:bg-gray-200 focus:ring-gray-300 dark:bg-gray-700 dark:text-gray-100 dark:hover:bg-gray-600 dark:focus:ring-gray-600",
|
115
|
+
"border border-gray-200 bg-white text-gray-900 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-gray-100 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-700"
|
116
|
+
)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def table_variant_class(table_class, default_class)
|
121
|
+
(@variant == :table) ? table_class : default_class
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module UI
|
3
|
+
class Breadcrumbs < Plutonium::UI::Component::Base
|
4
|
+
include Phlex::Rails::Helpers::ActionName
|
5
|
+
include Phlex::Rails::Helpers::LinkTo
|
6
|
+
|
7
|
+
def view_template
|
8
|
+
nav(
|
9
|
+
class:
|
10
|
+
"flex py-3 text-gray-700 mb-2",
|
11
|
+
aria_label: "Breadcrumb"
|
12
|
+
) do
|
13
|
+
ol(
|
14
|
+
class:
|
15
|
+
"inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse"
|
16
|
+
) do
|
17
|
+
# Dashboard
|
18
|
+
li(class: "inline-flex items-center") do
|
19
|
+
a(
|
20
|
+
href: helpers.root_path,
|
21
|
+
class:
|
22
|
+
"inline-flex items-center text-sm font-medium text-gray-700 hover:text-primary-600 dark:text-gray-200 dark:hover:text-white"
|
23
|
+
) do
|
24
|
+
svg(
|
25
|
+
class: "w-3 h-3 me-2.5",
|
26
|
+
aria_hidden: "true",
|
27
|
+
xmlns: "http://www.w3.org/2000/svg",
|
28
|
+
fill: "currentColor",
|
29
|
+
viewbox: "0 0 20 20"
|
30
|
+
) do |s|
|
31
|
+
s.path(
|
32
|
+
d:
|
33
|
+
"m19.707 9.293-2-2-7-7a1 1 0 0 0-1.414 0l-7 7-2 2a1 1 0 0 0 1.414 1.414L2 10.414V18a2 2 0 0 0 2 2h3a1 1 0 0 0 1-1v-4a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v4a1 1 0 0 0 1 1h3a2 2 0 0 0 2-2v-7.586l.293.293a1 1 0 0 0 1.414-1.414Z"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
plain " Dashboard "
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Parent
|
41
|
+
if current_parent.present?
|
42
|
+
# Parent Resource
|
43
|
+
li(class: "flex items-center") do
|
44
|
+
svg(
|
45
|
+
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
46
|
+
aria_hidden: "true",
|
47
|
+
xmlns: "http://www.w3.org/2000/svg",
|
48
|
+
fill: "none",
|
49
|
+
viewbox: "0 0 6 10"
|
50
|
+
) do |s|
|
51
|
+
s.path(
|
52
|
+
stroke: "currentColor",
|
53
|
+
stroke_linecap: "round",
|
54
|
+
stroke_linejoin: "round",
|
55
|
+
stroke_width: "2",
|
56
|
+
d: "m1 9 4-4-4-4"
|
57
|
+
)
|
58
|
+
end
|
59
|
+
link_to resource_name_plural(current_parent.class),
|
60
|
+
resource_url_for(current_parent.class, parent: nil),
|
61
|
+
class:
|
62
|
+
"ms-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ms-2 dark:text-gray-200 dark:hover:text-white"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Parent Itself
|
66
|
+
li(class: "flex items-center") do
|
67
|
+
svg(
|
68
|
+
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
69
|
+
aria_hidden: "true",
|
70
|
+
xmlns: "http://www.w3.org/2000/svg",
|
71
|
+
fill: "none",
|
72
|
+
viewbox: "0 0 6 10"
|
73
|
+
) do |s|
|
74
|
+
s.path(
|
75
|
+
stroke: "currentColor",
|
76
|
+
stroke_linecap: "round",
|
77
|
+
stroke_linejoin: "round",
|
78
|
+
stroke_width: "2",
|
79
|
+
d: "m1 9 4-4-4-4"
|
80
|
+
)
|
81
|
+
end
|
82
|
+
link_to display_name_of(current_parent),
|
83
|
+
resource_url_for(current_parent, parent: nil),
|
84
|
+
class:
|
85
|
+
"ms-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ms-2 dark:text-gray-200 dark:hover:text-white"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Record
|
90
|
+
if resource_record.present?
|
91
|
+
# Record Resource
|
92
|
+
li(class: "flex items-center") do
|
93
|
+
svg(
|
94
|
+
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
95
|
+
aria_hidden: "true",
|
96
|
+
xmlns: "http://www.w3.org/2000/svg",
|
97
|
+
fill: "none",
|
98
|
+
viewbox: "0 0 6 10"
|
99
|
+
) do |s|
|
100
|
+
s.path(
|
101
|
+
stroke: "currentColor",
|
102
|
+
stroke_linecap: "round",
|
103
|
+
stroke_linejoin: "round",
|
104
|
+
stroke_width: "2",
|
105
|
+
d: "m1 9 4-4-4-4"
|
106
|
+
)
|
107
|
+
end
|
108
|
+
link_to resource_name_plural(resource_class),
|
109
|
+
resource_url_for(resource_class),
|
110
|
+
class:
|
111
|
+
"ms-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ms-2 dark:text-gray-200 dark:hover:text-white"
|
112
|
+
end
|
113
|
+
|
114
|
+
# Record Itself
|
115
|
+
if resource_record.persisted? && action_name != "show"
|
116
|
+
li(class: "flex items-center") do
|
117
|
+
svg(
|
118
|
+
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
119
|
+
aria_hidden: "true",
|
120
|
+
xmlns: "http://www.w3.org/2000/svg",
|
121
|
+
fill: "none",
|
122
|
+
viewbox: "0 0 6 10"
|
123
|
+
) do |s|
|
124
|
+
s.path(
|
125
|
+
stroke: "currentColor",
|
126
|
+
stroke_linecap: "round",
|
127
|
+
stroke_linejoin: "round",
|
128
|
+
stroke_width: "2",
|
129
|
+
d: "m1 9 4-4-4-4"
|
130
|
+
)
|
131
|
+
end
|
132
|
+
link_to display_name_of(resource_record),
|
133
|
+
resource_url_for(resource_record),
|
134
|
+
class:
|
135
|
+
"ms-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ms-2 dark:text-gray-200 dark:hover:text-white"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Trailing Caret
|
141
|
+
li(class: "flex items-center") do
|
142
|
+
svg(
|
143
|
+
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
144
|
+
aria_hidden: "true",
|
145
|
+
xmlns: "http://www.w3.org/2000/svg",
|
146
|
+
fill: "none",
|
147
|
+
viewbox: "0 0 6 10"
|
148
|
+
) do |s|
|
149
|
+
s.path(
|
150
|
+
stroke: "currentColor",
|
151
|
+
stroke_linecap: "round",
|
152
|
+
stroke_linejoin: "round",
|
153
|
+
stroke_width: "2",
|
154
|
+
d: "m1 9 4-4-4-4"
|
155
|
+
)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "phlex"
|
4
|
+
|
5
|
+
module Plutonium
|
6
|
+
module UI
|
7
|
+
module Component
|
8
|
+
class Base < (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)
|
9
|
+
include Plutonium::UI::Component::Behaviour
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Component
|
6
|
+
module Behaviour
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include Methods
|
9
|
+
include Kit
|
10
|
+
|
11
|
+
if Rails.env.development?
|
12
|
+
def around_template(&)
|
13
|
+
comment { "open:#{self.class.name}" }
|
14
|
+
super
|
15
|
+
comment { "close:#{self.class.name}" }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def phlexi_render(arg, &)
|
22
|
+
return unless arg
|
23
|
+
raise ArgumentError, "phlexi_render requires a default render block" unless block_given?
|
24
|
+
|
25
|
+
# Handle Phlex components or Rails Renderables
|
26
|
+
if arg.class < Phlex::SGML || arg.respond_to?(:render_in)
|
27
|
+
render arg
|
28
|
+
# Handle procs
|
29
|
+
elsif arg.respond_to?(:to_proc)
|
30
|
+
instance_exec(&arg)
|
31
|
+
else
|
32
|
+
yield
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "phlex"
|
4
|
+
|
5
|
+
module Plutonium
|
6
|
+
module UI
|
7
|
+
module Component
|
8
|
+
module Kit
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
def Breadcrumbs(...) = render Plutonium::UI::Breadcrumbs.new(...)
|
12
|
+
|
13
|
+
def DynaFrameContent(...) = render Plutonium::UI::DynaFrame::Content.new(...)
|
14
|
+
|
15
|
+
def PageHeader(...) = render Plutonium::UI::PageHeader.new(...)
|
16
|
+
|
17
|
+
def ActionButton(...) = render Plutonium::UI::ActionButton.new(...)
|
18
|
+
|
19
|
+
def EmptyCard(...) = render Plutonium::UI::EmptyCard.new(...)
|
20
|
+
|
21
|
+
def TableSearchBar(...) = render Plutonium::UI::Table::Components::SearchBar.new(...)
|
22
|
+
|
23
|
+
def TableScopesBar(...) = render Plutonium::UI::Table::Components::ScopesBar.new(...)
|
24
|
+
|
25
|
+
def TableInfo(...) = render Plutonium::UI::Table::Components::PagyInfo.new(...)
|
26
|
+
|
27
|
+
def TablePagination(...) = render Plutonium::UI::Table::Components::PagyPagination.new(...)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "phlex"
|
4
|
+
|
5
|
+
module Plutonium
|
6
|
+
module UI
|
7
|
+
module Component
|
8
|
+
module Methods
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def resource_class
|
14
|
+
helpers.controller.send(:resource_class)
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource_record
|
18
|
+
helpers.controller.send(:resource_record)
|
19
|
+
end
|
20
|
+
|
21
|
+
def current_parent
|
22
|
+
helpers.controller.send(:current_parent)
|
23
|
+
end
|
24
|
+
|
25
|
+
def params
|
26
|
+
helpers.controller.params
|
27
|
+
end
|
28
|
+
|
29
|
+
def request
|
30
|
+
helpers.controller.request
|
31
|
+
end
|
32
|
+
|
33
|
+
def pagy_instance
|
34
|
+
helpers.controller.instance_variable_get(:@pagy)
|
35
|
+
end
|
36
|
+
|
37
|
+
delegate \
|
38
|
+
:resource_name,
|
39
|
+
:resource_name_plural,
|
40
|
+
:display_name_of,
|
41
|
+
:resource_url_for,
|
42
|
+
:current_definition,
|
43
|
+
:current_query_object,
|
44
|
+
:resource_query_params,
|
45
|
+
:current_policy,
|
46
|
+
:current_turbo_frame,
|
47
|
+
:policy_for,
|
48
|
+
:allowed_to?,
|
49
|
+
:registered_resources,
|
50
|
+
to: :helpers
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Display
|
6
|
+
class Base < Phlexi::Display::Base
|
7
|
+
include Plutonium::UI::Component::Behaviour
|
8
|
+
|
9
|
+
class Builder < Builder
|
10
|
+
def association_tag(**, &)
|
11
|
+
create_component(Plutonium::UI::Display::Component::Association, :association, **, &)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def fields_wrapper(&)
|
18
|
+
div(class: themed(:fields_wrapper)) {
|
19
|
+
yield
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Display
|
6
|
+
module Component
|
7
|
+
class Association < Phlexi::Display::Components::Association
|
8
|
+
include Plutonium::UI::Component::Methods
|
9
|
+
|
10
|
+
def render_value(value)
|
11
|
+
p(**attributes) {
|
12
|
+
if registered_resources.include?(value.class)
|
13
|
+
href = resource_url_for(value, parent: (field.association_reflection.macro == :has_many) ? field.object : nil)
|
14
|
+
a(class: themed(:link), href:) {
|
15
|
+
display_name_of value
|
16
|
+
}
|
17
|
+
else
|
18
|
+
display_name_of value
|
19
|
+
end
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Display
|
6
|
+
class Resource < Base
|
7
|
+
attr_reader :resource_fields, :resource_associations, :resource_definition
|
8
|
+
|
9
|
+
def initialize(*, resource_fields:, resource_associations:, resource_definition:, **, &)
|
10
|
+
super(*, **, &)
|
11
|
+
@resource_fields = resource_fields
|
12
|
+
@resource_associations = resource_associations
|
13
|
+
@resource_definition = resource_definition
|
14
|
+
end
|
15
|
+
|
16
|
+
def display_template
|
17
|
+
render_fields
|
18
|
+
render_associations if present_associations?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def render_fields
|
24
|
+
fields_wrapper {
|
25
|
+
resource_fields.each { |name|
|
26
|
+
render_resource_field name
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def render_associations
|
32
|
+
nil
|
33
|
+
# TODO
|
34
|
+
# resource_associations.each do |name, renderer|
|
35
|
+
# # <%= render renderer.with(record: details.record) %>
|
36
|
+
# end
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_resource_field(name)
|
40
|
+
# display :name, as: :string
|
41
|
+
# display :description, class: "col-span-full"
|
42
|
+
# display :age, field: {class: "max-h-fit"}
|
43
|
+
# display :dob do |f|
|
44
|
+
# f.date_tag
|
45
|
+
# end
|
46
|
+
|
47
|
+
when_permitted(name) do
|
48
|
+
display_definition = resource_definition.defined_displays[name] || {}
|
49
|
+
display_options = display_definition[:options] || {}
|
50
|
+
display_field_as = display_options.delete(:as)
|
51
|
+
|
52
|
+
display_field_options = display_options.delete(:field) || {}
|
53
|
+
display_block = display_definition[:block] || ->(f) {
|
54
|
+
display_field_as ||= f.inferred_field_component
|
55
|
+
f.send(:"#{display_field_as}_tag", **display_field_options)
|
56
|
+
}
|
57
|
+
|
58
|
+
field_options = resource_definition.defined_fields[name] ? resource_definition.defined_fields[name][:options] : {}
|
59
|
+
render field(name, **field_options).wrapped(**display_options) do |f|
|
60
|
+
render display_block.call(f)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def when_permitted(name, &)
|
66
|
+
return unless @resource_fields.include? name
|
67
|
+
|
68
|
+
yield
|
69
|
+
end
|
70
|
+
|
71
|
+
def present_associations?
|
72
|
+
current_parent.nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Display
|
6
|
+
class Theme < Phlexi::Display::Theme
|
7
|
+
def self.theme
|
8
|
+
super.merge({
|
9
|
+
base: "relative bg-white dark:bg-gray-800 shadow-md sm:rounded-lg my-3",
|
10
|
+
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",
|
11
|
+
label: "text-base font-bold text-gray-500 dark:text-gray-400 mb-1",
|
12
|
+
description: "text-sm text-gray-400 dark:text-gray-500",
|
13
|
+
placeholder: "text-md text-gray-500 dark:text-gray-300 mb-1 italic",
|
14
|
+
string: "max-h-[300px] overflow-y-auto text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
15
|
+
text: "max-h-[300px] overflow-y-auto text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
16
|
+
link: "text-primary-600 dark:text-primary-500 whitespace-pre-line",
|
17
|
+
color: "flex items-center text-md text-gray-900 dark:text-white mb-1 whitespace-pre-line",
|
18
|
+
color_indicator: "w-10 h-10 rounded-full mr-2", # max-h-fit
|
19
|
+
email: "flex items-center text-md text-primary-600 dark:text-primary-500 mb-1 whitespace-pre-line",
|
20
|
+
json: "max-h-[300px] overflow-y-auto text-sm text-gray-900 dark:text-white mb-1 whitespace-pre font-mono shadow-inner p-4",
|
21
|
+
prefixed_icon: "w-8 h-8 mr-2"
|
22
|
+
})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module UI
|
3
|
+
module DynaFrame
|
4
|
+
class Content < Plutonium::UI::Component::Base
|
5
|
+
include Phlex::Rails::Helpers::TurboFrameTag
|
6
|
+
|
7
|
+
def view_template
|
8
|
+
if current_turbo_frame.present?
|
9
|
+
render turbo_frame_tag(current_turbo_frame) {
|
10
|
+
render "flash"
|
11
|
+
yield
|
12
|
+
}
|
13
|
+
else
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module UI
|
3
|
+
class EmptyCard < Plutonium::UI::Component::Base
|
4
|
+
attr_accessor :message
|
5
|
+
|
6
|
+
def initialize(message)
|
7
|
+
@message = message
|
8
|
+
end
|
9
|
+
|
10
|
+
def view_template
|
11
|
+
div(class: "relative bg-white dark:bg-gray-800 shadow-md") do
|
12
|
+
div(class: "p-6 flex items-center flex-col gap-2") do
|
13
|
+
p(class: "text-gray-500 sm:text-lg dark:text-gray-200 text-center") { message }
|
14
|
+
yield if block_given?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module UI
|
5
|
+
module Form
|
6
|
+
class Base < Phlexi::Form::Base
|
7
|
+
include Plutonium::UI::Component::Behaviour
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def render_actions
|
12
|
+
actions_wrapper {
|
13
|
+
render submit_button
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def fields_wrapper(&)
|
18
|
+
div(class: themed(:fields_wrapper, nil)) {
|
19
|
+
yield
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def actions_wrapper(&)
|
24
|
+
div(class: themed(:actions_wrapper, nil)) {
|
25
|
+
yield
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def form_action
|
30
|
+
return @form_action unless object.present? && @form_action != false && helpers.present?
|
31
|
+
|
32
|
+
@form_action ||= url_for(object, action: object.new_record? ? :create : :update)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|