@strapi/content-releases 0.0.0-experimental.d00dc50c81bce037c4321a90cc2f790eb3c51acb → 0.0.0-experimental.d23c1d5b0e45dd06ef09977f526c85468be05403

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 (108) hide show
  1. package/dist/_chunks/{App-gu1aiP6i.mjs → App-Cmn2Mkn7.mjs} +213 -200
  2. package/dist/_chunks/App-Cmn2Mkn7.mjs.map +1 -0
  3. package/dist/_chunks/{App-HjWtUYmc.js → App-FVorrIzF.js} +224 -211
  4. package/dist/_chunks/App-FVorrIzF.js.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-C8djn9fP.mjs} +1 -1
  6. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs.map → PurchaseContentReleases-C8djn9fP.mjs.map} +1 -1
  7. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-sD6ADHk2.js} +1 -1
  8. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js.map → PurchaseContentReleases-sD6ADHk2.js.map} +1 -1
  9. package/dist/_chunks/{en-ltT1TlKQ.mjs → en-B9Ur3VsE.mjs} +1 -1
  10. package/dist/_chunks/en-B9Ur3VsE.mjs.map +1 -0
  11. package/dist/_chunks/{en-HrREghh3.js → en-DtFJ5ViE.js} +1 -1
  12. package/dist/_chunks/en-DtFJ5ViE.js.map +1 -0
  13. package/dist/_chunks/{index-ZNwxYN8H.js → index-BfJLth9Z.js} +120 -189
  14. package/dist/_chunks/index-BfJLth9Z.js.map +1 -0
  15. package/dist/_chunks/{index-mvj9PSKd.mjs → index-DDohgTaQ.mjs} +125 -194
  16. package/dist/_chunks/index-DDohgTaQ.mjs.map +1 -0
  17. package/dist/admin/index.js +1 -15
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +2 -16
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/admin/src/components/CMReleasesContainer.d.ts +22 -0
  22. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  23. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  24. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  25. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  26. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  27. package/dist/admin/src/components/ReleaseModal.d.ts +16 -0
  28. package/dist/admin/src/constants.d.ts +58 -0
  29. package/dist/admin/src/index.d.ts +3 -0
  30. package/dist/admin/src/pages/App.d.ts +1 -0
  31. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  32. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  33. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  34. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  35. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  36. package/dist/admin/src/pluginId.d.ts +1 -0
  37. package/dist/admin/src/services/axios.d.ts +29 -0
  38. package/dist/admin/src/services/release.d.ts +429 -0
  39. package/dist/admin/src/store/hooks.d.ts +7 -0
  40. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  41. package/dist/admin/src/utils/time.d.ts +1 -0
  42. package/dist/server/index.js +83 -86
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +84 -86
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/server/src/bootstrap.d.ts +5 -0
  47. package/dist/server/src/bootstrap.d.ts.map +1 -0
  48. package/dist/server/src/constants.d.ts +12 -0
  49. package/dist/server/src/constants.d.ts.map +1 -0
  50. package/dist/server/src/content-types/index.d.ts +99 -0
  51. package/dist/server/src/content-types/index.d.ts.map +1 -0
  52. package/dist/server/src/content-types/release/index.d.ts +48 -0
  53. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  54. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  55. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  56. package/dist/server/src/content-types/release-action/index.d.ts +50 -0
  57. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  58. package/dist/server/src/content-types/release-action/schema.d.ts +49 -0
  59. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  60. package/dist/server/src/controllers/index.d.ts +20 -0
  61. package/dist/server/src/controllers/index.d.ts.map +1 -0
  62. package/dist/server/src/controllers/release-action.d.ts +10 -0
  63. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  64. package/dist/server/src/controllers/release.d.ts +12 -0
  65. package/dist/server/src/controllers/release.d.ts.map +1 -0
  66. package/dist/server/src/controllers/validation/release-action.d.ts +8 -0
  67. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  68. package/dist/server/src/controllers/validation/release.d.ts +2 -0
  69. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  70. package/dist/server/src/destroy.d.ts +5 -0
  71. package/dist/server/src/destroy.d.ts.map +1 -0
  72. package/dist/server/src/index.d.ts +2096 -0
  73. package/dist/server/src/index.d.ts.map +1 -0
  74. package/dist/server/src/migrations/index.d.ts +13 -0
  75. package/dist/server/src/migrations/index.d.ts.map +1 -0
  76. package/dist/server/src/register.d.ts +5 -0
  77. package/dist/server/src/register.d.ts.map +1 -0
  78. package/dist/server/src/routes/index.d.ts +35 -0
  79. package/dist/server/src/routes/index.d.ts.map +1 -0
  80. package/dist/server/src/routes/release-action.d.ts +18 -0
  81. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  82. package/dist/server/src/routes/release.d.ts +18 -0
  83. package/dist/server/src/routes/release.d.ts.map +1 -0
  84. package/dist/server/src/services/index.d.ts +1826 -0
  85. package/dist/server/src/services/index.d.ts.map +1 -0
  86. package/dist/server/src/services/release.d.ts +66 -0
  87. package/dist/server/src/services/release.d.ts.map +1 -0
  88. package/dist/server/src/services/scheduling.d.ts +18 -0
  89. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  90. package/dist/server/src/services/validation.d.ts +18 -0
  91. package/dist/server/src/services/validation.d.ts.map +1 -0
  92. package/dist/server/src/utils/index.d.ts +14 -0
  93. package/dist/server/src/utils/index.d.ts.map +1 -0
  94. package/dist/shared/contracts/release-actions.d.ts +131 -0
  95. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  96. package/dist/shared/contracts/releases.d.ts +182 -0
  97. package/dist/shared/contracts/releases.d.ts.map +1 -0
  98. package/dist/shared/types.d.ts +24 -0
  99. package/dist/shared/types.d.ts.map +1 -0
  100. package/dist/shared/validation-schemas.d.ts +2 -0
  101. package/dist/shared/validation-schemas.d.ts.map +1 -0
  102. package/package.json +26 -31
  103. package/dist/_chunks/App-HjWtUYmc.js.map +0 -1
  104. package/dist/_chunks/App-gu1aiP6i.mjs.map +0 -1
  105. package/dist/_chunks/en-HrREghh3.js.map +0 -1
  106. package/dist/_chunks/en-ltT1TlKQ.mjs.map +0 -1
  107. package/dist/_chunks/index-ZNwxYN8H.js.map +0 -1
  108. package/dist/_chunks/index-mvj9PSKd.mjs.map +0 -1
