ruby_ui_admin 0.1.0

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.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +165 -0
  4. data/app/assets/stylesheets/ruby_ui_admin/application.tailwind.css +111 -0
  5. data/app/components/ruby_ui_admin/ui/base.rb +26 -0
  6. data/app/components/ruby_ui_admin/ui/icon.rb +79 -0
  7. data/app/components/ruby_ui_admin/ui/native_select.rb +37 -0
  8. data/app/components/ruby_ui_admin/ui/native_select_group.rb +18 -0
  9. data/app/components/ruby_ui_admin/ui/native_select_icon.rb +42 -0
  10. data/app/components/ruby_ui_admin/ui/native_select_option.rb +18 -0
  11. data/app/components/ruby_ui_admin/ui/pagination.rb +62 -0
  12. data/app/components/ruby_ui_admin/ui/pagination_content.rb +18 -0
  13. data/app/components/ruby_ui_admin/ui/pagination_ellipsis.rb +45 -0
  14. data/app/components/ruby_ui_admin/ui/pagination_item.rb +32 -0
  15. data/app/components/ruby_ui_admin/ui/select.rb +29 -0
  16. data/app/components/ruby_ui_admin/ui/toast_action.rb +30 -0
  17. data/app/components/ruby_ui_admin/ui/toast_cancel.rb +30 -0
  18. data/app/components/ruby_ui_admin/ui/toast_close.rb +43 -0
  19. data/app/components/ruby_ui_admin/ui/toast_description.rb +21 -0
  20. data/app/components/ruby_ui_admin/ui/toast_icon.rb +69 -0
  21. data/app/components/ruby_ui_admin/ui/toast_item.rb +75 -0
  22. data/app/components/ruby_ui_admin/ui/toast_region.rb +147 -0
  23. data/app/components/ruby_ui_admin/ui/toast_title.rb +21 -0
  24. data/app/components/ruby_ui_admin/ui.rb +12 -0
  25. data/app/components/ruby_ui_admin/views/action.rb +37 -0
  26. data/app/components/ruby_ui_admin/views/action_form.rb +104 -0
  27. data/app/components/ruby_ui_admin/views/action_trigger.rb +148 -0
  28. data/app/components/ruby_ui_admin/views/actions_menu.rb +34 -0
  29. data/app/components/ruby_ui_admin/views/base.rb +301 -0
  30. data/app/components/ruby_ui_admin/views/card_component.rb +69 -0
  31. data/app/components/ruby_ui_admin/views/dashboard.rb +40 -0
  32. data/app/components/ruby_ui_admin/views/docs.rb +91 -0
  33. data/app/components/ruby_ui_admin/views/field_input.rb +156 -0
  34. data/app/components/ruby_ui_admin/views/field_value.rb +301 -0
  35. data/app/components/ruby_ui_admin/views/filter_bar.rb +111 -0
  36. data/app/components/ruby_ui_admin/views/form.rb +151 -0
  37. data/app/components/ruby_ui_admin/views/home.rb +35 -0
  38. data/app/components/ruby_ui_admin/views/index.rb +324 -0
  39. data/app/components/ruby_ui_admin/views/path_helpers.rb +36 -0
  40. data/app/components/ruby_ui_admin/views/rails_helpers.rb +15 -0
  41. data/app/components/ruby_ui_admin/views/show.rb +77 -0
  42. data/app/components/ruby_ui_admin/views/show_fields.rb +37 -0
  43. data/app/components/ruby_ui_admin/views/show_tab.rb +58 -0
  44. data/app/components/ruby_ui_admin/views/structure_renderer.rb +148 -0
  45. data/app/components/ruby_ui_admin/views/translation.rb +12 -0
  46. data/app/controllers/ruby_ui_admin/actions_controller.rb +162 -0
  47. data/app/controllers/ruby_ui_admin/application_controller.rb +81 -0
  48. data/app/controllers/ruby_ui_admin/dashboards_controller.rb +12 -0
  49. data/app/controllers/ruby_ui_admin/docs_controller.rb +166 -0
  50. data/app/controllers/ruby_ui_admin/home_controller.rb +18 -0
  51. data/app/controllers/ruby_ui_admin/resources_controller.rb +259 -0
  52. data/config/locales/ruby_ui_admin.en.yml +59 -0
  53. data/config/locales/ruby_ui_admin.pt-BR.yml +59 -0
  54. data/config/routes/dynamic_routes.rb +11 -0
  55. data/config/routes.rb +23 -0
  56. data/docs/README.md +53 -0
  57. data/docs/actions/overview.md +112 -0
  58. data/docs/authorization/action-policy.md +72 -0
  59. data/docs/authorization/adapters.md +101 -0
  60. data/docs/authorization/explicit-mode.md +45 -0
  61. data/docs/authorization/field-authorization.md +53 -0
  62. data/docs/authorization/policies.md +62 -0
  63. data/docs/authorization/scopes.md +48 -0
  64. data/docs/customization/controllers.md +62 -0
  65. data/docs/customization/ejecting.md +55 -0
  66. data/docs/customization/javascript.md +161 -0
  67. data/docs/customization/theming-rubyui.md +80 -0
  68. data/docs/dashboards/overview.md +65 -0
  69. data/docs/fields/overview.md +94 -0
  70. data/docs/filters/overview.md +73 -0
  71. data/docs/generators-and-tasks/overview.md +42 -0
  72. data/docs/getting-started/authentication.md +98 -0
  73. data/docs/getting-started/configuration.md +174 -0
  74. data/docs/getting-started/installation.md +201 -0
  75. data/docs/getting-started/internationalization.md +50 -0
  76. data/docs/getting-started/practical-guide.md +310 -0
  77. data/docs/resources/associations.md +66 -0
  78. data/docs/resources/index-customization.md +68 -0
  79. data/docs/resources/overview.md +50 -0
  80. data/docs/resources/scopes.md +54 -0
  81. data/docs/resources/tabs-panels.md +65 -0
  82. data/lib/generators/ruby_ui_admin/action/action_generator.rb +21 -0
  83. data/lib/generators/ruby_ui_admin/action/templates/action.rb.tt +24 -0
  84. data/lib/generators/ruby_ui_admin/assets/assets_generator.rb +71 -0
  85. data/lib/generators/ruby_ui_admin/card/card_generator.rb +28 -0
  86. data/lib/generators/ruby_ui_admin/card/templates/chart_card.rb.tt +14 -0
  87. data/lib/generators/ruby_ui_admin/card/templates/metric_card.rb.tt +14 -0
  88. data/lib/generators/ruby_ui_admin/card/templates/partial_card.rb.tt +13 -0
  89. data/lib/generators/ruby_ui_admin/components/components_generator.rb +43 -0
  90. data/lib/generators/ruby_ui_admin/controller/controller_generator.rb +30 -0
  91. data/lib/generators/ruby_ui_admin/controller/templates/controller.rb.tt +24 -0
  92. data/lib/generators/ruby_ui_admin/dashboard/dashboard_generator.rb +18 -0
  93. data/lib/generators/ruby_ui_admin/dashboard/templates/dashboard.rb.tt +14 -0
  94. data/lib/generators/ruby_ui_admin/eject/eject_generator.rb +55 -0
  95. data/lib/generators/ruby_ui_admin/filter/filter_generator.rb +28 -0
  96. data/lib/generators/ruby_ui_admin/filter/templates/boolean_filter.rb.tt +13 -0
  97. data/lib/generators/ruby_ui_admin/filter/templates/select_filter.rb.tt +19 -0
  98. data/lib/generators/ruby_ui_admin/filter/templates/text_filter.rb.tt +13 -0
  99. data/lib/generators/ruby_ui_admin/install/install_generator.rb +62 -0
  100. data/lib/generators/ruby_ui_admin/install/templates/initializer.rb.tt +41 -0
  101. data/lib/generators/ruby_ui_admin/locales/locales_generator.rb +22 -0
  102. data/lib/generators/ruby_ui_admin/policy/policy_generator.rb +18 -0
  103. data/lib/generators/ruby_ui_admin/policy/templates/policy.rb.tt +24 -0
  104. data/lib/generators/ruby_ui_admin/resource/resource_generator.rb +84 -0
  105. data/lib/generators/ruby_ui_admin/resource/templates/resource.rb.tt +15 -0
  106. data/lib/generators/ruby_ui_admin/scope/scope_generator.rb +18 -0
  107. data/lib/generators/ruby_ui_admin/scope/templates/scope.rb.tt +11 -0
  108. data/lib/ruby_ui_admin/authorization/action_policy_adapter.rb +69 -0
  109. data/lib/ruby_ui_admin/authorization/adapter.rb +80 -0
  110. data/lib/ruby_ui_admin/authorization/can_can_can_adapter.rb +70 -0
  111. data/lib/ruby_ui_admin/authorization/pundit_adapter.rb +86 -0
  112. data/lib/ruby_ui_admin/authorization.rb +40 -0
  113. data/lib/ruby_ui_admin/base_action.rb +211 -0
  114. data/lib/ruby_ui_admin/base_dashboard.rb +70 -0
  115. data/lib/ruby_ui_admin/base_policy.rb +38 -0
  116. data/lib/ruby_ui_admin/base_resource.rb +503 -0
  117. data/lib/ruby_ui_admin/cards/base_card.rb +59 -0
  118. data/lib/ruby_ui_admin/cards/chart_card.rb +16 -0
  119. data/lib/ruby_ui_admin/cards/metric_card.rb +22 -0
  120. data/lib/ruby_ui_admin/cards/partial_card.rb +14 -0
  121. data/lib/ruby_ui_admin/configuration.rb +177 -0
  122. data/lib/ruby_ui_admin/current.rb +20 -0
  123. data/lib/ruby_ui_admin/dashboard_manager.rb +52 -0
  124. data/lib/ruby_ui_admin/engine.rb +80 -0
  125. data/lib/ruby_ui_admin/execution_context.rb +36 -0
  126. data/lib/ruby_ui_admin/fields/association_field.rb +67 -0
  127. data/lib/ruby_ui_admin/fields/badge_field.rb +19 -0
  128. data/lib/ruby_ui_admin/fields/base_field.rb +208 -0
  129. data/lib/ruby_ui_admin/fields/belongs_to_field.rb +49 -0
  130. data/lib/ruby_ui_admin/fields/boolean_field.rb +13 -0
  131. data/lib/ruby_ui_admin/fields/boolean_group_field.rb +54 -0
  132. data/lib/ruby_ui_admin/fields/code_field.rb +18 -0
  133. data/lib/ruby_ui_admin/fields/date_field.rb +34 -0
  134. data/lib/ruby_ui_admin/fields/date_time_field.rb +37 -0
  135. data/lib/ruby_ui_admin/fields/field_manager.rb +27 -0
  136. data/lib/ruby_ui_admin/fields/file_field.rb +67 -0
  137. data/lib/ruby_ui_admin/fields/files_field.rb +62 -0
  138. data/lib/ruby_ui_admin/fields/has_and_belongs_to_many_field.rb +9 -0
  139. data/lib/ruby_ui_admin/fields/has_many_field.rb +24 -0
  140. data/lib/ruby_ui_admin/fields/has_one_field.rb +13 -0
  141. data/lib/ruby_ui_admin/fields/hidden_field.rb +14 -0
  142. data/lib/ruby_ui_admin/fields/id_field.rb +19 -0
  143. data/lib/ruby_ui_admin/fields/key_value_field.rb +41 -0
  144. data/lib/ruby_ui_admin/fields/number_field.rb +13 -0
  145. data/lib/ruby_ui_admin/fields/password_field.rb +21 -0
  146. data/lib/ruby_ui_admin/fields/record_link_field.rb +45 -0
  147. data/lib/ruby_ui_admin/fields/select_field.rb +71 -0
  148. data/lib/ruby_ui_admin/fields/status_field.rb +21 -0
  149. data/lib/ruby_ui_admin/fields/text_field.rb +14 -0
  150. data/lib/ruby_ui_admin/fields/textarea_field.rb +13 -0
  151. data/lib/ruby_ui_admin/fields/url_field.rb +21 -0
  152. data/lib/ruby_ui_admin/filters/base_filter.rb +81 -0
  153. data/lib/ruby_ui_admin/filters/boolean_filter.rb +9 -0
  154. data/lib/ruby_ui_admin/filters/multiple_select_filter.rb +11 -0
  155. data/lib/ruby_ui_admin/filters/select_filter.rb +9 -0
  156. data/lib/ruby_ui_admin/filters/text_filter.rb +9 -0
  157. data/lib/ruby_ui_admin/menu/builder.rb +94 -0
  158. data/lib/ruby_ui_admin/resource_manager.rb +82 -0
  159. data/lib/ruby_ui_admin/scopes/base_scope.rb +107 -0
  160. data/lib/ruby_ui_admin/services/authorization_service.rb +38 -0
  161. data/lib/ruby_ui_admin/structure.rb +40 -0
  162. data/lib/ruby_ui_admin/tailwind_source.rb +65 -0
  163. data/lib/ruby_ui_admin/version.rb +5 -0
  164. data/lib/ruby_ui_admin/view.rb +34 -0
  165. data/lib/ruby_ui_admin.rb +110 -0
  166. data/lib/tasks/ruby_ui_admin.rake +71 -0
  167. data/public/ruby-ui-admin-assets/application.css +2 -0
  168. data/public/ruby-ui-admin-assets/controllers/index.js +36 -0
  169. data/public/ruby-ui-admin-assets/controllers/rua--bulk-select_controller.js +19 -0
  170. data/public/ruby-ui-admin-assets/controllers/rua--confirm_controller.js +51 -0
  171. data/public/ruby-ui-admin-assets/controllers/rua--dialog_controller.js +55 -0
  172. data/public/ruby-ui-admin-assets/controllers/rua--row-link_controller.js +16 -0
  173. data/public/ruby-ui-admin-assets/controllers/rua--tabs_controller.js +36 -0
  174. data/public/ruby-ui-admin-assets/controllers/ruby_ui--combobox_controller.js +197 -0
  175. data/public/ruby-ui-admin-assets/controllers/ruby_ui--sheet_content_controller.js +7 -0
  176. data/public/ruby-ui-admin-assets/controllers/ruby_ui--sheet_controller.js +15 -0
  177. data/public/ruby-ui-admin-assets/controllers/ruby_ui--sidebar_controller.js +67 -0
  178. data/public/ruby-ui-admin-assets/controllers/ruby_ui--toast_controller.js +151 -0
  179. data/public/ruby-ui-admin-assets/controllers/ruby_ui--toaster_controller.js +314 -0
  180. data/public/ruby-ui-admin-assets/vendor/stimulus.js +2567 -0
  181. data/public/ruby-ui-admin-assets/vendor/turbo.js +7178 -0
  182. metadata +379 -0
