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

Sign up to get free protection for your applications and to get access to all the features.
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