avo 2.45.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 (407) 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 +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 +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 +9 -5
  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 -66
  157. data/lib/avo/base_resource.rb +285 -225
  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/hydration.rb +17 -0
  169. data/lib/avo/concerns/is_resource_item.rb +16 -36
  170. data/lib/avo/concerns/is_visible.rb +15 -0
  171. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  172. data/lib/avo/concerns/visible_in_different_views.rb +132 -0
  173. data/lib/avo/concerns/visible_items.rb +7 -38
  174. data/lib/avo/configuration/branding.rb +0 -12
  175. data/lib/avo/configuration.rb +28 -11
  176. data/lib/avo/current.rb +39 -0
  177. data/lib/avo/dsl/field_parser.rb +3 -3
  178. data/lib/avo/dynamic_router.rb +18 -3
  179. data/lib/avo/engine.rb +35 -30
  180. data/lib/avo/error_manager.rb +25 -0
  181. data/lib/avo/execution_context.rb +14 -15
  182. data/lib/avo/fields/base_field.rb +84 -121
  183. data/lib/avo/fields/belongs_to_field.rb +19 -23
  184. data/lib/avo/fields/concerns/file_authorization.rb +2 -2
  185. data/lib/avo/fields/concerns/handles_field_args.rb +49 -0
  186. data/lib/avo/fields/concerns/has_default.rb +1 -5
  187. data/lib/avo/fields/concerns/has_field_name.rb +22 -0
  188. data/lib/avo/fields/concerns/has_html_attributes.rb +112 -0
  189. data/lib/avo/fields/concerns/is_disabled.rb +1 -5
  190. data/lib/avo/fields/concerns/is_readonly.rb +1 -5
  191. data/lib/avo/fields/concerns/is_required.rb +5 -7
  192. data/lib/avo/fields/concerns/is_searchable.rb +15 -0
  193. data/lib/avo/fields/concerns/use_resource.rb +5 -1
  194. data/lib/avo/fields/concerns/use_view_components.rb +45 -0
  195. data/lib/avo/fields/country_field.rb +4 -0
  196. data/lib/avo/fields/date_time_field.rb +1 -5
  197. data/lib/avo/fields/external_image_field.rb +2 -2
  198. data/lib/avo/fields/field_manager.rb +55 -0
  199. data/lib/avo/fields/file_field.rb +2 -2
  200. data/lib/avo/fields/gravatar_field.rb +2 -2
  201. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -2
  202. data/lib/avo/fields/has_base_field.rb +21 -17
  203. data/lib/avo/fields/has_many_field.rb +5 -2
  204. data/lib/avo/fields/has_one_field.rb +8 -12
  205. data/lib/avo/fields/heading_field.rb +9 -14
  206. data/lib/avo/fields/hidden_field.rb +1 -1
  207. data/lib/avo/fields/id_field.rb +3 -3
  208. data/lib/avo/fields/location_field.rb +10 -10
  209. data/lib/avo/fields/password_field.rb +1 -1
  210. data/lib/avo/fields/preview_field.rb +14 -0
  211. data/lib/avo/fields/select_field.rb +12 -8
  212. data/lib/avo/fields/status_field.rb +7 -1
  213. data/lib/avo/fields/text_field.rb +2 -2
  214. data/lib/avo/filters/base_filter.rb +9 -4
  215. data/lib/avo/html/builder.rb +8 -8
  216. data/lib/avo/item_grapher.rb +78 -0
  217. data/lib/avo/licensing/h_q.rb +11 -73
  218. data/lib/avo/licensing/license.rb +5 -1
  219. data/lib/avo/licensing/license_manager.rb +1 -1
  220. data/lib/avo/licensing/pro_license.rb +1 -7
  221. data/lib/avo/loaders/fields_loader.rb +7 -1
  222. data/lib/avo/plugin.rb +36 -0
  223. data/lib/avo/plugin_manager.rb +56 -0
  224. data/lib/avo/prefixed_test_helpers.rb +20 -0
  225. data/lib/avo/reloader.rb +3 -0
  226. data/lib/avo/resources/controls/actions_list.rb +7 -12
  227. data/lib/avo/resources/controls/attach_button.rb +15 -0
  228. data/lib/avo/resources/controls/back_button.rb +1 -1
  229. data/lib/avo/resources/controls/base_control.rb +15 -49
  230. data/lib/avo/resources/controls/create_button.rb +15 -0
  231. data/lib/avo/resources/controls/delete_button.rb +5 -1
  232. data/lib/avo/resources/controls/detach_button.rb +4 -1
  233. data/lib/avo/resources/controls/edit_button.rb +4 -1
  234. data/lib/avo/resources/controls/order_controls.rb +8 -0
  235. data/lib/avo/resources/controls/save_button.rb +13 -0
  236. data/lib/avo/resources/controls/show_button.rb +15 -0
  237. data/lib/avo/resources/items/holder.rb +96 -0
  238. data/lib/avo/resources/items/item_group.rb +44 -0
  239. data/lib/avo/resources/items/main_panel.rb +12 -0
  240. data/lib/avo/resources/items/panel.rb +2 -0
  241. data/lib/avo/resources/items/row.rb +42 -0
  242. data/lib/avo/resources/items/sidebar.rb +46 -0
  243. data/lib/avo/resources/items/tab.rb +54 -0
  244. data/lib/avo/resources/items/tab_group.rb +62 -0
  245. data/lib/avo/resources/resource_manager.rb +179 -0
  246. data/lib/avo/services/authorization_service.rb +11 -110
  247. data/lib/avo/services/debug_service.rb +93 -0
  248. data/lib/avo/services/encryption_service.rb +8 -12
  249. data/lib/avo/services/telemetry_service.rb +85 -0
  250. data/lib/avo/test_helpers.rb +362 -0
  251. data/lib/avo/tools/tool_manager.rb +30 -0
  252. data/lib/avo/version.rb +1 -1
  253. data/lib/avo/view_inquirer.rb +36 -0
  254. data/lib/avo.rb +109 -24
  255. data/lib/generators/avo/action_generator.rb +8 -8
  256. data/lib/generators/avo/card_generator.rb +27 -0
  257. data/lib/generators/avo/concerns/parent_controller.rb +20 -0
  258. data/lib/generators/avo/controller_generator.rb +3 -0
  259. data/lib/generators/avo/eject_generator.rb +180 -15
  260. data/lib/generators/avo/field_generator.rb +49 -2
  261. data/lib/generators/avo/filter_generator.rb +8 -8
  262. data/lib/generators/avo/js/install_generator.rb +2 -2
  263. data/lib/generators/avo/resource_generator.rb +12 -9
  264. data/lib/generators/avo/scope_generator.rb +15 -0
  265. data/lib/generators/avo/tailwindcss/install_generator.rb +70 -26
  266. data/lib/generators/avo/templates/action.tt +8 -6
  267. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  268. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  269. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  270. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  271. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  272. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  273. data/lib/generators/avo/templates/dashboards/dashboard.tt +5 -3
  274. data/lib/generators/avo/templates/field/%singular_name%_field.rb.tt +1 -1
  275. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  276. data/lib/generators/avo/templates/filters/multiple_select_filter.tt +1 -1
  277. data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
  278. data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
  279. data/lib/generators/avo/templates/initializer/avo.tt +7 -3
  280. data/lib/generators/avo/templates/locales/avo.ar.yml +2 -1
  281. data/lib/generators/avo/templates/locales/avo.en.yml +4 -3
  282. data/lib/generators/avo/templates/locales/avo.es.yml +1 -0
  283. data/lib/generators/avo/templates/locales/avo.fr.yml +1 -0
  284. data/lib/generators/avo/templates/locales/avo.nb.yml +1 -0
  285. data/lib/generators/avo/templates/locales/avo.nn.yml +1 -0
  286. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -0
  287. data/lib/generators/avo/templates/locales/avo.pt.yml +1 -0
  288. data/lib/generators/avo/templates/locales/avo.ro.yml +6 -5
  289. data/lib/generators/avo/templates/locales/avo.tr.yml +1 -0
  290. data/lib/generators/avo/templates/resource/controller.tt +1 -1
  291. data/lib/generators/avo/templates/resource/resource.tt +7 -7
  292. data/lib/generators/avo/templates/resource_tools/partial.tt +2 -2
  293. data/lib/generators/avo/templates/resource_tools/resource_tool.tt +1 -1
  294. data/lib/generators/avo/templates/scope.tt +6 -0
  295. data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
  296. data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +5 -3
  297. data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +11 -0
  298. data/lib/tasks/avo_tasks.rake +72 -4
  299. data/public/avo-assets/avo.base.css +1893 -1187
  300. data/public/avo-assets/avo.base.js +217 -305
  301. data/public/avo-assets/avo.base.js.map +3 -3
  302. data/public/avo-assets/avo.css +9744 -0
  303. data/public/avo-assets/avo.js +513 -0
  304. data/public/avo-assets/avo.js.map +7 -0
  305. data/tailwind.custom.js +47 -0
  306. data/tailwind.preset.js +152 -0
  307. metadata +104 -113
  308. data/app/components/avo/card_component.html.erb +0 -46
  309. data/app/components/avo/card_component.rb +0 -25
  310. data/app/components/avo/dashboards/divider_component.html.erb +0 -9
  311. data/app/components/avo/dashboards/divider_component.rb +0 -19
  312. data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +0 -47
  313. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +0 -95
  314. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -35
  315. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  316. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -10
  317. data/app/components/avo/fields/tags_field/index_component.rb +0 -9
  318. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  319. data/app/components/avo/fields/tags_field/show_component.rb +0 -5
  320. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  321. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  322. data/app/components/avo/index/ordering/base_component.rb +0 -9
  323. data/app/components/avo/index/ordering/button_component.html.erb +0 -11
  324. data/app/components/avo/index/ordering/button_component.rb +0 -23
  325. data/app/components/avo/index/ordering/buttons_component.html.erb +0 -32
  326. data/app/components/avo/index/ordering/buttons_component.rb +0 -47
  327. data/app/components/avo/item_switcher_component.html.erb +0 -27
  328. data/app/components/avo/item_switcher_component.rb +0 -48
  329. data/app/components/avo/sidebar/item_switcher_component.html.erb +0 -16
  330. data/app/components/avo/sidebar/item_switcher_component.rb +0 -15
  331. data/app/controllers/avo/dashboards/cards_controller.rb +0 -37
  332. data/app/controllers/avo/dashboards_controller.rb +0 -22
  333. data/app/controllers/avo/reorder_controller.rb +0 -25
  334. data/app/javascript/js/controllers/base_controller.js +0 -22
  335. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -127
  336. data/app/javascript/js/controllers/toggle_panel_controller.js +0 -18
  337. data/app/views/avo/dashboards/cards/_chartkick_card.html.erb +0 -3
  338. data/app/views/avo/dashboards/cards/_metric_card.html.erb +0 -5
  339. data/app/views/avo/dashboards/cards/chartkick_missing.html.erb +0 -14
  340. data/app/views/avo/dashboards/cards/show.html.erb +0 -3
  341. data/app/views/avo/dashboards/show.html.erb +0 -38
  342. data/app/views/avo/partials/_global_search.html.erb +0 -19
  343. data/app/views/avo/sidebar/_license_warnings.html.erb +0 -6
  344. data/lib/avo/app.rb +0 -237
  345. data/lib/avo/base_card.rb +0 -161
  346. data/lib/avo/concerns/fetches_things.rb +0 -150
  347. data/lib/avo/concerns/handles_field_args.rb +0 -47
  348. data/lib/avo/concerns/has_editable_controls.rb +0 -34
  349. data/lib/avo/concerns/has_fields.rb +0 -334
  350. data/lib/avo/concerns/has_html_attributes.rb +0 -108
  351. data/lib/avo/concerns/policy_helpers.rb +0 -31
  352. data/lib/avo/concerns/visible_in_dashboard.rb +0 -31
  353. data/lib/avo/dashboards/base_dashboard.rb +0 -89
  354. data/lib/avo/dashboards/base_divider.rb +0 -35
  355. data/lib/avo/dashboards/chartkick_card.rb +0 -77
  356. data/lib/avo/dashboards/dashboard_card.rb +0 -6
  357. data/lib/avo/dashboards/metric_card.rb +0 -9
  358. data/lib/avo/dashboards/partial_card.rb +0 -7
  359. data/lib/avo/fields/field_extensions/has_field_name.rb +0 -19
  360. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +0 -111
  361. data/lib/avo/fields/tags_field.rb +0 -102
  362. data/lib/avo/grid_collector.rb +0 -42
  363. data/lib/avo/hosts/association_scope_host.rb +0 -8
  364. data/lib/avo/hosts/base_host.rb +0 -25
  365. data/lib/avo/hosts/card_visibility.rb +0 -20
  366. data/lib/avo/hosts/dashboard_card.rb +0 -22
  367. data/lib/avo/hosts/dashboard_visibility.rb +0 -19
  368. data/lib/avo/hosts/ordering.rb +0 -22
  369. data/lib/avo/hosts/record_host.rb +0 -7
  370. data/lib/avo/hosts/resource_record_host.rb +0 -7
  371. data/lib/avo/hosts/resource_view_record_host.rb +0 -7
  372. data/lib/avo/hosts/search_scope_host.rb +0 -7
  373. data/lib/avo/hosts/view_record_host.rb +0 -7
  374. data/lib/avo/hosts/visibility_host.rb +0 -12
  375. data/lib/avo/items_holder.rb +0 -96
  376. data/lib/avo/main_panel.rb +0 -3
  377. data/lib/avo/menu/base_item.rb +0 -25
  378. data/lib/avo/menu/builder.rb +0 -82
  379. data/lib/avo/menu/dashboard.rb +0 -22
  380. data/lib/avo/menu/group.rb +0 -2
  381. data/lib/avo/menu/link.rb +0 -6
  382. data/lib/avo/menu/menu.rb +0 -2
  383. data/lib/avo/menu/resource.rb +0 -22
  384. data/lib/avo/menu/section.rb +0 -2
  385. data/lib/avo/panel.rb +0 -24
  386. data/lib/avo/panel_builder.rb +0 -25
  387. data/lib/avo/resources/controls/action.rb +0 -38
  388. data/lib/avo/resources/controls/execution_context.rb +0 -58
  389. data/lib/avo/resources/controls/items_holder.rb +0 -19
  390. data/lib/avo/resources/controls/link_to.rb +0 -27
  391. data/lib/avo/row.rb +0 -26
  392. data/lib/avo/row_builder.rb +0 -24
  393. data/lib/avo/services/authorization_clients/nil_client.rb +0 -37
  394. data/lib/avo/services/authorization_clients/pundit_client.rb +0 -51
  395. data/lib/avo/sidebar.rb +0 -30
  396. data/lib/avo/sidebar_builder.rb +0 -24
  397. data/lib/avo/tab.rb +0 -72
  398. data/lib/avo/tab_builder.rb +0 -25
  399. data/lib/avo/tab_group.rb +0 -42
  400. data/lib/avo/tab_group_builder.rb +0 -43
  401. data/lib/avo/tools_manager.rb +0 -11
  402. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  403. data/lib/generators/avo/card/metric_generator.rb +0 -18
  404. data/lib/generators/avo/card/partial_generator.rb +0 -19
  405. data/lib/generators/avo/templates/js/avo.custom.js +0 -2
  406. data/lib/generators/avo/templates/standalone_action.tt +0 -8
  407. /data/app/assets/stylesheets/css/{tags.css → fields/tags.css} +0 -0
