mini-max-mod 0.0.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 (213) hide show
  1. checksums.yaml +7 -0
  2. data/administrate-1.0.0/Rakefile +30 -0
  3. data/administrate-1.0.0/app/assets/builds/administrate/application.css +2614 -0
  4. data/administrate-1.0.0/app/assets/builds/administrate/application.css.map +1 -0
  5. data/administrate-1.0.0/app/assets/builds/administrate/application.js +31661 -0
  6. data/administrate-1.0.0/app/assets/builds/administrate/application.js.map +7 -0
  7. data/administrate-1.0.0/app/assets/builds/administrate-internal/docs.css +102 -0
  8. data/administrate-1.0.0/app/assets/builds/administrate-internal/docs.css.map +1 -0
  9. data/administrate-1.0.0/app/assets/config/administrate_manifest.js +2 -0
  10. data/administrate-1.0.0/app/assets/javascripts/administrate/add_jquery.js +4 -0
  11. data/administrate-1.0.0/app/assets/javascripts/administrate/application.js +9 -0
  12. data/administrate-1.0.0/app/assets/javascripts/administrate/controllers/application.js +9 -0
  13. data/administrate-1.0.0/app/assets/javascripts/administrate/controllers/index.js +9 -0
  14. data/administrate-1.0.0/app/assets/javascripts/administrate/controllers/select_controller.js +25 -0
  15. data/administrate-1.0.0/app/assets/javascripts/administrate/controllers/table_controller.js +23 -0
  16. data/administrate-1.0.0/app/assets/javascripts/administrate/controllers/tooltip_controller.js +24 -0
  17. data/administrate-1.0.0/app/assets/javascripts/administrate/vendor/css-anchor-positioning.js +9310 -0
  18. data/administrate-1.0.0/app/assets/stylesheets/administrate/application.scss +29 -0
  19. data/administrate-1.0.0/app/assets/stylesheets/administrate/base/_forms.scss +107 -0
  20. data/administrate-1.0.0/app/assets/stylesheets/administrate/base/_layout.scss +25 -0
  21. data/administrate-1.0.0/app/assets/stylesheets/administrate/base/_lists.scss +19 -0
  22. data/administrate-1.0.0/app/assets/stylesheets/administrate/base/_tables.scss +58 -0
  23. data/administrate-1.0.0/app/assets/stylesheets/administrate/base/_typography.scss +59 -0
  24. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_app-container.scss +9 -0
  25. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_attributes.scss +28 -0
  26. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_buttons.scss +88 -0
  27. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_cells.scss +54 -0
  28. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_field-unit.scss +56 -0
  29. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_flashes.scss +20 -0
  30. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_form-actions.scss +3 -0
  31. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_main-content.scss +30 -0
  32. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_navigation.scss +32 -0
  33. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_pagination.scss +18 -0
  34. data/administrate-1.0.0/app/assets/stylesheets/administrate/components/_search.scss +87 -0
  35. data/administrate-1.0.0/app/assets/stylesheets/administrate/library/_clearfix.scss +7 -0
  36. data/administrate-1.0.0/app/assets/stylesheets/administrate/library/_data-label.scss +8 -0
  37. data/administrate-1.0.0/app/assets/stylesheets/administrate/library/_variables.scss +69 -0
  38. data/administrate-1.0.0/app/assets/stylesheets/administrate/reset/_normalize.scss +453 -0
  39. data/administrate-1.0.0/app/assets/stylesheets/administrate-internal/docs.scss +95 -0
  40. data/administrate-1.0.0/app/controllers/administrate/application_controller.rb +279 -0
  41. data/administrate-1.0.0/app/controllers/concerns/administrate/punditize.rb +52 -0
  42. data/administrate-1.0.0/app/helpers/administrate/application_helper.rb +101 -0
  43. data/administrate-1.0.0/app/views/administrate/application/_collection.html.erb +102 -0
  44. data/administrate-1.0.0/app/views/administrate/application/_collection_header_actions.html.erb +4 -0
  45. data/administrate-1.0.0/app/views/administrate/application/_collection_item_actions.html.erb +17 -0
  46. data/administrate-1.0.0/app/views/administrate/application/_flashes.html.erb +21 -0
  47. data/administrate-1.0.0/app/views/administrate/application/_form.html.erb +60 -0
  48. data/administrate-1.0.0/app/views/administrate/application/_icons.html.erb +21 -0
  49. data/administrate-1.0.0/app/views/administrate/application/_index_header.html.erb +51 -0
  50. data/administrate-1.0.0/app/views/administrate/application/_javascript.html.erb +21 -0
  51. data/administrate-1.0.0/app/views/administrate/application/_navigation.html.erb +20 -0
  52. data/administrate-1.0.0/app/views/administrate/application/_pagination.html.erb +1 -0
  53. data/administrate-1.0.0/app/views/administrate/application/_search.html.erb +25 -0
  54. data/administrate-1.0.0/app/views/administrate/application/_stylesheet.html.erb +14 -0
  55. data/administrate-1.0.0/app/views/administrate/application/edit.html.erb +48 -0
  56. data/administrate-1.0.0/app/views/administrate/application/index.html.erb +55 -0
  57. data/administrate-1.0.0/app/views/administrate/application/new.html.erb +49 -0
  58. data/administrate-1.0.0/app/views/administrate/application/show.html.erb +77 -0
  59. data/administrate-1.0.0/app/views/fields/belongs_to/_form.html.erb +27 -0
  60. data/administrate-1.0.0/app/views/fields/belongs_to/_index.html.erb +27 -0
  61. data/administrate-1.0.0/app/views/fields/belongs_to/_show.html.erb +27 -0
  62. data/administrate-1.0.0/app/views/fields/boolean/_form.html.erb +23 -0
  63. data/administrate-1.0.0/app/views/fields/boolean/_index.html.erb +19 -0
  64. data/administrate-1.0.0/app/views/fields/boolean/_show.html.erb +19 -0
  65. data/administrate-1.0.0/app/views/fields/date/_form.html.erb +22 -0
  66. data/administrate-1.0.0/app/views/fields/date/_index.html.erb +21 -0
  67. data/administrate-1.0.0/app/views/fields/date/_show.html.erb +21 -0
  68. data/administrate-1.0.0/app/views/fields/date_time/_form.html.erb +22 -0
  69. data/administrate-1.0.0/app/views/fields/date_time/_index.html.erb +21 -0
  70. data/administrate-1.0.0/app/views/fields/date_time/_show.html.erb +21 -0
  71. data/administrate-1.0.0/app/views/fields/email/_form.html.erb +23 -0
  72. data/administrate-1.0.0/app/views/fields/email/_index.html.erb +18 -0
  73. data/administrate-1.0.0/app/views/fields/email/_show.html.erb +18 -0
  74. data/administrate-1.0.0/app/views/fields/has_many/_form.html.erb +29 -0
  75. data/administrate-1.0.0/app/views/fields/has_many/_index.html.erb +19 -0
  76. data/administrate-1.0.0/app/views/fields/has_many/_show.html.erb +39 -0
  77. data/administrate-1.0.0/app/views/fields/has_one/_form.html.erb +44 -0
  78. data/administrate-1.0.0/app/views/fields/has_one/_index.html.erb +24 -0
  79. data/administrate-1.0.0/app/views/fields/has_one/_show.html.erb +47 -0
  80. data/administrate-1.0.0/app/views/fields/number/_form.html.erb +23 -0
  81. data/administrate-1.0.0/app/views/fields/number/_index.html.erb +19 -0
  82. data/administrate-1.0.0/app/views/fields/number/_show.html.erb +19 -0
  83. data/administrate-1.0.0/app/views/fields/password/_form.html.erb +23 -0
  84. data/administrate-1.0.0/app/views/fields/password/_index.html.erb +18 -0
  85. data/administrate-1.0.0/app/views/fields/password/_show.html.erb +18 -0
  86. data/administrate-1.0.0/app/views/fields/polymorphic/_form.html.erb +29 -0
  87. data/administrate-1.0.0/app/views/fields/polymorphic/_index.html.erb +25 -0
  88. data/administrate-1.0.0/app/views/fields/polymorphic/_show.html.erb +28 -0
  89. data/administrate-1.0.0/app/views/fields/rich_text/_form.html.erb +22 -0
  90. data/administrate-1.0.0/app/views/fields/rich_text/_index.html.erb +18 -0
  91. data/administrate-1.0.0/app/views/fields/rich_text/_show.html.erb +18 -0
  92. data/administrate-1.0.0/app/views/fields/select/_form.html.erb +33 -0
  93. data/administrate-1.0.0/app/views/fields/select/_index.html.erb +16 -0
  94. data/administrate-1.0.0/app/views/fields/select/_show.html.erb +16 -0
  95. data/administrate-1.0.0/app/views/fields/string/_form.html.erb +23 -0
  96. data/administrate-1.0.0/app/views/fields/string/_index.html.erb +18 -0
  97. data/administrate-1.0.0/app/views/fields/string/_show.html.erb +18 -0
  98. data/administrate-1.0.0/app/views/fields/text/_form.html.erb +22 -0
  99. data/administrate-1.0.0/app/views/fields/text/_index.html.erb +18 -0
  100. data/administrate-1.0.0/app/views/fields/text/_show.html.erb +18 -0
  101. data/administrate-1.0.0/app/views/fields/time/_form.html.erb +22 -0
  102. data/administrate-1.0.0/app/views/fields/time/_index.html.erb +19 -0
  103. data/administrate-1.0.0/app/views/fields/time/_show.html.erb +19 -0
  104. data/administrate-1.0.0/app/views/fields/url/_form.html.erb +23 -0
  105. data/administrate-1.0.0/app/views/fields/url/_index.html.erb +20 -0
  106. data/administrate-1.0.0/app/views/fields/url/_show.html.erb +20 -0
  107. data/administrate-1.0.0/app/views/layouts/administrate/application.html.erb +41 -0
  108. data/administrate-1.0.0/config/locales/administrate.ar.yml +30 -0
  109. data/administrate-1.0.0/config/locales/administrate.bs.yml +29 -0
  110. data/administrate-1.0.0/config/locales/administrate.ca.yml +30 -0
  111. data/administrate-1.0.0/config/locales/administrate.da.yml +30 -0
  112. data/administrate-1.0.0/config/locales/administrate.de.yml +30 -0
  113. data/administrate-1.0.0/config/locales/administrate.en.yml +30 -0
  114. data/administrate-1.0.0/config/locales/administrate.es.yml +30 -0
  115. data/administrate-1.0.0/config/locales/administrate.fi.yml +30 -0
  116. data/administrate-1.0.0/config/locales/administrate.fr.yml +30 -0
  117. data/administrate-1.0.0/config/locales/administrate.id.yml +30 -0
  118. data/administrate-1.0.0/config/locales/administrate.it.yml +30 -0
  119. data/administrate-1.0.0/config/locales/administrate.ja.yml +30 -0
  120. data/administrate-1.0.0/config/locales/administrate.ko.yml +30 -0
  121. data/administrate-1.0.0/config/locales/administrate.nl.yml +30 -0
  122. data/administrate-1.0.0/config/locales/administrate.pl.yml +30 -0
  123. data/administrate-1.0.0/config/locales/administrate.pt-BR.yml +31 -0
  124. data/administrate-1.0.0/config/locales/administrate.pt.yml +31 -0
  125. data/administrate-1.0.0/config/locales/administrate.ru.yml +30 -0
  126. data/administrate-1.0.0/config/locales/administrate.sl.yml +30 -0
  127. data/administrate-1.0.0/config/locales/administrate.sq.yml +30 -0
  128. data/administrate-1.0.0/config/locales/administrate.sv.yml +30 -0
  129. data/administrate-1.0.0/config/locales/administrate.tr.yml +30 -0
  130. data/administrate-1.0.0/config/locales/administrate.uk.yml +30 -0
  131. data/administrate-1.0.0/config/locales/administrate.vi.yml +30 -0
  132. data/administrate-1.0.0/config/locales/administrate.zh-CN.yml +30 -0
  133. data/administrate-1.0.0/config/locales/administrate.zh-TW.yml +30 -0
  134. data/administrate-1.0.0/docs/adding_controllers_without_related_model.md +52 -0
  135. data/administrate-1.0.0/docs/adding_custom_field_types.md +81 -0
  136. data/administrate-1.0.0/docs/authentication.md +63 -0
  137. data/administrate-1.0.0/docs/authorization.md +94 -0
  138. data/administrate-1.0.0/docs/customizing_attribute_partials.md +56 -0
  139. data/administrate-1.0.0/docs/customizing_controller_actions.md +109 -0
  140. data/administrate-1.0.0/docs/customizing_dashboards.md +641 -0
  141. data/administrate-1.0.0/docs/customizing_page_views.md +143 -0
  142. data/administrate-1.0.0/docs/extending_administrate.md +27 -0
  143. data/administrate-1.0.0/docs/getting_started.md +150 -0
  144. data/administrate-1.0.0/docs/guides/customising_search.md +149 -0
  145. data/administrate-1.0.0/docs/guides/hiding_dashboards_from_sidebar.md +21 -0
  146. data/administrate-1.0.0/docs/guides/scoping_has_many_relations.md +27 -0
  147. data/administrate-1.0.0/docs/guides/switching_templates_with_view_variants.md +45 -0
  148. data/administrate-1.0.0/docs/guides.md +8 -0
  149. data/administrate-1.0.0/docs/migrating-to-v1.md +34 -0
  150. data/administrate-1.0.0/docs/rails_api.md +45 -0
  151. data/administrate-1.0.0/lib/administrate/base_dashboard.rb +145 -0
  152. data/administrate-1.0.0/lib/administrate/custom_dashboard.rb +15 -0
  153. data/administrate-1.0.0/lib/administrate/engine.rb +52 -0
  154. data/administrate-1.0.0/lib/administrate/field/associative.rb +72 -0
  155. data/administrate-1.0.0/lib/administrate/field/base.rb +119 -0
  156. data/administrate-1.0.0/lib/administrate/field/belongs_to.rb +55 -0
  157. data/administrate-1.0.0/lib/administrate/field/boolean.rb +15 -0
  158. data/administrate-1.0.0/lib/administrate/field/date.rb +24 -0
  159. data/administrate-1.0.0/lib/administrate/field/date_time.rb +31 -0
  160. data/administrate-1.0.0/lib/administrate/field/deferred.rb +59 -0
  161. data/administrate-1.0.0/lib/administrate/field/email.rb +11 -0
  162. data/administrate-1.0.0/lib/administrate/field/has_many.rb +140 -0
  163. data/administrate-1.0.0/lib/administrate/field/has_one.rb +55 -0
  164. data/administrate-1.0.0/lib/administrate/field/number.rb +46 -0
  165. data/administrate-1.0.0/lib/administrate/field/password.rb +29 -0
  166. data/administrate-1.0.0/lib/administrate/field/polymorphic.rb +52 -0
  167. data/administrate-1.0.0/lib/administrate/field/rich_text.rb +21 -0
  168. data/administrate-1.0.0/lib/administrate/field/select.rb +44 -0
  169. data/administrate-1.0.0/lib/administrate/field/string.rb +21 -0
  170. data/administrate-1.0.0/lib/administrate/field/text.rb +21 -0
  171. data/administrate-1.0.0/lib/administrate/field/time.rb +20 -0
  172. data/administrate-1.0.0/lib/administrate/field/url.rb +25 -0
  173. data/administrate-1.0.0/lib/administrate/generator_helpers.rb +13 -0
  174. data/administrate-1.0.0/lib/administrate/namespace/resource.rb +28 -0
  175. data/administrate-1.0.0/lib/administrate/namespace.rb +35 -0
  176. data/administrate-1.0.0/lib/administrate/not_authorized_error.rb +20 -0
  177. data/administrate-1.0.0/lib/administrate/order.rb +150 -0
  178. data/administrate-1.0.0/lib/administrate/page/base.rb +40 -0
  179. data/administrate-1.0.0/lib/administrate/page/collection.rb +38 -0
  180. data/administrate-1.0.0/lib/administrate/page/form.rb +36 -0
  181. data/administrate-1.0.0/lib/administrate/page/show.rb +32 -0
  182. data/administrate-1.0.0/lib/administrate/page.rb +4 -0
  183. data/administrate-1.0.0/lib/administrate/resource_resolver.rb +44 -0
  184. data/administrate-1.0.0/lib/administrate/search.rb +167 -0
  185. data/administrate-1.0.0/lib/administrate/version.rb +3 -0
  186. data/administrate-1.0.0/lib/administrate/view_generator.rb +48 -0
  187. data/administrate-1.0.0/lib/administrate.rb +8 -0
  188. data/administrate-1.0.0/lib/generators/administrate/dashboard/USAGE +9 -0
  189. data/administrate-1.0.0/lib/generators/administrate/dashboard/dashboard_generator.rb +168 -0
  190. data/administrate-1.0.0/lib/generators/administrate/dashboard/templates/controller.rb.erb +46 -0
  191. data/administrate-1.0.0/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +68 -0
  192. data/administrate-1.0.0/lib/generators/administrate/field/field_generator.rb +31 -0
  193. data/administrate-1.0.0/lib/generators/administrate/field/templates/_form.html.erb +6 -0
  194. data/administrate-1.0.0/lib/generators/administrate/field/templates/_index.html.erb +1 -0
  195. data/administrate-1.0.0/lib/generators/administrate/field/templates/_show.html.erb +1 -0
  196. data/administrate-1.0.0/lib/generators/administrate/field/templates/field_object.rb.erb +7 -0
  197. data/administrate-1.0.0/lib/generators/administrate/install/install_generator.rb +91 -0
  198. data/administrate-1.0.0/lib/generators/administrate/install/templates/application_controller.rb.erb +21 -0
  199. data/administrate-1.0.0/lib/generators/administrate/routes/routes_generator.rb +96 -0
  200. data/administrate-1.0.0/lib/generators/administrate/routes/templates/routes.rb.erb +5 -0
  201. data/administrate-1.0.0/lib/generators/administrate/test_record.rb +21 -0
  202. data/administrate-1.0.0/lib/generators/administrate/views/edit_generator.rb +16 -0
  203. data/administrate-1.0.0/lib/generators/administrate/views/field_generator.rb +50 -0
  204. data/administrate-1.0.0/lib/generators/administrate/views/form_generator.rb +15 -0
  205. data/administrate-1.0.0/lib/generators/administrate/views/index_generator.rb +21 -0
  206. data/administrate-1.0.0/lib/generators/administrate/views/layout_generator.rb +24 -0
  207. data/administrate-1.0.0/lib/generators/administrate/views/navigation_generator.rb +15 -0
  208. data/administrate-1.0.0/lib/generators/administrate/views/new_generator.rb +16 -0
  209. data/administrate-1.0.0/lib/generators/administrate/views/show_generator.rb +15 -0
  210. data/administrate-1.0.0/lib/generators/administrate/views/views_generator.rb +15 -0
  211. data/administrate-1.0.0/lib/tasks/administrate_tasks.rake +4 -0
  212. data/mini-max-mod.gemspec +12 -0
  213. metadata +252 -0
