@strapi/content-releases 0.0.0-experimental.f2351bcfa3965c60f063a492da51faa2c636eee8 → 0.0.0-experimental.f28dba7c374eae9c02b95b4b77aba4c3ad41a841

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/dist/_chunks/App-dLXY5ei3.js +1353 -0
  2. package/dist/_chunks/App-dLXY5ei3.js.map +1 -0
  3. package/dist/_chunks/{App-JwN_xBnA.mjs → App-jrh58sXY.mjs} +558 -602
  4. package/dist/_chunks/App-jrh58sXY.mjs.map +1 -0
  5. package/dist/_chunks/{PurchaseContentReleases-_MxP6-Dt.mjs → PurchaseContentReleases-3tRbmbY3.mjs} +7 -8
  6. package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +1 -0
  7. package/dist/_chunks/{PurchaseContentReleases-Be3acS2L.js → PurchaseContentReleases-bpIYXOfu.js} +6 -7
  8. package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +1 -0
  9. package/dist/_chunks/{en-CmYoEnA7.js → en-HrREghh3.js} +2 -9
  10. package/dist/_chunks/en-HrREghh3.js.map +1 -0
  11. package/dist/_chunks/{en-D0yVZFqf.mjs → en-ltT1TlKQ.mjs} +2 -9
  12. package/dist/_chunks/en-ltT1TlKQ.mjs.map +1 -0
  13. package/dist/_chunks/index-CVO0Rqdm.js +1336 -0
  14. package/dist/_chunks/index-CVO0Rqdm.js.map +1 -0
  15. package/dist/_chunks/index-PiOGBETy.mjs +1315 -0
  16. package/dist/_chunks/index-PiOGBETy.mjs.map +1 -0
  17. package/dist/admin/index.js +15 -1
  18. package/dist/admin/index.js.map +1 -1
  19. package/dist/admin/index.mjs +16 -2
  20. package/dist/admin/index.mjs.map +1 -1
  21. package/dist/server/index.js +646 -809
  22. package/dist/server/index.js.map +1 -1
  23. package/dist/server/index.mjs +646 -810
  24. package/dist/server/index.mjs.map +1 -1
  25. package/package.json +37 -31
  26. package/dist/_chunks/App-BFo3ibui.js +0 -1395
  27. package/dist/_chunks/App-BFo3ibui.js.map +0 -1
  28. package/dist/_chunks/App-JwN_xBnA.mjs.map +0 -1
  29. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +0 -1
  30. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +0 -1
  31. package/dist/_chunks/ReleasesSettingsPage-BanjZwEc.js +0 -178
  32. package/dist/_chunks/ReleasesSettingsPage-BanjZwEc.js.map +0 -1
  33. package/dist/_chunks/ReleasesSettingsPage-CNMXGcZC.mjs +0 -178
  34. package/dist/_chunks/ReleasesSettingsPage-CNMXGcZC.mjs.map +0 -1
  35. package/dist/_chunks/en-CmYoEnA7.js.map +0 -1
  36. package/dist/_chunks/en-D0yVZFqf.mjs.map +0 -1
  37. package/dist/_chunks/index-C_e6DQb0.mjs +0 -1342
  38. package/dist/_chunks/index-C_e6DQb0.mjs.map +0 -1
  39. package/dist/_chunks/index-Em3KctMx.js +0 -1361
  40. package/dist/_chunks/index-Em3KctMx.js.map +0 -1
  41. package/dist/_chunks/schemas-63pFihNF.mjs +0 -44
  42. package/dist/_chunks/schemas-63pFihNF.mjs.map +0 -1
  43. package/dist/_chunks/schemas-z5zp-_Gd.js +0 -62
  44. package/dist/_chunks/schemas-z5zp-_Gd.js.map +0 -1
  45. package/dist/admin/src/components/RelativeTime.d.ts +0 -28
  46. package/dist/admin/src/components/ReleaseAction.d.ts +0 -3
  47. package/dist/admin/src/components/ReleaseActionMenu.d.ts +0 -26
  48. package/dist/admin/src/components/ReleaseActionModal.d.ts +0 -24
  49. package/dist/admin/src/components/ReleaseActionOptions.d.ts +0 -9
  50. package/dist/admin/src/components/ReleaseListCell.d.ts +0 -28
  51. package/dist/admin/src/components/ReleaseModal.d.ts +0 -17
  52. package/dist/admin/src/components/ReleasesPanel.d.ts +0 -3
  53. package/dist/admin/src/constants.d.ts +0 -76
  54. package/dist/admin/src/index.d.ts +0 -3
  55. package/dist/admin/src/modules/hooks.d.ts +0 -7
  56. package/dist/admin/src/pages/App.d.ts +0 -1
  57. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +0 -2
  58. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +0 -2
  59. package/dist/admin/src/pages/ReleasesPage.d.ts +0 -8
  60. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +0 -1
  61. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +0 -181
  62. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +0 -39
  63. package/dist/admin/src/pluginId.d.ts +0 -1
  64. package/dist/admin/src/services/release.d.ts +0 -112
  65. package/dist/admin/src/store/hooks.d.ts +0 -7
  66. package/dist/admin/src/utils/api.d.ts +0 -6
  67. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +0 -3
  68. package/dist/admin/src/utils/time.d.ts +0 -10
  69. package/dist/admin/src/validation/schemas.d.ts +0 -6
  70. package/dist/server/src/bootstrap.d.ts +0 -5
  71. package/dist/server/src/bootstrap.d.ts.map +0 -1
  72. package/dist/server/src/constants.d.ts +0 -21
  73. package/dist/server/src/constants.d.ts.map +0 -1
  74. package/dist/server/src/content-types/index.d.ts +0 -97
  75. package/dist/server/src/content-types/index.d.ts.map +0 -1
  76. package/dist/server/src/content-types/release/index.d.ts +0 -48
  77. package/dist/server/src/content-types/release/index.d.ts.map +0 -1
  78. package/dist/server/src/content-types/release/schema.d.ts +0 -47
  79. package/dist/server/src/content-types/release/schema.d.ts.map +0 -1
  80. package/dist/server/src/content-types/release-action/index.d.ts +0 -48
  81. package/dist/server/src/content-types/release-action/index.d.ts.map +0 -1
  82. package/dist/server/src/content-types/release-action/schema.d.ts +0 -47
  83. package/dist/server/src/content-types/release-action/schema.d.ts.map +0 -1
  84. package/dist/server/src/controllers/index.d.ts +0 -25
  85. package/dist/server/src/controllers/index.d.ts.map +0 -1
  86. package/dist/server/src/controllers/release-action.d.ts +0 -10
  87. package/dist/server/src/controllers/release-action.d.ts.map +0 -1
  88. package/dist/server/src/controllers/release.d.ts +0 -18
  89. package/dist/server/src/controllers/release.d.ts.map +0 -1
  90. package/dist/server/src/controllers/settings.d.ts +0 -11
  91. package/dist/server/src/controllers/settings.d.ts.map +0 -1
  92. package/dist/server/src/controllers/validation/release-action.d.ts +0 -14
  93. package/dist/server/src/controllers/validation/release-action.d.ts.map +0 -1
  94. package/dist/server/src/controllers/validation/release.d.ts +0 -4
  95. package/dist/server/src/controllers/validation/release.d.ts.map +0 -1
  96. package/dist/server/src/controllers/validation/settings.d.ts +0 -3
  97. package/dist/server/src/controllers/validation/settings.d.ts.map +0 -1
  98. package/dist/server/src/destroy.d.ts +0 -5
  99. package/dist/server/src/destroy.d.ts.map +0 -1
  100. package/dist/server/src/index.d.ts +0 -2113
  101. package/dist/server/src/index.d.ts.map +0 -1
  102. package/dist/server/src/middlewares/documents.d.ts +0 -6
  103. package/dist/server/src/middlewares/documents.d.ts.map +0 -1
  104. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +0 -9
  105. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +0 -1
  106. package/dist/server/src/migrations/index.d.ts +0 -13
  107. package/dist/server/src/migrations/index.d.ts.map +0 -1
  108. package/dist/server/src/register.d.ts +0 -5
  109. package/dist/server/src/register.d.ts.map +0 -1
  110. package/dist/server/src/routes/index.d.ts +0 -51
  111. package/dist/server/src/routes/index.d.ts.map +0 -1
  112. package/dist/server/src/routes/release-action.d.ts +0 -18
  113. package/dist/server/src/routes/release-action.d.ts.map +0 -1
  114. package/dist/server/src/routes/release.d.ts +0 -18
  115. package/dist/server/src/routes/release.d.ts.map +0 -1
  116. package/dist/server/src/routes/settings.d.ts +0 -18
  117. package/dist/server/src/routes/settings.d.ts.map +0 -1
  118. package/dist/server/src/services/index.d.ts +0 -1826
  119. package/dist/server/src/services/index.d.ts.map +0 -1
  120. package/dist/server/src/services/release-action.d.ts +0 -36
  121. package/dist/server/src/services/release-action.d.ts.map +0 -1
  122. package/dist/server/src/services/release.d.ts +0 -31
  123. package/dist/server/src/services/release.d.ts.map +0 -1
  124. package/dist/server/src/services/scheduling.d.ts +0 -18
  125. package/dist/server/src/services/scheduling.d.ts.map +0 -1
  126. package/dist/server/src/services/settings.d.ts +0 -13
  127. package/dist/server/src/services/settings.d.ts.map +0 -1
  128. package/dist/server/src/services/validation.d.ts +0 -18
  129. package/dist/server/src/services/validation.d.ts.map +0 -1
  130. package/dist/server/src/utils/index.d.ts +0 -35
  131. package/dist/server/src/utils/index.d.ts.map +0 -1
  132. package/dist/shared/contracts/release-actions.d.ts +0 -130
  133. package/dist/shared/contracts/release-actions.d.ts.map +0 -1
  134. package/dist/shared/contracts/releases.d.ts +0 -184
  135. package/dist/shared/contracts/releases.d.ts.map +0 -1
  136. package/dist/shared/contracts/settings.d.ts +0 -39
  137. package/dist/shared/contracts/settings.d.ts.map +0 -1
  138. package/dist/shared/types.d.ts +0 -24
  139. package/dist/shared/types.d.ts.map +0 -1