@@ -1,6 +1,6 @@
1
1
  <%= content_tag :div, data: data_attributes, class: classes do %>
2
2
  <% if render_header? %>
3
- <div class="flex-1 flex flex-col xl:flex-row justify-between mb-4">
3
+ <div data-target="panel-header" class="flex-1 flex flex-col xl:flex-row justify-between mb-4">
4
4
  <div class="overflow-hidden flex flex-col">
5
5
  <% if display_breadcrumbs? %>
6
6
  <div class="breadcrumbs truncate mb-2">
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
  <% end %>
26
26
  <% if body? %>
27
- <div class="flex flex-col sm:flex-row space-y-4 sm:space-y-0 sm:gap-4 w-full">
27
+ <div data-target="panel-body" class="flex flex-col sm:flex-row space-y-4 sm:space-y-0 sm:gap-4 w-full">
28
28
  <div class="relative flex-1 w-full <% if sidebar? %> sm:w-2/3 <% end %>">
29
29
  <% # The body is wrapped inside another div in order to avoid long & tall panels next to sidebars when the sidebar taller. %>
30
30
  <div class="relative <%= white_panel_classes %> <%= @body_classes %>">
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
  </div>
34
34
  <% if sidebar? %>
35
- <div class="max-w-full sm:w-1/3 flex-shrink-0 h-full <%= white_panel_classes %>">
35
+ <div class="max-w-full sm:w-1/3 flex-shrink-0 h-full">
36
36
  <%= sidebar %>
