madmin 1.2.10 → 2.0.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/madmin_manifest.js +3 -0
  3. data/app/assets/stylesheets/madmin/actiontext.css +31 -0
  4. data/app/assets/stylesheets/madmin/application.css +88 -0
  5. data/app/assets/stylesheets/madmin/buttons.css +46 -0
  6. data/app/assets/stylesheets/madmin/forms.css +82 -0
  7. data/app/assets/stylesheets/madmin/pagination.css +59 -0
  8. data/app/assets/stylesheets/madmin/reset.css +242 -0
  9. data/app/assets/stylesheets/madmin/sidebar.css +80 -0
  10. data/app/assets/stylesheets/madmin/tables.css +56 -0
  11. data/app/controllers/madmin/application_controller.rb +7 -12
  12. data/app/controllers/madmin/base_controller.rb +1 -0
  13. data/app/helpers/madmin/application_helper.rb +1 -12
  14. data/app/helpers/madmin/sort_helper.rb +17 -1
  15. data/app/javascript/madmin/application.js +4 -0
  16. data/app/javascript/madmin/controllers/application.js +12 -0
  17. data/app/javascript/madmin/controllers/index.js +5 -0
  18. data/app/javascript/madmin/controllers/nested_form_controller.js +34 -0
  19. data/app/javascript/madmin/controllers/select_controller.js +32 -0
  20. data/app/views/layouts/madmin/application.html.erb +11 -13
  21. data/app/views/madmin/application/_form.html.erb +13 -12
  22. data/app/views/madmin/application/_javascript.html.erb +3 -136
  23. data/app/views/madmin/application/_navigation.html.erb +22 -27
  24. data/app/views/madmin/application/edit.html.erb +9 -5
  25. data/app/views/madmin/application/index.html.erb +37 -31
  26. data/app/views/madmin/application/new.html.erb +9 -5
  27. data/app/views/madmin/application/show.html.erb +28 -22
  28. data/app/views/madmin/dashboard/show.html.erb +4 -1
  29. data/app/views/madmin/fields/attachment/_form.html.erb +11 -4
  30. data/app/views/madmin/fields/attachment/_index.html.erb +5 -1
  31. data/app/views/madmin/fields/attachment/_show.html.erb +4 -4
  32. data/app/views/madmin/fields/attachments/_form.html.erb +1 -4
  33. data/app/views/madmin/fields/belongs_to/_form.html.erb +1 -4
  34. data/app/views/madmin/fields/belongs_to/_index.html.erb +2 -1
  35. data/app/views/madmin/fields/boolean/_form.html.erb +3 -4
  36. data/app/views/madmin/fields/currency/_form.html.erb +1 -0
  37. data/app/views/madmin/fields/currency/_index.html.erb +1 -0
  38. data/app/views/madmin/fields/currency/_show.html.erb +1 -0
  39. data/app/views/madmin/fields/date/_form.html.erb +1 -4
  40. data/app/views/madmin/fields/date_time/_form.html.erb +1 -4
  41. data/app/views/madmin/fields/decimal/_form.html.erb +0 -3
  42. data/app/views/madmin/fields/enum/_form.html.erb +1 -4
  43. data/app/views/madmin/fields/file/_form.html.erb +0 -3
  44. data/app/views/madmin/fields/float/_form.html.erb +0 -3
  45. data/app/views/madmin/fields/has_many/_form.html.erb +1 -4
  46. data/app/views/madmin/fields/has_one/_form.html.erb +0 -3
  47. data/app/views/madmin/fields/integer/_form.html.erb +0 -3
  48. data/app/views/madmin/fields/integer/_index.html.erb +1 -5
  49. data/app/views/madmin/fields/json/_form.html.erb +0 -3
  50. data/app/views/madmin/fields/nested_has_many/_fields.html.erb +4 -5
  51. data/app/views/madmin/fields/nested_has_many/_form.html.erb +0 -4
  52. data/app/views/madmin/fields/password/_form.html.erb +0 -3
  53. data/app/views/madmin/fields/polymorphic/_form.html.erb +1 -4
  54. data/app/views/madmin/fields/rich_text/_form.html.erb +1 -6
  55. data/app/views/madmin/fields/select/_form.html.erb +1 -0
  56. data/app/views/madmin/fields/select/_index.html.erb +1 -0
  57. data/app/views/madmin/fields/select/_show.html.erb +1 -0
  58. data/app/views/madmin/fields/string/_form.html.erb +1 -4
  59. data/app/views/madmin/fields/text/_form.html.erb +0 -3
  60. data/app/views/madmin/shared/_label.html.erb +2 -2
  61. data/config/importmap.rb +10 -0
  62. data/lib/generators/madmin/field/templates/_form.html.erb +0 -3
  63. data/lib/generators/madmin/install/templates/controller.rb.tt +5 -12
  64. data/lib/generators/madmin/resource/templates/resource.rb.tt +12 -10
  65. data/lib/madmin/engine.rb +20 -0
  66. data/lib/madmin/field.rb +17 -5
  67. data/lib/madmin/fields/belongs_to.rb +10 -5
  68. data/lib/madmin/fields/currency.rb +15 -0
  69. data/lib/madmin/fields/polymorphic.rb +1 -1
  70. data/lib/madmin/fields/select.rb +9 -0
  71. data/lib/madmin/menu.rb +70 -0
  72. data/lib/madmin/resource.rb +56 -24
  73. data/lib/madmin/search.rb +1 -1
  74. data/lib/madmin/version.rb +1 -1
  75. data/lib/madmin.rb +22 -1
  76. metadata +61 -13
  77. data/app/assets/config/manifest.js +0 -2
  78. data/app/assets/stylesheets/actiontext.scss +0 -36
  79. data/app/assets/stylesheets/application.css +0 -15
  80. data/app/views/madmin/application/_menu_resources.html.erb +0 -7
