@strapi/content-releases 0.0.0-experimental.ec089c69ff953942fb39de032c12daafaf7176e6 → 0.0.0-experimental.edc24aaa3bb5a90fa5fd4fee208167dd4e2e38d4

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 (139) hide show
  1. package/LICENSE +17 -1
  2. package/dist/_chunks/{App-HjWtUYmc.js → App-D-lWdVb2.js} +594 -575
  3. package/dist/_chunks/App-D-lWdVb2.js.map +1 -0
  4. package/dist/_chunks/{App-gu1aiP6i.mjs → App-UQxgTJY5.mjs} +575 -554
  5. package/dist/_chunks/App-UQxgTJY5.mjs.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
  7. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
  9. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  10. package/dist/_chunks/ReleasesSettingsPage-CuUXvABk.mjs +178 -0
  11. package/dist/_chunks/ReleasesSettingsPage-CuUXvABk.mjs.map +1 -0
  12. package/dist/_chunks/ReleasesSettingsPage-xfAoY8N3.js +178 -0
  13. package/dist/_chunks/ReleasesSettingsPage-xfAoY8N3.js.map +1 -0
  14. package/dist/_chunks/{en-HrREghh3.js → en-BCDLTJn3.js} +8 -2
  15. package/dist/_chunks/en-BCDLTJn3.js.map +1 -0
  16. package/dist/_chunks/{en-ltT1TlKQ.mjs → en-CGXIF4vQ.mjs} +8 -2
  17. package/dist/_chunks/en-CGXIF4vQ.mjs.map +1 -0
  18. package/dist/_chunks/index-b3Ej95H7.mjs +1099 -0
  19. package/dist/_chunks/index-b3Ej95H7.mjs.map +1 -0
  20. package/dist/_chunks/index-jnv9zdcE.js +1118 -0
  21. package/dist/_chunks/index-jnv9zdcE.js.map +1 -0
  22. package/dist/_chunks/schemas-63pFihNF.mjs +44 -0
  23. package/dist/_chunks/schemas-63pFihNF.mjs.map +1 -0
  24. package/dist/_chunks/schemas-z5zp-_Gd.js +62 -0
  25. package/dist/_chunks/schemas-z5zp-_Gd.js.map +1 -0
  26. package/dist/admin/index.js +1 -15
  27. package/dist/admin/index.js.map +1 -1
  28. package/dist/admin/index.mjs +2 -16
  29. package/dist/admin/index.mjs.map +1 -1
  30. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  31. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  32. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  33. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  34. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  35. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
  36. package/dist/admin/src/components/ReleaseModal.d.ts +17 -0
  37. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  38. package/dist/admin/src/constants.d.ts +76 -0
  39. package/dist/admin/src/index.d.ts +3 -0
  40. package/dist/admin/src/modules/hooks.d.ts +7 -0
  41. package/dist/admin/src/pages/App.d.ts +1 -0
  42. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  43. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  44. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  45. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  46. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  47. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  48. package/dist/admin/src/pluginId.d.ts +1 -0
  49. package/dist/admin/src/services/release.d.ts +110 -0
  50. package/dist/admin/src/store/hooks.d.ts +7 -0
  51. package/dist/admin/src/utils/api.d.ts +6 -0
  52. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  53. package/dist/admin/src/utils/time.d.ts +10 -0
  54. package/dist/admin/src/validation/schemas.d.ts +6 -0
  55. package/dist/server/index.js +845 -675
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/server/index.mjs +846 -675
  58. package/dist/server/index.mjs.map +1 -1
  59. package/dist/server/src/bootstrap.d.ts +5 -0
  60. package/dist/server/src/bootstrap.d.ts.map +1 -0
  61. package/dist/server/src/constants.d.ts +21 -0
  62. package/dist/server/src/constants.d.ts.map +1 -0
  63. package/dist/server/src/content-types/index.d.ts +97 -0
  64. package/dist/server/src/content-types/index.d.ts.map +1 -0
  65. package/dist/server/src/content-types/release/index.d.ts +48 -0
  66. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  67. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  68. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  69. package/dist/server/src/content-types/release-action/index.d.ts +48 -0
  70. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  71. package/dist/server/src/content-types/release-action/schema.d.ts +47 -0
  72. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  73. package/dist/server/src/controllers/index.d.ts +23 -0
  74. package/dist/server/src/controllers/index.d.ts.map +1 -0
  75. package/dist/server/src/controllers/release-action.d.ts +9 -0
  76. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  77. package/dist/server/src/controllers/release.d.ts +17 -0
  78. package/dist/server/src/controllers/release.d.ts.map +1 -0
  79. package/dist/server/src/controllers/settings.d.ts +11 -0
  80. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  81. package/dist/server/src/controllers/validation/release-action.d.ts +14 -0
  82. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  83. package/dist/server/src/controllers/validation/release.d.ts +4 -0
  84. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  85. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  86. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  87. package/dist/server/src/destroy.d.ts +5 -0
  88. package/dist/server/src/destroy.d.ts.map +1 -0
  89. package/dist/server/src/index.d.ts +2111 -0
  90. package/dist/server/src/index.d.ts.map +1 -0
  91. package/dist/server/src/middlewares/documents.d.ts +6 -0
  92. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  93. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  94. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  95. package/dist/server/src/migrations/index.d.ts +13 -0
  96. package/dist/server/src/migrations/index.d.ts.map +1 -0
  97. package/dist/server/src/register.d.ts +5 -0
  98. package/dist/server/src/register.d.ts.map +1 -0
  99. package/dist/server/src/routes/index.d.ts +51 -0
  100. package/dist/server/src/routes/index.d.ts.map +1 -0
  101. package/dist/server/src/routes/release-action.d.ts +18 -0
  102. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  103. package/dist/server/src/routes/release.d.ts +18 -0
  104. package/dist/server/src/routes/release.d.ts.map +1 -0
  105. package/dist/server/src/routes/settings.d.ts +18 -0
  106. package/dist/server/src/routes/settings.d.ts.map +1 -0
  107. package/dist/server/src/services/index.d.ts +1826 -0
  108. package/dist/server/src/services/index.d.ts.map +1 -0
  109. package/dist/server/src/services/release-action.d.ts +36 -0
  110. package/dist/server/src/services/release-action.d.ts.map +1 -0
  111. package/dist/server/src/services/release.d.ts +31 -0
  112. package/dist/server/src/services/release.d.ts.map +1 -0
  113. package/dist/server/src/services/scheduling.d.ts +18 -0
  114. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  115. package/dist/server/src/services/settings.d.ts +13 -0
  116. package/dist/server/src/services/settings.d.ts.map +1 -0
  117. package/dist/server/src/services/validation.d.ts +18 -0
  118. package/dist/server/src/services/validation.d.ts.map +1 -0
  119. package/dist/server/src/utils/index.d.ts +35 -0
  120. package/dist/server/src/utils/index.d.ts.map +1 -0
  121. package/dist/shared/contracts/release-actions.d.ts +132 -0
  122. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  123. package/dist/shared/contracts/releases.d.ts +183 -0
  124. package/dist/shared/contracts/releases.d.ts.map +1 -0
  125. package/dist/shared/contracts/settings.d.ts +39 -0
  126. package/dist/shared/contracts/settings.d.ts.map +1 -0
  127. package/dist/shared/types.d.ts +24 -0
  128. package/dist/shared/types.d.ts.map +1 -0
  129. package/package.json +30 -36
  130. package/dist/_chunks/App-HjWtUYmc.js.map +0 -1
  131. package/dist/_chunks/App-gu1aiP6i.mjs.map +0 -1
  132. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +0 -1
  133. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +0 -1
  134. package/dist/_chunks/en-HrREghh3.js.map +0 -1
  135. package/dist/_chunks/en-ltT1TlKQ.mjs.map +0 -1
  136. package/dist/_chunks/index-ZNwxYN8H.js +0 -1335
  137. package/dist/_chunks/index-ZNwxYN8H.js.map +0 -1
  138. package/dist/_chunks/index-mvj9PSKd.mjs +0 -1314
  139. package/dist/_chunks/index-mvj9PSKd.mjs.map +0 -1