@@ -1,54 +1,45 @@
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-C_e6DQb0.mjs";
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";
5
5
  import * as React from "react";
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";
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";
11
11
  import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
12
12
  import { useIntl } from "react-intl";
13
- import { styled } from "styled-components";
14
- import { intervalToDuration, isPast, formatISO, format } from "date-fns";
13
+ import styled from "styled-components";
14
+ import { formatISO } from "date-fns";
15
15
  import { Formik, Form, useFormikContext } from "formik";
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
- );
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();
49
41
  const ReleaseModal = ({
50
42
  handleClose,
51
- open,
52
43
  handleSubmit,
53
44
  initialValues,
54
45
  isLoading = false
@@ -72,8 +63,8 @@ const ReleaseModal = ({
72
63
  );
73
64
  return currentTimezone?.value || systemTimezone.value;
74
65
  };
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(
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(
77
68
  {
78
69
  id: "content-releases.modal.title",
79
70
  defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
@@ -96,143 +87,133 @@ const ReleaseModal = ({
96
87
  },
97
88
  validationSchema: RELEASE_SCHEMA,
98
89
  validateOnChange: false,
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) {
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: () => {
126
156
  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: () => {
127
180
  setFieldValue("time", "");
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(
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(
224
195
  {
225
196
  id: "content-releases.modal.form.button.submit",
226
197
  defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
227
198
  },
228
199
  { isCreatingRelease }
229
200
  ) })
230
- ] })
231
- ] });
232
- }
201
+ }
202
+ )
203
+ ] })
233
204
  }
