@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 +1 -1
- package/src/handlers/_shared/SettingsHandler.js +36 -0
- package/src/index.js +1 -2
- package/src/routeSettings.js +8 -4
- package/src/tests/handlers/_shared/SettingsHandler.test/edit_form.test.js +36 -0
- package/src/tests/handlers/_shared/SettingsHandler.test/update.test.js +114 -0
- package/src/views/layouts/application.ejs +4 -0
- package/src/views/settings/layout/edit_form.ejs +39 -3
- package/src/views/settings/meta/edit_form.ejs +5 -5
- package/src/handlers/settings/LayoutHandler.js +0 -51
- package/src/handlers/settings/MetaHandler.js +0 -52
package/package.json
CHANGED
|
@@ -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
|
|
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";
|
package/src/routeSettings.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import routeMember from "./routeMember";
|
|
2
|
-
import
|
|
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",
|
|
7
|
-
|
|
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({
|
|
38
|
+
<% form_for({ resource }, errors, (f) => { %>
|
|
10
39
|
<form action="<%= `/${_context.locale}/settings/layout` %>" method="post" class="form">
|
|
11
|
-
|
|
12
|
-
|
|
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({
|
|
9
|
+
<% form_for({ resource }, errors, (f) => { %>
|
|
10
10
|
<form action="<%= `/${_context.locale}/settings/meta` %>" method="post" class="form">
|
|
11
|
-
<%- f.field('
|
|
12
|
-
<%- f.field('
|
|
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="
|
|
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
|
-
};
|