admin_suite 0.2.8 → 0.3.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -1
  3. data/CONTRIBUTING.md +2 -2
  4. data/Gemfile +3 -0
  5. data/README.md +10 -24
  6. data/app/controllers/admin_suite/application_controller.rb +53 -11
  7. data/app/controllers/admin_suite/resources_controller.rb +63 -9
  8. data/app/views/admin_suite/resources/index.html.erb +3 -1
  9. data/app/views/admin_suite/resources/show.html.erb +2 -2
  10. data/lib/admin/base/filter_builder.rb +2 -1
  11. data/lib/admin/base/resource.rb +14 -2
  12. data/lib/admin_suite/auth/host_hook.rb +25 -0
  13. data/lib/admin_suite/auth/http_basic.rb +46 -0
  14. data/lib/admin_suite/auth/strategy.rb +25 -0
  15. data/lib/admin_suite/auth.rb +33 -0
  16. data/lib/admin_suite/configuration.rb +8 -0
  17. data/lib/admin_suite/ui/show_value_formatter.rb +2 -2
  18. data/lib/admin_suite/version.rb +1 -1
  19. data/lib/admin_suite.rb +16 -0
  20. data/lib/generators/admin_suite/install/templates/admin_suite.rb +24 -7
  21. data/test/controllers/resources_controller_test.rb +80 -0
  22. data/test/dummy/config/initializers/admin_suite_auth.rb +8 -0
  23. data/test/integration/authentication_test.rb +99 -0
  24. data/test/integration/authorization_test.rb +131 -0
  25. data/test/integration/read_only_resource_test.rb +130 -0
  26. data/test/lib/auth_http_basic_test.rb +62 -0
  27. data/test/lib/auth_resolution_test.rb +75 -0
  28. data/test/lib/auth_test.rb +29 -0
  29. data/test/lib/resource_observability_extensions_test.rb +53 -0
  30. data/test/test_helper.rb +43 -0
  31. metadata +15 -14
  32. data/docs/README.md +0 -26
  33. data/docs/actions.md +0 -98
  34. data/docs/configuration.md +0 -284
  35. data/docs/development.md +0 -64
  36. data/docs/docs_viewer.md +0 -79
  37. data/docs/fields.md +0 -188
  38. data/docs/installation.md +0 -80
  39. data/docs/portals.md +0 -140
  40. data/docs/releasing.md +0 -67
  41. data/docs/resources.md +0 -237
  42. data/docs/theming.md +0 -63
  43. data/docs/troubleshooting.md +0 -50
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ module AdminSuite
6
+ class ResourceObservabilityExtensionsTest < ActiveSupport::TestCase
7
+ FakeScope = Struct.new(:filters) do
8
+ def where(*arguments)
9
+ self.class.new(filters + [ arguments ])
10
+ end
11
+ end
12
+
13
+ class FilteredResource < Admin::Base::Resource
14
+ index do
15
+ filters do
16
+ filter :window, type: :select, default: "24h",
17
+ apply: ->(scope, value) { scope.where(window: value) }
18
+ filter :status, type: :select
19
+ end
20
+ end
21
+ end
22
+
23
+ class ReadOnlyResource < Admin::Base::Resource
24
+ read_only
25
+ end
26
+
27
+ test "resources are writable by default and may be declared read only" do
28
+ refute Admin::Base::Resource.read_only?
29
+ assert ReadOnlyResource.read_only?
30
+ end
31
+
32
+ test "filter defaults apply when the parameter is absent" do
33
+ scope = Admin::Base::FilterBuilder.new(FilteredResource, ActionController::Parameters.new)
34
+ .apply(FakeScope.new([]))
35
+
36
+ assert_equal [ [ { window: "24h" } ] ], scope.filters
37
+ end
38
+
39
+ test "filter defaults apply when the parameter is blank and compose with explicit filters" do
40
+ params = ActionController::Parameters.new(window: "", status: "failed")
41
+ scope = Admin::Base::FilterBuilder.new(FilteredResource, params).apply(FakeScope.new([]))
42
+
43
+ assert_equal [ [ { window: "24h" } ], [ { status: "failed" } ] ], scope.filters
44
+ end
45
+
46
+ test "an explicit filter overrides its default" do
47
+ params = ActionController::Parameters.new(window: "7d")
48
+ scope = Admin::Base::FilterBuilder.new(FilteredResource, params).apply(FakeScope.new([]))
49
+
50
+ assert_equal [ [ { window: "7d" } ] ], scope.filters
51
+ end
52
+ end
53
+ end
data/test/test_helper.rb CHANGED
@@ -22,3 +22,46 @@ require "action_dispatch/testing/integration"
22
22
 