234
205
  )
235
- ] }) });
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 };
236
217
  };
237
218
  const TimezoneComponent = ({ timezoneOptions }) => {
238
219
  const { values, errors, setFieldValue } = useFormikContext();
@@ -248,44 +229,32 @@ const TimezoneComponent = ({ timezoneOptions }) => {
248
229
  }
249
230
  }
250
231
  }, [setFieldValue, values.date, values.timezone]);
251
- return /* @__PURE__ */ jsxs(
252
- Field.Root,
232
+ return /* @__PURE__ */ jsx(
233
+ Combobox,
253
234
  {
235
+ label: formatMessage({
236
+ id: "content-releases.modal.form.input.label.timezone",
237
+ defaultMessage: "Timezone"
238
+ }),
239
+ autocomplete: { type: "list", filter: "contains" },
254
240
  name: "timezone",
255
- error: errors.timezone && formatMessage({ id: errors.timezone, defaultMessage: errors.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,
256
253
  required: true,
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
- ]
254
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
282
255
  }
283
256
  );
284
257
  };
285
- const useTypedDispatch = useDispatch;
286
- const isBaseQueryError = (error) => {
287
- return typeof error !== "undefined" && error.name !== void 0;
288
- };
289
258
  const LinkCard = styled(Link)`
290
259
  display: block;
291
260
  `;
@@ -323,7 +292,7 @@ const getBadgeProps = (status) => {
323
292
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
324
293
  const { formatMessage } = useIntl();
325
294
  if (isError) {
326
- return /* @__PURE__ */ jsx(Page.Error, {});
295
+ return /* @__PURE__ */ jsx(AnErrorOccurred, {});
327
296
  }
328
297
  if (releases?.length === 0) {
329
298
  return /* @__PURE__ */ jsx(
@@ -338,11 +307,11 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
338
307
  target: sectionTitle
339
308
  }
340
309
  ),
341
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
310
+ icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "10rem" })
342
311
  }
343
312
  );
344
313
  }
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(
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(
346
315
  Flex,
347
316
  {
348
317
  direction: "column",
@@ -357,7 +326,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
357
326
  gap: 4,
358
327
  children: [
359
328
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
360
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
329
+ /* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
361
330
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
362
331
  id: "content-releases.pages.Releases.not-scheduled",
363
332
  defaultMessage: "Not scheduled"
@@ -378,35 +347,33 @@ const StyledAlert = styled(Alert)`
378
347
  `;
379
348
  const INITIAL_FORM_VALUES = {
380
349
  name: "",
381
- date: format(/* @__PURE__ */ new Date(), "yyyy-MM-dd"),
350
+ date: null,
382
351
  time: "",
383
352
  isScheduled: true,
384
353
  scheduledAt: null,
385
354
  timezone: null
386
355
  };
387
356
  const ReleasesPage = () => {
357
+ const tabRef = React.useRef(null);
388
358
  const location = useLocation();
389
359
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
390
- const { toggleNotification } = useNotification();
360
+ const toggleNotification = useNotification();
391
361
  const { formatMessage } = useIntl();
392
- const navigate = useNavigate();
362
+ const { push, replace } = useHistory();
393
363
  const { formatAPIError } = useAPIErrorHandler();
394
364
  const [{ query }, setQuery] = useQueryParams();
395
365
  const response = useGetReleasesQuery(query);
396
- const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
397
366
  const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
398
367
  const { getFeature } = useLicenseLimits();
399
368
  const { maximumReleases = 3 } = getFeature("cms-content-releases");
400
369
  const { trackUsage } = useTracking();
401
- const {
402
- allowedActions: { canCreate }
403
- } = useRBAC(PERMISSIONS);
404
- const { isLoading: isLoadingReleases, isSuccess, isError } = response;
370
+ const { isLoading, isSuccess, isError } = response;
405
371
  const activeTab = response?.currentData?.meta?.activeTab || "pending";
372
+ const activeTabIndex = ["pending", "done"].indexOf(activeTab);
406
373
  React.useEffect(() => {
407
374
  if (location?.state?.errors) {
408
375
  toggleNotification({
409
- type: "danger",
376
+ type: "warning",
410
377
  title: formatMessage({
411
378
  id: "content-releases.pages.Releases.notification.error.title",
412
379
  defaultMessage: "Your request could not be processed."
@@ -416,25 +383,30 @@ const ReleasesPage = () => {
416
383
  defaultMessage: "Please try again or open another release."
417
384
  })
418
385
  });
419
- navigate("", { replace: true, state: null });
386
+ replace({ state: null });
420
387
  }
421
- }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
388
+ }, [formatMessage, location?.state?.errors, replace, toggleNotification]);
389
+ React.useEffect(() => {
390
+ if (tabRef.current) {
391
+ tabRef.current._handlers.setSelectedTabIndex(activeTabIndex);
392
+ }
393
+ }, [activeTabIndex]);
422
394
  const toggleAddReleaseModal = () => {
423
395
  setReleaseModalShown((prev) => !prev);
424
396
  };
425
- if (isLoadingReleases || isLoadingSettings) {
426
- return /* @__PURE__ */ jsx(Page.Loading, {});
397
+ if (isLoading) {
398
+ return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
427
399
  }
428
400
  const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
429
401
  const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
430
- const handleTabChange = (tabValue) => {
402
+ const handleTabChange = (index) => {
431
403
  setQuery({
432
404
  ...query,
433
405
  page: 1,
434
406
  pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
435
407
  filters: {
436
408
  releasedAt: {
437
- $notNull: tabValue !== "pending"
409
+ $notNull: index === 0 ? false : true
438
410
  }
439
411
  }
440
412
  });
@@ -454,22 +426,22 @@ const ReleasesPage = () => {
454
426
  })
455
427
  });
456
428
  trackUsage("didCreateRelease");
457
- navigate(response2.data.data.id.toString());
458
- } else if (isFetchError(response2.error)) {
429
+ push(`/plugins/content-releases/${response2.data.data.id}`);
430
+ } else if (isAxiosError(response2.error)) {
459
431
  toggleNotification({
460
- type: "danger",
432
+ type: "warning",
461
433
  message: formatAPIError(response2.error)
462
434
  });
463
435
  } else {
464
436
  toggleNotification({
465
- type: "danger",
437
+ type: "warning",
466
438
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
467
439
  });
468
440
  }
469
441
  };
470
- return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
442
+ return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoading, children: [
471
443
  /* @__PURE__ */ jsx(
472
- Layouts.Header,
444
+ HeaderLayout,
473
445
  {
474
446
  title: formatMessage({
475
447
  id: "content-releases.pages.Releases.title",
@@ -479,7 +451,7 @@ const ReleasesPage = () => {
479
451
  id: "content-releases.pages.Releases.header-subtitle",
480
452
  defaultMessage: "Create and manage content updates"
481
453
  }),
482
- primaryAction: canCreate ? /* @__PURE__ */ jsx(
454
+ primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
483
455
  Button,
484
456
  {
485
457
  startIcon: /* @__PURE__ */ jsx(Plus, {}),
@@ -490,10 +462,10 @@ const ReleasesPage = () => {
490
462
  defaultMessage: "New release"
491
463
  })
492
464
  }
493
- ) : null
465
+ ) })
494
466
  }
