avo 2.46.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 (409) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +28 -26
  3. data/Gemfile.lock +231 -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 +12 -29
  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 +3 -2
  73. data/app/components/avo/index/resource_table_component.rb +8 -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 +1 -1
  84. data/app/components/avo/paginator_component.rb +6 -6
  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 -86
  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 +29 -31
  105. data/app/controllers/avo/application_controller.rb +119 -180
  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 +139 -91
  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/controllers/action_controller.js +5 -3
  118. data/app/javascript/js/controllers/actions_overflow_controller.js +62 -0
  119. data/app/javascript/js/controllers/fields/reload_belongs_to_field_controller.js +7 -7
  120. data/app/javascript/js/controllers/filter_controller.js +1 -1
  121. data/app/javascript/js/controllers/input_autofocus_controller.js +12 -0
  122. data/app/javascript/js/controllers/preview_controller.js +24 -0
  123. data/app/javascript/js/controllers/search_controller.js +4 -2
  124. data/app/javascript/js/controllers/self_destroy_controller.js +7 -0
  125. data/app/javascript/js/controllers/toggle_controller.js +48 -0
  126. data/app/javascript/js/controllers.js +11 -5
  127. data/app/javascript/js/custom-stream-actions.js +15 -0
  128. data/app/views/avo/actions/show.html.erb +10 -6
  129. data/app/views/avo/associations/new.html.erb +2 -2
  130. data/app/views/avo/base/_new_via_belongs_to.html.erb +1 -1
  131. data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +3 -3
  132. data/app/views/avo/base/create_fail_action.turbo_stream.erb +2 -2
  133. data/app/views/avo/base/edit.html.erb +1 -1
  134. data/app/views/avo/base/index.html.erb +4 -3
  135. data/app/views/avo/base/new.html.erb +2 -1
  136. data/app/views/avo/base/preview.html.erb +19 -0
  137. data/app/views/avo/base/show.html.erb +2 -2
  138. data/app/views/avo/debug/_valid_indicator.html.erb +9 -0
  139. data/app/views/avo/debug/report.html.erb +32 -17
  140. data/app/views/avo/debug/{index.html.erb → status.html.erb} +31 -14
  141. data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
  142. data/app/views/avo/partials/_footer.html.erb +1 -1
  143. data/app/views/avo/partials/_javascript.html.erb +5 -0
  144. data/app/views/avo/partials/_logo.html.erb +1 -1
  145. data/app/views/avo/partials/_navbar.html.erb +3 -5
  146. data/app/views/avo/partials/_resource_search.html.erb +1 -0
  147. data/app/views/avo/partials/_table_header.html.erb +5 -11
  148. data/app/views/layouts/avo/application.html.erb +5 -4
  149. data/avo.gemspec +10 -8
  150. data/bin/dev +3 -1
  151. data/bin/prod +0 -0
  152. data/config/master.key +1 -0
  153. data/config/routes.rb +7 -10
  154. data/db/factories.rb +6 -0
  155. data/lib/avo/asset_manager.rb +30 -0
  156. data/lib/avo/base_action.rb +82 -67
  157. data/lib/avo/base_resource.rb +286 -226
  158. data/lib/avo/base_resource_tool.rb +9 -16
  159. data/lib/avo/concerns/borrow_items_holder.rb +35 -0
  160. data/lib/avo/concerns/breadcrumbs.rb +2 -2
  161. data/lib/avo/concerns/{can_replace_fields.rb → can_replace_items.rb} +5 -9
  162. data/lib/avo/concerns/filters_session_handler.rb +7 -5
  163. data/lib/avo/concerns/has_controls.rb +37 -0
  164. data/lib/avo/concerns/has_description.rb +23 -0
  165. data/lib/avo/concerns/has_helpers.rb +18 -0
  166. data/lib/avo/concerns/has_item_type.rb +42 -0
  167. data/lib/avo/concerns/has_items.rb +339 -0
  168. data/lib/avo/concerns/{has_resource_stimulus_controllers.rb → has_stimulus_controllers.rb} +1 -1
  169. data/lib/avo/concerns/hydration.rb +17 -0
  170. data/lib/avo/concerns/is_resource_item.rb +16 -36
  171. data/lib/avo/concerns/is_visible.rb +15 -0
  172. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  173. data/lib/avo/concerns/visible_in_different_views.rb +132 -0
  174. data/lib/avo/concerns/visible_items.rb +7 -38
  175. data/lib/avo/configuration/branding.rb +0 -12
  176. data/lib/avo/configuration.rb +28 -11
  177. data/lib/avo/current.rb +39 -0
  178. data/lib/avo/dsl/field_parser.rb +3 -3
  179. data/lib/avo/dynamic_router.rb +18 -3
  180. data/lib/avo/engine.rb +35 -30
  181. data/lib/avo/error_manager.rb +25 -0
  182. data/lib/avo/execution_context.rb +14 -15
  183. data/lib/avo/fields/base_field.rb +84 -122
  184. data/lib/avo/fields/belongs_to_field.rb +19 -23
  185. data/lib/avo/fields/concerns/file_authorization.rb +2 -2
  186. data/lib/avo/fields/concerns/handles_field_args.rb +49 -0
  187. data/lib/avo/fields/concerns/has_default.rb +1 -5
  188. data/lib/avo/fields/concerns/has_field_name.rb +22 -0
  189. data/lib/avo/fields/concerns/has_html_attributes.rb +112 -0
  190. data/lib/avo/fields/concerns/is_disabled.rb +1 -5
  191. data/lib/avo/fields/concerns/is_readonly.rb +1 -5
  192. data/lib/avo/fields/concerns/is_required.rb +5 -7
  193. data/lib/avo/fields/concerns/is_searchable.rb +15 -0
  194. data/lib/avo/fields/concerns/use_resource.rb +5 -1
  195. data/lib/avo/fields/concerns/use_view_components.rb +45 -0
  196. data/lib/avo/fields/country_field.rb +4 -0
  197. data/lib/avo/fields/date_time_field.rb +1 -5
  198. data/lib/avo/fields/external_image_field.rb +2 -2
  199. data/lib/avo/fields/field_manager.rb +55 -0
  200. data/lib/avo/fields/file_field.rb +2 -2
  201. data/lib/avo/fields/gravatar_field.rb +2 -2
  202. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -2
  203. data/lib/avo/fields/has_base_field.rb +21 -17
  204. data/lib/avo/fields/has_many_field.rb +5 -2
  205. data/lib/avo/fields/has_one_field.rb +8 -12
  206. data/lib/avo/fields/heading_field.rb +9 -14
  207. data/lib/avo/fields/hidden_field.rb +1 -1
  208. data/lib/avo/fields/id_field.rb +3 -3
  209. data/lib/avo/fields/location_field.rb +10 -10
  210. data/lib/avo/fields/password_field.rb +1 -1
  211. data/lib/avo/fields/preview_field.rb +14 -0
  212. data/lib/avo/fields/select_field.rb +12 -8
  213. data/lib/avo/fields/status_field.rb +7 -1
  214. data/lib/avo/fields/text_field.rb +2 -2
  215. data/lib/avo/filters/base_filter.rb +9 -4
  216. data/lib/avo/html/builder.rb +8 -8
  217. data/lib/avo/item_grapher.rb +78 -0
  218. data/lib/avo/licensing/h_q.rb +11 -73
  219. data/lib/avo/licensing/license.rb +5 -1
  220. data/lib/avo/licensing/license_manager.rb +1 -1
  221. data/lib/avo/licensing/pro_license.rb +1 -7
  222. data/lib/avo/loaders/fields_loader.rb +7 -1
  223. data/lib/avo/plugin.rb +36 -0
  224. data/lib/avo/plugin_manager.rb +56 -0
  225. data/lib/avo/prefixed_test_helpers.rb +20 -0
  226. data/lib/avo/reloader.rb +3 -0
  227. data/lib/avo/resources/controls/actions_list.rb +7 -12
  228. data/lib/avo/resources/controls/attach_button.rb +15 -0
  229. data/lib/avo/resources/controls/back_button.rb +1 -1
  230. data/lib/avo/resources/controls/base_control.rb +15 -49
  231. data/lib/avo/resources/controls/create_button.rb +15 -0
  232. data/lib/avo/resources/controls/delete_button.rb +5 -1
  233. data/lib/avo/resources/controls/detach_button.rb +4 -1
  234. data/lib/avo/resources/controls/edit_button.rb +4 -1
  235. data/lib/avo/resources/controls/order_controls.rb +8 -0
  236. data/lib/avo/resources/controls/save_button.rb +13 -0
  237. data/lib/avo/resources/controls/show_button.rb +15 -0
  238. data/lib/avo/resources/items/holder.rb +96 -0
  239. data/lib/avo/resources/items/item_group.rb +44 -0
  240. data/lib/avo/resources/items/main_panel.rb +12 -0
  241. data/lib/avo/resources/items/panel.rb +2 -0
  242. data/lib/avo/resources/items/row.rb +42 -0
  243. data/lib/avo/resources/items/sidebar.rb +46 -0
  244. data/lib/avo/resources/items/tab.rb +54 -0
  245. data/lib/avo/resources/items/tab_group.rb +62 -0
  246. data/lib/avo/resources/resource_manager.rb +179 -0
  247. data/lib/avo/services/authorization_service.rb +11 -110
  248. data/lib/avo/services/debug_service.rb +93 -0
  249. data/lib/avo/services/encryption_service.rb +8 -12
  250. data/lib/avo/services/telemetry_service.rb +85 -0
  251. data/lib/avo/test_helpers.rb +362 -0
  252. data/lib/avo/tools/tool_manager.rb +30 -0
  253. data/lib/avo/version.rb +1 -1
  254. data/lib/avo/view_inquirer.rb +36 -0
  255. data/lib/avo.rb +109 -24
  256. data/lib/generators/avo/action_generator.rb +8 -8
  257. data/lib/generators/avo/card_generator.rb +27 -0
  258. data/lib/generators/avo/concerns/parent_controller.rb +20 -0
  259. data/lib/generators/avo/controller_generator.rb +3 -0
  260. data/lib/generators/avo/eject_generator.rb +180 -15
  261. data/lib/generators/avo/field_generator.rb +49 -2
  262. data/lib/generators/avo/filter_generator.rb +8 -8
  263. data/lib/generators/avo/js/install_generator.rb +2 -2
  264. data/lib/generators/avo/resource_generator.rb +12 -9
  265. data/lib/generators/avo/scope_generator.rb +15 -0
  266. data/lib/generators/avo/tailwindcss/install_generator.rb +70 -26
  267. data/lib/generators/avo/templates/action.tt +8 -6
  268. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  269. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  270. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  271. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  272. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  273. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  274. data/lib/generators/avo/templates/dashboards/dashboard.tt +5 -3
  275. data/lib/generators/avo/templates/field/%singular_name%_field.rb.tt +1 -1
  276. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  277. data/lib/generators/avo/templates/filters/multiple_select_filter.tt +1 -1
  278. data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
  279. data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
  280. data/lib/generators/avo/templates/initializer/avo.tt +7 -3
  281. data/lib/generators/avo/templates/locales/avo.ar.yml +1 -0
  282. data/lib/generators/avo/templates/locales/avo.en.yml +4 -3
  283. data/lib/generators/avo/templates/locales/avo.es.yml +1 -0
  284. data/lib/generators/avo/templates/locales/avo.fr.yml +1 -0
  285. data/lib/generators/avo/templates/locales/avo.nb.yml +1 -0
  286. data/lib/generators/avo/templates/locales/avo.nn.yml +1 -0
  287. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -0
  288. data/lib/generators/avo/templates/locales/avo.pt.yml +1 -0
  289. data/lib/generators/avo/templates/locales/avo.ro.yml +6 -5
  290. data/lib/generators/avo/templates/locales/avo.tr.yml +1 -0
  291. data/lib/generators/avo/templates/resource/controller.tt +1 -1
  292. data/lib/generators/avo/templates/resource/resource.tt +7 -7
  293. data/lib/generators/avo/templates/resource_tools/partial.tt +2 -2
  294. data/lib/generators/avo/templates/resource_tools/resource_tool.tt +1 -1
  295. data/lib/generators/avo/templates/scope.tt +6 -0
  296. data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
  297. data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +5 -3
  298. data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +11 -0
  299. data/lib/tasks/avo_tasks.rake +72 -4
  300. data/public/avo-assets/avo.base.css +1893 -1187
  301. data/public/avo-assets/avo.base.js +217 -305
  302. data/public/avo-assets/avo.base.js.map +3 -3
  303. data/public/avo-assets/avo.css +9744 -0
  304. data/public/avo-assets/avo.js +513 -0
  305. data/public/avo-assets/avo.js.map +7 -0
  306. data/tailwind.custom.js +47 -0
  307. data/tailwind.preset.js +152 -0
  308. metadata +106 -116
  309. data/app/components/avo/card_component.html.erb +0 -46
  310. data/app/components/avo/card_component.rb +0 -25
  311. data/app/components/avo/dashboards/divider_component.html.erb +0 -9
  312. data/app/components/avo/dashboards/divider_component.rb +0 -19
  313. data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +0 -47
  314. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +0 -95
  315. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -35
  316. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  317. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -10
  318. data/app/components/avo/fields/tags_field/index_component.rb +0 -9
  319. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  320. data/app/components/avo/fields/tags_field/show_component.rb +0 -5
  321. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  322. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  323. data/app/components/avo/index/ordering/base_component.rb +0 -9
  324. data/app/components/avo/index/ordering/button_component.html.erb +0 -11
  325. data/app/components/avo/index/ordering/button_component.rb +0 -23
  326. data/app/components/avo/index/ordering/buttons_component.html.erb +0 -32
  327. data/app/components/avo/index/ordering/buttons_component.rb +0 -47
  328. data/app/components/avo/item_switcher_component.html.erb +0 -27
  329. data/app/components/avo/item_switcher_component.rb +0 -48
  330. data/app/components/avo/sidebar/item_switcher_component.html.erb +0 -16
  331. data/app/components/avo/sidebar/item_switcher_component.rb +0 -15
  332. data/app/controllers/avo/dashboards/cards_controller.rb +0 -37
  333. data/app/controllers/avo/dashboards_controller.rb +0 -22
  334. data/app/controllers/avo/reorder_controller.rb +0 -25
  335. data/app/javascript/js/controllers/base_controller.js +0 -22
  336. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -127
  337. data/app/javascript/js/controllers/toggle_panel_controller.js +0 -18
  338. data/app/views/avo/dashboards/cards/_chartkick_card.html.erb +0 -3
  339. data/app/views/avo/dashboards/cards/_metric_card.html.erb +0 -5
  340. data/app/views/avo/dashboards/cards/chartkick_missing.html.erb +0 -14
  341. data/app/views/avo/dashboards/cards/show.html.erb +0 -3
  342. data/app/views/avo/dashboards/show.html.erb +0 -38
  343. data/app/views/avo/partials/_global_search.html.erb +0 -19
  344. data/app/views/avo/sidebar/_license_warnings.html.erb +0 -6
  345. data/lib/avo/app.rb +0 -237
  346. data/lib/avo/base_card.rb +0 -161
  347. data/lib/avo/concerns/fetches_things.rb +0 -150
  348. data/lib/avo/concerns/handles_field_args.rb +0 -47
  349. data/lib/avo/concerns/has_action_stimulus_controllers.rb +0 -15
  350. data/lib/avo/concerns/has_editable_controls.rb +0 -34
  351. data/lib/avo/concerns/has_fields.rb +0 -334
  352. data/lib/avo/concerns/has_html_attributes.rb +0 -123
  353. data/lib/avo/concerns/policy_helpers.rb +0 -31
  354. data/lib/avo/concerns/visible_in_dashboard.rb +0 -31
  355. data/lib/avo/dashboards/base_dashboard.rb +0 -89
  356. data/lib/avo/dashboards/base_divider.rb +0 -35
  357. data/lib/avo/dashboards/chartkick_card.rb +0 -77
  358. data/lib/avo/dashboards/dashboard_card.rb +0 -6
  359. data/lib/avo/dashboards/metric_card.rb +0 -9
  360. data/lib/avo/dashboards/partial_card.rb +0 -7
  361. data/lib/avo/fields/field_extensions/has_field_name.rb +0 -19
  362. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +0 -111
  363. data/lib/avo/fields/tags_field.rb +0 -102
  364. data/lib/avo/grid_collector.rb +0 -42
  365. data/lib/avo/hosts/association_scope_host.rb +0 -8
  366. data/lib/avo/hosts/base_host.rb +0 -25
  367. data/lib/avo/hosts/card_visibility.rb +0 -20
  368. data/lib/avo/hosts/dashboard_card.rb +0 -22
  369. data/lib/avo/hosts/dashboard_visibility.rb +0 -19
  370. data/lib/avo/hosts/ordering.rb +0 -22
  371. data/lib/avo/hosts/record_host.rb +0 -7
  372. data/lib/avo/hosts/resource_record_host.rb +0 -7
  373. data/lib/avo/hosts/resource_view_record_host.rb +0 -7
  374. data/lib/avo/hosts/search_scope_host.rb +0 -7
  375. data/lib/avo/hosts/view_record_host.rb +0 -7
  376. data/lib/avo/hosts/visibility_host.rb +0 -12
  377. data/lib/avo/items_holder.rb +0 -96
  378. data/lib/avo/main_panel.rb +0 -3
  379. data/lib/avo/menu/base_item.rb +0 -25
  380. data/lib/avo/menu/builder.rb +0 -82
  381. data/lib/avo/menu/dashboard.rb +0 -22
  382. data/lib/avo/menu/group.rb +0 -2
  383. data/lib/avo/menu/link.rb +0 -6
  384. data/lib/avo/menu/menu.rb +0 -2
  385. data/lib/avo/menu/resource.rb +0 -22
  386. data/lib/avo/menu/section.rb +0 -2
  387. data/lib/avo/panel.rb +0 -24
  388. data/lib/avo/panel_builder.rb +0 -25
  389. data/lib/avo/resources/controls/action.rb +0 -38
  390. data/lib/avo/resources/controls/execution_context.rb +0 -58
  391. data/lib/avo/resources/controls/items_holder.rb +0 -19
  392. data/lib/avo/resources/controls/link_to.rb +0 -27
  393. data/lib/avo/row.rb +0 -26
  394. data/lib/avo/row_builder.rb +0 -24
  395. data/lib/avo/services/authorization_clients/nil_client.rb +0 -37
  396. data/lib/avo/services/authorization_clients/pundit_client.rb +0 -51
  397. data/lib/avo/sidebar.rb +0 -30
  398. data/lib/avo/sidebar_builder.rb +0 -24
  399. data/lib/avo/tab.rb +0 -72
  400. data/lib/avo/tab_builder.rb +0 -25
  401. data/lib/avo/tab_group.rb +0 -42
  402. data/lib/avo/tab_group_builder.rb +0 -43
  403. data/lib/avo/tools_manager.rb +0 -11
  404. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  405. data/lib/generators/avo/card/metric_generator.rb +0 -18
  406. data/lib/generators/avo/card/partial_generator.rb +0 -19
  407. data/lib/generators/avo/templates/js/avo.custom.js +0 -2
  408. data/lib/generators/avo/templates/standalone_action.tt +0 -8
  409. /data/app/assets/stylesheets/css/{tags.css → fields/tags.css} +0 -0
