@strapi/content-releases 0.0.0-experimental.d9f9f725e07a329ca272ecedef7bd85fa74dd661 → 0.0.0-experimental.da85533897155e719d784f0271223c866d2f69ab

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 (138) hide show
  1. package/dist/_chunks/{App-jrh58sXY.mjs → App-B4mkcLmw.mjs} +580 -554
  2. package/dist/_chunks/App-B4mkcLmw.mjs.map +1 -0
  3. package/dist/_chunks/{App-dLXY5ei3.js → App-DpoC8s97.js} +599 -575
  4. package/dist/_chunks/App-DpoC8s97.js.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-bpIYXOfu.js → PurchaseContentReleases-Be3acS2L.js} +7 -6
  6. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-3tRbmbY3.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +8 -7
  8. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
  9. package/dist/_chunks/ReleasesSettingsPage-B89WWWJf.js +178 -0
  10. package/dist/_chunks/ReleasesSettingsPage-B89WWWJf.js.map +1 -0
  11. package/dist/_chunks/ReleasesSettingsPage-DfL6yxLG.mjs +178 -0
  12. package/dist/_chunks/ReleasesSettingsPage-DfL6yxLG.mjs.map +1 -0
  13. package/dist/_chunks/{en-HrREghh3.js → en-CmYoEnA7.js} +9 -2
  14. package/dist/_chunks/en-CmYoEnA7.js.map +1 -0
  15. package/dist/_chunks/{en-ltT1TlKQ.mjs → en-D0yVZFqf.mjs} +9 -2
  16. package/dist/_chunks/en-D0yVZFqf.mjs.map +1 -0
  17. package/dist/_chunks/index-B3cqcIza.mjs +1342 -0
  18. package/dist/_chunks/index-B3cqcIza.mjs.map +1 -0
  19. package/dist/_chunks/index-sGcuP2hw.js +1361 -0
  20. package/dist/_chunks/index-sGcuP2hw.js.map +1 -0
  21. package/dist/_chunks/schemas-63pFihNF.mjs +44 -0
  22. package/dist/_chunks/schemas-63pFihNF.mjs.map +1 -0
  23. package/dist/_chunks/schemas-z5zp-_Gd.js +62 -0
  24. package/dist/_chunks/schemas-z5zp-_Gd.js.map +1 -0
  25. package/dist/admin/index.js +1 -15
  26. package/dist/admin/index.js.map +1 -1
  27. package/dist/admin/index.mjs +2 -16
  28. package/dist/admin/index.mjs.map +1 -1
  29. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  30. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  31. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  32. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  33. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  34. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  35. package/dist/admin/src/components/ReleaseModal.d.ts +17 -0
  36. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  37. package/dist/admin/src/constants.d.ts +76 -0
  38. package/dist/admin/src/index.d.ts +3 -0
  39. package/dist/admin/src/modules/hooks.d.ts +7 -0
  40. package/dist/admin/src/pages/App.d.ts +1 -0
  41. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  42. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  43. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  44. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  45. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  46. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  47. package/dist/admin/src/pluginId.d.ts +1 -0
  48. package/dist/admin/src/services/release.d.ts +112 -0
  49. package/dist/admin/src/store/hooks.d.ts +7 -0
  50. package/dist/admin/src/utils/api.d.ts +6 -0
  51. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  52. package/dist/admin/src/utils/time.d.ts +10 -0
  53. package/dist/admin/src/validation/schemas.d.ts +6 -0
  54. package/dist/server/index.js +807 -637
  55. package/dist/server/index.js.map +1 -1
  56. package/dist/server/index.mjs +808 -637
  57. package/dist/server/index.mjs.map +1 -1
  58. package/dist/server/src/bootstrap.d.ts +5 -0
  59. package/dist/server/src/bootstrap.d.ts.map +1 -0
  60. package/dist/server/src/constants.d.ts +21 -0
  61. package/dist/server/src/constants.d.ts.map +1 -0
  62. package/dist/server/src/content-types/index.d.ts +97 -0
  63. package/dist/server/src/content-types/index.d.ts.map +1 -0
  64. package/dist/server/src/content-types/release/index.d.ts +48 -0
  65. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  66. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  67. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  68. package/dist/server/src/content-types/release-action/index.d.ts +48 -0
  69. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  70. package/dist/server/src/content-types/release-action/schema.d.ts +47 -0
  71. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  72. package/dist/server/src/controllers/index.d.ts +25 -0
  73. package/dist/server/src/controllers/index.d.ts.map +1 -0
  74. package/dist/server/src/controllers/release-action.d.ts +10 -0
  75. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  76. package/dist/server/src/controllers/release.d.ts +18 -0
  77. package/dist/server/src/controllers/release.d.ts.map +1 -0
  78. package/dist/server/src/controllers/settings.d.ts +11 -0
  79. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  80. package/dist/server/src/controllers/validation/release-action.d.ts +14 -0
  81. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  82. package/dist/server/src/controllers/validation/release.d.ts +4 -0
  83. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  84. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  85. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  86. package/dist/server/src/destroy.d.ts +5 -0
  87. package/dist/server/src/destroy.d.ts.map +1 -0
  88. package/dist/server/src/index.d.ts +2113 -0
  89. package/dist/server/src/index.d.ts.map +1 -0
  90. package/dist/server/src/middlewares/documents.d.ts +6 -0
  91. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  92. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  93. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  94. package/dist/server/src/migrations/index.d.ts +13 -0
  95. package/dist/server/src/migrations/index.d.ts.map +1 -0
  96. package/dist/server/src/register.d.ts +5 -0
  97. package/dist/server/src/register.d.ts.map +1 -0
  98. package/dist/server/src/routes/index.d.ts +51 -0
  99. package/dist/server/src/routes/index.d.ts.map +1 -0
  100. package/dist/server/src/routes/release-action.d.ts +18 -0
  101. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  102. package/dist/server/src/routes/release.d.ts +18 -0
  103. package/dist/server/src/routes/release.d.ts.map +1 -0
  104. package/dist/server/src/routes/settings.d.ts +18 -0
  105. package/dist/server/src/routes/settings.d.ts.map +1 -0
  106. package/dist/server/src/services/index.d.ts +1826 -0
  107. package/dist/server/src/services/index.d.ts.map +1 -0
  108. package/dist/server/src/services/release-action.d.ts +36 -0
  109. package/dist/server/src/services/release-action.d.ts.map +1 -0
  110. package/dist/server/src/services/release.d.ts +31 -0
  111. package/dist/server/src/services/release.d.ts.map +1 -0
  112. package/dist/server/src/services/scheduling.d.ts +18 -0
  113. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  114. package/dist/server/src/services/settings.d.ts +13 -0
  115. package/dist/server/src/services/settings.d.ts.map +1 -0
  116. package/dist/server/src/services/validation.d.ts +18 -0
  117. package/dist/server/src/services/validation.d.ts.map +1 -0
  118. package/dist/server/src/utils/index.d.ts +35 -0
  119. package/dist/server/src/utils/index.d.ts.map +1 -0
  120. package/dist/shared/contracts/release-actions.d.ts +130 -0
  121. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  122. package/dist/shared/contracts/releases.d.ts +184 -0
  123. package/dist/shared/contracts/releases.d.ts.map +1 -0
  124. package/dist/shared/contracts/settings.d.ts +39 -0
  125. package/dist/shared/contracts/settings.d.ts.map +1 -0
  126. package/dist/shared/types.d.ts +24 -0
  127. package/dist/shared/types.d.ts.map +1 -0
  128. package/package.json +30 -36
  129. package/dist/_chunks/App-dLXY5ei3.js.map +0 -1
  130. package/dist/_chunks/App-jrh58sXY.mjs.map +0 -1
  131. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +0 -1
  132. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +0 -1
  133. package/dist/_chunks/en-HrREghh3.js.map +0 -1
  134. package/dist/_chunks/en-ltT1TlKQ.mjs.map +0 -1
  135. package/dist/_chunks/index-CVO0Rqdm.js +0 -1336
  136. package/dist/_chunks/index-CVO0Rqdm.js.map +0 -1
  137. package/dist/_chunks/index-PiOGBETy.mjs +0 -1315
  138. package/dist/_chunks/index-PiOGBETy.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-PiOGBETy.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-B3cqcIza.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, SimpleMenu, Dialog, 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, direction: "column", alignItems: "stretch", 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
