avo 3.30.4 → 4.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +18 -1
- data/Gemfile.lock +257 -174
- data/README.md +1 -1
- data/app/assets/builds/avo/application.css +13942 -0
- data/app/assets/builds/avo/application.js +1160 -0
- data/app/assets/builds/avo/application.js.map +7 -0
- data/app/assets/builds/avo/late-registration.js +2 -0
- data/app/assets/builds/avo/late-registration.js.map +7 -0
- data/app/assets/config/avo_manifest.js +2 -1
- data/app/assets/stylesheets/application.css +241 -0
- data/app/assets/stylesheets/css/button-group.css +23 -0
- data/app/assets/stylesheets/css/components/avatar.css +128 -0
- data/app/assets/stylesheets/css/components/breadcrumbs.css +43 -0
- data/app/assets/stylesheets/css/components/button.css +343 -0
- data/app/assets/stylesheets/css/components/color_scheme_switcher.css +226 -0
- data/app/assets/stylesheets/css/components/discreet_information.css +49 -0
- data/app/assets/stylesheets/css/components/field-wrapper.css +107 -0
- data/app/assets/stylesheets/css/components/grid.css +61 -0
- data/app/assets/stylesheets/css/components/input.css +312 -0
- data/app/assets/stylesheets/css/components/modal.css +228 -0
- data/app/assets/stylesheets/css/components/tooltip.css +25 -0
- data/app/assets/stylesheets/css/components/ui/badge.css +143 -0
- data/app/assets/stylesheets/css/components/ui/card.css +95 -0
- data/app/assets/stylesheets/css/components/ui/checkbox.css +50 -0
- data/app/assets/stylesheets/css/components/ui/description_list.css +3 -0
- data/app/assets/stylesheets/css/components/ui/dropdown.css +68 -0
- data/app/assets/stylesheets/css/components/ui/file_upload_input.css +94 -0
- data/app/assets/stylesheets/css/components/ui/file_upload_item.css +78 -0
- data/app/assets/stylesheets/css/components/ui/panel.css +59 -0
- data/app/assets/stylesheets/css/components/ui/panel_header.css +48 -0
- data/app/assets/stylesheets/css/components/ui/radio.css +22 -0
- data/app/assets/stylesheets/css/components/ui/tabs.css +74 -0
- data/app/assets/stylesheets/css/css-animations.css +54 -0
- data/app/assets/stylesheets/css/fields/code.css +75 -9
- data/app/assets/stylesheets/css/fields/easy-mde.css +7 -0
- data/app/assets/stylesheets/css/fields/key_value.css +97 -0
- data/app/assets/stylesheets/css/fields/progress.css +4 -4
- data/app/assets/stylesheets/css/fields/status.css +7 -1
- data/app/assets/stylesheets/css/fields/tags.css +33 -16
- data/app/assets/stylesheets/css/fields/tiptap.css +17 -15
- data/app/assets/stylesheets/css/fields/trix.css +62 -2
- data/app/assets/stylesheets/css/fonts.css +24 -24
- data/app/assets/stylesheets/css/layout.css +135 -0
- data/app/assets/stylesheets/css/pagination.css +114 -78
- data/app/assets/stylesheets/css/resource-controls.css +13 -0
- data/app/assets/stylesheets/css/search.css +22 -12
- data/app/assets/stylesheets/css/sidebar.css +310 -24
- data/app/assets/stylesheets/css/table.css +60 -0
- data/app/assets/stylesheets/css/tooltips.css +1 -1
- data/app/assets/stylesheets/css/typography.css +10 -1
- data/app/assets/stylesheets/css/variables.css +318 -0
- data/app/assets/svgs/avo/moon-plus-plus.svg +1 -0
- data/app/components/avo/actions_component.html.erb +30 -36
- data/app/components/avo/actions_component.rb +8 -11
- data/app/components/avo/alert_component.html.erb +3 -3
- data/app/components/avo/alert_component.rb +1 -1
- data/app/components/avo/asset_manager/javascript_component.html.erb +1 -2
- data/app/components/avo/backtrace_alert_component.html.erb +4 -4
- data/app/components/avo/base_component.rb +3 -4
- data/app/components/avo/breadcrumb_element_component.html.erb +17 -0
- data/app/components/avo/breadcrumb_element_component.rb +21 -0
- data/app/components/avo/breadcrumbs_component.html.erb +19 -0
- data/app/components/avo/breadcrumbs_component.rb +5 -0
- data/app/components/avo/button_component.rb +20 -126
- data/app/components/avo/clipboard_component.html.erb +3 -2
- data/app/components/avo/clipboard_component.rb +1 -1
- data/app/components/avo/component_missing_component.rb +11 -0
- data/app/components/avo/cover_component.html.erb +3 -0
- data/app/components/avo/cover_component.rb +25 -0
- data/app/components/avo/debug/status_component.html.erb +59 -0
- data/app/components/avo/debug/status_component.rb +30 -0
- data/app/components/avo/description_list_component.rb +11 -0
- data/app/components/avo/discreet_information_component.html.erb +31 -6
- data/app/components/avo/discreet_information_component.rb +23 -32
- data/app/components/avo/divider_component.html.erb +2 -2
- data/app/components/avo/empty_state_component.html.erb +2 -9
- data/app/components/avo/empty_state_component.rb +0 -8
- data/app/components/avo/field_wrapper_component.html.erb +21 -22
- data/app/components/avo/field_wrapper_component.rb +9 -18
- data/app/components/avo/fields/avatar_field/index_component.html.erb +9 -0
- data/app/components/avo/fields/avatar_field/index_component.rb +4 -0
- data/app/components/avo/fields/badge_field/index_component.html.erb +7 -1
- data/app/components/avo/fields/badge_field/show_component.html.erb +6 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +16 -14
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +13 -3
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +2 -2
- data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/boolean_group_field/edit_component.rb +2 -3
- data/app/components/avo/fields/code_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/common/boolean_check_component.rb +3 -3
- data/app/components/avo/fields/common/boolean_group_component.html.erb +2 -2
- data/app/components/avo/fields/common/files/controls_component.html.erb +30 -27
- data/app/components/avo/fields/common/files/controls_component.rb +0 -1
- data/app/components/avo/fields/common/files/list_viewer_component.html.erb +4 -5
- data/app/components/avo/fields/common/files/view_type/grid_item_component.html.erb +1 -1
- data/app/components/avo/fields/common/files/view_type/list_item_component.html.erb +7 -19
- data/app/components/avo/fields/common/heading_component.html.erb +2 -2
- data/app/components/avo/fields/common/heading_component.rb +1 -1
- data/app/components/avo/fields/common/key_value_component.html.erb +20 -24
- data/app/components/avo/fields/common/nested_field_component.html.erb +1 -1
- data/app/components/avo/fields/common/nested_field_component.rb +1 -1
- data/app/components/avo/fields/common/progress_bar_component.html.erb +2 -2
- data/app/components/avo/fields/common/stars_component.html.erb +1 -1
- data/app/components/avo/fields/common/status_viewer_component.html.erb +4 -10
- data/app/components/avo/fields/date_field/edit_component.html.erb +14 -1
- data/app/components/avo/fields/date_time_field/edit_component.html.erb +3 -3
- data/app/components/avo/fields/easy_mde_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/edit_component.rb +9 -5
- data/app/components/avo/fields/file_field/edit_component.html.erb +14 -6
- data/app/components/avo/fields/files_field/edit_component.html.erb +11 -4
- data/app/components/avo/fields/has_one_field/show_component.html.erb +10 -9
- data/app/components/avo/fields/heading_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/heading_field/show_component.html.erb +2 -2
- data/app/components/avo/fields/password_field/edit_component.html.erb +5 -7
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/radio_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/show_component.rb +4 -7
- data/app/components/avo/fields/stars_field/edit_component.html.erb +3 -4
- data/app/components/avo/fields/tags_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/tag_component.html.erb +7 -8
- data/app/components/avo/fields/time_field/edit_component.html.erb +3 -3
- data/app/components/avo/fields/tiptap_field/edit_component.html.erb +11 -11
- data/app/components/avo/fields/tiptap_field/show_component.html.erb +4 -4
- data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -2
- data/app/components/avo/filters_component.html.erb +8 -16
- data/app/components/avo/index/field_wrapper_component.html.erb +9 -2
- data/app/components/avo/index/field_wrapper_component.rb +0 -16
- data/app/components/avo/index/grid_cover_empty_state_component.html.erb +2 -2
- data/app/components/avo/index/grid_item_component.html.erb +29 -12
- data/app/components/avo/index/grid_item_component.rb +12 -10
- data/app/components/avo/index/resource_controls_component.html.erb +1 -1
- data/app/components/avo/index/resource_controls_component.rb +7 -17
- data/app/components/avo/index/resource_controls_dropdown_component.html.erb +3 -0
- data/app/components/avo/index/resource_controls_dropdown_component.rb +81 -0
- data/app/components/avo/index/table_row_component.html.erb +11 -11
- data/app/components/avo/items/panel_component.html.erb +8 -18
- data/app/components/avo/items/panel_component.rb +0 -20
- data/app/components/avo/items/switcher_component.html.erb +62 -1
- data/app/components/avo/items/switcher_component.rb +10 -5
- data/app/components/avo/items/visible_items_component.html.erb +2 -1
- data/app/components/avo/items/visible_items_component.rb +1 -0
- data/app/components/avo/media_library/item_details_component.html.erb +2 -2
- data/app/components/avo/media_library/list_component.html.erb +24 -19
- data/app/components/avo/media_library/list_component.rb +2 -2
- data/app/components/avo/media_library/list_item_component.html.erb +3 -3
- data/app/components/avo/modal_component.html.erb +52 -20
- data/app/components/avo/modal_component.rb +7 -12
- data/app/components/avo/paginator_component.html.erb +46 -33
- data/app/components/avo/paginator_component.rb +10 -5
- data/app/components/avo/panel_name_component.html.erb +1 -1
- data/app/components/avo/profile_item_component.html.erb +4 -4
- data/app/components/avo/profile_item_component.rb +2 -4
- data/app/components/avo/referrer_params_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +8 -19
- data/app/components/avo/resource_listing_component.html.erb +22 -0
- data/app/components/avo/resource_listing_component.rb +28 -0
- data/app/components/avo/resource_sidebar_component.html.erb +2 -2
- data/app/components/avo/resource_sidebar_component.rb +0 -4
- data/app/components/avo/row_component.html.erb +1 -1
- data/app/components/avo/row_selector_component.html.erb +2 -4
- data/app/components/avo/row_selector_component.rb +0 -1
- data/app/components/avo/search_overlay_component.html.erb +6 -0
- data/app/components/avo/search_overlay_component.rb +2 -0
- data/app/components/avo/sidebar/base_item_component.rb +9 -9
- data/app/components/avo/sidebar/group_component.html.erb +23 -27
- data/app/components/avo/sidebar/group_component.rb +4 -0
- data/app/components/avo/sidebar/link_component.html.erb +30 -7
- data/app/components/avo/sidebar/link_component.rb +30 -2
- data/app/components/avo/sidebar/section_component.html.erb +31 -11
- data/app/components/avo/sidebar/section_component.rb +1 -3
- data/app/components/avo/sidebar_component.html.erb +35 -36
- data/app/components/avo/sidebar_component.rb +16 -0
- data/app/components/avo/sidebar_profile_component.html.erb +27 -36
- data/app/components/avo/sidebar_profile_component.rb +14 -0
- data/app/components/avo/tab_group_component.html.erb +21 -9
- data/app/components/avo/tab_group_component.rb +54 -15
- data/app/components/avo/turbo_frame_wrapper_component.html.erb +4 -8
- data/app/components/avo/turbo_frame_wrapper_component.rb +9 -0
- data/app/components/avo/u_i/avatar_component.html.erb +11 -0
- data/app/components/avo/u_i/avatar_component.rb +61 -0
- data/app/components/avo/u_i/badge_component.html.erb +9 -0
- data/app/components/avo/u_i/badge_component.rb +35 -0
- data/app/components/avo/u_i/card_component.html.erb +29 -0
- data/app/components/avo/u_i/card_component.rb +65 -0
- data/app/components/avo/u_i/dropdown_component.html.erb +14 -0
- data/app/components/avo/u_i/dropdown_component.rb +26 -0
- data/app/components/avo/u_i/dropdown_menu_component.html.erb +16 -0
- data/app/components/avo/u_i/dropdown_menu_component.rb +8 -0
- data/app/components/avo/u_i/file_upload_input_component.html.erb +26 -0
- data/app/components/avo/u_i/file_upload_input_component.rb +15 -0
- data/app/components/avo/u_i/file_upload_item_component.html.erb +48 -0
- data/app/components/avo/u_i/file_upload_item_component.rb +17 -0
- data/app/components/avo/u_i/icon_button_component.html.erb +7 -0
- data/app/components/avo/u_i/icon_button_component.rb +22 -0
- data/app/components/avo/u_i/panel_component.html.erb +49 -0
- data/app/components/avo/u_i/panel_component.rb +29 -0
- data/app/components/avo/u_i/panel_header_component.html.erb +37 -0
- data/app/components/avo/u_i/panel_header_component.rb +24 -0
- data/app/components/avo/u_i/search_input_component.html.erb +28 -0
- data/app/components/avo/u_i/search_input_component.rb +12 -0
- data/app/components/avo/u_i/tabs/tab_component.html.erb +26 -0
- data/app/components/avo/u_i/tabs/tab_component.rb +25 -0
- data/app/components/avo/u_i/tabs/tabs_component.html.erb +7 -0
- data/app/components/avo/u_i/tabs/tabs_component.rb +13 -0
- data/app/components/avo/view_types/base_view_type_component.rb +26 -0
- data/app/components/avo/view_types/grid_component.html.erb +18 -0
- data/app/components/avo/view_types/grid_component.rb +4 -0
- data/app/components/avo/view_types/map_component.html.erb +17 -0
- data/app/components/avo/view_types/map_component.rb +110 -0
- data/app/components/avo/view_types/table_component.html.erb +63 -0
- data/app/components/avo/{index/resource_table_component.rb → view_types/table_component.rb} +1 -10
- data/app/components/avo/views/resource_edit_component.html.erb +12 -18
- data/app/components/avo/views/resource_edit_component.rb +1 -27
- data/app/components/avo/views/resource_index_component.html.erb +97 -74
- data/app/components/avo/views/resource_index_component.rb +21 -1
- data/app/components/avo/views/resource_show_component.html.erb +4 -2
- data/app/components/avo/views/resource_show_component.rb +1 -4
- data/app/controllers/avo/associations_controller.rb +1 -1
- data/app/controllers/avo/base_application_controller.rb +7 -5
- data/app/controllers/avo/base_controller.rb +139 -40
- data/app/controllers/avo/debug_controller.rb +0 -29
- data/app/controllers/avo/media_library_controller.rb +17 -1
- data/app/controllers/avo/search_controller.rb +5 -0
- data/app/controllers/concerns/avo/initializes_avo.rb +7 -8
- data/app/helpers/avo/application_helper.rb +60 -46
- data/app/helpers/avo/turbo_stream_actions_helper.rb +10 -1
- data/app/helpers/avo/url_helpers.rb +3 -2
- data/app/javascript/{avo.base.js → application.js} +9 -18
- data/app/javascript/js/application.js +40 -0
- data/app/javascript/js/controllers/action_controller.js +4 -4
- data/app/javascript/js/controllers/actions_overflow_controller.js +21 -6
- data/app/javascript/js/controllers/color_scheme_switcher_controller.js +226 -0
- data/app/javascript/js/controllers/dropdown_menu_controller.js +42 -0
- data/app/javascript/js/controllers/fields/code_field_controller.js +20 -3
- data/app/javascript/js/controllers/fields/easy_mde_controller.js +23 -1
- data/app/javascript/js/controllers/fields/key_value_controller.js +43 -39
- data/app/javascript/js/controllers/fields/panel_refresh_controller.js +4 -0
- data/app/javascript/js/controllers/fields/tags_field_controller.js +2 -2
- data/app/javascript/js/controllers/fields/tags_field_helpers.js +4 -6
- data/app/javascript/js/controllers/item_selector_controller.js +0 -2
- data/app/javascript/js/controllers/loading_button_controller.js +1 -5
- data/app/javascript/js/controllers/map_dark_mode_controller.js +131 -0
- data/app/javascript/js/controllers/menu_controller.js +38 -16
- data/app/javascript/js/controllers/modal_controller.js +16 -0
- data/app/javascript/js/controllers/modal_size_controller.js +83 -0
- data/app/javascript/js/controllers/nested_form_controller.js +2 -2
- data/app/javascript/js/controllers/password_visibility_controller.js +13 -0
- data/app/javascript/js/controllers/preview_controller.js +2 -2
- data/app/javascript/js/controllers/resource_search_controller.js +123 -0
- data/app/javascript/js/controllers/search_controller.js +10 -29
- data/app/javascript/js/controllers/sidebar_controller.js +29 -9
- data/app/javascript/js/controllers/table_row_controller.js +28 -0
- data/app/javascript/js/controllers/tippy_controller.js +1 -1
- data/app/javascript/js/controllers/toggle_controller.js +40 -5
- data/app/javascript/js/controllers.js +12 -2
- data/app/javascript/js/custom-stream-actions.js +10 -8
- data/app/views/avo/actions/show.html.erb +14 -10
- data/app/views/avo/base/_boolean_filter.html.erb +1 -1
- data/app/views/avo/base/_date_time_filter.html.erb +3 -3
- data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
- data/app/views/avo/base/_new_via_belongs_to.html.erb +2 -3
- data/app/views/avo/base/_text_filter.html.erb +1 -1
- data/app/views/avo/base/preview.html.erb +5 -4
- data/app/views/avo/debug/status.html.erb +5 -92
- data/app/views/avo/debug/status.text.erb +0 -2
- data/app/views/avo/home/_actions.html.erb +1 -1
- data/app/views/avo/home/_dashboards.html.erb +1 -1
- data/app/views/avo/home/_filters.html.erb +1 -1
- data/app/views/avo/home/_resources.html.erb +2 -2
- data/app/views/avo/home/failed_to_load.html.erb +2 -2
- data/app/views/avo/home/index.html.erb +25 -25
- data/app/views/avo/media_library/_form.html.erb +43 -28
- data/app/views/avo/media_library/show.html.erb +7 -3
- data/app/views/avo/modal/_size_selector.html.erb +46 -0
- data/app/views/avo/partials/_alerts.html.erb +1 -1
- data/app/views/avo/partials/_color_scheme_switcher.html.erb +106 -0
- data/app/views/avo/partials/_color_theme_override.html.erb +49 -0
- data/app/views/avo/partials/_confirm_dialog.html.erb +4 -4
- data/app/views/avo/partials/_custom_tools_alert.html.erb +6 -6
- data/app/views/avo/partials/_footer.html.erb +1 -1
- data/app/views/avo/partials/_header.html.erb +1 -1
- data/app/views/avo/partials/_javascript.html.erb +0 -2
- data/app/views/avo/partials/_navbar.html.erb +53 -8
- data/app/views/avo/partials/_sortable_component.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +28 -19
- data/app/views/avo/partials/_view_toggle_button.html.erb +6 -29
- data/app/views/avo/partials/distribution_chart.html.erb +2 -2
- data/app/views/avo/private/_links_and_buttons.html.erb +12 -8
- data/app/views/avo/private/design.html.erb +8 -4
- data/app/views/avo/sidebar/_license_warning.html.erb +3 -3
- data/app/views/layouts/avo/application.html.erb +39 -17
- data/app/views/layouts/avo/modal.html.erb +7 -0
- data/avo.gemspec +3 -4
- data/config/i18n-tasks.yml +1 -1
- data/config/importmap.rb +1 -0
- data/config/initializers/pagy.rb +5 -25
- data/config/routes/dynamic_routes.rb +4 -0
- data/config/routes.rb +6 -7
- data/db/factories.rb +14 -0
- data/lib/avo/asset_manager.rb +2 -0
- data/lib/avo/avatar.rb +7 -0
- data/lib/avo/base_action.rb +16 -4
- data/lib/avo/concerns/breadcrumbs.rb +7 -66
- data/lib/avo/concerns/form_builder.rb +41 -0
- data/lib/avo/concerns/{has_profile_photo.rb → has_avatar.rb} +8 -4
- data/lib/avo/concerns/{has_cover_photo.rb → has_cover.rb} +4 -4
- data/lib/avo/concerns/has_description.rb +9 -0
- data/lib/avo/concerns/has_item_type.rb +6 -2
- data/lib/avo/concerns/has_items.rb +43 -58
- data/lib/avo/concerns/pagination.rb +29 -19
- data/lib/avo/concerns/row_controls_configuration.rb +22 -15
- data/lib/avo/configuration/branding.rb +7 -7
- data/lib/avo/configuration.rb +92 -45
- data/lib/avo/{cover_photo.rb → cover.rb} +2 -2
- data/lib/avo/current.rb +0 -11
- data/lib/avo/discreet_information.rb +52 -29
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/engine.rb +41 -8
- data/lib/avo/error_manager.rb +1 -1
- data/lib/avo/fields/avatar_field.rb +19 -0
- data/lib/avo/fields/badge_field.rb +23 -3
- data/lib/avo/fields/base_field.rb +46 -1
- data/lib/avo/fields/concerns/dom_id.rb +17 -0
- data/lib/avo/fields/concerns/file_authorization.rb +4 -0
- data/lib/avo/fields/concerns/has_html_attributes.rb +1 -1
- data/lib/avo/fields/concerns/is_searchable.rb +2 -5
- data/lib/avo/fields/concerns/nested.rb +1 -1
- data/lib/avo/fields/files_field.rb +2 -2
- data/lib/avo/fields/frame_base_field.rb +2 -2
- data/lib/avo/fields/id_field.rb +5 -1
- data/lib/avo/fields/progress_bar_field.rb +1 -1
- data/lib/avo/fields/text_field.rb +1 -1
- data/lib/avo/plugin_manager.rb +4 -0
- data/lib/avo/resources/base.rb +33 -21
- data/lib/avo/resources/controls/actions_list.rb +3 -3
- data/lib/avo/resources/controls/base_control.rb +1 -1
- data/lib/avo/resources/items/card.rb +16 -0
- data/lib/avo/resources/items/header.rb +11 -0
- data/lib/avo/resources/items/holder.rb +18 -23
- data/lib/avo/resources/items/item_group.rb +5 -7
- data/lib/avo/resources/items/sidebar.rb +5 -9
- data/lib/avo/resources/items/tab.rb +8 -8
- data/lib/avo/resources/items/tab_group.rb +8 -10
- data/lib/avo/resources/resource_manager.rb +2 -1
- data/lib/avo/services/hq_reporter.rb +102 -0
- data/lib/avo/services/telemetry_service.rb +0 -1
- data/lib/avo/test_helpers.rb +36 -22
- data/lib/avo/u_i_instance.rb +60 -0
- data/lib/avo/version.rb +1 -1
- data/lib/avo/view_inquirer.rb +6 -1
- data/lib/avo/view_types/view_type_manager.rb +70 -0
- data/lib/avo.rb +30 -45
- data/lib/generators/avo/action_generator.rb +1 -1
- data/lib/generators/avo/resource_generator.rb +43 -0
- data/lib/generators/avo/resource_tool_generator.rb +1 -1
- data/lib/generators/avo/tailwindcss/install_generator.rb +0 -6
- data/lib/generators/avo/templates/cards/partial_card_partial.tt +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +7 -9
- data/lib/generators/avo/templates/locales/avo.ar.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.de.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.en.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.es.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.fr.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.it.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.ja.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.nb.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.nl.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.nn.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.pl.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.pt.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.ro.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.ru.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.tr.yml +25 -0
- data/lib/generators/avo/templates/locales/{avo.uk.yml → avo.ua.yml} +26 -1
- data/lib/generators/avo/templates/locales/avo.zh-TW.yml +25 -0
- data/lib/generators/avo/templates/locales/avo.zh.yml +25 -0
- data/lib/generators/avo/templates/resource/resource.tt +10 -1
- data/lib/generators/avo/templates/resource_tools/partial.tt +20 -22
- data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +1 -3
- data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +0 -7
- data/lib/generators/avo/templates/tool/view.tt +14 -16
- data/lib/generators/avo/tool_generator.rb +3 -3
- data/lib/generators/avo/version_generator.rb +1 -1
- data/lib/tasks/avo_tasks.rake +29 -25
- metadata +144 -97
- data/app/assets/stylesheets/avo.base.css +0 -130
- data/app/assets/stylesheets/css/breadcrumbs.css +0 -16
- data/app/assets/stylesheets/css/buttons.css +0 -19
- data/app/assets/stylesheets/css/tailwindcss/base.css +0 -1
- data/app/assets/stylesheets/css/tailwindcss/components.css +0 -1
- data/app/assets/stylesheets/css/tailwindcss/utilities.css +0 -1
- data/app/assets/svgs/avo/arrow-down.svg +0 -3
- data/app/assets/svgs/avo/arrow-up.svg +0 -3
- data/app/assets/svgs/avo/detach.svg +0 -8
- data/app/assets/svgs/avo/download-solid-reversed.svg +0 -3
- data/app/assets/svgs/avo/download-solid.svg +0 -3
- data/app/assets/svgs/avo/edit.svg +0 -5
- data/app/assets/svgs/avo/editor-bold.svg +0 -1
- data/app/assets/svgs/avo/editor-italic.svg +0 -1
- data/app/assets/svgs/avo/editor-link.svg +0 -1
- data/app/assets/svgs/avo/editor-list.svg +0 -1
- data/app/assets/svgs/avo/editor-strike.svg +0 -1
- data/app/assets/svgs/avo/editor-underline.svg +0 -1
- data/app/assets/svgs/avo/eye.svg +0 -1
- data/app/assets/svgs/avo/trash-sm.svg +0 -3
- data/app/assets/svgs/avo/trash.svg +0 -7
- data/app/components/avo/cover_photo_component.html.erb +0 -3
- data/app/components/avo/cover_photo_component.rb +0 -19
- data/app/components/avo/fields/common/badge_viewer_component.html.erb +0 -1
- data/app/components/avo/fields/common/badge_viewer_component.rb +0 -33
- data/app/components/avo/index/resource_grid_component.html.erb +0 -23
- data/app/components/avo/index/resource_grid_component.rb +0 -10
- data/app/components/avo/index/resource_map_component.html.erb +0 -16
- data/app/components/avo/index/resource_map_component.rb +0 -114
- data/app/components/avo/index/resource_table_component.html.erb +0 -52
- data/app/components/avo/panel_component.html.erb +0 -63
- data/app/components/avo/panel_component.rb +0 -43
- data/app/components/avo/panel_header_component.html.erb +0 -42
- data/app/components/avo/panel_header_component.rb +0 -31
- data/app/components/avo/profile_photo_component.html.erb +0 -6
- data/app/components/avo/profile_photo_component.rb +0 -9
- data/app/components/avo/sidebar/heading_component.html.erb +0 -21
- data/app/components/avo/sidebar/heading_component.rb +0 -9
- data/app/components/avo/tab_switcher_component.html.erb +0 -20
- data/app/components/avo/tab_switcher_component.rb +0 -45
- data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +0 -8
- data/app/views/avo/debug/report.html.erb +0 -37
- data/app/views/avo/partials/_panel_breadcrumbs.html.erb +0 -3
- data/app/views/avo/partials/_resource_search.html.erb +0 -16
- data/lib/avo/licensing/community_license.rb +0 -6
- data/lib/avo/licensing/h_q.rb +0 -202
- data/lib/avo/licensing/license.rb +0 -76
- data/lib/avo/licensing/license_manager.rb +0 -24
- data/lib/avo/licensing/nil_license.rb +0 -14
- data/lib/avo/licensing/pro_license.rb +0 -20
- data/lib/avo/licensing/request.rb +0 -20
- data/lib/avo/profile_photo.rb +0 -7
- data/lib/avo/services/debug_service.rb +0 -107
- data/tailwind.preset.js +0 -171
- /data/{public/avo-assets → app/assets/images/avo}/favicon.ico +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-500.eot +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-500.svg +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-500.ttf +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-500.woff +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-500.woff2 +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-600.eot +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-600.svg +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-600.ttf +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-600.woff +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-600.woff2 +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-700.eot +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-700.svg +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-700.ttf +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-700.woff +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-700.woff2 +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-regular.eot +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-regular.svg +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-regular.ttf +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-regular.woff +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/fonts/inter-v7-latin-regular.woff2 +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/logo-on-white.png +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/logo.png +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/logomark.png +0 -0
- /data/{public/avo-assets → app/assets/images/avo}/placeholder.svg +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
|
|
3
|
+
module Avo
|
|
4
|
+
module Services
|
|
5
|
+
class HqReporter
|
|
6
|
+
ENDPOINT = "https://v3.avohq.io/api/v3/licenses/check".freeze unless const_defined?(:ENDPOINT)
|
|
7
|
+
REQUEST_TIMEOUT = 5 unless const_defined?(:REQUEST_TIMEOUT) # seconds
|
|
8
|
+
CACHE_TIME = 24.hours.to_i unless const_defined?(:CACHE_TIME) # seconds
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def cache_key
|
|
12
|
+
"avo.hq_reporter-#{Avo::VERSION.parameterize}.reported"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Fire and forget - call this from a thread
|
|
16
|
+
# request_info should be a hash with :ip, :host, :port keys
|
|
17
|
+
def report(request_info = {})
|
|
18
|
+
return unless should_report?
|
|
19
|
+
|
|
20
|
+
cache_store.write(cache_key, {reported_at: Time.now}, expires_in: CACHE_TIME)
|
|
21
|
+
|
|
22
|
+
perform_request(request_info)
|
|
23
|
+
rescue
|
|
24
|
+
# Silently swallow all errors
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def should_report?
|
|
30
|
+
return false unless Rails.env.production?
|
|
31
|
+
return false if Avo.plugin_manager.installed?("avo-licensing")
|
|
32
|
+
return false if already_reported?
|
|
33
|
+
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def already_reported?
|
|
38
|
+
cached = cache_store.read(cache_key)
|
|
39
|
+
return false unless cached.present?
|
|
40
|
+
|
|
41
|
+
# Handle cache stores that don't auto-expire
|
|
42
|
+
reported_at = cached[:reported_at] || cached["reported_at"]
|
|
43
|
+
return false unless reported_at
|
|
44
|
+
|
|
45
|
+
Time.parse(reported_at.to_s) > Time.now - CACHE_TIME
|
|
46
|
+
rescue
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def cache_store
|
|
51
|
+
Avo.configuration.cache_store
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def payload(request_info)
|
|
55
|
+
result = {
|
|
56
|
+
license_key: Avo.configuration.license_key,
|
|
57
|
+
avo_version: Avo::VERSION,
|
|
58
|
+
rails_version: Rails::VERSION::STRING,
|
|
59
|
+
ruby_version: RUBY_VERSION,
|
|
60
|
+
environment: Rails.env,
|
|
61
|
+
ip: request_info[:ip],
|
|
62
|
+
host: request_info[:host],
|
|
63
|
+
port: request_info[:port],
|
|
64
|
+
app_name: app_name
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if Avo.configuration.send_metadata
|
|
68
|
+
begin
|
|
69
|
+
result[:avo_metadata] = Avo::Services::TelemetryService.avo_metadata
|
|
70
|
+
rescue => e
|
|
71
|
+
result[:avo_metadata] = {
|
|
72
|
+
error_message: e.message,
|
|
73
|
+
error: "Failed to generate the Avo metadata"
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
result[:avo_metadata] = :disabled
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
result
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def perform_request(request_info)
|
|
84
|
+
uri = URI.parse(ENDPOINT)
|
|
85
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
86
|
+
http.use_ssl = (uri.scheme == "https")
|
|
87
|
+
http.read_timeout = REQUEST_TIMEOUT
|
|
88
|
+
http.open_timeout = REQUEST_TIMEOUT
|
|
89
|
+
request = Net::HTTP::Post.new(uri.request_uri, {"Content-Type" => "application/json"})
|
|
90
|
+
request.body = payload(request_info).to_json
|
|
91
|
+
http.request(request)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def app_name
|
|
95
|
+
Rails.application.class.to_s.split("::").first
|
|
96
|
+
rescue
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/avo/test_helpers.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Avo
|
|
|
28
28
|
# show_field_wrapper(id: "name", type: "text")
|
|
29
29
|
# show_field_wrapper(id: "name")
|
|
30
30
|
def show_field_wrapper(id:, type: nil)
|
|
31
|
-
base_data = "[data-
|
|
31
|
+
base_data = "[data-field-id='#{id}']"
|
|
32
32
|
|
|
33
33
|
if type.present?
|
|
34
34
|
find("#{base_data}[data-resource-show-target='#{wrapper_name_for(id: id, type: type)}']")
|
|
@@ -93,21 +93,8 @@ module Avo
|
|
|
93
93
|
"—"
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
-
# Example usage:
|
|
97
|
-
# click_resource_search_input # opens the first search box on the given page
|
|
98
|
-
# opens the search box for the "users" resource
|
|
99
|
-
# within(has_and_belongs_to_many_field_wrapper(id: :users)) {
|
|
100
|
-
# click_resource_search_input
|
|
101
|
-
# write_in_search("Bob")
|
|
102
|
-
# }
|
|
103
|
-
def click_resource_search_input
|
|
104
|
-
first("[data-search-resource]:not([data-search-resource='global'])").click
|
|
105
|
-
wait_for_search_loaded
|
|
106
|
-
end
|
|
107
|
-
|
|
108
96
|
def click_global_search_input
|
|
109
|
-
page.find(
|
|
110
|
-
wait_for_search_loaded
|
|
97
|
+
page.find("[data-global-search-target='input']").click
|
|
111
98
|
end
|
|
112
99
|
|
|
113
100
|
# Should use the click_global_search_input or click_resource_search_input method to open the search box first.
|
|
@@ -119,10 +106,15 @@ module Avo
|
|
|
119
106
|
# }
|
|
120
107
|
def write_in_search(input)
|
|
121
108
|
# Use xpath to find outside of within context if any
|
|
122
|
-
find(
|
|
109
|
+
find('[data-resource-search-target="input"]').set(input)
|
|
123
110
|
wait_for_search_loaded
|
|
124
111
|
end
|
|
125
112
|
|
|
113
|
+
def write_in_global_search(input)
|
|
114
|
+
page.find("[data-global-search-target='input']").set(input)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# TODO: this will make sense only on global search
|
|
126
118
|
# Should use the click_global_search_input or click_resource_search_input method to open the search box first and optionaly write_in_search.
|
|
127
119
|
# Example usage:
|
|
128
120
|
# open_search_box(:users) # opens the search box for the "users" resource
|
|
@@ -142,7 +134,7 @@ module Avo
|
|
|
142
134
|
# Sometimes other element may be overlapping the button so the `.trigger("click")` solves the issue
|
|
143
135
|
# Trigger can't be used by default because it breaks on some feature specs
|
|
144
136
|
def save
|
|
145
|
-
button = find("button.button
|
|
137
|
+
button = find("button.button", text: "Save")
|
|
146
138
|
button.click
|
|
147
139
|
rescue Capybara::Cuprite::MouseEventFailed
|
|
148
140
|
button.trigger("click")
|
|
@@ -151,14 +143,16 @@ module Avo
|
|
|
151
143
|
end
|
|
152
144
|
|
|
153
145
|
def click_tab(tab_name = "", within_target: nil, **args)
|
|
146
|
+
tab_container_selector = '[data-controller="tabs"] [role="tablist"]'
|
|
147
|
+
|
|
154
148
|
if within_target.present?
|
|
155
149
|
within within_target do
|
|
156
|
-
within find(
|
|
150
|
+
within find(tab_container_selector) do
|
|
157
151
|
find_link(tab_name).trigger("click")
|
|
158
152
|
end
|
|
159
153
|
end
|
|
160
154
|
else
|
|
161
|
-
within find(
|
|
155
|
+
within find(tab_container_selector) do
|
|
162
156
|
find_link(tab_name).trigger("click")
|
|
163
157
|
end
|
|
164
158
|
end
|
|
@@ -192,6 +186,22 @@ module Avo
|
|
|
192
186
|
sleep 0.2
|
|
193
187
|
end
|
|
194
188
|
|
|
189
|
+
def set_picker_dates(input, *dates)
|
|
190
|
+
page.execute_script(
|
|
191
|
+
"arguments[0]._flatpickr.setDate(arguments[1], true)",
|
|
192
|
+
input.native,
|
|
193
|
+
(dates.length == 1) ? dates.first : dates
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def set_picker_time(input, hour:, minute: 0, second: 0)
|
|
198
|
+
page.execute_script(
|
|
199
|
+
"arguments[0]._flatpickr.setDate(arguments[1], true)",
|
|
200
|
+
input.native,
|
|
201
|
+
"#{hour}:#{minute}:#{second}"
|
|
202
|
+
)
|
|
203
|
+
end
|
|
204
|
+
|
|
195
205
|
def set_picker_hour(value)
|
|
196
206
|
find(".flatpickr-hour").set(value)
|
|
197
207
|
end
|
|
@@ -215,7 +225,7 @@ module Avo
|
|
|
215
225
|
end
|
|
216
226
|
|
|
217
227
|
def close_picker
|
|
218
|
-
|
|
228
|
+
all(".header__title").first.trigger("click")
|
|
219
229
|
sleep 0.3
|
|
220
230
|
end
|
|
221
231
|
|
|
@@ -227,7 +237,7 @@ module Avo
|
|
|
227
237
|
# open_panel_action(list: nil, action_name: "Release fish")
|
|
228
238
|
# open_panel_action(list: "Runnables", action_name: "Release fish")
|
|
229
239
|
def open_panel_action(action_name:, list: "Actions")
|
|
230
|
-
open_action(action_name: action_name, list: list, context: first("
|
|
240
|
+
open_action(action_name: action_name, list: list, context: first(".header__controls"))
|
|
231
241
|
end
|
|
232
242
|
|
|
233
243
|
# Open the action from the record_id row
|
|
@@ -363,7 +373,7 @@ module Avo
|
|
|
363
373
|
if list.present?
|
|
364
374
|
sleep 0.1
|
|
365
375
|
click_on list
|
|
366
|
-
within("[data-
|
|
376
|
+
within("[data-dropdown-list='#{list}']", visible: :all) do
|
|
367
377
|
find("a[data-action-name='#{action_name}']").click
|
|
368
378
|
end
|
|
369
379
|
else
|
|
@@ -382,5 +392,9 @@ module Avo
|
|
|
382
392
|
def row(id)
|
|
383
393
|
"[data-component-name='avo/index/table_row_component'][data-resource-id='#{id}']"
|
|
384
394
|
end
|
|
395
|
+
|
|
396
|
+
def strip_html(text)
|
|
397
|
+
text.strip.gsub(/\s+/, " ")
|
|
398
|
+
end
|
|
385
399
|
end
|
|
386
400
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Avo::UIInstance
|
|
4
|
+
unless defined?(MISSING_COMPONENT_CLASS)
|
|
5
|
+
MISSING_COMPONENT_CLASS = "Avo::ComponentMissingComponent"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Cache for resolved component classes to avoid repeated classify/constantize calls
|
|
9
|
+
@component_cache = {}
|
|
10
|
+
@cache_mutex = Mutex.new
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
def resolve_component(method)
|
|
14
|
+
# Check cache first (thread-safe read)
|
|
15
|
+
cached = @component_cache[method]
|
|
16
|
+
return cached if cached
|
|
17
|
+
|
|
18
|
+
# Cache miss - resolve and store (thread-safe write)
|
|
19
|
+
@cache_mutex.synchronize do
|
|
20
|
+
# Double-check after acquiring lock
|
|
21
|
+
return @component_cache[method] if @component_cache[method]
|
|
22
|
+
|
|
23
|
+
component_class = "#{method.to_s.delete_suffix("_component")}_component"
|
|
24
|
+
full_class_name = "Avo::#{component_class.classify}"
|
|
25
|
+
ui_full_class_name = "Avo::UI::#{component_class.classify}"
|
|
26
|
+
|
|
27
|
+
resolved = if Object.const_defined?(full_class_name)
|
|
28
|
+
full_class_name.constantize
|
|
29
|
+
elsif Object.const_defined?(ui_full_class_name)
|
|
30
|
+
ui_full_class_name.constantize
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
@component_cache[method] = resolved
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def clear_cache!
|
|
38
|
+
@cache_mutex.synchronize { @component_cache.clear }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Used in parent apps like this `ui.panel(...)`
|
|
42
|
+
# @method: string "panel"
|
|
43
|
+
# @return: (method: String) -> Component
|
|
44
|
+
def method_missing(method, ...)
|
|
45
|
+
component_class = resolve_component(method)
|
|
46
|
+
|
|
47
|
+
if component_class
|
|
48
|
+
component_class.new(...)
|
|
49
|
+
else
|
|
50
|
+
MISSING_COMPONENT_CLASS.safe_constantize.new(component_name: method)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def respond_to_missing?(method, include_private = false)
|
|
55
|
+
# Since method_missing always handles any method call (either with a real component
|
|
56
|
+
# or falling back to MISSING_COMPONENT_CLASS), respond_to? should return true
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
data/lib/avo/version.rb
CHANGED
data/lib/avo/view_inquirer.rb
CHANGED
|
@@ -10,6 +10,7 @@ module Avo
|
|
|
10
10
|
|
|
11
11
|
@display = in? DISPLAY_VIEWS
|
|
12
12
|
@form = in? FORM_VIEWS
|
|
13
|
+
@single = in? [*FORM_VIEWS, :show].compact.uniq
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def display?
|
|
@@ -20,12 +21,16 @@ module Avo
|
|
|
20
21
|
@form
|
|
21
22
|
end
|
|
22
23
|
|
|
24
|
+
def single?
|
|
25
|
+
@single
|
|
26
|
+
end
|
|
27
|
+
|
|
23
28
|
# To avoid breaking changes we allow the comparison with symbols
|
|
24
29
|
def ==(other)
|
|
25
30
|
if other.is_a? Symbol
|
|
26
31
|
to_sym == other
|
|
27
32
|
else
|
|
28
|
-
super
|
|
33
|
+
super
|
|
29
34
|
end
|
|
30
35
|
end
|
|
31
36
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Avo
|
|
2
|
+
module ViewTypes
|
|
3
|
+
class ViewTypeManager
|
|
4
|
+
attr_reader :registry
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@registry = {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def register(name, component:, icon:, active_icon:, translation_key: nil)
|
|
11
|
+
@registry[name.to_sym] = {
|
|
12
|
+
component: component,
|
|
13
|
+
icon: icon,
|
|
14
|
+
active_icon: active_icon,
|
|
15
|
+
translation_key: translation_key
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def find(name)
|
|
20
|
+
@registry[name.to_sym]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def component_for(name)
|
|
24
|
+
entry = find(name)
|
|
25
|
+
|
|
26
|
+
raise Avo::ViewTypeComponentNotFoundError, "No component registered for view type '#{name}'" unless entry
|
|
27
|
+
|
|
28
|
+
component = entry[:component]
|
|
29
|
+
component.is_a?(String) ? component.constantize : component
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def registered?(name)
|
|
33
|
+
@registry.key?(name.to_sym)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def reset
|
|
37
|
+
@registry = {}
|
|
38
|
+
register_defaults
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def register_defaults
|
|
44
|
+
register :table,
|
|
45
|
+
component: Avo::ViewTypes::TableComponent,
|
|
46
|
+
icon: "tabler/outline/layout-list",
|
|
47
|
+
active_icon: "tabler/filled/layout-list"
|
|
48
|
+
|
|
49
|
+
register :grid,
|
|
50
|
+
component: Avo::ViewTypes::GridComponent,
|
|
51
|
+
icon: "tabler/outline/layout-grid",
|
|
52
|
+
active_icon: "tabler/filled/layout-grid"
|
|
53
|
+
|
|
54
|
+
register :map,
|
|
55
|
+
component: Avo::ViewTypes::MapComponent,
|
|
56
|
+
icon: "tabler/outline/compass",
|
|
57
|
+
active_icon: "tabler/filled/compass"
|
|
58
|
+
|
|
59
|
+
register :list,
|
|
60
|
+
component: Avo::ViewTypes::TableComponent,
|
|
61
|
+
icon: "tabler/outline/layout-list",
|
|
62
|
+
active_icon: "tabler/filled/layout-list"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.view_type_manager
|
|
68
|
+
@view_type_manager ||= Avo::ViewTypes::ViewTypeManager.new.tap(&:reset)
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/avo.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require "zeitwerk"
|
|
2
2
|
require "net/http"
|
|
3
|
-
require "active_support/inflector"
|
|
4
3
|
require_relative "avo/version"
|
|
5
4
|
require_relative "avo/engine" if defined?(Rails)
|
|
6
5
|
|
|
@@ -36,6 +35,8 @@ module Avo
|
|
|
36
35
|
|
|
37
36
|
class DeprecatedAPIError < StandardError; end
|
|
38
37
|
|
|
38
|
+
class ViewTypeComponentNotFoundError < StandardError; end
|
|
39
|
+
|
|
39
40
|
# Exception raised when a resource is missing
|
|
40
41
|
class MissingResourceError < StandardError
|
|
41
42
|
def initialize(model_class, field)
|
|
@@ -69,16 +70,19 @@ module Avo
|
|
|
69
70
|
attr_reader :logger
|
|
70
71
|
attr_reader :cache_store
|
|
71
72
|
attr_reader :field_manager
|
|
72
|
-
|
|
73
|
-
delegate :license, :app, :error_manager, :tool_manager, :resource_manager, to: Avo::Current
|
|
73
|
+
delegate :app, :error_manager, :tool_manager, :resource_manager, to: Avo::Current
|
|
74
74
|
|
|
75
75
|
# Runs when the app boots up
|
|
76
76
|
def boot
|
|
77
77
|
Turbo::Streams::TagBuilder.prepend(Avo::TurboStreamActionsHelper)
|
|
78
78
|
@logger = Avo.configuration.logger
|
|
79
79
|
@field_manager = Avo::Fields::FieldManager.build
|
|
80
|
+
@view_type_manager = nil # force re-init with defaults on next access
|
|
80
81
|
@cache_store = Avo.configuration.cache_store
|
|
81
82
|
Avo.plugin_manager.reset
|
|
83
|
+
# Run load hooks for plugins to include them in the app.
|
|
84
|
+
# This is useful for plugins that need to include modules in the app that will be used on avo_boot hook.
|
|
85
|
+
ActiveSupport.run_load_hooks(:avo_plugin_include, self)
|
|
82
86
|
ActiveSupport.run_load_hooks(:avo_boot, self)
|
|
83
87
|
eager_load_actions
|
|
84
88
|
end
|
|
@@ -90,6 +94,7 @@ module Avo
|
|
|
90
94
|
unless Rails.env.production?
|
|
91
95
|
check_rails_version_issues
|
|
92
96
|
display_menu_editor_warning
|
|
97
|
+
display_profile_menu_editor_warning
|
|
93
98
|
end
|
|
94
99
|
Avo::Current.resource_manager = Avo::Resources::ResourceManager.build
|
|
95
100
|
Avo::Current.tool_manager = Avo::Tools::ToolManager.build
|
|
@@ -105,46 +110,14 @@ module Avo
|
|
|
105
110
|
.to_s
|
|
106
111
|
end
|
|
107
112
|
|
|
108
|
-
def main_menu
|
|
109
|
-
return unless Avo.plugin_manager.installed?("avo-menu")
|
|
110
|
-
|
|
111
|
-
# Return empty menu if the app doesn't have the profile menu configured
|
|
112
|
-
return Avo::Menu::Builder.new.build unless has_main_menu?
|
|
113
|
-
|
|
114
|
-
Avo::Menu::Builder.parse_menu(&Avo.configuration.main_menu)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def profile_menu
|
|
118
|
-
return unless Avo.plugin_manager.installed?("avo-menu")
|
|
119
|
-
|
|
120
|
-
# Return empty menu if the app doesn't have the profile menu configured
|
|
121
|
-
return Avo::Menu::Builder.new.build unless has_profile_menu?
|
|
122
|
-
|
|
123
|
-
Avo::Menu::Builder.parse_menu(&Avo.configuration.profile_menu)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
113
|
def app_status
|
|
127
|
-
|
|
114
|
+
true
|
|
128
115
|
end
|
|
129
116
|
|
|
130
117
|
def avo_dynamic_filters_installed?
|
|
131
118
|
defined?(Avo::DynamicFilters).present?
|
|
132
119
|
end
|
|
133
120
|
|
|
134
|
-
def has_main_menu?
|
|
135
|
-
return false if Avo.license.lacks_with_trial(:menu_editor)
|
|
136
|
-
return false if Avo.configuration.main_menu.nil?
|
|
137
|
-
|
|
138
|
-
true
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def has_profile_menu?
|
|
142
|
-
return false if Avo.license.lacks_with_trial(:menu_editor)
|
|
143
|
-
return false if Avo.configuration.profile_menu.nil?
|
|
144
|
-
|
|
145
|
-
true
|
|
146
|
-
end
|
|
147
|
-
|
|
148
121
|
def mount_engines
|
|
149
122
|
-> {
|
|
150
123
|
raise "'mount_engines' method is now obsolete. \n" \
|
|
@@ -162,7 +135,9 @@ module Avo
|
|
|
162
135
|
end
|
|
163
136
|
|
|
164
137
|
def check_rails_version_issues
|
|
165
|
-
if Rails.
|
|
138
|
+
return if Rails.env.test?
|
|
139
|
+
|
|
140
|
+
if Rails.version.start_with?("7.1")
|
|
166
141
|
Avo.error_manager.add({
|
|
167
142
|
url: "https://docs.avohq.io/3.0/upgrade.html#upgrade-from-3-7-4-to-3-9-1",
|
|
168
143
|
target: "_blank",
|
|
@@ -177,13 +152,23 @@ module Avo
|
|
|
177
152
|
end
|
|
178
153
|
|
|
179
154
|
def display_menu_editor_warning
|
|
180
|
-
if Avo.configuration.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
155
|
+
return if Avo.configuration.main_menu.nil?
|
|
156
|
+
|
|
157
|
+
Avo.error_manager.add({
|
|
158
|
+
url: "https://docs.avohq.io/3.0/menu-editor.html",
|
|
159
|
+
target: "_blank",
|
|
160
|
+
message: "The menu editor is available exclusively with the Pro license or above. Consider upgrading to access this feature."
|
|
161
|
+
})
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def display_profile_menu_editor_warning
|
|
165
|
+
return if Avo.configuration.profile_menu.nil?
|
|
166
|
+
|
|
167
|
+
Avo.error_manager.add({
|
|
168
|
+
url: "https://docs.avohq.io/3.0/menu-editor.html#profile-menu",
|
|
169
|
+
target: "_blank",
|
|
170
|
+
message: "The profile menu editor is available exclusively with the Pro license or above. Consider upgrading to access this feature."
|
|
171
|
+
})
|
|
187
172
|
end
|
|
188
173
|
end
|
|
189
174
|
end
|
|
@@ -192,4 +177,4 @@ def 🥑
|
|
|
192
177
|
Avo
|
|
193
178
|
end
|
|
194
179
|
|
|
195
|
-
loader.eager_load
|
|
180
|
+
loader.eager_load
|
|
@@ -15,7 +15,7 @@ module Generators
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def configuration_options
|
|
18
|
-
configuration = " self.name = \"#{options[:name] || name.
|
|
18
|
+
configuration = " self.name = \"#{options[:name] || name.humanize}\""
|
|
19
19
|
configuration += "\n self.standalone = true" if options[:standalone]
|
|
20
20
|
|
|
21
21
|
configuration
|
|
@@ -321,6 +321,49 @@ module Generators
|
|
|
321
321
|
def field(name, type)
|
|
322
322
|
::Avo::Mappings::NAMES_MAPPING[name.to_sym] || ::Avo::Mappings::FIELDS_MAPPING[type&.to_sym] || {field: "text"}
|
|
323
323
|
end
|
|
324
|
+
|
|
325
|
+
ICON_MAP = {
|
|
326
|
+
user: "tabler/outline/users",
|
|
327
|
+
customer: "tabler/outline/user",
|
|
328
|
+
transaction: "tabler/outline/credit-card-pay",
|
|
329
|
+
post: "tabler/outline/ballpen",
|
|
330
|
+
comment: "tabler/outline/message",
|
|
331
|
+
product: "tabler/outline/package",
|
|
332
|
+
order: "tabler/outline/shopping-cart",
|
|
333
|
+
category: "tabler/outline/folder",
|
|
334
|
+
tag: "tabler/outline/tag",
|
|
335
|
+
project: "tabler/outline/building-store",
|
|
336
|
+
team: "tabler/outline/users-group",
|
|
337
|
+
company: "tabler/outline/building",
|
|
338
|
+
invoice: "tabler/outline/file-invoice",
|
|
339
|
+
payment: "tabler/outline/cash",
|
|
340
|
+
article: "tabler/outline/article",
|
|
341
|
+
event: "tabler/outline/calendar-event",
|
|
342
|
+
notification: "tabler/outline/bell",
|
|
343
|
+
message: "tabler/outline/mail",
|
|
344
|
+
setting: "tabler/outline/settings",
|
|
345
|
+
report: "tabler/outline/chart-bar",
|
|
346
|
+
task: "tabler/outline/checklist",
|
|
347
|
+
review: "tabler/outline/star",
|
|
348
|
+
photo: "tabler/outline/photo",
|
|
349
|
+
image: "tabler/outline/photo",
|
|
350
|
+
video: "tabler/outline/video",
|
|
351
|
+
file: "tabler/outline/file",
|
|
352
|
+
document: "tabler/outline/file-text",
|
|
353
|
+
role: "tabler/outline/shield",
|
|
354
|
+
permission: "tabler/outline/lock",
|
|
355
|
+
subscription: "tabler/outline/credit-card",
|
|
356
|
+
plan: "tabler/outline/list",
|
|
357
|
+
address: "tabler/outline/map-pin",
|
|
358
|
+
location: "tabler/outline/map-pin",
|
|
359
|
+
country: "tabler/outline/globe",
|
|
360
|
+
city: "tabler/outline/building-community",
|
|
361
|
+
account: "tabler/outline/user-circle",
|
|
362
|
+
}.freeze
|
|
363
|
+
|
|
364
|
+
def icon_for_resource
|
|
365
|
+
ICON_MAP[singular_name.underscore.split("/").last.downcase.to_sym]
|
|
366
|
+
end
|
|
324
367
|
end
|
|
325
368
|
end
|
|
326
369
|
|
|
@@ -21,12 +21,6 @@ module Generators
|
|
|
21
21
|
copy_file template_path("tailwind.config.js"), path
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
unless (path = Rails.root.join("app", "assets", "stylesheets", "avo", "tailwindcss")).exist?
|
|
25
|
-
say "Generating the tailwindcss directory."
|
|
26
|
-
directory ::Avo::Engine.root.join("app", "assets", "stylesheets", "css", "tailwindcss"), path
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
|
|
30
24
|
unless (path = Rails.root.join("app", "assets", "stylesheets", "avo" ,"avo.tailwind.css")).exist?
|
|
31
25
|
say "Add default tailwind.css"
|
|
32
26
|
copy_file template_path("avo.tailwind.css"), path
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
@dashboard: <%%= @dashboard %>
|
|
6
6
|
<br />
|
|
7
7
|
<br />
|
|
8
|
-
Customize this partial under <code class='p-1 rounded bg-gray-500 text-white text-sm'>app/views/avo/cards/_<%= name.underscore %>.html.erb</code>
|
|
8
|
+
Customize this partial under <code class='p-1 rounded-sm bg-gray-500 text-white text-sm'>app/views/avo/cards/_<%= name.underscore %>.html.erb</code>
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
@@ -106,12 +106,11 @@ Avo.configure do |config|
|
|
|
106
106
|
# config.timezone = 'UTC'
|
|
107
107
|
# config.currency = 'USD'
|
|
108
108
|
# config.hide_layout_when_printing = false
|
|
109
|
-
# config.
|
|
110
|
-
# config.
|
|
109
|
+
# config.container_width = :large # :full, :large, or :small. Hash for per-view: { index: :full, single: :small }
|
|
110
|
+
# config.use_stacked_fields = false
|
|
111
111
|
# config.search_debounce = 300
|
|
112
112
|
# config.view_component_path = "app/components"
|
|
113
113
|
# config.display_license_request_timeout_error = true
|
|
114
|
-
# config.disabled_features = []
|
|
115
114
|
# config.buttons_on_form_footers = true
|
|
116
115
|
# config.field_wrapper_layout = true
|
|
117
116
|
# config.resource_parent_controller = "Avo::ResourcesController"
|
|
@@ -129,16 +128,15 @@ Avo.configure do |config|
|
|
|
129
128
|
# 600 => "#066BB2",
|
|
130
129
|
# },
|
|
131
130
|
# chart_colors: ["#0B8AE2", "#34C683", "#2AB1EE", "#34C6A8"],
|
|
132
|
-
# logo: "
|
|
133
|
-
# logomark: "
|
|
134
|
-
# placeholder: "
|
|
135
|
-
# favicon: "
|
|
131
|
+
# logo: "avo/logo.png",
|
|
132
|
+
# logomark: "avo/logomark.png",
|
|
133
|
+
# placeholder: "avo/placeholder.svg",
|
|
134
|
+
# favicon: "avo/favicon.ico"
|
|
136
135
|
# }
|
|
137
136
|
|
|
138
137
|
## == Breadcrumbs ==
|
|
139
|
-
# config.display_breadcrumbs = true
|
|
140
138
|
# config.set_initial_breadcrumbs do
|
|
141
|
-
# add_breadcrumb "Home", '/<%= options[:path] %>'
|
|
139
|
+
# add_breadcrumb title: "Home", path: '/<%= options[:path] %>'
|
|
142
140
|
# end
|
|
143
141
|
|
|
144
142
|
## == Menus ==
|