@@ -1,45 +1,54 @@
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, Layouts, Pagination, isFetchError, ConfirmDialog, BackButton, useStrapiApp, Table } from "@strapi/admin/strapi-admin";
3
+ import { useLocation, useNavigate, NavLink, useParams, Navigate, Link as Link$1, Routes, Route } from "react-router-dom";
4
+ import { g as getTimezones, p as pluginId, u as useGetReleasesQuery, a as useGetReleaseSettingsQuery, b as useCreateReleaseMutation, P as PERMISSIONS, c as useGetReleaseQuery, d as useUpdateReleaseMutation, e as useDeleteReleaseMutation, f as usePublishReleaseMutation, h as getTimezoneOffset, i as useGetReleaseActionsQuery, j as useUpdateReleaseActionMutation, R as ReleaseActionOptions, k as ReleaseActionMenu, r as releaseApi } from "./index-b3Ej95H7.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";
8
- import { Link, Menu, LinkButton } from "@strapi/design-system/v2";
9
- import { Plus, EmptyDocuments, Pencil, Trash, ArrowLeft, More, CrossCircle, CheckCircle } from "@strapi/icons";
10
- import format from "date-fns/format";
6
+ import { unstable_useDocument } from "@strapi/content-manager/strapi-admin";
7
+ import { Modal, Flex, Field, TextInput, Box, Checkbox, Typography, DatePicker, TimePicker, Button, Combobox, ComboboxOption, Link, Alert, Main, Tabs, Divider, EmptyStateLayout, Grid, Badge, MenuItem, Dialog, SimpleMenu, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
8
+ import { Plus, Pencil, Trash, More, CrossCircle, CheckCircle, ArrowsCounterClockwise } from "@strapi/icons";
9
+ import { EmptyDocuments } from "@strapi/icons/symbols";
10
+ import format$1 from "date-fns/format";
11
11
  import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
12
12
  import { useIntl } from "react-intl";
13
- import styled from "styled-components";
14
- import { formatISO } from "date-fns";
13
+ import { styled } from "styled-components";
14
+ import { intervalToDuration, isPast, formatISO, format } from "date-fns";
15
15
  import { Formik, Form, useFormikContext } from "formik";
16
- import * as yup from "yup";
17
- import "@reduxjs/toolkit/query";
18
- import "axios";
19
- import "@reduxjs/toolkit/query/react";
20
- import "react-redux";
21
- const RELEASE_SCHEMA = yup.object().shape({
22
- name: yup.string().trim().required(),
23
- scheduledAt: yup.string().nullable(),
24
- isScheduled: yup.boolean().optional(),
25
- time: yup.string().when("isScheduled", {
26
- is: true,
27
- then: yup.string().trim().required(),
28
- otherwise: yup.string().nullable()
29
- }),
30
- timezone: yup.string().when("isScheduled", {
31
- is: true,
32
- then: yup.string().required().nullable(),
33
- otherwise: yup.string().nullable()
34
- }),
35
- date: yup.string().when("isScheduled", {
36
- is: true,
37
- then: yup.string().required().nullable(),
38
- otherwise: yup.string().nullable()
39
- })
40
- }).required().noUnknown();
16
+ import { R as RELEASE_SCHEMA } from "./schemas-63pFihNF.mjs";
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
+ );
41
49
  const ReleaseModal = ({
42
50
  handleClose,
51
+ open,
43
52
  handleSubmit,
44
53
  initialValues,
45
54
  isLoading = false
@@ -63,8 +72,8 @@ const ReleaseModal = ({
63
72
  );
64
73
  return currentTimezone?.value || systemTimezone.value;
65
74
  };
66
- return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
67
- /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
75
+ return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
76
+ /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: formatMessage(
68
77
  {
69
78
  id: "content-releases.modal.title",
70
79
  defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
@@ -87,133 +96,143 @@ const ReleaseModal = ({
87
96
  },
88
97
  validationSchema: RELEASE_SCHEMA,
89
98
  validateOnChange: false,
90
- children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
91
- /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
92
- /* @__PURE__ */ jsx(
93
- TextInput,
94
- {
95
- label: formatMessage({
96
- id: "content-releases.modal.form.input.label.release-name",
97
- defaultMessage: "Name"
98
- }),
99
- name: "name",
100
- value: values.name,
101
- error: errors.name,
102
- onChange: handleChange,
103
- required: true
104
- }
105
- ),
106
- /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
107
- Checkbox,
108
- {
109
- name: "isScheduled",
110
- value: values.isScheduled,
111
- onChange: (event) => {
112
- setFieldValue("isScheduled", event.target.checked);
113
- if (!event.target.checked) {
114
- setFieldValue("date", null);
115
- setFieldValue("time", "");
116
- setFieldValue("timezone", null);
117
- } else {
118
- setFieldValue("date", initialValues.date);
119
- setFieldValue("time", initialValues.time);
120
- setFieldValue("timezone", initialValues.timezone ?? systemTimezone?.value);
121
- }
122
- },
123
- children: /* @__PURE__ */ jsx(
124
- Typography,
125
- {
126
- textColor: values.isScheduled ? "primary600" : "neutral800",
127
- fontWeight: values.isScheduled ? "semiBold" : "regular",
128
- children: formatMessage({
129
- id: "modal.form.input.label.schedule-release",
130
- defaultMessage: "Schedule release"
131
- })
132
- }
133
- )
134
- }
135
- ) }),
136
- values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
137
- /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
138
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
139
- DatePicker,
140
- {
141
- label: formatMessage({
142
- id: "content-releases.modal.form.input.label.date",
143
- defaultMessage: "Date"
144
- }),
145
- name: "date",
146
- error: errors.date,
147
- onChange: (date) => {
148
- const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
149
- setFieldValue("date", isoFormatDate);
150
- },
151
- clearLabel: formatMessage({
152
- id: "content-releases.modal.form.input.clearLabel",
153
- defaultMessage: "Clear"
154
- }),
155
- onClear: () => {
99
+ children: ({ values, errors, handleChange, setFieldValue }) => {
100
+ return /* @__PURE__ */ jsxs(Form, { children: [
101
+ /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
102
+ /* @__PURE__ */ jsxs(
103
+ Field.Root,
104
+ {
105
+ name: "name",
106
+ error: errors.name && formatMessage({ id: errors.name, defaultMessage: errors.name }),
107
+ required: true,
108
+ children: [
109
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
110
+ id: "content-releases.modal.form.input.label.release-name",
111
+ defaultMessage: "Name"
112
+ }) }),
113
+ /* @__PURE__ */ jsx(TextInput, { value: values.name, onChange: handleChange }),
114
+ /* @__PURE__ */ jsx(Field.Error, {})
115
+ ]
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
119
+ Checkbox,
120
+ {
121
+ name: "isScheduled",
122
+ checked: values.isScheduled,
123
+ onCheckedChange: (checked) => {
124
+ setFieldValue("isScheduled", checked);
125
+ if (!checked) {
156
126
  setFieldValue("date", null);
157
- },
158
- selectedDate: values.date || void 0,
159
- required: true,
160
- minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
161
- }
162
- ) }),
163
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
164
- TimePicker,
165
- {
166
- label: formatMessage({
167
- id: "content-releases.modal.form.input.label.time",
168
- defaultMessage: "Time"
169
- }),
170
- name: "time",
171
- error: errors.time,
172
- onChange: (time) => {
173
- setFieldValue("time", time);
174
- },
175
- clearLabel: formatMessage({
176
- id: "content-releases.modal.form.input.clearLabel",
177
- defaultMessage: "Clear"
178
- }),
179
- onClear: () => {
180
127
  setFieldValue("time", "");
181
- },
182
- value: values.time || void 0,
183
- required: true
184
- }
185
- ) })
186
- ] }),
187
- /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
188
- ] })
189
- ] }) }),
190
- /* @__PURE__ */ jsx(
191
- ModalFooter,
192
- {
193
- startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
194
- endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
128
+ setFieldValue("timezone", null);
129
+ } else {
130
+ setFieldValue("date", initialValues.date);
131
+ setFieldValue("time", initialValues.time);
132
+ setFieldValue(
133
+ "timezone",
134
+ initialValues.timezone ?? systemTimezone?.value
135
+ );
136
+ }
137
+ },
138
+ children: /* @__PURE__ */ jsx(
139
+ Typography,
140
+ {
141
+ textColor: values.isScheduled ? "primary600" : "neutral800",
142
+ fontWeight: values.isScheduled ? "semiBold" : "regular",
143
+ children: formatMessage({
144
+ id: "modal.form.input.label.schedule-release",
145
+ defaultMessage: "Schedule release"
146
+ })
147
+ }
148
+ )
149
+ }
150
+ ) }),
151
+ values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
152
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
153
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
154
+ Field.Root,
155
+ {
156
+ name: "date",
157
+ error: errors.date && formatMessage({ id: errors.date, defaultMessage: errors.date }),
158
+ required: true,
159
+ children: [
160
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
161
+ id: "content-releases.modal.form.input.label.date",
162
+ defaultMessage: "Date"
163
+ }) }),
164
+ /* @__PURE__ */ jsx(
165
+ DatePicker,
166
+ {
167
+ onChange: (date) => {
168
+ const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
169
+ setFieldValue("date", isoFormatDate);
170
+ },
171
+ clearLabel: formatMessage({
172
+ id: "content-releases.modal.form.input.clearLabel",
173
+ defaultMessage: "Clear"
174
+ }),
175
+ onClear: () => {
176
+ setFieldValue("date", null);
177
+ },
178
+ value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
179
+ minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
180
+ }
181
+ ),
182
+ /* @__PURE__ */ jsx(Field.Error, {})
183
+ ]
184
+ }
185
+ ) }),
186
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
187
+ Field.Root,
188
+ {
189
+ name: "time",
190
+ error: errors.time && formatMessage({ id: errors.time, defaultMessage: errors.time }),
191
+ required: true,
192
+ children: [
193
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
194
+ id: "content-releases.modal.form.input.label.time",
195
+ defaultMessage: "Time"
196
+ }) }),
197
+ /* @__PURE__ */ jsx(
198
+ TimePicker,
199
+ {
200
+ onChange: (time) => {
201
+ setFieldValue("time", time);
202
+ },
203
+ clearLabel: formatMessage({
204
+ id: "content-releases.modal.form.input.clearLabel",
205
+ defaultMessage: "Clear"
206
+ }),
207
+ onClear: () => {
208
+ setFieldValue("time", "");
209
+ },
210
+ value: values.time || void 0
211
+ }
212
+ ),
213
+ /* @__PURE__ */ jsx(Field.Error, {})
214
+ ]
215
+ }
216
+ ) })
217
+ ] }),
218
+ /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
219
+ ] })
220
+ ] }) }),
221
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
222
+ /* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }) }),
223
+ /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
195
224
  {
196
225
  id: "content-releases.modal.form.button.submit",
197
226
  defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
198
227
  },
199
228
  { isCreatingRelease }
200
229
  ) })
201
- }
202
- )
203
- ] })
230
+ ] })
231
+ ] });
232
+ }
204
233
  }
205
234
  )
206
- ] });
207
- };
208
- const getTimezones = (selectedDate) => {
209
- const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
210
- const utcOffset = getTimezoneOffset(timezone, selectedDate);
211
- return { offset: utcOffset, value: `${utcOffset}&${timezone}` };
212
- });
213
- const systemTimezone = timezoneList.find(
214
- (timezone) => timezone.value.split("&")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
215
- );
216
- return { timezoneList, systemTimezone };
235
+ ] }) });
217
236
  };
218
237
  const TimezoneComponent = ({ timezoneOptions }) => {
219
238
  const { values, errors, setFieldValue } = useFormikContext();
@@ -229,32 +248,44 @@ const TimezoneComponent = ({ timezoneOptions }) => {
229
248
  }
230
249
  }
231
250
  }, [setFieldValue, values.date, values.timezone]);
232
- return /* @__PURE__ */ jsx(
233
- Combobox,
251
+ return /* @__PURE__ */ jsxs(
252
+ Field.Root,
234
253
  {
235
- label: formatMessage({
236
- id: "content-releases.modal.form.input.label.timezone",
237
- defaultMessage: "Timezone"
238
- }),
239
- autocomplete: { type: "list", filter: "contains" },
240
254
  name: "timezone",
241
- value: values.timezone || void 0,
242
- textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
243
- onChange: (timezone) => {
244
- setFieldValue("timezone", timezone);
245
- },
246
- onTextValueChange: (timezone) => {
247
- setFieldValue("timezone", timezone);
248
- },
249
- onClear: () => {
250
- setFieldValue("timezone", "");
251
- },
252
- error: errors.timezone,
255
+ error: errors.timezone && formatMessage({ id: errors.timezone, defaultMessage: errors.timezone }),
253
256
  required: true,
254
- children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
257
+ children: [
258
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
259
+ id: "content-releases.modal.form.input.label.timezone",
260
+ defaultMessage: "Timezone"
261
+ }) }),
262
+ /* @__PURE__ */ jsx(
263
+ Combobox,
264
+ {
265
+ autocomplete: { type: "list", filter: "contains" },
266
+ value: values.timezone || void 0,
267
+ textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
268
+ onChange: (timezone) => {
269
+ setFieldValue("timezone", timezone);
270
+ },
271
+ onTextValueChange: (timezone) => {
272
+ setFieldValue("timezone", timezone);
273
+ },
274
+ onClear: () => {
275
+ setFieldValue("timezone", "");
276
+ },
277
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
278
+ }
279
+ ),
280
+ /* @__PURE__ */ jsx(Field.Error, {})
281
+ ]
255
282
  }
