jav_madmin 2.6.7 → 3.3.2
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/README.md +89 -4
- data/app/assets/stylesheets/madmin/actiontext.css +31 -0
- data/app/assets/stylesheets/madmin/base.css +22 -11
- data/app/assets/stylesheets/madmin/buttons.css +9 -9
- data/app/assets/stylesheets/madmin/forms.css +271 -11
- data/app/assets/stylesheets/madmin/pagination.css +25 -21
- data/app/assets/stylesheets/madmin/reset.css +1 -1
- data/app/assets/stylesheets/madmin/sidebar.css +6 -6
- data/app/assets/stylesheets/madmin/tables.css +2 -1
- data/app/controllers/madmin/base_controller.rb +1 -5
- data/app/controllers/madmin/resource_controller.rb +53 -19
- data/app/helpers/madmin/application_helper.rb +33 -2
- data/app/helpers/madmin/filters_helper.rb +26 -0
- data/app/helpers/madmin/sort_helper.rb +1 -1
- data/app/javascript/madmin/application.js +4 -0
- data/app/javascript/madmin/controllers/application.js +0 -3
- data/app/javascript/madmin/controllers/filters_controller.js +35 -0
- data/app/javascript/madmin/controllers/nested_form_controller.js +5 -0
- data/app/javascript/madmin/controllers/select_controller.js +269 -22
- data/app/views/layouts/madmin/application.html.erb +1 -0
- data/app/views/madmin/application/_active_filters.html.erb +15 -0
- data/app/views/madmin/application/_filter.html.erb +13 -0
- data/app/views/madmin/application/_filters.html.erb +30 -0
- data/app/views/madmin/application/_javascript.html.erb +0 -2
- data/app/views/madmin/application/_pagination.html.erb +33 -0
- data/app/views/madmin/application/_per_page.html.erb +10 -0
- data/app/views/madmin/application/edit.html.erb +1 -1
- data/app/views/madmin/application/index.html.erb +9 -12
- data/app/views/madmin/application/new.html.erb +1 -1
- data/app/views/madmin/application/show.html.erb +2 -2
- data/app/views/madmin/fields/array/_form.html.erb +1 -0
- data/app/views/madmin/fields/array/_index.html.erb +1 -0
- data/app/views/madmin/fields/array/_show.html.erb +1 -0
- data/app/views/madmin/fields/attachment/_form.html.erb +1 -5
- data/app/views/madmin/fields/attachment/_show.html.erb +3 -1
- data/app/views/madmin/fields/attachments/_form.html.erb +1 -1
- data/app/views/madmin/fields/belongs_to/_form.html.erb +1 -1
- data/app/views/madmin/fields/belongs_to/_index.html.erb +5 -2
- data/app/views/madmin/fields/belongs_to/_show.html.erb +1 -1
- data/app/views/madmin/fields/enum/_form.html.erb +1 -1
- data/app/views/madmin/fields/file/_form.html.erb +1 -1
- data/app/views/madmin/fields/has_many/_form.html.erb +1 -1
- data/app/views/madmin/fields/has_many/_show.html.erb +3 -11
- data/app/views/madmin/fields/has_one/_index.html.erb +5 -1
- data/app/views/madmin/fields/has_one/_show.html.erb +1 -1
- data/app/views/madmin/fields/json/_form.html.erb +1 -1
- data/app/views/madmin/fields/json/_show.html.erb +1 -1
- data/app/views/madmin/fields/nested_has_many/_show.html.erb +3 -11
- data/app/views/madmin/fields/nested_has_one/_form.html.erb +18 -0
- data/app/views/madmin/fields/polymorphic/_form.html.erb +1 -2
- data/app/views/madmin/fields/polymorphic/_index.html.erb +5 -1
- data/app/views/madmin/fields/polymorphic/_show.html.erb +1 -1
- data/app/views/madmin/fields/select/_form.html.erb +1 -1
- data/config/importmap.rb +0 -3
- data/config/locales/el.yml +47 -0
- data/config/locales/en.yml +47 -0
- data/config/locales/fr.yml +47 -0
- data/config/locales/ko.yml +48 -0
- data/lib/generators/madmin/resource/templates/resource.rb.tt +3 -0
- data/lib/madmin/field.rb +26 -0
- data/lib/madmin/fields/array.rb +16 -0
- data/lib/madmin/fields/attachment.rb +7 -0
- data/lib/madmin/fields/belongs_to.rb +2 -1
- data/lib/madmin/fields/boolean.rb +1 -0
- data/lib/madmin/fields/currency.rb +7 -0
- data/lib/madmin/fields/date.rb +1 -0
- data/lib/madmin/fields/date_time.rb +1 -0
- data/lib/madmin/fields/decimal.rb +1 -0
- data/lib/madmin/fields/float.rb +1 -0
- data/lib/madmin/fields/has_many.rb +8 -23
- data/lib/madmin/fields/integer.rb +1 -0
- data/lib/madmin/fields/json.rb +21 -0
- data/lib/madmin/fields/nested_has_many.rb +2 -2
- data/lib/madmin/fields/nested_has_one.rb +48 -0
- data/lib/madmin/fields/polymorphic.rb +5 -0
- data/lib/madmin/fields/string.rb +2 -0
- data/lib/madmin/fields/text.rb +2 -0
- data/lib/madmin/filter.rb +113 -0
- data/lib/madmin/menu.rb +2 -1
- data/lib/madmin/page.rb +89 -0
- data/lib/madmin/pagination.rb +50 -0
- data/lib/madmin/resource.rb +86 -19
- data/lib/madmin/search.rb +5 -7
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin.rb +45 -3
- metadata +17 -15
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Madmin
|
|
2
|
+
# Paginates ActiveRecord relations using only the relation API (count, order,
|
|
3
|
+
# offset, limit) so the SQL is generated by whichever database adapter is in use.
|
|
4
|
+
module Pagination
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# Returns [Madmin::Page, records]
|
|
8
|
+
def paginate(collection, page: 1, per_page: Madmin.per_page, param: :page)
|
|
9
|
+
page = Madmin::Page.new(count: count_for(collection), page: page, per_page: per_page, param: param)
|
|
10
|
+
[page, with_tiebreaker(collection).offset(page.offset).limit(page.per_page)]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def count_for(collection)
|
|
14
|
+
# count(:all) keeps custom selects valid, and ordering is irrelevant to a count
|
|
15
|
+
count = collection.unscope(:order).count(:all)
|
|
16
|
+
|
|
17
|
+
# Grouped relations return a Hash of counts per group
|
|
18
|
+
count.is_a?(Hash) ? count.size : count
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Appends the primary key to the ordering so rows with equal sort values keep
|
|
22
|
+
# a stable position across pages. It follows the direction of the existing
|
|
23
|
+
# ordering so indexes on the sort column can still be used.
|
|
24
|
+
def with_tiebreaker(collection)
|
|
25
|
+
return collection if collection.group_values.any? || collection.distinct_value
|
|
26
|
+
|
|
27
|
+
primary_keys = Array(collection.klass.primary_key).map(&:to_s)
|
|
28
|
+
return collection if primary_keys.empty?
|
|
29
|
+
|
|
30
|
+
orders = collection.order_values
|
|
31
|
+
return collection if orders.any? { |order| orders_by?(order, primary_keys) }
|
|
32
|
+
|
|
33
|
+
direction = descending?(orders.last) ? :desc : :asc
|
|
34
|
+
table = collection.klass.arel_table
|
|
35
|
+
collection.order(primary_keys.map { |key| table[key].public_send(direction) })
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def orders_by?(order, column_names)
|
|
39
|
+
order.is_a?(Arel::Nodes::Ordering) && order.expr.respond_to?(:name) && column_names.include?(order.expr.name.to_s)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def descending?(order)
|
|
43
|
+
case order
|
|
44
|
+
when Arel::Nodes::Descending then true
|
|
45
|
+
when String then order.match?(/\bdesc\s*\z/i)
|
|
46
|
+
else false
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/madmin/resource.rb
CHANGED
|
@@ -81,10 +81,22 @@ module Madmin
|
|
|
81
81
|
)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
# For example: "Forum::Post" -> "Forum / Post"
|
|
85
|
+
#
|
|
86
|
+
# Uses the model's translation (`activerecord.models.forum/post`) when there is one
|
|
87
|
+
def friendly_name
|
|
88
|
+
translated_name || model_name.split("::").map { |part| part.underscore.humanize }.join(" / ").titlecase
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Returns plural name
|
|
92
|
+
# For example: "Forum::Post" -> "Forum / Posts"
|
|
93
|
+
def friendly_plural_name
|
|
94
|
+
singular = translated_name
|
|
95
|
+
return friendly_name.pluralize unless singular
|
|
96
|
+
|
|
97
|
+
# A translation without `one` / `other` forms is the same for every count
|
|
98
|
+
return translated_name(count: 2) if plural_translation? || !locale_inflections?
|
|
99
|
+
singular.pluralize(I18n.locale)
|
|
88
100
|
end
|
|
89
101
|
|
|
90
102
|
# Support for isolated namespaces
|
|
@@ -97,20 +109,29 @@ module Madmin
|
|
|
97
109
|
@route_namespace = (namespace ? namespace.name.underscore.to_sym : nil)
|
|
98
110
|
end
|
|
99
111
|
|
|
100
|
-
def index_path(options =
|
|
101
|
-
|
|
112
|
+
def index_path(options = {})
|
|
113
|
+
route_path([:madmin, route_namespace, model], options)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def new_path
|
|
117
|
+
route_path([:madmin, route_namespace, model], action: :new)
|
|
102
118
|
end
|
|
103
119
|
|
|
104
|
-
def
|
|
105
|
-
|
|
120
|
+
def show_path(record)
|
|
121
|
+
route_path([:madmin, route_namespace, becomes(record)])
|
|
106
122
|
end
|
|
107
123
|
|
|
108
|
-
def
|
|
109
|
-
|
|
124
|
+
def edit_path(record)
|
|
125
|
+
route_path([:madmin, route_namespace, becomes(record)], action: :edit)
|
|
110
126
|
end
|
|
111
127
|
|
|
112
|
-
|
|
113
|
-
|
|
128
|
+
# Whether a route is drawn for the given action on this resource's controller
|
|
129
|
+
# For example: PostResource.route?(:destroy)
|
|
130
|
+
def route?(action)
|
|
131
|
+
controller = "madmin/#{model.model_name.collection}"
|
|
132
|
+
Rails.application.routes.routes.any? do |route|
|
|
133
|
+
route.defaults[:controller] == controller && route.defaults[:action] == action.to_s
|
|
134
|
+
end
|
|
114
135
|
end
|
|
115
136
|
|
|
116
137
|
def becomes(record)
|
|
@@ -129,6 +150,14 @@ module Madmin
|
|
|
129
150
|
"#{record.model_name.human} ##{record.id}"
|
|
130
151
|
end
|
|
131
152
|
|
|
153
|
+
# Override for wording that needs more than the display name. Return nil to skip the confirmation.
|
|
154
|
+
def delete_confirmation(record)
|
|
155
|
+
I18n.t("madmin.resources.#{model.model_name.i18n_key}.confirmations.delete",
|
|
156
|
+
default: :"madmin.confirmations.delete",
|
|
157
|
+
resource: friendly_name,
|
|
158
|
+
name: display_name(record))
|
|
159
|
+
end
|
|
160
|
+
|
|
132
161
|
def friendly_model?
|
|
133
162
|
model.respond_to? :friendly
|
|
134
163
|
end
|
|
@@ -149,6 +178,10 @@ module Madmin
|
|
|
149
178
|
attributes.values.select { |a| a.field.searchable? }
|
|
150
179
|
end
|
|
151
180
|
|
|
181
|
+
def filterable_attributes
|
|
182
|
+
attributes.values.select { |a| a.field&.filter_type }
|
|
183
|
+
end
|
|
184
|
+
|
|
152
185
|
def member_action(collection: false, &block)
|
|
153
186
|
member_actions << MemberAction.new(collection: collection, &block)
|
|
154
187
|
end
|
|
@@ -164,6 +197,7 @@ module Madmin
|
|
|
164
197
|
|
|
165
198
|
def field_for_type(type)
|
|
166
199
|
{
|
|
200
|
+
array: Fields::Array,
|
|
167
201
|
binary: Fields::String,
|
|
168
202
|
blob: Fields::Text,
|
|
169
203
|
boolean: Fields::Boolean,
|
|
@@ -223,7 +257,8 @@ module Madmin
|
|
|
223
257
|
has_many: Fields::HasMany,
|
|
224
258
|
has_one: Fields::HasOne,
|
|
225
259
|
rich_text: Fields::RichText,
|
|
226
|
-
nested_has_many: Fields::NestedHasMany
|
|
260
|
+
nested_has_many: Fields::NestedHasMany,
|
|
261
|
+
nested_has_one: Fields::NestedHasOne
|
|
227
262
|
}[type]
|
|
228
263
|
end
|
|
229
264
|
|
|
@@ -234,6 +269,8 @@ module Madmin
|
|
|
234
269
|
column_type = model.attribute_types[name_string]
|
|
235
270
|
if column_type.is_a? ::ActiveRecord::Enum::EnumType
|
|
236
271
|
:enum
|
|
272
|
+
elsif model.columns_hash[name_string].try(:array?)
|
|
273
|
+
:array
|
|
237
274
|
else
|
|
238
275
|
column_type.type || :string
|
|
239
276
|
end
|
|
@@ -272,6 +309,26 @@ module Madmin
|
|
|
272
309
|
@url_helpers ||= Rails.application.routes.url_helpers
|
|
273
310
|
end
|
|
274
311
|
|
|
312
|
+
# Raises MissingRoute with instructions instead of a NoMethodError for
|
|
313
|
+
# the undefined route helper when the resource's routes aren't drawn
|
|
314
|
+
def route_path(components, options = {})
|
|
315
|
+
url_helpers.polymorphic_path(components, options)
|
|
316
|
+
rescue NoMethodError => error
|
|
317
|
+
raise unless error.name.to_s.end_with?("_path")
|
|
318
|
+
|
|
319
|
+
*namespaces, resources = model.model_name.collection.split("/")
|
|
320
|
+
routes = namespaces.reverse.inject("resources :#{resources}") do |body, namespace|
|
|
321
|
+
"namespace :#{namespace} do\n#{body.indent(2)}\nend"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
raise MissingRoute, [
|
|
325
|
+
"`#{error.name}` is not defined, so #{name} has no route for this page.",
|
|
326
|
+
"Add the route inside `namespace :madmin` in your routes:",
|
|
327
|
+
routes.indent(4),
|
|
328
|
+
"To hide the resource from the menu instead, add `menu false` to #{name}."
|
|
329
|
+
].join("\n\n")
|
|
330
|
+
end
|
|
331
|
+
|
|
275
332
|
def model_store_accessors
|
|
276
333
|
return [] unless model.respond_to?(:stored_attributes)
|
|
277
334
|
|
|
@@ -286,18 +343,28 @@ module Madmin
|
|
|
286
343
|
def menu_options
|
|
287
344
|
return false if @menu_options == false
|
|
288
345
|
@menu_options ||= {}
|
|
289
|
-
|
|
346
|
+
# The default label follows the locale, so the menu tracks the item by resource instead
|
|
347
|
+
@menu_options.with_defaults(key: @menu_options[:label] || name, label: friendly_plural_name, url: index_path)
|
|
290
348
|
end
|
|
291
349
|
|
|
292
350
|
private
|
|
293
351
|
|
|
294
|
-
def
|
|
295
|
-
|
|
352
|
+
def translated_name(count: 1)
|
|
353
|
+
model.model_name.human(count: count, default: "").presence
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# Whether the model's translation spells out its own `one` / `other` forms
|
|
357
|
+
def plural_translation?
|
|
358
|
+
model.lookup_ancestors.each do |klass|
|
|
359
|
+
translation = I18n.t(klass.model_name.i18n_key, scope: [klass.i18n_scope, :models], default: "")
|
|
360
|
+
return translation.is_a?(Hash) if translation.present?
|
|
361
|
+
end
|
|
362
|
+
false
|
|
296
363
|
end
|
|
297
364
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
365
|
+
# Locales without inflection rules of their own (most non-English ones) are left unpluralized
|
|
366
|
+
def locale_inflections?
|
|
367
|
+
ActiveSupport::Inflector::Inflections.instance(I18n.locale).plurals.any?
|
|
301
368
|
end
|
|
302
369
|
end
|
|
303
370
|
|
data/lib/madmin/search.rb
CHANGED
|
@@ -2,20 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
module Madmin
|
|
4
4
|
class Search
|
|
5
|
-
attr_reader :query
|
|
5
|
+
attr_reader :query, :filters
|
|
6
6
|
|
|
7
|
-
def initialize(scoped_resource, resource, term)
|
|
7
|
+
def initialize(scoped_resource, resource, term, filters = [])
|
|
8
8
|
@resource = resource
|
|
9
9
|
@scoped_resource = scoped_resource
|
|
10
10
|
@query = term
|
|
11
|
+
@filters = filters
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def run
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
else
|
|
17
|
-
search_results(@scoped_resource)
|
|
18
|
-
end
|
|
15
|
+
results = query.blank? ? @scoped_resource.all : search_results(@scoped_resource)
|
|
16
|
+
filters.reduce(results) { |scope, filter| filter.apply(scope) }
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
private
|
data/lib/madmin/version.rb
CHANGED
data/lib/madmin.rb
CHANGED
|
@@ -2,18 +2,21 @@ require "madmin/engine"
|
|
|
2
2
|
require "importmap-rails"
|
|
3
3
|
require "stimulus-rails"
|
|
4
4
|
require "turbo-rails"
|
|
5
|
-
require "pagy"
|
|
6
5
|
|
|
7
6
|
module Madmin
|
|
8
7
|
autoload :Field, "madmin/field"
|
|
8
|
+
autoload :Filter, "madmin/filter"
|
|
9
9
|
autoload :GeneratorHelpers, "madmin/generator_helpers"
|
|
10
10
|
autoload :MemberAction, "madmin/member_action"
|
|
11
11
|
autoload :Menu, "madmin/menu"
|
|
12
|
+
autoload :Page, "madmin/page"
|
|
13
|
+
autoload :Pagination, "madmin/pagination"
|
|
12
14
|
autoload :Resource, "madmin/resource"
|
|
13
15
|
autoload :ResourceBuilder, "madmin/resource_builder"
|
|
14
16
|
autoload :Search, "madmin/search"
|
|
15
17
|
|
|
16
18
|
module Fields
|
|
19
|
+
autoload :Array, "madmin/fields/array"
|
|
17
20
|
autoload :Attachment, "madmin/fields/attachment"
|
|
18
21
|
autoload :Attachments, "madmin/fields/attachments"
|
|
19
22
|
autoload :BelongsTo, "madmin/fields/belongs_to"
|
|
@@ -30,6 +33,7 @@ module Madmin
|
|
|
30
33
|
autoload :Integer, "madmin/fields/integer"
|
|
31
34
|
autoload :Json, "madmin/fields/json"
|
|
32
35
|
autoload :NestedHasMany, "madmin/fields/nested_has_many"
|
|
36
|
+
autoload :NestedHasOne, "madmin/fields/nested_has_one"
|
|
33
37
|
autoload :Password, "madmin/fields/password"
|
|
34
38
|
autoload :Polymorphic, "madmin/fields/polymorphic"
|
|
35
39
|
autoload :RichText, "madmin/fields/rich_text"
|
|
@@ -41,14 +45,17 @@ module Madmin
|
|
|
41
45
|
|
|
42
46
|
mattr_accessor :importmap, default: Importmap::Map.new
|
|
43
47
|
mattr_accessor :menu, default: Menu.new
|
|
48
|
+
mattr_accessor :per_page, default: 20
|
|
44
49
|
mattr_accessor :site_name
|
|
45
50
|
mattr_accessor :stylesheets, default: []
|
|
46
51
|
mattr_accessor :resource_locations, default: []
|
|
47
|
-
mattr_accessor :multi_locales, default: false, instance_accessor: false
|
|
48
52
|
|
|
49
53
|
class MissingResource < StandardError
|
|
50
54
|
end
|
|
51
55
|
|
|
56
|
+
class MissingRoute < StandardError
|
|
57
|
+
end
|
|
58
|
+
|
|
52
59
|
class << self
|
|
53
60
|
# Returns a Madmin::Resource class for the given object
|
|
54
61
|
def resource_for(object)
|
|
@@ -59,6 +66,12 @@ module Madmin
|
|
|
59
66
|
elsif (resource_name = sti_resource_name_for(object)) && Object.const_defined?(resource_name)
|
|
60
67
|
resource_name.constantize
|
|
61
68
|
|
|
69
|
+
# A resource named differently from its model (`ArticleResource` for
|
|
70
|
+
# `Blog::Post`) still says which model it is for with `model`. Honor that
|
|
71
|
+
# declaration before giving up, so association cells can link to it.
|
|
72
|
+
elsif (resource = resource_declaring(object.class))
|
|
73
|
+
resource
|
|
74
|
+
|
|
62
75
|
else
|
|
63
76
|
raise MissingResource, <<~MESSAGE
|
|
64
77
|
`#{object.class.name}Resource` is missing.
|
|
@@ -70,6 +83,28 @@ module Madmin
|
|
|
70
83
|
end
|
|
71
84
|
end
|
|
72
85
|
|
|
86
|
+
# The one resource whose `model` is +klass+ or, failing that, its nearest
|
|
87
|
+
# superclass, or nil. Two resources declaring the same model with neither
|
|
88
|
+
# matching its name is ambiguous, and guessing would silently link to the
|
|
89
|
+
# wrong admin page, so that raises.
|
|
90
|
+
def resource_declaring(klass)
|
|
91
|
+
declared = klass.ancestors.grep(Class).find { |ancestor| resources_by_model.key?(ancestor) }
|
|
92
|
+
return unless declared
|
|
93
|
+
|
|
94
|
+
candidates = resources_by_model[declared]
|
|
95
|
+
return candidates.first if candidates.one?
|
|
96
|
+
|
|
97
|
+
raise MissingResource, <<~MESSAGE
|
|
98
|
+
`#{declared.name}Resource` is missing, and #{candidates.map(&:name).join(", ")} all declare `model #{declared.name}`.
|
|
99
|
+
|
|
100
|
+
Madmin can't tell which one to use. Name one of them `#{declared.name}Resource`.
|
|
101
|
+
MESSAGE
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def resources_by_model
|
|
105
|
+
@resources_by_model ||= resources.group_by(&:model)
|
|
106
|
+
end
|
|
107
|
+
|
|
73
108
|
def resource_name_for(object)
|
|
74
109
|
if object.is_a? ::ActiveStorage::Attached
|
|
75
110
|
"ActiveStorage::AttachmentResource"
|
|
@@ -86,13 +121,19 @@ module Madmin
|
|
|
86
121
|
end
|
|
87
122
|
end
|
|
88
123
|
|
|
124
|
+
# Returns the Madmin::Resource class for a model or model name, falling
|
|
125
|
+
# back to the resource that declares the model when none is named after it
|
|
89
126
|
def resource_by_name(name)
|
|
90
127
|
"#{name}Resource".constantize
|
|
91
128
|
rescue NameError
|
|
129
|
+
model = name.is_a?(Class) ? name : name.to_s.safe_constantize
|
|
130
|
+
resource = resource_declaring(model) if model
|
|
131
|
+
return resource if resource
|
|
132
|
+
|
|
92
133
|
raise MissingResource, <<~MESSAGE
|
|
93
134
|
#{name}Resource is missing. Create it by running:
|
|
94
135
|
|
|
95
|
-
bin/rails generate madmin:resource #{
|
|
136
|
+
bin/rails generate madmin:resource #{name}
|
|
96
137
|
MESSAGE
|
|
97
138
|
end
|
|
98
139
|
|
|
@@ -102,6 +143,7 @@ module Madmin
|
|
|
102
143
|
|
|
103
144
|
def reset_resources!
|
|
104
145
|
@resources = nil
|
|
146
|
+
@resources_by_model = nil
|
|
105
147
|
menu.reset
|
|
106
148
|
end
|
|
107
149
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jav_madmin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Oliver
|
|
@@ -25,20 +25,6 @@ dependencies:
|
|
|
25
25
|
- - ">="
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
27
|
version: 7.0.0
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: pagy
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - ">="
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: '3.5'
|
|
35
|
-
type: :runtime
|
|
36
|
-
prerelease: false
|
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
-
requirements:
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: '3.5'
|
|
42
28
|
- !ruby/object:Gem::Dependency
|
|
43
29
|
name: importmap-rails
|
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -109,25 +95,35 @@ files:
|
|
|
109
95
|
- app/controllers/madmin/dashboard_controller.rb
|
|
110
96
|
- app/controllers/madmin/resource_controller.rb
|
|
111
97
|
- app/helpers/madmin/application_helper.rb
|
|
98
|
+
- app/helpers/madmin/filters_helper.rb
|
|
112
99
|
- app/helpers/madmin/nav_helper.rb
|
|
113
100
|
- app/helpers/madmin/sort_helper.rb
|
|
114
101
|
- app/javascript/madmin/application.js
|
|
115
102
|
- app/javascript/madmin/controllers/application.js
|
|
103
|
+
- app/javascript/madmin/controllers/filters_controller.js
|
|
116
104
|
- app/javascript/madmin/controllers/index.js
|
|
117
105
|
- app/javascript/madmin/controllers/mobile_nav_controller.js
|
|
118
106
|
- app/javascript/madmin/controllers/nested_form_controller.js
|
|
119
107
|
- app/javascript/madmin/controllers/select_controller.js
|
|
120
108
|
- app/views/layouts/madmin/application.html.erb
|
|
109
|
+
- app/views/madmin/application/_active_filters.html.erb
|
|
110
|
+
- app/views/madmin/application/_filter.html.erb
|
|
111
|
+
- app/views/madmin/application/_filters.html.erb
|
|
121
112
|
- app/views/madmin/application/_flash.html.erb
|
|
122
113
|
- app/views/madmin/application/_form.html.erb
|
|
123
114
|
- app/views/madmin/application/_javascript.html.erb
|
|
124
115
|
- app/views/madmin/application/_missing_resource.html.erb
|
|
125
116
|
- app/views/madmin/application/_navigation.html.erb
|
|
117
|
+
- app/views/madmin/application/_pagination.html.erb
|
|
118
|
+
- app/views/madmin/application/_per_page.html.erb
|
|
126
119
|
- app/views/madmin/application/edit.html.erb
|
|
127
120
|
- app/views/madmin/application/index.html.erb
|
|
128
121
|
- app/views/madmin/application/new.html.erb
|
|
129
122
|
- app/views/madmin/application/show.html.erb
|
|
130
123
|
- app/views/madmin/dashboard/show.html.erb
|
|
124
|
+
- app/views/madmin/fields/array/_form.html.erb
|
|
125
|
+
- app/views/madmin/fields/array/_index.html.erb
|
|
126
|
+
- app/views/madmin/fields/array/_show.html.erb
|
|
131
127
|
- app/views/madmin/fields/attachment/_form.html.erb
|
|
132
128
|
- app/views/madmin/fields/attachment/_index.html.erb
|
|
133
129
|
- app/views/madmin/fields/attachment/_show.html.erb
|
|
@@ -177,6 +173,7 @@ files:
|
|
|
177
173
|
- app/views/madmin/fields/nested_has_many/_form.html.erb
|
|
178
174
|
- app/views/madmin/fields/nested_has_many/_index.html.erb
|
|
179
175
|
- app/views/madmin/fields/nested_has_many/_show.html.erb
|
|
176
|
+
- app/views/madmin/fields/nested_has_one/_form.html.erb
|
|
180
177
|
- app/views/madmin/fields/password/_form.html.erb
|
|
181
178
|
- app/views/madmin/fields/password/_index.html.erb
|
|
182
179
|
- app/views/madmin/fields/password/_show.html.erb
|
|
@@ -227,6 +224,7 @@ files:
|
|
|
227
224
|
- lib/madmin.rb
|
|
228
225
|
- lib/madmin/engine.rb
|
|
229
226
|
- lib/madmin/field.rb
|
|
227
|
+
- lib/madmin/fields/array.rb
|
|
230
228
|
- lib/madmin/fields/attachment.rb
|
|
231
229
|
- lib/madmin/fields/attachments.rb
|
|
232
230
|
- lib/madmin/fields/belongs_to.rb
|
|
@@ -243,6 +241,7 @@ files:
|
|
|
243
241
|
- lib/madmin/fields/integer.rb
|
|
244
242
|
- lib/madmin/fields/json.rb
|
|
245
243
|
- lib/madmin/fields/nested_has_many.rb
|
|
244
|
+
- lib/madmin/fields/nested_has_one.rb
|
|
246
245
|
- lib/madmin/fields/password.rb
|
|
247
246
|
- lib/madmin/fields/polymorphic.rb
|
|
248
247
|
- lib/madmin/fields/rich_text.rb
|
|
@@ -250,10 +249,13 @@ files:
|
|
|
250
249
|
- lib/madmin/fields/string.rb
|
|
251
250
|
- lib/madmin/fields/text.rb
|
|
252
251
|
- lib/madmin/fields/time.rb
|
|
252
|
+
- lib/madmin/filter.rb
|
|
253
253
|
- lib/madmin/generator_helpers.rb
|
|
254
254
|
- lib/madmin/member_action.rb
|
|
255
255
|
- lib/madmin/menu.rb
|
|
256
256
|
- lib/madmin/namespace.rb
|
|
257
|
+
- lib/madmin/page.rb
|
|
258
|
+
- lib/madmin/pagination.rb
|
|
257
259
|
- lib/madmin/resource.rb
|
|
258
260
|
- lib/madmin/resource_builder.rb
|
|
259
261
|
- lib/madmin/search.rb
|