37
37
  </div>
38
38
  <% end %>
@@ -44,12 +44,14 @@
44
44
  </div>
45
45
  <% end %>
46
46
  <% if bare_content? %>
47
- <div class="relative">
47
+ <div data-target="panel-bare-content" class="relative">
48
48
  <%= bare_content %>
49
49
  </div>
50
50
  <% end %>
51
51
  <% if footer_tools? %>
52
- <div class="flex-1 w-full flex flex-col sm:flex-row xl:justify-end sm:items-end space-y-2 sm:space-y-0 sm:space-x-2 mt-4 xl:mt-0">
52
+ <div
53
+ data-target="panel-footer-tools"
54
+ class="flex-1 w-full flex flex-col sm:flex-row xl:justify-end sm:items-end space-y-2 sm:space-y-0 sm:space-x-2 mt-4 xl:mt-0">
53
55
  <%= footer_tools %>
54
56
  </div>
55
57
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%# via_association_type is used in has_one create actions %>
2
2
  <%= hidden_field_tag :via_association_type, params[:via_association_type] if params[:via_association_type] %>
3
3
  <%= hidden_field_tag :via_resource_class, params[:via_resource_class] if params[:via_resource_class] %>
4
- <%= hidden_field_tag :via_resource_id, params[:via_resource_id] if params[:via_resource_id] %>
4
+ <%= hidden_field_tag :via_record_id, params[:via_record_id] if params[:via_record_id] %>
5
5
  <%= hidden_field_tag :via_relation, params[:via_relation] if params[:via_relation] %>
