alchemy_cms 6.0.0.pre.rc6 → 6.0.0.pre.rc7

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.

Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +8 -8
  3. data/.github/workflows/stale.yml +21 -7
  4. data/.gitignore +0 -1
  5. data/.rspec +1 -0
  6. data/CHANGELOG.md +69 -0
  7. data/Gemfile +7 -6
  8. data/Rakefile +5 -1
  9. data/alchemy_cms.gemspec +2 -2
  10. data/app/assets/javascripts/alchemy/admin.js +0 -1
  11. data/app/assets/javascripts/alchemy/page_select.js +13 -8
  12. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  13. data/app/assets/javascripts/alchemy/templates/page.hbs +17 -7
  14. data/app/assets/javascripts/alchemy/templates/page_folder.hbs +3 -0
  15. data/app/assets/stylesheets/alchemy/archive.scss +4 -0
  16. data/app/assets/stylesheets/alchemy/page-select.scss +29 -4
  17. data/app/assets/stylesheets/alchemy/sitemap.scss +2 -6
  18. data/app/controllers/alchemy/admin/pages_controller.rb +9 -12
  19. data/app/controllers/alchemy/api/pages_controller.rb +14 -4
  20. data/app/models/alchemy/ingredient.rb +6 -1
  21. data/app/serializers/alchemy/page_serializer.rb +7 -1
  22. data/app/serializers/alchemy/page_tree_serializer.rb +3 -3
  23. data/app/views/alchemy/admin/pages/_form.html.erb +19 -0
  24. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +16 -5
  25. data/app/views/alchemy/admin/pages/_page.html.erb +111 -133
  26. data/app/views/alchemy/admin/pages/_sitemap.html.erb +2 -8
  27. data/app/views/alchemy/admin/pages/_toolbar.html.erb +0 -12
  28. data/app/views/alchemy/admin/pages/index.html.erb +1 -1
  29. data/app/views/alchemy/admin/pages/update.js.erb +7 -0
  30. data/app/views/alchemy/admin/partials/_routes.html.erb +8 -1
  31. data/app/views/alchemy/essences/_essence_page_editor.html.erb +1 -1
  32. data/config/locales/alchemy.en.yml +0 -3
  33. data/config/routes.rb +4 -2
  34. data/lib/alchemy/permissions.rb +0 -1
  35. data/lib/alchemy/test_support/shared_ingredient_examples.rb +4 -2
  36. data/lib/alchemy/version.rb +1 -1
  37. data/lib/generators/alchemy/install/install_generator.rb +6 -1
  38. data/package/src/image_loader.js +4 -2
  39. data/package/src/node_tree.js +13 -6
  40. data/package/src/page_publication_fields.js +15 -14
  41. data/package/src/page_sorter.js +62 -0
  42. data/package/src/picture_editors.js +4 -4
  43. data/package/src/sitemap.js +51 -36
  44. data/package/src/utils/__tests__/ajax.spec.js +52 -16
  45. data/package/src/utils/ajax.js +12 -0
  46. data/package.json +1 -1
  47. metadata +21 -22
  48. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +0 -24
  49. data/app/views/alchemy/admin/pages/fold.js.erb +0 -2
  50. data/app/views/alchemy/admin/pages/sort.html.erb +0 -19
  51. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +0 -434
@@ -1,6 +1,6 @@
1
- import debounce from "lodash/debounce"
2
- import max from "lodash/max"
3
- import ajax from "./utils/ajax"
1
+ import debounce from "lodash-es/debounce"
2
+ import max from "lodash-es/max"
3
+ import { get } from "./utils/ajax"
4
4
  import ImageLoader from "./image_loader"
5
5
 
6
6
  const UPDATE_DELAY = 125
