jav_madmin 2.6.2

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 (172) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +294 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/config/madmin_manifest.js +3 -0
  6. data/app/assets/stylesheets/madmin/actiontext.css +31 -0
  7. data/app/assets/stylesheets/madmin/application-sprockets.css +11 -0
  8. data/app/assets/stylesheets/madmin/application.css +9 -0
  9. data/app/assets/stylesheets/madmin/base.css +144 -0
  10. data/app/assets/stylesheets/madmin/buttons.css +53 -0
  11. data/app/assets/stylesheets/madmin/forms.css +90 -0
  12. data/app/assets/stylesheets/madmin/pagination.css +59 -0
  13. data/app/assets/stylesheets/madmin/reset.css +242 -0
  14. data/app/assets/stylesheets/madmin/sidebar.css +179 -0
  15. data/app/assets/stylesheets/madmin/tables.css +71 -0
  16. data/app/controllers/madmin/application_controller.rb +17 -0
  17. data/app/controllers/madmin/base_controller.rb +15 -0
  18. data/app/controllers/madmin/dashboard_controller.rb +6 -0
  19. data/app/controllers/madmin/resource_controller.rb +119 -0
  20. data/app/helpers/madmin/application_helper.rb +10 -0
  21. data/app/helpers/madmin/nav_helper.rb +34 -0
  22. data/app/helpers/madmin/sort_helper.rb +48 -0
  23. data/app/javascript/madmin/application.js +3 -0
  24. data/app/javascript/madmin/controllers/application.js +12 -0
  25. data/app/javascript/madmin/controllers/index.js +5 -0
  26. data/app/javascript/madmin/controllers/mobile_nav_controller.js +50 -0
  27. data/app/javascript/madmin/controllers/nested_form_controller.js +34 -0
  28. data/app/javascript/madmin/controllers/select_controller.js +37 -0
  29. data/app/views/layouts/madmin/application.html.erb +41 -0
  30. data/app/views/madmin/application/_flash.html.erb +13 -0
  31. data/app/views/madmin/application/_form.html.erb +24 -0
  32. data/app/views/madmin/application/_javascript.html.erb +8 -0
  33. data/app/views/madmin/application/_missing_resource.html.erb +8 -0
  34. data/app/views/madmin/application/_navigation.html.erb +22 -0
  35. data/app/views/madmin/application/edit.html.erb +11 -0
  36. data/app/views/madmin/application/index.html.erb +85 -0
  37. data/app/views/madmin/application/new.html.erb +11 -0
  38. data/app/views/madmin/application/show.html.erb +40 -0
  39. data/app/views/madmin/dashboard/show.html.erb +2 -0
  40. data/app/views/madmin/fields/attachment/_form.html.erb +11 -0
  41. data/app/views/madmin/fields/attachment/_index.html.erb +7 -0
  42. data/app/views/madmin/fields/attachment/_show.html.erb +9 -0
  43. data/app/views/madmin/fields/attachments/_form.html.erb +1 -0
  44. data/app/views/madmin/fields/attachments/_index.html.erb +1 -0
  45. data/app/views/madmin/fields/attachments/_show.html.erb +11 -0
  46. data/app/views/madmin/fields/belongs_to/_form.html.erb +1 -0
  47. data/app/views/madmin/fields/belongs_to/_index.html.erb +4 -0
  48. data/app/views/madmin/fields/belongs_to/_show.html.erb +7 -0
  49. data/app/views/madmin/fields/boolean/_form.html.erb +3 -0
  50. data/app/views/madmin/fields/boolean/_index.html.erb +1 -0
  51. data/app/views/madmin/fields/boolean/_show.html.erb +1 -0
  52. data/app/views/madmin/fields/currency/_form.html.erb +1 -0
  53. data/app/views/madmin/fields/currency/_index.html.erb +1 -0
  54. data/app/views/madmin/fields/currency/_show.html.erb +1 -0
  55. data/app/views/madmin/fields/date/_form.html.erb +1 -0
  56. data/app/views/madmin/fields/date/_index.html.erb +1 -0
  57. data/app/views/madmin/fields/date/_show.html.erb +1 -0
  58. data/app/views/madmin/fields/date_time/_form.html.erb +1 -0
  59. data/app/views/madmin/fields/date_time/_index.html.erb +1 -0
  60. data/app/views/madmin/fields/date_time/_show.html.erb +1 -0
  61. data/app/views/madmin/fields/decimal/_form.html.erb +1 -0
  62. data/app/views/madmin/fields/decimal/_index.html.erb +1 -0
  63. data/app/views/madmin/fields/decimal/_show.html.erb +1 -0
  64. data/app/views/madmin/fields/enum/_form.html.erb +1 -0
  65. data/app/views/madmin/fields/enum/_index.html.erb +1 -0
  66. data/app/views/madmin/fields/enum/_show.html.erb +1 -0
  67. data/app/views/madmin/fields/file/_form.html.erb +1 -0
  68. data/app/views/madmin/fields/file/_index.html.erb +1 -0
  69. data/app/views/madmin/fields/file/_show.html.erb +6 -0
  70. data/app/views/madmin/fields/float/_form.html.erb +1 -0
  71. data/app/views/madmin/fields/float/_index.html.erb +1 -0
  72. data/app/views/madmin/fields/float/_show.html.erb +1 -0
  73. data/app/views/madmin/fields/has_many/_form.html.erb +1 -0
  74. data/app/views/madmin/fields/has_many/_index.html.erb +1 -0
  75. data/app/views/madmin/fields/has_many/_show.html.erb +18 -0
  76. data/app/views/madmin/fields/has_one/_form.html.erb +1 -0
  77. data/app/views/madmin/fields/has_one/_index.html.erb +3 -0
  78. data/app/views/madmin/fields/has_one/_show.html.erb +7 -0
  79. data/app/views/madmin/fields/integer/_form.html.erb +1 -0
  80. data/app/views/madmin/fields/integer/_index.html.erb +1 -0
  81. data/app/views/madmin/fields/integer/_show.html.erb +1 -0
  82. data/app/views/madmin/fields/json/_form.html.erb +1 -0
  83. data/app/views/madmin/fields/json/_index.html.erb +1 -0
  84. data/app/views/madmin/fields/json/_show.html.erb +1 -0
  85. data/app/views/madmin/fields/nested_has_many/_fields.html.erb +17 -0
  86. data/app/views/madmin/fields/nested_has_many/_form.html.erb +28 -0
  87. data/app/views/madmin/fields/nested_has_many/_index.html.erb +1 -0
  88. data/app/views/madmin/fields/nested_has_many/_show.html.erb +18 -0
  89. data/app/views/madmin/fields/password/_form.html.erb +1 -0
  90. data/app/views/madmin/fields/password/_index.html.erb +1 -0
  91. data/app/views/madmin/fields/password/_show.html.erb +1 -0
  92. data/app/views/madmin/fields/polymorphic/_form.html.erb +4 -0
  93. data/app/views/madmin/fields/polymorphic/_index.html.erb +3 -0
  94. data/app/views/madmin/fields/polymorphic/_show.html.erb +7 -0
  95. data/app/views/madmin/fields/rich_text/_form.html.erb +1 -0
  96. data/app/views/madmin/fields/rich_text/_index.html.erb +1 -0
  97. data/app/views/madmin/fields/rich_text/_show.html.erb +3 -0
  98. data/app/views/madmin/fields/select/_form.html.erb +1 -0
  99. data/app/views/madmin/fields/select/_index.html.erb +1 -0
  100. data/app/views/madmin/fields/select/_show.html.erb +1 -0
  101. data/app/views/madmin/fields/string/_form.html.erb +1 -0
  102. data/app/views/madmin/fields/string/_index.html.erb +1 -0
  103. data/app/views/madmin/fields/string/_show.html.erb +1 -0
  104. data/app/views/madmin/fields/text/_form.html.erb +1 -0
  105. data/app/views/madmin/fields/text/_index.html.erb +1 -0
  106. data/app/views/madmin/fields/text/_show.html.erb +1 -0
  107. data/app/views/madmin/fields/time/_form.html.erb +5 -0
  108. data/app/views/madmin/fields/time/_index.html.erb +1 -0
  109. data/app/views/madmin/fields/time/_show.html.erb +1 -0
  110. data/app/views/madmin/shared/_label.html.erb +4 -0
  111. data/config/importmap.rb +15 -0
  112. data/config/locales/el.yml +42 -0
  113. data/config/locales/en.yml +42 -0
  114. data/config/locales/fr.yml +42 -0
  115. data/config/locales/ko.yml +40 -0
  116. data/lib/generators/madmin/field/field_generator.rb +31 -0
  117. data/lib/generators/madmin/field/templates/_form.html.erb +1 -0
  118. data/lib/generators/madmin/field/templates/_index.html.erb +1 -0
  119. data/lib/generators/madmin/field/templates/_show.html.erb +1 -0
  120. data/lib/generators/madmin/field/templates/field.rb.tt +26 -0
  121. data/lib/generators/madmin/install/install_generator.rb +55 -0
  122. data/lib/generators/madmin/install/templates/controller.rb.tt +15 -0
  123. data/lib/generators/madmin/install/templates/routes.rb.tt +3 -0
  124. data/lib/generators/madmin/resource/resource_generator.rb +73 -0
  125. data/lib/generators/madmin/resource/templates/controller.rb.tt +10 -0
  126. data/lib/generators/madmin/resource/templates/resource.rb.tt +33 -0
  127. data/lib/generators/madmin/views/edit_generator.rb +16 -0
  128. data/lib/generators/madmin/views/form_generator.rb +15 -0
  129. data/lib/generators/madmin/views/index_generator.rb +15 -0
  130. data/lib/generators/madmin/views/javascript_generator.rb +15 -0
  131. data/lib/generators/madmin/views/layout_generator.rb +21 -0
  132. data/lib/generators/madmin/views/navigation_generator.rb +15 -0
  133. data/lib/generators/madmin/views/new_generator.rb +16 -0
  134. data/lib/generators/madmin/views/show_generator.rb +15 -0
  135. data/lib/generators/madmin/views/views_generator.rb +16 -0
  136. data/lib/madmin/engine.rb +47 -0
  137. data/lib/madmin/field.rb +67 -0
  138. data/lib/madmin/fields/attachment.rb +6 -0
  139. data/lib/madmin/fields/attachments.rb +9 -0
  140. data/lib/madmin/fields/belongs_to.rb +29 -0
  141. data/lib/madmin/fields/boolean.rb +6 -0
  142. data/lib/madmin/fields/currency.rb +15 -0
  143. data/lib/madmin/fields/date.rb +6 -0
  144. data/lib/madmin/fields/date_time.rb +6 -0
  145. data/lib/madmin/fields/decimal.rb +6 -0
  146. data/lib/madmin/fields/enum.rb +9 -0
  147. data/lib/madmin/fields/file.rb +9 -0
  148. data/lib/madmin/fields/float.rb +6 -0
  149. data/lib/madmin/fields/has_many.rb +62 -0
  150. data/lib/madmin/fields/has_one.rb +10 -0
  151. data/lib/madmin/fields/integer.rb +6 -0
  152. data/lib/madmin/fields/json.rb +6 -0
  153. data/lib/madmin/fields/nested_has_many.rb +44 -0
  154. data/lib/madmin/fields/password.rb +6 -0
  155. data/lib/madmin/fields/polymorphic.rb +22 -0
  156. data/lib/madmin/fields/rich_text.rb +6 -0
  157. data/lib/madmin/fields/select.rb +9 -0
  158. data/lib/madmin/fields/string.rb +9 -0
  159. data/lib/madmin/fields/text.rb +9 -0
  160. data/lib/madmin/fields/time.rb +6 -0
  161. data/lib/madmin/generator_helpers.rb +59 -0
  162. data/lib/madmin/member_action.rb +19 -0
  163. data/lib/madmin/menu.rb +70 -0
  164. data/lib/madmin/namespace.rb +35 -0
  165. data/lib/madmin/resource.rb +295 -0
  166. data/lib/madmin/resource_builder.rb +88 -0
  167. data/lib/madmin/search.rb +62 -0
  168. data/lib/madmin/version.rb +3 -0
  169. data/lib/madmin/view_generator.rb +43 -0
  170. data/lib/madmin.rb +114 -0
  171. data/lib/tasks/madmin_tasks.rake +11 -0
  172. metadata +284 -0