6
6
  <%= hidden_field_tag :via_belongs_to_resource_class, params[:via_belongs_to_resource_class] if params[:via_belongs_to_resource_class] %>
7
7
  <%= hidden_field_tag :referrer, back_path if params[:via_resource_class] %>
@@ -20,7 +20,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
20
20
  end
21
21
 
22
22
  def can_detach?
23
- return false if @reflection.blank? || @resource.model.blank? || !authorize_association_for(:detach)
23
+ return false if @reflection.blank? || @resource.record.blank? || !authorize_association_for(:detach)
24
24
 
25
25
  # If the inverse_of is a belongs_to, we need to check if it's optional in order to know if we can detach it.
26
26
  if inverse_of.is_a?(ActiveRecord::Reflection::BelongsToReflection)
@@ -33,7 +33,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
33
33
  def detach_path
34
34
  return "/" if @reflection.blank?
35
35
 
36
- helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.model.to_param)
36
+ helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.record.to_param)
37
37
  end
38
38
 
39
39
  def can_see_the_edit_button?
@@ -44,18 +44,25 @@ class Avo::ResourceComponent < Avo::BaseComponent
44
44
  @resource.authorization.authorize_action(:destroy, raise_exception: false)
45
45
  end
46
46
 
47
- def can_act_on?
47
+ def can_see_the_actions_button?
48
+ return false if @actions.blank?
49
+
48
50
  return authorize_association_for(:act_on) if @reflection.present?
49
51
 
50
52
  @resource.authorization.authorize_action(:act_on, raise_exception: false) && !has_reflection_and_is_read_only
51
53
  end
52
54
 
53
55
  def destroy_path
54
- if params[:via_resource_class].present?
55
- helpers.resource_path(model: @resource.model, resource: @resource, referrer: back_path)
56
- else
57
- helpers.resource_path(model: @resource.model, resource: @resource)
56
+ args = {record: @resource.record, resource: @resource}
57
+
58
+ args[:referrer] = if params[:via_resource_class].present?
59
+ back_path
60
+ # If we're deleting a resource from a parent resource, we need to go back to the parent resource page after the deletion
61
+ elsif @parent_resource.present?
62
+ helpers.resource_path(record: @parent_record, resource: @parent_resource)
58
63
  end
64
+
65
+ helpers.resource_path(**args)
59
66
  end
60
67
 
61
68
  # Ex: A Post has many Comments
@@ -65,9 +72,9 @@ class Avo::ResourceComponent < Avo::BaseComponent
65
72
  if @reflection.present?
66
73
  # Fetch the appropiate resource
67
74
  reflection_resource = field.resource
68
- # Fetch the model
69
- # Hydrate the resource with the model if we have one
70
- reflection_resource.hydrate(model: @parent_model) if @parent_model.present?
75
+ # Fetch the record
76
+ # Hydrate the resource with the record if we have one
77
+ reflection_resource.hydrate(record: @parent_record) if @parent_record.present?
71
78
  # Use the related_name as the base of the association
72
79
  association_name = @reflection.name
73
80
 
@@ -80,16 +87,17 @@ class Avo::ResourceComponent < Avo::BaseComponent
80
87
  if service.has_method?(method_name, raise_exception: false)
81
88
  # Some policy methods should get the parent record in order to have the necessarry information to do the authorization
82
89
  # Example: Post->has_many->Comments
90
+ #
83
91
  # When you want to authorize the creation/attaching of a Comment, you don't have the Comment instance.
84
92
  # But you do have the Post instance and you can get that in your policy to authorize against.
85
93
  parent_policy_methods = [:view, :create, :attach, :act_on]
