alchemy_cms 5.2.7 → 5.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d356d5cf9b97a20b587b2cdc07db82751af3cf71e9ce15c88ebb969667bccb33
4
- data.tar.gz: 8af9070583ecd3cdb3431c131f88bbb1dc6acec03b44ee1a7a6feeec2ebc621c
3
+ metadata.gz: b27eb5b4a0bdb143597a3e2cc33d0a8bfa4dd0d8febb2fd9261f2ad692716bc8
4
+ data.tar.gz: 7c67ed54f66b70419ac653421bdf3f8d38389bd3e67acfe70675bfcc8b357abd
5
5
  SHA512:
6
- metadata.gz: 9892f2979e766cb0159cc1d547709f9afe122e0ba1fbaf4a8e4d568d5158db6819db7031132dde61f1793318207a30021a65281305770c802318b25fab05becd
7
- data.tar.gz: c2c20b120289d05b74d19c1c51168f6218e5df1c8bec0d6fc3bfead3af65d9de51c93c01bbc9cb5795f53452b5835e573397744ba81c75547ce5689a32f47fb1
6
+ metadata.gz: aad3d674038b933605c7c8b5d11d74c707ed2687f9a5350e7762d56882a8994f85ea0a7e86e60ed4ee6cddb32aa46ecde70c42bcf91ceca62ad00e071195c497
7
+ data.tar.gz: c2f4a299345aafda98c2d40465ab8e011ee5d345104d32342503197afedccc4ed7bc527cce09afe8163dad148fe2019f3a2e18b0a0770eb48d971c9df51239dc
data/.gitignore CHANGED
@@ -34,7 +34,6 @@ spec/dummy/uploads/
34
34
  .ruby-gemset
35
35
  .ruby-version
36
36
  .env
37
- .rspec
38
37
  node_modules
39
38
  yarn-error.log
40
39
  yarn-debug.log*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Rakefile CHANGED
@@ -41,12 +41,16 @@ namespace :alchemy do
41
41
  task :prepare do
42
42
  system(
43
43
  <<~BASH
44
+ yarn install && \
45
+ yarn link && \
44
46
  cd spec/dummy && \
45
47
  export RAILS_ENV=test && \
46
48
  bin/rake db:create && \
47
49
  bin/rake db:environment:set && \
48
50
  bin/rake db:migrate:reset && \
49
51
  bin/rails g alchemy:install --skip --skip-demo-files --auto-accept && \
52
+ yarn link @alchemy_cms/admin && \
53
+ RAILS_ENV=test bin/webpack && \
50
54
  cd -
51
55
  BASH
52
56
  ) || fail
@@ -72,4 +76,18 @@ namespace :alchemy do
72
76
  File.delete(backup)
73
77
  end
74
78
  end
79
+
80
+ desc "Release a new Ruby gem and npm package in one command"
81
+ task :release do
82
+ require "json"
83
+ require_relative "lib/alchemy/version"
84
+ package = File.read("package.json")
85
+ unless JSON.parse(package)["version"] == Alchemy.version
86
+ abort "Ruby gem and npm package versions are out of sync! Please fix."
87
+ end
88
+ # Release the Ruby gem with bundler
89
+ Rake::Task["release"].invoke
90
+ # Publish npm package via CLI
91
+ system "npm publish"
92
+ end
75
93
  end
data/alchemy_cms.gemspec CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |gem|
33
33
  gem.add_runtime_dependency 'originator', ['~> 3.1']
34
34
  gem.add_runtime_dependency 'non-stupid-digest-assets', ['~> 1.0.8']
35
35
  gem.add_runtime_dependency 'rails', ['>= 5.2.0', '< 6.1']
36
- gem.add_runtime_dependency 'ransack', ['>= 1.8', '< 2.4.2'] # 2.4.2 dropped Ruby 2.5 support in a patch level release
36
+ gem.add_runtime_dependency 'ransack', ['>= 1.8', '< 3.0']
37
37
  gem.add_runtime_dependency 'request_store', ['~> 1.2']
38
38
  gem.add_runtime_dependency 'responders', ['>= 2.0', '< 4.0']
39
39
  gem.add_runtime_dependency 'sassc-rails', ['~> 2.1']
@@ -40,7 +40,6 @@
40
40
  //= require alchemy/alchemy.page_sorter
41
41
  //= require alchemy/alchemy.uploader
42
42
  //= require alchemy/alchemy.preview_window
43
- //= require alchemy/alchemy.sitemap
44
43
  //= require alchemy/alchemy.spinner