495
467
  ),
496
- /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
468
+ /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
497
469
  hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
498
470
  StyledAlert,
499
471
  {
@@ -518,17 +490,21 @@ const ReleasesPage = () => {
518
490
  })
519
491
  }
520
492
  ),
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(
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(
532
508
  {
533
509
  id: "content-releases.pages.Releases.tab.pending",
534
510
  defaultMessage: "Pending ({count})"
@@ -537,55 +513,59 @@ const ReleasesPage = () => {
537
513
  count: totalPendingReleases
538
514
  }
539
515
  ) }),
540
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "done", children: formatMessage({
516
+ /* @__PURE__ */ jsx(Tab, { children: formatMessage({
541
517
  id: "content-releases.pages.Releases.tab.done",
542
518
  defaultMessage: "Done"
543
519
  }) })
544
- ]
545
- }
546
- ),
547
- /* @__PURE__ */ jsx(Divider, {})
548
- ] }),
549
- /* @__PURE__ */ jsx(Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsx(
550
- ReleasesGrid,
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,
551
547
  {
552
- sectionTitle: "pending",
553
- releases: response?.currentData?.data,
554
- isError
548
+ options: ["8", "16", "32", "64"],
549
+ defaultValue: response?.currentData?.meta?.pagination?.pageSize.toString()
555
550
  }
556
- ) }),
557
- /* @__PURE__ */ jsx(Tabs.Content, { value: "done", children: /* @__PURE__ */ jsx(
558
- ReleasesGrid,
551
+ ),
552
+ /* @__PURE__ */ jsx(
553
+ PaginationURLQuery,
559
554
  {
560
- sectionTitle: "done",
561
- releases: response?.currentData?.data,
562
- isError
555
+ pagination: {
556
+ pageCount: response?.currentData?.meta?.pagination?.pageCount || 0
557
+ }
563
558
  }
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
- )
559
+ )
560
+ ] }) : null
577
561
  ] }) }),
578
- /* @__PURE__ */ jsx(
562
+ releaseModalShown && /* @__PURE__ */ jsx(
579
563
  ReleaseModal,
580
564
  {
581
- open: releaseModalShown,
582
565
  handleClose: toggleAddReleaseModal,
583
566
  handleSubmit: handleAddRelease,
584
567
  isLoading: isSubmittingForm,
585
- initialValues: {
586
- ...INITIAL_FORM_VALUES,
587
- timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
588
- }
568
+ initialValues: INITIAL_FORM_VALUES
589
569
  }
590
570
  )
591
571
  ] });
@@ -596,7 +576,7 @@ const ReleaseInfoWrapper = styled(Flex)`
596
576
  border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
597
577
  border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
598
578
  `;
599
- const StyledMenuItem = styled(MenuItem)`
579
+ const StyledMenuItem = styled(Menu.Item)`
600
580
  svg path {
601
581
  fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
602
582
  }
@@ -605,19 +585,19 @@ const StyledMenuItem = styled(MenuItem)`
605
585
  }
606
586
 
607
587
  &:hover {
608
- background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
588
+ background: ${({ theme, variant = "neutral" }) => theme.colors[`${variant}100`]};
609
589
  }
610
590
  `;
611
591
  const PencilIcon = styled(Pencil)`
612
- width: ${({ theme }) => theme.spaces[4]};
613
- height: ${({ theme }) => theme.spaces[4]};
592
+ width: ${({ theme }) => theme.spaces[3]};
593
+ height: ${({ theme }) => theme.spaces[3]};
614
594
  path {
615
595
  fill: ${({ theme }) => theme.colors.neutral600};
616
596
  }
617
597
  `;
618
598
  const TrashIcon = styled(Trash)`
619
- width: ${({ theme }) => theme.spaces[4]};
620
- height: ${({ theme }) => theme.spaces[4]};
599
+ width: ${({ theme }) => theme.spaces[3]};
600
+ height: ${({ theme }) => theme.spaces[3]};
621
601
  path {
622
602
  fill: ${({ theme }) => theme.colors.danger600};
623
603
  }
@@ -625,93 +605,40 @@ const TrashIcon = styled(Trash)`
625
605
  const TypographyMaxWidth = styled(Typography)`
626
606
  max-width: 300px;
627
607
  `;