+ SimpleMenuButton,
841
+ {
842
+ label: /* @__PURE__ */ jsx(More, {}),
843
+ variant: "tertiary",
844
+ endIcon: null,
845
+ paddingLeft: "7px",
846
+ paddingRight: "7px",
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: 4,
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,13 +918,18 @@ const ReleaseDetailsLayout = ({
877
918
  defaultMessage: "Publish"
878
919
  })
879
920
  }
880
- ) })
921
+ ) : null
881
922
  ] })
882
923
  }
883
924
  ),
884
925
  children
885
926
  ] });
886
927
  };
928
+ const SimpleMenuButton = styled(SimpleMenu)`
929
+ & > span {
930
+ display: flex;
931
+ }
932
+ `;
887
933
  const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
888
934
  const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
889
935
  const getGroupByOptionLabel = (value) => {
@@ -904,47 +950,32 @@ const getGroupByOptionLabel = (value) => {
904
950
  defaultMessage: "Content-Types"
905
951
  };
906
952
  };
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 = () => {
953
+ const ReleaseDetailsBody = ({ releaseId }) => {
923
954
  const { formatMessage } = useIntl();
924
- const { releaseId } = useParams();
925
955
  const [{ query }, setQuery] = useQueryParams();
926
- const toggleNotification = useNotification();
956
+ const { toggleNotification } = useNotification();
927
957
  const { formatAPIError } = useAPIErrorHandler();
928
958
  const {
929
959
  data: releaseData,
930
960
  isLoading: isReleaseLoading,
931
- isError: isReleaseError,
932
961
  error: releaseError
933
962
  } = useGetReleaseQuery({ id: releaseId });
934
963
  const {
935
964
  allowedActions: { canUpdate }
936
965
  } = 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
- );
966
+ const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
967
+ const { displayedHeaders, hasI18nEnabled } = runHookWaterfall("ContentReleases/pages/ReleaseDetails/add-locale-in-releases", {
968
+ displayedHeaders: [
969
+ {
970
+ label: {
971
+ id: "content-releases.page.ReleaseDetails.table.header.label.name",
972
+ defaultMessage: "name"
973
+ },
974
+ name: "name"
975
+ }
976
+ ],
977
+ hasI18nEnabled: false
978
+ });
948
979
  const release = releaseData?.data;
949
980
  const selectedGroupBy = query?.groupBy || "contentType";
950
981
  const {
@@ -973,65 +1004,59 @@ const ReleaseDetailsBody = () => {
973
1004
  // We are passing the action path to found the position in the cache of the action for optimistic updates
974
1005
  });
975
1006
  if ("error" in response) {
976
- if (isAxiosError(response.error)) {
1007
+ if (isFetchError(response.error)) {
977
1008
  toggleNotification({
978
- type: "warning",
1009
+ type: "danger",
979
1010
  message: formatAPIError(response.error)
980
1011
  });
981
1012
  } else {
982
1013
  toggleNotification({
983
- type: "warning",
1014
+ type: "danger",
984
1015
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
985
1016
  });
986
1017
  }
987
1018
  }
988
1019
  };
989
1020
  if (isLoading || isReleaseLoading) {
990
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
1021
+ return /* @__PURE__ */ jsx(Page.Loading, {});
991
1022
  }
992
1023
  const releaseActions = data?.data;
993
1024
  const releaseMeta = data?.meta;
994
1025
  const contentTypes = releaseMeta?.contentTypes || {};
995
1026
  const components = releaseMeta?.components || {};
996
- if (isReleaseError || !release) {
1027
+ if (isBaseQueryError(releaseError) || !release) {
997
1028
  const errorsArray = [];
998
- if (releaseError) {
1029
+ if (releaseError && "code" in releaseError) {
999
1030
  errorsArray.push({
1000
1031
  code: releaseError.code
1001
1032
  });
1002
1033
  }
1003
- if (releaseActionsError) {
1034
+ if (releaseActionsError && "code" in releaseActionsError) {
1004
1035
  errorsArray.push({
1005
1036
  code: releaseActionsError.code
1006
1037
  });
1007
1038
  }
1008
1039
  return /* @__PURE__ */ jsx(
1009
- Redirect,
1040
+ Navigate,
1010
1041
  {
1011
- to: {
1012
- pathname: "/plugins/content-releases",
1013
- state: {
1014
- errors: errorsArray
1015
- }
1042
+ to: "..",
1043
+ state: {
1044
+ errors: errorsArray
1016
1045
  }
1017
1046
  }
1018
1047
  );
1019
1048
  }
1020
1049
  if (isError || !releaseActions) {
1021
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1050
+ return /* @__PURE__ */ jsx(Page.Error, {});
1022
1051
  }
1023
1052
  if (Object.keys(releaseActions).length === 0) {
1024
- return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
1025
- NoContent,
1053
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1054
+ EmptyStateLayout,
1026
1055
  {
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
1056
  action: /* @__PURE__ */ jsx(
1032
1057
  LinkButton,
1033
1058
  {
1034
- as: Link$2,
1059
+ tag: Link$1,
1035
1060
  to: {
1036
1061
  pathname: "/content-manager"
1037
1062
  },
@@ -1042,19 +1067,52 @@ const ReleaseDetailsBody = () => {
1042
1067
  defaultMessage: "Open the Content Manager"
1043
1068
  })
1044
1069
  }
1045
- )
1070
+ ),
1071
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1072
+ content: formatMessage({
1073
+ id: "content-releases.pages.Details.tab.emptyEntries",
1074
+ defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1075
+ })
1046
1076
  }
1047
1077
  ) });
1048
1078
  }
