@strapi/content-releases 0.0.0-next.f4ff842a3cb7b83db540bee67554b704e042b042 → 0.0.0-next.f5312617ca16b870c2bf1adcea2c69b676979e29

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