alchemy_cms 7.4.5 → 8.0.0.a
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.
Potentially problematic release.
This version of alchemy_cms might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +92 -0
- data/Gemfile +13 -6
- data/README.md +13 -5
- data/alchemy_cms.gemspec +14 -5
- data/app/assets/builds/alchemy/admin/page-select.css +1 -1
- data/app/assets/builds/alchemy/admin/print.css +1 -1
- data/app/assets/builds/alchemy/admin.css +2 -2
- data/app/assets/builds/alchemy/custom-properties.css +1 -1
- data/app/assets/builds/alchemy/welcome.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
- data/app/assets/builds/tinymce/skins/ui/alchemy/content.min.css +1 -0
- data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css +1 -1
- data/app/assets/config/alchemy_manifest.js +0 -2
- data/app/assets/images/alchemy/icons-sprite.svg +1 -0
- data/app/components/alchemy/admin/resource/applied_filter.rb +29 -0
- data/app/components/alchemy/admin/resource/checkbox_filter.rb +36 -0
- data/app/components/alchemy/admin/resource/datepicker_filter.rb +42 -0
- data/app/components/alchemy/admin/resource/select_filter.rb +43 -0
- data/app/components/alchemy/admin/toolbar_button.rb +5 -2
- data/app/components/alchemy/ingredients/number_view.rb +18 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -15
- data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -6
- data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +15 -15
- data/app/controllers/alchemy/admin/picture_descriptions_controller.rb +5 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +10 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +16 -106
- data/app/controllers/alchemy/attachments_controller.rb +43 -14
- data/app/controllers/alchemy/messages_controller.rb +1 -1
- data/app/controllers/alchemy/pages_controller.rb +7 -2
- data/app/controllers/concerns/alchemy/admin/picture_descriptions_form_helper.rb +16 -0
- data/app/controllers/concerns/alchemy/admin/resource_filter.rb +92 -0
- data/app/decorators/alchemy/element_editor.rb +5 -48
- data/app/decorators/alchemy/ingredient_editor.rb +3 -53
- data/app/helpers/alchemy/admin/base_helper.rb +14 -84
- data/app/helpers/alchemy/admin/elements_helper.rb +4 -4
- data/app/helpers/alchemy/admin/pages_helper.rb +1 -1
- data/app/helpers/alchemy/base_helper.rb +0 -30
- data/app/helpers/alchemy/elements_block_helper.rb +0 -14
- data/app/helpers/alchemy/pages_helper.rb +1 -1
- data/{lib → app/helpers}/alchemy/resources_helper.rb +5 -45
- data/app/javascript/alchemy_admin/components/action.js +4 -0
- data/app/javascript/alchemy_admin/components/alchemy_html_element.js +3 -3
- data/app/javascript/alchemy_admin/components/datepicker.js +10 -2
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +7 -7
- data/app/javascript/alchemy_admin/components/element_editor.js +1 -1
- data/app/javascript/alchemy_admin/components/growl.js +1 -0
- data/app/javascript/alchemy_admin/components/index.js +1 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
- data/app/javascript/alchemy_admin/components/tags_autocomplete.js +5 -1
- data/app/javascript/alchemy_admin/components/tinymce.js +4 -2
- data/app/javascript/alchemy_admin/components/update_check.js +42 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +15 -8
- data/app/javascript/alchemy_admin/components/uploader/progress.js +12 -6
- data/app/javascript/alchemy_admin/components/uploader.js +4 -2
- data/app/javascript/alchemy_admin/confirm_dialog.js +27 -57
- data/app/javascript/alchemy_admin/dirty.js +3 -2
- data/app/javascript/alchemy_admin/i18n.js +15 -16
- data/app/javascript/alchemy_admin/initializer.js +1 -49
- data/app/javascript/alchemy_admin/utils/ajax.js +51 -44
- data/app/javascript/alchemy_admin.js +3 -8
- data/app/models/alchemy/admin/filters/base.rb +38 -0
- data/app/models/alchemy/admin/filters/checkbox.rb +24 -0
- data/app/models/alchemy/admin/filters/datepicker.rb +53 -0
- data/app/models/alchemy/admin/filters/select.rb +70 -0
- data/app/models/alchemy/admin/resource_name.rb +27 -0
- data/app/models/alchemy/attachment.rb +51 -34
- data/app/models/alchemy/base_record.rb +2 -0
- data/app/models/alchemy/element/definitions.rb +1 -1
- data/app/models/alchemy/element/element_ingredients.rb +6 -6
- data/app/models/alchemy/element/presenters.rb +3 -12
- data/app/models/alchemy/element.rb +9 -27
- data/app/models/alchemy/element_definition.rb +160 -0
- data/app/models/alchemy/ingredient.rb +10 -43
- data/app/models/alchemy/ingredient_definition.rb +134 -0
- data/app/models/alchemy/ingredient_validator.rb +7 -3
- data/app/models/alchemy/ingredients/number.rb +19 -0
- data/app/models/alchemy/language.rb +0 -14
- data/app/models/alchemy/message.rb +3 -7
- data/app/models/alchemy/node.rb +1 -1
- data/app/models/alchemy/page/{page_layouts.rb → definitions.rb} +12 -19
- data/app/models/alchemy/page/fixed_attributes.rb +1 -1
- data/app/models/alchemy/page/page_elements.rb +13 -14
- data/app/models/alchemy/page/page_natures.rb +7 -7
- data/app/models/alchemy/page/page_scopes.rb +1 -1
- data/app/models/alchemy/page.rb +11 -33
- data/app/models/alchemy/page_definition.rb +115 -0
- data/app/models/alchemy/picture.rb +69 -79
- data/app/models/alchemy/picture_variant.rb +115 -5
- data/{lib → app/models}/alchemy/resource.rb +4 -18
- data/{lib → app/models}/alchemy/searchable_resource.rb +15 -0
- data/app/models/alchemy/site/layout.rb +5 -5
- data/app/models/alchemy/site.rb +0 -15
- data/app/models/alchemy/storage_adapter/active_storage/attachment_url.rb +41 -0
- data/app/models/alchemy/storage_adapter/active_storage/picture_url.rb +55 -0
- data/app/models/alchemy/storage_adapter/active_storage/preprocessor.rb +40 -0
- data/app/models/alchemy/storage_adapter/active_storage.rb +173 -0
- data/app/models/alchemy/{attachment/url.rb → storage_adapter/dragonfly/attachment_url.rb} +12 -12
- data/app/models/alchemy/{picture/url.rb → storage_adapter/dragonfly/picture_url.rb} +28 -12
- data/app/models/alchemy/{picture → storage_adapter/dragonfly}/preprocessor.rb +4 -4
- data/app/models/alchemy/storage_adapter/dragonfly.rb +183 -0
- data/app/models/alchemy/storage_adapter.rb +74 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +19 -6
- data/app/serializers/alchemy/element_serializer.rb +0 -1
- data/app/services/alchemy/dragonfly_to_image_processing.rb +100 -0
- data/app/stylesheets/alchemy/_defaults.scss +3 -0
- data/app/stylesheets/alchemy/_extends.scss +69 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/_mixins.scss +36 -49
- data/app/stylesheets/alchemy/_variables.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/archive.scss +20 -37
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/base.scss +16 -14
- data/app/stylesheets/alchemy/admin/buttons.scss +160 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/clipboard.scss +2 -2
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dashboard.scss +13 -16
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dialogs.scss +23 -16
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/elements.scss +150 -105
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/errors.scss +5 -5
- data/app/stylesheets/alchemy/admin/filters.scss +58 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flatpickr.scss +53 -60
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/form_fields.scss +21 -7
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/forms.scss +31 -19
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/frame.scss +20 -16
- data/app/stylesheets/alchemy/admin/hints.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/icons.scss +10 -1
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/image_library.scss +10 -8
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/images.scss +1 -1
- data/app/stylesheets/alchemy/admin/labels.scss +5 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/lists.scss +3 -3
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/navigation.scss +61 -55
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/nodes.scss +21 -18
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/notices.scss +18 -18
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/page-select.scss +2 -2
- data/app/stylesheets/alchemy/admin/pagination.scss +144 -0
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/preview_window.scss +8 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/print.scss +1 -1
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/resource_info.scss +8 -5
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/search.scss +9 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/selects.scss +49 -37
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/shoelace.scss +5 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/sitemap.scss +38 -33
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tables.scss +6 -4
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tags.scss +6 -4
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/toolbar.scss +12 -6
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/typography.scss +2 -2
- data/app/{assets/stylesheets → stylesheets}/alchemy/admin/upload.scss +7 -5
- data/app/stylesheets/alchemy/admin.scss +44 -0
- data/app/stylesheets/alchemy/custom-properties.css +244 -0
- data/app/stylesheets/alchemy/welcome.scss +75 -0
- data/app/{assets/stylesheets → stylesheets}/tinymce/skins/content/alchemy/content.scss +8 -9
- data/app/stylesheets/tinymce/skins/ui/alchemy/content.scss +1 -0
- data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/skin.scss +133 -136
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +2 -2
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- data/app/views/alchemy/admin/{elements/_clipboard_button.html.erb → clipboard/_button.html.erb} +3 -5
- data/app/views/alchemy/admin/clipboard/_update_nested_element_button.turbo_stream.erb +11 -0
- data/app/views/alchemy/admin/clipboard/clear.turbo_stream.erb +4 -0
- data/app/views/alchemy/admin/clipboard/index.html.erb +15 -13
- data/app/views/alchemy/admin/clipboard/insert.turbo_stream.erb +18 -0
- data/app/views/alchemy/admin/clipboard/remove.turbo_stream.erb +9 -0
- data/app/views/alchemy/admin/dashboard/info.html.erb +17 -31
- data/app/views/alchemy/admin/elements/_element.html.erb +4 -8
- data/app/views/alchemy/admin/elements/_form.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +1 -0
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +4 -6
- data/app/views/alchemy/admin/elements/create.turbo_stream.erb +2 -1
- data/app/views/alchemy/admin/elements/index.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +3 -16
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +0 -9
- data/app/views/alchemy/admin/languages/_form.html.erb +1 -1
- data/app/views/alchemy/admin/languages/_table.html.erb +1 -1
- data/app/views/alchemy/admin/languages/index.html.erb +5 -2
- data/app/views/alchemy/admin/layoutpages/index.html.erb +1 -12
- data/app/views/alchemy/admin/pages/_form.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_page.html.erb +2 -3
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +1 -15
- data/app/views/alchemy/admin/pages/index.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -12
- data/app/views/alchemy/admin/partials/_search_form.html.erb +4 -9
- data/app/views/alchemy/admin/picture_descriptions/_form.html.erb +5 -7
- data/app/views/alchemy/admin/picture_descriptions/edit.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/_archive.html.erb +4 -7
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +2 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_form.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +21 -13
- data/app/views/alchemy/admin/pictures/index.html.erb +2 -7
- data/app/views/alchemy/admin/resources/_applied_filters.html.erb +8 -0
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +11 -21
- data/app/views/alchemy/admin/resources/_pagination.html.erb +6 -0
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +4 -2
- data/app/views/alchemy/admin/resources/_resource_table.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_table_header.html.erb +1 -15
- data/app/views/alchemy/admin/sites/index.html.erb +5 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +8 -0
- data/app/views/alchemy/admin/tags/index.html.erb +1 -1
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +7 -7
- data/app/{javascript/alchemy_admin/locales/en.js → views/alchemy/admin/translations/_en.js} +5 -2
- data/app/views/alchemy/admin/uploader/_button.html.erb +1 -1
- data/app/views/alchemy/admin/uploader/_setup.html.erb +4 -4
- data/app/views/alchemy/base/500.turbo_stream.erb +3 -0
- data/app/views/alchemy/base/redirect.js.erb +1 -1
- data/app/views/alchemy/ingredients/_number_editor.html.erb +24 -0
- data/app/views/alchemy/no_index.html.erb +31 -0
- data/app/views/alchemy/welcome.html.erb +12 -10
- data/app/views/kaminari/alchemy/_first_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_last_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_next_page.html.erb +5 -3
- data/app/views/kaminari/alchemy/_paginator.html.erb +18 -13
- data/app/views/kaminari/alchemy/_prev_page.html.erb +5 -3
- data/app/views/layouts/alchemy/admin.html.erb +5 -9
- data/bun.lockb +0 -0
- data/bundles/remixicon.mjs +153 -0
- data/config/alchemy/config.yml +3 -2
- data/config/initializers/dragonfly.rb +0 -1
- data/config/initializers/mime_types.rb +1 -0
- data/config/locales/alchemy.en.yml +32 -14
- data/config/routes.rb +0 -2
- data/db/migrate/20250626160259_add_unique_index_to_picture_descriptions.rb +7 -0
- data/eslint.config.js +2 -1
- data/lib/alchemy/admin/preview_url.rb +4 -5
- data/lib/alchemy/cache_digests/template_tracker.rb +6 -9
- data/lib/alchemy/config_missing.rb +14 -0
- data/lib/alchemy/configuration/base_option.rb +24 -0
- data/lib/alchemy/configuration/boolean_option.rb +16 -0
- data/lib/alchemy/configuration/class_option.rb +15 -0
- data/lib/alchemy/configuration/class_set_option.rb +46 -0
- data/lib/alchemy/configuration/integer_list_option.rb +13 -0
- data/lib/alchemy/configuration/integer_option.rb +12 -0
- data/lib/alchemy/configuration/list_option.rb +22 -0
- data/lib/alchemy/configuration/regexp_option.rb +11 -0
- data/lib/alchemy/configuration/string_list_option.rb +13 -0
- data/lib/alchemy/configuration/string_option.rb +11 -0
- data/lib/alchemy/configuration.rb +115 -0
- data/lib/alchemy/configuration_methods.rb +3 -1
- data/lib/alchemy/configurations/default_language.rb +12 -0
- data/lib/alchemy/configurations/default_site.rb +10 -0
- data/lib/alchemy/configurations/format_matchers.rb +11 -0
- data/lib/alchemy/configurations/mailer.rb +16 -0
- data/lib/alchemy/configurations/main.rb +216 -0
- data/lib/alchemy/configurations/preview.rb +32 -0
- data/lib/alchemy/configurations/sitemap.rb +10 -0
- data/lib/alchemy/configurations/uploader.rb +34 -0
- data/lib/alchemy/engine.rb +65 -17
- data/lib/alchemy/hints.rb +3 -7
- data/lib/alchemy/on_page_layout.rb +2 -2
- data/lib/alchemy/propshaft/tinymce_asset.rb +15 -0
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/tasks/usage.rb +4 -4
- data/lib/alchemy/test_support/config_stubbing.rb +1 -7
- data/lib/alchemy/test_support/factories/attachment_factory.rb +13 -2
- data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/page_factory.rb +2 -3
- data/lib/alchemy/test_support/factories/picture_factory.rb +30 -2
- data/lib/alchemy/test_support/factories/site_factory.rb +2 -2
- data/lib/alchemy/test_support/having_crop_action_examples.rb +2 -2
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +80 -26
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +5 -5
- data/lib/alchemy/upgrader/.keep +0 -0
- data/lib/alchemy/upgrader/eight_zero.rb +14 -0
- data/lib/alchemy/upgrader.rb +33 -20
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +192 -170
- data/lib/alchemy_cms.rb +1 -7
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +0 -3
- data/lib/generators/alchemy/install/files/_article.html.erb +6 -4
- data/lib/generators/alchemy/install/files/alchemy.en.yml +22 -3
- data/lib/generators/alchemy/install/files/application.html.erb +5 -0
- data/lib/generators/alchemy/install/install_generator.rb +5 -14
- data/lib/generators/alchemy/install/templates/alchemy.rb.tt +196 -0
- data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +0 -1
- data/lib/generators/alchemy/install/templates/elements.yml.tt +3 -1
- data/lib/generators/alchemy/install/templates/menus.yml.tt +1 -1
- data/lib/generators/alchemy/install/templates/page_layouts.yml.tt +2 -2
- data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +2 -2
- data/lib/tasks/alchemy/assets.rake +14 -0
- data/lib/tasks/alchemy/upgrade.rake +12 -47
- data/vendor/javascript/tinymce.min.js +1 -1
- data/vitest.config.js +21 -0
- metadata +184 -180
- data/app/assets/builds/alchemy/admin/page-select.css.map +0 -1
- data/app/assets/builds/alchemy/admin/print.css.map +0 -1
- data/app/assets/builds/alchemy/admin.css.map +0 -1
- data/app/assets/builds/alchemy/custom-properties.css.map +0 -1
- data/app/assets/builds/alchemy/welcome.css.map +0 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css.map +0 -1
- data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css.map +0 -1
- data/app/assets/javascripts/alchemy/admin.js +0 -10
- data/app/assets/stylesheets/alchemy/_defaults.scss +0 -3
- data/app/assets/stylesheets/alchemy/_deprecated_variables.scss +0 -45
- data/app/assets/stylesheets/alchemy/_deprecation.scss +0 -17
- data/app/assets/stylesheets/alchemy/_extends.scss +0 -62
- data/app/assets/stylesheets/alchemy/_variables.scss +0 -201
- data/app/assets/stylesheets/alchemy/admin/buttons.scss +0 -124
- data/app/assets/stylesheets/alchemy/admin/hints.scss +0 -5
- data/app/assets/stylesheets/alchemy/admin/labels.scss +0 -3
- data/app/assets/stylesheets/alchemy/admin/pagination.scss +0 -92
- data/app/assets/stylesheets/alchemy/admin.scss +0 -42
- data/app/assets/stylesheets/alchemy/custom-properties.css +0 -98
- data/app/assets/stylesheets/alchemy/welcome.scss +0 -57
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.css +0 -711
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.css +0 -705
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.css +0 -29
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.min.css +0 -7
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.css +0 -677
- data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.min.css +0 -7
- data/app/controllers/alchemy/elements_controller.rb +0 -32
- data/app/models/alchemy/element/dom_id.rb +0 -31
- data/app/models/alchemy/picture/calculations.rb +0 -49
- data/app/models/alchemy/picture/transformations.rb +0 -115
- data/app/views/alchemy/admin/attachments/destroy.js.erb +0 -1
- data/app/views/alchemy/admin/clipboard/clear.js.erb +0 -3
- data/app/views/alchemy/admin/clipboard/insert.js.erb +0 -29
- data/app/views/alchemy/admin/clipboard/remove.js.erb +0 -10
- data/app/views/alchemy/admin/resources/_filter.html.erb +0 -12
- data/app/views/alchemy/admin/resources/_resource.html.erb +0 -34
- data/app/views/alchemy/admin/resources/_table.html.erb +0 -29
- data/app/views/alchemy/elements/show.html.erb +0 -1
- data/app/views/alchemy/elements/show.js.erb +0 -1
- data/app/views/alchemy/ingredients/_audio_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_boolean_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_datetime_view.html.erb +0 -3
- data/app/views/alchemy/ingredients/_file_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_headline_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_html_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_link_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_node_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_page_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_picture_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_richtext_view.html.erb +0 -3
- data/app/views/alchemy/ingredients/_select_view.html.erb +0 -1
- data/app/views/alchemy/ingredients/_text_view.html.erb +0 -4
- data/app/views/alchemy/ingredients/_video_view.html.erb +0 -3
- data/babel.config.js +0 -12
- data/config/initializers/assets.rb +0 -4
- data/lib/alchemy/config.rb +0 -114
- data/lib/alchemy/element_definition.rb +0 -73
- data/lib/alchemy/page_layout.rb +0 -73
- data/lib/alchemy/resource_filter.rb +0 -40
- data/lib/alchemy/upgrader/seven_point_four.rb +0 -26
- data/lib/alchemy/upgrader/seven_point_three.rb +0 -52
- data/lib/generators/alchemy/ingredient/templates/view.html.erb +0 -1
- data/lib/generators/alchemy/install/files/alchemy_admin.js +0 -1
- data/lib/generators/alchemy/install/files/all.js +0 -11
- data/lib/generators/alchemy/install/files/article.css +0 -25
- data/vendor/assets/images/remixicon.symbol.svg +0 -11
- /data/app/{assets/stylesheets → stylesheets}/alchemy/_fonts.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/attachment-select.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/attachments.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flash.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/list_filter.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/node-select.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/spinner.scss +0 -0
- /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/skintool.json +0 -0
- /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/fonts/tinymce-mobile.woff +0 -0
@@ -14,7 +14,7 @@ module Alchemy
|
|
14
14
|
#
|
15
15
|
# @return Array<Alchemy::IngredientEditor>
|
16
16
|
def ingredients
|
17
|
-
|
17
|
+
ingredient_definitions.map do |ingredient|
|
18
18
|
Alchemy::IngredientEditor.new(find_or_create_ingredient(ingredient))
|
19
19
|
end
|
20
20
|
end
|
@@ -22,7 +22,7 @@ module Alchemy
|
|
22
22
|
# Are any ingredients defined?
|
23
23
|
# @return [Boolean]
|
24
24
|
def has_ingredients_defined?
|
25
|
-
|
25
|
+
ingredient_definitions.any?
|
26
26
|
end
|
27
27
|
|
28
28
|
# Returns the translated ingredient group for displaying in admin editor group headings
|
@@ -77,56 +77,13 @@ module Alchemy
|
|
77
77
|
super
|
78
78
|
end
|
79
79
|
|
80
|
-
# Returns a deprecation notice for elements marked deprecated
|
81
|
-
#
|
82
|
-
# You can either use localizations or pass a String as notice
|
83
|
-
# in the element definition.
|
84
|
-
#
|
85
|
-
# == Custom deprecation notices
|
86
|
-
#
|
87
|
-
# Use general element deprecation notice
|
88
|
-
#
|
89
|
-
# - name: old_element
|
90
|
-
# deprecated: true
|
91
|
-
#
|
92
|
-
# Add a translation to your locale file for a per element notice.
|
93
|
-
#
|
94
|
-
# en:
|
95
|
-
# alchemy:
|
96
|
-
# element_deprecation_notices:
|
97
|
-
# old_element: Foo baz widget is deprecated
|
98
|
-
#
|
99
|
-
# or use the global translation that apply to all deprecated elements.
|
100
|
-
#
|
101
|
-
# en:
|
102
|
-
# alchemy:
|
103
|
-
# element_deprecation_notice: Foo baz widget is deprecated
|
104
|
-
#
|
105
|
-
# or pass string as deprecation notice.
|
106
|
-
#
|
107
|
-
# - name: old_element
|
108
|
-
# deprecated: This element will be removed soon.
|
109
|
-
#
|
110
|
-
def deprecation_notice
|
111
|
-
case definition["deprecated"]
|
112
|
-
when String
|
113
|
-
definition["deprecated"]
|
114
|
-
when TrueClass
|
115
|
-
Alchemy.t(
|
116
|
-
name,
|
117
|
-
scope: :element_deprecation_notices,
|
118
|
-
default: Alchemy.t(:element_deprecated)
|
119
|
-
)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
80
|
private
|
124
81
|
|
125
82
|
def find_or_create_ingredient(definition)
|
126
|
-
element.ingredients.detect {
|
83
|
+
element.ingredients.detect { _1.role == definition.role } ||
|
127
84
|
element.ingredients.create!(
|
128
|
-
role: definition
|
129
|
-
type: Alchemy::Ingredient.normalize_type(definition
|
85
|
+
role: definition.role,
|
86
|
+
type: Alchemy::Ingredient.normalize_type(definition.type)
|
130
87
|
)
|
131
88
|
end
|
132
89
|
end
|
@@ -99,62 +99,12 @@ module Alchemy
|
|
99
99
|
Logger.warn("ingredient #{role} is missing its definition", caller(1..1))
|
100
100
|
Alchemy.t(:ingredient_definition_missing)
|
101
101
|
else
|
102
|
-
deprecation_notice
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Returns a deprecation notice for ingredients marked deprecated
|
107
|
-
#
|
108
|
-
# You can either use localizations or pass a String as notice
|
109
|
-
# in the ingredient definition.
|
110
|
-
#
|
111
|
-
# == Custom deprecation notices
|
112
|
-
#
|
113
|
-
# Use general ingredient deprecation notice
|
114
|
-
#
|
115
|
-
# - name: element_name
|
116
|
-
# ingredients:
|
117
|
-
# - role: old_ingredient
|
118
|
-
# type: Text
|
119
|
-
# deprecated: true
|
120
|
-
#
|
121
|
-
# Add a translation to your locale file for a per ingredient notice.
|
122
|
-
#
|
123
|
-
# en:
|
124
|
-
# alchemy:
|
125
|
-
# ingredient_deprecation_notices:
|
126
|
-
# element_name:
|
127
|
-
# old_ingredient: Foo baz widget is deprecated
|
128
|
-
#
|
129
|
-
# or use the global translation that apply to all deprecated ingredients.
|
130
|
-
#
|
131
|
-
# en:
|
132
|
-
# alchemy:
|
133
|
-
# ingredient_deprecation_notice: Foo baz widget is deprecated
|
134
|
-
#
|
135
|
-
# or pass string as deprecation notice.
|
136
|
-
#
|
137
|
-
# - name: element_name
|
138
|
-
# ingredients:
|
139
|
-
# - role: old_ingredient
|
140
|
-
# type: Text
|
141
|
-
# deprecated: This ingredient will be removed soon.
|
142
|
-
#
|
143
|
-
def deprecation_notice
|
144
|
-
case definition[:deprecated]
|
145
|
-
when String
|
146
|
-
definition[:deprecated]
|
147
|
-
when TrueClass
|
148
|
-
Alchemy.t(
|
149
|
-
role,
|
150
|
-
scope: [:ingredient_deprecation_notices, element.name],
|
151
|
-
default: Alchemy.t(:ingredient_deprecated)
|
152
|
-
)
|
102
|
+
definition.deprecation_notice(element_name: element&.name)
|
153
103
|
end
|
154
104
|
end
|
155
105
|
|
156
106
|
def validations
|
157
|
-
definition.
|
107
|
+
definition.validate
|
158
108
|
end
|
159
109
|
|
160
110
|
def format_validation
|
@@ -173,7 +123,7 @@ module Alchemy
|
|
173
123
|
private
|
174
124
|
|
175
125
|
def form_field_counter
|
176
|
-
element.
|
126
|
+
element.ingredient_definitions.index { _1.role == role }
|
177
127
|
end
|
178
128
|
end
|
179
129
|
end
|
@@ -73,6 +73,13 @@ module Alchemy
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
def alchemy_admin_js_translations(locale = ::I18n.locale)
|
77
|
+
render partial: "alchemy/admin/translations/#{locale}", formats: [:js]
|
78
|
+
rescue ActionView::MissingTemplate
|
79
|
+
# Fallback to default translations
|
80
|
+
render partial: "alchemy/admin/translations/en", formats: [:js]
|
81
|
+
end
|
82
|
+
|
76
83
|
# Used for site selector in Alchemy cockpit.
|
77
84
|
def sites_for_select
|
78
85
|
Alchemy::Site.all.map do |site|
|
@@ -80,36 +87,6 @@ module Alchemy
|
|
80
87
|
end
|
81
88
|
end
|
82
89
|
|
83
|
-
# Returns a javascript driven live filter for lists.
|
84
|
-
#
|
85
|
-
# The items must have a html +name+ attribute that holds the filterable value.
|
86
|
-
#
|
87
|
-
# == Example
|
88
|
-
#
|
89
|
-
# Given a list of items:
|
90
|
-
#
|
91
|
-
# <%= js_filter_field('#products .product') %>
|
92
|
-
#
|
93
|
-
# <ul id="products">
|
94
|
-
# <li class="product" name="kat litter">Kat Litter</li>
|
95
|
-
# <li class="product" name="milk">Milk</li>
|
96
|
-
# </ul>
|
97
|
-
#
|
98
|
-
# @param [String] items
|
99
|
-
# A jquery compatible selector string that represents the items to filter
|
100
|
-
# @param [Hash] options
|
101
|
-
# HTML options passed to the input field
|
102
|
-
#
|
103
|
-
# @option options [String] :class ('js_filter_field')
|
104
|
-
# The css class of the <input> tag
|
105
|
-
# @option options [String or Hash] :data ({'alchemy-list-filter' => items})
|
106
|
-
# A HTML data attribute that holds the jQuery selector that represents the list to be filtered
|
107
|
-
# @deprecated render Alchemy::Admin::ListFilter.new(items) instead
|
108
|
-
def js_filter_field(items, _options = {})
|
109
|
-
render Alchemy::Admin::ListFilter.new(items)
|
110
|
-
end
|
111
|
-
deprecate js_filter_field: "render Alchemy::Admin::ListFilter.new(items) instead", deprecator: Alchemy::Deprecation
|
112
|
-
|
113
90
|
# Returns a link that opens a modal confirmation to delete window.
|
114
91
|
#
|
115
92
|
# === Example:
|
@@ -137,12 +114,10 @@ module Alchemy
|
|
137
114
|
def link_to_confirm_dialog(link_string = "", message = "", url = "", html_options = {})
|
138
115
|
link_to(link_string, url,
|
139
116
|
html_options.merge(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
cancel_label: Alchemy.t("No")
|
145
|
-
}.to_json
|
117
|
+
data: {
|
118
|
+
"turbo-method": :delete,
|
119
|
+
"turbo-confirm": message
|
120
|
+
}
|
146
121
|
))
|
147
122
|
end
|
148
123
|
|
@@ -168,12 +143,10 @@ module Alchemy
|
|
168
143
|
def button_with_confirm(value = "", url = "", options = {}, html_options = {})
|
169
144
|
options = {
|
170
145
|
message: Alchemy.t(:confirm_to_proceed),
|
171
|
-
|
172
|
-
title: Alchemy.t(:please_confirm),
|
173
|
-
cancel_label: Alchemy.t("No")
|
146
|
+
title: Alchemy.t(:please_confirm)
|
174
147
|
}.merge(options)
|
175
148
|
form_tag url, {method: html_options.delete(:method), class: "button-with-confirm"} do
|
176
|
-
button_tag value, html_options.merge("data-
|
149
|
+
button_tag value, html_options.merge("data-turbo-confirm" => options[:message])
|
177
150
|
end
|
178
151
|
end
|
179
152
|
|
@@ -220,49 +193,6 @@ module Alchemy
|
|
220
193
|
"Alchemy CMS - #{title}"
|
221
194
|
end
|
222
195
|
|
223
|
-
# Renders a toolbar button for the Alchemy toolbar
|
224
|
-
#
|
225
|
-
# == Example
|
226
|
-
#
|
227
|
-
# <%= toolbar_button(
|
228
|
-
# icon: :plus,
|
229
|
-
# label: 'Create',
|
230
|
-
# url: new_resource_path,
|
231
|
-
# title: 'Create Resource',
|
232
|
-
# hotkey: 'alt+n',
|
233
|
-
# dialog_options: {
|
234
|
-
# title: 'Create Resource',
|
235
|
-
# size: "430x400"
|
236
|
-
# },
|
237
|
-
# if_permitted_to: [:create, resource_model]
|
238
|
-
# ) %>
|
239
|
-
#
|
240
|
-
# @option options [String] :icon
|
241
|
-
# Icon class. See +app/assets/stylesheets/alchemy/icons.css.sccs+ for available icons, or make your own.
|
242
|
-
# @option options [String] :label
|
243
|
-
# Text for button label.
|
244
|
-
# @option options [String] :url
|
245
|
-
# Url for link.
|
246
|
-
# @option options [String] :title
|
247
|
-
# Text for title tag.
|
248
|
-
# @option options [String] :hotkey
|
249
|
-
# Keyboard shortcut for this button. I.E +alt-n+
|
250
|
-
# @option options [Boolean] :dialog (true)
|
251
|
-
# Open the link in a modal dialog.
|
252
|
-
# @option options [Hash] :dialog_options
|
253
|
-
# Overlay options. See link_to_dialog helper.
|
254
|
-
# @option options [Array] :if_permitted_to ([:action, :controller])
|
255
|
-
# Check permission for button. Exactly how you defined the permission in your +authorization_rules.rb+. Defaults to controller and action from button url.
|
256
|
-
# @option options [Boolean] :skip_permission_check (false)
|
257
|
-
# Skip the permission check. NOT RECOMMENDED!
|
258
|
-
# @option options [Boolean] :loading_indicator (true)
|
259
|
-
# Shows the please wait dialog while loading. Only for buttons not opening an dialog.
|
260
|
-
# @deprecated render Alchemy::Admin::ToolbarButton.new instead
|
261
|
-
def toolbar_button(options = {})
|
262
|
-
render Alchemy::Admin::ToolbarButton.new(**options)
|
263
|
-
end
|
264
|
-
deprecate toolbar_button: "render Alchemy::Admin::ToolbarButton.new instead", deprecator: Alchemy::Deprecation
|
265
|
-
|
266
196
|
# Renders a textfield ready to display a datepicker
|
267
197
|
#
|
268
198
|
# A Javascript observer converts this into a fancy Datepicker.
|
@@ -346,7 +276,7 @@ module Alchemy
|
|
346
276
|
|
347
277
|
# Returns the regular expression used for external url validation in link dialog.
|
348
278
|
def link_url_regexp
|
349
|
-
Alchemy
|
279
|
+
Alchemy.config.format_matchers.link_url || /^(mailto:|\/|[a-z]+:\/\/)/
|
350
280
|
end
|
351
281
|
|
352
282
|
# Renders a hint with tooltip
|
@@ -13,12 +13,12 @@ module Alchemy
|
|
13
13
|
def elements_for_select(elements)
|
14
14
|
return [] if elements.nil?
|
15
15
|
|
16
|
-
elements.
|
16
|
+
elements.map do |e|
|
17
17
|
[
|
18
|
-
Element.display_name_for(e
|
19
|
-
e
|
18
|
+
Element.display_name_for(e.name),
|
19
|
+
e.name
|
20
20
|
]
|
21
|
-
end.sort
|
21
|
+
end.tap(&:sort!)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -10,7 +10,7 @@ module Alchemy
|
|
10
10
|
# You can configure the screen sizes in your +config/alchemy/config.yml+.
|
11
11
|
#
|
12
12
|
def preview_sizes_for_select
|
13
|
-
Alchemy
|
13
|
+
Alchemy.config.page_preview_sizes.map do |size|
|
14
14
|
[Alchemy.t(size, scope: "preview_sizes"), size]
|
15
15
|
end
|
16
16
|
end
|
@@ -2,14 +2,6 @@
|
|
2
2
|
|
3
3
|
module Alchemy
|
4
4
|
module BaseHelper
|
5
|
-
# An alias for truncate.
|
6
|
-
# Left here for downwards compatibilty.
|
7
|
-
# @deprecated
|
8
|
-
def shorten(text, length)
|
9
|
-
text.truncate(length: length)
|
10
|
-
end
|
11
|
-
deprecate :shorten, deprecator: Alchemy::Deprecation
|
12
|
-
|
13
5
|
# Logs a message in the Rails logger (warn level)
|
14
6
|
# and optionally displays an error message to the user.
|
15
7
|
def warning(message, text = nil)
|
@@ -45,27 +37,5 @@ module Alchemy
|
|
45
37
|
def render_message(type = :info, msg = nil, &)
|
46
38
|
render Alchemy::Admin::Message.new(msg || capture(&), type: type)
|
47
39
|
end
|
48
|
-
|
49
|
-
# Checks if the given argument is a String or a Page object.
|
50
|
-
# If a String is given, it tries to find the page via page_layout
|
51
|
-
# Logs a warning if no page is given.
|
52
|
-
# @deprecated
|
53
|
-
def page_or_find(page)
|
54
|
-
unless Current.language
|
55
|
-
warning("No default language set up")
|
56
|
-
return nil
|
57
|
-
end
|
58
|
-
|
59
|
-
if page.is_a?(String)
|
60
|
-
page = Current.language.pages.find_by(page_layout: page)
|
61
|
-
end
|
62
|
-
if page.blank?
|
63
|
-
warning("No Page found for #{page.inspect}")
|
64
|
-
nil
|
65
|
-
else
|
66
|
-
page
|
67
|
-
end
|
68
|
-
end
|
69
|
-
deprecate :page_or_find, deprecator: Alchemy::Deprecation
|
70
40
|
end
|
71
41
|
end
|
@@ -100,22 +100,8 @@ module Alchemy
|
|
100
100
|
# A lambda used for formatting the element's tags (see Alchemy::ElementsHelper::element_tags_attributes). Set to +false+ to not include tags in the wrapper element.
|
101
101
|
#
|
102
102
|
def element_view_for(element, options = {})
|
103
|
-
if options[:id].nil?
|
104
|
-
Alchemy::Deprecation.warn <<~WARN
|
105
|
-
Relying on an implicit DOM id in `element_view_for` is deprecated. Please provide an explicit `id` if you actually want to render an `id` attribute on the #{element.name} element wrapper tag.
|
106
|
-
WARN
|
107
|
-
end
|
108
|
-
|
109
|
-
if options[:class].nil?
|
110
|
-
Alchemy::Deprecation.warn <<~WARN
|
111
|
-
Relying on an implicit CSS class in `element_view_for` is deprecated. Please provide an explicit `class` for the #{element.name} element wrapper tag.
|
112
|
-
WARN
|
113
|
-
end
|
114
|
-
|
115
103
|
options = {
|
116
104
|
tag: :div,
|
117
|
-
id: (!!options[:id]) ? options[:id] : element.dom_id,
|
118
|
-
class: element.name,
|
119
105
|
tags_formatter: ->(tags) { tags.join(" ") }
|
120
106
|
}.merge(options)
|
121
107
|
|
@@ -46,7 +46,7 @@ module Alchemy
|
|
46
46
|
def render_page_layout
|
47
47
|
render @page, page: @page
|
48
48
|
rescue ActionView::MissingTemplate
|
49
|
-
warning("
|
49
|
+
warning("[alchemy]: '#{@page.page_layout}' page layout not found. Rendering 'standard' page layout.")
|
50
50
|
render "alchemy/page_layouts/standard", page: @page
|
51
51
|
end
|
52
52
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Alchemy
|
4
4
|
module ResourcesHelper
|
5
|
+
include Alchemy::Admin::ResourceName
|
6
|
+
|
5
7
|
# = Alchemy::ResourceHelper
|
6
8
|
#
|
7
9
|
# Used to DRY up resource like structures in Alchemy's admin backend in combination with Alchemy::Resource
|
@@ -14,11 +16,11 @@ module Alchemy
|
|
14
16
|
end
|
15
17
|
|
16
18
|
def resource_instance_variable
|
17
|
-
instance_variable_get(:"@#{
|
19
|
+
instance_variable_get(:"@#{resource_name}")
|
18
20
|
end
|
19
21
|
|
20
22
|
def resources_instance_variable
|
21
|
-
instance_variable_get(:"@#{
|
23
|
+
instance_variable_get(:"@#{resources_name}")
|
22
24
|
end
|
23
25
|
|
24
26
|
def resource_url_proxy
|
@@ -46,14 +48,10 @@ module Alchemy
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def edit_resource_path(resource = nil, options = {})
|
49
|
-
path_segments = resource_scope + [resource] ||
|
51
|
+
path_segments = resource_scope + [resource] || resource_array
|
50
52
|
edit_polymorphic_path path_segments, options
|
51
53
|
end
|
52
54
|
|
53
|
-
def resource_name
|
54
|
-
resource_handler.resource_name
|
55
|
-
end
|
56
|
-
|
57
55
|
def resource_model
|
58
56
|
resource_handler.model
|
59
57
|
end
|
@@ -127,44 +125,6 @@ module Alchemy
|
|
127
125
|
resource_handler.resource_relations.collect { |_k, v| v[:name].to_sym }
|
128
126
|
end
|
129
127
|
|
130
|
-
# Returns the attribute's column for sorting
|
131
|
-
#
|
132
|
-
# If the attribute contains a resource_relation, then the table and column for related model will be returned.
|
133
|
-
# @deprecated
|
134
|
-
def sortable_resource_header_column(attribute)
|
135
|
-
if (relation = attribute[:relation])
|
136
|
-
"#{relation[:model_association].name}_#{relation[:attr_method]}"
|
137
|
-
else
|
138
|
-
attribute[:name]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
deprecate sortable_resource_header_column: "Please `render Alchemy::Admin::Resource::Table instead`", deprecator: Alchemy::Deprecation
|
142
|
-
|
143
|
-
# Renders the row for a resource record in the resources table.
|
144
|
-
#
|
145
|
-
# This helper has a nice fallback. If you create a partial for your record then this partial will be rendered.
|
146
|
-
#
|
147
|
-
# Otherwise the default +app/views/alchemy/admin/resources/_resource.html.erb+ partial gets rendered.
|
148
|
-
#
|
149
|
-
# == Example
|
150
|
-
#
|
151
|
-
# For a resource named +Comment+ you can create a partial named +_comment.html.erb+
|
152
|
-
#
|
153
|
-
# # app/views/admin/comments/_comment.html.erb
|
154
|
-
# <tr>
|
155
|
-
# <td><%= comment.title %></td>
|
156
|
-
# <td><%= comment.body %></td>
|
157
|
-
# </tr>
|
158
|
-
#
|
159
|
-
# NOTE: Alchemy gives you a local variable named like your resource
|
160
|
-
# @deprecated
|
161
|
-
def render_resources(icon: nil)
|
162
|
-
render partial: resource_name, collection: resources_instance_variable, locals: {icon: icon}
|
163
|
-
rescue ActionView::MissingTemplate
|
164
|
-
render partial: "resource", collection: resources_instance_variable, locals: {icon: icon}
|
165
|
-
end
|
166
|
-
deprecate render_resources: "Please `render Alchemy::Admin::Resource::Table instead`", deprecator: Alchemy::Deprecation
|
167
|
-
|
168
128
|
def resource_has_tags
|
169
129
|
resource_model.respond_to?(:tag_counts) && resource_model.tag_counts.any?
|
170
130
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { reloadPreview } from "alchemy_admin/components/preview_window"
|
2
|
+
import { removeTab } from "alchemy_admin/fixed_elements"
|
2
3
|
import { closeCurrentDialog } from "alchemy_admin/dialog"
|
3
4
|
import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link"
|
4
5
|
|
@@ -13,6 +14,7 @@ class Action extends HTMLElement {
|
|
13
14
|
// we don't have to implicitly close the dialog
|
14
15
|
closeCurrentDialog,
|
15
16
|
reloadPreview,
|
17
|
+
removeFixedElement: removeTab,
|
16
18
|
updateAnchorIcon: IngredientAnchorLink.updateIcon
|
17
19
|
}
|
18
20
|
}
|
@@ -25,6 +27,8 @@ class Action extends HTMLElement {
|
|
25
27
|
} else {
|
26
28
|
console.error(`Unknown Alchemy action: ${this.name}`)
|
27
29
|
}
|
30
|
+
|
31
|
+
this.remove()
|
28
32
|
}
|
29
33
|
|
30
34
|
get name() {
|
@@ -26,7 +26,7 @@ export class AlchemyHTMLElement extends HTMLElement {
|
|
26
26
|
* this is a default function
|
27
27
|
* @link https://developer.mozilla.org/en-US/docs/Web/API/Web_Components#reference
|
28
28
|
*/
|
29
|
-
connectedCallback() {
|
29
|
+
async connectedCallback() {
|
30
30
|
// parse the properties object and register property with the default values
|
31
31
|
Object.keys(this.constructor.properties).forEach((name) => {
|
32
32
|
// if the options was given via the constructor, they should be prefer (e.g. new <WebComponentName>({title: "Foo"}))
|
@@ -39,7 +39,7 @@ export class AlchemyHTMLElement extends HTMLElement {
|
|
39
39
|
|
40
40
|
// render the component
|
41
41
|
this._updateComponent()
|
42
|
-
this.connected()
|
42
|
+
await this.connected()
|
43
43
|
}
|
44
44
|
|
45
45
|
/**
|
@@ -64,7 +64,7 @@ export class AlchemyHTMLElement extends HTMLElement {
|
|
64
64
|
/**
|
65
65
|
* a connected method to make it easier to overwrite the connection callback
|
66
66
|
*/
|
67
|
-
connected() {}
|
67
|
+
async connected() {}
|
68
68
|
|
69
69
|
/**
|
70
70
|
* a disconnected method to make it easier to overwrite the disconnection callback
|
@@ -2,6 +2,8 @@ import { AlchemyHTMLElement } from "alchemy_admin/components/alchemy_html_elemen
|
|
2
2
|
import { translate, currentLocale } from "alchemy_admin/i18n"
|
3
3
|
import flatpickr from "flatpickr"
|
4
4
|
|
5
|
+
const locale = currentLocale()
|
6
|
+
|
5
7
|
class Datepicker extends AlchemyHTMLElement {
|
6
8
|
static properties = {
|
7
9
|
inputType: { default: "date" }
|
@@ -12,7 +14,13 @@ class Datepicker extends AlchemyHTMLElement {
|
|
12
14
|
this.flatpickr = undefined
|
13
15
|
}
|
14
16
|
|
15
|
-
|
17
|
+
// Load the locales for flatpickr before setting it up.
|
18
|
+
async connected() {
|
19
|
+
// English is the default locale for flatpickr, so we don't need to load it
|
20
|
+
if (locale !== "en") {
|
21
|
+
await import(`flatpickr/${locale}.js`)
|
22
|
+
}
|
23
|
+
|
16
24
|
this.flatpickr = flatpickr(
|
17
25
|
this.getElementsByTagName("input")[0],
|
18
26
|
this.flatpickrOptions
|
@@ -27,7 +35,7 @@ class Datepicker extends AlchemyHTMLElement {
|
|
27
35
|
const enableTime = /time/.test(this.inputType)
|
28
36
|
const options = {
|
29
37
|
// alchemy_i18n supports `zh_CN` etc., but flatpickr only has two-letter codes (`zh`)
|
30
|
-
locale:
|
38
|
+
locale: locale.slice(0, 2),
|
31
39
|
altInput: true,
|
32
40
|
altFormat: translate(`formats.${this.inputType}`),
|
33
41
|
altInputClass: "flatpickr-input",
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { removeTab } from "alchemy_admin/fixed_elements"
|
2
2
|
import { growl } from "alchemy_admin/growler"
|
3
3
|
import { reloadPreview } from "alchemy_admin/components/preview_window"
|
4
|
-
import {
|
4
|
+
import { openConfirmDialog } from "alchemy_admin/confirm_dialog"
|
5
5
|
|
6
6
|
export class DeleteElementButton extends HTMLElement {
|
7
7
|
constructor() {
|
@@ -9,12 +9,12 @@ export class DeleteElementButton extends HTMLElement {
|
|
9
9
|
this.addEventListener("click", this)
|
10
10
|
}
|
11
11
|
|
12
|
-
handleEvent() {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
async handleEvent() {
|
13
|
+
const confirmed = await openConfirmDialog(this.message)
|
14
|
+
if (confirmed) {
|
15
|
+
const response = await fetch(this.url, { method: "DELETE" })
|
16
|
+
this.#removeElement(await response.json())
|
17
|
+
}
|
18
18
|
}
|
19
19
|
|
20
20
|
#removeElement(response) {
|
@@ -231,7 +231,7 @@ export class ElementEditor extends HTMLElement {
|
|
231
231
|
setDirty() {
|
232
232
|
if (this.hasEditors) {
|
233
233
|
this.dirty = true
|
234
|
-
window.onbeforeunload = () =>
|
234
|
+
window.onbeforeunload = (event) => event.preventDefault()
|
235
235
|
}
|
236
236
|
}
|
237
237
|
|
@@ -24,6 +24,7 @@ import "alchemy_admin/components/select"
|
|
24
24
|
import "alchemy_admin/components/spinner"
|
25
25
|
import "alchemy_admin/components/tags_autocomplete"
|
26
26
|
import "alchemy_admin/components/tinymce"
|
27
|
+
import "alchemy_admin/components/update_check"
|
27
28
|
|
28
29
|
await Promise.race([
|
29
30
|
// Load all global custom elements
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { AlchemyHTMLElement } from "alchemy_admin/components/alchemy_html_element"
|
2
|
+
import { setupSelectLocale } from "alchemy_admin/i18n"
|
2
3
|
|
3
4
|
export class RemoteSelect extends AlchemyHTMLElement {
|
4
5
|
static properties = {
|
@@ -9,7 +10,9 @@ export class RemoteSelect extends AlchemyHTMLElement {
|
|
9
10
|
url: { default: "" }
|
10
11
|
}
|
11
12
|
|
12
|
-
connected() {
|
13
|
+
async connected() {
|
14
|
+
await setupSelectLocale()
|
15
|
+
|
13
16
|
this.input.classList.add("alchemy_selectbox")
|
14
17
|
|
15
18
|
$(this.input)
|
@@ -1,5 +1,9 @@
|
|
1
|
+
import { setupSelectLocale } from "alchemy_admin/i18n"
|
2
|
+
|
1
3
|
class TagsAutocomplete extends HTMLElement {
|
2
|
-
connectedCallback() {
|
4
|
+
async connectedCallback() {
|
5
|
+
await setupSelectLocale()
|
6
|
+
|
3
7
|
this.classList.add("autocomplete_tag_list")
|
4
8
|
$(this.input).select2(this.select2Config)
|
5
9
|
}
|
@@ -76,8 +76,10 @@ class Tinymce extends AlchemyHTMLElement {
|
|
76
76
|
this.getElementsByTagName("alchemy-spinner")[0].remove()
|
77
77
|
|
78
78
|
// event listener to mark the editor as dirty
|
79
|
-
|
80
|
-
|
79
|
+
if (this.elementEditor) {
|
80
|
+
editor.on("dirty", () => this.elementEditor.setDirty())
|
81
|
+
editor.on("click", () => this.elementEditor.onClickElement(false))
|
82
|
+
}
|
81
83
|
})
|
82
84
|
})
|
83
85
|
}
|