@strapi/content-releases 0.0.0-experimental.check-license → 0.0.0-experimental.f7b9b47085e387e97f990d8695971b51d7f7149a

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.
@@ -0,0 +1,877 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const reactRouterDom = require("react-router-dom");
5
+ const index = require("./index-66d129ac.js");
6
+ const React = require("react");
7
+ const designSystem = require("@strapi/design-system");
8
+ const v2 = require("@strapi/design-system/v2");
9
+ const helperPlugin = require("@strapi/helper-plugin");
10
+ const icons = require("@strapi/icons");
11
+ const reactIntl = require("react-intl");
12
+ const styled = require("styled-components");
13
+ const formik = require("formik");
14
+ const yup = require("yup");
15
+ require("@reduxjs/toolkit/query");
16
+ require("axios");
17
+ require("@reduxjs/toolkit/query/react");
18
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
19
+ function _interopNamespace(e) {
20
+ if (e && e.__esModule)
21
+ return e;
22
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
23
+ if (e) {
24
+ for (const k in e) {
25
+ if (k !== "default") {
26
+ const d = Object.getOwnPropertyDescriptor(e, k);
27
+ Object.defineProperty(n, k, d.get ? d : {
28
+ enumerable: true,
29
+ get: () => e[k]
30
+ });
31
+ }
32
+ }
33
+ }
34
+ n.default = e;
35
+ return Object.freeze(n);
36
+ }
37
+ const React__namespace = /* @__PURE__ */ _interopNamespace(React);
38
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
39
+ const yup__namespace = /* @__PURE__ */ _interopNamespace(yup);
40
+ const RELEASE_SCHEMA = yup__namespace.object().shape({
41
+ name: yup__namespace.string().trim().required()
42
+ }).required().noUnknown();
43
+ const ReleaseModal = ({
44
+ handleClose,
45
+ handleSubmit,
46
+ initialValues,
47
+ isLoading = false
48
+ }) => {
49
+ const { formatMessage } = reactIntl.useIntl();
50
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
51
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage({
52
+ id: "content-releases.modal.add-release-title",
53
+ defaultMessage: "New release"
54
+ }) }) }),
55
+ /* @__PURE__ */ jsxRuntime.jsx(
56
+ formik.Formik,
57
+ {
58
+ validateOnChange: false,
59
+ onSubmit: handleSubmit,
60
+ initialValues,
61
+ validationSchema: RELEASE_SCHEMA,
62
+ children: ({ values, errors, handleChange }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
63
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalBody, { children: /* @__PURE__ */ jsxRuntime.jsx(
64
+ designSystem.TextInput,
65
+ {
66
+ label: formatMessage({
67
+ id: "content-releases.modal.form.input.label.release-name",
68
+ defaultMessage: "Name"
69
+ }),
70
+ name: "name",
71
+ value: values.name,
72
+ error: errors.name,
73
+ onChange: handleChange,
74
+ required: true
75
+ }
76
+ ) }),
77
+ /* @__PURE__ */ jsxRuntime.jsx(
78
+ designSystem.ModalFooter,
79
+ {
80
+ startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
81
+ endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { name: "submit", loading: isLoading, disabled: !values.name, type: "submit", children: formatMessage({
82
+ id: "content-releases.modal.form.button.submit",
83
+ defaultMessage: "Continue"
84
+ }) })
85
+ }
86
+ )
87
+ ] })
88
+ }
89
+ )
90
+ ] });
91
+ };
92
+ const ReleaseInfoWrapper = styled__default.default(designSystem.Flex)`
93
+ align-self: stretch;
94
+ border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
95
+ border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
96
+ border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
97
+ `;
98
+ const StyledFlex = styled__default.default(designSystem.Flex)`
99
+ align-self: stretch;
100
+ cursor: ${({ disabled }) => disabled ? "not-allowed" : "pointer"};
101
+
102
+ svg path {
103
+ fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
104
+ }
105
+ span {
106
+ color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
107
+ }
108
+ `;
109
+ const PencilIcon = styled__default.default(icons.Pencil)`
110
+ width: ${({ theme }) => theme.spaces[4]};
111
+ height: ${({ theme }) => theme.spaces[4]};
112
+ path {
113
+ fill: ${({ theme }) => theme.colors.neutral600};
114
+ }
115
+ `;
116
+ const TrashIcon = styled__default.default(icons.Trash)`
117
+ width: ${({ theme }) => theme.spaces[4]};
118
+ height: ${({ theme }) => theme.spaces[4]};
119
+ path {
120
+ fill: ${({ theme }) => theme.colors.danger600};
121
+ }
122
+ `;
123
+ const PopoverButton = ({ onClick, disabled, children }) => {
124
+ return /* @__PURE__ */ jsxRuntime.jsx(
125
+ StyledFlex,
126
+ {
127
+ paddingTop: 2,
128
+ paddingBottom: 2,
129
+ paddingLeft: 4,
130
+ paddingRight: 4,
131
+ alignItems: "center",
132
+ gap: 2,
133
+ as: "button",
134
+ hasRadius: true,
135
+ onClick,
136
+ disabled,
137
+ children
138
+ }
139
+ );
140
+ };
141
+ const ReleaseDetailsLayout = ({
142
+ toggleEditReleaseModal,
143
+ toggleWarningSubmit,
144
+ children
145
+ }) => {
146
+ const { formatMessage } = reactIntl.useIntl();
147
+ const { releaseId } = reactRouterDom.useParams();
148
+ const [isPopoverVisible, setIsPopoverVisible] = React__namespace.useState(false);
149
+ const moreButtonRef = React__namespace.useRef(null);
150
+ const {
151
+ data,
152
+ isLoading: isLoadingDetails,
153
+ isError,
154
+ error
155
+ } = index.useGetReleaseQuery({ id: releaseId });
156
+ const [publishRelease, { isLoading: isPublishing }] = index.usePublishReleaseMutation();
157
+ const toggleNotification = helperPlugin.useNotification();
158
+ const { formatAPIError } = helperPlugin.useAPIErrorHandler();
159
+ const {
160
+ allowedActions: { canUpdate, canDelete }
161
+ } = helperPlugin.useRBAC(index.PERMISSIONS);
162
+ const release = data?.data;
163
+ const handleTogglePopover = () => {
164
+ setIsPopoverVisible((prev) => !prev);
165
+ };
166
+ const openReleaseModal = () => {
167
+ toggleEditReleaseModal();
168
+ handleTogglePopover();
169
+ };
170
+ const handlePublishRelease = async () => {
171
+ const response = await publishRelease({ id: releaseId });
172
+ if ("data" in response) {
173
+ toggleNotification({
174
+ type: "success",
175
+ message: formatMessage({
176
+ id: "content-releases.pages.ReleaseDetails.publish-notification-success",
177
+ defaultMessage: "Release was published successfully."
178
+ })
179
+ });
180
+ } else if (index.isAxiosError(response.error)) {
181
+ toggleNotification({
182
+ type: "warning",
183
+ message: formatAPIError(response.error)
184
+ });
185
+ } else {
186
+ toggleNotification({
187
+ type: "warning",
188
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
189
+ });
190
+ }
191
+ };
192
+ const openWarningConfirmDialog = () => {
193
+ toggleWarningSubmit();
194
+ handleTogglePopover();
195
+ };
196
+ if (isLoadingDetails) {
197
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
198
+ }
199
+ if (isError || !release) {
200
+ return /* @__PURE__ */ jsxRuntime.jsx(
201
+ reactRouterDom.Redirect,
202
+ {
203
+ to: {
204
+ pathname: "/plugins/content-releases",
205
+ state: {
206
+ errors: [
207
+ {
208
+ code: error?.code
209
+ }
210
+ ]
211
+ }
212
+ }
213
+ }
214
+ );
215
+ }
216
+ const totalEntries = release.actions.meta.count || 0;
217
+ const createdBy = `${release.createdBy.firstname} ${release.createdBy.lastname}`;
218
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoadingDetails, children: [
219
+ /* @__PURE__ */ jsxRuntime.jsx(
220
+ designSystem.HeaderLayout,
221
+ {
222
+ title: release.name,
223
+ subtitle: formatMessage(
224
+ {
225
+ id: "content-releases.pages.Details.header-subtitle",
226
+ defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
227
+ },
228
+ { number: totalEntries }
229
+ ),
230
+ navigationAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Link, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
231
+ id: "global.back",
232
+ defaultMessage: "Back"
233
+ }) }),
234
+ primaryAction: !release.releasedAt && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
235
+ /* @__PURE__ */ jsxRuntime.jsx(
236
+ designSystem.IconButton,
237
+ {
238
+ label: formatMessage({
239
+ id: "content-releases.header.actions.open-release-actions",
240
+ defaultMessage: "Release actions"
241
+ }),
242
+ ref: moreButtonRef,
243
+ onClick: handleTogglePopover,
244
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.More, {})
245
+ }
246
+ ),
247
+ isPopoverVisible && /* @__PURE__ */ jsxRuntime.jsxs(
248
+ designSystem.Popover,
249
+ {
250
+ source: moreButtonRef,
251
+ placement: "bottom-end",
252
+ onDismiss: handleTogglePopover,
253
+ spacing: 4,
254
+ minWidth: "242px",
255
+ children: [
256
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", justifyContent: "center", direction: "column", padding: 1, children: [
257
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverButton, { disabled: !canUpdate, onClick: openReleaseModal, children: [
258
+ /* @__PURE__ */ jsxRuntime.jsx(PencilIcon, {}),
259
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, children: formatMessage({
260
+ id: "content-releases.header.actions.edit",
261
+ defaultMessage: "Edit"
262
+ }) })
263
+ ] }),
264
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverButton, { disabled: !canDelete, onClick: openWarningConfirmDialog, children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(TrashIcon, {}),
266
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
267
+ id: "content-releases.header.actions.delete",
268
+ defaultMessage: "Delete"
269
+ }) })
270
+ ] })
271
+ ] }),
272
+ /* @__PURE__ */ jsxRuntime.jsxs(
273
+ ReleaseInfoWrapper,
274
+ {
275
+ direction: "column",
276
+ justifyContent: "center",
277
+ alignItems: "flex-start",
278
+ gap: 1,
279
+ padding: 5,
280
+ children: [
281
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
282
+ id: "content-releases.header.actions.created",
283
+ defaultMessage: "Created"
284
+ }) }),
285
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", color: "neutral300", children: [
286
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.RelativeTime, { timestamp: new Date(release.createdAt) }),
287
+ formatMessage(
288
+ {
289
+ id: "content-releases.header.actions.created.description",
290
+ defaultMessage: " by {createdBy}"
291
+ },
292
+ { createdBy }
293
+ )
294
+ ] })
295
+ ]
296
+ }
297
+ )
298
+ ]
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.publish, children: /* @__PURE__ */ jsxRuntime.jsx(
302
+ designSystem.Button,
303
+ {
304
+ size: "S",
305
+ variant: "default",
306
+ onClick: handlePublishRelease,
307
+ loading: isPublishing,
308
+ disabled: release.actions.meta.count === 0,
309
+ children: formatMessage({
310
+ id: "content-releases.header.actions.publish",
311
+ defaultMessage: "Publish"
312
+ })
313
+ }
314
+ ) })
315
+ ] })
316
+ }
317
+ ),
318
+ children
319
+ ] });
320
+ };
321
+ const ReleaseDetailsBody = () => {
322
+ const { formatMessage } = reactIntl.useIntl();
323
+ const { releaseId } = reactRouterDom.useParams();
324
+ const [{ query }] = helperPlugin.useQueryParams();
325
+ const toggleNotification = helperPlugin.useNotification();
326
+ const { formatAPIError } = helperPlugin.useAPIErrorHandler();
327
+ const {
328
+ data: releaseData,
329
+ isLoading: isReleaseLoading,
330
+ isError: isReleaseError,
331
+ error: releaseError
332
+ } = index.useGetReleaseQuery({ id: releaseId });
333
+ const release = releaseData?.data;
334
+ const {
335
+ isLoading,
336
+ isFetching,
337
+ isError,
338
+ data,
339
+ error: releaseActionsError
340
+ } = index.useGetReleaseActionsQuery({
341
+ ...query,
342
+ releaseId
343
+ });
344
+ const [updateReleaseAction] = index.useUpdateReleaseActionMutation();
345
+ const handleChangeType = async (e, actionId) => {
346
+ const response = await updateReleaseAction({
347
+ params: {
348
+ releaseId,
349
+ actionId
350
+ },
351
+ body: {
352
+ type: e.target.value
353
+ }
354
+ });
355
+ if ("error" in response) {
356
+ if (index.isAxiosError(response.error)) {
357
+ toggleNotification({
358
+ type: "warning",
359
+ message: formatAPIError(response.error)
360
+ });
361
+ } else {
362
+ toggleNotification({
363
+ type: "warning",
364
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
365
+ });
366
+ }
367
+ }
368
+ };
369
+ if (isLoading || isReleaseLoading) {
370
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) });
371
+ }
372
+ if (isError || isReleaseError || !release) {
373
+ const errorsArray = [];
374
+ if (releaseError) {
375
+ errorsArray.push({
376
+ code: releaseError.code
377
+ });
378
+ }
379
+ if (releaseActionsError) {
380
+ errorsArray.push({
381
+ code: releaseActionsError.code
382
+ });
383
+ }
384
+ return /* @__PURE__ */ jsxRuntime.jsx(
385
+ reactRouterDom.Redirect,
386
+ {
387
+ to: {
388
+ pathname: "/plugins/content-releases",
389
+ state: {
390
+ errors: errorsArray
391
+ }
392
+ }
393
+ }
394
+ );
395
+ }
396
+ const releaseActions = data?.data;
397
+ const releaseMeta = data?.meta;
398
+ if (!releaseActions || !releaseActions.length) {
399
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
400
+ helperPlugin.NoContent,
401
+ {
402
+ content: {
403
+ id: "content-releases.pages.Details.tab.emptyEntries",
404
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
405
+ },
406
+ action: /* @__PURE__ */ jsxRuntime.jsx(
407
+ v2.LinkButton,
408
+ {
409
+ as: reactRouterDom.Link,
410
+ to: {
411
+ pathname: "/content-manager"
412
+ },
413
+ style: { textDecoration: "none" },
414
+ variant: "secondary",
415
+ children: formatMessage({
416
+ id: "content-releases.page.Details.button.openContentManager",
417
+ defaultMessage: "Open the Content Manager"
418
+ })
419
+ }
420
+ )
421
+ }
422
+ ) });
423
+ }
424
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
425
+ /* @__PURE__ */ jsxRuntime.jsx(
426
+ helperPlugin.Table.Root,
427
+ {
428
+ rows: releaseActions.map((item) => ({
429
+ ...item,
430
+ id: Number(item.entry.id)
431
+ })),
432
+ colCount: releaseActions.length,
433
+ isLoading,
434
+ isFetching,
435
+ children: /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Content, { children: [
436
+ /* @__PURE__ */ jsxRuntime.jsxs(helperPlugin.Table.Head, { children: [
437
+ /* @__PURE__ */ jsxRuntime.jsx(
438
+ helperPlugin.Table.HeaderCell,
439
+ {
440
+ fieldSchemaType: "string",
441
+ label: formatMessage({
442
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
443
+ defaultMessage: "name"
444
+ }),
445
+ name: "name"
446
+ }
447
+ ),
448
+ /* @__PURE__ */ jsxRuntime.jsx(
449
+ helperPlugin.Table.HeaderCell,
450
+ {
451
+ fieldSchemaType: "string",
452
+ label: formatMessage({
453
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
454
+ defaultMessage: "locale"
455
+ }),
456
+ name: "locale"
457
+ }
458
+ ),
459
+ /* @__PURE__ */ jsxRuntime.jsx(
460
+ helperPlugin.Table.HeaderCell,
461
+ {
462
+ fieldSchemaType: "string",
463
+ label: formatMessage({
464
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
465
+ defaultMessage: "content-type"
466
+ }),
467
+ name: "content-type"
468
+ }
469
+ ),
470
+ /* @__PURE__ */ jsxRuntime.jsx(
471
+ helperPlugin.Table.HeaderCell,
472
+ {
473
+ fieldSchemaType: "string",
474
+ label: formatMessage({
475
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
476
+ defaultMessage: "action"
477
+ }),
478
+ name: "action"
479
+ }
480
+ )
481
+ ] }),
482
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.LoadingBody, {}),
483
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.Table.Body, { children: releaseActions.map(({ id, type, entry }) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
484
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${entry.contentType.mainFieldValue || entry.id}` }) }),
485
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: `${entry?.locale?.name ? entry.locale.name : "-"}` }) }),
486
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: entry.contentType.displayName || "" }) }),
487
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: release.releasedAt ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { children: formatMessage(
488
+ {
489
+ id: "content-releases.page.ReleaseDetails.table.action-published",
490
+ defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
491
+ },
492
+ {
493
+ isPublish: type === "publish",
494
+ b: (children) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children })
495
+ }
496
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(
497
+ index.ReleaseActionOptions,
498
+ {
499
+ selected: type,
500
+ handleChange: (e) => handleChangeType(e, id),
501
+ name: `release-action-${id}-type`
502
+ }
503
+ ) })
504
+ ] }, id)) })
505
+ ] })
506
+ }
507
+ ),
508
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
509
+ /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
510
+ /* @__PURE__ */ jsxRuntime.jsx(
511
+ helperPlugin.PaginationURLQuery,
512
+ {
513
+ pagination: {
514
+ pageCount: releaseMeta?.pagination?.pageCount || 0
515
+ }
516
+ }
517
+ )
518
+ ] })
519
+ ] }) });
520
+ };
521
+ const ReleaseDetailsPage = () => {
522
+ const { formatMessage } = reactIntl.useIntl();
523
+ const { releaseId } = reactRouterDom.useParams();
524
+ const toggleNotification = helperPlugin.useNotification();
525
+ const { formatAPIError } = helperPlugin.useAPIErrorHandler();
526
+ const { push } = reactRouterDom.useHistory();
527
+ const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
528
+ const [showWarningSubmit, setWarningSubmit] = React__namespace.useState(false);
529
+ const {
530
+ isLoading: isLoadingDetails,
531
+ data,
532
+ isSuccess: isSuccessDetails
533
+ } = index.useGetReleaseQuery({ id: releaseId });
534
+ const [updateRelease, { isLoading: isSubmittingForm }] = index.useUpdateReleaseMutation();
535
+ const [deleteRelease, { isLoading: isDeletingRelease }] = index.useDeleteReleaseMutation();
536
+ const toggleEditReleaseModal = () => {
537
+ setReleaseModalShown((prev) => !prev);
538
+ };
539
+ const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
540
+ if (isLoadingDetails) {
541
+ return /* @__PURE__ */ jsxRuntime.jsx(
542
+ ReleaseDetailsLayout,
543
+ {
544
+ toggleEditReleaseModal,
545
+ toggleWarningSubmit,
546
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) })
547
+ }
548
+ );
549
+ }
550
+ const title = isSuccessDetails && data?.data?.name || "";
551
+ const handleEditRelease = async (values) => {
552
+ const response = await updateRelease({
553
+ id: releaseId,
554
+ name: values.name
555
+ });
556
+ if ("data" in response) {
557
+ toggleNotification({
558
+ type: "success",
559
+ message: formatMessage({
560
+ id: "content-releases.modal.release-updated-notification-success",
561
+ defaultMessage: "Release updated."
562
+ })
563
+ });
564
+ } else if (index.isAxiosError(response.error)) {
565
+ toggleNotification({
566
+ type: "warning",
567
+ message: formatAPIError(response.error)
568
+ });
569
+ } else {
570
+ toggleNotification({
571
+ type: "warning",
572
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
573
+ });
574
+ }
575
+ toggleEditReleaseModal();
576
+ };
577
+ const handleDeleteRelease = async () => {
578
+ const response = await deleteRelease({
579
+ id: releaseId
580
+ });
581
+ if ("data" in response) {
582
+ push("/plugins/content-releases");
583
+ } else if (index.isAxiosError(response.error)) {
584
+ toggleNotification({
585
+ type: "warning",
586
+ message: formatAPIError(response.error)
587
+ });
588
+ } else {
589
+ toggleNotification({
590
+ type: "warning",
591
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
592
+ });
593
+ }
594
+ };
595
+ return /* @__PURE__ */ jsxRuntime.jsxs(
596
+ ReleaseDetailsLayout,
597
+ {
598
+ toggleEditReleaseModal,
599
+ toggleWarningSubmit,
600
+ children: [
601
+ /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsBody, {}),
602
+ releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
603
+ ReleaseModal,
604
+ {
605
+ handleClose: toggleEditReleaseModal,
606
+ handleSubmit: handleEditRelease,
607
+ isLoading: isLoadingDetails || isSubmittingForm,
608
+ initialValues: { name: title || "" }
609
+ }
610
+ ),
611
+ /* @__PURE__ */ jsxRuntime.jsx(
612
+ helperPlugin.ConfirmDialog,
613
+ {
614
+ bodyText: {
615
+ id: "content-releases.dialog.confirmation-message",
616
+ defaultMessage: "Are you sure you want to delete this release?"
617
+ },
618
+ isOpen: showWarningSubmit,
619
+ isConfirmButtonLoading: isDeletingRelease,
620
+ onToggleDialog: toggleWarningSubmit,
621
+ onConfirm: handleDeleteRelease
622
+ }
623
+ )
624
+ ]
625
+ }
626
+ );
627
+ };
628
+ const ProtectedReleaseDetailsPage = () => /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsx(ReleaseDetailsPage, {}) });
629
+ const ReleasesLayout = ({
630
+ isLoading,
631
+ totalReleases,
632
+ onClickAddRelease,
633
+ children
634
+ }) => {
635
+ const { formatMessage } = reactIntl.useIntl();
636
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Main, { "aria-busy": isLoading, children: [
637
+ /* @__PURE__ */ jsxRuntime.jsx(
638
+ designSystem.HeaderLayout,
639
+ {
640
+ title: formatMessage({
641
+ id: "content-releases.pages.Releases.title",
642
+ defaultMessage: "Releases"
643
+ }),
644
+ subtitle: !isLoading && formatMessage(
645
+ {
646
+ id: "content-releases.pages.Releases.header-subtitle",
647
+ defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
648
+ },
649
+ { number: totalReleases }
650
+ ),
651
+ primaryAction: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.create, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), onClick: onClickAddRelease, children: formatMessage({
652
+ id: "content-releases.header.actions.add-release",
653
+ defaultMessage: "New release"
654
+ }) }) })
655
+ }
656
+ ),
657
+ children
658
+ ] });
659
+ };
660
+ const LinkCard = styled__default.default(v2.Link)`
661
+ display: block;
662
+ `;
663
+ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
664
+ const { formatMessage } = reactIntl.useIntl();
665
+ if (isError) {
666
+ return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.AnErrorOccurred, {});
667
+ }
668
+ if (releases?.length === 0) {
669
+ return /* @__PURE__ */ jsxRuntime.jsx(
670
+ designSystem.EmptyStateLayout,
671
+ {
672
+ content: formatMessage(
673
+ {
674
+ id: "content-releases.page.Releases.tab.emptyEntries",
675
+ defaultMessage: "No releases"
676
+ },
677
+ {
678
+ target: sectionTitle
679
+ }
680
+ ),
681
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.EmptyDocuments, { width: "10rem" })
682
+ }
683
+ );
684
+ }
685
+ 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(
686
+ designSystem.Flex,
687
+ {
688
+ direction: "column",
689
+ justifyContent: "space-between",
690
+ padding: 4,
691
+ hasRadius: true,
692
+ background: "neutral0",
693
+ shadow: "tableShadow",
694
+ height: "100%",
695
+ width: "100%",
696
+ alignItems: "start",
697
+ gap: 2,
698
+ children: [
699
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
700
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: formatMessage(
701
+ {
702
+ id: "content-releases.page.Releases.release-item.entries",
703
+ defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
704
+ },
705
+ { number: actions.meta.count }
706
+ ) })
707
+ ]
708
+ }
709
+ ) }) }, id)) });
710
+ };
711
+ const INITIAL_FORM_VALUES = {
712
+ name: ""
713
+ };
714
+ const ReleasesPage = () => {
715
+ const location = reactRouterDom.useLocation();
716
+ const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
717
+ const toggleNotification = helperPlugin.useNotification();
718
+ const { formatMessage } = reactIntl.useIntl();
719
+ const { push, replace } = reactRouterDom.useHistory();
720
+ const { formatAPIError } = helperPlugin.useAPIErrorHandler();
721
+ const [{ query }, setQuery] = helperPlugin.useQueryParams();
722
+ const response = index.useGetReleasesQuery(query);
723
+ const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
724
+ const { isLoading, isSuccess, isError } = response;
725
+ React__namespace.useEffect(() => {
726
+ if (location?.state?.errors) {
727
+ toggleNotification({
728
+ type: "warning",
729
+ title: formatMessage({
730
+ id: "content-releases.pages.Releases.notification.error.title",
731
+ defaultMessage: "Your request could not be processed."
732
+ }),
733
+ message: formatMessage({
734
+ id: "content-releases.pages.Releases.notification.error.message",
735
+ defaultMessage: "Please try again or open another release."
736
+ })
737
+ });
738
+ replace({ state: null });
739
+ }
740
+ }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
741
+ const toggleAddReleaseModal = () => {
742
+ setReleaseModalShown((prev) => !prev);
743
+ };
744
+ if (isLoading) {
745
+ return /* @__PURE__ */ jsxRuntime.jsx(ReleasesLayout, { onClickAddRelease: toggleAddReleaseModal, isLoading: true, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {}) }) });
746
+ }
747
+ const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
748
+ const handleTabChange = (index2) => {
749
+ setQuery({
750
+ ...query,
751
+ page: 1,
752
+ pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
753
+ filters: {
754
+ releasedAt: {
755
+ $notNull: index2 === 0 ? false : true
756
+ }
757
+ }
758
+ });
759
+ };
760
+ const activeTab = response?.currentData?.meta?.activeTab || "pending";
761
+ const handleAddRelease = async (values) => {
762
+ const response2 = await createRelease({
763
+ name: values.name
764
+ });
765
+ if ("data" in response2) {
766
+ toggleNotification({
767
+ type: "success",
768
+ message: formatMessage({
769
+ id: "content-releases.modal.release-created-notification-success",
770
+ defaultMessage: "Release created."
771
+ })
772
+ });
773
+ push(`/plugins/content-releases/${response2.data.data.id}`);
774
+ } else if (index.isAxiosError(response2.error)) {
775
+ toggleNotification({
776
+ type: "warning",
777
+ message: formatAPIError(response2.error)
778
+ });
779
+ } else {
780
+ toggleNotification({
781
+ type: "warning",
782
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
783
+ });
784
+ }
785
+ };
786
+ return /* @__PURE__ */ jsxRuntime.jsxs(ReleasesLayout, { onClickAddRelease: toggleAddReleaseModal, totalReleases, children: [
787
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
788
+ /* @__PURE__ */ jsxRuntime.jsxs(
789
+ designSystem.TabGroup,
790
+ {
791
+ label: formatMessage({
792
+ id: "content-releases.pages.Releases.tab-group.label",
793
+ defaultMessage: "Releases list"
794
+ }),
795
+ variant: "simple",
796
+ initialSelectedTabIndex: ["pending", "done"].indexOf(activeTab),
797
+ onTabChange: handleTabChange,
798
+ children: [
799
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingBottom: 8, children: [
800
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs, { children: [
801
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
802
+ id: "content-releases.pages.Releases.tab.pending",
803
+ defaultMessage: "Pending"
804
+ }) }),
805
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
806
+ id: "content-releases.pages.Releases.tab.done",
807
+ defaultMessage: "Done"
808
+ }) })
809
+ ] }),
810
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {})
811
+ ] }),
812
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.TabPanels, { children: [
813
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
814
+ ReleasesGrid,
815
+ {
816
+ sectionTitle: "pending",
817
+ releases: response?.currentData?.data,
818
+ isError
819
+ }
820
+ ) }),
821
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
822
+ ReleasesGrid,
823
+ {
824
+ sectionTitle: "done",
825
+ releases: response?.currentData?.data,
826
+ isError
827
+ }
828
+ ) })
829
+ ] })
830
+ ]
831
+ }
832
+ ),
833
+ totalReleases > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
834
+ /* @__PURE__ */ jsxRuntime.jsx(
835
+ helperPlugin.PageSizeURLQuery,
836
+ {
837
+ options: ["8", "16", "32", "64"],
838
+ defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
839
+ }
840
+ ),
841
+ /* @__PURE__ */ jsxRuntime.jsx(
842
+ helperPlugin.PaginationURLQuery,
843
+ {
844
+ pagination: {
845
+ pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
846
+ }
847
+ }
848
+ )
849
+ ] })
850
+ ] }) }),
851
+ releaseModalShown && /* @__PURE__ */ jsxRuntime.jsx(
852
+ ReleaseModal,
853
+ {
854
+ handleClose: toggleAddReleaseModal,
855
+ handleSubmit: handleAddRelease,
856
+ isLoading: isSubmittingForm,
857
+ initialValues: INITIAL_FORM_VALUES
858
+ }
859
+ )
860
+ ] });
861
+ };
862
+ const ProtectedReleasesPage = () => /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.CheckPermissions, { permissions: index.PERMISSIONS.main, children: /* @__PURE__ */ jsxRuntime.jsx(ReleasesPage, {}) });
863
+ const App = () => {
864
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
865
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { exact: true, path: `/plugins/${index.pluginId}`, component: ProtectedReleasesPage }),
866
+ /* @__PURE__ */ jsxRuntime.jsx(
867
+ reactRouterDom.Route,
868
+ {
869
+ exact: true,
870
+ path: `/plugins/${index.pluginId}/:releaseId`,
871
+ component: ProtectedReleaseDetailsPage
872
+ }
873
+ )
874
+ ] });
875
+ };
876
+ exports.App = App;
877
+ //# sourceMappingURL=App-f2cafd81.js.map