avo 2.43.0 → 3.0.2

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

Potentially problematic release.


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

Files changed (414) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +30 -26
  3. data/Gemfile.lock +235 -161
  4. data/README.md +19 -27
  5. data/Rakefile +2 -0
  6. data/app/assets/stylesheets/avo.base.css +1 -1
  7. data/app/assets/svgs/font.svg +1 -0
  8. data/app/assets/svgs/triangle-up.svg +1 -0
  9. data/app/components/avo/actions_component.html.erb +19 -5
  10. data/app/components/avo/actions_component.rb +39 -19
  11. data/app/components/avo/asset_manager/javascript_component.html.erb +3 -0
  12. data/app/components/avo/asset_manager/javascript_component.rb +13 -0
  13. data/app/components/avo/asset_manager/stylesheet_component.html.erb +3 -0
  14. data/app/components/avo/asset_manager/stylesheet_component.rb +13 -0
  15. data/app/components/avo/base_component.rb +15 -12
  16. data/app/components/avo/button_component.rb +20 -3
  17. data/app/components/avo/empty_state_component.rb +1 -1
  18. data/app/components/avo/field_wrapper_component.html.erb +1 -1
  19. data/app/components/avo/field_wrapper_component.rb +9 -15
  20. data/app/components/avo/fields/area_field/edit_component.html.erb +2 -2
  21. data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +75 -79
  22. data/app/components/avo/fields/belongs_to_field/edit_component.rb +7 -7
  23. data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
  24. data/app/components/avo/fields/belongs_to_field/show_component.rb +2 -2
  25. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
  26. data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
  27. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +3 -3
  28. data/app/components/avo/fields/common/badge_viewer_component.rb +1 -1
  29. data/app/components/avo/fields/common/boolean_check_component.html.erb +1 -12
  30. data/app/components/avo/fields/common/boolean_check_component.rb +2 -1
  31. data/app/components/avo/fields/common/boolean_group_component.html.erb +2 -2
  32. data/app/components/avo/fields/common/files/view_type/grid_item_component.rb +2 -2
  33. data/app/components/avo/fields/common/gravatar_viewer_component.html.erb +1 -1
  34. data/app/components/avo/fields/common/gravatar_viewer_component.rb +2 -2
  35. data/app/components/avo/fields/common/heading_component.html.erb +3 -8
  36. data/app/components/avo/fields/common/heading_component.rb +1 -3
  37. data/app/components/avo/fields/common/key_value_component.html.erb +2 -2
  38. data/app/components/avo/fields/common/key_value_component.rb +2 -2
  39. data/app/components/avo/fields/common/progress_bar_component.rb +3 -9
  40. data/app/components/avo/fields/common/status_viewer_component.html.erb +3 -0
  41. data/app/components/avo/fields/edit_component.rb +2 -2
  42. data/app/components/avo/fields/external_image_field/index_component.html.erb +1 -1
  43. data/app/components/avo/fields/file_field/index_component.html.erb +2 -2
  44. data/app/components/avo/fields/gravatar_field/index_component.html.erb +1 -1
  45. data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
  46. data/app/components/avo/fields/has_one_field/show_component.html.erb +3 -2
  47. data/app/components/avo/fields/has_one_field/show_component.rb +2 -2
  48. data/app/components/avo/fields/heading_field/edit_component.html.erb +1 -1
  49. data/app/components/avo/fields/heading_field/show_component.html.erb +1 -1
  50. data/app/components/avo/fields/id_field/index_component.html.erb +1 -1
  51. data/app/components/avo/fields/index_component.rb +6 -6
  52. data/app/components/avo/fields/location_field/edit_component.html.erb +12 -10
  53. data/app/components/avo/fields/preview_field/index_component.html.erb +10 -0
  54. data/app/components/avo/fields/preview_field/index_component.rb +4 -0
  55. data/app/components/avo/fields/select_field/edit_component.html.erb +1 -1
  56. data/app/components/avo/fields/show_component.rb +5 -2
  57. data/app/components/avo/fields/text_field/index_component.html.erb +1 -1
  58. data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -2
  59. data/app/components/avo/fields/trix_field/edit_component.rb +1 -1
  60. data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
  61. data/app/components/avo/filters_component.html.erb +9 -3
  62. data/app/components/avo/filters_component.rb +4 -4
  63. data/app/components/avo/index/field_wrapper_component.rb +1 -13
  64. data/app/components/avo/index/grid_item_component.html.erb +13 -36
  65. data/app/components/avo/index/grid_item_component.rb +43 -16
  66. data/app/components/avo/index/resource_controls_component.html.erb +3 -81
  67. data/app/components/avo/index/resource_controls_component.rb +125 -18
  68. data/app/components/avo/index/resource_grid_component.html.erb +5 -3
  69. data/app/components/avo/index/resource_grid_component.rb +5 -2
  70. data/app/components/avo/index/resource_map_component.html.erb +1 -1
  71. data/app/components/avo/index/resource_map_component.rb +3 -3
  72. data/app/components/avo/index/resource_table_component.html.erb +5 -4
  73. data/app/components/avo/index/resource_table_component.rb +24 -7
  74. data/app/components/avo/index/table_row_component.html.erb +9 -5
  75. data/app/components/avo/index/table_row_component.rb +3 -2
  76. data/app/components/avo/items/panel_component.html.erb +25 -0
  77. data/app/components/avo/items/panel_component.rb +43 -0
  78. data/app/components/avo/items/switcher_component.html.erb +17 -0
  79. data/app/components/avo/items/switcher_component.rb +79 -0
  80. data/app/components/avo/items/visible_items_component.html.erb +10 -0
  81. data/app/components/avo/items/visible_items_component.rb +11 -0
  82. data/app/components/avo/modal_component.html.erb +3 -4
  83. data/app/components/avo/paginator_component.html.erb +29 -40
  84. data/app/components/avo/paginator_component.rb +23 -5
  85. data/app/components/avo/panel_component.html.erb +7 -5
  86. data/app/components/avo/referrer_params_component.html.erb +1 -1
  87. data/app/components/avo/resource_component.rb +205 -26
  88. data/app/components/avo/resource_sidebar_component.html.erb +15 -18
  89. data/app/components/avo/resource_sidebar_component.rb +5 -3
  90. data/app/components/avo/sidebar/link_component.rb +1 -1
  91. data/app/components/avo/sidebar_component.html.erb +10 -3
  92. data/app/components/avo/sidebar_component.rb +5 -3
  93. data/app/components/avo/sidebar_profile_component.html.erb +18 -12
  94. data/app/components/avo/tab_group_component.html.erb +14 -8
  95. data/app/components/avo/tab_group_component.rb +1 -6
  96. data/app/components/avo/tab_switcher_component.html.erb +17 -40
  97. data/app/components/avo/tab_switcher_component.rb +6 -41
  98. data/app/components/avo/views/resource_edit_component.html.erb +23 -84
  99. data/app/components/avo/views/resource_edit_component.rb +20 -19
  100. data/app/components/avo/views/resource_index_component.html.erb +42 -47
  101. data/app/components/avo/views/resource_index_component.rb +76 -13
  102. data/app/components/avo/views/resource_show_component.html.erb +16 -177
  103. data/app/components/avo/views/resource_show_component.rb +16 -10
  104. data/app/controllers/avo/actions_controller.rb +37 -41
  105. data/app/controllers/avo/application_controller.rb +119 -181
  106. data/app/controllers/avo/associations_controller.rb +34 -43
  107. data/app/controllers/avo/attachments_controller.rb +4 -4
  108. data/app/controllers/avo/base_controller.rb +145 -98
  109. data/app/controllers/avo/debug_controller.rb +17 -5
  110. data/app/controllers/avo/home_controller.rb +1 -1
  111. data/app/controllers/avo/search_controller.rb +56 -50
  112. data/app/controllers/concerns/avo/initializes_avo.rb +22 -0
  113. data/app/helpers/avo/application_helper.rb +18 -8
  114. data/app/helpers/avo/resources_helper.rb +1 -1
  115. data/app/helpers/avo/url_helpers.rb +28 -12
  116. data/app/javascript/avo.base.js +1 -0
  117. data/app/javascript/js/application.js +3 -0
  118. data/app/javascript/js/controllers/action_controller.js +3 -1
  119. data/app/javascript/js/controllers/actions_overflow_controller.js +62 -0
  120. data/app/javascript/js/controllers/fields/reload_belongs_to_field_controller.js +7 -7
  121. data/app/javascript/js/controllers/filter_controller.js +1 -1
  122. data/app/javascript/js/controllers/input_autofocus_controller.js +12 -0
  123. data/app/javascript/js/controllers/preview_controller.js +24 -0
  124. data/app/javascript/js/controllers/search_controller.js +4 -2
  125. data/app/javascript/js/controllers/self_destroy_controller.js +7 -0
  126. data/app/javascript/js/controllers/toggle_controller.js +48 -0
  127. data/app/javascript/js/controllers.js +11 -5
  128. data/app/javascript/js/custom-stream-actions.js +15 -0
  129. data/app/views/avo/actions/show.html.erb +10 -7
  130. data/app/views/avo/associations/new.html.erb +2 -2
  131. data/app/views/avo/base/_new_via_belongs_to.html.erb +1 -1
  132. data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +3 -3
  133. data/app/views/avo/base/create_fail_action.turbo_stream.erb +2 -2
  134. data/app/views/avo/base/edit.html.erb +1 -1
  135. data/app/views/avo/base/index.html.erb +4 -3
  136. data/app/views/avo/base/new.html.erb +2 -1
  137. data/app/views/avo/base/preview.html.erb +19 -0
  138. data/app/views/avo/base/show.html.erb +2 -2
  139. data/app/views/avo/debug/_valid_indicator.html.erb +9 -0
  140. data/app/views/avo/debug/report.html.erb +32 -17
  141. data/app/views/avo/debug/{index.html.erb → status.html.erb} +31 -14
  142. data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
  143. data/app/views/avo/partials/_flash_alerts.turbo_stream.erb +1 -1
  144. data/app/views/avo/partials/_footer.html.erb +1 -1
  145. data/app/views/avo/partials/_javascript.html.erb +5 -0
  146. data/app/views/avo/partials/_logo.html.erb +1 -1
  147. data/app/views/avo/partials/_navbar.html.erb +3 -5
  148. data/app/views/avo/partials/_resource_search.html.erb +1 -0
  149. data/app/views/avo/partials/_table_header.html.erb +5 -11
  150. data/app/views/layouts/avo/application.html.erb +5 -4
  151. data/avo.gemspec +11 -8
  152. data/bin/dev +3 -1
  153. data/bin/prod +0 -0
  154. data/config/i18n-tasks.yml +1 -1
  155. data/config/initializers/pagy.rb +2 -0
  156. data/config/master.key +1 -0
  157. data/config/routes.rb +7 -10
  158. data/db/factories.rb +6 -0
  159. data/lib/avo/asset_manager.rb +30 -0
  160. data/lib/avo/base_action.rb +84 -82
  161. data/lib/avo/base_resource.rb +286 -225
  162. data/lib/avo/base_resource_tool.rb +9 -16
  163. data/lib/avo/concerns/borrow_items_holder.rb +35 -0
  164. data/lib/avo/concerns/breadcrumbs.rb +2 -2
  165. data/lib/avo/concerns/{can_replace_fields.rb → can_replace_items.rb} +5 -9
  166. data/lib/avo/concerns/filters_session_handler.rb +7 -5
  167. data/lib/avo/concerns/has_controls.rb +37 -0
  168. data/lib/avo/concerns/has_description.rb +23 -0
  169. data/lib/avo/concerns/has_helpers.rb +18 -0
  170. data/lib/avo/concerns/has_item_type.rb +42 -0
  171. data/lib/avo/concerns/has_items.rb +339 -0
  172. data/lib/avo/concerns/hydration.rb +17 -0
  173. data/lib/avo/concerns/is_resource_item.rb +16 -36
  174. data/lib/avo/concerns/is_visible.rb +15 -0
  175. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  176. data/lib/avo/concerns/pagination.rb +53 -0
  177. data/lib/avo/concerns/visible_in_different_views.rb +132 -0
  178. data/lib/avo/concerns/visible_items.rb +7 -38
  179. data/lib/avo/configuration/branding.rb +0 -12
  180. data/lib/avo/configuration.rb +28 -11
  181. data/lib/avo/current.rb +39 -0
  182. data/lib/avo/dsl/field_parser.rb +3 -3
  183. data/lib/avo/dynamic_router.rb +18 -3
  184. data/lib/avo/engine.rb +35 -30
  185. data/lib/avo/error_manager.rb +25 -0
  186. data/lib/avo/execution_context.rb +14 -15
  187. data/lib/avo/fields/base_field.rb +84 -115
  188. data/lib/avo/fields/belongs_to_field.rb +19 -23
  189. data/lib/avo/fields/concerns/file_authorization.rb +2 -2
  190. data/lib/avo/fields/concerns/handles_field_args.rb +49 -0
  191. data/lib/avo/fields/concerns/has_default.rb +1 -5
  192. data/lib/avo/fields/concerns/has_field_name.rb +22 -0
  193. data/lib/avo/fields/concerns/has_html_attributes.rb +112 -0
  194. data/lib/avo/fields/concerns/is_disabled.rb +1 -5
  195. data/lib/avo/fields/concerns/is_readonly.rb +1 -5
  196. data/lib/avo/fields/concerns/is_required.rb +5 -7
  197. data/lib/avo/fields/concerns/is_searchable.rb +15 -0
  198. data/lib/avo/fields/concerns/use_resource.rb +5 -1
  199. data/lib/avo/fields/concerns/use_view_components.rb +45 -0
  200. data/lib/avo/fields/country_field.rb +4 -0
  201. data/lib/avo/fields/date_time_field.rb +1 -5
  202. data/lib/avo/fields/external_image_field.rb +2 -2
  203. data/lib/avo/fields/field_manager.rb +55 -0
  204. data/lib/avo/fields/file_field.rb +2 -2
  205. data/lib/avo/fields/gravatar_field.rb +2 -2
  206. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -2
  207. data/lib/avo/fields/has_base_field.rb +21 -17
  208. data/lib/avo/fields/has_many_field.rb +5 -2
  209. data/lib/avo/fields/has_one_field.rb +8 -12
  210. data/lib/avo/fields/heading_field.rb +9 -14
  211. data/lib/avo/fields/hidden_field.rb +1 -1
  212. data/lib/avo/fields/id_field.rb +3 -3
  213. data/lib/avo/fields/location_field.rb +10 -10
  214. data/lib/avo/fields/password_field.rb +1 -1
  215. data/lib/avo/fields/preview_field.rb +14 -0
  216. data/lib/avo/fields/select_field.rb +12 -8
  217. data/lib/avo/fields/status_field.rb +7 -1
  218. data/lib/avo/fields/text_field.rb +2 -2
  219. data/lib/avo/filters/base_filter.rb +9 -4
  220. data/lib/avo/html/builder.rb +8 -8
  221. data/lib/avo/item_grapher.rb +78 -0
  222. data/lib/avo/licensing/h_q.rb +11 -73
  223. data/lib/avo/licensing/license.rb +5 -1
  224. data/lib/avo/licensing/license_manager.rb +1 -1
  225. data/lib/avo/licensing/pro_license.rb +1 -7
  226. data/lib/avo/loaders/fields_loader.rb +7 -1
  227. data/lib/avo/plugin.rb +36 -0
  228. data/lib/avo/plugin_manager.rb +56 -0
  229. data/lib/avo/prefixed_test_helpers.rb +20 -0
  230. data/lib/avo/reloader.rb +3 -0
  231. data/lib/avo/resources/controls/actions_list.rb +7 -12
  232. data/lib/avo/resources/controls/attach_button.rb +15 -0
  233. data/lib/avo/resources/controls/back_button.rb +1 -1
  234. data/lib/avo/resources/controls/base_control.rb +15 -49
  235. data/lib/avo/resources/controls/create_button.rb +15 -0
  236. data/lib/avo/resources/controls/delete_button.rb +5 -1
  237. data/lib/avo/resources/controls/detach_button.rb +4 -1
  238. data/lib/avo/resources/controls/edit_button.rb +4 -1
  239. data/lib/avo/resources/controls/order_controls.rb +8 -0
  240. data/lib/avo/resources/controls/save_button.rb +13 -0
  241. data/lib/avo/resources/controls/show_button.rb +15 -0
  242. data/lib/avo/resources/items/holder.rb +96 -0
  243. data/lib/avo/resources/items/item_group.rb +44 -0
  244. data/lib/avo/resources/items/main_panel.rb +12 -0
  245. data/lib/avo/resources/items/panel.rb +2 -0
  246. data/lib/avo/resources/items/row.rb +42 -0
  247. data/lib/avo/resources/items/sidebar.rb +46 -0
  248. data/lib/avo/resources/items/tab.rb +54 -0
  249. data/lib/avo/resources/items/tab_group.rb +62 -0
  250. data/lib/avo/resources/resource_manager.rb +179 -0
  251. data/lib/avo/services/authorization_service.rb +11 -110
  252. data/lib/avo/services/debug_service.rb +93 -0
  253. data/lib/avo/services/encryption_service.rb +8 -12
  254. data/lib/avo/services/telemetry_service.rb +85 -0
  255. data/lib/avo/test_helpers.rb +362 -0
  256. data/lib/avo/tools/tool_manager.rb +30 -0
  257. data/lib/avo/version.rb +1 -1
  258. data/lib/avo/view_inquirer.rb +36 -0
  259. data/lib/avo.rb +109 -24
  260. data/lib/generators/avo/action_generator.rb +8 -8
  261. data/lib/generators/avo/card_generator.rb +27 -0
  262. data/lib/generators/avo/concerns/parent_controller.rb +20 -0
  263. data/lib/generators/avo/controller_generator.rb +3 -0
  264. data/lib/generators/avo/eject_generator.rb +180 -15
  265. data/lib/generators/avo/field_generator.rb +49 -2
  266. data/lib/generators/avo/filter_generator.rb +8 -8
  267. data/lib/generators/avo/js/install_generator.rb +2 -2
  268. data/lib/generators/avo/resource_generator.rb +12 -9
  269. data/lib/generators/avo/scope_generator.rb +15 -0
  270. data/lib/generators/avo/tailwindcss/install_generator.rb +70 -26
  271. data/lib/generators/avo/templates/action.tt +8 -6
  272. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  273. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  274. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  275. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  276. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  277. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  278. data/lib/generators/avo/templates/dashboards/dashboard.tt +5 -3
  279. data/lib/generators/avo/templates/field/%singular_name%_field.rb.tt +1 -1
  280. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  281. data/lib/generators/avo/templates/filters/multiple_select_filter.tt +1 -1
  282. data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
  283. data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
  284. data/lib/generators/avo/templates/initializer/avo.tt +7 -3
  285. data/lib/generators/avo/templates/locales/avo.ar.yml +7 -6
  286. data/lib/generators/avo/templates/locales/avo.en.yml +6 -3
  287. data/lib/generators/avo/templates/locales/avo.es.yml +127 -0
  288. data/lib/generators/avo/templates/locales/avo.fr.yml +3 -0
  289. data/lib/generators/avo/templates/locales/avo.nb.yml +3 -0
  290. data/lib/generators/avo/templates/locales/avo.nn.yml +3 -0
  291. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +3 -0
  292. data/lib/generators/avo/templates/locales/avo.pt.yml +3 -0
  293. data/lib/generators/avo/templates/locales/avo.ro.yml +8 -5
  294. data/lib/generators/avo/templates/locales/avo.tr.yml +3 -0
  295. data/lib/generators/avo/templates/resource/controller.tt +1 -1
  296. data/lib/generators/avo/templates/resource/resource.tt +7 -7
  297. data/lib/generators/avo/templates/resource_tools/partial.tt +2 -2
  298. data/lib/generators/avo/templates/resource_tools/resource_tool.tt +1 -1
  299. data/lib/generators/avo/templates/scope.tt +6 -0
  300. data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
  301. data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +5 -3
  302. data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +11 -0
  303. data/lib/tasks/avo_tasks.rake +72 -4
  304. data/public/avo-assets/avo.base.css +1893 -1187
  305. data/public/avo-assets/avo.base.js +223 -311
  306. data/public/avo-assets/avo.base.js.map +3 -3
  307. data/public/avo-assets/avo.css +9744 -0
  308. data/public/avo-assets/avo.js +513 -0
  309. data/public/avo-assets/avo.js.map +7 -0
  310. data/tailwind.custom.js +47 -0
  311. data/tailwind.preset.js +152 -0
  312. metadata +121 -116
  313. data/app/components/avo/card_component.html.erb +0 -46
  314. data/app/components/avo/card_component.rb +0 -25
  315. data/app/components/avo/dashboards/divider_component.html.erb +0 -9
  316. data/app/components/avo/dashboards/divider_component.rb +0 -19
  317. data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +0 -47
  318. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +0 -95
  319. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -35
  320. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  321. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -10
  322. data/app/components/avo/fields/tags_field/index_component.rb +0 -9
  323. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  324. data/app/components/avo/fields/tags_field/show_component.rb +0 -5
  325. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  326. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  327. data/app/components/avo/index/ordering/base_component.rb +0 -9
  328. data/app/components/avo/index/ordering/button_component.html.erb +0 -11
  329. data/app/components/avo/index/ordering/button_component.rb +0 -23
  330. data/app/components/avo/index/ordering/buttons_component.html.erb +0 -32
  331. data/app/components/avo/index/ordering/buttons_component.rb +0 -47
  332. data/app/components/avo/item_switcher_component.html.erb +0 -27
  333. data/app/components/avo/item_switcher_component.rb +0 -48
  334. data/app/components/avo/sidebar/item_switcher_component.html.erb +0 -16
  335. data/app/components/avo/sidebar/item_switcher_component.rb +0 -15
  336. data/app/controllers/avo/dashboards/cards_controller.rb +0 -37
  337. data/app/controllers/avo/dashboards_controller.rb +0 -22
  338. data/app/controllers/avo/reorder_controller.rb +0 -25
  339. data/app/controllers/avo/team_users_controller.rb +0 -4
  340. data/app/javascript/js/controllers/base_controller.js +0 -22
  341. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -127
  342. data/app/javascript/js/controllers/toggle_panel_controller.js +0 -18
  343. data/app/views/avo/dashboards/cards/_chartkick_card.html.erb +0 -3
  344. data/app/views/avo/dashboards/cards/_metric_card.html.erb +0 -5
  345. data/app/views/avo/dashboards/cards/chartkick_missing.html.erb +0 -14
  346. data/app/views/avo/dashboards/cards/show.html.erb +0 -3
  347. data/app/views/avo/dashboards/show.html.erb +0 -38
  348. data/app/views/avo/partials/_global_search.html.erb +0 -19
  349. data/app/views/avo/sidebar/_license_warnings.html.erb +0 -6
  350. data/lib/avo/action_model.rb +0 -20
  351. data/lib/avo/app.rb +0 -237
  352. data/lib/avo/base_card.rb +0 -161
  353. data/lib/avo/concerns/fetches_things.rb +0 -150
  354. data/lib/avo/concerns/handles_field_args.rb +0 -47
  355. data/lib/avo/concerns/has_editable_controls.rb +0 -34
  356. data/lib/avo/concerns/has_fields.rb +0 -334
  357. data/lib/avo/concerns/has_html_attributes.rb +0 -108
  358. data/lib/avo/concerns/policy_helpers.rb +0 -31
  359. data/lib/avo/concerns/visible_in_dashboard.rb +0 -31
  360. data/lib/avo/dashboards/base_dashboard.rb +0 -89
  361. data/lib/avo/dashboards/base_divider.rb +0 -35
  362. data/lib/avo/dashboards/chartkick_card.rb +0 -77
  363. data/lib/avo/dashboards/dashboard_card.rb +0 -6
  364. data/lib/avo/dashboards/metric_card.rb +0 -9
  365. data/lib/avo/dashboards/partial_card.rb +0 -7
  366. data/lib/avo/fields/field_extensions/has_field_name.rb +0 -19
  367. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +0 -111
  368. data/lib/avo/fields/tags_field.rb +0 -102
  369. data/lib/avo/grid_collector.rb +0 -42
  370. data/lib/avo/hosts/association_scope_host.rb +0 -8
  371. data/lib/avo/hosts/base_host.rb +0 -25
  372. data/lib/avo/hosts/card_visibility.rb +0 -20
  373. data/lib/avo/hosts/dashboard_card.rb +0 -22
  374. data/lib/avo/hosts/dashboard_visibility.rb +0 -19
  375. data/lib/avo/hosts/ordering.rb +0 -22
  376. data/lib/avo/hosts/record_host.rb +0 -7
  377. data/lib/avo/hosts/resource_record_host.rb +0 -7
  378. data/lib/avo/hosts/resource_view_record_host.rb +0 -7
  379. data/lib/avo/hosts/search_scope_host.rb +0 -7
  380. data/lib/avo/hosts/view_record_host.rb +0 -7
  381. data/lib/avo/hosts/visibility_host.rb +0 -12
  382. data/lib/avo/items_holder.rb +0 -96
  383. data/lib/avo/main_panel.rb +0 -3
  384. data/lib/avo/menu/base_item.rb +0 -25
  385. data/lib/avo/menu/builder.rb +0 -82
  386. data/lib/avo/menu/dashboard.rb +0 -22
  387. data/lib/avo/menu/group.rb +0 -2
  388. data/lib/avo/menu/link.rb +0 -6
  389. data/lib/avo/menu/menu.rb +0 -2
  390. data/lib/avo/menu/resource.rb +0 -22
  391. data/lib/avo/menu/section.rb +0 -2
  392. data/lib/avo/panel.rb +0 -24
  393. data/lib/avo/panel_builder.rb +0 -25
  394. data/lib/avo/resources/controls/action.rb +0 -38
  395. data/lib/avo/resources/controls/execution_context.rb +0 -58
  396. data/lib/avo/resources/controls/items_holder.rb +0 -19
  397. data/lib/avo/resources/controls/link_to.rb +0 -27
  398. data/lib/avo/row.rb +0 -26
  399. data/lib/avo/row_builder.rb +0 -24
  400. data/lib/avo/services/authorization_clients/nil_client.rb +0 -37
  401. data/lib/avo/services/authorization_clients/pundit_client.rb +0 -51
  402. data/lib/avo/sidebar.rb +0 -30
  403. data/lib/avo/sidebar_builder.rb +0 -24
  404. data/lib/avo/tab.rb +0 -72
  405. data/lib/avo/tab_builder.rb +0 -25
  406. data/lib/avo/tab_group.rb +0 -42
  407. data/lib/avo/tab_group_builder.rb +0 -43
  408. data/lib/avo/tools_manager.rb +0 -11
  409. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  410. data/lib/generators/avo/card/metric_generator.rb +0 -18
  411. data/lib/generators/avo/card/partial_generator.rb +0 -19
  412. data/lib/generators/avo/templates/js/avo.custom.js +0 -2
  413. data/lib/generators/avo/templates/standalone_action.tt +0 -8
  414. /data/app/assets/stylesheets/css/{tags.css → fields/tags.css} +0 -0
