avo 2.45.0 → 3.0.0.beta1

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 (371) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +26 -25
  3. data/Gemfile.lock +179 -147
  4. data/README.md +1 -1
  5. data/app/assets/stylesheets/avo.base.css +0 -1
  6. data/app/assets/svgs/font.svg +1 -0
  7. data/app/assets/svgs/triangle-up.svg +1 -0
  8. data/app/components/avo/actions_component.html.erb +19 -5
  9. data/app/components/avo/actions_component.rb +37 -17
  10. data/app/components/avo/asset_manager/javascript_component.html.erb +3 -0
  11. data/app/components/avo/asset_manager/javascript_component.rb +13 -0
  12. data/app/components/avo/asset_manager/stylesheet_component.html.erb +3 -0
  13. data/app/components/avo/asset_manager/stylesheet_component.rb +13 -0
  14. data/app/components/avo/base_component.rb +15 -12
  15. data/app/components/avo/button_component.rb +20 -3
  16. data/app/components/avo/empty_state_component.rb +1 -1
  17. data/app/components/avo/field_wrapper_component.html.erb +1 -1
  18. data/app/components/avo/field_wrapper_component.rb +8 -8
  19. data/app/components/avo/fields/area_field/edit_component.html.erb +2 -2
  20. data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +96 -118
  21. data/app/components/avo/fields/belongs_to_field/edit_component.rb +6 -17
  22. data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
  23. data/app/components/avo/fields/belongs_to_field/show_component.rb +2 -2
  24. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
  25. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +3 -3
  26. data/app/components/avo/fields/common/badge_viewer_component.html.erb +24 -1
  27. data/app/components/avo/fields/common/badge_viewer_component.rb +0 -24
  28. data/app/components/avo/fields/common/boolean_group_component.html.erb +2 -2
  29. data/app/components/avo/fields/common/files/list_viewer_component.rb +3 -3
  30. data/app/components/avo/fields/common/files/view_type/{grid_item_component.html.erb → grid_component.html.erb} +2 -2
  31. data/app/components/avo/fields/common/files/view_type/{grid_item_component.rb → grid_component.rb} +4 -5
  32. data/app/components/avo/fields/common/files/view_type/{list_item_component.rb → list_component.rb} +1 -1
  33. data/app/components/avo/fields/edit_component.rb +1 -1
  34. data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
  35. data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
  36. data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
  37. data/app/components/avo/fields/has_one_field/show_component.html.erb +3 -2
  38. data/app/components/avo/fields/has_one_field/show_component.rb +2 -2
  39. data/app/components/avo/fields/index_component.rb +5 -5
  40. data/app/components/avo/fields/preview_field/index_component.html.erb +10 -0
  41. data/app/components/avo/fields/preview_field/index_component.rb +4 -0
  42. data/app/components/avo/fields/select_field/edit_component.html.erb +1 -1
  43. data/app/components/avo/fields/show_component.rb +4 -1
  44. data/app/components/avo/fields/trix_field/edit_component.rb +1 -1
  45. data/app/components/avo/filters_component.html.erb +9 -3
  46. data/app/components/avo/filters_component.rb +4 -4
  47. data/app/components/avo/index/field_wrapper_component.rb +0 -12
  48. data/app/components/avo/index/grid_item_component.html.erb +13 -36
  49. data/app/components/avo/index/grid_item_component.rb +43 -16
  50. data/app/components/avo/index/resource_controls_component.html.erb +3 -81
  51. data/app/components/avo/index/resource_controls_component.rb +124 -17
  52. data/app/components/avo/index/resource_grid_component.html.erb +5 -3
  53. data/app/components/avo/index/resource_grid_component.rb +5 -2
  54. data/app/components/avo/index/resource_map_component.html.erb +1 -1
  55. data/app/components/avo/index/resource_map_component.rb +3 -3
  56. data/app/components/avo/index/resource_table_component.html.erb +5 -4
  57. data/app/components/avo/index/resource_table_component.rb +14 -20
  58. data/app/components/avo/index/table_row_component.html.erb +8 -4
  59. data/app/components/avo/index/table_row_component.rb +3 -2
  60. data/app/components/avo/item_switcher_component.rb +2 -2
  61. data/app/components/avo/modal_component.html.erb +7 -12
  62. data/app/components/avo/modal_component.rb +0 -21
  63. data/app/components/avo/paginator_component.html.erb +40 -29
  64. data/app/components/avo/paginator_component.rb +5 -23
  65. data/app/components/avo/panel_component.html.erb +8 -6
  66. data/app/components/avo/referrer_params_component.html.erb +1 -2
  67. data/app/components/avo/resource_component.rb +189 -14
  68. data/app/components/avo/resource_sidebar_component.html.erb +6 -2
  69. data/app/components/avo/resource_sidebar_component.rb +1 -1
  70. data/app/components/avo/sidebar/link_component.rb +1 -1
  71. data/app/components/avo/sidebar_component.html.erb +10 -3
  72. data/app/components/avo/sidebar_component.rb +5 -3
  73. data/app/components/avo/sidebar_profile_component.html.erb +15 -8
  74. data/app/components/avo/tab_group_component.html.erb +13 -7
  75. data/app/components/avo/tab_group_component.rb +1 -6
  76. data/app/components/avo/tab_switcher_component.html.erb +17 -40
  77. data/app/components/avo/tab_switcher_component.rb +4 -39
  78. data/app/components/avo/views/resource_edit_component.html.erb +12 -48
  79. data/app/components/avo/views/resource_edit_component.rb +7 -18
  80. data/app/components/avo/views/resource_index_component.html.erb +41 -47
  81. data/app/components/avo/views/resource_index_component.rb +62 -12
  82. data/app/components/avo/views/resource_show_component.html.erb +6 -149
  83. data/app/components/avo/views/resource_show_component.rb +6 -11
  84. data/app/controllers/avo/actions_controller.rb +27 -24
  85. data/app/controllers/avo/application_controller.rb +105 -151
  86. data/app/controllers/avo/associations_controller.rb +34 -43
  87. data/app/controllers/avo/attachments_controller.rb +4 -4
  88. data/app/controllers/avo/base_controller.rb +102 -102
  89. data/app/controllers/avo/debug_controller.rb +17 -5
  90. data/app/controllers/avo/home_controller.rb +1 -1
  91. data/app/controllers/avo/search_controller.rb +30 -51
  92. data/app/controllers/avo/team_users_controller.rb +4 -0
  93. data/app/controllers/concerns/avo/initializes_avo.rb +21 -0
  94. data/app/helpers/avo/application_helper.rb +15 -9
  95. data/app/helpers/avo/resources_helper.rb +1 -1
  96. data/app/helpers/avo/url_helpers.rb +27 -11
  97. data/app/javascript/avo.base.js +1 -0
  98. data/app/javascript/js/application.js +0 -3
  99. data/app/javascript/js/controllers/action_controller.js +5 -3
  100. data/app/javascript/js/controllers/actions_overflow_controller.js +62 -0
  101. data/app/javascript/js/controllers/filter_controller.js +1 -1
  102. data/app/javascript/js/controllers/input_autofocus_controller.js +12 -0
  103. data/app/javascript/js/controllers/preview_controller.js +24 -0
  104. data/app/javascript/js/controllers/search_controller.js +2 -2
  105. data/app/javascript/js/controllers/self_destroy_controller.js +7 -0
  106. data/app/javascript/js/controllers/toggle_controller.js +48 -0
  107. data/app/javascript/js/controllers.js +10 -6
  108. data/app/javascript/js/custom-stream-actions.js +15 -0
  109. data/app/views/avo/actions/keep_modal_open.turbo_stream.erb +5 -0
  110. data/app/views/avo/actions/show.html.erb +9 -6
  111. data/app/views/avo/associations/new.html.erb +2 -2
  112. data/app/views/avo/base/index.html.erb +3 -2
  113. data/app/views/avo/base/new.html.erb +2 -1
  114. data/app/views/avo/base/preview.html.erb +19 -0
  115. data/app/views/avo/base/show.html.erb +1 -1
  116. data/app/views/avo/debug/_valid_indicator.html.erb +9 -0
  117. data/app/views/avo/debug/report.html.erb +32 -17
  118. data/app/views/avo/debug/{index.html.erb → status.html.erb} +31 -14
  119. data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
  120. data/app/views/avo/partials/_footer.html.erb +1 -1
  121. data/app/views/avo/partials/_javascript.html.erb +5 -0
  122. data/app/views/avo/partials/_logo.html.erb +1 -1
  123. data/app/views/avo/partials/_navbar.html.erb +3 -5
  124. data/app/views/avo/partials/_table_header.html.erb +5 -11
  125. data/app/views/layouts/avo/application.html.erb +4 -2
  126. data/avo.gemspec +7 -7
  127. data/bin/dev +1 -1
  128. data/bin/prod +0 -0
  129. data/config/i18n-tasks.yml +1 -1
  130. data/config/initializers/pagy.rb +0 -2
  131. data/config/master.key +1 -0
  132. data/config/routes.rb +6 -10
  133. data/db/factories.rb +7 -1
  134. data/lib/avo/action_model.rb +20 -0
  135. data/lib/avo/asset_manager.rb +30 -0
  136. data/lib/avo/base_action.rb +57 -41
  137. data/lib/avo/base_resource.rb +263 -226
  138. data/lib/avo/base_resource_tool.rb +9 -16
  139. data/lib/avo/concerns/breadcrumbs.rb +2 -2
  140. data/lib/avo/concerns/{can_replace_fields.rb → can_replace_items.rb} +5 -9
  141. data/lib/avo/concerns/filters_session_handler.rb +5 -3
  142. data/lib/avo/concerns/has_controls.rb +37 -0
  143. data/lib/avo/concerns/has_description.rb +23 -0
  144. data/lib/avo/concerns/has_item_type.rb +42 -0
  145. data/lib/avo/concerns/has_items.rb +325 -0
  146. data/lib/avo/concerns/is_resource_item.rb +24 -36
  147. data/lib/avo/concerns/is_visible.rb +15 -0
  148. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  149. data/lib/avo/concerns/visible_in_different_views.rb +126 -0
  150. data/lib/avo/configuration/branding.rb +0 -12
  151. data/lib/avo/configuration.rb +1 -37
  152. data/lib/avo/current.rb +39 -0
  153. data/lib/avo/dsl/field_parser.rb +1 -1
  154. data/lib/avo/dynamic_router.rb +18 -3
  155. data/lib/avo/engine.rb +35 -30
  156. data/lib/avo/error_manager.rb +25 -0
  157. data/lib/avo/execution_context.rb +10 -14
  158. data/lib/avo/fields/badge_field.rb +1 -1
  159. data/lib/avo/fields/base_field.rb +91 -105
  160. data/lib/avo/fields/belongs_to_field.rb +18 -22
  161. data/lib/avo/fields/concerns/file_authorization.rb +2 -2
  162. data/lib/avo/fields/concerns/handles_field_args.rb +49 -0
  163. data/lib/avo/fields/concerns/has_default.rb +1 -5
  164. data/lib/avo/fields/concerns/has_field_name.rb +22 -0
  165. data/lib/avo/fields/concerns/has_html_attributes.rb +110 -0
  166. data/lib/avo/fields/concerns/is_disabled.rb +1 -5
  167. data/lib/avo/fields/concerns/is_readonly.rb +1 -5
  168. data/lib/avo/fields/concerns/is_required.rb +5 -7
  169. data/lib/avo/fields/concerns/is_searchable.rb +13 -0
  170. data/lib/avo/fields/concerns/use_resource.rb +5 -1
  171. data/lib/avo/fields/country_field.rb +4 -0
  172. data/lib/avo/fields/date_time_field.rb +1 -5
  173. data/lib/avo/fields/field_manager.rb +55 -0
  174. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -2
  175. data/lib/avo/fields/has_base_field.rb +12 -15
  176. data/lib/avo/fields/has_many_field.rb +5 -2
  177. data/lib/avo/fields/has_one_field.rb +6 -10
  178. data/lib/avo/fields/heading_field.rb +4 -1
  179. data/lib/avo/fields/hidden_field.rb +1 -1
  180. data/lib/avo/fields/id_field.rb +1 -1
  181. data/lib/avo/fields/location_field.rb +8 -8
  182. data/lib/avo/fields/password_field.rb +1 -1
  183. data/lib/avo/fields/preview_field.rb +14 -0
  184. data/lib/avo/fields/select_field.rb +12 -8
  185. data/lib/avo/fields/status_field.rb +4 -0
  186. data/lib/avo/filters/base_filter.rb +8 -4
  187. data/lib/avo/html/builder.rb +7 -8
  188. data/lib/avo/item_grapher.rb +78 -0
  189. data/lib/avo/licensing/h_q.rb +7 -66
  190. data/lib/avo/licensing/license.rb +1 -1
  191. data/lib/avo/licensing/pro_license.rb +1 -7
  192. data/lib/avo/loaders/fields_loader.rb +7 -1
  193. data/lib/avo/plugin.rb +16 -0
  194. data/lib/avo/plugin_manager.rb +56 -0
  195. data/lib/avo/prefixed_test_helpers.rb +20 -0
  196. data/lib/avo/reloader.rb +3 -0
  197. data/lib/avo/resources/controls/actions_list.rb +7 -12
  198. data/lib/avo/resources/controls/attach_button.rb +15 -0
  199. data/lib/avo/resources/controls/back_button.rb +1 -1
  200. data/lib/avo/resources/controls/base_control.rb +15 -49
  201. data/lib/avo/resources/controls/create_button.rb +15 -0
  202. data/lib/avo/resources/controls/delete_button.rb +5 -1
  203. data/lib/avo/resources/controls/detach_button.rb +4 -1
  204. data/lib/avo/resources/controls/edit_button.rb +4 -1
  205. data/lib/avo/resources/controls/order_controls.rb +8 -0
  206. data/lib/avo/resources/controls/save_button.rb +13 -0
  207. data/lib/avo/resources/controls/show_button.rb +15 -0
  208. data/lib/avo/resources/items/holder.rb +84 -0
  209. data/lib/avo/resources/items/item_group.rb +49 -0
  210. data/lib/avo/resources/items/main_panel.rb +2 -0
  211. data/lib/avo/resources/items/panel.rb +2 -0
  212. data/lib/avo/resources/items/row.rb +54 -0
  213. data/lib/avo/resources/items/sidebar.rb +47 -0
  214. data/lib/avo/resources/items/tab.rb +60 -0
  215. data/lib/avo/resources/items/tab_group.rb +68 -0
  216. data/lib/avo/resources/resource_manager.rb +174 -0
  217. data/lib/avo/services/authorization_service.rb +11 -110
  218. data/lib/avo/services/debug_service.rb +93 -0
  219. data/lib/avo/services/telemetry_service.rb +85 -0
  220. data/lib/avo/test_helpers.rb +362 -0
  221. data/lib/avo/tools/tool_manager.rb +30 -0
  222. data/lib/avo/version.rb +1 -1
  223. data/lib/avo.rb +115 -24
  224. data/lib/generators/avo/action_generator.rb +8 -8
  225. data/lib/generators/avo/card_generator.rb +27 -0
  226. data/lib/generators/avo/filter_generator.rb +8 -8
  227. data/lib/generators/avo/resource_generator.rb +4 -4
  228. data/lib/generators/avo/scope_generator.rb +15 -0
  229. data/lib/generators/avo/tailwindcss/install_generator.rb +1 -15
  230. data/lib/generators/avo/templates/action.tt +8 -6
  231. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  232. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  233. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  234. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  235. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  236. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  237. data/lib/generators/avo/templates/dashboards/dashboard.tt +5 -3
  238. data/lib/generators/avo/templates/field/%singular_name%_field.rb.tt +1 -1
  239. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  240. data/lib/generators/avo/templates/filters/multiple_select_filter.tt +1 -1
  241. data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
  242. data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
  243. data/lib/generators/avo/templates/initializer/avo.tt +1 -9
  244. data/lib/generators/avo/templates/locales/avo.ar.yml +5 -5
  245. data/lib/generators/avo/templates/locales/avo.en.yml +4 -5
  246. data/lib/generators/avo/templates/locales/avo.fr.yml +1 -2
  247. data/lib/generators/avo/templates/locales/avo.nb.yml +1 -2
  248. data/lib/generators/avo/templates/locales/avo.nn.yml +1 -2
  249. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -2
  250. data/lib/generators/avo/templates/locales/avo.pt.yml +1 -2
  251. data/lib/generators/avo/templates/locales/avo.ro.yml +6 -7
  252. data/lib/generators/avo/templates/locales/avo.tr.yml +1 -2
  253. data/lib/generators/avo/templates/resource/resource.tt +7 -7
  254. data/lib/generators/avo/templates/resource_tools/partial.tt +4 -4
  255. data/lib/generators/avo/templates/resource_tools/resource_tool.tt +1 -1
  256. data/lib/generators/avo/templates/scope.tt +6 -0
  257. data/lib/generators/avo/templates/tool/view.tt +2 -2
  258. data/lib/tasks/avo_tasks.rake +27 -0
  259. data/public/avo-assets/avo.base.css +1810 -1189
  260. data/public/avo-assets/avo.base.js +217 -305
  261. data/public/avo-assets/avo.base.js.map +3 -3
  262. data/public/avo-assets/avo.css +9744 -0
  263. data/public/avo-assets/avo.js +513 -0
  264. data/public/avo-assets/avo.js.map +7 -0
  265. metadata +96 -137
  266. data/app/assets/stylesheets/css/tags.css +0 -32
  267. data/app/components/avo/card_component.html.erb +0 -46
  268. data/app/components/avo/card_component.rb +0 -25
  269. data/app/components/avo/dashboards/divider_component.html.erb +0 -9
  270. data/app/components/avo/dashboards/divider_component.rb +0 -19
  271. data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +0 -47
  272. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +0 -95
  273. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -35
  274. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  275. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -10
  276. data/app/components/avo/fields/tags_field/index_component.rb +0 -9
  277. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  278. data/app/components/avo/fields/tags_field/show_component.rb +0 -5
  279. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  280. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  281. data/app/components/avo/index/ordering/base_component.rb +0 -9
  282. data/app/components/avo/index/ordering/button_component.html.erb +0 -11
  283. data/app/components/avo/index/ordering/button_component.rb +0 -23
  284. data/app/components/avo/index/ordering/buttons_component.html.erb +0 -32
  285. data/app/components/avo/index/ordering/buttons_component.rb +0 -47
  286. data/app/components/avo/sidebar/item_switcher_component.html.erb +0 -16
  287. data/app/components/avo/sidebar/item_switcher_component.rb +0 -15
  288. data/app/controllers/avo/dashboards/cards_controller.rb +0 -37
  289. data/app/controllers/avo/dashboards_controller.rb +0 -22
  290. data/app/controllers/avo/reorder_controller.rb +0 -25
  291. data/app/javascript/js/controllers/base_controller.js +0 -22
  292. data/app/javascript/js/controllers/fields/reload_belongs_to_field_controller.js +0 -51
  293. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -127
  294. data/app/javascript/js/controllers/toggle_panel_controller.js +0 -18
  295. data/app/views/avo/base/_new_via_belongs_to.html.erb +0 -12
  296. data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +0 -8
  297. data/app/views/avo/base/create_fail_action.turbo_stream.erb +0 -13
  298. data/app/views/avo/dashboards/cards/_chartkick_card.html.erb +0 -3
  299. data/app/views/avo/dashboards/cards/_metric_card.html.erb +0 -5
  300. data/app/views/avo/dashboards/cards/chartkick_missing.html.erb +0 -14
  301. data/app/views/avo/dashboards/cards/show.html.erb +0 -3
  302. data/app/views/avo/dashboards/show.html.erb +0 -38
  303. data/app/views/avo/partials/_flash_alerts.turbo_stream.erb +0 -3
  304. data/app/views/avo/partials/_global_search.html.erb +0 -19
  305. data/app/views/avo/sidebar/_license_warnings.html.erb +0 -6
  306. data/lib/avo/app.rb +0 -237
  307. data/lib/avo/base_card.rb +0 -161
  308. data/lib/avo/concerns/fetches_things.rb +0 -150
  309. data/lib/avo/concerns/handles_field_args.rb +0 -47
  310. data/lib/avo/concerns/has_editable_controls.rb +0 -34
  311. data/lib/avo/concerns/has_fields.rb +0 -334
  312. data/lib/avo/concerns/has_html_attributes.rb +0 -108
  313. data/lib/avo/concerns/pagination.rb +0 -53
  314. data/lib/avo/concerns/policy_helpers.rb +0 -31
  315. data/lib/avo/concerns/visible_in_dashboard.rb +0 -31
  316. data/lib/avo/concerns/visible_items.rb +0 -51
  317. data/lib/avo/dashboards/base_dashboard.rb +0 -89
  318. data/lib/avo/dashboards/base_divider.rb +0 -35
  319. data/lib/avo/dashboards/chartkick_card.rb +0 -77
  320. data/lib/avo/dashboards/dashboard_card.rb +0 -6
  321. data/lib/avo/dashboards/metric_card.rb +0 -9
  322. data/lib/avo/dashboards/partial_card.rb +0 -7
  323. data/lib/avo/fields/field_extensions/has_field_name.rb +0 -19
  324. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +0 -111
  325. data/lib/avo/fields/tags_field.rb +0 -102
  326. data/lib/avo/grid_collector.rb +0 -42
  327. data/lib/avo/hosts/association_scope_host.rb +0 -8
  328. data/lib/avo/hosts/base_host.rb +0 -25
  329. data/lib/avo/hosts/card_visibility.rb +0 -20
  330. data/lib/avo/hosts/dashboard_card.rb +0 -22
  331. data/lib/avo/hosts/dashboard_visibility.rb +0 -19
  332. data/lib/avo/hosts/ordering.rb +0 -22
  333. data/lib/avo/hosts/record_host.rb +0 -7
  334. data/lib/avo/hosts/resource_record_host.rb +0 -7
  335. data/lib/avo/hosts/resource_view_record_host.rb +0 -7
  336. data/lib/avo/hosts/search_scope_host.rb +0 -7
  337. data/lib/avo/hosts/view_record_host.rb +0 -7
  338. data/lib/avo/hosts/visibility_host.rb +0 -12
  339. data/lib/avo/items_holder.rb +0 -96
  340. data/lib/avo/main_panel.rb +0 -3
  341. data/lib/avo/menu/base_item.rb +0 -25
  342. data/lib/avo/menu/builder.rb +0 -82
  343. data/lib/avo/menu/dashboard.rb +0 -22
  344. data/lib/avo/menu/group.rb +0 -2
  345. data/lib/avo/menu/link.rb +0 -6
  346. data/lib/avo/menu/menu.rb +0 -2
  347. data/lib/avo/menu/resource.rb +0 -22
  348. data/lib/avo/menu/section.rb +0 -2
  349. data/lib/avo/panel.rb +0 -24
  350. data/lib/avo/panel_builder.rb +0 -25
  351. data/lib/avo/resources/controls/action.rb +0 -38
  352. data/lib/avo/resources/controls/execution_context.rb +0 -58
  353. data/lib/avo/resources/controls/items_holder.rb +0 -19
  354. data/lib/avo/resources/controls/link_to.rb +0 -27
  355. data/lib/avo/row.rb +0 -26
  356. data/lib/avo/row_builder.rb +0 -24
  357. data/lib/avo/services/authorization_clients/nil_client.rb +0 -37
  358. data/lib/avo/services/authorization_clients/pundit_client.rb +0 -51
  359. data/lib/avo/sidebar.rb +0 -30
  360. data/lib/avo/sidebar_builder.rb +0 -24
  361. data/lib/avo/tab.rb +0 -72
  362. data/lib/avo/tab_builder.rb +0 -25
  363. data/lib/avo/tab_group.rb +0 -42
  364. data/lib/avo/tab_group_builder.rb +0 -43
  365. data/lib/avo/tools_manager.rb +0 -11
  366. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  367. data/lib/generators/avo/card/metric_generator.rb +0 -18
  368. data/lib/generators/avo/card/partial_generator.rb +0 -19
  369. data/lib/generators/avo/templates/locales/avo.es.yml +0 -126
  370. data/lib/generators/avo/templates/standalone_action.tt +0 -8
  371. /data/app/components/avo/fields/common/files/view_type/{list_item_component.html.erb → list_component.html.erb} +0 -0