@@ -62,7 +62,7 @@ class PictureEditor {
62
62
  this.image.removeAttribute("alt")
63
63
  this.image.removeAttribute("src")
64
64
  this.imageLoader.load(true)
65
- ajax("GET", `/admin/pictures/${this.pictureId}/url`, {
65
+ get(`/admin/pictures/${this.pictureId}/url`, {
66
66
  crop: this.imageCropperEnabled,
67
67
  crop_from: this.cropFrom,
68
68
  crop_size: this.cropSize,
@@ -1,12 +1,15 @@
1
1
  // The admin sitemap Alchemy class
2
+ import PageSorter from "./page_sorter"
3
+ import { on } from "./utils/events"
4
+ import { get, patch } from "./utils/ajax"
5
+ import { createSortables, displayPageFolders } from "./page_sorter"
2
6
 
3
7
  export default class Sitemap {
4
8
  // Storing some objects.
5
9
  constructor(options) {
6
- const list_template_regexp = new RegExp("/" + options.page_root_id, "g")
7
10
  const list_template_html = document
8
11
  .getElementById("sitemap-list")
9
- .innerHTML.replace(list_template_regexp, "/{{id}}")
12
+ .innerHTML.replace(/__ID__/g, "{{id}}")
10
13
  this.search_field = document.querySelector(".search_input_field")
11
14
  this.filter_field_clear = document.querySelector(".search_field_clear")
12
15
  this.filter_field_clear.removeAttribute("href")
@@ -24,56 +27,63 @@ export default class Sitemap {
24
27
 
25
28
  // Loads the sitemap
26
29
  load(pageId) {
27
- const spinner = this.options.spinner || new Alchemy.Spinner("medium")
30
+ const spinner = new Alchemy.Spinner("medium")
28
31
  const spinTarget = this.sitemap_wrapper
29
32
  spinTarget.innerHTML = ""
30
33
  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
- })
34
+ get(this.options.url, { id: pageId })
35
+ .then(async (response) => {
36
+ this.render(await response.data)
37
+ this.handlePageFolders()
38
+ spinner.stop()
39
+ })
40
+ .catch(this.errorHandler)
37
41
  }
38
42
 
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
- }
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)
50
55
 
51
- fetch(url) {
52
- return fetch(url).catch((error) => console.warn(`Request failed: ${error}`))
56
+ patch(Alchemy.routes.fold_admin_page_path(pageId))
57
+ .then(async (response) => {
58
+ this.reRender(pageId, await response.data)
59
+ spinner.stop()
60
+ })
61
+ .catch(this.errorHandler)
62
+ }.bind(this)
63
+ )
53
64
  }
54
65
 
55
66
  // Renders the sitemap
56
- render(data, foldingId) {
57
- let renderTarget, renderTemplate
67
+ render(data) {
68
+ const renderTarget = this.sitemap_wrapper
69
+ const renderTemplate = this.template
58
70
 
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
- }
71
+ renderTarget.innerHTML = renderTemplate({ children: data.pages })
68
72
  this.items = document
69
73
  .getElementById("sitemap")
70
74
  .querySelectorAll(".sitemap_page")
71
75
  this.sitemap_wrapper = document.getElementById("sitemap-wrapper")
72
76
  this._observe()
77
+ PageSorter()
78
+ }
73
79
 
74
- if (this.options.ready) {
75
- this.options.ready()
76
- }
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()
77
87
  }
78
88
 
79
89
  // Filters the sitemap
@@ -130,4 +140,9 @@ export default class Sitemap {
130
140
  return false
131
141
  })
132
142
  }
143
+
144
+ errorHandler(error) {
145
+ Alchemy.growl(error.message || error, "error")
146
+ console.error(error)
147
+ }
133
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("http://localhost/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("http://localhost/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,7 +79,7 @@ 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
  })
@@ -88,18 +88,54 @@ describe("ajax('get')", () => {
88
88
  xhrMock.get("http://localhost/users?name=foo", (_req, res) => {
89
89
  return res.status(200).body(`{"name":"foo"}`)
90
90
  })
91
- const { data } = await ajax("get", "/users", { name: "foo" })
91
+ const { data } = await get("/users", { name: "foo" })
92
92
  expect(data.name).toEqual("foo")
93
93
  })
94
94
  })
95
95
 