@@ -3,52 +3,64 @@ module Avo
3
3
  extend ActiveSupport::DescendantsTracker
4
4
 
5
5
  include ActionView::Helpers::UrlHelper
6
- include Avo::Concerns::HasFields
7
- include Avo::Concerns::CanReplaceFields
8
- include Avo::Concerns::HasEditableControls
6
+ include Avo::Concerns::HasItems
7
+ include Avo::Concerns::CanReplaceItems
8
+ include Avo::Concerns::HasControls
9
9
  include Avo::Concerns::HasStimulusControllers
10
10
  include Avo::Concerns::ModelClassConstantized
11
+ include Avo::Concerns::HasDescription
12
+ include Avo::Concerns::HasHelpers
13
+ include Avo::Concerns::Hydration
14
+ include Avo::Concerns::Pagination
11
15
 
12
- delegate :view_context, to: ::Avo::App
13
- delegate :current_user, to: ::Avo::App
14
- delegate :params, to: ::Avo::App
16
+ # Avo::Current methods
17
+ delegate :context, to: Avo::Current
18
+ def current_user
19
+ Avo::Current.user
20
+ end
21
+ delegate :params, to: Avo::Current
22
+ delegate :request, to: Avo::Current
23
+ delegate :view_context, to: Avo::Current
24
+
25
+ # view_context methods
15
26
  delegate :simple_format, :content_tag, to: :view_context