@@ -1,23 +1,51 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { RelativeTime as RelativeTime$1, useNotification, useAPIErrorHandler, useQueryParams, useTracking, LoadingIndicatorPage, CheckPermissions, PageSizeURLQuery, PaginationURLQuery, AnErrorOccurred, ConfirmDialog, useRBAC, useStrapiApp, NoContent, Table, CheckPagePermissions } from "@strapi/helper-plugin";
3
- import { useLocation, useHistory, useParams, Redirect, Link as Link$2, Switch, Route } from "react-router-dom";
4
- import { g as getTimezoneOffset, p as pluginId, u as useGetReleasesQuery, a as useCreateReleaseMutation, P as PERMISSIONS, i as isAxiosError, b as useGetReleaseQuery, c as useUpdateReleaseMutation, d as useDeleteReleaseMutation, e as usePublishReleaseMutation, f as useTypedDispatch, h as useGetReleaseActionsQuery, j as useUpdateReleaseActionMutation, R as ReleaseActionOptions, k as ReleaseActionMenu, r as releaseApi } from "./index-mvj9PSKd.mjs";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useNotification, useAPIErrorHandler, useQueryParams, useTracking, useRBAC, Page, Pagination, ConfirmDialog, BackButton, useStrapiApp, Table } from "@strapi/admin/strapi-admin";
3
+ import { useLocation, useNavigate, useParams, Navigate, Link as Link$1, Routes, Route } from "react-router-dom";
4
+ import { g as getTimezoneOffset, p as pluginId, u as useGetReleasesQuery, a as useCreateReleaseMutation, P as PERMISSIONS, i as isAxiosError, b as useGetReleaseQuery, c as useUpdateReleaseMutation, d as useDeleteReleaseMutation, e as usePublishReleaseMutation, f as useGetReleaseActionsQuery, h as useUpdateReleaseActionMutation, R as ReleaseActionOptions, j as ReleaseActionMenu, r as releaseApi } from "./index-DDohgTaQ.mjs";
5
5
  import * as React from "react";
6
- import { useLicenseLimits, unstable_useDocument } from "@strapi/admin/strapi-admin";
7
- import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, Alert, Main, HeaderLayout, ContentLayout, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem, Badge, Link as Link$1, IconButton, SingleSelect, SingleSelectOption, Tr, Td, Icon, Tooltip } from "@strapi/design-system";
6
+ import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, Alert, Main, HeaderLayout, ContentLayout, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem, Badge, IconButton, SingleSelect, SingleSelectOption, Tr, Td, Icon, Tooltip } from "@strapi/design-system";
8
7
  import { Link, Menu, LinkButton } from "@strapi/design-system/v2";