@@ -1,15 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
4
- include Avo::ResourcesHelper
5
4
  include Avo::ApplicationHelper
6
5
 
7
- def initialize(resource: nil, reflection: nil, parent_resource: nil, parent_model: nil, resource_panel: nil, actions: [])
6
+ def initialize(resource: nil, reflection: nil, parent_resource: nil, parent_record: nil, resource_panel: nil, actions: [])
8
7
  @resource = resource
9
8
  @reflection = reflection
10
9
  @resource_panel = resource_panel
11
10
  @actions = actions
12
- @parent_model = parent_model
11
+ @parent_record = parent_record
13
12
  @parent_resource = parent_resource
14
13
  @view = :show
15
14
  end
@@ -26,7 +25,7 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
26
25
 
27
26
  def back_path
28
27
  if via_resource?
29
- helpers.resource_path(model: association_resource.model_class, resource: association_resource, resource_id: params[:via_resource_id])
28
+ helpers.resource_path(record: association_resource.model_class, resource: association_resource, resource_id: params[:via_record_id])
30
29
  else
31
30
  helpers.resources_path(resource: @resource)
32
31
  end
@@ -38,20 +37,16 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
38
37
  if via_resource?
39
38
  args = {
40
39
  via_resource_class: params[:via_resource_class],
41
- via_resource_id: params[:via_resource_id]
40
+ via_record_id: params[:via_record_id]
42
41
  }