23
23
  # Ensure the engine is loaded (and its initializers run).
24
24
  require "admin_suite"
25
+
26
+ # The dummy app is intentionally database-free, while the generic controller
27
+ # supports Active Record hosts. Supply only the exception type its lookup path
28
+ # rescues so show-page behavior can be exercised with an in-memory fixture.
29
+ unless defined?(ActiveRecord::RecordNotFound)
30
+ module ActiveRecord
31
+ class RecordNotFound < StandardError; end
32
+ end
33
+ end
34
+
35
+ module TurboFrameTestHelper
36
+ def turbo_frame_tag(name, **options, &block)
37
+ content_tag(:turbo_frame, capture(&block), id: name, **options)
38
+ end
39
+ end
40
+
41
+ ActionView::Base.include(TurboFrameTestHelper)
42
+
43
+ module ReadOnlyResourceFixtures
44
+ class Relation
45
+ include Enumerable
46
+
47
+ def initialize(records)
48
+ @records = records
49
+ end
50
+
51
+ def each(&block)
52
+ @records.each(&block)
53
+ end
54
+
55
+ def count(*)
56
+ @records.count
57
+ end
58
+
59
+ def offset(*)
60
+ self
61
+ end
62
+
63
+ def limit(*)
64
+ self
65
+ end
66
+ end
67
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: admin_suite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TechWright Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-23 00:00:00.000000000 Z
11
+ date: 2026-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -173,23 +173,15 @@ files:
173
173
  - app/views/layouts/admin_suite/application.html.erb
174
174
  - config/importmap.rb
175
175
  - config/routes.rb
176
- - docs/README.md
177
- - docs/actions.md
178
- - docs/configuration.md
179
- - docs/development.md
180
- - docs/docs_viewer.md
181
- - docs/fields.md
182
- - docs/installation.md
183
- - docs/portals.md
184
- - docs/releasing.md
185
- - docs/resources.md
186
- - docs/theming.md
187
- - docs/troubleshooting.md
188
176
  - lib/admin/base/action_executor.rb
189
177
  - lib/admin/base/action_handler.rb
190
178
  - lib/admin/base/filter_builder.rb
191
179
  - lib/admin/base/resource.rb
192
180
  - lib/admin_suite.rb
181
+ - lib/admin_suite/auth.rb
182
+ - lib/admin_suite/auth/host_hook.rb
183
+ - lib/admin_suite/auth/http_basic.rb
184
+ - lib/admin_suite/auth/strategy.rb
193
185
  - lib/admin_suite/configuration.rb
194
186
  - lib/admin_suite/engine.rb
195
187
  - lib/admin_suite/markdown_renderer.rb
@@ -209,6 +201,7 @@ files:
209
201
  - lib/generators/admin_suite/scaffold/scaffold_generator.rb
210
202
  - lib/tasks/admin_suite_tailwind.rake
211
203
  - lib/tasks/admin_suite_test.rake
204
+ - test/controllers/resources_controller_test.rb
212
205
  - test/dummy/Gemfile
213
206
  - test/dummy/README.md
214
207
  - test/dummy/Rakefile
@@ -233,6 +226,7 @@ files:
233
226
  - test/dummy/config/environments/development.rb
234
227
  - test/dummy/config/environments/production.rb
235
228
  - test/dummy/config/environments/test.rb
229
+ - test/dummy/config/initializers/admin_suite_auth.rb
236
230
  - test/dummy/config/initializers/assets.rb
237
231
  - test/dummy/config/initializers/content_security_policy.rb
238
232
  - test/dummy/config/initializers/filter_parameter_logging.rb
@@ -251,11 +245,18 @@ files:
251
245
  - test/dummy/public/robots.txt
252
246
  - test/dummy/test/test_helper.rb
253
247
  - test/fixtures/docs/progress/PROGRESS_REPORT.md
248
+ - test/integration/authentication_test.rb
249
+ - test/integration/authorization_test.rb
254
250
  - test/integration/dashboard_test.rb
255
251
  - test/integration/docs_test.rb
252
+ - test/integration/read_only_resource_test.rb
256
253
  - test/integration/theme_test.rb
257
254
  - test/lib/action_executor_test.rb