256
283
  );
257
284
  };
285
+ const useTypedDispatch = useDispatch;
286
+ const isBaseQueryError = (error) => {
287
+ return typeof error !== "undefined" && error.name !== void 0;
288
+ };
258
289
  const LinkCard = styled(Link)`
259
290
  display: block;
260
291
  `;
@@ -292,7 +323,7 @@ const getBadgeProps = (status) => {
292
323
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
293
324
  const { formatMessage } = useIntl();
294
325
  if (isError) {
295
- return /* @__PURE__ */ jsx(AnErrorOccurred, {});
326
+ return /* @__PURE__ */ jsx(Page.Error, {});
296
327
  }
297
328
  if (releases?.length === 0) {
298
329
  return /* @__PURE__ */ jsx(
@@ -307,11 +338,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
307
338
  target: sectionTitle
308
339
  }
309
340
  ),
310
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" })
341
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
311
342
  }
312
343
  );
313
344
  }
314
- return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
345
+ return /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { tag: NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
315
346
  Flex,
316
347
  {
317
348
  direction: "column",
@@ -326,7 +357,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
326
357
  gap: 4,
327
358
  children: [
328
359
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
329
- /* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
360
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
330
361
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
331
362
  id: "content-releases.pages.Releases.not-scheduled",
332
363
  defaultMessage: "Not scheduled"
@@ -347,33 +378,35 @@ const StyledAlert = styled(Alert)`
347
378
  `;
348
379
  const INITIAL_FORM_VALUES = {
349
380
  name: "",
350
- date: null,
381
+ date: format(/* @__PURE__ */ new Date(), "yyyy-MM-dd"),
351
382
  time: "",
352
383
  isScheduled: true,
353
384
  scheduledAt: null,
354
385
  timezone: null
355
386
  };
356
387
  const ReleasesPage = () => {
357
- const tabRef = React.useRef(null);
358
388
  const location = useLocation();
359
389
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
360
- const toggleNotification = useNotification();
390
+ const { toggleNotification } = useNotification();
361
391
  const { formatMessage } = useIntl();
362
- const { push, replace } = useHistory();
392
+ const navigate = useNavigate();
363
393
  const { formatAPIError } = useAPIErrorHandler();
364
394
  const [{ query }, setQuery] = useQueryParams();
365
395
  const response = useGetReleasesQuery(query);
396
+ const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
366
397
  const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
367
398
  const { getFeature } = useLicenseLimits();
368
399
  const { maximumReleases = 3 } = getFeature("cms-content-releases");
369
400
  const { trackUsage } = useTracking();
370
- const { isLoading, isSuccess, isError } = response;
401
+ const {
402
+ allowedActions: { canCreate }
403
+ } = useRBAC(PERMISSIONS);
404
+ const { isLoading: isLoadingReleases, isSuccess, isError } = response;
371
405
  const activeTab = response?.currentData?.meta?.activeTab || "pending";
372
- const activeTabIndex = ["pending", "done"].indexOf(activeTab);
373
406
  React.useEffect(() => {
374
407
  if (location?.state?.errors) {
375
408
  toggleNotification({
376
- type: "warning",
409
+ type: "danger",
377
410
  title: formatMessage({
378
411
  id: "content-releases.pages.Releases.notification.error.title",
379
412
  defaultMessage: "Your request could not be processed."
@@ -383,30 +416,25 @@ const ReleasesPage = () => {
383
416
  defaultMessage: "Please try again or open another release."
384
417
  })
385
418
  });
386
- replace({ state: null });
387
- }
388
- }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
389
- React.useEffect(() => {
390
- if (tabRef.current) {
391
- tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
419
+ navigate("", { replace: true, state: null });
392
420
  }
393
- }, [activeTabIndex]);
421
+ }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
394
422
  const toggleAddReleaseModal = () => {
395
423
  setReleaseModalShown((prev) => !prev);
396
424
  };
397
- if (isLoading) {
398
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
425
+ if (isLoadingReleases || isLoadingSettings) {
426
+ return /* @__PURE__ */ jsx(Page.Loading, {});
399
427
  }
400
428
  const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
401
429
  const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
402
- const handleTabChange = (index) => {
430
+ const handleTabChange = (tabValue) => {
403
431
  setQuery({
404
432
  ...query,
405
433
  page: 1,
406
434
  pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
407
435
  filters: {
408
436
  releasedAt: {
409
- $notNull: index === 0 ? false : true
437
+ $notNull: tabValue !== "pending"
410
438
  }
411
439
  }
412
440
  });
@@ -426,22 +454,22 @@ const ReleasesPage = () => {
426
454
  })
427
455
  });
428
456
  trackUsage("didCreateRelease");
429
- push(`/plugins/content-releases/${response2.data.data.id}`);
430
- } else if (isAxiosError(response2.error)) {
457
+ navigate(response2.data.data.id.toString());
458
+ } else if (isFetchError(response2.error)) {
431
459
  toggleNotification({
432
- type: "warning",
460
+ type: "danger",
433
461
  message: formatAPIError(response2.error)
434
462
  });
435
463
  } else {
436
464
  toggleNotification({
437
- type: "warning",
465
+ type: "danger",
438
466
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
439
467
  });
440
468
  }
441
469
  };
442
- return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoading, children: [
470
+ return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
443
471
  /* @__PURE__ */ jsx(
444
- HeaderLayout,
472
+ Layouts.Header,
445
473
  {
446
474
  title: formatMessage({
447
475
  id: "content-releases.pages.Releases.title",
@@ -451,7 +479,7 @@ const ReleasesPage = () => {
451
479
  id: "content-releases.pages.Releases.header-subtitle",
452
480
  defaultMessage: "Create and manage content updates"
453
481
  }),
454
- primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
482
+ primaryAction: canCreate ? /* @__PURE__ */ jsx(
455
483
  Button,
456
484
  {
457
485
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
@@ -462,10 +490,10 @@ const ReleasesPage = () => {
462
490
  defaultMessage: "New release"
463
491
  })
464
492
  }
465
- ) })
493
+ ) : null
466
494
  }
