@strapi/content-releases 0.0.0-next.60335b11eca9587b558035fe9ecca90e05db036b → 0.0.0-next.64bd4f3d1efcc9420d27c4f4d2013677ded62360

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/LICENSE +17 -1
  2. package/dist/_chunks/App-BKB1esYS.js +1395 -0
  3. package/dist/_chunks/App-BKB1esYS.js.map +1 -0
  4. package/dist/_chunks/App-Cne--1Z8.mjs +1374 -0
  5. package/dist/_chunks/App-Cne--1Z8.mjs.map +1 -0
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js +52 -0
  7. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs +52 -0
  9. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  10. package/dist/_chunks/ReleasesSettingsPage-C1WwGWIH.mjs +178 -0
  11. package/dist/_chunks/ReleasesSettingsPage-C1WwGWIH.mjs.map +1 -0
  12. package/dist/_chunks/ReleasesSettingsPage-kuXIwpWp.js +178 -0
  13. package/dist/_chunks/ReleasesSettingsPage-kuXIwpWp.js.map +1 -0
  14. package/dist/_chunks/{en-r9YocBH0.js → en-CmYoEnA7.js} +31 -5
  15. package/dist/_chunks/en-CmYoEnA7.js.map +1 -0
  16. package/dist/_chunks/{en-m9eTk4UF.mjs → en-D0yVZFqf.mjs} +31 -5
  17. package/dist/_chunks/en-D0yVZFqf.mjs.map +1 -0
  18. package/dist/_chunks/index-5Odi61vw.js +1381 -0
  19. package/dist/_chunks/index-5Odi61vw.js.map +1 -0
  20. package/dist/_chunks/index-Cy7qwpaU.mjs +1362 -0
  21. package/dist/_chunks/index-Cy7qwpaU.mjs.map +1 -0
  22. package/dist/_chunks/schemas-BE1LxE9J.js +62 -0
  23. package/dist/_chunks/schemas-BE1LxE9J.js.map +1 -0
  24. package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
  25. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
  26. package/dist/admin/index.js +1 -15
  27. package/dist/admin/index.js.map +1 -1
  28. package/dist/admin/index.mjs +2 -16
  29. package/dist/admin/index.mjs.map +1 -1
  30. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  31. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  32. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  33. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  34. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  35. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  36. package/dist/admin/src/components/ReleaseModal.d.ts +17 -0
  37. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  38. package/dist/admin/src/constants.d.ts +76 -0
  39. package/dist/admin/src/index.d.ts +3 -0
  40. package/dist/admin/src/modules/hooks.d.ts +7 -0
  41. package/dist/admin/src/pages/App.d.ts +1 -0
  42. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  43. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  44. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  45. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  46. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  47. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  48. package/dist/admin/src/pluginId.d.ts +1 -0
  49. package/dist/admin/src/services/release.d.ts +112 -0
  50. package/dist/admin/src/store/hooks.d.ts +7 -0
  51. package/dist/admin/src/utils/api.d.ts +6 -0
  52. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  53. package/dist/admin/src/utils/time.d.ts +10 -0
  54. package/dist/admin/src/validation/schemas.d.ts +6 -0
  55. package/dist/server/index.js +1292 -525
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/server/index.mjs +1292 -525
  58. package/dist/server/index.mjs.map +1 -1
  59. package/dist/server/src/bootstrap.d.ts +5 -0
  60. package/dist/server/src/bootstrap.d.ts.map +1 -0
  61. package/dist/server/src/constants.d.ts +21 -0
  62. package/dist/server/src/constants.d.ts.map +1 -0
  63. package/dist/server/src/content-types/index.d.ts +97 -0
  64. package/dist/server/src/content-types/index.d.ts.map +1 -0
  65. package/dist/server/src/content-types/release/index.d.ts +48 -0
  66. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  67. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  68. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  69. package/dist/server/src/content-types/release-action/index.d.ts +48 -0
  70. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  71. package/dist/server/src/content-types/release-action/schema.d.ts +47 -0
  72. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  73. package/dist/server/src/controllers/index.d.ts +25 -0
  74. package/dist/server/src/controllers/index.d.ts.map +1 -0
  75. package/dist/server/src/controllers/release-action.d.ts +10 -0
  76. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  77. package/dist/server/src/controllers/release.d.ts +18 -0
  78. package/dist/server/src/controllers/release.d.ts.map +1 -0
  79. package/dist/server/src/controllers/settings.d.ts +11 -0
  80. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  81. package/dist/server/src/controllers/validation/release-action.d.ts +14 -0
  82. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  83. package/dist/server/src/controllers/validation/release.d.ts +4 -0
  84. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  85. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  86. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  87. package/dist/server/src/destroy.d.ts +5 -0
  88. package/dist/server/src/destroy.d.ts.map +1 -0
  89. package/dist/server/src/index.d.ts +2115 -0
  90. package/dist/server/src/index.d.ts.map +1 -0
  91. package/dist/server/src/middlewares/documents.d.ts +6 -0
  92. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  93. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  94. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  95. package/dist/server/src/migrations/index.d.ts +13 -0
  96. package/dist/server/src/migrations/index.d.ts.map +1 -0
  97. package/dist/server/src/register.d.ts +5 -0
  98. package/dist/server/src/register.d.ts.map +1 -0
  99. package/dist/server/src/routes/index.d.ts +51 -0
  100. package/dist/server/src/routes/index.d.ts.map +1 -0
  101. package/dist/server/src/routes/release-action.d.ts +18 -0
  102. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  103. package/dist/server/src/routes/release.d.ts +18 -0
  104. package/dist/server/src/routes/release.d.ts.map +1 -0
  105. package/dist/server/src/routes/settings.d.ts +18 -0
  106. package/dist/server/src/routes/settings.d.ts.map +1 -0
  107. package/dist/server/src/services/index.d.ts +1828 -0
  108. package/dist/server/src/services/index.d.ts.map +1 -0
  109. package/dist/server/src/services/release-action.d.ts +38 -0
  110. package/dist/server/src/services/release-action.d.ts.map +1 -0
  111. package/dist/server/src/services/release.d.ts +31 -0
  112. package/dist/server/src/services/release.d.ts.map +1 -0
  113. package/dist/server/src/services/scheduling.d.ts +18 -0
  114. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  115. package/dist/server/src/services/settings.d.ts +13 -0
  116. package/dist/server/src/services/settings.d.ts.map +1 -0
  117. package/dist/server/src/services/validation.d.ts +18 -0
  118. package/dist/server/src/services/validation.d.ts.map +1 -0
  119. package/dist/server/src/utils/index.d.ts +35 -0
  120. package/dist/server/src/utils/index.d.ts.map +1 -0
  121. package/dist/shared/contracts/release-actions.d.ts +130 -0
  122. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  123. package/dist/shared/contracts/releases.d.ts +184 -0
  124. package/dist/shared/contracts/releases.d.ts.map +1 -0
  125. package/dist/shared/contracts/settings.d.ts +39 -0
  126. package/dist/shared/contracts/settings.d.ts.map +1 -0
  127. package/dist/shared/types.d.ts +24 -0
  128. package/dist/shared/types.d.ts.map +1 -0
  129. package/package.json +34 -37
  130. package/dist/_chunks/App-BFMg2T7b.mjs +0 -1080
  131. package/dist/_chunks/App-BFMg2T7b.mjs.map +0 -1
  132. package/dist/_chunks/App-HSsvlR7P.js +0 -1102
  133. package/dist/_chunks/App-HSsvlR7P.js.map +0 -1
  134. package/dist/_chunks/en-m9eTk4UF.mjs.map +0 -1
  135. package/dist/_chunks/en-r9YocBH0.js.map +0 -1
  136. package/dist/_chunks/index-GAnmm0Zl.js +0 -957
  137. package/dist/_chunks/index-GAnmm0Zl.js.map +0 -1
  138. package/dist/_chunks/index-y1lk-7GR.mjs +0 -936
  139. package/dist/_chunks/index-y1lk-7GR.mjs.map +0 -1
  140. package/strapi-server.js +0 -3