628
- const EntryValidationText = ({ action, schema, entry, status }) => {
608
+ const EntryValidationText = ({ action, schema, components, entry }) => {
629
609
  const { formatMessage } = useIntl();
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
- const errorsToString = (errors2, prefix = "") => {
641
- if (Object.keys(errors2).length === 0) {
642
- return "";
643
- }
644
- return Object.entries(errors2).map(([key, value]) => {
645
- if (value === void 0 || value === null) {
646
- return "";
647
- }
648
- if (typeof value === "string") {
649
- return formatMessage(
650
- { id: value, defaultMessage: value },
651
- { field: prefix ? `${prefix}.${key}` : key }
652
- );
653
- }
654
- if (typeof value === "object" && value !== null && "id" in value && "defaultMessage" in value) {
655
- return formatMessage(
656
- // @ts-expect-error – TODO: default message will be a string
657
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
658
- { field: prefix ? `${prefix}.${key}` : key }
659
- );
660
- }
661
- return errorsToString(value, key);
662
- }).join(" ");
663
- };
664
- if (isLoading) {
665
- return null;
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
+ ] });
666
627
  }
667
- const errors = validate(entry) ?? {};
668
- if (action === "publish") {
669
- if (Object.keys(errors).length > 0) {
670
- const validationErrorsMessages = errorsToString(errors);
671
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
672
- /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
673
- /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(
674
- TypographyMaxWidth,
675
- {
676
- textColor: "danger600",
677
- variant: "omega",
678
- fontWeight: "semiBold",
679
- ellipsis: true,
680
- children: validationErrorsMessages
681
- }
682
- ) })
683
- ] });
684
- }
685
- if (status === "draft") {
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.ready-to-publish",
690
- defaultMessage: "Ready to publish"
691
- }) })
692
- ] });
693
- }
694
- if (status === "modified") {
695
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
696
- /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
697
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
698
- id: "content-releases.pages.ReleaseDetails.entry-validation.modified",
699
- defaultMessage: "Ready to publish changes"
700
- }) })
701
- ] });
702
- }
703
- if (status === "published") {
704
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
705
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
706
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
707
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
708
- defaultMessage: "Already published"
709
- }) })
710
- ] });
711
- }
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
+ ] });
712
639
  }
713
640
  return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
714
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
641
+ /* @__PURE__ */ jsx(Icon, { color: "success600", as: CheckCircle }),
715
642
  !entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
716
643
  id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
717
644
  defaultMessage: "Already unpublished"
@@ -731,23 +658,20 @@ const ReleaseDetailsLayout = ({
731
658
  const {
732
659
  data,
733
660
  isLoading: isLoadingDetails,
661
+ isError,
734
662
  error
735
- } = useGetReleaseQuery(
736
- { id: releaseId },
737
- {
738
- skip: !releaseId
739
- }
740
- );
663
+ } = useGetReleaseQuery({ id: releaseId });
741
664
  const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
742
- const { toggleNotification } = useNotification();
665
+ const toggleNotification = useNotification();
743
666
  const { formatAPIError } = useAPIErrorHandler();
744
- const { allowedActions } = useRBAC(PERMISSIONS);
745
- const { canUpdate, canDelete, canPublish } = allowedActions;
667
+ const {
668
+ allowedActions: { canUpdate, canDelete }
669
+ } = useRBAC(PERMISSIONS);
746
670
  const dispatch = useTypedDispatch();
747
671
  const { trackUsage } = useTracking();
748
672
  const release = data?.data;
749
- const handlePublishRelease = (id) => async () => {
750
- const response = await publishRelease({ id });
673
+ const handlePublishRelease = async () => {
674
+ const response = await publishRelease({ id: releaseId });
751
675
  if ("data" in response) {
752
676
  toggleNotification({
753
677
  type: "success",
@@ -762,14 +686,14 @@ const ReleaseDetailsLayout = ({
762
686
  totalPublishedEntries,
763
687
  totalUnpublishedEntries
764
688
  });
765
- } else if (isFetchError(response.error)) {
689
+ } else if (isAxiosError(response.error)) {
766
690
  toggleNotification({
767
- type: "danger",
691
+ type: "warning",
768
692
  message: formatAPIError(response.error)
769
693
  });
770
694
  } else {
771
695
  toggleNotification({
772
- type: "danger",
696
+ type: "warning",
773
697
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
774
698
  });
775
699
  }
@@ -795,20 +719,21 @@ const ReleaseDetailsLayout = ({
795
719
  return release.createdBy.email;
796
720
  };
797
721
  if (isLoadingDetails) {
798
- return /* @__PURE__ */ jsx(Page.Loading, {});
722
+ return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoadingDetails, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
799
723
  }
800
- if (isBaseQueryError(error) && "code" in error || !release) {
724
+ if (isError || !release) {
801
725
  return /* @__PURE__ */ jsx(
802
- Navigate,
726
+ Redirect,
803
727
  {
804
- to: "..",
805
- state: {
806
- errors: [
807
- {
808
- // @ts-expect-error – TODO: fix this weird error flow
809
- code: error?.code
810
- }
811
- ]
728
+ to: {
729
+ pathname: "/plugins/content-releases",
730
+ state: {
731
+ errors: [
732
+ {
733
+ code: error?.code
734
+ }
735
+ ]
736
+ }
812
737
  }
813
738
  }
814
739
  );
@@ -845,90 +770,106 @@ const ReleaseDetailsLayout = ({
845
770
  ) : "";
846
771
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
847
772
  /* @__PURE__ */ jsx(
848
- Layouts.Header,
773
+ HeaderLayout,
849
774
  {
850
775
  title: release.name,
851
776
  subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
852
777
  /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
853
778
  /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
854
779
  ] }),
855
- navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
780
+ navigationAction: /* @__PURE__ */ jsx(Link$1, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
781
+ id: "global.back",
782
+ defaultMessage: "Back"
783
+ }) }),
856
784
  primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
857
- /* @__PURE__ */ jsxs(
858
- SimpleMenuButton,
859
- {
860
- label: /* @__PURE__ */ jsx(More, {}),
861
- variant: "tertiary",
862
- endIcon: null,
863
- paddingLeft: "7px",
864
- paddingRight: "7px",
865
- "aria-label": formatMessage({
866
- id: "content-releases.header.actions.open-release-actions",
867
- defaultMessage: "Release edit and delete menu"
868
- }),
869
- popoverPlacement: "bottom-end",
870
- children: [
871
- /* @__PURE__ */ jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
872
- /* @__PURE__ */ jsx(PencilIcon, {}),
873
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
874
- id: "content-releases.header.actions.edit",
875
- defaultMessage: "Edit"
876
- }) })
877
- ] }) }),
878
- /* @__PURE__ */ jsx(
879
- StyledMenuItem,
880
- {
881
- disabled: !canDelete,
882
- onSelect: toggleWarningSubmit,
883
- $variant: "danger",
884
- children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
885
- /* @__PURE__ */ jsx(TrashIcon, {}),
886
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
887
- id: "content-releases.header.actions.delete",
888
- defaultMessage: "Delete"
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"
889
815
  }) })
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
+ )
890
857
  ] })