467
495
  ),
468
- /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
496
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
469
497
  hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
470
498
  StyledAlert,
471
499
  {
@@ -490,21 +518,17 @@ const ReleasesPage = () => {
490
518
  })
491
519
  }
492
520
  ),
493
- /* @__PURE__ */ jsxs(
494
- TabGroup,
495
- {
496
- label: formatMessage({
497
- id: "content-releases.pages.Releases.tab-group.label",
498
- defaultMessage: "Releases list"
499
- }),
500
- variant: "simple",
501
- initialSelectedTabIndex: activeTabIndex,
502
- onTabChange: handleTabChange,
503
- ref: tabRef,
504
- children: [
505
- /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
506
- /* @__PURE__ */ jsxs(Tabs, { children: [
507
- /* @__PURE__ */ jsx(Tab, { children: formatMessage(
521
+ /* @__PURE__ */ jsxs(Tabs.Root, { variant: "simple", onValueChange: handleTabChange, value: activeTab, children: [
522
+ /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
523
+ /* @__PURE__ */ jsxs(
524
+ Tabs.List,
525
+ {
526
+ "aria-label": formatMessage({
527
+ id: "content-releases.pages.Releases.tab-group.label",
528
+ defaultMessage: "Releases list"
529
+ }),
530
+ children: [
531
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "pending", children: formatMessage(
508
532
  {
509
533
  id: "content-releases.pages.Releases.tab.pending",
510
534
  defaultMessage: "Pending ({count})"
@@ -513,59 +537,55 @@ const ReleasesPage = () => {
513
537
  count: totalPendingReleases
514
538
  }
515
539
  ) }),
516
- /* @__PURE__ */ jsx(Tab, { children: formatMessage({
540
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "done", children: formatMessage({
517
541
  id: "content-releases.pages.Releases.tab.done",
518
542
  defaultMessage: "Done"
519
543
  }) })
520
- ] }),
521
- /* @__PURE__ */ jsx(Divider, {})
522
- ] }),
523
- /* @__PURE__ */ jsxs(TabPanels, { children: [
524
- /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
525
- ReleasesGrid,
526
- {
527
- sectionTitle: "pending",
528
- releases: response?.currentData?.data,
529
- isError
530
- }
531
- ) }),
532
- /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
533
- ReleasesGrid,
534
- {
535
- sectionTitle: "done",
536
- releases: response?.currentData?.data,
537
- isError
538
- }
539
- ) })
540
- ] })
541
- ]
542
- }
543
- ),
544
- response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
545
- /* @__PURE__ */ jsx(
546
- PageSizeURLQuery,
544
+ ]
545
+ }
546
+ ),
547
+ /* @__PURE__ */ jsx(Divider, {})
548
+ ] }),
549
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsx(
550
+ ReleasesGrid,
547
551
  {
548
- options: ["8", "16", "32", "64"],
549
- defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
552
+ sectionTitle: "pending",
553
+ releases: response?.currentData?.data,
554
+ isError
550
555
  }
551
- ),
552
- /* @__PURE__ */ jsx(
553
- PaginationURLQuery,
556
+ ) }),
557
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "done", children: /* @__PURE__ */ jsx(
558
+ ReleasesGrid,
554
559
  {
555
- pagination: {
556
- pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
557
- }
560
+ sectionTitle: "done",
561
+ releases: response?.currentData?.data,
562
+ isError
558
563
  }
559
- )
560
- ] }) : null
564
+ ) })
565
+ ] }),
566
+ /* @__PURE__ */ jsxs(
567
+ Pagination.Root,
568
+ {
569
+ ...response?.currentData?.meta?.pagination,
570
+ defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
571
+ children: [
572
+ /* @__PURE__ */ jsx(Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
573
+ /* @__PURE__ */ jsx(Pagination.Links, {})
574
+ ]
575
+ }
576
+ )
561
577
  ] }) }),