1079
+ const groupByLabel = formatMessage({
1080
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1081
+ defaultMessage: "Group by"
1082
+ });
1083
+ const headers = [
1084
+ ...displayedHeaders,
1085
+ {
1086
+ label: {
1087
+ id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1088
+ defaultMessage: "content-type"
1089
+ },
1090
+ name: "content-type"
1091
+ },
1092
+ {
1093
+ label: {
1094
+ id: "content-releases.page.ReleaseDetails.table.header.label.action",
1095
+ defaultMessage: "action"
1096
+ },
1097
+ name: "action"
1098
+ },
1099
+ ...!release.releasedAt ? [
1100
+ {
1101
+ label: {
1102
+ id: "content-releases.page.ReleaseDetails.table.header.label.status",
1103
+ defaultMessage: "status"
1104
+ },
1105
+ name: "status"
1106
+ }
1107
+ ] : []
1108
+ ];
1049
1109
  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: [
1110
+ return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1051
1111
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1052
1112
  SingleSelect,
1053
1113
  {
1054
- "aria-label": formatMessage({
1055
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1056
- defaultMessage: "Group by"
1057
- }),
1114
+ placeholder: groupByLabel,
1115
+ "aria-label": groupByLabel,
1058
1116
  customizeContent: (value) => formatMessage(
1059
1117
  {
1060
1118
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1078,57 +1136,13 @@ const ReleaseDetailsBody = () => {
1078
1136
  ...item,
1079
1137
  id: Number(item.entry.id)
1080
1138
  })),
1081
- colCount: releaseActions[key].length,
1082
- isLoading,
1083
- isFetching,
1139
+ headers,
1140
+ isLoading: isLoading || isFetching,
1084
1141
  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, {}),
1142
+ /* @__PURE__ */ jsx(Table.Head, { children: headers.map(({ label, name }) => /* @__PURE__ */ jsx(Table.HeaderCell, { label: formatMessage(label), name }, name)) }),
1143
+ /* @__PURE__ */ jsx(Table.Loading, {}),
1130
1144
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1131
- ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1145
+ ({ id, contentType, locale, type, entry, status }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1132
1146
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
1133
1147
  hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1134
1148
  /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
@@ -1157,7 +1171,8 @@ const ReleaseDetailsBody = () => {
1157
1171
  action: type,
1158
1172
  schema: contentTypes?.[contentType.uid],
1159
1173
  components,
1160
- entry
1174
+ entry,
1175
+ status
1161
1176
  }
1162
1177
  ) }),
