alchemy_cms 5.2.7 → 5.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +19 -0
  5. data/Rakefile +18 -0
  6. data/alchemy_cms.gemspec +1 -1
  7. data/app/assets/javascripts/alchemy/admin.js +0 -2
  8. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +5 -2
  9. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +6 -1
  10. data/app/assets/javascripts/alchemy/page_select.js +13 -8
  11. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  12. data/app/assets/javascripts/alchemy/templates/page.hbs +17 -7
  13. data/app/assets/javascripts/alchemy/templates/page_folder.hbs +3 -0
  14. data/app/assets/stylesheets/alchemy/archive.scss +4 -0
  15. data/app/assets/stylesheets/alchemy/page-select.scss +29 -4
  16. data/app/assets/stylesheets/alchemy/sitemap.scss +9 -7
  17. data/app/controllers/alchemy/admin/pages_controller.rb +10 -13
  18. data/app/controllers/alchemy/api/pages_controller.rb +14 -4
  19. data/app/serializers/alchemy/page_serializer.rb +7 -1
  20. data/app/serializers/alchemy/page_tree_serializer.rb +3 -3
  21. data/app/views/alchemy/admin/pages/_form.html.erb +19 -0
  22. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +16 -5
  23. data/app/views/alchemy/admin/pages/_page.html.erb +111 -133
  24. data/app/views/alchemy/admin/pages/_sitemap.html.erb +10 -16
  25. data/app/views/alchemy/admin/pages/_toolbar.html.erb +0 -12
  26. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  27. data/app/views/alchemy/admin/pages/index.html.erb +1 -1
  28. data/app/views/alchemy/admin/pages/update.js.erb +7 -0
  29. data/app/views/alchemy/admin/partials/_routes.html.erb +8 -1
  30. data/app/views/alchemy/essences/_essence_page_editor.html.erb +1 -1
  31. data/config/locales/alchemy.en.yml +0 -3
  32. data/config/routes.rb +4 -2
  33. data/lib/alchemy/permissions.rb +0 -1
  34. data/lib/alchemy/version.rb +1 -1
  35. data/package/admin.js +5 -1
  36. data/package/src/node_tree.js +3 -3
  37. data/package/src/page_publication_fields.js +27 -0
  38. data/package/src/page_sorter.js +62 -0
  39. data/package/src/sitemap.js +148 -0
  40. data/package/src/utils/__tests__/ajax.spec.js +61 -15
  41. data/package/src/utils/ajax.js +12 -0
  42. data/package.json +1 -1
  43. metadata +9 -9
  44. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +0 -24
  45. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +0 -119
  46. data/app/views/alchemy/admin/pages/fold.js.erb +0 -2
  47. data/app/views/alchemy/admin/pages/sort.html.erb +0 -19
  48. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +0 -434