891
- }
892
- ),
893
- /* @__PURE__ */ jsxs(
894
- ReleaseInfoWrapper,
895
- {
896
- direction: "column",
897
- justifyContent: "center",
898
- alignItems: "flex-start",
899
- gap: 1,
900
- padding: 4,
901
- children: [
902
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
903
- id: "content-releases.header.actions.created",
904
- defaultMessage: "Created"
905
- }) }),
906
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
907
- /* @__PURE__ */ jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
908
- formatMessage(
909
- {
910
- id: "content-releases.header.actions.created.description",
911
- defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
912
- },
913
- { createdBy: getCreatedByUser(), hasCreatedByUser }
914
- )
915
- ] })
916
- ]
917
- }
918
- )
919
- ]
920
- }
921
- ),
858
+ ]
859
+ }
860
+ )
861
+ ] })
862
+ ] }),
922
863
  /* @__PURE__ */ jsx(Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
923
864
  id: "content-releases.header.actions.refresh",
924
865
  defaultMessage: "Refresh"
925
866
  }) }),
926
- canPublish ? /* @__PURE__ */ jsx(
867
+ /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.publish, children: /* @__PURE__ */ jsx(
927
868
  Button,
928
869
  {
929
870
  size: "S",
930
871
  variant: "default",
931
- onClick: handlePublishRelease(release.id.toString()),
872
+ onClick: handlePublishRelease,
932
873
  loading: isPublishing,
933
874
  disabled: release.actions.meta.count === 0,
934
875
  children: formatMessage({
@@ -936,18 +877,13 @@ const ReleaseDetailsLayout = ({
936
877
  defaultMessage: "Publish"
937
878
  })
938
879
  }
939
- ) : null
880
+ ) })
940
881
  ] })
941
882
  }
942
883
  ),
943
884
  children
944
885
  ] });
945
886
  };
946
- const SimpleMenuButton = styled(SimpleMenu)`
947
- & > span {
948
- display: flex;
949
- }
950
- `;
951
887
  const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
952
888
  const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
953
889
  const getGroupByOptionLabel = (value) => {
@@ -968,32 +904,47 @@ const getGroupByOptionLabel = (value) => {
968
904
  defaultMessage: "Content-Types"
969
905
  };
970
906
  };
971
- const ReleaseDetailsBody = ({ releaseId }) => {
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 = () => {
972
923
  const { formatMessage } = useIntl();
924
+ const { releaseId } = useParams();
973
925
  const [{ query }, setQuery] = useQueryParams();
974
- const { toggleNotification } = useNotification();
926
+ const toggleNotification = useNotification();
975
927
  const { formatAPIError } = useAPIErrorHandler();
976
928
  const {
977
929
  data: releaseData,
978
930
  isLoading: isReleaseLoading,
931
+ isError: isReleaseError,
979
932
  error: releaseError
980
933
  } = useGetReleaseQuery({ id: releaseId });
981
934
  const {
982
935
  allowedActions: { canUpdate }
983
936
  } = useRBAC(PERMISSIONS);
984
- const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
985
- const { displayedHeaders, hasI18nEnabled } = runHookWaterfall("ContentReleases/pages/ReleaseDetails/add-locale-in-releases", {
986
- displayedHeaders: [
987
- {
988
- label: {
989
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
990
- defaultMessage: "name"
991
- },
992
- name: "name"
993
- }
994
- ],
995
- hasI18nEnabled: false
996
- });
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
+ );
997
948
  const release = releaseData?.data;
998
949
  const selectedGroupBy = query?.groupBy || "contentType";
999
950
  const {
@@ -1022,59 +973,65 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1022
973
  // We are passing the action path to found the position in the cache of the action for optimistic updates
1023
974
  });
1024
975
  if ("error" in response) {
1025
- if (isFetchError(response.error)) {
976
+ if (isAxiosError(response.error)) {
1026
977
  toggleNotification({
1027
- type: "danger",
978
+ type: "warning",
1028
979
  message: formatAPIError(response.error)
1029
980
  });
1030
981
  } else {
1031
982
  toggleNotification({
1032
- type: "danger",
983
+ type: "warning",
1033
984
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1034
985
  });
1035
986
  }
1036
987
  }
1037
988
  };
1038
989
  if (isLoading || isReleaseLoading) {
1039
- return /* @__PURE__ */ jsx(Page.Loading, {});
990
+ return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
1040
991
  }