9
- import { Plus, EmptyDocuments, Pencil, Trash, ArrowLeft, More, CrossCircle, CheckCircle } from "@strapi/icons";
8
+ import { Plus, EmptyDocuments, Pencil, Trash, More, CrossCircle, CheckCircle } from "@strapi/icons";
9
+ import { unstable_useDocument } from "@strapi/plugin-content-manager/strapi-admin";
10
10
  import format from "date-fns/format";
11
11
  import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
12
12
  import { useIntl } from "react-intl";
13
13
  import styled from "styled-components";
14
- import { formatISO } from "date-fns";
14
+ import { intervalToDuration, isPast, formatISO } from "date-fns";
15
15
  import { Formik, Form, useFormikContext } from "formik";
16
16
  import * as yup from "yup";
17
- import "@reduxjs/toolkit/query";
18
- import "axios";
19
- import "@reduxjs/toolkit/query/react";
20
- import "react-redux";
17
+ import { useDispatch } from "react-redux";
18
+ import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
19
+ const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
20
+ const RelativeTime$1 = React.forwardRef(
21
+ ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
22
+ const { formatRelativeTime, formatDate, formatTime } = useIntl();
23
+ const interval = intervalToDuration({
24
+ start: timestamp,
25
+ end: Date.now()
26
+ // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
27
+ });
28
+ const unit = intervals.find((intervalUnit) => {
29
+ return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
30
+ });
31
+ const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
32
+ const customInterval = customIntervals.find(
33
+ (custom) => interval[custom.unit] < custom.threshold
34
+ );
35
+ const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
36
+ return /* @__PURE__ */ jsx(
37
+ "time",
38
+ {
39
+ ref: forwardedRef,
40
+ dateTime: timestamp.toISOString(),
41
+ role: "time",
42
+ title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
43
+ ...restProps,
44
+ children: displayText
45
+ }
46
+ );
47
+ }
48
+ );
21
49
  const RELEASE_SCHEMA = yup.object().shape({
22
50
  name: yup.string().trim().required(),
23
51
  scheduledAt: yup.string().nullable(),
@@ -255,6 +283,7 @@ const TimezoneComponent = ({ timezoneOptions }) => {
255
283
  }
256
284
  );
257
285
  };
286
+ const useTypedDispatch = useDispatch;
258
287
  const LinkCard = styled(Link)`
259
288
  display: block;
260
289
  `;