86
94
 
87
95
  record = if parent_policy_methods.include?(policy_method)
88
96
  # Use the parent record (Post)
89
- reflection_resource.model
97
+ reflection_resource.record
90
98
  else
91
99
  # Override the record with the child record (Comment)
92
- resource.model
100
+ resource.record
93
101
  end
94
102
  policy_result = service.authorize_action(method_name, record: record, raise_exception: false)
95
103
  end
@@ -105,43 +113,214 @@ class Avo::ResourceComponent < Avo::BaseComponent
105
113
  end
106
114
  end
107
115
 
108
- def sidebar
109
- return if Avo::App.license.lacks_with_trial(:resource_sidebar)
110
-
111
- @sidebar ||= search_for_sidebar
112
- end
116
+ def sidebars
117
+ return if Avo.license.lacks_with_trial(:resource_sidebar)
113
118
 
114
- def sidebar_component(form: nil)
115
- Avo::ResourceSidebarComponent.new resource: @resource, fields: sidebar.visible_items, params: params, view: view, form: form
119
+ @item.items.select do |item|
120
+ item.is_sidebar?
121
+ end
122
+ .map do |sidebar|
123
+ sidebar.hydrate(view: view, resource: resource)
124
+ end
116
125
  end
117
126
 
118
127
  def has_reflection_and_is_read_only
119
128
  if @reflection.present? && @reflection.active_record.name && @reflection.name
120
- fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
129
+ resource = Avo.resource_manager.get_resource_by_model_class(@reflection.active_record.name).new(params: helpers.params, view: view, user: helpers._current_user)
130
+ fields = resource.get_field_definitions
121
131
  filtered_fields = fields.filter { |f| f.id == @reflection.name }
122
132
  else
123
133
  return false
124
134
  end
125
135
 
126
136
  if filtered_fields.present?
127
- filtered_fields.find { |f| f.id == @reflection.name }.is_readonly?
137
+ filtered_fields.find { |f| f.id == @reflection.name }.is_disabled?
128
138
  else
129
139
  false
130
140
  end
131
141
  end
132
142
 
143
+ def render_control(control)
144
+ send "render_#{control.type}", control
145
+ end
146
+
147
+ def render_cards_component
148
+ if Avo.plugin_manager.installed?("avo-dashboards")
149
+ render Avo::CardsComponent.new cards: @resource.detect_cards.visible_cards, classes: "pb-4 sm:grid-cols-3"
150
+ end
151
+ end
152
+
133
153
  private
134
154
 
135
155
  def via_resource?
136
- (params[:via_resource_class].present? || params[:via_relation_class].present?) && params[:via_resource_id].present?
156
+ (params[:via_resource_class].present? || params[:via_relation_class].present?) && params[:via_record_id].present?
137
157
  end
138
158
 
139
- def search_for_sidebar
140
- item = @resource.get_items.find do |item|
141
- item.is_sidebar?
159
+ def render_back_button(control)
160
+ return if back_path.blank? || is_a_related_resource?
161
+
162
+ tippy = control.title ? :tooltip : nil
163
+ a_link back_path,
164
+ style: :text,
165
+ title: control.title,
166
+ data: {tippy: tippy},
167
+ icon: "arrow-left" do
168
+ control.label
142
169
  end
