madmin 1.0.1 → 1.2.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -1
  3. data/app/controllers/madmin/base_controller.rb +0 -5
  4. data/app/controllers/madmin/resource_controller.rb +23 -2
  5. data/app/helpers/madmin/application_helper.rb +4 -0
  6. data/app/helpers/madmin/nav_helper.rb +30 -0
  7. data/app/helpers/madmin/sort_helper.rb +32 -0
  8. data/app/views/layouts/madmin/application.html.erb +5 -5
  9. data/app/views/madmin/application/_form.html.erb +6 -8
  10. data/app/views/madmin/application/_javascript.html.erb +73 -7
  11. data/app/views/madmin/application/_navigation.html.erb +31 -5
  12. data/app/views/madmin/application/edit.html.erb +5 -1
  13. data/app/views/madmin/application/index.html.erb +34 -22
  14. data/app/views/madmin/application/new.html.erb +5 -1
  15. data/app/views/madmin/application/show.html.erb +24 -17
  16. data/app/views/madmin/fields/attachment/_form.html.erb +3 -1
  17. data/app/views/madmin/fields/attachment/_show.html.erb +7 -1
  18. data/app/views/madmin/fields/attachments/_form.html.erb +3 -1
  19. data/app/views/madmin/fields/attachments/_show.html.erb +7 -3
  20. data/app/views/madmin/fields/belongs_to/_form.html.erb +4 -2
  21. data/app/views/madmin/fields/belongs_to/_show.html.erb +1 -1
  22. data/app/views/madmin/fields/boolean/_form.html.erb +3 -1
  23. data/app/views/madmin/fields/date/_form.html.erb +3 -1
  24. data/app/views/madmin/fields/date_time/_form.html.erb +3 -1
  25. data/app/views/madmin/fields/decimal/_form.html.erb +3 -1
  26. data/app/views/madmin/fields/enum/_form.html.erb +4 -2
  27. data/app/views/madmin/fields/float/_form.html.erb +3 -1
  28. data/app/views/madmin/fields/has_many/_form.html.erb +4 -2
  29. data/app/views/madmin/fields/has_many/_show.html.erb +1 -1
  30. data/app/views/madmin/fields/has_one/_form.html.erb +3 -2
  31. data/app/views/madmin/fields/integer/_form.html.erb +3 -1
  32. data/app/views/madmin/fields/json/_form.html.erb +3 -1
  33. data/app/views/madmin/fields/nested_has_many/_fields.html.erb +18 -0
  34. data/app/views/madmin/fields/nested_has_many/_form.html.erb +32 -0
  35. data/app/views/madmin/fields/nested_has_many/_index.html.erb +1 -0
  36. data/app/views/madmin/fields/nested_has_many/_show.html.erb +5 -0
  37. data/app/views/madmin/fields/password/_form.html.erb +4 -0
  38. data/app/views/madmin/fields/password/_index.html.erb +1 -0
  39. data/app/views/madmin/fields/password/_show.html.erb +1 -0
  40. data/app/views/madmin/fields/polymorphic/_form.html.erb +3 -1
  41. data/app/views/madmin/fields/polymorphic/_show.html.erb +1 -1
  42. data/app/views/madmin/fields/rich_text/_form.html.erb +3 -1
  43. data/app/views/madmin/fields/string/_form.html.erb +3 -1
  44. data/app/views/madmin/fields/text/_form.html.erb +3 -1
  45. data/app/views/madmin/fields/time/_form.html.erb +3 -1
  46. data/app/views/madmin/shared/_label.html.erb +4 -0
  47. data/lib/generators/madmin/field/field_generator.rb +31 -0
  48. data/lib/generators/madmin/field/templates/_form.html.erb +2 -0
  49. data/lib/generators/madmin/field/templates/_index.html.erb +1 -0
  50. data/lib/generators/madmin/field/templates/_show.html.erb +1 -0
  51. data/lib/generators/madmin/field/templates/field.rb.tt +26 -0
  52. data/lib/generators/madmin/install/install_generator.rb +6 -1
  53. data/lib/generators/madmin/install/templates/routes.rb.tt +3 -0
  54. data/lib/generators/madmin/resource/resource_generator.rb +15 -4
  55. data/lib/generators/madmin/resource/templates/controller.rb.tt +6 -0
  56. data/lib/generators/madmin/resource/templates/resource.rb.tt +14 -0
  57. data/lib/generators/madmin/views/javascript_generator.rb +15 -0
  58. data/lib/generators/madmin/views/views_generator.rb +6 -5
  59. data/lib/madmin/engine.rb +1 -1
  60. data/lib/madmin/field.rb +4 -0
  61. data/lib/madmin/fields/belongs_to.rb +9 -5
  62. data/lib/madmin/fields/has_many.rb +10 -5
  63. data/lib/madmin/fields/nested_has_many.rb +40 -0
  64. data/lib/madmin/fields/password.rb +6 -0
  65. data/lib/madmin/fields/string.rb +3 -0
  66. data/lib/madmin/fields/text.rb +3 -0
  67. data/lib/madmin/generator_helpers.rb +22 -4
  68. data/lib/madmin/resource.rb +53 -19
  69. data/lib/madmin/search.rb +60 -0
  70. data/lib/madmin/version.rb +1 -1
  71. data/lib/madmin.rb +30 -14
  72. metadata +25 -5
