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