@@ -4,21 +4,13 @@ module Avo
4
4
  class SearchController < ApplicationController
5
5
  include Rails.application.routes.url_helpers
6
6
 
7
- before_action :set_resource_name, only: [:show]
8
- before_action :set_resource, only: [:show]
9
-
10
- def index
11
- raise ActionController::BadRequest.new("This feature requires the pro license https://avohq.io/purchase/pro") if App.license.lacks_with_trial(:global_search)
12
-
13
- resources = Avo::App.resources.reject do |resource|
14
- resource.class.hide_from_global_search
15
- end
16
-
17
- render json: search_resources(resources)
18
- end
7
+ before_action :set_resource_name, only: :show
8
+ before_action :set_resource, only: :show
19
9
 
20
10
  def show
21
11
  render json: search_resources([resource])
12
+ rescue => error
13
+ render_search_error(error)
22
14
  end
23
15
 
24
16
  private
@@ -28,7 +20,6 @@ module Avo
28
20
  .map do |resource|
29
21
  # Apply authorization
30
22
  next unless @authorization.set_record(resource.model_class).authorize_action(:search, raise_exception: false)
31
-
32
23
  # Filter out the models without a search_query
33
24
  next if resource.search_query.nil?
34
25
 
@@ -45,10 +36,10 @@ module Avo
45
36
  end