@@ -1,3 +1,7 @@
1
- <h1><%= link_to resource.friendly_name.pluralize, resource.index_path %> / New <%= resource.friendly_name %></h1>
1
+ <h1 class="text-xl mb-4">
2
+ <%= link_to resource.friendly_name.pluralize, resource.index_path, class: "text-indigo-500" %>
3
+ /
4
+ <strong>New <%= resource.friendly_name %></strong>
5
+ </h1>
2
6
 
3
7
  <%= render partial: "form", locals: { record: @record, resource: resource } %>
@@ -1,24 +1,31 @@
1
- <div class="flex justify-between">
2
- <h1><%= link_to resource.friendly_name.pluralize, resource.index_path %> / <%= resource.model.name.singularize %> #<%= @record.id %></h1>
1
+ <div class="md:flex items-center justify-between mb-4">
2
+ <h1 class="text-xl">
3
+ <%= link_to resource.friendly_name.pluralize, resource.index_path, class: "text-indigo-500" %>
4
+ /
5
+ <%= link_to resource.display_name(@record), resource.show_path(@record), class: "text-indigo-500 font-bold" %>
6
+ </h1>
3
7
 
4
- <div class="flex px-4">
5
- <%= link_to "Edit", resource.edit_path(@record), class: "mr-2" %>
6
- <%= button_to "Delete", resource.show_path(@record), method: :delete, data: { confirm: "Are you sure?" }, class: "inline-block" %>
8
+ <div class="flex items-center px-4">
9
+ <div class="mr-2">
10
+ <%= link_to "Edit", resource.edit_path(@record), class: "block bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" %>
11
+ </div>
12
+ <%= button_to "Delete", resource.show_path(@record), method: :delete, data: { confirm: "Are you sure?" }, class: "bg-white hover:bg-gray-100 text-red-500 font-semibold py-2 px-4 border border-red-500 rounded shadow pointer-cursor" %>
7
13
  </div>
8
14
  </div>
9
15
 
10
- <% resource.attributes.each do |attribute| %>
11
- <% next if attribute[:field].nil? %>
12
- <% next unless attribute[:field].visible?(action_name) %>
13
- <% field = attribute[:field] %>
16
+ <div class="divide-y">
17
+ <% resource.attributes.values.each do |attribute| %>
18
+ <% next if attribute.field.nil? %>
19
+ <% next unless attribute.field.visible?(action_name) %>
14
20
 
15
- <div class="flex py-2">
16
- <div class="w-32 flex-shrink-0 text-gray-700 uppercase tracking-wide text-sm">
17
- <%= field.attribute_name.to_s.titleize %>
18
- </div>
21
+ <div class="px-4 py-3 md:grid md:grid-cols-4 md:gap-4 md:px-6">
22
+ <div class="text-sm font-medium text-gray-500">
23
+ <%= attribute.field.attribute_name.to_s.titleize %>
24
+ </div>
19
25
 
