alchemy_cms 6.0.0.pre.rc5 → 6.0.0.pre.rc6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of alchemy_cms might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 380b59193f2297abbf578f48a662afd797a678edd9948b5967a5df870df20b5f
4
- data.tar.gz: e36993e934138b801ce941d7a3b272790b41dde673f1cbded7e874cba637dd8d
3
+ metadata.gz: b2c4b9cbf469cb88a351047757a38e9ab434cd67006b0390170e22dd5b64d0a8
4
+ data.tar.gz: 48d6dec7c669c2f854ac0414e16801236cace3a6cef2eef5fb07fa4e509ef996
5
5
  SHA512:
6
- metadata.gz: '01489e9bf191e8ba5f42d19dfc93336d318744c41ccf6764625ebf787b8f2f030d219829be4b3b5830db93699e681883217909d8239ca023323469c95b7aab28'
7
- data.tar.gz: 33599581bdff5315660e260562179f7e9b12ef9269dd50aeba7e5e52cdcb8bf5db5188bb86cb8cc60b53a0346d6c0bf8fe336c5eef234aec54a6110f7d5386b8
6
+ metadata.gz: 9b290944338b8ca490e0472fa886c8f4b09d47bd957a7d45c014ab328c81a9545cc74196a69eda2969dcf2e5fb0af3bad4bfc9d5079e45c645a51d41582b4137
7
+ data.tar.gz: 67c3a355c1df19256609680c562d0ae0c2bd76811daee6ea930b1425e85e3ff2087313e3a2d5d203523320f0da20d643d79b11badd1700912930e3209dfb2ddd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 6.0.0-rc6 (2022-03-05)
2
+
3
+ - Rework sitemap JS [#2249](https://github.com/AlchemyCMS/alchemy_cms/pull/2249) ([tvdeyen](https://github.com/tvdeyen))
4
+ - Remove old page layout change code from update action [#2248](https://github.com/AlchemyCMS/alchemy_cms/pull/2248) ([tvdeyen](https://github.com/tvdeyen))
5
+ - Fix rendering errors in page configure overlay [#2247](https://github.com/AlchemyCMS/alchemy_cms/pull/2247) ([tvdeyen](https://github.com/tvdeyen))
6
+ - Fix copying page with descendants to a different language [#2243](https://github.com/AlchemyCMS/alchemy_cms/pull/2243) ([dbwinger](https://github.com/dbwinger))
7
+ - Handle copying/pasting global pages [#2241](https://github.com/AlchemyCMS/alchemy_cms/pull/2241) ([dbwinger](https://github.com/dbwinger))
8
+
1
9
  ## 6.0.0-rc5 (2022-02-24)
2
10
 
3
11
  ### Changes
@@ -38,7 +38,6 @@
38
38
  //= require alchemy/alchemy.page_sorter
39
39
  //= require alchemy/alchemy.uploader
40
40
  //= require alchemy/alchemy.preview_window
41
- //= require alchemy/alchemy.sitemap
42
41
  //= require alchemy/alchemy.spinner
43
42
  //= require alchemy/alchemy.tinymce
44
43
  //= require alchemy/alchemy.tooltips
@@ -82,7 +82,12 @@ class window.Alchemy.Dialog
82
82
  @dialog_body.hide()
83
83
  @dialog_body.html(data)
84
84
  @init()
85
- @dialog.trigger('DialogReady.Alchemy', @dialog_body)
85
+ @dialog[0].dispatchEvent(new CustomEvent(
86
+ "DialogReady.Alchemy",
87
+ bubbles: true
88
+ detail:
89
+ body: @dialog_body[0]
90
+ ))
86
91
  if @options.ready?
87
92
  @options.ready(@dialog_body)
88
93
  @dialog_body.show('fade', 200)
@@ -23,7 +23,7 @@ $sitemap-url-xlarge-width: 350px;
23
23
 
24
24
  #sitemap-wrapper {
25
25
  position: relative;
26
- min-height: calc(100vh - 96px);
26
+ min-height: calc(100vh - 148px);
27
27
  }
28
28
 
29
29
  .sitemap_pagename_link {
@@ -154,6 +154,8 @@ $sitemap-url-xlarge-width: 350px;
154
154
  position: absolute;
155
155
  left: -23px;
156
156
  top: 0;
157
+ width: 16px;
158
+ height: $sitemap-line-height;
157
159
  }
158
160
 
159
161
  .placeholder {
@@ -258,3 +260,7 @@ $sitemap-url-xlarge-width: 350px;
258
260
  }
259
261
  }
260
262
  }
263
+
264
+ #search_field_clear {
265
+ cursor: pointer;
266
+ }
@@ -123,8 +123,6 @@ module Alchemy
123
123
  # * fetches page via before filter
124
124
  #
125
125
  def update
126
- # stores old page_layout value, because unfurtunally rails @page.changes does not work here.
127
- @old_page_layout = @page.page_layout
128
126
  if @page.update(page_params)
129
127
  @notice = Alchemy.t("Page saved", name: @page.name)
130
128
  @while_page_edit = request.referer.include?("edit")
@@ -133,7 +131,7 @@ module Alchemy
133
131
  @tree = serialized_page_tree
134
132
  end
135
133
  else
136
- configure
134
+ render :configure
137
135
  end
138
136
  end
139
137
 
@@ -245,8 +245,8 @@ module Alchemy
245
245
 
246
246
  def copy_and_paste(source, new_parent, new_name)
247
247
  page = copy(source, {
248
- parent_id: new_parent.id,
249
- language: new_parent.language,
248
+ parent: new_parent,
249
+ language: new_parent&.language,
250
250
  name: new_name,
251
251
  title: new_name,
252
252
  })
@@ -448,6 +448,7 @@ module Alchemy
448
448
  next if child == new_parent
449
449
 
450
450
  new_child = Page.copy(child, {
451
+ parent_id: new_parent.id,
451
452
  language_id: new_parent.language_id,
452
453
  language_code: new_parent.language_code,
453
454
  })
@@ -1,11 +1,10 @@
1
- <div id="sitemap-wrapper">
2
- <h4 id="sitemap_heading">
3
- <span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
4
- <span class="page_urlname"><%= Alchemy::Page.human_attribute_name(:urlname) %></span>
5
- <span class="page_status"><%= Alchemy.t(:page_status) %></span>
6
- </h4>
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>
7
6
 
8
- <p class="loading"></p>
7
+ <div id="sitemap-wrapper">
9
8
  </div>
10
9
 
11
10
  <script id="sitemap-template" type="text/x-handlebars-template">
@@ -22,7 +21,7 @@
22
21
 
23
22
  <script type="text/javascript">
24
23
  $(function() {
25
- Alchemy.Sitemap.init({
24
+ Alchemy.currentSitemap = new Alchemy.Sitemap({
26
25
  url: '<%= alchemy.tree_admin_pages_path %>',
27
26
  page_root_id: <%= @page_root.id %>,
28
27
  full: <%= full %>
@@ -32,5 +31,6 @@
32
31
  }
33
32
  <% end %>
34
33
  });
34
+ Alchemy.PagePublicationFields();
35
35
  });
36
36
  </script>
@@ -154,7 +154,7 @@
154
154
  if (!not_dirty) Alchemy.pleaseWaitOverlay(false);
155
155
  return not_dirty;
156
156
  });
