alchemy_cms 7.1.7 → 7.2.0.b
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 +133 -0
- data/Gemfile +2 -4
- data/LICENSE +1 -1
- data/README.md +5 -6
- data/SECURITY.md +1 -1
- data/alchemy_cms.gemspec +3 -4
- data/app/assets/javascripts/alchemy/admin.js +0 -9
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +5 -15
- data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +5 -4
- data/app/assets/javascripts/alchemy/templates/index.js +0 -1
- data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
- data/app/assets/javascripts/alchemy/templates/page_folder.hbs +1 -1
- data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +20 -7
- data/app/assets/stylesheets/alchemy/_custom-properties.scss +12 -0
- data/app/assets/stylesheets/alchemy/_mixins.scss +10 -6
- data/app/assets/stylesheets/alchemy/_variables.scss +3 -0
- data/app/assets/stylesheets/alchemy/admin.scss +2 -2
- data/app/assets/stylesheets/alchemy/archive.scss +4 -3
- data/app/assets/stylesheets/alchemy/attachment-select.scss +19 -0
- data/app/assets/stylesheets/alchemy/base.scss +31 -18
- data/app/assets/stylesheets/alchemy/buttons.scss +3 -4
- data/app/assets/stylesheets/alchemy/dashboard.scss +1 -1
- data/app/assets/stylesheets/alchemy/dialogs.scss +2 -5
- data/app/assets/stylesheets/alchemy/elements.scss +76 -46
- data/app/assets/stylesheets/alchemy/flash.scss +20 -70
- data/app/assets/stylesheets/alchemy/forms.scss +41 -36
- data/app/assets/stylesheets/alchemy/frame.scss +12 -3
- data/app/assets/stylesheets/alchemy/icons.scss +34 -2
- data/app/assets/stylesheets/alchemy/image_library.scss +18 -9
- data/app/assets/stylesheets/alchemy/{filter_field.scss → list_filter.scss} +8 -7
- data/app/assets/stylesheets/alchemy/lists.scss +1 -1
- data/app/assets/stylesheets/alchemy/navigation.scss +9 -12
- data/app/assets/stylesheets/alchemy/node-select.scss +1 -1
- data/app/assets/stylesheets/alchemy/nodes.scss +15 -13
- data/app/assets/stylesheets/alchemy/notices.scss +56 -39
- data/app/assets/stylesheets/alchemy/page-select.scss +1 -4
- data/app/assets/stylesheets/alchemy/pagination.scss +11 -1
- data/app/assets/stylesheets/alchemy/preview_window.scss +7 -3
- data/app/assets/stylesheets/alchemy/search.scss +4 -4
- data/app/assets/stylesheets/alchemy/selects.scss +13 -7
- data/app/assets/stylesheets/alchemy/shoelace.scss +33 -2
- data/app/assets/stylesheets/alchemy/sitemap.scss +155 -159
- data/app/assets/stylesheets/alchemy/tables.scss +49 -12
- data/app/assets/stylesheets/alchemy/tags.scss +17 -11
- data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
- data/app/assets/stylesheets/alchemy/typography.scss +41 -22
- data/app/assets/stylesheets/alchemy/upload.scss +5 -4
- data/app/components/alchemy/admin/attachment_select.rb +39 -0
- data/app/components/alchemy/admin/icon.rb +72 -0
- data/app/components/alchemy/admin/link_dialog/anchor_tab.rb +41 -0
- data/app/components/alchemy/admin/link_dialog/base_tab.rb +75 -0
- data/app/components/alchemy/admin/link_dialog/external_tab.rb +42 -0
- data/app/components/alchemy/admin/link_dialog/file_tab.rb +45 -0
- data/app/components/alchemy/admin/link_dialog/internal_tab.rb +66 -0
- data/app/components/alchemy/admin/link_dialog/tabs.rb +33 -0
- data/app/components/alchemy/admin/list_filter.rb +42 -0
- data/app/components/alchemy/admin/message.rb +19 -0
- data/app/components/alchemy/admin/tags_autocomplete.rb +25 -0
- data/app/components/alchemy/admin/toolbar_button.rb +111 -0
- data/app/components/alchemy/ingredients/link_view.rb +1 -7
- data/app/components/alchemy/ingredients/picture_view.rb +2 -2
- data/app/components/alchemy/ingredients/text_view.rb +1 -2
- data/app/controllers/alchemy/admin/base_controller.rb +1 -1
- data/app/controllers/alchemy/admin/elements_controller.rb +4 -2
- data/app/controllers/alchemy/admin/ingredients_controller.rb +2 -0
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +12 -4
- data/app/controllers/alchemy/admin/nodes_controller.rb +26 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +11 -78
- data/app/controllers/alchemy/admin/picture_descriptions_controller.rb +15 -0
- data/app/controllers/alchemy/admin/pictures_controller.rb +18 -1
- data/app/controllers/alchemy/admin/resources_controller.rb +15 -10
- data/app/controllers/alchemy/api/attachments_controller.rb +44 -0
- data/app/controllers/alchemy/api/pages_controller.rb +10 -6
- data/app/controllers/alchemy/base_controller.rb +2 -2
- data/app/controllers/alchemy/messages_controller.rb +2 -2
- data/app/controllers/alchemy/pages_controller.rb +8 -6
- data/app/controllers/concerns/alchemy/admin/current_language.rb +1 -1
- data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +1 -1
- data/app/decorators/alchemy/element_editor.rb +2 -2
- data/app/helpers/alchemy/admin/base_helper.rb +8 -60
- data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
- data/app/helpers/alchemy/admin/ingredients_helper.rb +1 -1
- data/app/helpers/alchemy/base_helper.rb +9 -91
- data/app/helpers/alchemy/elements_helper.rb +3 -3
- data/app/helpers/alchemy/pages_helper.rb +16 -9
- data/app/javascript/alchemy_admin/components/attachment_select.js +24 -0
- data/app/javascript/alchemy_admin/components/button.js +3 -0
- data/app/javascript/alchemy_admin/components/clipboard_button.js +3 -2
- data/app/javascript/alchemy_admin/components/dialog_link.js +10 -7
- data/app/javascript/alchemy_admin/components/dom_id_select.js +69 -0
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +42 -0
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +4 -2
- data/app/javascript/alchemy_admin/components/element_editor.js +21 -13
- data/app/javascript/alchemy_admin/components/elements_window.js +87 -0
- data/app/javascript/alchemy_admin/components/growl.js +13 -0
- data/app/javascript/alchemy_admin/components/icon.js +51 -0
- data/app/javascript/alchemy_admin/components/index.js +24 -0
- data/app/javascript/alchemy_admin/components/ingredient_group.js +6 -0
- data/app/javascript/alchemy_admin/components/link_buttons/link_button.js +21 -11
- data/app/javascript/alchemy_admin/components/link_buttons/unlink_button.js +2 -1
- data/app/javascript/alchemy_admin/components/link_buttons.js +1 -0
- data/app/javascript/alchemy_admin/components/list_filter.js +68 -0
- data/app/javascript/alchemy_admin/components/message.js +69 -0
- data/app/javascript/alchemy_admin/components/node_select.js +1 -1
- data/app/javascript/alchemy_admin/components/overlay.js +6 -6
- data/app/javascript/alchemy_admin/components/page_select.js +3 -7
- data/app/javascript/alchemy_admin/components/preview_window.js +121 -0
- data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
- data/app/javascript/alchemy_admin/components/select.js +37 -1
- data/app/javascript/alchemy_admin/components/tags_autocomplete.js +57 -0
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +4 -3
- data/app/javascript/alchemy_admin/components/uploader/progress.js +1 -1
- data/app/javascript/alchemy_admin/confirm_dialog.js +133 -0
- data/app/javascript/alchemy_admin/dirty.js +19 -14
- data/app/javascript/alchemy_admin/fixed_elements.js +24 -0
- data/app/javascript/alchemy_admin/growler.js +15 -0
- data/app/javascript/alchemy_admin/gui.js +2 -4
- data/app/javascript/alchemy_admin/hotkeys.js +60 -0
- data/app/javascript/alchemy_admin/image_loader.js +2 -2
- data/app/javascript/alchemy_admin/ingredient_anchor_link.js +2 -3
- data/app/javascript/alchemy_admin/initializer.js +1 -8
- data/app/javascript/alchemy_admin/link_dialog.js +131 -0
- data/app/javascript/alchemy_admin/locales/en.js +3 -0
- data/app/javascript/alchemy_admin/node_tree.js +4 -3
- data/app/javascript/alchemy_admin/page_sorter.js +23 -14
- data/app/javascript/alchemy_admin/picture_editors.js +3 -2
- data/app/javascript/alchemy_admin/shoelace_theme.js +60 -0
- data/app/javascript/alchemy_admin/sitemap.js +9 -3
- data/app/javascript/alchemy_admin/sortable_elements.js +4 -6
- data/app/javascript/alchemy_admin.js +18 -42
- data/app/models/alchemy/current.rb +26 -0
- data/app/models/alchemy/element.rb +1 -1
- data/app/models/alchemy/ingredients/headline.rb +8 -1
- data/app/models/alchemy/ingredients/picture.rb +6 -0
- data/app/models/alchemy/language.rb +8 -6
- data/app/models/alchemy/node.rb +2 -2
- data/app/models/alchemy/page/page_elements.rb +8 -8
- data/app/models/alchemy/page/page_layouts.rb +3 -3
- data/app/models/alchemy/page/page_natures.rb +13 -9
- data/app/models/alchemy/page/page_scopes.rb +2 -2
- data/app/models/alchemy/page/publisher.rb +1 -0
- data/app/models/alchemy/page.rb +13 -28
- data/app/models/alchemy/picture.rb +8 -0
- data/app/models/alchemy/picture_description.rb +8 -0
- data/app/models/alchemy/picture_variant.rb +1 -1
- data/app/models/alchemy/site.rb +10 -7
- data/app/serializers/alchemy/attachment_serializer.rb +8 -0
- data/app/serializers/alchemy/page_node_serializer.rb +9 -0
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/_preview_mode_code.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
- data/app/views/alchemy/admin/attachments/edit.html.erb +3 -4
- data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
- data/app/views/alchemy/admin/clipboard/remove.js.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_sites.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/help.html.erb +48 -12
- data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/info.html.erb +5 -8
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +5 -5
- data/app/views/alchemy/admin/elements/_footer.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +6 -2
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +8 -6
- data/app/views/alchemy/admin/elements/create.js.erb +0 -5
- data/app/views/alchemy/admin/elements/index.html.erb +70 -34
- data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +1 -2
- data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +3 -5
- data/app/views/alchemy/admin/languages/_language.html.erb +1 -1
- data/app/views/alchemy/admin/languages/index.html.erb +2 -2
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +18 -18
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +3 -4
- data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
- data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +10 -11
- data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +15 -17
- data/app/views/alchemy/admin/legacy_page_urls/_table.html.erb +16 -0
- data/app/views/alchemy/admin/legacy_page_urls/_update.turbo_stream.erb +12 -0
- data/app/views/alchemy/admin/legacy_page_urls/create.turbo_stream.erb +8 -0
- data/app/views/alchemy/admin/legacy_page_urls/destroy.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/legacy_page_urls/edit.html.erb +27 -0
- data/app/views/alchemy/admin/legacy_page_urls/show.html.erb +1 -0
- data/app/views/alchemy/admin/legacy_page_urls/update.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/_form.html.erb +12 -11
- data/app/views/alchemy/admin/nodes/_label.html.erb +1 -0
- data/app/views/alchemy/admin/nodes/_node.html.erb +19 -19
- data/app/views/alchemy/admin/nodes/_page_nodes.html.erb +48 -0
- data/app/views/alchemy/admin/nodes/_update.turbo_stream.erb +9 -0
- data/app/views/alchemy/admin/nodes/create.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/destroy.turbo_stream.erb +1 -0
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_form.html.erb +3 -4
- data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +4 -15
- data/app/views/alchemy/admin/pages/_page.html.erb +39 -39
- data/app/views/alchemy/admin/pages/_table_row.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +2 -2
- data/app/views/alchemy/admin/pages/configure.html.erb +6 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +15 -62
- data/app/views/alchemy/admin/pages/unlock.js.erb +2 -2
- data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +3 -1
- data/app/views/alchemy/admin/partials/_flash_notices.html.erb +4 -2
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +5 -2
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_search_form.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_site_select.html.erb +1 -1
- data/app/views/alchemy/admin/picture_descriptions/_form.html.erb +11 -0
- data/app/views/alchemy/admin/picture_descriptions/edit.html.erb +6 -0
- data/app/views/alchemy/admin/pictures/_form.html.erb +4 -3
- data/app/views/alchemy/admin/pictures/_infos.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +29 -0
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -2
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +3 -3
- data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
- data/app/views/alchemy/admin/resources/_form.html.erb +3 -4
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +2 -2
- data/app/views/alchemy/admin/resources/index.html.erb +2 -2
- data/app/views/alchemy/admin/sites/index.html.erb +1 -1
- data/app/views/alchemy/admin/styleguide/index.html.erb +29 -24
- data/app/views/alchemy/admin/tags/_tag.html.erb +1 -1
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/admin/tags/index.html.erb +1 -1
- data/app/views/alchemy/base/500.html.erb +7 -18
- data/app/views/alchemy/base/error_notice.html.erb +3 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +13 -8
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -1
- data/app/views/alchemy/language_links/_language.html.erb +1 -1
- data/app/views/kaminari/alchemy/_first_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
- data/app/views/kaminari/alchemy/_last_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_next_page.html.erb +2 -2
- data/app/views/kaminari/alchemy/_prev_page.html.erb +2 -2
- data/app/views/layouts/alchemy/admin.html.erb +2 -1
- data/bundles/shoelace.js +3 -1
- data/config/locales/alchemy.en.yml +16 -3
- data/config/routes.rb +3 -1
- data/db/migrate/20240314105244_create_alchemy_picture_descriptions.rb +11 -0
- data/lib/alchemy/configuration_methods.rb +1 -1
- data/lib/alchemy/controller_actions.rb +3 -3
- data/lib/alchemy/element_definition.rb +10 -6
- data/lib/alchemy/engine.rb +19 -2
- data/lib/alchemy/page_layout.rb +10 -6
- data/lib/alchemy/permissions.rb +3 -2
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/test_support/capybara_helpers.rb +4 -0
- data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
- data/lib/alchemy/test_support/shared_contexts.rb +8 -0
- data/lib/alchemy/tinymce.rb +2 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +36 -0
- data/lib/alchemy_cms.rb +0 -1
- data/lib/generators/alchemy/menus/templates/node.html.erb +2 -2
- data/lib/generators/alchemy/menus/templates/node.html.haml +2 -2
- data/lib/generators/alchemy/menus/templates/node.html.slim +2 -2
- data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
- data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
- data/lib/tasks/alchemy/sitemap.rake +97 -0
- data/package.json +8 -8
- data/vendor/assets/fonts/remixicon.symbol.svg +11 -0
- data/vendor/javascript/shoelace.min.js +333 -118
- data/vendor/javascript/sortable.min.js +1 -1
- data/vendor/javascript/tinymce.min.js +1 -1
- data/vendor/javascript/ungap-custom-elements.min.js +1 -1
- metadata +61 -54
- data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +0 -85
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +0 -107
- data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +0 -66
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +0 -45
- data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +0 -24
- data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +0 -49
- data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +0 -0
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +0 -230
- data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +0 -49
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +0 -82
- data/app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee +0 -11
- data/app/assets/javascripts/alchemy/templates/page.hbs +0 -19
- data/app/javascript/alchemy_admin/tags_autocomplete.js +0 -46
- data/app/models/alchemy/tree_node.rb +0 -7
- data/app/views/alchemy/admin/elements/destroy.js.erb +0 -8
- data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +0 -5
- data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -9
- data/app/views/alchemy/admin/legacy_page_urls/destroy.js.erb +0 -6
- data/app/views/alchemy/admin/legacy_page_urls/update.js.erb +0 -2
- data/app/views/alchemy/admin/pages/_anchor_link.html.erb +0 -22
- data/app/views/alchemy/admin/pages/_external_link.html.erb +0 -31
- data/app/views/alchemy/admin/pages/_file_link.html.erb +0 -31
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +0 -35
- data/app/views/alchemy/admin/pages/link.html.erb +0 -26
- data/app/views/alchemy/admin/partials/_flash.html.erb +0 -4
- data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +0 -29
- data/vendor/assets/fonts/remixicon.eot +0 -0
- data/vendor/assets/fonts/remixicon.svg +0 -7816
- 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 +0 -10480
|
@@ -250,6 +250,7 @@ en:
|
|
|
250
250
|
"Confirm new password": "Confirm new password"
|
|
251
251
|
"Copy": "Copy"
|
|
252
252
|
"Could not load Adobe Flash® Plugin!": "Could not load Adobe Flash® Plugin!"
|
|
253
|
+
"Create node on parent:": "Create node on parent:"
|
|
253
254
|
"Currently locked pages": "Currently locked pages"
|
|
254
255
|
"Default language has to be public": "Default language has to be public"
|
|
255
256
|
"Delete image": "Delete image"
|
|
@@ -286,6 +287,7 @@ en:
|
|
|
286
287
|
"New": "New"
|
|
287
288
|
"New Element": "New element"
|
|
288
289
|
"New page": "New page"
|
|
290
|
+
"No menu node for this page found": "No menu node for this page found"
|
|
289
291
|
"No page links for this page found": "No page links for this page found"
|
|
290
292
|
"New password": "New password"
|
|
291
293
|
"New Tag": "New tag"
|
|
@@ -300,7 +302,6 @@ en:
|
|
|
300
302
|
"Page deleted": "%{name} deleted"
|
|
301
303
|
"Page saved": "%{name} saved"
|
|
302
304
|
"Page cache flushed": "Page cache flushed"
|
|
303
|
-
"Pages order saved": "Pages order saved"
|
|
304
305
|
"Password": "Password"
|
|
305
306
|
"Password reset": "Password reset"
|
|
306
307
|
"Paste from clipboard": "Paste from clipboard"
|
|
@@ -411,6 +412,9 @@ en:
|
|
|
411
412
|
delete_node: "Delete this menu node"
|
|
412
413
|
delete_page: "Delete this page"
|
|
413
414
|
delete_tag: "Delete tag"
|
|
415
|
+
search_page: "Search page"
|
|
416
|
+
search_node: "Search menu node"
|
|
417
|
+
search_tag: "Search tag"
|
|
414
418
|
document: "File"
|
|
415
419
|
download_csv: "Download CSV"
|
|
416
420
|
download_file: "Download file '%{filename}'"
|
|
@@ -587,7 +591,12 @@ en:
|
|
|
587
591
|
replace: replace
|
|
588
592
|
replace_file: Replace file
|
|
589
593
|
"Replaced Tag": "Tag '%{old_tag}' was replaced with '%{new_tag}'"
|
|
594
|
+
"%{resource_name} successfully %{action}": "%{resource_name} successfully %{action}."
|
|
590
595
|
resources:
|
|
596
|
+
actions:
|
|
597
|
+
created: "created"
|
|
598
|
+
updated: "updated"
|
|
599
|
+
removed: "removed"
|
|
591
600
|
relation_select:
|
|
592
601
|
blank: "- none -"
|
|
593
602
|
right: "right"
|
|
@@ -656,7 +665,6 @@ en:
|
|
|
656
665
|
"Successfully updated": "Successfully updated"
|
|
657
666
|
"Successfully removed": "Successfully removed"
|
|
658
667
|
"Nothing found": "Nothing found."
|
|
659
|
-
complete: "Abgeschlossen"
|
|
660
668
|
"Update available": "Update available"
|
|
661
669
|
"Update status unavailable": "Update status unavailable"
|
|
662
670
|
"Uploading": "Uploading"
|
|
@@ -790,7 +798,7 @@ en:
|
|
|
790
798
|
other: "Elements"
|
|
791
799
|
alchemy/ingredients/headline:
|
|
792
800
|
one: Headline
|
|
793
|
-
other:
|
|
801
|
+
other: Headlines
|
|
794
802
|
alchemy/legacy_page_url:
|
|
795
803
|
one: "Link"
|
|
796
804
|
other: "Links"
|
|
@@ -809,6 +817,9 @@ en:
|
|
|
809
817
|
alchemy/picture:
|
|
810
818
|
one: Picture
|
|
811
819
|
other: Pictures
|
|
820
|
+
alchemy/picture_description:
|
|
821
|
+
one: Picture Description
|
|
822
|
+
other: Picture Descriptions
|
|
812
823
|
alchemy/user:
|
|
813
824
|
one: User
|
|
814
825
|
other: User
|
|
@@ -899,6 +910,8 @@ en:
|
|
|
899
910
|
image_file_size: "Filesize"
|
|
900
911
|
name: "Name"
|
|
901
912
|
tag_list: Tags
|
|
913
|
+
alchemy/picture_description:
|
|
914
|
+
text: "Description"
|
|
902
915
|
alchemy/site:
|
|
903
916
|
name: "Name"
|
|
904
917
|
host: "Primary Host"
|
data/config/routes.rb
CHANGED
|
@@ -22,7 +22,6 @@ Alchemy::Engine.routes.draw do
|
|
|
22
22
|
resources :pages do
|
|
23
23
|
resources :elements
|
|
24
24
|
collection do
|
|
25
|
-
post :order
|
|
26
25
|
post :flush
|
|
27
26
|
post :copy_language_tree
|
|
28
27
|
get :create_language
|
|
@@ -65,6 +64,8 @@ Alchemy::Engine.routes.draw do
|
|
|
65
64
|
end
|
|
66
65
|
end
|
|
67
66
|
|
|
67
|
+
resources :picture_descriptions, only: [:index, :edit]
|
|
68
|
+
|
|
68
69
|
resources :attachments, except: [:new] do
|
|
69
70
|
member do
|
|
70
71
|
get :download
|
|
@@ -116,6 +117,7 @@ Alchemy::Engine.routes.draw do
|
|
|
116
117
|
resources :elements, only: :show
|
|
117
118
|
|
|
118
119
|
namespace :api, defaults: {format: "json"} do
|
|
120
|
+
resources :attachments, only: [:index]
|
|
119
121
|
resources :ingredients, only: [:index]
|
|
120
122
|
|
|
121
123
|
resources :elements, only: [:index, :show]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class CreateAlchemyPictureDescriptions < ActiveRecord::Migration[7.0]
|
|
2
|
+
def change
|
|
3
|
+
create_table :alchemy_picture_descriptions do |t|
|
|
4
|
+
t.belongs_to :picture, null: false, foreign_key: {to_table: :alchemy_pictures}
|
|
5
|
+
t.belongs_to :language, null: false, foreign_key: {to_table: :alchemy_languages}
|
|
6
|
+
t.text :text
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -28,7 +28,7 @@ module Alchemy
|
|
|
28
28
|
# matches the current I18n.locale then the prefix os omitted.
|
|
29
29
|
# Also, if only one published language exists.
|
|
30
30
|
#
|
|
31
|
-
def prefix_locale?(locale =
|
|
31
|
+
def prefix_locale?(locale = Current.language&.code)
|
|
32
32
|
return false unless locale
|
|
33
33
|
|
|
34
34
|
multi_language? && locale != ::I18n.default_locale.to_s
|
|
@@ -56,7 +56,7 @@ module Alchemy
|
|
|
56
56
|
# can be scoped against it.
|
|
57
57
|
#
|
|
58
58
|
def set_current_alchemy_site
|
|
59
|
-
|
|
59
|
+
Current.site = current_alchemy_site
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
# Sets the current language for Alchemy.
|
|
@@ -83,11 +83,11 @@ module Alchemy
|
|
|
83
83
|
Language.find_by_code(id_or_code)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
# Stores language in +
|
|
86
|
+
# Stores language in +Current.language+
|
|
87
87
|
#
|
|
88
88
|
def store_current_alchemy_language(language)
|
|
89
89
|
if language&.id
|
|
90
|
-
|
|
90
|
+
Current.language = language
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -42,6 +42,16 @@ module Alchemy
|
|
|
42
42
|
all.detect { |a| a["name"] == name }
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
def reset!
|
|
46
|
+
@definitions = nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The absolute +elements.yml+ file path
|
|
50
|
+
# @return [Pathname]
|
|
51
|
+
def definitions_file_path
|
|
52
|
+
Rails.root.join("config", "alchemy", "elements.yml")
|
|
53
|
+
end
|
|
54
|
+
|
|
45
55
|
private
|
|
46
56
|
|
|
47
57
|
# Reads the element definitions from +config/alchemy/elements.yml+.
|
|
@@ -58,12 +68,6 @@ module Alchemy
|
|
|
58
68
|
"Could not find elements.yml file! Please run `rails generate alchemy:install`"
|
|
59
69
|
end
|
|
60
70
|
end
|
|
61
|
-
|
|
62
|
-
# Returns the elements.yml file path
|
|
63
|
-
#
|
|
64
|
-
def definitions_file_path
|
|
65
|
-
Rails.root.join "config/alchemy/elements.yml"
|
|
66
|
-
end
|
|
67
71
|
end
|
|
68
72
|
end
|
|
69
73
|
end
|
data/lib/alchemy/engine.rb
CHANGED
|
@@ -35,6 +35,23 @@ module Alchemy
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
initializer "alchemy.watch_definition_changes" do |app|
|
|
39
|
+
elements_reloader = app.config.file_watcher.new([ElementDefinition.definitions_file_path]) do
|
|
40
|
+
Rails.logger.info "[#{engine_name}] Reloading Element Definitions."
|
|
41
|
+
ElementDefinition.reset!
|
|
42
|
+
end
|
|
43
|
+
page_layouts_reloader = app.config.file_watcher.new([PageLayout.layouts_file_path]) do
|
|
44
|
+
Rails.logger.info "[#{engine_name}] Reloading Page Layouts."
|
|
45
|
+
PageLayout.reset!
|
|
46
|
+
end
|
|
47
|
+
[elements_reloader, page_layouts_reloader].each do |reloader|
|
|
48
|
+
app.reloaders << reloader
|
|
49
|
+
app.reloader.to_run do
|
|
50
|
+
reloader.execute_if_updated
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
38
55
|
# Gutentag downcases all tags before save
|
|
39
56
|
# and Gutentag validations are not case sensitive.
|
|
40
57
|
# But we support having tags with uppercase characters.
|
|
@@ -47,8 +64,8 @@ module Alchemy
|
|
|
47
64
|
initializer "alchemy.ransack" do
|
|
48
65
|
Ransack.configure do |config|
|
|
49
66
|
config.custom_arrows = {
|
|
50
|
-
up_arrow: '<
|
|
51
|
-
down_arrow: '<
|
|
67
|
+
up_arrow: '<alchemy-icon name="arrow-up" size="1x"></alchemy-icon>',
|
|
68
|
+
down_arrow: '<alchemy-icon name="arrow-down" size="1x"></alchemy-icon>'
|
|
52
69
|
}
|
|
53
70
|
end
|
|
54
71
|
end
|
data/lib/alchemy/page_layout.rb
CHANGED
|
@@ -41,6 +41,16 @@ module Alchemy
|
|
|
41
41
|
all.detect { |a| a["name"].casecmp(name).zero? }
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def reset!
|
|
45
|
+
@definitions = nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# The absolute +page_layouts.yml+ file path
|
|
49
|
+
# @return [Pathname]
|
|
50
|
+
def layouts_file_path
|
|
51
|
+
Rails.root.join("config", "alchemy", "page_layouts.yml")
|
|
52
|
+
end
|
|
53
|
+
|
|
44
54
|
private
|
|
45
55
|
|
|
46
56
|
# Reads the layout definitions from +config/alchemy/page_layouts.yml+.
|
|
@@ -58,12 +68,6 @@ module Alchemy
|
|
|
58
68
|
raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:install`"
|
|
59
69
|
end
|
|
60
70
|
end
|
|
61
|
-
|
|
62
|
-
# Returns the page_layouts.yml file path
|
|
63
|
-
#
|
|
64
|
-
def layouts_file_path
|
|
65
|
-
Rails.root.join "config/alchemy/page_layouts.yml"
|
|
66
|
-
end
|
|
67
71
|
end
|
|
68
72
|
end
|
|
69
73
|
end
|
data/lib/alchemy/permissions.rb
CHANGED
|
@@ -42,7 +42,7 @@ module Alchemy
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
can :read, Alchemy::Page, Alchemy::Page.published.not_restricted.from_current_site do |p|
|
|
45
|
-
p.public? && !p.restricted? && p.site == Alchemy::
|
|
45
|
+
p.public? && !p.restricted? && p.site == Alchemy::Current.site
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -65,7 +65,7 @@ module Alchemy
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
can :read, Alchemy::Page, Alchemy::Page.published.from_current_site do |p|
|
|
68
|
-
p.public? && p.site == Alchemy::
|
|
68
|
+
p.public? && p.site == Alchemy::Current.site
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -157,6 +157,7 @@ module Alchemy
|
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
can :manage, Alchemy::Picture
|
|
160
|
+
can :manage, Alchemy::PictureDescription
|
|
160
161
|
can :manage, Alchemy::Attachment
|
|
161
162
|
can :manage, Alchemy::Tag
|
|
162
163
|
can :index, Alchemy::Language
|
data/lib/alchemy/seeder.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Alchemy
|
|
|
31
31
|
log "There are already pages present in your database. " \
|
|
32
32
|
"Please use `rake db:reset' if you want to rebuild your database.", :skip
|
|
33
33
|
else
|
|
34
|
-
create_default_site! unless Alchemy::Site.
|
|
34
|
+
create_default_site! unless Alchemy::Site.first
|
|
35
35
|
create_default_language! unless Alchemy::Language.default
|
|
36
36
|
seed_pages if contentpages.present?
|
|
37
37
|
seed_layoutpages if layoutpages.present?
|
|
@@ -126,7 +126,7 @@ module Alchemy
|
|
|
126
126
|
page_layout: default_language["page_layout"],
|
|
127
127
|
public: true,
|
|
128
128
|
default: true,
|
|
129
|
-
site: Alchemy::Site.
|
|
129
|
+
site: Alchemy::Site.first
|
|
130
130
|
)
|
|
131
131
|
else
|
|
132
132
|
raise DefaultLanguageNotFoundError
|
data/lib/alchemy/tinymce.rb
CHANGED
data/lib/alchemy/version.rb
CHANGED
data/lib/alchemy.rb
CHANGED
|
@@ -102,4 +102,40 @@ module Alchemy
|
|
|
102
102
|
# JS Importmap instance
|
|
103
103
|
singleton_class.attr_accessor :importmap
|
|
104
104
|
self.importmap = Importmap::Map.new
|
|
105
|
+
|
|
106
|
+
# Configure tabs in the link dialog
|
|
107
|
+
#
|
|
108
|
+
# With this configuration that tabs in the link dialog can be extended
|
|
109
|
+
# without overwriting or defacing the Admin Interface.
|
|
110
|
+
#
|
|
111
|
+
# == Example
|
|
112
|
+
#
|
|
113
|
+
# # components/acme/link_tab.rb
|
|
114
|
+
# module Acme
|
|
115
|
+
# class LinkTab < ::Alchemy::Admin::LinkDialog::BaseTab
|
|
116
|
+
# def title
|
|
117
|
+
# "Awesome Tab Title"
|
|
118
|
+
# end
|
|
119
|
+
#
|
|
120
|
+
# def name
|
|
121
|
+
# :unique_name
|
|
122
|
+
# end
|
|
123
|
+
#
|
|
124
|
+
# def fields
|
|
125
|
+
# [ title_input, target_select ]
|
|
126
|
+
# end
|
|
127
|
+
# end
|
|
128
|
+
# end
|
|
129
|
+
#
|
|
130
|
+
# # config/initializers/alchemy.rb
|
|
131
|
+
# Alchemy.link_dialog_tabs << Acme::LinkTab
|
|
132
|
+
#
|
|
133
|
+
def self.link_dialog_tabs
|
|
134
|
+
@_link_dialog_tabs ||= Set.new([
|
|
135
|
+
Alchemy::Admin::LinkDialog::InternalTab,
|
|
136
|
+
Alchemy::Admin::LinkDialog::AnchorTab,
|
|
137
|
+
Alchemy::Admin::LinkDialog::ExternalTab,
|
|
138
|
+
Alchemy::Admin::LinkDialog::FileTab
|
|
139
|
+
])
|
|
140
|
+
end
|
|
105
141
|
end
|
data/lib/alchemy_cms.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<%% cache [node, @page,
|
|
1
|
+
<%% cache [node, @page, Alchemy::Current.preview_page?] do %>
|
|
2
2
|
<%%= content_tag :li, class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do %>
|
|
3
3
|
<%%= link_to_if node.url,
|
|
4
4
|
node.name,
|
|
5
|
-
|
|
5
|
+
Alchemy::Current.preview_page? ? 'javascript: void(0)' : node.url,
|
|
6
6
|
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
|
7
7
|
title: node.title,
|
|
8
8
|
target: node.external? ? '_blank' : nil,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
- cache [node, @page,
|
|
1
|
+
- cache [node, @page, Alchemy::Current.preview_page?] do
|
|
2
2
|
= content_tag :li,
|
|
3
3
|
class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do
|
|
4
4
|
= link_to_if node.url,
|
|
5
5
|
node.name,
|
|
6
|
-
|
|
6
|
+
Alchemy::Current.preview_page? ? 'javascript: void(0)' : node.url,
|
|
7
7
|
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
|
8
8
|
title: node.title,
|
|
9
9
|
target: node.external? ? '_blank' : nil,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
- cache [node, @page,
|
|
1
|
+
- cache [node, @page, Alchemy::Current.preview_page?] do
|
|
2
2
|
= content_tag :li,
|
|
3
3
|
class: ['nav-item', node.children.any? ? 'dropdown' : nil].compact do
|
|
4
4
|
= link_to_if node.url,
|
|
5
5
|
node.name,
|
|
6
|
-
|
|
6
|
+
Alchemy::Current.preview_page? ? 'javascript: void(0)' : node.url,
|
|
7
7
|
class: ['nav-link', current_page?(node.url) ? 'active' : nil].compact,
|
|
8
8
|
title: node.title,
|
|
9
9
|
target: node.external? ? '_blank' : nil,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
class SiteMapIssueFinder
|
|
2
|
+
attr_reader :save
|
|
3
|
+
attr_accessor :depth_issue_page_ids, :lft_rgt_issue_page_ids
|
|
4
|
+
|
|
5
|
+
def initialize(save: false)
|
|
6
|
+
@save = save
|
|
7
|
+
@depth_issue_page_ids = Set.new
|
|
8
|
+
@lft_rgt_issue_page_ids = Set.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def depth_issues
|
|
12
|
+
puts "\nFind Page Depth Issues"
|
|
13
|
+
puts "======================\n"
|
|
14
|
+
|
|
15
|
+
Alchemy::Page.each_with_level(Alchemy::Page.root.self_and_descendants) do |page, level|
|
|
16
|
+
not_the_same_level = level != page.depth
|
|
17
|
+
print not_the_same_level ? "F" : "."
|
|
18
|
+
if not_the_same_level
|
|
19
|
+
depth_issue_page_ids << page.id
|
|
20
|
+
page.update_column(:depth, level) if save
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
print_conclusion(depth_issue_page_ids, "depth")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def lft_rgt_issues
|
|
28
|
+
puts "\nFind Page Left/Right Value Issues"
|
|
29
|
+
puts "=================================\n"
|
|
30
|
+
|
|
31
|
+
Alchemy::Page.roots.each do |root_page|
|
|
32
|
+
traverse_children(root_page, root_page.lft)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
print_conclusion(lft_rgt_issue_page_ids, "left/right value")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def print_conclusion(page_ids, field_description)
|
|
41
|
+
puts "\n\n"
|
|
42
|
+
if page_ids.length > 0
|
|
43
|
+
if save
|
|
44
|
+
puts "Found and corrected #{field_description} for #{page_ids.length} page(s)!"
|
|
45
|
+
else
|
|
46
|
+
puts "Following Pages have an incorrect #{field_description}: #{page_ids.join(", ")}"
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
puts "All pages have the correct #{field_description}!\n"
|
|
50
|
+
end
|
|
51
|
+
puts "\n"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fix_page_field(page, field, counter)
|
|
55
|
+
wrong_counter = page[field] != counter
|
|
56
|
+
print wrong_counter ? "F" : "."
|
|
57
|
+
if wrong_counter
|
|
58
|
+
lft_rgt_issue_page_ids << page.id
|
|
59
|
+
page.update_column(field, counter) if save
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
##
|
|
64
|
+
# @param [Alchemy::Page] page
|
|
65
|
+
# @param [Integer] counter
|
|
66
|
+
# @return [Integer]
|
|
67
|
+
def traverse_children(page, counter)
|
|
68
|
+
page.children.order(lft: :asc).each do |child_page|
|
|
69
|
+
counter += 1
|
|
70
|
+
fix_page_field(child_page, :lft, counter)
|
|
71
|
+
counter = traverse_children(child_page, counter) unless child_page.leaf?
|
|
72
|
+
|
|
73
|
+
counter += 1
|
|
74
|
+
fix_page_field(child_page, :rgt, counter)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
counter
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
namespace :alchemy do
|
|
82
|
+
namespace :sitemap do
|
|
83
|
+
desc "Get an overview over all sitemap issues"
|
|
84
|
+
task anomalies: [:environment] do
|
|
85
|
+
finder = SiteMapIssueFinder.new
|
|
86
|
+
finder.lft_rgt_issues
|
|
87
|
+
finder.depth_issues
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
desc "Fix nested set sitemap issues"
|
|
91
|
+
task fix: [:environment] do
|
|
92
|
+
finder = SiteMapIssueFinder.new(save: true)
|
|
93
|
+
finder.lft_rgt_issues
|
|
94
|
+
finder.depth_issues
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/package.json
CHANGED
|
@@ -11,28 +11,28 @@
|
|
|
11
11
|
"license": "BSD-3-Clause",
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@rails/ujs": "^7.1.3",
|
|
14
|
-
"@shoelace-style/shoelace": "^2.
|
|
14
|
+
"@shoelace-style/shoelace": "^2.14.0",
|
|
15
15
|
"@ungap/custom-elements": "^1.3.0",
|
|
16
16
|
"clipboard": "^2.0.11",
|
|
17
17
|
"flatpickr": "^4.6.13",
|
|
18
18
|
"keymaster": "^1.6.2",
|
|
19
19
|
"sortablejs": "^1.15.2",
|
|
20
|
-
"tinymce": "^
|
|
20
|
+
"tinymce": "^7.1.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@babel/core": "^7.
|
|
24
|
-
"@babel/preset-env": "^7.
|
|
23
|
+
"@babel/core": "^7.24.5",
|
|
24
|
+
"@babel/preset-env": "^7.24.5",
|
|
25
25
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
26
26
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
27
27
|
"@rollup/plugin-terser": "^0.4.4",
|
|
28
28
|
"babel-jest": "^29.6.4",
|
|
29
|
-
"eslint": "^8.
|
|
29
|
+
"eslint": "^8.57.0",
|
|
30
30
|
"jest": "^29.6.4",
|
|
31
31
|
"jest-environment-jsdom": "^29.6.4",
|
|
32
32
|
"jquery": "^3.7.1",
|
|
33
|
-
"jsdom-testing-mocks": "^1.
|
|
34
|
-
"prettier": "^3.2.
|
|
35
|
-
"rollup": "^4.
|
|
33
|
+
"jsdom-testing-mocks": "^1.13.0",
|
|
34
|
+
"prettier": "^3.2.5",
|
|
35
|
+
"rollup": "^4.17.2",
|
|
36
36
|
"xhr-mock": "^2.5.1"
|
|
37
37
|
},
|
|
38
38
|
"jest": {
|