plutonium 0.10.3 → 0.11.1
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/Rakefile +1 -2
- data/app/assets/application.js.bk +31419 -0
- data/app/assets/plutonium-original.png +0 -0
- data/app/assets/plutonium-white.png +0 -0
- data/app/assets/plutonium.css +1 -0
- data/app/assets/plutonium.ico +0 -0
- data/app/assets/plutonium.js +12416 -0
- data/app/assets/plutonium.js.map +7 -0
- data/app/assets/plutonium.min.js +39 -0
- data/app/assets/plutonium.min.js.map +7 -0
- data/app/assets/plutonium.png +0 -0
- data/app/views/application/_flash_alerts.html.erb +2 -2
- data/app/views/application/_resource_header.html.erb +261 -697
- data/app/views/application/_resource_sidebar.html.erb +14 -12
- data/app/views/components/action_button/action_button_component.rb +3 -3
- data/app/views/components/attributes.rb +184 -0
- data/app/views/components/base.rb +19 -40
- data/app/views/components/block/block_component.html.erb +1 -1
- data/app/views/components/block/block_component.rb +11 -7
- data/app/views/components/breadcrumbs/breadcrumbs_component.rb +3 -3
- data/app/views/components/button/button_component.html.erb +2 -2
- data/app/views/components/button/button_component.rb +10 -5
- data/app/views/components/dyna_frame_content/dyna_frame_content_component.html.erb +1 -0
- data/app/views/components/dyna_frame_content/dyna_frame_content_component.rb +3 -3
- data/app/views/components/dyna_frame_host/dyna_frame_host_component.html.erb +1 -2
- data/app/views/components/dyna_frame_host/dyna_frame_host_component.rb +12 -5
- data/app/views/components/empty_card/empty_card_component.rb +3 -3
- data/app/views/components/form/form_builder.rb +1 -1
- data/app/views/components/form/form_component.rb +3 -3
- data/app/views/components/has_many_panel/has_many_panel_component.html.erb +25 -0
- data/app/views/components/has_many_panel/has_many_panel_component.rb +16 -0
- data/app/views/components/header/header_component.rb +3 -3
- data/app/views/components/interactive_action_form/interactive_action_form_component.rb +3 -3
- data/app/views/components/nav_grid_menu/nav_grid_menu_component.html.erb +24 -0
- data/app/views/components/nav_grid_menu/nav_grid_menu_component.rb +23 -0
- data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.html.erb +4 -0
- data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.rb +20 -0
- data/app/views/components/nav_user/nav_user_component.html.erb +50 -0
- data/app/views/components/nav_user/nav_user_component.rb +32 -0
- data/app/views/components/nav_user_link/nav_user_link_component.html.erb +7 -0
- data/app/views/components/nav_user_link/nav_user_link_component.rb +23 -0
- data/app/views/components/nav_user_section/nav_user_section_component.html.erb +7 -0
- data/app/views/components/nav_user_section/nav_user_section_component.rb +18 -0
- data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.html.erb +1 -3
- data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.rb +11 -5
- data/app/views/components/pagination/pagination_component.html.erb +1 -1
- data/app/views/components/pagination/pagination_component.rb +10 -7
- data/app/views/components/panel/panel_component.html.erb +13 -6
- data/app/views/components/panel/panel_component.rb +11 -5
- data/app/views/components/resource_header/resource_header_component.html.erb +83 -0
- data/app/views/components/resource_header/resource_header_component.rb +30 -0
- data/app/views/components/resource_layout/resource_layout_component.html.erb +49 -0
- data/app/views/components/resource_layout/resource_layout_component.rb +41 -0
- data/app/views/components/sidebar/sidebar_component.html.erb +3 -33
- data/app/views/components/sidebar/sidebar_component.rb +3 -3
- data/app/views/components/sidebar_menu/sidebar_menu_component.html.erb +4 -2
- data/app/views/components/sidebar_menu/sidebar_menu_component.rb +10 -6
- data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.html.erb +63 -71
- data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.rb +27 -8
- data/app/views/components/skeleton/table/table_component.html.erb +1 -1
- data/app/views/components/skeleton/table/table_component.rb +3 -3
- data/app/views/components/table/table_component.html.erb +40 -89
- data/app/views/components/table/table_component.rb +124 -28
- data/app/views/components/table_search_input/table_search_input_component.html.erb +1 -1
- data/app/views/components/table_search_input/table_search_input_component.rb +11 -6
- data/app/views/components/table_toolbar/table_toolbar_component.html.erb +1 -1
- data/app/views/components/table_toolbar/table_toolbar_component.rb +11 -3
- data/app/views/components/toolbar/toolbar_component.html.erb +2 -2
- data/app/views/components/toolbar/toolbar_component.rb +16 -8
- data/app/views/layouts/resource.html.erb +12 -45
- data/app/views/layouts/rodauth.html.erb +20 -36
- data/app/views/resource/_interactive_resource_action_form.html.erb +1 -1
- data/app/views/resource/_resource_details.html.erb +8 -5
- data/app/views/resource/_resource_table.html.erb +70 -1
- data/app/views/resource/interactive_resource_collection_action.html.erb +1 -0
- data/app/views/resource/interactive_resource_record_action.html.erb +1 -0
- data/app/views/resource/interactive_resource_recordless_action.html.erb +1 -0
- data/app/views/resource/new.html.erb +1 -0
- data/config/initializers/simple_form.rb +22 -2
- data/esbuild.config.js +35 -31
- data/lib/generators/pu/core/assets/assets_generator.rb +44 -0
- data/lib/generators/pu/core/assets/templates/tailwind.config.js +18 -0
- data/lib/generators/pu/core/install/install_generator.rb +4 -1
- data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +6 -0
- data/lib/generators/pu/gen/component/component_generator.rb +13 -10
- data/lib/generators/pu/gen/component/templates/component.html.erb.tt +1 -1
- data/lib/generators/pu/gen/component/templates/component.rb.tt +10 -4
- data/lib/generators/pu/pkg/app/app_generator.rb +4 -4
- data/lib/generators/pu/pkg/app/templates/app/controllers/concerns/controller.rb.tt +28 -0
- data/lib/generators/pu/pkg/app/templates/app/controllers/controller.rb.tt +5 -0
- data/lib/generators/pu/pkg/app/templates/app/controllers/dashboard_controller.rb.tt +1 -1
- data/lib/generators/pu/res/conn/conn_generator.rb +4 -4
- data/lib/generators/pu/res/conn/templates/app/controllers/resource_controller.rb.tt +1 -1
- data/lib/generators/pu/res/model/model_generator.rb +3 -3
- data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -0
- data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +0 -5
- data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +0 -2
- data/lib/plutonium/config.rb +2 -14
- data/lib/plutonium/core/associations/renderers/basic_renderer.rb +28 -0
- data/lib/plutonium/core/associations/renderers/factory.rb +36 -0
- data/lib/plutonium/core/associations/renderers/has_many_renderer.rb +16 -0
- data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +31 -0
- data/lib/plutonium/core/controllers/authorizable.rb +13 -17
- data/lib/plutonium/core/controllers/base.rb +3 -7
- data/lib/plutonium/core/controllers/presentable.rb +6 -1
- data/lib/plutonium/core/definers/association_renderer_definer.rb +33 -0
- data/lib/plutonium/core/fields/inputs/checkbox_input.rb +13 -0
- data/lib/plutonium/core/fields/inputs/factory.rb +1 -0
- data/lib/plutonium/core/fields/inputs/polymorphic_belongs_to_association_input.rb +1 -1
- data/lib/plutonium/core/ui/detail.rb +1 -0
- data/lib/plutonium/helpers/application_helper.rb +8 -9
- data/lib/plutonium/helpers/assets_helper.rb +41 -0
- data/lib/plutonium/helpers/display_helper.rb +13 -0
- data/lib/plutonium/helpers/form_helper.rb +1 -1
- data/lib/plutonium/helpers.rb +1 -0
- data/lib/plutonium/icons.rb +12 -5
- data/lib/plutonium/pkg/app.rb +10 -0
- data/lib/plutonium/pundit/context.rb +18 -0
- data/lib/plutonium/pundit/policy_finder.rb +25 -0
- data/lib/plutonium/railtie.rb +26 -8
- data/lib/plutonium/reloader.rb +18 -7
- data/lib/plutonium/resource/controller.rb +4 -0
- data/lib/plutonium/resource/policy.rb +69 -47
- data/lib/plutonium/resource/presenter.rb +1 -0
- data/lib/plutonium/resource/query_object.rb +139 -130
- data/lib/plutonium/rodauth/controller_methods.rb +7 -3
- data/lib/plutonium/version.rb +1 -1
- data/lib/plutonium.rb +9 -57
- data/package-lock.json +782 -17
- data/package.json +31 -8
- data/postcss.config.js +17 -7
- data/src/.npmignore +2 -0
- data/src/js/controllers/color_mode_controller.js +41 -0
- data/src/js/controllers/frame_navigator_controller.js +99 -0
- data/src/js/controllers/has_many_panel_controller.js +8 -0
- data/src/js/controllers/nav_grid_menu_controller.js +8 -0
- data/src/js/controllers/nav_grid_menu_item_controller.js +8 -0
- data/{app/views/components/tab_bar/tab_bar_controller.js → src/js/controllers/nav_user_controller.js} +2 -2
- data/src/js/controllers/nav_user_link_controller.js +8 -0
- data/src/js/controllers/nav_user_section_controller.js +8 -0
- data/src/js/controllers/register_controllers.js +45 -0
- data/{app/assets/javascripts → src/js}/controllers/resource_dismiss_controller.js +2 -0
- data/{app/assets/javascripts → src/js}/controllers/resource_drop_down_controller.js +2 -0
- data/src/js/controllers/resource_header_controller.js +8 -0
- data/src/js/controllers/resource_layout_controller.js +8 -0
- data/src/js/controllers/sidebar_menu_controller.js +8 -0
- data/src/js/controllers/sidebar_menu_item_controller.js +8 -0
- data/src/js/core.js +4 -0
- data/{app/assets/javascripts/plutonium-app.js → src/js/plutonium.js} +1 -1
- data/{app/assets/javascripts → src/js}/turbo/turbo_debug.js +2 -4
- data/tailwind.config.js +85 -84
- metadata +73 -39
- data/app/assets/build/plutonium.js +0 -5122
- data/app/assets/javascripts/controllers/index.js +0 -34
- data/app/assets/javascripts/plutonium.js +0 -1
- data/app/views/application/_color_modes.html.erb +0 -57
- data/app/views/components/tab_bar/tab_bar_component.html.erb +0 -11
- data/app/views/components/tab_bar/tab_bar_component.rb +0 -9
- data/app/views/resource/_nav_user.html.erb +0 -4
- data/app/views/resource/_tab_menu.html.erb +0 -13
- data/css.manifest +0 -3
- data/js.manifest +0 -4
- data/lib/generators/pu/pkg/app/templates/app/controllers/app_controller.rb.tt +0 -5
- data/lib/generators/pu/pkg/app/templates/app/controllers/package_controller.rb.tt +0 -26
- data/public/plutonium-assets/application.css +0 -25086
- data/public/plutonium-assets/plutonium-app-36KN5FVJ.js +0 -6
- data/public/plutonium-assets/plutonium-app-36KN5FVJ.js.map +0 -7
- data/public/plutonium-assets/plutonium-app-6WILQCTT.js +0 -39
- data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +0 -7
- data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +0 -3424
- data/public/plutonium-assets/plutonium.50232e35b5495f5ad90d.css +0 -3415
- data/public/plutonium-assets/plutonium.8bee7a8482988b0360e3.css +0 -3420
- /data/{app/assets/build → lib/generators/pu/core/assets/templates}/.keep +0 -0
- /data/{app/assets/stylesheets → src/css}/plutonium.css +0 -0
- /data/{app/views/components/form → src/js/controllers}/form_controller.js +0 -0
- /data/{app/views/components/interactive_action_form → src/js/controllers}/interactive_action_form_controller.js +0 -0
- /data/{app/views/components/nested_resource_form_fields → src/js/controllers}/nested_resource_form_fields_controller.js +0 -0
- /data/{app/views/components/table → src/js/controllers}/table_controller.js +0 -0
- /data/{app/views/components/table_search_input → src/js/controllers}/table_search_input_controller.js +0 -0
- /data/{app/views/components/table_toolbar → src/js/controllers}/table_toolbar_controller.js +0 -0
- /data/{app/views/components/toolbar → src/js/controllers}/toolbar_controller.js +0 -0
- /data/{app/assets/javascripts → src/js}/turbo/index.js +0 -0
- /data/{app/assets/javascripts → src/js}/turbo/turbo_actions.js +0 -0
- /data/{app/assets/javascripts → src/js}/turbo/turbo_frame_monkey_patch.js +0 -0
@@ -1,61 +1,57 @@
|
|
1
|
-
# TODO: make standard query type names e.g. search and scope configurable
|
2
|
-
|
3
1
|
module Plutonium
|
4
2
|
module Resource
|
5
|
-
# The QueryObject class is responsible for handling various query types and applying them to the given scope.
|
6
3
|
class QueryObject
|
7
4
|
class << self
|
8
5
|
end
|
9
6
|
|
10
|
-
# The Query class serves as a base for different types of queries.
|
11
7
|
class Query
|
12
8
|
include Plutonium::Core::Definers::InputDefiner
|
13
9
|
|
14
|
-
# Applies the query to the given scope
|
10
|
+
# Applies the query to the given scope using the provided parameters.
|
15
11
|
#
|
16
|
-
# @param scope [Object]
|
17
|
-
# @param params [Hash]
|
18
|
-
# @return [Object]
|
12
|
+
# @param scope [Object] The initial scope to which the query will be applied.
|
13
|
+
# @param params [Hash] The parameters for the query.
|
14
|
+
# @return [Object] The modified scope.
|
19
15
|
def apply(scope, params)
|
20
16
|
params = extract_query_params(params)
|
21
|
-
|
17
|
+
|
18
|
+
if input_definitions.size == params.size
|
19
|
+
apply_internal(scope, params)
|
20
|
+
else
|
21
|
+
scope
|
22
|
+
end
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
25
26
|
|
26
|
-
#
|
27
|
+
# Abstract method to apply the query logic to the scope.
|
28
|
+
# Should be implemented by subclasses.
|
27
29
|
#
|
28
|
-
# @param scope [Object]
|
29
|
-
# @param params [Hash]
|
30
|
-
# @raise [NotImplementedError]
|
30
|
+
# @param scope [Object] The initial scope.
|
31
|
+
# @param params [Hash] The parameters for the query.
|
32
|
+
# @raise [NotImplementedError] If the method is not implemented.
|
31
33
|
def apply_internal(scope, params)
|
32
34
|
raise NotImplementedError, "#{self.class}#apply_internal"
|
33
35
|
end
|
34
36
|
|
35
|
-
# Extracts
|
37
|
+
# Extracts query parameters based on the defined inputs.
|
36
38
|
#
|
37
|
-
# @param params [Hash]
|
38
|
-
# @return [Hash]
|
39
|
+
# @param params [Hash] The parameters to extract.
|
40
|
+
# @return [Hash] The extracted and symbolized parameters.
|
39
41
|
def extract_query_params(params)
|
40
42
|
input_definitions.collect_all(params).compact.symbolize_keys
|
41
43
|
end
|
42
44
|
|
43
|
-
#
|
44
|
-
|
45
|
-
# @return [Class, nil] the resource class
|
46
|
-
def resource_class
|
47
|
-
nil
|
48
|
-
end
|
45
|
+
# @return [nil] The resource class (default implementation returns nil).
|
46
|
+
def resource_class = nil
|
49
47
|
end
|
50
48
|
|
51
|
-
# The ScopeQuery class represents a query based on a scope.
|
52
49
|
class ScopeQuery < Query
|
53
50
|
attr_reader :name
|
54
51
|
|
55
|
-
# Initializes a ScopeQuery.
|
52
|
+
# Initializes a ScopeQuery with a given name.
|
56
53
|
#
|
57
|
-
# @param name [Symbol]
|
58
|
-
# @yield [self] optional block to configure the query
|
54
|
+
# @param name [Symbol] The name of the scope.
|
59
55
|
def initialize(name)
|
60
56
|
@name = name
|
61
57
|
yield self if block_given?
|
@@ -63,24 +59,22 @@ module Plutonium
|
|
63
59
|
|
64
60
|
private
|
65
61
|
|
66
|
-
# Applies the scope query to the given scope
|
62
|
+
# Applies the scope query to the given scope.
|
67
63
|
#
|
68
|
-
# @param scope [Object]
|
69
|
-
# @param params [Hash]
|
70
|
-
# @return [Object]
|
64
|
+
# @param scope [Object] The initial scope.
|
65
|
+
# @param params [Hash] The parameters for the query.
|
66
|
+
# @return [Object] The modified scope.
|
71
67
|
def apply_internal(scope, params)
|
72
68
|
scope.send(name, **params)
|
73
69
|
end
|
74
70
|
end
|
75
71
|
|
76
|
-
# The BlockQuery class represents a query based on a block.
|
77
72
|
class BlockQuery < Query
|
78
73
|
attr_reader :body
|
79
74
|
|
80
|
-
# Initializes a BlockQuery.
|
75
|
+
# Initializes a BlockQuery with a given block of code.
|
81
76
|
#
|
82
|
-
# @param body [Proc]
|
83
|
-
# @yield [self] optional block to configure the query
|
77
|
+
# @param body [Proc] The block of code for the query.
|
84
78
|
def initialize(body)
|
85
79
|
@body = body
|
86
80
|
yield self if block_given?
|
@@ -88,22 +82,26 @@ module Plutonium
|
|
88
82
|
|
89
83
|
private
|
90
84
|
|
91
|
-
# Applies the block query to the given scope
|
85
|
+
# Applies the block query to the given scope.
|
92
86
|
#
|
93
|
-
# @param scope [Object]
|
94
|
-
# @param params [Hash]
|
95
|
-
# @return [Object]
|
87
|
+
# @param scope [Object] The initial scope.
|
88
|
+
# @param params [Hash] The parameters for the query.
|
89
|
+
# @return [Object] The modified scope.
|
96
90
|
def apply_internal(scope, params)
|
97
|
-
|
91
|
+
if body.arity == 1
|
92
|
+
body.call(scope)
|
93
|
+
else
|
94
|
+
body.call(scope, **params)
|
95
|
+
end
|
98
96
|
end
|
99
97
|
end
|
100
98
|
|
101
|
-
attr_reader :search_filter, :search_query
|
99
|
+
attr_reader :search_filter, :search_query
|
102
100
|
|
103
|
-
# Initializes a QueryObject.
|
101
|
+
# Initializes a QueryObject with the given context and parameters.
|
104
102
|
#
|
105
|
-
# @param context [Object]
|
106
|
-
# @param params [Hash]
|
103
|
+
# @param context [Object] The context in which the query object is used.
|
104
|
+
# @param params [Hash] The parameters for initialization.
|
107
105
|
def initialize(context, params)
|
108
106
|
@context = context
|
109
107
|
|
@@ -116,59 +114,43 @@ module Plutonium
|
|
116
114
|
extract_sort_params(params)
|
117
115
|
end
|
118
116
|
|
119
|
-
# Builds a URL with the
|
117
|
+
# Builds a URL with the given options for search and sorting.
|
120
118
|
#
|
121
|
-
# @param options [Hash]
|
122
|
-
# @return [String]
|
119
|
+
# @param options [Hash] The options for building the URL.
|
120
|
+
# @return [String] The constructed URL with query parameters.
|
123
121
|
def build_url(**options)
|
124
122
|
q = {}
|
125
|
-
|
126
|
-
q[:
|
123
|
+
|
124
|
+
q[:search] = options.key?(:search) ? options[:search].presence : search_query
|
125
|
+
q[:scope] = options.key?(:scope) ? options[:scope].presence : selected_scope_filter
|
126
|
+
|
127
127
|
q[:sort_directions] = selected_sort_directions.dup
|
128
128
|
q[:sort_fields] = selected_sort_fields.dup
|
129
|
-
|
130
|
-
if (sort = options[:sort])
|
131
|
-
handle_sort_options(q, sort, options[:reset])
|
132
|
-
end
|
129
|
+
handle_sort_options!(q, options)
|
133
130
|
|
134
131
|
"?#{{q: q}.to_param}"
|
135
132
|
end
|
136
133
|
|
137
|
-
# Applies the
|
134
|
+
# Applies the defined filters and sorts to the given scope.
|
138
135
|
#
|
139
|
-
# @param scope [Object]
|
140
|
-
# @return [Object]
|
136
|
+
# @param scope [Object] The initial scope to which filters and sorts are applied.
|
137
|
+
# @return [Object] The modified scope.
|
141
138
|
def apply(scope)
|
142
139
|
scope = search_filter.apply(scope, {search: search_query}) if search_filter.present?
|
143
140
|
scope = scope_definitions[selected_scope_filter].apply(scope, {}) if selected_scope_filter.present?
|
144
|
-
|
141
|
+
apply_sorts(scope)
|
145
142
|
end
|
146
143
|
|
147
|
-
|
148
|
-
#
|
149
|
-
# @return [HashWithIndifferentAccess] the scope definitions
|
150
|
-
def scope_definitions
|
151
|
-
@scope_definitions ||= {}.with_indifferent_access
|
152
|
-
end
|
144
|
+
def scope_definitions = @scope_definitions ||= {}.with_indifferent_access
|
153
145
|
|
154
|
-
|
155
|
-
#
|
156
|
-
# @return [HashWithIndifferentAccess] the filter definitions
|
157
|
-
def filter_definitions
|
158
|
-
@filter_definitions ||= {}.with_indifferent_access
|
159
|
-
end
|
146
|
+
def filter_definitions = @filter_definitions ||= {}.with_indifferent_access
|
160
147
|
|
161
|
-
|
162
|
-
#
|
163
|
-
# @return [HashWithIndifferentAccess] the sort definitions
|
164
|
-
def sort_definitions
|
165
|
-
@sort_definitions ||= {}.with_indifferent_access
|
166
|
-
end
|
148
|
+
def sort_definitions = @sort_definitions ||= {}.with_indifferent_access
|
167
149
|
|
168
|
-
#
|
150
|
+
# Provides sorting parameters for the given field name.
|
169
151
|
#
|
170
|
-
# @param name [Symbol]
|
171
|
-
# @return [Hash, nil]
|
152
|
+
# @param name [Symbol, String] The name of the field to sort.
|
153
|
+
# @return [Hash, nil] The sorting parameters including URL and direction.
|
172
154
|
def sort_params_for(name)
|
173
155
|
return unless sort_definitions[name]
|
174
156
|
|
@@ -182,59 +164,64 @@ module Plutonium
|
|
182
164
|
|
183
165
|
private
|
184
166
|
|
185
|
-
|
167
|
+
attr_reader :context, :selected_sort_fields, :selected_sort_directions, :selected_scope_filter
|
168
|
+
|
169
|
+
# Defines standard filters.
|
186
170
|
def define_filters
|
171
|
+
# Implement filter definitions if needed
|
187
172
|
end
|
188
173
|
|
189
|
-
#
|
174
|
+
# Defines standard scopes.
|
190
175
|
def define_scopes
|
176
|
+
# Implement scope definitions if needed
|
191
177
|
end
|
192
178
|
|
193
|
-
#
|
179
|
+
# Defines standard sorters.
|
194
180
|
def define_sorters
|
181
|
+
# Implement sorter definitions if needed
|
195
182
|
end
|
196
183
|
|
197
|
-
# Defines standard queries.
|
184
|
+
# Defines standard queries for search and scope.
|
198
185
|
def define_standard_queries
|
199
186
|
define_search(:search) if resource_class.respond_to?(:search)
|
200
187
|
end
|
201
188
|
|
202
|
-
# Defines a filter.
|
189
|
+
# Defines a filter with the given name and body.
|
203
190
|
#
|
204
|
-
# @param name [Symbol]
|
205
|
-
# @param body [Proc, nil]
|
206
|
-
# @yield [Query] optional block to configure the query
|
191
|
+
# @param name [Symbol] The name of the filter.
|
192
|
+
# @param body [Proc, nil] The body of the filter.
|
207
193
|
def define_filter(name, body = nil, &block)
|
208
194
|
body ||= name
|
209
195
|
filter_definitions[name] = build_query(body, &block)
|
210
196
|
end
|
211
197
|
|
212
|
-
# Defines a scope.
|
198
|
+
# Defines a scope with the given name and body.
|
213
199
|
#
|
214
|
-
# @param name [Symbol]
|
215
|
-
# @param body [Proc, nil]
|
200
|
+
# @param name [Symbol] The name of the scope.
|
201
|
+
# @param body [Proc, nil] The body of the scope.
|
216
202
|
def define_scope(name, body = nil)
|
217
203
|
body ||= name
|
218
204
|
scope_definitions[name] = build_query(body)
|
219
205
|
end
|
220
206
|
|
221
|
-
# Defines a sort.
|
207
|
+
# Defines a sort with the given name and body.
|
222
208
|
#
|
223
|
-
# @param name [Symbol]
|
224
|
-
# @param body [Proc, nil]
|
225
|
-
def
|
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)
|
226
212
|
if body.nil?
|
227
213
|
sort_field = determine_sort_field(name)
|
228
214
|
body = ->(scope, direction:) { scope.order(sort_field => direction) }
|
229
215
|
end
|
216
|
+
|
230
217
|
sort_definitions[name] = build_query(body) do |query|
|
231
218
|
query.define_input :direction
|
232
219
|
end
|
233
220
|
end
|
234
221
|
|
235
|
-
# Defines a search filter.
|
222
|
+
# Defines a search filter with the given body.
|
236
223
|
#
|
237
|
-
# @param body [Proc]
|
224
|
+
# @param body [Proc, Symbol] The body of the search filter.
|
238
225
|
def define_search(body)
|
239
226
|
@search_filter = build_query(body) do |query|
|
240
227
|
query.define_input :search
|
@@ -243,7 +230,7 @@ module Plutonium
|
|
243
230
|
|
244
231
|
# Extracts filter parameters from the given params.
|
245
232
|
#
|
246
|
-
# @param params [Hash]
|
233
|
+
# @param params [Hash] The parameters to extract.
|
247
234
|
def extract_filter_params(params)
|
248
235
|
@search_query = params[:search]
|
249
236
|
@selected_scope_filter = params[:scope]
|
@@ -251,39 +238,35 @@ module Plutonium
|
|
251
238
|
|
252
239
|
# Extracts sort parameters from the given params.
|
253
240
|
#
|
254
|
-
# @param params [Hash]
|
241
|
+
# @param params [Hash] The parameters to extract.
|
255
242
|
def extract_sort_params(params)
|
256
|
-
@selected_sort_fields = Array(params[:sort_fields])
|
257
|
-
@
|
243
|
+
@selected_sort_fields = Array(params[:sort_fields])
|
244
|
+
@selected_sort_fields &= sort_definitions.keys
|
245
|
+
|
246
|
+
@selected_sort_directions = extract_sort_directions(params)
|
258
247
|
end
|
259
248
|
|
260
|
-
# Builds a query object.
|
249
|
+
# Builds a query object based on the given body and optional block.
|
261
250
|
#
|
262
|
-
# @param body [
|
263
|
-
# @
|
264
|
-
# @return [Query]
|
251
|
+
# @param body [Proc, Symbol] The body of the query.
|
252
|
+
# @yieldparam query [Query] The query object.
|
253
|
+
# @return [Query] The constructed query object.
|
265
254
|
def build_query(body, &block)
|
266
255
|
case body
|
267
256
|
when Symbol
|
268
257
|
raise "Cannot find scope :#{body} on #{resource_class}" unless resource_class.respond_to?(body)
|
258
|
+
|
269
259
|
ScopeQuery.new(body, &block)
|
270
260
|
else
|
271
261
|
BlockQuery.new(body, &block)
|
272
262
|
end
|
273
263
|
end
|
274
264
|
|
275
|
-
#
|
265
|
+
# Determines the sort field for the given name.
|
276
266
|
#
|
277
|
-
# @
|
278
|
-
|
279
|
-
|
280
|
-
end
|
281
|
-
|
282
|
-
# Determines the sort field for a given name.
|
283
|
-
#
|
284
|
-
# @param name [Symbol] the name of the sort field
|
285
|
-
# @return [Symbol] the determined sort field
|
286
|
-
# @raise [RuntimeError] if unable to determine sort logic for the field
|
267
|
+
# @param name [Symbol, String] The name of the field.
|
268
|
+
# @return [Symbol] The sort field.
|
269
|
+
# @raise [RuntimeError] If unable to determine sort logic.
|
287
270
|
def determine_sort_field(name)
|
288
271
|
if resource_class.primary_key == name.to_s || resource_class.content_column_field_names.include?(name)
|
289
272
|
name
|
@@ -294,39 +277,65 @@ module Plutonium
|
|
294
277
|
end
|
295
278
|
end
|
296
279
|
|
297
|
-
#
|
280
|
+
# Extracts sort directions from the given params.
|
281
|
+
#
|
282
|
+
# @param params [Hash] The parameters to extract.
|
283
|
+
# @return [Hash] The extracted sort directions.
|
284
|
+
def extract_sort_directions(params)
|
285
|
+
params[:sort_directions]&.slice(*sort_definitions.keys) || {}
|
286
|
+
end
|
287
|
+
|
288
|
+
# Handles the sort options for building the URL.
|
289
|
+
#
|
290
|
+
# @param query_params [Hash] The query parameters.
|
291
|
+
# @param options [Hash] The options for sorting.
|
292
|
+
def handle_sort_options!(query_params, options)
|
293
|
+
if (sort = options[:sort])
|
294
|
+
handle_sort_reset!(query_params, sort, options[:reset])
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Handles the reset option for sorting.
|
298
299
|
#
|
299
|
-
# @param
|
300
|
-
# @param sort [Symbol]
|
301
|
-
# @param reset [Boolean]
|
302
|
-
def
|
300
|
+
# @param query_params [Hash] The query parameters.
|
301
|
+
# @param sort [Symbol, String] The sort field.
|
302
|
+
# @param reset [Boolean] Whether to reset the sort.
|
303
|
+
def handle_sort_reset!(query_params, sort, reset)
|
303
304
|
if reset
|
304
|
-
|
305
|
-
|
305
|
+
query_params[:sort_fields].delete_if { |e| e == sort.to_s }
|
306
|
+
query_params[:sort_directions].delete(sort)
|
306
307
|
else
|
307
|
-
|
308
|
+
query_params[:sort_fields] << sort.to_s unless query_params[:sort_fields].include?(sort.to_s)
|
309
|
+
|
308
310
|
sort_direction = selected_sort_directions[sort]
|
309
|
-
|
310
|
-
"ASC"
|
311
|
+
if sort_direction.nil?
|
312
|
+
query_params[:sort_directions][sort] = "ASC"
|
313
|
+
elsif sort_direction == "ASC"
|
314
|
+
query_params[:sort_directions][sort] = "DESC"
|
311
315
|
else
|
312
|
-
|
316
|
+
query_params[:sort_fields].delete_if { |e| e == sort.to_s }
|
317
|
+
query_params[:sort_directions].delete(sort)
|
313
318
|
end
|
314
|
-
query[:sort_fields].delete_if { |e| e == sort.to_s } if query[:sort_directions][sort] == "ASC"
|
315
319
|
end
|
316
320
|
end
|
317
321
|
|
318
|
-
# Applies sorters to the scope.
|
322
|
+
# Applies the defined sorters to the given scope.
|
319
323
|
#
|
320
|
-
# @param scope [Object]
|
321
|
-
# @return [Object]
|
322
|
-
def
|
324
|
+
# @param scope [Object] The initial scope.
|
325
|
+
# @return [Object] The modified scope.
|
326
|
+
def apply_sorts(scope)
|
323
327
|
selected_sort_fields.each do |name|
|
324
328
|
sorter = sort_definitions[name]
|
325
329
|
next unless sorter.present?
|
326
|
-
|
330
|
+
|
331
|
+
params = {direction: selected_sort_directions[name] || "ASC"}
|
332
|
+
scope = sorter.apply(scope, params)
|
327
333
|
end
|
328
334
|
scope
|
329
335
|
end
|
336
|
+
|
337
|
+
# @return [Object] The resource class from the context.
|
338
|
+
def resource_class = context.resource_class
|
330
339
|
end
|
331
340
|
end
|
332
341
|
end
|
@@ -4,15 +4,19 @@ module Plutonium
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
+
helper Plutonium::Helpers::ApplicationHelper
|
8
|
+
helper Plutonium::Helpers::ComponentHelper
|
9
|
+
helper Plutonium::Helpers::AssetsHelper
|
10
|
+
|
7
11
|
layout "rodauth"
|
8
12
|
append_view_path File.expand_path("app/views", Plutonium.root)
|
9
|
-
helper_method :
|
13
|
+
helper_method :root_path
|
10
14
|
end
|
11
15
|
|
12
16
|
private
|
13
17
|
|
14
|
-
def
|
15
|
-
|
18
|
+
def root_path
|
19
|
+
"/"
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
data/lib/plutonium/version.rb
CHANGED
data/lib/plutonium.rb
CHANGED
@@ -24,70 +24,22 @@ module Plutonium
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.application_name
|
27
|
-
Rails.application.class.module_parent.name
|
27
|
+
@application_name || Rails.application.class.module_parent.name
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.
|
31
|
-
|
30
|
+
def self.application_name=(application_name)
|
31
|
+
@application_name = application_name
|
32
32
|
end
|
33
33
|
|
34
|
-
def self.
|
35
|
-
|
36
|
-
|
37
|
-
if development?
|
38
|
-
base_dir = "/plutonium-assets/build"
|
39
|
-
filename = "plutonium-dev.css"
|
40
|
-
else
|
41
|
-
base_dir = "/plutonium-assets"
|
42
|
-
filename = "plutonium.css"
|
43
|
-
end
|
44
|
-
|
45
|
-
file = stylesheet_manifest[filename]
|
46
|
-
@stylesheet_link = "#{base_dir}/#{file}"
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.script_link
|
50
|
-
return @script_link if defined?(@script_link) && !development?
|
51
|
-
|
52
|
-
filename = "plutonium-app.js"
|
53
|
-
base_dir = if development?
|
54
|
-
"/plutonium-assets/build"
|
55
|
-
else
|
56
|
-
"/plutonium-assets"
|
57
|
-
end
|
58
|
-
|
59
|
-
file = script_manifest[filename]
|
60
|
-
@script_link = "#{base_dir}/#{file}"
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.favicon_link
|
64
|
-
"/plutonium-assets/plutonium.ico"
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.logo_link
|
68
|
-
"/plutonium-assets/plutonium-logo.png"
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.stylesheet_manifest
|
72
|
-
return @stylesheet_manifest if defined?(@stylesheet_manifest) && !development?
|
73
|
-
|
74
|
-
manifest = if development?
|
75
|
-
"css.dev.manifest"
|
76
|
-
else
|
77
|
-
"css.manifest"
|
78
|
-
end
|
79
|
-
@stylesheet_manifest = JSON.parse(File.read(root.join(manifest)))
|
34
|
+
def self.development?
|
35
|
+
ActiveModel::Type::Boolean.new.cast(ENV["PLUTONIUM_DEV"]).present?
|
80
36
|
end
|
81
37
|
|
82
|
-
def self.
|
83
|
-
return
|
38
|
+
def self.eager_load_rails!
|
39
|
+
return if Rails.env.production? && defined?(@rails_eager_loaded)
|
84
40
|
|
85
|
-
|
86
|
-
|
87
|
-
else
|
88
|
-
"js.manifest"
|
89
|
-
end
|
90
|
-
@script_manifest = JSON.parse(File.read(root.join(manifest)))
|
41
|
+
Rails.application.eager_load! unless Rails.application.config.eager_load
|
42
|
+
@rails_eager_loaded = true
|
91
43
|
end
|
92
44
|
end
|
93
45
|
|