@@ -1,10 +1,11 @@
1
- require "ostruct"
2
-
3
1
  module Madmin
4
2
  class Resource
3
+ Attribute = Data.define(:name, :type, :field)
4
+
5
5
  class_attribute :attributes, default: ActiveSupport::OrderedHash.new
6
6
  class_attribute :member_actions, default: []
7
7
  class_attribute :scopes, default: []
8
+ class_attribute :menu_options, instance_reader: false
8
9
 
9
10
  class << self
10
11
  def inherited(base)
@@ -14,12 +15,17 @@ module Madmin
14
15
  super
15
16
  end
16
17
 
17
- def model
18
- @model ||= model_name.constantize
18
+ def model(value = nil)
19
+ if value
20
+ @model = value
21
+ else
22
+ @model ||= model_name.constantize
23
+ end
19
24
  end
20
25
 
21
26
  def model_find(id)
22
- friendly_model? ? model.friendly.find(id) : model.find(id)
27
+ record = friendly_model? ? model.friendly.find(id) : model.find(id)
28
+ becomes(record)
23
29
  end
24
30
 
25
31
  def model_name
@@ -36,26 +42,36 @@ module Madmin
36
42
 
37
43
  def attribute(name, type = nil, **options)
38
44
  type ||= infer_type(name)
39
- field = options[:field] || field_for_type(type)
45
+ field = options.delete(:field) || field_for_type(type)
40
46
 
41
- attributes[name] = OpenStruct.new(
42
- name: name,
43
- type: type,
44
- field: field.new(**options.merge(attribute_name: name, model: model, resource: self))
45
- )
46
- rescue => e
47
- builder = ResourceBuilder.new(model)
48
- raise ArgumentError, <<~MESSAGE
49
- Madmin couldn't find attribute or association '#{name}' on #{model} model.
47
+ if field.nil?
48
+ Rails.logger.warn <<~MESSAGE
49
+ WARNING: Madmin could not infer a field type for `#{name}` attribute. Defaulting to a String type.
50
+ You can set the type by specifying the type on the attribute:
51
+
52
+ attribute :#{name}, :boolean
53
+ MESSAGE
54
+ field = Fields::String
55
+ end
56
+
57
+ config = ActiveSupport::OrderedOptions.new.merge(options)
58
+ yield config if block_given?
50
59
 
51
- We searched these attributes and associations:
52
- #{(builder.attributes + builder.associations).join(", ")}
60
+ # Form is an alias for new & edit
61
+ if config.has_key?(:form)
62
+ config.new = config[:form]
63
+ config.edit = config[:form]
64
+ end
53
65
 
54
- This attribute is defined in a Madmin resource at:
55
- #{e.backtrace.find { |l| l =~ /_resource.rb/ }}
66
+ # New/create and edit/update need to match
67
+ config.create = config[:create] if config.has_key?(:new)
68
+ config.update = config[:update] if config.has_key?(:edit)
56
69
 
57
- Either add the missing attribute or assocation, or remove this line from your Madmin resource.
58
- MESSAGE
70
+ attributes[name] = Attribute.new(
71
+ name: name,
72
+ type: type,
73
+ field: field.new(attribute_name: name, model: model, resource: self, options: config)
74
+ )
59
75
  end
