alchemy_cms 7.0.16 → 7.1.0.pre.b1
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/.github/workflows/backport.yml +36 -0
- data/.github/workflows/brakeman-analysis.yml +5 -13
- data/.github/workflows/lint.yml +2 -9
- data/.github/workflows/stale.yml +2 -5
- data/.github/workflows/test.yml +7 -15
- data/.gitignore +0 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +144 -51
- data/Gemfile +7 -18
- data/README.md +10 -8
- data/alchemy_cms.gemspec +4 -3
- data/app/assets/config/alchemy_manifest.js +0 -1
- data/app/assets/javascripts/alchemy/admin.js +1 -19
- data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +2 -3
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +19 -34
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +38 -13
- data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +32 -25
- data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +3 -5
- data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +0 -57
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +22 -63
- data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +5 -4
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +5 -5
- data/app/assets/javascripts/alchemy/templates/index.js +0 -2
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page_folder.hbs +2 -2
- data/app/assets/stylesheets/alchemy/_custom-properties.scss +82 -0
- data/app/assets/stylesheets/alchemy/_mixins.scss +38 -30
- data/app/assets/stylesheets/alchemy/_variables.scss +12 -5
- data/app/assets/stylesheets/alchemy/admin.scss +3 -4
- data/app/assets/stylesheets/alchemy/archive.scss +107 -50
- data/app/assets/stylesheets/alchemy/attachments.scss +5 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +38 -164
- data/app/assets/stylesheets/alchemy/dashboard.scss +31 -6
- data/app/assets/stylesheets/alchemy/dialogs.scss +12 -28
- data/app/assets/stylesheets/alchemy/elements.scss +273 -282
- data/app/assets/stylesheets/alchemy/flash.scss +20 -12
- data/app/assets/stylesheets/alchemy/forms.scss +21 -34
- data/app/assets/stylesheets/alchemy/frame.scss +11 -32
- data/app/assets/stylesheets/alchemy/hints.scss +4 -62
- data/app/assets/stylesheets/alchemy/image_library.scss +36 -33
- data/app/assets/stylesheets/alchemy/labels.scss +4 -1
- data/app/assets/stylesheets/alchemy/menubar.scss +7 -6
- data/app/assets/stylesheets/alchemy/navigation.scss +27 -15
- data/app/assets/stylesheets/alchemy/nodes.scss +11 -7
- data/app/assets/stylesheets/alchemy/notices.scss +16 -4
- data/app/assets/stylesheets/alchemy/page-select.scss +10 -2
- data/app/assets/stylesheets/alchemy/pagination.scss +22 -13
- data/app/assets/stylesheets/alchemy/preview_window.scss +4 -8
- data/app/assets/stylesheets/alchemy/resource_info.scss +7 -5
- data/app/assets/stylesheets/alchemy/selects.scss +49 -42
- data/app/assets/stylesheets/alchemy/shoelace.scss +345 -0
- data/app/assets/stylesheets/alchemy/sitemap.scss +24 -14
- data/app/assets/stylesheets/alchemy/spinner.scss +9 -19
- data/app/assets/stylesheets/alchemy/tables.scss +16 -24
- data/app/assets/stylesheets/alchemy/tags.scss +4 -0
- data/app/assets/stylesheets/alchemy/toolbar.scss +29 -25
- data/app/assets/stylesheets/alchemy/upload.scss +140 -89
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +80 -108
- data/app/components/alchemy/admin/node_select.rb +39 -0
- data/app/components/alchemy/admin/page_select.rb +42 -0
- data/app/components/alchemy/ingredients/audio_view.rb +1 -1
- data/app/components/alchemy/ingredients/base_view.rb +1 -1
- data/app/components/alchemy/ingredients/boolean_view.rb +1 -1
- data/app/components/alchemy/ingredients/datetime_view.rb +3 -4
- data/app/components/alchemy/ingredients/file_view.rb +1 -1
- data/app/components/alchemy/ingredients/headline_view.rb +7 -16
- data/app/components/alchemy/ingredients/link_view.rb +1 -1
- data/app/components/alchemy/ingredients/page_view.rb +1 -1
- data/app/components/alchemy/ingredients/picture_view.rb +1 -1
- data/app/components/alchemy/ingredients/richtext_view.rb +1 -1
- data/app/components/alchemy/ingredients/text_view.rb +1 -1
- data/app/components/alchemy/ingredients/video_view.rb +1 -1
- data/app/controllers/alchemy/admin/base_controller.rb +7 -32
- data/app/controllers/alchemy/admin/elements_controller.rb +63 -35
- data/app/controllers/alchemy/admin/languages_controller.rb +2 -3
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -19
- data/app/controllers/alchemy/admin/pages_controller.rb +4 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/base_controller.rb +4 -2
- data/app/controllers/alchemy/messages_controller.rb +1 -1
- data/app/controllers/concerns/alchemy/admin/current_language.rb +1 -5
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +1 -1
- data/app/decorators/alchemy/element_editor.rb +0 -2
- data/app/helpers/alchemy/admin/attachments_helper.rb +6 -5
- data/app/helpers/alchemy/admin/base_helper.rb +17 -12
- data/app/helpers/alchemy/admin/ingredients_helper.rb +4 -1
- data/app/helpers/alchemy/admin/pages_helper.rb +5 -11
- data/app/helpers/alchemy/base_helper.rb +47 -13
- data/app/javascript/alchemy_admin/components/alchemy_html_element.js +129 -0
- data/app/javascript/alchemy_admin/components/button.js +59 -0
- data/app/javascript/alchemy_admin/components/char_counter.js +40 -0
- data/app/javascript/alchemy_admin/components/datepicker.js +39 -0
- data/app/javascript/alchemy_admin/components/dialog_link.js +45 -0
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +36 -0
- data/app/javascript/alchemy_admin/components/element_editor.js +553 -0
- data/app/javascript/alchemy_admin/components/ingredient_group.js +54 -0
- data/app/javascript/alchemy_admin/components/link_buttons/link_button.js +48 -0
- data/app/javascript/alchemy_admin/components/link_buttons/unlink_button.js +38 -0
- data/app/javascript/alchemy_admin/components/link_buttons.js +79 -0
- data/app/javascript/alchemy_admin/components/node_select.js +45 -0
- data/app/javascript/alchemy_admin/components/overlay.js +18 -0
- data/app/javascript/alchemy_admin/components/page_select.js +63 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +134 -0
- data/app/javascript/alchemy_admin/components/select.js +12 -0
- data/app/javascript/alchemy_admin/components/spinner.js +31 -0
- data/app/javascript/alchemy_admin/components/tinymce.js +146 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +266 -0
- data/app/javascript/alchemy_admin/components/uploader/progress.js +258 -0
- data/app/javascript/alchemy_admin/components/uploader.js +132 -0
- data/app/javascript/alchemy_admin/dirty.js +49 -0
- data/app/javascript/alchemy_admin/file_editors.js +1 -1
- data/app/javascript/alchemy_admin/gui.js +14 -0
- data/app/javascript/alchemy_admin/i18n.js +12 -8
- data/app/javascript/alchemy_admin/image_cropper.js +6 -3
- data/app/javascript/alchemy_admin/image_loader.js +7 -15
- data/app/javascript/alchemy_admin/ingredient_anchor_link.js +2 -5
- data/app/javascript/alchemy_admin/initializer.js +65 -0
- data/app/javascript/alchemy_admin/locales/en.js +31 -0
- data/app/javascript/alchemy_admin/picture_editors.js +2 -2
- data/app/javascript/alchemy_admin/picture_selector.js +38 -0
- data/app/javascript/alchemy_admin/please_wait_overlay.js +8 -0
- data/app/javascript/alchemy_admin/sortable_elements.js +78 -0
- data/app/javascript/alchemy_admin/spinner.js +36 -0
- data/app/javascript/alchemy_admin/tags_autocomplete.js +46 -0
- data/app/javascript/alchemy_admin/utils/ajax.js +6 -5
- data/app/javascript/alchemy_admin/utils/dom_helpers.js +20 -0
- data/app/javascript/alchemy_admin/utils/format.js +11 -0
- data/app/javascript/alchemy_admin/utils/string_conversions.js +10 -0
- data/app/javascript/alchemy_admin.js +70 -13
- data/app/javascript/menubar.js +10 -0
- data/app/models/alchemy/attachment.rb +9 -11
- data/app/models/alchemy/element.rb +11 -0
- data/app/models/alchemy/ingredients/audio.rb +0 -11
- data/app/models/alchemy/ingredients/datetime.rb +1 -1
- data/app/models/alchemy/ingredients/richtext.rb +1 -10
- data/app/models/alchemy/ingredients/video.rb +0 -12
- data/app/models/alchemy/node.rb +4 -0
- data/app/models/alchemy/page/page_elements.rb +2 -11
- data/app/models/alchemy/page/page_natures.rb +10 -2
- data/app/models/alchemy/page.rb +12 -54
- data/app/models/alchemy/picture/url.rb +1 -9
- data/app/models/concerns/alchemy/picture_thumbnails.rb +5 -4
- data/app/serializers/alchemy/page_tree_serializer.rb +2 -1
- data/app/services/alchemy/copy_page.rb +98 -0
- data/app/views/alchemy/_menubar.html.erb +17 -13
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +14 -10
- data/app/views/alchemy/admin/attachments/_attachment.html.erb +44 -36
- data/app/views/alchemy/admin/attachments/_replace_button.html.erb +15 -21
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
- data/app/views/alchemy/admin/attachments/assign.js.erb +1 -1
- data/app/views/alchemy/admin/attachments/index.html.erb +6 -4
- data/app/views/alchemy/admin/attachments/show.html.erb +8 -8
- data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/index.html.erb +3 -7
- data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
- data/app/views/alchemy/admin/crop.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/index.html.erb +13 -11
- data/app/views/alchemy/admin/dashboard/info.html.erb +7 -7
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +21 -23
- data/app/views/alchemy/admin/elements/_element.html.erb +52 -44
- data/app/views/alchemy/admin/elements/_footer.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_form.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +11 -12
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +33 -45
- data/app/views/alchemy/admin/elements/create.js.erb +7 -15
- data/app/views/alchemy/admin/elements/destroy.js.erb +0 -2
- data/app/views/alchemy/admin/elements/index.html.erb +27 -24
- data/app/views/alchemy/admin/elements/new.html.erb +9 -11
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +3 -3
- data/app/views/alchemy/admin/ingredients/_video_fields.html.erb +1 -2
- data/app/views/alchemy/admin/languages/_form.html.erb +2 -3
- data/app/views/alchemy/admin/languages/_language.html.erb +15 -8
- data/app/views/alchemy/admin/languages/_table.html.erb +1 -0
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +28 -16
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
- data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +12 -8
- data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/_form.html.erb +20 -21
- data/app/views/alchemy/admin/nodes/_node.html.erb +39 -34
- data/app/views/alchemy/admin/nodes/index.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_current_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_external_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_file_link.html.erb +5 -5
- data/app/views/alchemy/admin/pages/_form.html.erb +10 -21
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +4 -17
- data/app/views/alchemy/admin/pages/_page.html.erb +76 -72
- data/app/views/alchemy/admin/pages/_page_infos.html.erb +23 -7
- data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +2 -1
- data/app/views/alchemy/admin/pages/_page_status.html.erb +11 -21
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +2 -5
- data/app/views/alchemy/admin/pages/_table.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_table_row.html.erb +43 -39
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +43 -38
- data/app/views/alchemy/admin/pages/configure.html.erb +12 -14
- data/app/views/alchemy/admin/pages/edit.html.erb +80 -103
- data/app/views/alchemy/admin/pages/info.html.erb +20 -11
- data/app/views/alchemy/admin/pages/link.html.erb +22 -16
- data/app/views/alchemy/admin/pages/new.html.erb +9 -11
- data/app/views/alchemy/admin/pages/unlock.js.erb +10 -3
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +15 -13
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +3 -5
- data/app/views/alchemy/admin/partials/_routes.html.erb +10 -2
- data/app/views/alchemy/admin/partials/_site_select.html.erb +6 -5
- data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +28 -23
- data/app/views/alchemy/admin/pictures/_archive.html.erb +5 -5
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +21 -23
- data/app/views/alchemy/admin/pictures/_infos.html.erb +2 -6
- data/app/views/alchemy/admin/pictures/_picture.html.erb +15 -17
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +17 -16
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +1 -1
- data/app/views/alchemy/admin/pictures/assign.js.erb +1 -1
- data/app/views/alchemy/admin/pictures/index.html.erb +34 -30
- data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
- data/app/views/alchemy/admin/resources/_filter.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_form.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_resource.html.erb +16 -9
- data/app/views/alchemy/admin/resources/_table.html.erb +4 -1
- data/app/views/alchemy/admin/resources/index.html.erb +22 -19
- data/app/views/alchemy/admin/sites/index.html.erb +2 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +54 -28
- data/app/views/alchemy/admin/tags/_tag.html.erb +16 -18
- data/app/views/alchemy/admin/tags/index.html.erb +15 -12
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +29 -0
- data/app/views/alchemy/admin/uploader/_button.html.erb +23 -29
- data/app/views/alchemy/admin/uploader/_setup.html.erb +3 -8
- data/app/views/alchemy/base/500.html.erb +1 -1
- data/app/views/alchemy/base/error_notice.js.erb +0 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +2 -3
- data/app/views/alchemy/ingredients/_file_editor.html.erb +5 -5
- data/app/views/alchemy/ingredients/_link_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_node_editor.html.erb +6 -19
- data/app/views/alchemy/ingredients/_page_editor.html.erb +7 -19
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +2 -2
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +6 -15
- data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -1
- data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_anchor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +10 -20
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +42 -49
- data/app/views/kaminari/alchemy/_first_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
- data/app/views/kaminari/alchemy/_last_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_next_page.html.erb +4 -2
- data/app/views/kaminari/alchemy/_prev_page.html.erb +4 -2
- data/app/views/layouts/alchemy/admin.html.erb +10 -29
- data/config/alchemy/modules.yml +30 -30
- data/config/importmap.rb +10 -1
- data/config/initializers/rails_live_reload.rb +13 -0
- data/config/locales/alchemy.en.yml +23 -9
- data/config/routes.rb +3 -2
- data/lib/alchemy/auth_accessors.rb +6 -1
- data/lib/alchemy/controller_actions.rb +17 -4
- data/lib/alchemy/dev_support/live_reload_watcher.rb +5 -0
- data/lib/alchemy/engine.rb +8 -2
- data/lib/alchemy/forms/builder.rb +18 -12
- data/lib/alchemy/modules.rb +2 -2
- data/lib/alchemy/permissions.rb +1 -1
- data/lib/alchemy/resources_helper.rb +3 -3
- data/lib/alchemy/routing_constraints.rb +1 -1
- data/lib/alchemy/test_support/capybara_helpers.rb +8 -5
- data/lib/alchemy/test_support/rspec_matchers.rb +14 -0
- data/lib/alchemy/test_support/shared_uploader_examples.rb +1 -1
- data/lib/alchemy/tinymce.rb +8 -3
- data/lib/alchemy/version.rb +1 -1
- data/lib/tasks/alchemy/tidy.rake +1 -0
- data/package.json +14 -5
- data/vendor/assets/fonts/remixicon.eot +0 -0
- data/vendor/assets/fonts/remixicon.svg +7816 -0
- data/vendor/assets/fonts/remixicon.ttf +0 -0
- data/vendor/assets/fonts/remixicon.woff +0 -0
- data/vendor/assets/fonts/remixicon.woff2 +0 -0
- data/vendor/assets/stylesheets/remixicon.scss +10480 -0
- metadata +87 -97
- data/.gem_release.yml +0 -8
- data/app/assets/javascripts/alchemy/alchemy.autocomplete.js.coffee +0 -30
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -53
- data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +0 -45
- data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +0 -19
- data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +0 -59
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -79
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -267
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +0 -27
- data/app/assets/javascripts/alchemy/alchemy.spinner.js +0 -32
- data/app/assets/javascripts/alchemy/alchemy.tooltips.coffee +0 -10
- data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +0 -131
- data/app/assets/javascripts/alchemy/menubar.js.coffee +0 -8
- data/app/assets/javascripts/alchemy/node_select.js +0 -39
- data/app/assets/javascripts/alchemy/page_select.js +0 -46
- data/app/assets/javascripts/alchemy/templates/node.hbs +0 -16
- data/app/assets/javascripts/alchemy/templates/spinner.hbs +0 -7
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +0 -435
- data/app/javascript/alchemy_admin/datepicker.js +0 -40
- data/app/javascript/alchemy_admin/tinymce.js +0 -146
- data/app/javascript/alchemy_admin/translations.js +0 -32
- data/app/views/alchemy/admin/elements/fold.js.erb +0 -33
- data/app/views/alchemy/admin/elements/order.js.erb +0 -11
- data/app/views/alchemy/admin/elements/publish.js.erb +0 -21
- data/app/views/alchemy/admin/elements/update.js.erb +0 -27
- data/vendor/assets/fonts/fa-regular-400.eot +0 -0
- data/vendor/assets/fonts/fa-regular-400.svg +0 -803
- data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff +0 -0
- data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
- data/vendor/assets/fonts/fa-solid-900.eot +0 -0
- data/vendor/assets/fonts/fa-solid-900.svg +0 -4938
- data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff +0 -0
- data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-process.js +0 -178
- data/vendor/assets/javascripts/fileupload/jquery.fileupload-validate.js +0 -125
- data/vendor/assets/javascripts/fileupload/jquery.fileupload.js +0 -1502
- data/vendor/assets/javascripts/fileupload/jquery.iframe-transport.js +0 -224
- data/vendor/assets/javascripts/jquery-ui/data.js +0 -45
- 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/plugin.js +0 -49
- 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/unique-id.js +0 -54
- data/vendor/assets/javascripts/jquery-ui/version.js +0 -20
- data/vendor/assets/javascripts/jquery-ui/widget.js +0 -754
- 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/sortable.js +0 -1623
- data/vendor/assets/javascripts/jquery-ui/widgets/tabs.js +0 -931
- data/vendor/assets/javascripts/jquery_plugins/jquery.scrollTo.min.js +0 -7
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +0 -296
- data/vendor/assets/stylesheets/fontawesome/_animated.scss +0 -20
- data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +0 -20
- data/vendor/assets/stylesheets/fontawesome/_core.scss +0 -21
- data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +0 -6
- data/vendor/assets/stylesheets/fontawesome/_icons.scss +0 -1441
- data/vendor/assets/stylesheets/fontawesome/_larger.scss +0 -23
- data/vendor/assets/stylesheets/fontawesome/_list.scss +0 -18
- data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -56
- data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +0 -24
- data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +0 -5
- data/vendor/assets/stylesheets/fontawesome/_stacked.scss +0 -31
- data/vendor/assets/stylesheets/fontawesome/_variables.scss +0 -1458
- data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +0 -16
- data/vendor/assets/stylesheets/fontawesome/regular.scss +0 -23
- data/vendor/assets/stylesheets/fontawesome/solid.scss +0 -24
@@ -0,0 +1,14 @@
|
|
1
|
+
import TagsAutocomplete from "alchemy_admin/tags_autocomplete"
|
2
|
+
|
3
|
+
function init(scope) {
|
4
|
+
if (!scope) {
|
5
|
+
Alchemy.watchForDialogs()
|
6
|
+
}
|
7
|
+
Alchemy.Hotkeys(scope)
|
8
|
+
Alchemy.ListFilter(scope)
|
9
|
+
TagsAutocomplete(scope)
|
10
|
+
}
|
11
|
+
|
12
|
+
export default {
|
13
|
+
init
|
14
|
+
}
|
@@ -1,11 +1,8 @@
|
|
1
|
-
|
1
|
+
import { en } from "alchemy_admin/locales/en"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
}
|
7
|
-
return Alchemy.locale
|
8
|
-
}
|
3
|
+
Alchemy.translations = Object.assign(Alchemy.translations || {}, { en })
|
4
|
+
|
5
|
+
const KEY_SEPARATOR = /\./
|
9
6
|
|
10
7
|
function getTranslations() {
|
11
8
|
const locale = currentLocale()
|
@@ -36,7 +33,14 @@ function getTranslation(key) {
|
|
36
33
|
return translations[key] || key
|
37
34
|
}
|
38
35
|
|
39
|
-
export
|
36
|
+
export function currentLocale() {
|
37
|
+
if (document.documentElement.lang) {
|
38
|
+
return document.documentElement.lang
|
39
|
+
}
|
40
|
+
return "en"
|
41
|
+
}
|
42
|
+
|
43
|
+
export function translate(key, replacement = undefined) {
|
40
44
|
let translation = getTranslation(key)
|
41
45
|
|
42
46
|
if (replacement) {
|
@@ -90,12 +90,15 @@ export default class ImageCropper {
|
|
90
90
|
}
|
91
91
|
|
92
92
|
bind() {
|
93
|
-
this.dialog.dialog_body.find('button[type="submit"]').click(
|
94
|
-
|
93
|
+
this.dialog.dialog_body.find('button[type="submit"]').on("click", () => {
|
94
|
+
const elementEditor = document.querySelector(
|
95
|
+
`[data-element-id='${this.elementId}']`
|
96
|
+
)
|
97
|
+
elementEditor.setDirty()
|
95
98
|
this.dialog.close()
|
96
99
|
return false
|
97
100
|
})
|
98
|
-
this.dialog.dialog_body.find('button[type="reset"]').click(
|
101
|
+
this.dialog.dialog_body.find('button[type="reset"]').on("click", () => {
|
99
102
|
this.reset()
|
100
103
|
return false
|
101
104
|
})
|
@@ -1,23 +1,21 @@
|
|
1
1
|
// Shows spinner while loading images and
|
2
2
|
// fades the image after its been loaded
|
3
3
|
|
4
|
-
const DEFAULT_SPINNER_OPTIONS = { fill: "#fff" }
|
5
|
-
|
6
4
|
export default class ImageLoader {
|
7
|
-
static init(scope = document
|
5
|
+
static init(scope = document) {
|
8
6
|
if (typeof scope === "string") {
|
9
7
|
scope = document.querySelector(scope)
|
10
8
|
}
|
11
9
|
scope.querySelectorAll("img").forEach((image) => {
|
12
|
-
const loader = new ImageLoader(image
|
10
|
+
const loader = new ImageLoader(image)
|
13
11
|
loader.load()
|
14
12
|
})
|
15
13
|
}
|
16
14
|
|
17
|
-
constructor(image
|
15
|
+
constructor(image) {
|
18
16
|
this.image = image
|
19
17
|
this.parent = image.parentNode
|
20
|
-
this.spinner = new Alchemy.Spinner("small"
|
18
|
+
this.spinner = new Alchemy.Spinner("small")
|
21
19
|
this.bind()
|
22
20
|
}
|
23
21
|
|
@@ -34,15 +32,15 @@ export default class ImageLoader {
|
|
34
32
|
}
|
35
33
|
|
36
34
|
onLoaded() {
|
37
|
-
this.
|
35
|
+
this.spinner.stop()
|
38
36
|
this.image.classList.remove("loading")
|
39
37
|
this.unbind()
|
40
38
|
}
|
41
39
|
|
42
40
|
onError(evt) {
|
43
41
|
const message = `Could not load "${this.image.src}"`
|
44
|
-
this.
|
45
|
-
this.parent.innerHTML = `<span class="icon error
|
42
|
+
this.spinner.stop()
|
43
|
+
this.parent.innerHTML = `<span class="icon error ri-alert-line" title="${message}" />`
|
46
44
|
console.error(message, evt)
|
47
45
|
this.unbind()
|
48
46
|
}
|
@@ -51,10 +49,4 @@ export default class ImageLoader {
|
|
51
49
|
this.image.removeEventListener("load", this.onLoaded)
|
52
50
|
this.image.removeEventListener("error", this.onError)
|
53
51
|
}
|
54
|
-
|
55
|
-
removeSpinner() {
|
56
|
-
this.parent.querySelectorAll(".spinner").forEach((spinner) => {
|
57
|
-
spinner.remove()
|
58
|
-
})
|
59
|
-
}
|
60
52
|
}
|
@@ -7,11 +7,8 @@ export default class IngredientAnchorLink {
|
|
7
7
|
const icon = ingredientEditor.querySelector(
|
8
8
|
".edit-ingredient-anchor-link > a > .icon"
|
9
9
|
)
|
10
|
-
|
11
|
-
|
12
|
-
? icon.classList.replace("far", "fas")
|
13
|
-
: icon.classList.replace("fas", "far")
|
14
|
-
}
|
10
|
+
icon?.classList.toggle("ri-bookmark-fill", active)
|
11
|
+
icon?.classList.toggle("ri-bookmark-line", !active)
|
15
12
|
}
|
16
13
|
}
|
17
14
|
}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
/**
|
2
|
+
* add change listener to select to redirect the user after selecting another locale or site
|
3
|
+
* @param {string} selectId
|
4
|
+
* @param {string} parameterName
|
5
|
+
* @param {boolean} forcedReload
|
6
|
+
*/
|
7
|
+
function selectHandler(selectId, parameterName, forcedReload = false) {
|
8
|
+
$(`select#${selectId}`).on("change", function (e) {
|
9
|
+
let url = window.location.pathname
|
10
|
+
let delimiter = url.match(/\?/) ? "&" : "?"
|
11
|
+
const location = `${url}${delimiter}${parameterName}=${$(this).val()}`
|
12
|
+
|
13
|
+
if (forcedReload) {
|
14
|
+
window.location.href = location
|
15
|
+
} else {
|
16
|
+
Turbo.visit(location, {})
|
17
|
+
}
|
18
|
+
})
|
19
|
+
}
|
20
|
+
|
21
|
+
function Initialize() {
|
22
|
+
// We obviously have javascript enabled.
|
23
|
+
$("html").removeClass("no-js")
|
24
|
+
|
25
|
+
// Initialize the GUI.
|
26
|
+
Alchemy.GUI.init()
|
27
|
+
|
28
|
+
// Fade all growl notifications.
|
29
|
+
if ($("#flash_notices").length > 0) {
|
30
|
+
Alchemy.Growler.fade()
|
31
|
+
}
|
32
|
+
|
33
|
+
// Add observer for please wait overlay.
|
34
|
+
$(".please_wait")
|
35
|
+
.not("*[data-alchemy-confirm]")
|
36
|
+
.on("click", Alchemy.pleaseWaitOverlay)
|
37
|
+
|
38
|
+
// Hack for enabling tab focus for <a>'s styled as button.
|
39
|
+
$("a.button").attr({ tabindex: 0 })
|
40
|
+
|
41
|
+
// Locale select handler
|
42
|
+
selectHandler("change_locale", "admin_locale", true)
|
43
|
+
|
44
|
+
// Site select handler
|
45
|
+
selectHandler("change_site", "site_id")
|
46
|
+
|
47
|
+
// Submit forms of selects with `data-autosubmit="true"`
|
48
|
+
$('select[data-auto-submit="true"]').on("change", function () {
|
49
|
+
$(this.form).submit()
|
50
|
+
})
|
51
|
+
|
52
|
+
// Attaches the image loader on all images
|
53
|
+
Alchemy.ImageLoader("#main_content")
|
54
|
+
|
55
|
+
// Override the filter of keymaster.js so we can blur the fields on esc key.
|
56
|
+
key.filter = function (event) {
|
57
|
+
let tagName = (event.target || event.srcElement).tagName
|
58
|
+
return (
|
59
|
+
key.isPressed("esc") ||
|
60
|
+
!(tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA")
|
61
|
+
)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
export default Initialize
|
@@ -0,0 +1,31 @@
|
|
1
|
+
export const en = {
|
2
|
+
allowed_chars: "of %{count} chars",
|
3
|
+
cancel: "Cancel",
|
4
|
+
cancelled: "Cancelled",
|
5
|
+
click_to_edit: "click to edit",
|
6
|
+
complete: "Complete",
|
7
|
+
element_dirty_notice:
|
8
|
+
"This element has unsaved changes. Do you really want to fold it?",
|
9
|
+
help: "Help",
|
10
|
+
ok: "Ok",
|
11
|
+
page_dirty_notice:
|
12
|
+
"You have unsaved changes on this page. They will be lost if you continue.",
|
13
|
+
page_found: "Page found",
|
14
|
+
pages_found: "Pages found",
|
15
|
+
url_validation_failed: "The url has no valid format.",
|
16
|
+
warning: "Warning!",
|
17
|
+
"File is too large": "File is too large",
|
18
|
+
"File is too small": "File is too small",
|
19
|
+
"File type not allowed": "File type not allowed",
|
20
|
+
"Maximum number of files exceeded": "Maximum number of files exceeded",
|
21
|
+
"Uploaded bytes exceed file size": "Uploaded bytes exceed file size",
|
22
|
+
"Abort upload": "Abort upload",
|
23
|
+
"Cancel all uploads": "Cancel all uploads",
|
24
|
+
Close: "Close",
|
25
|
+
formats: {
|
26
|
+
datetime: "Y-m-d H:i",
|
27
|
+
date: "Y-m-d",
|
28
|
+
time: "H:i",
|
29
|
+
time_24hr: false
|
30
|
+
}
|
31
|
+
}
|
@@ -4,7 +4,7 @@ import { get } from "alchemy_admin/utils/ajax"
|
|
4
4
|
import ImageLoader from "alchemy_admin/image_loader"
|
5
5
|
|
6
6
|
const UPDATE_DELAY = 125
|
7
|
-
const IMAGE_PLACEHOLDER = '<i class="icon
|
7
|
+
const IMAGE_PLACEHOLDER = '<i class="icon ri-image-line ri-fw"></i>'
|
8
8
|
const THUMBNAIL_SIZE = "160x120"
|
9
9
|
|
10
10
|
class PictureEditor {
|
@@ -93,7 +93,7 @@ class PictureEditor {
|
|
93
93
|
this.pictureIdField.value = ""
|
94
94
|
this.image = null
|
95
95
|
this.cropLink.classList.add("disabled")
|
96
|
-
|
96
|
+
this.container.closest(".element-editor").setDirty()
|
97
97
|
}
|
98
98
|
|
99
99
|
updateCropLink() {
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { on } from "alchemy_admin/utils/events"
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Multiple picture select handler for the picture archive.
|
5
|
+
*/
|
6
|
+
export default function PictureSelector() {
|
7
|
+
const selectedItemTools = document.querySelector(".selected_item_tools")
|
8
|
+
const checkedInputs = () =>
|
9
|
+
document.querySelectorAll("#picture_archive input:checked")
|
10
|
+
|
11
|
+
// make the item toolbar visible and show the checkbox also if it is not hovered anymore
|
12
|
+
on("change", ".picture_tool.select", "input", (event) => {
|
13
|
+
selectedItemTools.style.display =
|
14
|
+
checkedInputs().length > 0 ? "block" : "none"
|
15
|
+
|
16
|
+
const parentElementClassList = event.target.parentElement.classList
|
17
|
+
const checked = event.target.checked
|
18
|
+
|
19
|
+
parentElementClassList.toggle("visible", checked)
|
20
|
+
parentElementClassList.toggle("hidden", !checked)
|
21
|
+
})
|
22
|
+
|
23
|
+
// open the edit view in a dialog modal
|
24
|
+
on("click", ".selected_item_tools", "a#edit_multiple_pictures", (event) => {
|
25
|
+
event.preventDefault()
|
26
|
+
|
27
|
+
const searchParameters = new URLSearchParams()
|
28
|
+
checkedInputs().forEach((entry) =>
|
29
|
+
searchParameters.append(entry.name, entry.value)
|
30
|
+
)
|
31
|
+
const url = event.target.href + "?" + searchParameters.toString()
|
32
|
+
|
33
|
+
Alchemy.openDialog(url, {
|
34
|
+
title: event.target.title,
|
35
|
+
size: "400x295"
|
36
|
+
})
|
37
|
+
})
|
38
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import Sortable from "sortablejs"
|
2
|
+
import { post } from "alchemy_admin/utils/ajax"
|
3
|
+
|
4
|
+
const SORTABLE_OPTIONS = {
|
5
|
+
draggable: ".element-editor",
|
6
|
+
handle: ".element-handle",
|
7
|
+
ghostClass: "dragged",
|
8
|
+
animation: 150,
|
9
|
+
swapThreshold: 0.65,
|
10
|
+
easing: "cubic-bezier(1, 0, 0, 1)"
|
11
|
+
}
|
12
|
+
|
13
|
+
function onStart(event) {
|
14
|
+
const name = event.item.dataset.elementName
|
15
|
+
document
|
16
|
+
.querySelectorAll(`[data-droppable-elements~="${name}"]`)
|
17
|
+
.forEach((dropzone) => dropzone.classList.add("droppable-elements"))
|
18
|
+
}
|
19
|
+
|
20
|
+
function onSort(event) {
|
21
|
+
const item = event.item
|
22
|
+
const parentElement = event.to.parentElement.closest(".element-editor")
|
23
|
+
const params = {
|
24
|
+
element_id: item.dataset.elementId,
|
25
|
+
position: event.newIndex + 1
|
26
|
+
}
|
27
|
+
|
28
|
+
if (parentElement) {
|
29
|
+
params.parent_element_id = parentElement.dataset.elementId
|
30
|
+
}
|
31
|
+
|
32
|
+
post(Alchemy.routes.order_admin_elements_path, params).then((response) => {
|
33
|
+
const data = response.data
|
34
|
+
Alchemy.growl(data.message)
|
35
|
+
Alchemy.PreviewWindow.refresh()
|
36
|
+
item.updateTitle(data.preview_text)
|
37
|
+
})
|
38
|
+
}
|
39
|
+
|
40
|
+
function onEnd() {
|
41
|
+
const dropzones = document.querySelectorAll("[data-droppable-elements]")
|
42
|
+
dropzones.forEach((dropzone) =>
|
43
|
+
dropzone.classList.remove("droppable-elements")
|
44
|
+
)
|
45
|
+
}
|
46
|
+
|
47
|
+
function createSortable(element, options = {}) {
|
48
|
+
const group = {
|
49
|
+
name: element.dataset.elementName,
|
50
|
+
put(to, _from, item) {
|
51
|
+
return to.el.dataset.droppableElements
|
52
|
+
.split(" ")
|
53
|
+
.includes(item.dataset.elementName)
|
54
|
+
}
|
55
|
+
}
|
56
|
+
new Sortable(element, {
|
57
|
+
...SORTABLE_OPTIONS,
|
58
|
+
...options,
|
59
|
+
onStart,
|
60
|
+
onSort,
|
61
|
+
onEnd,
|
62
|
+
group
|
63
|
+
})
|
64
|
+
}
|
65
|
+
|
66
|
+
export default function SortableElements(selector) {
|
67
|
+
if (selector == null) selector = ".sortable-elements"
|
68
|
+
|
69
|
+
const sortable_areas = document.querySelectorAll(selector, {
|
70
|
+
direction: "vertical"
|
71
|
+
})
|
72
|
+
|
73
|
+
sortable_areas.forEach((element) => createSortable(element))
|
74
|
+
|
75
|
+
document.querySelectorAll(".nested-elements").forEach((nestedElement) => {
|
76
|
+
createSortable(nestedElement)
|
77
|
+
})
|
78
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { createHtmlElement } from "alchemy_admin/utils/dom_helpers"
|
2
|
+
|
3
|
+
export default class Spinner {
|
4
|
+
constructor(size, color = "currentColor") {
|
5
|
+
this.size = size
|
6
|
+
this.color = color
|
7
|
+
this.spinner = undefined
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @returns {HTMLElement|undefined}
|
12
|
+
*/
|
13
|
+
get el() {
|
14
|
+
return this.spinner
|
15
|
+
}
|
16
|
+
/**
|
17
|
+
* @param {HTMLElement|undefined} parent
|
18
|
+
*/
|
19
|
+
spin(parent) {
|
20
|
+
if (typeof parent === "undefined") {
|
21
|
+
parent = document.body
|
22
|
+
}
|
23
|
+
this.spinner = createHtmlElement(
|
24
|
+
`<alchemy-spinner size="${this.size}" color="${this.color}"></alchemy-spinner>`
|
25
|
+
)
|
26
|
+
parent.append(this.spinner)
|
27
|
+
return this
|
28
|
+
}
|
29
|
+
|
30
|
+
stop() {
|
31
|
+
if (this.spinner) {
|
32
|
+
this.spinner.remove()
|
33
|
+
this.spinner = undefined
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
function createSearchChoice(term, data) {
|
2
|
+
if (
|
3
|
+
$(data).filter(function () {
|
4
|
+
return this.text.localeCompare(term) === 0
|
5
|
+
}).length === 0
|
6
|
+
) {
|
7
|
+
return {
|
8
|
+
id: term,
|
9
|
+
text: term
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
function initSelection(element, callback) {
|
15
|
+
const data = []
|
16
|
+
$(element.val().split(",")).each(function () {
|
17
|
+
data.push({
|
18
|
+
id: this.trim(),
|
19
|
+
text: this
|
20
|
+
})
|
21
|
+
})
|
22
|
+
callback(data)
|
23
|
+
}
|
24
|
+
|
25
|
+
export default function TagsAutocomplete(scope) {
|
26
|
+
const field = $("[data-autocomplete]", scope)
|
27
|
+
const url = field.data("autocomplete")
|
28
|
+
field.select2({
|
29
|
+
tags: true,
|
30
|
+
tokenSeparators: [","],
|
31
|
+
minimumInputLength: 1,
|
32
|
+
openOnEnter: false,
|
33
|
+
createSearchChoice,
|
34
|
+
ajax: {
|
35
|
+
url,
|
36
|
+
dataType: "json",
|
37
|
+
data: (term) => {
|
38
|
+
return { term }
|
39
|
+
},
|
40
|
+
results: (data) => {
|
41
|
+
return { results: data }
|
42
|
+
}
|
43
|
+
},
|
44
|
+
initSelection
|
45
|
+
})
|
46
|
+
}
|
@@ -24,7 +24,7 @@ function buildPromise(xhr) {
|
|
24
24
|
})
|
25
25
|
}
|
26
26
|
|
27
|
-
function getToken() {
|
27
|
+
export function getToken() {
|
28
28
|
const metaTag = document.querySelector('meta[name="csrf-token"]')
|
29
29
|
return metaTag.attributes.content.textContent
|
30
30
|
}
|
@@ -37,11 +37,11 @@ export function patch(url, data) {
|
|
37
37
|
return ajax("PATCH", url, data)
|
38
38
|
}
|
39
39
|
|
40
|
-
export function post(url, data) {
|
41
|
-
return ajax("POST", url, data)
|
40
|
+
export function post(url, data, accept = "application/json") {
|
41
|
+
return ajax("POST", url, data, accept)
|
42
42
|
}
|
43
43
|
|
44
|
-
export default function ajax(method, path, data) {
|
44
|
+
export default function ajax(method, path, data, accept = "application/json") {
|
45
45
|
const xhr = new XMLHttpRequest()
|
46
46
|
const promise = buildPromise(xhr)
|
47
47
|
const url = new URL(window.location.origin + path)
|
@@ -52,7 +52,8 @@ export default function ajax(method, path, data) {
|
|
52
52
|
|
53
53
|
xhr.open(method, url.toString())
|
54
54
|
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8")
|
55
|
-
xhr.setRequestHeader("Accept",
|
55
|
+
xhr.setRequestHeader("Accept", accept)
|
56
|
+
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
|
56
57
|
xhr.setRequestHeader("X-CSRF-Token", getToken())
|
57
58
|
|
58
59
|
if (data && method.toLowerCase() !== "get") {
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/**
|
2
|
+
* create a HTML element
|
3
|
+
* @param {string} text
|
4
|
+
* @returns {HTMLElement}
|
5
|
+
*/
|
6
|
+
export function createHtmlElement(text) {
|
7
|
+
const element = document.createElement("template")
|
8
|
+
element.innerHTML = text
|
9
|
+
return element.content.children[0]
|
10
|
+
}
|
11
|
+
|
12
|
+
/**
|
13
|
+
* wrap element with wrappingElement
|
14
|
+
* @param {HTMLElement} element
|
15
|
+
* @param {HTMLElement} wrappingElement
|
16
|
+
*/
|
17
|
+
export function wrap(element, wrappingElement) {
|
18
|
+
element.replaceWith(wrappingElement)
|
19
|
+
wrappingElement.appendChild(element)
|
20
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export function formatFileSize(bytes) {
|
2
|
+
let exponent = bytes === 0 ? 0 : Math.floor(Math.log(bytes) / Math.log(1024))
|
3
|
+
|
4
|
+
// prevent format higher than GB
|
5
|
+
if (exponent > 3) {
|
6
|
+
exponent = 3
|
7
|
+
}
|
8
|
+
|
9
|
+
let value = (bytes / Math.pow(1024, exponent)).toFixed(2)
|
10
|
+
return value + " " + ["B", "kB", "MB", "GB"][exponent]
|
11
|
+
}
|
@@ -1,17 +1,69 @@
|
|
1
|
+
import "@ungap/custom-elements"
|
1
2
|
import "@hotwired/turbo-rails"
|
3
|
+
import Rails from "@rails/ujs"
|
2
4
|
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import
|
5
|
+
import GUI from "alchemy_admin/gui"
|
6
|
+
import { translate } from "alchemy_admin/i18n"
|
7
|
+
import Dirty from "alchemy_admin/dirty"
|
6
8
|
import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link"
|
7
|
-
import pictureEditors from "alchemy_admin/picture_editors"
|
8
9
|
import ImageLoader from "alchemy_admin/image_loader"
|
9
10
|
import ImageCropper from "alchemy_admin/image_cropper"
|
10
|
-
import
|
11
|
+
import Initializer from "alchemy_admin/initializer"
|
12
|
+
import pictureSelector from "alchemy_admin/picture_selector"
|
13
|
+
import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay"
|
11
14
|
import Sitemap from "alchemy_admin/sitemap"
|
12
|
-
import
|
15
|
+
import SortableElements from "alchemy_admin/sortable_elements"
|
16
|
+
import Spinner from "alchemy_admin/spinner"
|
13
17
|
import PagePublicationFields from "alchemy_admin/page_publication_fields"
|
14
18
|
|
19
|
+
// Setting jQueryUIs global animation duration to something more snappy
|
20
|
+
$.fx.speeds._default = 400
|
21
|
+
|
22
|
+
// Web Components
|
23
|
+
import "alchemy_admin/components/button"
|
24
|
+
import "alchemy_admin/components/char_counter"
|
25
|
+
import "alchemy_admin/components/datepicker"
|
26
|
+
import "alchemy_admin/components/dialog_link"
|
27
|
+
import "alchemy_admin/components/element_editor"
|
28
|
+
import "alchemy_admin/components/ingredient_group"
|
29
|
+
import "alchemy_admin/components/link_buttons"
|
30
|
+
import "alchemy_admin/components/node_select"
|
31
|
+
import "alchemy_admin/components/uploader"
|
32
|
+
import "alchemy_admin/components/overlay"
|
33
|
+
import "alchemy_admin/components/page_select"
|
34
|
+
import "alchemy_admin/components/select"
|
35
|
+
import "alchemy_admin/components/spinner"
|
36
|
+
import "alchemy_admin/components/tinymce"
|
37
|
+
import "@shoelace/progress-bar"
|
38
|
+
import "@shoelace/switch"
|
39
|
+
import "@shoelace/tab"
|
40
|
+
import "@shoelace/tab-group"
|
41
|
+
import "@shoelace/tab-panel"
|
42
|
+
import "@shoelace/tooltip"
|
43
|
+
|
44
|
+
import { setDefaultAnimation } from "@shoelace/animation-registry"
|
45
|
+
|
46
|
+
// Change the default animation for all dialogs
|
47
|
+
setDefaultAnimation("tooltip.show", {
|
48
|
+
keyframes: [
|
49
|
+
{ transform: "translateY(10px)", opacity: "0" },
|
50
|
+
{ transform: "translateY(0)", opacity: "1" }
|
51
|
+
],
|
52
|
+
options: {
|
53
|
+
duration: 100
|
54
|
+
}
|
55
|
+
})
|
56
|
+
|
57
|
+
setDefaultAnimation("tooltip.hide", {
|
58
|
+
keyframes: [
|
59
|
+
{ transform: "translateY(0)", opacity: "1" },
|
60
|
+
{ transform: "translateY(10px)", opacity: "0" }
|
61
|
+
],
|
62
|
+
options: {
|
63
|
+
duration: 100
|
64
|
+
}
|
65
|
+
})
|
66
|
+
|
15
67
|
// Global Alchemy object
|
16
68
|
if (typeof window.Alchemy === "undefined") {
|
17
69
|
window.Alchemy = {}
|
@@ -19,16 +71,21 @@ if (typeof window.Alchemy === "undefined") {
|
|
19
71
|
|
20
72
|
// Enhance the global Alchemy object with imported features
|
21
73
|
Object.assign(Alchemy, {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
fileEditors,
|
26
|
-
pictureEditors,
|
74
|
+
...Dirty,
|
75
|
+
GUI,
|
76
|
+
t: translate, // Global utility method for translating a given string
|
27
77
|
ImageLoader: ImageLoader.init,
|
28
78
|
ImageCropper,
|
79
|
+
Initializer,
|
29
80
|
IngredientAnchorLink,
|
30
|
-
|
81
|
+
pictureSelector,
|
82
|
+
pleaseWaitOverlay,
|
31
83
|
Sitemap,
|
32
|
-
|
84
|
+
SortableElements,
|
85
|
+
Spinner,
|
33
86
|
PagePublicationFields
|
34
87
|
})
|
88
|
+
|
89
|
+
Rails.start()
|
90
|
+
|
91
|
+
$(document).on("turbo:load", Initializer)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Menubar extends HTMLElement {
|
2
|
+
constructor() {
|
3
|
+
super()
|
4
|
+
const template = this.querySelector("template")
|
5
|
+
const attachedShadowRoot = this.attachShadow({ mode: "open" })
|
6
|
+
attachedShadowRoot.appendChild(template.content.cloneNode(true))
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
customElements.define("alchemy-menubar", Menubar)
|