@raketa-cloud/admin 1.8.7 → 1.8.9

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 (120) hide show
  1. package/dist/application.css +0 -4
  2. package/package.json +1 -1
  3. package/src/HonoAdapter.js +34 -33
  4. package/src/index.js +0 -3
  5. package/src/routeCategoriesModule.js +1 -1
  6. package/src/routeCollection.js +15 -8
  7. package/src/routeNestedCollection.js +1 -1
  8. package/src/routeNestedMember.js +1 -1
  9. package/src/routeResource.js +19 -21
  10. package/src/routeStandard.js +6 -6
  11. package/src/tests/HonoAdapter.coverage.test.js +15 -25
  12. package/src/tests/routeCategoriesModule.test.js +2 -2
  13. package/src/tests/routeResource.test.js +12 -37
  14. package/src/tests/routeStandard.test.js +13 -13
  15. package/src/views/_shared/_date_fields_input.ejs +13 -0
  16. package/src/views/{page_revisions → resource_revisions}/general/_form.ejs +1 -0
  17. package/src/views/{pages → resources}/_form.ejs +1 -0
  18. package/src/views/{pages → resources}/history/index.ejs +1 -1
  19. package/src/views/{articles → resources}/index.ejs +6 -0
  20. package/src/views/{pages → resources}/show.ejs +7 -7
  21. package/src/views/{articles → resources}/translations/create_form.ejs +2 -2
  22. package/src/routeArticlesModule.js +0 -15
  23. package/src/routeEventsModule.js +0 -15
  24. package/src/routePagesModule.js +0 -15
  25. package/src/tests/routeArticlesModule.test.js +0 -43
  26. package/src/tests/routeEventsModule.test.js +0 -43
  27. package/src/tests/routePagesModule.test.js +0 -43
  28. package/src/views/article_revisions/_nav.ejs +0 -53
  29. package/src/views/article_revisions/general/_form.ejs +0 -18
  30. package/src/views/article_revisions/tags/edit_form.ejs +0 -16
  31. package/src/views/articles/_form.ejs +0 -45
  32. package/src/views/articles/_shared/history_table.ejs +0 -74
  33. package/src/views/articles/deletes/create_form.ejs +0 -68
  34. package/src/views/articles/history/index.ejs +0 -80
  35. package/src/views/articles/show.ejs +0 -222
  36. package/src/views/articles/urls/create_form.ejs +0 -36
  37. package/src/views/event_revisions/codes/_form.ejs +0 -14
  38. package/src/views/event_revisions/codes/edit_form.ejs +0 -16
  39. package/src/views/event_revisions/general/_form.ejs +0 -20
  40. package/src/views/event_revisions/general/edit_form.ejs +0 -16
  41. package/src/views/event_revisions/locks/_form.ejs +0 -11
  42. package/src/views/event_revisions/locks/create_form.ejs +0 -27
  43. package/src/views/event_revisions/meta/_form.ejs +0 -16
  44. package/src/views/event_revisions/meta/edit_form.ejs +0 -16
  45. package/src/views/event_revisions/publishes/_form.ejs +0 -77
  46. package/src/views/event_revisions/publishes/create_form.ejs +0 -9
  47. package/src/views/event_revisions/tags/_form.ejs +0 -13
  48. package/src/views/event_revisions/tags/edit_form.ejs +0 -16
  49. package/src/views/event_revisions/visuals/_form.ejs +0 -13
  50. package/src/views/event_revisions/visuals/edit_form.ejs +0 -16
  51. package/src/views/events/_form.ejs +0 -47
  52. package/src/views/events/_shared/_addons.ejs +0 -0
  53. package/src/views/events/_shared/_export_button.ejs +0 -9
  54. package/src/views/events/_shared/_history_toolbar.ejs +0 -24
  55. package/src/views/events/_shared/_revision_operator.ejs +0 -8
  56. package/src/views/events/_shared/_revision_toolbar.ejs +0 -68
  57. package/src/views/events/_shared/_title.ejs +0 -14
  58. package/src/views/events/_shared/_toolbar.ejs +0 -45
  59. package/src/views/events/_shared/history_table.ejs +0 -74
  60. package/src/views/events/create_form.ejs +0 -9
  61. package/src/views/events/deletes/create_form.ejs +0 -68
  62. package/src/views/events/history/index.ejs +0 -80
  63. package/src/views/events/index.ejs +0 -190
  64. package/src/views/events/show.ejs +0 -222
  65. package/src/views/events/translations/_translation_toolbar.ejs +0 -18
  66. package/src/views/events/translations/create_form.ejs +0 -75
  67. package/src/views/events/translations/index.ejs +0 -39
  68. package/src/views/events/urls/create_form.ejs +0 -36
  69. package/src/views/page_revisions/_nav.ejs +0 -53
  70. package/src/views/page_revisions/codes/_form.ejs +0 -14
  71. package/src/views/page_revisions/codes/edit_form.ejs +0 -16
  72. package/src/views/page_revisions/general/edit_form.ejs +0 -16
  73. package/src/views/page_revisions/locks/_form.ejs +0 -11
  74. package/src/views/page_revisions/locks/create_form.ejs +0 -27
  75. package/src/views/page_revisions/meta/_form.ejs +0 -16
  76. package/src/views/page_revisions/meta/edit_form.ejs +0 -16
  77. package/src/views/page_revisions/publishes/_form.ejs +0 -76
  78. package/src/views/page_revisions/publishes/create_form.ejs +0 -9
  79. package/src/views/page_revisions/tags/_form.ejs +0 -13
  80. package/src/views/page_revisions/visuals/_form.ejs +0 -13
  81. package/src/views/page_revisions/visuals/edit_form.ejs +0 -16
  82. package/src/views/pages/_shared/_addons.ejs +0 -0
  83. package/src/views/pages/_shared/_export_button.ejs +0 -9
  84. package/src/views/pages/_shared/_history_toolbar.ejs +0 -24
  85. package/src/views/pages/_shared/_revision_operator.ejs +0 -8
  86. package/src/views/pages/_shared/_revision_toolbar.ejs +0 -68
  87. package/src/views/pages/_shared/_title.ejs +0 -14
  88. package/src/views/pages/_shared/_toolbar.ejs +0 -45
  89. package/src/views/pages/create_form.ejs +0 -9
  90. package/src/views/pages/index.ejs +0 -185
  91. package/src/views/pages/translations/_translation_toolbar.ejs +0 -18
  92. package/src/views/pages/translations/create_form.ejs +0 -75
  93. package/src/views/pages/translations/index.ejs +0 -39
  94. /package/src/views/{event_revisions → resource_revisions}/_nav.ejs +0 -0
  95. /package/src/views/{article_revisions → resource_revisions}/codes/_form.ejs +0 -0
  96. /package/src/views/{article_revisions → resource_revisions}/codes/edit_form.ejs +0 -0
  97. /package/src/views/{article_revisions → resource_revisions}/general/edit_form.ejs +0 -0
  98. /package/src/views/{article_revisions → resource_revisions}/locks/_form.ejs +0 -0
  99. /package/src/views/{article_revisions → resource_revisions}/locks/create_form.ejs +0 -0
  100. /package/src/views/{article_revisions → resource_revisions}/meta/_form.ejs +0 -0
  101. /package/src/views/{article_revisions → resource_revisions}/meta/edit_form.ejs +0 -0
  102. /package/src/views/{article_revisions → resource_revisions}/publishes/_form.ejs +0 -0
  103. /package/src/views/{article_revisions → resource_revisions}/publishes/create_form.ejs +0 -0
  104. /package/src/views/{article_revisions → resource_revisions}/tags/_form.ejs +0 -0
  105. /package/src/views/{page_revisions → resource_revisions}/tags/edit_form.ejs +0 -0
  106. /package/src/views/{article_revisions → resource_revisions}/visuals/_form.ejs +0 -0
  107. /package/src/views/{article_revisions → resource_revisions}/visuals/edit_form.ejs +0 -0
  108. /package/src/views/{articles → resources}/_shared/_addons.ejs +0 -0
  109. /package/src/views/{articles → resources}/_shared/_export_button.ejs +0 -0
  110. /package/src/views/{articles → resources}/_shared/_history_toolbar.ejs +0 -0
  111. /package/src/views/{articles → resources}/_shared/_revision_operator.ejs +0 -0
  112. /package/src/views/{articles → resources}/_shared/_revision_toolbar.ejs +0 -0
  113. /package/src/views/{articles → resources}/_shared/_title.ejs +0 -0
  114. /package/src/views/{articles → resources}/_shared/_toolbar.ejs +0 -0
  115. /package/src/views/{pages → resources}/_shared/history_table.ejs +0 -0
  116. /package/src/views/{articles → resources}/create_form.ejs +0 -0
  117. /package/src/views/{pages → resources}/deletes/create_form.ejs +0 -0
  118. /package/src/views/{articles → resources}/translations/_translation_toolbar.ejs +0 -0
  119. /package/src/views/{articles → resources}/translations/index.ejs +0 -0
  120. /package/src/views/{pages → resources}/urls/create_form.ejs +0 -0
