@raketa-cloud/admin 0.0.65 → 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.65",
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
+ });
@@ -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
 
@@ -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
- };