avo 2.43.0 → 3.0.2

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

Potentially problematic release.


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

Files changed (414) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +30 -26
  3. data/Gemfile.lock +235 -161
  4. data/README.md +19 -27
  5. data/Rakefile +2 -0
  6. data/app/assets/stylesheets/avo.base.css +1 -1
  7. data/app/assets/svgs/font.svg +1 -0
  8. data/app/assets/svgs/triangle-up.svg +1 -0
  9. data/app/components/avo/actions_component.html.erb +19 -5
  10. data/app/components/avo/actions_component.rb +39 -19
  11. data/app/components/avo/asset_manager/javascript_component.html.erb +3 -0
  12. data/app/components/avo/asset_manager/javascript_component.rb +13 -0
  13. data/app/components/avo/asset_manager/stylesheet_component.html.erb +3 -0
  14. data/app/components/avo/asset_manager/stylesheet_component.rb +13 -0
  15. data/app/components/avo/base_component.rb +15 -12
  16. data/app/components/avo/button_component.rb +20 -3
  17. data/app/components/avo/empty_state_component.rb +1 -1
  18. data/app/components/avo/field_wrapper_component.html.erb +1 -1
  19. data/app/components/avo/field_wrapper_component.rb +9 -15
  20. data/app/components/avo/fields/area_field/edit_component.html.erb +2 -2
  21. data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +75 -79
  22. data/app/components/avo/fields/belongs_to_field/edit_component.rb +7 -7
  23. data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
  24. data/app/components/avo/fields/belongs_to_field/show_component.rb +2 -2
  25. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
  26. data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
  27. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +3 -3
  28. data/app/components/avo/fields/common/badge_viewer_component.rb +1 -1
  29. data/app/components/avo/fields/common/boolean_check_component.html.erb +1 -12
  30. data/app/components/avo/fields/common/boolean_check_component.rb +2 -1
  31. data/app/components/avo/fields/common/boolean_group_component.html.erb +2 -2
  32. data/app/components/avo/fields/common/files/view_type/grid_item_component.rb +2 -2
  33. data/app/components/avo/fields/common/gravatar_viewer_component.html.erb +1 -1
  34. data/app/components/avo/fields/common/gravatar_viewer_component.rb +2 -2
  35. data/app/components/avo/fields/common/heading_component.html.erb +3 -8
  36. data/app/components/avo/fields/common/heading_component.rb +1 -3
  37. data/app/components/avo/fields/common/key_value_component.html.erb +2 -2
  38. data/app/components/avo/fields/common/key_value_component.rb +2 -2
  39. data/app/components/avo/fields/common/progress_bar_component.rb +3 -9
  40. data/app/components/avo/fields/common/status_viewer_component.html.erb +3 -0
  41. data/app/components/avo/fields/edit_component.rb +2 -2
  42. data/app/components/avo/fields/external_image_field/index_component.html.erb +1 -1
  43. data/app/components/avo/fields/file_field/index_component.html.erb +2 -2
  44. data/app/components/avo/fields/gravatar_field/index_component.html.erb +1 -1
  45. data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
  46. data/app/components/avo/fields/has_one_field/show_component.html.erb +3 -2
  47. data/app/components/avo/fields/has_one_field/show_component.rb +2 -2
  48. data/app/components/avo/fields/heading_field/edit_component.html.erb +1 -1
  49. data/app/components/avo/fields/heading_field/show_component.html.erb +1 -1
  50. data/app/components/avo/fields/id_field/index_component.html.erb +1 -1
  51. data/app/components/avo/fields/index_component.rb +6 -6
  52. data/app/components/avo/fields/location_field/edit_component.html.erb +12 -10
  53. data/app/components/avo/fields/preview_field/index_component.html.erb +10 -0
  54. data/app/components/avo/fields/preview_field/index_component.rb +4 -0
  55. data/app/components/avo/fields/select_field/edit_component.html.erb +1 -1
  56. data/app/components/avo/fields/show_component.rb +5 -2
  57. data/app/components/avo/fields/text_field/index_component.html.erb +1 -1
  58. data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -2
  59. data/app/components/avo/fields/trix_field/edit_component.rb +1 -1
  60. data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
  61. data/app/components/avo/filters_component.html.erb +9 -3
  62. data/app/components/avo/filters_component.rb +4 -4
  63. data/app/components/avo/index/field_wrapper_component.rb +1 -13
  64. data/app/components/avo/index/grid_item_component.html.erb +13 -36
  65. data/app/components/avo/index/grid_item_component.rb +43 -16
  66. data/app/components/avo/index/resource_controls_component.html.erb +3 -81
  67. data/app/components/avo/index/resource_controls_component.rb +125 -18
  68. data/app/components/avo/index/resource_grid_component.html.erb +5 -3
  69. data/app/components/avo/index/resource_grid_component.rb +5 -2
  70. data/app/components/avo/index/resource_map_component.html.erb +1 -1
  71. data/app/components/avo/index/resource_map_component.rb +3 -3
  72. data/app/components/avo/index/resource_table_component.html.erb +5 -4
  73. data/app/components/avo/index/resource_table_component.rb +24 -7
  74. data/app/components/avo/index/table_row_component.html.erb +9 -5
  75. data/app/components/avo/index/table_row_component.rb +3 -2
  76. data/app/components/avo/items/panel_component.html.erb +25 -0
  77. data/app/components/avo/items/panel_component.rb +43 -0
  78. data/app/components/avo/items/switcher_component.html.erb +17 -0
  79. data/app/components/avo/items/switcher_component.rb +79 -0
  80. data/app/components/avo/items/visible_items_component.html.erb +10 -0
  81. data/app/components/avo/items/visible_items_component.rb +11 -0
  82. data/app/components/avo/modal_component.html.erb +3 -4
  83. data/app/components/avo/paginator_component.html.erb +29 -40
  84. data/app/components/avo/paginator_component.rb +23 -5
  85. data/app/components/avo/panel_component.html.erb +7 -5
  86. data/app/components/avo/referrer_params_component.html.erb +1 -1
  87. data/app/components/avo/resource_component.rb +205 -26
  88. data/app/components/avo/resource_sidebar_component.html.erb +15 -18
  89. data/app/components/avo/resource_sidebar_component.rb +5 -3
  90. data/app/components/avo/sidebar/link_component.rb +1 -1
  91. data/app/components/avo/sidebar_component.html.erb +10 -3
  92. data/app/components/avo/sidebar_component.rb +5 -3
  93. data/app/components/avo/sidebar_profile_component.html.erb +18 -12
  94. data/app/components/avo/tab_group_component.html.erb +14 -8
  95. data/app/components/avo/tab_group_component.rb +1 -6
  96. data/app/components/avo/tab_switcher_component.html.erb +17 -40
  97. data/app/components/avo/tab_switcher_component.rb +6 -41
  98. data/app/components/avo/views/resource_edit_component.html.erb +23 -84
  99. data/app/components/avo/views/resource_edit_component.rb +20 -19
  100. data/app/components/avo/views/resource_index_component.html.erb +42 -47
  101. data/app/components/avo/views/resource_index_component.rb +76 -13
  102. data/app/components/avo/views/resource_show_component.html.erb +16 -177
  103. data/app/components/avo/views/resource_show_component.rb +16 -10
  104. data/app/controllers/avo/actions_controller.rb +37 -41
  105. data/app/controllers/avo/application_controller.rb +119 -181
  106. data/app/controllers/avo/associations_controller.rb +34 -43
  107. data/app/controllers/avo/attachments_controller.rb +4 -4
  108. data/app/controllers/avo/base_controller.rb +145 -98
  109. data/app/controllers/avo/debug_controller.rb +17 -5
  110. data/app/controllers/avo/home_controller.rb +1 -1
  111. data/app/controllers/avo/search_controller.rb +56 -50
  112. data/app/controllers/concerns/avo/initializes_avo.rb +22 -0
  113. data/app/helpers/avo/application_helper.rb +18 -8
  114. data/app/helpers/avo/resources_helper.rb +1 -1
  115. data/app/helpers/avo/url_helpers.rb +28 -12
  116. data/app/javascript/avo.base.js +1 -0
  117. data/app/javascript/js/application.js +3 -0
  118. data/app/javascript/js/controllers/action_controller.js +3 -1
  119. data/app/javascript/js/controllers/actions_overflow_controller.js +62 -0
  120. data/app/javascript/js/controllers/fields/reload_belongs_to_field_controller.js +7 -7
  121. data/app/javascript/js/controllers/filter_controller.js +1 -1
  122. data/app/javascript/js/controllers/input_autofocus_controller.js +12 -0
  123. data/app/javascript/js/controllers/preview_controller.js +24 -0
  124. data/app/javascript/js/controllers/search_controller.js +4 -2
  125. data/app/javascript/js/controllers/self_destroy_controller.js +7 -0
  126. data/app/javascript/js/controllers/toggle_controller.js +48 -0
  127. data/app/javascript/js/controllers.js +11 -5
  128. data/app/javascript/js/custom-stream-actions.js +15 -0
  129. data/app/views/avo/actions/show.html.erb +10 -7
  130. data/app/views/avo/associations/new.html.erb +2 -2
  131. data/app/views/avo/base/_new_via_belongs_to.html.erb +1 -1
  132. data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +3 -3
  133. data/app/views/avo/base/create_fail_action.turbo_stream.erb +2 -2
  134. data/app/views/avo/base/edit.html.erb +1 -1
  135. data/app/views/avo/base/index.html.erb +4 -3
  136. data/app/views/avo/base/new.html.erb +2 -1
  137. data/app/views/avo/base/preview.html.erb +19 -0
  138. data/app/views/avo/base/show.html.erb +2 -2
  139. data/app/views/avo/debug/_valid_indicator.html.erb +9 -0
  140. data/app/views/avo/debug/report.html.erb +32 -17
  141. data/app/views/avo/debug/{index.html.erb → status.html.erb} +31 -14
  142. data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
  143. data/app/views/avo/partials/_flash_alerts.turbo_stream.erb +1 -1
  144. data/app/views/avo/partials/_footer.html.erb +1 -1
  145. data/app/views/avo/partials/_javascript.html.erb +5 -0
  146. data/app/views/avo/partials/_logo.html.erb +1 -1
  147. data/app/views/avo/partials/_navbar.html.erb +3 -5
  148. data/app/views/avo/partials/_resource_search.html.erb +1 -0
  149. data/app/views/avo/partials/_table_header.html.erb +5 -11
  150. data/app/views/layouts/avo/application.html.erb +5 -4
  151. data/avo.gemspec +11 -8
  152. data/bin/dev +3 -1
  153. data/bin/prod +0 -0
  154. data/config/i18n-tasks.yml +1 -1
  155. data/config/initializers/pagy.rb +2 -0
  156. data/config/master.key +1 -0
  157. data/config/routes.rb +7 -10
  158. data/db/factories.rb +6 -0
  159. data/lib/avo/asset_manager.rb +30 -0
  160. data/lib/avo/base_action.rb +84 -82
  161. data/lib/avo/base_resource.rb +286 -225
  162. data/lib/avo/base_resource_tool.rb +9 -16
  163. data/lib/avo/concerns/borrow_items_holder.rb +35 -0
  164. data/lib/avo/concerns/breadcrumbs.rb +2 -2
  165. data/lib/avo/concerns/{can_replace_fields.rb → can_replace_items.rb} +5 -9
  166. data/lib/avo/concerns/filters_session_handler.rb +7 -5
  167. data/lib/avo/concerns/has_controls.rb +37 -0
  168. data/lib/avo/concerns/has_description.rb +23 -0
  169. data/lib/avo/concerns/has_helpers.rb +18 -0
  170. data/lib/avo/concerns/has_item_type.rb +42 -0
  171. data/lib/avo/concerns/has_items.rb +339 -0
  172. data/lib/avo/concerns/hydration.rb +17 -0
  173. data/lib/avo/concerns/is_resource_item.rb +16 -36
  174. data/lib/avo/concerns/is_visible.rb +15 -0
  175. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  176. data/lib/avo/concerns/pagination.rb +53 -0
  177. data/lib/avo/concerns/visible_in_different_views.rb +132 -0
  178. data/lib/avo/concerns/visible_items.rb +7 -38
  179. data/lib/avo/configuration/branding.rb +0 -12
  180. data/lib/avo/configuration.rb +28 -11
  181. data/lib/avo/current.rb +39 -0
  182. data/lib/avo/dsl/field_parser.rb +3 -3
  183. data/lib/avo/dynamic_router.rb +18 -3
  184. data/lib/avo/engine.rb +35 -30
  185. data/lib/avo/error_manager.rb +25 -0
  186. data/lib/avo/execution_context.rb +14 -15
  187. data/lib/avo/fields/base_field.rb +84 -115
  188. data/lib/avo/fields/belongs_to_field.rb +19 -23
  189. data/lib/avo/fields/concerns/file_authorization.rb +2 -2
  190. data/lib/avo/fields/concerns/handles_field_args.rb +49 -0
  191. data/lib/avo/fields/concerns/has_default.rb +1 -5
  192. data/lib/avo/fields/concerns/has_field_name.rb +22 -0
  193. data/lib/avo/fields/concerns/has_html_attributes.rb +112 -0
  194. data/lib/avo/fields/concerns/is_disabled.rb +1 -5
  195. data/lib/avo/fields/concerns/is_readonly.rb +1 -5
  196. data/lib/avo/fields/concerns/is_required.rb +5 -7
  197. data/lib/avo/fields/concerns/is_searchable.rb +15 -0
  198. data/lib/avo/fields/concerns/use_resource.rb +5 -1
  199. data/lib/avo/fields/concerns/use_view_components.rb +45 -0
  200. data/lib/avo/fields/country_field.rb +4 -0
  201. data/lib/avo/fields/date_time_field.rb +1 -5
  202. data/lib/avo/fields/external_image_field.rb +2 -2
  203. data/lib/avo/fields/field_manager.rb +55 -0
  204. data/lib/avo/fields/file_field.rb +2 -2
  205. data/lib/avo/fields/gravatar_field.rb +2 -2
  206. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -2
  207. data/lib/avo/fields/has_base_field.rb +21 -17
  208. data/lib/avo/fields/has_many_field.rb +5 -2
  209. data/lib/avo/fields/has_one_field.rb +8 -12
  210. data/lib/avo/fields/heading_field.rb +9 -14
  211. data/lib/avo/fields/hidden_field.rb +1 -1
  212. data/lib/avo/fields/id_field.rb +3 -3
  213. data/lib/avo/fields/location_field.rb +10 -10
  214. data/lib/avo/fields/password_field.rb +1 -1
  215. data/lib/avo/fields/preview_field.rb +14 -0
  216. data/lib/avo/fields/select_field.rb +12 -8
  217. data/lib/avo/fields/status_field.rb +7 -1
  218. data/lib/avo/fields/text_field.rb +2 -2
  219. data/lib/avo/filters/base_filter.rb +9 -4
  220. data/lib/avo/html/builder.rb +8 -8
  221. data/lib/avo/item_grapher.rb +78 -0
  222. data/lib/avo/licensing/h_q.rb +11 -73
  223. data/lib/avo/licensing/license.rb +5 -1
  224. data/lib/avo/licensing/license_manager.rb +1 -1
  225. data/lib/avo/licensing/pro_license.rb +1 -7
  226. data/lib/avo/loaders/fields_loader.rb +7 -1
  227. data/lib/avo/plugin.rb +36 -0
  228. data/lib/avo/plugin_manager.rb +56 -0
  229. data/lib/avo/prefixed_test_helpers.rb +20 -0
  230. data/lib/avo/reloader.rb +3 -0
  231. data/lib/avo/resources/controls/actions_list.rb +7 -12
  232. data/lib/avo/resources/controls/attach_button.rb +15 -0
  233. data/lib/avo/resources/controls/back_button.rb +1 -1
  234. data/lib/avo/resources/controls/base_control.rb +15 -49
  235. data/lib/avo/resources/controls/create_button.rb +15 -0
  236. data/lib/avo/resources/controls/delete_button.rb +5 -1
  237. data/lib/avo/resources/controls/detach_button.rb +4 -1
  238. data/lib/avo/resources/controls/edit_button.rb +4 -1
  239. data/lib/avo/resources/controls/order_controls.rb +8 -0
  240. data/lib/avo/resources/controls/save_button.rb +13 -0
  241. data/lib/avo/resources/controls/show_button.rb +15 -0
  242. data/lib/avo/resources/items/holder.rb +96 -0
  243. data/lib/avo/resources/items/item_group.rb +44 -0
  244. data/lib/avo/resources/items/main_panel.rb +12 -0
  245. data/lib/avo/resources/items/panel.rb +2 -0
  246. data/lib/avo/resources/items/row.rb +42 -0
  247. data/lib/avo/resources/items/sidebar.rb +46 -0
  248. data/lib/avo/resources/items/tab.rb +54 -0
  249. data/lib/avo/resources/items/tab_group.rb +62 -0
  250. data/lib/avo/resources/resource_manager.rb +179 -0
  251. data/lib/avo/services/authorization_service.rb +11 -110
  252. data/lib/avo/services/debug_service.rb +93 -0
  253. data/lib/avo/services/encryption_service.rb +8 -12
  254. data/lib/avo/services/telemetry_service.rb +85 -0
  255. data/lib/avo/test_helpers.rb +362 -0
  256. data/lib/avo/tools/tool_manager.rb +30 -0
  257. data/lib/avo/version.rb +1 -1
  258. data/lib/avo/view_inquirer.rb +36 -0
  259. data/lib/avo.rb +109 -24
  260. data/lib/generators/avo/action_generator.rb +8 -8
  261. data/lib/generators/avo/card_generator.rb +27 -0
  262. data/lib/generators/avo/concerns/parent_controller.rb +20 -0
  263. data/lib/generators/avo/controller_generator.rb +3 -0
  264. data/lib/generators/avo/eject_generator.rb +180 -15
  265. data/lib/generators/avo/field_generator.rb +49 -2
  266. data/lib/generators/avo/filter_generator.rb +8 -8
  267. data/lib/generators/avo/js/install_generator.rb +2 -2
  268. data/lib/generators/avo/resource_generator.rb +12 -9
  269. data/lib/generators/avo/scope_generator.rb +15 -0
  270. data/lib/generators/avo/tailwindcss/install_generator.rb +70 -26
  271. data/lib/generators/avo/templates/action.tt +8 -6
  272. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  273. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  274. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  275. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  276. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  277. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  278. data/lib/generators/avo/templates/dashboards/dashboard.tt +5 -3
  279. data/lib/generators/avo/templates/field/%singular_name%_field.rb.tt +1 -1
  280. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  281. data/lib/generators/avo/templates/filters/multiple_select_filter.tt +1 -1
  282. data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
  283. data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
  284. data/lib/generators/avo/templates/initializer/avo.tt +7 -3
  285. data/lib/generators/avo/templates/locales/avo.ar.yml +7 -6
  286. data/lib/generators/avo/templates/locales/avo.en.yml +6 -3
  287. data/lib/generators/avo/templates/locales/avo.es.yml +127 -0
  288. data/lib/generators/avo/templates/locales/avo.fr.yml +3 -0
  289. data/lib/generators/avo/templates/locales/avo.nb.yml +3 -0
  290. data/lib/generators/avo/templates/locales/avo.nn.yml +3 -0
  291. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +3 -0
  292. data/lib/generators/avo/templates/locales/avo.pt.yml +3 -0
  293. data/lib/generators/avo/templates/locales/avo.ro.yml +8 -5
  294. data/lib/generators/avo/templates/locales/avo.tr.yml +3 -0
  295. data/lib/generators/avo/templates/resource/controller.tt +1 -1
  296. data/lib/generators/avo/templates/resource/resource.tt +7 -7
  297. data/lib/generators/avo/templates/resource_tools/partial.tt +2 -2
  298. data/lib/generators/avo/templates/resource_tools/resource_tool.tt +1 -1
  299. data/lib/generators/avo/templates/scope.tt +6 -0
  300. data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
  301. data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +5 -3
  302. data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +11 -0
  303. data/lib/tasks/avo_tasks.rake +72 -4
  304. data/public/avo-assets/avo.base.css +1893 -1187
  305. data/public/avo-assets/avo.base.js +223 -311
  306. data/public/avo-assets/avo.base.js.map +3 -3
  307. data/public/avo-assets/avo.css +9744 -0
  308. data/public/avo-assets/avo.js +513 -0
  309. data/public/avo-assets/avo.js.map +7 -0
  310. data/tailwind.custom.js +47 -0
  311. data/tailwind.preset.js +152 -0
  312. metadata +121 -116
  313. data/app/components/avo/card_component.html.erb +0 -46
  314. data/app/components/avo/card_component.rb +0 -25
  315. data/app/components/avo/dashboards/divider_component.html.erb +0 -9
  316. data/app/components/avo/dashboards/divider_component.rb +0 -19
  317. data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +0 -47
  318. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +0 -95
  319. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -35
  320. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  321. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -10
  322. data/app/components/avo/fields/tags_field/index_component.rb +0 -9
  323. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  324. data/app/components/avo/fields/tags_field/show_component.rb +0 -5
  325. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  326. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  327. data/app/components/avo/index/ordering/base_component.rb +0 -9
  328. data/app/components/avo/index/ordering/button_component.html.erb +0 -11
  329. data/app/components/avo/index/ordering/button_component.rb +0 -23
  330. data/app/components/avo/index/ordering/buttons_component.html.erb +0 -32
  331. data/app/components/avo/index/ordering/buttons_component.rb +0 -47
  332. data/app/components/avo/item_switcher_component.html.erb +0 -27
  333. data/app/components/avo/item_switcher_component.rb +0 -48
  334. data/app/components/avo/sidebar/item_switcher_component.html.erb +0 -16
  335. data/app/components/avo/sidebar/item_switcher_component.rb +0 -15
  336. data/app/controllers/avo/dashboards/cards_controller.rb +0 -37
  337. data/app/controllers/avo/dashboards_controller.rb +0 -22
  338. data/app/controllers/avo/reorder_controller.rb +0 -25
  339. data/app/controllers/avo/team_users_controller.rb +0 -4
  340. data/app/javascript/js/controllers/base_controller.js +0 -22
  341. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -127
  342. data/app/javascript/js/controllers/toggle_panel_controller.js +0 -18
  343. data/app/views/avo/dashboards/cards/_chartkick_card.html.erb +0 -3
  344. data/app/views/avo/dashboards/cards/_metric_card.html.erb +0 -5
  345. data/app/views/avo/dashboards/cards/chartkick_missing.html.erb +0 -14
  346. data/app/views/avo/dashboards/cards/show.html.erb +0 -3
  347. data/app/views/avo/dashboards/show.html.erb +0 -38
  348. data/app/views/avo/partials/_global_search.html.erb +0 -19
  349. data/app/views/avo/sidebar/_license_warnings.html.erb +0 -6
  350. data/lib/avo/action_model.rb +0 -20
  351. data/lib/avo/app.rb +0 -237
  352. data/lib/avo/base_card.rb +0 -161
  353. data/lib/avo/concerns/fetches_things.rb +0 -150
  354. data/lib/avo/concerns/handles_field_args.rb +0 -47
  355. data/lib/avo/concerns/has_editable_controls.rb +0 -34
  356. data/lib/avo/concerns/has_fields.rb +0 -334
  357. data/lib/avo/concerns/has_html_attributes.rb +0 -108
  358. data/lib/avo/concerns/policy_helpers.rb +0 -31
  359. data/lib/avo/concerns/visible_in_dashboard.rb +0 -31
  360. data/lib/avo/dashboards/base_dashboard.rb +0 -89
  361. data/lib/avo/dashboards/base_divider.rb +0 -35
  362. data/lib/avo/dashboards/chartkick_card.rb +0 -77
  363. data/lib/avo/dashboards/dashboard_card.rb +0 -6
  364. data/lib/avo/dashboards/metric_card.rb +0 -9
  365. data/lib/avo/dashboards/partial_card.rb +0 -7
  366. data/lib/avo/fields/field_extensions/has_field_name.rb +0 -19
  367. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +0 -111
  368. data/lib/avo/fields/tags_field.rb +0 -102
  369. data/lib/avo/grid_collector.rb +0 -42
  370. data/lib/avo/hosts/association_scope_host.rb +0 -8
  371. data/lib/avo/hosts/base_host.rb +0 -25
  372. data/lib/avo/hosts/card_visibility.rb +0 -20
  373. data/lib/avo/hosts/dashboard_card.rb +0 -22
  374. data/lib/avo/hosts/dashboard_visibility.rb +0 -19
  375. data/lib/avo/hosts/ordering.rb +0 -22
  376. data/lib/avo/hosts/record_host.rb +0 -7
  377. data/lib/avo/hosts/resource_record_host.rb +0 -7
  378. data/lib/avo/hosts/resource_view_record_host.rb +0 -7
  379. data/lib/avo/hosts/search_scope_host.rb +0 -7
  380. data/lib/avo/hosts/view_record_host.rb +0 -7
  381. data/lib/avo/hosts/visibility_host.rb +0 -12
  382. data/lib/avo/items_holder.rb +0 -96
  383. data/lib/avo/main_panel.rb +0 -3
  384. data/lib/avo/menu/base_item.rb +0 -25
  385. data/lib/avo/menu/builder.rb +0 -82
  386. data/lib/avo/menu/dashboard.rb +0 -22
  387. data/lib/avo/menu/group.rb +0 -2
  388. data/lib/avo/menu/link.rb +0 -6
  389. data/lib/avo/menu/menu.rb +0 -2
  390. data/lib/avo/menu/resource.rb +0 -22
  391. data/lib/avo/menu/section.rb +0 -2
  392. data/lib/avo/panel.rb +0 -24
  393. data/lib/avo/panel_builder.rb +0 -25
  394. data/lib/avo/resources/controls/action.rb +0 -38
  395. data/lib/avo/resources/controls/execution_context.rb +0 -58
  396. data/lib/avo/resources/controls/items_holder.rb +0 -19
  397. data/lib/avo/resources/controls/link_to.rb +0 -27
  398. data/lib/avo/row.rb +0 -26
  399. data/lib/avo/row_builder.rb +0 -24
  400. data/lib/avo/services/authorization_clients/nil_client.rb +0 -37
  401. data/lib/avo/services/authorization_clients/pundit_client.rb +0 -51
  402. data/lib/avo/sidebar.rb +0 -30
  403. data/lib/avo/sidebar_builder.rb +0 -24
  404. data/lib/avo/tab.rb +0 -72
  405. data/lib/avo/tab_builder.rb +0 -25
  406. data/lib/avo/tab_group.rb +0 -42
  407. data/lib/avo/tab_group_builder.rb +0 -43
  408. data/lib/avo/tools_manager.rb +0 -11
  409. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  410. data/lib/generators/avo/card/metric_generator.rb +0 -18
  411. data/lib/generators/avo/card/partial_generator.rb +0 -19
  412. data/lib/generators/avo/templates/js/avo.custom.js +0 -2
  413. data/lib/generators/avo/templates/standalone_action.tt +0 -8
  414. /data/app/assets/stylesheets/css/{tags.css → fields/tags.css} +0 -0
