@strapi/content-releases 0.0.0-experimental.d362bf200f5f9359a4bbd4a549603de5ee1f04ca → 0.0.0-experimental.d3cdf79a0d5f803dfeb6d0f055bb2f3b913bb015

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 (121) hide show
  1. package/LICENSE +17 -1
  2. package/dist/_chunks/{App-X01LBg5V.mjs → App-CiZCkScI.mjs} +666 -437
  3. package/dist/_chunks/App-CiZCkScI.mjs.map +1 -0
  4. package/dist/_chunks/App-SGjO5UPV.js +1578 -0
  5. package/dist/_chunks/App-SGjO5UPV.js.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases--qQepXpP.js} +9 -8
  7. package/dist/_chunks/PurchaseContentReleases--qQepXpP.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-D-n-w-st.mjs} +10 -9
  9. package/dist/_chunks/PurchaseContentReleases-D-n-w-st.mjs.map +1 -0
  10. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js +178 -0
  11. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js.map +1 -0
  12. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs +178 -0
  13. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs.map +1 -0
  14. package/dist/_chunks/{en-faJDuv3q.js → en-BWPPsSH-.js} +28 -3
  15. package/dist/_chunks/en-BWPPsSH-.js.map +1 -0
  16. package/dist/_chunks/{en-RdapH-9X.mjs → en-D9Q4YW03.mjs} +28 -3
  17. package/dist/_chunks/en-D9Q4YW03.mjs.map +1 -0
  18. package/dist/_chunks/index-BjvFfTtA.mjs +1386 -0
  19. package/dist/_chunks/index-BjvFfTtA.mjs.map +1 -0
  20. package/dist/_chunks/index-CyU534vL.js +1404 -0
  21. package/dist/_chunks/index-CyU534vL.js.map +1 -0
  22. package/dist/_chunks/schemas-DBYv9gK8.js +61 -0
  23. package/dist/_chunks/schemas-DBYv9gK8.js.map +1 -0
  24. package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
  25. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
  26. package/dist/admin/index.js +1 -1
  27. package/dist/admin/index.mjs +2 -2
  28. package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
  29. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  30. package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
  31. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  32. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  33. package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
  34. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  35. package/dist/admin/src/constants.d.ts +18 -0
  36. package/dist/admin/src/modules/hooks.d.ts +7 -0
  37. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  38. package/dist/admin/src/services/release.d.ts +56 -313
  39. package/dist/admin/src/utils/api.d.ts +6 -0
  40. package/dist/admin/src/utils/time.d.ts +9 -0
  41. package/dist/admin/src/validation/schemas.d.ts +6 -0
  42. package/dist/server/index.js +916 -580
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +916 -579
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts +1 -1
  47. package/dist/server/src/bootstrap.d.ts.map +1 -1
  48. package/dist/server/src/constants.d.ts +11 -2
  49. package/dist/server/src/constants.d.ts.map +1 -1
  50. package/dist/server/src/content-types/index.d.ts +3 -5
  51. package/dist/server/src/content-types/index.d.ts.map +1 -1
  52. package/dist/server/src/content-types/release-action/index.d.ts +3 -5
  53. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
  54. package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
  55. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
  56. package/dist/server/src/controllers/index.d.ts +7 -1
  57. package/dist/server/src/controllers/index.d.ts.map +1 -1
  58. package/dist/server/src/controllers/release-action.d.ts.map +1 -1
  59. package/dist/server/src/controllers/release.d.ts +8 -1
  60. package/dist/server/src/controllers/release.d.ts.map +1 -1
  61. package/dist/server/src/controllers/settings.d.ts +11 -0
  62. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  63. package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
  64. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
  65. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  66. package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
  67. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  68. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  69. package/dist/server/src/destroy.d.ts +1 -1
  70. package/dist/server/src/destroy.d.ts.map +1 -1
  71. package/dist/server/src/index.d.ts +72 -56
  72. package/dist/server/src/index.d.ts.map +1 -1
  73. package/dist/server/src/middlewares/documents.d.ts +6 -0
  74. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  75. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  76. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  77. package/dist/server/src/migrations/index.d.ts.map +1 -1
  78. package/dist/server/src/register.d.ts +1 -1
  79. package/dist/server/src/register.d.ts.map +1 -1
  80. package/dist/server/src/routes/index.d.ts +16 -0
  81. package/dist/server/src/routes/index.d.ts.map +1 -1
  82. package/dist/server/src/routes/release.d.ts.map +1 -1
  83. package/dist/server/src/routes/settings.d.ts +18 -0
  84. package/dist/server/src/routes/settings.d.ts.map +1 -0
  85. package/dist/server/src/services/index.d.ts +39 -41
  86. package/dist/server/src/services/index.d.ts.map +1 -1
  87. package/dist/server/src/services/release-action.d.ts +34 -0
  88. package/dist/server/src/services/release-action.d.ts.map +1 -0
  89. package/dist/server/src/services/release.d.ts +7 -42
  90. package/dist/server/src/services/release.d.ts.map +1 -1
  91. package/dist/server/src/services/scheduling.d.ts +1 -1
  92. package/dist/server/src/services/scheduling.d.ts.map +1 -1
  93. package/dist/server/src/services/settings.d.ts +13 -0
  94. package/dist/server/src/services/settings.d.ts.map +1 -0
  95. package/dist/server/src/services/validation.d.ts +2 -2
  96. package/dist/server/src/services/validation.d.ts.map +1 -1
  97. package/dist/server/src/utils/index.d.ts +33 -12
  98. package/dist/server/src/utils/index.d.ts.map +1 -1
  99. package/dist/shared/contracts/release-actions.d.ts +17 -11
  100. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  101. package/dist/shared/contracts/releases.d.ts +24 -6
  102. package/dist/shared/contracts/releases.d.ts.map +1 -1
  103. package/dist/shared/contracts/settings.d.ts +39 -0
  104. package/dist/shared/contracts/settings.d.ts.map +1 -0
  105. package/package.json +24 -22
  106. package/dist/_chunks/App-1LckaIGY.js +0 -1352
  107. package/dist/_chunks/App-1LckaIGY.js.map +0 -1
  108. package/dist/_chunks/App-X01LBg5V.mjs.map +0 -1
  109. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  110. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  111. package/dist/_chunks/en-RdapH-9X.mjs.map +0 -1
  112. package/dist/_chunks/en-faJDuv3q.js.map +0 -1
  113. package/dist/_chunks/index-OD9AlD-6.mjs +0 -1033
  114. package/dist/_chunks/index-OD9AlD-6.mjs.map +0 -1
  115. package/dist/_chunks/index-cYWov2wa.js +0 -1054
  116. package/dist/_chunks/index-cYWov2wa.js.map +0 -1
  117. package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
  118. package/dist/admin/src/services/axios.d.ts +0 -29
  119. package/dist/shared/validation-schemas.d.ts +0 -2
  120. package/dist/shared/validation-schemas.d.ts.map +0 -1
  121. package/strapi-server.js +0 -3
