@raketa-cloud/admin 0.0.7 → 0.0.8

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.
Files changed (114) hide show
  1. package/package.json +3 -2
  2. package/src/Adapter.js +1 -4
  3. package/src/cloud/ChangePageURL.js +24 -0
  4. package/src/cloud/ClonesPage.js +14 -0
  5. package/src/cloud/DeletePage.js +35 -0
  6. package/src/cloud/PageChanges.js +15 -0
  7. package/src/cloud/PageRevisions.js +135 -0
  8. package/src/cloud/PageTranslations.js +22 -0
  9. package/src/cloud/Pages.js +63 -0
  10. package/src/cloud/RaketaClient.js +118 -0
  11. package/src/cloud/Redirects.js +81 -0
  12. package/src/cloud/RevertPageRevision.js +18 -0
  13. package/src/cloud/Settings.js +30 -0
  14. package/src/cloud/Tags.js +80 -0
  15. package/src/cloud/documents/articlesDocuments.js +608 -0
  16. package/src/cloud/documents/categoryDocuments.js +64 -0
  17. package/src/cloud/documents/common.js +84 -0
  18. package/src/cloud/documents/pagesDocuments.js +245 -0
  19. package/src/cloud/documents/redirectsDocuments.js +82 -0
  20. package/src/cloud/documents/settingsDocuments.js +23 -0
  21. package/src/cloud/documents/tagsDocuments.js +63 -0
  22. package/src/handlers/PageCloneHandler.js +17 -0
  23. package/src/handlers/PageCloneHandler.test/create.test.js +55 -0
  24. package/src/handlers/PageDeleteHandler.js +68 -0
  25. package/src/handlers/PageDeleteHandler.test/create.test.js +112 -0
  26. package/src/handlers/PageDeleteHandler.test/create_form.test.js +54 -0
  27. package/src/handlers/PageRevisionsCodesHandler.js +83 -0
  28. package/src/handlers/PageRevisionsCodesHandler.test/edit_form.test.js +56 -0
  29. package/src/handlers/PageRevisionsCodesHandler.test/update.test.js +137 -0
  30. package/src/handlers/PageRevisionsGeneralHandler.js +86 -0
  31. package/src/handlers/PageRevisionsGeneralHandler.test/edit_form.test.js +62 -0
  32. package/src/handlers/PageRevisionsGeneralHandler.test/update.test.js +147 -0
  33. package/src/handlers/PageRevisionsHandler.js +47 -0
  34. package/src/handlers/PageRevisionsHandler.test/create.test.js +67 -0
  35. package/src/handlers/PageRevisionsHandler.test/destroy.test.js +54 -0
  36. package/src/handlers/PageRevisionsLockHandler.js +54 -0
  37. package/src/handlers/PageRevisionsMetaHandler.js +83 -0
  38. package/src/handlers/PageRevisionsMetaHandler.test/edit_form.test.js +57 -0
  39. package/src/handlers/PageRevisionsMetaHandler.test/update.test.js +141 -0
  40. package/src/handlers/PageRevisionsTagsHandler.js +80 -0
  41. package/src/handlers/PageRevisionsTagsHandler.test/edit_form.test.js +69 -0
  42. package/src/handlers/PageRevisionsTagsHandler.test/update.test.js +141 -0
  43. package/src/handlers/PageRevisionsUnlockHandler.js +22 -0
  44. package/src/handlers/PageRevisionsVisualsHandler.js +77 -0
  45. package/src/handlers/PageRevisionsVisualsHandler.test/edit_form.test.js +55 -0
  46. package/src/handlers/PageRevisionsVisualsHandler.test/update.test.js +129 -0
  47. package/src/handlers/PageRevisionsWidgetsHandler.js +41 -0
  48. package/src/handlers/PageRevisionsWidgetsHandler.test/show.test.js +47 -0
  49. package/src/handlers/PageRevisionsWidgetsHandler.test/update.test.js +104 -0
  50. package/src/handlers/PageTranslationsHandler.js +91 -0
  51. package/src/handlers/PageURLsHandler.js +69 -0
  52. package/src/handlers/PageURLsHandler.test/create.test.js +157 -0
  53. package/src/handlers/PageURLsHandler.test/create_form.test.js +51 -0
  54. package/src/handlers/PagesHandler.js +114 -0
  55. package/src/handlers/PagesHandler.test/create.test.js +140 -0
  56. package/src/handlers/PagesHandler.test/create_form.test.js +41 -0
  57. package/src/handlers/PagesHandler.test/index.test.js +49 -0
  58. package/src/handlers/PagesHandler.test/show.test.js +103 -0
  59. package/src/handlers/PublishPageRevisionHandler.js +84 -0
  60. package/src/handlers/PublishPageRevisionHandler.test/create.test.js +136 -0
  61. package/src/handlers/PublishPageRevisionHandler.test/create_form.test.js +47 -0
  62. package/src/handlers/RedirectsHandler.js +124 -0
  63. package/src/handlers/RedirectsHandler.test/create.test.js +84 -0
  64. package/src/handlers/RedirectsHandler.test/create_form.test.js +29 -0
  65. package/src/handlers/RedirectsHandler.test/destroy.test.js +54 -0
  66. package/src/handlers/RedirectsHandler.test/edit_form.test.js +38 -0
  67. package/src/handlers/RedirectsHandler.test/index.test.js +42 -0
  68. package/src/handlers/RedirectsHandler.test/show.test.js +41 -0
  69. package/src/handlers/RedirectsHandler.test/update.test.js +89 -0
  70. package/src/handlers/RevertPageRevisionHandler.js +26 -0
  71. package/src/handlers/RevertPageRevisionHandler.test/create.test.js +80 -0
  72. package/src/handlers/SettingsGeneralHandler.js +13 -0
  73. package/src/handlers/SettingsLayoutHandler.js +51 -0
  74. package/src/handlers/SettingsMetaHandler.js +52 -0
  75. package/src/handlers/TagsHandler.js +113 -0
  76. package/src/helpers/FormBuilder.js +12 -4
  77. package/src/index.js +33 -0
  78. package/src/setupAuthentication.js +1 -1
  79. package/src/styles/application.css +55 -19
  80. package/src/views/layouts/application.ejs +30 -31
  81. package/src/views/layouts/header.ejs +5 -6
  82. package/src/views/page_deletes/create_form.ejs +55 -0
  83. package/src/views/page_lock/create_form.ejs +35 -0
  84. package/src/views/page_publish/_form.ejs +57 -0
  85. package/src/views/page_publish/create_form.ejs +11 -0
  86. package/src/views/page_revisions/_nav.ejs +40 -0
  87. package/src/views/page_revisions/codes/edit_form.ejs +39 -0
  88. package/src/views/page_revisions/general/edit_form.ejs +69 -0
  89. package/src/views/page_revisions/meta/edit_form.ejs +41 -0
  90. package/src/views/page_revisions/tags/edit_form.ejs +64 -0
  91. package/src/views/page_revisions/visuals/edit_form.ejs +42 -0
  92. package/src/views/page_translations/_form.ejs +76 -0
  93. package/src/views/page_translations/create_form.ejs +11 -0
  94. package/src/views/page_urls/create_form.ejs +31 -0
  95. package/src/views/pages/_form.ejs +84 -0
  96. package/src/views/pages/create_form.ejs +9 -0
  97. package/src/views/pages/edit_form.ejs +3 -0
  98. package/src/views/pages/index.ejs +161 -0
  99. package/src/views/pages/show.ejs +281 -0
  100. package/src/views/redirects/_form.ejs +40 -0
  101. package/src/views/redirects/create_form.ejs +9 -0
  102. package/src/views/redirects/edit_form.ejs +9 -0
  103. package/src/views/redirects/index.ejs +75 -1
  104. package/src/views/redirects/show.ejs +60 -0
  105. package/src/views/settings/_nav.ejs +28 -0
  106. package/src/views/settings/general/edit_form.ejs +26 -0
  107. package/src/views/settings/layout/edit_form.ejs +22 -0
  108. package/src/views/settings/meta/edit_form.ejs +38 -0
  109. package/src/views/tags/_form.ejs +39 -0
  110. package/src/views/tags/create_form.ejs +9 -0
  111. package/src/views/tags/edit_form.ejs +9 -0
  112. package/src/views/tags/index.ejs +43 -0
  113. package/test/factory.js +91 -0
  114. package/test/handlersHelper.js +9 -0
