madmin 3.4.0 → 3.4.1

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: 1cc585ef796e1b69307c5d7c7de6d439a863560598c48a66c3cbba7adeb9d112
4
- data.tar.gz: 13dd04b5044f612acb2b86369cd21d21b4806a358cd7b15e6f79721cb2a24514
3
+ metadata.gz: bd82191abecdc838bfce22f4ce0ee425c76bb90e4b2d7dbc84c9ef67300e87ad
4
+ data.tar.gz: 021edea5d8d473665fc7e7a8d4f7329fbf538d80bc7dbb8ba3ea501d63522888
5
5
  SHA512:
6
- metadata.gz: 66f3e4e692af87ef13f6561cffae41903789cc51b31f6355e4e4f9c322896679987133531b3bfc13f16e3a4f02ca01b6ec56cf752ba8bbb0abaae474fefdb6a6
7
- data.tar.gz: 6967d527507a21b521237f5c5810810069708fd637538b04602415f37aad157f408300fdc57d571e48c87be4058d00c839fb58decc9de6daa6170d2285429356
6
+ metadata.gz: aca73d8097279751ad80464a78b5622a0e561b0d0c092f3ad87ef1fc76aa14d00b77585e037777b2a822d756551c893045856d7140a50f388e659b9f2d6ef4b1
7
+ data.tar.gz: b2f109c4bdae4bdb28f69b84bf2881bebbbcaf70ebe33ee3b4142b280ae83df81fc3c22e0bbb3b3788d80b7c00c308bcd00b0bf38895c85bd7658cf6b16c3580
data/README.md CHANGED
@@ -73,7 +73,7 @@ class AuditLogResource < Madmin::Resource
73
73
  end