@@ -0,0 +1,73 @@
1
+ module Madmin
2
+ module Generators
3
+ class ResourceGenerator < 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_resource
13
+ template "resource.rb", "app/madmin/resources/#{file_path}_resource.rb"
14
+ end
15
+
16
+ def generate_controller
17
+ destination = Rails.root.join("app/controllers/madmin/#{file_path.pluralize}_controller.rb")
18
+ template("controller.rb", destination)
19
+ end
20
+
21
+ def generate_route
22
+ if route_namespace_exists?
23
+ route "resources :#{plural_name}", namespace: class_path, indentation: separated_routes_file? ? 2 : 4, sentinel: /namespace :madmin[^\n]*do\s*\n/m
24
+ else
25
+ route "resources :#{plural_name}", namespace: [:madmin] + class_path
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def model
32
+ @model ||= class_name.constantize
33
+ end
34
+
35
+ def resource_builder
36
+ @resource_builder ||= ResourceBuilder.new(model)
37
+ end
38
+
39
+ def model_attributes
40
+ resource_builder.attributes
41
+ end
42
+
43
+ delegate :associations, :virtual_attributes, :store_accessors, to: :resource_builder
44
+
45
+ def formatted_options_for_attribute(name)
46
+ options = options_for_attribute(name)
47
+ return if options.blank?
48
+
49
+ ", " + options.map { |key, value|
50
+ "#{key}: #{value}"
51
+ }.join(", ")
52
+ end
53
+
54
+ def options_for_attribute(name)
55
+ if %w[id created_at updated_at].include?(name)
56
+ {form: false}
57
+
58
+ # has_secure_passwords should only show on forms
59
+ elsif name.ends_with?("_confirmation") || virtual_attributes.include?("#{name}_confirmation")
60
+ {index: false, show: false}
61
+
62
+ # Counter cache columns are typically not editable
63
+ elsif name.ends_with?("_count")
64
+ {form: false}
65
+
66
+ # Attributes without a database column
67
+ elsif !model.column_names.include?(name) && !store_accessors.map(&:to_s).include?(name)
68
+ {index: false}
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ module Madmin
2
+ class <%= class_name.pluralize %>Controller < Madmin::ResourceController
3
+ <% if class_name == "ActiveStorage::Blob" -%>
4
+ def new
5
+ super
6
+ @record.assign_attributes(filename: "")
7
+ end
8
+ <% end -%>
9
+ end
10
+ end
@@ -0,0 +1,33 @@
1
+ class <%= class_name %>Resource < Madmin::Resource
2
+ # Attributes
3
+ <% model_attributes.each do |attribute_name| -%>
4
+ attribute :<%= attribute_name %><%= formatted_options_for_attribute(attribute_name) %>
5
+ <% end -%>
6
+
7
+ # Associations
8
+ <% associations.each do |association_name| -%>
9
+ attribute :<%= association_name %>
10
+ <% end -%>
11
+
12
+ # Add scopes to easily filter records
13
+ # scope :published
14
+
15
+ # Add actions to the resource's show page
16
+ # Pass collection: true to also render it in each row on the index page
17
+ # member_action do |record|
18
+ # link_to "Do Something", some_path
19
+ # end
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
+
26
+ # Customize the display name of records in the admin area.
27
+ # def self.display_name(record) = record.name
28
+
29
+ # Customize the default sort column and direction.
30
+ # def self.default_sort_column = "created_at"
31
+ #
32
+ # def self.default_sort_direction = "desc"
33
+ end
@@ -0,0 +1,16 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class EditGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_edit
10
+ copy_resource_template("edit")
11
+ copy_resource_template("_form")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class FormGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_form
10
+ copy_resource_template("_form")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class IndexGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_template
10
+ copy_resource_template("index")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class JavascriptGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_navigation
10
+ copy_resource_template("_javascript")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class LayoutGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_template
10
+ copy_file(
11
+ "../../layouts/madmin/application.html.erb",
12
+ "app/views/layouts/madmin/application.html.erb"
13
+ )
14
+
15
+ call_generator("madmin:views:navigation")
16
+ copy_resource_template("_javascript")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class NavigationGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_navigation
10
+ copy_resource_template("_navigation")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class NewGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_new
10
+ copy_resource_template("new")
11
+ copy_resource_template("_form")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ module Views
6
+ class ShowGenerator < Madmin::ViewGenerator
7
+ source_root template_source_path
8
+
9
+ def copy_template
10
+ copy_resource_template("show")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require "madmin/view_generator"
2
+
3
+ module Madmin
4
+ module Generators
5
+ class ViewsGenerator < Madmin::ViewGenerator
6
+ def copy_templates
7
+ # Some generators duplicate templates, so not everything is present here
8
+ call_generator("madmin:views:edit", resource_path, "--namespace", namespace)
9
+ call_generator("madmin:views:index", resource_path, "--namespace", namespace)
10
+ call_generator("madmin:views:layout", resource_path, "--namespace", namespace)
11
+ call_generator("madmin:views:new", resource_path, "--namespace", namespace)
12
+ call_generator("madmin:views:show", resource_path, "--namespace", namespace)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,47 @@
1
+ module Madmin
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Madmin
4
+
5
+ config.before_configuration do |app|
6
+ app.config.eager_load_paths << app.root.join("app/madmin/resources")
7
+ app.config.eager_load_paths << app.root.join("app/madmin/fields")
8
+ Madmin.resource_locations << Rails.root.join("app/madmin/resources/")
9
+
10
+ Rails::Engine.subclasses.each do |engine|
11
+ app.config.eager_load_paths << engine.root.join("app/madmin/resources")
12
+ app.config.eager_load_paths << engine.root.join("app/madmin/fields")
13
+ Madmin.resource_locations << engine.root.join("app/madmin/resources/")
14
+ end
15
+ end
16
+
17
+ config.to_prepare do
18
+ Madmin.reset_resources!
19
+ Madmin.site_name ||= Rails.application.class.module_parent_name.titleize
20
+ end
21
+
22
+ initializer "madmin.assets" do |app|
23
+ if app.config.respond_to?(:assets)
24
+ app.config.assets.paths << root.join("app/assets/stylesheets")
25
+ app.config.assets.paths << root.join("app/javascript")
26
+ app.config.assets.precompile += %w[madmin_manifest]
27
+
28
+ Madmin.stylesheets << if defined?(::Sprockets)
29
+ "madmin/application-sprockets"
30
+ else
31
+ "madmin/application"
32
+ end
33
+
34
+ Madmin.stylesheets << "lexxy" if defined?(::Lexxy)
35
+ end
36
+ end
37
+
38
+ initializer "madmin.importmap", before: "importmap" do |app|
39
+ Madmin.importmap.draw root.join("config/importmap.rb")
40
+ Madmin.importmap.cache_sweeper watches: root.join("app/javascript")
41
+
42
+ ActiveSupport.on_load(:action_controller_base) do
43
+ before_action { Madmin.importmap.cache_sweeper.execute_if_updated }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,67 @@
1
+ module Madmin
2
+ class Field
3
+ attr_reader :attribute_name, :model, :options, :resource
4
+
5
+ def self.field_type
6
+ to_s.split("::").last.underscore
7
+ end
8
+
9
+ def initialize(attribute_name:, model:, resource:, options:)
10
+ @attribute_name = attribute_name.to_sym
11
+ @model = model
12
+ @resource = resource
13
+ @options = options
14
+ end
15
+
16
+ def value(record)
17
+ record.try(attribute_name)
18
+ end
19
+
20
+ def to_partial_path(name)
21
+ unless %w[index show form].include? name.to_s
22
+ raise ArgumentError, "`partial` must be 'index', 'show', or 'form'"
23
+ end
24
+
25
+ "/madmin/fields/#{self.class.field_type}/#{name}"
26
+ end
27
+
28
+ def to_param
29
+ attribute_name
30
+ end
31
+
32
+ def label
33
+ options[:label].presence || model.human_attribute_name(attribute_name)
34
+ end
35
+
36
+ # Used for checking visibility of attribute on an view
37
+ def visible?(action)
38
+ action = action.to_sym
39
+ options.fetch(action) do
40
+ case action
41
+ when :index
42
+ default_index_attributes.include?(attribute_name)
43
+ else
44
+ true
45
+ end
46
+ end
47
+ end
48
+
49
+ def default_index_attributes
50
+ [model.primary_key.to_sym, :avatar, :title, :name, :user, :created_at]
51
+ end
52
+
53
+ def required?
54
+ model.validators_on(attribute_name).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
55
+ end
56
+
57
+ def searchable?
58
+ false
59
+ end
60
+
61
+ def paginateable?
62
+ false
63
+ end
64
+
65
+ ActiveSupport.run_load_hooks(:madmin_field, self)
66
+ end
67
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Attachment < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Madmin
2
+ module Fields
3
+ class Attachments < Field
4
+ def to_param
5
+ {attribute_name => []}
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Madmin
2
+ module Fields
3
+ class BelongsTo < Field
4
+ def options_for_select(record)
5
+ current_value = record.send(attribute_name)
6
+ records = [current_value].compact + associated_resource.model.excluding(current_value).limit(25)
7
+ records.map { [Madmin.resource_for(_1).display_name(_1), _1.id] }
8
+ end
9
+
10
+ def to_param
11
+ "#{attribute_name}_id"
12
+ end
13
+
14
+ def index_path(format: :json)
15
+ associated_resource&.index_path(format: format)
16
+ end
17
+
18
+ def associated_resource
19
+ Madmin.resource_by_name(model.reflect_on_association(attribute_name).klass)
20
+ rescue MissingResource
21
+ end
22
+
23
+ def associated_resource_for(object)
24
+ Madmin.resource_for(object)
25
+ rescue MissingResource
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Boolean < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module Madmin
2
+ module Fields
3
+ class Currency < Field
4
+ def value(record)
5
+ value = record.public_send(attribute_name)
6
+ value /= 100.0 if value && options.minor_units
7
+ value
8
+ end
9
+
10
+ def searchable?
11
+ options.fetch(:searchable, model.column_names.include?(attribute_name.to_s))
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Date < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class DateTime < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Decimal < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Madmin
2
+ module Fields
3
+ class Enum < Field
4
+ def options_for_select(record)
5
+ model.defined_enums[attribute_name.to_s].keys
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Madmin
2
+ module Fields
3
+ class File < Field
4
+ def searchable?
5
+ false
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Float < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,62 @@
1
+ module Madmin
2
+ module Fields
3
+ class HasMany < Field
4
+ def options_for_select(record)
5
+ if (records = record.send(attribute_name))
6
+ return [] unless records.first
7
+ resource = Madmin.resource_for(records.first)
8
+ records.map { |record| [resource.display_name(record), record.id] }
9
+ else
10
+ []
11
+ end
12
+ end
13
+
14
+ def to_param
15
+ {"#{attribute_name.to_s.singularize}_ids": []}
16
+ end
17
+
18
+ def index_path(format: :json)
19
+ associated_resource&.index_path(format: format)
20
+ end
21
+
22
+ def associated_resource
23
+ Madmin.resource_by_name(model.reflect_on_association(attribute_name).klass)
24
+ rescue MissingResource
25
+ end
26
+
27
+ def associated_resource_for(object)
28
+ Madmin.resource_for(object)
29
+ rescue MissingResource
30
+ end
31
+
32
+ def paginateable?
33
+ true
34
+ end
35
+
36
+ if Gem::Version.new(Pagy::VERSION) >= Gem::Version.new("43.0.0.rc")
37
+ include Pagy::Method
38
+
39
+ def paginated_value(record, params)
40
+ page_key = "#{attribute_name}_page"
41
+ request = {
42
+ params: {
43
+ "#{attribute_name}_page" => [params[page_key].to_i, 1].max
44
+ }
45
+ }
46
+ pagy value(record), page_key: page_key, request: request
47
+ rescue Pagy::OptionError
48
+ end
49
+ else
50
+ include Pagy::Backend
51
+
52
+ def paginated_value(record, params)
53
+ page_key = "#{attribute_name}_page"
54
+ page = [params[page_key].to_i, 1].max
55
+ pagy value(record), page: page, page_param: page_key
56
+ rescue Pagy::OverflowError, Pagy::VariableError
57
+ pagy value, page: 1, page_param: page_key
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,10 @@
1
+ module Madmin
2
+ module Fields
3
+ class HasOne < Field
4
+ def associated_resource_for(object)
5
+ Madmin.resource_for(object)
6
+ rescue MissingResource
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Integer < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Json < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,44 @@
1
+ module Madmin
2
+ module Fields
3
+ class NestedHasMany < HasMany
4
+ DEFAULT_ATTRIBUTES = %w[_destroy id].freeze
5
+ def nested_attributes
6
+ resource.attributes.except(*skipped_fields)
7
+ end
8
+
9
+ def resource
10
+ "#{to_model.name}Resource".constantize
11
+ end
12
+
13
+ def to_param
14
+ {"#{attribute_name}_attributes": permitted_fields}
15
+ end
16
+
17
+ def to_partial_path(name)
18
+ unless %w[index show form fields].include? name
19
+ raise ArgumentError, "`partial` must be 'index', 'show', 'form' or 'fields'"
20
+ end
21
+
22
+ "/madmin/fields/#{self.class.field_type}/#{name}"
23
+ end
24
+
25
+ def to_model
26
+ attribute_name.to_s.singularize.classify.constantize
27
+ end
28
+
29
+ def paginateable?
30
+ true
31
+ end
32
+
33
+ private
34
+
35
+ def permitted_fields
36
+ (resource.permitted_params - skipped_fields + DEFAULT_ATTRIBUTES).uniq
37
+ end
38
+
39
+ def skipped_fields
40
+ options[:skip] || []
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ module Madmin
2
+ module Fields
3
+ class Password < Field
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ module Madmin
2
+ module Fields
3
+ class Polymorphic < Field
4
+ def options_for_select(record)
5
+ if (collection = options[:collection])
6
+ collection.call
7
+ else
8
+ [value(record)].compact
9
+ end
10
+ end
11
+
12
+ def to_param
13
+ {attribute_name => %i[type value]}
14
+ end
15
+
16
+ def associated_resource_for(object)
17
+ Madmin.resource_for(object)
18
+ rescue MissingResource
19
+ end
20
+ end
21
+ end
22
+ end