@@ -0,0 +1,148 @@
1
+ // The admin sitemap Alchemy class
2
+ import PageSorter from "./page_sorter"
3
+ import { on } from "./utils/events"
4
+ import { patch } from "./utils/ajax"
5
+ import { createSortables, displayPageFolders } from "./page_sorter"
6
+
7
+ export default class Sitemap {
8
+ // Storing some objects.
9
+ constructor(options) {
10
+ const list_template_html = document
11
+ .getElementById("sitemap-list")
12
+ .innerHTML.replace(/__ID__/g, "{{id}}")
13
+ this.search_field = document.querySelector(".search_input_field")
14
+ this.filter_field_clear = document.querySelector(".search_field_clear")
15
+ this.filter_field_clear.removeAttribute("href")
16
+ this.display = document.getElementById("page_filter_result")
17
+ this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
18
+ this.template = Handlebars.compile(
19
+ document.getElementById("sitemap-template").innerHTML
20
+ )
21
+ this.list_template = Handlebars.compile(list_template_html)
22
+ this.items = null
23
+ this.options = options
24
+ Handlebars.registerPartial("list", list_template_html)
25
+ this.load(options.page_root_id)
26
+ }
27
+
28
+ // Loads the sitemap
29
+ load(pageId) {
30
+ const spinner = new Alchemy.Spinner("medium")
31
+ const spinTarget = this.sitemap_wrapper
32
+ spinTarget.innerHTML = ""
33
+ spinner.spin(spinTarget)
34
+ fetch(`${this.options.url}?id=${pageId}`)
35
+ .then(async (response) => {
36
+ this.render(await response.json())
37
+ this.handlePageFolders()
38
+ spinner.stop()
39
+ })
40
+ .catch(this.errorHandler)
41
+ }
42
+
43
+ // Watch page folder clicks and re-render the page branch
44
+ handlePageFolders() {
45
+ on(
46
+ "click",
47
+ "#sitemap",
48
+ ".page_folder",
49
+ function (evt) {
50
+ const spinner = new Alchemy.Spinner("small")
51
+ const pageFolder = evt.target.closest(".page_folder")
52
+ const pageId = pageFolder.dataset.pageId
53
+ pageFolder.innerHTML = ""
54
+ spinner.spin(pageFolder)
55
+
56
+ patch(Alchemy.routes.fold_admin_page_path(pageId))
57
+ .then(async (response) => {
58
+ this.reRender(pageId, await response.json())
59
+ spinner.stop()
60
+ })
61
+ .catch(this.errorHandler)
62
+ }.bind(this)
63
+ )
64
+ }
65
+
66
+ // Renders the sitemap
67
+ render(data) {
68
+ const renderTarget = this.sitemap_wrapper
69
+ const renderTemplate = this.template
70
+
71
+ renderTarget.innerHTML = renderTemplate({ children: data.pages })
72
+ this.items = document
73
+ .getElementById("sitemap")
74
+ .querySelectorAll(".sitemap_page")
75
+ this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
76
+ this._observe()
77
+ PageSorter()
78
+ }
79
+
80
+ reRender(pageId, data) {
81
+ let pageEl = document.getElementById(`page_${pageId}`)
82
+ pageEl.outerHTML = this.list_template({ children: data.pages })
83
+ pageEl = document.getElementById(`page_${pageId}`)
84
+ const sortables = pageEl.querySelectorAll("ul.children")
85
+ createSortables(sortables)
86
+ displayPageFolders()
87
+ }
88
+
89
+ // Filters the sitemap
90
+ filter(term) {
91
+ const results = []
92
+
93
+ this.items.forEach(function (item) {
94
+ if (
95
+ term !== "" &&
96
+ item.getAttribute("name").toLowerCase().indexOf(term) !== -1
97
+ ) {
98
+ item.classList.add("highlight")
99
+ item.classList.remove("no-match")
100
+ results.push(item)
101
+ } else {
102
+ item.classList.add("no-match")
103
+ item.classList.remove("highlight")
104
+ }
105
+ })
106
+ this.filter_field_clear.style.display = "inline-block"
107
+ const { length } = results
108
+
109
+ if (length === 1) {
110
+ this.display.style.display = "block"
111
+ this.display.innerText = `1 ${Alchemy.t("page_found")}`
112
+ results[0].scrollIntoView({ behavior: "smooth", block: "center" })
113
+ } else if (length > 1) {
114
+ this.display.style.display = "block"
115
+ this.display.innerText = `${length} ${Alchemy.t("pages_found")}`
116
+ } else {
117
+ this.items.forEach((item) =>
118
+ item.classList.remove("no-match", "highlight")
119
+ )
120
+ this.display.style.display = "none"
121
+ window.scrollTo({
122
+ top: 0,
123
+ left: 0,
124
+ behavior: "smooth"
125
+ })
126
+ this.filter_field_clear.style.display = "none"
127
+ }
128
+ }
129
+
130
+ // Adds onkey up observer to search field
131
+ _observe() {
132
+ this.search_field.addEventListener("keyup", (evt) => {
133
+ const term = evt.target.value
134
+ this.filter(term.toLowerCase())
135
+ })
136
+ this.search_field.addEventListener("focus", () => key.setScope("search"))
137
+ this.filter_field_clear.addEventListener("click", () => {
138
+ this.search_field.value = ""
139
+ this.filter("")
140
+ return false
141
+ })
142
+ }
143
+
144
+ errorHandler(error) {
145
+ Alchemy.growl(error.message || error, "error")
146
+ console.error(error)
147
+ }
148
+ }
@@ -1,5 +1,5 @@
1
1
  import xhrMock from "xhr-mock"
