viniBaxterDesk 0.13.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 (189) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +32 -0
  3. data/app/assets/javascripts/administrate/application.js +6 -0
  4. data/app/assets/javascripts/administrate/components/associative.js +4 -0
  5. data/app/assets/javascripts/administrate/components/date_time_picker.js +14 -0
  6. data/app/assets/javascripts/administrate/components/table.js +23 -0
  7. data/app/assets/stylesheets/administrate/application.scss +30 -0
  8. data/app/assets/stylesheets/administrate/base/_forms.scss +107 -0
  9. data/app/assets/stylesheets/administrate/base/_layout.scss +20 -0
  10. data/app/assets/stylesheets/administrate/base/_lists.scss +19 -0
  11. data/app/assets/stylesheets/administrate/base/_tables.scss +58 -0
  12. data/app/assets/stylesheets/administrate/base/_typography.scss +45 -0
  13. data/app/assets/stylesheets/administrate/components/_app-container.scss +9 -0
  14. data/app/assets/stylesheets/administrate/components/_attributes.scss +26 -0
  15. data/app/assets/stylesheets/administrate/components/_buttons.scss +51 -0
  16. data/app/assets/stylesheets/administrate/components/_cells.scss +47 -0
  17. data/app/assets/stylesheets/administrate/components/_field-unit.scss +45 -0
  18. data/app/assets/stylesheets/administrate/components/_flashes.scss +28 -0
  19. data/app/assets/stylesheets/administrate/components/_form-actions.scss +3 -0
  20. data/app/assets/stylesheets/administrate/components/_main-content.scss +29 -0
  21. data/app/assets/stylesheets/administrate/components/_navigation.scss +32 -0
  22. data/app/assets/stylesheets/administrate/components/_pagination.scss +18 -0
  23. data/app/assets/stylesheets/administrate/components/_search.scss +46 -0
  24. data/app/assets/stylesheets/administrate/library/_clearfix.scss +7 -0
  25. data/app/assets/stylesheets/administrate/library/_data-label.scss +8 -0
  26. data/app/assets/stylesheets/administrate/library/_variables.scss +63 -0
  27. data/app/assets/stylesheets/administrate/reset/_normalize.scss +447 -0
  28. data/app/assets/stylesheets/administrate/utilities/_text-color.scss +3 -0
  29. data/app/assets/stylesheets/docs.scss +93 -0
  30. data/app/controllers/administrate/application_controller.rb +189 -0
  31. data/app/controllers/concerns/administrate/punditize.rb +36 -0
  32. data/app/helpers/administrate/application_helper.rb +83 -0
  33. data/app/views/administrate/application/_collection.html.erb +97 -0
  34. data/app/views/administrate/application/_flashes.html.erb +20 -0
  35. data/app/views/administrate/application/_form.html.erb +45 -0
  36. data/app/views/administrate/application/_icons.html.erb +13 -0
  37. data/app/views/administrate/application/_javascript.html.erb +21 -0
  38. data/app/views/administrate/application/_navigation.html.erb +20 -0
  39. data/app/views/administrate/application/_search.html.erb +25 -0
  40. data/app/views/administrate/application/_stylesheet.html.erb +14 -0
  41. data/app/views/administrate/application/edit.html.erb +36 -0
  42. data/app/views/administrate/application/index.html.erb +66 -0
  43. data/app/views/administrate/application/new.html.erb +37 -0
  44. data/app/views/administrate/application/show.html.erb +49 -0
  45. data/app/views/fields/belongs_to/_form.html.erb +26 -0
  46. data/app/views/fields/belongs_to/_index.html.erb +27 -0
  47. data/app/views/fields/belongs_to/_show.html.erb +27 -0
  48. data/app/views/fields/boolean/_form.html.erb +23 -0
  49. data/app/views/fields/boolean/_index.html.erb +19 -0
  50. data/app/views/fields/boolean/_show.html.erb +19 -0
  51. data/app/views/fields/date/_form.html.erb +24 -0
  52. data/app/views/fields/date/_index.html.erb +21 -0
  53. data/app/views/fields/date/_show.html.erb +21 -0
  54. data/app/views/fields/date_time/_form.html.erb +24 -0
  55. data/app/views/fields/date_time/_index.html.erb +21 -0
  56. data/app/views/fields/date_time/_show.html.erb +21 -0
  57. data/app/views/fields/email/_form.html.erb +23 -0
  58. data/app/views/fields/email/_index.html.erb +18 -0
  59. data/app/views/fields/email/_show.html.erb +18 -0
  60. data/app/views/fields/has_many/_form.html.erb +29 -0
  61. data/app/views/fields/has_many/_index.html.erb +19 -0
  62. data/app/views/fields/has_many/_show.html.erb +38 -0
  63. data/app/views/fields/has_one/_form.html.erb +28 -0
  64. data/app/views/fields/has_one/_index.html.erb +23 -0
  65. data/app/views/fields/has_one/_show.html.erb +40 -0
  66. data/app/views/fields/number/_form.html.erb +23 -0
  67. data/app/views/fields/number/_index.html.erb +19 -0
  68. data/app/views/fields/number/_show.html.erb +19 -0
  69. data/app/views/fields/password/_form.html.erb +23 -0
  70. data/app/views/fields/password/_index.html.erb +18 -0
  71. data/app/views/fields/password/_show.html.erb +18 -0
  72. data/app/views/fields/polymorphic/_form.html.erb +29 -0
  73. data/app/views/fields/polymorphic/_index.html.erb +24 -0
  74. data/app/views/fields/polymorphic/_show.html.erb +28 -0
  75. data/app/views/fields/select/_form.html.erb +31 -0
  76. data/app/views/fields/select/_index.html.erb +16 -0
  77. data/app/views/fields/select/_show.html.erb +16 -0
  78. data/app/views/fields/string/_form.html.erb +23 -0
  79. data/app/views/fields/string/_index.html.erb +18 -0
  80. data/app/views/fields/string/_show.html.erb +18 -0
  81. data/app/views/fields/text/_form.html.erb +22 -0
  82. data/app/views/fields/text/_index.html.erb +18 -0
  83. data/app/views/fields/text/_show.html.erb +18 -0
  84. data/app/views/fields/time/_form.html.erb +22 -0
  85. data/app/views/fields/time/_index.html.erb +17 -0
  86. data/app/views/fields/time/_show.html.erb +17 -0
  87. data/app/views/fields/url/_form.html.erb +23 -0
  88. data/app/views/fields/url/_index.html.erb +20 -0
  89. data/app/views/fields/url/_show.html.erb +20 -0
  90. data/app/views/layouts/administrate/application.html.erb +41 -0
  91. data/config/i18n-tasks.yml +18 -0
  92. data/config/locales/administrate.ar.yml +28 -0
  93. data/config/locales/administrate.bs.yml +27 -0
  94. data/config/locales/administrate.ca.yml +28 -0
  95. data/config/locales/administrate.da.yml +28 -0
  96. data/config/locales/administrate.de.yml +28 -0
  97. data/config/locales/administrate.en.yml +28 -0
  98. data/config/locales/administrate.es.yml +28 -0
  99. data/config/locales/administrate.fr.yml +28 -0
  100. data/config/locales/administrate.id.yml +28 -0
  101. data/config/locales/administrate.it.yml +28 -0
  102. data/config/locales/administrate.ja.yml +28 -0
  103. data/config/locales/administrate.ko.yml +28 -0
  104. data/config/locales/administrate.nl.yml +28 -0
  105. data/config/locales/administrate.pl.yml +28 -0
  106. data/config/locales/administrate.pt-BR.yml +29 -0
  107. data/config/locales/administrate.pt.yml +29 -0
  108. data/config/locales/administrate.ru.yml +28 -0
  109. data/config/locales/administrate.sq.yml +28 -0
  110. data/config/locales/administrate.sv.yml +28 -0
  111. data/config/locales/administrate.uk.yml +28 -0
  112. data/config/locales/administrate.vi.yml +28 -0
  113. data/config/locales/administrate.zh-CN.yml +28 -0
  114. data/config/locales/administrate.zh-TW.yml +28 -0
  115. data/config/routes.rb +2 -0
  116. data/config/unicorn.rb +30 -0
  117. data/docs/adding_controllers_without_related_model.md +36 -0
  118. data/docs/adding_custom_field_types.md +81 -0
  119. data/docs/authentication.md +63 -0
  120. data/docs/authorization.md +71 -0
  121. data/docs/contributing.md +1 -0
  122. data/docs/customizing_attribute_partials.md +56 -0
  123. data/docs/customizing_controller_actions.md +58 -0
  124. data/docs/customizing_dashboards.md +303 -0
  125. data/docs/customizing_page_views.md +84 -0
  126. data/docs/getting_started.md +128 -0
  127. data/docs/rails_api.md +45 -0
  128. data/lib/administrate/base_dashboard.rb +97 -0
  129. data/lib/administrate/custom_dashboard.rb +15 -0
  130. data/lib/administrate/engine.rb +44 -0
  131. data/lib/administrate/field/associative.rb +33 -0
  132. data/lib/administrate/field/base.rb +54 -0
  133. data/lib/administrate/field/belongs_to.rb +38 -0
  134. data/lib/administrate/field/boolean.rb +15 -0
  135. data/lib/administrate/field/date.rb +20 -0
  136. data/lib/administrate/field/date_time.rb +32 -0
  137. data/lib/administrate/field/deferred.rb +44 -0
  138. data/lib/administrate/field/email.rb +11 -0
  139. data/lib/administrate/field/has_many.rb +94 -0
  140. data/lib/administrate/field/has_one.rb +35 -0
  141. data/lib/administrate/field/number.rb +35 -0
  142. data/lib/administrate/field/password.rb +25 -0
  143. data/lib/administrate/field/polymorphic.rb +51 -0
  144. data/lib/administrate/field/select.rb +24 -0
  145. data/lib/administrate/field/string.rb +21 -0
  146. data/lib/administrate/field/text.rb +21 -0
  147. data/lib/administrate/field/time.rb +8 -0
  148. data/lib/administrate/field/url.rb +21 -0
  149. data/lib/administrate/generator_helpers.rb +13 -0
  150. data/lib/administrate/namespace/resource.rb +28 -0
  151. data/lib/administrate/namespace.rb +35 -0
  152. data/lib/administrate/order.rb +88 -0
  153. data/lib/administrate/page/base.rb +41 -0
  154. data/lib/administrate/page/collection.rb +37 -0
  155. data/lib/administrate/page/form.rb +28 -0
  156. data/lib/administrate/page/show.rb +24 -0
  157. data/lib/administrate/page.rb +4 -0
  158. data/lib/administrate/resource_resolver.rb +43 -0
  159. data/lib/administrate/search.rb +157 -0
  160. data/lib/administrate/version.rb +3 -0
  161. data/lib/administrate/view_generator.rb +36 -0
  162. data/lib/administrate.rb +4 -0
  163. data/lib/generators/administrate/assets/assets_generator.rb +12 -0
  164. data/lib/generators/administrate/assets/javascripts_generator.rb +17 -0
  165. data/lib/generators/administrate/assets/stylesheets_generator.rb +17 -0
  166. data/lib/generators/administrate/dashboard/USAGE +9 -0
  167. data/lib/generators/administrate/dashboard/dashboard_generator.rb +143 -0
  168. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +46 -0
  169. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +68 -0
  170. data/lib/generators/administrate/field/field_generator.rb +31 -0
  171. data/lib/generators/administrate/field/templates/_form.html.erb +6 -0
  172. data/lib/generators/administrate/field/templates/_index.html.erb +1 -0
  173. data/lib/generators/administrate/field/templates/_show.html.erb +1 -0
  174. data/lib/generators/administrate/field/templates/field_object.rb.erb +7 -0
  175. data/lib/generators/administrate/install/install_generator.rb +49 -0
  176. data/lib/generators/administrate/install/templates/application_controller.rb.erb +21 -0
  177. data/lib/generators/administrate/routes/routes_generator.rb +96 -0
  178. data/lib/generators/administrate/routes/templates/routes.rb.erb +5 -0
  179. data/lib/generators/administrate/views/edit_generator.rb +16 -0
  180. data/lib/generators/administrate/views/field_generator.rb +50 -0
  181. data/lib/generators/administrate/views/form_generator.rb +15 -0
  182. data/lib/generators/administrate/views/index_generator.rb +16 -0
  183. data/lib/generators/administrate/views/layout_generator.rb +24 -0
  184. data/lib/generators/administrate/views/navigation_generator.rb +15 -0
  185. data/lib/generators/administrate/views/new_generator.rb +16 -0
  186. data/lib/generators/administrate/views/show_generator.rb +15 -0
  187. data/lib/generators/administrate/views/views_generator.rb +14 -0
  188. data/lib/tasks/administrate_tasks.rake +4 -0
  189. metadata +398 -0
