plutonium 0.14.1 → 0.15.0.pre.rc2
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/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 +1 -8
- data/lib/generators/pu/eject/shell/shell_generator.rb +2 -2
- data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +1 -1
- 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 +0 -8
- data/lib/plutonium/core/actions/collection.rb +1 -1
- data/lib/plutonium/core/associations/renderers/factory.rb +3 -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/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/{config → lib}/overlayed_hash.rb +1 -1
- 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 +33 -1
- data/lib/plutonium/reloader.rb +5 -5
- 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 +14 -1
- data/package-lock.json +19 -22
- data/package.json +4 -4
- data/src/css/plutonium.css +15 -0
- data/tailwind.options.js +11 -3
- metadata +218 -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/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
@@ -1,5 +1,5 @@
|
|
1
1
|
module Plutonium
|
2
|
-
module
|
2
|
+
module Resource
|
3
3
|
module Controllers
|
4
4
|
module CrudActions
|
5
5
|
extend ActiveSupport::Concern
|
@@ -10,44 +10,40 @@ module Plutonium
|
|
10
10
|
|
11
11
|
# GET /resources(.{format})
|
12
12
|
def index
|
13
|
-
|
13
|
+
authorize_current! resource_class
|
14
14
|
set_page_title resource_class.model_name.human.pluralize.titleize
|
15
15
|
|
16
16
|
@search_object = current_query_object
|
17
|
-
base_query =
|
17
|
+
base_query = current_authorized_scope
|
18
18
|
base_query = @search_object.apply(base_query)
|
19
|
-
base_query = base_query.public_send(params[:scope].to_sym) if params[:scope].present?
|
19
|
+
# base_query = base_query.public_send(params[:scope].to_sym) if params[:scope].present?
|
20
20
|
@pagy, @resource_records = pagy base_query
|
21
|
-
@collection = build_collection
|
22
21
|
|
23
22
|
render :index
|
24
23
|
end
|
25
24
|
|
26
25
|
# GET /resources/1(.{format})
|
27
26
|
def show
|
28
|
-
|
27
|
+
authorize_current! resource_record
|
29
28
|
set_page_title resource_record.to_label.titleize
|
30
29
|
|
31
|
-
@detail = build_detail
|
32
|
-
|
33
30
|
render :show
|
34
31
|
end
|
35
32
|
|
36
33
|
# GET /resources/new
|
37
34
|
def new
|
38
|
-
|
35
|
+
authorize_current! resource_class
|
39
36
|
set_page_title "Create #{resource_class.model_name.human.titleize}"
|
40
37
|
|
41
38
|
@resource_record = resource_class.new
|
42
39
|
maybe_apply_submitted_resource_params!
|
43
|
-
@form = build_form
|
44
40
|
|
45
41
|
render :new
|
46
42
|
end
|
47
43
|
|
48
44
|
# POST /resources(.{format})
|
49
45
|
def create
|
50
|
-
|
46
|
+
authorize_current! resource_class
|
51
47
|
set_page_title "Create #{resource_class.model_name.human.titleize}"
|
52
48
|
|
53
49
|
@resource_record = resource_class.new resource_params
|
@@ -61,7 +57,6 @@ module Plutonium
|
|
61
57
|
format.any { render :show, status: :created, location: redirect_url_after_submit }
|
62
58
|
else
|
63
59
|
format.html do
|
64
|
-
@form = build_form
|
65
60
|
render :new, status: :unprocessable_entity
|
66
61
|
end
|
67
62
|
format.any do
|
@@ -74,18 +69,17 @@ module Plutonium
|
|
74
69
|
|
75
70
|
# GET /resources/1/edit
|
76
71
|
def edit
|
77
|
-
|
72
|
+
authorize_current! resource_record
|
78
73
|
set_page_title "Update #{resource_record.to_label.titleize}"
|
79
74
|
|
80
75
|
maybe_apply_submitted_resource_params!
|
81
|
-
@form = build_form
|
82
76
|
|
83
77
|
render :edit
|
84
78
|
end
|
85
79
|
|
86
80
|
# PATCH/PUT /resources/1(.{format})
|
87
81
|
def update
|
88
|
-
|
82
|
+
authorize_current! resource_record
|
89
83
|
set_page_title "Update #{resource_record.to_label.titleize}"
|
90
84
|
|
91
85
|
respond_to do |format|
|
@@ -97,7 +91,6 @@ module Plutonium
|
|
97
91
|
format.any { render :show, status: :ok, location: redirect_url_after_submit }
|
98
92
|
else
|
99
93
|
format.html do
|
100
|
-
@form = build_form
|
101
94
|
render :edit, status: :unprocessable_entity
|
102
95
|
end
|
103
96
|
format.any do
|
@@ -110,13 +103,13 @@ module Plutonium
|
|
110
103
|
|
111
104
|
# DELETE /resources/1(.{format})
|
112
105
|
def destroy
|
113
|
-
|
106
|
+
authorize_current! resource_record
|
114
107
|
|
115
108
|
respond_to do |format|
|
116
109
|
resource_record.destroy
|
117
110
|
|
118
111
|
format.html do
|
119
|
-
redirect_to
|
112
|
+
redirect_to redirect_url_after_destroy,
|
120
113
|
notice: "#{resource_class.model_name.human} was successfully deleted."
|
121
114
|
end
|
122
115
|
format.json { head :no_content }
|
@@ -143,13 +136,13 @@ module Plutonium
|
|
143
136
|
|
144
137
|
url = case preferred_action_after_submit
|
145
138
|
when "show"
|
146
|
-
resource_url_for(resource_record) if current_policy.show?
|
139
|
+
resource_url_for(resource_record) if current_policy.allowed_to? :show?
|
147
140
|
when "edit"
|
148
|
-
resource_url_for(resource_record, action: :edit) if current_policy.edit?
|
141
|
+
resource_url_for(resource_record, action: :edit) if current_policy.allowed_to? :edit?
|
149
142
|
when "new"
|
150
|
-
resource_url_for(resource_class, action: :new) if current_policy.new?
|
143
|
+
resource_url_for(resource_class, action: :new) if current_policy.allowed_to? :new?
|
151
144
|
when "index"
|
152
|
-
resource_url_for(resource_class) if current_policy.index?
|
145
|
+
resource_url_for(resource_class) if current_policy.allowed_to? :index?
|
153
146
|
else
|
154
147
|
# ensure we have a valid value
|
155
148
|
session[:action_after_submit_preference] = "show"
|
@@ -157,6 +150,14 @@ module Plutonium
|
|
157
150
|
url || resource_url_for(resource_record)
|
158
151
|
end
|
159
152
|
|
153
|
+
def redirect_url_after_destroy
|
154
|
+
if (return_to = url_from(params[:return_to]))
|
155
|
+
return return_to
|
156
|
+
end
|
157
|
+
|
158
|
+
resource_url_for(resource_class)
|
159
|
+
end
|
160
|
+
|
160
161
|
def preferred_action_after_submit
|
161
162
|
@preferred_action_after_submit = begin
|
162
163
|
if %w[new edit show index].include? params[:commit]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
using Plutonium::Refinements::ParameterRefinements
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module Resource
|
5
|
+
module Controllers
|
6
|
+
module Defineable
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
helper_method :current_definition, :resource_definition
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def resource_definition(resource_class)
|
16
|
+
definition_class = "#{resource_class}Definition".constantize
|
17
|
+
definition_class.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def current_definition
|
21
|
+
@current_definition ||= resource_definition resource_class
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Plutonium
|
2
|
-
module
|
2
|
+
module Resource
|
3
3
|
module Controllers
|
4
4
|
module InteractiveActions
|
5
5
|
extend ActiveSupport::Concern
|
@@ -7,17 +7,17 @@ module Plutonium
|
|
7
7
|
included do
|
8
8
|
helper_method :current_interactive_action
|
9
9
|
|
10
|
-
before_action :validate_interactive_resource_action
|
10
|
+
before_action :validate_interactive_resource_action!, only: %i[
|
11
11
|
begin_interactive_resource_record_action commit_interactive_resource_record_action
|
12
12
|
begin_interactive_resource_collection_action commit_interactive_resource_collection_action
|
13
13
|
begin_interactive_resource_recordless_action commit_interactive_resource_recordless_action
|
14
14
|
]
|
15
15
|
|
16
|
-
before_action :authorize_interactive_resource_record_action
|
16
|
+
before_action :authorize_interactive_resource_record_action!, only: %i[
|
17
17
|
begin_interactive_resource_record_action commit_interactive_resource_record_action
|
18
18
|
]
|
19
19
|
|
20
|
-
before_action :authorize_interactive_resource_action
|
20
|
+
before_action :authorize_interactive_resource_action!, only: %i[
|
21
21
|
begin_interactive_resource_collection_action commit_interactive_resource_collection_action
|
22
22
|
begin_interactive_resource_recordless_action commit_interactive_resource_recordless_action
|
23
23
|
]
|
@@ -123,7 +123,7 @@ module Plutonium
|
|
123
123
|
|
124
124
|
# GET /resources/actions/:interactive_action
|
125
125
|
def begin_interactive_resource_recordless_action
|
126
|
-
skip_policy_scope
|
126
|
+
# skip_policy_scope
|
127
127
|
|
128
128
|
@interaction = current_interactive_action.interaction.new interaction_params
|
129
129
|
|
@@ -136,7 +136,7 @@ module Plutonium
|
|
136
136
|
|
137
137
|
# POST /resources/actions/:interactive_action
|
138
138
|
def commit_interactive_resource_recordless_action
|
139
|
-
skip_policy_scope
|
139
|
+
# skip_policy_scope
|
140
140
|
|
141
141
|
respond_to do |format|
|
142
142
|
inputs = interaction_params
|
@@ -182,25 +182,25 @@ module Plutonium
|
|
182
182
|
@interactive_resource_actions ||= current_presenter.actions.except :new, :show, :edit, :destroy
|
183
183
|
end
|
184
184
|
|
185
|
-
def validate_interactive_resource_action
|
185
|
+
def validate_interactive_resource_action!
|
186
186
|
interactive_resource_action = params[:interactive_action]&.to_sym
|
187
187
|
unless interactive_resource_actions.key?(interactive_resource_action)
|
188
188
|
raise ::AbstractController::ActionNotFound, "Unknown action '#{interactive_resource_action}'"
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
def authorize_interactive_resource_record_action
|
192
|
+
def authorize_interactive_resource_record_action!
|
193
193
|
interactive_resource_action = params[:interactive_action]&.to_sym
|
194
|
-
|
194
|
+
authorize_current! resource_record, to: :"#{interactive_resource_action}?"
|
195
195
|
end
|
196
196
|
|
197
|
-
def authorize_interactive_resource_action
|
197
|
+
def authorize_interactive_resource_action!
|
198
198
|
interactive_resource_action = params[:interactive_action]&.to_sym
|
199
|
-
|
199
|
+
authorize_current! resource_class, to: :"#{interactive_resource_action}?"
|
200
200
|
end
|
201
201
|
|
202
202
|
def interactive_resource_collection
|
203
|
-
@interactive_resource_collection ||=
|
203
|
+
@interactive_resource_collection ||= current_authorized_scope.from_path_param(params.require(:ids))
|
204
204
|
end
|
205
205
|
|
206
206
|
def interaction_params
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Plutonium
|
2
|
+
module Resource
|
3
|
+
module Controllers
|
4
|
+
module Presentable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
helper_method :presentable_attributes, :present_associations?
|
9
|
+
helper_method :build_form, :build_detail, :build_collection
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def presentable_attributes
|
15
|
+
@presentable_attributes ||= begin
|
16
|
+
presentable_attributes = permitted_attributes
|
17
|
+
presentable_attributes -= [scoped_entity_param_key, :"#{scoped_entity_param_key}_id"] if scoped_to_entity?
|
18
|
+
presentable_attributes -= [parent_input_param, :"#{parent_input_param}_id"] if current_parent.present?
|
19
|
+
presentable_attributes
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_collection
|
24
|
+
current_definition.collection_class.new(@resource_records, resource_fields: presentable_attributes, resource_definition: current_definition)
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_detail
|
28
|
+
current_definition.detail_class.new(resource_record, resource_fields: presentable_attributes, resource_associations: permitted_associations, resource_definition: current_definition)
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_form(record = resource_record)
|
32
|
+
current_definition.form_class.new(record, resource_fields: presentable_attributes, resource_definition: current_definition)
|
33
|
+
end
|
34
|
+
|
35
|
+
def present_associations?
|
36
|
+
current_parent.nil?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
using Plutonium::Refinements::ParameterRefinements
|
2
|
+
|
3
|
+
module Plutonium
|
4
|
+
module Resource
|
5
|
+
module Controllers
|
6
|
+
module Queryable
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
helper_method :resource_query_params, :current_query_object
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource_query_object(resource_class, params)
|
14
|
+
query_object_class = "#{resource_class}QueryObject".constantize
|
15
|
+
query_object_class.new resource_context, params
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_query_object
|
19
|
+
@current_query_object ||= Plutonium::Resource::QueryObject.new(resource_context, resource_query_params) do |query_object|
|
20
|
+
if current_definition.search_definition
|
21
|
+
query_object.define_search proc { |scope, search:|
|
22
|
+
current_definition.search_definition.call(scope, search)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
current_definition.defined_scopes.each do |key, value|
|
27
|
+
query_object.define_scope key, value[:block]
|
28
|
+
end
|
29
|
+
|
30
|
+
current_definition.defined_sorts.each do |key, value|
|
31
|
+
query_object.define_sorter key, value[:block]
|
32
|
+
end
|
33
|
+
|
34
|
+
query_object
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def resource_query_params
|
39
|
+
(params[:q]&.nilify&.to_unsafe_h || {}).with_indifferent_access
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,13 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Plutonium
|
2
4
|
module Resource
|
3
5
|
# Policy class to define permissions and attributes for a resource.
|
4
6
|
# This class provides methods to check permissions for various actions
|
5
7
|
# and to retrieve permitted attributes for these actions.
|
6
|
-
class Policy
|
7
|
-
|
8
|
+
class Policy < ActionPolicy::Base
|
9
|
+
authorize :user, allow_nil: false
|
10
|
+
authorize :scope, allow_nil: true
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
relation_scope do |relation|
|
13
|
+
if scope.present?
|
14
|
+
relation = relation.associated_with(scope)
|
15
|
+
end
|
16
|
+
relation
|
11
17
|
end
|
12
18
|
|
13
19
|
# Sends a method and raises an error if the method is not implemented.
|
@@ -95,7 +101,7 @@ module Plutonium
|
|
95
101
|
# @return [Array<Symbol>] The permitted attributes.
|
96
102
|
def permitted_attributes_for_create
|
97
103
|
autodetect_permitted_fields(:permitted_attributes_for_create) - [
|
98
|
-
|
104
|
+
resource_class.primary_key.to_sym, # primary_key
|
99
105
|
:created_at, :updated_at # timestamps
|
100
106
|
]
|
101
107
|
end
|
@@ -153,13 +159,17 @@ module Plutonium
|
|
153
159
|
|
154
160
|
private
|
155
161
|
|
162
|
+
def resource_class
|
163
|
+
record.instance_of?(Class) ? record : record.class
|
164
|
+
end
|
165
|
+
|
156
166
|
# Autodetects the permitted fields for a given method.
|
157
167
|
#
|
158
168
|
# @param method_name [Symbol] The name of the method.
|
159
169
|
# @return [Array<Symbol>] The auto-detected permitted fields.
|
160
170
|
def autodetect_permitted_fields(method_name)
|
161
171
|
warn_about_autodetect_usage(method_name)
|
162
|
-
|
172
|
+
resource_class.resource_field_names
|
163
173
|
end
|
164
174
|
|
165
175
|
# Warns about the usage of auto-detection of fields.
|
@@ -171,16 +181,18 @@ module Plutonium
|
|
171
181
|
raise "Resource field auto-detection: #{self.class}##{method} outside development"
|
172
182
|
end
|
173
183
|
|
174
|
-
Plutonium.logger.warn
|
175
|
-
|
184
|
+
Plutonium.logger.warn {
|
185
|
+
%(
|
186
|
+
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
176
187
|
|
177
|
-
|
188
|
+
Resource field auto-detection: #{self.class}##{method}
|
178
189
|
|
179
|
-
|
180
|
-
|
190
|
+
Auto-detected resource fields result in security holes and will fail outside of development.
|
191
|
+
Override #{resource_class}Policy or #{self.class} with your own ##{method} method.
|
181
192
|
|
182
|
-
|
183
|
-
|
193
|
+
🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
|
194
|
+
)
|
195
|
+
}
|
184
196
|
end
|
185
197
|
end
|
186
198
|
end
|
@@ -102,7 +102,7 @@ module Plutonium
|
|
102
102
|
#
|
103
103
|
# @param context [Object] The context in which the query object is used.
|
104
104
|
# @param params [Hash] The parameters for initialization.
|
105
|
-
def initialize(context, params)
|
105
|
+
def initialize(context, params, &)
|
106
106
|
@context = context
|
107
107
|
|
108
108
|
define_standard_queries
|
@@ -110,10 +110,54 @@ module Plutonium
|
|
110
110
|
define_filters
|
111
111
|
define_sorters
|
112
112
|
|
113
|
+
yield self if block_given?
|
114
|
+
|
113
115
|
extract_filter_params(params)
|
114
116
|
extract_sort_params(params)
|
115
117
|
end
|
116
118
|
|
119
|
+
# Defines a filter with the given name and body.
|
120
|
+
#
|
121
|
+
# @param name [Symbol] The name of the filter.
|
122
|
+
# @param body [Proc, nil] The body of the filter.
|
123
|
+
def define_filter(name, body = nil, &)
|
124
|
+
body ||= name
|
125
|
+
filter_definitions[name] = build_query(body, &)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Defines a scope with the given name and body.
|
129
|
+
#
|
130
|
+
# @param name [Symbol] The name of the scope.
|
131
|
+
# @param body [Proc, nil] The body of the scope.
|
132
|
+
def define_scope(name, body = nil)
|
133
|
+
body ||= name
|
134
|
+
scope_definitions[name] = build_query(body)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Defines a sort with the given name and body.
|
138
|
+
#
|
139
|
+
# @param name [Symbol] The name of the sort.
|
140
|
+
# @param body [Proc, nil] The body of the sort.
|
141
|
+
def define_sorter(name, body = nil)
|
142
|
+
if body.nil?
|
143
|
+
sort_field = determine_sort_field(name)
|
144
|
+
body = ->(scope, direction:) { scope.order(sort_field => direction) }
|
145
|
+
end
|
146
|
+
|
147
|
+
sort_definitions[name] = build_query(body) do |query|
|
148
|
+
query.define_field_input :direction
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Defines a search filter with the given body.
|
153
|
+
#
|
154
|
+
# @param body [Proc, Symbol] The body of the search filter.
|
155
|
+
def define_search(body)
|
156
|
+
@search_filter = build_query(body) do |query|
|
157
|
+
query.define_field_input :search
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
117
161
|
# Builds a URL with the given options for search and sorting.
|
118
162
|
#
|
119
163
|
# @param options [Hash] The options for building the URL.
|
@@ -186,48 +230,6 @@ module Plutonium
|
|
186
230
|
define_search(:search) if resource_class.respond_to?(:search)
|
187
231
|
end
|
188
232
|
|
189
|
-
# Defines a filter with the given name and body.
|
190
|
-
#
|
191
|
-
# @param name [Symbol] The name of the filter.
|
192
|
-
# @param body [Proc, nil] The body of the filter.
|
193
|
-
def define_filter(name, body = nil, &)
|
194
|
-
body ||= name
|
195
|
-
filter_definitions[name] = build_query(body, &)
|
196
|
-
end
|
197
|
-
|
198
|
-
# Defines a scope with the given name and body.
|
199
|
-
#
|
200
|
-
# @param name [Symbol] The name of the scope.
|
201
|
-
# @param body [Proc, nil] The body of the scope.
|
202
|
-
def define_scope(name, body = nil)
|
203
|
-
body ||= name
|
204
|
-
scope_definitions[name] = build_query(body)
|
205
|
-
end
|
206
|
-
|
207
|
-
# Defines a sort with the given name and body.
|
208
|
-
#
|
209
|
-
# @param name [Symbol] The name of the sort.
|
210
|
-
# @param body [Proc, nil] The body of the sort.
|
211
|
-
def define_sorter(name, body = nil)
|
212
|
-
if body.nil?
|
213
|
-
sort_field = determine_sort_field(name)
|
214
|
-
body = ->(scope, direction:) { scope.order(sort_field => direction) }
|
215
|
-
end
|
216
|
-
|
217
|
-
sort_definitions[name] = build_query(body) do |query|
|
218
|
-
query.define_field_input :direction
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# Defines a search filter with the given body.
|
223
|
-
#
|
224
|
-
# @param body [Proc, Symbol] The body of the search filter.
|
225
|
-
def define_search(body)
|
226
|
-
@search_filter = build_query(body) do |query|
|
227
|
-
query.define_field_input :search
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
233
|
# Extracts filter parameters from the given params.
|
232
234
|
#
|
233
235
|
# @param params [Hash] The parameters to extract.
|
@@ -308,14 +310,11 @@ module Plutonium
|
|
308
310
|
query_params[:sort_fields] << sort.to_s unless query_params[:sort_fields].include?(sort.to_s)
|
309
311
|
|
310
312
|
sort_direction = selected_sort_directions[sort]
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
query_params[:sort_fields].delete_if { |e| e == sort.to_s }
|
317
|
-
query_params[:sort_directions].delete(sort)
|
318
|
-
end
|
313
|
+
query_params[:sort_directions][sort] = (sort_direction == "ASC") ? "DESC" : "ASC"
|
314
|
+
# else
|
315
|
+
# query_params[:sort_fields].delete_if { |e| e == sort.to_s }
|
316
|
+
# query_params[:sort_directions].delete(sort)
|
317
|
+
# end
|
319
318
|
end
|
320
319
|
end
|
321
320
|
|