2
- import ajax from "../ajax"
2
+ import { get, patch, post } from "../ajax"
3
3
 
4
4
  const token = "s3cr3t"
5
5
 
@@ -8,13 +8,13 @@ beforeEach(() => {
8
8
  xhrMock.setup()
9
9
  })
10
10
 
11
- describe("ajax('get')", () => {
11
+ describe("get", () => {
12
12
  it("sends X-CSRF-TOKEN header", async () => {
13
13
  xhrMock.get("/users", (req, res) => {
14
14
  expect(req.header("X-CSRF-TOKEN")).toEqual(token)
15
15
  return res.status(200).body('{"message":"Ok"}')
16
16
  })
17
- await ajax("get", "/users")
17
+ await get("/users")
18
18
  })
19
19
 
20
20
  it("sends Content-Type header", async () => {
@@ -24,7 +24,7 @@ describe("ajax('get')", () => {
24
24
  )
25
25
  return res.status(200).body('{"message":"Ok"}')
26
26
  })
27
- await ajax("get", "/users")
27
+ await get("/users")
28
28
  })
29
29
 
30
30
  it("sends Accept header", async () => {
@@ -32,14 +32,14 @@ describe("ajax('get')", () => {
32
32
  expect(req.header("Accept")).toEqual("application/json")
33
33
  return res.status(200).body('{"message":"Ok"}')
34
34
  })
35
- await ajax("get", "/users")
35
+ await get("/users")
36
36
  })
37
37
 
38
38
  it("returns JSON", async () => {
39
39
  xhrMock.get("/users", (_req, res) => {
40
40
  return res.status(200).body('{"email":"mail@example.com"}')
41
41
  })
42
- await ajax("get", "/users").then((res) => {
42
+ await get("/users").then((res) => {
43
43
  expect(res.data).toEqual({ email: "mail@example.com" })
44
44
  })
45
45
  })
@@ -49,7 +49,7 @@ describe("ajax('get')", () => {
49
49
  return res.status(200).body('email => "mail@example.com"')
50
50
  })
51
51
  expect.assertions(1)
52
- await ajax("get", "/users").catch((e) => {
52
+ await get("/users").catch((e) => {
53
53
  expect(e.message).toMatch("Unexpected token")
54
54
  })
55
55
  })
@@ -59,7 +59,7 @@ describe("ajax('get')", () => {
59
59
  return Promise.reject(new Error())
60
60
  })
61
61
  expect.assertions(1)
62
- await ajax("get", "/users").catch((e) => {
62
+ await get("/users").catch((e) => {
63
63
  expect(e.message).toEqual("An error occurred during the transaction")
64
64
  })
65
65
  })
@@ -69,7 +69,7 @@ describe("ajax('get')", () => {
69
69
  return res.status(401).body('{"error":"Unauthorized"}')
70
70
  })
71
71
  expect.assertions(1)
72
- await ajax("get", "/users").catch((e) => {
72
+ await get("/users").catch((e) => {
73
73
  expect(e.error).toEqual("Unauthorized")
74
74
  })
75
75
  })
@@ -79,19 +79,19 @@ describe("ajax('get')", () => {
79
79
  return res.status(401).body("Unauthorized")
80
80
  })
81
81
  expect.assertions(1)
82
- await ajax("get", "/users").catch((e) => {
82
+ await get("/users").catch((e) => {
83
83
  expect(e.message).toMatch("Unexpected token")
84
84
  })
85
85
  })
86
86
  })
87
87
 
88
- describe("ajax('post')", () => {
88
+ describe("patch", () => {
89
89
  it("sends X-CSRF-TOKEN header", async () => {
90
90
  xhrMock.post("/users", (req, res) => {
91
91
  expect(req.header("X-CSRF-TOKEN")).toEqual(token)
92
92
  return res.status(200).body('{"message":"Ok"}')
93
93
  })
94
- await ajax("post", "/users")
94
+ await patch("/users")
95
95
  })
96
96
 
97
97
  it("sends Content-Type header", async () => {
@@ -101,7 +101,7 @@ describe("ajax('post')", () => {
101
101
  )
102
102
  return res.status(200).body('{"message":"Ok"}')
103
103
  })
104
- await ajax("post", "/users")
104
+ await patch("/users")
105
105
  })
106
106
 
107
107
  it("sends Accept header", async () => {
@@ -109,7 +109,53 @@ describe("ajax('post')", () => {
109
109
  expect(req.header("Accept")).toEqual("application/json")
110
110
  return res.status(200).body('{"message":"Ok"}')
111
111
  })
112
- await ajax("post", "/users")
112
+ await patch("/users")
113
+ })
114
+
115
+ it("sends method override data", async () => {
116
+ xhrMock.post("/users", (req, res) => {
117
+ expect(req.body()).toEqual('{"_method":"patch"}')
118
+ return res.status(200).body('{"message":"Ok"}')
119
+ })
120
+ await patch("/users")
121
+ })
122
+
123
+ it("sends JSON data", async () => {
124
+ xhrMock.post("/users", (req, res) => {
125
+ expect(req.body()).toEqual(
126
+ '{"email":"mail@example.com","_method":"patch"}'
127
+ )
128
+ return res.status(200).body('{"message":"Ok"}')
129
+ })
130
+ await patch("/users", { email: "mail@example.com" })
131
+ })
132
+ })
133
+
134
+ describe("post", () => {
135
+ it("sends X-CSRF-TOKEN header", async () => {
136
+ xhrMock.post("/users", (req, res) => {
137
+ expect(req.header("X-CSRF-TOKEN")).toEqual(token)
138
+ return res.status(200).body('{"message":"Ok"}')
139
+ })
140
+ await post("/users")
141
+ })
142
+
143
+ it("sends Content-Type header", async () => {
144
+ xhrMock.post("/users", (req, res) => {
145
+ expect(req.header("Content-Type")).toEqual(
146
+ "application/json; charset=utf-8"
147
+ )
148
+ return res.status(200).body('{"message":"Ok"}')
149
+ })
150
+ await post("/users")
151
+ })
152
+
153
+ it("sends Accept header", async () => {
154
+ xhrMock.post("/users", (req, res) => {
155
+ expect(req.header("Accept")).toEqual("application/json")
156
+ return res.status(200).body('{"message":"Ok"}')
157
+ })
158
+ await post("/users")
113
159
  })
114
160
 
115
161
  it("sends JSON data", async () => {
@@ -117,7 +163,7 @@ describe("ajax('post')", () => {
117
163
  expect(req.body()).toEqual('{"email":"mail@example.com"}')
118
164
  return res.status(200).body('{"message":"Ok"}')
119
165
  })
120
- await ajax("post", "/users", { email: "mail@example.com" })
166
+ await post("/users", { email: "mail@example.com" })
121
167
  })
122
168
  })
123
169
 
@@ -29,6 +29,18 @@ function getToken() {
29
29
  return metaTag.attributes.content.textContent
30
30
  }
31
31
 
32
+ export function get(url, params) {
33
+ return ajax("GET", url, params)
34
+ }
35
+
36
+ export function patch(url, data = {}) {
37
+ return ajax("POST", url, { ...data, _method: "patch" })
38
+ }
39
+
40
+ export function post(url, data) {
41
+ return ajax("POST", url, data)
42
+ }
43
+
32
44
  export default function ajax(method, url, data) {
33
45
  const xhr = new XMLHttpRequest()
34
46
  const promise = buildPromise(xhr)
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.2",
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.2
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-24 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
@@ -632,10 +633,8 @@ files:
632
633
  - app/assets/javascripts/alchemy/alchemy.initializer.js.coffee
633
634
  - app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee
634
635
  - app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee
635
- - app/assets/javascripts/alchemy/alchemy.page_sorter.js
636
636
  - app/assets/javascripts/alchemy/alchemy.preview.js.coffee
637
637
  - app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee
638
- - app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee
639
638
  - app/assets/javascripts/alchemy/alchemy.spinner.js
640
639
  - app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee
641
640
  - app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee
@@ -650,6 +649,7 @@ files:
650
649
  - app/assets/javascripts/alchemy/templates/node.hbs
651
650
  - app/assets/javascripts/alchemy/templates/node_folder.hbs
652
651
  - app/assets/javascripts/alchemy/templates/page.hbs
652
+ - app/assets/javascripts/alchemy/templates/page_folder.hbs
653
653
  - app/assets/javascripts/alchemy/templates/spinner.hbs
654
654
  - app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js
655
655
  - app/assets/stylesheets/alchemy/_defaults.scss
@@ -927,7 +927,6 @@ files:
927
927
  - app/views/alchemy/admin/pages/configure.html.erb
928
928
  - app/views/alchemy/admin/pages/edit.html.erb
929
929
  - app/views/alchemy/admin/pages/flush.js.erb
930
- - app/views/alchemy/admin/pages/fold.js.erb
931
930
  - app/views/alchemy/admin/pages/index.html.erb
932
931
  - app/views/alchemy/admin/pages/info.html.erb
933
932
  - app/views/alchemy/admin/pages/link.html.erb
@@ -935,7 +934,6 @@ files:
935
934
  - app/views/alchemy/admin/pages/locked.html.erb
936
935
  - app/views/alchemy/admin/pages/new.html.erb
937
936
  - app/views/alchemy/admin/pages/show.html.erb
938
- - app/views/alchemy/admin/pages/sort.html.erb
939
937
  - app/views/alchemy/admin/pages/unlock.js.erb
940
938
  - app/views/alchemy/admin/pages/update.js.erb
941
939
  - app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb
@@ -1189,6 +1187,9 @@ files:
1189
1187
  - package/src/__tests__/i18n.spec.js
1190
1188
  - package/src/i18n.js
1191
1189
  - package/src/node_tree.js
1190
+ - package/src/page_publication_fields.js
1191
+ - package/src/page_sorter.js
1192
+ - package/src/sitemap.js
1192
1193
  - package/src/translations.js
1193
1194
  - package/src/utils/__tests__/ajax.spec.js
1194
1195
  - package/src/utils/__tests__/events.spec.js
@@ -1213,7 +1214,6 @@ files:
1213
1214
  - vendor/assets/javascripts/flatpickr/flatpickr.min.js
1214
1215
  - vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js
1215
1216
  - vendor/assets/javascripts/jquery_plugins/jquery.scrollTo.min.js
1216
- - vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js
1217
1217
  - vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js
1218
1218
  - vendor/assets/javascripts/jquery_plugins/select2.js
1219
1219
  - vendor/assets/javascripts/keymaster.js
@@ -1,24 +0,0 @@
1
- Alchemy.PageSorter = function () {
2
- var $sortables = $("ul#sitemap").find("ul.level_0_children")
3
-
4
- $sortables.nestedSortable({
5
- disableNesting: "no-nest",
6
- forcePlaceholderSize: true,
7
- handle: ".handle",
8
- items: "li",
9
- listType: "ul",
10
- opacity: 0.5,
11
- placeholder: "placeholder",
12
- tabSize: 16,
13
- tolerance: "pointer",
14
- toleranceElement: "> div"
15
- })
16
-
17
- $("#save_page_order").click(function (e) {
18
- e.preventDefault()
19
- Alchemy.Buttons.disable(this)
20
- $.post(Alchemy.routes.order_admin_pages_path, {
21
- set: JSON.stringify($sortables.nestedSortable("toHierarchy"))
22
- })
23
- })
24
- }
@@ -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
@@ -1,2 +0,0 @@
1
- $('#fold_button_<%= @page.id %>').css('background', 'none');
2
- Alchemy.Sitemap.fetch(<%= @page.id %>);
@@ -1,19 +0,0 @@
1
- <% content_for :toolbar do %>
2
- <div class="button_with_label">
3
- <%= link_to alchemy.admin_pages_path, class: 'icon_button' do %>
4
- <%= render_icon 'angle-double-left' %>
5
- <% end %>
6
- <label><%= Alchemy.t(:cancel) %></label>
7
- </div>
8
- <% end %>
9
-
10
- <div id="sort_panel">
11
- <%= render_message do %>
12
- <%= Alchemy.t(:explain_sitemap_dragndrop_sorting) %>
13
- <% end %>
14
- <div class="buttons">
15
- <%= button_tag Alchemy.t('save order'), id: 'save_page_order' %>
16
- </div>
17
- </div>
18
-
19
- <%= render 'sitemap', page_partial: 'page', full: true %>