46
37
 
47
38
  def search_resource(resource)
48
- query = Avo::Hosts::SearchScopeHost.new(
49
- block: resource.search_query,
39
+ query = Avo::ExecutionContext.new(
40
+ target: resource.search_query,
50
41
  params: params,
51
- scope: resource.class.scope
42
+ query: resource.query_scope
52
43
  ).handle
53
44
 
54
45
  query = apply_scope(query) if should_apply_any_scope?
@@ -69,9 +60,9 @@ module Avo
69
60
 
70
61
  result_object = {
71
62
  header: header,
72
- help: resource.class.search_query_help,
63
+ help: resource.fetch_search(:help) || "",
73
64
  results: results,
74
- count: results_count
65
+ count: results.count
75
66
  }
76
67
 
77
68
  [resource.name.pluralize.downcase, result_object]
@@ -96,9 +87,9 @@ module Avo
96
87
  # to scope the query.
97
88
  # Example usage: Got to a project, create a new review, and search for a user.
98
89
  if parent.blank? && params[:via_parent_resource_id].present? && params[:via_parent_resource_class].present? && params[:via_relation].present?
99
- parent_resource_class = BaseResource.valid_model_class params[:via_parent_resource_class]
90
+ parent_resource_class = BaseResource.get_model_by_name params[:via_parent_resource_class]
100
91
 
101
- reflection_class = BaseResource.valid_model_class params[:via_reflection_class]
92
+ reflection_class = BaseResource.get_model_by_name params[:via_reflection_class]
102
93
 
103
94
  grandparent = parent_resource_class.find params[:via_parent_resource_id]
104
95
  parent = reflection_class.new(
@@ -106,7 +97,7 @@ module Avo
106
97
  )
107
98
  end
108
99
 
109
- Avo::Hosts::AssociationScopeHost.new(block: attach_scope, query: query, parent: parent).handle
100
+ Avo::ExecutionContext.new(target: attach_scope, query: query, parent: parent).handle
110
101
  end
111
102
 
112
103
  # This scope is applied if the search is being performed on a has_many association
@@ -114,44 +105,34 @@ module Avo
114
105
  association_name = BaseResource.valid_association_name(parent, params[:via_association_id])
115
106
 
116
107
  # Get association records
117
- scope = parent.send(association_name)
108
+ query = parent.send(association_name)
118
109
 
119
110
  # Apply policy scope if authorization is present
120
- scope = resource.authorization&.apply_policy scope
111
+ query = resource.authorization&.apply_policy query
121
112
 
122
- Avo::Hosts::SearchScopeHost.new(block: @resource.search_query, params: params, scope: scope).handle
113
+ Avo::ExecutionContext.new(target: @resource.class.search_query, params: params, query: query).handle
123
114
  end
124
115
 
125
- def apply_search_metadata(models, avo_resource)
126
- models.map do |model|
127
- resource = avo_resource.dup.hydrate(model: model).hydrate_fields(model: model)
128
-
129
- record_path = if resource.search_result_path.present?
130
- Avo::Hosts::ResourceRecordHost.new(block: resource.search_result_path, resource: resource, record: model).handle
131
- else
132
- resource.record_path
133
- end
134
-
135
- result = {
136
- _id: model.id,
137
- _label: resource.label,
138
- _url: record_path
139
- }
140
-
141
- if App.license.has_with_trial(:enhanced_search_results)
142
- result[:_description] = resource.description
143
- result[:_avatar] = resource.avatar.present? ? main_app.url_for(resource.avatar) : nil
144
- result[:_avatar_type] = resource.avatar_type
145
- end
116
+ def apply_search_metadata(records, avo_resource)
117
+ records.map do |record|
118
+ resource = avo_resource.new(record: record)
146
119
 
147
- result
120
+ fetch_result_information record, resource, resource.class.fetch_search(:item, record: record)
148
121
  end
149
122
  end
150
123
 
151
124
  private
152
125
 
126
+ def fetch_result_information(record, resource, item)
127
+ {
128
+ _id: record.id,
129
+ _label: item&.dig(:title) || resource.record_title,
130
+ _url: resource.class.fetch_search(:result_path, record: resource.record) || resource.record_path
131
+ }
132
+ end
133
+
153
134
  def should_apply_has_many_scope?
154
- params[:via_association] == "has_many" && @resource.search_query.present?
135
+ params[:via_association] == "has_many" && @resource.class.search_query.present?
155
136
  end
156
137
 
157
138
  def should_apply_attach_scope?
@@ -175,15 +156,40 @@ module Avo
175
156
  end
176
157
 
177
158
  def fetch_field
178
- fields = ::Avo::App.get_resource_by_model_name(params[:via_reflection_class]).get_field_definitions
179
- fields.find { |f| f.id.to_s == params[:via_association_id] }
159
+ return if params[:via_association_id].nil?
160
+
161
+ reflection_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_reflection_class]).new(
162
+ view: Avo::ViewInquirer.new(params[:via_reflection_view]),
163
+ record: parent,
164
+ params: params,
165
+ user: current_user
166
+ )
167
+
168
+ reflection_resource.detect_fields.get_field_definitions.find do |field|
169
+ field.id.to_s == params[:via_association_id]
170
+ end
180
171
  end