20
- <div>
21
- <%= render partial: field.to_partial_path("show"), locals: { field: field, record: @record } %>
26
+ <div class="md:col-span-3">
27
+ <%= render partial: attribute.field.to_partial_path("show"), locals: { field: attribute.field, record: @record } %>
28
+ </div>
22
29
  </div>
23
- </div>
24
- <% end %>
30
+ <% end %>
31
+ </div>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.file_field field.to_param %>
@@ -1,3 +1,9 @@
1
1
  <% if (attachment = field.value(record)) && attachment.attached? %>
2
- <%= link_to attachment.filename, attachment, target: :_blank %>
2
+ <% if attachment.variable? %>
3
+ <%= link_to attachment, target: :_blank do %>
4
+ <%= image_tag attachment, class: "max-h-32" %>
5
+ <% end %>
6
+ <% else %>
7
+ <%= link_to attachment.filename, attachment, target: :_blank, class: "text-indigo-500 underline" %>
8
+ <% end %>
3
9
  <% end %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.file_field field.attribute_name, multiple: true %>
@@ -1,7 +1,11 @@
1
1
  <% if (attachments = field.value(record)) && attachments.attached? %>
2
2
  <% attachments.each do |attachment| %>
3
- <div>
4
- <%= link_to attachment.filename, attachment, target: :_blank %>
5
- </div>
3
+ <% if attachment.variable? %>
4
+ <%= link_to attachment, target: :_blank do %>
5
+ <%= image_tag attachment, class: "max-h-32" %>
6
+ <% end %>
7
+ <% else %>
8
+ <%= link_to attachment.filename, attachment, target: :_blank, class: "text-indigo-500 underline" %>
9
+ <% end %>
6
10
  <% end %>
7
11
  <% end %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
- <%= form.select field.to_param, field.options_for_select(record), { prompt: true }, { class: "form-select", data: { controller: "slimselect", data: { controller: "slimselect" } } } %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
4
+ <%= form.select field.to_param, field.options_for_select(record), { prompt: true }, { class: "form-select", data: { controller: "select", select_url_value: field.index_path } } %>
@@ -1,3 +1,3 @@
1
1
  <% if (object = field.value(record)) %>
2
- <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
3
3
  <% end %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.check_box field.attribute_name, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.text_field field.attribute_name, { class: "form-select", data: { controller: "flatpickr" } } %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.text_field field.attribute_name, data: { controller: "flatpickr", flatpickr_enable_time: true } %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.number_field field.attribute_name, step: :any, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
- <%= form.select field.attribute_name, field.options_for_select(record), { prompt: true }, { class: "form-select" } %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
4
+ <%= form.select field.attribute_name, field.options_for_select(record), { prompt: true }, { class: "form-select", data: { controller: "select" } } %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.number_field field.attribute_name, step: :any, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
- <%= form.select "#{field.attribute_name.to_s.singularize}_ids", field.options_for_select(record), { prompt: true }, { multiple: true, class: "form-select", data: { controller: "slimselect" } } %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
4
+ <%= form.select "#{field.attribute_name.to_s.singularize}_ids", field.options_for_select(record), { prompt: true }, { multiple: true, class: "form-select", data: { controller: "select", select_url_value: field.index_path } } %>
@@ -1,5 +1,5 @@
1
1
  <% field.value(record).each do |object| %>
2
2
  <div>
3
- <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
3
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
4
4
  </div>
5
5
  <% end %>
@@ -1,3 +1,4 @@
1
- HAS ONE
2
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
3
4
  <%= field.value(record) %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.number_field field.attribute_name, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.text_area field.attribute_name, class: "form-input" %>