43
42
  end
44
43
 
45
- helpers.edit_resource_path(model: @resource.model, resource: @resource, **args)
46
- end
47
-
48
- def render_action_control?(action)
49
- can_act_on? && action.visible_in_view(parent_resource: @parent_resource)
44
+ helpers.edit_resource_path(record: @resource.record, resource: @resource, **args)
50
45
  end
51
46
 
52
47
  private
53
48
 
54
- # In development and test environments we shoudl show the invalid field errors
49
+ # In development and test environments we should show the invalid field errors
55
50
  def should_display_invalid_fields_errors?
56
51
  (Rails.env.development? || Rails.env.test?) && @resource.invalid_fields.present?
57
52
  end
@@ -4,9 +4,9 @@ module Avo
4
4
  class ActionsController < ApplicationController
5
5
  before_action :set_resource_name
6
6
  before_action :set_resource
7
- before_action :set_model, only: :show, if: ->(request) do
8
- # Try to se the model only if the user is on the record page.
9
- # set_model will fail if it's tried to be used from the Index page.
7
+ before_action :set_record, only: :show, if: ->(request) do
8
+ # Try to se the record only if the user is on the record page.
9
+ # set_record will fail if it's tried to be used from the Index page.
10
10
  request.params[:id].present?
11
11
  end