1163
1178
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { children: [
@@ -1165,7 +1180,7 @@ const ReleaseDetailsBody = () => {
1165
1180
  ReleaseActionMenu.ReleaseActionEntryLinkItem,
1166
1181
  {
1167
1182
  contentTypeUid: contentType.uid,
1168
- entryId: entry.id,
1183
+ documentId: entry.documentId,
1169
1184
  locale: locale?.code
1170
1185
  }
1171
1186
  ),
@@ -1184,54 +1199,73 @@ const ReleaseDetailsBody = () => {
1184
1199
  }
1185
1200
  )
1186
1201
  ] }, `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
- ] })
1202
+ /* @__PURE__ */ jsxs(
1203
+ Pagination.Root,
1204
+ {
1205
+ ...releaseMeta?.pagination,
1206
+ defaultPageSize: releaseMeta?.pagination?.pageSize,
1207
+ children: [
1208
+ /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1209
+ /* @__PURE__ */ jsx(Pagination.Links, {})
1210
+ ]
1211
+ }
1212
+ )
1198
1213
  ] }) });
1199
1214
  };
1200
1215
  const ReleaseDetailsPage = () => {
1201
1216
  const { formatMessage } = useIntl();
1202
1217
  const { releaseId } = useParams();
1203
- const toggleNotification = useNotification();
1218
+ const { toggleNotification } = useNotification();
1204
1219
  const { formatAPIError } = useAPIErrorHandler();
1205
- const { replace } = useHistory();
1220
+ const navigate = useNavigate();
1206
1221
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1207
1222
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1208
1223
  const {
1209
1224
  isLoading: isLoadingDetails,
1210
1225
  data,
1211
1226
  isSuccess: isSuccessDetails
1212
- } = useGetReleaseQuery({ id: releaseId });
1227
+ } = useGetReleaseQuery(
1228
+ { id: releaseId },
1229
+ {
1230
+ skip: !releaseId
1231
+ }
1232
+ );
1233
+ const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
1213
1234
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1214
- const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1235
+ const [deleteRelease] = useDeleteReleaseMutation();
1215
1236
  const toggleEditReleaseModal = () => {
1216
1237
  setReleaseModalShown((prev) => !prev);
1217
1238
  };
1239
+ const getTimezoneValue = () => {
1240
+ if (releaseData?.timezone) {
1241
+ return releaseData.timezone;
1242
+ } else {
1243
+ if (dataTimezone?.data.defaultTimezone) {
1244
+ return dataTimezone.data.defaultTimezone;
1245
+ }
1246
+ return null;
1247
+ }
1248
+ };
1218
1249
  const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
1219
- if (isLoadingDetails) {
1250
+ if (isLoadingDetails || isLoadingTimezone) {
1220
1251
  return /* @__PURE__ */ jsx(
1221
1252
  ReleaseDetailsLayout,
1222
1253
  {
1223
1254
  toggleEditReleaseModal,
1224
1255
  toggleWarningSubmit,
1225
- children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1256
+ children: /* @__PURE__ */ jsx(Page.Loading, {})
1226
1257
  }
1227
1258
  );
1228
1259
  }
1260
+ if (!releaseId) {
1261
+ return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1262
+ }
1229
1263
  const releaseData = isSuccessDetails && data?.data || null;
1230
1264
  const title = releaseData?.name || "";
1231
- const timezone = releaseData?.timezone ?? null;
1265
+ const timezone = getTimezoneValue();
1232
1266
  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") : "";
1267
+ const date = scheduledAt ? format$1(scheduledAt, "yyyy-MM-dd") : void 0;
1268
+ const time = scheduledAt ? format$1(scheduledAt, "HH:mm") : "";
1235
1269
  const handleEditRelease = async (values) => {
1236
1270
  const response = await updateRelease({
1237
1271
  id: releaseId,
@@ -1248,14 +1282,14 @@ const ReleaseDetailsPage = () => {
1248
1282
  })
1249
1283
  });
1250
1284
  toggleEditReleaseModal();
1251
- } else if (isAxiosError(response.error)) {
1285
+ } else if (isFetchError(response.error)) {
1252
1286
  toggleNotification({
1253
- type: "warning",
1287
+ type: "danger",
1254
1288
  message: formatAPIError(response.error)
1255
1289
  });
1256
1290
  } else {
1257
1291
  toggleNotification({
1258
- type: "warning",
1292
+ type: "danger",
1259
1293
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1260
1294
  });
1261
1295
  }
@@ -1265,15 +1299,15 @@ const ReleaseDetailsPage = () => {
1265
1299
  id: releaseId
1266
1300
  });
1267
1301
  if ("data" in response) {
1268
- replace("/plugins/content-releases");
1269
- } else if (isAxiosError(response.error)) {
1302
+ navigate("..");
1303
+ } else if (isFetchError(response.error)) {
1270
1304
  toggleNotification({
1271
- type: "warning",
1305
+ type: "danger",
1272
1306
  message: formatAPIError(response.error)
1273
1307
  });
1274
1308
  } else {
1275
1309
  toggleNotification({
1276
- type: "warning",
1310
+ type: "danger",
1277
1311
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1278
1312
  });
1279
1313
  }
@@ -1284,10 +1318,11 @@ const ReleaseDetailsPage = () => {
1284
1318
  toggleEditReleaseModal,
1285
1319
  toggleWarningSubmit,
1286
1320
  children: [
1287
- /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1288
- releaseModalShown && /* @__PURE__ */ jsx(
1321
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1322
+ /* @__PURE__ */ jsx(
1289
1323
  ReleaseModal,
1290
1324
  {
1325
+ open: releaseModalShown,
1291
1326
  handleClose: toggleEditReleaseModal,
1292
1327
  handleSubmit: handleEditRelease,
1293
1328
  isLoading: isLoadingDetails || isSubmittingForm,
@@ -1301,30 +1336,21 @@ const ReleaseDetailsPage = () => {
1301
1336
  }
1302
1337
  }
1303
1338
  ),
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
- )
1339
+ /* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1340
+ id: "content-releases.dialog.confirmation-message",
1341
+ defaultMessage: "Are you sure you want to delete this release?"
1342
+ }) }) })
1317
1343
  ]
1318
1344
  }
1319
1345
  );
1320
1346
  };
1321
1347
  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 })
1348
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1349
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1350
+ /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1325
1351
  ] }) });
1326
1352
  };
1327
1353
  export {
1328
1354
  App
1329
1355
  };
1330
- //# sourceMappingURL=App-jrh58sXY.mjs.map
1356
+ //# sourceMappingURL=App-B4mkcLmw.mjs.map