@strapi/content-releases 0.0.0-next.f8af92b375dc730ba47ed2117f25df893aae696c → 0.0.0-next.fc1775f7731f8999840e56e298a216b9a6c5c4ad

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