@@ -292,7 +321,7 @@ const getBadgeProps = (status) => {
292
321
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
293
322
  const { formatMessage } = useIntl();
294
323
  if (isError) {
295
- return /* @__PURE__ */ jsx(AnErrorOccurred, {});
324
+ return /* @__PURE__ */ jsx(Page.Error, {});
296
325
  }
297
326
  if (releases?.length === 0) {
298
327
  return /* @__PURE__ */ jsx(
@@ -357,9 +386,9 @@ const ReleasesPage = () => {
357
386
  const tabRef = React.useRef(null);
358
387
  const location = useLocation();
359
388
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
360
- const toggleNotification = useNotification();
389
+ const { toggleNotification } = useNotification();
361
390
  const { formatMessage } = useIntl();
362
- const { push, replace } = useHistory();
391
+ const navigate = useNavigate();
363
392
  const { formatAPIError } = useAPIErrorHandler();
364
393
  const [{ query }, setQuery] = useQueryParams();
365
394
  const response = useGetReleasesQuery(query);
@@ -367,13 +396,16 @@ const ReleasesPage = () => {
367
396
  const { getFeature } = useLicenseLimits();
368
397
  const { maximumReleases = 3 } = getFeature("cms-content-releases");
369
398
  const { trackUsage } = useTracking();
399
+ const {
400
+ allowedActions: { canCreate }
401
+ } = useRBAC(PERMISSIONS);
370
402
  const { isLoading, isSuccess, isError } = response;
371
403
  const activeTab = response?.currentData?.meta?.activeTab || "pending";
372
404
  const activeTabIndex = ["pending", "done"].indexOf(activeTab);
373
405
  React.useEffect(() => {
374
406
  if (location?.state?.errors) {
375
407
  toggleNotification({
376
- type: "warning",
408
+ type: "danger",
377
409
  title: formatMessage({
378
410
  id: "content-releases.pages.Releases.notification.error.title",
379
411
  defaultMessage: "Your request could not be processed."
@@ -383,9 +415,9 @@ const ReleasesPage = () => {
383
415
  defaultMessage: "Please try again or open another release."
384
416
  })
385
417
  });
386
- replace({ state: null });
418
+ navigate("", { replace: true, state: null });
387
419
  }
388
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
420
+ }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
389
421
  React.useEffect(() => {
390
422
  if (tabRef.current) {
391
423
  tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
@@ -395,7 +427,7 @@ const ReleasesPage = () => {
395
427
  setReleaseModalShown((prev) => !prev);
396
428
  };
397
429
  if (isLoading) {
398
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
430
+ return /* @__PURE__ */ jsx(Page.Loading, {});
399
431
  }
400
432
  const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
401
433
  const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
@@ -426,15 +458,15 @@ const ReleasesPage = () => {
426
458
  })
427
459
  });
428
460
  trackUsage("didCreateRelease");
429
- push(`/plugins/content-releases/${response2.data.data.id}`);
461
+ navigate(response2.data.data.id.toString());
430
462
  } else if (isAxiosError(response2.error)) {
431
463
  toggleNotification({
432
- type: "warning",
464
+ type: "danger",
433
465
  message: formatAPIError(response2.error)
434
466
  });
435
467
  } else {
436
468
  toggleNotification({
437
- type: "warning",
469
+ type: "danger",
438
470
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
439
471
  });
440
472
  }
@@ -451,7 +483,7 @@ const ReleasesPage = () => {
451
483
  id: "content-releases.pages.Releases.header-subtitle",
452
484
  defaultMessage: "Create and manage content updates"
453
485
  }),
454
- primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
486
+ primaryAction: canCreate ? /* @__PURE__ */ jsx(
455
487
  Button,
456
488
  {
457
489
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
@@ -462,7 +494,7 @@ const ReleasesPage = () => {
462
494
  defaultMessage: "New release"
463
495
  })
464
496
  }
465
- ) })
497
+ ) : null
466
498
  }
467
499
  ),
468
500
  /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -541,23 +573,17 @@ const ReleasesPage = () => {
541
573
  ]
542
574
  }
543
575
  ),
544
- response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
545
- /* @__PURE__ */ jsx(
546
- PageSizeURLQuery,
547
- {
548
- options: ["8", "16", "32", "64"],
549
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
550
- }
551
- ),
552
- /* @__PURE__ */ jsx(
553
- PaginationURLQuery,
554
- {
555
- pagination: {
556
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
557
- }
558
- }
559
- )
560
- ] }) : null
576
+ /* @__PURE__ */ jsxs(
577
+ Pagination.Root,
578
+ {
579
+ ...response?.currentData?.meta?.pagination,
580
+ defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
581
+ children: [
582
+ /* @__PURE__ */ jsx(Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
583
+ /* @__PURE__ */ jsx(Pagination.Links, {})
584
+ ]
585
+ }
586
+ )
561
587
  ] }) }),
