@strapi/content-releases 0.0.0-experimental.check-license → 0.0.0-experimental.d362bf200f5f9359a4bbd4a549603de5ee1f04ca

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 (106) hide show
  1. package/dist/_chunks/App-1LckaIGY.js +1352 -0
  2. package/dist/_chunks/App-1LckaIGY.js.map +1 -0
  3. package/dist/_chunks/App-X01LBg5V.mjs +1329 -0
  4. package/dist/_chunks/App-X01LBg5V.mjs.map +1 -0
  5. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs +51 -0
  6. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +1 -0
  7. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js +51 -0
  8. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +1 -0
  9. package/dist/_chunks/en-RdapH-9X.mjs +77 -0
  10. package/dist/_chunks/en-RdapH-9X.mjs.map +1 -0
  11. package/dist/_chunks/en-faJDuv3q.js +77 -0
  12. package/dist/_chunks/en-faJDuv3q.js.map +1 -0
  13. package/dist/_chunks/index-OD9AlD-6.mjs +1033 -0
  14. package/dist/_chunks/index-OD9AlD-6.mjs.map +1 -0
  15. package/dist/_chunks/index-cYWov2wa.js +1054 -0
  16. package/dist/_chunks/index-cYWov2wa.js.map +1 -0
  17. package/dist/admin/index.js +3 -35
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +3 -35
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/admin/src/components/CMReleasesContainer.d.ts +1 -0
  22. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  23. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  24. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  25. package/dist/admin/src/components/ReleaseModal.d.ts +16 -0
  26. package/dist/admin/src/constants.d.ts +58 -0
  27. package/dist/admin/src/index.d.ts +3 -15
  28. package/dist/admin/src/pages/App.d.ts +1 -0
  29. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  30. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  31. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  32. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  33. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  34. package/dist/admin/src/pluginId.d.ts +1 -0
  35. package/dist/admin/src/services/axios.d.ts +29 -0
  36. package/dist/admin/src/services/release.d.ts +369 -0
  37. package/dist/admin/src/store/hooks.d.ts +7 -0
  38. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  39. package/dist/admin/src/utils/time.d.ts +1 -0
  40. package/dist/server/index.js +1715 -6
  41. package/dist/server/index.js.map +1 -1
  42. package/dist/server/index.mjs +1693 -6
  43. package/dist/server/index.mjs.map +1 -1
  44. package/dist/server/src/bootstrap.d.ts +5 -0
  45. package/dist/server/src/bootstrap.d.ts.map +1 -0
  46. package/dist/server/src/constants.d.ts +12 -0
  47. package/dist/server/src/constants.d.ts.map +1 -0
  48. package/dist/server/src/content-types/index.d.ts +99 -0
  49. package/dist/server/src/content-types/index.d.ts.map +1 -0
  50. package/dist/server/src/content-types/release/index.d.ts +48 -0
  51. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  52. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  53. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  54. package/dist/server/src/content-types/release-action/index.d.ts +50 -0
  55. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  56. package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
  57. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  58. package/dist/server/src/controllers/index.d.ts +19 -0
  59. package/dist/server/src/controllers/index.d.ts.map +1 -0
  60. package/dist/server/src/controllers/release-action.d.ts +10 -0
  61. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  62. package/dist/server/src/controllers/release.d.ts +11 -0
  63. package/dist/server/src/controllers/release.d.ts.map +1 -0
  64. package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
  65. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  66. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  67. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  68. package/dist/server/src/destroy.d.ts +5 -0
  69. package/dist/server/src/destroy.d.ts.map +1 -0
  70. package/dist/server/src/index.d.ts +2092 -1
  71. package/dist/server/src/index.d.ts.map +1 -0
  72. package/dist/server/src/migrations/index.d.ts +13 -0
  73. package/dist/server/src/migrations/index.d.ts.map +1 -0
  74. package/dist/server/src/register.d.ts +5 -1
  75. package/dist/server/src/register.d.ts.map +1 -0
  76. package/dist/server/src/routes/index.d.ts +35 -0
  77. package/dist/server/src/routes/index.d.ts.map +1 -0
  78. package/dist/server/src/routes/release-action.d.ts +18 -0
  79. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  80. package/dist/server/src/routes/release.d.ts +18 -0
  81. package/dist/server/src/routes/release.d.ts.map +1 -0
  82. package/dist/server/src/services/index.d.ts +1826 -0
  83. package/dist/server/src/services/index.d.ts.map +1 -0
  84. package/dist/server/src/services/release.d.ts +66 -0
  85. package/dist/server/src/services/release.d.ts.map +1 -0
  86. package/dist/server/src/services/scheduling.d.ts +18 -0
  87. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  88. package/dist/server/src/services/validation.d.ts +18 -0
  89. package/dist/server/src/services/validation.d.ts.map +1 -0
  90. package/dist/server/src/utils/index.d.ts +14 -0
  91. package/dist/server/src/utils/index.d.ts.map +1 -0
  92. package/dist/shared/contracts/release-actions.d.ts +131 -0
  93. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  94. package/dist/shared/contracts/releases.d.ts +166 -0
  95. package/dist/shared/contracts/releases.d.ts.map +1 -0
  96. package/dist/shared/types.d.ts +24 -0
  97. package/dist/shared/types.d.ts.map +1 -0
  98. package/dist/shared/validation-schemas.d.ts +2 -0
  99. package/dist/shared/validation-schemas.d.ts.map +1 -0
  100. package/package.json +39 -30
  101. package/dist/_chunks/en-21947221.js +0 -5
  102. package/dist/_chunks/en-21947221.js.map +0 -1
  103. package/dist/_chunks/en-92157b33.mjs +0 -5
  104. package/dist/_chunks/en-92157b33.mjs.map +0 -1
  105. package/dist/admin/src/tests/index.test.d.ts +0 -0
  106. package/dist/server/src/__tests__/index.test.d.ts +0 -2
@@ -0,0 +1,1033 @@
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