1041
992
  const releaseActions = data?.data;
1042
993
  const releaseMeta = data?.meta;
1043
994
  const contentTypes = releaseMeta?.contentTypes || {};
1044
995
  const components = releaseMeta?.components || {};
1045
- if (isBaseQueryError(releaseError) || !release) {
996
+ if (isReleaseError || !release) {
1046
997
  const errorsArray = [];
1047
- if (releaseError && "code" in releaseError) {
998
+ if (releaseError) {
1048
999
  errorsArray.push({
1049
1000
  code: releaseError.code
1050
1001
  });
1051
1002
  }
1052
- if (releaseActionsError && "code" in releaseActionsError) {
1003
+ if (releaseActionsError) {
1053
1004
  errorsArray.push({
1054
1005
  code: releaseActionsError.code
1055
1006
  });
1056
1007
  }
1057
1008
  return /* @__PURE__ */ jsx(
1058
- Navigate,
1009
+ Redirect,
1059
1010
  {
1060
- to: "..",
1061
- state: {
1062
- errors: errorsArray
1011
+ to: {
1012
+ pathname: "/plugins/content-releases",
1013
+ state: {
1014
+ errors: errorsArray
1015
+ }
1063
1016
  }
1064
1017
  }
1065
1018
  );
1066
1019
  }
1067
1020
  if (isError || !releaseActions) {
1068
- return /* @__PURE__ */ jsx(Page.Error, {});
1021
+ return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(AnErrorOccurred, {}) });
1069
1022
  }
1070
1023
  if (Object.keys(releaseActions).length === 0) {
1071
- return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1072
- EmptyStateLayout,
1024
+ return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(
1025
+ NoContent,
1073
1026
  {
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
+ },
1074
1031
  action: /* @__PURE__ */ jsx(
1075
1032
  LinkButton,
1076
1033
  {
1077
- tag: Link$1,
1034
+ as: Link$2,
1078
1035
  to: {
1079
1036
  pathname: "/content-manager"
1080
1037
  },
@@ -1085,52 +1042,19 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1085
1042
  defaultMessage: "Open the Content Manager"
1086
1043
  })
1087
1044
  }
1088
- ),
1089
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1090
- content: formatMessage({
1091
- id: "content-releases.pages.Details.tab.emptyEntries",
1092
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1093
- })
1045
+ )
1094
1046
  }
1095
1047
  ) });
1096
1048
  }
1097
- const groupByLabel = formatMessage({
1098
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1099
- defaultMessage: "Group by"
1100
- });
1101
- const headers = [
1102
- ...displayedHeaders,
1103
- {
1104
- label: {
1105
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1106
- defaultMessage: "content-type"
1107
- },
1108
- name: "content-type"
1109
- },
1110
- {
1111
- label: {
1112
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
1113
- defaultMessage: "action"
1114
- },
1115
- name: "action"
1116
- },
1117
- ...!release.releasedAt ? [
1118
- {
1119
- label: {
1120
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
1121
- defaultMessage: "status"
1122
- },
1123
- name: "status"
1124
- }
1125
- ] : []
1126
- ];
1127
1049
  const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1128
- return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1050
+ return /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1129
1051
  /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1130
1052
  SingleSelect,
1131
1053
  {
1132
- placeholder: groupByLabel,
1133
- "aria-label": groupByLabel,
1054
+ "aria-label": formatMessage({
1055
+ id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1056
+ defaultMessage: "Group by"
1057
+ }),
1134
1058
  customizeContent: (value) => formatMessage(
1135
1059
  {
1136
1060
  id: `content-releases.pages.ReleaseDetails.groupBy.label`,
@@ -1154,13 +1078,57 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1154
1078
  ...item,
1155
1079
  id: Number(item.entry.id)
1156
1080
  })),
1157
- headers,
1158
- isLoading: isLoading || isFetching,
1081
+ colCount: releaseActions[key].length,
1082
+ isLoading,
1083
+ isFetching,
1159
1084
  children: /* @__PURE__ */ jsxs(Table.Content, { children: [
1160
- /* @__PURE__ */ jsx(Table.Head, { children: headers.map(({ label, name }) => /* @__PURE__ */ jsx(Table.HeaderCell, { label: formatMessage(label), name }, name)) }),
1161
- /* @__PURE__ */ jsx(Table.Loading, {}),
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, {}),
1162
1130
  /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1163
- ({ id, contentType, locale, type, entry, status }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1131
+ ({ id, contentType, locale, type, entry }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1164
1132
  /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
1165
1133
  hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1166
1134
  /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
@@ -1189,8 +1157,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1189
1157
  action: type,
1190
1158
  schema: contentTypes?.[contentType.uid],
1191
1159
  components,
1192
- entry,
1193
- status
1160
+ entry
1194
1161
  }
1195
1162
  ) }),
1196
1163
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { children: [
@@ -1198,7 +1165,7 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1198
1165
  ReleaseActionMenu.ReleaseActionEntryLinkItem,
1199
1166
  {
1200
1167
  contentTypeUid: contentType.uid,
1201
- documentId: entry.documentId,
1168
+ entryId: entry.id,
1202
1169
  locale: locale?.code
1203
1170
  }
1204
1171
  ),
@@ -1217,73 +1184,54 @@ const ReleaseDetailsBody = ({ releaseId }) => {
1217
1184
  }
1218
1185
  )
1219
1186
  ] }, `releases-group-${key}`)),
1220
- /* @__PURE__ */ jsxs(
1221
- Pagination.Root,
1222
- {
1223
- ...releaseMeta?.pagination,
1224
- defaultPageSize: releaseMeta?.pagination?.pageSize,
1225
- children: [
1226
- /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1227
- /* @__PURE__ */ jsx(Pagination.Links, {})
1228
- ]
1229
- }
1230
- )
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
+ ] })
1231
1198
  ] }) });