16
27
  delegate :main_app, to: :view_context
17
28
  delegate :avo, to: :view_context
18
29
  delegate :resource_path, to: :view_context
19
30
  delegate :resources_path, to: :view_context
31
+
32
+ # I18n methods
20
33
  delegate :t, to: ::I18n
21
- delegate :context, to: ::Avo::App
34
+
35
+ # class methods
36
+ delegate :class_name, to: :class
37
+ delegate :route_key, to: :class
38
+ delegate :singular_route_key, to: :class
22
39
 
23
40
  attr_accessor :view
24
41
  attr_accessor :reflection
25
42
  attr_accessor :user
26
- attr_accessor :params
43
+ attr_accessor :record
27
44
 
28
45
  class_attribute :id, default: :id
29
- class_attribute :title, default: :id
30
- class_attribute :description, default: :id
31
- class_attribute :search_query, default: nil
32
- class_attribute :search_query_help, default: ""
33
- class_attribute :search_result_path
46
+ class_attribute :title
47
+ class_attribute :search, default: {}
34
48
  class_attribute :includes, default: []
35
49
  class_attribute :authorization_policy
36
50
  class_attribute :translation_key
37
51
  class_attribute :default_view_type, default: :table
38
52
  class_attribute :devise_password_optional, default: false
39
- class_attribute :actions_loader
53
+ class_attribute :scopes_loader
40
54
  class_attribute :filters_loader