562
- releaseModalShown && /* @__PURE__ */ jsx(
578
+ /* @__PURE__ */ jsx(
563
579
  ReleaseModal,
564
580
  {
581
+ open: releaseModalShown,
565
582
  handleClose: toggleAddReleaseModal,
566
583
  handleSubmit: handleAddRelease,
567
584
  isLoading: isSubmittingForm,
568
- initialValues: INITIAL_FORM_VALUES
585
+ initialValues: {
586
+ ...INITIAL_FORM_VALUES,
587
+ timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
588
+ }
569
589
  }
570
590
  )
571
591
  ] });
@@ -576,7 +596,7 @@ const ReleaseInfoWrapper = styled(Flex)`
576
596
  border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
577
597
  border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
578
598
  `;
579
- const StyledMenuItem = styled(Menu.Item)`
599
+ const StyledMenuItem = styled(MenuItem)`
580
600
  svg path {
581
601
  fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
582
602
  }
@@ -585,7 +605,7 @@ const StyledMenuItem = styled(Menu.Item)`
585
605
  }
586
606
 
587
607
  &:hover {
588
- background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
608
+ background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
589
609
  }
590
610
  `;
591
611
  const PencilIcon = styled(Pencil)`
@@ -605,40 +625,75 @@ const TrashIcon = styled(Trash)`
605
625
  const TypographyMaxWidth = styled(Typography)`
606
626
  max-width: 300px;
607
627
  `;
608
- const EntryValidationText = ({ action, schema, components, entry }) => {
628
+ const EntryValidationText = ({ action, schema, entry, status }) => {
609
629
  const { formatMessage } = useIntl();
610
- const { validate } = unstable_useDocument();
611
- const { errors } = validate(entry, {
612
- contentType: schema,
613
- components,
614
- isCreatingEntry: false
615
- });
616
- if (Object.keys(errors).length > 0) {
617
- const validationErrorsMessages = Object.entries(errors).map(
618
- ([key, value]) => formatMessage(
619
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
620
- { field: key }
621
- )
622
- ).join(" ");
623
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
624
- /* @__PURE__ */ jsx(Icon, { color: "danger600", as: CrossCircle }),
625
- /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
626
- ] });
630
+ const { validate, isLoading } = unstable_useDocument(
631
+ {
632
+ collectionType: schema?.kind ?? "",
633
+ model: schema?.uid ?? ""
634
+ },
635
+ {
636
+ // useDocument makes a request to get more data about the entry, but we only want to have the validation function so we skip the request
637
+ skip: true
638
+ }
639
+ );
640
+ if (isLoading) {
641
+ return null;
627
642
  }
628
- if (action == "publish") {
629
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
630
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
631
- entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
632
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
633
- defaultMessage: "Already published"
634
- }) }) : /* @__PURE__ */ jsx(Typography, { children: formatMessage({
635
- id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
636
- defaultMessage: "Ready to publish"
637
- }) })
638
- ] });
643
+ const errors = validate(entry) ?? {};
644
+ if (action === "publish") {
645
+ if (Object.keys(errors).length > 0) {
646
+ const validationErrorsMessages = Object.entries(errors).map(
647
+ ([key, value]) => formatMessage(
648
+ // @ts-expect-error – TODO: fix this will better checks
649
+ { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
650
+ { field: key }
651
+ )
652
+ ).join(" ");
653
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
654
+ /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
655
+ /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(
656
+ TypographyMaxWidth,
657
+ {
658
+ textColor: "danger600",
659
+ variant: "omega",
660
+ fontWeight: "semiBold",
661
+ ellipsis: true,
662
+ children: validationErrorsMessages
663
+ }
664
+ ) })
665
+ ] });
666
+ }
667
+ if (status === "draft") {
668
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
669
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
670
+ /* @__PURE__ */ jsx(Typography, { children: formatMessage({
671
+ id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
672
+ defaultMessage: "Ready to publish"
673
+ }) })
674
+ ] });
675
+ }
676
+ if (status === "modified") {
677
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
678
+ /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
679
+ /* @__PURE__ */ jsx(Typography, { children: formatMessage({
680
+ id: "content-releases.pages.ReleaseDetails.entry-validation.modified",
681
+ defaultMessage: "Ready to publish changes"
682
+ }) })
683
+ ] });
684
+ }
685
+ if (status === "published") {
686
+ return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
687
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
688
+ /* @__PURE__ */ jsx(Typography, { children: formatMessage({
689
+ id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
690
+ defaultMessage: "Already published"
691
+ }) })
692
+ ] });
693
+ }
639
694
  }
640
695
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
641
- /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
696
+ /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
642
697
  !entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
643
698
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
644
699
  defaultMessage: "Already unpublished"
