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