activeadmin 3.4.0 → 4.0.0.beta18
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/CHANGELOG.md +4 -102
- data/CONTRIBUTING.md +32 -117
- data/README.md +17 -30
- data/UPGRADING.md +241 -0
- data/app/assets/config/active_admin_manifest.js +2 -0
- data/{lib → app/controllers}/active_admin/base_controller/authorization.rb +1 -1
- data/app/controllers/active_admin/base_controller/menu.rb +39 -0
- data/{lib → app/controllers}/active_admin/base_controller.rb +46 -18
- data/{lib → app/controllers}/active_admin/page_controller.rb +0 -4
- data/{lib → app/controllers}/active_admin/resource_controller/action_builder.rb +1 -1
- data/{lib → app/controllers}/active_admin/resource_controller/data_access.rb +11 -6
- data/{lib → app/controllers}/active_admin/resource_controller/scoping.rb +1 -1
- data/{lib → app/controllers}/active_admin/resource_controller/streaming.rb +4 -4
- data/app/controllers/active_admin/resource_controller.rb +102 -0
- data/app/helpers/active_admin/auto_link_helper.rb +66 -0
- data/app/helpers/active_admin/breadcrumb_helper.rb +41 -0
- data/app/helpers/active_admin/display_helper.rb +117 -0
- data/app/helpers/active_admin/form_helper.rb +95 -0
- data/app/helpers/active_admin/index_helper.rb +40 -0
- data/app/helpers/active_admin/layout_helper.rb +63 -0
- data/app/javascript/active_admin/features/batch_actions.js +95 -0
- data/app/javascript/active_admin/features/dark_mode_toggle.js +37 -0
- data/app/javascript/active_admin/features/filters.js +34 -0
- data/app/javascript/active_admin/features/has_many.js +28 -0
- data/app/javascript/active_admin/features/main_menu.js +12 -0
- data/app/javascript/active_admin/features/per_page.js +9 -0
- data/app/javascript/active_admin/utils/dom.js +17 -0
- data/app/javascript/active_admin.js +10 -0
- data/app/views/active_admin/_flash_messages.html.erb +22 -0
- data/app/views/active_admin/_html_head.html.erb +13 -0
- data/app/views/active_admin/_main_navigation.html.erb +28 -0
- data/app/views/active_admin/_page_header.html.erb +27 -0
- data/app/views/active_admin/_sidebar.html.erb +5 -0
- data/app/views/active_admin/_site_footer.html.erb +7 -0
- data/app/views/active_admin/_site_header.html.erb +30 -0
- data/app/views/active_admin/devise/confirmations/new.html.erb +5 -3
- data/app/views/active_admin/devise/passwords/edit.html.erb +5 -3
- data/app/views/active_admin/devise/passwords/new.html.erb +5 -4
- data/app/views/active_admin/devise/registrations/new.html.erb +6 -4
- data/app/views/active_admin/devise/sessions/new.html.erb +6 -4
- data/app/views/active_admin/devise/shared/_links.erb +3 -1
- data/app/views/active_admin/devise/unlocks/new.html.erb +6 -4
- data/app/views/{kaminari/active_admin_countless → active_admin/kaminari}/_gap.html.erb +3 -1
- data/app/views/active_admin/kaminari/_next_page.html.erb +16 -0
- data/app/views/active_admin/kaminari/_page.html.erb +14 -0
- data/app/views/{kaminari/active_admin_countless → active_admin/kaminari}/_paginator.html.erb +1 -2
- data/app/views/active_admin/kaminari/_prev_page.html.erb +16 -0
- data/app/views/active_admin/page/index.html.arb +5 -2
- data/app/views/active_admin/resource/_active_filters.html.erb +32 -0
- data/app/views/active_admin/resource/_batch_actions_dropdown.html.erb +19 -0
- data/app/views/active_admin/resource/_form.html.arb +15 -0
- data/app/views/active_admin/resource/_form_default.html.arb +11 -0
- data/app/views/active_admin/resource/_index_as_table_default.html.arb +8 -0
- data/app/views/active_admin/resource/_index_blank_slate.html.erb +14 -0
- data/app/views/active_admin/resource/_index_empty_results.html.erb +5 -0
- data/app/views/active_admin/resource/_index_table_actions_default.html.erb +9 -0
- data/app/views/active_admin/resource/_show_default.html.arb +2 -0
- data/app/views/active_admin/resource/edit.html.arb +1 -2
- data/app/views/active_admin/resource/index.html.arb +94 -2
- data/app/views/active_admin/resource/new.html.arb +1 -2
- data/app/views/active_admin/resource/show.html.arb +12 -2
- data/app/views/active_admin/shared/_action_items.html.erb +3 -0
- data/app/views/active_admin/shared/_download_format_links.html.erb +7 -0
- data/app/views/active_admin/shared/_resource_comments.html.erb +51 -0
- data/app/views/active_admin/shared/_sidebar_section.html.arb +6 -0
- data/app/views/active_admin/shared/_sidebar_sections.html.erb +5 -0
- data/app/views/layouts/active_admin.html.erb +20 -0
- data/app/views/layouts/active_admin_logged_out.html.erb +8 -45
- data/config/importmap.rb +5 -0
- data/config/locales/ar.yml +136 -116
- data/config/locales/az.yml +103 -118
- data/config/locales/bg.yml +91 -99
- data/config/locales/bs.yml +95 -101
- data/config/locales/ca.yml +131 -86
- data/config/locales/cs.yml +82 -90
- data/config/locales/da.yml +102 -117
- data/config/locales/de.yml +130 -141
- data/config/locales/el.yml +94 -106
- data/config/locales/en-CA.yml +104 -119
- data/config/locales/en-GB.yml +104 -119
- data/config/locales/en.yml +134 -140
- data/config/locales/eo.yml +107 -123
- data/config/locales/es-MX.yml +70 -78
- data/config/locales/es.yml +129 -138
- data/config/locales/fa.yml +91 -99
- data/config/locales/fi.yml +84 -92
- data/config/locales/fr.yml +135 -120
- data/config/locales/he.yml +103 -118
- data/config/locales/hr.yml +95 -103
- data/config/locales/hu.yml +76 -81
- data/config/locales/id.yml +97 -112
- data/config/locales/it.yml +134 -140
- data/config/locales/ja.yml +109 -120
- data/config/locales/ko.yml +136 -101
- data/config/locales/lt.yml +106 -121
- data/config/locales/lv.yml +70 -75
- data/config/locales/mk.yml +100 -114
- data/config/locales/nb.yml +98 -109
- data/config/locales/nl.yml +113 -122
- data/config/locales/pl.yml +137 -146
- data/config/locales/pt-BR.yml +134 -121
- data/config/locales/pt-PT.yml +71 -76
- data/config/locales/ro.yml +74 -79
- data/config/locales/ru.yml +142 -122
- data/config/locales/sk.yml +131 -146
- data/config/locales/sv-SE.yml +126 -141
- data/config/locales/tr.yml +105 -120
- data/config/locales/uk.yml +140 -119
- data/config/locales/vi.yml +125 -140
- data/config/locales/zh-CN.yml +135 -141
- data/config/locales/zh-TW.yml +136 -116
- data/lib/active_admin/application.rb +6 -14
- data/lib/active_admin/application_settings.rb +1 -1
- data/lib/active_admin/async_count.rb +23 -0
- data/lib/active_admin/batch_actions/controller.rb +1 -4
- data/lib/active_admin/batch_actions/resource_extension.rb +8 -15
- data/lib/active_admin/batch_actions/views/batch_action_form.rb +1 -7
- data/lib/active_admin/batch_actions/views/selection_cells.rb +3 -3
- data/lib/active_admin/batch_actions.rb +4 -9
- data/lib/active_admin/callbacks.rb +6 -4
- data/lib/active_admin/collection_decorator.rb +1 -1
- data/lib/active_admin/component.rb +0 -1
- data/lib/active_admin/csv_builder.rb +2 -2
- data/lib/active_admin/devise.rb +3 -3
- data/lib/active_admin/dsl.rb +3 -3
- data/lib/active_admin/dynamic_settings_node.rb +6 -6
- data/lib/active_admin/engine.rb +23 -7
- data/lib/active_admin/filters/active.rb +8 -6
- data/lib/active_admin/filters/active_filter.rb +2 -10
- data/lib/active_admin/filters/forms.rb +1 -45
- data/lib/active_admin/filters/resource_extension.rb +18 -10
- data/lib/active_admin/filters.rb +5 -7
- data/lib/active_admin/form_builder.rb +14 -17
- data/lib/active_admin/helpers/optional_display.rb +1 -1
- data/lib/active_admin/inputs/filters/base/search_method_select.rb +10 -12
- data/lib/active_admin/inputs/filters/base.rb +1 -1
- data/lib/active_admin/inputs/filters/check_boxes_input.rb +1 -6
- data/lib/active_admin/inputs/filters/date_range_input.rb +4 -2
- data/lib/active_admin/inputs.rb +0 -3
- data/lib/active_admin/localizers.rb +1 -1
- data/lib/active_admin/menu.rb +10 -7
- data/lib/active_admin/menu_collection.rb +1 -1
- data/lib/active_admin/menu_item.rb +24 -3
- data/lib/active_admin/namespace.rb +3 -45
- data/lib/active_admin/namespace_settings.rb +3 -36
- data/lib/active_admin/order_clause.rb +4 -1
- data/lib/active_admin/orm/active_record/comments/views/active_admin_comments.rb +4 -76
- data/lib/active_admin/orm/active_record/comments/views.rb +2 -2
- data/lib/active_admin/orm/active_record/comments.rb +13 -8
- data/lib/active_admin/orm/active_record.rb +1 -1
- data/lib/active_admin/pundit_adapter.rb +3 -3
- data/lib/active_admin/resource/action_items.rb +18 -23
- data/lib/active_admin/resource/naming.rb +2 -3
- data/lib/active_admin/resource/page_presenters.rb +2 -2
- data/lib/active_admin/resource/sidebars.rb +1 -1
- data/lib/active_admin/resource.rb +17 -16
- data/lib/active_admin/resource_collection.rb +1 -1
- data/lib/active_admin/resource_dsl.rb +3 -3
- data/lib/active_admin/scope.rb +11 -1
- data/lib/active_admin/settings_node.rb +1 -1
- data/lib/active_admin/sidebar_section.rb +0 -5
- data/lib/active_admin/version.rb +1 -1
- data/lib/active_admin/view_helpers/method_or_proc_helper.rb +1 -1
- data/lib/active_admin/view_helpers.rb +0 -12
- data/lib/active_admin/views/components/active_admin_form.rb +21 -29
- data/lib/active_admin/views/components/attributes_table.rb +14 -16
- data/lib/active_admin/views/components/index_list.rb +10 -23
- data/lib/active_admin/views/components/paginated_collection.rb +34 -39
- data/lib/active_admin/views/components/panel.rb +3 -11
- data/lib/active_admin/views/components/scopes.rb +39 -26
- data/lib/active_admin/views/components/status_tag.rb +22 -19
- data/lib/active_admin/views/components/table_for.rb +25 -25
- data/lib/active_admin/views/index_as_table.rb +39 -101
- data/lib/active_admin.rb +16 -15
- data/lib/activeadmin.rb +1 -1
- data/lib/generators/active_admin/assets/assets_generator.rb +4 -4
- data/lib/generators/active_admin/assets/templates/active_admin.css +3 -0
- data/lib/generators/active_admin/assets/templates/tailwind.config.js +21 -0
- data/lib/generators/active_admin/devise/devise_generator.rb +2 -2
- data/lib/generators/active_admin/install/install_generator.rb +2 -8
- data/lib/generators/active_admin/install/templates/active_admin.rb.erb +10 -87
- data/lib/generators/active_admin/install/templates/dashboard.rb +8 -25
- data/lib/generators/active_admin/page/page_generator.rb +0 -1
- data/lib/generators/active_admin/resource/resource_generator.rb +50 -7
- data/lib/generators/active_admin/resource/templates/resource.rb.erb +42 -0
- data/lib/generators/active_admin/views_generator.rb +18 -0
- data/plugin.js +414 -0
- data/vendor/bundle/offense.rb +1 -0
- data/vendor/javascript/flowbite.js +1 -0
- data/vendor/javascript/rails_ujs_esm.js +1 -0
- metadata +80 -207
- data/app/assets/javascripts/active_admin/base.js +0 -517
- data/app/assets/stylesheets/active_admin/_base.scss +0 -57
- data/app/assets/stylesheets/active_admin/_forms.scss +0 -315
- data/app/assets/stylesheets/active_admin/_header.scss +0 -188
- data/app/assets/stylesheets/active_admin/_mixins.scss +0 -1
- data/app/assets/stylesheets/active_admin/_normalize.scss +0 -349
- data/app/assets/stylesheets/active_admin/_print.scss +0 -287
- data/app/assets/stylesheets/active_admin/_typography.scss +0 -100
- data/app/assets/stylesheets/active_admin/components/_batch_actions.scss +0 -6
- data/app/assets/stylesheets/active_admin/components/_blank_slates.scss +0 -30
- data/app/assets/stylesheets/active_admin/components/_breadcrumbs.scss +0 -20
- data/app/assets/stylesheets/active_admin/components/_buttons.scss +0 -6
- data/app/assets/stylesheets/active_admin/components/_columns.scss +0 -3
- data/app/assets/stylesheets/active_admin/components/_comments.scss +0 -41
- data/app/assets/stylesheets/active_admin/components/_date_picker.scss +0 -148
- data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +0 -154
- data/app/assets/stylesheets/active_admin/components/_flash_messages.scss +0 -37
- data/app/assets/stylesheets/active_admin/components/_grid.scss +0 -9
- data/app/assets/stylesheets/active_admin/components/_index_list.scss +0 -12
- data/app/assets/stylesheets/active_admin/components/_links.scss +0 -5
- data/app/assets/stylesheets/active_admin/components/_modal_dialog.scss +0 -34
- data/app/assets/stylesheets/active_admin/components/_pagination.scss +0 -58
- data/app/assets/stylesheets/active_admin/components/_panels.scss +0 -6
- data/app/assets/stylesheets/active_admin/components/_scopes.scss +0 -13
- data/app/assets/stylesheets/active_admin/components/_status_tags.scss +0 -12
- data/app/assets/stylesheets/active_admin/components/_table_tools.scss +0 -70
- data/app/assets/stylesheets/active_admin/components/_tables.scss +0 -112
- data/app/assets/stylesheets/active_admin/components/_tabs.scss +0 -68
- data/app/assets/stylesheets/active_admin/components/_unsupported_browser.scss +0 -16
- data/app/assets/stylesheets/active_admin/mixins/_all.scss +0 -8
- data/app/assets/stylesheets/active_admin/mixins/_buttons.scss +0 -65
- data/app/assets/stylesheets/active_admin/mixins/_gradients.scss +0 -28
- data/app/assets/stylesheets/active_admin/mixins/_rounded.scss +0 -22
- data/app/assets/stylesheets/active_admin/mixins/_sections.scss +0 -41
- data/app/assets/stylesheets/active_admin/mixins/_shadows.scss +0 -15
- data/app/assets/stylesheets/active_admin/mixins/_typography.scss +0 -3
- data/app/assets/stylesheets/active_admin/mixins/_utilities.scss +0 -17
- data/app/assets/stylesheets/active_admin/mixins/_variables.scss +0 -51
- data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +0 -44
- data/app/assets/stylesheets/active_admin/structure/_footer.scss +0 -19
- data/app/assets/stylesheets/active_admin/structure/_main_structure.scss +0 -29
- data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +0 -43
- data/app/javascript/active_admin/base.js +0 -28
- data/app/javascript/active_admin/ext/jquery-ui.js +0 -7
- data/app/javascript/active_admin/ext/jquery.js +0 -9
- data/app/javascript/active_admin/initializers/batch-actions.js +0 -61
- data/app/javascript/active_admin/initializers/checkbox-toggler.js +0 -3
- data/app/javascript/active_admin/initializers/datepicker.js +0 -16
- data/app/javascript/active_admin/initializers/dropdown-menu.js +0 -9
- data/app/javascript/active_admin/initializers/filters.js +0 -10
- data/app/javascript/active_admin/initializers/has-many.js +0 -98
- data/app/javascript/active_admin/initializers/per-page.js +0 -13
- data/app/javascript/active_admin/initializers/table-checkbox-toggler.js +0 -3
- data/app/javascript/active_admin/initializers/tabs.js +0 -6
- data/app/javascript/active_admin/lib/checkbox-toggler.js +0 -49
- data/app/javascript/active_admin/lib/dropdown-menu.js +0 -116
- data/app/javascript/active_admin/lib/filters.js +0 -39
- data/app/javascript/active_admin/lib/modal-dialog.js +0 -63
- data/app/javascript/active_admin/lib/per-page.js +0 -38
- data/app/javascript/active_admin/lib/table-checkbox-toggler.js +0 -38
- data/app/javascript/active_admin/lib/utils.js +0 -40
- data/app/views/kaminari/active_admin/_first_page.html.erb +0 -11
- data/app/views/kaminari/active_admin/_gap.html.erb +0 -8
- data/app/views/kaminari/active_admin/_last_page.html.erb +0 -11
- data/app/views/kaminari/active_admin/_next_page.html.erb +0 -11
- data/app/views/kaminari/active_admin/_page.html.erb +0 -12
- data/app/views/kaminari/active_admin/_paginator.html.erb +0 -25
- data/app/views/kaminari/active_admin/_prev_page.html.erb +0 -11
- data/app/views/kaminari/active_admin_countless/_first_page.html.erb +0 -11
- data/app/views/kaminari/active_admin_countless/_next_page.html.erb +0 -11
- data/app/views/kaminari/active_admin_countless/_page.html.erb +0 -12
- data/app/views/kaminari/active_admin_countless/_prev_page.html.erb +0 -11
- data/app/views/layouts/active_admin.html.arb +0 -2
- data/config/locales/de-CH.yml +0 -94
- data/lib/active_admin/abstract_view_factory.rb +0 -48
- data/lib/active_admin/asset_registration.rb +0 -30
- data/lib/active_admin/base_controller/menu.rb +0 -35
- data/lib/active_admin/batch_actions/views/batch_action_selector.rb +0 -59
- data/lib/active_admin/filters/active_sidebar.rb +0 -28
- data/lib/active_admin/generators/boilerplate.rb +0 -54
- data/lib/active_admin/helpers/collection.rb +0 -21
- data/lib/active_admin/helpers/i18n.rb +0 -8
- data/lib/active_admin/inputs/datepicker_input.rb +0 -28
- data/lib/active_admin/inputs/filters/date_picker_input.rb +0 -14
- data/lib/active_admin/orm/active_record/comments/show_page_helper.rb +0 -24
- data/lib/active_admin/orm/mongoid.rb +0 -2
- data/lib/active_admin/resource_controller/sidebars.rb +0 -19
- data/lib/active_admin/resource_controller.rb +0 -68
- data/lib/active_admin/view_factory.rb +0 -28
- data/lib/active_admin/view_helpers/active_admin_application_helper.rb +0 -13
- data/lib/active_admin/view_helpers/auto_link_helper.rb +0 -46
- data/lib/active_admin/view_helpers/breadcrumb_helper.rb +0 -34
- data/lib/active_admin/view_helpers/display_helper.rb +0 -119
- data/lib/active_admin/view_helpers/download_format_links_helper.rb +0 -60
- data/lib/active_admin/view_helpers/fields_for.rb +0 -51
- data/lib/active_admin/view_helpers/flash_helper.rb +0 -15
- data/lib/active_admin/view_helpers/form_helper.rb +0 -21
- data/lib/active_admin/view_helpers/scope_name_helper.rb +0 -17
- data/lib/active_admin/view_helpers/sidebar_helper.rb +0 -16
- data/lib/active_admin/view_helpers/title_helper.rb +0 -12
- data/lib/active_admin/view_helpers/view_factory_helper.rb +0 -12
- data/lib/active_admin/views/action_items.rb +0 -18
- data/lib/active_admin/views/components/active_filters_sidebar_content.rb +0 -59
- data/lib/active_admin/views/components/blank_slate.rb +0 -18
- data/lib/active_admin/views/components/columns.rb +0 -162
- data/lib/active_admin/views/components/dropdown_menu.rb +0 -69
- data/lib/active_admin/views/components/menu.rb +0 -33
- data/lib/active_admin/views/components/menu_item.rb +0 -59
- data/lib/active_admin/views/components/sidebar.rb +0 -14
- data/lib/active_admin/views/components/sidebar_section.rb +0 -35
- data/lib/active_admin/views/components/site_title.rb +0 -55
- data/lib/active_admin/views/components/tabs.rb +0 -41
- data/lib/active_admin/views/components/unsupported_browser.rb +0 -12
- data/lib/active_admin/views/footer.rb +0 -32
- data/lib/active_admin/views/header.rb +0 -20
- data/lib/active_admin/views/index_as_block.rb +0 -37
- data/lib/active_admin/views/index_as_blog.rb +0 -156
- data/lib/active_admin/views/index_as_grid.rb +0 -81
- data/lib/active_admin/views/pages/base.rb +0 -134
- data/lib/active_admin/views/pages/form.rb +0 -65
- data/lib/active_admin/views/pages/index.rb +0 -166
- data/lib/active_admin/views/pages/layout.rb +0 -27
- data/lib/active_admin/views/pages/page.rb +0 -31
- data/lib/active_admin/views/pages/show.rb +0 -60
- data/lib/active_admin/views/tabbed_navigation.rb +0 -12
- data/lib/active_admin/views/title_bar.rb +0 -56
- data/lib/generators/active_admin/assets/templates/active_admin.js +0 -1
- data/lib/generators/active_admin/assets/templates/active_admin.scss +0 -17
- data/lib/generators/active_admin/resource/templates/admin.rb.erb +0 -46
- data/lib/generators/active_admin/webpacker/plugins/jquery.js +0 -7
- data/lib/generators/active_admin/webpacker/templates/active_admin.js +0 -5
- data/lib/generators/active_admin/webpacker/templates/active_admin.scss +0 -17
- data/lib/generators/active_admin/webpacker/templates/print.scss +0 -2
- data/lib/generators/active_admin/webpacker/webpacker_generator.rb +0 -27
- data/vendor/assets/javascripts/jquery-ui/data.js +0 -45
- data/vendor/assets/javascripts/jquery-ui/disable-selection.js +0 -51
- data/vendor/assets/javascripts/jquery-ui/focusable.js +0 -89
- data/vendor/assets/javascripts/jquery-ui/form-reset-mixin.js +0 -83
- data/vendor/assets/javascripts/jquery-ui/form.js +0 -25
- data/vendor/assets/javascripts/jquery-ui/ie.js +0 -20
- data/vendor/assets/javascripts/jquery-ui/keycode.js +0 -51
- data/vendor/assets/javascripts/jquery-ui/labels.js +0 -71
- data/vendor/assets/javascripts/jquery-ui/plugin.js +0 -49
- data/vendor/assets/javascripts/jquery-ui/position.js +0 -513
- data/vendor/assets/javascripts/jquery-ui/safe-active-element.js +0 -46
- data/vendor/assets/javascripts/jquery-ui/safe-blur.js +0 -27
- data/vendor/assets/javascripts/jquery-ui/scroll-parent.js +0 -50
- data/vendor/assets/javascripts/jquery-ui/tabbable.js +0 -41
- data/vendor/assets/javascripts/jquery-ui/unique-id.js +0 -54
- data/vendor/assets/javascripts/jquery-ui/version.js +0 -20
- data/vendor/assets/javascripts/jquery-ui/widget.js +0 -758
- data/vendor/assets/javascripts/jquery-ui/widgets/button.js +0 -454
- data/vendor/assets/javascripts/jquery-ui/widgets/checkboxradio.js +0 -294
- data/vendor/assets/javascripts/jquery-ui/widgets/controlgroup.js +0 -304
- data/vendor/assets/javascripts/jquery-ui/widgets/datepicker.js +0 -2243
- data/vendor/assets/javascripts/jquery-ui/widgets/dialog.js +0 -971
- data/vendor/assets/javascripts/jquery-ui/widgets/draggable.js +0 -1268
- data/vendor/assets/javascripts/jquery-ui/widgets/mouse.js +0 -241
- data/vendor/assets/javascripts/jquery-ui/widgets/resizable.js +0 -1228
- data/vendor/assets/javascripts/jquery-ui/widgets/sortable.js +0 -1622
- data/vendor/assets/javascripts/jquery-ui/widgets/tabs.js +0 -931
- /data/{lib → app/controllers}/active_admin/resource_controller/decorators.rb +0 -0
- /data/{lib → app/controllers}/active_admin/resource_controller/polymorphic_routes.rb +0 -0
- /data/{lib → app/controllers}/active_admin/resource_controller/resource_class_methods.rb +0 -0
- /data/lib/{active_admin/orm/mongoid/.gitkeep → generators/active_admin/assets/templates/builds/.keep} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module ActiveAdmin
|
|
3
|
+
module BreadcrumbHelper
|
|
4
|
+
ID_FORMAT_REGEXP = /\A(\d+|[a-f0-9]{24}|(?:[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}))\z/.freeze
|
|
5
|
+
|
|
6
|
+
# Returns an array of links to use in a breadcrumb
|
|
7
|
+
def build_breadcrumb_links(path = request.path, html_options = {})
|
|
8
|
+
config = active_admin_config.breadcrumb
|
|
9
|
+
if config.is_a?(Proc)
|
|
10
|
+
instance_exec(controller, &config)
|
|
11
|
+
elsif config.present?
|
|
12
|
+
default_breadcrumb_links(path, html_options)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def default_breadcrumb_links(path, html_options = {})
|
|
17
|
+
# remove leading "/" and split up the URL
|
|
18
|
+
# and remove last since it's used as the page title
|
|
19
|
+
parts = path.split("/").select(&:present?)[0..-2]
|
|
20
|
+
|
|
21
|
+
parts.each_with_index.map do |part, index|
|
|
22
|
+
# 1. try using `display_name` if we can locate a DB object
|
|
23
|
+
# 2. try using the model name translation
|
|
24
|
+
# 3. default to calling `titlecase` on the URL fragment
|
|
25
|
+
if ID_FORMAT_REGEXP.match?(part) && parts[index - 1]
|
|
26
|
+
parent = active_admin_config.belongs_to_config.try :target
|
|
27
|
+
config = parent && parent.resource_name.route_key == parts[index - 1] ? parent : active_admin_config
|
|
28
|
+
name = display_name config.find_resource part
|
|
29
|
+
end
|
|
30
|
+
name ||= I18n.t "activerecord.models.#{part.singularize}", count: 2.1, default: part.titlecase
|
|
31
|
+
|
|
32
|
+
# Don't create a link if the resource's show action is disabled
|
|
33
|
+
if !config || config.defined_actions.include?(:show)
|
|
34
|
+
link_to name, "/" + parts[0..index].join("/"), html_options
|
|
35
|
+
else
|
|
36
|
+
name
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module ActiveAdmin
|
|
3
|
+
module DisplayHelper
|
|
4
|
+
DISPLAY_NAME_FALLBACK = -> {
|
|
5
|
+
klass = self.class
|
|
6
|
+
name = if klass.respond_to?(:model_name)
|
|
7
|
+
if klass.respond_to?(:primary_key)
|
|
8
|
+
"#{klass.model_name.human} ##{send(klass.primary_key)}"
|
|
9
|
+
else
|
|
10
|
+
klass.model_name.human
|
|
11
|
+
end
|
|
12
|
+
elsif klass.respond_to?(:primary_key)
|
|
13
|
+
" ##{send(klass.primary_key)}"
|
|
14
|
+
end
|
|
15
|
+
name.present? ? name : to_s
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def DISPLAY_NAME_FALLBACK.inspect
|
|
19
|
+
"DISPLAY_NAME_FALLBACK"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Attempts to call any known display name methods on the resource.
|
|
23
|
+
# See the setting in `application.rb` for the list of methods and their priority.
|
|
24
|
+
def display_name(resource)
|
|
25
|
+
unless resource.nil?
|
|
26
|
+
result = render_in_context(resource, display_name_method_for(resource))
|
|
27
|
+
if result.to_s.strip.present?
|
|
28
|
+
ERB::Util.html_escape(result)
|
|
29
|
+
else
|
|
30
|
+
ERB::Util.html_escape(render_in_context(resource, DISPLAY_NAME_FALLBACK))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def format_attribute(resource, attr)
|
|
36
|
+
value = find_value resource, attr
|
|
37
|
+
|
|
38
|
+
if value.is_a?(Arbre::Element)
|
|
39
|
+
value
|
|
40
|
+
elsif boolean_attr?(resource, attr, value)
|
|
41
|
+
Arbre::Context.new { status_tag value }
|
|
42
|
+
else
|
|
43
|
+
pretty_format value
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Attempts to create a human-readable string for any object
|
|
48
|
+
def pretty_format(object)
|
|
49
|
+
case object
|
|
50
|
+
when String, Numeric, Symbol, Arbre::Element
|
|
51
|
+
object.to_s
|
|
52
|
+
when Date, Time
|
|
53
|
+
I18n.localize object, format: active_admin_application.localize_format
|
|
54
|
+
when Array
|
|
55
|
+
format_collection(object)
|
|
56
|
+
else
|
|
57
|
+
if defined?(::ActiveRecord) && object.is_a?(ActiveRecord::Base) ||
|
|
58
|
+
defined?(::Mongoid) && object.class.include?(Mongoid::Document)
|
|
59
|
+
auto_link object
|
|
60
|
+
elsif defined?(::ActiveRecord) && object.is_a?(ActiveRecord::Relation)
|
|
61
|
+
format_collection(object)
|
|
62
|
+
else
|
|
63
|
+
display_name object
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
# Looks up and caches the first available display name method.
|
|
71
|
+
# To prevent conflicts, we exclude any methods that happen to be associations.
|
|
72
|
+
# If no methods are available and we're about to use the Kernel's `to_s`, provide our own.
|
|
73
|
+
def display_name_method_for(resource)
|
|
74
|
+
@@display_name_methods_cache ||= {}
|
|
75
|
+
@@display_name_methods_cache[resource.class] ||= begin
|
|
76
|
+
methods = active_admin_application.display_name_methods - association_methods_for(resource)
|
|
77
|
+
method = methods.detect { |method| resource.respond_to? method }
|
|
78
|
+
|
|
79
|
+
if method != :to_s || resource.method(method).source_location
|
|
80
|
+
method
|
|
81
|
+
else
|
|
82
|
+
DISPLAY_NAME_FALLBACK
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def association_methods_for(resource)
|
|
88
|
+
return [] unless resource.class.respond_to? :reflect_on_all_associations
|
|
89
|
+
resource.class.reflect_on_all_associations.map(&:name)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def find_value(resource, attr)
|
|
93
|
+
if attr.is_a? Proc
|
|
94
|
+
attr.call resource
|
|
95
|
+
elsif resource.respond_to? attr
|
|
96
|
+
resource.public_send attr
|
|
97
|
+
elsif resource.respond_to? :[]
|
|
98
|
+
resource[attr]
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def format_collection(collection)
|
|
103
|
+
safe_join(collection.map { |item| pretty_format(item) }, ", ")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def boolean_attr?(resource, attr, value)
|
|
107
|
+
case value
|
|
108
|
+
when TrueClass, FalseClass
|
|
109
|
+
true
|
|
110
|
+
else
|
|
111
|
+
if resource.class.respond_to? :attribute_types
|
|
112
|
+
resource.class.attribute_types[attr.to_s].is_a?(ActiveModel::Type::Boolean)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module ActiveAdmin
|
|
3
|
+
module FormHelper
|
|
4
|
+
RESERVED_PARAMS = %w(controller action commit utf8).freeze
|
|
5
|
+
|
|
6
|
+
def active_admin_form_for(resource, options = {}, &block)
|
|
7
|
+
Arbre::Context.new({}, self) do
|
|
8
|
+
active_admin_form_for resource, options, &block
|
|
9
|
+
end.content
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def hidden_field_tags_for(params, options = {})
|
|
13
|
+
fields_for_params(params.to_unsafe_hash, options).map do |kv|
|
|
14
|
+
k, v = kv.first
|
|
15
|
+
hidden_field_tag k, v, id: sanitize_to_id("hidden_active_admin_#{k}")
|
|
16
|
+
end.join("\n").html_safe
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Flatten a params Hash to an array of fields.
|
|
20
|
+
#
|
|
21
|
+
# @param params [Hash]
|
|
22
|
+
# @param options [Hash] :namespace and :except
|
|
23
|
+
#
|
|
24
|
+
# @return [Array] of [Hash] with one element.
|
|
25
|
+
#
|
|
26
|
+
# @example
|
|
27
|
+
# fields_for_params(scope: "all", users: ["greg"])
|
|
28
|
+
# => [ {"scope" => "all"} , {"users[]" => "greg"} ]
|
|
29
|
+
#
|
|
30
|
+
def fields_for_params(params, options = {})
|
|
31
|
+
namespace = options[:namespace]
|
|
32
|
+
except = Array.wrap(options[:except]).map(&:to_s)
|
|
33
|
+
|
|
34
|
+
params.flat_map do |k, v|
|
|
35
|
+
next if namespace.nil? && RESERVED_PARAMS.include?(k.to_s)
|
|
36
|
+
next if except.include?(k.to_s)
|
|
37
|
+
|
|
38
|
+
if namespace
|
|
39
|
+
k = "#{namespace}[#{k}]"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
case v
|
|
43
|
+
when String, TrueClass, FalseClass
|
|
44
|
+
{ k => v }
|
|
45
|
+
when Symbol
|
|
46
|
+
{ k => v.to_s }
|
|
47
|
+
when Hash
|
|
48
|
+
fields_for_params(v, namespace: k)
|
|
49
|
+
when Array
|
|
50
|
+
v.map do |v|
|
|
51
|
+
{ "#{k}[]" => v }
|
|
52
|
+
end
|
|
53
|
+
when nil
|
|
54
|
+
{ k => "" }
|
|
55
|
+
else
|
|
56
|
+
raise TypeError, "Cannot convert #{v.class} value: #{v.inspect}"
|
|
57
|
+
end
|
|
58
|
+
end.compact
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Helper method to render a filter form
|
|
62
|
+
def active_admin_filters_form_for(search, filters, options = {})
|
|
63
|
+
defaults = { builder: ActiveAdmin::Filters::FormBuilder, url: collection_path, html: { class: "filters-form" } }
|
|
64
|
+
required = { html: { method: :get }, as: :q }
|
|
65
|
+
options = defaults.deep_merge(options).deep_merge(required)
|
|
66
|
+
|
|
67
|
+
form_for search, options do |f|
|
|
68
|
+
f.template.concat hidden_field_tags_for(params, except: except_hidden_fields)
|
|
69
|
+
|
|
70
|
+
filters.each do |attribute, opts|
|
|
71
|
+
next if opts.key?(:if) && !call_method_or_proc_on(self, opts[:if])
|
|
72
|
+
next if opts.key?(:unless) && call_method_or_proc_on(self, opts[:unless])
|
|
73
|
+
|
|
74
|
+
filter_opts = opts.except(:if, :unless)
|
|
75
|
+
filter_opts[:input_html] = instance_exec(&filter_opts[:input_html]) if filter_opts[:input_html].is_a?(Proc)
|
|
76
|
+
|
|
77
|
+
f.filter attribute, filter_opts
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
buttons = content_tag :div, class: "filters-form-buttons" do
|
|
81
|
+
f.submit(I18n.t("active_admin.filters.buttons.filter"), class: "filters-form-submit") +
|
|
82
|
+
link_to(I18n.t("active_admin.filters.buttons.clear"), collection_path, class: "filters-form-clear")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
f.template.concat buttons
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def except_hidden_fields
|
|
92
|
+
[:q, :page]
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module ActiveAdmin
|
|
3
|
+
module IndexHelper
|
|
4
|
+
def scope_name(scope)
|
|
5
|
+
case scope.name
|
|
6
|
+
when Proc then
|
|
7
|
+
self.instance_exec(&scope.name).to_s
|
|
8
|
+
else
|
|
9
|
+
scope.name.to_s
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def batch_actions_to_display
|
|
14
|
+
@batch_actions_to_display ||= begin
|
|
15
|
+
if active_admin_config && active_admin_config.batch_actions.any?
|
|
16
|
+
active_admin_config.batch_actions.select do |batch_action|
|
|
17
|
+
call_method_or_proc_on(self, batch_action.display_if_block)
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
[]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# 1. removes `select` and `order` to prevent invalid SQL
|
|
26
|
+
# 2. correctly handles the Hash returned when `group by` is used
|
|
27
|
+
def collection_size(c = collection)
|
|
28
|
+
return c.count if c.is_a?(Array)
|
|
29
|
+
return c.length if c.limit_value
|
|
30
|
+
|
|
31
|
+
c = c.except :select, :order
|
|
32
|
+
|
|
33
|
+
c.group_values.present? ? c.count.count : c.count
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def collection_empty?(c = collection)
|
|
37
|
+
collection_size(c) == 0
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module ActiveAdmin
|
|
3
|
+
module LayoutHelper
|
|
4
|
+
# Returns the current Active Admin application instance
|
|
5
|
+
def active_admin_application
|
|
6
|
+
ActiveAdmin.application
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def set_page_title(title)
|
|
10
|
+
@page_title = title
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def site_title
|
|
14
|
+
# Prioritize namespace and account for Devise views where namespace is not available
|
|
15
|
+
namespace = active_admin_namespace if respond_to?(:active_admin_namespace)
|
|
16
|
+
(namespace || active_admin_application).site_title(self)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def html_head_site_title(separator: "-")
|
|
20
|
+
"#{@page_title || page_title} #{separator} #{site_title}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def action_items_for_action
|
|
24
|
+
@action_items_for_action ||= begin
|
|
25
|
+
if active_admin_config&.action_items?
|
|
26
|
+
active_admin_config.action_items_for(params[:action], self)
|
|
27
|
+
else
|
|
28
|
+
[]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def sidebar_sections_for_action
|
|
34
|
+
@sidebar_sections_for_action ||= begin
|
|
35
|
+
if active_admin_config&.sidebar_sections?
|
|
36
|
+
active_admin_config.sidebar_sections_for(params[:action], self)
|
|
37
|
+
else
|
|
38
|
+
[]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def skip_sidebar!
|
|
44
|
+
@skip_sidebar = true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def skip_sidebar?
|
|
48
|
+
@skip_sidebar == true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def flash_messages
|
|
52
|
+
@flash_messages ||= flash.to_hash.except(*active_admin_application.flash_keys_to_except)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def url_for_comments(*args)
|
|
56
|
+
parts = []
|
|
57
|
+
parts << active_admin_namespace.name unless active_admin_namespace.root?
|
|
58
|
+
parts << active_admin_namespace.comments_registration_name.underscore
|
|
59
|
+
parts << "path"
|
|
60
|
+
send parts.join("_"), *args
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
|
|
3
|
+
const submitForm = function() {
|
|
4
|
+
let form = document.getElementById("collection_selection")
|
|
5
|
+
if (form) {
|
|
6
|
+
form.submit()
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const batchActionClick = function(event) {
|
|
11
|
+
event.preventDefault()
|
|
12
|
+
let batchAction = document.getElementById("batch_action")
|
|
13
|
+
if (batchAction) {
|
|
14
|
+
batchAction.value = this.dataset.action
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!event.target.dataset.confirm && !event.target.dataset.modalTarget) { submitForm() }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const batchActionConfirmComplete = function(event) {
|
|
21
|
+
event.preventDefault()
|
|
22
|
+
if (event.detail[0] === true) {
|
|
23
|
+
let batchAction = document.getElementById("batch_action")
|
|
24
|
+
if (batchAction) {
|
|
25
|
+
batchAction.value = this.dataset.action
|
|
26
|
+
}
|
|
27
|
+
submitForm()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const batchActionFormSubmit = function(event) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
let json = JSON.stringify(Object.fromEntries(new FormData(this).entries()));
|
|
34
|
+
let inputsField = document.getElementById('batch_action_inputs')
|
|
35
|
+
let form = document.getElementById("collection_selection")
|
|
36
|
+
if (json && inputsField && form) {
|
|
37
|
+
inputsField.value = json
|
|
38
|
+
form.submit()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Rails.delegate(document, "[data-batch-action-item]", "confirm:complete", batchActionConfirmComplete)
|
|
43
|
+
Rails.delegate(document, "[data-batch-action-item]", "click", batchActionClick)
|
|
44
|
+
Rails.delegate(document, "form[data-batch-action-form]", "submit", batchActionFormSubmit)
|
|
45
|
+
|
|
46
|
+
const disableDropdown = function(condition) {
|
|
47
|
+
const button = document.querySelector(".batch-actions-dropdown-toggle")
|
|
48
|
+
if (button) {
|
|
49
|
+
button.disabled = condition
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const toggleAllChange = function(event) {
|
|
54
|
+
const checkboxes = document.querySelectorAll(".batch-actions-resource-selection")
|
|
55
|
+
for (const checkbox of checkboxes) {
|
|
56
|
+
checkbox.checked = this.checked
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const rows = document.querySelectorAll(".paginated-collection tbody tr")
|
|
60
|
+
for (const row of rows) {
|
|
61
|
+
row.classList.toggle("selected", this.checked);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
disableDropdown(!this.checked)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Rails.delegate(document, ".batch-actions-toggle-all", "change", toggleAllChange)
|
|
68
|
+
|
|
69
|
+
const toggleCheckboxChange = function(event) {
|
|
70
|
+
const numChecked = document.querySelectorAll(".batch-actions-resource-selection:checked").length;
|
|
71
|
+
const allChecked = numChecked === document.querySelectorAll(".batch-actions-resource-selection").length;
|
|
72
|
+
const someChecked = (numChecked > 0) && (numChecked < document.querySelectorAll(".batch-actions-resource-selection").length);
|
|
73
|
+
|
|
74
|
+
const toggleAll = document.querySelector(".batch-actions-toggle-all")
|
|
75
|
+
if (toggleAll) {
|
|
76
|
+
toggleAll.checked = allChecked
|
|
77
|
+
toggleAll.indeterminate = someChecked
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
disableDropdown(numChecked === 0)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Rails.delegate(document, ".batch-actions-resource-selection", "change", toggleCheckboxChange)
|
|
84
|
+
|
|
85
|
+
const tableRowClick = function(event) {
|
|
86
|
+
const type = event.target.type;
|
|
87
|
+
if (typeof type === "undefined" || (type !== "checkbox" && type !== "button" && type !== "")) {
|
|
88
|
+
const checkbox = event.target.closest("tr").querySelector("input[type=checkbox]")
|
|
89
|
+
if (checkbox) {
|
|
90
|
+
checkbox.click()
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Rails.delegate(document, ".paginated-collection tbody td", "click", tableRowClick)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
|
|
3
|
+
const THEME_KEY = "theme";
|
|
4
|
+
const darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)');
|
|
5
|
+
|
|
6
|
+
const setTheme = () => {
|
|
7
|
+
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
|
|
8
|
+
if (localStorage.getItem(THEME_KEY) === 'dark' || (!(THEME_KEY in localStorage) && darkModeMedia.matches)) {
|
|
9
|
+
document.documentElement.classList.add('dark');
|
|
10
|
+
} else {
|
|
11
|
+
document.documentElement.classList.remove('dark');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Detect when user changes their system level preference to set theme.
|
|
16
|
+
darkModeMedia.addEventListener("change", setTheme);
|
|
17
|
+
|
|
18
|
+
// When the page loads, set theme. By default, uses the system preference.
|
|
19
|
+
document.addEventListener("DOMContentLoaded", setTheme);
|
|
20
|
+
|
|
21
|
+
// If user deletes the Local Storage key, then re-apply theme.
|
|
22
|
+
window.addEventListener("storage", (event) => {
|
|
23
|
+
if (event.key === THEME_KEY) {
|
|
24
|
+
setTheme()
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const toggleTheme = () => {
|
|
29
|
+
if (localStorage.getItem(THEME_KEY) === 'dark' || (!(THEME_KEY in localStorage) && darkModeMedia.matches)) {
|
|
30
|
+
localStorage.setItem(THEME_KEY, 'light');
|
|
31
|
+
} else {
|
|
32
|
+
localStorage.setItem(THEME_KEY, 'dark');
|
|
33
|
+
}
|
|
34
|
+
setTheme();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Rails.delegate(document, ".dark-mode-toggle", "click", toggleTheme);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
import { nextSibling } from 'active_admin/utils/dom'
|
|
3
|
+
|
|
4
|
+
const disableEmptyFields = function(event) {
|
|
5
|
+
Array.from(this.querySelectorAll("input, select, textarea"))
|
|
6
|
+
.filter((el) => el.value === "")
|
|
7
|
+
.forEach((el) => el.disabled = true)
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
Rails.delegate(document, ".filters-form", "submit", disableEmptyFields)
|
|
11
|
+
|
|
12
|
+
const setSearchType = function(event) {
|
|
13
|
+
const input = nextSibling(this, "input")
|
|
14
|
+
if (input) {
|
|
15
|
+
input.name = `q[${this.value}]`
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Rails.delegate(document, ".filters-form-field [data-search-methods]", "change", setSearchType)
|
|
20
|
+
|
|
21
|
+
const clearFiltersForm = function(event) {
|
|
22
|
+
event.preventDefault()
|
|
23
|
+
|
|
24
|
+
const regex = /^(q\[|page|utf8|commit)/
|
|
25
|
+
const params = new URLSearchParams(window.location.search)
|
|
26
|
+
|
|
27
|
+
Array.from(params.keys())
|
|
28
|
+
.filter(k => k.match(regex))
|
|
29
|
+
.forEach(k => params.delete(k))
|
|
30
|
+
|
|
31
|
+
window.location.search = params.toString()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Rails.delegate(document, ".filters-form-clear", "click", clearFiltersForm)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
|
|
3
|
+
const hasManyRemoveClick = function(event) {
|
|
4
|
+
event.preventDefault()
|
|
5
|
+
const oldGroup = this.closest("fieldset")
|
|
6
|
+
if (oldGroup) {
|
|
7
|
+
oldGroup.remove()
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Rails.delegate(document, "form .has-many-remove", "click", hasManyRemoveClick)
|
|
12
|
+
|
|
13
|
+
const hasManyAddClick = function(event) {
|
|
14
|
+
event.preventDefault()
|
|
15
|
+
const parent = this.closest(".has-many-container")
|
|
16
|
+
|
|
17
|
+
let index = parseInt(parent.dataset.has_many_index || (parent.querySelectorAll('fieldset').length - 1), 10)
|
|
18
|
+
parent.dataset.has_many_index = ++index
|
|
19
|
+
|
|
20
|
+
const regex = new RegExp(this.dataset.placeholder, 'g')
|
|
21
|
+
const html = this.dataset.html.replace(regex, index)
|
|
22
|
+
|
|
23
|
+
const tempEl = document.createElement("div");
|
|
24
|
+
tempEl.innerHTML = html
|
|
25
|
+
this.before(tempEl.firstChild)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Rails.delegate(document, "form .has-many-add", "click", hasManyAddClick)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
|
|
3
|
+
const toggleMenu = function(event) {
|
|
4
|
+
const parent = this.parentNode
|
|
5
|
+
if (!("open" in parent.dataset)) {
|
|
6
|
+
parent.dataset.open = ""
|
|
7
|
+
} else {
|
|
8
|
+
delete parent.dataset.open
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Rails.delegate(document, "#main-menu [data-menu-button]", "click", toggleMenu)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Rails from '@rails/ujs';
|
|
2
|
+
|
|
3
|
+
const setPerPage = function(event) {
|
|
4
|
+
const params = new URLSearchParams(window.location.search)
|
|
5
|
+
params.set("per_page", this.value)
|
|
6
|
+
window.location.search = params
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Rails.delegate(document, ".pagination-per-page", "change", setPerPage)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const nextSibling = function next(element, selector) {
|
|
2
|
+
let sibling = element.nextElementSibling;
|
|
3
|
+
|
|
4
|
+
if (!selector) {
|
|
5
|
+
return sibling;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
while (sibling) {
|
|
9
|
+
if (sibling && sibling.matches(selector)) {
|
|
10
|
+
return sibling;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
sibling = sibling.nextElementSibling;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { nextSibling }
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "flowbite"
|
|
2
|
+
import Rails from "@rails/ujs"
|
|
3
|
+
import "active_admin/features/batch_actions"
|
|
4
|
+
import "active_admin/features/dark_mode_toggle"
|
|
5
|
+
import "active_admin/features/has_many"
|
|
6
|
+
import "active_admin/features/filters"
|
|
7
|
+
import "active_admin/features/main_menu"
|
|
8
|
+
import "active_admin/features/per_page"
|
|
9
|
+
|
|
10
|
+
Rails.start()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<% if flash_messages.present? %>
|
|
2
|
+
<div class="px-2.5 lg:px-5 mb-8">
|
|
3
|
+
<% flash_messages.each do |type, message| %>
|
|
4
|
+
<% if type == "error" %>
|
|
5
|
+
<div class="flex items-center gap-3 p-4 mb-2 rounded-lg bg-red-50 text-red-800 dark:bg-red-800 dark:text-red-300">
|
|
6
|
+
<svg class="w-5 h-5 shrink-0 text-red-400 dark:text-red-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z"/></svg>
|
|
7
|
+
<%= message %>
|
|
8
|
+
</div>
|
|
9
|
+
<% elsif type == "alert" %>
|
|
10
|
+
<div class="flex items-center gap-3 p-4 mb-2 rounded-lg bg-yellow-50 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-300">
|
|
11
|
+
<svg class="w-5 h-5 shrink-0 rtl:-scale-x-100 text-yellow-400 dark:text-yellow-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/></svg>
|
|
12
|
+
<%= message %>
|
|
13
|
+
</div>
|
|
14
|
+
<% elsif type == "notice" %>
|
|
15
|
+
<div class="flex items-center gap-3 p-4 mb-2 rounded-lg bg-green-50 text-green-800 dark:bg-green-800 dark:text-green-300">
|
|
16
|
+
<svg class="w-5 h-5 shrink-0 rtl:-scale-x-100 text-green-400 dark:text-green-300" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"/></svg>
|
|
17
|
+
<%= message %>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
</div>
|
|
22
|
+
<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<%= stylesheet_link_tag "active_admin" %>
|
|
2
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
3
|
+
<%= csrf_meta_tags %>
|
|
4
|
+
<%= csp_meta_tag %>
|
|
5
|
+
<% # On page load or when changing themes, best to add inline in `head` to avoid FOUC %>
|
|
6
|
+
<%= javascript_tag nonce: true do %>
|
|
7
|
+
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
|
8
|
+
document.documentElement.classList.add('dark')
|
|
9
|
+
} else {
|
|
10
|
+
document.documentElement.classList.remove('dark')
|
|
11
|
+
}
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= javascript_importmap_tags "active_admin", importmap: ActiveAdmin.importmap %>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div id="main-menu" class="fixed top-0 xl:top-16 bottom-0 start-0 z-40 w-72 xl:w-60 p-4 overflow-y-auto transition-transform duration-200 -translate-x-full xl:translate-x-0 bg-white dark:bg-gray-950 xl:border-e xl:border-gray-200 xl:dark:border-white/10" tabindex="-1">
|
|
2
|
+
<ul role="list" class="flex flex-1 flex-col space-y-1.5">
|
|
3
|
+
<% current_menu.items(self).each do |item| %>
|
|
4
|
+
<% children = item.items(self).presence %>
|
|
5
|
+
<li <%= current_menu_item?(item) && "data-open" %> class="group" data-item-id="<%= item.id %>">
|
|
6
|
+
<% if children %>
|
|
7
|
+
<button data-menu-button class="text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white flex items-center w-full rounded-md p-2 gap-x-2 text-sm" aria-label="<%= t('active_admin.toggle_section') %>">
|
|
8
|
+
<%= item.label(self) %>
|
|
9
|
+
<svg class="group-data-[open]:rotate-90 group-data-[open]:rtl:-rotate-90 ms-auto h-5 w-5 shrink-0 rtl:-scale-x-100" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
10
|
+
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
|
11
|
+
</svg>
|
|
12
|
+
</button>
|
|
13
|
+
<ul role="list" class="mt-1 space-y-1 hidden group-data-[open]:block">
|
|
14
|
+
<% children.each do |j| %>
|
|
15
|
+
<li data-item-id="<%= j.id %>">
|
|
16
|
+
<%= link_to j.label(self), j.url(self), j.html_options.merge(class: "text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white block rounded-md py-1.5 px-2 text-sm no-underline #{(current_menu_item?(j) ? "bg-gray-100 dark:bg-white/5 text-gray-900 dark:text-white selected" : "")}") %>
|
|
17
|
+
</li>
|
|
18
|
+
<% end %>
|
|
19
|
+
</ul>
|
|
20
|
+
<% elsif url = item.url(self) %>
|
|
21
|
+
<%= link_to item.label(self), url, item.html_options.merge(class: "text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white flex items-center w-full rounded-md p-2 gap-x-2 text-sm no-underline #{(current_menu_item?(item) ? "bg-gray-100 dark:bg-white/5 text-gray-900 dark:text-white selected" : "")}") %>
|
|
22
|
+
<% else %>
|
|
23
|
+
<%= item.label(self) %>
|
|
24
|
+
<% end %>
|
|
25
|
+
</li>
|
|
26
|
+
<% end %>
|
|
27
|
+
</ul>
|
|
28
|
+
</div>
|