madmin 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +7 -82
  4. data/Rakefile +1 -6
  5. data/app/assets/config/manifest.js +2 -0
  6. data/app/assets/stylesheets/actiontext.scss +36 -0
  7. data/app/assets/stylesheets/{madmin/application.css → application.css} +2 -9
  8. data/app/controllers/madmin/application_controller.rb +6 -10
  9. data/app/controllers/madmin/dashboard_controller.rb +1 -3
  10. data/app/controllers/madmin/resource_controller.rb +72 -0
  11. data/app/helpers/madmin/application_helper.rb +1 -11
  12. data/app/views/layouts/madmin/application.html.erb +25 -26
  13. data/app/views/madmin/application/_form.html.erb +25 -0
  14. data/app/views/madmin/application/_navigation.html.erb +6 -0
  15. data/app/views/madmin/application/edit.html.erb +3 -0
  16. data/app/views/madmin/application/index.html.erb +35 -0
  17. data/app/views/madmin/application/new.html.erb +3 -0
  18. data/app/views/madmin/application/show.html.erb +24 -0
  19. data/app/views/madmin/dashboard/show.html.erb +1 -0
  20. data/app/views/madmin/fields/attachment/_form.html.erb +2 -0
  21. data/app/views/madmin/fields/attachment/_index.html.erb +3 -0
  22. data/app/views/madmin/fields/attachment/_show.html.erb +3 -0
  23. data/app/views/madmin/fields/attachments/_form.html.erb +2 -0
  24. data/app/views/madmin/fields/attachments/_index.html.erb +1 -0
  25. data/app/views/madmin/fields/attachments/_show.html.erb +7 -0
  26. data/app/views/madmin/fields/belongs_to/_form.html.erb +2 -14
  27. data/app/views/madmin/fields/belongs_to/_index.html.erb +2 -7
  28. data/app/views/madmin/fields/belongs_to/_show.html.erb +2 -8
  29. data/app/views/madmin/fields/boolean/_form.html.erb +2 -0
  30. data/app/views/madmin/fields/boolean/_index.html.erb +1 -0
  31. data/app/views/madmin/fields/boolean/_show.html.erb +1 -0
  32. data/app/views/madmin/fields/date/_form.html.erb +2 -0
  33. data/app/views/madmin/fields/date/_index.html.erb +1 -0
  34. data/app/views/madmin/fields/date/_show.html.erb +1 -0
  35. data/app/views/madmin/fields/date_time/_form.html.erb +2 -0
  36. data/app/views/madmin/fields/date_time/_index.html.erb +1 -0
  37. data/app/views/madmin/fields/date_time/_show.html.erb +1 -0
  38. data/app/views/madmin/fields/enum/_form.html.erb +3 -0
  39. data/app/views/madmin/fields/enum/_index.html.erb +1 -0
  40. data/app/views/madmin/fields/enum/_show.html.erb +1 -0
  41. data/app/views/madmin/fields/float/_form.html.erb +2 -0
  42. data/app/views/madmin/fields/float/_index.html.erb +1 -0
  43. data/app/views/madmin/fields/float/_show.html.erb +1 -0
  44. data/app/views/madmin/fields/has_many/_form.html.erb +2 -0
  45. data/app/views/madmin/fields/has_many/_index.html.erb +1 -0
  46. data/app/views/madmin/fields/has_many/_show.html.erb +4 -14
  47. data/app/views/madmin/fields/has_one/_form.html.erb +3 -0
  48. data/app/views/madmin/fields/has_one/_index.html.erb +3 -0
  49. data/app/views/madmin/fields/has_one/_show.html.erb +3 -12
  50. data/app/views/madmin/fields/integer/_form.html.erb +2 -0
  51. data/app/views/madmin/fields/integer/_index.html.erb +1 -0
  52. data/app/views/madmin/fields/integer/_show.html.erb +1 -0
  53. data/app/views/madmin/fields/json/_form.html.erb +2 -0
  54. data/app/views/madmin/fields/json/_index.html.erb +1 -0
  55. data/app/views/madmin/fields/json/_show.html.erb +1 -0
  56. data/app/views/madmin/fields/polymorphic/_form.html.erb +5 -32
  57. data/app/views/madmin/fields/polymorphic/_index.html.erb +3 -1
  58. data/app/views/madmin/fields/polymorphic/_show.html.erb +3 -14
  59. data/app/views/madmin/fields/rich_text/_form.html.erb +4 -0
  60. data/app/views/madmin/fields/rich_text/_index.html.erb +1 -0
  61. data/app/views/madmin/fields/rich_text/_show.html.erb +3 -0
  62. data/app/views/madmin/fields/string/_form.html.erb +2 -0
  63. data/app/views/madmin/fields/string/_index.html.erb +1 -0
  64. data/app/views/madmin/fields/string/_show.html.erb +1 -0
  65. data/app/views/madmin/fields/text/_form.html.erb +2 -4
  66. data/app/views/madmin/fields/text/_index.html.erb +1 -1
  67. data/app/views/madmin/fields/text/_show.html.erb +1 -8
  68. data/app/views/madmin/fields/time/_form.html.erb +2 -0
  69. data/app/views/madmin/fields/time/_index.html.erb +1 -0
  70. data/app/views/madmin/fields/time/_show.html.erb +1 -0
  71. data/lib/generators/madmin/install/install_generator.rb +24 -12
  72. data/lib/generators/madmin/resource/resource_generator.rb +83 -47
  73. data/lib/generators/madmin/resource/templates/controller.rb.tt +4 -0
  74. data/lib/generators/madmin/resource/templates/resource.rb.tt +11 -0
  75. data/lib/madmin.rb +33 -23
  76. data/lib/madmin/engine.rb +5 -2
  77. data/lib/madmin/field.rb +18 -47
  78. data/lib/madmin/fields/attachment.rb +6 -0
  79. data/lib/madmin/fields/attachments.rb +9 -0
  80. data/lib/madmin/fields/belongs_to.rb +18 -0
  81. data/lib/madmin/fields/boolean.rb +6 -0
  82. data/lib/madmin/fields/date.rb +6 -0
  83. data/lib/madmin/fields/date_time.rb +6 -0
  84. data/lib/madmin/fields/enum.rb +6 -0
  85. data/lib/madmin/fields/float.rb +6 -0
  86. data/lib/madmin/fields/has_many.rb +18 -0
  87. data/lib/madmin/fields/has_one.rb +6 -0
  88. data/lib/madmin/fields/integer.rb +6 -0
  89. data/lib/madmin/fields/json.rb +6 -0
  90. data/lib/madmin/fields/polymorphic.rb +17 -0
  91. data/lib/madmin/fields/rich_text.rb +6 -0
  92. data/lib/madmin/fields/string.rb +6 -0
  93. data/lib/madmin/fields/text.rb +6 -0
  94. data/lib/madmin/fields/time.rb +6 -0
  95. data/lib/madmin/generator_helpers.rb +24 -0
  96. data/lib/madmin/resource.rb +125 -0
  97. data/lib/madmin/version.rb +1 -1
  98. data/lib/tasks/madmin_tasks.rake +7 -0
  99. metadata +90 -97
  100. data/app/assets/config/madmin_manifest.js +0 -2
  101. data/app/assets/javascripts/madmin/application.js +0 -15
  102. data/app/assets/javascripts/madmin/dashboard.js +0 -2
  103. data/app/assets/javascripts/madmin/resources.js +0 -36
  104. data/app/assets/stylesheets/madmin/dashboard.css +0 -4
  105. data/app/assets/stylesheets/madmin/resources.css +0 -4
  106. data/app/controllers/madmin/base_controller.rb +0 -16
  107. data/app/controllers/madmin/resources_controller.rb +0 -97
  108. data/app/decorators/madmin/resource_decorator.rb +0 -16
  109. data/app/helpers/madmin/fields/polymorphic_helper.rb +0 -25
  110. data/app/jobs/madmin/application_job.rb +0 -4
  111. data/app/mailers/madmin/application_mailer.rb +0 -6
  112. data/app/models/madmin/application_record.rb +0 -5
  113. data/app/views/application/_navigation.html.erb +0 -17
  114. data/app/views/madmin/dashboard/index.html.erb +0 -6
  115. data/app/views/madmin/fields/check_box/_form.html.erb +0 -4
  116. data/app/views/madmin/fields/check_box/_index.html.erb +0 -1
  117. data/app/views/madmin/fields/check_box/_show.html.erb +0 -8
  118. data/app/views/madmin/fields/email/_form.html.erb +0 -4
  119. data/app/views/madmin/fields/email/_index.html.erb +0 -1
  120. data/app/views/madmin/fields/email/_show.html.erb +0 -8
  121. data/app/views/madmin/fields/number/_form.html.erb +0 -4
  122. data/app/views/madmin/fields/number/_index.html.erb +0 -1
  123. data/app/views/madmin/fields/number/_show.html.erb +0 -8
  124. data/app/views/madmin/fields/password/_form.html.erb +0 -4
  125. data/app/views/madmin/fields/password/_index.html.erb +0 -1
  126. data/app/views/madmin/fields/password/_show.html.erb +0 -8
  127. data/app/views/madmin/fields/select/_form.html.erb +0 -4
  128. data/app/views/madmin/fields/select/_index.html.erb +0 -1
  129. data/app/views/madmin/fields/select/_show.html.erb +0 -8
  130. data/app/views/madmin/fields/text_area/_form.html.erb +0 -4
  131. data/app/views/madmin/fields/text_area/_index.html.erb +0 -1
  132. data/app/views/madmin/fields/text_area/_show.html.erb +0 -8
  133. data/app/views/madmin/resources/_form.html.erb +0 -15
  134. data/app/views/madmin/resources/_scopes.html.erb +0 -10
  135. data/app/views/madmin/resources/edit.html.erb +0 -2
  136. data/app/views/madmin/resources/index.html.erb +0 -13
  137. data/app/views/madmin/resources/index/_content.html.erb +0 -33
  138. data/app/views/madmin/resources/new.html.erb +0 -2
  139. data/app/views/madmin/resources/show.html.erb +0 -10
  140. data/config/routes.rb +0 -11
  141. data/lib/generators/madmin/controller/USAGE +0 -8
  142. data/lib/generators/madmin/controller/controller_generator.rb +0 -10
  143. data/lib/generators/madmin/page/USAGE +0 -8
  144. data/lib/generators/madmin/page/page_generator.rb +0 -20
  145. data/lib/generators/madmin/page/templates/template.html.erb +0 -2
  146. data/lib/generators/madmin/page/templates/template.rb.erb +0 -10
  147. data/lib/generators/madmin/resource/templates/resource.rb.erb +0 -11
  148. data/lib/generators/madmin/views/views_generator.rb +0 -15
  149. data/lib/madmin/field/associatable.rb +0 -58
  150. data/lib/madmin/field/belongs_to.rb +0 -9
  151. data/lib/madmin/field/check_box.rb +0 -8
  152. data/lib/madmin/field/date_time.rb +0 -8
  153. data/lib/madmin/field/email.rb +0 -8
  154. data/lib/madmin/field/has_many.rb +0 -9
  155. data/lib/madmin/field/has_one.rb +0 -9
  156. data/lib/madmin/field/number.rb +0 -8
  157. data/lib/madmin/field/password.rb +0 -8
  158. data/lib/madmin/field/polymorphic.rb +0 -57
  159. data/lib/madmin/field/select.rb +0 -13
  160. data/lib/madmin/field/text.rb +0 -8
  161. data/lib/madmin/field/text_area.rb +0 -8
  162. data/lib/madmin/resourceable.rb +0 -72
  163. data/lib/madmin/resourceable/class_methods.rb +0 -152
  164. data/lib/madmin/resources.rb +0 -13
