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

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