@@ -1,1033 +0,0 @@
1
- import { Cross, Pencil, More, Plus, EmptyDocuments, PaperPlane } from "@strapi/icons";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { skipToken } from "@reduxjs/toolkit/query";
5
- import { getFetchClient, useNotification, useAPIErrorHandler, useRBAC, useAuth, unstable_useDocument, useQueryParams } from "@strapi/admin/strapi-admin";
6
- import { IconButton, Flex, Icon, Typography, Field, FieldLabel, VisuallyHidden, FieldInput, Box, Button, ModalLayout, ModalHeader, ModalBody, SingleSelect, SingleSelectOption, ModalFooter, EmptyStateLayout } from "@strapi/design-system";
7
- import { Menu, Link, LinkButton } from "@strapi/design-system/v2";
8
- import { isAxiosError as isAxiosError$1 } from "axios";
9
- import { Formik, Form } from "formik";
10
- import { useIntl } from "react-intl";
11
- import { NavLink, useParams, Link as Link$1 } from "react-router-dom";
12
- import * as yup from "yup";
13
- import { createApi } from "@reduxjs/toolkit/query/react";
14
- import styled from "styled-components";
15
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
16
- const v = glob[path];
17
- if (v) {
18
- return typeof v === "function" ? v() : Promise.resolve(v);
19
- }
20
- return new Promise((_, reject) => {
21
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
22
- });
23
- };
24
- const PERMISSIONS = {
25
- main: [
26
- {
27
- action: "plugin::content-releases.read",
28
- subject: null,
29
- id: "",
30
- actionParameters: {},
31
- properties: {},
32
- conditions: []
33
- }
34
- ],
35
- create: [
36
- {
37
- action: "plugin::content-releases.create",
38
- subject: null,
39
- id: "",
40
- actionParameters: {},
41
- properties: {},
42
- conditions: []
43
- }
44
- ],
45
- update: [
46
- {
47
- action: "plugin::content-releases.update",
48
- subject: null,
49
- id: "",
50
- actionParameters: {},
51
- properties: {},
52
- conditions: []
53
- }
54
- ],
55
- delete: [
56
- {
57
- action: "plugin::content-releases.delete",
58
- subject: null,
59
- id: "",
60
- actionParameters: {},
61
- properties: {},
62
- conditions: []
63
- }
64
- ],
65
- createAction: [
66
- {
67
- action: "plugin::content-releases.create-action",
68
- subject: null,
69
- id: "",
70
- actionParameters: {},
71
- properties: {},
72
- conditions: []
73
- }
74
- ],
75
- deleteAction: [
76
- {
77
- action: "plugin::content-releases.delete-action",
78
- subject: null,
79
- id: "",
80
- actionParameters: {},
81
- properties: {},
82
- conditions: []
83
- }
84
- ],
85
- publish: [
86
- {
87
- action: "plugin::content-releases.publish",
88
- subject: null,
89
- id: "",
90
- actionParameters: {},
91
- properties: {},
92
- conditions: []
93
- }
94
- ]
95
- };
96
- const pluginId = "content-releases";
97
- const axiosBaseQuery = async ({
98
- url,
99
- method,
100
- data,
101
- config
102
- }) => {
103
- try {
104
- const { get, post, del, put } = getFetchClient();
105
- if (method === "POST") {
106
- const result2 = await post(url, data, config);
107
- return { data: result2.data };
108
- }
109
- if (method === "DELETE") {
110
- const result2 = await del(url, config);
111
- return { data: result2.data };
112
- }
113
- if (method === "PUT") {
114
- const result2 = await put(url, data, config);
115
- return { data: result2.data };
116
- }
117
- const result = await get(url, config);
118
- return { data: result.data };
119
- } catch (error) {
120
- const err = error;
121
- return {
122
- error: {
123
- status: err.response?.status,
124
- code: err.code,
125
- response: {
126
- data: err.response?.data
127
- }
128
- }
129
- };
130
- }
131
- };
132
- const isAxiosError = (err) => {
133
- return typeof err === "object" && err !== null && "response" in err && typeof err.response === "object" && err.response !== null && "data" in err.response;
134
- };
135
- const releaseApi = createApi({
136
- reducerPath: pluginId,
137
- baseQuery: axiosBaseQuery,
138
- tagTypes: ["Release", "ReleaseAction"],
139
- endpoints: (build) => {
140
- return {
141
- getReleasesForEntry: build.query({
142
- query(params) {
143
- return {
144
- url: "/content-releases",
145
- method: "GET",
146
- config: {
147
- params
148
- }
149
- };
150
- },
151
- providesTags: (result) => result ? [
152
- ...result.data.map(({ id }) => ({ type: "Release", id })),
153
- { type: "Release", id: "LIST" }
154
- ] : []
155
- }),
156
- getReleases: build.query({
157
- query({ page, pageSize, filters } = {
158
- page: 1,
159
- pageSize: 16,
160
- filters: {
161
- releasedAt: {
162
- $notNull: false
163
- }
164
- }
165
- }) {
166
- return {
167
- url: "/content-releases",
168
- method: "GET",
169
- config: {
170
- params: {
171
- page: page || 1,
172
- pageSize: pageSize || 16,
173
- filters: filters || {
174
- releasedAt: {
175
- $notNull: false
176
- }
177
- }
178
- }
179
- }
180
- };
181
- },
182
- transformResponse(response, meta, arg) {
183
- const releasedAtValue = arg?.filters?.releasedAt?.$notNull;
184
- const isActiveDoneTab = releasedAtValue === "true";
185
- const newResponse = {
186
- ...response,
187
- meta: {
188
- ...response.meta,
189
- activeTab: isActiveDoneTab ? "done" : "pending"
190
- }
191
- };
192
- return newResponse;
193
- },
194
- providesTags: (result) => result ? [
195
- ...result.data.map(({ id }) => ({ type: "Release", id })),
196
- { type: "Release", id: "LIST" }
197
- ] : [{ type: "Release", id: "LIST" }]
198
- }),
199
- getRelease: build.query({
200
- query({ id }) {
201
- return {
202
- url: `/content-releases/${id}`,
203
- method: "GET"
204
- };
205
- },
206
- providesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
207
- }),
208
- getReleaseActions: build.query({
209
- query({ releaseId, ...params }) {
210
- return {
211
- url: `/content-releases/${releaseId}/actions`,
212
- method: "GET",
213
- config: {
214
- params
215
- }
216
- };
217
- },
218
- providesTags: [{ type: "ReleaseAction", id: "LIST" }]
219
- }),
220
- createRelease: build.mutation({
221
- query(data) {
222
- return {
223
- url: "/content-releases",
224
- method: "POST",
225
- data
226
- };
227
- },
228
- invalidatesTags: [{ type: "Release", id: "LIST" }]
229
- }),
230
- updateRelease: build.mutation({
231
- query({ id, ...data }) {
232
- return {
233
- url: `/content-releases/${id}`,
234
- method: "PUT",
235
- data
236
- };
237
- },
238
- invalidatesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
239
- }),
240
- createReleaseAction: build.mutation({
241
- query({ body, params }) {
242
- return {
243
- url: `/content-releases/${params.releaseId}/actions`,
244
- method: "POST",
245
- data: body
246
- };
247
- },
248
- invalidatesTags: [
249
- { type: "Release", id: "LIST" },
250
- { type: "ReleaseAction", id: "LIST" }
251
- ]
252
- }),
253
- updateReleaseAction: build.mutation({
254
- query({ body, params }) {
255
- return {
256
- url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,
257
- method: "PUT",
258
- data: body
259
- };
260
- },
261
- invalidatesTags: () => [{ type: "ReleaseAction", id: "LIST" }],
262
- async onQueryStarted({ body, params, query, actionPath }, { dispatch, queryFulfilled }) {
263
- const paramsWithoutActionId = {
264
- releaseId: params.releaseId,
265
- ...query
266
- };
267
- const patchResult = dispatch(
268
- releaseApi.util.updateQueryData("getReleaseActions", paramsWithoutActionId, (draft) => {
269
- const [key, index] = actionPath;
270
- const action = draft.data[key][index];
271
- if (action) {
272
- action.type = body.type;
273
- }
274
- })
275
- );
276
- try {
277
- await queryFulfilled;
278
- } catch {
279
- patchResult.undo();
280
- }
281
- }
282
- }),
283
- deleteReleaseAction: build.mutation({
284
- query({ params }) {
285
- return {
286
- url: `/content-releases/${params.releaseId}/actions/${params.actionId}`,
287
- method: "DELETE"
288
- };
289
- },
290
- invalidatesTags: (result, error, arg) => [
291
- { type: "Release", id: "LIST" },
292
- { type: "Release", id: arg.params.releaseId },
293
- { type: "ReleaseAction", id: "LIST" }
294
- ]
295
- }),
296
- publishRelease: build.mutation({
297
- query({ id }) {
298
- return {
299
- url: `/content-releases/${id}/publish`,
300
- method: "POST"
301
- };
302
- },
303
- invalidatesTags: (result, error, arg) => [{ type: "Release", id: arg.id }]
304
- }),
305
- deleteRelease: build.mutation({
306
- query({ id }) {
307
- return {
308
- url: `/content-releases/${id}`,
309
- method: "DELETE"
310
- };
311
- },
312
- invalidatesTags: () => [{ type: "Release", id: "LIST" }]
313
- })
314
- };
315
- }
316
- });
317
- const {
318
- useGetReleasesQuery,
319
- useGetReleasesForEntryQuery,
320
- useGetReleaseQuery,
321
- useGetReleaseActionsQuery,
322
- useCreateReleaseMutation,
323
- useCreateReleaseActionMutation,
324
- useUpdateReleaseMutation,
325
- useUpdateReleaseActionMutation,
326
- usePublishReleaseMutation,
327
- useDeleteReleaseActionMutation,
328
- useDeleteReleaseMutation
329
- } = releaseApi;
330
- const getTimezoneOffset = (timezone, date) => {
331
- try {
332
- const offsetPart = new Intl.DateTimeFormat("en", {
333
- timeZone: timezone,
334
- timeZoneName: "longOffset"
335
- }).formatToParts(date).find((part) => part.type === "timeZoneName");
336
- const offset = offsetPart ? offsetPart.value : "";
337
- let utcOffset = offset.replace("GMT", "UTC");
338
- if (!utcOffset.includes("+") && !utcOffset.includes("-")) {
339
- utcOffset = `${utcOffset}+00:00`;
340
- }
341
- return utcOffset;
342
- } catch (error) {
343
- return "";
344
- }
345
- };
346
- const StyledMenuItem = styled(Menu.Item)`
347
- &:hover {
348
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
349
-
350
- svg {
351
- path {
352
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
353
- }
354
- }
355
-
356
- a {
357
- color: ${({ theme }) => theme.colors.neutral800};
358
- }
359
- }
360
-
361
- svg {
362
- path {
363
- fill: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}600`]};
364
- }
365
- }
366
-
367
- a {
368
- color: ${({ theme }) => theme.colors.neutral800};
369
- }
370
-
371
- span,
372
- a {
373
- width: 100%;
374
- }
375
- `;
376
- const StyledIconButton = styled(IconButton)`
377
- /* Setting this style inline with borderColor will not apply the style */
378
- border: ${({ theme }) => `1px solid ${theme.colors.neutral200}`};
379
- `;
380
- const DeleteReleaseActionItem = ({ releaseId, actionId }) => {
381
- const { formatMessage } = useIntl();
382
- const { toggleNotification } = useNotification();
383
- const { formatAPIError } = useAPIErrorHandler();
384
- const [deleteReleaseAction] = useDeleteReleaseActionMutation();
385
- const {
386
- allowedActions: { canDeleteAction }
387
- } = useRBAC(PERMISSIONS);
388
- const handleDeleteAction = async () => {
389
- const response = await deleteReleaseAction({
390
- params: { releaseId, actionId }
391
- });
392
- if ("data" in response) {
393
- toggleNotification({
394
- type: "success",
395
- message: formatMessage({
396
- id: "content-releases.content-manager-edit-view.remove-from-release.notification.success",
397
- defaultMessage: "Entry removed from release"
398
- })
399
- });
400
- return;
401
- }
402
- if ("error" in response) {
403
- if (isAxiosError$1(response.error)) {
404
- toggleNotification({
405
- type: "danger",
406
- message: formatAPIError(response.error)
407
- });
408
- } else {
409
- toggleNotification({
410
- type: "danger",
411
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
412
- });
413
- }
414
- }
415
- };
416
- if (!canDeleteAction) {
417
- return null;
418
- }
419
- return /* @__PURE__ */ jsx(StyledMenuItem, { variant: "danger", onSelect: handleDeleteAction, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
420
- /* @__PURE__ */ jsx(Icon, { as: Cross, width: 3, height: 3 }),
421
- /* @__PURE__ */ jsx(Typography, { textColor: "danger600", variant: "omega", children: formatMessage({
422
- id: "content-releases.content-manager-edit-view.remove-from-release",
423
- defaultMessage: "Remove from release"
424
- }) })
425
- ] }) });
426
- };
427
- const ReleaseActionEntryLinkItem = ({
428
- contentTypeUid,
429
- entryId,
430
- locale
431
- }) => {
432
- const { formatMessage } = useIntl();
433
- const userPermissions = useAuth("ReleaseActionEntryLinkItem", (state) => state.permissions);
434
- const canUpdateEntryForLocale = React.useMemo(() => {
435
- const updatePermissions = userPermissions.find(
436
- (permission) => permission.subject === contentTypeUid && permission.action === "plugin::content-manager.explorer.update"
437
- );
438
- if (!updatePermissions) {
439
- return false;
440
- }
441
- return Boolean(!locale || updatePermissions.properties?.locales?.includes(locale));
442
- }, [contentTypeUid, locale, userPermissions]);
443
- const {
444
- allowedActions: { canUpdateContentType }
445
- } = useRBAC({
446
- updateContentType: [
447
- {
448
- action: "plugin::content-manager.explorer.update",
449
- subject: contentTypeUid
450
- }
451
- ]
452
- });
453
- if (!canUpdateContentType || !canUpdateEntryForLocale) {
454
- return null;
455
- }
456
- return /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
457
- Link,
458
- {
459
- as: NavLink,
460
- to: {
461
- pathname: `/content-manager/collection-types/${contentTypeUid}/${entryId}`,
462
- search: locale && `?plugins[i18n][locale]=${locale}`
463
- },
464
- startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
465
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
466
- id: "content-releases.content-manager-edit-view.edit-entry",
467
- defaultMessage: "Edit entry"
468
- }) })
469
- }
470
- ) });
471
- };
472
- const EditReleaseItem = ({ releaseId }) => {
473
- const { formatMessage } = useIntl();
474
- return /* @__PURE__ */ jsx(StyledMenuItem, { children: /* @__PURE__ */ jsx(
475
- Link,
476
- {
477
- href: `/admin/plugins/content-releases/${releaseId}`,
478
- startIcon: /* @__PURE__ */ jsx(Icon, { as: Pencil, width: 3, height: 3 }),
479
- isExternal: false,
480
- children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatMessage({
481
- id: "content-releases.content-manager-edit-view.edit-release",
482
- defaultMessage: "Edit release"
483
- }) })
484
- }
485
- ) });
486
- };
487
- const Root = ({ children, hasTriggerBorder = false }) => {
488
- const { formatMessage } = useIntl();
489
- const { allowedActions } = useRBAC(PERMISSIONS);
490
- return (
491
- // A user can access the dropdown if they have permissions to delete a release-action OR update a release
492
- allowedActions.canDeleteAction || allowedActions.canUpdate ? /* @__PURE__ */ jsxs(Menu.Root, { children: [
493
- /* @__PURE__ */ jsx(
494
- Menu.Trigger,
495
- {
496
- as: hasTriggerBorder ? StyledIconButton : IconButton,
497
- paddingLeft: 2,
498
- paddingRight: 2,
499
- "aria-label": formatMessage({
500
- id: "content-releases.content-manager-edit-view.release-action-menu",
501
- defaultMessage: "Release action options"
502
- }),
503
- icon: /* @__PURE__ */ jsx(More, {})
504
- }
505
- ),
506
- /* @__PURE__ */ jsx(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children })
507
- ] }) : null
508
- );
509
- };
510
- const ReleaseActionMenu = {
511
- Root,
512
- EditReleaseItem,
513
- DeleteReleaseActionItem,
514
- ReleaseActionEntryLinkItem
515
- };
516
- const getBorderLeftRadiusValue = (actionType) => {
517
- return actionType === "publish" ? 1 : 0;
518
- };
519
- const getBorderRightRadiusValue = (actionType) => {
520
- return actionType === "publish" ? 0 : 1;
521
- };
522
- const FieldWrapper = styled(Field)`
523
- border-top-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
524
- border-bottom-left-radius: ${({ actionType, theme }) => theme.spaces[getBorderLeftRadiusValue(actionType)]};
525
- border-top-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
526
- border-bottom-right-radius: ${({ actionType, theme }) => theme.spaces[getBorderRightRadiusValue(actionType)]};
527
-
528
- > label {
529
- color: inherit;
530
- padding: ${({ theme }) => `${theme.spaces[2]} ${theme.spaces[3]}`};
531
- text-align: center;
532
- vertical-align: middle;
533
- text-transform: capitalize;
534
- }
535
-
536
- &[data-checked='true'] {
537
- color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
538
- background-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary100 : theme.colors.danger100};
539
- border-color: ${({ theme, actionType }) => actionType === "publish" ? theme.colors.primary700 : theme.colors.danger600};
540
- }
541
-
542
- &[data-checked='false'] {
543
- border-left: ${({ actionType }) => actionType === "unpublish" && "none"};
544
- border-right: ${({ actionType }) => actionType === "publish" && "none"};
545
- }
546
-
547
- &[data-checked='false'][data-disabled='false']:hover {
548
- color: ${({ theme }) => theme.colors.neutral700};
549
- background-color: ${({ theme }) => theme.colors.neutral100};
550
- border-color: ${({ theme }) => theme.colors.neutral200};
551
-
552
- & > label {
553
- cursor: pointer;
554
- }
555
- }
556
-
557
- &[data-disabled='true'] {
558
- color: ${({ theme }) => theme.colors.neutral600};
559
- background-color: ${({ theme }) => theme.colors.neutral150};
560
- border-color: ${({ theme }) => theme.colors.neutral300};
561
- }
562
- `;
563
- const ActionOption = ({
564
- selected,
565
- actionType,
566
- handleChange,
567
- name,
568
- disabled = false
569
- }) => {
570
- return /* @__PURE__ */ jsx(
571
- FieldWrapper,
572
- {
573
- actionType,
574
- background: "primary0",
575
- borderColor: "neutral200",
576
- color: selected === actionType ? "primary600" : "neutral600",
577
- position: "relative",
578
- cursor: "pointer",
579
- "data-checked": selected === actionType,
580
- "data-disabled": disabled && selected !== actionType,
581
- children: /* @__PURE__ */ jsxs(FieldLabel, { htmlFor: `${name}-${actionType}`, children: [
582
- /* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx(
583
- FieldInput,
584
- {
585
- type: "radio",
586
- id: `${name}-${actionType}`,
587
- name,
588
- checked: selected === actionType,
589
- onChange: handleChange,
590
- value: actionType,
591
- disabled
592
- }
593
- ) }),
594
- actionType
595
- ] })
596
- }
597
- );
598
- };
599
- const ReleaseActionOptions = ({
600
- selected,
601
- handleChange,
602
- name,
603
- disabled = false
604
- }) => {
605
- return /* @__PURE__ */ jsxs(Flex, { children: [
606
- /* @__PURE__ */ jsx(
607
- ActionOption,
608
- {
609
- actionType: "publish",
610
- selected,
611
- handleChange,
612
- name,
613
- disabled
614
- }
615
- ),
616
- /* @__PURE__ */ jsx(
617
- ActionOption,
618
- {
619
- actionType: "unpublish",
620
- selected,
621
- handleChange,
622
- name,
623
- disabled
624
- }
625
- )
626
- ] });
627
- };
628
- const RELEASE_ACTION_FORM_SCHEMA = yup.object().shape({
629
- type: yup.string().oneOf(["publish", "unpublish"]).required(),
630
- releaseId: yup.string().required()
631
- });
632
- const INITIAL_VALUES = {
633
- type: "publish",
634
- releaseId: ""
635
- };
636
- const NoReleases = () => {
637
- const { formatMessage } = useIntl();
638
- return /* @__PURE__ */ jsx(
639
- EmptyStateLayout,
640
- {
641
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" }),
642
- content: formatMessage({
643
- id: "content-releases.content-manager-edit-view.add-to-release.no-releases-message",
644
- defaultMessage: "No available releases. Open the list of releases and create a new one from there."
645
- }),
646
- action: /* @__PURE__ */ jsx(
647
- LinkButton,
648
- {
649
- to: {
650
- pathname: "/plugins/content-releases"
651
- },
652
- as: Link$1,
653
- variant: "secondary",
654
- children: formatMessage({
655
- id: "content-releases.content-manager-edit-view.add-to-release.redirect-button",
656
- defaultMessage: "Open the list of releases"
657
- })
658
- }
659
- )
660
- }
661
- );
662
- };
663
- const AddActionToReleaseModal = ({
664
- handleClose,
665
- contentTypeUid,
666
- entryId
667
- }) => {
668
- const releaseHeaderId = React.useId();
669
- const { formatMessage } = useIntl();
670
- const { toggleNotification } = useNotification();
671
- const { formatAPIError } = useAPIErrorHandler();
672
- const [{ query }] = useQueryParams();
673
- const locale = query.plugins?.i18n?.locale;
674
- const response = useGetReleasesForEntryQuery({
675
- contentTypeUid,
676
- entryId,
677
- hasEntryAttached: false
678
- });
679
- const releases = response.data?.data;
680
- const [createReleaseAction, { isLoading }] = useCreateReleaseActionMutation();
681
- const handleSubmit = async (values) => {
682
- const releaseActionEntry = {
683
- contentType: contentTypeUid,
684
- id: entryId,
685
- locale
686
- };
687
- const response2 = await createReleaseAction({
688
- body: { type: values.type, entry: releaseActionEntry },
689
- params: { releaseId: values.releaseId }
690
- });
691
- if ("data" in response2) {
692
- toggleNotification({
693
- type: "success",
694
- message: formatMessage({
695
- id: "content-releases.content-manager-edit-view.add-to-release.notification.success",
696
- defaultMessage: "Entry added to release"
697
- })
698
- });
699
- handleClose();
700
- return;
701
- }
702
- if ("error" in response2) {
703
- if (isAxiosError$1(response2.error)) {
704
- toggleNotification({
705
- type: "danger",
706
- message: formatAPIError(response2.error)
707
- });
708
- } else {
709
- toggleNotification({
710
- type: "danger",
711
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
712
- });
713
- }
714
- }
715
- };
716
- return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: releaseHeaderId, children: [
717
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: releaseHeaderId, fontWeight: "bold", textColor: "neutral800", children: formatMessage({
718
- id: "content-releases.content-manager-edit-view.add-to-release",
719
- defaultMessage: "Add to release"
720
- }) }) }),
721
- /* @__PURE__ */ jsx(
722
- Formik,
723
- {
724
- onSubmit: handleSubmit,
725
- validationSchema: RELEASE_ACTION_FORM_SCHEMA,
726
- initialValues: INITIAL_VALUES,
727
- children: ({ values, setFieldValue }) => {
728
- return /* @__PURE__ */ jsxs(Form, { children: [
729
- releases?.length === 0 ? /* @__PURE__ */ jsx(NoReleases, {}) : /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
730
- /* @__PURE__ */ jsx(Box, { paddingBottom: 6, children: /* @__PURE__ */ jsx(
731
- SingleSelect,
732
- {
733
- required: true,
734
- label: formatMessage({
735
- id: "content-releases.content-manager-edit-view.add-to-release.select-label",
736
- defaultMessage: "Select a release"
737
- }),
738
- placeholder: formatMessage({
739
- id: "content-releases.content-manager-edit-view.add-to-release.select-placeholder",
740
- defaultMessage: "Select"
741
- }),
742
- onChange: (value) => setFieldValue("releaseId", value),
743
- value: values.releaseId,
744
- children: releases?.map((release) => /* @__PURE__ */ jsx(SingleSelectOption, { value: release.id, children: release.name }, release.id))
745
- }
746
- ) }),
747
- /* @__PURE__ */ jsx(FieldLabel, { children: formatMessage({
748
- id: "content-releases.content-manager-edit-view.add-to-release.action-type-label",
749
- defaultMessage: "What do you want to do with this entry?"
750
- }) }),
751
- /* @__PURE__ */ jsx(
752
- ReleaseActionOptions,
753
- {
754
- selected: values.type,
755
- handleChange: (e) => setFieldValue("type", e.target.value),
756
- name: "type"
757
- }
758
- )
759
- ] }) }),
760
- /* @__PURE__ */ jsx(
761
- ModalFooter,
762
- {
763
- startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({
764
- id: "content-releases.content-manager-edit-view.add-to-release.cancel-button",
765
- defaultMessage: "Cancel"
766
- }) }),
767
- endActions: (
768
- /**
769
- * TODO: Ideally we would use isValid from Formik to disable the button, however currently it always returns true
770
- * for yup.string().required(), even when the value is falsy (including empty string)
771
- */
772
- /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !values.releaseId, loading: isLoading, children: formatMessage({
773
- id: "content-releases.content-manager-edit-view.add-to-release.continue-button",
774
- defaultMessage: "Continue"
775
- }) })
776
- )
777
- }
778
- )
779
- ] });
780
- }
781
- }
782
- )
783
- ] });
784
- };
785
- const CMReleasesContainer = () => {
786
- const [isModalOpen, setIsModalOpen] = React.useState(false);
787
- const { formatMessage, formatDate, formatTime } = useIntl();
788
- const { id, slug, collectionType } = useParams();
789
- const isCreatingEntry = id === "create";
790
- const {
791
- allowedActions: { canCreateAction, canMain, canDeleteAction }
792
- } = useRBAC(PERMISSIONS);
793
- const { schema } = unstable_useDocument({
794
- collectionType,
795
- model: slug
796
- });
797
- const hasDraftAndPublish = schema?.options?.draftAndPublish;
798
- const contentTypeUid = slug;
799
- const canFetch = id != null && contentTypeUid != null;
800
- const fetchParams = canFetch ? {
801
- contentTypeUid,
802
- entryId: id,
803
- hasEntryAttached: true
804
- } : skipToken;
805
- const response = useGetReleasesForEntryQuery(fetchParams);
806
- const releases = response.data?.data;
807
- if (!canFetch) {
808
- return null;
809
- }
810
- if (isCreatingEntry || !hasDraftAndPublish) {
811
- return null;
812
- }
813
- const toggleModal = () => setIsModalOpen((prev) => !prev);
814
- const getReleaseColorVariant = (actionType, shade) => {
815
- if (actionType === "unpublish") {
816
- return `secondary${shade}`;
817
- }
818
- return `success${shade}`;
819
- };
820
- if (!canMain) {
821
- return null;
822
- }
823
- return /* @__PURE__ */ jsxs(
824
- Box,
825
- {
826
- as: "aside",
827
- "aria-label": formatMessage({
828
- id: "content-releases.plugin.name",
829
- defaultMessage: "Releases"
830
- }),
831
- background: "neutral0",
832
- borderColor: "neutral150",
833
- hasRadius: true,
834
- padding: 4,
835
- shadow: "tableShadow",
836
- children: [
837
- /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 3, children: [
838
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({
839
- id: "content-releases.plugin.name",
840
- defaultMessage: "Releases"
841
- }) }),
842
- releases?.map((release) => {
843
- return /* @__PURE__ */ jsxs(
844
- Flex,
845
- {
846
- direction: "column",
847
- alignItems: "start",
848
- borderWidth: "1px",
849
- borderStyle: "solid",
850
- borderColor: getReleaseColorVariant(release.action.type, "200"),
851
- overflow: "hidden",
852
- hasRadius: true,
853
- children: [
854
- /* @__PURE__ */ jsx(
855
- Box,
856
- {
857
- paddingTop: 3,
858
- paddingBottom: 3,
859
- paddingLeft: 4,
860
- paddingRight: 4,
861
- background: getReleaseColorVariant(release.action.type, "100"),
862
- width: "100%",
863
- children: /* @__PURE__ */ jsx(
864
- Typography,
865
- {
866
- fontSize: 1,
867
- variant: "pi",
868
- textColor: getReleaseColorVariant(release.action.type, "600"),
869
- children: formatMessage(
870
- {
871
- id: "content-releases.content-manager-edit-view.list-releases.title",
872
- defaultMessage: "{isPublish, select, true {Will be published in} other {Will be unpublished in}}"
873
- },
874
- { isPublish: release.action.type === "publish" }
875
- )
876
- }
877
- )
878
- }
879
- ),
880
- /* @__PURE__ */ jsx(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: /* @__PURE__ */ jsxs(Flex, { padding: 4, direction: "column", gap: 2, width: "100%", alignItems: "flex-start", children: [
881
- /* @__PURE__ */ jsx(Typography, { fontSize: 2, fontWeight: "bold", variant: "omega", textColor: "neutral700", children: release.name }),
882
- release.scheduledAt && release.timezone && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
883
- {
884
- id: "content-releases.content-manager-edit-view.scheduled.date",
885
- defaultMessage: "{date} at {time} ({offset})"
886
- },
887
- {
888
- date: formatDate(new Date(release.scheduledAt), {
889
- day: "2-digit",
890
- month: "2-digit",
891
- year: "numeric",
892
- timeZone: release.timezone
893
- }),
894
- time: formatTime(new Date(release.scheduledAt), {
895
- hourCycle: "h23",
896
- timeZone: release.timezone
897
- }),
898
- offset: getTimezoneOffset(
899
- release.timezone,
900
- new Date(release.scheduledAt)
901
- )
902
- }
903
- ) }),
904
- canDeleteAction ? /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { hasTriggerBorder: true, children: [
905
- /* @__PURE__ */ jsx(ReleaseActionMenu.EditReleaseItem, { releaseId: release.id }),
906
- /* @__PURE__ */ jsx(
907
- ReleaseActionMenu.DeleteReleaseActionItem,
908
- {
909
- releaseId: release.id,
910
- actionId: release.action.id
911
- }
912
- )
913
- ] }) : null
914
- ] }) })
915
- ]
916
- },
917
- release.id
918
- );
919
- }),
920
- canCreateAction ? /* @__PURE__ */ jsx(
921
- Button,
922
- {
923
- justifyContent: "center",
924
- paddingLeft: 4,
925
- paddingRight: 4,
926
- color: "neutral700",
927
- variant: "tertiary",
928
- startIcon: /* @__PURE__ */ jsx(Plus, {}),
929
- onClick: toggleModal,
930
- children: formatMessage({
931
- id: "content-releases.content-manager-edit-view.add-to-release",
932
- defaultMessage: "Add to release"
933
- })
934
- }
935
- ) : null
936
- ] }),
937
- isModalOpen && /* @__PURE__ */ jsx(
938
- AddActionToReleaseModal,
939
- {
940
- handleClose: toggleModal,
941
- contentTypeUid,
942
- entryId: id
943
- }
944
- )
945
- ]
946
- }
947
- );
948
- };
949
- const prefixPluginTranslations = (trad, pluginId2) => {
950
- if (!pluginId2) {
951
- throw new TypeError("pluginId can't be empty");
952
- }
953
- return Object.keys(trad).reduce((acc, current) => {
954
- acc[`${pluginId2}.${current}`] = trad[current];
955
- return acc;
956
- }, {});
957
- };
958
- const admin = {
959
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
960
- register(app) {
961
- if (window.strapi.features.isEnabled("cms-content-releases")) {
962
- app.addMenuLink({
963
- to: `plugins/${pluginId}`,
964
- icon: PaperPlane,
965
- intlLabel: {
966
- id: `${pluginId}.plugin.name`,
967
- defaultMessage: "Releases"
968
- },
969
- Component: () => import("./App-X01LBg5V.mjs").then((mod) => ({ default: mod.App })),
970
- permissions: PERMISSIONS.main
971
- });
972
- app.addMiddlewares([() => releaseApi.middleware]);
973
- app.addReducers({
974
- [releaseApi.reducerPath]: releaseApi.reducer
975
- });
976
- app.injectContentManagerComponent("editView", "right-links", {
977
- name: `${pluginId}-link`,
978
- Component: CMReleasesContainer
979
- });
980
- } else if (!window.strapi.features.isEnabled("cms-content-releases") && window.strapi?.flags?.promoteEE) {
981
- app.addMenuLink({
982
- to: `/plugins/purchase-content-releases`,
983
- icon: PaperPlane,
984
- intlLabel: {
985
- id: `${pluginId}.plugin.name`,
986
- defaultMessage: "Releases"
987
- },
988
- async Component() {
989
- const { PurchaseContentReleases } = await import("./PurchaseContentReleases-Clm0iACO.mjs");
990
- return PurchaseContentReleases;
991
- },
992
- lockIcon: true
993
- });
994
- }
995
- },
996
- async registerTrads({ locales }) {
997
- const importedTrads = await Promise.all(
998
- locales.map((locale) => {
999
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-RdapH-9X.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
1000
- return {
1001
- data: prefixPluginTranslations(data, "content-releases"),
1002
- locale
1003
- };
1004
- }).catch(() => {
1005
- return {
1006
- data: {},
1007
- locale
1008
- };
1009
- });
1010
- })
1011
- );
1012
- return Promise.resolve(importedTrads);
1013
- }
1014
- };
1015
- export {
1016
- PERMISSIONS as P,
1017
- ReleaseActionOptions as R,
1018
- useCreateReleaseMutation as a,
1019
- useGetReleaseQuery as b,
1020
- useUpdateReleaseMutation as c,
1021
- useDeleteReleaseMutation as d,
1022
- usePublishReleaseMutation as e,
1023
- useGetReleaseActionsQuery as f,
1024
- getTimezoneOffset as g,
1025
- useUpdateReleaseActionMutation as h,
1026
- isAxiosError as i,
1027
- ReleaseActionMenu as j,
1028
- admin as k,
1029
- pluginId as p,
1030
- releaseApi as r,
1031
- useGetReleasesQuery as u
1032
- };
1033
- //# sourceMappingURL=index-OD9AlD-6.mjs.map