181
172
 
182
173
  def fetch_parent
183
174
  return unless params[:via_reflection_id].present?
184
175
 
185
- parent_resource = ::Avo::App.get_resource_by_model_name params[:via_reflection_class]
176
+ parent_resource = Avo.resource_manager.get_resource_by_model_class params[:via_reflection_class]
186
177
  parent_resource.find_record params[:via_reflection_id], params: params
187
178
  end
179
+
180
+ def render_search_error(error)
181
+ raise error unless Rails.env.development?
182
+
183
+ render json: {
184
+ error: {
185
+ header: "🚨 An error occurred while searching. 🚨",
186
+ help: "Please see the error and fix it before deploying.",
187
+ results: {
188
+ _label: error.message
189
+ },
190
+ count: 1
191
+ }
192
+ }, status: 500
193
+ end
188
194
  end
189
195
  end
@@ -0,0 +1,22 @@
1
+ module Avo
2
+ module InitializesAvo
3
+ def init_app
4
+ Avo::Current.license = Avo::Licensing::NilLicense.new
5
+ Avo::Current.context = context
6
+ Avo::Current.user = _current_user
7
+ Avo::Current.view_context = view_context
8
+ Avo.init
9
+ Avo::Current.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
10
+ Avo::Current.locale = locale
11
+ Avo.plugin_manager.init_plugins
12
+ end
13
+
14
+ def _current_user
15
+ instance_eval(&Avo.configuration.current_user)
16
+ end
17
+
18
+ def context
19
+ instance_eval(&Avo.configuration.context)
20
+ end
21
+ end
22
+ end
@@ -1,12 +1,7 @@
1
1
  module Avo