@@ -0,0 +1,3 @@
1
+ <h1><%= link_to resource.friendly_name.pluralize, resource.index_path %> / New <%= resource.friendly_name %></h1>
2
+
3
+ <%= render partial: "form", locals: { record: @record, resource: resource } %>
@@ -0,0 +1,24 @@
1
+ <div class="flex justify-between">
2
+ <h1><%= link_to resource.friendly_name.pluralize, resource.index_path %> / <%= resource.model.name.singularize %> #<%= @record.id %></h1>
3
+
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" %>
7
+ </div>
8
+ </div>
9
+
10
+ <% resource.attributes.each do |attribute| %>
11
+ <% next if attribute[:field].nil? %>
12
+ <% next unless attribute[:field].visible?(action_name) %>
13
+ <% field = attribute[:field] %>
14
+
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>
19
+
20
+ <div>
21
+ <%= render partial: field.to_partial_path("show"), locals: { field: field, record: @record } %>
22
+ </div>
23
+ </div>
24
+ <% end %>
@@ -0,0 +1 @@
1
+ <h1>Madmin</h1>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.file_field field.to_param %>
@@ -0,0 +1,3 @@
1
+ <% if (attachment = field.value(record)) && attachment.attached? %>
2
+ <%= link_to attachment.filename, attachment, target: :_blank %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% if (attachment = field.value(record)) && attachment.attached? %>
2
+ <%= link_to attachment.filename, attachment, target: :_blank %>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.file_field field.attribute_name, multiple: true %>
@@ -0,0 +1 @@
1
+ <%= pluralize field.value(record).count, "attachment" %>
@@ -0,0 +1,7 @@
1
+ <% if (attachments = field.value(record)) && attachments.attached? %>
2
+ <% attachments.each do |attachment| %>
3
+ <div>
4
+ <%= link_to attachment.filename, attachment, target: :_blank %>
5
+ </div>
6
+ <% end %>
7
+ <% end %>
@@ -1,14 +1,2 @@
1
- <div class="form-group">
2
- <%= form.label field.key %>
3
- <%=
4
- form.select field.association_foreign_key,
5
- options_from_collection_for_select(
6
- field.association_collection,
7
- :id,
8
- field.association_display_value,
9
- field.association_id_or_blank_for(resource)
10
- ),
11
- { include_blank: true },
12
- class: 'form-control'
13
- %>
14
- </div>
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" } %>
@@ -1,7 +1,2 @@
1
- <%=
2
- link_to field.association_value_for(resource),
3
- resource_path(
4
- field.association_slug,
5
- field.association_id_for(resource)
6
- )
7
- %>
1
+ <% object = field.value(record) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
@@ -1,8 +1,2 @@
1
- <div class="row">
2
- <div class="col-3">
3
- <%= field.label %>
4
- </div>
5
- <div class="col-9">
6
- <%= field.association_value_for(resource) %>
7
- </div>
8
- </div>
1
+ <% object = field.value(record) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.check_box field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.date_select field.attribute_name, {}, { class: "form-select" } %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.datetime_select field.attribute_name, {}, { class: "form-select" } %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,3 @@
1
+ ENUM
2
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
3
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.number_field field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
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" } %>
@@ -0,0 +1 @@
1
+ <%= pluralize field.value(record).count, field.attribute_name.to_s %>
@@ -1,15 +1,5 @@
1
- <div class="mt-3">
2
- <div class="row">
3
- <div class="col">
4
- <h3><%= field.label %></h3>
5
- <%= link_to "Add", new_resource_path(field.association_slug, field.association_param => { field.association_foreign_key => resource.id }) %>
6
- <%=
7
- render "madmin/resources/index/content",
8
- headers: [],
9
- collection: field.value_for(resource),
10
- madmin_resource: madmin_resource_for(model: field.association_class),
11
- show_new_button: false
12
- %>
13
- </div>
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) %>
14
4
  </div>