@@ -1,1102 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const helperPlugin = require("@strapi/helper-plugin");
5
- const reactRouterDom = require("react-router-dom");
6
- const index = require("./index-GAnmm0Zl.js");
7
- const React = require("react");
8
- const strapiAdmin = require("@strapi/admin/strapi-admin");
9
- const designSystem = require("@strapi/design-system");
10
- const v2 = require("@strapi/design-system/v2");
11
- const icons = require("@strapi/icons");
12
- const reactIntl = require("react-intl");
13
- const styled = require("styled-components");
14
- const formik = require("formik");
15
- const yup = require("yup");
16
- require("@reduxjs/toolkit/query");
17
- require("axios");
18
- require("@reduxjs/toolkit/query/react");
19
- require("react-redux");
20
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
21
- function _interopNamespace(e) {
22
- if (e && e.__esModule)
23
- return e;
24
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
25
- if (e) {
26
- for (const k in e) {
27
- if (k !== "default") {
28
- const d = Object.getOwnPropertyDescriptor(e, k);
29
- Object.defineProperty(n, k, d.get ? d : {
30
- enumerable: true,
31
- get: () => e[k]
32
- });
33
- }
34
- }
35
- }
36
- n.default = e;
37
- return Object.freeze(n);
38
- }
39
- const React__namespace = /* @__PURE__ */ _interopNamespace(React);
40
- const styled__default = /* @__PURE__ */ _interopDefault(styled);
41
- const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
42
- const RELEASE_SCHEMA = yup__namespace.object().shape({
43
- name: yup__namespace.string().trim().required(),
44
- // scheduledAt is a date, but we always receive strings from the client
45
- scheduledAt: yup__namespace.string()
46
- }).required().noUnknown();
47
- const ReleaseModal = ({
48
- handleClose,
49
- handleSubmit,
50
- initialValues,
51
- isLoading = false
52
- }) => {
53
- const { formatMessage } = reactIntl.useIntl();
54
- const { pathname } = reactRouterDom.useLocation();
55
- const isCreatingRelease = pathname === `/plugins/${index.pluginId}`;
56
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
57
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
58
- {
59
- id: "content-releases.modal.title",
60
- defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
61
- },
62
- { isCreatingRelease }
63
- ) }) }),
64
- /* @__PURE__ */ jsxRuntime.jsx(
65
- formik.Formik,
66
- {
67
- validateOnChange: false,
68
- onSubmit: handleSubmit,
69
- initialValues,
70
- validationSchema: RELEASE_SCHEMA,
71
- children: ({ values, errors, handleChange }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
72
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsx(
73
- designSystem.TextInput,
74
- {
75
- label: formatMessage({
76
- id: "content-releases.modal.form.input.label.release-name",
77
- defaultMessage: "Name"
78
- }),
79
- name: "name",
80
- value: values.name,
81
- error: errors.name,
82
- onChange: handleChange,
83
- required: true
84
- }
85
- ) }),
86
- /* @__PURE__ */ jsxRuntime.jsx(
87
- designSystem.ModalFooter,
88
- {
89
- startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
90
- endActions: /* @__PURE__ */ jsxRuntime.jsx(
91
- designSystem.Button,
92
- {
93
- name: "submit",
94
- loading: isLoading,
95
- disabled: !values.name || values.name === initialValues.name,
96
- type: "submit",
97
- children: formatMessage(
98
- {
99
- id: "content-releases.modal.form.button.submit",
100
- defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
101
- },
102
- { isCreatingRelease }
103
- )
104
- }
105
- )
106
- }
107
- )
108
- ] })
109
- }
110
- )
111
- ] });
112
- };
113
- const ReleaseInfoWrapper = styled__default.default(designSystem.Flex)`
114
- align-self: stretch;
115
- border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
116
- border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
117
- border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
118
- `;
119
- const StyledFlex = styled__default.default(designSystem.Flex)`
120
- align-self: stretch;
121
- cursor: ${({ disabled }) => disabled ? "not-allowed" : "pointer"};
122
-
123
- svg path {
124
- fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
125
- }
126
- span {
127
- color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
128
- }
129
- `;
130
- const PencilIcon = styled__default.default(icons.Pencil)`
131
- width: ${({ theme }) => theme.spaces[3]};
132
- height: ${({ theme }) => theme.spaces[3]};
133
- path {
134
- fill: ${({ theme }) => theme.colors.neutral600};
135
- }
136
- `;
137
- const TrashIcon = styled__default.default(icons.Trash)`
138
- width: ${({ theme }) => theme.spaces[3]};
139
- height: ${({ theme }) => theme.spaces[3]};
140
- path {
141
- fill: ${({ theme }) => theme.colors.danger600};
142
- }
143
- `;
144
- const TypographyMaxWidth = styled__default.default(designSystem.Typography)`
145
- max-width: 300px;
146
- `;
147
- const PopoverButton = ({ onClick, disabled, children }) => {
148
- return /* @__PURE__ */ jsxRuntime.jsx(
149
- StyledFlex,
150
- {
151
- paddingTop: 2,
152
- paddingBottom: 2,
153
- paddingLeft: 4,
154
- paddingRight: 4,
155
- alignItems: "center",
156
- gap: 2,
157
- as: "button",
158
- hasRadius: true,
159
- onClick,
160
- disabled,
161
- children
162
- }
163
- );
164
- };
165
- const EntryValidationText = ({ action, schema, components, entry }) => {
166
- const { formatMessage } = reactIntl.useIntl();
167
- const { validate } = strapiAdmin.unstable_useDocument();
168
- const { errors } = validate(entry, {
169
- contentType: schema,
170
- components,
171
- isCreatingEntry: false
172
- });
173
- if (Object.keys(errors).length > 0) {
174
- const validationErrorsMessages = Object.entries(errors).map(
175
- ([key, value]) => formatMessage(
176
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
177
- { field: key }
178
- )
179
- ).join(" ");
180
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
181
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "danger600", as: icons.CrossCircle }),
182
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsxRuntime.jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
183
- ] });
184
- }
185
- if (action == "publish") {
186
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
187
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
188
- entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
189
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
190
- defaultMessage: "Already published"
191
- }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
192
- id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
193
- defaultMessage: "Ready to publish"
194
- }) })
195
- ] });
196
- }
197
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
198
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Icon, { color: "success600", as: icons.CheckCircle }),
199
- !entry.publishedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
200
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
201
- defaultMessage: "Already unpublished"
202
- }) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage({
203
- id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish",
204
- defaultMessage: "Ready to unpublish"
205
- }) })
206
- ] });
207
- };
208
- const ReleaseDetailsLayout = ({
209
- toggleEditReleaseModal,
210
- toggleWarningSubmit,
211
- children
212
- }) => {
213
- const { formatMessage } = reactIntl.useIntl();
214
- const { releaseId } = reactRouterDom.useParams();
215
- const [isPopoverVisible, setIsPopoverVisible] = React__namespace.useState(false);
216
- const moreButtonRef = React__namespace.useRef(null);
217
- const {
218
- data,
219
- isLoading: isLoadingDetails,
220
- isError,
221
- error
222
- } = index.useGetReleaseQuery({ id: releaseId });
223
- const [publishRelease, { isLoading: isPublishing }] = index.usePublishReleaseMutation();
224
- const toggleNotification = helperPlugin.useNotification();
225
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
226
- const {
227
- allowedActions: { canUpdate, canDelete }
228
- } = helperPlugin.useRBAC(index.PERMISSIONS);
229
- const dispatch = index.useTypedDispatch();
230
- const { trackUsage } = helperPlugin.useTracking();
231
- const release = data?.data;
232
- const handleTogglePopover = () => {
233
- setIsPopoverVisible((prev) => !prev);
234
- };
235
- const openReleaseModal = () => {
236
- toggleEditReleaseModal();
237
- handleTogglePopover();
238
- };
239
- const handlePublishRelease = async () => {
240
- const response = await publishRelease({ id: releaseId });
241
- if ("data" in response) {
242
- toggleNotification({
243
- type: "success",
244
- message: formatMessage({
245
- id: "content-releases.pages.ReleaseDetails.publish-notification-success",
246
- defaultMessage: "Release was published successfully."
247
- })
248
- });
249
- const { totalEntries: totalEntries2, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;
250
- trackUsage("didPublishRelease", {
251
- totalEntries: totalEntries2,
252
- totalPublishedEntries,
253
- totalUnpublishedEntries
254
- });
255
- } else if (index.isAxiosError(response.error)) {
256
- toggleNotification({
257
- type: "warning",
258
- message: formatAPIError(response.error)
259
- });
260
- } else {
261
- toggleNotification({
262
- type: "warning",
263
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
264
- });
265
- }
266
- };
267
- const openWarningConfirmDialog = () => {
268
- toggleWarningSubmit();
269
- handleTogglePopover();
270
- };
271
- const handleRefresh = () => {
272
- dispatch(index.releaseApi.util.invalidateTags([{ type: "ReleaseAction", id: "LIST" }]));
273
- };
274
- const getCreatedByUser = () => {
275
- if (!release?.createdBy) {
276
- return null;
277
- }
278
- if (release.createdBy.username) {
279
- return release.createdBy.username;
280
- }
281
- if (release.createdBy.firstname) {
282
- return `${release.createdBy.firstname} ${release.createdBy.lastname || ""}`.trim();
283
- }
284
- return release.createdBy.email;
285
- };
286
- if (isLoadingDetails) {
287
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
288
- }
289
- if (isError || !release) {
290
- return /* @__PURE__ */ jsxRuntime.jsx(
291
- reactRouterDom.Redirect,
292
- {
293
- to: {
294
- pathname: "/plugins/content-releases",
295
- state: {
296
- errors: [
297
- {
298
- code: error?.code
299
- }
300
- ]
301
- }
302
- }
303
- }
304
- );
305
- }
306
- const totalEntries = release.actions.meta.count || 0;
307
- const hasCreatedByUser = Boolean(getCreatedByUser());
308
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingDetails, children: [
309
- /* @__PURE__ */ jsxRuntime.jsx(
310
- designSystem.HeaderLayout,
311
- {
312
- title: release.name,
313
- subtitle: formatMessage(
314
- {
315
- id: "content-releases.pages.Details.header-subtitle",
316
- defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
317
- },
318
- { number: totalEntries }
319
- ),
320
- navigationAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
321
- id: "global.back",
322
- defaultMessage: "Back"
323
- }) }),
324
- primaryAction: !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
325
- /* @__PURE__ */ jsxRuntime.jsx(
326
- designSystem.IconButton,
327
- {
328
- label: formatMessage({
329
- id: "content-releases.header.actions.open-release-actions",
330
- defaultMessage: "Release edit and delete menu"
331
- }),
332
- ref: moreButtonRef,
333
- onClick: handleTogglePopover,
334
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
335
- }
336
- ),
337
- isPopoverVisible && /* @__PURE__ */ jsxRuntime.jsxs(
338
- designSystem.Popover,
339
- {
340
- source: moreButtonRef,
341
- placement: "bottom-end",
342
- onDismiss: handleTogglePopover,
343
- spacing: 4,
344
- minWidth: "242px",
345
- children: [
346
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", justifyContent: "center", direction: "column", padding: 1, children: [
347
- /* @__PURE__ */ jsxRuntime.jsxs(PopoverButton, { disabled: !canUpdate, onClick: openReleaseModal, children: [
348
- /* @__PURE__ */ jsxRuntime.jsx(PencilIcon, {}),
349
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: formatMessage({
350
- id: "content-releases.header.actions.edit",
351
- defaultMessage: "Edit"
352
- }) })
353
- ] }),
354
- /* @__PURE__ */ jsxRuntime.jsxs(PopoverButton, { disabled: !canDelete, onClick: openWarningConfirmDialog, children: [
355
- /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {}),
356
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
357
- id: "content-releases.header.actions.delete",
358
- defaultMessage: "Delete"
359
- }) })
360
- ] })
361
- ] }),
362
- /* @__PURE__ */ jsxRuntime.jsxs(
363
- ReleaseInfoWrapper,
364
- {
365
- direction: "column",
366
- justifyContent: "center",
367
- alignItems: "flex-start",
368
- gap: 1,
369
- padding: 5,
370
- children: [
371
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
372
- id: "content-releases.header.actions.created",
373
- defaultMessage: "Created"
374
- }) }),
375
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", color: "neutral300", children: [
376
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.RelativeTime, { timestamp: new Date(release.createdAt) }),
377
- formatMessage(
378
- {
379
- id: "content-releases.header.actions.created.description",
380
- defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
381
- },
382
- { createdBy: getCreatedByUser(), hasCreatedByUser }
383
- )
384
- ] })
385
- ]
386
- }
387
- )
388
- ]
389
- }
390
- ),
391
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
392
- id: "content-releases.header.actions.refresh",
393
- defaultMessage: "Refresh"
394
- }) }),
395
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.publish, children: /* @__PURE__ */ jsxRuntime.jsx(
396
- designSystem.Button,
397
- {
398
- size: "S",
399
- variant: "default",
400
- onClick: handlePublishRelease,
401
- loading: isPublishing,
402
- disabled: release.actions.meta.count === 0,
403
- children: formatMessage({
404
- id: "content-releases.header.actions.publish",
405
- defaultMessage: "Publish"
406
- })
407
- }
408
- ) })
409
- ] })
410
- }
411
- ),
412
- children
413
- ] });
414
- };
415
- const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
416
- const getGroupByOptionLabel = (value) => {
417
- if (value === "locale") {
418
- return {
419
- id: "content-releases.pages.ReleaseDetails.groupBy.option.locales",
420
- defaultMessage: "Locales"
421
- };
422
- }
423
- if (value === "action") {
424
- return {
425
- id: "content-releases.pages.ReleaseDetails.groupBy.option.actions",
426
- defaultMessage: "Actions"
427
- };
428
- }
429
- return {
430
- id: "content-releases.pages.ReleaseDetails.groupBy.option.content-type",
431
- defaultMessage: "Content-Types"
432
- };
433
- };
434
- const ReleaseDetailsBody = () => {
435
- const { formatMessage } = reactIntl.useIntl();
436
- const { releaseId } = reactRouterDom.useParams();
437
- const [{ query }, setQuery] = helperPlugin.useQueryParams();
438
- const toggleNotification = helperPlugin.useNotification();
439
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
440
- const {
441
- data: releaseData,
442
- isLoading: isReleaseLoading,
443
- isError: isReleaseError,
444
- error: releaseError
445
- } = index.useGetReleaseQuery({ id: releaseId });
446
- const {
447
- allowedActions: { canUpdate }
448
- } = helperPlugin.useRBAC(index.PERMISSIONS);
449
- const release = releaseData?.data;
450
- const selectedGroupBy = query?.groupBy || "contentType";
451
- const {
452
- isLoading,
453
- isFetching,
454
- isError,
455
- data,
456
- error: releaseActionsError
457
- } = index.useGetReleaseActionsQuery({
458
- ...query,
459
- releaseId
460
- });
461
- const [updateReleaseAction] = index.useUpdateReleaseActionMutation();
462
- const handleChangeType = async (e, actionId, actionPath) => {
463
- const response = await updateReleaseAction({
464
- params: {
465
- releaseId,
466
- actionId
467
- },
468
- body: {
469
- type: e.target.value
470
- },
471
- query,
472
- // We are passing the query params to make optimistic updates
473
- actionPath
474
- // We are passing the action path to found the position in the cache of the action for optimistic updates
475
- });
476
- if ("error" in response) {
477
- if (index.isAxiosError(response.error)) {
478
- toggleNotification({
479
- type: "warning",
480
- message: formatAPIError(response.error)
481
- });
482
- } else {
483
- toggleNotification({
484
- type: "warning",
485
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
486
- });
487
- }
488
- }
489
- };
490
- if (isLoading || isReleaseLoading) {
491
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
492
- }
493
- const releaseActions = data?.data;
494
- const releaseMeta = data?.meta;
495
- const contentTypes = releaseMeta?.contentTypes || {};
496
- const components = releaseMeta?.components || {};
497
- if (isReleaseError || !release) {
498
- const errorsArray = [];
499
- if (releaseError) {
500
- errorsArray.push({
501
- code: releaseError.code
502
- });
503
- }
504
- if (releaseActionsError) {
505
- errorsArray.push({
506
- code: releaseActionsError.code
507
- });
508
- }
509
- return /* @__PURE__ */ jsxRuntime.jsx(
510
- reactRouterDom.Redirect,
511
- {
512
- to: {
513
- pathname: "/plugins/content-releases",
514
- state: {
515
- errors: errorsArray
516
- }
517
- }
518
- }
519
- );
520
- }
521
- if (isError || !releaseActions) {
522
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {}) });
523
- }
524
- if (Object.keys(releaseActions).length === 0) {
525
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
526
- helperPlugin.NoContent,
527
- {
528
- content: {
529
- id: "content-releases.pages.Details.tab.emptyEntries",
530
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
531
- },
532
- action: /* @__PURE__ */ jsxRuntime.jsx(
533
- v2.LinkButton,
534
- {
535
- as: reactRouterDom.Link,
536
- to: {
537
- pathname: "/content-manager"
538
- },
539
- style: { textDecoration: "none" },
540
- variant: "secondary",
541
- children: formatMessage({
542
- id: "content-releases.page.Details.button.openContentManager",
543
- defaultMessage: "Open the Content Manager"
544
- })
545
- }
546
- )
547
- }
548
- ) });
549
- }
550
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
551
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { children: /* @__PURE__ */ jsxRuntime.jsx(
552
- designSystem.SingleSelect,
553
- {
554
- "aria-label": formatMessage({
555
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
556
- defaultMessage: "Group by"
557
- }),
558
- customizeContent: (value) => formatMessage(
559
- {
560
- id: `content-releases.pages.ReleaseDetails.groupBy.label`,
561
- defaultMessage: `Group by {groupBy}`
562
- },
563
- {
564
- groupBy: value
565
- }
566
- ),
567
- value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
568
- onChange: (value) => setQuery({ groupBy: value }),
569
- children: GROUP_BY_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
570
- }
571
- ) }),
572
- Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
573
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { role: "separator", "aria-label": key, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { children: key }) }),
574
- /* @__PURE__ */ jsxRuntime.jsx(
575
- helperPlugin.Table.Root,
576
- {
577
- rows: releaseActions[key].map((item) => ({
578
- ...item,
579
- id: Number(item.entry.id)
580
- })),
581
- colCount: releaseActions[key].length,
582
- isLoading,
583
- isFetching,
584
- children: /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Content, { children: [
585
- /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Head, { children: [
586
- /* @__PURE__ */ jsxRuntime.jsx(
587
- helperPlugin.Table.HeaderCell,
588
- {
589
- fieldSchemaType: "string",
590
- label: formatMessage({
591
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
592
- defaultMessage: "name"
593
- }),
594
- name: "name"
595
- }
596
- ),
597
- /* @__PURE__ */ jsxRuntime.jsx(
598
- helperPlugin.Table.HeaderCell,
599
- {
600
- fieldSchemaType: "string",
601
- label: formatMessage({
602
- id: "content-releases.page.ReleaseDetails.table.header.label.locale",
603
- defaultMessage: "locale"
604
- }),
605
- name: "locale"
606
- }
607
- ),
608
- /* @__PURE__ */ jsxRuntime.jsx(
609
- helperPlugin.Table.HeaderCell,
610
- {
611
- fieldSchemaType: "string",
612
- label: formatMessage({
613
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
614
- defaultMessage: "content-type"
615
- }),
616
- name: "content-type"
617
- }
618
- ),
619
- /* @__PURE__ */ jsxRuntime.jsx(
620
- helperPlugin.Table.HeaderCell,
621
- {
622
- fieldSchemaType: "string",
623
- label: formatMessage({
624
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
625
- defaultMessage: "action"
626
- }),
627
- name: "action"
628
- }
629
- ),
630
- !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsx(
631
- helperPlugin.Table.HeaderCell,
632
- {
633
- fieldSchemaType: "string",
634
- label: formatMessage({
635
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
636
- defaultMessage: "status"
637
- }),
638
- name: "status"
639
- }
640
- )
641
- ] }),
642
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
643
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions[key].map(
644
- ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
645
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
646
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
647
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "10%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: contentType.displayName || "" }) }),
648
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
649
- {
650
- id: "content-releases.page.ReleaseDetails.table.action-published",
651
- defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
652
- },
653
- {
654
- isPublish: type === "publish",
655
- b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
656
- }
657
- ) }) : /* @__PURE__ */ jsxRuntime.jsx(
658
- index.ReleaseActionOptions,
659
- {
660
- selected: type,
661
- handleChange: (e) => handleChangeType(e, id, [key, actionIndex]),
662
- name: `release-action-${id}-type`,
663
- disabled: !canUpdate
664
- }
665
- ) }),
666
- !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
667
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { width: "20%", minWidth: "200px", children: /* @__PURE__ */ jsxRuntime.jsx(
668
- EntryValidationText,
669
- {
670
- action: type,
671
- schema: contentTypes?.[contentType.uid],
672
- components,
673
- entry
674
- }
675
- ) }),
676
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsxs(index.ReleaseActionMenu.Root, { children: [
677
- /* @__PURE__ */ jsxRuntime.jsx(
678
- index.ReleaseActionMenu.ReleaseActionEntryLinkItem,
679
- {
680
- contentTypeUid: contentType.uid,
681
- entryId: entry.id,
682
- locale: locale?.code
683
- }
684
- ),
685
- /* @__PURE__ */ jsxRuntime.jsx(
686
- index.ReleaseActionMenu.DeleteReleaseActionItem,
687
- {
688
- releaseId: release.id,
689
- actionId: id
690
- }
691
- )
692
- ] }) }) })
693
- ] })
694
- ] }, id)
695
- ) })
696
- ] })
697
- }
698
- )
699
- ] }, `releases-group-${key}`)),
700
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
701
- /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
702
- /* @__PURE__ */ jsxRuntime.jsx(
703
- helperPlugin.PaginationURLQuery,
704
- {
705
- pagination: {
706
- pageCount: releaseMeta?.pagination?.pageCount || 0
707
- }
708
- }
709
- )
710
- ] })
711
- ] }) });
712
- };
713
- const ReleaseDetailsPage = () => {
714
- const { formatMessage } = reactIntl.useIntl();
715
- const { releaseId } = reactRouterDom.useParams();
716
- const toggleNotification = helperPlugin.useNotification();
717
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
718
- const { push } = reactRouterDom.useHistory();
719
- const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
720
- const [showWarningSubmit, setWarningSubmit] = React__namespace.useState(false);
721
- const {
722
- isLoading: isLoadingDetails,
723
- data,
724
- isSuccess: isSuccessDetails
725
- } = index.useGetReleaseQuery({ id: releaseId });
726
- const [updateRelease, { isLoading: isSubmittingForm }] = index.useUpdateReleaseMutation();
727
- const [deleteRelease, { isLoading: isDeletingRelease }] = index.useDeleteReleaseMutation();
728
- const toggleEditReleaseModal = () => {
729
- setReleaseModalShown((prev) => !prev);
730
- };
731
- const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
732
- if (isLoadingDetails) {
733
- return /* @__PURE__ */ jsxRuntime.jsx(
734
- ReleaseDetailsLayout,
735
- {
736
- toggleEditReleaseModal,
737
- toggleWarningSubmit,
738
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) })
739
- }
740
- );
741
- }
742
- const title = isSuccessDetails && data?.data?.name || "";
743
- const handleEditRelease = async (values) => {
744
- const response = await updateRelease({
745
- id: releaseId,
746
- name: values.name
747
- });
748
- if ("data" in response) {
749
- toggleNotification({
750
- type: "success",
751
- message: formatMessage({
752
- id: "content-releases.modal.release-updated-notification-success",
753
- defaultMessage: "Release updated."
754
- })
755
- });
756
- } else if (index.isAxiosError(response.error)) {
757
- toggleNotification({
758
- type: "warning",
759
- message: formatAPIError(response.error)
760
- });
761
- } else {
762
- toggleNotification({
763
- type: "warning",
764
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
765
- });
766
- }
767
- toggleEditReleaseModal();
768
- };
769
- const handleDeleteRelease = async () => {
770
- const response = await deleteRelease({
771
- id: releaseId
772
- });
773
- if ("data" in response) {
774
- push("/plugins/content-releases");
775
- } else if (index.isAxiosError(response.error)) {
776
- toggleNotification({
777
- type: "warning",
778
- message: formatAPIError(response.error)
779
- });
780
- } else {
781
- toggleNotification({
782
- type: "warning",
783
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
784
- });
785
- }
786
- };
787
- return /* @__PURE__ */ jsxRuntime.jsxs(
788
- ReleaseDetailsLayout,
789
- {
790
- toggleEditReleaseModal,
791
- toggleWarningSubmit,
792
- children: [
793
- /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsBody, {}),
794
- releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
795
- ReleaseModal,
796
- {
797
- handleClose: toggleEditReleaseModal,
798
- handleSubmit: handleEditRelease,
799
- isLoading: isLoadingDetails || isSubmittingForm,
800
- initialValues: { name: title || "" }
801
- }
802
- ),
803
- /* @__PURE__ */ jsxRuntime.jsx(
804
- helperPlugin.ConfirmDialog,
805
- {
806
- bodyText: {
807
- id: "content-releases.dialog.confirmation-message",
808
- defaultMessage: "Are you sure you want to delete this release?"
809
- },
810
- isOpen: showWarningSubmit,
811
- isConfirmButtonLoading: isDeletingRelease,
812
- onToggleDialog: toggleWarningSubmit,
813
- onConfirm: handleDeleteRelease
814
- }
815
- )
816
- ]
817
- }
818
- );
819
- };
820
- const LinkCard = styled__default.default(v2.Link)`
821
- display: block;
822
- `;
823
- const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
824
- const { formatMessage } = reactIntl.useIntl();
825
- if (isError) {
826
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {});
827
- }
828
- if (releases?.length === 0) {
829
- return /* @__PURE__ */ jsxRuntime.jsx(
830
- designSystem.EmptyStateLayout,
831
- {
832
- content: formatMessage(
833
- {
834
- id: "content-releases.page.Releases.tab.emptyEntries",
835
- defaultMessage: "No releases"
836
- },
837
- {
838
- target: sectionTitle
839
- }
840
- ),
841
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.EmptyDocuments, { width: "10rem" })
842
- }
843
- );
844
- }
845
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid, { gap: 4, children: releases.map(({ id, name, actions }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsxRuntime.jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
846
- designSystem.Flex,
847
- {
848
- direction: "column",
849
- justifyContent: "space-between",
850
- padding: 4,
851
- hasRadius: true,
852
- background: "neutral0",
853
- shadow: "tableShadow",
854
- height: "100%",
855
- width: "100%",
856
- alignItems: "start",
857
- gap: 2,
858
- children: [
859
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
860
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: formatMessage(
861
- {
862
- id: "content-releases.page.Releases.release-item.entries",
863
- defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
864
- },
865
- { number: actions.meta.count }
866
- ) })
867
- ]
868
- }
869
- ) }) }, id)) });
870
- };
871
- const StyledAlert = styled__default.default(designSystem.Alert)`
872
- button {
873
- display: none;
874
- }
875
- p + div {
876
- margin-left: auto;
877
- }
878
- `;
879
- const INITIAL_FORM_VALUES = {
880
- name: ""
881
- };
882
- const ReleasesPage = () => {
883
- const tabRef = React__namespace.useRef(null);
884
- const location = reactRouterDom.useLocation();
885
- const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
886
- const toggleNotification = helperPlugin.useNotification();
887
- const { formatMessage } = reactIntl.useIntl();
888
- const { push, replace } = reactRouterDom.useHistory();
889
- const { formatAPIError } = helperPlugin.useAPIErrorHandler();
890
- const [{ query }, setQuery] = helperPlugin.useQueryParams();
891
- const response = index.useGetReleasesQuery(query);
892
- const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
893
- const { getFeature } = strapiAdmin.useLicenseLimits();
894
- const { maximumReleases = 3 } = getFeature("cms-content-releases");
895
- const { trackUsage } = helperPlugin.useTracking();
896
- const { isLoading, isSuccess, isError } = response;
897
- const activeTab = response?.currentData?.meta?.activeTab || "pending";
898
- const activeTabIndex = ["pending", "done"].indexOf(activeTab);
899
- React__namespace.useEffect(() => {
900
- if (location?.state?.errors) {
901
- toggleNotification({
902
- type: "warning",
903
- title: formatMessage({
904
- id: "content-releases.pages.Releases.notification.error.title",
905
- defaultMessage: "Your request could not be processed."
906
- }),
907
- message: formatMessage({
908
- id: "content-releases.pages.Releases.notification.error.message",
909
- defaultMessage: "Please try again or open another release."
910
- })
911
- });
912
- replace({ state: null });
913
- }
914
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
915
- React__namespace.useEffect(() => {
916
- if (tabRef.current) {
917
- tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
918
- }
919
- }, [activeTabIndex]);
920
- const toggleAddReleaseModal = () => {
921
- setReleaseModalShown((prev) => !prev);
922
- };
923
- if (isLoading) {
924
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
925
- }
926
- const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
927
- const hasReachedMaximumPendingReleases = totalReleases >= maximumReleases;
928
- const handleTabChange = (index2) => {
929
- setQuery({
930
- ...query,
931
- page: 1,
932
- pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
933
- filters: {
934
- releasedAt: {
935
- $notNull: index2 === 0 ? false : true
936
- }
937
- }
938
- });
939
- };
940
- const handleAddRelease = async (values) => {
941
- const response2 = await createRelease({
942
- name: values.name
943
- });
944
- if ("data" in response2) {
945
- toggleNotification({
946
- type: "success",
947
- message: formatMessage({
948
- id: "content-releases.modal.release-created-notification-success",
949
- defaultMessage: "Release created."
950
- })
951
- });
952
- trackUsage("didCreateRelease");
953
- push(`/plugins/content-releases/${response2.data.data.id}`);
954
- } else if (index.isAxiosError(response2.error)) {
955
- toggleNotification({
956
- type: "warning",
957
- message: formatAPIError(response2.error)
958
- });
959
- } else {
960
- toggleNotification({
961
- type: "warning",
962
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
963
- });
964
- }
965
- };
966
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
967
- /* @__PURE__ */ jsxRuntime.jsx(
968
- designSystem.HeaderLayout,
969
- {
970
- title: formatMessage({
971
- id: "content-releases.pages.Releases.title",
972
- defaultMessage: "Releases"
973
- }),
974
- subtitle: formatMessage(
975
- {
976
- id: "content-releases.pages.Releases.header-subtitle",
977
- defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
978
- },
979
- { number: totalReleases }
980
- ),
981
- primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(
982
- designSystem.Button,
983
- {
984
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
985
- onClick: toggleAddReleaseModal,
986
- disabled: hasReachedMaximumPendingReleases,
987
- children: formatMessage({
988
- id: "content-releases.header.actions.add-release",
989
- defaultMessage: "New release"
990
- })
991
- }
992
- ) })
993
- }
994
- ),
995
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
996
- activeTab === "pending" && hasReachedMaximumPendingReleases && /* @__PURE__ */ jsxRuntime.jsx(
997
- StyledAlert,
998
- {
999
- marginBottom: 6,
1000
- action: /* @__PURE__ */ jsxRuntime.jsx(v2.Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
1001
- id: "content-releases.pages.Releases.max-limit-reached.action",
1002
- defaultMessage: "Explore plans"
1003
- }) }),
1004
- title: formatMessage(
1005
- {
1006
- id: "content-releases.pages.Releases.max-limit-reached.title",
1007
- defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
1008
- },
1009
- { number: maximumReleases }
1010
- ),
1011
- onClose: () => {
1012
- },
1013
- closeLabel: "",
1014
- children: formatMessage({
1015
- id: "content-releases.pages.Releases.max-limit-reached.message",
1016
- defaultMessage: "Upgrade to manage an unlimited number of releases."
1017
- })
1018
- }
1019
- ),
1020
- /* @__PURE__ */ jsxRuntime.jsxs(
1021
- designSystem.TabGroup,
1022
- {
1023
- label: formatMessage({
1024
- id: "content-releases.pages.Releases.tab-group.label",
1025
- defaultMessage: "Releases list"
1026
- }),
1027
- variant: "simple",
1028
- initialSelectedTabIndex: activeTabIndex,
1029
- onTabChange: handleTabChange,
1030
- ref: tabRef,
1031
- children: [
1032
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingBottom: 8, children: [
1033
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs, { children: [
1034
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
1035
- id: "content-releases.pages.Releases.tab.pending",
1036
- defaultMessage: "Pending"
1037
- }) }),
1038
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
1039
- id: "content-releases.pages.Releases.tab.done",
1040
- defaultMessage: "Done"
1041
- }) })
1042
- ] }),
1043
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {})
1044
- ] }),
1045
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.TabPanels, { children: [
1046
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
1047
- ReleasesGrid,
1048
- {
1049
- sectionTitle: "pending",
1050
- releases: response?.currentData?.data,
1051
- isError
1052
- }
1053
- ) }),
1054
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
1055
- ReleasesGrid,
1056
- {
1057
- sectionTitle: "done",
1058
- releases: response?.currentData?.data,
1059
- isError
1060
- }
1061
- ) })
1062
- ] })
1063
- ]
1064
- }
1065
- ),
1066
- totalReleases > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1067
- /* @__PURE__ */ jsxRuntime.jsx(
1068
- helperPlugin.PageSizeURLQuery,
1069
- {
1070
- options: ["8", "16", "32", "64"],
1071
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
1072
- }
1073
- ),
1074
- /* @__PURE__ */ jsxRuntime.jsx(
1075
- helperPlugin.PaginationURLQuery,
1076
- {
1077
- pagination: {
1078
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
1079
- }
1080
- }
1081
- )
1082
- ] })
1083
- ] }) }),
1084
- releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
1085
- ReleaseModal,
1086
- {
1087
- handleClose: toggleAddReleaseModal,
1088
- handleSubmit: handleAddRelease,
1089
- isLoading: isSubmittingForm,
1090
- initialValues: INITIAL_FORM_VALUES
1091
- }
1092
- )
1093
- ] });
1094
- };
1095
- const App = () => {
1096
- return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPagePermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
1097
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}`, component: ReleasesPage }),
1098
- /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}/:releaseId`, component: ReleaseDetailsPage })
1099
- ] }) });
1100
- };
1101
- exports.App = App;
1102
- //# sourceMappingURL=App-HSsvlR7P.js.map