157
- Alchemy.Sitemap.watchPagePublicationState();
157
+ Alchemy.PagePublicationFields();
158
158
  Alchemy.PageLeaveObserver();
159
159
  Alchemy.ElementsWindow.init('<%= alchemy.admin_elements_path(page_version_id: @page_version.id) %>', {
160
160
  texts: {
@@ -1,2 +1,2 @@
1
1
  $('#fold_button_<%= @page.id %>').css('background', 'none');
2
- Alchemy.Sitemap.fetch(<%= @page.id %>);
2
+ Alchemy.currentSitemap.reload(<%= @page.id %>);
@@ -1,11 +1,6 @@
1
1
  (function() {
2
2
  var page = document.querySelector('#page_<%= @page.id %>');
3
3
 
4
- <% if @old_page_layout != @page.page_layout -%>
5
- Alchemy.ElementsWindow.reload();
6
- Alchemy.growl('<%= j Alchemy.t(:page_layout_changed_notice) %>');
7
- <% end -%>
8
-
9
4
  <% if @while_page_edit -%>
10
5
 
11
6
  Alchemy.reloadPreview();
@@ -534,7 +534,6 @@ en:
534
534
  or_replace_it_with_an_existing_tag: 'Or replace it with an existing tag'
535
535
  "Page created": "Page: '%{name}' created."
536
536
  page_infos: 'Page info'
537
- page_layout_changed_notice: "Page type was changed. Elements not usable anymore have been hided."
538
537
  page_properties: "Page properties"
539
538
  page_public: "published"
540
539
  page_published: "Published page"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "6.0.0-rc5"
4
+ VERSION = "6.0.0-rc6"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/package/admin.js CHANGED
@@ -6,6 +6,8 @@ import pictureEditors from "./src/picture_editors"
6
6
  import ImageLoader from "./src/image_loader"
7
7
  import ImageCropper from "./src/image_cropper"
8
8
  import Datepicker from "./src/datepicker"
9
+ import Sitemap from "./src/sitemap"
10
+ import PagePublicationFields from "./src/page_publication_fields.js"
9
11
 
10
12
  // Global Alchemy object
11
13
  if (typeof window.Alchemy === "undefined") {
@@ -22,5 +24,7 @@ Object.assign(Alchemy, {
22
24
  pictureEditors,
23
25
  ImageLoader: ImageLoader.init,
24
26
  ImageCropper,
25
- Datepicker
27
+ Datepicker,
28
+ Sitemap,
29
+ PagePublicationFields
26
30
  })
@@ -0,0 +1,27 @@
1
+ // Handles the page publication date fields
2
+ export default function () {
3
+ document.addEventListener("DialogReady.Alchemy", function (evt) {
4
+ const dialog = evt.detail.body
5
+ const public_on_field = dialog.querySelector("#page_public_on")
6
+ const public_until_field = dialog.querySelector("#page_public_until")
7
+ const publication_date_fields = dialog.querySelector(
8
+ ".page-publication-date-fields"
9
+ )
10
+
11
+ dialog
12
+ .querySelector("#page_public")
13
+ .addEventListener("click", function (evt) {
14
+ const checkbox = evt.target
15
+ const now = new Date()
16
+
17
+ if (checkbox.checked) {
18
+ publication_date_fields.classList.remove("hidden")
19
+ public_on_field._flatpickr.setDate(now)
20
+ } else {
21
+ publication_date_fields.classList.add("hidden")
22
+ public_on_field.value = ""
23
+ }
24
+ public_until_field.value = ""
25
+ })
26
+ })
27
+ }
@@ -0,0 +1,133 @@
1
+ // The admin sitemap Alchemy class
2
+
3
+ export default class Sitemap {
4
+ // Storing some objects.
5
+ constructor(options) {
6
+ const list_template_regexp = new RegExp("/" + options.page_root_id, "g")
7
+ const list_template_html = document
8
+ .getElementById("sitemap-list")
9
+ .innerHTML.replace(list_template_regexp, "/{{id}}")
10
+ this.search_field = document.querySelector(".search_input_field")
11
+ this.filter_field_clear = document.querySelector(".search_field_clear")
12
+ this.filter_field_clear.removeAttribute("href")
13
+ this.display = document.getElementById("page_filter_result")
14
+ this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
15
+ this.template = Handlebars.compile(
16
+ document.getElementById("sitemap-template").innerHTML
17
+ )
18
+ this.list_template = Handlebars.compile(list_template_html)
19
+ this.items = null
20
+ this.options = options
21
+ Handlebars.registerPartial("list", list_template_html)
22
+ this.load(options.page_root_id)
23
+ }
24
+
25
+ // Loads the sitemap
26
+ load(pageId) {
27
+ const spinner = this.options.spinner || new Alchemy.Spinner("medium")
28
+ const spinTarget = this.sitemap_wrapper
29
+ spinTarget.innerHTML = ""
30
+ spinner.spin(spinTarget)
31
+ this.fetch(
32
+ `${this.options.url}?id=${pageId}&full=${this.options.full}`
33
+ ).then(async (response) => {
34
+ this.render(await response.json())
35
+ spinner.stop()
36
+ })
37
+ }
38
+
39
+ // Reload the sitemap for a specific branch
40
+ reload(pageId) {
41
+ const spinner = new Alchemy.Spinner("small")
42
+ const spinTarget = document.getElementById(`fold_button_${pageId}`)
43
+ spinTarget.querySelector(".far").remove()
44
+ spinner.spin(spinTarget)
45
+ this.fetch(`${this.options.url}?id=${pageId}`).then(async (response) => {
46
+ this.render(await response.json(), pageId)
47
+ spinner.stop()
48
+ })
49
+ }
50
+
51
+ fetch(url) {
52
+ return fetch(url).catch((error) => console.warn(`Request failed: ${error}`))
53
+ }
54
+
55
+ // Renders the sitemap
56
+ render(data, foldingId) {
57
+ let renderTarget, renderTemplate
58
+
59
+ if (foldingId) {
60
+ renderTarget = document.getElementById(`page_${foldingId}`)
61
+ renderTemplate = this.list_template
62
+ renderTarget.outerHTML = renderTemplate({ children: data.pages })
63
+ } else {
64
+ renderTarget = this.sitemap_wrapper
65
+ renderTemplate = this.template
66
+ renderTarget.innerHTML = renderTemplate({ children: data.pages })
67
+ }
68
+ this.items = document
69
+ .getElementById("sitemap")
70
+ .querySelectorAll(".sitemap_page")
71
+ this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
72
+ this._observe()
73
+
74
+ if (this.options.ready) {
75
+ this.options.ready()
76
+ }
77
+ }
78
+
79
+ // Filters the sitemap
80
+ filter(term) {
81
+ const results = []
82
+
83
+ this.items.forEach(function (item) {
84
+ if (
85
+ term !== "" &&
86
+ item.getAttribute("name").toLowerCase().indexOf(term) !== -1
87
+ ) {
88
+ item.classList.add("highlight")
89
+ item.classList.remove("no-match")
90
+ results.push(item)
91
+ } else {
92
+ item.classList.add("no-match")
93
+ item.classList.remove("highlight")
94
+ }
95
+ })
96
+ this.filter_field_clear.style.display = "inline-block"
97
+ const { length } = results
98
+
99
+ if (length === 1) {
100
+ this.display.style.display = "block"
101
+ this.display.innerText = `1 ${Alchemy.t("page_found")}`
102
+ results[0].scrollIntoView({ behavior: "smooth", block: "center" })
103
+ } else if (length > 1) {
104
+ this.display.style.display = "block"
105
+ this.display.innerText = `${length} ${Alchemy.t("pages_found")}`
106
+ } else {
107
+ this.items.forEach((item) =>
108
+ item.classList.remove("no-match", "highlight")
109
+ )
110
+ this.display.style.display = "none"
111
+ window.scrollTo({
112
+ top: 0,
113
+ left: 0,
114
+ behavior: "smooth"
115
+ })
116
+ this.filter_field_clear.style.display = "none"
117
+ }
118
+ }
119
+
120
+ // Adds onkey up observer to search field
121
+ _observe() {
122
+ this.search_field.addEventListener("keyup", (evt) => {
123
+ const term = evt.target.value
124
+ this.filter(term.toLowerCase())
125
+ })
126
+ this.search_field.addEventListener("focus", () => key.setScope("search"))
127
+ this.filter_field_clear.addEventListener("click", () => {
128
+ this.search_field.value = ""
129
+ this.filter("")
130
+ return false
131
+ })
132
+ }
133
+ }
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy_cms/admin",
3
- "version": "6.0.0-rc4",
3
+ "version": "6.0.0-rc6",
4
4
  "description": "AlchemyCMS",
5
5
  "browser": "package/admin.js",
6
6
  "files": [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.pre.rc5
4
+ version: 6.0.0.pre.rc6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2022-02-24 00:00:00.000000000 Z
16
+ date: 2022-03-05 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionmailer
@@ -775,7 +775,6 @@ files:
775
775
  - app/assets/javascripts/alchemy/alchemy.page_sorter.js
776
776
  - app/assets/javascripts/alchemy/alchemy.preview.js.coffee
777
777
  - app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee
778
- - app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee
779
778
  - app/assets/javascripts/alchemy/alchemy.spinner.js
780
779
  - app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee
781
780
  - app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee
@@ -1431,7 +1430,9 @@ files:
1431
1430
  - package/src/image_cropper.js
1432
1431
  - package/src/image_loader.js
1433
1432
  - package/src/node_tree.js
1433
+ - package/src/page_publication_fields.js
1434
1434
  - package/src/picture_editors.js
1435
+ - package/src/sitemap.js
1435
1436
  - package/src/translations.js
1436
1437
  - package/src/utils/__tests__/ajax.spec.js
1437
1438
  - package/src/utils/__tests__/events.spec.js
@@ -1,119 +0,0 @@
1
- window.Alchemy = {} if typeof(window.Alchemy) is 'undefined'
2
-
3
- # The admin sitemap Alchemy module
4
- Alchemy.Sitemap =
5
-
6
- # Storing some objects.
7
- init: (options) ->
8
- @search_field = $(".search_input_field")
9
- @filter_field_clear = $('.search_field_clear')
10
- @display = $('#page_filter_result')
11
- @sitemap_wrapper = $('#sitemap-wrapper p.loading')
12
- @template = Handlebars.compile($('#sitemap-template').html())
13
- list_template_regexp = new RegExp '\/' + options.page_root_id, 'g'
14
- list_template_html = $('#sitemap-list').html().replace(list_template_regexp, '/{{id}}')
15
- @list_template = Handlebars.compile(list_template_html)
16
- @items = null
17
- @options = options
18
- @watchPagePublicationState()
19
- true
20
-
21
- Handlebars.registerPartial('list', list_template_html)
22
-
23
- @fetch()
24
-
25
- # Fetches the sitemap from JSON
26
- fetch: (foldingId) ->
27
- self = Alchemy.Sitemap
28
-
29
- if foldingId
30
- spinner = new Alchemy.Spinner('small')
31
- spinTarget = $('#fold_button_' + foldingId)
32
- renderTarget = $('#page_' + foldingId)
33
- renderTemplate = @list_template
34
- pageId = foldingId
35
- else
36
- spinner = @options.spinner || new Alchemy.Spinner('medium')
37
- spinTarget = @sitemap_wrapper
38
- renderTarget = @sitemap_wrapper
39
- renderTemplate = @template
40
- pageId = @options.page_root_id
41
-
42
- spinner.spin(spinTarget[0])
43
-
44
- request = $.ajax url: @options.url, data:
45
- id: pageId
46
- full: @options.full
47
-
48
- request.done (data) ->
49
- # This will also remove the spinner
50
- renderTarget.replaceWith(renderTemplate({children: data.pages}))
51
- self.items = $(".sitemap_page", '#sitemap')
52
- self._observe()
53
-
54
- if self.options.ready
55
- self.options.ready()
56
-
57
- request.fail (jqXHR, status) ->
58
- console.warn("Request failed: " + status)
59
-
60
- # Filters the sitemap
61
- filter: (term) ->
62
- results = []
63
- self = Alchemy.Sitemap
64
- self.items.map ->
65
- item = $(this)
66
- if term != '' && item.attr('name').toLowerCase().indexOf(term) != -1
67
- item.addClass('highlight')
68
- item.removeClass('no-match')
69
- results.push item
70
- else
71
- item.addClass('no-match')
72
- item.removeClass('highlight')
73
- self.filter_field_clear.show()
74
- length = results.length
75
- if length == 1
76
- self.display.show().text("1 #{Alchemy.t('page_found')}")
77
- $.scrollTo(results[0], {duration: 400, offset: -80})
78
- else if length > 1
79
- self.display.show().text("#{length} #{Alchemy.t('pages_found')}")
80
- else
81
- self.items.removeClass('no-match highlight')
82
- self.display.hide()
83
- $.scrollTo('0', 400)
84
- self.filter_field_clear.hide()
85
-
86
- # Adds onkey up observer to search field
87
- _observe: ->
88
- filter = @filter
89
- @search_field.on 'keyup', ->
90
- term = $(this).val()
91
- filter(term.toLowerCase())
92
- @search_field.on 'focus', ->
93
- key.setScope('search')
94
- @filter_field_clear.click =>
95
- @search_field.val('')
96
- filter('')
97
- false
98
-
99
- # Handles the page publication date fields
100
- watchPagePublicationState: ->
101
- $(document).on 'DialogReady.Alchemy', (e, $dialog) ->
102
- $public_on_field = $('#page_public_on', $dialog)
103
- $public_until_field = $('#page_public_until', $dialog)
104
- $publication_date_fields = $('.page-publication-date-fields', $dialog)
105
-
106
- $('#page_public', $dialog).click ->
107
- $checkbox = $(this)
108
- format = $checkbox.data('date-format')
109
- now = new Date()
110
- if $checkbox.is(':checked')
111
- $publication_date_fields.removeClass('hidden')
112
- $public_on_field[0]._flatpickr.setDate(now)
113
- else
114
- $publication_date_fields.addClass('hidden')
115
- $public_on_field.val('')
116
- $public_until_field.val('')
117
- true
118
-
119
- return