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

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