170
+ end
171
+
172
+ def render_actions_list(actions_list)
173
+ return unless can_see_the_actions_button?
174
+
175
+ render Avo::ActionsComponent.new(
176
+ actions: @actions,
177
+ resource: @resource,
178
+ view: @view,
179
+ exclude: actions_list.exclude,
180
+ include: actions_list.include,
181
+ style: actions_list.style,
182
+ color: actions_list.color,
183
+ label: actions_list.label,
184
+ size: actions_list.size,
185
+ as_row_control: instance_of?(Avo::Index::ResourceControlsComponent)
186
+ )
187
+ end
188
+
189
+ def render_delete_button(control)
190
+ # If the resource is a related resource, we use the can_delete? policy method because it uses
191
+ # authorize_association_for(:destroy).
192
+ # Otherwise we use the can_see_the_destroy_button? policy method becuse it do no check for assiciation
193
+ # only for authorize_action .
194
+ policy_method = is_a_related_resource? ? :can_delete? : :can_see_the_destroy_button?
195
+ return unless send policy_method
196
+
197
+ a_link destroy_path,
198
+ style: :text,
199
+ color: :red,
200
+ icon: "trash",
201
+ form_class: "flex flex-col sm:flex-row sm:inline-flex",
202
+ title: control.title,
203
+ data: {
204
+ turbo_confirm: t("avo.are_you_sure", item: @resource.record.model_name.name.downcase),
205
+ turbo_method: :delete,
206
+ target: "control:destroy",
207
+ control: :destroy,
208
+ tippy: control.title ? :tooltip : nil,
209
+ "resource-id": @resource.record.id,
210
+ } do
211
+ control.label
212
+ end
213
+ end
214
+
215
+ def render_save_button(control)
216
+ return unless can_see_the_save_button?
217
+
218
+ a_button color: :primary,
219
+ style: :primary,
220
+ loading: true,
221
+ type: :submit,
222
+ icon: "save" do
223
+ control.label
224
+ end
225
+ end
226
+
227
+ def render_edit_button(control)
228
+ return unless can_see_the_edit_button?
229
+
230
+ a_link edit_path,
231
+ color: :primary,
232
+ style: :primary,
233
+ title: control.title,
234
+ data: {tippy: control.title ? :tooltip : nil},
235
+ icon: "edit" do
236
+ control.label
237
+ end
238
+ end
239
+
240
+ def render_detach_button(control)
241
+ return unless is_a_related_resource? && can_detach?
242
+
243
+ a_button url: detach_path,
244
+ icon: "detach",
245
+ method: :delete,
246
+ form_class: "flex flex-col sm:flex-row sm:inline-flex",
247
+ style: :text,
248
+ data: {
249
+ confirm: "Are you sure you want to detach this #{title}."
250
+ } do
251
+ control.label || t("avo.detach_item", item: title).humanize
252
+ end
253
+ end
254
+
255
+ def render_create_button(control)
256
+ return unless can_see_the_create_button?
257
+
258
+ a_link create_path,
259
+ color: :primary,
260
+ style: :primary,
261
+ icon: "heroicons/outline/plus",
262
+ data: {
263
+ target: :create
264
+ } do
265
+ control.label
266
+ end
267
+ end
268
+
269
+ def render_attach_button(control)
270
+ return unless can_attach?
271
+
272
+ a_link attach_path,
273
+ icon: "heroicons/outline/link",
274
+ color: :primary,
275
+ style: :text,
276
+ data: {
277
+ turbo_frame: :attach_modal,
278
+ target: :attach
279
+ } do
280
+ control.label
281
+ end
282
+ end
283
+
284
+ def render_link_to(link)
285
+ a_link link.path,
286
+ color: link.color,
287
+ style: link.style,
288
+ icon: link.icon,
289
+ icon_class: link.icon_class,
290
+ title: link.title, target: link.target,
291
+ class: link.classes,
292
+ size: link.size,
293
+ data: {
294
+ **link.data,
295
+ tippy: link.title ? :tooltip : nil,
296
+ } do
297
+ link.label
298
+ end
299
+ end
300
+
301
+ def render_action(action)
302
+ return if !can_see_the_actions_button?
303
+ return if !action.action.visible_in_view(parent_resource: @parent_resource)
304
+
305
+ a_link action.path,
306
+ color: action.color,
307
+ style: action.style,
308
+ icon: action.icon,
309
+ icon_class: action.icon_class,
310
+ title: action.title,
311
+ size: action.size,
312
+ data: {
313
+ turbo_frame: "actions_show",
314
+ action_name: action.action.action_name,
315
+ tippy: action.title ? :tooltip : nil,
316
+ action: "click->actions-picker#visitAction",
317
+ } do
318
+ action.label
319
+ end
320
+ end
143
321
 
144
- item&.hydrate(view: view)
322
+ def is_a_related_resource?
323
+ @reflection.present? && @resource.record.present?
145
324
  end
146
325
 
147
326
  def inverse_of
@@ -1,19 +1,16 @@
1
- <div class="resource-sidebar-component divide-y">
2
- <% fields.each_with_index do |field, index| %>
3
- <%= render field
4
- .hydrate(
5
- resource: resource,
6
- model: resource.model,
7
- user: resource.user,
8
- view: view
9
- ).component_for_view(view)
10
- .new(
11
- field: field,
12
- resource: resource,
13
- form: form,
14
- stacked: true,
15
- index: index
16
- )
17
- %>
18
- <% end %>
1
+ <div class="resource-sidebar-component divide-y"
2
+ data-component-name="<%= self.class.to_s.underscore %>"
3
+ data-component-index="<%= index %>"
4
+ data-resource-name="<%= @resource.class.to_s %>"
5
+ data-record-id="<%= @resource.record.id %>"
6
+ >
7
+ <%= render Avo::Items::VisibleItemsComponent.new(
8
+ resource: @resource,
9
+ item: @sidebar,
10
+ view: @view,
11
+ form: @form,
12
+ field_component_extra_args: {
13
+ stacked: true
14
+ }
15
+ )%>
19
16
  </div>
@@ -6,16 +6,18 @@ class Avo::ResourceSidebarComponent < ViewComponent::Base
6
6
  attr_reader :view
7
7
  attr_reader :form
8
8
  attr_reader :fields
9
+ attr_reader :index
9
10
 
10
- def initialize(resource: nil, fields: nil, index: nil, params: nil, form: nil, view: nil)
11
+ def initialize(resource: nil, sidebar: nil, index: nil, params: nil, form: nil, view: nil)
11
12
  @resource = resource
12
- @fields = fields
13
+ @sidebar = sidebar
13
14
  @params = params
14
15
  @view = view
15
16
  @form = form
17
+ @index = index
16
18
  end
17
19
 
18
20
  def render?
19
- Avo::App.license.has_with_trial(:resource_sidebar)
21
+ Avo.license.has_with_trial(:resource_sidebar)
20
22
  end
21
23
  end
@@ -19,7 +19,7 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
19
19
 
20
20
  def is_external?
21
21
  # If the path contains the scheme, check if it includes the root path or not
22
- return !path.include?(Avo::App.root_path) if URI(path).scheme.present?
22
+ return !path.include?(Avo.mount_path) if URI(path).scheme.present?
23
23
 
24
24
  false
25
25
  end
@@ -13,8 +13,8 @@
13
13
  <div class="space-y-6 mb-4">
14
14
  <%= render Avo::Sidebar::LinkComponent.new label: 'Get started', path: helpers.avo.root_path, active: :exclusive if Rails.env.development? && Avo.configuration.home_path.nil? %>
15
15
 
16
- <% if Avo::App.has_main_menu? %>
17
- <% Avo::App.main_menu.items.each do |item| %>
16
+ <% if Avo.plugin_manager.installed?("avo-menu") && Avo.has_main_menu? %>
17
+ <% Avo.main_menu.items.each do |item| %>
18
18
  <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