12
12
  before_action :set_action, only: [:show, :handle]
@@ -15,7 +15,8 @@ module Avo
15
15
  # Se the view to :new so the default value gets prefilled
16
16
  @view = :new
17
17
 
18
- @resource.hydrate(model: @model, view: @view, user: _current_user, params: params)
18
+ @resource.hydrate(record: @record, view: @view, user: _current_user, params: params)
19
+ @record = ActionModel.new @action.get_attributes_for_action
19
20
  end
20
21
 
21
22
  def handle
@@ -30,12 +31,10 @@ module Avo
30
31
  resource: resource
31
32
  }
32
33
 
33
- unless @action.standalone
34
- args[:models] = if @selected_query.present?
35
- @resource.model_class.find_by_sql decrypted_query
36
- else
37
- @resource.find_record resource_ids, params: params
38
- end
34
+ args[:records] = if @selected_query.present?
35
+ @resource.model_class.find_by_sql decrypted_query
36
+ else
37
+ @resource.find_record resource_ids, params: params
39
38
  end
40
39
 
41
40
  performed_action = @action.handle_action(**args)
@@ -51,19 +50,17 @@ module Avo
51
50
 
52
51
  def set_action
53
52
  @action = action_class.new(
54
- model: @model,
53
+ record: @record,
55
54
  resource: @resource,
56
55
  user: _current_user,
57
56
  view: :new, # force the action view to in order to render new-related fields (hidden field)
58
- arguments: @resource.get_action_arguments(action_class)
57
+ arguments: decrypted_arguments || {}
59
58
  )
