activeadmin 1.1.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activeadmin might be problematic. Click here for more details.

Files changed (486) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +492 -108
  3. data/CODE_OF_CONDUCT.md +64 -12
  4. data/CONTRIBUTING.md +117 -49
  5. data/README.md +73 -19
  6. data/app/assets/javascripts/active_admin/base.js +509 -0
  7. data/app/assets/stylesheets/active_admin/_base.scss +29 -29
  8. data/app/assets/stylesheets/active_admin/_forms.scss +3 -15
  9. data/app/assets/stylesheets/active_admin/_header.scss +3 -5
  10. data/app/assets/stylesheets/active_admin/_mixins.scss +1 -1
  11. data/app/assets/stylesheets/active_admin/components/_scopes.scss +3 -0
  12. data/app/assets/stylesheets/active_admin/components/_status_tags.scss +0 -5
  13. data/app/assets/stylesheets/active_admin/components/_tables.scss +1 -2
  14. data/app/assets/stylesheets/active_admin/components/_tabs.scss +1 -1
  15. data/app/assets/stylesheets/active_admin/mixins/_all.scss +8 -8
  16. data/app/assets/stylesheets/active_admin/mixins/_gradients.scss +1 -1
  17. data/app/assets/stylesheets/active_admin/mixins/_variables.scss +5 -0
  18. data/app/assets/stylesheets/active_admin/print.scss +2 -2
  19. data/app/assets/stylesheets/active_admin/structure/_main_structure.scss +1 -1
  20. data/app/javascript/active_admin/base.js +19 -0
  21. data/app/javascript/active_admin/ext/jquery-ui.js +7 -0
  22. data/app/javascript/active_admin/ext/jquery.js +9 -0
  23. data/app/javascript/active_admin/initializers/batch-actions.js +61 -0
  24. data/app/javascript/active_admin/initializers/checkbox-toggler.js +3 -0
  25. data/app/javascript/active_admin/initializers/datepicker.js +16 -0
  26. data/app/javascript/active_admin/initializers/dropdown-menu.js +9 -0
  27. data/app/javascript/active_admin/initializers/filters.js +10 -0
  28. data/app/javascript/active_admin/initializers/has-many.js +95 -0
  29. data/app/javascript/active_admin/initializers/per-page.js +13 -0
  30. data/app/javascript/active_admin/initializers/table-checkbox-toggler.js +3 -0
  31. data/app/javascript/active_admin/initializers/tabs.js +6 -0
  32. data/app/javascript/active_admin/lib/checkbox-toggler.js +49 -0
  33. data/app/javascript/active_admin/lib/dropdown-menu.js +116 -0
  34. data/app/javascript/active_admin/lib/filters.js +39 -0
  35. data/app/javascript/active_admin/lib/modal-dialog.js +63 -0
  36. data/app/javascript/active_admin/lib/per-page.js +38 -0
  37. data/app/javascript/active_admin/lib/table-checkbox-toggler.js +38 -0
  38. data/app/javascript/active_admin/lib/utils.js +40 -0
  39. data/app/views/active_admin/devise/confirmations/new.html.erb +2 -2
  40. data/app/views/active_admin/devise/passwords/edit.html.erb +2 -2
  41. data/app/views/active_admin/devise/passwords/new.html.erb +2 -2
  42. data/app/views/active_admin/devise/registrations/new.html.erb +2 -3
  43. data/app/views/active_admin/devise/sessions/new.html.erb +1 -1
  44. data/app/views/active_admin/devise/shared/_error_messages.html.erb +15 -0
  45. data/app/views/active_admin/devise/unlocks/new.html.erb +2 -2
  46. data/app/views/kaminari/active_admin_countless/_first_page.html.erb +11 -0
  47. data/app/views/kaminari/active_admin_countless/_gap.html.erb +8 -0
  48. data/app/views/kaminari/active_admin_countless/_next_page.html.erb +11 -0
  49. data/app/views/kaminari/active_admin_countless/_page.html.erb +12 -0
  50. data/app/views/kaminari/active_admin_countless/_paginator.html.erb +24 -0
  51. data/app/views/kaminari/active_admin_countless/_prev_page.html.erb +11 -0
  52. data/app/views/layouts/active_admin_logged_out.html.erb +2 -2
  53. data/config/locales/ar.yml +3 -2
  54. data/config/locales/az.yml +138 -0
  55. data/config/locales/bg.yml +1 -1
  56. data/config/locales/bs.yml +1 -0
  57. data/config/locales/ca.yml +1 -1
  58. data/config/locales/cs.yml +1 -0
  59. data/config/locales/da.yml +1 -0
  60. data/config/locales/de-CH.yml +1 -0
  61. data/config/locales/de.yml +29 -0
  62. data/config/locales/el.yml +1 -0
  63. data/config/locales/en-CA.yml +1 -0
  64. data/config/locales/en-GB.yml +1 -0
  65. data/config/locales/en.yml +21 -1
  66. data/config/locales/eo.yml +145 -0
  67. data/config/locales/es-MX.yml +1 -0
  68. data/config/locales/es.yml +21 -1
  69. data/config/locales/fa.yml +1 -0
  70. data/config/locales/fi.yml +2 -1
  71. data/config/locales/fr.yml +2 -1
  72. data/config/locales/he.yml +1 -1
  73. data/config/locales/hr.yml +1 -0
  74. data/config/locales/hu.yml +5 -0
  75. data/config/locales/id.yml +1 -0
  76. data/config/locales/it.yml +13 -3
  77. data/config/locales/ja.yml +6 -0
  78. data/config/locales/ko.yml +1 -0
  79. data/config/locales/lt.yml +3 -2
  80. data/config/locales/lv.yml +1 -0
  81. data/config/locales/mk.yml +134 -0
  82. data/config/locales/nb.yml +16 -5
  83. data/config/locales/nl.yml +12 -0
  84. data/config/locales/pl.yml +72 -3
  85. data/config/locales/pt-BR.yml +9 -0
  86. data/config/locales/pt-PT.yml +1 -0
  87. data/config/locales/ro.yml +1 -0
  88. data/config/locales/ru.yml +3 -0
  89. data/config/locales/sk.yml +60 -0
  90. data/config/locales/sv-SE.yml +3 -0
  91. data/config/locales/tr.yml +10 -0
  92. data/config/locales/uk.yml +3 -0
  93. data/config/locales/vi.yml +48 -6
  94. data/config/locales/zh-CN.yml +34 -5
  95. data/config/locales/zh-TW.yml +1 -0
  96. data/docs/.gitignore +1 -0
  97. data/docs/0-installation.md +2 -2
  98. data/docs/1-general-configuration.md +36 -1
  99. data/docs/10-custom-pages.md +14 -0
  100. data/docs/12-arbre-components.md +41 -1
  101. data/docs/13-authorization-adapter.md +41 -22
  102. data/docs/2-resource-customization.md +10 -5
  103. data/docs/3-index-pages/custom-index.md +1 -1
  104. data/docs/3-index-pages/index-as-blog.md +1 -1
  105. data/docs/3-index-pages/index-as-table.md +12 -5
  106. data/docs/3-index-pages.md +17 -0
  107. data/docs/5-forms.md +16 -2
  108. data/docs/8-custom-actions.md +11 -0
  109. data/docs/CNAME +1 -1
  110. data/docs/Gemfile +2 -1
  111. data/docs/Gemfile.lock +249 -0
  112. data/docs/_config.yml +3 -1
  113. data/docs/_includes/toc.html +1 -1
  114. data/docs/_includes/top-menu.html +9 -1
  115. data/docs/documentation.md +1 -1
  116. data/docs/images/tidelift.svg +14 -0
  117. data/docs/index.html +109 -8
  118. data/docs/stylesheets/main.css +55 -2
  119. data/lib/active_admin/abstract_view_factory.rb +13 -51
  120. data/lib/active_admin/application.rb +53 -160
  121. data/lib/active_admin/application_settings.rb +42 -0
  122. data/lib/active_admin/asset_registration.rb +0 -8
  123. data/lib/active_admin/base_controller/authorization.rb +4 -6
  124. data/lib/active_admin/base_controller.rb +6 -6
  125. data/lib/active_admin/batch_actions/controller.rb +2 -2
  126. data/lib/active_admin/batch_actions/resource_extension.rb +9 -5
  127. data/lib/active_admin/callbacks.rb +1 -1
  128. data/lib/active_admin/controller_action.rb +2 -1
  129. data/lib/active_admin/csv_builder.rb +10 -7
  130. data/lib/active_admin/dependency.rb +3 -67
  131. data/lib/active_admin/deprecation.rb +0 -25
  132. data/lib/active_admin/dsl.rb +1 -8
  133. data/lib/active_admin/dynamic_setting.rb +38 -0
  134. data/lib/active_admin/dynamic_settings_node.rb +28 -0
  135. data/lib/active_admin/engine.rb +5 -0
  136. data/lib/active_admin/error.rb +4 -2
  137. data/lib/active_admin/filters/active_filter.rb +49 -12
  138. data/lib/active_admin/filters/active_sidebar.rb +6 -2
  139. data/lib/active_admin/filters/forms.rb +7 -4
  140. data/lib/active_admin/filters/formtastic_addons.rb +1 -1
  141. data/lib/active_admin/filters/resource_extension.rb +28 -4
  142. data/lib/active_admin/form_builder.rb +98 -63
  143. data/lib/active_admin/generators/boilerplate.rb +12 -4
  144. data/lib/active_admin/helpers/scope_chain.rb +1 -0
  145. data/lib/active_admin/inputs/datepicker_input.rb +8 -1
  146. data/lib/active_admin/inputs/filters/base/search_method_select.rb +2 -2
  147. data/lib/active_admin/inputs/filters/date_range_input.rb +4 -4
  148. data/lib/active_admin/inputs/filters/select_input.rb +5 -1
  149. data/lib/active_admin/menu.rb +2 -8
  150. data/lib/active_admin/menu_item.rb +4 -32
  151. data/lib/active_admin/namespace.rb +20 -8
  152. data/lib/active_admin/namespace_settings.rb +123 -0
  153. data/lib/active_admin/order_clause.rb +2 -2
  154. data/lib/active_admin/orm/active_record/comments/comment.rb +2 -2
  155. data/lib/active_admin/orm/active_record/comments/views/active_admin_comments.rb +17 -7
  156. data/lib/active_admin/orm/active_record/comments.rb +15 -4
  157. data/lib/active_admin/page_dsl.rb +1 -1
  158. data/lib/active_admin/page_presenter.rb +2 -1
  159. data/lib/active_admin/pundit_adapter.rb +18 -5
  160. data/lib/active_admin/resource/action_items.rb +7 -2
  161. data/lib/active_admin/resource/attributes.rb +7 -4
  162. data/lib/active_admin/resource/belongs_to.rb +6 -1
  163. data/lib/active_admin/resource/menu.rb +3 -3
  164. data/lib/active_admin/resource/model.rb +15 -0
  165. data/lib/active_admin/resource/naming.rb +3 -3
  166. data/lib/active_admin/resource/routes.rb +20 -7
  167. data/lib/active_admin/resource/scopes.rb +3 -3
  168. data/lib/active_admin/resource/sidebars.rb +1 -1
  169. data/lib/active_admin/resource.rb +18 -4
  170. data/lib/active_admin/resource_collection.rb +2 -2
  171. data/lib/active_admin/resource_controller/action_builder.rb +10 -0
  172. data/lib/active_admin/resource_controller/data_access.rb +5 -1
  173. data/lib/active_admin/resource_controller/decorators.rb +5 -5
  174. data/lib/active_admin/resource_controller/polymorphic_routes.rb +37 -0
  175. data/lib/active_admin/resource_controller/resource_class_methods.rb +2 -0
  176. data/lib/active_admin/resource_controller/scoping.rb +1 -1
  177. data/lib/active_admin/resource_controller.rb +2 -0
  178. data/lib/active_admin/resource_dsl.rb +7 -3
  179. data/lib/active_admin/router.rb +90 -84
  180. data/lib/active_admin/scope.rb +16 -8
  181. data/lib/active_admin/settings_node.rb +19 -0
  182. data/lib/active_admin/sidebar_section.rb +3 -1
  183. data/lib/active_admin/version.rb +1 -1
  184. data/lib/active_admin/view_helpers/breadcrumb_helper.rb +2 -2
  185. data/lib/active_admin/view_helpers/display_helper.rb +13 -4
  186. data/lib/active_admin/view_helpers/download_format_links_helper.rb +1 -0
  187. data/lib/active_admin/view_helpers/method_or_proc_helper.rb +3 -0
  188. data/lib/active_admin/view_helpers.rb +1 -1
  189. data/lib/active_admin/views/components/active_admin_form.rb +9 -4
  190. data/lib/active_admin/views/components/attributes_table.rb +3 -3
  191. data/lib/active_admin/views/components/menu.rb +32 -0
  192. data/lib/active_admin/views/components/menu_item.rb +58 -0
  193. data/lib/active_admin/views/components/paginated_collection.rb +4 -3
  194. data/lib/active_admin/views/components/scopes.rb +11 -4
  195. data/lib/active_admin/views/components/sidebar.rb +13 -0
  196. data/lib/active_admin/views/components/site_title.rb +5 -6
  197. data/lib/active_admin/views/components/status_tag.rb +6 -19
  198. data/lib/active_admin/views/components/table_for.rb +4 -12
  199. data/lib/active_admin/views/components/tabs.rb +15 -3
  200. data/lib/active_admin/views/footer.rb +3 -7
  201. data/lib/active_admin/views/header.rb +3 -15
  202. data/lib/active_admin/views/index_as_blog.rb +1 -1
  203. data/lib/active_admin/views/index_as_grid.rb +25 -25
  204. data/lib/active_admin/views/index_as_table.rb +18 -10
  205. data/lib/active_admin/views/pages/base.rb +31 -54
  206. data/lib/active_admin/views/pages/index.rb +1 -0
  207. data/lib/active_admin/views/tabbed_navigation.rb +4 -59
  208. data/lib/active_admin/views.rb +1 -1
  209. data/lib/active_admin.rb +9 -4
  210. data/lib/generators/active_admin/assets/assets_generator.rb +2 -2
  211. data/lib/generators/active_admin/assets/templates/active_admin.js +1 -0
  212. data/lib/generators/active_admin/install/install_generator.rb +7 -3
  213. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +38 -3
  214. data/lib/generators/active_admin/install/templates/dashboard.rb +2 -3
  215. data/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb.erb +1 -15
  216. data/lib/generators/active_admin/page/page_generator.rb +1 -1
  217. data/lib/generators/active_admin/resource/resource_generator.rb +2 -2
  218. data/lib/generators/active_admin/resource/templates/admin.rb.erb +40 -37
  219. data/lib/ransack_ext.rb +3 -3
  220. data/vendor/assets/javascripts/jquery-ui/form-reset-mixin.js +80 -0
  221. data/vendor/assets/javascripts/jquery-ui/form.js +22 -0
  222. data/vendor/assets/javascripts/jquery-ui/labels.js +65 -0
  223. data/vendor/assets/javascripts/jquery-ui/widgets/checkboxradio.js +274 -283
  224. metadata +115 -527
  225. data/.github/ISSUE_TEMPLATE.md +0 -20
  226. data/.gitignore +0 -49
  227. data/.mdlrc +0 -1
  228. data/.rubocop.yml +0 -76
  229. data/.simplecov +0 -13
  230. data/.travis.yml +0 -51
  231. data/.yardopts +0 -7
  232. data/Gemfile +0 -58
  233. data/Rakefile +0 -54
  234. data/activeadmin.gemspec +0 -32
  235. data/app/assets/images/active_admin/nested_menu_arrow.gif +0 -0
  236. data/app/assets/images/active_admin/nested_menu_arrow_dark.gif +0 -0
  237. data/app/assets/images/active_admin/orderable.png +0 -0
  238. data/app/assets/javascripts/active_admin/base.js.coffee +0 -13
  239. data/app/assets/javascripts/active_admin/ext/jquery-ui.js.coffee +0 -6
  240. data/app/assets/javascripts/active_admin/ext/jquery.js.coffee +0 -7
  241. data/app/assets/javascripts/active_admin/initializers/batch_actions.js.coffee +0 -11
  242. data/app/assets/javascripts/active_admin/initializers/datepicker.js.coffee +0 -14
  243. data/app/assets/javascripts/active_admin/initializers/filters.js.coffee +0 -26
  244. data/app/assets/javascripts/active_admin/initializers/tabs.js.coffee +0 -7
  245. data/app/assets/javascripts/active_admin/lib/batch_actions.js.coffee +0 -42
  246. data/app/assets/javascripts/active_admin/lib/checkbox-toggler.js.coffee +0 -46
  247. data/app/assets/javascripts/active_admin/lib/dropdown-menu.js.coffee +0 -104
  248. data/app/assets/javascripts/active_admin/lib/flash.js.coffee +0 -19
  249. data/app/assets/javascripts/active_admin/lib/has_many.js.coffee +0 -79
  250. data/app/assets/javascripts/active_admin/lib/modal_dialog.js.coffee +0 -45
  251. data/app/assets/javascripts/active_admin/lib/per_page.js.coffee +0 -46
  252. data/app/assets/javascripts/active_admin/lib/table-checkbox-toggler.js.coffee +0 -22
  253. data/codecov.yml +0 -25
  254. data/config/i18n-tasks.yml +0 -26
  255. data/config/mdl_style.rb +0 -9
  256. data/cucumber.yml +0 -3
  257. data/features/action_item.feature +0 -73
  258. data/features/authorization.feature +0 -64
  259. data/features/authorization_cancan.feature +0 -52
  260. data/features/authorization_pundit.feature +0 -37
  261. data/features/belongs_to.feature +0 -124
  262. data/features/breadcrumb.feature +0 -75
  263. data/features/comments/commenting.feature +0 -178
  264. data/features/comments/viewing_index.feature +0 -19
  265. data/features/create_another.feature +0 -55
  266. data/features/dashboard.feature +0 -16
  267. data/features/decorators.feature +0 -43
  268. data/features/development_reloading.feature +0 -28
  269. data/features/edit_page.feature +0 -116
  270. data/features/favicon.feature +0 -20
  271. data/features/first_boot.feature +0 -16
  272. data/features/footer.feature +0 -28
  273. data/features/global_navigation.feature +0 -29
  274. data/features/i18n.feature +0 -55
  275. data/features/index/batch_actions.feature +0 -218
  276. data/features/index/filters.feature +0 -239
  277. data/features/index/format_as_csv.feature +0 -220
  278. data/features/index/formats.feature +0 -88
  279. data/features/index/index_as_block.feature +0 -15
  280. data/features/index/index_as_blog.feature +0 -69
  281. data/features/index/index_as_grid.feature +0 -45
  282. data/features/index/index_as_table.feature +0 -291
  283. data/features/index/index_blank_slate.feature +0 -83
  284. data/features/index/index_parameters.feature +0 -75
  285. data/features/index/index_scope_to.feature +0 -56
  286. data/features/index/index_scopes.feature +0 -285
  287. data/features/index/page_title.feature +0 -41
  288. data/features/index/pagination.feature +0 -63
  289. data/features/index/switch_index_view.feature +0 -73
  290. data/features/menu.feature +0 -72
  291. data/features/meta_tags.feature +0 -21
  292. data/features/new_page.feature +0 -107
  293. data/features/registering_assets.feature +0 -38
  294. data/features/registering_pages.feature +0 -237
  295. data/features/registering_resources.feature +0 -33
  296. data/features/renamed_resource.feature +0 -30
  297. data/features/root_to.feature +0 -17
  298. data/features/show/attributes_table_title.feature +0 -54
  299. data/features/show/columns.feature +0 -40
  300. data/features/show/default_content.feature +0 -44
  301. data/features/show/page_title.feature +0 -58
  302. data/features/show/tabs.feature +0 -33
  303. data/features/sidebar_sections.feature +0 -210
  304. data/features/site_title.feature +0 -47
  305. data/features/specifying_actions.feature +0 -118
  306. data/features/step_definitions/action_item_steps.rb +0 -7
  307. data/features/step_definitions/action_link_steps.rb +0 -19
  308. data/features/step_definitions/additional_web_steps.rb +0 -81
  309. data/features/step_definitions/asset_steps.rb +0 -15
  310. data/features/step_definitions/attribute_steps.rb +0 -18
  311. data/features/step_definitions/attributes_table_title_steps.rb +0 -11
  312. data/features/step_definitions/batch_action_steps.rb +0 -81
  313. data/features/step_definitions/blog_steps.rb +0 -3
  314. data/features/step_definitions/breadcrumb_steps.rb +0 -3
  315. data/features/step_definitions/column_steps.rb +0 -8
  316. data/features/step_definitions/comment_steps.rb +0 -32
  317. data/features/step_definitions/configuration_steps.rb +0 -100
  318. data/features/step_definitions/dashboard_steps.rb +0 -15
  319. data/features/step_definitions/factory_steps.rb +0 -35
  320. data/features/step_definitions/filter_steps.rb +0 -48
  321. data/features/step_definitions/flash_steps.rb +0 -11
  322. data/features/step_definitions/footer_steps.rb +0 -11
  323. data/features/step_definitions/format_steps.rb +0 -56
  324. data/features/step_definitions/i18n_steps.rb +0 -11
  325. data/features/step_definitions/index_scope_steps.rb +0 -29
  326. data/features/step_definitions/index_views_steps.rb +0 -3
  327. data/features/step_definitions/layout_steps.rb +0 -3
  328. data/features/step_definitions/member_link_steps.rb +0 -7
  329. data/features/step_definitions/menu_steps.rb +0 -11
  330. data/features/step_definitions/meta_tag_steps.rb +0 -3
  331. data/features/step_definitions/pagination_steps.rb +0 -15
  332. data/features/step_definitions/sidebar_steps.rb +0 -11
  333. data/features/step_definitions/site_title_steps.rb +0 -17
  334. data/features/step_definitions/tab_steps.rb +0 -8
  335. data/features/step_definitions/table_steps.rb +0 -116
  336. data/features/step_definitions/user_steps.rb +0 -52
  337. data/features/step_definitions/web_steps.rb +0 -86
  338. data/features/sti_resource.feature +0 -65
  339. data/features/strong_parameters.feature +0 -69
  340. data/features/support/env.rb +0 -122
  341. data/features/support/paths.rb +0 -73
  342. data/features/support/regular_env.rb +0 -7
  343. data/features/support/reload_env.rb +0 -7
  344. data/features/support/selectors.rb +0 -45
  345. data/features/users/logging_in.feature +0 -36
  346. data/features/users/logging_out.feature +0 -13
  347. data/features/users/resetting_password.feature +0 -34
  348. data/gemfiles/rails_42.gemfile +0 -10
  349. data/gemfiles/rails_50.gemfile +0 -10
  350. data/gemfiles/rails_51.gemfile +0 -10
  351. data/lib/active_admin/event.rb +0 -24
  352. data/lib/active_admin/helpers/settings.rb +0 -114
  353. data/lib/active_admin/reloader.rb +0 -25
  354. data/lib/bug_report_templates/active_admin_master.rb +0 -113
  355. data/lib/generators/active_admin/assets/templates/active_admin.js.coffee +0 -1
  356. data/spec/bug_report_templates_spec.rb +0 -26
  357. data/spec/javascripts/coffeescripts/jquery.aa.checkbox-toggler-spec.js.coffee +0 -50
  358. data/spec/javascripts/coffeescripts/jquery.aa.flash.js.coffee +0 -25
  359. data/spec/javascripts/coffeescripts/jquery.aa.table-checkbox-toggler-spec.js.coffee +0 -34
  360. data/spec/javascripts/fixtures/checkboxes.html +0 -9
  361. data/spec/javascripts/fixtures/flashes.html +0 -2
  362. data/spec/javascripts/fixtures/table_checkboxes.html +0 -17
  363. data/spec/javascripts/helpers/SpecHelper.js +0 -3
  364. data/spec/javascripts/support/jasmine.yml +0 -74
  365. data/spec/javascripts/support/jasmine_runner.rb +0 -19
  366. data/spec/rails_helper.rb +0 -59
  367. data/spec/requests/default_namespace_spec.rb +0 -81
  368. data/spec/requests/memory_spec.rb +0 -25
  369. data/spec/requests/stylesheets_spec.rb +0 -18
  370. data/spec/spec_helper.rb +0 -1
  371. data/spec/support/active_admin_integration_spec_helper.rb +0 -73
  372. data/spec/support/active_admin_request_helpers.rb +0 -39
  373. data/spec/support/rails_template.rb +0 -150
  374. data/spec/support/rails_template_with_data.rb +0 -327
  375. data/spec/support/templates/admin/stores.rb +0 -7
  376. data/spec/support/templates/en.yml +0 -8
  377. data/spec/support/templates/manifest.js +0 -3
  378. data/spec/support/templates/policies/active_admin/comment_policy.rb +0 -9
  379. data/spec/support/templates/policies/active_admin/page_policy.rb +0 -18
  380. data/spec/support/templates/policies/admin_user_policy.rb +0 -11
  381. data/spec/support/templates/policies/application_policy.rb +0 -44
  382. data/spec/support/templates/policies/category_policy.rb +0 -7
  383. data/spec/support/templates/policies/post_policy.rb +0 -15
  384. data/spec/support/templates/policies/store_policy.rb +0 -11
  385. data/spec/support/templates/policies/user_policy.rb +0 -11
  386. data/spec/support/templates/post_decorator.rb +0 -10
  387. data/spec/unit/abstract_view_factory_spec.rb +0 -78
  388. data/spec/unit/action_builder_spec.rb +0 -125
  389. data/spec/unit/active_admin_spec.rb +0 -11
  390. data/spec/unit/application_spec.rb +0 -184
  391. data/spec/unit/asset_registration_spec.rb +0 -81
  392. data/spec/unit/authorization/authorization_adapter_spec.rb +0 -61
  393. data/spec/unit/authorization/controller_authorization_spec.rb +0 -43
  394. data/spec/unit/authorization/index_overriding_spec.rb +0 -23
  395. data/spec/unit/auto_link_spec.rb +0 -93
  396. data/spec/unit/batch_actions/resource_spec.rb +0 -84
  397. data/spec/unit/batch_actions/settings_spec.rb +0 -61
  398. data/spec/unit/belongs_to_spec.rb +0 -76
  399. data/spec/unit/cancan_adapter_spec.rb +0 -43
  400. data/spec/unit/comments_spec.rb +0 -176
  401. data/spec/unit/component_spec.rb +0 -18
  402. data/spec/unit/config_shared_examples.rb +0 -59
  403. data/spec/unit/controller_filters_spec.rb +0 -41
  404. data/spec/unit/csv_builder_spec.rb +0 -304
  405. data/spec/unit/dependency_spec.rb +0 -135
  406. data/spec/unit/devise_spec.rb +0 -110
  407. data/spec/unit/dsl_spec.rb +0 -120
  408. data/spec/unit/filters/active_filter_spec.rb +0 -135
  409. data/spec/unit/filters/active_spec.rb +0 -24
  410. data/spec/unit/filters/filter_form_builder_spec.rb +0 -502
  411. data/spec/unit/filters/resource_spec.rb +0 -128
  412. data/spec/unit/form_builder_spec.rb +0 -990
  413. data/spec/unit/generators/install_spec.rb +0 -31
  414. data/spec/unit/helpers/collection_spec.rb +0 -68
  415. data/spec/unit/helpers/scope_chain_spec.rb +0 -35
  416. data/spec/unit/helpers/settings_spec.rb +0 -30
  417. data/spec/unit/i18n_spec.rb +0 -29
  418. data/spec/unit/localizers/resource_localizer_spec.rb +0 -36
  419. data/spec/unit/menu_collection_spec.rb +0 -62
  420. data/spec/unit/menu_item_spec.rb +0 -141
  421. data/spec/unit/menu_spec.rb +0 -71
  422. data/spec/unit/namespace/authorization_spec.rb +0 -27
  423. data/spec/unit/namespace/register_page_spec.rb +0 -99
  424. data/spec/unit/namespace/register_resource_spec.rb +0 -162
  425. data/spec/unit/namespace_spec.rb +0 -124
  426. data/spec/unit/order_clause_spec.rb +0 -81
  427. data/spec/unit/page_controller_spec.rb +0 -5
  428. data/spec/unit/page_spec.rb +0 -128
  429. data/spec/unit/pretty_format_spec.rb +0 -82
  430. data/spec/unit/pundit_adapter_spec.rb +0 -98
  431. data/spec/unit/resource/action_items_spec.rb +0 -69
  432. data/spec/unit/resource/attributes_spec.rb +0 -49
  433. data/spec/unit/resource/includes_spec.rb +0 -21
  434. data/spec/unit/resource/menu_spec.rb +0 -18
  435. data/spec/unit/resource/naming_spec.rb +0 -122
  436. data/spec/unit/resource/ordering_spec.rb +0 -35
  437. data/spec/unit/resource/page_presenters_spec.rb +0 -44
  438. data/spec/unit/resource/pagination_spec.rb +0 -38
  439. data/spec/unit/resource/routes_spec.rb +0 -125
  440. data/spec/unit/resource/scopes_spec.rb +0 -50
  441. data/spec/unit/resource/sidebars_spec.rb +0 -43
  442. data/spec/unit/resource_collection_spec.rb +0 -175
  443. data/spec/unit/resource_controller/data_access_spec.rb +0 -230
  444. data/spec/unit/resource_controller/decorators_spec.rb +0 -94
  445. data/spec/unit/resource_controller/sidebars_spec.rb +0 -37
  446. data/spec/unit/resource_controller_spec.rb +0 -273
  447. data/spec/unit/resource_registration_spec.rb +0 -61
  448. data/spec/unit/resource_spec.rb +0 -320
  449. data/spec/unit/routing_spec.rb +0 -211
  450. data/spec/unit/scope_spec.rb +0 -209
  451. data/spec/unit/settings_spec.rb +0 -117
  452. data/spec/unit/view_factory_spec.rb +0 -19
  453. data/spec/unit/view_helpers/breadcrumbs_spec.rb +0 -252
  454. data/spec/unit/view_helpers/display_helper_spec.rb +0 -195
  455. data/spec/unit/view_helpers/download_format_links_helper_spec.rb +0 -39
  456. data/spec/unit/view_helpers/fields_for_spec.rb +0 -50
  457. data/spec/unit/view_helpers/flash_helper_spec.rb +0 -24
  458. data/spec/unit/view_helpers/form_helper_spec.rb +0 -42
  459. data/spec/unit/view_helpers/method_or_proc_helper_spec.rb +0 -138
  460. data/spec/unit/views/components/attributes_table_spec.rb +0 -271
  461. data/spec/unit/views/components/batch_action_selector_spec.rb +0 -43
  462. data/spec/unit/views/components/blank_slate_spec.rb +0 -27
  463. data/spec/unit/views/components/columns_spec.rb +0 -187
  464. data/spec/unit/views/components/index_list_spec.rb +0 -49
  465. data/spec/unit/views/components/index_table_for_spec.rb +0 -127
  466. data/spec/unit/views/components/paginated_collection_spec.rb +0 -249
  467. data/spec/unit/views/components/panel_spec.rb +0 -58
  468. data/spec/unit/views/components/sidebar_section_spec.rb +0 -68
  469. data/spec/unit/views/components/site_title_spec.rb +0 -76
  470. data/spec/unit/views/components/status_tag_spec.rb +0 -265
  471. data/spec/unit/views/components/table_for_spec.rb +0 -436
  472. data/spec/unit/views/components/tabs_spec.rb +0 -67
  473. data/spec/unit/views/components/unsupported_browser_spec.rb +0 -41
  474. data/spec/unit/views/index_as_blog_spec.rb +0 -76
  475. data/spec/unit/views/pages/form_spec.rb +0 -54
  476. data/spec/unit/views/pages/index_spec.rb +0 -60
  477. data/spec/unit/views/pages/layout_spec.rb +0 -59
  478. data/spec/unit/views/pages/show_spec.rb +0 -32
  479. data/spec/unit/views/tabbed_navigation_spec.rb +0 -158
  480. data/tasks/docs.rake +0 -64
  481. data/tasks/lint.rake +0 -21
  482. data/tasks/local.rake +0 -25
  483. data/tasks/parallel_tests.rake +0 -66
  484. data/tasks/test.rake +0 -29
  485. /data/{vendor → app}/assets/stylesheets/active_admin/_normalize.scss +0 -0
  486. /data/lib/generators/active_admin/install/templates/{admin_user.rb.erb → admin_users.rb.erb} +0 -0