255
+ - test/lib/auth_http_basic_test.rb
256
+ - test/lib/auth_resolution_test.rb
257
+ - test/lib/auth_test.rb
258
258
  - test/lib/markdown_renderer_test.rb
259
+ - test/lib/resource_observability_extensions_test.rb
259
260
  - test/lib/theme_palette_test.rb
260
261
  - test/lib/zeitwerk_integration_test.rb
261
262
  - test/test_helper.rb
data/docs/README.md DELETED
@@ -1,26 +0,0 @@
1
- # AdminSuite Documentation
2
-
3
- AdminSuite is a mountable Rails engine that provides:
4
-
5
- - A **resource DSL** for CRUD + search/sort/filter + show/form configuration
6
- - A **portal system** (navigation + optional portal dashboards)
7
- - A built-in **docs viewer** (renders Markdown from your host app filesystem)
8
- - A small baseline **UI layer** (Tailwind optional)
9
-
10
- ## Getting started
11
-
12
- - [Installation](installation.md)
13
- - [Configuration](configuration.md)
14
- - [Portals & dashboards](portals.md)
15
- - [Resources](resources.md)
16
- - [Fields](fields.md)
17
- - [Actions](actions.md)
18
- - [Theming & assets](theming.md)
19
- - [Docs viewer](docs_viewer.md)
20
- - [Troubleshooting](troubleshooting.md)
21
-
22
- ## Contributing / maintainers
23
-
24
- - [Development](development.md)
25
- - [Releasing](releasing.md)
26
-
data/docs/actions.md DELETED
@@ -1,98 +0,0 @@
1
- # Actions
2
-
3
- AdminSuite supports three action “shapes” in the resource DSL:
4
-
5
- - `action` (member action on a single record)
6
- - `bulk_action` (runs across selected records)
7
- - `collection_action` (runs on a scope / collection)
8
-
9
- ## Defining actions
10
-
11
- ```ruby
12
- actions do
13
- action :reindex, label: "Reindex", method: :post, confirm: "Reindex this record?"
14
- bulk_action :archive, label: "Archive", confirm: "Archive selected records?"
15
- end
16
- ```
17
-
18
- Supported action options:
19
-
20
- - `method:` HTTP method (default `:post`)
21
- - `label:` button label (default is humanized action name)
22
- - `icon:` lucide icon name (optional)
23
- - `color:` (optional)
24
- - `confirm:` string confirmation (optional)
25
- - `type:` reserved (default `:button`)
26
- - `if:` Proc condition (member actions only)
27
- - `unless:` Proc condition (member actions only)
28
-
29
- ## How actions execute
30
-
31
- When you trigger an action, AdminSuite resolves behavior in this order:
32
-
33
- 1. **Model method**: if the target responds to `action_name`, it calls that method.
34
- 2. **Bang model method**: else if it responds to `action_name!`, it calls that.
35
- 3. **Action handler class**: else it tries to find a handler class.
36
-
37
- ### Handler class naming convention
38
-
39
- By default, AdminSuite looks for:
40
-
41
- ```ruby
42
- Admin::Actions::<ResourceName><ActionName>Action
43
- ```
44
-
45
- Example for `UserResource` + `:reset_password`:
46
-
47
- ```ruby
48
- Admin::Actions::UserResetPasswordAction
49
- ```
50
-
51
- Handlers should inherit from `Admin::Base::ActionHandler`:
52
-
53
- ```ruby
54
- # app/admin/actions/user_reset_password_action.rb
55
- module Admin
56
- module Actions
57
- class UserResetPasswordAction < Admin::Base::ActionHandler
58
- def call
59
- # record is available as `record`, actor as `actor`, request params as `params`
60
- record.send_reset_password_instructions!
61
- success "Reset email sent."
62
- rescue StandardError => e
63
- failure "Failed to send reset: #{e.message}"
64
- end
65
- end
66
- end
67
- end
68
- ```
69
-
70
- ## Overriding handler resolution (`config.resolve_action_handler`)
71
-
72
- If your app doesn’t want to follow the default naming convention, you can provide a resolver:
73
-
74
- ```ruby
75
- AdminSuite.configure do |config|
76
- config.resolve_action_handler = ->(resource_class, action_name) do
77
- # return a Class or nil
78
- if resource_class.name == "Admin::Resources::UserResource" && action_name.to_sym == :reset_password
79
- Admin::Actions::UserResetPasswordAction
80
- end
81
- end
82
- end
83
- ```
84
-
85
- ## Auditing hook (`config.on_action_executed`)
86
-
87
- You can record or log all actions after they run:
88
-
89
- ```ruby
90
- AdminSuite.configure do |config|
91
- config.on_action_executed = ->(actor:, action_name:, resource_class:, subject:, params:, result:) do
92
- Rails.logger.info(
93
- "[admin_suite] actor=#{actor&.id} action=#{resource_class.name}##{action_name} success=#{result.success?}"
94
- )
95
- end
96
- end
97
- ```
98
-
@@ -1,284 +0,0 @@
1
- # Configuration
2
-
3
- AdminSuite is configured via an initializer:
4
-
5
- - `config/initializers/admin_suite.rb` (generated by `bin/rails g admin_suite:install`)
6
-
7
- All configuration lives on `AdminSuite.config` (an `AdminSuite::Configuration` instance).
8
-
9
- ## Minimal secure configuration
10
-
11
- ```ruby
12
- # config/initializers/admin_suite.rb
13
- AdminSuite.configure do |config|
14
- config.authenticate = ->(controller) do
15
- # Example: require an admin user
16
- controller.redirect_to(controller.main_app.root_path) unless controller.respond_to?(:current_user) && controller.current_user&.admin?
17
- end
18
-
19
- config.current_actor = ->(controller) do
20
- controller.respond_to?(:current_user) ? controller.current_user : nil
21
- end
22
- end
23
- ```
24
-
25
- ## Defaults
26
-
27
- These are the defaults in `AdminSuite::Configuration` / `AdminSuite::Engine`:
28
-
29
- - `authenticate`: `nil`
30
- - `current_actor`: `nil`
31
- - `authorize`: `nil`
32
- - `logout_path`: `nil`
33
- - `logout_method`: `:delete`
34
- - `logout_label`: `"Log out"`
35
- - `resource_globs`: defaults to:
36
- - `Rails.root/config/admin_suite/resources/*.rb`
37
- - `Rails.root/app/admin/resources/*.rb`
38
- - `action_globs`: defaults to:
39
- - `Rails.root/config/admin_suite/actions/*.rb`
40
- - `Rails.root/app/admin/actions/*.rb`
41
- - `portal_globs`: defaults to:
42
- - `Rails.root/config/admin_suite/portals/*.rb`
43
- - `Rails.root/app/admin/portals/*.rb`
44
- - `Rails.root/app/admin_suite/portals/*.rb`
45
- - `dashboard_globs`: defaults to:
46
- - `Rails.root/config/admin_suite/dashboard.rb`
47
- - `Rails.root/config/admin_suite/dashboard/*.rb`
48
- - `Rails.root/app/admin_suite/dashboard.rb`
49
- - `Rails.root/app/admin_suite/dashboard/*.rb`
50
-
51
- Note: AdminSuite definition files (resources, actions, portals) often don't follow
52
- Zeitwerk's path-to-constant naming conventions. To prevent eager-load `Zeitwerk::NameError`s
53
- in production, the engine only configures Zeitwerk to ignore these directories and load them via globs instead:
54
- - `app/admin_suite`
55
- - `app/admin/portals` (when portal DSL usage is detected)
56
-
57
- Other `app/admin/*` directories (such as `app/admin/resources`, `app/admin/actions`, and `app/admin/base`) are
58
- not ignored by default and may be treated as normal Zeitwerk autoload paths if they are added to the loader
59
- (for example, via `loader.push_dir("app/admin")` in the host app). Do not rely on these directories being
60
- ignored for autoloading; instead, keep files there Zeitwerk-compatible.
61
-
62
- We recommend placing non-Zeitwerk-compatible definition files under `config/admin_suite/*` or `app/admin_suite/*`
63
- for clearer separation from standard Rails autoloading.
64
- - `portals`: default portal metadata for `:ops`, `:email`, `:ai`, `:assistant`
65
- - `custom_renderers`: `{}`
66
- - `icon_renderer`: `nil` (uses lucide-rails by default when available)
67
- - `docs_url`: `nil`
68
- - `docs_path`: `Rails.root.join("docs")`
69
- - `partials`: `{}`
70
- - `theme`: `{ primary: :indigo, secondary: :purple }`
71
- - `host_stylesheet`: `nil`
72
- - `tailwind_cdn`: `true`
73
- - `on_action_executed`: `nil`
74
- - `resolve_action_handler`: `nil`
75
-
76
- ## Options
77
-
78
- ### `authenticate`
79
-
80
- Called as a `before_action` inside the engine.
81
-
82
- - **Type**: `Proc` or `nil`
83
- - **Signature**: `->(controller) { ... }`
84
-
85
- If you don’t set it, AdminSuite will be accessible to any user that can reach the mounted route.
86
-
87
- ### `current_actor`
88
-
89
- Used by actions/auditing hooks to identify “who initiated this”.
90
-
91
- - **Type**: `Proc` or `nil`
92
- - **Signature**: `->(controller) { current_user }`
93
-
94
- ### `authorize`
95
-
96
- Optional authorization hook (you can wire Pundit/CanCan/ActionPolicy/etc).
97
-
98
- - **Type**: `Proc` or `nil`
99
- - **Signature**: `->(actor, action:, subject:, resource:, controller:) { true/false }`
100
-
101
- Note: this hook is available, but your app must call it from resource definitions / custom actions as needed (AdminSuite will not guess your authorization policy).
102
-
103
- ### `logout_path`
104
-
105
- Optional sign-out action shown in the top bar.
106
-
107
- - **Type**: `Proc`, `String`, `Symbol`, or `nil`
108
- - **Proc signature**: `->(view_context) { ... }`
109
-
110
- Example:
111
-
112
- ```ruby
113
- config.logout_path = ->(view) { view.main_app.internal_developer_logout_path }
114
- ```
115
-
116
- ### `logout_method`
117
-
118
- HTTP method for the topbar sign-out button.
119
-
120
- - **Type**: `Symbol` or `String`
121
- - **Default**: `:delete`
122
-
123
- ### `logout_label`
124
-
125
- Button label for the topbar sign-out action.
126
-
127
- - **Type**: `String` (or `Proc` for dynamic label)
128
- - **Default**: `"Log out"`
129
-
130
- ### `resource_globs`
131
-
132
- Where AdminSuite should load resource definition files from.
133
-
134
- - **Type**: `Array<String>`
135
-
136
- Example:
137
-
138
- ```ruby
139
- config.resource_globs = [
140
- Rails.root.join("app/admin/resources/**/*.rb").to_s
141
- ]
142
- ```
143
-
144
- ### `action_globs`
145
-
146
- Where AdminSuite should load action handler files from (files that define custom action handlers, typically subclasses of `Admin::Base::ActionHandler`).
147
-
148
- - **Type**: `Array<String>`
149
-
150
- Example:
151
-
152
- ```ruby
153
- config.action_globs = [
154
- Rails.root.join("app/admin/actions/**/*.rb").to_s
155
- ]
156
- ```
157
-
158
- ### `portal_globs`
159
-
160
- Where AdminSuite should load portal definition files from (files typically call `AdminSuite.portal(:key) { ... }`).
161
-
162
- - **Type**: `Array<String>`
163
-
164
- ### `dashboard_globs`
165
-
166
- Where AdminSuite should load the root dashboard definition file(s) from (files typically call `AdminSuite.root_dashboard { ... }`).
167
-
168
- - **Type**: `Array<String>`
169
-
170
- ### `root_dashboard_title`
171
-
172
- Optional title shown on the root dashboard.
173
-
174
- - **Type**: `String`, `Proc`, or `nil`
175
- - **Proc signature**: `->(controller) { "Admin Suite" }`
176
-
177
- ### `root_dashboard_description`
178
-
179
- Optional description shown on the root dashboard.
180
-
181
- - **Type**: `String`, `Proc`, or `nil`
182
- - **Proc signature**: `->(controller) { "..." }`
183
-
184
- ### `portals`
185
-
186
- Portal metadata used for navigation (label/icon/color/order). This is separate from the portal DSL and can be used alone.
187
-
188
- - **Type**: `Hash{Symbol => Hash}`
189
-
190
- Example:
191
-
192
- ```ruby
193
- config.portals = {
194
- ops: { label: "Ops", icon: "settings", color: :amber, order: 10 },
195
- billing: { label: "Billing", icon: "credit-card", color: :emerald, order: 20 }
196
- }
197
- ```
198
-
199
- ### `theme`
200
-
201
- Two-color theme used to set CSS variables scoped to AdminSuite.
202
-
203
- - **Type**: `Hash` with `:primary` and `:secondary`
204
- - **Values**: Tailwind-ish color names (`:indigo`, `:emerald`, …) or a hex string (`"#4f46e5"`)
205
-
206
- See [Theming & assets](theming.md).
207
-
208
- ### `host_stylesheet`
209
-
210
- If set, AdminSuite will include your host app stylesheet **after** its own styles in the engine layout.
211
-
212
- - **Type**: `Symbol` or `String` (passed to `stylesheet_link_tag`)
213
- - **Example**: `config.host_stylesheet = :app`
214
-
215
- ### `tailwind_cdn`
216
-
217
- Reserved for host setups that want a CDN fallback. (AdminSuite already builds its own Tailwind CSS into your host app during `assets:precompile`.)
218
-
219
- - **Type**: `true/false`
220
-
221
- ### `docs_url`
222
-
223
- If set, shows a “Docs” link in the AdminSuite sidebar.
224
-
225
- - **Type**: `String` or `nil`
226
-
227
- ### `docs_path`
228
-
229
- Filesystem path where the docs viewer reads markdown from.
230
-
231
- - **Type**: `Pathname`, `String`, or `Proc`
232
- - **Proc signature**: `->(controller) { Rails.root.join("docs") }`
233
-
234
- ### `partials`
235
-
236
- Override specific engine partials.
237
-
238
- - **Type**: `Hash`
239
-
240
- Example:
241
-
242
- ```ruby
243
- config.partials[:flash] = "shared/flash"
244
- config.partials[:panel_stat] = "admin/panels/stat"
245
- ```
246
-
247
- ### `custom_renderers`
248
-
249
- Register custom show-section renderers (used when a show panel uses `render: :your_key`).
250
-
251
- - **Type**: `Hash{Symbol => Proc}`
252
- - **Proc signature**: `->(record, view_context) { ... }`
253
-
254
- Example:
255
-
256
- ```ruby
257
- config.custom_renderers[:billing_snapshot] = ->(record, view) do
258
- view.render(partial: "admin/billing_snapshot", locals: { record: record })
259
- end
260
- ```
261
-
262
- ### `icon_renderer`
263
-
264
- Replace the default icon provider (lucide-rails).
265
-
266
- - **Type**: `Proc` or `nil`
267
- - **Proc signature**: `->(name, view_context, **opts) { ... }`
268
-
269
- ### `resolve_action_handler`
270
-
271
- Override how AdminSuite finds action handler classes.
272
-
273
- - **Type**: `Proc` or `nil`
274
- - **Proc signature**: `->(resource_class, action_name) { handler_class_or_nil }`
275
-
276
- See [Actions](actions.md).
277
-
278
- ### `on_action_executed`
279
-
280
- Hook called after action execution (success or failure).
281
-
282
- - **Type**: `Proc` or `nil`
283
- - **Proc signature**: `->(actor:, action_name:, resource_class:, subject:, params:, result:) { ... }`
284
-
data/docs/development.md DELETED
@@ -1,64 +0,0 @@
1
- # Development
2
-
3
- This page is intended for contributors/maintainers working on the engine itself.
4
-
5
- ## Setup
6
-
7
- From the gem root:
8
-
9
- ```bash
10
- bundle install
11
- ```
12
-
13
- ## Run tests
14
-
15
- ```bash
16
- bundle exec rake test
17
- ```
18
-
19
- ## Dummy app
20
-
21
- AdminSuite uses a Rails “dummy” app under `test/dummy` for integration tests and to
22
- exercise routing/assets in a host-like environment.
23
-
24
- Useful commands (from the gem root):
25
-
26
- ```bash
27
- cd test/dummy
28
- bin/rails s
29
- ```
30
-
31
- ## Assets / Tailwind
32
-
33
- AdminSuite ships:
34
-
35
- - `app/assets/admin_suite.css` (baseline CSS)
36
- - `app/assets/tailwind/admin_suite.css` (Tailwind input)
37
-
38
- The engine Tailwind build task writes the compiled CSS into the **host app** builds folder:
39
-
40
- - Output: `Rails.root/app/assets/builds/admin_suite_tailwind.css`
41
-
42
- In a host app, this is run automatically during `assets:precompile`:
43
-
44
- ```bash
45
- bin/rails admin_suite:tailwind:build
46
- ```
47
-
48
- When developing inside the engine repo itself, you can run it from the dummy app:
49
-
50
- ```bash
51
- cd test/dummy
52
- bin/rails admin_suite:tailwind:build
53
- ```
54
-
55
- ## Docs
56
-
57
- Engine docs live under:
58
-
59
- - `docs/`
60
-
61
- The docs viewer feature in the engine reads from the host app by default:
62
-
63
- - `Rails.root/docs` (configurable via `AdminSuite.config.docs_path`)
64
-