60
59
  end
61
60
 
62
61
  def action_class
63
- klass_name = params[:action_id].gsub("avo_actions_", "").camelize
64
-
65
62
  Avo::BaseAction.descendants.find do |action|
66
- action.to_s == klass_name
63
+ action.to_s == params[:action_id]
67
64
  end
68
65
  end
69
66
 
@@ -78,18 +75,14 @@ module Avo
78
75
  end
79
76
 
80
77
  respond_to do |format|
81
- format.turbo_stream do
78
+ format.html do
82
79
  # Flash the messages collected from the action
83
80
  flash_messages messages
84
81
 
85
82
  if response[:type] == :redirect
86
- render turbo_stream: turbo_stream.redirect_to(
87
- Avo::ExecutionContext.new(target: response[:path]).handle,
88
- nil,
89
- response[:redirect_args][:turbo_frame],
90
- **response[:redirect_args].except(:turbo_frame)
91
- )
92
- else
83
+ redirect_to Avo::ExecutionContext.new(target: response[:path]).handle,
84
+ **{allow_other_host: response[:allow_other_host], status: response[:status]}.compact
85
+ elsif response[:type] == :reload
93
86
  redirect_back fallback_location: resources_path(resource: @resource)
94
87
  end
95
88
  end
@@ -119,6 +112,16 @@ module Avo
119
112
  )