@@ -83,14 +83,7 @@ module ActiveAdmin
83
83
  # this action item on.
84
84
  # :except: A single or array of controller actions not to
85
85
  # display this action item on.
86
- def action_item(name = nil, options = {}, &block)
87
- if name.is_a?(Hash)
88
- options = name
89
- name = nil
90
- end
91
-
92
- Deprecation.warn "using `action_item` without a name is deprecated! Use `action_item(:edit)`." unless name
93
-
86
+ def action_item(name, options = {}, &block)
94
87
  config.add_action_item(name, options, &block)
95
88
  end
96
89
 
@@ -0,0 +1,38 @@
1
+ module ActiveAdmin
2
+
3
+ class DynamicSetting
4
+ def self.build(setting, type)
5
+ (type ? klass(type) : self).new(setting)
6
+ end
7
+
8
+ def self.klass(type)
9
+ klass = "#{type.to_s.camelcase}Setting"
10
+ raise ArgumentError, "Unknown type: #{type}" unless ActiveAdmin.const_defined?(klass)
11
+ ActiveAdmin.const_get(klass)
12
+ end
13
+
14
+ def initialize(setting)
15
+ @setting = setting
16
+ end
17
+
18
+ def value(*_args)
19
+ @setting
20
+ end
21
+ end
22
+
23
+ # Many configuration options (Ex: site_title, title_image) could either be
24
+ # static (String), methods (Symbol) or procs (Proc). This wrapper takes care of
25
+ # returning the content when String or using instance_eval when Symbol or Proc.
26
+ #
27
+ class StringSymbolOrProcSetting < DynamicSetting
28
+ def value(context = self)
29
+ case @setting
30
+ when Symbol, Proc
31
+ context.instance_eval(&@setting)
32
+ else
33
+ @setting
34
+ end
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_admin/dynamic_setting'
2
+ require 'active_admin/settings_node'
3
+
4
+ module ActiveAdmin
5
+
6
+ class DynamicSettingsNode < SettingsNode
7
+ class << self
8
+ def register(name, value, type = nil)
9
+ class_attribute "#{name}_setting"
10
+ add_reader(name)
11
+ add_writer(name, type)
12
+ send "#{name}=", value
13
+ end
14
+
15
+ def add_reader(name)
16
+ define_singleton_method(name) do |*args|
17
+ send("#{name}_setting").value(*args)
18
+ end
19
+ end
20
+
21
+ def add_writer(name, type)
22
+ define_singleton_method("#{name}=") do |value|
23
+ send("#{name}_setting=", DynamicSetting.build(value, type))
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,10 @@
1
1
  module ActiveAdmin