15
- </div>
5
+ <% end %>
@@ -0,0 +1,3 @@
1
+ HAS ONE
2
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
3
+ <%= field.value(record) %>
@@ -0,0 +1,3 @@
1
+ <% if (object = field.value(record)) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
3
+ <% end %>
@@ -1,12 +1,3 @@
1
- <div class="mt-3">
2
- <div class="row">
3
- <div class="col">
4
- <h3><%= field.name %></h3>
5
- <% if !field.value %>
6
- <%= link_to "Add", new_resource_path(madmin_resource_for(model: field.foreign_class).slug, ActiveModel::Naming.param_key(field.foreign_class) => { field.foreign_key => field.resource.id }) %>
7
- <% else %>
8
- <%= render "madmin/resources/index/content", headers: [], collection: [Madmin::ResourceDecorator.new(field.value)], show_new_button: false %>
9
- <% end %>
10
- </div>
11
- </div>
12
- </div>
1
+ <% if (object = field.value(record)) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.number_field field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.text_area field.attribute_name, class: "form-input" %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -1,32 +1,5 @@
1
- <div class="form-group">
2
- <%= form.label field.key %>
3
- <%=
4
- form.select field.polymorphic_type_param,
5
- polymorphic_models(field.key).map { |m| [m.name, m.name, { "data-slug" => madmin_resource_for(model: m).slug }] },
6
- { include_blank: true },
7
- id: field.polymorphic_type_param,
8
- class: "form-control"
9
- %>
10
- <% if field.polymorphic_relationship_exists?(form.object) %>
11
- <%=
12
- form.select field.polymorphic_id_param,
13
- polymorphic_options_for_selected_type(form: form, field: field),
14
- {},
15
- id: field.polymorphic_id_param,
16
- class: "form-control"
17
- %>
18
- <% else %>
19
- <%=
20
- form.select field.polymorphic_id_param,
21
- [],
22
- {},
23
- id: field.polymorphic_id_param,
24
- class: "d-none form-control"
25
- %>
26
- <% end %>
27
- </div>
28
-
29
- <script>
30
- window.polymorphicFields = window.polymorphicFields || [];
31
- window.polymorphicFields.push('<%= field.key %>')
32
- </script>
1
+ <%= form.fields_for field.attribute_name do |pf| %>
2
+ <%= pf.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
3
+ <%= pf.select :value, field.options_for_select(record).map(&:to_global_id), { selected: field.value(record)&.to_global_id, prompt: true }, { class: "form-select" } %>
4
+ <%= pf.hidden_field :type, value: "polymorphic" %>
5
+ <% end %>
@@ -1 +1,3 @@
1
- <%= link_to field.polymorphic_value_for(resource), resource_path(field.polymorphic_slug_for(resource), field.polymorphic_id_for(resource)) %>
1
+ <% if (object = field.value(record)) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
3
+ <% end %>
@@ -1,14 +1,3 @@
1
- <div class="row">
2
- <div class="col-3">
3
- <%= field.label %>
4
- </div>
5
- <div class="col-9">
6
- <%=
7
- link_to field.polymorphic_value_for(resource),
8
- resource_path(
9
- field.polymorphic_slug_for(resource),
10
- field.polymorphic_id_for(resource)
11
- )
12
- %>
13
- </div>
14
- </div>
1
+ <% if (object = field.value(record)) %>
2
+ <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
3
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <div>
3
+ <%= form.rich_text_area field.attribute_name, class: "form-input" %>
4
+ </div>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1,3 @@
1
+ <div class="prose">
2
+ <%= field.value(record) %>
3
+ </div>
@@ -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) %>
@@ -1,4 +1,2 @@
1
- <div class="form-group">
2
- <%= form.label field.key, field.label %>
3
- <%= form.text_field field.key, class: "form-control" %>
4
- </div>
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.text_area field.attribute_name, class: "form-input" %>
@@ -1 +1 @@
1
- <%= field.value_for(resource) %>
1
+ <%= field.value(record) %>
@@ -1,8 +1 @@
1
- <div class="row">
2
- <div class="col-3">
3
- <%= field.label %>
4
- </div>
5
- <div class="col-9">
6
- <%= field.value_for(resource) %>
7
- </div>
8
- </div>
1
+ <%= field.value(record) %>
@@ -0,0 +1,2 @@
1
+ <%= form.label field.attribute_name, class: "inline-block w-32 flex-shrink-0" %>
2
+ <%= form.time_select field.attribute_name, {}, { class: "form-select" } %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -0,0 +1 @@
1
+ <%= field.value(record) %>
@@ -1,4 +1,3 @@
1
- require "rails/generators/base"
2
1
  require "madmin/generator_helpers"
