alchemy_cms 8.1.8 → 8.2.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 +12 -1
- data/app/assets/builds/alchemy/admin.css +1 -1
- data/app/assets/builds/alchemy/alchemy_admin.min.js +2 -0
- data/app/assets/builds/alchemy/alchemy_admin.min.js.map +1 -0
- 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/theme.css +1 -1
- data/app/assets/builds/alchemy/welcome.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
- data/app/assets/builds/tinymce/skins/content/alchemy-dark/content.min.css +1 -1
- data/app/assets/images/alchemy/icons-sprite.svg +1 -1
- data/app/components/alchemy/admin/current_user_name.rb +34 -0
- data/app/components/alchemy/admin/locale_select.rb +12 -8
- data/app/components/alchemy/admin/page_node.html.erb +3 -2
- data/app/components/alchemy/admin/picture_thumbnail.rb +1 -1
- data/app/components/alchemy/admin/preview_time_select.rb +55 -0
- data/app/components/alchemy/admin/publish_element_button.html.erb +41 -0
- data/app/components/alchemy/admin/publish_element_button.rb +13 -0
- data/app/components/alchemy/admin/timezone_select.rb +47 -0
- data/app/components/alchemy/ingredients/base_editor.rb +1 -1
- data/app/components/alchemy/ingredients/select_editor.rb +6 -1
- data/app/controllers/alchemy/admin/base_controller.rb +1 -0
- data/app/controllers/alchemy/admin/elements_controller.rb +54 -34
- data/app/controllers/alchemy/admin/languages_controller.rb +3 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -0
- data/app/controllers/alchemy/admin/resources_controller.rb +11 -6
- data/app/controllers/alchemy/pages_controller.rb +1 -2
- data/app/decorators/alchemy/ingredient_editor.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +4 -7
- data/app/helpers/alchemy/url_helper.rb +2 -10
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +28 -27
- data/app/javascript/alchemy_admin/components/element_editor.js +11 -2
- data/app/javascript/alchemy_admin/components/message.js +5 -1
- data/app/javascript/alchemy_admin/components/uploader/file_upload.js +5 -5
- data/app/javascript/alchemy_admin/image_cropper.js +10 -6
- data/app/javascript/alchemy_admin/initializer.js +6 -33
- data/app/javascript/alchemy_admin/shoelace_theme.js +6 -2
- data/app/javascript/alchemy_admin/templates/compiled.js +1 -1
- data/app/javascript/alchemy_admin.js +12 -2
- data/app/models/alchemy/attachment.rb +1 -1
- data/app/models/alchemy/current.rb +5 -1
- data/app/models/alchemy/element/element_ingredients.rb +11 -3
- data/app/models/alchemy/element.rb +10 -0
- data/app/models/alchemy/ingredient.rb +2 -0
- data/app/models/alchemy/ingredients/select.rb +1 -2
- data/app/models/alchemy/language/code.rb +1 -0
- data/app/models/alchemy/page/etag_generator.rb +21 -0
- data/app/models/alchemy/page/url_path.rb +11 -2
- data/app/models/alchemy/page.rb +12 -2
- data/app/models/alchemy/page_version.rb +5 -5
- data/app/models/alchemy/picture.rb +19 -2
- data/app/models/alchemy/storage_adapter/active_storage.rb +9 -0
- data/app/models/alchemy/storage_adapter/dragonfly.rb +9 -0
- data/app/models/alchemy/storage_adapter.rb +1 -0
- data/app/models/concerns/alchemy/publishable.rb +20 -12
- data/app/models/concerns/alchemy/relatable_resource.rb +16 -2
- data/app/models/concerns/alchemy/touch_elements.rb +3 -3
- data/app/services/alchemy/element_preloader.rb +107 -0
- data/app/services/alchemy/update_checks/alchemy_app.rb +1 -1
- data/app/stylesheets/alchemy/_custom-properties.scss +1 -0
- data/app/stylesheets/alchemy/_mixins.scss +1 -1
- data/app/stylesheets/alchemy/_themes.scss +2 -0
- data/app/stylesheets/alchemy/admin/base.scss +2 -1
- data/app/stylesheets/alchemy/admin/elements.scss +22 -19
- data/app/stylesheets/alchemy/admin/form_fields.scss +3 -0
- data/app/stylesheets/alchemy/admin/forms.scss +14 -1
- data/app/stylesheets/alchemy/admin/frame.scss +9 -8
- data/app/stylesheets/alchemy/admin/notices.scss +1 -1
- data/app/stylesheets/alchemy/admin/popover.scss +37 -0
- data/app/stylesheets/alchemy/admin/selects.scss +4 -0
- data/app/stylesheets/alchemy/admin/shoelace.scss +16 -4
- data/app/stylesheets/alchemy/admin/toolbar.scss +8 -0
- data/app/stylesheets/alchemy/admin.scss +1 -0
- data/app/views/alchemy/admin/_header.html.erb +4 -0
- data/app/views/alchemy/admin/_left_menu.html.erb +24 -0
- data/app/views/alchemy/admin/_main_navi.html.erb +6 -0
- data/app/views/alchemy/admin/_top_menu.html.erb +6 -0
- data/app/views/alchemy/admin/_user_info.html.erb +5 -0
- data/app/views/alchemy/admin/crop.html.erb +6 -11
- data/app/views/alchemy/admin/elements/_header.html.erb +16 -6
- data/app/views/alchemy/admin/elements/_schedule.html.erb +62 -0
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +1 -15
- data/app/views/alchemy/admin/elements/publish.turbo_stream.erb +28 -0
- data/app/views/alchemy/admin/nodes/index.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_locked_pages.html.erb +5 -0
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_table.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +6 -2
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +10 -10
- data/app/views/alchemy/admin/partials/_site_select.html.erb +6 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +2 -2
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +9 -16
- data/app/views/alchemy/admin/uploader/_setup.html.erb +1 -6
- data/app/views/alchemy/language_links/_language.html.erb +1 -2
- data/app/views/layouts/alchemy/admin.html.erb +2 -45
- data/config/importmap.rb +7 -2
- data/config/locales/alchemy.en.yml +35 -5
- data/lib/alchemy/admin/preview_time.rb +23 -0
- data/lib/alchemy/admin/preview_url.rb +13 -2
- data/lib/alchemy/admin/timezone.rb +56 -0
- data/lib/alchemy/configuration.rb +2 -0
- data/lib/alchemy/configurations/main.rb +13 -1
- data/lib/alchemy/controller_actions.rb +2 -1
- data/lib/alchemy/tasks/tidy.rb +6 -7
- data/lib/alchemy/test_support/factories/element_factory.rb +2 -2
- data/lib/alchemy/test_support/relatable_resource_examples.rb +2 -2
- data/lib/alchemy/test_support/shared_publishable_examples.rb +44 -2
- data/lib/alchemy/upgrader.rb +3 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +2 -0
- data/lib/generators/alchemy/install/install_generator.rb +2 -1
- data/vendor/javascript/handlebars.min.js +4 -4
- data/vendor/javascript/shoelace.min.js +1419 -1323
- data/vendor/javascript/sortable.min.js +2 -2
- data/vendor/javascript/tinymce.min.js +1 -1
- metadata +35 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.alchemy-popover {
|
|
2
|
+
position: relative;
|
|
3
|
+
padding: var(--spacing-2);
|
|
4
|
+
|
|
5
|
+
alchemy-message {
|
|
6
|
+
margin-left: 0;
|
|
7
|
+
margin-right: 0;
|
|
8
|
+
margin-bottom: var(--spacing-3);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.timezone-select {
|
|
12
|
+
display: flex;
|
|
13
|
+
gap: var(--spacing-2);
|
|
14
|
+
align-items: center;
|
|
15
|
+
|
|
16
|
+
.alchemy_selectbox {
|
|
17
|
+
min-width: var(--select-x-large-width);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
span.error {
|
|
22
|
+
display: block;
|
|
23
|
+
background-color: var(--notice-error-background-color);
|
|
24
|
+
color: var(--notice-error-text-color);
|
|
25
|
+
padding: var(--spacing-2);
|
|
26
|
+
border-radius: var(--border-radius_medium);
|
|
27
|
+
font-size: var(--font-size_small);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.submit {
|
|
31
|
+
gap: var(--spacing-2);
|
|
32
|
+
|
|
33
|
+
button {
|
|
34
|
+
width: 50%;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
--sl-font-size-2x-small: 0.625rem; /* 10px */
|
|
107
107
|
--sl-font-size-x-small: var(--font-size_small); /* 10px */
|
|
108
108
|
--sl-font-size-small: var(--font-size_medium); /* 12px */
|
|
109
|
-
--sl-font-size-medium: var(--font-
|
|
110
|
-
--sl-font-size-large:
|
|
111
|
-
--sl-font-size-x-large:
|
|
109
|
+
--sl-font-size-medium: var(--font-size_medium); /* 16px */
|
|
110
|
+
--sl-font-size-large: var(--font-size_medium); /* 20px */
|
|
111
|
+
--sl-font-size-x-large: var(--font-size_large); /* 24px */
|
|
112
112
|
--sl-font-size-2x-large: 2.25rem; /* 36px */
|
|
113
113
|
--sl-font-size-3x-large: 3rem; /* 48px */
|
|
114
114
|
--sl-font-size-4x-large: 4.5rem; /* 72px */
|
|
@@ -285,6 +285,15 @@
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
sl-dropdown {
|
|
289
|
+
&::part(panel) {
|
|
290
|
+
background-color: var(--dialog-background-color);
|
|
291
|
+
box-shadow: none;
|
|
292
|
+
filter: drop-shadow(var(--dialog-box-shadow));
|
|
293
|
+
border: 1px solid var(--border-color);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
288
297
|
sl-tab-group {
|
|
289
298
|
--indicator-color: var(--tabs_indicator-color);
|
|
290
299
|
--track-color: var(--tabs_track-color);
|
|
@@ -326,6 +335,10 @@ sl-button {
|
|
|
326
335
|
&[disabled]::part(base) {
|
|
327
336
|
border-color: var(--button-disabled-border-color);
|
|
328
337
|
}
|
|
338
|
+
&[variant="primary"]::part(base),
|
|
339
|
+
&[variant="default"]::part(base) {
|
|
340
|
+
--sl-color-neutral-0: var(--button-primary-text-color);
|
|
341
|
+
}
|
|
329
342
|
}
|
|
330
343
|
|
|
331
344
|
sl-dialog {
|
|
@@ -348,7 +361,6 @@ sl-dialog {
|
|
|
348
361
|
}
|
|
349
362
|
|
|
350
363
|
&::part(title) {
|
|
351
|
-
--sl-font-size-large: var(--font-size_medium);
|
|
352
364
|
color: var(--dialog-header-text-color);
|
|
353
365
|
font-weight: var(--font-weight_bold);
|
|
354
366
|
-webkit-font-smoothing: antialiased;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<div id="left_menu">
|
|
2
|
+
<%= render "alchemy/admin/main_navi" %>
|
|
3
|
+
|
|
4
|
+
<div id="logout">
|
|
5
|
+
<div class="main_navi_entry">
|
|
6
|
+
<% if current_alchemy_user %>
|
|
7
|
+
<%= link_to_dialog(
|
|
8
|
+
%(
|
|
9
|
+
#{render_icon('logout-box-r', class: 'module')}
|
|
10
|
+
<label>#{Alchemy.t(:leave)}</label>
|
|
11
|
+
).html_safe,
|
|
12
|
+
alchemy.leave_admin_path, {
|
|
13
|
+
size: "320x140",
|
|
14
|
+
title: Alchemy.t("Leave Alchemy")
|
|
15
|
+
}, {'data-alchemy-hotkey' => 'alt+q'}) %>
|
|
16
|
+
<% else %>
|
|
17
|
+
<%= link_to(alchemy.root_path) do %>
|
|
18
|
+
<%= render_icon "logout-box-r", size: "lg" %>
|
|
19
|
+
<label><%= Alchemy.t(:leave) %></label>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% end %>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
@@ -18,19 +18,14 @@
|
|
|
18
18
|
<% end %>
|
|
19
19
|
<% if @settings %>
|
|
20
20
|
<script type="module">
|
|
21
|
-
import ImageCropper from "alchemy_admin/image_cropper";
|
|
21
|
+
import { ImageCropper } from "alchemy_admin/image_cropper";
|
|
22
22
|
|
|
23
23
|
const image = document.getElementById("imageToCrop")?.querySelector("img");
|
|
24
24
|
|
|
25
|
-
new ImageCropper(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"<%= params[:crop_from_form_field_id] %>",
|
|
31
|
-
"<%= params[:crop_size_form_field_id] %>",
|
|
32
|
-
],
|
|
33
|
-
<%= @element.id %>
|
|
34
|
-
);
|
|
25
|
+
new ImageCropper(image, <%== @settings.merge(
|
|
26
|
+
crop_from_form_field_id: params[:crop_from_form_field_id],
|
|
27
|
+
crop_size_form_field_id: params[:crop_size_form_field_id],
|
|
28
|
+
element_id: @element.id
|
|
29
|
+
).to_json %>);
|
|
35
30
|
</script>
|
|
36
31
|
<% end %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div class="element-header<%= ' has-hint' if element.has_hint? %>">
|
|
1
|
+
<div class="element-header<%= ' has-hint' if element.has_hint? %>" id="element-header-<%= element.id %>">
|
|
2
2
|
<span class="element-handle<%= ' draggable' if can?(:order, element) %>">
|
|
3
3
|
<% if element.definition.blank? %>
|
|
4
4
|
<%= hint_with_tooltip Alchemy.t(:element_definition_missing), icon_class: "element-icon" %>
|
|
@@ -18,11 +18,21 @@
|
|
|
18
18
|
<%= sanitize(element.preview_text.presence || ' ') %>
|
|
19
19
|
</span>
|
|
20
20
|
</span>
|
|
21
|
-
<span class="element-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
<span class="element-status-icons">
|
|
22
|
+
<% unless element.public? || element.scheduled? %>
|
|
23
|
+
<%= render_icon("cloud-off", size: "1x") %>
|
|
24
|
+
<span class="element-hidden-label">
|
|
25
|
+
<%= Alchemy.t(:element_hidden) %>
|
|
26
|
+
</span>
|
|
27
|
+
<% end %>
|
|
28
|
+
<sl-tooltip
|
|
29
|
+
class="element-scheduled-icon"
|
|
30
|
+
content="<%= Alchemy.t(element.public_on&.future? ? :public_on : :public_until, scope: :element_scheduled, public_on: element.public_on && l(element.public_on, format: :"alchemy.default"), public_until: element.public_until && l(element.public_until, format: :"alchemy.default")) %>"
|
|
31
|
+
<%= "hidden" if !element.scheduled? %>
|
|
32
|
+
>
|
|
33
|
+
<%= render_icon("calendar-schedule", size: "1x") %>
|
|
34
|
+
<%= element.public_on&.future? ? element.public_on && l(element.public_on, format: :"alchemy.short_datetime") : element.public_until && l(element.public_until, format: :"alchemy.short_datetime") %>
|
|
35
|
+
</sl-tooltip>
|
|
26
36
|
</span>
|
|
27
37
|
<sl-tooltip content="<%= Alchemy.t(element.folded? ? :show_element_content : :hide_element_content) %>">
|
|
28
38
|
<%= button_tag(class: "element-toggle") do %>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<div id="element-<%= element.id %>-schedule">
|
|
2
|
+
<% if element.errors.any? %>
|
|
3
|
+
<alchemy-message type="error" icon="warn">
|
|
4
|
+
<%= Alchemy.t(:default_message, scope: "forms.error_notification") %>
|
|
5
|
+
</alchemy-message>
|
|
6
|
+
<% else %>
|
|
7
|
+
<alchemy-message type="info">
|
|
8
|
+
<% if element.public? %>
|
|
9
|
+
<p><%= sanitize t(".visibility_status.public_html") %></p>
|
|
10
|
+
<% if element.scheduled? && element.public_until.present? %>
|
|
11
|
+
<%= sanitize t(".public_scheduled_html",
|
|
12
|
+
public_until: l(element.public_until, format: :"alchemy.element_date")) %>
|
|
13
|
+
<% else %>
|
|
14
|
+
<%= t(".public_no_schedule") %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% else %>
|
|
17
|
+
<p><%= sanitize t(".visibility_status.hidden_html") %></p>
|
|
18
|
+
<% if element.scheduled? %>
|
|
19
|
+
<% if element.public_until.present? %>
|
|
20
|
+
<%= sanitize t(".hidden_window_html",
|
|
21
|
+
public_on: l(element.public_on, format: :"alchemy.element_date"),
|
|
22
|
+
public_until: l(element.public_until, format: :"alchemy.element_date")) %>
|
|
23
|
+
<% else %>
|
|
24
|
+
<%= sanitize t(".hidden_scheduled_html",
|
|
25
|
+
public_on: l(element.public_on, format: :"alchemy.element_date")) %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% else %>
|
|
28
|
+
<%= t(".hidden_no_schedule") %>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% end %>
|
|
31
|
+
</alchemy-message>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<%= alchemy_form_for [:publish, :admin, element], remote: false, data: {turbo: true} do |f| %>
|
|
35
|
+
<div class="input">
|
|
36
|
+
<div class="input-row">
|
|
37
|
+
<div class="input-column">
|
|
38
|
+
<label for="element_public_on"><%= Alchemy::Element.human_attribute_name(:public_on) %></label>
|
|
39
|
+
<%= f.datetime_local_field :public_on, include_seconds: false %>
|
|
40
|
+
<%= f.error :public_on %>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="input-column">
|
|
43
|
+
<label for="element_public_until"><%= Alchemy::Element.human_attribute_name(:public_until) %></label>
|
|
44
|
+
<%= f.datetime_local_field :public_until, include_seconds: false %>
|
|
45
|
+
<%= f.error :public_until %>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="submit">
|
|
50
|
+
<button
|
|
51
|
+
type="button"
|
|
52
|
+
class="secondary"
|
|
53
|
+
onclick="this.form.querySelectorAll('input[type=datetime-local]').forEach((i) => i.value = '')">
|
|
54
|
+
<%= Alchemy.t(:clear_schedule) %>
|
|
55
|
+
</button>
|
|
56
|
+
<button type="submit">
|
|
57
|
+
<%= hidden_field_tag :alchemy_preview_time, params[:alchemy_preview_time] %>
|
|
58
|
+
<%= Alchemy.t(:save) %>
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
61
|
+
<% end %>
|
|
62
|
+
</div>
|
|
@@ -43,19 +43,5 @@
|
|
|
43
43
|
</button>
|
|
44
44
|
</alchemy-delete-element-button>
|
|
45
45
|
</sl-tooltip>
|
|
46
|
-
|
|
47
|
-
content="<%= element.public? ? Alchemy.t(:hide_element) : Alchemy.t(:show_element) %>"
|
|
48
|
-
placement="top-end"
|
|
49
|
-
<%= "disabled" if cannot?(:update, element) %>
|
|
50
|
-
>
|
|
51
|
-
<alchemy-publish-element-button>
|
|
52
|
-
<sl-switch
|
|
53
|
-
size="small"
|
|
54
|
-
<%= "checked" if !element.public? %>
|
|
55
|
-
<%= "disabled" if cannot?(:update, element) %>
|
|
56
|
-
>
|
|
57
|
-
<%= t(".hide") %>
|
|
58
|
-
</sl-switch>
|
|
59
|
-
</alchemy-publish-element-button>
|
|
60
|
-
</sl-tooltip>
|
|
46
|
+
<%= render Alchemy::Admin::PublishElementButton.new(element:) %>
|
|
61
47
|
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<% if @element.errors.any? %>
|
|
2
|
+
<%= turbo_stream.replace "element-#{@element.id}-schedule",
|
|
3
|
+
partial: "schedule", locals: {element: @element} %>
|
|
4
|
+
<% else %>
|
|
5
|
+
<% if @element.scheduled? %>
|
|
6
|
+
<alchemy-growl>
|
|
7
|
+
<%= Alchemy.t(:successfully_scheduled_element) %>
|
|
8
|
+
</alchemy-growl>
|
|
9
|
+
<% end %>
|
|
10
|
+
<alchemy-action name="closeCurrentDialog"></alchemy-action>
|
|
11
|
+
<alchemy-action name="reloadPreview"></alchemy-action>
|
|
12
|
+
<%= turbo_stream.replace "element_#{@element.id}" do %>
|
|
13
|
+
<%= render Alchemy::Admin::ElementEditor.new(
|
|
14
|
+
element: @element
|
|
15
|
+
) %>
|
|
16
|
+
<% end %>
|
|
17
|
+
<%= turbo_stream.replace "publish_page_button" do %>
|
|
18
|
+
<%= render Alchemy::Admin::PublishPageButton.new(
|
|
19
|
+
page: @element.page
|
|
20
|
+
) %>
|
|
21
|
+
<% end %>
|
|
22
|
+
<%= turbo_stream.replace "preview_time_select" do %>
|
|
23
|
+
<%= render Alchemy::Admin::PreviewTimeSelect.new(
|
|
24
|
+
@element.page_version,
|
|
25
|
+
url: edit_admin_page_path(@element.page),
|
|
26
|
+
selected: params[:alchemy_preview_time]) %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
'input-row'
|
|
20
20
|
] do %>
|
|
21
21
|
<div class="input-column">
|
|
22
|
-
|
|
23
|
-
<%=
|
|
22
|
+
<%= label :page, :public_on %>
|
|
23
|
+
<%= datetime_local_field :page, :public_on, include_seconds: false,
|
|
24
24
|
disabled: @page.attribute_fixed?(:public_on) %>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="input-column">
|
|
27
|
-
|
|
28
|
-
<%=
|
|
27
|
+
<%= label :page, :public_until %>
|
|
28
|
+
<%= datetime_local_field :page, :public_until, include_seconds: false,
|
|
29
29
|
disabled: @page.attribute_fixed?(:public_until) %>
|
|
30
30
|
</div>
|
|
31
31
|
<% end %>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
alchemy.configure_admin_page_path(@page),
|
|
50
50
|
{
|
|
51
51
|
title: Alchemy.t(:page_properties),
|
|
52
|
-
size: '
|
|
52
|
+
size: '530x680'
|
|
53
53
|
},
|
|
54
54
|
class: :icon_button,
|
|
55
55
|
'data-alchemy-hotkey' => 'alt+e'
|
|
@@ -91,6 +91,10 @@
|
|
|
91
91
|
</sl-tooltip>
|
|
92
92
|
</div>
|
|
93
93
|
<div class="toolbar_spacer"></div>
|
|
94
|
+
<%= render Alchemy::Admin::PreviewTimeSelect.new(
|
|
95
|
+
@page_version,
|
|
96
|
+
url: edit_admin_page_path(@page),
|
|
97
|
+
selected: params[:alchemy_preview_time]) %>
|
|
94
98
|
<% if @preview_urls.many? %>
|
|
95
99
|
<div class="select_with_label">
|
|
96
100
|
<label><%= Alchemy.t(:preview_url) %></label>
|
|
@@ -132,7 +136,7 @@
|
|
|
132
136
|
title="<%= Alchemy.t("Page preview") %>">
|
|
133
137
|
</iframe>
|
|
134
138
|
|
|
135
|
-
<%= turbo_frame_tag "alchemy_elements_window", src: alchemy.admin_elements_path(page_version_id: @page_version.id) do %>
|
|
139
|
+
<%= turbo_frame_tag "alchemy_elements_window", src: alchemy.admin_elements_path(page_version_id: @page_version.id, alchemy_preview_time: params[:alchemy_preview_time]) do %>
|
|
136
140
|
<alchemy-spinner></alchemy-spinner>
|
|
137
141
|
<% end %>
|
|
138
142
|
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
<div class="toolbar_button">
|
|
4
4
|
<sl-tooltip content="<%= Alchemy.t("Language tree") %>">
|
|
5
5
|
<%= form_tag switch_admin_languages_path, method: 'get' do %>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
<alchemy-auto-submit>
|
|
7
|
+
<%= select_tag(
|
|
8
|
+
:language_id,
|
|
9
|
+
options_for_select(
|
|
10
|
+
languages.map { |l| [l.name, l.id] },
|
|
11
|
+
Alchemy::Current.language.id
|
|
12
|
+
),
|
|
13
|
+
class: "short"
|
|
14
|
+
) %>
|
|
15
|
+
</alchemy-auto-submit>
|
|
16
16
|
<% end %>
|
|
17
17
|
</sl-tooltip>
|
|
18
18
|
</div>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
<%- if multi_site? -%>
|
|
2
2
|
<div class="toolbar_button">
|
|
3
3
|
<sl-tooltip content="<%= Alchemy.t("Current site") %>">
|
|
4
|
-
<%=
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
<%= form_tag url_for, method: :get do %>
|
|
5
|
+
<alchemy-auto-submit>
|
|
6
|
+
<%= select_tag :site_id,
|
|
7
|
+
options_for_select(sites_for_select, Alchemy::Current.site.id) %>
|
|
8
|
+
</alchemy-auto-submit>
|
|
9
|
+
<% end %>
|
|
7
10
|
</sl-tooltip>
|
|
8
11
|
</div>
|
|
9
12
|
<div class="toolbar_spacer"></div>
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
|
|
73
73
|
<% content_for :javascripts do %>
|
|
74
74
|
<script type="module">
|
|
75
|
-
import ImageOverlay from "alchemy_admin/image_overlay";
|
|
76
|
-
import pictureSelector from "alchemy_admin/picture_selector";
|
|
75
|
+
import { ImageOverlay } from "alchemy_admin/image_overlay";
|
|
76
|
+
import { pictureSelector } from "alchemy_admin/picture_selector";
|
|
77
77
|
import { on } from "alchemy_admin/utils/events";
|
|
78
78
|
|
|
79
79
|
pictureSelector();
|
|
@@ -9,20 +9,13 @@
|
|
|
9
9
|
<% end %>
|
|
10
10
|
|
|
11
11
|
<script>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// Holds the default Alchemy TinyMCE configuration
|
|
22
|
-
Alchemy.TinymceDefaults = {
|
|
23
|
-
plugins: '<%= Alchemy::Tinymce.plugins.join(',') %>',
|
|
24
|
-
<% Alchemy::Tinymce.init.each do |k, v| %>
|
|
25
|
-
<%= k %>: <%== v.to_json %>,
|
|
26
|
-
<% end %>
|
|
27
|
-
};
|
|
12
|
+
var tinyMCEPreInit = <%== {
|
|
13
|
+
base: ActionController::Base.config.asset_host ?
|
|
14
|
+
asset_url(tinymce_base_path, host: ActionController::Base.config.asset_host) :
|
|
15
|
+
tinymce_base_path,
|
|
16
|
+
suffix: ".min"
|
|
17
|
+
}.to_json %>;
|
|
18
|
+
Alchemy.TinymceDefaults = <%== Alchemy::Tinymce.init.merge(
|
|
19
|
+
plugins: Alchemy::Tinymce.plugins.join(",")
|
|
20
|
+
).to_json %>;
|
|
28
21
|
</script>
|
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
Alchemy.uploader_defaults =
|
|
3
|
-
file_size_limit: <%= Alchemy.config.uploader.file_size_limit -%>,
|
|
4
|
-
upload_limit: <%= Alchemy.config.uploader.upload_limit -%>,
|
|
5
|
-
allowed_filetype_pictures: "<%= Alchemy.config.uploader.allowed_filetypes.alchemy_pictures.join(", ") -%>",
|
|
6
|
-
allowed_filetype_attachments: "<%= Alchemy.config.uploader.allowed_filetypes.alchemy_attachments.join(", ") -%>",
|
|
7
|
-
}
|
|
2
|
+
Alchemy.uploader_defaults = <%== Alchemy.config.uploader.to_json %>
|
|
8
3
|
</script>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<%= link_to(
|
|
2
2
|
content_tag(:span, language.label(options[:linkname])).html_safe,
|
|
3
3
|
show_alchemy_page_path(
|
|
4
|
-
language.pages.language_roots.first
|
|
5
|
-
locale: prefix_locale?(language.code) ? language.code : nil
|
|
4
|
+
language.pages.language_roots.first
|
|
6
5
|
),
|
|
7
6
|
class: [
|
|
8
7
|
language.code,
|
|
@@ -44,52 +44,9 @@
|
|
|
44
44
|
<p><%= Alchemy.t(:javascript_disabled_text) %></p>
|
|
45
45
|
</noscript>
|
|
46
46
|
<alchemy-overlay text="<%= Alchemy.t(:please_wait) %>"></alchemy-overlay>
|
|
47
|
-
|
|
48
|
-
<div id="main_navi">
|
|
49
|
-
<% sorted_alchemy_modules.each do |alchemy_module| %>
|
|
50
|
-
<%= alchemy_main_navigation_entry(alchemy_module) %>
|
|
51
|
-
<% end %>
|
|
52
|
-
<%= yield(:alchemy_main_navigation) %>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div id="logout">
|
|
56
|
-
<div class="main_navi_entry">
|
|
57
|
-
<% if current_alchemy_user %>
|
|
58
|
-
<%= link_to_dialog(
|
|
59
|
-
%(
|
|
60
|
-
#{render_icon('logout-box-r', class: 'module')}
|
|
61
|
-
<label>#{Alchemy.t(:leave)}</label>
|
|
62
|
-
).html_safe,
|
|
63
|
-
alchemy.leave_admin_path, {
|
|
64
|
-
size: "320x140",
|
|
65
|
-
title: Alchemy.t("Leave Alchemy")
|
|
66
|
-
}, {'data-alchemy-hotkey' => 'alt+q'}) %>
|
|
67
|
-
<% else %>
|
|
68
|
-
<%= link_to(alchemy.root_path) do %>
|
|
69
|
-
<%= render_icon "logout-box-r", size: "lg" %>
|
|
70
|
-
<label><%= Alchemy.t(:leave) %></label>
|
|
71
|
-
<% end %>
|
|
72
|
-
<% end %>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
47
|
+
<%= render "alchemy/admin/left_menu" %>
|
|
76
48
|
<% if current_alchemy_user %>
|
|
77
|
-
|
|
78
|
-
<div id="header">
|
|
79
|
-
<% if @locked_pages.present? %>
|
|
80
|
-
<div id="locked_pages">
|
|
81
|
-
<%= render partial: 'alchemy/admin/pages/locked_page', collection: @locked_pages %>
|
|
82
|
-
</div>
|
|
83
|
-
<% end %>
|
|
84
|
-
<div id="user_info">
|
|
85
|
-
<%= current_alchemy_user_name %>
|
|
86
|
-
<%= render Alchemy::Admin::LocaleSelect.new %>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
<div id="toolbar">
|
|
90
|
-
<%= yield(:toolbar) %>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
49
|
+
<%= render "alchemy/admin/top_menu", locked_pages: @locked_pages %>
|
|
93
50
|
<% end %>
|
|
94
51
|
<%= render 'alchemy/admin/partials/flash_notices' %>
|
|
95
52
|
<div id="main_content">
|
data/config/importmap.rb
CHANGED
|
@@ -12,5 +12,10 @@ pin "shoelace", to: "shoelace.min.js", preload: true
|
|
|
12
12
|
pin "@rails/ujs", to: "rails-ujs.min.js", preload: true # @7.1.2
|
|
13
13
|
pin "tinymce", to: "tinymce.min.js", preload: true
|
|
14
14
|
|
|
15
|
-
pin "alchemy_admin", to: "alchemy_admin.js", preload: true
|
|
16
|
-
|
|
15
|
+
pin "alchemy_admin", to: "alchemy/alchemy_admin.min.js", preload: true
|
|
16
|
+
pin "alchemy_admin/components/remote_select", to: "alchemy/alchemy_admin.min.js"
|
|
17
|
+
pin "alchemy_admin/image_cropper", to: "alchemy/alchemy_admin.min.js"
|
|
18
|
+
pin "alchemy_admin/image_overlay", to: "alchemy/alchemy_admin.min.js"
|
|
19
|
+
pin "alchemy_admin/picture_selector", to: "alchemy/alchemy_admin.min.js"
|
|
20
|
+
pin "alchemy_admin/node_tree", to: "alchemy/alchemy_admin.min.js"
|
|
21
|
+
pin "alchemy_admin/utils/events", to: "alchemy/alchemy_admin.min.js"
|