60
76
 
61
77
  def friendly_name
@@ -81,11 +97,15 @@ module Madmin
81
97
  end
82
98
 
83
99
  def show_path(record)
84
- url_helpers.polymorphic_path([:madmin, route_namespace, record])
100
+ url_helpers.polymorphic_path([:madmin, route_namespace, becomes(record)])
85
101
  end
86
102
 
87
103
  def edit_path(record)
88
- url_helpers.polymorphic_path([:madmin, route_namespace, record], action: :edit)
104
+ url_helpers.polymorphic_path([:madmin, route_namespace, becomes(record)], action: :edit)
105
+ end
106
+
107
+ def becomes(record)
108
+ record.instance_of?(model) ? record : record.becomes(model)
89
109
  end
90
110
 
91
111
  def param_key
@@ -121,6 +141,7 @@ module Madmin
121
141
  binary: Fields::String,
122
142
  blob: Fields::Text,
123
143
  boolean: Fields::Boolean,
144
+ currency: Fields::Currency,
124
145
  date: Fields::Date,
125
146
  datetime: Fields::DateTime,
126
147
  decimal: Fields::Decimal,
@@ -131,6 +152,7 @@ module Madmin
131
152
  json: Fields::Json,
132
153
  jsonb: Fields::Json,
133
154
  primary_key: Fields::String,
155
+ select: Fields::Select,
134
156
  string: Fields::String,
135
157
  text: Fields::Text,
136
158
  time: Fields::Time,
@@ -176,7 +198,7 @@ module Madmin
176
198
  has_one: Fields::HasOne,
177
199
  rich_text: Fields::RichText,
178
200
  nested_has_many: Fields::NestedHasMany
179
- }.fetch(type)
201
+ }[type]
180
202
  end
181
203
 
182
204
  def infer_type(name)
@@ -228,6 +250,16 @@ module Madmin
228
250
  store_accessors = model.stored_attributes.values
229
251
  store_accessors.flatten
230
252
  end
253
+
254
+ def menu(options)
255
+ @menu_options = options
256
+ end
257
+
258
+ def menu_options
259
+ return false if @menu_options == false
260
+ @menu_options ||= {}
261
+ @menu_options.with_defaults(label: friendly_name.pluralize, url: index_path)
262
+ end
231
263
  end
232
264
  end
233
265
  end
data/lib/madmin/search.rb CHANGED
@@ -35,7 +35,7 @@ module Madmin
35
35
  end
36
36
 
37
37
  def searchable_fields(attr)
38
- [attr[:name]]
38
+ [attr.name]
39
39
  end
40
40
 
41
41
  def query_values
@@ -1,3 +1,3 @@
1
1
  module Madmin
2
- VERSION = "1.2.10"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/madmin.rb CHANGED
@@ -5,6 +5,7 @@ require "pagy"
5
5
  module Madmin
6
6
  autoload :Field, "madmin/field"
7
7
  autoload :GeneratorHelpers, "madmin/generator_helpers"
8
+ autoload :Menu, "madmin/menu"
8
9
  autoload :Resource, "madmin/resource"
9
10
  autoload :ResourceBuilder, "madmin/resource_builder"
10
11
  autoload :Search, "madmin/search"
@@ -14,6 +15,7 @@ module Madmin
14
15
  autoload :Attachments, "madmin/fields/attachments"
15
16
  autoload :BelongsTo, "madmin/fields/belongs_to"
16
17
  autoload :Boolean, "madmin/fields/boolean"
18
+ autoload :Currency, "madmin/fields/currency"
17
19
  autoload :Date, "madmin/fields/date"
18
20
  autoload :DateTime, "madmin/fields/date_time"
19
21
  autoload :Decimal, "madmin/fields/decimal"
@@ -28,14 +30,32 @@ module Madmin
28
30
  autoload :Password, "madmin/fields/password"
29
31
  autoload :Polymorphic, "madmin/fields/polymorphic"
30
32
  autoload :RichText, "madmin/fields/rich_text"
33
+ autoload :Select, "madmin/fields/select"
31
34
  autoload :String, "madmin/fields/string"
32
35
  autoload :Text, "madmin/fields/text"
33
36
  autoload :Time, "madmin/fields/time"
34
37
  end
35
38
 
39
+ mattr_accessor :importmap, default: Importmap::Map.new
40
+ mattr_accessor :menu, default: Menu.new
41
+ mattr_accessor :site_name
42
+
36
43
  class << self
37
44
  def resource_for(object)