2
2
  module ApplicationHelper
3
3
  include ::Pagy::Frontend
4
-
5
- def render_license_warnings
6
- render partial: "avo/sidebar/license_warnings", locals: {
7
- license: Avo::App.license.properties
8
- }
9
- end
4
+ include Avo::ResourcesHelper
10
5
 
11
6
  def render_license_warning(title: "", message: "", icon: "exclamation")
12
7
  render partial: "avo/sidebar/license_warning", locals: {
@@ -119,8 +114,23 @@ module Avo
119
114
  Avo::Filters::BaseFilter.encode_filters(filter_params)
120
115
  end
121
116
 
117
+ def number_to_social(number, start_at: 10_000)
118
+ return number_with_delimiter(number) if number < start_at
119
+
120
+ number_to_human(number,
121
+ precision: 1,
122
+ significant: false,
123
+ round_mode: :down,
124
+ format: "%n%u",
125
+ units: {
126
+ thousand: "K",
127
+ million: "M",
128
+ billion: "B"
129
+ })
130
+ end
131
+
122
132
  def frame_id(resource)
123
- ["frame", resource.model_name.singular, resource.model.id].compact.join("-")
133
+ ["frame", resource.model_name.singular, resource.record.id].compact.join("-")
124
134
  end
125
135
 
126
136
  private
@@ -144,7 +154,7 @@ module Avo
144
154
  field = field_klass.new id, form: form, view: view, **args, &block
145
155
 
146
156
  # Add the form record to the field so all fields have access to it.
147
- field.hydrate(model: form.object) if form.present?
157
+ field.hydrate(record: form.object) if form.present?
148
158
 
149
159
  render field.component_for_view(view).new field: field, form: form, **component_options
150
160
  end
@@ -38,7 +38,7 @@ module Avo
38
38
  end
39
39
 
40
40
  def item_selector_init(resource)
41
- "data-resource-name='#{resource.model_key}' data-resource-id='#{resource.model.id}' data-controller='item-selector'"
41
+ "data-resource-name='#{resource.model_key}' data-resource-id='#{resource.record.to_param}' data-controller='item-selector'"
42
42
  end
43
43
 
44
44
  def item_selector_input(floating: false, size: :md)
@@ -20,14 +20,14 @@ module Avo
20
20
  end
21
21
 
22
22
  def resource_path(
23
- model:,
23
+ record:,
24
24
  resource:,
25
25
  resource_id: nil,
26
26
  keep_query_params: false,
27
27
  **args
28
28
  )
29
- if model.respond_to? :id
30
- id = model
29
+ if record.respond_to? :id
30
+ id = record
31
31
  elsif resource_id.present?
32
32
  id = resource_id
33
33
  end
@@ -35,29 +35,45 @@ module Avo
35
35
  avo.send :"resources_#{resource.singular_route_key}_path", id, **args
36
36
  end
37
37
 
38
+ def preview_resource_path(
39
+ record:,
40
+ resource:,
41
+ resource_id: nil,
42
+ keep_query_params: false,
43
+ **args
44
+ )
45
+ if record.respond_to? resource.id_attribute
46
+ id = record
47
+ elsif resource_id.present?
48
+ id = resource_id
49
+ end
50
+
51
+ avo.send :"preview_resources_#{resource.singular_route_key}_path", id, **args
52
+ end
53
+
38
54
  def new_resource_path(resource:, **args)
39
55
  avo.send :"new_resources_#{resource.singular_route_key}_path", **args
40
56
  end
41
57
 
42
- def edit_resource_path(model:, resource:, **args)
43
- avo.send :"edit_resources_#{resource.singular_route_key}_path", model, **args
58
+ def edit_resource_path(record:, resource:, **args)
59
+ avo.send :"edit_resources_#{resource.singular_route_key}_path", record, **args
44
60
  end
45
61
 
46
- def resource_attach_path(resource, model_id, related_name, related_id = nil)
47
- helpers.avo.resources_associations_new_path(resource.singular_route_key, model_id, related_name)
62
+ def resource_attach_path(resource, record_id, related_name, related_id = nil)
63
+ helpers.avo.resources_associations_new_path(resource.singular_route_key, record_id, related_name)
48
64
  end
49
65
 
50
66
  def resource_detach_path(
51
67
  model_name, # teams
52
- model_id, # 1
68
+ record_id, # 1
53
69
  related_name, # admin
54
70
  related_id = nil
55
71
  )
56
- avo.resources_associations_destroy_path(model_name, model_id, related_name, related_id)
72
+ avo.resources_associations_destroy_path(model_name, record_id, related_name, related_id)
57
73
  end
58
74
 
59
75
  def related_resources_path(
60
- parent_model,
76
+ parent_record,
61
77
  record,
62
78
  keep_query_params: false,
63
79
  **args
@@ -74,11 +90,11 @@ module Avo
74
90
  rescue
75
91
  end
76
92
 
77
- avo.resources_associations_index_path(parent_model.model_name.route_key, record.id, **existing_params, **args)
93
+ avo.resources_associations_index_path(parent_record.model_name.route_key, record.id, **existing_params, **args)
78
94
  end
79
95
 
80
96
  def resource_view_path(**args)
81
- if Avo.configuration.resource_default_view == :edit
97
+ if Avo.configuration.resource_default_view.edit?
82
98
  edit_resource_path(**args)
83
99
  else
84
100
  resource_path(**args)
@@ -12,6 +12,7 @@ import 'chartkick/chart.js/chart.esm'
12
12
 
13
13
  import './js/active-storage'
14
14
  import './js/controllers'
15
+ import './js/custom-stream-actions'
15
16
 
16
17
  Rails.start()
17
18
 
@@ -2,10 +2,12 @@ import { Controller } from '@hotwired/stimulus'
2
2
  import { castBoolean } from '../helpers/cast_boolean'
3
3
 
4
4
  export default class extends Controller {
5
- static targets = ['controllerDiv', 'resourceIds', 'submit', 'selectedAllQuery']
5
+ static targets = ['controllerDiv', 'resourceIds', 'form', 'selectedAllQuery']
6
6
 
7
7
  connect() {
8
- this.resourceIdsTarget.value = this.resourceIds
8
+ if (this.resourceIdsTarget.value === '') {
9
+ this.resourceIdsTarget.value = this.resourceIds
10
+ }
9
11
 
10
12
  // This value is picked up from the DOM so we check true/false as strings
11
13
  if (this.selectionOptions.itemSelectAllSelectedAllValue === 'true') {
@@ -13,7 +15,7 @@ export default class extends Controller {
13
15
  }
14
16
 
15
17
  if (this.noConfirmation) {
16
- this.submitTarget.click()
18
+ this.formTarget.submit()
17
19
  } else {
18
20
  this.controllerDivTarget.classList.remove('hidden')
19
21
  }
@@ -0,0 +1,62 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ static targets = ['content']
5
+
6
+ static values = {
7
+ panelList: Boolean,
8
+ }
9
+
10
+ // get the table or grid component, if both null, get the panel body (for show page for example)
11
+ get parentTarget() {
12
+ return document.querySelector('[data-component-name="avo/index/resource_table_component"]')
13
+ || document.querySelector('[data-component-name="avo/index/resource_grid_component"]')
14
+ || document.querySelector('[data-target="panel-body"]')
15
+ }
16
+
17
+ childDimensions = null
18
+
19
+ parentDimensions = null
20
+
21
+ connect() {
22
+ // We need to make the element visible in order to get it's position
23
+ this.element.style.display = 'block'
24
+ this.childDimensions = this.contentTarget.getBoundingClientRect()
25
+ this.element.style.display = ''
26
+ this.parentDimensions = this.parentTarget.getBoundingClientRect()
27
+
28
+ this.adjustOverflow()
29
+ }
30
+
31
+ adjustOverflow() {
32
+ this.adjustVerticalOverflow()
33
+ this.adjustHorizontalOverflow()
34
+ }
35
+
36
+ adjustVerticalOverflow() {
37
+ if (this.contentBottomOverflow) {
38
+ this.contentTarget.classList.remove('top-full', 'mt-2')
39
+ this.contentTarget.classList.add('bottom-full', 'mb-2')
40
+ }
41
+ }
42
+
43
+ adjustHorizontalOverflow() {
44
+ if (this.contentLeftOverflow) {
45
+ this.contentTarget.classList.remove('xl:right-0', 'sm:right-0')
46
+ this.contentTarget.classList.add('xl:left-0', 'sm:left-0')
47
+ }
48
+ }
49
+
50
+ get contentBottomOverflow() {
51
+ // If the list is on panel header, we don't want to adjust the vertical overflow
52
+ if (this.panelListValue === true) {
53
+ return false
54
+ }
55
+
56
+ return this.parentDimensions.bottom < this.childDimensions.bottom
57
+ }
58
+
59
+ get contentLeftOverflow() {
60
+ return this.parentDimensions.left > this.childDimensions.left
61
+ }
62
+ }
@@ -6,27 +6,27 @@ export default class extends Controller {
6
6
  polymorphic: Boolean,
7
7
  searchable: Boolean,
8
8
  targetName: String,
9
- relationName: String
9
+ relationName: String,
10
10
  }
11
11
 
12
12
  beforeStreamRender(event) {
13
13
  const { relationName } = event.target.dataset
14
- if (event.target.action !== "update-belongs-to" || this.relationNameValue !== relationName) {
15
- return false;
14
+ if (event.target.action !== 'update-belongs-to' || this.relationNameValue !== relationName) {
15
+ return false
16
16
  }
17
17
 
18
18
  event.detail.render = (stream) => {
19
19
  if (this.searchableValue) {
20
20
  this.updateSearchable(stream)
21
- } else{
21
+ } else {
22
22
  this.updateNonSearchable(stream)
23
23
  }
24
- };
24
+ }
25
25
  }
26
26
 
27
27
  updateSearchable(stream) {
28
28
  // Update the id component
29
- document.querySelector(`input[name="${this.targetNameValue}"][type="hidden"]`).value = stream.dataset.targetResourceId
29
+ document.querySelector(`input[name="${this.targetNameValue}"][type="hidden"]`).value = stream.dataset.targetRecordId
30
30
  // Update the label
31
31
  document.querySelector(`input[name="${this.targetNameValue}"][type="text"]`).value = stream.dataset.targetResourceLabel
32
32
  }
@@ -34,7 +34,7 @@ export default class extends Controller {
34
34
  updateNonSearchable(stream) {
35
35
  const select = this.selectorContext(stream).querySelector(`select[name="${this.targetNameValue}"]`)
36
36
  const option = document.createElement('option')
37
- option.value = stream.dataset.targetResourceId
37
+ option.value = stream.dataset.targetRecordId
38
38
  option.text = stream.dataset.targetResourceLabel
39
39
  option.selected = true
40
40
  select.appendChild(option)
@@ -98,7 +98,7 @@ export default class extends Controller {
98
98
 
99
99
  url.query(query)
100
100
 
101
- this.urlRedirectTarget.href = url
101
+ this.urlRedirectTarget.href = url.readable().toString()
102
102
  this.urlRedirectTarget.click()
103
103
  }
104
104
  }
@@ -0,0 +1,12 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ static targets = ['element'];
5
+
6
+ focus({ params }) {
7
+ const element = this.context.element.querySelector(params.selector)
8
+ if (this.element) {
9
+ element.focus()
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,24 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import tippy from 'tippy.js'
3
+
4
+ export default class extends Controller {
5
+ static values = {
6
+ url: String,
7
+ }
8
+
9
+ connect() {
10
+ const vm = this;
11
+
12
+ tippy(vm.context.element, {
13
+ content: "loading...",
14
+ allowHTML: true,
15
+ theme: 'light',
16
+ maxWidth: 550,
17
+ async onShow(instance) {
18
+ const response = await fetch(vm.urlValue)
19
+ const content = await response.text()
20
+ instance.setContent(content)
21
+ },
22
+ })
23
+ }
24
+ }
@@ -212,8 +212,8 @@ export default class extends Controller {
212
212
  const url = URI()
213
213
 
214
214
  return url.segment([window.Avo.configuration.root_path, ...this.searchSegments()])
215
- .search(this.searchParams(encodeURIComponent(query)))
216
- .readable().toString()
215
+ .search(this.searchParams(encodeURIComponent(query)))
216
+ .readable().toString()
217
217
  }
218
218
 
219
219
  searchSegments() {
@@ -279,6 +279,8 @@ export default class extends Controller {
279
279
  via_reflection_class: this.dataset.viaReflectionClass,
280
280
  // eslint-disable-next-line camelcase
281
281
  via_reflection_id: this.dataset.viaReflectionId,
282
+ // eslint-disable-next-line camelcase
283
+ via_reflection_view: this.dataset.viaReflectionView,
282
284
  }
283
285
 
284
286
  return params
@@ -0,0 +1,7 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ destroy() {
5
+ this.context.element.remove()
6
+ }
7
+ }
@@ -0,0 +1,48 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { leave, toggle } from 'el-transition'
3
+ import { useClickOutside } from 'stimulus-use'
4
+
5
+ export default class extends Controller {
6
+ static targets = ['panel']
7
+
8
+ static values = {
9
+ // One may want to have an element that is exempt from triggerring the click outside event
10
+ exemptionContainer: String,
11
+ }
12
+
13
+ get exemptionContainerTarget() {
14
+ return document.querySelector(this.exemptionContainerValue)
15
+ }
16
+
17
+ connect() {
18
+ useClickOutside(this)
19
+ }
20
+
21
+ clickOutside(e) {
22
+ if (this.hasPanelTarget) {
23
+ if (this.hasExemptionContainerValue) {
24
+ const inExemptionContainer = this.exemptionContainerTarget.contains(e.target)
25
+
26
+ if (!inExemptionContainer) {
27
+ leave(this.panelTarget)
28
+ }
29
+ } else {
30
+ leave(this.panelTarget)
31
+ }
32
+ }
33
+ }
34
+
35
+ togglePanel() {
36
+ if (this.hasPanelTarget) {
37
+ toggle(this.panelTarget)
38
+ }
39
+ }
40
+
41
+ outlet({ params }) {
42
+ const { outlet } = params
43
+
44
+ if (outlet && document.querySelector(outlet)) {
45
+ document.querySelector(outlet).classList.toggle('hidden')
46
+ }
47
+ }
48
+ }