data/lib/avo.rb CHANGED
@@ -11,37 +11,16 @@ loader.inflector.inflect(
11
11
  loader.ignore("#{__dir__}/generators")
12
12
  loader.setup
13
13
 
14
- # .//*,,.....,,*/(*
15
- # **,,..............,*#.
16
- # ,*,,..... .....*/#.
17
- # **,,.... ....,*/%%
18
- # ,**,,....... . ....*/#&%
19
- # **,,,...... . . ....*/#&&%
20
- # **,,........ . . ...,//#&&&.
21
- # */*,,..*//***,,,,*/(,.. .. .....*//%&%&*
22
- # ,/**,..**/******,,***/(###,...........,//(%&&%.
23
- # /**,,..((//*****////((##%%%%%*.........*//%%&&%
24
- # ****,...#/**,,,*,*/(#%##%%%%&&&(*,.....,*/(%&&&/
25
- # /**,....(/*,,,,,,,*(##%%%%%&&&&&(,.....,*(#&&&&.
26
- # ,//*,.....(/*,,**//(##%%%%&&&&@&&%/,....,*((&&&&*
27
- # .//*,,.....(((//(((##%%%&&&&&&&&@#/,....,*/#%&&&#
28
- # (/**,,......###%%%%%&&&&&&&&&&@#/,,...,,*/#&&&&&
29
- # (/**,,........%%%%%&&&&&&&&@%(*,...,,,*//(&&&&%.
30
- # ///*,,,.........,*#&&&&#(/,,.....,,,*//(%&&&&%*
31
- # (//**,,,.....................,,,,*//(%&&&&&&*
32
- # *(///**,,,,............,,,,,,**/((&&&&&&&%.
33
- # ((///*****,,,,,,,,,,,,***//((&&&&&%&%&#
34
- # .((((////********///(((%&%&&&&%%%%%
35
- # (############%%%%%%%%%%%%%%%*
36
- # ,(############%%%%%#*
37
-
38
14
  module Avo
15
+ extend ActiveSupport::LazyLoadHooks
16
+
39
17
  ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
40
18
  IN_DEVELOPMENT = ENV["AVO_IN_DEVELOPMENT"] == "1"
41
19
  PACKED = !IN_DEVELOPMENT
42
20
  COOKIES_KEY = "avo"
43
21
  ENTITIES = {
44
22
  cards: ["app", "avo", "cards"],
23
+ scopes: ["app", "avo", "scopes"],
45
24
  fields: ["app", "avo", "fields"],
46
25
  filters: ["app", "avo", "filters"],
47
26
  actions: ["app", "avo", "actions"],
@@ -59,6 +38,112 @@ module Avo
59
38
  class NoPolicyError < StandardError; end
60
39
 
61
40
  class MissingGemError < StandardError; end
41
+
42
+ class DeprecatedAPIError < StandardError; end
43
+
44
+ class << self
45
+ attr_reader :logger
46
+ attr_reader :cache_store
47
+ attr_reader :field_manager
48
+
49
+ delegate :license, :app, :error_manager, :tool_manager, :resource_manager, to: Avo::Current
50
+
51
+ def boot
52
+ boot_logger
53
+ boot_fields
54
+ @cache_store = Avo.configuration.cache_store
55
+ plugin_manager.boot_plugins
56
+ Avo.run_load_hooks(:boot, self)
57
+ end
58
+
59
+ def init
60
+ Avo::Current.error_manager = Avo::ErrorManager.build
61
+ Avo::Current.resource_manager = Avo::Resources::ResourceManager.build
62
+ Avo::Current.tool_manager = Avo::Tools::ToolManager.build
63
+
64
+ Avo.run_load_hooks(:init, self)
65
+ end
66
+
67
+ # Generate a dynamic root path using the URIService
68
+ def root_path(paths: [], query: {}, **args)
69
+ Avo::Services::URIService.parse(Avo::Current.view_context.avo.root_url.to_s)
70
+ .append_paths(paths)
71
+ .append_query(query)
72
+ .to_s
73
+ end
74
+
75
+ def mount_path
76
+ Avo::Engine.routes.find_script_name({})
77
+ end
78
+
79
+ def main_menu
80
+ return unless Avo.plugin_manager.installed?("avo-menu")
81
+
82
+ # Return empty menu if the app doesn't have the profile menu configured
83
+ return Avo::Menu::Builder.new.build unless has_main_menu?
84
+
85
+ Avo::Menu::Builder.parse_menu(&Avo.configuration.main_menu)
86
+ end
87
+
88
+ def profile_menu
89
+ return unless Avo.plugin_manager.installed?("avo-menu")
90
+
91
+ # Return empty menu if the app doesn't have the profile menu configured
92
+ return Avo::Menu::Builder.new.build unless has_profile_menu?
93
+
94
+ Avo::Menu::Builder.parse_menu(&Avo.configuration.profile_menu)
95
+ end
96
+
97
+ def app_status
98
+ license.valid?
99
+ end
100
+
101
+ def avo_dynamic_filters_installed?
102
+ defined?(Avo::DynamicFilters).present?
103
+ end
104
+
105
+ def has_main_menu?
106
+ return false if Avo.license.lacks_with_trial(:menu_editor)
107
+ return false if Avo.configuration.main_menu.nil?
108
+
109
+ true
110
+ end
111
+
112
+ def has_profile_menu?
113
+ return false if Avo.license.lacks_with_trial(:menu_editor)
114
+ return false if Avo.configuration.profile_menu.nil?
115
+
116
+ true
117
+ end
118
+
119
+ # Mount all Avo engines
120
+ def mount_engines
121
+ -> {
122
+ mount Avo::DynamicFilters::Engine, at: "/avo-dynamic_filters" if defined?(Avo::DynamicFilters::Engine)
123
+ mount Avo::Dashboards::Engine, at: "/dashboards" if defined?(Avo::Dashboards::Engine)
124
+ mount Avo::Pro::Engine, at: "/avo-pro" if defined?(Avo::Pro::Engine)
125
+ }
126
+ end
127
+
128
+ private
129
+
130
+ def boot_logger
131
+ file_logger = ActiveSupport::Logger.new(Rails.root.join("log", "avo.log"))
132
+
133
+ file_logger.datetime_format = "%Y-%m-%d %H:%M:%S"
134
+ file_logger.formatter = proc do |severity, time, progname, msg|
135
+ "[Avo] #{time}: #{msg}\n".tap do |i|
136
+ puts i
137
+ end
138
+ end
139
+
140
+ @logger = file_logger
141
+ end
142
+
143
+ def boot_fields
144
+ @field_manager = Avo::Fields::FieldManager.build
145
+ end
146
+ end
62
147
  end
63
148
 
64
149
  loader.eager_load
@@ -5,20 +5,20 @@ module Generators
5
5
  class ActionGenerator < NamedBaseGenerator
6
6
  source_root File.expand_path("templates", __dir__)
7
7
 
8
- class_option :standalone, type: :boolean
8
+ class_option :standalone, type: :boolean, default: false
9
+ class_option :name, type: :string
9
10
 
10
11
  namespace "avo:action"
11
12
 
12
13
  def create_resource_file
13
- type = "resource"
14
+ template "action.tt", "app/avo/actions/#{singular_name}.rb"
15
+ end
14
16
 
15
- type = "standalone" if options[:standalone]
17
+ def configuration_options
18
+ configuration = " self.name = \"#{options[:name] || name.titleize}\""
19
+ configuration += "\n self.standalone = true" if options[:standalone]
16
20
 
17
- if type == "standalone"
18
- template "standalone_action.tt", "app/avo/actions/#{singular_name}.rb"
19
- else
20
- template "action.tt", "app/avo/actions/#{singular_name}.rb"
21
- end
21
+ configuration
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,27 @@
1
+ require_relative "named_base_generator"
2
+
3
+ module Generators
4
+ module Avo
5
+ class Card < NamedBaseGenerator
6
+ namespace "avo:card"
7
+ source_root File.expand_path("templates", __dir__)
8
+ class_option :type, type: :string
9
+
10
+ def handle
11
+ raise "Invalid card type '#{options[:type]}'" unless card_types.include? options[:type]
12
+
13
+ template "cards/#{options[:type]}_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
14
+
15
+ if options[:type].to_sym == :partial
16
+ template "cards/partial_card_partial.tt", "app/views/avo/cards/_#{name.underscore}.html.erb"
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def card_types
23
+ %w[metric chartkick partial]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Generators
2
+ module Avo
3
+ module Concerns
4
+ module ParentController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_option "parent-controller",
9
+ desc: "The name of the parent controller.",
10
+ type: :string,
11
+ required: false
12
+ end
13
+
14
+ def parent_controller
15
+ options["parent-controller"] || ::Avo.configuration.resource_parent_controller
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,8 +1,11 @@
1
1
  require_relative "named_base_generator"
2
+ require_relative "concerns/parent_controller"
2
3
 
3
4
  module Generators
4
5
  module Avo
5
6
  class ControllerGenerator < NamedBaseGenerator
7
+ include Generators::Avo::Concerns::ParentController
8
+
6
9
  source_root File.expand_path("templates", __dir__)
7
10
 
8
11
  namespace "avo:controller"
@@ -3,7 +3,30 @@ require_relative "base_generator"
3
3
  module Generators
4
4
  module Avo
5
5
  class EjectGenerator < BaseGenerator
6
- argument :filename, type: :string, required: true
6
+ class_option :partial,
7
+ desc: "The partial to eject. Example: ':logo', 'app/views/layouts/avo/application.html.erb'",
8
+ type: :string,
9
+ required: false
10
+
11
+ class_option :component,
12
+ desc: "The component to eject. Example: 'Avo::Index::TableRowComponent', 'avo/index/table_row_component'",
13
+ type: :string,
14
+ required: false
15
+
16
+ class_option :scope,
17
+ desc: "The scope of the component. Example: 'users', 'admins'",
18
+ type: :string,
19
+ required: false
20
+
21
+ class_option "field-components",
22
+ desc: "The field components to eject. Example: 'trix', 'text'",
23
+ type: :string,
24
+ required: false
25
+
26
+ class_option :view,
27
+ desc: "The view of the component to eject when using --field-component option. Example: 'index', 'show'",
28
+ type: :string,
29
+ required: false
7
30
 
8
31
  source_root ::Avo::Engine.root
9
32
 
@@ -21,19 +44,23 @@ module Generators
21
44
  }
22
45
 
23
46
  def handle
24
- if @filename.starts_with?(":")
25
- template_id = path_to_sym @filename
26
- template_path = TEMPLATES[template_id]
27
-
28
- if path_exists? template_path
29
- eject template_path
30
- else
31
- say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
32
- end
33
- elsif path_exists? @filename
34
- eject @filename
47
+ if options[:partial].present?
48
+ eject_partial
49
+ elsif options[:component].present?
50
+ eject_component
51
+ elsif options["field-components"].present?
52
+ eject_field_components
35
53
  else
36
- say("Failed to find the `#{@filename}` template.", :yellow)
54
+ say "Please specify a partial or a component to eject.\n" \
55
+ "Examples: rails g avo:eject --partial :logo\n" \
56
+ " rails g avo:eject --partial app/views/layouts/avo/application.html.erb\n" \
57
+ " rails g avo:eject --component Avo::Index::TableRowComponent\n" \
58
+ " rails g avo:eject --component avo/index/table_row_component\n" \
59
+ " rails g avo:eject --field-components trix\n" \
60
+ " rails g avo:eject --field-components trix --scope users\n" \
61
+ " rails g avo:eject --field-components text --scope users --view edit\n" \
62
+ " rails g avo:eject --component Avo::Views::ResourceIndexComponent --scope users\n" \
63
+ " rails g avo:eject --component avo/views/resource_index_component --scope users", :yellow
37
64
  end
38
65
  end
39
66
 
@@ -48,8 +75,146 @@ module Generators
48
75
  path.present? && File.file?(::Avo::Engine.root.join(path))
49
76
  end
50
77
 
51
- def eject(path)
52
- copy_file ::Avo::Engine.root.join(path), ::Rails.root.join(path)
78
+ def dir_exists?(path)
79
+ path.present? && Dir.exist?(::Avo::Engine.root.join(path))
80
+ end
81
+
82
+ def eject(path, dest_path = nil, is_directory: false)
83
+ method = is_directory ? :directory : :copy_file
84
+
85
+ send method, ::Avo::Engine.root.join(path), ::Rails.root.join(dest_path || path)
86
+ end
87
+
88
+ def eject_partial
89
+ if options[:partial].starts_with?(":")
90
+ template_id = path_to_sym options[:partial]
91
+ template_path = TEMPLATES[template_id]
92
+
93
+ if path_exists? template_path
94
+ return unless confirm_ejection_on template_path
95
+ eject template_path
96
+ else
97
+ say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
98
+ end
99
+ elsif path_exists? options[:partial]
100
+ return unless confirm_ejection_on template_path
101
+ eject options[:partial]
102
+ else
103
+ say("Failed to find the `#{options[:partial]}` template.", :yellow)
104
+ end
105
+ end
106
+
107
+ def eject_component(component_to_eject = options[:component], confirmation: true)
108
+ # Underscore the component name
109
+ # Example: Avo::Views::ResourceIndexComponent => avo/views/resource_index_component
110
+ component = component_to_eject.underscore
111
+
112
+ # Get the component path for both, the rb and erb files
113
+ rb, erb = ["app/components/#{component}.rb", "app/components/#{component}.html.erb"]
114
+
115
+ # Return if one of the components doesn't exist
116
+ if !path_exists?(rb) || !path_exists?(erb)
117
+ return say("Failed to find the `#{component_to_eject}` component.", :yellow)
118
+ end
119
+
120
+ # Add the scope to the component if it's possible
121
+ if add_scope? component
122
+ component = if component.starts_with?("avo/views/")
123
+ component.gsub("avo/views/", "avo/views/#{options[:scope].underscore}/")
124
+ elsif component.starts_with?("avo/fields/")
125
+ component.gsub("avo/fields/", "avo/fields/#{options[:scope].underscore}/")
126
+ end
127
+ added_scope = true
128
+ end
129
+
130
+ # Confirm the ejection
131
+ if confirmation
132
+ return if !confirm_ejection_on(component.camelize)
133
+ end
134
+
135
+ # Get the destination path for both, the rb and erb files
136
+ dest_rb = "#{::Avo.configuration.view_component_path}/#{component}.rb"
137
+ dest_erb = "#{::Avo.configuration.view_component_path}/#{component}.html.erb"
138
+
139
+ # Eject the component
140
+ eject rb, dest_rb
141
+ eject erb, dest_erb
142
+
143
+ # Remame the component class if scope was added
144
+ # Example: Avo::Views::ResourceIndexComponent => Avo::Views::Admins::ResourceIndexComponent
145
+ if added_scope
146
+ [dest_rb, dest_erb].each do |path|
147
+ if component.starts_with?("avo/views/")
148
+ modified_content = File.read(path).gsub("Avo::Views::", "Avo::Views::#{options[:scope].camelize}::")
149
+ elsif component.starts_with?("avo/fields/")
150
+ modified_content = File.read(path).gsub("#{options["field-components"].camelize}Field", "#{options[:scope].camelize}::#{options["field-components"].camelize}Field")
151
+ end
152
+
153
+ File.open(path, "w") do |file|
154
+ file.puts modified_content
155
+ end
156
+ end
157
+
158
+ if component.starts_with?("avo/views/")
159
+ say "You can now use this component on any resource by configuring the 'self.components' option.\n" \
160
+ " self.components = {\n" \
161
+ " #{component.split("/").last}: #{component.camelize}\n" \
162
+ " }", :green
163
+ elsif component.starts_with?("avo/fields/")
164
+ say "You can now use this component on any field by configuring the 'components' option.\n" \
165
+ " field :name, as: :#{options["field-components"]}, components: {\n" \
166
+ " #{component.split("/").last}: #{component.camelize}\n" \
167
+ " }", :green
168
+ end
169
+ end
170
+ end
171
+
172
+ def eject_field_components
173
+ # Check if the field exists
174
+ field_path = "lib/avo/fields/#{options["field-components"]}_field.rb"
175
+ return say("Failed to find the `#{options["field-components"]}` field.", :yellow) if !path_exists?(field_path)
176
+
177
+ # Eject single component if view is specified
178
+ if options[:view].present?
179
+ return eject_component "Avo::Fields::#{options["field-components"].camelize}Field::#{options[:view].camelize}Component"
180
+ end
181
+
182
+ # Check if the field components directory exist
183
+ components_path = "app/components/avo/fields/#{options["field-components"]}_field"
184
+ return say("Failed to find the `#{options["field-components"]}` field components.", :yellow) if !dir_exists?(components_path)
185
+
186
+ # Build the destination path for the components directory add the scope
187
+ destination_components_path = "#{::Avo.configuration.view_component_path}/#{components_path.gsub("app/components/", "")}"
188
+
189
+ if options[:scope].present?
190
+ destination_components_path = destination_components_path.gsub("avo/fields/", "avo/fields/#{options[:scope].underscore}/")
191
+ end
192
+
193
+ # Confirm the ejection
194
+ confirm_ejection_on destination_components_path, is_directory: true
195
+
196
+ # Eject the components directory
197
+ eject components_path, destination_components_path, is_directory: true
198
+
199
+ # Rename the component classes if scope was added
200
+ if options[:scope].present?
201
+ Dir.glob("#{destination_components_path}/*").each do |file|
202
+ modified_content = File.read(file).gsub("#{options["field-components"].camelize}Field", "#{options[:scope].camelize}::#{options["field-components"].camelize}Field")
203
+
204
+ File.open(file, "w") do |open_file|
205
+ open_file.puts modified_content
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ def confirm_ejection_on(path, is_directory: false)
212
+ say("By ejecting the '#{path}'#{" directory" if is_directory} \033[1myou'll take on the responsibility for maintain it.", :yellow)
213
+ yes?("Are you sure you want to eject the '#{path}'#{" directory" if is_directory}? [y/N]", :yellow)
214
+ end
215
+
216
+ def add_scope?(component)
217
+ (component.starts_with?("avo/views/") || component.starts_with?("avo/fields/")) && options[:scope].present?
53
218
  end
54
219
  end
55
220
  end
@@ -8,9 +8,56 @@ module Generators
8
8
  namespace "avo:field"
9
9
  desc "Add a custom Avo field to your project."
10
10
 
11
+ class_option "field-template", type: :string, required: false
12
+
11
13
  def handle
12
- directory "field/components", "#{::Avo.configuration.view_component_path}/avo/fields/#{singular_name}_field"
13
- template "field/%singular_name%_field.rb.tt", "app/avo/fields/#{singular_name}_field.rb"
14
+ return field_from_template if field_template.present?
15
+
16
+ directory "field/components", destination_components_path
17
+ template "field/%singular_name%_field.rb.tt", destination_field_path
18
+ end
19
+
20
+ no_tasks do
21
+ def field_from_template
22
+ if !File.file? ::Avo::Engine.root.join(template_field_path)
23
+ return say("Failed to find the `#{field_template}` template field.", :yellow)
24
+ end
25
+
26
+ if !Dir.exist? ::Avo::Engine.root.join(template_components_path)
27
+ return say("Failed to find the `#{field_template}` template field components.", :yellow)
28
+ end
29
+
30
+ directory ::Avo::Engine.root.join(template_components_path), destination_components_path
31
+ copy_file ::Avo::Engine.root.join(template_field_path), destination_field_path
32
+
33
+ Dir.glob("#{destination_components_path}/*").push(destination_field_path).each do |file|
34
+ modified_content = File.read(file).gsub("#{field_template.camelize}Field", "#{singular_name.camelize}Field")
35
+
36
+ File.open(file, "w") do |open_file|
37
+ open_file.puts modified_content
38
+ end
39
+ end
40
+ end
41
+
42
+ def field_template
43
+ options["field-template"]
44
+ end
45
+
46
+ def template_field_path
47
+ "lib/avo/fields/#{field_template}_field.rb"
48
+ end
49
+
50
+ def template_components_path
51
+ "app/components/avo/fields/#{field_template}_field"
52
+ end
53
+
54
+ def destination_components_path
55
+ "#{::Avo.configuration.view_component_path}/avo/fields/#{singular_name}_field"
56
+ end
57
+
58
+ def destination_field_path
59
+ "app/avo/fields/#{singular_name}_field.rb"
60
+ end
14
61
  end
15
62
  end
16
63
  end
@@ -5,20 +5,20 @@ module Generators
5
5
  class FilterGenerator < NamedBaseGenerator
6
6
  source_root File.expand_path("templates", __dir__)
7
7
 
8
- class_option :multiple_select, type: :boolean
9
- class_option :select, type: :boolean
10
- class_option :text, type: :boolean
8
+ class_option :type, type: :string, default: "boolean"
11
9
 
12
10
  namespace "avo:filter"
13
11
 
14
12
  def create_resource_file
15
- type = "boolean"
13
+ raise "Invalid filter type '#{options[:type]}'" unless filter_types.include? options[:type]
16
14
 
17
- type = "multiple_select" if options[:multiple_select]
18
- type = "select" if options[:select]
19
- type = "text" if options[:text]
15
+ template "filters/#{options[:type]}_filter.tt", "app/avo/filters/#{singular_name}.rb"
16
+ end
17
+
18
+ private
20
19
 
21
- template "filters/#{type}_filter.tt", "app/avo/filters/#{singular_name}.rb"
20
+ def filter_types
21
+ %w[boolean select text multiple_select]
22
22
  end
23
23
  end
24
24
  end
@@ -31,7 +31,7 @@ module Generators
31
31
  end
32
32
 
33
33
  say "Ejecting the _head.html.erb partial"
34
- Rails::Generators.invoke("avo:eject", [":head", "--skip-avo-version"], {destination_root: Rails.root})
34
+ Rails::Generators.invoke("avo:eject", ["--partial", ":head", "--skip-avo-version"], {destination_root: Rails.root})
35
35
 
36
36
  say "Adding the JS asset to the partial"
37
37
  append_to_file Rails.root.join("app", "views", "avo", "partials", "_head.html.erb"), "<%= javascript_importmap_tags \"avo.custom\" %>"
@@ -48,7 +48,7 @@ module Generators
48
48
  end
49
49
 
50
50
  say "Ejecting the _head.html.erb partial"
51
- Rails::Generators.invoke("avo:eject", [":head", "--skip-avo-version"], {destination_root: Rails.root})
51
+ Rails::Generators.invoke("avo:eject", ["--partial", ":head", "--skip-avo-version"], {destination_root: Rails.root})
52
52
 
53
53
  say "Adding the JS asset to the partial"
54
54
  append_to_file Rails.root.join("app", "views", "avo", "partials", "_head.html.erb"), "<%= javascript_include_tag \"avo.custom\", \"data-turbo-track\": \"reload\", defer: true %>"
@@ -1,16 +1,19 @@
1
1
  require_relative "named_base_generator"
2
+ require_relative "concerns/parent_controller"
2
3
 
3
4
  module Generators
4
5
  module Avo
5
6
  class ResourceGenerator < NamedBaseGenerator
7
+ include Generators::Avo::Concerns::ParentController
8
+
6
9
  source_root File.expand_path("templates", __dir__)
7
10
 
8
11
  namespace "avo:resource"
9
12
 
10
13
  class_option "model-class",
14
+ desc: "The name of the model.",
11
15
  type: :string,
12
- required: false,
13
- desc: "The name of the model."
16
+ required: false
14
17
 
15
18
  def create
16
19
  template "resource/resource.tt", "app/avo/resources/#{resource_name}.rb"
@@ -18,7 +21,7 @@ module Generators
18
21
  end
19
22
 
20
23
  def resource_class
21
- "#{class_name.remove(":")}Resource"
24
+ class_name.remove(":").to_s
22
25
  end
23
26
 
24
27
  def controller_class
@@ -26,7 +29,7 @@ module Generators
26
29
  end
27
30
 
28
31
  def resource_name
29
- "#{model_resource_name}_resource"
32
+ model_resource_name.to_s
30
33
  end
31
34
 
32
35
  def controller_name
@@ -132,16 +135,16 @@ module Generators
132
135
  def generated_fields_template
133
136
  return if fields.blank?
134
137
 
135
- fields_string = "\n # Fields generated from the model"
138
+ fields_string = ""
136
139
 
137
140
  fields.each do |field_name, field_options|
138
141
  # if field_options are not available (likely a missing resource for an association), skip the field
139
- fields_string += "\n # Could not generate a field for #{field_name}" and next unless field_options
140
-
142
+ fields_string += "\n # Could not generate a field for #{field_name}" and next unless field_options
143
+
141
144
  options = ""
142
145
  field_options[:options].each { |k, v| options += ", #{k}: #{v}" } if field_options[:options].present?
143
146
 
144
- fields_string += "\n #{field_string field_name, field_options[:field], options}"
147
+ fields_string += "\n #{field_string field_name, field_options[:field], options}"
145
148
  end
146
149
 
147
150
  fields_string
@@ -163,7 +166,7 @@ module Generators
163
166
 
164
167
  def fields_from_model_rich_texts
165
168
  rich_texts.each do |name, _|
166
- fields[(name.delete_prefix("rich_text_"))] = {field: "trix"}
169
+ fields[name.delete_prefix("rich_text_")] = {field: "trix"}
167
170
  end
168
171
  end
169
172
 
@@ -0,0 +1,15 @@
1
+ require_relative "named_base_generator"
2
+
3
+ module Generators
4
+ module Avo
5
+ class ScopeGenerator < NamedBaseGenerator
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ namespace "avo:scope"
9
+
10
+ def create
11
+ template "scope.tt", "app/avo/scopes/#{singular_name}.rb"
12
+ end
13
+ end
14
+ end
15
+ end