120
113
  end
121
114
 
115
+ def decrypted_arguments
116
+ arguments = params[:arguments] || params.dig(:fields, :arguments)
117
+ return if arguments.blank?
118
+
119
+ Avo::Services::EncryptionService.decrypt(
120
+ message: Base64.decode64(arguments),
121
+ purpose: :action_arguments
122
+ )
123
+ end
124
+
122
125
  def flash_messages(messages)
123
126
  messages.each do |message|
124
127
  flash[message[:type]] = message[:body]
@@ -130,7 +133,7 @@ module Avo
130
133
 
131
134
  respond_to do |format|
132
135
  format.turbo_stream do
133
- render partial: "avo/partials/flash_alerts"
136
+ render "keep_modal_open"
134
137
  end
135
138
  end
136
139
  end
@@ -6,16 +6,18 @@ module Avo
6
6
  Avo::ApplicationController.include Pundit
7
7
  end
8
8
 
9
+ include Avo::InitializesAvo
9
10
  include Avo::ApplicationHelper
10
11
  include Avo::UrlHelpers
11
12
  include Avo::Concerns::Breadcrumbs
13
+ include Pagy::Backend
12
14
 
13
15
  protect_from_forgery with: :exception
14
16
  around_action :set_avo_locale
15
17
  around_action :set_force_locale, if: -> { params[:force_locale].present? }
16
18
  before_action :set_default_locale, if: -> { params[:set_locale].present? }
17
19
  before_action :init_app
18
- before_action :check_avo_license
20
+ before_action :set_active_storage_current_host
19
21
  before_action :set_resource_name
20
22
  before_action :_authenticate!
21
23
  before_action :set_authorization
@@ -27,15 +29,9 @@ module Avo
27
29
  rescue_from Avo::NotAuthorizedError, with: :render_unauthorized
28
30
  rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
29
31
 
30
- helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path
32
+ helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path, :preview_resource_path
31
33
  add_flash_types :info, :warning, :success, :error
32
34
 
33
- def init_app
34
- Avo::App.init request: request, context: context, current_user: _current_user, view_context: view_context, params: params
35
-
36
- @license = Avo::App.license
37
- end
38
-
39
35
  def exception_logger(exception)
40
36
  respond_to do |format|
41
37
  format.html { raise exception }
@@ -49,49 +45,6 @@ module Avo
49
45
  end
50
46
  end
51
47
 
52
- def render(*args)
53
- raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:check_avo_license).source_location.first.match?(/.*\/app\/controllers\/avo\/application_controller\.rb/)
54
-
55
- if params[:controller] == "avo/search" && params[:action] == "index"
56
- raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:index).source_location.first.match?(/.*\/app\/controllers\/avo\/search_controller\.rb/)
57
- end
58
-
59
- if params[:controller] == "avo/dashboards" && params[:action] == "show"
60
- raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:show).source_location.first.match?(/.*\/app\/controllers\/avo\/dashboards_controller\.rb/)
61
- end
62
-
63
- if params[:controller] == "avo/dashboards" && params[:action] == "card"
64
- raise Avo::LicenseVerificationTemperedError, "License verification mechanism tempered with." unless method(:card).source_location.first.match?(/.*\/app\/controllers\/avo\/dashboards_controller\.rb/)
65
- end
66
-
67
- super(*args)
68
- end
69
-
70
- def check_avo_license
71
- # Check to see if the path is a custom tool
72
- if on_custom_tool_page
73
- if @license.lacks(:custom_tools) || @license.invalid?
74
- message = "Your license is invalid or doesn't support custom tools."
75
- end
76
- end
77
-
78
- # Check to see if the path is a dashboard
79
- if on_dashboards_path
80
- if @license.lacks(:dashboards) || @license.invalid?
81
- message = "Your license is invalid or doesn't support dashboards."
82
- end
83
- end
84
-
85
- if message.present?
86
- if Rails.env.development? || Rails.env.test?
87
- @custom_tools_alert_visible = message
88
- elsif @license.lacks_with_trial(:custom_tools)
89
- # Raise error in non-development environments.
90
- raise Avo::LicenseInvalidError, message
91
- end
92
- end
93
- end
94
-
95
48
  def _current_user