96
- describe("ajax('post')", () => {
96
+ describe("patch", () => {
97
+ it("sends X-CSRF-TOKEN header", async () => {
98
+ xhrMock.patch("http://localhost/users", (req, res) => {
99
+ expect(req.header("X-CSRF-TOKEN")).toEqual(token)
100
+ return res.status(200).body('{"message":"Ok"}')
101
+ })
102
+ await patch("/users")
103
+ })
104
+
105
+ it("sends Content-Type header", async () => {
106
+ xhrMock.patch("http://localhost/users", (req, res) => {
107
+ expect(req.header("Content-Type")).toEqual(
108
+ "application/json; charset=utf-8"
109
+ )
110
+ return res.status(200).body('{"message":"Ok"}')
111
+ })
112
+ await patch("/users")
113
+ })
114
+
115
+ it("sends Accept header", async () => {
116
+ xhrMock.patch("http://localhost/users", (req, res) => {
117
+ expect(req.header("Accept")).toEqual("application/json")
118
+ return res.status(200).body('{"message":"Ok"}')
119
+ })
120
+ await patch("/users")
121
+ })
122
+
123
+ it("sends JSON data", async () => {
124
+ xhrMock.patch("http://localhost/users", (req, res) => {
125
+ expect(req.body()).toEqual('{"email":"mail@example.com"}')
126
+ return res.status(200).body('{"message":"Ok"}')
127
+ })
128
+ await patch("/users", { email: "mail@example.com" })
129
+ })
130
+ })
131
+
132
+ describe("post", () => {
97
133
  it("sends X-CSRF-TOKEN header", async () => {
98
134
  xhrMock.post("http://localhost/users", (req, res) => {
99
135
  expect(req.header("X-CSRF-TOKEN")).toEqual(token)
100
136
  return res.status(200).body('{"message":"Ok"}')
101
137
  })
102
- await ajax("post", "/users")
138
+ await post("/users")
103
139
  })
104
140
 
105
141
  it("sends Content-Type header", async () => {
@@ -109,7 +145,7 @@ describe("ajax('post')", () => {
109
145
  )
110
146
  return res.status(200).body('{"message":"Ok"}')
111
147
  })
112
- await ajax("post", "/users")
148
+ await post("/users")
113
149
  })
114
150
 
115
151
  it("sends Accept header", async () => {
@@ -117,7 +153,7 @@ describe("ajax('post')", () => {
117
153
  expect(req.header("Accept")).toEqual("application/json")
118
154
  return res.status(200).body('{"message":"Ok"}')
119
155
  })
120
- await ajax("post", "/users")
156
+ await post("/users")
121
157
  })
122
158
 
123
159
  it("sends JSON data", async () => {
@@ -125,7 +161,7 @@ describe("ajax('post')", () => {
125
161
  expect(req.body()).toEqual('{"email":"mail@example.com"}')
126
162
  return res.status(200).body('{"message":"Ok"}')
127
163
  })
128
- await ajax("post", "/users", { email: "mail@example.com" })
164
+ await post("/users", { email: "mail@example.com" })
129
165
  })
130
166
  })
131
167
 
@@ -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("PATCH", url, data)
38
+ }
39
+
40
+ export function post(url, data) {
41
+ return ajax("POST", url, data)
42
+ }
43
+
32
44
  export default function ajax(method, path, 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": "6.0.0-rc6",
3
+ "version": "6.0.0-rc7",
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.rc6
4
+ version: 6.0.0.pre.rc7
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-05 00:00:00.000000000 Z
16
+ date: 2022-03-28 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionmailer
@@ -410,7 +410,7 @@ dependencies:
410
410
  version: '1.8'
411
411
  - - "<="
412
412
  - !ruby/object:Gem::Version
413
- version: 2.5.0
413
+ version: 2.6.0
414
414
  type: :runtime
415
415
  prerelease: false
416
416
  version_requirements: !ruby/object:Gem::Requirement
@@ -420,7 +420,7 @@ dependencies:
420
420
  version: '1.8'
421
421
  - - "<="
422
422
  - !ruby/object:Gem::Version
423
- version: 2.5.0
423
+ version: 2.6.0
424
424
  - !ruby/object:Gem::Dependency
425
425
  name: request_store
426
426
  requirement: !ruby/object:Gem::Requirement
@@ -571,20 +571,6 @@ dependencies:
571
571
  - - "~>"
572
572
  - !ruby/object:Gem::Version
573
573
  version: '1.0'
574
- - !ruby/object:Gem::Dependency
575
- name: cuprite
576
- requirement: !ruby/object:Gem::Requirement
577
- requirements:
578
- - - "~>"
579
- - !ruby/object:Gem::Version
580
- version: '0.13'
581
- type: :development
582
- prerelease: false
583
- version_requirements: !ruby/object:Gem::Requirement
584
- requirements:
585
- - - "~>"
586
- - !ruby/object:Gem::Version
587
- version: '0.13'
588
574
  - !ruby/object:Gem::Dependency
589
575
  name: factory_bot_rails
590
576
  requirement: !ruby/object:Gem::Requirement
@@ -669,6 +655,20 @@ dependencies:
669
655
  - - "~>"
670
656
  - !ruby/object:Gem::Version
671
657
  version: '0.20'
658
+ - !ruby/object:Gem::Dependency
659
+ name: webdrivers
660
+ requirement: !ruby/object:Gem::Requirement
661
+ requirements:
662
+ - - "~>"
663
+ - !ruby/object:Gem::Version
664
+ version: '5.0'
665
+ type: :development
666
+ prerelease: false
667
+ version_requirements: !ruby/object:Gem::Requirement
668
+ requirements:
669
+ - - "~>"
670
+ - !ruby/object:Gem::Version
671
+ version: '5.0'
672
672
  - !ruby/object:Gem::Dependency
673
673
  name: webmock
674
674
  requirement: !ruby/object:Gem::Requirement
@@ -731,6 +731,7 @@ files:
731
731
  - ".hound.yml"
732
732
  - ".localeapp/config.rb"
733
733
  - ".prettierrc"
734
+ - ".rspec"
734
735
  - ".rubocop.yml"
735
736
  - ".yardopts"
736
737
  - CHANGELOG.md
@@ -772,7 +773,6 @@ files:
772
773
  - app/assets/javascripts/alchemy/alchemy.initializer.js.coffee
773
774
  - app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee
774
775
  - app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee
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
778
  - app/assets/javascripts/alchemy/alchemy.spinner.js
@@ -788,6 +788,7 @@ files:
788
788
  - app/assets/javascripts/alchemy/templates/node.hbs
789
789
  - app/assets/javascripts/alchemy/templates/node_folder.hbs
790
790
  - app/assets/javascripts/alchemy/templates/page.hbs
791
+ - app/assets/javascripts/alchemy/templates/page_folder.hbs
791
792
  - app/assets/javascripts/alchemy/templates/spinner.hbs
792
793
  - app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js
793
794
  - app/assets/stylesheets/alchemy/_defaults.scss
@@ -1106,7 +1107,6 @@ files:
1106
1107
  - app/views/alchemy/admin/pages/configure.html.erb
1107
1108
  - app/views/alchemy/admin/pages/edit.html.erb
1108
1109
  - app/views/alchemy/admin/pages/flush.js.erb
1109
- - app/views/alchemy/admin/pages/fold.js.erb
1110
1110
  - app/views/alchemy/admin/pages/index.html.erb
1111
1111
  - app/views/alchemy/admin/pages/info.html.erb
1112
1112
  - app/views/alchemy/admin/pages/link.html.erb
@@ -1114,7 +1114,6 @@ files:
1114
1114
  - app/views/alchemy/admin/pages/locked.html.erb
1115
1115
  - app/views/alchemy/admin/pages/new.html.erb
1116
1116
  - app/views/alchemy/admin/pages/show.html.erb
1117
- - app/views/alchemy/admin/pages/sort.html.erb
1118
1117
  - app/views/alchemy/admin/pages/unlock.js.erb
1119
1118
  - app/views/alchemy/admin/pages/update.js.erb
1120
1119
  - app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb
@@ -1431,6 +1430,7 @@ files:
1431
1430
  - package/src/image_loader.js
1432
1431
  - package/src/node_tree.js
1433
1432
  - package/src/page_publication_fields.js
1433
+ - package/src/page_sorter.js
1434
1434
  - package/src/picture_editors.js
1435
1435
  - package/src/sitemap.js
1436
1436
  - package/src/translations.js
@@ -1457,7 +1457,6 @@ files:
1457
1457
  - vendor/assets/javascripts/flatpickr/flatpickr.min.js
1458
1458
  - vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js
1459
1459
  - vendor/assets/javascripts/jquery_plugins/jquery.scrollTo.min.js
1460
- - vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js
1461
1460
  - vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js
1462
1461
  - vendor/assets/javascripts/jquery_plugins/select2.js
1463
1462
  - 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,2 +0,0 @@
1
- $('#fold_button_<%= @page.id %>').css('background', 'none');
2
- Alchemy.currentSitemap.reload(<%= @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 %>