@@ -0,0 +1,211 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/class/attribute"
4
+
5
+ module RubyUIAdmin
6
+ # Base class for custom actions: declarative fields, response helpers and `handle`.
7
+ # Action execution is wired through ActionsController.
8
+ class BaseAction
9
+ class_attribute :message, instance_accessor: false, default: nil
10
+ class_attribute :confirm_button_label, instance_accessor: false, default: "Run"
11
+ class_attribute :cancel_button_label, instance_accessor: false, default: "Cancel"
12
+ class_attribute :standalone, instance_accessor: false, default: false
13
+ class_attribute :no_confirmation, instance_accessor: false, default: false
14
+ class_attribute :visible, instance_accessor: false, default: nil
15
+ class_attribute :authorize, instance_accessor: false, default: true
16
+
17
+ class << self
18
+ # Class-level `self.name =` with fallback to the real class name.
19
+ def name=(value)
20
+ @display_name = value
21
+ end
22
+
23
+ def name
24
+ @display_name || super
25
+ end
26
+
27
+ def action_name
28
+ name
29
+ end
30
+
31
+ # URL-safe identifier for this action, stable across namespaces, e.g.
32
+ # RubyUIAdmin::Actions::Users::ResetPassword -> "users_reset_password".
33
+ def action_key
34
+ to_s.sub(/^RubyUIAdmin::Actions::/, "").gsub("::", "_").underscore
35
+ end
36
+ end
37
+
38
+ # NOTE: `fields` is the DSL declaration method (below), so submitted values are
39
+ # stored separately as `field_values`.
40
+ attr_accessor :view, :resource, :user, :records, :field_values, :arguments, :current_user
41
+ attr_reader :response
42
+ # The controller running the action, used to expose route helpers inside `handle`.
43
+ attr_writer :controller
44
+
45
+ def initialize(view: nil, resource: nil, user: nil, arguments: {})
46
+ @view = view
47
+ @resource = resource
48
+ @user = user
49
+ @current_user = user
50
+ @arguments = arguments || {}
51
+ @records = []
52
+ @response = default_response
53
+ end
54
+
55
+ # ---- Action form fields DSL ----
56
+
57
+ def field(id, as: :text, **options, &block)
58
+ field_class = Fields.field_class_for(as)
59
+ action_fields << field_class.new(id, **options, &block)
60
+ end
61
+
62
+ def action_fields
63
+ @action_fields ||= []
64
+ end
65
+
66
+ # Overridden by subclasses to declare action form fields.
67
+ def fields; end
68
+
69
+ def get_fields
70
+ @action_fields = []
71
+ fields
72
+ action_fields
73
+ end
74
+
75
+ def has_fields?
76
+ get_fields.any?
77
+ end
78
+
79
+ # ---- Handler ----
80
+
81
+ # Subclasses implement `handle`. Two signatures are supported:
82
+ # def handle(query:, fields:, current_user:, resource:, **); end
83
+ # def handle(args); end # args[:records], args[:fields], args[:current_user]
84
+ def handle(**args); end
85
+
86
+ def name
87
+ self.class.name
88
+ end
89
+
90
+ # The confirmation message shown in the action modal. Accepts a literal or a proc
91
+ # evaluated with `resource`/`record`/`records` available (dynamic message).
92
+ def message
93
+ msg = self.class.message
94
+ return msg unless msg.respond_to?(:call)
95
+
96
+ ExecutionContext.new(
97
+ target: msg,
98
+ view: View.wrap(@view),
99
+ resource: resource,
100
+ record: records&.first,
101
+ records: records,
102
+ current_user: current_user
103
+ ).handle
104
+ end
105
+
106
+ # ---- Route helpers (available inside `handle`) ----
107
+ # Expose `main_app.*` (host routes) and the engine route proxy (`ruby_ui_admin.*`),
108
+ # plus bare `*_path`/`*_url` helpers resolved against either.
109
+
110
+ def main_app
111
+ @controller&.main_app
112
+ end
113
+
114
+ def ruby_ui_admin
115
+ return @controller.ruby_ui_admin if @controller.respond_to?(:ruby_ui_admin)
116
+
117
+ RubyUIAdmin::Engine.routes.url_helpers if defined?(RubyUIAdmin::Engine)
118
+ end
119
+
120
+ def standalone?
121
+ !!self.class.standalone
122
+ end
123
+
124
+ def no_confirmation?
125
+ !!self.class.no_confirmation
126
+ end
127
+
128
+ def visible_in_view?(current_view)
129
+ return true if self.class.visible.nil?
130
+
131
+ ExecutionContext.new(
132
+ target: self.class.visible,
133
+ view: View.wrap(current_view),
134
+ resource: resource,
135
+ record: (records&.first)
136
+ ).handle
137
+ end
138
+
139
+ # ---- Response helpers (mutating @response) ----
140
+
141
+ def succeed(text, **opts)
142
+ add_message(:success, text, **opts)
143
+ end
144
+
145
+ def error(text, **opts)
146
+ add_message(:error, text, **opts)
147
+ end
148
+
149
+ def inform(text, **opts)
150
+ add_message(:info, text, **opts)
151
+ end
152
+
153
+ def warn(text, **opts)
154
+ add_message(:warning, text, **opts)
155
+ end
156
+
157
+ def redirect_to(path = nil, **opts, &block)
158
+ @response[:type] = :redirect
159
+ @response[:path] = block || path
160
+ @response[:redirect_options] = opts
161
+ end
162
+
163
+ def reload
164
+ @response[:type] = :reload
165
+ end
166
+
167
+ def keep_modal_open
168
+ @response[:keep_modal_open] = true
169
+ end
170
+
171
+ def silent
172
+ @response[:messages] = []
173
+ @response[:silent] = true
174
+ end
175
+
176
+ def download(content, filename)
177
+ @response[:type] = :download
178
+ @response[:download] = {content: content, filename: filename}
179
+ end
180
+
181
+ # Resolves bare `*_path`/`*_url` calls in `handle` against the engine routes first,
182
+ # then the host app (`main_app`), so e.g. `resources_posts_path` or a host
183
+ # `login_url(...)` work without a prefix.
184
+ def method_missing(name, *args, **kwargs, &block)
185
+ if route_helper?(name)
186
+ [ruby_ui_admin, main_app].compact.each do |helpers|
187
+ return helpers.public_send(name, *args, **kwargs) if helpers.respond_to?(name)
188
+ end
189
+ end
190
+ super
191
+ end
192
+
193
+ def respond_to_missing?(name, include_private = false)
194
+ (route_helper?(name) && [ruby_ui_admin, main_app].compact.any? { |h| h.respond_to?(name) }) || super
195
+ end
196
+
197
+ private
198
+
199
+ def route_helper?(name)
200
+ name.to_s.end_with?("_path", "_url")
201
+ end
202
+
203
+ def default_response
204
+ {type: :reload, messages: [], keep_modal_open: false, silent: false}
205
+ end
206
+
207
+ def add_message(kind, text, **opts)
208
+ @response[:messages] << {type: kind, body: text, **opts}
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUIAdmin
4
+ # Base class for dashboards. Host dashboards (RubyUIAdmin::Dashboards::*) inherit
5
+ # this and declare cards in `def cards`.
6
+ class BaseDashboard
7
+ class << self
8
+ # Class-level `self.name =` with fallback to the real class name.
9
+ def name=(value)
10
+ @display_name = value
11
+ end
12
+
13
+ def name
14
+ @display_name || super
15
+ end
16
+
17
+ def id=(value)
18
+ @id = value
19
+ end
20
+
21
+ def id
22
+ (defined?(@id) && @id) || to_s.demodulize.underscore
23
+ end
24
+
25
+ def description=(value)
26
+ @description = value
27
+ end
28
+
29
+ def description
30
+ defined?(@description) ? @description : nil
31
+ end
32
+
33
+ def grid_columns=(value)
34
+ @grid_columns = value
35
+ end
36
+
37
+ def grid_columns
38
+ (defined?(@grid_columns) && @grid_columns) || 3
39
+ end
40
+
41
+ # Display title (falls back to a humanized class name).
42
+ def title
43
+ @display_name || to_s.demodulize.titleize
44
+ end
45
+
46
+ def abstract?
47
+ self == RubyUIAdmin::BaseDashboard
48
+ end
49
+ end
50
+
51
+ # Overridden by subclasses to declare cards.
52
+ def cards; end
53
+
54
+ def card(klass, **options)
55
+ card_items << {klass: klass, options: options}
56
+ end
57
+
58
+ def divider(**); end
59
+
60
+ def card_items
61
+ @card_items ||= []
62
+ end
63
+
64
+ def get_cards
65
+ @card_items = []
66
+ cards
67
+ card_items.map { |entry| entry[:klass].new(**(entry[:options] || {})) }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_policy"
4
+
5
+ module RubyUIAdmin
6
+ # Base class for admin policies. Host policies (RubyUIAdmin::Policies::*) inherit
7
+ # from this. It lives outside the `RubyUIAdmin::Policies` namespace so Zeitwerk can
8
+ # fully own that namespace for host-defined policies.
9
+ #
10
+ # Migration note: a host's existing base policy maps to this class.
11
+ #
12
+ # `manage?` is action_policy's default rule (fallback for any rule the host policy
13
+ # doesn't define). We defer it to `explicit_authorization`: when explicit_authorization
14
+ # is false, undefined rules are allowed; when true, they are denied.
15
+ class BasePolicy < ActionPolicy::Base
16
+ # `allow_nil: true` so policies can be evaluated with no signed-in user (rules
17
+ # guard with `user&.`); avoids AuthorizationContextMissing in that edge case.
18
+ authorize :user, allow_nil: true
19
+ # The real (non-impersonated) user, for policies that gate on it. Defaults to `user`.
20
+ authorize :true_user, allow_nil: true
21
+
22
+ def manage?
23
+ !RubyUIAdmin.configuration.explicit_authorization
24
+ end
25
+
26
+ # `index?` and `create?` are concretely defined as `false` by action_policy's
27
+ # Defaults module, so redirect them to the same fallback as every other rule.
28
+ def index? = manage?
29
+
30
+ def create? = manage?
31
+
32
+ # NOTE: no default `relation_scope` is declared here on purpose. The Rails
33
+ # `relation_scope` alias is only registered after the action_policy railtie
34
+ # loads (post-boot), whereas this base class is required at gem load time.
35
+ # When a host policy defines no scope, AuthorizationService#apply_policy
36
+ # rescues the UnknownScope error and returns the relation untouched.
37
+ end
38
+ end