19
19
  <% end %>
20
20
  <% else %>
@@ -57,7 +57,14 @@
57
57
  <%= render partial: "/avo/partials/sidebar_extra" %>
58
58
  </div>
59
59
  </div>
60
- <%= helpers.render_license_warnings unless Rails.env.production? %>
60
+ <% if Rails.env.development? %>
61
+ <div class="p-4 border-t group">
62
+ <%= link_to helpers.avo.avo_private_status_path, class: "block px-4 py-2 border rounded flex justify-between items-center w-full text-black text-sm" do %>
63
+ <span>Avo Status</span> <span><div class="rounded-full w-4 h-4 <%= Avo.app_status ? "bg-green-400" : "bg-orange-400" %>"></div></span>
64
+ <% end %>
65
+ <div class="absolute text-xs text-gray-700 group-hover:block hidden text-center w-full -ml-4">👆Visible only in development👆</div>
66
+ </div>
67
+ <% end %>
61
68
  <%= render Avo::SidebarProfileComponent.new user: helpers._current_user %>
62
69
  </div>
63
70
  </div>
@@ -7,15 +7,17 @@ class Avo::SidebarComponent < ViewComponent::Base
7
7
  end
8
8
 
9
9
  def dashboards
10
- Avo::App.dashboards_for_navigation
10
+ return [] unless Avo.plugin_manager.installed?("avo-dashboards")
11
+
12
+ Avo::Dashboards.dashboard_manager.dashboards_for_navigation
11
13
  end
12
14
 
13
15
  def resources
14
- Avo::App.resources_for_navigation
16
+ Avo.resource_manager.resources_for_navigation helpers._current_user
15
17
  end
16
18
 
17
19
  def tools
18
- Avo::App.tools_for_navigation
20
+ Avo.tool_manager.tools_for_navigation
19
21
  end
20
22
 
21
23
  def stimulus_target
@@ -1,12 +1,12 @@
1
1
  <div class="text-black border-gray-150 p-4 flex border-t">
2
- <div class="flex-1 flex space-x-4">
2
+ <div class="flex-1 flex space-x-4 w-full">
3
3
  <% if avatar.present? %>
4
- <div class="relative aspect-square w-10 h-10 overflow-hidden rounded">
5
- <%= image_tag avatar, class: "object-cover min-w-full min-h-full h-full" %>
4
+ <div class="relative aspect-square w-10 h-10 overflow-hidden rounded shrink-0">
5
+ <%= image_tag helpers.main_app.url_for(avatar), class: "object-cover min-w-full min-h-full h-full" %>
6
6
  </div>
7
7
  <% end %>
8
- <div class="flex flex-col">
9
- <div class="font-medium">
8
+ <div class="flex flex-col pr-3 min-w-0">
9
+ <div class="font-medium text-ellipsis overflow-hidden">
10
10
  <%= name %>
11
11
  </div>
12
12
  <% if title.present? %>
@@ -16,17 +16,23 @@
16
16
  <% end %>
17
17
  </div>
18
18
  </div>
19
- <div class="relative" data-controller="toggle-panel">
20
- <a class="flex items-center h-full cursor-pointer" data-control="profile-dots" data-action="click->toggle-panel#togglePanel">
19
+ <div class="relative" data-controller="toggle">
20
+ <a class="flex items-center h-full cursor-pointer" data-control="profile-dots" data-action="click->toggle#togglePanel">
21
21
  <%= helpers.svg 'three-dots', class: 'h-4' %>
22
22
  </a>
23
23
  <div
24
24
  class="hidden absolute flex flex-col inset-auto right-0 -mt-12 bg-white rounded min-w-[200px] shadow-context -translate-y-full z-40"
25
- data-toggle-panel-target="panel"
25
+ data-toggle-target="panel"
26
+ data-transition-enter="transition ease-out duration-100"
27
+ data-transition-enter-start="transform opacity-0 translate-y-1"
28
+ data-transition-enter-end="transform opacity-100 translate-y-0"
29
+ data-transition-leave="transition ease-in duration-75"
30
+ data-transition-leave-start="transform opacity-100 translate-y-0"
31
+ data-transition-leave-end="transform opacity-0 translate-y-1"
26
32
  >
27
- <% if Avo::App.has_profile_menu? %>
28
- <div class="text-black">
29
- <% Avo::App.profile_menu.items.each do |item| %>
33
+ <% if Avo.plugin_manager.installed?("avo-menu") && Avo.has_profile_menu? %>
34
+ <div class="text-black space-y-4">
35
+ <% Avo.profile_menu.items.each do |item| %>
30
36
  <% if item.is_a? Avo::Menu::Link %>
31
37
  <%= render Avo::ProfileItemComponent.new label: item.name, path: item.path, icon: item.icon, method: item.method, params: item.params %>
32
38
  <% end %>
@@ -45,7 +51,7 @@
45
51
  form_class: 'flex-1' do %>
46
52
  <%= helpers.svg 'logout', class: 'h-4 mr-1' %> <%= t('avo.sign_out') %>
47
53
  <% end %>
48
- <% end %>
54
+ <% end %>
49
55
  </div>
50
56
  </div>
51
57
  </div>
@@ -25,26 +25,32 @@
25
25
  # On edit screens we want to load each tab because we wnst the DOM to have the fields present on form submission.
26
26
  # If you have a field which is in the second tab and it's required, the form submission will fail because the required field is not in view, and we don't want that.
27
27
  # We also want to load the current tab
28
- should_lazy_load = if @view.to_s.in?(['edit', 'new', 'update', 'create'])
28
+ should_lazy_load = if @view.in?(%w[edit new update create])
29
29
  false