3
2
 
4
3
  module Madmin
@@ -6,25 +5,38 @@ module Madmin
6
5
  class InstallGenerator < Rails::Generators::Base
7
6
  include Madmin::GeneratorHelpers
8
7
 
9
- def generate_resources
10
- resources.each do |model|
11
- call_generator "madmin:resource", model.to_s
8
+ def eager_load
9
+ Rails.application.eager_load!
10
+ end
11
+
12
+ def generate_routes
13
+ if route_namespace_exists?
14
+ route "root to: \"dashboard#show\"", indentation: 4, sentinel: /namespace :madmin do\s*\n/m
15
+ else
16
+ route "root to: \"dashboard#show\"", namespace: [:madmin]
12
17
  end
13
18
  end
14
19
 
15
- def install_route
16
- inject_into_file(
17
- Rails.root.join("config/routes.rb"),
18
- after: "Rails.application.routes.draw do\n"
19
- ) { " namespace :madmin do\n end\n mount Madmin::Engine => \"/madmin\"\n" }
20
+ def generate_resources
21
+ generateable_models.each do |model|
22
+ if model.table_exists?
23
+ call_generator "madmin:resource", model.to_s
24
+ else
25
+ puts "Skipping #{model} because database table does not exist"
26
+ end
27
+ end
20
28
  end