@@ -0,0 +1,18 @@
1
+ <%= content_tag :div, class: "nested-fields bg-gray-100 rounded-t-xl p-5", data: { new_record: f.object.new_record? } do %>
2
+ <% field.nested_attributes.each do |nested_attribute| %>
3
+ <% next if nested_attribute[:field].nil? %>
4
+ <% next unless nested_attribute[:field].visible?(action_name) %>
5
+ <% next unless nested_attribute[:field].visible?(:form) %>
6
+
7
+ <% nested_field = nested_attribute[:field] %>
8
+
9
+ <div class="mb-4 flex">
10
+ <%= render partial: nested_field.to_partial_path("form"), locals: { field: nested_field, record: f.object, form: f, resource: field.resource } %>
11
+ </div>
12
+ <% end %>
13
+
14
+ <small><%= link_to "Remove", "#", data: { action: "click->nested-form#remove_association" } %></small>
15
+
16
+ <%= f.hidden_field :_destroy %>
17
+
18
+ <% end %>
@@ -0,0 +1,32 @@
1
+ <div class="block md:inline-block w-32 flex-shrink-0">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
4
+
5
+ <div class="container space-y-8" data-controller="nested-form">
6
+ <template data-target="nested-form.template">
7
+
8
+ <%= form.fields_for field.attribute_name, field.to_model.new, child_index: 'NEW_RECORD' do |nested_form| %>
9
+ <%= render(
10
+ partial: field.to_partial_path('fields'),
11
+ locals: {
12
+ f: nested_form,
13
+ field: field
14
+ }
15
+ ) %>
16
+ <% end %>
17
+ </template>
18
+
19
+ <%= form.fields_for field.attribute_name do |nested_form| %>
20
+ <%= render(
21
+ partial: field.to_partial_path('fields'),
22
+ locals: {
23
+ f: nested_form,
24
+ field: field
25
+ }
26
+ ) %>
27
+ <% end %>
28
+
29
+ <%= content_tag :div, class: '', data: { target:"nested-form.links" } do %>
30
+ <%= link_to "+ Add new", "#", data: { action: "click->nested-form#add_association" } %>
31
+ <% end %>
32
+ </div>
@@ -0,0 +1 @@
1
+ <%= pluralize field.value(record).count, field.attribute_name.to_s %>
@@ -0,0 +1,5 @@
1
+ <% field.value(record).each do |object| %>
2
+ <div>
3
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
4
+ <%= form.password_field field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -1,5 +1,7 @@
1
1
  <%= form.fields_for field.attribute_name do |pf| %>
2
- <%= pf.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
3
+ <%= render "madmin/shared/label", form: pf, field: field %>
4
+ </div>
3
5
  <%= pf.select :value, field.options_for_select(record).map(&:to_global_id), { selected: field.value(record)&.to_global_id, prompt: true }, { class: "form-select", data: { controller: "slimselect" } } %>
4
6
  <%= pf.hidden_field :type, value: "polymorphic" %>
5
7
  <% end %>
@@ -1,3 +1,3 @@
1
1
  <% if (object = field.value(record)) %>
2
- <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
3
3
  <% end %>
@@ -1,4 +1,6 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <div class="flex-1">
3
5
  <%= form.rich_text_area field.attribute_name, class: "form-input block" %>
4
6
  </div>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.text_field field.attribute_name, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.text_area field.attribute_name, class: "form-input" %>
@@ -1,2 +1,4 @@
1
- <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
1
+ <div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
2
+ <%= render "madmin/shared/label", form: form, field: field %>
3
+ </div>
2
4
  <%= form.time_select field.attribute_name, {}, { class: "form-select" } %>