@@ -0,0 +1,279 @@
1
+ module Administrate
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+
5
+ def index
6
+ authorize_resource(resource_class)
7
+ search_term = params[:search].to_s.strip
8
+ resources = filter_resources(scoped_resource, search_term: search_term)
9
+ resources = apply_collection_includes(resources)
10
+ resources = order.apply(resources)
11
+ resources = paginate_resources(resources)
12
+ page = Administrate::Page::Collection.new(dashboard, order: order)
13
+ filters = Administrate::Search.new(scoped_resource, dashboard, search_term).valid_filters
14
+
15
+ render locals: {
16
+ resources: resources,
17
+ search_term: search_term,
18
+ page: page,
19
+ show_search_bar: show_search_bar?,
20
+ filters: filters
21
+ }
22
+ end
23
+
24
+ def show
25
+ render locals: {
26
+ page: Administrate::Page::Show.new(dashboard, requested_resource)
27
+ }
28
+ end
29
+
30
+ def new
31
+ resource = new_resource
32
+ authorize_resource(resource)
33
+ render locals: {
34
+ page: Administrate::Page::Form.new(dashboard, resource)
35
+ }
36
+ end
37
+
38
+ def edit
39
+ render locals: {
40
+ page: Administrate::Page::Form.new(dashboard, requested_resource)
41
+ }
42
+ end
43
+
44
+ def create
45
+ resource = new_resource(resource_params)
46
+ authorize_resource(resource)
47
+
48
+ if resource.save
49
+ yield(resource) if block_given?
50
+ redirect_to(
51
+ after_resource_created_path(resource),
52
+ notice: translate_with_resource("create.success")
53
+ )
54
+ else
55
+ render :new, locals: {
56
+ page: Administrate::Page::Form.new(dashboard, resource)
57
+ }, status: :unprocessable_entity
58
+ end
59
+ end
60
+
61
+ def update
62
+ if requested_resource.update(resource_params)
63
+ redirect_to(
64
+ after_resource_updated_path(requested_resource),
65
+ notice: translate_with_resource("update.success"),
66
+ status: :see_other
67
+ )
68
+ else
69
+ render :edit, locals: {
70
+ page: Administrate::Page::Form.new(dashboard, requested_resource)
71
+ }, status: :unprocessable_entity
72
+ end
73
+ end
74
+
75
+ def destroy
76
+ if requested_resource.destroy
77
+ flash[:notice] = translate_with_resource("destroy.success")
78
+ else
79
+ flash[:error] = requested_resource.errors.full_messages.join("<br/>")
80
+ end
81
+ redirect_to after_resource_destroyed_path(requested_resource), status: :see_other
82
+ end
83
+
84
+ private
85
+
86
+ def filter_resources(resources, search_term:)
87
+ Administrate::Search.new(
88
+ resources,
89
+ dashboard,
90
+ search_term
91
+ ).run
92
+ end
93
+
94
+ def after_resource_destroyed_path(_requested_resource)
95
+ {action: :index}
96
+ end
97
+
98
+ def after_resource_created_path(requested_resource)
99
+ [namespace, requested_resource]
100
+ end
101
+
102
+ def after_resource_updated_path(requested_resource)
103
+ [namespace, requested_resource]
104
+ end
105
+
106
+ helper_method :nav_link_state
107
+ def nav_link_state(resource)
108
+ underscore_resource = resource.to_s.split("/").join("__")
109
+ (resource_name.to_s.pluralize == underscore_resource) ? :active : :inactive
110
+ end
111
+
112
+ # Whether the named action route exists for the resource class.
113
+ #
114
+ # @param resource [Class, String, Symbol] A class of resources, or the name
115
+ # of a class of resources.
116
+ # @param action_name [String, Symbol] The name of an action that might be
117
+ # possible to perform on a resource or resource class.
118
+ # @return [Boolean] `true` if a route exists for the resource class and the
119
+ # action. `false` otherwise.
120
+ def existing_action?(resource, action_name)
121
+ routes.include?([resource.to_s.underscore.pluralize, action_name.to_s])
122
+ end
123
+ helper_method :existing_action?
124
+
125
+ def routes
126
+ @routes ||= Namespace.new(namespace).routes.to_set
127
+ end
128
+
129
+ def records_per_page
130
+ params[:per_page] || 20
131
+ end
132
+
133
+ def order
134
+ @order ||= Administrate::Order.new(
135
+ sorting_attribute,
136
+ sorting_direction,
137
+ sorting_column: sorting_column(
138
+ dashboard_attribute(sorting_attribute)
139
+ )
140
+ )
141
+ end
142
+
143
+ def sorting_column(dashboard_attribute)
144
+ return unless dashboard_attribute.try(:options)
145
+
146
+ dashboard_attribute.options.fetch(:sorting_column) {
147
+ dashboard_attribute.options.fetch(:order, nil)
148
+ }
149
+ end
150
+
151
+ def dashboard_attribute(attribute)
152
+ dashboard.attribute_types[attribute.to_sym] if attribute
153
+ end
154
+
155
+ def sorting_attribute
156
+ sorting_params.fetch(:order) { default_sorting_attribute }
157
+ end
158
+
159
+ def default_sorting_attribute
160
+ nil
161
+ end
162
+
163
+ def sorting_direction
164
+ sorting_params.fetch(:direction) { default_sorting_direction }
165
+ end
166
+
167
+ def default_sorting_direction
168
+ nil
169
+ end
170
+
171
+ def sorting_params
172
+ Hash.try_convert(request.query_parameters[resource_name]) || {}
173
+ end
174
+
175
+ def dashboard
176
+ @dashboard ||= dashboard_class.new
177
+ end
178
+
179
+ def requested_resource
180
+ @requested_resource ||= find_resource(params[:id]).tap do |resource|
181
+ authorize_resource(resource)
182
+ end
183
+ end
184
+
185
+ def find_resource(param)
186
+ scoped_resource.find(param)
187
+ end
188
+
189
+ def scoped_resource
190
+ resource_class.default_scoped
191
+ end
192
+
193
+ def apply_collection_includes(relation)
194
+ resource_includes = dashboard.collection_includes
195
+ return relation if resource_includes.empty?
196
+ relation.includes(*resource_includes)
197
+ end
198
+
199
+ def resource_params
200
+ params.require(resource_class.model_name.param_key)
201
+ .permit(dashboard.permitted_attributes(action_name))
202
+ .transform_values { |v| read_param_value(v) }
203
+ end
204
+
205
+ def read_param_value(data)
206
+ if data.is_a?(ActionController::Parameters) && data[:type]
207
+ if data[:type] == Administrate::Field::Polymorphic.to_s
208
+ GlobalID::Locator.locate(data[:value])
209
+ else
210
+ raise "Unrecognised param data: #{data.inspect}"
211
+ end
212
+ elsif data.is_a?(ActionController::Parameters)
213
+ data.transform_values { |v| read_param_value(v) }
214
+ elsif data.is_a?(String) && data.blank?
215
+ nil
216
+ else
217
+ data
218
+ end
219
+ end
220
+
221
+ delegate :dashboard_class, :resource_class, :resource_name, :namespace,
222
+ to: :resource_resolver
223
+ helper_method :namespace
224
+ helper_method :resource_name
225
+ helper_method :resource_class
226
+
227
+ def resource_resolver
228
+ @resource_resolver ||=
229
+ Administrate::ResourceResolver.new(controller_path)
230
+ end
231
+
232
+ def translate_with_resource(key)
233
+ t(
234
+ "administrate.controller.#{key}",
235
+ resource: resource_resolver.resource_title
236
+ )
237
+ end
238
+
239
+ def show_search_bar?
240
+ dashboard.attribute_types_for(
241
+ dashboard.all_attributes
242
+ ).any? { |_name, attribute| attribute.searchable? }
243
+ end
244
+
245
+ # Whether the current user is authorized to perform the named action on the
246
+ # resource.
247
+ #
248
+ # @param _resource [ActiveRecord::Base, Class, String, Symbol] The
249
+ # temptative target of the action, or the name of its class.
250
+ # @param _action_name [String, Symbol] The name of an action that might be
251
+ # possible to perform on a resource or resource class.
252
+ # @return [Boolean] `true` if the current user is authorized to perform the
253
+ # action on the resource. `false` otherwise.
254
+ def authorized_action?(_resource, _action_name)
255
+ true
256
+ end
257
+ helper_method :authorized_action?
258
+
259
+ def new_resource(params = {})
260
+ resource_class.new(params)
261
+ end
262
+ helper_method :new_resource
263
+
264
+ def authorize_resource(resource)
265
+ if authorized_action?(resource, action_name)
266
+ resource
267
+ else
268
+ raise Administrate::NotAuthorizedError.new(
269
+ action: action_name,
270
+ resource: resource
271
+ )
272
+ end
273
+ end
274
+
275
+ def paginate_resources(resources)
276
+ resources.page(params[:_page]).per(records_per_page)
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,52 @@
1
+ module Administrate
2
+ module Punditize
3
+ if Object.const_defined?(:Pundit)
4
+ extend ActiveSupport::Concern
5
+
6
+ if Pundit.const_defined?(:Authorization)
7
+ include Pundit::Authorization
8
+ else
9
+ include Pundit
10
+ end
11
+
12
+ private
13
+
14
+ def policy_namespace
15
+ []
16
+ end
17
+
18
+ def scoped_resource
19
+ namespaced_scope = policy_namespace + [super]
20
+ policy_scope!(pundit_user, namespaced_scope)
21
+ end
22
+
23
+ def authorize_resource(resource)
24
+ namespaced_resource = policy_namespace + [resource]
25
+ authorize namespaced_resource
26
+ end
27
+
28
+ def authorized_action?(resource, action)
29
+ namespaced_resource = policy_namespace + [resource]
30
+ policy = Pundit.policy!(pundit_user, namespaced_resource)
31
+ policy.send(:"#{action}?")
32
+ end
33
+
34
+ def policy_scope!(user, scope)
35
+ policy_scope_class = Pundit::PolicyFinder.new(scope).scope!
36
+
37
+ begin
38
+ policy_scope = policy_scope_class.new(user, pundit_model(scope))
39
+ rescue ArgumentError
40
+ raise(Pundit::InvalidConstructorError,
41
+ "Invalid #<#{policy_scope_class}> constructor is called")
42
+ end
43
+
44
+ policy_scope.resolve
45
+ end
46
+
47
+ def pundit_model(record)
48
+ record.is_a?(Array) ? record.last : record
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,101 @@
1
+ module Administrate
2
+ module ApplicationHelper
3
+ PLURAL_MANY_COUNT = 2.1
4
+ SINGULAR_COUNT = 1
5
+
6
+ def application_title
7
+ Rails.application.class.module_parent_name.titlecase
8
+ end
9
+
10
+ def render_field(field, locals = {})
11
+ locals[:field] = field
12
+ if (prefix = find_partial_prefix(field))
13
+ render locals: locals, partial: "#{prefix}/#{field.page}"
14
+ end
15
+ end
16
+
17
+ def find_partial_prefix(field)
18
+ field.partial_prefixes.detect do |prefix|
19
+ lookup_context.template_exists?(field.page, [prefix], true)
20
+ end
21
+ end
22
+
23
+ def requireness(field)
24
+ field.required? ? "required" : "optional"
25
+ end
26
+
27
+ def dashboard_from_resource(resource_name)
28
+ "#{resource_name.to_s.singularize}_dashboard".classify.constantize
29
+ end
30
+
31
+ def model_from_resource(resource_name)
32
+ dashboard = dashboard_from_resource(resource_name)
33
+ dashboard.try(:model) || resource_name.to_sym
34
+ end
35
+
36
+ # Unification of
37
+ # {Administrate::ApplicationController#existing_action? existing_action?}
38
+ # and
39
+ # {Administrate::ApplicationController#authorized_action?
40
+ # authorized_action?}
41
+ #
42
+ # @param target [ActiveRecord::Base, Class, Symbol, String] A resource,
43
+ # a class of resources, or the name of a class of resources.
44
+ # @param action_name [String, Symbol] The name of an action that might be
45
+ # possible to perform on a resource or resource class.
46
+ # @return [Boolean] Whether the action both (a) exists for the record class,
47
+ # and (b) the current user is authorized to perform it on the record
48
+ # instance or class.
49
+ def accessible_action?(target, action_name)
50
+ target = target.to_sym if target.is_a?(String)
51
+ target_class_or_class_name =
52
+ target.is_a?(ActiveRecord::Base) ? target.class : target
53
+
54
+ existing_action?(target_class_or_class_name, action_name) &&
55
+ authorized_action?(target, action_name)
56
+ end
57
+
58
+ def display_resource_name(resource_name, opts = {})
59
+ dashboard_from_resource(resource_name).resource_name(
60
+ count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
61
+ default: default_resource_name(resource_name, opts)
62
+ )
63
+ end
64
+
65
+ def sort_order(order)
66
+ case order
67
+ when "asc" then "ascending"
68
+ when "desc" then "descending"
69
+ else "none"
70
+ end
71
+ end
72
+
73
+ def resource_index_route(resource_name)
74
+ url_for(
75
+ action: "index",
76
+ controller: "/#{namespace}/#{resource_name}"
77
+ )
78
+ end
79
+
80
+ def sanitized_order_params(page, current_field_name)
81
+ collection_names = page.item_associations + [current_field_name]
82
+ association_params = collection_names.map do |assoc_name|
83
+ {assoc_name => %i[order direction page per_page]}
84
+ end
85
+ params.permit(:search, :id, :_page, :per_page, association_params)
86
+ end
87
+
88
+ def clear_search_params
89
+ params.except(:search, :_page).permit(
90
+ :per_page, resource_name => %i[order direction]
91
+ )
92
+ end
93
+
94
+ private
95
+
96
+ def default_resource_name(name, opts = {})
97
+ resource_name = (opts[:singular] ? name.to_s : name.to_s.pluralize)
98
+ resource_name.tr("/", "_").titleize
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,102 @@
1
+ <%#
2
+ # Collection
3
+
4
+ This partial is used on the `index` and `show` pages
5
+ to display a collection of resources in an HTML table.
6
+
7
+ ## Local variables:
8
+
9
+ - `collection_presenter`:
10
+ An instance of [Administrate::Page::Collection][1].
11
+ The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine
12
+ the columns displayed in the table
13
+ - `resources`:
14
+ An ActiveModel::Relation collection of resources to be displayed in the table.
15
+ By default, the number of resources is limited by pagination
16
+ or by a hard limit to prevent excessive page load times
17
+
18
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
19
+ %>
20
+
21
+ <table aria-labelledby="<%= table_title %>" data-controller="table" data-action="click->table#visitDataUrl keydown->table#visitDataUrl">
22
+ <thead>
23
+ <tr>
24
+ <% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
25
+ <th class="cell-label
26
+ cell-label--<%= attr_type.html_class %>
27
+ cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>
28
+ cell-label--<%= "#{collection_presenter.resource_name}_#{attr_name}" %>"
29
+ scope="col"
30
+ <% if attr_type.sortable? %>
31
+ aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>"
32
+ <% end %>
33
+ >
34
+ <% if attr_type.sortable? %>
35
+ <%= link_to(params: sanitized_order_params(page, collection_field_name).merge(
36
+ collection_presenter.order_params_for(attr_name, key: collection_field_name)
37
+ )) do %>
38
+ <%= t(
39
+ "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
40
+ default: resource_class.human_attribute_name(attr_name).titleize,
41
+ ) %>
42
+ <% if collection_presenter.ordered_by?(attr_name) %>
43
+ <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
44
+ <svg aria-hidden="true">
45
+ <use xlink:href="#icon-up-caret" />
46
+ </svg>
47
+ </span>
48
+ <% end %>
49
+ <% end %>
50
+ <% else %>
51
+ <%= t(
52
+ "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
53
+ default: resource_class.human_attribute_name(attr_name).titleize,
54
+ ) %>
55
+ <% end %>
56
+ </th>
57
+ <% end %>
58
+ <%= render(
59
+ "collection_header_actions",
60
+ collection_presenter: collection_presenter,
61
+ page: page,
62
+ resources: resources,
63
+ table_title: "page-title"
64
+ ) %>
65
+ </tr>
66
+ </thead>
67
+
68
+ <tbody>
69
+ <% resources.each do |resource| %>
70
+ <tr class="js-table-row"
71
+ <% if accessible_action?(resource, :show) %>
72
+ <%= %(tabindex=0 data-url=#{polymorphic_path([namespace, resource])}) %>
73
+ <% end %>
74
+ >
75
+ <% collection_presenter.attributes_for(resource).each do |attribute| %>
76
+ <td class="cell-data cell-data--<%= attribute.html_class %>">
77
+ <% if accessible_action?(resource, :show) -%>
78
+ <a href="<%= polymorphic_path([namespace, resource]) -%>"
79
+ tabindex="-1"
80
+ class="action-show"
81
+ >
82
+ <%= render_field attribute %>
83
+ </a>
84
+ <% else %>
85
+ <%= render_field attribute %>
86
+ <% end -%>
87
+ </td>
88
+ <% end %>
89
+
90
+ <%= render(
91
+ "collection_item_actions",
92
+ collection_presenter: collection_presenter,
93
+ collection_field_name: collection_field_name,
94
+ page: page,
95
+ namespace: namespace,
96
+ resource: resource,
97
+ table_title: "page-title"
98
+ ) %>
99
+ </tr>
100
+ <% end %>
101
+ </tbody>
102
+ </table>
@@ -0,0 +1,4 @@
1
+ <% [existing_action?(collection_presenter.resource_name, :edit),
2
+ existing_action?(collection_presenter.resource_name, :destroy)].count(true).times do %>
3
+ <th scope="col" class="cell-label--action-button"></th>
4
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <% if existing_action?(collection_presenter.resource_name, :edit) %>
2
+ <td class="cell-label--action-button"><%= link_to(
3
+ t("administrate.actions.edit"),
4
+ [:edit, namespace, resource],
5
+ class: "action-edit",
6
+ ) if accessible_action?(resource, :edit) %></td>
7
+ <% end %>
8
+
9
+ <% if existing_action?(collection_presenter.resource_name, :destroy) %>
10
+ <td class="cell-label--action-button"><%= button_to(
11
+ t("administrate.actions.destroy"),
12
+ [namespace, resource],
13
+ class: "link link--danger",
14
+ method: :delete,
15
+ data: { turbo_confirm: t("administrate.actions.confirm") }
16
+ ) if accessible_action?(resource, :destroy) %></td>
17
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <%#
2
+ # Flash Partial
3
+
4
+ This partial renders flash messages on every page.
5
+
6
+ ## Relevant Helpers:
7
+
8
+ - `flash`:
9
+ Returns a hash,
10
+ where the keys are the type of flash (alert, error, notice, etc)
11
+ and the values are the message to be displayed.
12
+ %>
13
+
14
+ <% if flash.any? %>
15
+ <div class="flashes">
16
+ <% flash.each do |key, value| -%>
17
+ <% next unless value.respond_to?(:html_safe) %>
18
+ <div class="flash flash-<%= key %>"><%= value.html_safe %></div>
19
+ <% end -%>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1,60 @@
1
+ <%#
2
+ # Form Partial
3
+
4
+ This partial is rendered on a resource's `new` and `edit` pages,
5
+ and renders all form fields for a resource's editable attributes.
6
+
7
+ ## Local variables:
8
+
9
+ - `page`:
10
+ An instance of [Administrate::Page::Form][1].
11
+ Contains helper methods to display a form,
12
+ and knows which attributes should be displayed in the resource's form.
13
+
14
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
15
+ %>
16
+
17
+ <%= form_with(model: page.resource, url: [namespace, page.resource], scope: page.resource, local: true, class: "form") do |f| %>
18
+ <% if page.resource.errors.any? %>
19
+ <div id="error_explanation">
20
+ <h2>
21
+ <%= t(
22
+ "administrate.form.errors",
23
+ pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
24
+ resource_name: display_resource_name(page.resource_name, singular: true)
25
+ ) %>
26
+ </h2>
27
+
28
+ <ul>
29
+ <% page.resource.errors.full_messages.each do |message| %>
30
+ <li class="flash-error"><%= message %></li>
31
+ <% end %>
32
+ </ul>
33
+ </div>
34
+ <% end %>
35
+
36
+ <% page.attributes(controller.action_name).each do |title, attributes| -%>
37
+ <fieldset class="<%= "field-unit--nested" if title.present? %>">
38
+ <% if title.present? %>
39
+ <legend><%= t "helpers.label.#{f.object_name}.#{title}", default: title %></legend>
40
+ <% end %>
41
+
42
+ <% attributes.each do |attribute| %>
43
+ <div class="field-unit field-unit--<%= attribute.html_class %> field-unit--<%= requireness(attribute) %>">
44
+ <%= render_field attribute, f: f %>
45
+
46
+ <% hint_key = "administrate.field_hints.#{page.resource_name}.#{attribute.name}" %>
47
+ <% if I18n.exists?(hint_key) -%>
48
+ <div class="field-unit__hint">
49
+ <%= I18n.t(hint_key) %>
50
+ </div>
51
+ <% end -%>
52
+ </div>
53
+ <% end %>
54
+ </fieldset>
55
+ <% end -%>
56
+
57
+ <div class="form-actions">
58
+ <%= f.submit %>
59
+ </div>
60
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <svg hidden xmlns="http://www.w3.org/2000/svg">
2
+ <symbol id="icon-cancel" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3
+ <circle cx="12" cy="12" r="10"></circle>
4
+ <line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>
5
+ </symbol>
6
+
7
+ <symbol id="icon-eyeglass" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
8
+ <circle cx="11" cy="11" r="8"></circle>
9
+ <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
10
+ </symbol>
11
+
12
+ <symbol id="icon-up-caret" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
13
+ <polyline points="18 15 12 9 6 15"></polyline>
14
+ </symbol>
15
+
16
+ <symbol id="icon-question-mark" viewBox="0 0 24 24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
17
+ <circle cx="12" cy="12" r="10"></circle>
18
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
19
+ <line x1="12" y1="17" x2="12.01" y2="17"></line>
20
+ <symbol>
21
+ </svg>