@@ -0,0 +1,104 @@
1
+ import PageRevisionsWidgetsHandler from "../PageRevisionsWidgetsHandler";
2
+ import PageRevisions from "../../cloud/PageRevisions";
3
+ import Settings from "../../cloud/Settings";
4
+
5
+ import { testConfig } from "../../../../../apps/admin/test/handlersHelper";
6
+ import Factory from "../../../../../apps/admin/test/factory";
7
+
8
+ function buildCtx(revision, newWidgets) {
9
+ return {
10
+ client: {
11
+ pageRevisions: new PageRevisions(testConfig, "token"),
12
+ settings: new Settings(testConfig, "token"),
13
+ },
14
+ params: { parent_id: revision.id },
15
+ resourceParams: {
16
+ widgets: newWidgets,
17
+ },
18
+ locale: "en",
19
+ };
20
+ }
21
+
22
+ describe("PageRevisionsWidgetsHandler", () => {
23
+ test("update successful", async () => {
24
+ const revision = Factory.build("page_revision");
25
+ const settings = Factory.build("settings");
26
+ const newWidgets = [
27
+ {
28
+ component: "SectionTitle",
29
+ settings: {},
30
+ id: "d2adwadw",
31
+ },
32
+ ];
33
+
34
+ const ctx = buildCtx(revision, newWidgets);
35
+
36
+ const mockFind = jest
37
+ .spyOn(ctx.client.pageRevisions, "find")
38
+ .mockImplementation(() => revision);
39
+
40
+ const mockSettings = jest
41
+ .spyOn(ctx.client.settings, "find")
42
+ .mockImplementation(() => settings);
43
+
44
+ const mockUpdate = jest
45
+ .spyOn(ctx.client.pageRevisions, "updateWidgets")
46
+ .mockImplementation(() => ({
47
+ revision: { ...revision, widgets: newWidgets },
48
+ errors: [],
49
+ }));
50
+
51
+ const result = await PageRevisionsWidgetsHandler.update(ctx);
52
+
53
+ expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", newWidgets);
54
+ expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
55
+ expect(mockSettings).toHaveBeenCalledWith("en");
56
+
57
+ expect(result).toEqual({
58
+ json: {
59
+ revision: {
60
+ ...revision,
61
+ websiteSettings: { ...settings },
62
+ widgets: newWidgets,
63
+ },
64
+ errors: [],
65
+ },
66
+ });
67
+ });
68
+
69
+ test("update failed", async () => {
70
+ const revision = Factory.build("page_revision");
71
+ const newWidgets = [
72
+ {
73
+ component: "SectionTitle",
74
+ settings: {},
75
+ id: "d2adwadw",
76
+ },
77
+ ];
78
+
79
+ const ctx = buildCtx(revision, newWidgets);
80
+
81
+ const mockFind = jest
82
+ .spyOn(ctx.client.pageRevisions, "find")
83
+ .mockImplementation(() => revision);
84
+
85
+ const mockUpdate = jest
86
+ .spyOn(ctx.client.pageRevisions, "updateWidgets")
87
+ .mockImplementation(() => ({
88
+ revision: null,
89
+ errors: [{ key: "widgets", message: "Wrong format" }],
90
+ }));
91
+
92
+ const result = await PageRevisionsWidgetsHandler.update(ctx);
93
+
94
+ expect(mockUpdate).toHaveBeenCalledWith(revision.id, "en", newWidgets);
95
+ expect(mockFind).toHaveBeenCalledWith(revision.id, "en");
96
+
97
+ expect(result).toEqual({
98
+ json: {
99
+ revision: null,
100
+ errors: [{ key: "widgets", message: "Wrong format" }],
101
+ },
102
+ });
103
+ });
104
+ });
@@ -0,0 +1,91 @@
1
+ const create_form = async (ctx) => {
2
+ // const tags = await ctx.client.tags.all(ctx.locale);
3
+ const { target_locale } = ctx.query;
4
+ const target_locate_tags = await ctx.client.tags.all(target_locale);
5
+
6
+ const { parent_id } = ctx.params;
7
+ const blueprint_page = await ctx.client.pages.find(parent_id, ctx.locale);
8
+
9
+ const translation = {
10
+ title: blueprint_page.title,
11
+ slug: blueprint_page.slug,
12
+ visibility: blueprint_page.visibility,
13
+ layout: blueprint_page.settings.layout,
14
+ meta_title: blueprint_page.settings.meta.title,
15
+ meta_description: blueprint_page.settings.meta.description,
16
+ meta_image: blueprint_page.settings.meta?.image || {},
17
+ username: blueprint_page.settings.credentials.user,
18
+ password: blueprint_page.settings.credentials.password,
19
+ tags: [],
20
+ // categories: blueprint_page.categories, # TODO: this will be added later?
21
+ };
22
+
23
+ return {
24
+ assigns: {
25
+ page: blueprint_page,
26
+ translation: translation,
27
+ targetLocale: target_locale,
28
+ tags: target_locate_tags.list,
29
+ blueprint_tags: blueprint_page.tags,
30
+ errors: {},
31
+ visibilityOptions: ctx.client.pages.visibilityOptions(),
32
+ _translations: [],
33
+ },
34
+ };
35
+ };
36
+
37
+ const create = async (ctx) => {
38
+ const { parent_id } = ctx.params;
39
+ const blueprint_page = await ctx.client.pages.find(parent_id, ctx.locale);
40
+
41
+ const { target_locale, translation } = ctx.resourceParams;
42
+ translation.meta_image = JSON.parse(translation.meta_image);
43
+
44
+ const { errors } = await ctx.client.pageTranslations.create(
45
+ target_locale,
46
+ parent_id,
47
+ {
48
+ title: translation.title,
49
+ slug: translation.slug,
50
+ visibility: translation.visibility,
51
+ settings: {
52
+ ...blueprint_page.settings,
53
+ layout: translation.layout,
54
+ meta: {
55
+ title: translation.meta_title,
56
+ description: translation.meta_description,
57
+ image: JSON.parse(translation.meta_image || "{}"),
58
+ },
59
+ credentials: {
60
+ user: translation.username || "",
61
+ password: translation.password || "",
62
+ },
63
+ },
64
+ widgets: blueprint_page.widgets,
65
+ tags: translation.tags || [],
66
+ categories: blueprint_page.categories.map((category) => category.id),
67
+ }
68
+ );
69
+ if (errors) {
70
+ const tags = await ctx.client.tags.all(target_locale);
71
+ return {
72
+ assigns: {
73
+ page: blueprint_page,
74
+ translation: translation,
75
+ targetLocale: translation.target_locate,
76
+ tags: tags.list,
77
+ errors: {},
78
+ visibilityOptions: ctx.client.pages.visibilityOptions(),
79
+ _translations: [],
80
+ },
81
+ };
82
+ }
83
+ return {
84
+ redirect: `/${ctx.locale}/pages/${parent_id}`,
85
+ };
86
+ };
87
+
88
+ export default {
89
+ create_form,
90
+ create,
91
+ };
@@ -0,0 +1,69 @@
1
+ const create_form = async (ctx) => {
2
+ const { parent_id } = ctx.params;
3
+ const page = await ctx.client.pages.find(parent_id, ctx.locale);
4
+
5
+ if (!page) {
6
+ throw new Error(`Cannot find page with id ${parent_id}`);
7
+ }
8
+
9
+ return {
10
+ assigns: {
11
+ change: {
12
+ id: page.id,
13
+ slug: page.slug,
14
+ redirect: null,
15
+ },
16
+ errors: {},
17
+ _translations: [],
18
+ },
19
+ };
20
+ };
21
+
22
+ const create = async (ctx) => {
23
+ const { parent_id } = ctx.params;
24
+ const change = ctx.resourceParams.change;
25
+
26
+ const page = await ctx.client.pages.find(parent_id, ctx.locale);
27
+
28
+ if (!page) {
29
+ throw new Error(`Cannot find page with id ${parent_id}`);
30
+ }
31
+
32
+ let redirectParams = null;
33
+
34
+ if (change.redirect) {
35
+ redirectParams = {
36
+ // TODO: We need some config from the FE project on how to build paths here!
37
+ url: `/${page.slug}`,
38
+ destination: change.slug,
39
+ httpResponseCode: 301,
40
+ note: "Created with changed URL for a page",
41
+ };
42
+ }
43
+
44
+ const { errors } = await ctx.client.changePageURL.update(
45
+ parent_id,
46
+ change.slug,
47
+ ctx.locale,
48
+ redirectParams
49
+ );
50
+
51
+ if (errors) {
52
+ return {
53
+ assigns: {
54
+ change: { ...change, id: page.id },
55
+ errors: { change: ctx.client.pages.formatErrors(errors, "redirect") },
56
+ _translations: [],
57
+ },
58
+ };
59
+ }
60
+
61
+ return {
62
+ redirect: `/${ctx.locale}/pages/${parent_id}`,
63
+ };
64
+ };
65
+
66
+ export default {
67
+ create_form,
68
+ create,
69
+ };
@@ -0,0 +1,157 @@
1
+ import PageURLsHandler from "../PageURLsHandler";
2
+ import Pages from "../../cloud/Pages";
3
+ import ChangePageURL from "../../cloud/ChangePageURL";
4
+ import Factory from "../../../../../apps/admin/test/factory";
5
+ import { testConfig } from "../../../../../apps/admin/test/handlersHelper";
6
+
7
+ function buildCtx(page, updateSettings) {
8
+ return {
9
+ client: {
10
+ pages: new Pages(testConfig, "token"),
11
+ changePageURL: new ChangePageURL(testConfig, "token"),
12
+ },
13
+ params: { parent_id: page.id },
14
+ resourceParams: {
15
+ change: updateSettings,
16
+ },
17
+ locale: "en",
18
+ };
19
+ }
20
+
21
+ describe("Page change url", () => {
22
+ test("create successful", async () => {
23
+ const page = Factory.build("page");
24
+ const updateSettings = {
25
+ slug: "new-slug",
26
+ redirect: "1",
27
+ };
28
+ const ctx = buildCtx(page, updateSettings);
29
+
30
+ const mockFind = jest
31
+ .spyOn(ctx.client.pages, "find")
32
+ .mockImplementation(() => page);
33
+
34
+ const mockChange = jest
35
+ .spyOn(ctx.client.changePageURL, "update")
36
+ .mockImplementation(() => ({ page, errors: null }));
37
+
38
+ const result = await PageURLsHandler.create(ctx);
39
+
40
+ expect(mockFind).toHaveBeenCalledWith(page.id, "en");
41
+ expect(mockChange).toHaveBeenCalledWith(
42
+ page.id,
43
+ updateSettings.slug,
44
+ "en",
45
+ {
46
+ url: `/${page.slug}`,
47
+ destination: updateSettings.slug,
48
+ httpResponseCode: 301,
49
+ note: "Created with changed URL for a page",
50
+ }
51
+ );
52
+
53
+ expect(result).toEqual({
54
+ redirect: `/en/pages/${page.id}`,
55
+ });
56
+ });
57
+
58
+ test("create failed due to slug error", async () => {
59
+ const page = Factory.build("page");
60
+ const updateSettings = {
61
+ slug: "new-slug",
62
+ };
63
+ const ctx = buildCtx(page, updateSettings);
64
+
65
+ const mockFind = jest
66
+ .spyOn(ctx.client.pages, "find")
67
+ .mockImplementation(() => page);
68
+
69
+ const mockChange = jest
70
+ .spyOn(ctx.client.changePageURL, "update")
71
+ .mockImplementation(() => ({
72
+ page: null,
73
+ errors: [{ codes: [], key: "slug", message: "has already been taken" }],
74
+ }));
75
+
76
+ const result = await PageURLsHandler.create(ctx);
77
+
78
+ expect(mockFind).toHaveBeenCalledWith(page.id, "en");
79
+ expect(mockChange).toHaveBeenCalledWith(
80
+ page.id,
81
+ updateSettings.slug,
82
+ "en",
83
+ null
84
+ );
85
+
86
+ expect(result).toEqual({
87
+ assigns: {
88
+ change: { ...updateSettings, id: page.id },
89
+ errors: { change: { slug: "has already been taken" } },
90
+ _translations: [],
91
+ },
92
+ });
93
+ });
94
+
95
+ test("create failed due to redirect create", async () => {
96
+ const page = Factory.build("page");
97
+ const updateSettings = {
98
+ slug: "new-slug",
99
+ redirect: "1",
100
+ };
101
+ const ctx = buildCtx(page, updateSettings);
102
+
103
+ const mockFind = jest
104
+ .spyOn(ctx.client.pages, "find")
105
+ .mockImplementation(() => page);
106
+
107
+ const mockChange = jest
108
+ .spyOn(ctx.client.changePageURL, "update")
109
+ .mockImplementation(() => ({
110
+ page: null,
111
+ errors: [
112
+ {
113
+ codes: [],
114
+ key: "generalError",
115
+ message: "url: has already been taken",
116
+ },
117
+ ],
118
+ }));
119
+
120
+ const result = await PageURLsHandler.create(ctx);
121
+
122
+ expect(mockFind).toHaveBeenCalledWith(page.id, "en");
123
+ expect(mockChange).toHaveBeenCalledWith(
124
+ page.id,
125
+ updateSettings.slug,
126
+ "en",
127
+ {
128
+ url: `/${page.slug}`,
129
+ destination: updateSettings.slug,
130
+ httpResponseCode: 301,
131
+ note: "Created with changed URL for a page",
132
+ }
133
+ );
134
+
135
+ expect(result).toEqual({
136
+ assigns: {
137
+ change: { ...updateSettings, id: page.id },
138
+ errors: { change: { redirect: "url: has already been taken" } },
139
+ _translations: [],
140
+ },
141
+ });
142
+ });
143
+
144
+ test("create for non existing page", async () => {
145
+ const ctx = buildCtx({ id: "42" }, {});
146
+
147
+ const mockFind = jest
148
+ .spyOn(ctx.client.pages, "find")
149
+ .mockImplementation(() => null);
150
+
151
+ expect(async () => {
152
+ await PageURLsHandler.create(ctx);
153
+ }).rejects.toThrow("Cannot find page with id 42");
154
+
155
+ expect(mockFind).toHaveBeenCalledWith("42", "en");
156
+ });
157
+ });
@@ -0,0 +1,51 @@
1
+ import PageURLsHandler from "../PageURLsHandler";
2
+ import Pages from "../../cloud/Pages";
3
+ import Factory from "../../../test/factory";
4
+ import { testConfig } from "../../../test/handlersHelper";
5
+
6
+ function buildCtx(page) {
7
+ return {
8
+ client: {
9
+ pages: new Pages(testConfig, "token"),
10
+ },
11
+ params: { parent_id: page.id },
12
+ locale: "en",
13
+ };
14
+ }
15
+
16
+ describe("Page change url", () => {
17
+ test("create_form for existing page", async () => {
18
+ const page = Factory.build("page");
19
+ const ctx = buildCtx(page);
20
+
21
+ const mockFind = jest
22
+ .spyOn(ctx.client.pages, "find")
23
+ .mockImplementation(() => page);
24
+
25
+ const result = await PageURLsHandler.create_form(ctx);
26
+
27
+ expect(mockFind).toHaveBeenCalledWith(page.id, "en");
28
+
29
+ expect(result).toEqual({
30
+ assigns: {
31
+ change: { slug: page.slug, id: page.id, redirect: null },
32
+ errors: {},
33
+ _translations: [],
34
+ },
35
+ });
36
+ });
37
+
38
+ test("create_form for non existing page", async () => {
39
+ const ctx = buildCtx({ id: "42" });
40
+
41
+ const mockFind = jest
42
+ .spyOn(ctx.client.pages, "find")
43
+ .mockImplementation(() => null);
44
+
45
+ expect(async () => {
46
+ await PageURLsHandler.create_form(ctx);
47
+ }).rejects.toThrow("Cannot find page with id 42");
48
+
49
+ expect(mockFind).toHaveBeenCalledWith("42", "en");
50
+ });
51
+ });
@@ -0,0 +1,114 @@
1
+ const index = async (ctx) => {
2
+ const items = await ctx.client.pages.list(ctx.query, ctx.locale);
3
+ const tags = await ctx.client.tags.all(ctx.locale);
4
+
5
+ return {
6
+ assigns: {
7
+ tags: tags.list,
8
+ items,
9
+ visibilityOptions: ctx.client.pages.visibilityOptions(),
10
+ },
11
+ };
12
+ };
13
+
14
+ const show = async (ctx) => {
15
+ const { id } = ctx.params;
16
+ const page = await ctx.client.pages.find(id, ctx.locale);
17
+
18
+ if (!page) {
19
+ throw new Error(`Missing page #${id}`);
20
+ }
21
+
22
+ const revisions = await ctx.client.pageRevisions.all(id, ctx.locale);
23
+ const changes = await ctx.client.pageChanges.all(id, ctx.locale);
24
+
25
+ return {
26
+ assigns: {
27
+ page,
28
+ revisions: revisions.list,
29
+ changes: changes.list,
30
+ _translations: Object.keys(ctx.locales)
31
+ .map((locale) => {
32
+ const translation = page.translations[locale];
33
+
34
+ if (translation) {
35
+ return {
36
+ locale,
37
+ path: `/${locale}/pages/${translation.id}`,
38
+ };
39
+ }
40
+
41
+ return null;
42
+ })
43
+ .filter(Boolean),
44
+ },
45
+ };
46
+ };
47
+
48
+ const create_form = async (ctx) => {
49
+ const tags = await ctx.client.tags.all(ctx.locale);
50
+
51
+ return {
52
+ assigns: {
53
+ page: { ...ctx.client.pages.defaults(), meta_image: {} },
54
+ tags: tags.list,
55
+ errors: {},
56
+ visibilityOptions: ctx.client.pages.visibilityOptions(),
57
+ _translations: [],
58
+ },
59
+ };
60
+ };
61
+
62
+ const create = async (ctx) => {
63
+ const params = ctx.resourceParams.page;
64
+
65
+ const { errors } = await ctx.client.pages.create(
66
+ {
67
+ title: params.title,
68
+ slug: params.slug,
69
+ visibility: params.visibility,
70
+ settings: {
71
+ layout: params.layout,
72
+ meta: {
73
+ title: params.meta_title,
74
+ description: params.meta_description,
75
+ image: JSON.parse(params.meta_image || "{}"),
76
+ },
77
+ credentials: {
78
+ user: params.username || "",
79
+ password: params.password || "",
80
+ },
81
+ },
82
+ widgets: [],
83
+ tags: params.tags || [],
84
+ categories: params.categories || [],
85
+ },
86
+ ctx.locale,
87
+ "page"
88
+ );
89
+
90
+ if (errors) {
91
+ const tags = await ctx.client.tags.all(ctx.locale);
92
+
93
+ return {
94
+ assigns: {
95
+ page: params,
96
+ tags: tags.list,
97
+ errors: { page: ctx.client.pages.formatErrors(errors) },
98
+ visibilityOptions: ctx.client.pages.visibilityOptions(),
99
+ _translations: [],
100
+ },
101
+ };
102
+ }
103
+
104
+ return {
105
+ redirect: `/${ctx.locale}/pages`,
106
+ };
107
+ };
108
+
109
+ export default {
110
+ index,
111
+ show,
112
+ create_form,
113
+ create,
114
+ };