38
- "#{object.class.name}Resource".constantize
45
+ if object.is_a? ::ActiveStorage::Attached
46
+ "ActiveStorage::AttachmentResource".constantize
47
+ else
48
+ begin
49
+ "#{object.class.name}Resource".constantize
50
+ rescue
51
+ # For STI models, see if there's a superclass resource available
52
+ if (column = object.class.inheritance_column) && object.class.column_names.include?(column)
53
+ "#{object.class.superclass.base_class.name}Resource".constantize
54
+ else
55
+ raise
56
+ end
57
+ end
58
+ end
39
59
  end
40
60
 
41
61
  def resource_by_name(name)
@@ -48,6 +68,7 @@ module Madmin
48
68
 
49
69
  def reset_resources!
50
70
  @resources = nil
71
+ menu.reset
51
72
  end
52
73
 
53
74
  def resource_names
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: madmin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.10
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
8
  - Andrea Fomera
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-05-02 00:00:00.000000000 Z
12
+ date: 2024-11-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 6.0.3
20
+ version: 7.0.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 6.0.3
27
+ version: 7.0.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: pagy
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -39,6 +39,34 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '3.5'
42
+ - !ruby/object:Gem::Dependency
43
+ name: importmap-rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: propshaft
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
42
70
  description: It's an admin, obviously.
43
71
  email:
44
72
  - excid3@gmail.com
@@ -50,9 +78,15 @@ files:
50
78
  - MIT-LICENSE
51
79
  - README.md
52
80
  - Rakefile
53
- - app/assets/config/manifest.js
54
- - app/assets/stylesheets/actiontext.scss
55
- - app/assets/stylesheets/application.css
81
+ - app/assets/config/madmin_manifest.js
82
+ - app/assets/stylesheets/madmin/actiontext.css
83
+ - app/assets/stylesheets/madmin/application.css
84
+ - app/assets/stylesheets/madmin/buttons.css
85
+ - app/assets/stylesheets/madmin/forms.css
86
+ - app/assets/stylesheets/madmin/pagination.css
87
+ - app/assets/stylesheets/madmin/reset.css
88
+ - app/assets/stylesheets/madmin/sidebar.css
89
+ - app/assets/stylesheets/madmin/tables.css
56
90
  - app/controllers/madmin/application_controller.rb
57
91
  - app/controllers/madmin/base_controller.rb
58
92
  - app/controllers/madmin/dashboard_controller.rb
@@ -60,10 +94,14 @@ files:
60
94
  - app/helpers/madmin/application_helper.rb
61
95
  - app/helpers/madmin/nav_helper.rb
62
96
  - app/helpers/madmin/sort_helper.rb
97
+ - app/javascript/madmin/application.js
98
+ - app/javascript/madmin/controllers/application.js
99
+ - app/javascript/madmin/controllers/index.js
100
+ - app/javascript/madmin/controllers/nested_form_controller.js
101
+ - app/javascript/madmin/controllers/select_controller.js
63
102
  - app/views/layouts/madmin/application.html.erb
64
103
  - app/views/madmin/application/_form.html.erb
65
104
  - app/views/madmin/application/_javascript.html.erb
66
- - app/views/madmin/application/_menu_resources.html.erb
67
105
  - app/views/madmin/application/_navigation.html.erb
68
106
  - app/views/madmin/application/edit.html.erb
69
107
  - app/views/madmin/application/index.html.erb
@@ -82,6 +120,9 @@ files:
82
120
  - app/views/madmin/fields/boolean/_form.html.erb
83
121
  - app/views/madmin/fields/boolean/_index.html.erb
84
122
  - app/views/madmin/fields/boolean/_show.html.erb
123
+ - app/views/madmin/fields/currency/_form.html.erb
124
+ - app/views/madmin/fields/currency/_index.html.erb
125
+ - app/views/madmin/fields/currency/_show.html.erb
85
126
  - app/views/madmin/fields/date/_form.html.erb
86
127
  - app/views/madmin/fields/date/_index.html.erb
87
128
  - app/views/madmin/fields/date/_show.html.erb
@@ -125,6 +166,9 @@ files:
125
166
  - app/views/madmin/fields/rich_text/_form.html.erb
126
167
  - app/views/madmin/fields/rich_text/_index.html.erb
127
168
  - app/views/madmin/fields/rich_text/_show.html.erb
169
+ - app/views/madmin/fields/select/_form.html.erb
170
+ - app/views/madmin/fields/select/_index.html.erb
171
+ - app/views/madmin/fields/select/_show.html.erb
128
172
  - app/views/madmin/fields/string/_form.html.erb
129
173
  - app/views/madmin/fields/string/_index.html.erb
