madmin 2.4.0 → 2.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bfdf6827cb1ef98872c55b9c786c08d9e9f8def47a2a9fa8bc5a3552c3bbee8
4
- data.tar.gz: b4c73bdb4cfebfc209e7edce32d926c0e32ef9a291c8404c755665e2bbdc62f3
3
+ metadata.gz: fd0df17707eadc918a0379fa955748a67f70255e1875befe53aa4837c3ae0bb1
4
+ data.tar.gz: ee70de4f5cbf5789e2325545352e45afb53006f7cde1c63601a132d8283f8179
5
5
  SHA512:
6
- metadata.gz: 4d973242c54c9f3da6f0fbf8110b8c14b221d1d63841c1056d2e0310a4464869f638c7e20dad217a9d5f014853258fb482b40e84642462afeeda7a39af0477f0
7
- data.tar.gz: 349dc39b717ce028990db3935de771396b0d6a62f877997b37231447d9fed6163bf57651245a9b5bb085c3edb37f8cf3c28e748ea546c3c45ab59da6e68241d2
6
+ metadata.gz: 898e0a9b8da25e3af1b08bf90525d488e441a3d7b09141f8528e3e2af9473098500492871ce3d330ac31702ee2b7b25f1b1e22aa9210efe6d2842f652040229a
7
+ data.tar.gz: 6347a3efb59bdd6a87c529580a4936833b9296d326a000c214813ee7aed24a158e13ac12f226da4d44e0fe1c6edcc6535fa34d2c493d546717c37dbcbdf9b551
data/README.md CHANGED
@@ -172,6 +172,16 @@ class PostResource < Madmin::Resource
172
172
  end
173
173
  ```
174
174
 
175
+ Pass `collection: true` to also render the action on the **index** page, in each row next to the built-in "View" and "Edit" links:
176
+
177
+ ```ruby
178
+ class PostResource < Madmin::Resource
179
+ member_action collection: true do |record|
180
+ link_to "Publish", publish_admin_post_path(record), class: "btn btn-secondary"
181
+ end
182
+ end
183
+ ```
184
+
175
185
  ### Collection Actions
176
186
 
177
187
  `collection_action` is the index-page counterpart to `member_action`. Blocks are rendered in the index header's `.actions` div, immediately before the built-in "New \<Resource\>" link.
@@ -192,6 +202,35 @@ class PostResource < Madmin::Resource
192
202
  end
193
203
  ```
194
204
 
205
+ ## Extending Madmin
206
+
207
+ Madmin runs `ActiveSupport` load hooks on its core classes so you can extend them from an initializer without reopening or monkey patching them. This is the recommended way for engines and gems to add behavior to Madmin.
208
+
209
+ | Hook | Base | Use it for |
210
+ | --- | --- | --- |
211
+ | `:madmin_resource` | `Madmin::Resource` | Adding to the resource DSL |
212
+ | `:madmin_field` | `Madmin::Field` | Shared behavior across every field type |
213
+ | `:madmin_search` | `Madmin::Search` | Customizing how the search query is built |
214
+ | `:madmin_base_controller` | `Madmin::BaseController` | Layouts, helpers, `rescue_from`, authentication |
215
+ | `:madmin_resource_controller` | `Madmin::ResourceController` | CRUD callbacks, scoping records, audit logging |
216
+
217
+ Blocks are `class_eval`-ed on the base class, so `self` is the class itself:
218
+
219
+ ```ruby
220
+ # config/initializers/madmin.rb
221
+ ActiveSupport.on_load(:madmin_resource) do
222
+ # self == Madmin::Resource, so `extend` adds class-level DSL to every resource
223
+ extend MyAdmin::ResourceExtensions
224
+ end
225
+
226
+ ActiveSupport.on_load(:madmin_base_controller) do
227
+ # self == Madmin::BaseController
228
+ rescue_from Pundit::NotAuthorizedError, with: :admin_not_authorized
229
+ end
230
+ ```
231
+
232
+ Hooks registered after a class has already loaded run immediately, so ordering in your initializers doesn't matter. The controllers live in the engine's `app/` directory and are reloadable, which means their hooks re-run on every reload in development — keep the blocks idempotent.
233
+
195
234
  ## Authentication
196
235
 
197
236
  You can use a couple of strategies to authenticate users who are trying to
@@ -9,5 +9,7 @@ module Madmin
9
9
  end
10
10
 
11
11
  protect_from_forgery with: :exception
12
+
13
+ ActiveSupport.run_load_hooks(:madmin_base_controller, self)
12
14
  end
13
15
  end
@@ -101,5 +101,7 @@ module Madmin
101
101
  def search_term