96
49
  instance_eval(&Avo.configuration.current_user)
97
50
  end
@@ -108,6 +61,49 @@ module Avo
108
61
 
109
62
  private
110
63
 
64
+ # Get the pluralized resource name for this request
65
+ # Ex: projects, teams, users
66
+ def resource_name
67
+ return params[:resource_name] if params[:resource_name].present?
68
+
69
+ return controller_name if controller_name.present?
70
+
71
+ begin
72
+ request.path
73
+ .match(/\/?#{Avo.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
74
+ .captures
75
+ .first
76
+ rescue
77
+ end
78
+ end
79
+
80
+ def related_resource_name
81
+ params[:related_name]
82
+ end
83
+
84
+ # Gets the Avo resource for this request based on the request from the `resource_name` "param"
85
+ # Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
86
+ def resource
87
+ resource = Avo.resource_manager.get_resource @resource_name.to_s.camelize.singularize
88
+
89
+ return resource if resource.present?
90
+
91
+ Avo.resource_manager.get_resource_by_controller_name @resource_name
92
+ end
93
+
94
+ def related_resource
95
+ # Find the field from the parent resource
96
+ field = @resource.get_field params[:related_name]
97
+
98
+ return field.use_resource if field&.use_resource.present?
99
+
100
+ reflection = @record._reflections[params[:related_name]]
101
+
102
+ reflected_model = reflection.klass
103
+
104
+ Avo.resource_manager.get_resource_by_model_class reflected_model
105
+ end
106
+
111
107
  def set_resource_name
112
108
  @resource_name = resource_name
113
109
  end
@@ -119,15 +115,28 @@ module Avo
119
115
  def set_resource
120
116
  raise ActionController::RoutingError.new "No route matches" if resource.nil?
121
117
 
122
- @resource = resource.hydrate(params: params)
118
+ @resource = resource.new(view: action_name.to_sym, user: _current_user, params: params)
119
+
120
+ set_authorization
123
121
  end
124
122
 
125
123
  def set_related_resource
126
- @related_resource = related_resource.hydrate(params: params)
124
+ @related_resource = related_resource.new(params: params, view: action_name.to_sym, user: _current_user, record: @related_record)
127
125
  end
128
126
 
129
- def set_model
130
- @model = @resource.find_record(params[:id], query: model_find_scope, params: params)
127
+ def set_record
128
+ @record = @resource.find_record(params[:id], query: model_find_scope, params: params)
129
+ @resource.hydrate(record: @record)
130
+ end
131
+
132
+ def set_related_record
133
+ association_name = BaseResource.valid_association_name(@record, params[:related_name])
134
+ @related_record = if @field.is_a? Avo::Fields::HasOneField
135
+ @record.send association_name
136
+ else
137
+ @related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @record.send(association_name)), params: params
138
+ end
139
+ @related_resource.hydrate(record: @related_record)
131
140
  end
132
141
 
133
142
  def model_find_scope
@@ -135,50 +144,49 @@ module Avo
135
144
  end
136
145
 
137
146
  def model_scope
147
+ # abort @resource.inspect
138
148
  @resource.class.find_scope
139
149
  end
140
150
 
141
- def set_related_model
142
- association_name = BaseResource.valid_association_name(@model, params[:related_name])
143
- @related_model = if @field.is_a? Avo::Fields::HasOneField
144
- @model.send association_name
145
- else
146
- @related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @model.send(association_name)), params: params
147
- end
148
- end
149
-
150
151
  def set_view
151
152
  @view = action_name.to_sym
152
153
  end
153
154
 
154
- def set_model_to_fill
155
- @model_to_fill = @resource.model_class.new if @view == :create
156
- @model_to_fill = @model if @view == :update
155
+ def set_record_to_fill
156
+ @record_to_fill = @resource.model_class.new if @view == :create
157
+ @record_to_fill = @record if @view == :update
157
158
 
158
- # If resource.model is nil, most likely the user is creating a new record.
159
- # In that case, to access resource.model in visible and readonly blocks we hydrate the resource with a new model.
160
- @resource.hydrate(model: @model_to_fill) if @resource.model.nil?
159
+ # If resource.record is nil, most likely the user is creating a new record.
160
+ # In that case, to access resource.record in visible and readonly blocks we hydrate the resource with a new record.
161
+ # TODO: commented this
162
+ @resource.hydrate(record: @record_to_fill) if @resource.record.nil?
161
163
  end
162
164
 
163
- def fill_model
164
- # We have to skip filling the the model if this is an attach action
165
- is_attach_action = params[model_param_key].blank? && params[:related_name].present? && params[:fields].present?
165
+ def fill_record
166
+ # We have to skip filling the the record if this is an attach action
167
+ return if is_attach_action?
166
168
 
167
- unless is_attach_action
168
- @model = @resource.fill_model(@model_to_fill, cast_nullable(model_params), extra_params: extra_params)
169
- end
169
+ @record = @resource.fill_record(@record_to_fill, cast_nullable(model_params), extra_params: extra_params)
170
+ assign_default_value_to_disabled_fields if @view == :create
170
171
  end