562
588
  releaseModalShown && /* @__PURE__ */ jsx(
563
589
  ReleaseModal,
@@ -605,14 +631,18 @@ const TrashIcon = styled(Trash)`
605
631
  const TypographyMaxWidth = styled(Typography)`
606
632
  max-width: 300px;
607
633
  `;
608
- const EntryValidationText = ({ action, schema, components, entry }) => {
634
+ const EntryValidationText = ({ action, schema, entry }) => {
609
635
  const { formatMessage } = useIntl();
610
- const { validate } = unstable_useDocument();
611
- const { errors } = validate(entry, {
612
- contentType: schema,
613
- components,
614
- isCreatingEntry: false
615
- });
636
+ const { validate } = unstable_useDocument(
637
+ {
638
+ collectionType: schema?.kind ?? "",
639
+ model: schema?.uid ?? ""
640
+ },
641
+ {
642
+ skip: !schema
643
+ }
644
+ );
645
+ const errors = validate(entry) ?? {};
616
646
  if (Object.keys(errors).length > 0) {
617
647
  const validationErrorsMessages = Object.entries(errors).map(
618
648
  ([key, value]) => formatMessage(
@@ -660,18 +690,22 @@ const ReleaseDetailsLayout = ({
660
690
  isLoading: isLoadingDetails,
661
691
  isError,
662
692
  error
663
- } = useGetReleaseQuery({ id: releaseId });
693
+ } = useGetReleaseQuery(
694
+ { id: releaseId },
695
+ {
696
+ skip: !releaseId
697
+ }
698
+ );
664
699
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
665
- const toggleNotification = useNotification();
700
+ const { toggleNotification } = useNotification();
666
701
  const { formatAPIError } = useAPIErrorHandler();
667
- const {
668
- allowedActions: { canUpdate, canDelete }
669
- } = useRBAC(PERMISSIONS);
702
+ const { allowedActions } = useRBAC(PERMISSIONS);
703
+ const { canUpdate, canDelete, canPublish } = allowedActions;
670
704
  const dispatch = useTypedDispatch();
671
705
  const { trackUsage } = useTracking();
672
706
  const release = data?.data;
673
- const handlePublishRelease = async () => {
674
- const response = await publishRelease({ id: releaseId });
707
+ const handlePublishRelease = (id) => async () => {
708
+ const response = await publishRelease({ id });
675
709
  if ("data" in response) {
676
710
  toggleNotification({
677
711
  type: "success",
@@ -688,12 +722,12 @@ const ReleaseDetailsLayout = ({
688
722
  });
689
723
  } else if (isAxiosError(response.error)) {
690
724
  toggleNotification({
691
- type: "warning",
725
+ type: "danger",
692
726
  message: formatAPIError(response.error)
693
727
  });
694
728
  } else {
695
729
  toggleNotification({
696
- type: "warning",
730
+ type: "danger",
697
731
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
698
732
  });
699
733
  }
@@ -719,21 +753,19 @@ const ReleaseDetailsLayout = ({
719
753
  return release.createdBy.email;
720
754
  };
721
755
  if (isLoadingDetails) {
722
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
756
+ return /* @__PURE__ */ jsx(Page.Loading, {});
723
757
  }
724
758
  if (isError || !release) {
725
759
  return /* @__PURE__ */ jsx(
726
- Redirect,
760
+ Navigate,
727
761
  {
728
- to: {
729
- pathname: "/plugins/content-releases",
730
- state: {
731
- errors: [
732
- {
733
- code: error?.code
734
- }
735
- ]
736
- }
762
+ to: "..",
763
+ state: {
764
+ errors: [
765
+ {
766
+ code: error?.code
767
+ }
768
+ ]
737
769
  }
738
770
  }
739
771
  );
@@ -777,10 +809,7 @@ const ReleaseDetailsLayout = ({
777
809
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
778
810
  /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
779
811
  ] }),
780
- navigationAction: /* @__PURE__ */ jsx(Link$1, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
781
- id: "global.back",
782
- defaultMessage: "Back"
783
- }) }),
812
+ navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
784
813
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
785
814
  /* @__PURE__ */ jsxs(Menu.Root, { children: [
786
815
  /* @__PURE__ */ jsx(
@@ -864,12 +893,12 @@ const ReleaseDetailsLayout = ({
864
893
  id: "content-releases.header.actions.refresh",
865
894
  defaultMessage: "Refresh"
866
895
  }) }),
867
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
896
+ canPublish ? /* @__PURE__ */ jsx(
868
897
  Button,
869
898
  {
870
899
  size: "S",
871
900
  variant: "default",
872
- onClick: handlePublishRelease,
901
+ onClick: handlePublishRelease(release.id.toString()),
873
902
  loading: isPublishing,
874
903
  disabled: release.actions.meta.count === 0,
875
904
  children: formatMessage({
@@ -877,7 +906,7 @@ const ReleaseDetailsLayout = ({
877
906
  defaultMessage: "Publish"
878
907
  })
879
908
  }
880
- ) })
909
+ ) : null
881
910
  ] })
882
911
  }
883
912
  ),
@@ -904,26 +933,10 @@ const getGroupByOptionLabel = (value) => {
904
933
  defaultMessage: "Content-Types"
905
934
  };
906
935
  };
907
- const DEFAULT_RELEASE_DETAILS_HEADER = [
908
- {
909
- key: "__name__",
910
- fieldSchema: { type: "string" },
911
- metadatas: {
912
- label: {
913
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
914
- defaultMessage: "name"
915
- },
916
- searchable: false,
917
- sortable: false
918
- },
919
- name: "name"
920
- }
921
- ];
922
- const ReleaseDetailsBody = () => {
936
+ const ReleaseDetailsBody = ({ releaseId }) => {
923
937
  const { formatMessage } = useIntl();
924
- const { releaseId } = useParams();
925
938
  const [{ query }, setQuery] = useQueryParams();
926
- const toggleNotification = useNotification();
939
+ const { toggleNotification } = useNotification();
927
940
  const { formatAPIError } = useAPIErrorHandler();
928
941
  const {
929
942
  data: releaseData,
@@ -934,14 +947,17 @@ const ReleaseDetailsBody = () => {
934
947
  const {
935
948
  allowedActions: { canUpdate }
936
949
  } = useRBAC(PERMISSIONS);
937
- const { runHookWaterfall } = useStrapiApp();
938
- const {
939
- displayedHeaders,
940
- hasI18nEnabled
941
- } = runHookWaterfall(
950
+ const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
951
+ const { hasI18nEnabled } = runHookWaterfall(
942
952
  "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
943
953
  {
944
- displayedHeaders: DEFAULT_RELEASE_DETAILS_HEADER,
954
+ displayedHeaders: {
955
+ label: formatMessage({
956
+ id: "content-releases.page.ReleaseDetails.table.header.label.locale",
957
+ defaultMessage: "locale"
958
+ }),
959
+ name: "locale"
960
+ },
945
961
  hasI18nEnabled: false
946
962
  }
947
963
  );
@@ -975,19 +991,19 @@ const ReleaseDetailsBody = () => {
975
991
  if ("error" in response) {
976
992
  if (isAxiosError(response.error)) {
977
993
  toggleNotification({
978
- type: "warning",
994
+ type: "danger",
979
995
  message: formatAPIError(response.error)
980
996
  });
981
997
  } else {
982
998
  toggleNotification({
983
- type: "warning",
999
+ type: "danger",
984
1000
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
985
1001
  });
986
1002
  }
987
1003
  }
988
1004
  };
989
1005
  if (isLoading || isReleaseLoading) {
990
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
1006
+ return /* @__PURE__ */ jsx(Page.Loading, {});
991
1007
  }
992
1008
  const releaseActions = data?.data;
993
1009
  const releaseMeta = data?.meta;
@@ -1006,32 +1022,26 @@ const ReleaseDetailsBody = () => {
1006
1022
  });
1007
1023
  }
1008
1024
  return /* @__PURE__ */ jsx(
1009
- Redirect,
1025
+ Navigate,
1010
1026
  {
1011
- to: {
1012
- pathname: "/plugins/content-releases",
1013
- state: {
1014
- errors: errorsArray
1015
- }
1027
+ to: "..",
1028
+ state: {
1029
+ errors: errorsArray
1016
1030
  }
1017
1031
  }
1018
1032
  );
1019
1033
  }
1020
1034
  if (isError || !releaseActions) {
1021
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1035
+ return /* @__PURE__ */ jsx(Page.Error, {});
1022
1036
  }
1023
1037
  if (Object.keys(releaseActions).length === 0) {
1024
1038
  return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
1025
- NoContent,
1039
+ EmptyStateLayout,
1026
1040
  {
1027
- content: {
1028
- id: "content-releases.pages.Details.tab.emptyEntries",
1029
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1030
- },
1031
1041
  action: /* @__PURE__ */ jsx(
1032
1042
  LinkButton,
1033
1043
  {
1034
- as: Link$2,
1044
+ as: Link$1,
1035
1045
  to: {
1036
1046
  pathname: "/content-manager"
1037
1047
  },
@@ -1042,19 +1052,59 @@ const ReleaseDetailsBody = () => {
1042
1052
  defaultMessage: "Open the Content Manager"
1043
1053
  })
1044
1054
  }
1045
- )
1055
+ ),
1056
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" }),
1057
+ content: formatMessage({
1058
+ id: "content-releases.pages.Details.tab.emptyEntries",
1059
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1060
+ })
1046
1061
  }
1047
1062
  ) });
1048
1063
  }
1064
+ const groupByLabel = formatMessage({
1065
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1066
+ defaultMessage: "Group by"
1067
+ });
1068
+ const headers = [
1069
+ // ...displayedHeaders,
1070
+ {
1071
+ label: formatMessage({
1072
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
1073
+ defaultMessage: "name"
1074
+ }),
1075
+ name: "name"
1076
+ },
1077
+ {
1078
+ label: formatMessage({
1079
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1080
+ defaultMessage: "content-type"
1081
+ }),
1082
+ name: "content-type"
1083
+ },
1084
+ {
1085
+ label: formatMessage({
1086
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1087
+ defaultMessage: "action"
1088
+ }),
1089
+ name: "action"
1090
+ },
1091
+ ...!release.releasedAt ? [
1092
+ {
1093
+ label: formatMessage({
1094
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1095
+ defaultMessage: "status"
1096
+ }),
1097
+ name: "status"
1098
+ }
1099
+ ] : []
1100
+ ];
1049
1101
  const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1050
1102
  return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1051
1103
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1052
1104
  SingleSelect,
1053
1105
  {
1054
- "aria-label": formatMessage({
1055
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1056
- defaultMessage: "Group by"
1057
- }),
1106
+ placeholder: groupByLabel,
1107
+ "aria-label": groupByLabel,
1058
1108
  customizeContent: (value) => formatMessage(
1059
1109
  {
1060
1110
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1078,55 +1128,11 @@ const ReleaseDetailsBody = () => {
1078
1128
  ...item,
1079
1129
  id: Number(item.entry.id)
1080
1130
  })),
1081
- colCount: releaseActions[key].length,
1082
- isLoading,
1083
- isFetching,
1131
+ headers,
1132
+ isLoading: isLoading || isFetching,
1084
1133
  children: /* @__PURE__ */ jsxs(Table.Content, { children: [
1085
- /* @__PURE__ */ jsxs(Table.Head, { children: [
1086
- displayedHeaders.map(({ key: key2, fieldSchema, metadatas, name }) => /* @__PURE__ */ jsx(
1087
- Table.HeaderCell,
1088
- {
1089
- fieldSchemaType: fieldSchema.type,
1090
- label: formatMessage(metadatas.label),
1091
- name
1092
- },
1093
- key2
1094
- )),
1095
- /* @__PURE__ */ jsx(
1096
- Table.HeaderCell,
1097
- {
1098
- fieldSchemaType: "string",
1099
- label: formatMessage({
1100
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1101
- defaultMessage: "content-type"
1102
- }),
1103
- name: "content-type"
1104
- }
1105
- ),
1106
- /* @__PURE__ */ jsx(
1107
- Table.HeaderCell,
1108
- {
1109
- fieldSchemaType: "string",
1110
- label: formatMessage({
1111
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
1112
- defaultMessage: "action"
1113
- }),
1114
- name: "action"
1115
- }
1116
- ),
1117
- !release.releasedAt && /* @__PURE__ */ jsx(
1118
- Table.HeaderCell,
1119
- {
1120
- fieldSchemaType: "string",
1121
- label: formatMessage({
1122
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
1123
- defaultMessage: "status"
1124
- }),
1125
- name: "status"
1126
- }
1127
- )
1128
- ] }),
1129
- /* @__PURE__ */ jsx(Table.LoadingBody, {}),
1134
+ /* @__PURE__ */ jsx(Table.Head, { children: headers.map((header) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...header }, header.name)) }),
1135
+ /* @__PURE__ */ jsx(Table.Loading, {}),
1130
1136
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1131
1137
  ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1132
1138
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
@@ -1184,34 +1190,39 @@ const ReleaseDetailsBody = () => {
1184
1190
  }
1185
1191
  )
1186
1192
  ] }, `releases-group-${key}`)),
1187
- /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1188
- /* @__PURE__ */ jsx(PageSizeURLQuery, { defaultValue: releaseMeta?.pagination?.pageSize.toString() }),
1189
- /* @__PURE__ */ jsx(
1190
- PaginationURLQuery,
1191
- {
1192
- pagination: {
1193
- pageCount: releaseMeta?.pagination?.pageCount || 0
1194
- }
1195
- }
1196
- )
1197
- ] })
1193
+ /* @__PURE__ */ jsxs(
1194
+ Pagination.Root,
1195
+ {
1196
+ ...releaseMeta?.pagination,
1197
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1198
+ children: [
1199
+ /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1200
+ /* @__PURE__ */ jsx(Pagination.Links, {})
1201
+ ]
1202
+ }
1203
+ )
1198
1204
  ] }) });
1199
1205
  };
1200
1206
  const ReleaseDetailsPage = () => {
1201
1207
  const { formatMessage } = useIntl();
1202
1208
  const { releaseId } = useParams();
1203
- const toggleNotification = useNotification();
1209
+ const { toggleNotification } = useNotification();
1204
1210
  const { formatAPIError } = useAPIErrorHandler();
1205
- const { replace } = useHistory();
1211
+ const navigate = useNavigate();
1206
1212
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1207
1213
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1208
1214
  const {
1209
1215
  isLoading: isLoadingDetails,
1210
1216
  data,
1211
1217
  isSuccess: isSuccessDetails
1212
- } = useGetReleaseQuery({ id: releaseId });
1218
+ } = useGetReleaseQuery(
1219
+ { id: releaseId },
1220
+ {
1221
+ skip: !releaseId
1222
+ }
1223
+ );
1213
1224
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1214
- const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1225
+ const [deleteRelease] = useDeleteReleaseMutation();
1215
1226
  const toggleEditReleaseModal = () => {
1216
1227
  setReleaseModalShown((prev) => !prev);
1217
1228
  };
@@ -1222,10 +1233,13 @@ const ReleaseDetailsPage = () => {
1222
1233
  {
1223
1234
  toggleEditReleaseModal,
1224
1235
  toggleWarningSubmit,
1225
- children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1236
+ children: /* @__PURE__ */ jsx(Page.Loading, {})
1226
1237
  }
1227
1238
  );
1228
1239
  }
1240
+ if (!releaseId) {
1241
+ return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1242
+ }
1229
1243
  const releaseData = isSuccessDetails && data?.data || null;
1230
1244
  const title = releaseData?.name || "";
1231
1245
  const timezone = releaseData?.timezone ?? null;
@@ -1250,12 +1264,12 @@ const ReleaseDetailsPage = () => {
1250
1264
  toggleEditReleaseModal();
1251
1265
  } else if (isAxiosError(response.error)) {
1252
1266
  toggleNotification({
1253
- type: "warning",
1267
+ type: "danger",
1254
1268
  message: formatAPIError(response.error)
1255
1269
  });
1256
1270
  } else {
1257
1271
  toggleNotification({
1258
- type: "warning",
1272
+ type: "danger",
1259
1273
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1260
1274
  });
1261
1275
  }
@@ -1265,15 +1279,15 @@ const ReleaseDetailsPage = () => {
1265
1279
  id: releaseId
1266
1280
  });
1267
1281
  if ("data" in response) {
1268
- replace("/plugins/content-releases");
1282
+ navigate("..");
1269
1283
  } else if (isAxiosError(response.error)) {
1270
1284
  toggleNotification({
1271
- type: "warning",
1285
+ type: "danger",
1272
1286
  message: formatAPIError(response.error)
1273
1287
  });
1274
1288
  } else {
1275
1289
  toggleNotification({
1276
- type: "warning",
1290
+ type: "danger",
1277
1291
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1278
1292
  });
1279
1293
  }
@@ -1284,7 +1298,7 @@ const ReleaseDetailsPage = () => {
1284
1298
  toggleEditReleaseModal,
1285
1299
  toggleWarningSubmit,
1286
1300
  children: [
1287
- /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1301
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1288
1302
  releaseModalShown && /* @__PURE__ */ jsx(
1289
1303
  ReleaseModal,
1290
1304
  {
@@ -1304,14 +1318,13 @@ const ReleaseDetailsPage = () => {
1304
1318
  /* @__PURE__ */ jsx(
1305
1319
  ConfirmDialog,
1306
1320
  {
1307
- bodyText: {
1321
+ isOpen: showWarningSubmit,
1322
+ onClose: toggleWarningSubmit,
1323
+ onConfirm: handleDeleteRelease,
1324
+ children: formatMessage({
1308
1325
  id: "content-releases.dialog.confirmation-message",
1309
1326
  defaultMessage: "Are you sure you want to delete this release?"
1310
- },
1311
- isOpen: showWarningSubmit,
1312
- isConfirmButtonLoading: isDeletingRelease,
1313
- onToggleDialog: toggleWarningSubmit,
1314
- onConfirm: handleDeleteRelease
1327
+ })
1315
1328
  }
1316
1329
  )
1317
1330
  ]
@@ -1319,12 +1332,12 @@ const ReleaseDetailsPage = () => {
1319
1332
  );
1320
1333
  };
1321
1334
  const App = () => {
1322
- return /* @__PURE__ */ jsx(CheckPagePermissions, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Switch, { children: [
1323
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}`, component: ReleasesPage }),
1324
- /* @__PURE__ */ jsx(Route, { exact: true, path: `/plugins/${pluginId}/:releaseId`, component: ReleaseDetailsPage })
1335
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1336
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1337
+ /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1325
1338
  ] }) });
1326
1339
  };
1327
1340
  export {
1328
1341
  App
1329
1342
  };
1330
- //# sourceMappingURL=App-gu1aiP6i.mjs.map
1343
+ //# sourceMappingURL=App-Cmn2Mkn7.mjs.map