@@ -658,20 +713,23 @@ const ReleaseDetailsLayout = ({
658
713
  const {
659
714
  data,
660
715
  isLoading: isLoadingDetails,
661
- isError,
662
716
  error
663
- } = useGetReleaseQuery({ id: releaseId });
717
+ } = useGetReleaseQuery(
718
+ { id: releaseId },
719
+ {
720
+ skip: !releaseId
721
+ }
722
+ );
664
723
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
665
- const toggleNotification = useNotification();
724
+ const { toggleNotification } = useNotification();
666
725
  const { formatAPIError } = useAPIErrorHandler();
667
- const {
668
- allowedActions: { canUpdate, canDelete }
669
- } = useRBAC(PERMISSIONS);
726
+ const { allowedActions } = useRBAC(PERMISSIONS);
727
+ const { canUpdate, canDelete, canPublish } = allowedActions;
670
728
  const dispatch = useTypedDispatch();
671
729
  const { trackUsage } = useTracking();
672
730
  const release = data?.data;
673
- const handlePublishRelease = async () => {
674
- const response = await publishRelease({ id: releaseId });
731
+ const handlePublishRelease = (id) => async () => {
732
+ const response = await publishRelease({ id });
675
733
  if ("data" in response) {
676
734
  toggleNotification({
677
735
  type: "success",
@@ -686,14 +744,14 @@ const ReleaseDetailsLayout = ({
686
744
  totalPublishedEntries,
687
745
  totalUnpublishedEntries
688
746
  });
689
- } else if (isAxiosError(response.error)) {
747
+ } else if (isFetchError(response.error)) {
690
748
  toggleNotification({
691
- type: "warning",
749
+ type: "danger",
692
750
  message: formatAPIError(response.error)
693
751
  });
694
752
  } else {
695
753
  toggleNotification({
696
- type: "warning",
754
+ type: "danger",
697
755
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
698
756
  });
699
757
  }
@@ -719,21 +777,20 @@ const ReleaseDetailsLayout = ({
719
777
  return release.createdBy.email;
720
778
  };
721
779
  if (isLoadingDetails) {
722
- return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
780
+ return /* @__PURE__ */ jsx(Page.Loading, {});
723
781
  }
724
- if (isError || !release) {
782
+ if (isBaseQueryError(error) && "code" in error || !release) {
725
783
  return /* @__PURE__ */ jsx(
726
- Redirect,
784
+ Navigate,
727
785
  {
728
- to: {
729
- pathname: "/plugins/content-releases",
730
- state: {
731
- errors: [
732
- {
733
- code: error?.code
734
- }
735
- ]
736
- }
786
+ to: "..",
787
+ state: {
788
+ errors: [
789
+ {
790
+ // @ts-expect-error – TODO: fix this weird error flow
791
+ code: error?.code
792
+ }
793
+ ]
737
794
  }
738
795
  }
739
796
  );
@@ -770,106 +827,90 @@ const ReleaseDetailsLayout = ({
770
827
  ) : "";
771
828
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
772
829
  /* @__PURE__ */ jsx(
773
- HeaderLayout,
830
+ Layouts.Header,
774
831
  {
775
832
  title: release.name,
776
833
  subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
777
834
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
778
835
  /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
779
836
  ] }),
780
- navigationAction: /* @__PURE__ */ jsx(Link$1, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
781
- id: "global.back",
782
- defaultMessage: "Back"
783
- }) }),
837
+ navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
784
838
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
785
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
786
- /* @__PURE__ */ jsx(
787
- Menu.Trigger,
788
- {
789
- as: IconButton,
790
- paddingLeft: 2,
791
- paddingRight: 2,
792
- "aria-label": formatMessage({
793
- id: "content-releases.header.actions.open-release-actions",
794
- defaultMessage: "Release edit and delete menu"
795
- }),
796
- icon: /* @__PURE__ */ jsx(More, {}),
797
- variant: "tertiary"
798
- }
799
- ),
800
- /* @__PURE__ */ jsxs(Menu.Content, { top: 1, popoverPlacement: "bottom-end", children: [
801
- /* @__PURE__ */ jsxs(
802
- Flex,
803
- {
804
- alignItems: "center",
805
- justifyContent: "center",
806
- direction: "column",
807
- padding: 1,
808
- width: "100%",
809
- children: [
810
- /* @__PURE__ */ jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
811
- /* @__PURE__ */ jsx(PencilIcon, {}),
812
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
813
- id: "content-releases.header.actions.edit",
814
- defaultMessage: "Edit"
839
+ /* @__PURE__ */ jsxs(
840
+ SimpleMenu,
841
+ {
842
+ label: /* @__PURE__ */ jsx(More, {}),
843
+ variant: "tertiary",
844
+ endIcon: null,
845
+ paddingLeft: 2,
846
+ paddingRight: 2,
847
+ "aria-label": formatMessage({
848
+ id: "content-releases.header.actions.open-release-actions",
849
+ defaultMessage: "Release edit and delete menu"
850
+ }),
851
+ popoverPlacement: "bottom-end",
852
+ children: [
853
+ /* @__PURE__ */ jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
854
+ /* @__PURE__ */ jsx(PencilIcon, {}),
855
+ /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
856
+ id: "content-releases.header.actions.edit",
857
+ defaultMessage: "Edit"
858
+ }) })
859
+ ] }) }),
860
+ /* @__PURE__ */ jsx(
861
+ StyledMenuItem,
862
+ {
863
+ disabled: !canDelete,
864
+ onSelect: toggleWarningSubmit,
865
+ $variant: "danger",
866
+ children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
867
+ /* @__PURE__ */ jsx(TrashIcon, {}),
868
+ /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
869
+ id: "content-releases.header.actions.delete",
870
+ defaultMessage: "Delete"
815
871
  }) })
816
- ] }) }),
817
- /* @__PURE__ */ jsx(
818
- StyledMenuItem,
819
- {
820
- disabled: !canDelete,
821
- onSelect: toggleWarningSubmit,
822
- variant: "danger",
823
- children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
824
- /* @__PURE__ */ jsx(TrashIcon, {}),
825
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
826
- id: "content-releases.header.actions.delete",
827
- defaultMessage: "Delete"
828
- }) })
829
- ] })
830
- }
831
- )
832
- ]
833
- }
834
- ),
835
- /* @__PURE__ */ jsxs(
836
- ReleaseInfoWrapper,
837
- {
838
- direction: "column",
839
- justifyContent: "center",
840
- alignItems: "flex-start",
841
- gap: 1,
842
- padding: 5,
843
- children: [
844
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
845
- id: "content-releases.header.actions.created",
846
- defaultMessage: "Created"
847
- }) }),
848
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
849
- /* @__PURE__ */ jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
850
- formatMessage(
851
- {
852
- id: "content-releases.header.actions.created.description",
853
- defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
854
- },
855
- { createdBy: getCreatedByUser(), hasCreatedByUser }
856
- )
857
872
  ] })
858
- ]
859
- }
860
- )
861
- ] })
862
- ] }),
873
+ }
874
+ ),
875
+ /* @__PURE__ */ jsxs(
876
+ ReleaseInfoWrapper,
877
+ {
878
+ direction: "column",
879
+ justifyContent: "center",
880
+ alignItems: "flex-start",
881
+ gap: 1,
882
+ padding: 5,
883
+ children: [
884
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
885
+ id: "content-releases.header.actions.created",
886
+ defaultMessage: "Created"
887
+ }) }),
888
+ /* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
889
+ /* @__PURE__ */ jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
890
+ formatMessage(
891
+ {
892
+ id: "content-releases.header.actions.created.description",
893
+ defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
894
+ },
895
+ { createdBy: getCreatedByUser(), hasCreatedByUser }
896
+ )
897
+ ] })
898
+ ]
899
+ }
900
+ )
901
+ ]
902
+ }
903
+ ),
863
904
  /* @__PURE__ */ jsx(Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
864
905
  id: "content-releases.header.actions.refresh",
865
906
  defaultMessage: "Refresh"
866
907
  }) }),
