alchemy_cms 8.0.10 → 8.1.0
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/README.md +14 -10
- data/app/assets/builds/alchemy/admin.css +1 -1
- data/app/assets/builds/alchemy/dark-theme.css +1 -1
- data/app/assets/builds/alchemy/light-theme.css +1 -1
- data/app/assets/builds/alchemy/preview.min.js +1 -1
- data/app/assets/builds/alchemy/theme.css +1 -1
- data/app/{views/alchemy/admin/elements/_element.html.erb → components/alchemy/admin/element_editor.html.erb} +34 -29
- data/app/components/alchemy/admin/element_editor.rb +115 -0
- data/app/components/alchemy/admin/element_select.rb +12 -9
- data/app/components/alchemy/admin/ingredient_editor.rb +54 -0
- data/app/components/alchemy/admin/list_filter.rb +16 -5
- data/app/components/alchemy/admin/page_node.html.erb +214 -0
- data/app/components/alchemy/admin/page_node.rb +70 -0
- data/app/components/alchemy/admin/picture_thumbnail.rb +36 -0
- data/app/components/alchemy/admin/publish_page_button.html.erb +15 -0
- data/app/components/alchemy/admin/publish_page_button.rb +54 -0
- data/app/{helpers/alchemy/admin/tags_helper.rb → components/alchemy/admin/tags_list.rb} +19 -11
- data/app/components/alchemy/admin/toolbar_button.rb +17 -13
- data/app/components/alchemy/ingredients/audio_editor.rb +8 -0
- data/app/components/alchemy/ingredients/base_editor.rb +222 -0
- data/app/components/alchemy/ingredients/boolean_editor.rb +21 -0
- data/app/components/alchemy/ingredients/color_editor.rb +80 -0
- data/app/components/alchemy/ingredients/color_view.rb +13 -0
- data/app/components/alchemy/ingredients/datetime_editor.rb +28 -0
- data/app/components/alchemy/ingredients/file_editor.rb +69 -0
- data/app/components/alchemy/ingredients/headline_editor.rb +88 -0
- data/app/components/alchemy/ingredients/html_editor.rb +11 -0
- data/app/components/alchemy/ingredients/link_editor.rb +29 -0
- data/app/components/alchemy/ingredients/node_editor.rb +23 -0
- data/app/components/alchemy/ingredients/number_editor.rb +28 -0
- data/app/components/alchemy/ingredients/page_editor.rb +19 -0
- data/app/components/alchemy/ingredients/picture_editor.rb +81 -0
- data/app/components/alchemy/ingredients/richtext_editor.rb +31 -0
- data/app/components/alchemy/ingredients/select_editor.rb +37 -0
- data/app/components/alchemy/ingredients/select_view.rb +7 -0
- data/app/components/alchemy/ingredients/text_editor.rb +41 -0
- data/app/components/alchemy/ingredients/video_editor.rb +8 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -6
- data/app/controllers/alchemy/admin/base_controller.rb +7 -18
- data/app/controllers/alchemy/admin/clipboard_controller.rb +15 -11
- data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -2
- data/app/controllers/alchemy/admin/elements_controller.rb +34 -32
- data/app/controllers/alchemy/admin/ingredients_controller.rb +1 -0
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +2 -1
- data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +1 -1
- data/app/controllers/alchemy/admin/nodes_controller.rb +24 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +36 -42
- data/app/controllers/alchemy/admin/pictures_controller.rb +2 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/api/ingredients_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +5 -3
- data/app/controllers/alchemy/base_controller.rb +6 -6
- data/app/controllers/alchemy/pages_controller.rb +12 -6
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +0 -1
- data/app/controllers/concerns/alchemy/admin/clipboard.rb +57 -0
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +2 -2
- data/app/controllers/concerns/alchemy/site_redirects.rb +1 -1
- data/app/decorators/alchemy/ingredient_editor.rb +37 -4
- data/app/helpers/alchemy/admin/base_helper.rb +10 -6
- data/app/helpers/alchemy/admin/ingredients_helper.rb +6 -3
- data/app/helpers/alchemy/base_helper.rb +1 -1
- data/app/helpers/alchemy/pages_helper.rb +1 -1
- data/app/javascript/alchemy_admin/components/action.js +5 -1
- data/app/javascript/alchemy_admin/components/color_select.js +73 -0
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +11 -3
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +7 -2
- data/app/javascript/alchemy_admin/components/element_editor.js +11 -12
- data/app/javascript/alchemy_admin/components/element_select.js +39 -17
- data/app/javascript/alchemy_admin/components/elements_window.js +0 -2
- data/app/javascript/alchemy_admin/components/file_editor.js +26 -0
- data/app/javascript/alchemy_admin/components/index.js +9 -0
- data/app/javascript/alchemy_admin/components/list_filter.js +57 -8
- data/app/javascript/alchemy_admin/components/message.js +9 -3
- data/app/javascript/alchemy_admin/components/page_node.js +119 -0
- data/app/javascript/alchemy_admin/{page_publication_fields.js → components/page_publication_fields.js} +9 -8
- data/app/javascript/alchemy_admin/{picture_editors.js → components/picture_editor.js} +30 -45
- data/app/javascript/alchemy_admin/components/picture_thumbnail.js +107 -0
- data/app/javascript/alchemy_admin/components/publish_page_button.js +41 -0
- data/app/javascript/alchemy_admin/components/select.js +3 -1
- data/app/javascript/alchemy_admin/components/sitemap.js +210 -0
- data/app/javascript/alchemy_admin/{sortable_elements.js → components/sortable_elements.js} +22 -25
- data/app/javascript/alchemy_admin/components/tinymce.js +10 -5
- data/app/javascript/alchemy_admin/components/uploader.js +30 -0
- data/app/javascript/alchemy_admin/image_overlay.js +0 -2
- data/app/javascript/alchemy_admin/initializer.js +0 -3
- data/app/javascript/alchemy_admin/link_dialog.js +1 -6
- data/app/javascript/alchemy_admin/templates/compiled.js +1 -1
- data/app/javascript/alchemy_admin/utils/ajax.js +15 -3
- data/app/javascript/alchemy_admin.js +0 -6
- data/app/models/alchemy/attachment.rb +4 -4
- data/app/models/alchemy/element/definitions.rb +1 -2
- data/app/models/alchemy/element/element_ingredients.rb +6 -2
- data/app/models/alchemy/element.rb +54 -13
- data/app/models/alchemy/element_definition.rb +4 -1
- data/app/models/alchemy/elements_repository.rb +6 -0
- data/app/models/alchemy/folded_page.rb +2 -2
- data/app/models/alchemy/ingredient.rb +38 -1
- data/app/models/alchemy/ingredient_definition.rb +4 -1
- data/app/models/alchemy/ingredient_validator.rb +6 -2
- data/app/models/alchemy/ingredients/color.rb +10 -0
- data/app/models/alchemy/ingredients/headline.rb +2 -17
- data/app/models/alchemy/ingredients/picture.rb +4 -4
- data/app/models/alchemy/ingredients/select.rb +19 -0
- data/app/models/alchemy/node.rb +28 -1
- data/app/models/alchemy/page/page_naming.rb +0 -7
- data/app/models/alchemy/page/page_natures.rb +7 -3
- data/app/models/alchemy/page/page_scopes.rb +13 -1
- data/app/models/alchemy/page/publisher.rb +14 -2
- data/app/models/alchemy/page.rb +102 -23
- data/app/models/alchemy/page_definition.rb +4 -1
- data/app/models/alchemy/page_version.rb +22 -6
- data/app/models/alchemy/picture.rb +10 -11
- data/app/models/alchemy/picture_variant.rb +1 -3
- data/app/models/alchemy/resource.rb +1 -1
- data/app/models/alchemy/storage_adapter/active_storage.rb +14 -2
- data/app/models/alchemy/storage_adapter/dragonfly.rb +12 -0
- data/app/models/alchemy/storage_adapter.rb +2 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +4 -4
- data/app/models/concerns/alchemy/publishable.rb +54 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +11 -31
- data/app/services/alchemy/copy_page.rb +17 -0
- data/app/services/alchemy/duplicate_element.rb +1 -1
- data/app/services/alchemy/page_tree_preloader.rb +105 -0
- data/app/services/alchemy/update_checks/alchemy_app.rb +1 -1
- data/app/stylesheets/alchemy/_extends.scss +3 -9
- data/app/stylesheets/alchemy/_mixins.scss +3 -1
- data/app/stylesheets/alchemy/_themes.scss +19 -10
- data/app/stylesheets/alchemy/admin/archive.scss +1 -0
- data/app/stylesheets/alchemy/admin/base.scss +5 -2
- data/app/stylesheets/alchemy/admin/buttons.scss +3 -3
- data/app/stylesheets/alchemy/admin/element-select.scss +18 -0
- data/app/stylesheets/alchemy/admin/elements.scss +123 -23
- data/app/stylesheets/alchemy/admin/errors.scss +1 -1
- data/app/stylesheets/alchemy/admin/flash.scss +6 -4
- data/app/stylesheets/alchemy/admin/images.scss +9 -5
- data/app/stylesheets/alchemy/admin/list_filter.scss +4 -4
- data/app/stylesheets/alchemy/admin/navigation.scss +1 -1
- data/app/stylesheets/alchemy/admin/notices.scss +1 -2
- data/app/stylesheets/alchemy/admin/selects.scss +36 -21
- data/app/stylesheets/alchemy/admin/shoelace.scss +14 -1
- data/app/stylesheets/alchemy/admin/sitemap.scss +11 -3
- data/app/stylesheets/alchemy/admin/tags.scss +3 -1
- data/app/stylesheets/alchemy/admin/toolbar.scss +1 -1
- data/app/views/alchemy/_edit_mode.html.erb +1 -1
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +35 -31
- data/app/views/alchemy/admin/attachments/_library_sidebar.html.erb +6 -0
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_replace_button.html.erb +1 -8
- data/app/views/alchemy/admin/attachments/_sorting_select.html.erb +13 -0
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/attachments/index.html.erb +5 -11
- data/app/views/alchemy/admin/attachments/show.html.erb +1 -1
- data/app/views/alchemy/admin/clipboard/_button.html.erb +1 -0
- data/app/views/alchemy/admin/clipboard/index.html.erb +4 -5
- data/app/views/alchemy/admin/clipboard/insert.turbo_stream.erb +1 -1
- data/app/views/alchemy/admin/crop.html.erb +5 -7
- data/app/views/alchemy/admin/dashboard/widgets/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +6 -6
- data/app/views/alchemy/admin/elements/_fixed_element.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_footer.html.erb +7 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +5 -5
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +33 -8
- data/app/views/alchemy/admin/elements/create.turbo_stream.erb +10 -10
- data/app/views/alchemy/admin/elements/index.html.erb +29 -16
- data/app/views/alchemy/admin/elements/new.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/update.turbo_stream.erb +3 -5
- data/app/views/alchemy/admin/leave.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/_node.html.erb +19 -0
- data/app/views/alchemy/admin/nodes/edit.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -1
- data/app/views/alchemy/admin/nodes/new.html.erb +14 -1
- data/app/views/alchemy/admin/pages/_current_page.html.erb +3 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +21 -9
- data/app/views/alchemy/admin/pages/_page_status.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +28 -26
- data/app/views/alchemy/admin/pages/_table.html.erb +0 -7
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +3 -6
- data/app/views/alchemy/admin/pages/edit.html.erb +5 -11
- data/app/views/alchemy/admin/pages/flush.turbo_stream.erb +2 -0
- data/app/views/alchemy/admin/pages/fold.turbo_stream.erb +5 -0
- data/app/views/alchemy/admin/pages/index.html.erb +5 -3
- data/app/views/alchemy/admin/pages/new.html.erb +2 -12
- data/app/views/alchemy/admin/pages/publish.turbo_stream.erb +12 -0
- data/app/views/alchemy/admin/pages/tree.html.erb +13 -0
- data/app/views/alchemy/admin/pages/update.turbo_stream.erb +5 -16
- data/app/views/alchemy/admin/partials/_flash_notices.html.erb +1 -1
- data/app/views/alchemy/admin/partials/{_remote_search_form.html.erb → _overlay_search_form.html.erb} +1 -2
- data/app/views/alchemy/admin/partials/_paste_from_clipboard_form.html.erb +12 -0
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +24 -21
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +18 -26
- data/app/views/alchemy/admin/pictures/_picture.html.erb +11 -15
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +3 -6
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +0 -1
- data/app/views/alchemy/admin/pictures/update.turbo_stream.erb +1 -1
- data/app/views/alchemy/admin/resources/_resource_usage_info.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/styleguide/index.html.erb +25 -20
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +2 -2
- data/app/views/alchemy/admin/uploader/_button.html.erb +1 -15
- data/app/views/alchemy/attachments/show.html.erb +1 -1
- data/app/views/alchemy/base/permission_denied.js.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_anchor.html.erb +9 -7
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +12 -5
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +10 -11
- data/app/views/alchemy/language_links/_spacer.html.erb +1 -1
- data/app/views/alchemy/messages_mailer/new.html.erb +1 -1
- data/app/views/alchemy/welcome.html.erb +1 -1
- data/config/locales/alchemy.en.yml +12 -3
- data/config/routes.rb +2 -2
- data/db/migrate/20230123112425_add_searchable_to_alchemy_pages.rb +1 -1
- data/db/migrate/20230505132743_add_indexes_to_alchemy_pictures.rb +1 -1
- data/db/migrate/20231113104432_create_page_mutexes.rb +1 -1
- data/db/migrate/20240314105244_create_alchemy_picture_descriptions.rb +1 -1
- data/db/migrate/20250626160259_add_unique_index_to_picture_descriptions.rb +1 -1
- data/db/migrate/20250905140323_add_created_at_index_to_pictures_and_attachments.rb +1 -1
- data/db/migrate/20251106150010_convert_select_value_for_multiple.rb +11 -0
- data/db/migrate/20260102121232_add_metadata_to_page_versions.rb +9 -0
- data/db/migrate/20260115164704_add_publication_timestamps_to_alchemy_elements.rb +30 -0
- data/db/migrate/20260115164705_add_index_to_element_publication_timestamps.rb +13 -0
- data/lib/alchemy/ability_helper.rb +1 -3
- data/lib/alchemy/auth_accessors.rb +51 -117
- data/lib/alchemy/configuration.rb +1 -0
- data/lib/alchemy/configurations/main.rb +63 -0
- data/lib/alchemy/controller_actions.rb +1 -1
- data/lib/alchemy/engine.rb +9 -12
- data/lib/alchemy/error_tracking/error_logger.rb +1 -1
- data/lib/alchemy/errors.rb +1 -1
- data/lib/alchemy/logger.rb +34 -4
- data/lib/alchemy/name_conversions.rb +0 -6
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/tasks/usage.rb +4 -4
- data/lib/alchemy/test_support/factories/page_version_factory.rb +3 -0
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +30 -0
- data/lib/alchemy/test_support/shared_ingredient_editor_examples.rb +26 -6
- data/lib/alchemy/test_support/shared_publishable_examples.rb +114 -0
- data/lib/alchemy/upgrader/eight_one.rb +56 -0
- data/lib/alchemy/upgrader.rb +9 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +1 -4
- data/lib/alchemy_cms.rb +0 -1
- data/lib/generators/alchemy/elements/templates/view.html.erb +3 -3
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +6 -8
- data/lib/generators/alchemy/ingredient/templates/editor_component.rb.tt +22 -0
- data/lib/generators/alchemy/page_layouts/templates/layout.html.erb +1 -1
- data/lib/generators/alchemy/site_layouts/templates/layout.html.erb +1 -1
- data/lib/tasks/alchemy/upgrade.rake +21 -7
- data/vendor/javascript/shoelace.min.js +713 -31
- data/vendor/javascript/tinymce.min.js +1 -1
- metadata +104 -84
- data/app/decorators/alchemy/element_editor.rb +0 -90
- data/app/helpers/alchemy/admin/pictures_helper.rb +0 -14
- data/app/javascript/alchemy_admin/file_editors.js +0 -28
- data/app/javascript/alchemy_admin/image_loader.js +0 -54
- data/app/javascript/alchemy_admin/page_sorter.js +0 -71
- data/app/javascript/alchemy_admin/sitemap.js +0 -154
- data/app/javascript/alchemy_admin/templates/page_folder.hbs +0 -3
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -4
- data/app/views/alchemy/admin/pages/_page.html.erb +0 -163
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +0 -30
- data/app/views/alchemy/admin/pages/flush.js.erb +0 -2
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -5
- data/app/views/alchemy/admin/pictures/index.js.erb +0 -2
- data/app/views/alchemy/ingredients/_audio_editor.html.erb +0 -5
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +0 -11
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +0 -20
- data/app/views/alchemy/ingredients/_file_editor.html.erb +0 -52
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +0 -44
- data/app/views/alchemy/ingredients/_html_editor.html.erb +0 -8
- data/app/views/alchemy/ingredients/_link_editor.html.erb +0 -30
- data/app/views/alchemy/ingredients/_node_editor.html.erb +0 -13
- data/app/views/alchemy/ingredients/_number_editor.html.erb +0 -24
- data/app/views/alchemy/ingredients/_page_editor.html.erb +0 -13
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +0 -59
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +0 -15
- data/app/views/alchemy/ingredients/_select_editor.html.erb +0 -31
- data/app/views/alchemy/ingredients/_text_editor.html.erb +0 -29
- data/app/views/alchemy/ingredients/_video_editor.html.erb +0 -5
- data/lib/generators/alchemy/ingredient/templates/editor.html.erb +0 -14
- /data/{lib → app/models}/alchemy/permissions.rb +0 -0
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Alchemy
|
|
4
|
-
class ElementEditor < SimpleDelegator
|
|
5
|
-
alias_method :element, :__getobj__
|
|
6
|
-
|
|
7
|
-
def to_partial_path
|
|
8
|
-
"alchemy/admin/elements/element"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# Returns ingredient editor instances for defined ingredients
|
|
12
|
-
#
|
|
13
|
-
# Creates ingredient on demand if the ingredient is not yet present on the element
|
|
14
|
-
#
|
|
15
|
-
# @return Array<Alchemy::IngredientEditor>
|
|
16
|
-
def ingredients
|
|
17
|
-
ingredient_definitions.map do |ingredient|
|
|
18
|
-
Alchemy::IngredientEditor.new(find_or_create_ingredient(ingredient))
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Are any ingredients defined?
|
|
23
|
-
# @return [Boolean]
|
|
24
|
-
def has_ingredients_defined?
|
|
25
|
-
ingredient_definitions.any?
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Returns the translated ingredient group for displaying in admin editor group headings
|
|
29
|
-
#
|
|
30
|
-
# Translate it in your locale yml file:
|
|
31
|
-
#
|
|
32
|
-
# alchemy:
|
|
33
|
-
# element_groups:
|
|
34
|
-
# foo: Bar
|
|
35
|
-
#
|
|
36
|
-
# Optionally you can scope your ingredient role to an element:
|
|
37
|
-
#
|
|
38
|
-
# alchemy:
|
|
39
|
-
# element_groups:
|
|
40
|
-
# article:
|
|
41
|
-
# foo: Baz
|
|
42
|
-
#
|
|
43
|
-
def translated_group(group)
|
|
44
|
-
Alchemy.t(
|
|
45
|
-
group,
|
|
46
|
-
scope: "element_groups.#{element.name}",
|
|
47
|
-
default: Alchemy.t("element_groups.#{group}", default: group.humanize)
|
|
48
|
-
)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# CSS classes for the element editor partial.
|
|
52
|
-
def css_classes
|
|
53
|
-
[
|
|
54
|
-
"element-editor",
|
|
55
|
-
ingredient_definitions.present? ? "with-ingredients" : "without-ingredients",
|
|
56
|
-
nestable_elements.any? ? "nestable" : "not-nestable",
|
|
57
|
-
taggable? ? "taggable" : "not-taggable",
|
|
58
|
-
folded ? "folded" : "expanded",
|
|
59
|
-
compact? ? "compact" : nil,
|
|
60
|
-
deprecated? ? "deprecated" : nil,
|
|
61
|
-
fixed? ? "is-fixed" : "not-fixed",
|
|
62
|
-
public? ? nil : "element-hidden"
|
|
63
|
-
]
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Tells us, if we should show the element footer and form inputs.
|
|
67
|
-
def editable?
|
|
68
|
-
ingredient_definitions.any? || taggable?
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Fixes Rails partial renderer calling to_model on the object
|
|
72
|
-
# which reveals the delegated element instead of this decorator.
|
|
73
|
-
def respond_to?(*args, **kwargs)
|
|
74
|
-
method_name = args.first
|
|
75
|
-
return false if method_name == :to_model
|
|
76
|
-
|
|
77
|
-
super
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
private
|
|
81
|
-
|
|
82
|
-
def find_or_create_ingredient(definition)
|
|
83
|
-
element.ingredients.detect { _1.role == definition.role } ||
|
|
84
|
-
element.ingredients.create!(
|
|
85
|
-
role: definition.role,
|
|
86
|
-
type: Alchemy::Ingredient.normalize_type(definition.type)
|
|
87
|
-
)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
class FileEditor {
|
|
2
|
-
constructor(container) {
|
|
3
|
-
this.container = container
|
|
4
|
-
this.deleteLink = container.querySelector(".remove_file_link")
|
|
5
|
-
this.fileIcon = container.querySelector(".file_icon")
|
|
6
|
-
this.fileName = container.querySelector(".file_name")
|
|
7
|
-
this.deleteLink.addEventListener("click", this.removeFile.bind(this))
|
|
8
|
-
this.formFieldId = this.deleteLink.dataset.formFieldId
|
|
9
|
-
this.formField = container.querySelector(`#${this.formFieldId}`)
|
|
10
|
-
this.assignFileText = this.deleteLink.dataset.assignFileText
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
removeFile(event) {
|
|
14
|
-
event.stopPropagation()
|
|
15
|
-
this.formField.value = ""
|
|
16
|
-
this.fileIcon.innerHTML = ""
|
|
17
|
-
this.fileName.innerHTML = ""
|
|
18
|
-
this.deleteLink.classList.add("hidden")
|
|
19
|
-
this.container.closest("alchemy-element-editor").setDirty(this.formField)
|
|
20
|
-
return false
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default function init(selector) {
|
|
25
|
-
document.querySelectorAll(selector).forEach((node) => {
|
|
26
|
-
new FileEditor(node)
|
|
27
|
-
})
|
|
28
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// Shows spinner while loading images and
|
|
2
|
-
// fades the image after its been loaded
|
|
3
|
-
|
|
4
|
-
import Spinner from "alchemy_admin/spinner"
|
|
5
|
-
|
|
6
|
-
export default class ImageLoader {
|
|
7
|
-
static init(scope = document) {
|
|
8
|
-
if (typeof scope === "string") {
|
|
9
|
-
scope = document.querySelector(scope)
|
|
10
|
-
}
|
|
11
|
-
scope.querySelectorAll("img").forEach((image) => {
|
|
12
|
-
const loader = new ImageLoader(image)
|
|
13
|
-
loader.load()
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
constructor(image) {
|
|
18
|
-
this.image = image
|
|
19
|
-
this.parent = image.parentNode
|
|
20
|
-
this.spinner = new Spinner("small")
|
|
21
|
-
this.bind()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
bind() {
|
|
25
|
-
this.image.addEventListener("load", this.onLoaded.bind(this))
|
|
26
|
-
this.image.addEventListener("error", this.onError.bind(this))
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
load(force = false) {
|
|
30
|
-
if (!force && this.image.complete) return
|
|
31
|
-
|
|
32
|
-
this.image.classList.add("loading")
|
|
33
|
-
this.spinner.spin(this.parent)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
onLoaded() {
|
|
37
|
-
this.spinner.stop()
|
|
38
|
-
this.image.classList.remove("loading")
|
|
39
|
-
this.unbind()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
onError(evt) {
|
|
43
|
-
const message = `Could not load ${this.image.src}`
|
|
44
|
-
this.spinner.stop()
|
|
45
|
-
this.parent.innerHTML = `<alchemy-icon name="alert" class="error" title="${message}" />`
|
|
46
|
-
console.error(message, evt)
|
|
47
|
-
this.unbind()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
unbind() {
|
|
51
|
-
this.image.removeEventListener("load", this.onLoaded)
|
|
52
|
-
this.image.removeEventListener("error", this.onError)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import Sortable from "sortablejs"
|
|
2
|
-
import { growl } from "alchemy_admin/growler"
|
|
3
|
-
import { patch } from "alchemy_admin/utils/ajax"
|
|
4
|
-
import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay"
|
|
5
|
-
|
|
6
|
-
function onSort(evt) {
|
|
7
|
-
const pageId = evt.item.dataset.pageId
|
|
8
|
-
const url = Alchemy.routes.move_admin_page_path(pageId)
|
|
9
|
-
const data = {
|
|
10
|
-
target_parent_id: evt.to.dataset.parentId,
|
|
11
|
-
new_position: evt.newIndex
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (evt.target === evt.to) {
|
|
15
|
-
pleaseWaitOverlay(true)
|
|
16
|
-
patch(url, data)
|
|
17
|
-
.then(async (response) => {
|
|
18
|
-
const pageData = await response.data
|
|
19
|
-
const pageEl = document.getElementById(`page_${pageId}`)
|
|
20
|
-
const urlPathEl = pageEl.querySelector(".sitemap_url")
|
|
21
|
-
|
|
22
|
-
growl(Alchemy.t("Successfully moved page"))
|
|
23
|
-
urlPathEl.textContent = pageData.url_path
|
|
24
|
-
displayPageFolders()
|
|
25
|
-
})
|
|
26
|
-
.catch((error) => {
|
|
27
|
-
growl(error.message || error, "error")
|
|
28
|
-
Alchemy.currentSitemap.reload()
|
|
29
|
-
})
|
|
30
|
-
.finally(() => {
|
|
31
|
-
pleaseWaitOverlay(false)
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function displayPageFolders() {
|
|
37
|
-
document.querySelectorAll("li.sitemap-item").forEach((el) => {
|
|
38
|
-
const pageFolderEl = el.querySelector(".page_folder")
|
|
39
|
-
const list = el.querySelector(".children")
|
|
40
|
-
const page = {
|
|
41
|
-
folded: el.dataset.folded === "true",
|
|
42
|
-
id: el.dataset.pageId,
|
|
43
|
-
type: el.dataset.type
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (list.children.length > 0 || page.folded) {
|
|
47
|
-
pageFolderEl.outerHTML = Handlebars.templates["page_folder.hbs"]({ page })
|
|
48
|
-
} else {
|
|
49
|
-
pageFolderEl.innerHTML = ""
|
|
50
|
-
}
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function createSortables(sortables) {
|
|
55
|
-
sortables.forEach((el) => {
|
|
56
|
-
new Sortable(el, {
|
|
57
|
-
group: "pages",
|
|
58
|
-
animation: 150,
|
|
59
|
-
fallbackOnBody: true,
|
|
60
|
-
swapThreshold: 0.65,
|
|
61
|
-
handle: ".handle",
|
|
62
|
-
onSort
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export default function () {
|
|
68
|
-
const sortables = document.querySelectorAll("ul.children")
|
|
69
|
-
displayPageFolders()
|
|
70
|
-
createSortables(sortables)
|
|
71
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
// The admin sitemap Alchemy class
|
|
2
|
-
import PageSorter from "alchemy_admin/page_sorter"
|
|
3
|
-
import { on } from "alchemy_admin/utils/events"
|
|
4
|
-
import { get, patch } from "alchemy_admin/utils/ajax"
|
|
5
|
-
import { growl } from "alchemy_admin/growler"
|
|
6
|
-
import { createSortables, displayPageFolders } from "alchemy_admin/page_sorter"
|
|
7
|
-
|
|
8
|
-
export default class Sitemap {
|
|
9
|
-
// Storing some objects.
|
|
10
|
-
constructor(options) {
|
|
11
|
-
const list_template_html = document
|
|
12
|
-
.getElementById("sitemap-list")
|
|
13
|
-
.innerHTML.replace(/__ID__/g, "{{id}}")
|
|
14
|
-
this.search_field = document.querySelector(".search_input_field")
|
|
15
|
-
this.filter_field_clear = document.querySelector(".search_field_clear")
|
|
16
|
-
this.filter_field_clear.removeAttribute("href")
|
|
17
|
-
this.display = document.getElementById("page_filter_result")
|
|
18
|
-
this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
|
|
19
|
-
this.template = Handlebars.compile(
|
|
20
|
-
document.getElementById("sitemap-template").innerHTML
|
|
21
|
-
)
|
|
22
|
-
this.list_template = Handlebars.compile(list_template_html)
|
|
23
|
-
this.items = null
|
|
24
|
-
this.options = options
|
|
25
|
-
Handlebars.registerPartial("list", list_template_html)
|
|
26
|
-
this.load(options.page_root_id)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Loads the sitemap
|
|
30
|
-
load(pageId) {
|
|
31
|
-
const spinner = new Alchemy.Spinner("medium")
|
|
32
|
-
const spinTarget = this.sitemap_wrapper
|
|
33
|
-
spinTarget.innerHTML = ""
|
|
34
|
-
spinner.spin(spinTarget)
|
|
35
|
-
get(this.options.url, { id: pageId })
|
|
36
|
-
.then(async (response) => {
|
|
37
|
-
this.render(await response.data)
|
|
38
|
-
this.handlePageFolders()
|
|
39
|
-
spinner.stop()
|
|
40
|
-
})
|
|
41
|
-
.catch(this.errorHandler)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Reloads the sitemap
|
|
45
|
-
reload() {
|
|
46
|
-
this.load(this.options.page_root_id)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Watch page folder clicks and re-render the page branch
|
|
50
|
-
handlePageFolders() {
|
|
51
|
-
on(
|
|
52
|
-
"click",
|
|
53
|
-
"#sitemap",
|
|
54
|
-
".page_folder",
|
|
55
|
-
function (evt) {
|
|
56
|
-
const spinner = new Alchemy.Spinner("small")
|
|
57
|
-
const pageFolder = evt.target.closest(".page_folder")
|
|
58
|
-
const pageId = pageFolder.dataset.pageId
|
|
59
|
-
pageFolder.innerHTML = ""
|
|
60
|
-
spinner.spin(pageFolder)
|
|
61
|
-
|
|
62
|
-
patch(Alchemy.routes.fold_admin_page_path(pageId))
|
|
63
|
-
.then(async (response) => {
|
|
64
|
-
this.reRender(pageId, await response.data)
|
|
65
|
-
spinner.stop()
|
|
66
|
-
})
|
|
67
|
-
.catch(this.errorHandler)
|
|
68
|
-
}.bind(this)
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Renders the sitemap
|
|
73
|
-
render(data) {
|
|
74
|
-
const renderTarget = this.sitemap_wrapper
|
|
75
|
-
const renderTemplate = this.template
|
|
76
|
-
|
|
77
|
-
renderTarget.innerHTML = renderTemplate({ children: data.pages })
|
|
78
|
-
this.items = document
|
|
79
|
-
.getElementById("sitemap")
|
|
80
|
-
.querySelectorAll(".sitemap_page")
|
|
81
|
-
this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
|
|
82
|
-
this._observe()
|
|
83
|
-
PageSorter()
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
reRender(pageId, data) {
|
|
87
|
-
let pageEl = document.getElementById(`page_${pageId}`)
|
|
88
|
-
pageEl.outerHTML = this.list_template({ children: data.pages })
|
|
89
|
-
pageEl = document.getElementById(`page_${pageId}`)
|
|
90
|
-
const sortables = pageEl.querySelectorAll("ul.children")
|
|
91
|
-
createSortables(sortables)
|
|
92
|
-
displayPageFolders()
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Filters the sitemap
|
|
96
|
-
filter(term) {
|
|
97
|
-
const results = []
|
|
98
|
-
|
|
99
|
-
this.items.forEach(function (item) {
|
|
100
|
-
if (
|
|
101
|
-
term !== "" &&
|
|
102
|
-
item.getAttribute("name").toLowerCase().indexOf(term) !== -1
|
|
103
|
-
) {
|
|
104
|
-
item.classList.add("highlight")
|
|
105
|
-
item.classList.remove("no-match")
|
|
106
|
-
results.push(item)
|
|
107
|
-
} else {
|
|
108
|
-
item.classList.add("no-match")
|
|
109
|
-
item.classList.remove("highlight")
|
|
110
|
-
}
|
|
111
|
-
})
|
|
112
|
-
const { length } = results
|
|
113
|
-
|
|
114
|
-
if (length === 1) {
|
|
115
|
-
this.display.style.display = "block"
|
|
116
|
-
this.display.innerText = `1 ${Alchemy.t("page_found")}`
|
|
117
|
-
results[0].scrollIntoView({ behavior: "smooth", block: "center" })
|
|
118
|
-
} else if (length > 1) {
|
|
119
|
-
this.display.style.display = "block"
|
|
120
|
-
this.display.innerText = `${length} ${Alchemy.t("pages_found")}`
|
|
121
|
-
} else {
|
|
122
|
-
this.items.forEach((item) =>
|
|
123
|
-
item.classList.remove("no-match", "highlight")
|
|
124
|
-
)
|
|
125
|
-
this.display.style.display = "none"
|
|
126
|
-
window.scrollTo({
|
|
127
|
-
top: 0,
|
|
128
|
-
left: 0,
|
|
129
|
-
behavior: "smooth"
|
|
130
|
-
})
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Adds onkey up observer to search field
|
|
135
|
-
_observe() {
|
|
136
|
-
this.search_field.addEventListener("keyup", (evt) => {
|
|
137
|
-
const term = evt.target.value
|
|
138
|
-
this.filter_field_clear.style.visibility =
|
|
139
|
-
term == "" ? "hidden" : "visible"
|
|
140
|
-
this.filter(term.toLowerCase())
|
|
141
|
-
})
|
|
142
|
-
this.search_field.addEventListener("focus", () => key.setScope("search"))
|
|
143
|
-
this.filter_field_clear.addEventListener("click", () => {
|
|
144
|
-
this.search_field.value = ""
|
|
145
|
-
this.filter("")
|
|
146
|
-
return false
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
errorHandler(error) {
|
|
151
|
-
growl(error.message || error, "error")
|
|
152
|
-
console.error(error)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
<li id="page_{{id}}" class="sitemap-item {{page_layout}}" data-slug="{{slug}}" data-restricted="{{restricted}}" data-page-id="{{id}}" data-folded="{{folded}}">
|
|
2
|
-
<div class="sitemap_page{{#if locked}} locked{{/if}}" name="{{name}}">
|
|
3
|
-
<div class="sitemap_left_images">
|
|
4
|
-
<span class="page_folder"></span>
|
|
5
|
-
{{#if definition_missing}}
|
|
6
|
-
<%= page_layout_missing_warning %>
|
|
7
|
-
{{else}}
|
|
8
|
-
{{#if permissions.edit_content}}
|
|
9
|
-
<span class="page-icon {{#unless root}}handle{{/unless}}">
|
|
10
|
-
{{#if locked}}
|
|
11
|
-
<sl-tooltip content="{{locked_notice}}" class="like-hint-tooltip" placement="bottom-start">
|
|
12
|
-
<alchemy-icon name="file-edit" size="xl"></alchemy-icon>
|
|
13
|
-
</sl-tooltip>
|
|
14
|
-
{{else}}
|
|
15
|
-
<alchemy-icon name="file" size="xl"></alchemy-icon>
|
|
16
|
-
{{/if}}
|
|
17
|
-
</span>
|
|
18
|
-
{{else}}
|
|
19
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
20
|
-
<alchemy-icon name="file-forbid" size="xl"></alchemy-icon>
|
|
21
|
-
</sl-tooltip>
|
|
22
|
-
{{/if}}
|
|
23
|
-
{{/if}}
|
|
24
|
-
</div>
|
|
25
|
-
<div class="sitemap_sitename">
|
|
26
|
-
{{#if permissions.edit_content}}
|
|
27
|
-
<%= link_to(
|
|
28
|
-
"{{name}}",
|
|
29
|
-
alchemy.edit_admin_page_path(id: "__ID__"),
|
|
30
|
-
title: Alchemy.t(:edit_page),
|
|
31
|
-
class: "sitemap_pagename_link"
|
|
32
|
-
) -%>
|
|
33
|
-
{{else}}
|
|
34
|
-
<%= content_tag("span", "{{name}}", class: "sitemap_pagename_link") %>
|
|
35
|
-
{{/if}}
|
|
36
|
-
</div>
|
|
37
|
-
<div class="sitemap_url" title="{{url_path}}">
|
|
38
|
-
{{ url_path }}
|
|
39
|
-
</div>
|
|
40
|
-
<div class="page_infos">
|
|
41
|
-
{{#if locked}}
|
|
42
|
-
<span class="page_status locked">
|
|
43
|
-
<alchemy-icon name="edit" size="1x"></alchemy-icon>
|
|
44
|
-
{{status_titles.locked}}
|
|
45
|
-
</span>
|
|
46
|
-
{{/if}}
|
|
47
|
-
{{#if restricted}}
|
|
48
|
-
<span class="page_status">
|
|
49
|
-
<alchemy-icon name="lock" size="1x"></alchemy-icon>
|
|
50
|
-
{{status_titles.restricted}}
|
|
51
|
-
</span>
|
|
52
|
-
{{/if}}
|
|
53
|
-
{{#unless public}}
|
|
54
|
-
<span class="page_status">
|
|
55
|
-
<alchemy-icon name="cloud-off" size="1x"></alchemy-icon>
|
|
56
|
-
{{status_titles.public}}
|
|
57
|
-
</span>
|
|
58
|
-
{{/unless}}
|
|
59
|
-
</div>
|
|
60
|
-
<div class="sitemap_right_tools">
|
|
61
|
-
{{#if permissions.info}}
|
|
62
|
-
<sl-tooltip content="<%= Alchemy.t(:page_infos) %>">
|
|
63
|
-
<%= link_to_dialog(
|
|
64
|
-
render_icon("information"),
|
|
65
|
-
alchemy.info_admin_page_path(id: "__ID__"),
|
|
66
|
-
{
|
|
67
|
-
title: Alchemy.t(:page_infos),
|
|
68
|
-
size: "520x290"
|
|
69
|
-
},
|
|
70
|
-
class: "icon_button"
|
|
71
|
-
) %>
|
|
72
|
-
</sl-tooltip>
|
|
73
|
-
{{else}}
|
|
74
|
-
<div class="sitemap_tool disabled">
|
|
75
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
76
|
-
<%= render_icon("information") %>
|
|
77
|
-
</sl-tooltip>
|
|
78
|
-
</div>
|
|
79
|
-
{{/if}}
|
|
80
|
-
{{#if permissions.configure}}
|
|
81
|
-
<sl-tooltip content="<%= Alchemy.t(:edit_page_properties) %>">
|
|
82
|
-
<%= link_to_dialog(
|
|
83
|
-
render_icon("settings-3"),
|
|
84
|
-
alchemy.configure_admin_page_path(id: "__ID__"),
|
|
85
|
-
{
|
|
86
|
-
title: Alchemy.t(:edit_page_properties),
|
|
87
|
-
size: "500x680"
|
|
88
|
-
},
|
|
89
|
-
class: "icon_button"
|
|
90
|
-
) -%>
|
|
91
|
-
</sl-tooltip>
|
|
92
|
-
{{else}}
|
|
93
|
-
<div class="sitemap_tool disabled">
|
|
94
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
95
|
-
<%= render_icon("settings-3") %>
|
|
96
|
-
</sl-tooltip>
|
|
97
|
-
</div>
|
|
98
|
-
{{/if}}
|
|
99
|
-
{{#if permissions.copy}}
|
|
100
|
-
<sl-tooltip content="<%= Alchemy.t(:copy_page) %>">
|
|
101
|
-
<%= button_to(
|
|
102
|
-
render_icon("file-copy"),
|
|
103
|
-
alchemy.insert_admin_clipboard_path(
|
|
104
|
-
remarkable_type: :pages,
|
|
105
|
-
remarkable_id: "__ID__",
|
|
106
|
-
),
|
|
107
|
-
"data-turbo-method": :post,
|
|
108
|
-
class: "icon_button"
|
|
109
|
-
) %>
|
|
110
|
-
</sl-tooltip>
|
|
111
|
-
{{else}}
|
|
112
|
-
<div class="sitemap_tool disabled">
|
|
113
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
114
|
-
<%= render_icon("file-copy") %>
|
|
115
|
-
</sl-tooltip>
|
|
116
|
-
</div>
|
|
117
|
-
{{/if}}
|
|
118
|
-
{{#if permissions.destroy}}
|
|
119
|
-
<sl-tooltip content="<%= Alchemy.t(:delete_page) %>">
|
|
120
|
-
<%= link_to_confirm_dialog(
|
|
121
|
-
render_icon("delete-bin-2"),
|
|
122
|
-
Alchemy.t(:confirm_to_delete_page),
|
|
123
|
-
url_for(
|
|
124
|
-
controller: "pages",
|
|
125
|
-
action: "destroy",
|
|
126
|
-
id: "__ID__"
|
|
127
|
-
),
|
|
128
|
-
class: "icon_button"
|
|
129
|
-
) -%>
|
|
130
|
-
</sl-tooltip>
|
|
131
|
-
{{else}}
|
|
132
|
-
<div class="sitemap_tool disabled">
|
|
133
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
134
|
-
<%= render_icon("delete-bin-2") %>
|
|
135
|
-
</sl-tooltip>
|
|
136
|
-
</div>
|
|
137
|
-
{{/if}}
|
|
138
|
-
{{#if permissions.create}}
|
|
139
|
-
<sl-tooltip content="<%= Alchemy.t(:create_page) %>">
|
|
140
|
-
<%= link_to_dialog(
|
|
141
|
-
render_icon(:add),
|
|
142
|
-
alchemy.new_admin_page_path(parent_id: "__ID__"),
|
|
143
|
-
{
|
|
144
|
-
title: Alchemy.t(:create_page),
|
|
145
|
-
size: "340x165",
|
|
146
|
-
overflow: true
|
|
147
|
-
},
|
|
148
|
-
class: "icon_button"
|
|
149
|
-
) -%>
|
|
150
|
-
</sl-tooltip>
|
|
151
|
-
{{else}}
|
|
152
|
-
<div class="sitemap_tool disabled">
|
|
153
|
-
<sl-tooltip content="<%= Alchemy.t("Your user role does not allow you to edit this page") %>" class="like-hint-tooltip" placement="bottom-start">
|
|
154
|
-
<%= render_icon("file-add") %>
|
|
155
|
-
</sl-tooltip>
|
|
156
|
-
</div>
|
|
157
|
-
{{/if}}
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
<ul id="page_{{id}}_children" class="children" data-parent-id="{{id}}">
|
|
161
|
-
{{> list}}
|
|
162
|
-
</ul>
|
|
163
|
-
</li>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<h4 id="sitemap_heading">
|
|
2
|
-
<span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
|
|
3
|
-
<span class="page_urlname"><%= Alchemy::Page.human_attribute_name(:urlname) %></span>
|
|
4
|
-
<span class="page_status"><%= Alchemy.t(:page_status) %></span>
|
|
5
|
-
</h4>
|
|
6
|
-
|
|
7
|
-
<div id="sitemap-wrapper">
|
|
8
|
-
</div>
|
|
9
|
-
|
|
10
|
-
<script id="sitemap-template" type="text/x-handlebars-template">
|
|
11
|
-
<ul id="sitemap" class="list">
|
|
12
|
-
{{> list}}
|
|
13
|
-
</ul>
|
|
14
|
-
</script>
|
|
15
|
-
|
|
16
|
-
<script id="sitemap-list" type="text/x-handlebars-template">
|
|
17
|
-
{{#each children}}
|
|
18
|
-
<%= render partial: page_partial, object: @page_root %>
|
|
19
|
-
{{/each}}
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<script type="module">
|
|
23
|
-
$(function() {
|
|
24
|
-
Alchemy.currentSitemap = new Alchemy.Sitemap({
|
|
25
|
-
url: '<%= alchemy.tree_admin_pages_path %>',
|
|
26
|
-
page_root_id: <%= @page_root.id %>
|
|
27
|
-
});
|
|
28
|
-
Alchemy.PagePublicationFields();
|
|
29
|
-
});
|
|
30
|
-
</script>
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<%= content_tag :div,
|
|
2
|
-
class: boolean_editor.css_classes,
|
|
3
|
-
data: boolean_editor.data_attributes do %>
|
|
4
|
-
<%= element_form.fields_for(:ingredients, boolean_editor.ingredient) do |f| %>
|
|
5
|
-
<%= f.label :value, style: "display: inline-block", for: nil do %>
|
|
6
|
-
<%= f.check_box :value, id: nil %>
|
|
7
|
-
<%= render_ingredient_role(boolean_editor) %>
|
|
8
|
-
<%= render_hint_for(boolean_editor, size: "1x", fixed_width: false) %>
|
|
9
|
-
<% end %>
|
|
10
|
-
<% end %>
|
|
11
|
-
<% end %>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<%= content_tag :div,
|
|
2
|
-
class: datetime_editor.css_classes,
|
|
3
|
-
data: datetime_editor.data_attributes do %>
|
|
4
|
-
<%= element_form.fields_for(:ingredients, datetime_editor.ingredient) do |f| %>
|
|
5
|
-
<%= ingredient_label(datetime_editor) %>
|
|
6
|
-
<div class="input-field">
|
|
7
|
-
<%= alchemy_datepicker(
|
|
8
|
-
datetime_editor, :value, {
|
|
9
|
-
name: datetime_editor.form_field_name,
|
|
10
|
-
id: datetime_editor.form_field_id,
|
|
11
|
-
value: datetime_editor.value,
|
|
12
|
-
type: datetime_editor.settings[:input_type]
|
|
13
|
-
}
|
|
14
|
-
) %>
|
|
15
|
-
<label for="<%= datetime_editor.form_field_id %>" class="ingredient-date--label">
|
|
16
|
-
<%= render_icon "calendar" %>
|
|
17
|
-
</label>
|
|
18
|
-
</div>
|
|
19
|
-
<% end %>
|
|
20
|
-
<% end %>
|