45
44
  //= require alchemy/alchemy.tinymce
46
45
  //= 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)
@@ -1,9 +1,11 @@
1
- $.fn.alchemyPageSelect = function(options) {
1
+ $.fn.alchemyPageSelect = function (options) {
2
2
  var pageTemplate = HandlebarsTemplates.page
3
3
 
4
4
  return this.select2({
5
5
  placeholder: options.placeholder,
6
- allowClear: true,
6
+ allowClear: options.hasOwnProperty("allowClear")
7
+ ? options.allowClear
8
+ : true,
7
9
  minimumInputLength: 3,
8
10
  initSelection: function (_$el, callback) {
9
11
  if (options.initialSelection) {
@@ -12,13 +14,16 @@ $.fn.alchemyPageSelect = function(options) {
12
14
  },
13
15
  ajax: {
14
16
  url: options.url,
15
- datatype: 'json',
17
+ datatype: "json",
16
18
  quietMillis: 300,
17
19
  data: function (term, page) {
18
20
  return {
19
- q: $.extend({
20
- name_cont: term
21
- }, options.query_params),
21
+ q: $.extend(
22
+ {
23
+ name_cont: term
24
+ },
25
+ options.query_params
26
+ ),
22
27
  page: page
23
28
  }
24
29
  },
@@ -34,8 +39,8 @@ $.fn.alchemyPageSelect = function(options) {
34
39
  formatSelection: function (page) {
35
40
  return page.text || page.name
36
41
  },
37
- formatResult: function(page) {
38
- return pageTemplate({page: page})
42
+ formatResult: function (page) {
43
+ return pageTemplate({ page: page })
39
44
  }
40
45
  })
41
46
  }
@@ -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
+ }
@@ -128,6 +128,7 @@ module Alchemy
128
128
  def update
129
129
  # stores old page_layout value, because unfurtunally rails @page.changes does not work here.
130
130
  @old_page_layout = @page.page_layout
131
+ @old_parent_id = @page.parent_id
131
132
  if @page.update(page_params)
132
133
  @notice = Alchemy.t("Page saved", name: @page.name)
133
134
  @while_page_edit = request.referer.include?("edit")
@@ -136,7 +137,7 @@ module Alchemy
136
137
  @tree = serialized_page_tree
137
138
  end
138
139
  else
139
- configure
140
+ render :configure
140
141
  end
141
142
  end
142
143
 
@@ -1,4 +1,8 @@
1
1
  <%= alchemy_form_for [:admin, @page], class: 'edit_page' do |f| %>
2
+ <% unless @page.language_root? || @page.layoutpage %>
3
+ <%= f.input :parent_id, required: true, input_html: { class: 'alchemy_selectbox' } %>
4
+ <% end %>
5
+
2
6
  <%= f.input :page_layout,
3
7
  collection: @page_layouts,
4
8
  label: page_layout_label(@page),
@@ -43,3 +47,18 @@
43
47
 
44
48
  <%= f.submit Alchemy.t(:save) %>
45
49
  <% end %>
50
+
51
+ <script>
52
+ $('#page_parent_id').alchemyPageSelect({
53
+ placeholder: "<%= Alchemy.t(:search_page) %>",
54
+ url: "<%= alchemy.api_pages_path %>",
55
+ allowClear: false,
56
+ <% if @page.parent %>
57
+ initialSelection: {
58
+ id: <%= @page.parent.id %>,
59
+ text: "<%= @page.parent.name %>",
60
+ url_path: "<%= @page.parent.url_path %>"
61
+ }
62
+ <% end %>
63
+ })
64
+ </script>
@@ -3,11 +3,7 @@
3
3
  <%= f.hidden_field(:parent_id) %>
4
4
  <% else %>
5
5
  <% @page.parent = @current_language.root_page %>
6
- <%= f.input :parent_id,
7
- collection: @current_language.pages.contentpages,
8
- label_method: :name,
9
- value_method: :id,
10
- input_html: { class: "alchemy_selectbox" } %>
6
+ <%= f.input :parent_id, as: :string, input_html: { class: 'alchemy_selectbox' } %>
11
7
  <% end %>
12
8
  <%= f.hidden_field(:language_id) %>
13
9
  <%= f.hidden_field(:layoutpage) %>
@@ -21,3 +17,18 @@
21
17
  <%= f.input :name %>
22
18
  <%= f.submit Alchemy.t(:create) %>
23
19
  <% end %>
20
+
21
+ <script>
22
+ $('input[type="text"]#page_parent_id').alchemyPageSelect({
23
+ placeholder: "<%= Alchemy.t(:search_page) %>",
24
+ url: "<%= alchemy.api_pages_path %>",
25
+ allowClear: false,
26
+ <% if @page.parent %>
27
+ initialSelection: {
28
+ id: <%= @page.parent.id %>,
29
+ text: "<%= @page.parent.name %>",
30
+ url_path: "<%= @page.parent.url_path %>"
31
+ }
32
+ <% end %>
33
+ })
34
+ </script>
@@ -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>
@@ -133,7 +133,7 @@
133
133
  if (!not_dirty) Alchemy.pleaseWaitOverlay(false);
134
134
  return not_dirty;
135
135
  });
136
- Alchemy.Sitemap.watchPagePublicationState();
136
+ Alchemy.PagePublicationFields();
137
137
  Alchemy.PageLeaveObserver();
138
138
  Alchemy.ElementsWindow.init('<%= alchemy.admin_elements_path(page_id: @page.id) %>', {
139
139
  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 %>);
@@ -13,6 +13,13 @@
13
13
  Alchemy.growl("<%= j @notice %>");
14
14
  Alchemy.closeCurrentDialog();
15
15
 
16
+ <% elsif @page.parent_id != @old_parent_id -%>
17
+
18
+ Alchemy.closeCurrentDialog(function() {
19
+ Alchemy.growl("<%= j @notice %>");
20
+ Alchemy.currentSitemap.load(<%= @page.get_language_root.id %>);
21
+ });
22
+
16
23
  <% else -%>
17
24
 
18
25
  if (page) {
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "5.2.7"
4
+ VERSION = "5.3.0"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/package/admin.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import translate from "./src/i18n"
2
2
  import translationData from "./src/translations"
3
3
  import NodeTree from "./src/node_tree"
4
+ import Sitemap from "./src/sitemap"
5
+ import PagePublicationFields from "./src/page_publication_fields.js"
4
6
 
5
7
  // Global Alchemy object
6
8
  if (typeof window.Alchemy === "undefined") {
@@ -12,5 +14,7 @@ Object.assign(Alchemy, {
12
14
  // Global utility method for translating a given string
13
15
  t: translate,
14
16
  translations: Object.assign(Alchemy.translations || {}, translationData),
15
- NodeTree
17
+ NodeTree,
18
+ Sitemap,
19
+ PagePublicationFields
16
20
  })
@@ -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": "5.2.7",
3
+ "version": "5.3.0",
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: 5.2.7
4
+ version: 5.3.0
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-03-01 00:00:00.000000000 Z
16
+ date: 2022-03-09 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: active_model_serializers
@@ -270,7 +270,7 @@ dependencies:
270
270
  version: '1.8'
271
271
  - - "<"
272
272
  - !ruby/object:Gem::Version
273
- version: 2.4.2
273
+ version: '3.0'
274
274
  type: :runtime
275
275
  prerelease: false
276
276
  version_requirements: !ruby/object:Gem::Requirement
@@ -280,7 +280,7 @@ dependencies:
280
280
  version: '1.8'
281
281
  - - "<"
282
282
  - !ruby/object:Gem::Version
283
- version: 2.4.2
283
+ version: '3.0'
284
284
  - !ruby/object:Gem::Dependency
285
285
  name: request_store
286
286
  requirement: !ruby/object:Gem::Requirement
@@ -590,6 +590,7 @@ files:
590
590
  - ".hound.yml"
591
591
  - ".localeapp/config.rb"
592
592
  - ".prettierrc"
593
+ - ".rspec"
593
594
  - ".rubocop.yml"
594
595
  - ".yardopts"
595
596
  - CHANGELOG.md
@@ -635,7 +636,6 @@ files:
635
636
  - app/assets/javascripts/alchemy/alchemy.page_sorter.js
636
637
  - app/assets/javascripts/alchemy/alchemy.preview.js.coffee
637
638
  - app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee
638
- - app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee
639
639
  - app/assets/javascripts/alchemy/alchemy.spinner.js
640
640
  - app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee
641
641
  - app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee
@@ -1189,6 +1189,8 @@ files:
1189
1189
  - package/src/__tests__/i18n.spec.js
1190
1190
  - package/src/i18n.js
1191
1191
  - package/src/node_tree.js
1192
+ - package/src/page_publication_fields.js
1193
+ - package/src/sitemap.js
1192
1194
  - package/src/translations.js
1193
1195
  - package/src/utils/__tests__/ajax.spec.js
1194
1196
  - 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