171
172
 
172
- def hydrate_resource
173
- @resource.hydrate(view: action_name.to_sym, user: _current_user, model: @model)
173
+ def is_attach_action?
174
+ params[model_param_key].blank? && params[:related_name].present? && params[:fields].present?
174
175
  end
175
176
 
176
- def hydrate_related_resource
177
- @related_resource.hydrate(view: action_name.to_sym, user: _current_user, model: @related_model)
177
+ def assign_default_value_to_disabled_fields
178
+ @resource.get_field_definitions.select do |field|
179
+ field.is_disabled? && field.visible? && !field.computed
180
+ end.each do |field|
181
+ # Get the default value from the field default definition
182
+ # If there is no default value specified on the resource, get the value from the record (DB, Callbacks, etc.)
183
+ default_value = field.default || @record.send(field.id)
184
+ field.fill_field @record, field.id, default_value, params
185
+ end
178
186
  end
179
187
 
180
188
  def authorize_base_action
181
- class_to_authorize = @model || @resource.model_class
189
+ class_to_authorize = @record || @resource.model_class
182
190
 
183
191
  authorize_action class_to_authorize
184
192
  end
@@ -190,49 +198,6 @@ module Avo
190
198
  @authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
191
199
  end
192
200
 
193
- # Get the pluralized resource name for this request
194
- # Ex: projects, teams, users
195
- def resource_name
196
- return params[:resource_name] if params[:resource_name].present?
197
-
198
- return controller_name if controller_name.present?
199
-
200
- begin
201
- request.path
202
- .match(/\/?#{Avo::App.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
203
- .captures
204
- .first
205
- rescue
206
- end
207
- end
208
-
209
- def related_resource_name
210
- params[:related_name]
211
- end
212
-
213
- # Gets the Avo resource for this request based on the request from the `resource_name` "param"
214
- # Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
215
- def resource
216
- resource = App.get_resource @resource_name.to_s.camelize.singularize
217
-
218
- return resource if resource.present?
219
-
220
- App.get_resource_by_controller_name @resource_name
221
- end
222
-
223
- def related_resource
224
- # Find the field from the parent resource
225
- field = @resource.get_field params[:related_name]
226
-
227
- return field.use_resource if field&.use_resource.present?
228
-
229
- reflection = @model._reflections[params[:related_name]]
230
-
231
- reflected_model = reflection.klass
232
-
233
- App.get_resource_by_model_name reflected_model
234
- end
235
-
236
201
  def eager_load_files(resource, query)
237
202
  # Get the non-computed file fields and try to eager load them
238
203
  attachment_fields = resource
@@ -263,7 +228,7 @@ module Avo
263
228
  instance_eval(&Avo.configuration.authenticate)
264
229
  end
265
230
 
266
- def render_unauthorized(_exception)
231
+ def render_unauthorized(exception)
267
232
  flash[:notice] = t "avo.not_authorized"
268
233
 
269
234
  redirect_url = if request.referrer.blank? || (request.referrer == request.url)
@@ -278,8 +243,8 @@ module Avo
278
243
  def set_authorization
279
244
  # We need to set @resource_name for the #resource method to work properly
280
245
  set_resource_name
281
- @authorization = if resource
282
- resource.authorization(user: _current_user)
246
+ @authorization = if @resource
247
+ @resource.authorization(user: _current_user)
283
248
  else
284
249
  Services::AuthorizationService.new _current_user
285
250
  end
@@ -301,30 +266,6 @@ module Avo
301
266
  instance_eval(&Avo.configuration.initial_breadcrumbs) if Avo.configuration.initial_breadcrumbs.present?
302
267
  end
303
268
 
304
- def on_root_path
305
- [Avo.configuration.root_path, "#{Avo.configuration.root_path}/"].include?(request.original_fullpath)
306
- end
307
-
308
- def on_resources_path
309
- request.original_url.match?(/.*#{Avo.configuration.root_path}\/resources\/.*/)
310
- end
311
-
312
- def on_api_path
313
- request.original_url.match?(/.*#{Avo.configuration.root_path}\/avo_api\/.*/)
314
- end
315
-
316
- def on_dashboards_path
317
- request.original_url.match?(/.*#{Avo.configuration.root_path}\/dashboards\/.*/)
318
- end
319
-
320
- def on_debug_path
321
- request.original_url.match?(/.*#{Avo.configuration.root_path}\/avo_private\/debug.*/)
322
- end
323
-
324
- def on_custom_tool_page
325
- !(on_root_path || on_resources_path || on_api_path || on_dashboards_path || on_debug_path)
326
- end
327
-
328
269
  def model_param_key
329
270
  @resource.form_scope
330
271
  end
@@ -360,5 +301,18 @@ module Avo
360
301
  value = cookies["#{Avo::COOKIES_KEY}.sidebar.open"]
361
302
  @sidebar_open = value.blank? || value == "1"
362
303
  end
304
+
305
+ # Set the current host for ActiveStorage
306
+ def set_active_storage_current_host
307
+ if defined?(ActiveStorage::Current)
308
+ if Rails::VERSION::MAJOR === 6
309
+ ActiveStorage::Current.host = request.base_url
310
+ elsif Rails::VERSION::MAJOR === 7
311
+ ActiveStorage::Current.url_options = {protocol: request.protocol, host: request.host, port: request.port}
312
+ end
313
+ end
314
+ rescue => exception
315
+ Avo.logger.debug "Failed to set ActiveStorage::Current.url_options, #{exception.inspect}"
316
+ end
363
317
  end
364
318
  end