867
- /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
908
+ canPublish ? /* @__PURE__ */ jsx(
868
909
  Button,
869
910
  {
870
911
  size: "S",
871
912
  variant: "default",
872
- onClick: handlePublishRelease,
913
+ onClick: handlePublishRelease(release.id.toString()),
873
914
  loading: isPublishing,
874
915
  disabled: release.actions.meta.count === 0,
875
916
  children: formatMessage({
@@ -877,7 +918,7 @@ const ReleaseDetailsLayout = ({
877
918
  defaultMessage: "Publish"
878
919
  })
879
920
  }
880
- ) })
921
+ ) : null
881
922
  ] })
882
923
  }
883
924
  ),
@@ -904,47 +945,32 @@ const getGroupByOptionLabel = (value) => {
904
945
  defaultMessage: "Content-Types"
905
946
  };
906
947
  };
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 = () => {
948
+ const ReleaseDetailsBody = ({ releaseId }) => {
923
949
  const { formatMessage } = useIntl();
924
- const { releaseId } = useParams();
925
950
  const [{ query }, setQuery] = useQueryParams();
926
- const toggleNotification = useNotification();
951
+ const { toggleNotification } = useNotification();
927
952
  const { formatAPIError } = useAPIErrorHandler();
928
953
  const {
929
954
  data: releaseData,
930
955
  isLoading: isReleaseLoading,
931
- isError: isReleaseError,
932
956
  error: releaseError
933
957
  } = useGetReleaseQuery({ id: releaseId });
934
958
  const {
935
959
  allowedActions: { canUpdate }
936
960
  } = useRBAC(PERMISSIONS);
937
- const { runHookWaterfall } = useStrapiApp();
938
- const {
939
- displayedHeaders,
940
- hasI18nEnabled
941
- } = runHookWaterfall(
942
- "ContentReleases/pages/ReleaseDetails/add-locale-in-releases",
943
- {
944
- displayedHeaders: DEFAULT_RELEASE_DETAILS_HEADER,
945
- hasI18nEnabled: false
946
- }
947
- );
961
+ const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
962
+ const { displayedHeaders, hasI18nEnabled } = runHookWaterfall("ContentReleases/pages/ReleaseDetails/add-locale-in-releases", {
963
+ displayedHeaders: [
964
+ {
965
+ label: {
966
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
967
+ defaultMessage: "name"
968
+ },
969
+ name: "name"
970
+ }
971
+ ],
972
+ hasI18nEnabled: false
973
+ });
948
974
  const release = releaseData?.data;
949
975
  const selectedGroupBy = query?.groupBy || "contentType";
950
976
  const {
@@ -973,65 +999,59 @@ const ReleaseDetailsBody = () => {
973
999
  // We are passing the action path to found the position in the cache of the action for optimistic updates
974
1000
  });
975
1001
  if ("error" in response) {
976
- if (isAxiosError(response.error)) {
1002
+ if (isFetchError(response.error)) {
977
1003
  toggleNotification({
978
- type: "warning",
1004
+ type: "danger",
979
1005
  message: formatAPIError(response.error)
980
1006
  });
981
1007
  } else {
982
1008
  toggleNotification({
983
- type: "warning",
1009
+ type: "danger",
984
1010
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
985
1011
  });
986
1012
  }
987
1013
  }
988
1014
  };
989
1015
  if (isLoading || isReleaseLoading) {
990
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
1016
+ return /* @__PURE__ */ jsx(Page.Loading, {});
991
1017
  }
992
1018
  const releaseActions = data?.data;
993
1019
  const releaseMeta = data?.meta;
994
1020
  const contentTypes = releaseMeta?.contentTypes || {};
995
1021
  const components = releaseMeta?.components || {};
996
- if (isReleaseError || !release) {
1022
+ if (isBaseQueryError(releaseError) || !release) {
997
1023
  const errorsArray = [];
998
- if (releaseError) {
1024
+ if (releaseError && "code" in releaseError) {
999
1025
  errorsArray.push({
1000
1026
  code: releaseError.code
1001
1027
  });
1002
1028
  }
1003
- if (releaseActionsError) {
1029
+ if (releaseActionsError && "code" in releaseActionsError) {
1004
1030
  errorsArray.push({
1005
1031
  code: releaseActionsError.code
1006
1032
  });
1007
1033
  }
1008
1034
  return /* @__PURE__ */ jsx(
1009
- Redirect,
1035
+ Navigate,
1010
1036
  {
1011
- to: {
1012
- pathname: "/plugins/content-releases",
1013
- state: {
1014
- errors: errorsArray
1015
- }
1037
+ to: "..",
1038
+ state: {
1039
+ errors: errorsArray
1016
1040
  }
1017
1041
  }
1018
1042
  );
1019
1043
  }
1020
1044
  if (isError || !releaseActions) {
1021
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1045
+ return /* @__PURE__ */ jsx(Page.Error, {});
1022
1046
  }
1023
1047
  if (Object.keys(releaseActions).length === 0) {
1024
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
1025
- NoContent,
1048
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1049
+ EmptyStateLayout,
1026
1050
  {
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
1051
  action: /* @__PURE__ */ jsx(
1032
1052
  LinkButton,
1033
1053
  {
1034
- as: Link$2,
1054
+ tag: Link$1,
1035
1055
  to: {
1036
1056
  pathname: "/content-manager"
1037
1057
  },
@@ -1042,19 +1062,52 @@ const ReleaseDetailsBody = () => {
1042
1062
  defaultMessage: "Open the Content Manager"
1043
1063
  })
1044
1064
  }
1045
- )
1065
+ ),
1066
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1067
+ content: formatMessage({
1068
+ id: "content-releases.pages.Details.tab.emptyEntries",
1069
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1070
+ })
1046
1071
  }
1047
1072
  ) });
1048
1073
  }
1074
+ const groupByLabel = formatMessage({
1075
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1076
+ defaultMessage: "Group by"
1077
+ });
1078
+ const headers = [
1079
+ ...displayedHeaders,
1080
+ {
1081
+ label: {
1082
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1083
+ defaultMessage: "content-type"
1084
+ },
1085
+ name: "content-type"
1086
+ },
1087
+ {
1088
+ label: {
1089
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1090
+ defaultMessage: "action"
1091
+ },
1092
+ name: "action"
1093
+ },
1094
+ ...!release.releasedAt ? [
1095
+ {
1096
+ label: {
1097
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1098
+ defaultMessage: "status"
1099
+ },
1100
+ name: "status"
1101
+ }
1102
+ ] : []
1103
+ ];
1049
1104
  const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1050
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1105
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1051
1106
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1052
1107
  SingleSelect,
1053
1108
  {
1054
- "aria-label": formatMessage({
1055
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1056
- defaultMessage: "Group by"
1057
- }),
1109
+ placeholder: groupByLabel,
1110
+ "aria-label": groupByLabel,
1058
1111
  customizeContent: (value) => formatMessage(
1059
1112
  {
1060
1113
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1078,57 +1131,13 @@ const ReleaseDetailsBody = () => {
1078
1131
  ...item,
1079
1132
  id: Number(item.entry.id)
1080
1133
  })),
1081
- colCount: releaseActions[key].length,
1082
- isLoading,
1083
- isFetching,
1134
+ headers,
1135
+ isLoading: isLoading || isFetching,
1084
1136
  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, {}),
1137
+ /* @__PURE__ */ jsx(Table.Head, { children: headers.map(({ label, name }) => /* @__PURE__ */ jsx(Table.HeaderCell, { label: formatMessage(label), name }, name)) }),
1138
+ /* @__PURE__ */ jsx(Table.Loading, {}),
1130
1139
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1131
- ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1140
+ ({ id, contentType, locale, type, entry, status }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1132
1141
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
1133
1142
  hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1134
1143
  /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
@@ -1157,7 +1166,8 @@ const ReleaseDetailsBody = () => {
1157
1166
  action: type,
1158
1167
  schema: contentTypes?.[contentType.uid],
1159
1168
  components,
1160
- entry
1169
+ entry,
1170
+ status
1161
1171
  }
1162
1172
  ) }),
