@strapi/content-releases 0.0.0-experimental.f0d4afee92a0d386f80385590c87955656f995ce → 0.0.0-experimental.f28dba7c374eae9c02b95b4b77aba4c3ad41a841

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