madmin 2.3.3 → 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 +4 -4
- data/README.md +73 -0
- data/app/controllers/madmin/base_controller.rb +2 -0
- data/app/controllers/madmin/resource_controller.rb +2 -0
- data/app/views/layouts/madmin/application.html.erb +2 -2
- data/app/views/madmin/application/_form.html.erb +2 -2
- data/app/views/madmin/application/_missing_resource.html.erb +2 -2
- data/app/views/madmin/application/_navigation.html.erb +2 -2
- data/app/views/madmin/application/edit.html.erb +2 -2
- data/app/views/madmin/application/index.html.erb +13 -5
- data/app/views/madmin/application/new.html.erb +2 -2
- data/app/views/madmin/application/show.html.erb +2 -2
- data/app/views/madmin/dashboard/show.html.erb +2 -2
- data/app/views/madmin/fields/attachment/_form.html.erb +1 -1
- data/app/views/madmin/fields/attachment/_show.html.erb +1 -1
- data/app/views/madmin/fields/attachments/_index.html.erb +1 -1
- data/app/views/madmin/fields/nested_has_many/_fields.html.erb +1 -1
- data/app/views/madmin/fields/nested_has_many/_form.html.erb +1 -1
- data/config/locales/en.yml +40 -0
- data/config/locales/fr.yml +40 -0
- data/lib/generators/madmin/resource/templates/resource.rb.tt +6 -0
- data/lib/madmin/engine.rb +0 -2
- data/lib/madmin/field.rb +2 -0
- data/lib/madmin/member_action.rb +19 -0
- data/lib/madmin/resource.rb +16 -3
- data/lib/madmin/search.rb +2 -0
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin.rb +1 -1
- metadata +5 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd0df17707eadc918a0379fa955748a67f70255e1875befe53aa4837c3ae0bb1
|
|
4
|
+
data.tar.gz: ee70de4f5cbf5789e2325545352e45afb53006f7cde1c63601a132d8283f8179
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 898e0a9b8da25e3af1b08bf90525d488e441a3d7b09141f8528e3e2af9473098500492871ce3d330ac31702ee2b7b25f1b1e22aa9210efe6d2842f652040229a
|
|
7
|
+
data.tar.gz: 6347a3efb59bdd6a87c529580a4936833b9296d326a000c214813ee7aed24a158e13ac12f226da4d44e0fe1c6edcc6535fa34d2c493d546717c37dbcbdf9b551
|
data/README.md
CHANGED
|
@@ -158,6 +158,79 @@ class PostResource < Madmin::Resource
|
|
|
158
158
|
end
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
+
## Actions
|
|
162
|
+
|
|
163
|
+
### Member Actions
|
|
164
|
+
|
|
165
|
+
`member_action` lets you add custom buttons to a resource's **show** page. Each block receives the current `record` and is rendered in the header's `.actions` div:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
class PostResource < Madmin::Resource
|
|
169
|
+
member_action do |record|
|
|
170
|
+
link_to "Publish", publish_admin_post_path(record), class: "btn btn-secondary"
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
```
|
|
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
|
+
|
|
185
|
+
### Collection Actions
|
|
186
|
+
|
|
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.
|
|
188
|
+
|
|
189
|
+
Unlike `member_action`, blocks receive **no** arguments. Each block is `instance_exec`-ed on the index view context, so `link_to`, route helpers, `policy`, `current_user`, `params`, `resource`, and `@records` are all available. Multiple blocks render in registration order.
|
|
190
|
+
|
|
191
|
+
Each block is responsible for its own authorization gating — if a button should be hidden for some users, guard it inside the block.
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
class PostResource < Madmin::Resource
|
|
195
|
+
collection_action do
|
|
196
|
+
link_to "Bulk Import", bulk_import_admin_posts_path, class: "btn btn-secondary"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
collection_action do
|
|
200
|
+
link_to "Export CSV", export_admin_posts_path(format: :csv), class: "btn btn-secondary"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
```
|
|
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
|
+
|
|
161
234
|
## Authentication
|
|
162
235
|
|
|
163
236
|
You can use a couple of strategies to authenticate users who are trying to
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<% if content_for? :title %>
|
|
9
9
|
<%= yield(:title) %> -
|
|
10
10
|
<% end %>
|
|
11
|
-
<%= Madmin.site_name %>
|
|
11
|
+
<%= Madmin.site_name %> <%= t("madmin.layout.admin_suffix") %>
|
|
12
12
|
</title>
|
|
13
13
|
<%= csrf_meta_tags %>
|
|
14
14
|
<%= render "javascript" %>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</header>
|
|
20
20
|
<header id="navbar">
|
|
21
21
|
<div class="nav-group">
|
|
22
|
-
<button id="hamburger-menu" type="button" data-action="click->mobile-nav#toggle" aria-label="
|
|
22
|
+
<button id="hamburger-menu" type="button" data-action="click->mobile-nav#toggle" aria-label="<%= t("madmin.layout.open_menu") %>" aria-expanded="false" aria-controls="sidebar">
|
|
23
23
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5"> <path fill-rule="evenodd" d="M2 4.75A.75.75 0 0 1 2.75 4h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 4.75ZM2 10a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 10Zm0 5.25a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1-.75-.75Z" clip-rule="evenodd" /> </svg>
|
|
24
24
|
</button>
|
|
25
25
|
<%= link_to Madmin.site_name, try(:root_url) || madmin_root_url, data: {turbo: false} %>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%= form_with model: [:madmin, record], url: (record.persisted? ? resource.show_path(record) : resource.index_path), local: true do |form| %>
|
|
2
2
|
<% if form.object.errors.any? %>
|
|
3
3
|
<div class="alert alert-danger">
|
|
4
|
-
<div class=""
|
|
4
|
+
<div class=""><%= t("madmin.form.errors", count: form.object.errors.full_messages.count) %>:</div>
|
|
5
5
|
|
|
6
6
|
<ul>
|
|
7
7
|
<% form.object.errors.full_messages.each do |message| %>
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
<% end %>
|
|
21
21
|
|
|
22
22
|
<%= form.submit class: "btn btn-primary" %>
|
|
23
|
-
<%= link_to "
|
|
23
|
+
<%= link_to t("madmin.actions.cancel"), (record.persisted? ? resource.show_path(record) : resource.index_path), class: "btn" %>
|
|
24
24
|
<% end %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<div class="error"><%=
|
|
1
|
+
<div class="error"><%= t("madmin.missing_resource.message", resource: resource_name) %></div>
|
|
2
2
|
<% if Rails.env.development? %>
|
|
3
|
-
<div
|
|
3
|
+
<div><%= t("madmin.missing_resource.create_hint") %>
|
|
4
4
|
<code>
|
|
5
5
|
bin/rails generate madmin:resource <%= resource_name.split("Resource").first %>
|
|
6
6
|
</code>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<nav>
|
|
2
|
-
<%= nav_link_to "
|
|
2
|
+
<%= nav_link_to t("madmin.navigation.dashboard"), madmin_root_path %>
|
|
3
3
|
|
|
4
4
|
<% Madmin.menu.render do |item| %>
|
|
5
5
|
<% if item.url %>
|
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
<footer>
|
|
18
18
|
<%= link_to "https://github.com/excid3/madmin", target: :_blank do %>
|
|
19
19
|
<svg viewBox="0 0 16 16" height="1rem" width="1rem" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
|
|
20
|
-
|
|
20
|
+
<%= t("madmin.navigation.github") %>
|
|
21
21
|
<% end %>
|
|
22
22
|
</footer>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<%= content_for :title, "
|
|
1
|
+
<%= content_for :title, t("madmin.titles.edit", name: resource.display_name(@record)) %>
|
|
2
2
|
|
|
3
3
|
<header class="header">
|
|
4
4
|
<h1>
|
|
5
5
|
<%= link_to resource.friendly_name.pluralize, resource.index_path %>
|
|
6
6
|
/
|
|
7
|
-
<strong
|
|
7
|
+
<strong><%= t("madmin.actions.edit") %> <%= link_to resource.display_name(@record), resource.show_path(@record) %></strong>
|
|
8
8
|
</h1>
|
|
9
9
|
</header>
|
|
10
10
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<div class="actions">
|
|
7
7
|
<form class="search">
|
|
8
8
|
<%= hidden_field_tag :page, params[:page], value: 1 %>
|
|
9
|
-
<%= search_field_tag :q, params[:q], placeholder: "
|
|
9
|
+
<%= search_field_tag :q, params[:q], placeholder: t("madmin.search.placeholder") %>
|
|
10
10
|
</form>
|
|
11
11
|
|
|
12
12
|
<%= link_to clear_search_params, class: "btn btn-secondary" do %>
|
|
@@ -15,15 +15,19 @@
|
|
|
15
15
|
</svg>
|
|
16
16
|
<% end if params[:q].present? %>
|
|
17
17
|
|
|
18
|
+
<% resource.collection_actions.each do |action| %>
|
|
19
|
+
<%= instance_exec(&action) %>
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
18
22
|
<%= link_to resource.new_path, class: "btn btn-secondary" do %>
|
|
19
|
-
|
|
23
|
+
<%= t("madmin.actions.new") %> <%= tag.span resource.friendly_name, class: "hidden md:inline-block" %>
|
|
20
24
|
<% end %>
|
|
21
25
|
</div>
|
|
22
26
|
</header>
|
|
23
27
|
|
|
24
28
|
<nav class="scopes">
|
|
25
29
|
<% if resource.scopes.any? %>
|
|
26
|
-
<%= link_to "
|
|
30
|
+
<%= link_to t("madmin.actions.all"), resource.index_path, class: class_names("btn btn-secondary", {"active" => params[:scope].blank?}) %>
|
|
27
31
|
<% end %>
|
|
28
32
|
|
|
29
33
|
<% resource.scopes.each do |scope| %>
|
|
@@ -55,8 +59,12 @@
|
|
|
55
59
|
<% end %>
|
|
56
60
|
|
|
57
61
|
<td>
|
|
58
|
-
<%= link_to "
|
|
59
|
-
<%= link_to "
|
|
62
|
+
<%= link_to t("madmin.actions.view"), resource.show_path(record) %>
|
|
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 %>
|
|
60
68
|
</td>
|
|
61
69
|
</tr>
|
|
62
70
|
<% end %>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<%= content_for :title, "
|
|
1
|
+
<%= content_for :title, t("madmin.titles.new", name: resource.friendly_name) %>
|
|
2
2
|
|
|
3
3
|
<header class="header">
|
|
4
4
|
<h1>
|
|
5
5
|
<%= link_to resource.friendly_name.pluralize, resource.index_path %>
|
|
6
6
|
/
|
|
7
|
-
<strong
|
|
7
|
+
<strong><%= t("madmin.titles.new", name: resource.friendly_name) %></strong>
|
|
8
8
|
</h1>
|
|
9
9
|
</header>
|
|
10
10
|
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
<% resource.member_actions.each do |action| %>
|
|
12
12
|
<%= instance_exec(@record, &action) %>
|
|
13
13
|
<% end %>
|
|
14
|
-
<%= link_to "
|
|
15
|
-
<%= button_to "
|
|
14
|
+
<%= link_to t("madmin.actions.edit"), resource.edit_path(@record), class: "btn btn-secondary" %>
|
|
15
|
+
<%= button_to t("madmin.actions.delete"), resource.show_path(@record), method: :delete, data: { turbo_confirm: t("madmin.confirmations.delete") }, class: "btn btn-danger" %>
|
|
16
16
|
</div>
|
|
17
17
|
</header>
|
|
18
18
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<h1
|
|
2
|
-
<p
|
|
1
|
+
<h1><%= t("madmin.dashboard.title") %></h1>
|
|
2
|
+
<p><%= t("madmin.dashboard.hint_html") %></p>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<%= render partial: field.to_partial_path("show"), locals: {field: field, record: record} %>
|
|
6
6
|
|
|
7
7
|
<% if (value = field.value(record) && value&.attached?) %>
|
|
8
|
-
<%= link_to "
|
|
8
|
+
<%= link_to t("madmin.actions.remove"), Madmin.resource_for(value).show_path(value), data: { turbo_method: :delete, turbo_confirm: t("madmin.confirmations.remove_with_changes")} %>
|
|
9
9
|
<% end %>
|
|
10
10
|
</div>
|
|
11
11
|
<% end %>
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
<%= link_to attachment.filename, main_app.url_for(attachment), target: :_blank, class: "text-blue-500 underline" %>
|
|
6
6
|
<% end %>
|
|
7
7
|
|
|
8
|
-
<%= link_to "
|
|
8
|
+
<%= link_to t("madmin.actions.remove"), Madmin.resource_for(attachment).show_path(attachment), data: { turbo_method: :delete, turbo_confirm: t("madmin.confirmations.remove_with_changes")} %>
|
|
9
9
|
<% end %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%=
|
|
1
|
+
<%= t("madmin.fields.attachment", count: field.value(record).count) %>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
<% end %>
|
|
13
13
|
|
|
14
|
-
<small><%= link_to "
|
|
14
|
+
<small><%= link_to t("madmin.actions.remove"), "#", data: { action: "click->nested-form#remove_association" } %></small>
|
|
15
15
|
|
|
16
16
|
<%= f.hidden_field :_destroy %>
|
|
17
17
|
<% end %>
|
|
@@ -23,6 +23,6 @@
|
|
|
23
23
|
<% end %>
|
|
24
24
|
|
|
25
25
|
<%= content_tag :div, class: '', data: { target:"nested-form.links" } do %>
|
|
26
|
-
<%= link_to "
|
|
26
|
+
<%= link_to t("madmin.nested_form.add_new"), "#", data: { action: "click->nested-form#add_association" } %>
|
|
27
27
|
<% end %>
|
|
28
28
|
</div>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
en:
|
|
2
|
+
madmin:
|
|
3
|
+
layout:
|
|
4
|
+
open_menu: Open menu
|
|
5
|
+
admin_suffix: Admin
|
|
6
|
+
navigation:
|
|
7
|
+
dashboard: Dashboard
|
|
8
|
+
github: Madmin on GitHub
|
|
9
|
+
dashboard:
|
|
10
|
+
title: Madmin Dashboard
|
|
11
|
+
hint_html: Create <code>app/views/madmin/dashboard/show.html.erb</code> to customize your dashboard.
|
|
12
|
+
actions:
|
|
13
|
+
all: All
|
|
14
|
+
view: View
|
|
15
|
+
edit: Edit
|
|
16
|
+
delete: Delete
|
|
17
|
+
new: New
|
|
18
|
+
remove: Remove
|
|
19
|
+
cancel: Cancel
|
|
20
|
+
search:
|
|
21
|
+
placeholder: Search
|
|
22
|
+
titles:
|
|
23
|
+
new: New %{name}
|
|
24
|
+
edit: Edit %{name}
|
|
25
|
+
form:
|
|
26
|
+
errors:
|
|
27
|
+
one: There was 1 error with your submission
|
|
28
|
+
other: There were %{count} errors with your submission
|
|
29
|
+
confirmations:
|
|
30
|
+
delete: Are you sure?
|
|
31
|
+
remove_with_changes: Are you sure? You will lose any other changes.
|
|
32
|
+
nested_form:
|
|
33
|
+
add_new: "+ Add new"
|
|
34
|
+
fields:
|
|
35
|
+
attachment:
|
|
36
|
+
one: "%{count} attachment"
|
|
37
|
+
other: "%{count} attachments"
|
|
38
|
+
missing_resource:
|
|
39
|
+
message: "%{resource} is missing."
|
|
40
|
+
create_hint: "Create it by running:"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
fr:
|
|
2
|
+
madmin:
|
|
3
|
+
layout:
|
|
4
|
+
open_menu: Ouvrir le menu
|
|
5
|
+
admin_suffix: Administration
|
|
6
|
+
navigation:
|
|
7
|
+
dashboard: Tableau de bord
|
|
8
|
+
github: Madmin sur GitHub
|
|
9
|
+
dashboard:
|
|
10
|
+
title: Tableau de bord Madmin
|
|
11
|
+
hint_html: Créez <code>app/views/madmin/dashboard/show.html.erb</code> pour personnaliser votre tableau de bord.
|
|
12
|
+
actions:
|
|
13
|
+
all: Tous
|
|
14
|
+
view: Voir
|
|
15
|
+
edit: Modifier
|
|
16
|
+
delete: Supprimer
|
|
17
|
+
new: Nouveau
|
|
18
|
+
remove: Retirer
|
|
19
|
+
cancel: Annuler
|
|
20
|
+
search:
|
|
21
|
+
placeholder: Rechercher
|
|
22
|
+
titles:
|
|
23
|
+
new: Nouveau %{name}
|
|
24
|
+
edit: Modifier %{name}
|
|
25
|
+
form:
|
|
26
|
+
errors:
|
|
27
|
+
one: Il y a eu 1 erreur dans votre soumission
|
|
28
|
+
other: Il y a eu %{count} erreurs dans votre soumission
|
|
29
|
+
confirmations:
|
|
30
|
+
delete: Êtes-vous sûr ?
|
|
31
|
+
remove_with_changes: Êtes-vous sûr ? Vous perdrez toutes les autres modifications.
|
|
32
|
+
nested_form:
|
|
33
|
+
add_new: "+ Ajouter"
|
|
34
|
+
fields:
|
|
35
|
+
attachment:
|
|
36
|
+
one: "%{count} pièce jointe"
|
|
37
|
+
other: "%{count} pièces jointes"
|
|
38
|
+
missing_resource:
|
|
39
|
+
message: "%{resource} est introuvable."
|
|
40
|
+
create_hint: "Pour le créer, exécutez :"
|
|
@@ -13,10 +13,16 @@ 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
|
|
19
20
|
|
|
21
|
+
# Add actions to the resource's index page
|
|
22
|
+
# collection_action do
|
|
23
|
+
# link_to "Bulk Import", bulk_import_path, class: "btn btn-secondary"
|
|
24
|
+
# end
|
|
25
|
+
|
|
20
26
|
# Customize the display name of records in the admin area.
|
|
21
27
|
# def self.display_name(record) = record.name
|
|
22
28
|
|
data/lib/madmin/engine.rb
CHANGED
data/lib/madmin/field.rb
CHANGED
|
@@ -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
|
data/lib/madmin/resource.rb
CHANGED
|
@@ -4,13 +4,15 @@ module Madmin
|
|
|
4
4
|
|
|
5
5
|
class_attribute :attributes, default: ActiveSupport::OrderedHash.new
|
|
6
6
|
class_attribute :member_actions, default: []
|
|
7
|
+
class_attribute :collection_actions, default: []
|
|
7
8
|
class_attribute :scopes, default: []
|
|
8
9
|
class_attribute :menu_options, instance_reader: false
|
|
9
10
|
|
|
10
11
|
class << self
|
|
11
12
|
def inherited(base)
|
|
12
13
|
base.attributes = attributes.dup
|
|
13
|
-
base.member_actions =
|
|
14
|
+
base.member_actions = member_actions.dup
|
|
15
|
+
base.collection_actions = collection_actions.dup
|
|
14
16
|
base.scopes = scopes.dup
|
|
15
17
|
super
|
|
16
18
|
end
|
|
@@ -132,8 +134,17 @@ module Madmin
|
|
|
132
134
|
attributes.values.select { |a| a.field.searchable? }
|
|
133
135
|
end
|
|
134
136
|
|
|
135
|
-
def member_action(&block)
|
|
136
|
-
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? }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def collection_action(&block)
|
|
147
|
+
collection_actions << block
|
|
137
148
|
end
|
|
138
149
|
|
|
139
150
|
def field_for_type(type)
|
|
@@ -261,5 +272,7 @@ module Madmin
|
|
|
261
272
|
@menu_options.with_defaults(label: friendly_name.pluralize, url: index_path)
|
|
262
273
|
end
|
|
263
274
|
end
|
|
275
|
+
|
|
276
|
+
ActiveSupport.run_load_hooks(:madmin_resource, self)
|
|
264
277
|
end
|
|
265
278
|
end
|
data/lib/madmin/search.rb
CHANGED
data/lib/madmin/version.rb
CHANGED
data/lib/madmin.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require "madmin/engine"
|
|
2
|
-
|
|
3
2
|
require "importmap-rails"
|
|
4
3
|
require "stimulus-rails"
|
|
5
4
|
require "turbo-rails"
|
|
@@ -8,6 +7,7 @@ require "pagy"
|
|
|
8
7
|
module Madmin
|
|
9
8
|
autoload :Field, "madmin/field"
|
|
10
9
|
autoload :GeneratorHelpers, "madmin/generator_helpers"
|
|
10
|
+
autoload :MemberAction, "madmin/member_action"
|
|
11
11
|
autoload :Menu, "madmin/menu"
|
|
12
12
|
autoload :Resource, "madmin/resource"
|
|
13
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
|
+
version: 2.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Oliver
|
|
@@ -38,20 +38,6 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '3.5'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: propshaft
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
41
|
- !ruby/object:Gem::Dependency
|
|
56
42
|
name: importmap-rails
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -212,6 +198,8 @@ files:
|
|
|
212
198
|
- app/views/madmin/fields/time/_show.html.erb
|
|
213
199
|
- app/views/madmin/shared/_label.html.erb
|
|
214
200
|
- config/importmap.rb
|
|
201
|
+
- config/locales/en.yml
|
|
202
|
+
- config/locales/fr.yml
|
|
215
203
|
- lib/generators/madmin/field/field_generator.rb
|
|
216
204
|
- lib/generators/madmin/field/templates/_form.html.erb
|
|
217
205
|
- lib/generators/madmin/field/templates/_index.html.erb
|
|
@@ -259,6 +247,7 @@ files:
|
|
|
259
247
|
- lib/madmin/fields/text.rb
|
|
260
248
|
- lib/madmin/fields/time.rb
|
|
261
249
|
- lib/madmin/generator_helpers.rb
|
|
250
|
+
- lib/madmin/member_action.rb
|
|
262
251
|
- lib/madmin/menu.rb
|
|
263
252
|
- lib/madmin/namespace.rb
|
|
264
253
|
- lib/madmin/resource.rb
|
|
@@ -285,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
285
274
|
- !ruby/object:Gem::Version
|
|
286
275
|
version: '0'
|
|
287
276
|
requirements: []
|
|
288
|
-
rubygems_version: 4.0.
|
|
277
|
+
rubygems_version: 4.0.18
|
|
289
278
|
specification_version: 4
|
|
290
279
|
summary: A modern admin for Ruby on Rails apps
|
|
291
280
|
test_files: []
|