1163
1173
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { children: [
@@ -1165,7 +1175,7 @@ const ReleaseDetailsBody = () => {
1165
1175
  ReleaseActionMenu.ReleaseActionEntryLinkItem,
1166
1176
  {
1167
1177
  contentTypeUid: contentType.uid,
1168
- entryId: entry.id,
1178
+ documentId: entry.documentId,
1169
1179
  locale: locale?.code
1170
1180
  }
1171
1181
  ),
@@ -1184,54 +1194,73 @@ const ReleaseDetailsBody = () => {
1184
1194
  }
1185
1195
  )
1186
1196
  ] }, `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
- ] })
1197
+ /* @__PURE__ */ jsxs(
1198
+ Pagination.Root,
1199
+ {
1200
+ ...releaseMeta?.pagination,
1201
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1202
+ children: [
1203
+ /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1204
+ /* @__PURE__ */ jsx(Pagination.Links, {})
1205
+ ]
1206
+ }
1207
+ )
1198
1208
  ] }) });
1199
1209
  };
1200
1210
  const ReleaseDetailsPage = () => {
1201
1211
  const { formatMessage } = useIntl();
1202
1212
  const { releaseId } = useParams();
1203
- const toggleNotification = useNotification();
1213
+ const { toggleNotification } = useNotification();
1204
1214
  const { formatAPIError } = useAPIErrorHandler();
1205
- const { replace } = useHistory();
1215
+ const navigate = useNavigate();
1206
1216
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1207
1217
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1208
1218
  const {
1209
1219
  isLoading: isLoadingDetails,
1210
1220
  data,
1211
1221
  isSuccess: isSuccessDetails
1212
- } = useGetReleaseQuery({ id: releaseId });
1222
+ } = useGetReleaseQuery(
1223
+ { id: releaseId },
1224
+ {
1225
+ skip: !releaseId
1226
+ }
1227
+ );
1228
+ const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
1213
1229
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1214
- const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1230
+ const [deleteRelease] = useDeleteReleaseMutation();
1215
1231
  const toggleEditReleaseModal = () => {
1216
1232
  setReleaseModalShown((prev) => !prev);
1217
1233
  };
1234
+ const getTimezoneValue = () => {
1235
+ if (releaseData?.timezone) {
1236
+ return releaseData.timezone;
1237
+ } else {
1238
+ if (dataTimezone?.data.defaultTimezone) {
1239
+ return dataTimezone.data.defaultTimezone;
1240
+ }
1241
+ return null;
1242
+ }
1243
+ };
1218
1244
  const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
1219
- if (isLoadingDetails) {
1245
+ if (isLoadingDetails || isLoadingTimezone) {
1220
1246
  return /* @__PURE__ */ jsx(
1221
1247
  ReleaseDetailsLayout,
1222
1248
  {
1223
1249
  toggleEditReleaseModal,
1224
1250
  toggleWarningSubmit,
1225
- children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1251
+ children: /* @__PURE__ */ jsx(Page.Loading, {})
1226
1252
  }
1227
1253
  );
1228
1254
  }
1255
+ if (!releaseId) {
1256
+ return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1257
+ }
1229
1258
  const releaseData = isSuccessDetails && data?.data || null;
1230
1259
  const title = releaseData?.name || "";
1231
- const timezone = releaseData?.timezone ?? null;
1260
+ const timezone = getTimezoneValue();
1232
1261
  const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1233
- const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : null;
1234
- const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
1262
+ const date = scheduledAt ? format$1(scheduledAt, "yyyy-MM-dd") : void 0;
1263
+ const time = scheduledAt ? format$1(scheduledAt, "HH:mm") : "";
1235
1264
  const handleEditRelease = async (values) => {
1236
1265
  const response = await updateRelease({
1237
1266
  id: releaseId,
@@ -1248,14 +1277,14 @@ const ReleaseDetailsPage = () => {
1248
1277
  })
1249
1278
  });
1250
1279
  toggleEditReleaseModal();
1251
- } else if (isAxiosError(response.error)) {
1280
+ } else if (isFetchError(response.error)) {
1252
1281
  toggleNotification({
1253
- type: "warning",
1282
+ type: "danger",
1254
1283
  message: formatAPIError(response.error)
1255
1284
  });
1256
1285
  } else {
1257
1286
  toggleNotification({
1258
- type: "warning",
1287
+ type: "danger",
1259
1288
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1260
1289
  });
1261
1290
  }
@@ -1265,15 +1294,15 @@ const ReleaseDetailsPage = () => {
1265
1294
  id: releaseId
1266
1295
  });
1267
1296
  if ("data" in response) {
1268
- replace("/plugins/content-releases");
1269
- } else if (isAxiosError(response.error)) {
1297
+ navigate("..");
1298
+ } else if (isFetchError(response.error)) {
1270
1299
  toggleNotification({
1271
- type: "warning",
1300
+ type: "danger",
1272
1301
  message: formatAPIError(response.error)
1273
1302
  });
1274
1303
  } else {
1275
1304
  toggleNotification({
1276
- type: "warning",
1305
+ type: "danger",
1277
1306
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1278
1307
  });
1279
1308
  }
@@ -1284,10 +1313,11 @@ const ReleaseDetailsPage = () => {
1284
1313
  toggleEditReleaseModal,
1285
1314
  toggleWarningSubmit,
1286
1315
  children: [
1287
- /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1288
- releaseModalShown && /* @__PURE__ */ jsx(
1316
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1317
+ /* @__PURE__ */ jsx(
1289
1318
  ReleaseModal,
1290
1319
  {
1320
+ open: releaseModalShown,
1291
1321
  handleClose: toggleEditReleaseModal,
1292
1322
  handleSubmit: handleEditRelease,
1293
1323
  isLoading: isLoadingDetails || isSubmittingForm,
@@ -1301,30 +1331,21 @@ const ReleaseDetailsPage = () => {
1301
1331
  }
1302
1332
  }
1303
1333
  ),
1304
- /* @__PURE__ */ jsx(
1305
- ConfirmDialog,
1306
- {
1307
- bodyText: {
1308
- id: "content-releases.dialog.confirmation-message",
1309
- defaultMessage: "Are you sure you want to delete this release?"
1310
- },
1311
- isOpen: showWarningSubmit,
1312
- isConfirmButtonLoading: isDeletingRelease,
1313
- onToggleDialog: toggleWarningSubmit,
1314
- onConfirm: handleDeleteRelease
1315
- }
1316
- )
1334
+ /* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1335
+ id: "content-releases.dialog.confirmation-message",
1336
+ defaultMessage: "Are you sure you want to delete this release?"
1337
+ }) }) })
1317
1338
  ]
1318
1339
  }
1319
1340
  );
1320
1341
  };
1321
1342
  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 })
1343
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1344
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1345
+ /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1325
1346
  ] }) });
1326
1347
  };
1327
1348
  export {
1328
1349
  App
1329
1350
  };
1330
- //# sourceMappingURL=App-gu1aiP6i.mjs.map
1351
+ //# sourceMappingURL=App-UQxgTJY5.mjs.map