130
174
  - app/views/madmin/fields/string/_show.html.erb
@@ -135,6 +179,7 @@ files:
135
179
  - app/views/madmin/fields/time/_index.html.erb
136
180
  - app/views/madmin/fields/time/_show.html.erb
137
181
  - app/views/madmin/shared/_label.html.erb
182
+ - config/importmap.rb
138
183
  - lib/generators/madmin/field/field_generator.rb
139
184
  - lib/generators/madmin/field/templates/_form.html.erb
140
185
  - lib/generators/madmin/field/templates/_index.html.erb
@@ -162,6 +207,7 @@ files:
162
207
  - lib/madmin/fields/attachments.rb
163
208
  - lib/madmin/fields/belongs_to.rb
164
209
  - lib/madmin/fields/boolean.rb
210
+ - lib/madmin/fields/currency.rb
165
211
  - lib/madmin/fields/date.rb
166
212
  - lib/madmin/fields/date_time.rb
167
213
  - lib/madmin/fields/decimal.rb
@@ -176,10 +222,12 @@ files:
176
222
  - lib/madmin/fields/password.rb
177
223
  - lib/madmin/fields/polymorphic.rb
178
224
  - lib/madmin/fields/rich_text.rb
225
+ - lib/madmin/fields/select.rb
179
226
  - lib/madmin/fields/string.rb
180
227
  - lib/madmin/fields/text.rb
181
228
  - lib/madmin/fields/time.rb
182
229
  - lib/madmin/generator_helpers.rb
230
+ - lib/madmin/menu.rb
183
231
  - lib/madmin/namespace.rb
184
232
  - lib/madmin/resource.rb
185
233
  - lib/madmin/resource_builder.rb
@@ -191,7 +239,7 @@ homepage: https://github.com/excid3/madmin
191
239
  licenses:
192
240
  - MIT
193
241
  metadata: {}
194
- post_install_message:
242
+ post_install_message:
195
243
  rdoc_options: []
196
244
  require_paths:
197
245
  - lib
@@ -199,15 +247,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
199
247
  requirements:
200
248
  - - ">="
201
249
  - !ruby/object:Gem::Version
202
- version: 2.5.0
250
+ version: 3.2.0
203
251
  required_rubygems_version: !ruby/object:Gem::Requirement
204
252
  requirements:
205
253
  - - ">="
206
254
  - !ruby/object:Gem::Version
207
255
  version: '0'
208
256
  requirements: []
209
- rubygems_version: 3.5.9
210
- signing_key:
257
+ rubygems_version: 3.5.23
258
+ signing_key:
211
259
  specification_version: 4
212
260
  summary: A modern admin for Ruby on Rails apps
213
261
  test_files: []
@@ -1,2 +0,0 @@
1
- //= link_tree ../images
2
- //= link_directory ../stylesheets .css
@@ -1,36 +0,0 @@
1
- //
2
- // Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
3
- // the trix-editor content (whether displayed or under editing). Feel free to incorporate this
4
- // inclusion directly in any other asset bundle and remove this file.
5
- //
6
- //= require trix/dist/trix
7
-
8
- // We need to override trix.css’s image gallery styles to accommodate the
9
- // <action-text-attachment> element we wrap around attachments. Otherwise,
10
- // images in galleries will be squished by the max-width: 33%; rule.
11
- .trix-content {
12
- .attachment-gallery {
13
- > action-text-attachment,
14
- > .attachment {
15
- flex: 1 0 33%;
16
- padding: 0 0.5em;
17
- max-width: 33%;
18
- }
19
-
20
- &.attachment-gallery--2,
21
- &.attachment-gallery--4 {
22
- > action-text-attachment,
23
- > .attachment {
24
- flex-basis: 50%;
25
- max-width: 50%;
26
- }
27
- }
28
- }
29
-
30
- action-text-attachment {
31
- .attachment {
32
- padding: 0 !important;
33
- max-width: 100% !important;
34
- }
35
- }
36
- }
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
6
- * vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,7 +0,0 @@
1
- <% Madmin.resources.each do |resource| %>
2
- <%= nav_link_to resource.friendly_name.pluralize, resource.index_path, class: "block p-2 rounded hover:bg-gray-100", starts_with: resource.index_path, active_class: "font-bold text-black" %>
3
- <% end %>
4
-
5
- <div class="mt-auto">
6
- <%= link_to "View Madmin on GitHub", "https://github.com/excid3/madmin", target: :_blank, class: "block p-2 rounded text-gray-500 hover:bg-gray-100" %>
7
- </div>