admin_suite 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -0
- data/app/assets/vendor/easymde.min.css +7 -0
- data/app/assets/vendor/easymde.min.js +7 -0
- data/app/controllers/admin_suite/application_controller.rb +26 -47
- data/app/controllers/admin_suite/portals_controller.rb +2 -2
- data/app/controllers/admin_suite/resources_controller.rb +8 -1
- data/app/helpers/admin_suite/base_helper.rb +49 -385
- data/app/javascript/controllers/admin_suite/markdown_editor_controller.js +21 -2
- data/app/views/admin_suite/panels/_stat.html.erb +10 -0
- data/app/views/admin_suite/resources/index.html.erb +7 -77
- data/app/views/admin_suite/shared/_pagination.html.erb +74 -0
- data/app/views/admin_suite/shared/_sidebar.html.erb +1 -1
- data/app/views/layouts/admin_suite/application.html.erb +5 -3
- data/lib/admin/base/action_executor.rb +19 -51
- data/lib/admin/base/resource.rb +53 -14
- data/lib/admin_suite/configuration.rb +28 -3
- data/lib/admin_suite/definition_loader.rb +194 -0
- data/lib/admin_suite/deprecation.rb +48 -0
- data/lib/admin_suite/engine.rb +55 -76
- data/lib/admin_suite/host_autoload_policy.rb +132 -0
- data/lib/admin_suite/legacy_custom_renderer_procs.rb +29 -0
- data/lib/admin_suite/portal_definition.rb +11 -0
- data/lib/admin_suite/renderer.rb +133 -0
- data/lib/admin_suite/renderer_registry.rb +70 -0
- data/lib/admin_suite/renderers/code_renderer.rb +15 -0
- data/lib/admin_suite/renderers/json_renderer.rb +15 -0
- data/lib/admin_suite/renderers/key_value_renderer.rb +39 -0
- data/lib/admin_suite/renderers/legacy_gleania.rb +230 -0
- data/lib/admin_suite/renderers/table_from_renderer.rb +22 -0
- data/lib/admin_suite/section_definition.rb +42 -0
- data/lib/admin_suite/ui/field_renderer_registry.rb +31 -4
- data/lib/admin_suite/ui/form_field_renderer.rb +1 -7
- data/lib/admin_suite/ui/show_formatter_registry.rb +9 -0
- data/lib/admin_suite/ui/show_value_formatter.rb +7 -3
- data/lib/admin_suite/version.rb +1 -1
- data/lib/admin_suite.rb +37 -0
- data/lib/generators/admin_suite/install/templates/admin_suite.rb +0 -4
- data/test/controllers/resources_controller_test.rb +76 -1
- data/test/integration/layout_assets_test.rb +112 -0
- data/test/integration/navigation_sections_test.rb +41 -0
- data/test/integration/pagination_and_stats_test.rb +152 -0
- data/test/lib/action_executor_redirect_test.rb +41 -0
- data/test/lib/builtin_renderers_test.rb +202 -0
- data/test/lib/definition_loader_test.rb +264 -0
- data/test/lib/engine_defaults_test.rb +39 -0
- data/test/lib/form_field_renderer_test.rb +64 -0
- data/test/lib/legacy_renderer_deprecation_test.rb +35 -0
- data/test/lib/renderer_test.rb +221 -0
- data/test/lib/resource_exportable_deprecation_test.rb +39 -0
- data/test/lib/show_value_formatter_test.rb +88 -0
- data/test/lib/zeitwerk_integration_test.rb +28 -64
- data/test/test_helper.rb +77 -0
- metadata +28 -1
|
@@ -81,37 +81,14 @@ module AdminSuite
|
|
|
81
81
|
#
|
|
82
82
|
# @return [void]
|
|
83
83
|
def ensure_resources_loaded!
|
|
84
|
-
|
|
85
|
-
return if Admin::Base::Resource.registered_resources.any?
|
|
86
|
-
|
|
87
|
-
Array(AdminSuite.config.resource_globs).flat_map { |g| Dir[g] }.uniq.each do |file|
|
|
88
|
-
require file
|
|
89
|
-
end
|
|
90
|
-
rescue NameError
|
|
91
|
-
# Ensure base DSL is loaded first.
|
|
92
|
-
require "admin/base/resource"
|
|
93
|
-
retry
|
|
84
|
+
AdminSuite::DefinitionLoader.load!(:resources)
|
|
94
85
|
end
|
|
95
86
|
|
|
96
87
|
# Loads portal definition files in development (safe to call per-request).
|
|
97
88
|
#
|
|
98
89
|
# @return [void]
|
|
99
90
|
def ensure_portals_loaded!
|
|
100
|
-
|
|
101
|
-
return if globs.empty?
|
|
102
|
-
|
|
103
|
-
if Rails.env.development?
|
|
104
|
-
# Re-evaluate definitions on each request in development.
|
|
105
|
-
AdminSuite::PortalRegistry.reset!
|
|
106
|
-
globs.each { |file| load file }
|
|
107
|
-
else
|
|
108
|
-
# In non-dev, load once (typically at boot / first request).
|
|
109
|
-
return if AdminSuite::PortalRegistry.all.any?
|
|
110
|
-
globs.each { |file| require file }
|
|
111
|
-
end
|
|
112
|
-
rescue NameError
|
|
113
|
-
require "admin_suite"
|
|
114
|
-
retry
|
|
91
|
+
AdminSuite::DefinitionLoader.load!(:portals)
|
|
115
92
|
end
|
|
116
93
|
|
|
117
94
|
# Loads the root dashboard definition files (safe to call per-request).
|
|
@@ -122,33 +99,25 @@ module AdminSuite
|
|
|
122
99
|
#
|
|
123
100
|
# @return [void]
|
|
124
101
|
def ensure_root_dashboard_loaded!
|
|
125
|
-
|
|
126
|
-
globs = Array(AdminSuite.config.dashboard_globs).flat_map { |g| Dir[g] }.uniq
|
|
127
|
-
# Re-evaluate dashboard layout on each request in development.
|
|
128
|
-
# Always reset, even when no files match, so removed dashboards are cleared.
|
|
129
|
-
AdminSuite.reset_root_dashboard!
|
|
130
|
-
globs.each { |file| load file }
|
|
131
|
-
else
|
|
132
|
-
# In non-dev, load once.
|
|
133
|
-
return if AdminSuite.config.root_dashboard_loaded
|
|
134
|
-
globs = Array(AdminSuite.config.dashboard_globs).flat_map { |g| Dir[g] }.uniq
|
|
135
|
-
if globs.empty?
|
|
136
|
-
# Avoid hitting the filesystem on every request when no dashboard files exist.
|
|
137
|
-
AdminSuite.config.root_dashboard_loaded = true
|
|
138
|
-
return
|
|
139
|
-
end
|
|
140
|
-
globs.each { |file| require file }
|
|
141
|
-
AdminSuite.config.root_dashboard_loaded = true
|
|
142
|
-
end
|
|
143
|
-
rescue NameError
|
|
144
|
-
require "admin_suite"
|
|
145
|
-
retry
|
|
102
|
+
AdminSuite::DefinitionLoader.load!(:dashboards)
|
|
146
103
|
end
|
|
147
104
|
|
|
148
105
|
# Builds the navigation structure from registered resources.
|
|
149
106
|
#
|
|
107
|
+
# Memoized per request/controller-instance: views re-enter this method
|
|
108
|
+
# repeatedly while rendering a single page (e.g. `portal_color` and
|
|
109
|
+
# `portal_icon` in base_helper.rb each call it, and the sidebar partial
|
|
110
|
+
# calls those once per portal), and it's rebuilt from scratch each time
|
|
111
|
+
# it isn't memoized -- on top of that, `ensure_resources_loaded!` /
|
|
112
|
+
# `ensure_portals_loaded!` would otherwise glob the filesystem on every
|
|
113
|
+
# one of those re-entries in development.
|
|
114
|
+
#
|
|
150
115
|
# @return [Hash]
|
|
151
116
|
def navigation_items
|
|
117
|
+
@navigation_items ||= build_navigation_items
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def build_navigation_items
|
|
152
121
|
ensure_resources_loaded!
|
|
153
122
|
ensure_portals_loaded!
|
|
154
123
|
|
|
@@ -163,6 +132,13 @@ module AdminSuite
|
|
|
163
132
|
navigation[key.to_sym] ||= { label: key.to_s.humanize, order: 100, sections: {} }
|
|
164
133
|
navigation[key.to_sym].merge!(definition.to_nav_meta)
|
|
165
134
|
navigation[key.to_sym][:sections] ||= {}
|
|
135
|
+
|
|
136
|
+
# Declared sections appear even before any resource is assigned to
|
|
137
|
+
# them, so their label/order take effect immediately.
|
|
138
|
+
definition.sections.each do |section_key, section_definition|
|
|
139
|
+
navigation[key.to_sym][:sections][section_key] ||=
|
|
140
|
+
{ label: section_key.to_s.humanize, order: 100, items: [] }.merge(section_definition.to_nav_meta)
|
|
141
|
+
end
|
|
166
142
|
end
|
|
167
143
|
|
|
168
144
|
Admin::Base::Resource.registered_resources.each do |resource|
|
|
@@ -172,7 +148,10 @@ module AdminSuite
|
|
|
172
148
|
section = resource.section_name.to_sym
|
|
173
149
|
|
|
174
150
|
navigation[portal] ||= { label: portal.to_s.humanize, order: 100, sections: {} }
|
|
175
|
-
navigation[portal][:sections][section] ||=
|
|
151
|
+
navigation[portal][:sections][section] ||= begin
|
|
152
|
+
declared = AdminSuite::PortalRegistry.all[portal]&.sections&.[](section)
|
|
153
|
+
{ label: section.to_s.humanize, order: 100, items: [] }.merge(declared&.to_nav_meta || {})
|
|
154
|
+
end
|
|
176
155
|
|
|
177
156
|
label = resource.nav_label.presence || resource.human_name_plural
|
|
178
157
|
navigation[portal][:sections][section][:items] << {
|
|
@@ -11,8 +11,8 @@ module AdminSuite
|
|
|
11
11
|
raise ActionController::RoutingError, "Portal not found" if @portal.blank?
|
|
12
12
|
|
|
13
13
|
@sections =
|
|
14
|
-
(@portal[:sections] || {}).sort_by { |(_k, s)| s[:label].to_s }.map do |section_key, section|
|
|
15
|
-
items = Array(section[:items]).sort_by { |it| it[:label].to_s }
|
|
14
|
+
(@portal[:sections] || {}).sort_by { |(_k, s)| [ (s[:order] || 100).to_i, s[:label].to_s ] }.map do |section_key, section|
|
|
15
|
+
items = Array(section[:items]).sort_by { |it| [ (it[:order] || 100).to_i, it[:label].to_s ] }
|
|
16
16
|
[ section_key, section.merge(items: items) ]
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -200,7 +200,14 @@ module AdminSuite
|
|
|
200
200
|
end
|
|
201
201
|
|
|
202
202
|
@resource = klass.find(id)
|
|
203
|
-
rescue
|
|
203
|
+
rescue StandardError => e
|
|
204
|
+
# A bare `rescue ActiveRecord::RecordNotFound` raises `NameError`
|
|
205
|
+
# *while handling* whatever the real exception was, in a host without
|
|
206
|
+
# ActiveRecord loaded (e.g. `column_names` above failing on a PORO
|
|
207
|
+
# model) -- destroying the original diagnostic. Only recover the one
|
|
208
|
+
# case this method actually knows how to recover from.
|
|
209
|
+
raise unless defined?(ActiveRecord::RecordNotFound) && e.is_a?(ActiveRecord::RecordNotFound)
|
|
210
|
+
|
|
204
211
|
@resource = find_friendly_resource!(klass, id, columns)
|
|
205
212
|
end
|
|
206
213
|
|