alchemy_cms 5.3.1 → 5.3.2

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: 0d0f346b9e40e791697acdf21d5e1193c72023f8f2570b777683ba2e781b67c1
4
- data.tar.gz: b0c6a7f6e466bd0b134f9a7fdc76cb88ec1a56d0ca068209fa6b004619ed3a8e
3
+ metadata.gz: e2df8b8b8a114a3c838038e49ed3f464fdb45aca2706d7a691aa9674a6d0fceb
4
+ data.tar.gz: e94ecf5d831ada56e030d86f83e98e79dca35a9cd8638349aca7d3376ad20cd0
5
5
  SHA512:
6
- metadata.gz: e10199dcdc4b12d01bfebef27d23b752d1dd95c393263dac664c2d5588677aca80113c8b99ca281aefa130592767cc01304ab635d09273c63f3cc575ab2a1313
7
- data.tar.gz: eaf3f967e1cb5ac4644cddf31ffdfcf3e931107be5508091fe94f61ceb7c096bacc4e39a8203ab8ba1ddf820992abfdae795774f91ac4ff571fc7687f7efd0ba
6
+ metadata.gz: 24b96afb3447382b6d66cdf47be50ba012e83c86236fd9bd8b45a83b8685752c8820a938829920ba615c45217863966a7e46af07db027b04cff24ee9227879ae
7
+ data.tar.gz: e2206807c7a623254540441742d1017c40d75fabd8cc097793d040c55271f0c33a6feedee3994deb68d75dc3fddcf0f1b2a8ad98205ce254852f164877d5940a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 5.3.2 (2022-03-24)
2
+
3
+ - ImageLoader: Add error handling ([tvdeyen](https://github.com/tvdeyen))
4
+ - Fix new Sitemap ([tvdeyen](https://github.com/tvdeyen))
5
+
1
6
  ## 5.3.1 (2022-03-11)
2
7
 
3
8
  - Allow all pages in API again ([tvdeyen](https://github.com/tvdeyen))
@@ -54,9 +54,12 @@ $.extend Alchemy,
54
54
  image.on 'load', ->
55
55
  spinner.stop()
56
56
  image.fadeIn 400
57
- image.on 'error', ->
57
+ image.on 'error', (evt) ->
58
+ message = "Could not load #{this.src}"
58
59
  spinner.stop()
59
- $parent.html('<span class="icon warn"/>')
60
+ console.error(message, evt)
61
+ $parent.html('<span class="icon fas fa-exclamation-triangle" title="' + message + '" />')
62
+ return
60
63
 
61
64
  # Removes the picture from essence picture thumbnail
62
65
  removePicture: (selector) ->
@@ -33,6 +33,10 @@ div#image_assign_filter_and_image_sizing {
33
33
  background-color: $thumbnail-background-color;
34
34
  width: 100%;
35
35
  height: 120px;
36
+
37
+ &:hover {
38
+ text-decoration: none;
39
+ }
36
40
  }
37
41
 
38
42
  .picture_thumbnail {
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "5.3.1"
4
+ VERSION = "5.3.2"
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -1,5 +1,5 @@
1
1
  import Sortable from "sortablejs"
2
- import ajax from "./utils/ajax"
2
+ import { patch } from "./utils/ajax"
3
3
  import { on } from "./utils/events"
4
4
 
5
5
  function displayNodeFolders() {
@@ -23,7 +23,7 @@ function onFinishDragging(evt) {
23
23
  new_position: evt.newIndex
24
24
  }
25
25
 
26
- ajax("PATCH", url, data)
26
+ patch(url, data)
27
27
  .then(() => {
28
28
  const message = Alchemy.t("Successfully moved menu item")
29
29
  Alchemy.growl(message)
@@ -41,7 +41,7 @@ function handleNodeFolders() {
41
41
  const url = Alchemy.routes.toggle_folded_api_node_path(nodeId)
42
42
  const list = menu_item.querySelector(".children")
43
43
 
44
- ajax("PATCH", url)
44
+ patch(url)
45
45
  .then(() => {
46
46
  list.classList.toggle("folded")
47
47
  menu_item.dataset.folded =
@@ -1,4 +1,5 @@
1
1
  import Sortable from "sortablejs"
2
+ import { patch } from "./utils/ajax"
2
3
 
3
4
  function onFinishDragging(evt) {
4
5
  const pageId = evt.item.dataset.pageId
@@ -8,14 +9,7 @@ function onFinishDragging(evt) {
8
9
  new_position: evt.newIndex
9
10
  }
10
11
 
11
- fetch(url, {
12
- method: "PATCH",
13
- headers: {
14
- "Content-Type": "application/json",
15
- Accept: "application/json"
16
- },
17
- body: JSON.stringify(data)
18
- })
12
+ patch(url, data)
19
13
  .then(async (response) => {
20
14
  const pageData = await response.json()
21
15
  const pageEl = document.getElementById(`page_${pageId}`)
@@ -1,6 +1,7 @@
1
1
  // The admin sitemap Alchemy class
2
2
  import PageSorter from "./page_sorter"
3
3
  import { on } from "./utils/events"
4
+ import { patch } from "./utils/ajax"
4
5
  import { createSortables, displayPageFolders } from "./page_sorter"
5
6
 
6
7
  export default class Sitemap {
@@ -52,12 +53,7 @@ export default class Sitemap {
52
53
  pageFolder.innerHTML = ""
53
54
  spinner.spin(pageFolder)
54
55
 
55
- fetch(Alchemy.routes.fold_admin_page_path(pageId), {
56
- method: "PATCH",
57
- headers: {
58
- Accept: "application/json"
59
- }
60
- })
56
+ patch(Alchemy.routes.fold_admin_page_path(pageId))
61
57
  .then(async (response) => {
62
58
  this.reRender(pageId, await response.json())
63
59
  spinner.stop()
@@ -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.3.1",
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.3.1
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-11 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