@raketa-cloud/admin 0.0.64 → 0.0.66

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raketa-cloud/admin",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
4
4
  "main": "src/index.js",
5
5
  "scripts": {
6
6
  "dev": "npx tailwindcss -i ./src/styles/application.css -o ../../apps/admin/static/application.css --watch",
@@ -0,0 +1,36 @@
1
+ const edit_form = async (ctx) => {
2
+ const data = await ctx.client.settings.find(ctx.locale);
3
+
4
+ return {
5
+ assigns: {
6
+ errors: {},
7
+ resource: data,
8
+ },
9
+ };
10
+ };
11
+
12
+ const update = async (ctx) => {
13
+ const params = ctx.resourceParams.resource;
14
+ const current = await ctx.client.settings.find(ctx.locale);
15
+ const updated = ctx.client.settings.deepMerge(current, params);
16
+
17
+ const { errors } = await ctx.client.settings.update(ctx.locale, updated);
18
+
19
+ if (errors) {
20
+ return {
21
+ assigns: {
22
+ resource: { ...params },
23
+ errors: { resource: ctx.client.settings.formatErrors(errors) },
24
+ },
25
+ };
26
+ }
27
+
28
+ return {
29
+ redirect: `/${ctx.locale}/${ctx.resourceConfig.resource}/edit`,
30
+ };
31
+ };
32
+
33
+ export default {
34
+ edit_form,
35
+ update,
36
+ };
package/src/index.js CHANGED
@@ -49,8 +49,7 @@ export { default as PageTranslationsHandler } from "./handlers/pages/Translation
49
49
  export { default as PageURLsHandler } from "./handlers/pages/URLsHandler";
50
50
  export { default as PagesHandler } from "./handlers/pages/PagesHandler";
51
51
 
52
- export { default as SettingsLayoutHandler } from "./handlers/settings/LayoutHandler";
53
- export { default as SettingsMetaHandler } from "./handlers/settings/MetaHandler";
52
+ export { default as SettingsHandler } from "./handlers/_shared/SettingsHandler";
54
53
 
55
54
  export { default as ArticleRevisionsHandler } from "./handlers/article_revisions/ArticleRevisionsHandler";
56
55
  export { default as ArticleRevisionsCodeHandler } from "./handlers/article_revisions/CodeHandler";
@@ -1,10 +1,14 @@
1
1
  import routeMember from "./routeMember";
2
- import LayoutHandler from "./handlers/settings/LayoutHandler";
3
- import MetaHandler from "./handlers/settings/MetaHandler";
2
+ import SettingsHandler from "./handlers/_shared/SettingsHandler";
4
3
 
5
4
  function routeSettings(adapter) {
6
- routeMember(adapter, "settings/meta", MetaHandler);
7
- routeMember(adapter, "settings/layout", LayoutHandler);
5
+ routeMember(adapter, "settings/meta", SettingsHandler, {
6
+ resource: "settings/meta",
7
+ });
8
+
9
+ routeMember(adapter, "settings/layout", SettingsHandler, {
10
+ resource: "settings/layout",
11
+ });
8
12
  }
9
13
 
10
14
  export default routeSettings;
@@ -0,0 +1,36 @@
1
+ import SettingsHandler from "../../../../handlers/_shared/SettingsHandler";
2
+ import Settings from "../../../../cloud/Settings";
3
+
4
+ import Factory from "../../../support/factory";
5
+
6
+ function buildCtx() {
7
+ return {
8
+ client: {
9
+ settings: new Settings(() => ({}), "token"),
10
+ },
11
+ locale: "en",
12
+ };
13
+ }
14
+
15
+ describe("Settings edit", () => {
16
+ test("edit_form", async () => {
17
+ const settings = Factory.build("settings");
18
+
19
+ const ctx = buildCtx();
20
+
21
+ const mockFind = jest
22
+ .spyOn(ctx.client.settings, "find")
23
+ .mockImplementation(() => settings.value);
24
+
25
+ const result = await SettingsHandler.edit_form(ctx);
26
+
27
+ expect(mockFind).toHaveBeenCalledWith("en");
28
+
29
+ expect(result).toEqual({
30
+ assigns: {
31
+ resource: settings.value,
32
+ errors: {},
33
+ },
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,114 @@
1
+ import SettingsHandler from "../../../../handlers/_shared/SettingsHandler";
2
+ import Settings from "../../../../cloud/Settings";
3
+
4
+ import Factory from "../../../support/factory";
5
+
6
+ function buildCtx(params) {
7
+ return {
8
+ client: {
9
+ settings: new Settings(() => ({}), "token"),
10
+ },
11
+ locale: "en",
12
+ resourceParams: {
13
+ resource: params,
14
+ },
15
+ locale: "en",
16
+ resourceConfig: {
17
+ resource: "settings/meta",
18
+ },
19
+ };
20
+ }
21
+
22
+ describe("Settings update", () => {
23
+ test("update succesfully", async () => {
24
+ const settings = Factory.build("settings", {
25
+ value: {
26
+ meta: {
27
+ title: "Not A title!",
28
+ description: "No, no!",
29
+ },
30
+ },
31
+ });
32
+
33
+ const ctx = buildCtx({
34
+ meta: {
35
+ title: "A title",
36
+ description: "A description",
37
+ image: JSON.stringify({ url: "https://image-url.com" }),
38
+ },
39
+ });
40
+
41
+ const mockFind = jest
42
+ .spyOn(ctx.client.settings, "find")
43
+ .mockImplementation(() => settings.value);
44
+
45
+ const mockUpdate = jest
46
+ .spyOn(ctx.client.settings, "update")
47
+ .mockImplementation(() => ({ setting: {}, errors: null }));
48
+
49
+ const result = await SettingsHandler.update(ctx);
50
+
51
+ expect(mockFind).toHaveBeenCalledWith("en");
52
+ expect(mockUpdate).toHaveBeenCalledWith("en", {
53
+ meta: {
54
+ title: "A title",
55
+ description: "A description",
56
+ image: { url: "https://image-url.com" },
57
+ },
58
+ });
59
+
60
+ expect(result).toEqual({
61
+ redirect: "/en/settings/meta/edit",
62
+ });
63
+ });
64
+
65
+ test("update failed", async () => {
66
+ const settings = Factory.build("settings", {
67
+ value: {
68
+ meta: {
69
+ title: "Not A title!",
70
+ description: "No, no!",
71
+ },
72
+ },
73
+ });
74
+
75
+ const updateParams = {
76
+ meta: {
77
+ title: "A title",
78
+ description: "A description",
79
+ image: JSON.stringify({ url: "https://image-url.com" }),
80
+ },
81
+ };
82
+
83
+ const ctx = buildCtx(updateParams);
84
+
85
+ const mockFind = jest
86
+ .spyOn(ctx.client.settings, "find")
87
+ .mockImplementation(() => settings.value);
88
+
89
+ const mockUpdate = jest
90
+ .spyOn(ctx.client.settings, "update")
91
+ .mockImplementation(() => ({
92
+ setting: null,
93
+ errors: [{ key: "generalError", message: "some error" }],
94
+ }));
95
+
96
+ const result = await SettingsHandler.update(ctx);
97
+
98
+ expect(mockFind).toHaveBeenCalledWith("en");
99
+ expect(mockUpdate).toHaveBeenCalledWith("en", {
100
+ meta: {
101
+ title: "A title",
102
+ description: "A description",
103
+ image: { url: "https://image-url.com" },
104
+ },
105
+ });
106
+
107
+ expect(result).toEqual({
108
+ assigns: {
109
+ resource: updateParams,
110
+ errors: { resource: { generalError: "some error" } },
111
+ },
112
+ });
113
+ });
114
+ });
@@ -20,6 +20,8 @@
20
20
  <tr>
21
21
  <th><%- sort_button("Title", "title", _context) %></th>
22
22
  <th>Visibility</th>
23
+ <th><%- sort_button("Publish at", "publish_at", _context) %></th>
24
+ <th><%- sort_button("Last change", "updated_at", _context) %></th>
23
25
  <th>Translations</th>
24
26
  </tr>
25
27
  </thead>
@@ -75,6 +77,30 @@
75
77
  </div>
76
78
  </td>
77
79
 
80
+ <td>
81
+ <time data-pretty-datetime datetime="<%= item.publishAt %>"><%= item.publishAt %></time>
82
+ </td>
83
+
84
+ <td>
85
+ <div class="body-3 text-raketa-foreground/50">
86
+ <div class="flex items-center gap-1 mb-0.5">
87
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4 text-raketa-foreground">
88
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
89
+ </svg>
90
+ <time data-pretty-datetime datetime="<%= item.updatedAt %>"><%= item.updatedAt %></time>
91
+ </div>
92
+
93
+ <div class="flex items-center gap-1" title="<%= item.changes[0]?.operatorMeta?.name %>">
94
+ <% if (item.changes[0]?.operatorMeta?.avatar) { %>
95
+ <img src="<%= item.changes[0]?.operatorMeta?.avatar %>" class="size-4 rounded-full" alt="<%= item.changes[0]?.operatorMeta?.name %>">
96
+ <% } else { %>
97
+ <div class="size-4 rounded-full"></div>
98
+ <% } %>
99
+ <%= item.changes[0]?.operatorMeta?.name %>
100
+ </div>
101
+ </div>
102
+ </td>
103
+
78
104
  <td>
79
105
  <div class="flex flex-wrap items-center gap-1">
80
106
  <% Object.keys(_context.locales).forEach(key => { %>
@@ -142,4 +168,4 @@
142
168
  searchToggle.addEventListener('click', () => {
143
169
  sidebar.classList.toggle('hidden');
144
170
  });
145
- </script>
171
+ </script>
@@ -77,7 +77,7 @@
77
77
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
78
78
  </svg>
79
79
 
80
- <%= (new Date(revision.insertedAt)).toLocaleString() %>
80
+ <time data-pretty-datetime datetime="<%= revision.insertedAt %>"><%= revision.insertedAt %></time>
81
81
  </div>
82
82
  </div>
83
83
  </td>
@@ -133,7 +133,7 @@
133
133
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
134
134
  </svg>
135
135
 
136
- <%= (new Date(change.insertedAt)).toLocaleString() %>
136
+ <time data-pretty-datetime datetime="<%= change.insertedAt %>"><%= change.insertedAt %></time>
137
137
  </div>
138
138
  </div>
139
139
  </td>
@@ -20,6 +20,8 @@
20
20
  <tr>
21
21
  <th><%- sort_button("Title", "title", _context) %></th>
22
22
  <th>Visibility</th>
23
+ <th><%- sort_button("Publish at", "publish_at", _context) %></th>
24
+ <th><%- sort_button("Last change", "updated_at", _context) %></th>
23
25
  <th>Translations</th>
24
26
  </tr>
25
27
  </thead>
@@ -75,6 +77,30 @@
75
77
  </div>
76
78
  </td>
77
79
 
80
+ <td>
81
+ <time data-pretty-datetime datetime="<%= item.publishAt %>"><%= item.publishAt %></time>
82
+ </td>
83
+
84
+ <td>
85
+ <div class="body-3 text-raketa-foreground/50">
86
+ <div class="flex items-center gap-1 mb-0.5">
87
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4 text-raketa-foreground">
88
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
89
+ </svg>
90
+ <time data-pretty-datetime datetime="<%= item.updatedAt %>"><%= item.updatedAt %></time>
91
+ </div>
92
+
93
+ <div class="flex items-center gap-1" title="<%= item.changes[0]?.operatorMeta?.name %>">
94
+ <% if (item.changes[0]?.operatorMeta?.avatar) { %>
95
+ <img src="<%= item.changes[0]?.operatorMeta?.avatar %>" class="size-4 rounded-full" alt="<%= item.changes[0]?.operatorMeta?.name %>">
96
+ <% } else { %>
97
+ <div class="size-4 rounded-full"></div>
98
+ <% } %>
99
+ <%= item.changes[0]?.operatorMeta?.name %>
100
+ </div>
101
+ </div>
102
+ </td>
103
+
78
104
  <td>
79
105
  <div class="flex flex-wrap items-center gap-1">
80
106
  <% Object.keys(_context.locales).forEach(key => { %>
@@ -142,4 +168,4 @@
142
168
  searchToggle.addEventListener('click', () => {
143
169
  sidebar.classList.toggle('hidden');
144
170
  });
145
- </script>
171
+ </script>
@@ -77,7 +77,7 @@
77
77
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
78
78
  </svg>
79
79
 
80
- <%= (new Date(revision.insertedAt)).toLocaleString() %>
80
+ <time data-pretty-datetime datetime="<%= revision.insertedAt %>"><%= revision.insertedAt %></time>
81
81
  </div>
82
82
  </div>
83
83
  </td>
@@ -133,7 +133,7 @@
133
133
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
134
134
  </svg>
135
135
 
136
- <%= (new Date(change.insertedAt)).toLocaleString() %>
136
+ <time data-pretty-datetime datetime="<%= change.insertedAt %>"><%= change.insertedAt %></time>
137
137
  </div>
138
138
  </div>
139
139
  </td>
@@ -41,6 +41,10 @@
41
41
  }
42
42
  </style>
43
43
 
44
+ <script src="https://storage.googleapis.com/cdn-raketa-cloud/js/raketa-menu-builder-webcomponent.umd.js"></script>
45
+
46
+ <script src="https://storage.googleapis.com/cdn-raketa-cloud/js/raketa-list-input-webcomponent.umd.js"></script>
47
+
44
48
  <body class="relative max-h-screen overflow-hidden">
45
49
  <%- include('header.ejs') %>
46
50
 
@@ -143,10 +147,22 @@
143
147
 
144
148
  parent.querySelectorAll('[data-auto="1"]').forEach(node => node.remove())
145
149
 
150
+ // Add user's localtime
151
+ const strTime = fakeUTCDate.toLocaleString("en-GB", {});
152
+
153
+ const hint = document.createElement("div");
154
+
155
+ hint.classList.add('hint')
156
+ hint.innerText = `In your local time: ${strTime}`;
157
+ hint.dataset.auto = "1";
158
+
159
+ parent.appendChild(hint)
160
+
146
161
  TIMEZONES.forEach(timeZone => {
147
- const strTime = fakeUTCDate.toLocaleString("en-EU", {
162
+ const strTime = fakeUTCDate.toLocaleString("en-GB", {
148
163
  timeZone: `${timeZone.value}`
149
164
  });
165
+
150
166
  const hint = document.createElement("div");
151
167
 
152
168
  hint.classList.add('hint')
@@ -156,12 +172,6 @@
156
172
  parent.appendChild(hint)
157
173
  })
158
174
  }
159
-
160
- document.querySelectorAll('input[type="datetime-local"]').forEach(input => {
161
- enhanceDateTimeInputs(input);
162
-
163
- input.addEventListener("change", (event) => enhanceDateTimeInputs(event.target))
164
- })
165
175
  </script>
166
176
 
167
177
  <script>
@@ -183,6 +193,29 @@
183
193
  })
184
194
  })
185
195
  </script>
196
+
197
+ <script>
198
+ window.addEventListener("load", (_event) => {
199
+
200
+ // Setup datetime inputs
201
+ document.querySelectorAll('input[type="datetime-local"]').forEach(input => {
202
+ enhanceDateTimeInputs(input);
203
+
204
+ input.addEventListener("change", (event) => enhanceDateTimeInputs(event.target))
205
+ })
206
+
207
+
208
+ // Setup time presentation
209
+ document.querySelectorAll('time[data-pretty-datetime]').forEach(item => {
210
+ const dateStr = item.getAttribute("datetime");
211
+
212
+ item.innerText = new Date(dateStr).toLocaleString('en-GB', {
213
+ dateStyle: "short",
214
+ timeStyle: "short"
215
+ })
216
+ })
217
+ })
218
+ </script>
186
219
  </body>
187
220
 
188
221
  </html>
@@ -20,6 +20,7 @@
20
20
  <tr>
21
21
  <th><%- sort_button("Title", "title", _context) %></th>
22
22
  <th>Visibility</th>
23
+ <th><%- sort_button("Last change", "updated_at", _context) %></th>
23
24
  <th>Translations</th>
24
25
  </tr>
25
26
  </thead>
@@ -75,6 +76,26 @@
75
76
  </div>
76
77
  </td>
77
78
 
79
+ <td>
80
+ <div class="body-3 text-raketa-foreground/50">
81
+ <div class="flex items-center gap-1 mb-0.5">
82
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4 text-raketa-foreground">
83
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
84
+ </svg>
85
+ <time data-pretty-datetime datetime="<%= item.updatedAt %>"><%= item.updatedAt %></time>
86
+ </div>
87
+
88
+ <div class="flex items-center gap-1" title="<%= item.changes[0]?.operatorMeta?.name %>">
89
+ <% if (item.changes[0]?.operatorMeta?.avatar) { %>
90
+ <img src="<%= item.changes[0]?.operatorMeta?.avatar %>" class="size-4 rounded-full" alt="<%= item.changes[0]?.operatorMeta?.name %>">
91
+ <% } else { %>
92
+ <div class="size-4 rounded-full"></div>
93
+ <% } %>
94
+ <%= item.changes[0]?.operatorMeta?.name %>
95
+ </div>
96
+ </div>
97
+ </td>
98
+
78
99
  <td>
79
100
  <div class="flex flex-wrap items-center gap-1">
80
101
  <% Object.keys(_context.locales).forEach(key => { %>
@@ -142,4 +163,4 @@
142
163
  searchToggle.addEventListener('click', () => {
143
164
  sidebar.classList.toggle('hidden');
144
165
  });
145
- </script>
166
+ </script>
@@ -91,7 +91,7 @@
91
91
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
92
92
  </svg>
93
93
 
94
- <%= (new Date(revision.insertedAt)).toLocaleString() %>
94
+ <time data-pretty-datetime datetime="<%= revision.insertedAt %>"><%= revision.insertedAt %></time>
95
95
  </div>
96
96
  </div>
97
97
  </td>
@@ -147,7 +147,7 @@
147
147
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
148
148
  </svg>
149
149
 
150
- <%= (new Date(change.insertedAt)).toLocaleString() %>
150
+ <time data-pretty-datetime datetime="<%= change.insertedAt %>"><%= change.insertedAt %></time>
151
151
  </div>
152
152
  </div>
153
153
  </td>
@@ -54,7 +54,7 @@
54
54
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
55
55
  </svg>
56
56
 
57
- <%= new Date(item.updatedAt).toLocaleString('en-GB', { dateStyle: "short", timeStyle: "short" }) %>
57
+ <time data-pretty-datetime datetime="<%= item.updatedAt %>"><%= item.updatedAt %></time>
58
58
  </div>
59
59
  </td>
60
60
  <td class="actions">
@@ -72,4 +72,4 @@
72
72
  </table>
73
73
 
74
74
  <%- pagination(items.pagination, _context) %>
75
- </div>
75
+ </div>
@@ -29,7 +29,7 @@
29
29
  </tr>
30
30
  <tr>
31
31
  <th class="w-1 whitespace-nowrap">Updated at</th>
32
- <td><%= new Date(item.updatedAt).toLocaleString('en-GB', { dateStyle: "short", timeStyle: "short" }) %></td>
32
+ <time data-pretty-datetime datetime="<%= item.updatedAt %>"><%= item.updatedAt %></time>
33
33
  </tr>
34
34
  </tbody>
35
35
  </table>
@@ -52,9 +52,9 @@
52
52
  <td><%= item.version %></td>
53
53
  <td><%= item.title %></td>
54
54
  <td><%= item.operatorMeta.name %></td>
55
- <td><%= new Date(item.insertedAt).toLocaleString('en-GB', { dateStyle: "short", timeStyle: "short" }) %></td>
55
+ <td><time data-pretty-datetime datetime="<%= item.insertedAt %>"><%= item.insertedAt %></time></td>
56
56
  </tr>
57
57
  <% }) %>
58
58
  </tbody>
59
59
  </table>
60
- </div>
60
+ </div>
@@ -5,11 +5,47 @@
5
5
 
6
6
  <%- render_partial('../_nav.ejs', { active: 'layout' }) %>
7
7
 
8
+ <% const WIDGETS = {
9
+ HTML: {
10
+ defaults: {
11
+ code: "<div>HTML</div>"
12
+ },
13
+ admin: {
14
+ code: { type: "textarea" }
15
+ }
16
+ },
17
+ Image: {
18
+ primaryField: "image",
19
+ defaults: {
20
+ image: "https://placeholder.raketa.cloud/images/1920x1080"
21
+ },
22
+ admin: {
23
+ image: { type: "text" }
24
+ }
25
+ },
26
+ Title: {
27
+ primaryField: "title",
28
+ defaults: {
29
+ title: "Title"
30
+ },
31
+ admin: {
32
+ title: { type: "text" }
33
+ }
34
+ }
35
+ }; %>
36
+
8
37
  <div>
9
- <% form_for({ layout_settings }, errors, (f) => { %>
38
+ <% form_for({ resource }, errors, (f) => { %>
10
39
  <form action="<%= `/${_context.locale}/settings/layout` %>" method="post" class="form">
11
- <%- f.field('layout_settings.header', {as: "textarea"}) %>
12
- <%- f.field('layout_settings.footer', {as: "textarea"}) %>
40
+ <div class="mb-4">
41
+ <label>Header</label>
42
+ <raketa-menu-builder-input id="header-menu" name="resource[menus][header]" value="<%= JSON.stringify(resource.menus?.header || []) %>" widgets="<%= JSON.stringify(WIDGETS) %>"></raketa-menu-builder-input>
43
+ </div>
44
+
45
+ <div class="mb-4">
46
+ <label>Footer</label>
47
+ <raketa-menu-builder-input id="header-menu" name="resource[menus][footer]" value="<%= JSON.stringify(resource.menus?.footer || []) %>" widgets="<%= JSON.stringify(WIDGETS) %>"></raketa-menu-builder-input>
48
+ </div>
13
49
 
14
50
  <div class="form-actions">
15
51
  <div class="btn-toolbar">
@@ -6,12 +6,12 @@
6
6
  <%- render_partial('../_nav.ejs', { active: 'meta' }) %>
7
7
 
8
8
  <div class="grid gap-4 md:grid-cols-3">
9
- <% form_for({ meta_settings }, errors, (f) => { %>
9
+ <% form_for({ resource }, errors, (f) => { %>
10
10
  <form action="<%= `/${_context.locale}/settings/meta` %>" method="post" class="form">
11
- <%- f.field('meta_settings.title', { label: "Meta title", hint: "Used for both meta and OpenGraph" }) %>
12
- <%- f.field('meta_settings.description', { as: "textarea", label: "Meta description", hint: "Used for both meta and OpenGraph" }) %>
11
+ <%- f.field('resource.meta.title', { label: "Meta title", hint: "Used for both meta and OpenGraph" }) %>
12
+ <%- f.field('resource.meta.description', { as: "textarea", label: "Meta description", hint: "Used for both meta and OpenGraph" }) %>
13
13
 
14
- <raketa-image-picker name="meta_settings[image]" value="<%= JSON.stringify(meta_settings.image) %>" label="OpenGraph image"></raketa-image-picker>
14
+ <raketa-image-picker name="resource[image]" value="<%= JSON.stringify(resource.meta?.image || {}) %>" label="OpenGraph image"></raketa-image-picker>
15
15
 
16
16
  <div class="form-actions">
17
17
  <div class="btn-toolbar">
@@ -21,4 +21,4 @@
21
21
  </form>
22
22
  <% }) %>
23
23
  </div>
24
- </div>
24
+ </div>
@@ -1,51 +0,0 @@
1
- const edit_form = async (ctx) => {
2
- const data = await ctx.client.settings.find(ctx.locale);
3
-
4
- const layout_settings = {
5
- header: JSON.stringify(data.menus?.header),
6
- footer: JSON.stringify(data.menus?.footer),
7
- };
8
-
9
- return {
10
- assigns: {
11
- errors: {},
12
- layout_settings,
13
- },
14
- };
15
- };
16
-
17
- const update = async (ctx) => {
18
- const params = ctx.resourceParams.layout_settings;
19
-
20
- const currentSettings = await ctx.client.settings.find(ctx.locale);
21
-
22
- if (!currentSettings.menus) {
23
- currentSettings.menus = {};
24
- }
25
-
26
- currentSettings.menus.header = JSON.parse(params.header);
27
- currentSettings.menus.footer = JSON.parse(params.footer);
28
-
29
- const { errors } = await ctx.client.settings.update(
30
- ctx.locale,
31
- currentSettings
32
- );
33
-
34
- if (errors) {
35
- return {
36
- assigns: {
37
- setting: { ...params },
38
- errors: { setting: ctx.client.settings.formatErrors(errors) },
39
- },
40
- };
41
- }
42
-
43
- return {
44
- redirect: `/${ctx.locale}/settings/layout/edit`,
45
- };
46
- };
47
-
48
- export default {
49
- edit_form,
50
- update,
51
- };
@@ -1,52 +0,0 @@
1
- const edit_form = async (ctx) => {
2
- const data = await ctx.client.settings.find(ctx.locale);
3
- const meta_settings = {
4
- ...data.meta,
5
- image: data.meta?.image || {},
6
- };
7
- const errors = {};
8
-
9
- return {
10
- assigns: {
11
- errors,
12
- meta_settings,
13
- },
14
- };
15
- };
16
-
17
- const update = async (ctx) => {
18
- const params = ctx.resourceParams.meta_settings;
19
-
20
- const currentSettings = await ctx.client.settings.find(ctx.locale);
21
-
22
- if (!currentSettings.meta) {
23
- currentSettings.meta = {};
24
- }
25
-
26
- currentSettings.meta.title = params.title;
27
- currentSettings.meta.description = params.description;
28
- currentSettings.meta.image = JSON.parse(params.image);
29
-
30
- const { errors } = await ctx.client.settings.update(
31
- ctx.locale,
32
- currentSettings
33
- );
34
-
35
- if (errors) {
36
- return {
37
- assigns: {
38
- setting: { ...params },
39
- errors: { setting: ctx.client.settings.formatErrors(errors) },
40
- },
41
- };
42
- }
43
-
44
- return {
45
- redirect: `/${ctx.locale}/settings/meta/edit`,
46
- };
47
- };
48
-
49
- export default {
50
- edit_form,
51
- update,
52
- };