21
29
 
22
30
  private
23
31
 
24
- def resources
25
- Rails.application.eager_load! unless Rails.application.config.cache_classes
32
+ def generateable_models
33
+ active_record_models.reject do |model|
34
+ model.abstract_class? || model == ActiveRecord::Base
35
+ end
36
+ end
26
37
 
27
- ActiveRecord::Base.descendants.reject(&:abstract_class?)
38
+ def active_record_models
39
+ ObjectSpace.each_object(ActiveRecord::Base.singleton_class)
28
40
  end
29
41
  end
30
42
  end
@@ -1,75 +1,111 @@
1
- require "rails/generators/named_base"
2
- require "madmin/generator_helpers"
3
-
4
1
  module Madmin
5
2
  module Generators
6
3
  class ResourceGenerator < Rails::Generators::NamedBase
7
- ATTRIBUTE_TYPE_MAPPING = {
8
- boolean: "Field::CheckBox",
9
- date: "Field::DateTime",
10
- datetime: "Field::DateTime",
11
- enum: "Field::Text",
12
- float: "Field::Number",
13
- integer: "Field::Number",
14
- time: "Field::DateTime",
15
- text: "Field::TextArea",
16
- string: "Field::Text",
17
- }
4
+ include Madmin::GeneratorHelpers
18
5
 