74
74
  ```
75
75
 
76
- The new, edit, and delete links are hidden for read-only resources, and any write actions redirect back to the index.
76
+ The new, edit, and delete links are hidden for read-only resources, and any write actions redirect back to the referring page. An attachment belongs to its record, so writes to it are refused when either resource is read-only.
77
77
 
78
78
  ### Large Tables
79
79
 
@@ -147,7 +147,9 @@ module Madmin
147
147
  helper_method :filters
148
148
 
149
149
  def enforce_readonly
150
- redirect_to resource.index_path, alert: t("madmin.flash.readonly", name: resource.friendly_name) if resource.readonly?
150
+ if resource.readonly_for?(@record)
151
+ redirect_back_or_to resource.index_path, alert: t("madmin.flash.readonly", name: resource.friendly_name), status: :see_other
152
+ end
151
153
  end
152
154
 
153
155
  ActiveSupport.run_load_hooks(:madmin_resource_controller, self)
@@ -1,7 +1,7 @@
1
- <% if (attachment = field.value(record)) && attachment.attached? %>
2
- <% if attachment.variable? %>
3
- <%= image_tag main_app.url_for(attachment), class: "max-h-8" %>
1
+ <% if (attached = field.value(record)) && attached.attached? %>
2
+ <% if attached.variable? %>
3
+ <%= image_tag main_app.url_for(attached), class: "max-h-8" %>
4
4
  <% else %>
5
- <%= attachment.filename %>
5
+ <%= attached.filename %>
6
6
  <% end %>
7
7
  <% end %>
@@ -1,11 +1,11 @@
1
- <% if (attachment = field.value(record)) && attachment.attached? %>
2
- <% if attachment.variable? %>
3
- <%= image_tag main_app.url_for(attachment), class: "max-h-32" %>
1
+ <% if (attached = field.value(record)) && attached.attached? %>
2
+ <% if attached.variable? %>
3
+ <%= image_tag main_app.url_for(attached), class: "max-h-32" %>
4
4
  <% else %>
5
- <%= link_to attachment.filename, main_app.url_for(attachment), target: :_blank, class: "text-blue-500 underline" %>
5
+ <%= link_to attached.filename, main_app.url_for(attached), target: :_blank, class: "text-blue-500 underline" %>
6
6
  <% end %>
7
7
 
8
- <% if (remove_path = field.remove_path(attachment)) %>
9
- <%= link_to t("madmin.actions.remove"), remove_path, data: { turbo_method: :delete, turbo_confirm: t("madmin.confirmations.remove_with_changes", name: attachment.filename.to_s) } %>
8
+ <% if (remove_path = field.remove_path(attached)) %>
9
+ <%= link_to t("madmin.actions.remove"), remove_path, data: { turbo_method: :delete, turbo_confirm: t("madmin.confirmations.remove_with_changes", name: attached.filename.to_s) } %>
10
10
  <% end %>
11
11
  <% end %>
@@ -3,11 +3,13 @@
3
3
  module Madmin
4
4
  module Fields
5
5
  class Attachment < Field
6
- # Path for removing the attachment, or nil when the attachment resource
7
- # or its destroy route has been removed from the app
8
- def remove_path(attachment)
9
- resource = Madmin.resource_for(attachment)
10
- resource.show_path(attachment) if resource.route?(:destroy)
6
+ # Path for removing the attachment, or nil when it can't be removed
7
+ def remove_path(attached)
8
+ attachment_resource = Madmin.resource_for(attached)
9
+
10
+ if attachment_resource.route?(:destroy) && !attachment_resource.readonly_for?(attached.attachment)
11
+ attachment_resource.show_path(attached)
12
+ end
11
13
  rescue MissingResource
12
14
  end
13
15
  end
@@ -169,6 +169,13 @@ module Madmin
169
169
  false
170
170
  end
171
171
 
172
+ # Whether a write to `record` through this resource is refused. Attachments
173
+ # defer to the resource of the record they belong to, and that check lives
174
+ # here because ActiveStorage::AttachmentResource is generated into the host app
175
+ def readonly_for?(record)
176
+ readonly? || (record.is_a?(::ActiveStorage::Attachment) && Madmin.resource_for(record.record).readonly?)
177
+ end
178
+
172
179
  # Override to return true for tables too large to count. Index and has many
173
180
  # pages then page with Previous and Next links and no page numbers or total
174
181
  def countless?
@@ -271,29 +278,30 @@ module Madmin
271
278
  }[type]
272
279
  end
273
280
 
281
+ # Plain ActiveModel classes have no columns or associations to ask, so their unknown attributes default to a String field
274
282
  def infer_type(name)
275
283
  name_string = name.to_s
276
284
 
277
- if model.attribute_types.include?(name_string)
278
- column_type = model.attribute_types[name_string]
285
+ if model_attribute_types.include?(name_string)
286
+ column_type = model_attribute_types[name_string]
279
287
  if column_type.is_a? ::ActiveRecord::Enum::EnumType
280
288
  :enum
281
- elsif model.columns_hash[name_string].try(:array?)
289
+ elsif model_column(name_string).try(:array?)
282
290
  :array
283
291
  else
284
292
  column_type.type || :string
285
293
  end
286
- elsif (association = model.reflect_on_association(name))
294
+ elsif (association = model.try(:reflect_on_association, name))
287
295
  type_for_association(association)
288
- elsif model.reflect_on_association(:"rich_text_#{name_string}")
296
+ elsif model.try(:reflect_on_association, :"rich_text_#{name_string}")
289
297
  :rich_text
290
- elsif model.reflect_on_association(:"#{name_string}_attachment")
298
+ elsif model.try(:reflect_on_association, :"#{name_string}_attachment")
291
299
  :attachment
292
- elsif model.reflect_on_association(:"#{name_string}_attachments")
300
+ elsif model.try(:reflect_on_association, :"#{name_string}_attachments")
293
301
  :attachments
294
302
 
295
303
  # has_secure_password
296
- elsif model.attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
304
+ elsif model_attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
297
305
  :password
298
306
 
299
307
  # ActiveRecord Store
@@ -370,6 +378,14 @@ module Madmin
370
378
 
371
379
  private
372
380
 
381
+ def model_attribute_types
382
+ model.try(:attribute_types) || {}
383
+ end
384
+
385
+ def model_column(name)
386
+ model.columns_hash[name] if model.respond_to?(:columns_hash)
387
+ end
388
+
373
389
  def translated_name(count: 1)
374
390
  model.model_name.human(count: count, default: "").presence
375
391
  end
data/lib/madmin/search.rb CHANGED
@@ -13,7 +13,10 @@ module Madmin
13
13
  @filters = filters
14
14
  end
15
15
 
16
+ # Search and filters are SQL, so collections without a table pass through for `scoped_resources` to search
16
17
  def run
18
+ return @scoped_resource unless @scoped_resource.respond_to?(:table_name)
19
+
17
20
  results = query.blank? ? @scoped_resource.all : search_results(@scoped_resource)
18
21
  filters.reduce(results) { |scope, filter| filter.apply(scope) }
19
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Madmin
4
- VERSION = "3.4.0"
4
+ VERSION = "3.4.1"
5
5
  end
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: 3.4.0
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver