@strapi/content-releases 0.0.0-next.e9b6852d1c05518ff6e37d599321f7aa7aa0683b → 0.0.0-next.ee56af7ae29770097422de95c0d5500908dce15c

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