@@ -0,0 +1,4 @@
1
+ <%= form.label field.attribute_name %>
2
+ <% if field.required? %>
3
+ <span class="text-red-500">*</span>
4
+ <% end %>
@@ -0,0 +1,31 @@
1
+ module Madmin
2
+ module Generators
3
+ class FieldGenerator < Rails::Generators::NamedBase
4
+ include Madmin::GeneratorHelpers
5
+
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ def eager_load
9
+ Rails.application.eager_load!
10
+ end
11
+
12
+ def generate_field
13
+ template "field.rb", "app/madmin/fields/#{file_path}_field.rb"
14
+ copy_resource_template "_form"
15
+ copy_resource_template "_index"
16
+ copy_resource_template "_show"
17
+ end
18
+
19
+ private
20
+
21
+ def copy_resource_template(template_name)
22
+ template_file = "#{template_name}.html.erb"
23
+
24
+ copy_file(
25
+ template_file,
26
+ "app/views/madmin/fields/#{file_path}_field/#{template_file}"
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.text_field field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,26 @@
1
+ class <%= class_name %>Field < Madmin::Field
2
+ # def value(record)
3
+ # record.public_send(attribute_name)
4
+ # end
5
+
6
+ # def to_partial_path(name)
7
+ # unless %w[index show form].include? name
8
+ # raise ArgumentError, "`partial` must be 'index', 'show', or 'form'"
9
+ # end
10
+ #
11
+ # "/madmin/fields/#{self.class.field_type}/#{name}"
12
+ # end
13
+
14
+ # def to_param
15
+ # attribute_name
16
+ # end
17
+
18
+ # # Used for checking visibility of attribute on an view
19
+ # def visible?(action, default: true)
20
+ # options.fetch(action.to_sym, default)
21
+ # end
22
+
23
+ # def required?
24
+ # model.validators_on(attribute_name).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
25
+ # end
26
+ end
@@ -16,8 +16,13 @@ module Madmin
16
16
  end
17
17
 
18
18
  def generate_routes
19
+ if rails6_1_and_up?
20
+ route "draw :madmin", file: ROUTES_FILE[:default]
21
+ template("routes.rb.tt", "config/routes/madmin.rb")
22
+ end
23
+
19
24
  if route_namespace_exists?
20
- route "root to: \"dashboard#show\"", indentation: 4, sentinel: /namespace :madmin do\s*\n/m
25
+ route "root to: \"dashboard#show\"", indentation: separated_routes_file? ? 2 : 4, sentinel: /namespace :madmin do\s*\n/m
21
26
  else
22
27
  route "root to: \"dashboard#show\"", namespace: [:madmin]
23
28
  end
@@ -0,0 +1,3 @@
1
+ # Below are the routes for madmin
2
+ namespace :madmin do
3
+ end
@@ -20,7 +20,7 @@ module Madmin
20
20
 
21
21
  def generate_route
22
22
  if route_namespace_exists?
23
- route "resources :#{plural_name}", namespace: class_path, indentation: 4, sentinel: /namespace :madmin do\s*\n/m
23
+ route "resources :#{plural_name}", namespace: class_path, indentation: separated_routes_file? ? 2 : 4, sentinel: /namespace :madmin do\s*\n/m
24
24
  else
25
25
  route "resources :#{plural_name}", namespace: [:madmin] + class_path
26
26
  end
@@ -46,6 +46,10 @@ module Madmin
46
46
  def virtual_attributes
47
47
  virtual = []
48
48
 
49
+ # has_secure_password columns
50
+ password_attributes = model.attribute_types.keys.select { |k| k.ends_with?("_digest") }.map { |k| k.delete_suffix("_digest") }
51
+ virtual += password_attributes.map { |attr| [attr, "#{attr}_confirmation"] }.flatten
52
+
49
53
  # Add virtual attributes for ActionText and ActiveStorage
50
54
  model.reflections.each do |name, association|
51
55
  if name.starts_with?("rich_text")
@@ -63,6 +67,9 @@ module Madmin
63
67
  def redundant_attributes
64
68
  redundant = []
65
69
 
70
+ # has_secure_password columns
71
+ redundant += model.attribute_types.keys.select { |k| k.ends_with?("_digest") }
72
+
66
73
  model.reflections.each do |name, association|
67
74
  if association.has_one?
68
75
  next
@@ -98,13 +105,17 @@ module Madmin
98
105
  if %w[id created_at updated_at].include?(name)
99
106
  {form: false}
100
107
 
101
- # Attributes without a database column
102
- elsif !model.column_names.include?(name)
103
- {index: false}
108
+ # has_secure_passwords should only show on forms
109
+ elsif name.ends_with?("_confirmation") || virtual_attributes.include?("#{name}_confirmation")
110
+ {index: false, show: false}
104
111
 
105
112
  # Counter cache columns are typically not editable
106
113
  elsif name.ends_with?("_count")
107
114
  {form: false}
115
+
116
+ # Attributes without a database column
117
+ elsif !model.column_names.include?(name)
118
+ {index: false}
108
119
  end
109
120
  end
110
121
  end