19
6
  source_root File.expand_path("../templates", __FILE__)
20
7
 
21
- def create_resource_file
22
- template(
23
- "resource.rb.erb",
24
- Rails.root.join("app/madmin/resources/#{file_name}.rb"),
25
- )
8
+ def eager_load
9
+ Rails.application.eager_load!
26
10
  end
27
11
 
28
- private
12
+ def generate_resource
13
+ template "resource.rb", "app/madmin/resources/#{file_path}_resource.rb"
14
+ end
29
15
 
30
- def attributes
31
- klass.attribute_types.map { |name, attr|
32
- # Skip attributes related to associations
33
- next if ignored_attributes.include?(name)
16
+ def generate_controller
17
+ destination = Rails.root.join("app/controllers/madmin/#{file_path.pluralize}_controller.rb")
18
+ template("controller.rb", destination)
19
+ end
34
20
 
35
- [name, madmin_type_for_column(attr.type)]
36
- }.compact
21
+ def generate_route
22
+ if route_namespace_exists?
23
+ route "resources :#{plural_name}", namespace: class_path, indentation: 4, sentinel: /namespace :madmin do\s*\n/m
24
+ else
25
+ route "resources :#{plural_name}", namespace: [:madmin] + class_path
26
+ end
37
27
  end
38
28
 