@@ -13,8 +13,6 @@ describe("routeResource", () => {
13
13
  const adapter = makeAdapter();
14
14
 
15
15
  routeResource(adapter, "article", "articles", {
16
- viewsType: "article",
17
- viewsTypePlural: "articles",
18
16
  dateFields: ["publish_at"],
19
17
  });
20
18
 
@@ -25,7 +23,7 @@ describe("routeResource", () => {
25
23
  "GET",
26
24
  "/articles/exports",
27
25
  "exports",
28
- "articles/exports",
26
+ "resources/exports",
29
27
  "index",
30
28
  expect.any(Function),
31
29
  ],
@@ -41,8 +39,6 @@ describe("routeResource", () => {
41
39
  const adapter = makeAdapter();
42
40
 
43
41
  routeResource(adapter, "event", "events", {
44
- viewsType: "event",
45
- viewsTypePlural: "events",
46
42
  dateFields: ["publish_at", "starts_at", "ends_at"],
47
43
  });
48
44
 
@@ -64,10 +60,7 @@ describe("routeResource", () => {
64
60
  test("registers ResourcesHandler collection at base resource", () => {
65
61
  const adapter = makeAdapter();
66
62
 
67
- routeResource(adapter, "page", "pages", {
68
- viewsType: "page",
69
- viewsTypePlural: "pages",
70
- });
63
+ routeResource(adapter, "page", "pages");
71
64
 
72
65
  const baseCollection = adapter.routeCollection.mock.calls.find(
73
66
  ([mapping]) => mapping.some(([, path]) => path === "/pages")
@@ -75,17 +68,14 @@ describe("routeResource", () => {
75
68
 
76
69
  expect(baseCollection).toBeDefined();
77
70
  expect(baseCollection[1]).toMatchObject({
78
- viewsFallback: "pages",
71
+ views: "resources",
79
72
  });
80
73
  });
81
74
 
82
75
  test("registers api collection for resources", () => {
83
76
  const adapter = makeAdapter();
84
77
 
85
- routeResource(adapter, "page", "pages", {
86
- viewsType: "page",
87
- viewsTypePlural: "pages",
88
- });
78
+ routeResource(adapter, "page", "pages");
89
79
 
90
80
  const apiCollection = adapter.routeCollection.mock.calls.find(
91
81
  ([mapping]) => mapping.some(([, path]) => path === "/api/pages")
@@ -97,10 +87,7 @@ describe("routeResource", () => {
97
87
  test("registers nested collections for revisions, translations, history, locks, unlocks, clones, urls, deletes, publishes, cancel_schedules, reverts", () => {
98
88
  const adapter = makeAdapter();
99
89
 
100
- routeResource(adapter, "article", "articles", {
101
- viewsType: "article",
102
- viewsTypePlural: "articles",
103
- });
90
+ routeResource(adapter, "article", "articles");
104
91
 
105
92
  const nestedPaths = adapter.routeNestedCollection.mock.calls.flatMap(
106
93
  ([mapping]) => mapping.map(([, path]) => path)
@@ -126,10 +113,7 @@ describe("routeResource", () => {
126
113
  test("registers nested members for general, visuals, codes, meta, tags", () => {
127
114
  const adapter = makeAdapter();
128
115
 
129
- routeResource(adapter, "article", "articles", {
130
- viewsType: "article",
131
- viewsTypePlural: "articles",
132
- });
116
+ routeResource(adapter, "article", "articles");
133
117
 
134
118
  const nestedMemberPaths = adapter.routeNestedMember.mock.calls.flatMap(
135
119
  ([mapping]) => mapping.map(([, path]) => path)
@@ -149,10 +133,7 @@ describe("routeResource", () => {
149
133
  test("registers api widgets and change endpoints", () => {
150
134
  const adapter = makeAdapter();
151
135
 
152
- routeResource(adapter, "page", "pages", {
153
- viewsType: "page",
154
- viewsTypePlural: "pages",
155
- });
136
+ routeResource(adapter, "page", "pages");
156
137
 
157
138
  const nestedMemberPaths = adapter.routeNestedMember.mock.calls.flatMap(
158
139
  ([mapping]) => mapping.map(([, path]) => path)
@@ -169,34 +150,28 @@ describe("routeResource", () => {
169
150
  test("uses default empty dateFields when not provided", () => {
170
151
  const adapter = makeAdapter();
171
152
 
172
- routeResource(adapter, "page", "pages", {
173
- viewsType: "page",
174
- viewsTypePlural: "pages",
175
- });
153
+ routeResource(adapter, "page", "pages");
176
154
 
177
155
  const firstCall = adapter.routeCollection.mock.calls[0];
178
156
  expect(firstCall[1].dateFields).toEqual([]);
179
157
  });
180
158
 
181
- test("propagates viewsFallback with viewsTypePlural for collection helpers", () => {
159
+ test("propagates shared resources views for migrated collection helpers", () => {
182
160
  const adapter = makeAdapter();
183
161
 
184
- routeResource(adapter, "event", "events", {
185
- viewsType: "event",
186
- viewsTypePlural: "events",
187
- });
162
+ routeResource(adapter, "event", "events");
188
163
 
189
164
  const baseCollection = adapter.routeCollection.mock.calls.find(
190
165
  ([mapping]) => mapping.some(([, path]) => path === "/events")
191
166
  );
192
167
 
193
- expect(baseCollection[1].viewsFallback).toBe("events");
168
+ expect(baseCollection[1].views).toBe("resources");
194
169
 
195
170
  const translationsCall = adapter.routeNestedCollection.mock.calls.find(
196
171
  ([mapping]) =>
197
172
  mapping.some(([, path]) => path === "/events/:parent_id/translations")
198
173
  );
199
174
 
200
- expect(translationsCall[1].viewsFallback).toBe("events/translations");
175
+ expect(translationsCall[1].views).toBe("resources/translations");
201
176
  });
202
177
  });
@@ -1,9 +1,7 @@
1
1
  import routeStandard from "../routeStandard";
2
2
  import routeCollection from "../routeCollection";
3
3
  import routeSettings from "../routeSettings";
4
- import routePagesModule from "../routePagesModule";
5
- import routeArticlesModule from "../routeArticlesModule";
6
- import routeEventsModule from "../routeEventsModule";
4
+ import routeResource from "../routeResource";
7
5
 
8
6
  import DashboardsHandler from "../handlers/DashboardsHandler";
9
7
  import RedirectsHandler from "../handlers/RedirectsHandler";
@@ -12,17 +10,13 @@ import TagsAPIHandler from "../handlers/TagsAPIHandler";
12
10
 
13
11
  jest.mock("../routeCollection", () => jest.fn());
14
12
  jest.mock("../routeSettings", () => jest.fn());
15
- jest.mock("../routePagesModule", () => jest.fn());
16
- jest.mock("../routeArticlesModule", () => jest.fn());
17
- jest.mock("../routeEventsModule", () => jest.fn());
13
+ jest.mock("../routeResource", () => jest.fn());
18
14
 
19
15
  describe("routeStandard", () => {
20
16
  beforeEach(() => {
21
17
  routeCollection.mockClear();
22
18
  routeSettings.mockClear();
23
- routePagesModule.mockClear();
24
- routeArticlesModule.mockClear();
25
- routeEventsModule.mockClear();
19
+ routeResource.mockClear();
26
20
  });
27
21
 
28
22
  test("registers dashboard mapping via adapter.routeCollection", () => {
@@ -57,14 +51,20 @@ describe("routeStandard", () => {
57
51
  expect(routeCollection).toHaveBeenCalledWith(adapter, "api/tags", TagsAPIHandler);
58
52
  });
59
53
 
60
- test("delegates to module-specific route registrars", () => {
54
+ test("delegates to routeSettings and registers page/article/event resources", () => {
61
55
  const adapter = { routeCollection: jest.fn() };
62
56
 
63
57
  routeStandard(adapter);
64
58
 
65
59
  expect(routeSettings).toHaveBeenCalledWith(adapter);
66
- expect(routePagesModule).toHaveBeenCalledWith(adapter);
67
- expect(routeArticlesModule).toHaveBeenCalledWith(adapter);
68
- expect(routeEventsModule).toHaveBeenCalledWith(adapter);
60
+ expect(routeResource).toHaveBeenCalledWith(adapter, "page", "pages", {
61
+ dateFields: [],
62
+ });
63
+ expect(routeResource).toHaveBeenCalledWith(adapter, "article", "articles", {
64
+ dateFields: ["publish_at"],
65
+ });
66
+ expect(routeResource).toHaveBeenCalledWith(adapter, "event", "events", {
67
+ dateFields: ["publish_at", "starts_at", "ends_at"],
68
+ });
69
69
  });
70
70
  });
@@ -0,0 +1,13 @@
1
+ <%
2
+ const dateFieldMeta = {
3
+ publish_at: { type: "date", label: `${Inflector.capitalize(_context.resourceConfig.resourceType)} post date` },
4
+ starts_at: { type: "datetime-local", label: "Starts at (UTC)" },
5
+ ends_at: { type: "datetime-local", label: "Ends at (UTC)" },
6
+ };
7
+ %>
8
+ <% (_context.resourceConfig.dateFields || []).forEach((name) => { %>
9
+ <% const meta = dateFieldMeta[name]; %>
10
+ <% if (meta) { %>
11
+ <%- f.field(`resource.settings.${name}`, { required: true, type: meta.type, label: meta.label }) %>
12
+ <% } %>
13
+ <% }) %>
@@ -2,6 +2,7 @@
2
2
  <form action="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/general` %>" method="POST" class="form">
3
3
  <%- f.field('resource.title', { required: true }) %>
4
4
  <%- f.field('resource.slug', { label: "URL", required: true, hint: "Only lowercase letters, numbers, slash and dash allowed. E.g: celebrate/friday-13" }) %>
5
+ <%- include('../../_shared/_date_fields_input.ejs', { f }) %>
5
6
  <%- f.field('resource.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
6
7
 
7
8
  <%- include('../../_shared/_credentials_input.ejs', { f, visibilityFieldId: "f_resource_visibility"}) %>
@@ -4,6 +4,7 @@
4
4
 
5
5
  <%- f.field('resource.title', { required: true }) %>
6
6
  <%- f.field('resource.slug', { label: "URL", required: true, hint: "Only lowercase letters, numbers, slash and dash allowed. Ex: celebrate/friday-13" }) %>
7
+ <%- include('../_shared/_date_fields_input.ejs', { f }) %>
7
8
  <%- f.field('resource.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
8
9
 
9
10
  <%- include('../_shared/_credentials_input.ejs', { f, visibilityFieldId: "f_resource_visibility"}) %>
@@ -1,7 +1,7 @@
1
1
  <div class="page-wrapper">
2
2
  <div class="page-title">
3
3
  <div>
4
- <h1 class="heading-1">Pages / History of changes</h1>
4
+ <h1 class="heading-1"><%= Inflector.humanize(Inflector.capitalize(_context.resourceConfig.resourceTypePlural)) %> / History of changes</h1>
5
5
  <span class="body-2 opacity-50"><%= %></span>
6
6
  </div>
7
7
 
@@ -15,12 +15,16 @@
15
15
  </div>
16
16
  </div>
17
17
 
18
+ <% const hasPublishAt = _context.resourceConfig.dateFields?.includes('publish_at'); %>
19
+
18
20
  <table class="data-grid">
19
21
  <thead>
20
22
  <tr>
21
23
  <th><%- sort_button("Title", "title", _context) %></th>
22
24
  <th>Visibility</th>
25
+ <% if (hasPublishAt) { %>
23
26
  <th><%- sort_button(`${Inflector.capitalize(_context.resourceConfig.resourceType)} post date`, "publish_at", _context) %></th>
27
+ <% } %>
24
28
  <th><%- sort_button("Last change", "updated_at", _context) %></th>
25
29
  <th>Translations</th>
26
30
  </tr>
@@ -77,9 +81,11 @@
77
81
  </div>
78
82
  </td>
79
83
 
84
+ <% if (hasPublishAt) { %>
80
85
  <td>
81
86
  <time data-pretty-date datetime="<%= item.settings.publish_at %>"><%= utils.formattedDate(item.settings.publish_at) %></time>
82
87
  </td>
88
+ <% } %>
83
89
 
84
90
  <td>
85
91
  <div class="body-3 text-raketa-foreground/50">
@@ -4,12 +4,12 @@
4
4
  <%- render_partial('./_shared/_toolbar.ejs') %>
5
5
  </div>
6
6
 
7
- <div class="flex flex-wrap items-center gap-1 mb-6 -mt-4">
7
+ <div class="flex flex-wrap items-center gap-1 mb-6 -my-4">
8
8
  <%
9
- const availableLocales = Object.keys(_context.locales);
10
- const totalPossibleTranslations = availableLocales.length - 1;
11
- const existingTranslationsCount = Object.keys(resource.translations).length;
12
- const canBeTranslated = existingTranslationsCount < totalPossibleTranslations;
9
+ const availableLocales = Object.keys(_context.locales);
10
+ const totalPossibleTranslations = availableLocales.length - 1;
11
+ const existingTranslationsCount = Object.keys(resource.translations).length;
12
+ const canBeTranslated = existingTranslationsCount < totalPossibleTranslations;
13
13
  %>
14
14
 
15
15
  <% Object.keys(_context.locales).forEach(key => { %>
@@ -215,8 +215,8 @@
215
215
  toolbarPath: './_shared/_history_toolbar.ejs'
216
216
  }) %>
217
217
 
218
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/history` %>" class="ml-2 btn-text">
218
+ <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}/history` %>" class="my-8 ml-2 btn-text">
219
219
  Full page history
220
220
  </a>
221
221
  </div>
222
- </div>
222
+ </div>
@@ -59,13 +59,13 @@
59
59
  <path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" />
60
60
  </svg>
61
61
 
62
- <h3 class="heading-3">Translating articles</h3>
62
+ <h3 class="heading-3">Translating <%= Inflector.downcase(_context.resourceConfig.resourceTypePlural) %></h3>
63
63
  </div>
64
64
 
65
65
  <div class="markdown">
66
66
  <ol>
67
67
  <li>Select multiple locales to initiate bulk translations.</li>
68
- <li>A private copy of the article will be automatically created for each selected language, with a new revision opened to facilitate the translation process.</li>
68
+ <li>A private copy of the <%= Inflector.downcase(_context.resourceConfig.resourceType) %> will be automatically created for each selected language, with a new revision opened to facilitate the translation process.</li>
69
69
  <li>On the next screen you'll see a list with quick links to transalte settings and widgets</li>
70
70
  </ol>
71
71
  </div>
@@ -1,15 +0,0 @@
1
- import routeResource from "./routeResource";
2
-
3
- function routeArticlesModule(
4
- adapter,
5
- resourceType = "article",
6
- resourceTypePlural = "articles",
7
- ) {
8
- return routeResource(adapter, resourceType, resourceTypePlural, {
9
- viewsType: "article",
10
- viewsTypePlural: "articles",
11
- dateFields: ["publish_at"],
12
- });
13
- }
14
-
15
- export default routeArticlesModule;
@@ -1,15 +0,0 @@
1
- import routeResource from "./routeResource";
2
-
3
- function routeEventsModule(
4
- adapter,
5
- resourceType = "event",
6
- resourceTypePlural = "events",
7
- ) {
8
- return routeResource(adapter, resourceType, resourceTypePlural, {
9
- viewsType: "event",
10
- viewsTypePlural: "events",
11
- dateFields: ["publish_at", "starts_at", "ends_at"],
12
- });
13
- }
14
-
15
- export default routeEventsModule;
@@ -1,15 +0,0 @@
1
- import routeResource from "./routeResource";
2
-
3
- function routePagesModule(
4
- adapter,
5
- resourceType = "page",
6
- resourceTypePlural = "pages",
7
- ) {
8
- return routeResource(adapter, resourceType, resourceTypePlural, {
9
- viewsType: "page",
10
- viewsTypePlural: "pages",
11
- dateFields: [],
12
- });
13
- }
14
-
15
- export default routePagesModule;
@@ -1,43 +0,0 @@
1
- import routeArticlesModule from "../routeArticlesModule";
2
- import routeResource from "../routeResource";
3
-
4
- jest.mock("../routeResource", () => jest.fn());
5
-
6
- describe("routeArticlesModule", () => {
7
- beforeEach(() => {
8
- routeResource.mockClear();
9
- });
10
-
11
- test("delegates to routeResource with default types and publish_at dateField", () => {
12
- const adapter = {};
13
-
14
- routeArticlesModule(adapter);
15
-
16
- expect(routeResource).toHaveBeenCalledWith(adapter, "article", "articles", {
17
- viewsType: "article",
18
- viewsTypePlural: "articles",
19
- dateFields: ["publish_at"],
20
- });
21
- });
22
-
23
- test("delegates to routeResource with custom types", () => {
24
- const adapter = {};
25
-
26
- routeArticlesModule(adapter, "post", "posts");
27
-
28
- expect(routeResource).toHaveBeenCalledWith(adapter, "post", "posts", {
29
- viewsType: "article",
30
- viewsTypePlural: "articles",
31
- dateFields: ["publish_at"],
32
- });
33
- });
34
-
35
- test("returns value of routeResource", () => {
36
- const adapter = {};
37
- routeResource.mockReturnValueOnce("ok");
38
-
39
- const result = routeArticlesModule(adapter);
40
-
41
- expect(result).toBe("ok");
42
- });
43
- });
@@ -1,43 +0,0 @@
1
- import routeEventsModule from "../routeEventsModule";
2
- import routeResource from "../routeResource";
3
-
4
- jest.mock("../routeResource", () => jest.fn());
5
-
6
- describe("routeEventsModule", () => {
7
- beforeEach(() => {
8
- routeResource.mockClear();
9
- });
10
-
11
- test("delegates to routeResource with default types and event dateFields", () => {
12
- const adapter = {};
13
-
14
- routeEventsModule(adapter);
15
-
16
- expect(routeResource).toHaveBeenCalledWith(adapter, "event", "events", {
17
- viewsType: "event",
18
- viewsTypePlural: "events",
19
- dateFields: ["publish_at", "starts_at", "ends_at"],
20
- });
21
- });
22
-
23
- test("delegates to routeResource with custom types", () => {
24
- const adapter = {};
25
-
26
- routeEventsModule(adapter, "meeting", "meetings");
27
-
28
- expect(routeResource).toHaveBeenCalledWith(adapter, "meeting", "meetings", {
29
- viewsType: "event",
30
- viewsTypePlural: "events",
31
- dateFields: ["publish_at", "starts_at", "ends_at"],
32
- });
33
- });
34
-
35
- test("returns value of routeResource", () => {
36
- const adapter = {};
37
- routeResource.mockReturnValueOnce("ok");
38
-
39
- const result = routeEventsModule(adapter);
40
-
41
- expect(result).toBe("ok");
42
- });
43
- });
@@ -1,43 +0,0 @@
1
- import routePagesModule from "../routePagesModule";
2
- import routeResource from "../routeResource";
3
-
4
- jest.mock("../routeResource", () => jest.fn());
5
-
6
- describe("routePagesModule", () => {
7
- beforeEach(() => {
8
- routeResource.mockClear();
9
- });
10
-
11
- test("delegates to routeResource with default types", () => {
12
- const adapter = {};
13
-
14
- routePagesModule(adapter);
15
-
16
- expect(routeResource).toHaveBeenCalledWith(adapter, "page", "pages", {
17
- viewsType: "page",
18
- viewsTypePlural: "pages",
19
- dateFields: [],
20
- });
21
- });
22
-
23
- test("delegates to routeResource with custom types", () => {
24
- const adapter = {};
25
-
26
- routePagesModule(adapter, "landing", "landings");
27
-
28
- expect(routeResource).toHaveBeenCalledWith(adapter, "landing", "landings", {
29
- viewsType: "page",
30
- viewsTypePlural: "pages",
31
- dateFields: [],
32
- });
33
- });
34
-
35
- test("returns value of routeResource", () => {
36
- const adapter = {};
37
- routeResource.mockReturnValueOnce("ok");
38
-
39
- const result = routePagesModule(adapter);
40
-
41
- expect(result).toBe("ok");
42
- });
43
- });
@@ -1,53 +0,0 @@
1
- <% if (_context.query?.success) { %>
2
- <div class="mb-6 text-emerald-600">Settings saved successfully.</div>
3
- <% } %>
4
-
5
- <%
6
- const activeClass = "relative top-0.5 px-4 border-b-2 border-raketa-primary pb-4";
7
- const inactiveClass = "relative top-0.5 px-4 border-b-2 border-transparent pb-4";
8
- %>
9
-
10
- <div class="flex gap-4 w-full pb-4">
11
- <div class="flex items-center justify-between mb-4">
12
- <div class="flex items-center border-b-2">
13
- <div class=" <%= active === 'general' ? activeClass : inactiveClass %>">
14
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/general/edit` %>" class="text-raketa-primary font-semibold">
15
- General
16
- </a>
17
- </div>
18
-
19
- <div class="<%= active === 'visuals' ? activeClass : inactiveClass %>">
20
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/visuals/edit` %>" class="text-raketa-primary font-semibold">
21
- Visuals
22
- </a>
23
- </div>
24
-
25
- <div class="<%= active === 'codes' ? activeClass : inactiveClass %>">
26
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/codes/edit` %>" class="text-raketa-primary font-semibold">
27
- Code customizations
28
- </a>
29
- </div>
30
-
31
- <div class="<%= active === 'meta' ? activeClass : inactiveClass %>">
32
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/meta/edit` %>" class="text-raketa-primary font-semibold">
33
- Open graph & meta tags
34
- </a>
35
- </div>
36
-
37
- <div class="<%= active === 'tags' ? activeClass : inactiveClass %>">
38
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/tags/edit` %>" class="text-raketa-primary font-semibold">
39
- Content tags
40
- </a>
41
- </div>
42
- </div>
43
- </div>
44
-
45
- <div>
46
- <a href="/remote/login?redirect_to=/<%= _context.locale %>/admin/<%= _context.resourceConfig.resourceType %>-revisions/<%= resource.id %>/builder" class="btn-secondary has-icon <%= resource.meta && resource.meta.locked ? 'cursor-not-allowed text-gray-400 pointer-events-none' : '' %>">
47
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
48
- <path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" />
49
- </svg>
50
- Edit content
51
- </a>
52
- </div>
53
- </div>
@@ -1,18 +0,0 @@
1
- <% form_for({ resource }, errors, (f) => { %>
2
- <form action="<%= `/${_context.locale}/${_context.resourceConfig.resourceType}_revisions/${resource.id}/general` %>" method="POST" class="form">
3
- <%- f.field('resource.title', { required: true }) %>
4
- <%- f.field('resource.slug', { label: "URL", required: true, hint: "Only lowercase letters, numbers and dash allowed. E.g: celebrate-friday-13" }) %>
5
- <%- f.field('resource.settings.publish_at', { required: true, type: 'date', label: `${Inflector.capitalize(_context.resourceConfig.resourceType)} post date` }) %>
6
- <%- f.field('resource.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
7
-
8
- <%- include('../../_shared/_credentials_input.ejs', { f, visibilityFieldId: "f_resource_visibility"}) %>
9
-
10
- <div class="form-actions">
11
- <div class="btn-toolbar">
12
- <%- f.submit('Save', { class: 'btn-primary' }) %>
13
- <%- f.submit('Save and publish', { class: 'btn-secondary', name: '_next', value: 'publish' }) %>
14
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.originalId}` %>" class="btn-text">Back</a>
15
- </div>
16
- </div>
17
- </form>
18
- <% }) %>
@@ -1,16 +0,0 @@
1
- <div class="page-wrapper">
2
- <div class="page-title">
3
- <h1 class="heading-1">
4
- <span class="opacity-50">Tags / </span>
5
- <%= resource.title %>
6
- </h1>
7
- </div>
8
-
9
- <%- render_partial('../_nav.ejs', { resource, active: 'tags' }) %>
10
-
11
- <div class="grid gap-4 md:grid-cols-3">
12
- <div>
13
- <%- render_partial('_form.ejs', { tags: tags }) %>
14
- </div>
15
- </div>
16
- </div>
@@ -1,45 +0,0 @@
1
- <% form_for({ resource }, errors, (f) => { %>
2
- <form action="<%= resource?.id ? `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}` : `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}` %>" method="post" class="form">
3
- <h2 class="mb-4 heading-2">General</h2>
4
-
5
- <%- f.field('resource.title', { required: true }) %>
6
- <%- f.field('resource.slug', { label: "URL", required: true, hint: "Only lowercase letters, numbers and dash allowed. Ex: celebrate-friday-13" }) %>
7
- <%- f.field('resource.settings.publish_at', { required: true, type: 'date', label: `${Inflector.capitalize(_context.resourceConfig.resourceType)} post date` }) %>
8
- <%- f.field('resource.visibility', { as: 'select', required: true, options: visibilityOptions }) %>
9
-
10
- <%- include('../_shared/_credentials_input.ejs', { f, visibilityFieldId: "f_resource_visibility"}) %>
11
-
12
- <h2 class="my-4 heading-2">Visuals</h2>
13
-
14
- <%- include('../_shared/_layout_input.ejs', { f }) %>
15
-
16
- <h2 class="my-4 heading-2">OpenGraph & Meta tags</h2>
17
-
18
- <%- f.field('resource.settings.meta.title', { required: true, label: "Meta title", hint: "Used for both meta and OpenGraph" }) %>
19
- <%- f.field('resource.settings.meta.description', { as: "textarea", required: true, label: "Meta description", hint: "Used for both meta and OpenGraph" }) %>
20
-
21
- <raketa-image-picker name="resource[settings][meta][image]" value="<%= JSON.stringify(resource.settings?.meta?.image || {}) %>" label="OpenGraph image"></raketa-image-picker>
22
-
23
- <h2 class="my-4 heading-2">Content tags</h2>
24
-
25
- <%- f.field('resource.tags', { as: 'checkbox_group', options: tags.map(tag => [tag.id, tag.name]) }) %>
26
-
27
- <div class="form-actions">
28
- <div class="btn-toolbar">
29
- <%- f.submit('Save record', { class: 'btn-primary' }) %>
30
-
31
- <a href="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}` %>" class="btn-secondary">Back to list</a>
32
- </div>
33
-
34
- <% if (resource?.id) {%>
35
- <button hx-delete="<%= `/${_context.locale}/${_context.resourceConfig.resourceTypePlural}/${resource.id}` %>" hx-confirm="Are you sure?" class="btn-danger has-icon">
36
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-4">
37
- <path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
38
- </svg>
39
-
40
- Delete record
41
- </button>
42
- <% } %>
43
- </div>
44
- </form>
45
- <% }) %>