102
102
  @search_term ||= params[:q].to_s.strip
103
103
  end
104
+
105
+ ActiveSupport.run_load_hooks(:madmin_resource_controller, self)
104
106
  end
105
107
  end
@@ -61,6 +61,10 @@
61
61
  <td>
62
62
  <%= link_to t("madmin.actions.view"), resource.show_path(record) %>
63
63
  <%= link_to t("madmin.actions.edit"), resource.edit_path(record) %>
64
+
65
+ <% resource.collection_member_actions.each do |action| %>
66
+ <%= instance_exec(record, &action) %>
67
+ <% end %>
64
68
  </td>
65
69
  </tr>
66
70
  <% end %>
@@ -13,6 +13,7 @@ class <%= class_name %>Resource < Madmin::Resource
13
13
  # scope :published
14
14
 
15
15
  # Add actions to the resource's show page
16
+ # Pass collection: true to also render it in each row on the index page
16
17
  # member_action do |record|
17
18
  # link_to "Do Something", some_path
18
19
  # end
data/lib/madmin/field.rb CHANGED
@@ -61,5 +61,7 @@ module Madmin
61
61
  def paginateable?
62
62
  false
63
63
  end
64
+
65
+ ActiveSupport.run_load_hooks(:madmin_field, self)
64
66
  end
65
67
  end
@@ -0,0 +1,19 @@
1
+ module Madmin
2
+ # Wraps a member action block along with its options so views can decide
3
+ # where to render it. Responds to `to_proc` and `call` so it can be used
4
+ # anywhere the raw block was.
5
+ class MemberAction
6
+ attr_reader :block
7
+
8
+ def initialize(collection: false, &block)
9
+ @collection = collection
10
+ @block = block
11
+ end
12
+
13
+ def collection? = @collection
14
+
15
+ def call(*args, &blk) = block.call(*args, &blk)
16
+
17
+ def to_proc = block
18
+ end
19
+ end
@@ -11,7 +11,7 @@ module Madmin
11
11
  class << self
12
12
  def inherited(base)
13
13
  base.attributes = attributes.dup
14
- base.member_actions = scopes.dup
14
+ base.member_actions = member_actions.dup
15
15
  base.collection_actions = collection_actions.dup
16
16
  base.scopes = scopes.dup
17
17
  super
@@ -134,8 +134,13 @@ module Madmin
134
134
  attributes.values.select { |a| a.field.searchable? }
135
135
  end
136
136
 
137
- def member_action(&block)
138
- member_actions << block
137
+ def member_action(collection: false, &block)
138
+ member_actions << MemberAction.new(collection: collection, &block)
139
+ end
140
+
141
+ # Member actions that should also render in each row on the index page
142
+ def collection_member_actions
143
+ member_actions.select { |action| action.respond_to?(:collection?) && action.collection? }
139
144
  end
140
145
 
141
146
  def collection_action(&block)
@@ -267,5 +272,7 @@ module Madmin
267
272
  @menu_options.with_defaults(label: friendly_name.pluralize, url: index_path)
268
273
  end
269
274
  end
275
+
276
+ ActiveSupport.run_load_hooks(:madmin_resource, self)
270
277
  end
271
278
  end
data/lib/madmin/search.rb CHANGED
@@ -56,5 +56,7 @@ module Madmin
56
56
  def column_to_query(attr)
57
57
  ::ActiveRecord::Base.connection.quote_column_name(attr)
58
58
  end
59
+
60
+ ActiveSupport.run_load_hooks(:madmin_search, self)
59
61
  end
60
62
  end
@@ -1,3 +1,3 @@
1
1
  module Madmin
2
- VERSION = "2.4.0"
2
+ VERSION = "2.5.0"
3
3
  end
data/lib/madmin.rb CHANGED
@@ -7,6 +7,7 @@ require "pagy"
7
7
  module Madmin
8
8
  autoload :Field, "madmin/field"
9
9
  autoload :GeneratorHelpers, "madmin/generator_helpers"
10
+ autoload :MemberAction, "madmin/member_action"
10
11
  autoload :Menu, "madmin/menu"
11
12
  autoload :Resource, "madmin/resource"
12
13
  autoload :ResourceBuilder, "madmin/resource_builder"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: madmin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
@@ -247,6 +247,7 @@ files:
247
247
  - lib/madmin/fields/text.rb
248
248
  - lib/madmin/fields/time.rb
249
249
  - lib/madmin/generator_helpers.rb
250
+ - lib/madmin/member_action.rb
250
251
  - lib/madmin/menu.rb
251
252
  - lib/madmin/namespace.rb
252
253
  - lib/madmin/resource.rb