2
2
  class Engine < ::Rails::Engine
3
+ initializer "active_admin.load_app_path" do |app|
4
+ ActiveAdmin::Application.setting :app_path, app.root
5
+ ActiveAdmin::Application.setting :load_paths, [File.expand_path('app/admin', app.root)]
6
+ end
7
+
3
8
  initializer "active_admin.precompile", group: :all do |app|
4
9
  ActiveAdmin.application.stylesheets.each do |path, _|
5
10
  app.config.assets.precompile << path
@@ -6,7 +6,9 @@ module ActiveAdmin
6
6
  attr_reader :user, :action, :subject
7
7
 
8
8
  def initialize(user, action, subject = nil)
9
- @user, @action, @subject = user, action, subject
9
+ @user = user
10
+ @action = action
11
+ @subject = subject
10
12
 
11
13
  super()
12
14
  end
@@ -22,7 +24,7 @@ module ActiveAdmin
22
24
  class ErrorLoading < Error
23
25
  # Locates the most recent file and line from the caught exception's backtrace.
24
26
  def find_cause(folder, backtrace)
25
- backtrace.grep(/\/(#{folder}\/.*\.rb):(\d+)/){ [$1, $2] }.first
27
+ backtrace.grep(/\/(#{folder}\/.*\.rb):(\d+)/) { [$1, $2] }.first
26
28
  end
27
29
  end
28
30
 
@@ -19,20 +19,23 @@ module ActiveAdmin
19
19
  def values
20
20
  condition_values = condition.values.map(&:value)
21
21
  if related_class
22
- related_class.find(condition_values)
22
+ related_class.where(related_primary_key => condition_values)
23
23
  else
24
24
  condition_values
25
25
  end
26
26
  end
27
27
 
28
28
  def label
29
- # TODO: to remind us to go back to the simpler str.downcase once we support ruby >= 2.4 only.
30
- translated_predicate = predicate_name.mb_chars.downcase.to_s
31
- if related_class
32
- "#{related_class.model_name.human} #{translated_predicate}".strip
29
+ translated_predicate = predicate_name.downcase
30
+ if filter_label && filter_label.is_a?(Proc)
31
+ "#{filter_label.call} #{translated_predicate}"
32
+ elsif filter_label
33
+ "#{filter_label} #{translated_predicate}"
34
+ elsif related_class
35
+ "#{related_class_name} #{translated_predicate}"
33
36
  else
34
- "#{attribute_name} #{translated_predicate}".strip
35
- end
37
+ "#{attribute_name} #{translated_predicate}"
38
+ end.strip
36
39
  end
37
40
 
38
41
  def predicate_name
@@ -54,6 +57,18 @@ module ActiveAdmin
54
57
  resource_class.human_attribute_name(name)
55
58
  end
56
59
 
60
+ def related_class_name
61
+ return unless related_class
62
+
63
+ related_class.model_name.human
64
+ end
65
+
66
+ def filter_label
67
+ return unless filter
68
+
69
+ filter[:label] || I18n.t(name, scope: ['formtastic', 'labels'], default: nil)
70
+ end
71
+
57
72
  #@return Ransack::Nodes::Attribute
58
73
  def condition_attribute
59
74
  condition.attributes[0]
@@ -75,13 +90,35 @@ module ActiveAdmin
75
90
  def find_class
76
91
  if condition_attribute.klass != resource_class && condition_attribute.klass.primary_key == name.to_s
77
92
  condition_attribute.klass
78
- else
79
- assoc = condition_attribute.klass.reflect_on_all_associations.
80
- reject { |r| r.options[:polymorphic] }. #skip polymorphic
81
- detect { |r| r.foreign_key.to_s == name.to_s }
82
- assoc.class_name.constantize if assoc
93
+ elsif predicate_association
94
+ predicate_association.klass
95
+ end
96
+ end
97
+
98
+ def filter
99
+ resource.filters[name.to_sym] || resource.filters[condition.key.to_sym]
100
+ end
101
+
102
+ def related_primary_key
103
+ if predicate_association
104
+ predicate_association.association_primary_key
105
+ elsif related_class
106
+ related_class.primary_key
83
107
  end
84
108
  end
109
+
110
+ def predicate_association
111
+ @predicate_association = find_predicate_association unless defined?(@predicate_association)
112
+ @predicate_association
113
+ end
114
+
115
+ private
116
+
117
+ def find_predicate_association
118
+ condition_attribute.klass.reflect_on_all_associations.
119
+ reject { |r| r.options[:polymorphic] }. #skip polymorphic
120
+ detect { |r| r.foreign_key.to_s == name.to_s }
121
+ end
85
122
  end
86
123
  end
87
124
  end
@@ -5,7 +5,7 @@ module ActiveAdmin
5
5
  class ActiveSidebar < ActiveAdmin::SidebarSection
6
6
 
7
7
  def initialize
8
- super I18n.t("active_admin.search_status.headline"), sidebar_options
8
+ super 'search_status', sidebar_options
9
9
  end
10
10
 
11
11
  def block
@@ -28,7 +28,7 @@ module ActiveAdmin
28
28
  text_node filter.label
29
29
  end
30
30
  b do
31
- text_node filter.values.map { |v| pretty_format(v) }.to_sentence.html_safe
31
+ text_node to_sentence(filter.values.map { |v| pretty_format(v) })
32
32
  end
33
33
  end
34
34
  end
@@ -39,6 +39,10 @@ module ActiveAdmin
39
39
  end
40
40
  end
41
41
 
42
+ def title
43
+ I18n.t("active_admin.search_status.headline")
44
+ end
45
+
42
46
  protected
43
47
 
44
48
  def sidebar_options
@@ -48,8 +48,8 @@ module ActiveAdmin
48
48
  def active_admin_filters_form_for(search, filters, options = {})
49
49
  defaults = { builder: ActiveAdmin::Filters::FormBuilder,
50
50
  url: collection_path,
51
- html: {class: 'filter_form'} }
52
- required = { html: {method: :get},
51
+ html: { class: 'filter_form' } }
52
+ required = { html: { method: :get },
53
53
  as: :q }
54
54
  options = defaults.deep_merge(options).deep_merge(required)
55
55
 
@@ -57,8 +57,11 @@ module ActiveAdmin
57
57
  filters.each do |attribute, opts|
58
58
  next if opts.key?(:if) && !call_method_or_proc_on(self, opts[:if])
59
59
  next if opts.key?(:unless) && call_method_or_proc_on(self, opts[:unless])
60
- opts[:input_html] = instance_exec(&opts[:input_html]) if opts[:input_html].is_a?(Proc)
61
- f.filter attribute, opts.except(:if, :unless)
60
+
61
+ filter_opts = opts.except(:if, :unless)
62
+ filter_opts[:input_html] = instance_exec(&filter_opts[:input_html]) if filter_opts[:input_html].is_a?(Proc)
63
+
64
+ f.filter attribute, filter_opts
62
65
  end
63
66
 
64
67
  buttons = content_tag :div, class: "buttons" do
@@ -37,7 +37,7 @@ module ActiveAdmin
37
37
  end
38
38
 
39
39
  def polymorphic_foreign_type?(method)
40
- klass.reflect_on_all_associations.select{ |r| r.macro == :belongs_to && r.options[:polymorphic] }
40
+ klass.reflect_on_all_associations.select { |r| r.macro == :belongs_to && r.options[:polymorphic] }
41
41
  .map(&:foreign_type).include? method.to_s
42
42
  end
43
43
 
@@ -83,7 +83,7 @@ module ActiveAdmin
83
83
  @filters_to_remove = nil
84
84
  end
85
85
 
86
- private
86
+ private
87
87
 
88
88
  # Collapses the waveform, if you will, of which filters should be displayed.
89
89
  # Removes filters and adds in default filters as desired.
@@ -123,24 +123,48 @@ module ActiveAdmin
123
123
  # Returns a default set of filters for the associations
124
124
  def default_association_filters
125
125
  if resource_class.respond_to?(:reflect_on_all_associations)
126
- poly, not_poly = resource_class.reflect_on_all_associations.partition{ |r| r.macro == :belongs_to && r.options[:polymorphic] }
126
+ poly, not_poly = resource_class.reflect_on_all_associations.partition { |r| r.macro == :belongs_to && r.options[:polymorphic] }
127
127
 
128
128
  # remove deeply nested associations
129
- not_poly.reject!{ |r| r.chain.length > 2 }
129
+ not_poly.reject! { |r| r.chain.length > 2 }
130
130
 
131
131
  filters = poly.map(&:foreign_type) + not_poly.map(&:name)
132
+
133
+ # Check high-arity associations for filterable columns
134
+ max = namespace.maximum_association_filter_arity
135
+ if max != :unlimited
136
+ high_arity, low_arity = not_poly.partition do |r|
137
+ r.klass.reorder(nil).limit(max + 1).count > max
138
+ end
139
+
140
+ # Remove high-arity associations with no searchable column
141
+ high_arity = high_arity.select(&method(:searchable_column_for))
142
+
143
+ high_arity = high_arity.map { |r| r.name.to_s + "_" + searchable_column_for(r) + namespace.filter_method_for_large_association }
144
+
145
+ filters = poly.map(&:foreign_type) + low_arity.map(&:name) + high_arity
146
+ end
147
+
132
148
  filters.map &:to_sym
133
149
  else
134
150
  []
135
151
  end
136
152
  end
137
153
 
154
+ def search_columns
155
+ @search_columns ||= namespace.filter_columns_for_large_association.map(&:to_s)
156
+ end
157
+
158
+ def searchable_column_for(relation)
159
+ relation.klass.column_names.find { |name| search_columns.include?(name) }
160
+ end
161
+
138
162
  def add_filters_sidebar_section
139
163
  self.sidebar_sections << filters_sidebar_section
140
164
  end
141
165
 
142
166
  def filters_sidebar_section
143
- ActiveAdmin::SidebarSection.new :filters, only: :index, if: ->{ active_admin_config.filters.any? } do
167
+ ActiveAdmin::SidebarSection.new :filters, only: :index, if: -> { active_admin_config.filters.any? } do
144
168
  active_admin_filters_form_for assigns[:search], active_admin_config.filters
145
169
  end
146
170
  end
@@ -13,7 +13,6 @@ end
13
13
 
14
14
  module ActiveAdmin
15
15
  class FormBuilder < ::Formtastic::FormBuilder
16
- include MethodOrProcHelper
17
16
 
18
17
  self.input_namespaces = [::Object, ::ActiveAdmin::Inputs, ::Formtastic::Inputs]
19
18
 
@@ -21,7 +20,7 @@ module ActiveAdmin
21
20
  self.input_class_finder = ::Formtastic::InputClassFinder
22
21
  self.action_class_finder = ::Formtastic::ActionClassFinder
23
22
 
24
- def cancel_link(url = {action: "index"}, html_options = {}, li_attrs = {})
23
+ def cancel_link(url = { action: "index" }, html_options = {}, li_attrs = {})
25
24
  li_attrs[:class] ||= "cancel"
26
25
  li_content = template.link_to I18n.t('active_admin.cancel'), url, html_options
27
26
  template.content_tag(:li, li_content, li_attrs)
@@ -29,119 +28,155 @@ module ActiveAdmin
29
28
 
30
29
  attr_accessor :already_in_an_inputs_block
31
30
 
32
- def assoc_heading(assoc)
33
- object.class.reflect_on_association(assoc).klass.model_name.
34
- human(count: ::ActiveAdmin::Helpers::I18n::PLURAL_MANY_COUNT)
31
+ def has_many(assoc, options = {}, &block)
32
+ HasManyBuilder.new(self, assoc, options).render(&block)
35
33
  end
34
+ end
36
35
 
37
- def has_many(assoc, options = {}, &block)
38
- # remove options that should not render as attributes
39
- custom_settings = :new_record, :allow_destroy, :heading, :sortable, :sortable_start
40
- builder_options = {new_record: true}.merge! options.slice *custom_settings
41
- options = {for: assoc }.merge! options.except *custom_settings
42
- options[:class] = [options[:class], "inputs has_many_fields"].compact.join(' ')
43
- sortable_column = builder_options[:sortable]
44
- sortable_start = builder_options.fetch(:sortable_start, 0)
36
+ # Decorates a FormBuilder with the additional attributes and methods
37
+ # to build a has_many block. Nested has_many blocks are handled by
38
+ # nested decorators.
39
+ class HasManyBuilder < SimpleDelegator
40
+ attr_reader :assoc
41
+ attr_reader :options
42
+ attr_reader :heading, :sortable_column, :sortable_start
43
+ attr_reader :new_record, :destroy_option
44
+
45
+ def initialize(has_many_form, assoc, options)
46
+ super has_many_form
47
+ @assoc = assoc
48
+ @options = extract_custom_settings!(options.dup)
49
+ @options.reverse_merge!(for: assoc)
50
+ @options[:class] = [options[:class], "inputs has_many_fields"].compact.join(' ')
45
51
 
46
52
  if sortable_column
47
- options[:for] = [assoc, sorted_children(assoc, sortable_column)]
53
+ @options[:for] = [assoc, sorted_children(sortable_column)]
48
54
  end
55
+ end
49
56
 
57
+ def render(&block)
50
58
  html = "".html_safe
51
- unless builder_options.key?(:heading) && !builder_options[:heading]
52
- html << template.content_tag(:h3) do
53
- builder_options[:heading] || assoc_heading(assoc)
54
- end
55
- end
59
+ html << template.content_tag(:h3) { heading } if heading.present?
60
+ html << template.capture { content_has_many(&block) }
61
+ html = wrap_div_or_li(html)
62
+ template.concat(html) if template.output_buffer
63
+ html
64
+ end
56
65
 
57
- html << template.capture do
58
- form_block = proc do |has_many_form|
59
- index = parent_child_index options[:parent] if options[:parent]
60
- block_contents = template.capture do
61
- block.call(has_many_form, index)
62
- end
63
- template.concat(block_contents)
64
- template.concat has_many_actions(has_many_form, builder_options, "".html_safe)
65
- end
66
+ protected
66
67
 
67
- template.assigns[:has_many_block] = true
68
- contents = without_wrapper { inputs(options, &form_block) } || "".html_safe
68
+ # remove options that should not render as attributes
69
+ def extract_custom_settings!(options)
70
+ @heading = options.key?(:heading) ? options.delete(:heading) : default_heading
71
+ @sortable_column = options.delete(:sortable)
72
+ @sortable_start = options.delete(:sortable_start) || 0
73
+ @new_record = options.key?(:new_record) ? options.delete(:new_record) : true
74
+ @destroy_option = options.delete(:allow_destroy)
75
+ options
76
+ end
69
77
 
70
- if builder_options[:new_record]
71
- contents << js_for_has_many(assoc, form_block, template, builder_options[:new_record], options[:class])
72
- else
73
- contents
74
- end
78
+ def default_heading
79
+ assoc_klass.model_name.
80
+ human(count: ::ActiveAdmin::Helpers::I18n::PLURAL_MANY_COUNT)
81
+ end
82
+
83
+ def assoc_klass
84
+ @assoc_klass ||= __getobj__.object.class.reflect_on_association(assoc).klass
85
+ end
86
+
87
+ def content_has_many(&block)
88
+ form_block = proc do |form_builder|
89
+ render_has_many_form(form_builder, options[:parent], &block)
75
90
  end
76
91
 
77
- tag = @already_in_an_inputs_block ? :li : :div
78
- html = template.content_tag(tag, html, class: "has_many_container #{assoc}", 'data-sortable' => sortable_column, 'data-sortable-start' => sortable_start)
79
- template.concat(html) if template.output_buffer
80
- html
92
+ template.assigns[:has_many_block] = true
93
+ contents = without_wrapper { inputs(options, &form_block) }
94
+ contents ||= "".html_safe
95
+
96
+ js = new_record ? js_for_has_many(options[:class], &form_block) : ''
97
+ contents << js
81
98
  end
82
99
 
83
- protected
100
+ # Renders the Formtastic inputs then appends ActiveAdmin delete and sort actions.
101
+ def render_has_many_form(form_builder, parent, &block)
102
+ index = parent && form_builder.send(:parent_child_index, parent)
103
+ template.concat template.capture { yield(form_builder, index) }
104
+ template.concat has_many_actions(form_builder, "".html_safe)
105
+ end
84
106
 
85
- def has_many_actions(has_many_form, builder_options, contents)
86
- if has_many_form.object.new_record?
107
+ def has_many_actions(form_builder, contents)
108
+ if form_builder.object.new_record?
87
109
  contents << template.content_tag(:li) do
88
110
  template.link_to I18n.t('active_admin.has_many_remove'), "#", class: 'button has_many_remove'
89
111
  end
90
- elsif call_method_or_proc_on(has_many_form.object,
91
- builder_options[:allow_destroy],
92
- exec: false)
93
-
94
- has_many_form.input(:_destroy, as: :boolean,
95
- wrapper_html: {class: 'has_many_delete'},
112
+ elsif allow_destroy?(form_builder.object)
113
+ form_builder.input(:_destroy, as: :boolean,
114
+ wrapper_html: { class: 'has_many_delete' },
96
115
  label: I18n.t('active_admin.has_many_delete'))
97
116
  end
98
117
 
99
- if builder_options[:sortable]
100
- has_many_form.input builder_options[:sortable], as: :hidden
118
+ if sortable_column
119
+ form_builder.input sortable_column, as: :hidden
101
120
 
102
121
  contents << template.content_tag(:li, class: 'handle') do
103
- "MOVE"
122
+ I18n.t('active_admin.move')
104
123
  end
105
124
  end
106
125
 
107
126
  contents
108
127
  end
109
128
 
110
- def sorted_children(assoc, column)
111
- object.public_send(assoc).sort_by do |o|
129
+ def allow_destroy?(form_object)
130
+ !! case destroy_option
131
+ when Symbol, String
132
+ form_object.public_send destroy_option
133
+ when Proc
134
+ destroy_option.call form_object
135
+ else
136
+ destroy_option
137
+ end
138
+ end
139
+
140
+ def sorted_children(column)
141
+ __getobj__.object.public_send(assoc).sort_by do |o|
112
142
  attribute = o.public_send column
113
143
  [attribute.nil? ? Float::INFINITY : attribute, o.id || Float::INFINITY]
114
144
  end
115
145
  end
116
146
 
117
- private
118
-
119
147
  def without_wrapper
120
- is_being_wrapped = @already_in_an_inputs_block
121
- @already_in_an_inputs_block = false
148
+ is_being_wrapped = already_in_an_inputs_block
149
+ self.already_in_an_inputs_block = false
122
150
 
123
151
  html = yield
124
152
 
125
- @already_in_an_inputs_block = is_being_wrapped
153
+ self.already_in_an_inputs_block = is_being_wrapped
126
154
  html
127
155
  end
128
156
 
129
157
  # Capture the ADD JS
130
- def js_for_has_many(assoc, form_block, template, new_record, class_string)
131
- assoc_reflection = object.class.reflect_on_association assoc
132
- assoc_name = assoc_reflection.klass.model_name
158
+ def js_for_has_many(class_string, &form_block)
159
+ assoc_name = assoc_klass.model_name
133
160
  placeholder = "NEW_#{assoc_name.to_s.underscore.upcase.gsub(/\//, '_')}_RECORD"
134
161
  opts = {
135
- for: [assoc, assoc_reflection.klass.new],
162
+ for: [assoc, assoc_klass.new],
136
163
  class: class_string,
137
164
  for_options: { child_index: placeholder }
138
165
  }
139
- html = template.capture{ inputs_for_nested_attributes opts, &form_block }
166
+ html = template.capture { __getobj__.send(:inputs_for_nested_attributes, opts, &form_block) }
140
167
  text = new_record.is_a?(String) ? new_record : I18n.t('active_admin.has_many_new', model: assoc_name.human)
141
168
 
142
169
  template.link_to text, '#', class: "button has_many_add", data: {
143
170
  html: CGI.escapeHTML(html).html_safe, placeholder: placeholder
144
171
  }
145
172
  end
173
+
174
+ def wrap_div_or_li(html)
175
+ template.content_tag(already_in_an_inputs_block ? :li : :div,
176
+ html,
177
+ class: "has_many_container #{assoc}",
178
+ 'data-sortable' => sortable_column,
179
+ 'data-sortable-start' => sortable_start)
180
+ end
146
181
  end
147
182
  end
@@ -9,8 +9,16 @@ module ActiveAdmin
9
9
  @class_name.constantize.new.attributes.keys
10
10
  end
11
11
 
12
+ def assignable_attributes
13
+ attributes - %w(id created_at updated_at)
14
+ end
15
+
16
+ def permit_params
17
+ assignable_attributes.map { |a| a.to_sym.inspect }.join(', ')
18
+ end
19
+
12
20
  def rows
13
- attributes.map { |a| row(a) }.join("\n")
21
+ attributes.map { |a| row(a) }.join("\n ")
14
22
  end
15
23
 
16
24
  def row(name)
@@ -18,7 +26,7 @@ module ActiveAdmin
18
26
  end
19
27
 
20
28
  def columns
21
- attributes.map { |a| column(a) }.join("\n")
29
+ attributes.map { |a| column(a) }.join("\n ")
22
30
  end
23
31
 
24
32
  def column(name)
@@ -26,7 +34,7 @@ module ActiveAdmin
26
34
  end
27
35
 
28
36
  def filters
29
- attributes.map { |a| filter(a) }.join("\n")
37
+ attributes.map { |a| filter(a) }.join("\n ")
30
38
  end
31
39
 
32
40
  def filter(name)
@@ -34,7 +42,7 @@ module ActiveAdmin
34
42
  end
35
43
 
36
44
  def form_inputs
37
- attributes.reject{|a| %w(id created_at updated_at).include? a}.map{ |a| form_input(a) }.join("\n")
45
+ assignable_attributes.map { |a| form_input(a) }.join("\n ")
38
46
  end
39
47
 
40
48
  def form_input(name)
@@ -1,5 +1,6 @@
1
1
  module ActiveAdmin
2
2
  module ScopeChain
3
+ private
3
4
  # Scope an ActiveRecord::Relation chain
4
5
  #
5
6
  # Example:
@@ -9,10 +9,17 @@ module ActiveAdmin
9
9
  end
10
10
  end
11
11
 
12
+ # Can pass proc to filter label option
13
+ def label_from_options
14
+ res = super
15
+ res = res.call if res.is_a? Proc
16
+ res
17
+ end
18
+
12
19
  private
13
20
  def datepicker_options
14
21
  options = self.options.fetch(:datepicker_options, {})
15
- options = Hash[options.map{ |k, v| [k.to_s.camelcase(:lower), v] }]
22
+ options = Hash[options.map { |k, v| [k.to_s.camelcase(:lower), v] }]
16
23
  { datepicker_options: options }
17
24
  end
18
25
  end
@@ -57,8 +57,8 @@ module ActiveAdmin
57
57
 
58
58
  def current_filter
59
59
  @current_filter ||= begin
60
- methods = filters.map{ |f| "#{method}_#{f}" }
61
- methods.detect{ |m| @object.public_send m } || methods.first
60
+ methods = filters.map { |f| "#{method}_#{f}" }
61
+ methods.detect { |m| @object.public_send m } || methods.first
62
62
  end
63
63
  end
64
64