30
30
  else
31
31
  !is_current_tab
32
32
  end
33
33
 
34
34
  if should_lazy_load
35
- args[:src] = helpers.resource_path(resource: resource, model: resource.model, keep_query_params: true, active_tab_name: tab.name, tab_turbo_frame: group.turbo_frame_id)
35
+ args[:src] = helpers.resource_path(resource: resource, record: resource.record, keep_query_params: true, active_tab_name: tab.name, tab_turbo_frame: group.turbo_frame_id)
36
36
  args[:loading] = :lazy
37
37
  end
38
38
  %>
39
39
  <%= turbo_frame_tag tab.turbo_frame_id(parent: @group), **args do %>
40
40
  <div class="border rounded-lg p-2 -mx-2 -my-2 lg:p-4 lg:-mx-4 lg:-my-4 space-y-4">
41
- <%= render Avo::TabSwitcherComponent.new resource: resource, current_tab: tab, group: group, active_tab_name: active_tab_name, view: view, style: tabs_style %>
42
- <% if !should_lazy_load && !tab.empty? %>
43
- <div class="space-y-12">
44
- <% tab.visible_items.each do |item| %>
45
- <%= render Avo::ItemSwitcherComponent.new resource: resource, item: item, index: index, form: form, view: @view %>
46
- <% end %>
41
+ <%= render Avo::TabSwitcherComponent.new resource: resource, current_tab: tab, group: group, active_tab_name: active_tab_name, view: view %>
42
+ <% if should_lazy_load %>
43
+ <div class="block w-full">
44
+ <%= render Avo::LoadingComponent.new title: "#{tab.name}" %>
47
45
  </div>
46
+ <% else %>
47
+ <% if !tab.is_empty? %>
48
+ <div class="space-y-12">
49
+ <% tab.visible_items.each do |item| %>
50
+ <%= render Avo::Items::SwitcherComponent.new resource: resource, item: item, index: index, form: form, view: @view %>
51
+ <% end %>
52
+ </div>
53
+ <% end %>
48
54
  <% end %>
49
55
  </div>
50
56
  <% end %>
@@ -7,14 +7,13 @@ class Avo::TabGroupComponent < Avo::BaseComponent
7
7
  attr_reader :form
8
8
  attr_reader :resource
9
9
 
10
- def initialize(resource:, group:, index:, form:, params:, view:, tabs_style:)
10
+ def initialize(resource:, group:, index:, form:, params:, view:)
11
11
  @resource = resource
12
12
  @group = group
13
13
  @index = index
14
14
  @form = form
15
15
  @params = params
16
16
  @view = view
17
- @tabs_style = tabs_style
18
17
 
19
18
  @group.index = index
20
19
  end
@@ -50,8 +49,4 @@ class Avo::TabGroupComponent < Avo::BaseComponent
50
49
  tab.name.to_s == active_tab_name.to_s
51
50
  end
52
51
  end
53
-
54
- def tabs_style
55
- @tabs_style || Avo.configuration.tabs_style
56
- end
57
52
  end
@@ -1,41 +1,18 @@
1
- <% if style == :tabs %>
2
- <div class="flex overflow-auto mac-styled-scrollbar" data-target="tab-switcher" data-style="tabs">
3
- <div class="button-group">
4
- <% visible_items.each do |tab| %>
5
- <%= a_link tab_path(tab),
6
- color: selected?(tab) ? :primary : :gray ,
7
- rounded: false,
8
- size: :sm,
9
- class: "active:outline-0 #{selected?(tab) ? "z-20" : "bg-gray-100 border-gray-300"}",
10
- title: tab.description,
11
- data: {
12
- tippy: tab.description.present? ? 'tooltip' : '',
13
- selected: selected?(tab),
14
- action: 'click->tabs#changeTab',
15
- tabs_id_param: tab.name
16
- } do %>
17
- <%= tab.name %>
18
- <% end %>
19
- <% end %>
20
- </div>
21
- </div>
22
- <% else %>
23
- <div class="flex flex-wrap gap-2 p-2 <%= white_panel_classes %>" data-target="tab-switcher" data-style="pills">
24
- <% visible_items.each do |tab| %>
25
- <%= a_link tab_path(tab),
26
- color: selected?(tab) ? :primary : :gray,
27
- style: selected?(tab) ? :outline : :text,
28
- size: :sm,
29
- class: selected?(tab) ? "z-20 bg-primary-100" : "",
30
- title: tab.description,
31
- data: {
32
- tippy: tab.description.present? ? 'tooltip' : '',
33
- selected: selected?(tab),
34
- action: 'click->tabs#changeTab',
35
- tabs_id_param: tab.name
36
- } do %>
37
- <%= tab.name %>
38
- <% end %>
1
+ <div class="flex flex-wrap gap-2 p-2 <%= white_panel_classes %>" data-target="tab-switcher">
2
+ <% group.visible_items.each do |tab| %>
3
+ <%= a_link tab_path(tab),
4
+ color: selected?(tab) ? :primary : :gray,
5
+ style: selected?(tab) ? :outline : :text,
6
+ size: :sm,
7
+ class: selected?(tab) ? "z-20 bg-primary-100" : "",
8
+ title: tab.description,
9
+ data: {
10
+ tippy: tab.description.present? ? 'tooltip' : '',
11
+ selected: selected?(tab),
12
+ action: 'click->tabs#changeTab',
13
+ tabs_id_param: tab.name
14
+ } do %>
15
+ <%= tab.name %>
39
16
  <% end %>
40
- </div>
41
- <% end %>
17
+ <% end %>
18
+ </div>