1232
1199
  };
1233
1200
  const ReleaseDetailsPage = () => {
1234
1201
  const { formatMessage } = useIntl();
1235
1202
  const { releaseId } = useParams();
1236
- const { toggleNotification } = useNotification();
1203
+ const toggleNotification = useNotification();
1237
1204
  const { formatAPIError } = useAPIErrorHandler();
1238
- const navigate = useNavigate();
1205
+ const { replace } = useHistory();
1239
1206
  const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1240
1207
  const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1241
1208
  const {
1242
1209
  isLoading: isLoadingDetails,
1243
1210
  data,
1244
1211
  isSuccess: isSuccessDetails
1245
- } = useGetReleaseQuery(
1246
- { id: releaseId },
1247
- {
1248
- skip: !releaseId
1249
- }
1250
- );
1251
- const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
1212
+ } = useGetReleaseQuery({ id: releaseId });
1252
1213
  const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1253
- const [deleteRelease] = useDeleteReleaseMutation();
1214
+ const [deleteRelease, { isLoading: isDeletingRelease }] = useDeleteReleaseMutation();
1254
1215
  const toggleEditReleaseModal = () => {
1255
1216
  setReleaseModalShown((prev) => !prev);
1256
1217
  };
1257
- const getTimezoneValue = () => {
1258
- if (releaseData?.timezone) {
1259
- return releaseData.timezone;
1260
- } else {
1261
- if (dataTimezone?.data.defaultTimezone) {
1262
- return dataTimezone.data.defaultTimezone;
1263
- }
1264
- return null;
1265
- }
1266
- };
1267
1218
  const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
1268
- if (isLoadingDetails || isLoadingTimezone) {
1219
+ if (isLoadingDetails) {
1269
1220
  return /* @__PURE__ */ jsx(
1270
1221
  ReleaseDetailsLayout,
1271
1222
  {
1272
1223
  toggleEditReleaseModal,
1273
1224
  toggleWarningSubmit,
1274
- children: /* @__PURE__ */ jsx(Page.Loading, {})
1225
+ children: /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) })
1275
1226
  }
1276
1227
  );
1277
1228
  }
1278
- if (!releaseId) {
1279
- return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1280
- }
1281
1229
  const releaseData = isSuccessDetails && data?.data || null;
1282
1230
  const title = releaseData?.name || "";
1283
- const timezone = getTimezoneValue();
1231
+ const timezone = releaseData?.timezone ?? null;
1284
1232
  const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1285
- const date = scheduledAt ? format$1(scheduledAt, "yyyy-MM-dd") : void 0;
1286
- const time = scheduledAt ? format$1(scheduledAt, "HH:mm") : "";
1233
+ const date = scheduledAt ? format(scheduledAt, "yyyy-MM-dd") : null;
1234
+ const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
1287
1235
  const handleEditRelease = async (values) => {
1288
1236
  const response = await updateRelease({
1289
1237
  id: releaseId,
@@ -1300,14 +1248,14 @@ const ReleaseDetailsPage = () => {
1300
1248
  })
1301
1249
  });
1302
1250
  toggleEditReleaseModal();
1303
- } else if (isFetchError(response.error)) {
1251
+ } else if (isAxiosError(response.error)) {
1304
1252
  toggleNotification({
1305
- type: "danger",
1253
+ type: "warning",
1306
1254
  message: formatAPIError(response.error)
1307
1255
  });
1308
1256
  } else {
1309
1257
  toggleNotification({
1310
- type: "danger",
1258
+ type: "warning",
1311
1259
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1312
1260
  });
1313
1261
  }
@@ -1317,15 +1265,15 @@ const ReleaseDetailsPage = () => {
1317
1265
  id: releaseId
1318
1266
  });
1319
1267
  if ("data" in response) {
1320
- navigate("..");
1321
- } else if (isFetchError(response.error)) {
1268
+ replace("/plugins/content-releases");
1269
+ } else if (isAxiosError(response.error)) {
1322
1270
  toggleNotification({
1323
- type: "danger",
1271
+ type: "warning",
1324
1272
  message: formatAPIError(response.error)
1325
1273
  });
1326
1274
  } else {
1327
1275
  toggleNotification({
1328
- type: "danger",
1276
+ type: "warning",
1329
1277
  message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1330
1278
  });
1331
1279
  }
@@ -1336,11 +1284,10 @@ const ReleaseDetailsPage = () => {
1336
1284
  toggleEditReleaseModal,
1337
1285
  toggleWarningSubmit,
1338
1286
  children: [
1339
- /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1340
- /* @__PURE__ */ jsx(
1287
+ /* @__PURE__ */ jsx(ReleaseDetailsBody, {}),
1288
+ releaseModalShown && /* @__PURE__ */ jsx(
1341
1289
  ReleaseModal,
1342
1290
  {
1343
- open: releaseModalShown,
1344
1291
  handleClose: toggleEditReleaseModal,
1345
1292
  handleSubmit: handleEditRelease,
1346
1293
  isLoading: isLoadingDetails || isSubmittingForm,
@@ -1354,21 +1301,30 @@ const ReleaseDetailsPage = () => {
1354
1301
  }
1355
1302
  }
1356
1303
  ),
1357
- /* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1358
- id: "content-releases.dialog.confirmation-message",
1359
- defaultMessage: "Are you sure you want to delete this release?"
1360
- }) }) })
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
+ )
1361
1317
  ]
1362
1318
  }
1363
1319
  );
1364
1320
  };
1365
1321
  const App = () => {
1366
- return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1367
- /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1368
- /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
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 })
1369
1325
  ] }) });
1370
1326
  };
1371
1327
  export {
1372
1328
  App
1373
1329
  };
1374
- //# sourceMappingURL=App-JwN_xBnA.mjs.map
1330
+ //# sourceMappingURL=App-jrh58sXY.mjs.map