41
- class_attribute :grid_loader
55
+ class_attribute :view_types
56
+ class_attribute :grid_view
42
57
  class_attribute :visible_on_sidebar, default: true
43
- class_attribute :unscoped_queries_on_index, default: false
44
- class_attribute :resolve_query_scope
45
- class_attribute :resolve_find_scope
46
- # TODO: refactor this into a Host without args
47
- class_attribute :find_record_method, default: ->(model_class:, id:, params:) {
48
- model_class.find id
58
+ class_attribute :index_query, default: -> {
59
+ query
60
+ }
61
+ class_attribute :find_record_method, default: -> {
62
+ query.find id
49
63
  }
50
- class_attribute :ordering
51
- class_attribute :hide_from_global_search, default: false
52
64
  class_attribute :after_create_path, default: :show
53
65
  class_attribute :after_update_path, default: :show
54
66
  class_attribute :record_selector, default: true
@@ -56,60 +68,46 @@ module Avo
56
68
  class_attribute :extra_params
57
69
  class_attribute :link_to_child_resource, default: false
58
70
  class_attribute :map_view
71
+ class_attribute :components, default: {}
72
+
73
+ # EXTRACT:
74
+ class_attribute :ordering
59
75
 
60
76
  class << self
61
77
  delegate :t, to: ::I18n
62
- delegate :context, to: ::Avo::App
63
-
64
- def grid(&block)
65
- grid_collector = GridCollector.new
66
- grid_collector.instance_eval(&block)
67
-
68
- self.grid_loader = grid_collector
69
- end
78
+ delegate :context, to: ::Avo::Current
70
79
 
71
80
  def action(action_class, arguments: {})
72
- self.actions_loader ||= Avo::Loaders::Loader.new
73
-
74
- action = { class: action_class, arguments: arguments }
75
- self.actions_loader.use action
81
+ deprecated_dsl_api __method__, "actions"
76
82
  end
77
83
 
78
84
  def filter(filter_class, arguments: {})
79
- self.filters_loader ||= Avo::Loaders::Loader.new
80
-
81
- filter = { class: filter_class , arguments: arguments }
82
- self.filters_loader.use filter
85
+ deprecated_dsl_api __method__, "filters"
83
86
  end
84
87
 
85
- # This is the search_query scope
86
- # This should be removed and passed to the search block
87
- def scope
88
- query_scope
88
+ def scope(scope_class)
89
+ deprecated_dsl_api __method__, "scopes"
89
90
  end
90
91
 
91
92
  # This resolves the scope when doing "where" queries (not find queries)
93
+ #
94
+ # It's used to apply the authorization feature.
92
95
  def query_scope
93
- final_scope = resolve_query_scope.present? ? resolve_query_scope.call(model_class: model_class) : model_class
94
-
95
- authorization.apply_policy final_scope
96
+ authorization.apply_policy Avo::ExecutionContext.new(
97
+ target: index_query,
98
+ query: model_class
99
+ ).handle
96
100
  end
97
101
 
98
102
  # This resolves the scope when finding records (not "where" queries)
103
+ #
104
+ # It's used to apply the authorization feature.
99
105
  def find_scope
100
- final_scope = resolve_find_scope.present? ? resolve_find_scope.call(model_class: model_class) : model_class
101
-
102
- authorization.apply_policy final_scope
106
+ authorization.apply_policy model_class
103
107
  end
104
108
 
105
109
  def authorization
106
- Avo::Services::AuthorizationService.new Avo::App.current_user, model_class, policy_class: authorization_policy
107
- end
108
-
109
- def order_actions
110
- return {} if ordering.blank?
111
-
112
- ordering.dig(:actions) || {}
110
+ Avo::Services::AuthorizationService.new Avo::Current.user, model_class, policy_class: authorization_policy
113
111
  end
114
112
 
115
113
  def get_record_associations(record)
@@ -133,170 +131,261 @@ module Avo
133
131
  ApplicationRecord.descendants
134
132
  end
135
133
 
136
- def valid_model_class(model_class)
134
+ def get_model_by_name(model_name)
137
135
  get_available_models.find do |m|
138
- m.to_s == model_class.to_s
136
+ m.to_s == model_name.to_s
139
137
  end
140
138
  end
141
- end
142
139
 
143
- def initialize
144
- unless self.class.model_class.present?
145
- if model_class.present? && model_class.respond_to?(:base_class)
146
- self.class.model_class = model_class.base_class
147
- end
140
+ # Returns the model class being used for this resource.
141
+ #
142
+ # The Resource instance has a model_class method too so it can support the STI use cases
143
+ # where we figure out the model class from the record
144
+ def model_class(record_class: nil)
145
+ # get the model class off of the static property
146
+ return @model_class if @model_class.present?
147
+
148
+ # get the model class off of the record for STI models
149
+ return record_class if record_class.present?
150
+
151
+ # generate a model class
152
+ class_name.safe_constantize
148
153
  end
149
- end
150
154
 
151
- def record
152
- @model
153
- end
154
- alias_method :model, :record
155
+ # This is used as the model class ID
156
+ # We use this instead of the route_key to maintain compatibility with uncountable models
157
+ # With uncountable models route key appends an _index suffix (Fish->fish_index)
158
+ # Example: User->users, MediaItem->media_items, Fish->fish
159
+ def model_key
160
+ model_class.model_name.plural
161
+ end
155
162
 
163
+ def class_name
164
+ to_s.demodulize
165
+ end
156
166
 
157
- def hydrate(model: nil, view: nil, user: nil, params: nil)
158
- @view = view if view.present?
159
- @user = user if user.present?
160
- @params = params if params.present?
167
+ def route_key
168
+ class_name.underscore.pluralize
169
+ end
161
170
 
162
- if model.present?
163
- @model = model
171
+ def singular_route_key
172
+ route_key.singularize
173
+ end
164
174
 
165
- hydrate_model_with_default_values if @view == :new
175
+ def translation_key
176
+ @translation_key || "avo.resource_translations.#{class_name.underscore}"
166
177
  end
167
178
 
168
- self
169
- end
179
+ def name
180
+ default = class_name.underscore.humanize
170
181
 
171
- def get_grid_fields
172
- return if self.class.grid_loader.blank?
182
+ if translation_key
183
+ t(translation_key, count: 1, default: default).humanize
184
+ else
185
+ default
186
+ end
187
+ end
188
+ alias_method :singular_name, :name
173
189
 
174
- self.class.grid_loader.hydrate(model: @model, view: @view, resource: self)
175
- end
190
+ def plural_name
191
+ default = name.pluralize
176
192
 
177
- def get_filters
178
- return [] if self.class.filters_loader.blank?
193
+ if translation_key
194
+ t(translation_key, count: 2, default: default).humanize
195
+ else
196
+ default
197
+ end
198
+ end
179
199
 
180
- self.class.filters_loader.bag
181
- end
200
+ def underscore_name
201
+ return @name if @name.present?
182
202
 
183
- def get_filter_arguments(filter_class)
184
- filter = get_filters.find { |filter| filter[:class] == filter_class.constantize }
203
+ name.demodulize.underscore
204
+ end
185
205
 
186
- filter[:arguments]
187
- end
206
+ def navigation_label
207
+ plural_name.humanize
208
+ end
188
209
 
189
- def get_actions
190
- return [] if self.class.actions_loader.blank?
210
+ def find_record(id, query: nil, params: nil)
211
+ Avo::ExecutionContext.new(
212
+ target: find_record_method,
213
+ query: query || find_scope, # If no record is given we'll use the default
214
+ id: id,
215
+ params: params
216
+ ).handle
217
+ end
218
+
219
+ def search_query
220
+ search.dig(:query)
221
+ end
191
222
 
192
- self.class.actions_loader.bag
223
+ def fetch_search(key, record: nil)
224
+ # self.class.fetch_search
225
+ Avo::ExecutionContext.new(target: search[key], resource: self, record: record).handle
226
+ end
193
227
  end
194
228
 
195
- def get_action_arguments(action_class)
196
- action = get_actions.find { |action| action[:class].to_s == action_class.to_s }
229
+ delegate :context, to: ::Avo::Current
230
+ delegate :name, to: :class
231
+ delegate :singular_name, to: :class
232
+ delegate :plural_name, to: :class
233
+ delegate :underscore_name, to: :class
234
+ delegate :underscore_name, to: :class
235
+ delegate :find_record, to: :class
236
+ delegate :model_key, to: :class
237
+ delegate :tab, to: :items_holder
197
238
 
198
- action[:arguments]
199
- end
239
+ def initialize(record: nil, view: nil, user: nil, params: nil)
240
+ @view = Avo::ViewInquirer.new(view) if view.present?
241
+ @user = user if user.present?
242
+ @params = params if params.present?
200
243
 
201
- def default_panel_name
202
- return @params[:related_name].capitalize if @params.present? && @params[:related_name].present?
244
+ if record.present?
245
+ @record = record
203
246
 
204
- case @view
205
- when :show
206
- model_title
207
- when :edit
208
- model_title
209
- when :new
210
- t("avo.create_new_item", item: name.downcase).upcase_first
247
+ hydrate_model_with_default_values if @view&.new?
211
248
  end
212
- end
213
249
 
214
- def class_name_without_resource
215
- self.class.name.demodulize.delete_suffix("Resource")
250
+ unless self.class.model_class.present?
251
+ if model_class.present? && model_class.respond_to?(:base_class)
252
+ self.class.model_class = model_class.base_class
253
+ end
254
+ end
216
255
  end
217
256
 
218
- def model_class
219
- # get the model class off of the static property
220
- return self.class.model_class if self.class.model_class.present?
257
+ def detect_fields
258
+ self.items_holder = Avo::Resources::Items::Holder.new(parent: self)
221
259
 
222
- # get the model class off of the model for STI models
223
- return @model.base_class if @model.present?
260
+ # Used in testing to replace items
261
+ if temporary_items.present?
262
+ instance_eval(&temporary_items)
263
+ else
264
+ fetch_fields
265
+ end
224
266
 
225
- # generate a model class
226
- class_name_without_resource.safe_constantize
267
+ self
227
268
  end
228
269
 
229
- def model_id
230
- @model.send id
231
- end
270
+ VIEW_METHODS_MAPPING = {
271
+ index: [:index_fields, :display_fields],
272
+ show: [:show_fields, :display_fields],
273
+ edit: [:edit_fields, :form_fields],
274
+ update: [:edit_fields, :form_fields],
275
+ new: [:new_fields, :form_fields],
276
+ create: [:new_fields, :form_fields]
277
+ } unless defined? VIEW_METHODS_MAPPING
232
278
 
233
- def model_title
234
- return name if @model.nil?
279
+ def fetch_fields
280
+ possible_methods_for_view = VIEW_METHODS_MAPPING[view.to_sym]
235
281
 
236
- the_title = @model.send title
237
- return the_title if the_title.present?
282
+ # Safe navigation operator is used because the view can be "destroy" or "preview"
283
+ possible_methods_for_view&.each do |method_for_view|
284
+ return send(method_for_view) if respond_to?(method_for_view)
285
+ end
238
286
 
239
- model_id
240
- rescue
241
- name
287
+ fields
242
288
  end
243
289
 
244
- def resource_description
245
- return instance_exec(&self.class.description) if self.class.description.respond_to? :call
290
+ def fields
291
+ # blank fields method
292
+ end
246
293
 
247
- # Show the description only on the resource index view.
248
- # If the user wants to conditionally it on all pages, they should use a block.
249
- if view == :index
250
- return self.class.description if self.class.description.is_a? String
294
+ [:action, :filter, :scope].each do |entity|
295
+ plural_entity = entity.to_s.pluralize
296
+
297
+ # def actions / def filters / def scopes
298
+ define_method plural_entity do
299
+ # blank entity method
251
300
  end
252
- end
253
301
 
254
- def translation_key
255
- return "avo.resource_translations.#{class_name_without_resource.underscore}" if ::Avo::App.translation_enabled
302
+ # def action / def filter / def scope
303
+ define_method entity do |entity_class, arguments: {}|
304
+ entity_loader(entity).use({class: entity_class, arguments: arguments})
305
+ end
256
306
 
257
- self.class.translation_key
258
- end
307
+ # def get_actions / def get_filters / def get_scopes
308
+ define_method "get_#{plural_entity}" do
309
+ return entity_loader(entity).bag if entity_loader(entity).present?
310
+
311
+ instance_variable_set("@#{plural_entity}_loader", Avo::Loaders::Loader.new)
312
+ send plural_entity
259
313
 
260
- def name
261
- default = class_name_without_resource.to_s.gsub('::', ' ').underscore.humanize
314
+ entity_loader(entity).bag
315
+ end
262
316
 
263
- return @name if @name.present?
317
+ # def get_action_arguments / def get_filter_arguments / def get_scope_arguments
318
+ define_method "get_#{entity}_arguments" do |entity_class|
319
+ klass = send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
264
320
 
265
- if translation_key && ::Avo::App.translation_enabled
266
- t(translation_key, count: 1, default: default).humanize
267
- else
268
- default
321
+ raise "Couldn't find '#{entity_class}' in the 'def #{plural_entity}' method on your '#{self.class}' resource." if klass.nil?
322
+
323
+ klass[:arguments]
269
324
  end
270
325
  end
271
326
 
272
- def singular_name
273
- name
327
+ def hydrate(...)
328
+ super(...)
329
+
330
+ if @record.present?
331
+ hydrate_model_with_default_values if @view&.new?
332
+ end
333
+
334
+ self
274
335
  end
275
336
 
276
- def plural_name
277
- default = name.pluralize
337
+ def default_panel_name
338
+ return @params[:related_name].capitalize if @params.present? && @params[:related_name].present?
278
339
 
279
- if translation_key && ::Avo::App.translation_enabled
280
- t(translation_key, count: 2, default: default).humanize
281
- else
282
- default
340
+ case @view.to_sym
341
+ when :show
342
+ record_title
343
+ when :edit
344
+ record_title
345
+ when :new
346
+ t("avo.create_new_item", item: name.humanize(capitalize: false)).upcase_first
283
347
  end
284
348
  end
285
349
 
286
- def underscore_name
287
- return @name if @name.present?
350
+ # Returns the model class being used for this resource.
351
+ #
352
+ # We use the class method as a fallback but we pass it the record too so it can support the STI use cases
353
+ # where we figure out the model class from that record.
354
+ def model_class
355
+ record_class = @record&.class
288
356
 
289
- self.class.name.demodulize.underscore
357
+ self.class.model_class record_class: record_class
290
358
  end
291
359
 
292
- def navigation_label
293
- plural_name.humanize
360
+ def record_title
361
+ return name if @record.nil?
362
+
363
+ # Get the title from the record if title is not set, try to get the name, title or label, or fallback to the id
364
+ return @record.try(:name) || @record.try(:title) || @record.try(:label) || @record.id if title.nil?
365
+
366
+ # If the title is a symbol, get the value from the record else execute the block/string
367
+ case title
368
+ when Symbol
369
+ @record.send title
370
+ when Proc
371
+ Avo::ExecutionContext.new(target: title, resource: self, record: @record).handle
372
+ end
294
373
  end
295
374
 
296
375
  def available_view_types
376
+ if self.class.view_types.present?
377
+ return Array(
378
+ Avo::ExecutionContext.new(
379
+ target: self.class.view_types,
380
+ resource: self,
381
+ record: record
382
+ ).handle
383
+ )
384
+ end
385
+
297
386
  view_types = [:table]
298
387
 
299
- view_types << :grid if get_grid_fields.present?
388
+ view_types << :grid if self.class.grid_view.present?
300
389
  view_types << :map if map_view.present?
301
390
 
302
391
  view_types
@@ -308,7 +397,7 @@ module Avo
308
397
  end
309
398
  end
310
399
 
311
- # Map the received params to their actual fields.
400
+ # Map the received params to their actual fields
312
401
  def fields_by_database_id
313
402
  get_field_definitions
314
403
  .reject do |field|
@@ -320,28 +409,28 @@ module Avo
320
409
  .to_h
321
410
  end
322
411
 
323
- def fill_model(model, params, extra_params: [])
412
+ def fill_record(record, params, extra_params: [])
324
413
  # Write the field values
325
414
  params.each do |key, value|
326
415
  field = fields_by_database_id[key]
327
416
 
328
417
  next unless field.present?
329
418
 
330
- model = field.fill_field model, key, value, params
419
+ record = field.fill_field record, key, value, params
331
420
  end
332
421
 
333
- # Write the user configured extra params to the model
422
+ # Write the user configured extra params to the record
334
423
  if extra_params.present?
335
424
  # Let Rails fill in the rest of the params
336
- model.assign_attributes params.permit(extra_params)
425
+ record.assign_attributes params.permit(extra_params)
337
426
  end
338
427
 
339
- model
428
+ record
340
429
  end
341
430
 
342
431
  def authorization(user: nil)
343
- current_user = user || Avo::App.current_user
344
- Avo::Services::AuthorizationService.new(current_user, model || model_class, policy_class: authorization_policy)
432
+ current_user = user || Avo::Current.user
433
+ Avo::Services::AuthorizationService.new(current_user, record || model_class, policy_class: authorization_policy)
345
434
  end
346
435
 
347
436
  def file_hash
@@ -362,37 +451,37 @@ module Avo
362
451
  Digest::MD5.hexdigest(content_to_be_hashed)
363
452
  end
364
453
 
365
- def cache_hash(parent_model)
366
- if parent_model.present?
367
- [model, file_hash, parent_model]
454
+ def cache_hash(parent_record)
455
+ if parent_record.present?
456
+ [record, file_hash, parent_record]
368
457
  else
369
- [model, file_hash]
458
+ [record, file_hash]
370
459
  end
371
460
  end
372
461
 
373
- # We will not overwrite any attributes that come pre-filled in the model.
462
+ # We will not overwrite any attributes that come pre-filled in the record.
374
463
  def hydrate_model_with_default_values
375
464
  default_values = get_fields
376
465
  .select do |field|
377
- !field.computed
466
+ !field.computed && !field.is_a?(Avo::Fields::HeadingField)
378
467
  end
379
468
  .map do |field|
380
469
  value = field.value
381
470
 
382
471
  if field.type == "belongs_to"
383
472
 
384
- reflection = @model._reflections[@params[:via_relation]]
473
+ reflection = @record._reflections[@params[:via_relation]]
385
474
 
386
475
  if field.polymorphic_as.present? && field.types.map(&:to_s).include?(@params[:via_relation_class])
387
476
  # set the value to the actual record
388
- via_resource = ::Avo::App.get_resource_by_model_name(@params[:via_relation_class])
389
- value = via_resource.find_record(@params[:via_resource_id])
477
+ via_resource = Avo.resource_manager.get_resource_by_model_class(@params[:via_relation_class])
478
+ value = via_resource.find_record(@params[:via_record_id])
390
479
  elsif reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
391
- resource = Avo::App.get_resource_by_model_name params[:via_relation_class]
392
- model = resource.find_record @params[:via_resource_id], params: params
480
+ resource = Avo.resource_manager.get_resource_by_model_class params[:via_relation_class]
481
+ record = resource.find_record @params[:via_record_id], params: params
393
482
  id_param = reflection.options[:primary_key] || :id
394
483
 
395
- value = model.send(id_param)
484
+ value = record.send(id_param)
396
485
  end
397
486
  end
398
487
 
@@ -404,26 +493,10 @@ module Avo
404
493
  end
405
494
 
406
495
  default_values.each do |field, value|
407
- field.assign_value record: @model, value: value
496
+ field.assign_value record: @record, value: value
408
497
  end
409
498
  end
410
499
 
411
- def route_key
412
- class_name_without_resource.underscore.pluralize
413
- end
414
-
415
- def singular_route_key
416
- route_key.singularize
417
- end
418
-
419
- # This is used as the model class ID
420
- # We use this instead of the route_key to maintain compatibility with uncountable models
421
- # With uncountable models route key appends an _index suffix (Fish->fish_index)
422
- # Example: User->users, MediaItem->media_items, Fish->fish
423
- def model_key
424
- model_class.model_name.plural
425
- end
426
-
427
500
  def model_name
428
501
  model_class.model_name
429
502
  end
@@ -433,25 +506,13 @@ module Avo
433
506
  end
434
507
 
435
508
  def record_path
436
- resource_path(model: model, resource: self)
509
+ resource_path(record: record, resource: self)
437
510
  end
438
511
 
439
512
  def records_path
440
513
  resources_path(resource: self)
441
514
  end
442
515
 
443
- def label_field
444
- get_field_definitions.find do |field|
445
- field.as_label.present?
446
- end
447
- rescue
448
- nil
449
- end
450
-
451
- def label
452
- label_field&.value || model_title
453
- end
454
-
455
516
  def avatar_field
456
517
  get_field_definitions.find do |field|
457
518
  field.as_avatar.present?
@@ -476,34 +537,34 @@ module Avo
476
537
  nil
477
538
  end
478
539
 
479
- def description_field
480
- get_field_definitions.find do |field|
481
- field.as_description.present?
482
- end
483
- rescue
484
- nil
540
+ def form_scope
541
+ model_class.base_class.to_s.underscore.downcase
485
542
  end
486
543
 
487
- def description
488
- description_field&.value
544
+ def has_record_id?
545
+ record.present? && record_id.present?
489
546
  end
490
547
 
491
- def form_scope
492
- model_class.base_class.to_s.underscore.downcase
548
+ def id_attribute
549
+ :id
493
550
  end
494
551
 
495
- def ordering_host(**args)
496
- Avo::Hosts::Ordering.new resource: self, options: self.class.ordering, **args
552
+ def record_id
553
+ record.send(id_attribute)
497
554
  end
498
555
 
499
- def has_model_id?
500
- model.present? && model.id.present?
556
+ def description_attributes
557
+ {
558
+ view: view,
559
+ resource: self,
560
+ record: record
561
+ }
501
562
  end
502
563
 
503
- def find_record(id, query: nil, params: nil)
504
- query ||= self.class.find_scope
564
+ private
505
565
 
506
- self.class.find_record_method.call(model_class: query, id: id, params: params)
566
+ def entity_loader(entity)
567
+ instance_variable_get("@#{entity.to_s.pluralize}_loader")
507
568
  end
508
569
  end
509
570
  end