29
+ private
30
+
39
31
  def associations
40
- klass.reflections.map do |name, association|
41
- if association.polymorphic?
42
- [name, "Field::Polymorphic"]
43
- elsif association.belongs_to?
44
- [name, "Field::BelongsTo"]
45
- elsif association.has_one?
46
- [name, "Field::HasOne"]
47
- else
48
- [name, "Field::HasMany"]
32
+ model.reflections.reject { |name, association|
33
+ # Hide these special associations
34
+ name.starts_with?("rich_text") ||
35
+ name.ends_with?("_attachment") ||
36
+ name.ends_with?("_attachments") ||
37
+ name.ends_with?("_blob") ||
38
+ name.ends_with?("_blobs")
39
+ }.keys
40
+ end
41
+
42
+ def attributes
43
+ model.attribute_names + virtual_attributes - redundant_attributes
44
+ end
45
+
46
+ def virtual_attributes
47
+ virtual = []
48
+
49
+ # Add virtual attributes for ActionText and ActiveStorage
50
+ model.reflections.each do |name, association|
51
+ if name.starts_with?("rich_text")
52
+ virtual << name.split("rich_text_").last
53
+ elsif name.ends_with?("_attachment")
54
+ virtual << name.split("_attachment").first
55
+ elsif name.ends_with?("_attachments")
56
+ virtual << name.split("_attachments").first
49
57
  end
50
58
  end
59
+
60
+ virtual
51
61
  end
52
62
 
53
- def ignored_attributes
54
- attrs = []
63
+ def redundant_attributes
64
+ redundant = []
55
65
 
56
- klass.reflections.map do |name, association|
57
- if association.polymorphic?
58
- attrs += [association.foreign_key, association.foreign_type]
59
- elsif association.belongs_to?
60
- attrs += [association.foreign_key]
66
+ model.reflections.each do |name, association|
67
+ if association.has_one?
68
+ next
69
+ elsif association.collection?
70
+ next
71
+ elsif association.polymorphic?
72
+ redundant << "#{name}_id"
73
+ redundant << "#{name}_type"
74
+ elsif name.starts_with?("rich_text")
75
+ redundant << name
76
+ else # belongs to
77
+ redundant << "#{name}_id"
61
78
  end
62
79
  end
63
80
 
64
- attrs
81
+ redundant
82
+ end
83
+
84
+ def model
85
+ @model ||= class_name.constantize
65
86
  end
66
87
 
67
- def klass
68
- @klass ||= Object.const_get(class_name)
88
+ def formatted_options_for_attribute(name)
89
+ options = options_for_attribute(name)
90
+ return if options.blank?
91
+
92
+ ", " + options.map { |key, value|
93
+ "#{key}: #{value}"
94
+ }.join(", ")
69
95
  end
70
96
 
71
- def madmin_type_for_column(column_type)
72
- ATTRIBUTE_TYPE_MAPPING[column_type]
97
+ def options_for_attribute(name)
98
+ if %w[id created_at updated_at].include?(name)
99
+ {form: false}
100
+
101
+ # Attributes without a database column
102
+ elsif !model.column_names.include?(name)
103
+ {index: false}
104
+
105
+ # Counter cache columns are typically not editable
106
+ elsif name.ends_with?("_count")
107
+ {form: false}
108
+ end
73
109
  end
74
110
  end
75
111
  end