@@ -0,0 +1,94 @@
1
+ require_relative "associative"
2
+ require "administrate/page/collection"
3
+ require "administrate/order"
4
+
5
+ module Administrate
6
+ module Field
7
+ class HasMany < Associative
8
+ DEFAULT_LIMIT = 5
9
+
10
+ def self.permitted_attribute(attr, _options = nil)
11
+ { "#{attr.to_s.singularize}_ids".to_sym => [] }
12
+ end
13
+
14
+ def associated_collection(order = self.order)
15
+ Administrate::Page::Collection.new(associated_dashboard, order: order)
16
+ end
17
+
18
+ def attribute_key
19
+ permitted_attribute.keys.first
20
+ end
21
+
22
+ def associated_resource_options
23
+ candidate_resources.map do |resource|
24
+ [display_candidate_resource(resource), resource.send(primary_key)]
25
+ end
26
+ end
27
+
28
+ def selected_options
29
+ return if data.empty?
30
+
31
+ data.map { |object| object.send(primary_key) }
32
+ end
33
+
34
+ def limit
35
+ options.fetch(:limit, DEFAULT_LIMIT)
36
+ end
37
+
38
+ def permitted_attribute
39
+ self.class.permitted_attribute(attribute)
40
+ end
41
+
42
+ def resources(page = 1, order = self.order)
43
+ resources = order.apply(data).page(page).per(limit)
44
+ includes.any? ? resources.includes(*includes) : resources
45
+ end
46
+
47
+ def more_than_limit?
48
+ data.count(:all) > limit
49
+ end
50
+
51
+ def data
52
+ @data ||= associated_class.none
53
+ end
54
+
55
+ def order_from_params(params)
56
+ Administrate::Order.new(
57
+ params.fetch(:order, sort_by),
58
+ params.fetch(:direction, direction),
59
+ )
60
+ end
61
+
62
+ def order
63
+ @order ||= Administrate::Order.new(sort_by, direction)
64
+ end
65
+
66
+ private
67
+
68
+ def includes
69
+ associated_dashboard.collection_includes
70
+ end
71
+
72
+ def candidate_resources
73
+ if options.key?(:includes)
74
+ includes = options.fetch(:includes)
75
+ associated_class.includes(*includes).all
76
+ else
77
+ associated_class.all
78
+ end
79
+ end
80
+
81
+ def display_candidate_resource(resource)
82
+ associated_dashboard.display_resource(resource)
83
+ end
84
+
85
+ def sort_by
86
+ options[:sort_by]
87
+ end
88
+
89
+ def direction
90
+ options[:direction]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "associative"
2
+
3
+ module Administrate
4
+ module Field
5
+ class HasOne < Associative
6
+ def self.permitted_attribute(attr, options = nil)
7
+ associated_class_name =
8
+ if options
9
+ options.fetch(:class_name, attr.to_s.singularize.camelcase)
10
+ else
11
+ attr
12
+ end
13
+ related_dashboard_attributes =
14
+ Administrate::ResourceResolver.new("admin/#{associated_class_name}").
15
+ dashboard_class.new.permitted_attributes + [:id]
16
+
17
+ { "#{attr}_attributes": related_dashboard_attributes }
18
+ end
19
+
20
+ def nested_form
21
+ @nested_form ||= Administrate::Page::Form.new(
22
+ resolver.dashboard_class.new,
23
+ data || resolver.resource_class.new,
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ def resolver
30
+ @resolver ||=
31
+ Administrate::ResourceResolver.new("admin/#{associated_class_name}")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Number < Field::Base
6
+ def to_s
7
+ data.nil? ? "-" : format_string % value
8
+ end
9
+
10
+ private
11
+
12
+ def format_string
13
+ prefix + "%.#{decimals}f" + suffix
14
+ end
15
+
16
+ def prefix
17
+ options[:prefix].to_s
18
+ end
19
+
20
+ def suffix
21
+ options[:suffix].to_s
22
+ end
23
+
24
+ def decimals
25
+ _left, right = data.to_s.split(".")
26
+ default = right.nil? ? 0 : right.size
27
+ options.fetch(:decimals, default)
28
+ end
29
+
30
+ def value
31
+ data * options.fetch(:multiplier, 1)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Password < Field::Base
6
+ def self.searchable?
7
+ false
8
+ end
9
+
10
+ def truncate
11
+ data.to_s.gsub(/./, character)[0...truncation_length]
12
+ end
13
+
14
+ private
15
+
16
+ def truncation_length
17
+ options.fetch(:truncate, 50)
18
+ end
19
+
20
+ def character
21
+ options.fetch(:character, "•")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,51 @@
1
+ require_relative "associative"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Polymorphic < BelongsTo
6
+ def self.permitted_attribute(attr, _options = nil)
7
+ { attr => %i{type value} }
8
+ end
9
+
10
+ def associated_resource_grouped_options
11
+ classes.map do |klass|
12
+ [klass.to_s, candidate_resources_for(klass).map do |resource|
13
+ [display_candidate_resource(resource), resource.to_global_id]
14
+ end]
15
+ end
16
+ end
17
+
18
+ def permitted_attribute
19
+ { attribute => %i{type value} }
20
+ end
21
+
22
+ def selected_global_id
23
+ data ? data.to_global_id : nil
24
+ end
25
+
26
+ protected
27
+
28
+ def associated_dashboard(klass = data.class)
29
+ "#{klass.name}Dashboard".constantize.new
30
+ end
31
+
32
+ def classes
33
+ options.fetch(:classes, [])
34
+ end
35
+
36
+ private
37
+
38
+ def order
39
+ @_order ||= options.delete(:order)
40
+ end
41
+
42
+ def candidate_resources_for(klass)
43
+ order ? klass.order(order) : klass.all
44
+ end
45
+
46
+ def display_candidate_resource(resource)
47
+ associated_dashboard(resource.class).display_resource(resource)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Select < Field::Base
6
+ def self.searchable?
7
+ true
8
+ end
9
+
10
+ def selectable_options
11
+ collection
12
+ end
13
+
14
+ private
15
+
16
+ def collection
17
+ maybe_proc = options.fetch(:collection, [])
18
+ return maybe_proc.call if maybe_proc.respond_to? :call
19
+
20
+ @collection ||= maybe_proc
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class String < Field::Base
6
+ def self.searchable?
7
+ true
8
+ end
9
+
10
+ def truncate
11
+ data.to_s[0...truncation_length]
12
+ end
13
+
14
+ private
15
+
16
+ def truncation_length
17
+ options.fetch(:truncate, 50)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Text < Administrate::Field::Base
6
+ def self.searchable?
7
+ false
8
+ end
9
+
10
+ def truncate
11
+ data.to_s[0...truncation_length]
12
+ end
13
+
14
+ private
15
+
16
+ def truncation_length
17
+ options.fetch(:truncate, 50)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Time < Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Url < Field::Base
6
+ def self.searchable?
7
+ true
8
+ end
9
+
10
+ def truncate
11
+ data.to_s[0...truncation_length]
12
+ end
13
+
14
+ private
15
+
16
+ def truncation_length
17
+ options.fetch(:truncate, 50)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module Administrate
2
+ module GeneratorHelpers
3
+ def call_generator(generator, *args)
4
+ Rails::Generators.invoke(generator, args, generator_options)
5
+ end
6
+
7
+ private
8
+
9
+ def generator_options
10
+ { behavior: behavior }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ module Administrate
2
+ class Namespace
3
+ class Resource
4
+ attr_reader :namespace, :resource
5
+
6
+ def initialize(namespace, resource)
7
+ @namespace = namespace
8
+ @resource = resource
9
+ end
10
+
11
+ def to_s
12
+ name.to_s
13
+ end
14
+
15
+ def to_sym
16
+ name
17
+ end
18
+
19
+ def name
20
+ resource.to_s.gsub(/^#{namespace}\//, "").to_sym
21
+ end
22
+
23
+ def path
24
+ name.to_s.gsub("/", "_")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ module Administrate
2
+ class Namespace
3
+ def initialize(namespace)
4
+ @namespace = namespace
5
+ end
6
+
7
+ def resources
8
+ @resources ||= routes.map(&:first).uniq.map do |path|
9
+ Resource.new(namespace, path)
10
+ end
11
+ end
12
+
13
+ def routes
14
+ @routes ||= all_routes.select do |controller, _action|
15
+ controller.starts_with?("#{namespace}/")
16
+ end.map do |controller, action|
17
+ [controller.gsub(/^#{namespace}\//, ""), action]
18
+ end
19
+ end
20
+
21
+ def resources_with_index_route
22
+ routes.select { |_resource, route| route == "index" }.map(&:first).uniq
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :namespace
28
+
29
+ def all_routes
30
+ Rails.application.routes.routes.map do |route|
31
+ route.defaults.values_at(:controller, :action).map(&:to_s)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,88 @@
1
+ module Administrate
2
+ class Order
3
+ def initialize(attribute = nil, direction = nil)
4
+ @attribute = attribute
5
+ @direction = sanitize_direction(direction)
6
+ end
7
+
8
+ def apply(relation)
9
+ return order_by_association(relation) unless
10
+ reflect_association(relation).nil?
11
+
12
+ order = "#{relation.table_name}.#{attribute} #{direction}"
13
+
14
+ return relation.reorder(Arel.sql(order)) if
15
+ relation.columns_hash.keys.include?(attribute.to_s)
16
+
17
+ relation
18
+ end
19
+
20
+ def ordered_by?(attr)
21
+ attr.to_s == attribute.to_s
22
+ end
23
+
24
+ def order_params_for(attr)
25
+ {
26
+ order: attr,
27
+ direction: reversed_direction_param_for(attr)
28
+ }
29
+ end
30
+
31
+ attr_reader :direction
32
+
33
+ private
34
+
35
+ attr_reader :attribute
36
+
37
+ def sanitize_direction(direction)
38
+ %w[asc desc].include?(direction.to_s) ? direction.to_sym : :asc
39
+ end
40
+
41
+ def reversed_direction_param_for(attr)
42
+ if ordered_by?(attr)
43
+ opposite_direction
44
+ else
45
+ :asc
46
+ end
47
+ end
48
+
49
+ def opposite_direction
50
+ direction == :asc ? :desc : :asc
51
+ end
52
+
53
+ def order_by_association(relation)
54
+ return order_by_count(relation) if has_many_attribute?(relation)
55
+
56
+ return order_by_id(relation) if belongs_to_attribute?(relation)
57
+
58
+ relation
59
+ end
60
+
61
+ def order_by_count(relation)
62
+ relation.
63
+ left_joins(attribute.to_sym).
64
+ group(:id).
65
+ reorder("COUNT(#{attribute}.id) #{direction}")
66
+ end
67
+
68
+ def order_by_id(relation)
69
+ relation.reorder("#{foreign_key(relation)} #{direction}")
70
+ end
71
+
72
+ def has_many_attribute?(relation)
73
+ reflect_association(relation).macro == :has_many
74
+ end
75
+
76
+ def belongs_to_attribute?(relation)
77
+ reflect_association(relation).macro == :belongs_to
78
+ end
79
+
80
+ def reflect_association(relation)
81
+ relation.klass.reflect_on_association(attribute.to_s)
82
+ end
83
+
84
+ def foreign_key(relation)
85
+ reflect_association(relation).foreign_key
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,41 @@
1
+ module Administrate
2
+ module Page
3
+ class Base
4
+ def initialize(dashboard, options = {})
5
+ @dashboard = dashboard
6
+ @options = options
7
+ end
8
+
9
+ def resource_name
10
+ @resource_name ||=
11
+ dashboard.class.to_s.scan(/(.+)Dashboard/).first.first.underscore
12
+ end
13
+
14
+ def resource_path
15
+ @resource_path ||= resource_name.gsub("/", "_")
16
+ end
17
+
18
+ def collection_includes
19
+ dashboard.try(:collection_includes) || []
20
+ end
21
+
22
+ def item_includes
23
+ dashboard.try(:item_includes) || []
24
+ end
25
+
26
+ protected
27
+
28
+ def attribute_field(dashboard, resource, attribute_name, page)
29
+ value = get_attribute_value(resource, attribute_name)
30
+ field = dashboard.attribute_type_for(attribute_name)
31
+ field.new(attribute_name, value, page, resource: resource)
32
+ end
33
+
34
+ def get_attribute_value(resource, attribute_name)
35
+ resource.public_send(attribute_name)
36
+ end
37
+
38
+ attr_reader :dashboard, :options
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Page
5
+ class Collection < Page::Base
6
+ def attribute_names
7
+ dashboard.collection_attributes
8
+ end
9
+
10
+ def attributes_for(resource)
11
+ attribute_names.map do |attr_name|
12
+ attribute_field(dashboard, resource, attr_name, :index)
13
+ end
14
+ end
15
+
16
+ def attribute_types
17
+ dashboard.attribute_types_for(attribute_names)
18
+ end
19
+
20
+ def ordered_html_class(attr)
21
+ ordered_by?(attr) && order.direction
22
+ end
23
+
24
+ delegate :ordered_by?, to: :order
25
+
26
+ def order_params_for(attr, key: resource_name)
27
+ { key => order.order_params_for(attr) }
28
+ end
29
+
30
+ private
31
+
32
+ def order
33
+ options[:order] || Order.new
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Page
5
+ class Form < Page::Base
6
+ def initialize(dashboard, resource)
7
+ super(dashboard)
8
+ @resource = resource
9
+ end
10
+
11
+ attr_reader :resource
12
+
13
+ def attributes
14
+ dashboard.form_attributes.map do |attribute|
15
+ attribute_field(dashboard, resource, attribute, :form)
16
+ end
17
+ end
18
+
19
+ def page_title
20
+ dashboard.display_resource(resource)
21
+ end
22
+
23
+ protected
24
+
25
+ attr_reader :dashboard
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Page
5
+ class Show < Page::Base
6
+ def initialize(dashboard, resource)
7
+ super(dashboard)
8
+ @resource = resource
9
+ end
10
+
11
+ attr_reader :resource
12
+
13
+ def page_title
14
+ dashboard.display_resource(resource)
15
+ end
16
+
17
+ def attributes
18
+ dashboard.show_page_attributes.map do |attr_name|
19
+ attribute_field(dashboard, resource, attr_name, :show)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Administrate
2
+ module Page
3
+ end
4
+ end
@@ -0,0 +1,43 @@
1
+ module Administrate
2
+ class ResourceResolver
3
+ def initialize(controller_path)
4
+ @controller_path = controller_path
5
+ end
6
+
7
+ def dashboard_class
8
+ ActiveSupport::Inflector.constantize("#{resource_class_name}Dashboard")
9
+ end
10
+
11
+ def namespace
12
+ controller_path.split("/").first
13
+ end
14
+
15
+ def resource_class
16
+ ActiveSupport::Inflector.constantize(resource_class_name)
17
+ end
18
+
19
+ def resource_name
20
+ model_path_parts.map(&:underscore).join("__").to_sym
21
+ end
22
+
23
+ def resource_title
24
+ model_path_parts.join(" ")
25
+ end
26
+
27
+ private
28
+
29
+ def resource_class_name
30
+ model_path_parts.join("::")
31
+ end
32
+
33
+ def model_path_parts
34
+ controller_path_parts.map(&:camelize)
35
+ end
36
+
37
+ def controller_path_parts
38
+ controller_path.split("/")[1..-1].map(&:singularize)
39
+ end
40
+
41
+ attr_reader :controller_path
42
+ end
43
+ end