@strapi/content-releases 0.0.0-next.aa7c7ec6724534e157d8a23fe85ee8318dabbf37 → 0.0.0-next.b6d552f6e63dec5627cb8611ab2adcb8244359be

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 (29) hide show
  1. package/dist/_chunks/{App-pspKUC-W.js → App-5G7GEzBM.js} +292 -69
  2. package/dist/_chunks/App-5G7GEzBM.js.map +1 -0
  3. package/dist/_chunks/{App-8FCxPK8-.mjs → App-WMxox0mk.mjs} +293 -71
  4. package/dist/_chunks/App-WMxox0mk.mjs.map +1 -0
  5. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs +51 -0
  6. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +1 -0
  7. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js +51 -0
  8. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +1 -0
  9. package/dist/_chunks/{en-m9eTk4UF.mjs → en-WuuhP6Bn.mjs} +15 -4
  10. package/dist/_chunks/en-WuuhP6Bn.mjs.map +1 -0
  11. package/dist/_chunks/{en-r9YocBH0.js → en-gcJJ5htG.js} +15 -4
  12. package/dist/_chunks/en-gcJJ5htG.js.map +1 -0
  13. package/dist/_chunks/{index-8aK7GzI5.mjs → index-BZ8RPGiV.mjs} +91 -14
  14. package/dist/_chunks/index-BZ8RPGiV.mjs.map +1 -0
  15. package/dist/_chunks/{index-nGaPcY9m.js → index-pQ3hnZJy.js} +87 -10
  16. package/dist/_chunks/index-pQ3hnZJy.js.map +1 -0
  17. package/dist/admin/index.js +1 -1
  18. package/dist/admin/index.mjs +2 -2
  19. package/dist/server/index.js +769 -431
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/server/index.mjs +768 -431
  22. package/dist/server/index.mjs.map +1 -1
  23. package/package.json +13 -11
  24. package/dist/_chunks/App-8FCxPK8-.mjs.map +0 -1
  25. package/dist/_chunks/App-pspKUC-W.js.map +0 -1
  26. package/dist/_chunks/en-m9eTk4UF.mjs.map +0 -1
  27. package/dist/_chunks/en-r9YocBH0.js.map +0 -1
  28. package/dist/_chunks/index-8aK7GzI5.mjs.map +0 -1
  29. package/dist/_chunks/index-nGaPcY9m.js.map +0 -1
@@ -1,15 +1,18 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { useNotification, useAPIErrorHandler, LoadingIndicatorPage, ConfirmDialog, useRBAC, useTracking, RelativeTime, CheckPermissions, useQueryParams, AnErrorOccurred, NoContent, Table, PageSizeURLQuery, PaginationURLQuery, CheckPagePermissions } from "@strapi/helper-plugin";
3
3
  import { useLocation, useParams, useHistory, Redirect, Link as Link$1, Switch, Route } from "react-router-dom";
4
- import { p as pluginId, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, P as PERMISSIONS, d as useTypedDispatch, e as useGetReleaseActionsQuery, f as useUpdateReleaseActionMutation, R as ReleaseActionOptions, g as ReleaseActionMenu, i as isAxiosError, r as releaseApi, h as useGetReleasesQuery, j as useCreateReleaseMutation } from "./index-8aK7GzI5.mjs";
4
+ import { g as getTimezoneOffset, p as pluginId, u as useGetReleaseQuery, a as useUpdateReleaseMutation, b as useDeleteReleaseMutation, c as usePublishReleaseMutation, P as PERMISSIONS, d as useTypedDispatch, e as useGetReleaseActionsQuery, f as useUpdateReleaseActionMutation, R as ReleaseActionOptions, h as ReleaseActionMenu, i as isAxiosError, r as releaseApi, j as useGetReleasesQuery, k as useCreateReleaseMutation } from "./index-BZ8RPGiV.mjs";
5
5
  import * as React from "react";
6
6
  import { unstable_useDocument, useLicenseLimits } from "@strapi/admin/strapi-admin";
7
- import { ModalLayout, ModalHeader, Typography, ModalBody, TextInput, ModalFooter, Button, Flex, ContentLayout, Main, HeaderLayout, Link, IconButton, SingleSelect, SingleSelectOption, Badge, Tr, Td, Icon, Tooltip, Alert, TabGroup, Box, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem } from "@strapi/design-system";
7
+ import { ModalLayout, ModalHeader, Typography, ModalBody, Flex, TextInput, Box, Checkbox, DatePicker, TimePicker, ModalFooter, Button, Combobox, ComboboxOption, ContentLayout, Main, HeaderLayout, Link, IconButton, SingleSelect, SingleSelectOption, Badge, Tr, Td, Icon, Tooltip, Alert, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, EmptyStateLayout, Grid, GridItem } from "@strapi/design-system";
8
8
  import { Menu, LinkButton, Link as Link$2 } from "@strapi/design-system/v2";
9
9
  import { Pencil, Trash, ArrowLeft, More, CrossCircle, CheckCircle, Plus, EmptyDocuments } from "@strapi/icons";
10
+ import format from "date-fns/format";
11
+ import { zonedTimeToUtc, utcToZonedTime } from "date-fns-tz";
10
12
  import { useIntl } from "react-intl";
11
13
  import styled from "styled-components";
12
- import { Formik, Form } from "formik";
14
+ import { formatISO, parse } from "date-fns";
15
+ import { Formik, Form, useFormikContext } from "formik";
13
16
  import * as yup from "yup";
14
17
  import "@reduxjs/toolkit/query";
15
18
  import "axios";
@@ -17,8 +20,23 @@ import "@reduxjs/toolkit/query/react";
17
20
  import "react-redux";
18
21
  const RELEASE_SCHEMA = yup.object().shape({
19
22
  name: yup.string().trim().required(),
20
- // scheduledAt is a date, but we always receive strings from the client
21
- scheduledAt: yup.string().nullable()
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
+ })
22
40
  }).required().noUnknown();
23
41
  const ReleaseModal = ({
24
42
  handleClose,
@@ -29,6 +47,24 @@ const ReleaseModal = ({
29
47
  const { formatMessage } = useIntl();
30
48
  const { pathname } = useLocation();
31
49
  const isCreatingRelease = pathname === `/plugins/${pluginId}`;
50
+ const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
51
+ const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
52
+ initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
53
+ );
54
+ const getScheduledTimestamp = (values) => {
55
+ const { date, time, timezone } = values;
56
+ if (!date || !time || !timezone)
57
+ return null;
58
+ const formattedDate = parse(time, "HH:mm", new Date(date));
59
+ const timezoneWithoutOffset = timezone.split("_")[1];
60
+ return zonedTimeToUtc(formattedDate, timezoneWithoutOffset);
61
+ };
62
+ const getTimezoneWithOffset = () => {
63
+ const currentTimezone = timezoneList.find(
64
+ (timezone) => timezone.value.split("_")[1] === initialValues.timezone
65
+ );
66
+ return currentTimezone?.value || systemTimezone.value;
67
+ };
32
68
  return /* @__PURE__ */ jsxs(ModalLayout, { onClose: handleClose, labelledBy: "title", children: [
33
69
  /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { id: "title", fontWeight: "bold", textColor: "neutral800", children: formatMessage(
34
70
  {
@@ -40,45 +76,134 @@ const ReleaseModal = ({
40
76
  /* @__PURE__ */ jsx(
41
77
  Formik,
42
78
  {
43
- validateOnChange: false,
44
- onSubmit: handleSubmit,
45
- initialValues,
79
+ onSubmit: (values) => {
80
+ handleSubmit({
81
+ ...values,
82
+ timezone: values.timezone ? values.timezone.split("_")[1] : null,
83
+ scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
84
+ });
85
+ },
86
+ initialValues: {
87
+ ...initialValues,
88
+ timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
89
+ },
46
90
  validationSchema: RELEASE_SCHEMA,
47
- children: ({ values, errors, handleChange }) => /* @__PURE__ */ jsxs(Form, { children: [
48
- /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsx(
49
- TextInput,
50
- {
51
- label: formatMessage({
52
- id: "content-releases.modal.form.input.label.release-name",
53
- defaultMessage: "Name"
54
- }),
55
- name: "name",
56
- value: values.name,
57
- error: errors.name,
58
- onChange: handleChange,
59
- required: true
60
- }
61
- ) }),
91
+ validateOnChange: false,
92
+ children: ({ values, errors, handleChange, setFieldValue }) => /* @__PURE__ */ jsxs(Form, { children: [
93
+ /* @__PURE__ */ jsx(ModalBody, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
94
+ /* @__PURE__ */ jsx(
95
+ TextInput,
96
+ {
97
+ label: formatMessage({
98
+ id: "content-releases.modal.form.input.label.release-name",
99
+ defaultMessage: "Name"
100
+ }),
101
+ name: "name",
102
+ value: values.name,
103
+ error: errors.name,
104
+ onChange: handleChange,
105
+ required: true
106
+ }
107
+ ),
108
+ IsSchedulingEnabled && /* @__PURE__ */ jsxs(Fragment, { children: [
109
+ /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
110
+ Checkbox,
111
+ {
112
+ name: "isScheduled",
113
+ value: values.isScheduled,
114
+ onChange: (event) => {
115
+ setFieldValue("isScheduled", event.target.checked);
116
+ if (!event.target.checked) {
117
+ setFieldValue("date", null);
118
+ setFieldValue("time", "");
119
+ setFieldValue("timezone", null);
120
+ } else {
121
+ setFieldValue("date", initialValues.date);
122
+ setFieldValue("time", initialValues.time);
123
+ setFieldValue(
124
+ "timezone",
125
+ initialValues.timezone ?? systemTimezone?.value
126
+ );
127
+ }
128
+ },
129
+ children: /* @__PURE__ */ jsx(
130
+ Typography,
131
+ {
132
+ textColor: values.isScheduled ? "primary600" : "neutral800",
133
+ fontWeight: values.isScheduled ? "semiBold" : "regular",
134
+ children: formatMessage({
135
+ id: "modal.form.input.label.schedule-release",
136
+ defaultMessage: "Schedule release"
137
+ })
138
+ }
139
+ )
140
+ }
141
+ ) }),
142
+ values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
143
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
144
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
145
+ DatePicker,
146
+ {
147
+ label: formatMessage({
148
+ id: "content-releases.modal.form.input.label.date",
149
+ defaultMessage: "Date"
150
+ }),
151
+ name: "date",
152
+ error: errors.date,
153
+ onChange: (date) => {
154
+ const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
155
+ setFieldValue("date", isoFormatDate);
156
+ },
157
+ clearLabel: formatMessage({
158
+ id: "content-releases.modal.form.input.clearLabel",
159
+ defaultMessage: "Clear"
160
+ }),
161
+ onClear: () => {
162
+ setFieldValue("date", null);
163
+ },
164
+ selectedDate: values.date || void 0,
165
+ required: true
166
+ }
167
+ ) }),
168
+ /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
169
+ TimePicker,
170
+ {
171
+ label: formatMessage({
172
+ id: "content-releases.modal.form.input.label.time",
173
+ defaultMessage: "Time"
174
+ }),
175
+ name: "time",
176
+ error: errors.time,
177
+ onChange: (time) => {
178
+ setFieldValue("time", time);
179
+ },
180
+ clearLabel: formatMessage({
181
+ id: "content-releases.modal.form.input.clearLabel",
182
+ defaultMessage: "Clear"
183
+ }),
184
+ onClear: () => {
185
+ setFieldValue("time", "");
186
+ },
187
+ value: values.time || void 0,
188
+ required: true
189
+ }
190
+ ) })
191
+ ] }),
192
+ /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
193
+ ] })
194
+ ] })
195
+ ] }) }),
62
196
  /* @__PURE__ */ jsx(
63
197
  ModalFooter,
64
198
  {
65
199
  startActions: /* @__PURE__ */ jsx(Button, { onClick: handleClose, variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }),
66
- endActions: /* @__PURE__ */ jsx(
67
- Button,
200
+ endActions: /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
68
201
  {
69
- name: "submit",
70
- loading: isLoading,
71
- disabled: !values.name || values.name === initialValues.name,
72
- type: "submit",
73
- children: formatMessage(
74
- {
75
- id: "content-releases.modal.form.button.submit",
76
- defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
77
- },
78
- { isCreatingRelease }
79
- )
80
- }
81
- )
202
+ id: "content-releases.modal.form.button.submit",
203
+ defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
204
+ },
205
+ { isCreatingRelease }
206
+ ) })
82
207
  }
83
208
  )
84
209
  ] })
@@ -86,6 +211,52 @@ const ReleaseModal = ({
86
211
  )
87
212
  ] });
88
213
  };
214
+ const getTimezones = (selectedDate) => {
215
+ const timezoneList = Intl.supportedValuesOf("timeZone").map((timezone) => {
216
+ const utcOffset = getTimezoneOffset(timezone, selectedDate);
217
+ return { offset: utcOffset, value: `${utcOffset}_${timezone}` };
218
+ });
219
+ const systemTimezone = timezoneList.find(
220
+ (timezone) => timezone.value.split("_")[1] === Intl.DateTimeFormat().resolvedOptions().timeZone
221
+ );
222
+ return { timezoneList, systemTimezone };
223
+ };
224
+ const TimezoneComponent = ({ timezoneOptions }) => {
225
+ const { values, errors, setFieldValue } = useFormikContext();
226
+ const { formatMessage } = useIntl();
227
+ const [timezoneList, setTimezoneList] = React.useState(timezoneOptions);
228
+ React.useEffect(() => {
229
+ if (values.date) {
230
+ const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
231
+ setTimezoneList(timezoneList2);
232
+ const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("_")[1] === values.timezone.split("_")[1]);
233
+ if (updatedTimezone) {
234
+ setFieldValue("timezone", updatedTimezone.value);
235
+ }
236
+ }
237
+ }, [setFieldValue, values.date, values.timezone]);
238
+ return /* @__PURE__ */ jsx(
239
+ Combobox,
240
+ {
241
+ label: formatMessage({
242
+ id: "content-releases.modal.form.input.label.timezone",
243
+ defaultMessage: "Timezone"
244
+ }),
245
+ name: "timezone",
246
+ value: values.timezone || void 0,
247
+ textValue: values.timezone ? values.timezone.replace("_", " ") : void 0,
248
+ onChange: (timezone) => {
249
+ setFieldValue("timezone", timezone);
250
+ },
251
+ onClear: () => {
252
+ setFieldValue("timezone", "");
253
+ },
254
+ error: errors.timezone,
255
+ required: true,
256
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace("_", " ") }, timezone.value))
257
+ }
258
+ );
259
+ };
89
260
  const ReleaseInfoWrapper = styled(Flex)`
90
261
  align-self: stretch;
91
262
  border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
@@ -165,7 +336,7 @@ const ReleaseDetailsLayout = ({
165
336
  toggleWarningSubmit,
166
337
  children
167
338
  }) => {
168
- const { formatMessage } = useIntl();
339
+ const { formatMessage, formatDate, formatTime } = useIntl();
169
340
  const { releaseId } = useParams();
170
341
  const {
171
342
  data,
@@ -247,18 +418,41 @@ const ReleaseDetailsLayout = ({
247
418
  }
248
419
  const totalEntries = release.actions.meta.count || 0;
249
420
  const hasCreatedByUser = Boolean(getCreatedByUser());
421
+ const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
422
+ const isScheduled = release.scheduledAt && release.timezone;
423
+ const numberOfEntriesText = formatMessage(
424
+ {
425
+ id: "content-releases.pages.Details.header-subtitle",
426
+ defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
427
+ },
428
+ { number: totalEntries }
429
+ );
430
+ const scheduledText = isScheduled ? formatMessage(
431
+ {
432
+ id: "content-releases.pages.ReleaseDetails.header-subtitle.scheduled",
433
+ defaultMessage: "Scheduled for {date} at {time} ({offset})"
434
+ },
435
+ {
436
+ date: formatDate(new Date(release.scheduledAt), {
437
+ weekday: "long",
438
+ day: "numeric",
439
+ month: "long",
440
+ year: "numeric",
441
+ timeZone: release.timezone
442
+ }),
443
+ time: formatTime(new Date(release.scheduledAt), {
444
+ timeZone: release.timezone,
445
+ hourCycle: "h23"
446
+ }),
447
+ offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
448
+ }
449
+ ) : "";
250
450
  return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
251
451
  /* @__PURE__ */ jsx(
252
452
  HeaderLayout,
253
453
  {
254
454
  title: release.name,
255
- subtitle: formatMessage(
256
- {
257
- id: "content-releases.pages.Details.header-subtitle",
258
- defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
259
- },
260
- { number: totalEntries }
261
- ),
455
+ subtitle: numberOfEntriesText + (IsSchedulingEnabled && isScheduled ? ` - ${scheduledText}` : ""),
262
456
  navigationAction: /* @__PURE__ */ jsx(Link, { startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}), to: "/plugins/content-releases", children: formatMessage({
263
457
  id: "global.back",
264
458
  defaultMessage: "Back"
@@ -707,11 +901,18 @@ const ReleaseDetailsPage = () => {
707
901
  }
708
902
  );
709
903
  }
710
- const title = isSuccessDetails && data?.data?.name || "";
904
+ const releaseData = isSuccessDetails && data?.data || null;
905
+ const title = releaseData?.name || "";
906
+ const timezone = releaseData?.timezone ?? null;
907
+ const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
908
+ const date = scheduledAt ? new Date(format(scheduledAt, "yyyy-MM-dd")) : null;
909
+ const time = scheduledAt ? format(scheduledAt, "HH:mm") : "";
711
910
  const handleEditRelease = async (values) => {
712
911
  const response = await updateRelease({
713
912
  id: releaseId,
714
- name: values.name
913
+ name: values.name,
914
+ scheduledAt: values.scheduledAt,
915
+ timezone: values.timezone
715
916
  });
716
917
  if ("data" in response) {
717
918
  toggleNotification({
@@ -765,7 +966,14 @@ const ReleaseDetailsPage = () => {
765
966
  handleClose: toggleEditReleaseModal,
766
967
  handleSubmit: handleEditRelease,
767
968
  isLoading: isLoadingDetails || isSubmittingForm,
768
- initialValues: { name: title || "" }
969
+ initialValues: {
970
+ name: title || "",
971
+ scheduledAt,
972
+ date,
973
+ time,
974
+ isScheduled: Boolean(scheduledAt),
975
+ timezone
976
+ }
769
977
  }
770
978
  ),
771
979
  /* @__PURE__ */ jsx(
@@ -790,6 +998,7 @@ const LinkCard = styled(Link$2)`
790
998
  `;
791
999
  const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
792
1000
  const { formatMessage } = useIntl();
1001
+ const IsSchedulingEnabled = window.strapi.future.isEnabled("contentReleasesScheduling");
793
1002
  if (isError) {
794
1003
  return /* @__PURE__ */ jsx(AnErrorOccurred, {});
795
1004
  }
@@ -810,7 +1019,7 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
810
1019
  }
811
1020
  );
812
1021
  }
813
- return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, actions }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
1022
+ return /* @__PURE__ */ jsx(Grid, { gap: 4, children: releases.map(({ id, name, actions, scheduledAt }) => /* @__PURE__ */ jsx(GridItem, { col: 3, s: 6, xs: 12, children: /* @__PURE__ */ jsx(LinkCard, { href: `content-releases/${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
814
1023
  Flex,
815
1024
  {
816
1025
  direction: "column",
@@ -825,7 +1034,10 @@ const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
825
1034
  gap: 2,
826
1035
  children: [
827
1036
  /* @__PURE__ */ jsx(Typography, { as: "h3", variant: "delta", fontWeight: "bold", children: name }),
828
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: formatMessage(
1037
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: IsSchedulingEnabled ? scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
1038
+ id: "content-releases.pages.Releases.not-scheduled",
1039
+ defaultMessage: "Not scheduled"
1040
+ }) : formatMessage(
829
1041
  {
830
1042
  id: "content-releases.page.Releases.release-item.entries",
831
1043
  defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
@@ -845,7 +1057,13 @@ const StyledAlert = styled(Alert)`
845
1057
  }
846
1058
  `;
847
1059
  const INITIAL_FORM_VALUES = {
848
- name: ""
1060
+ name: "",
1061
+ date: null,
1062
+ time: "",
1063
+ // Remove future flag check after Scheduling Beta release and replace with true as creating new release should include scheduling by default
1064
+ isScheduled: window.strapi.future.isEnabled("contentReleasesScheduling"),
1065
+ scheduledAt: null,
1066
+ timezone: null
849
1067
  };
850
1068
  const ReleasesPage = () => {
851
1069
  const tabRef = React.useRef(null);
@@ -891,8 +1109,8 @@ const ReleasesPage = () => {
891
1109
  if (isLoading) {
892
1110
  return /* @__PURE__ */ jsx(Main, { "aria-busy": isLoading, children: /* @__PURE__ */ jsx(LoadingIndicatorPage, {}) });
893
1111
  }
894
- const totalReleases = isSuccess && response.currentData?.meta?.pagination?.total || 0;
895
- const hasReachedMaximumPendingReleases = totalReleases >= maximumReleases;
1112
+ const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
1113
+ const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
896
1114
  const handleTabChange = (index) => {
897
1115
  setQuery({
898
1116
  ...query,
@@ -905,9 +1123,11 @@ const ReleasesPage = () => {
905
1123
  }
906
1124
  });
907
1125
  };
908
- const handleAddRelease = async (values) => {
1126
+ const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
909
1127
  const response2 = await createRelease({
910
- name: values.name
1128
+ name,
1129
+ scheduledAt,
1130
+ timezone
911
1131
  });
912
1132
  if ("data" in response2) {
913
1133
  toggleNotification({
@@ -939,13 +1159,10 @@ const ReleasesPage = () => {
939
1159
  id: "content-releases.pages.Releases.title",
940
1160
  defaultMessage: "Releases"
941
1161
  }),
942
- subtitle: formatMessage(
943
- {
944
- id: "content-releases.pages.Releases.header-subtitle",
945
- defaultMessage: "{number, plural, =0 {No releases} one {# release} other {# releases}}"
946
- },
947
- { number: totalReleases }
948
- ),
1162
+ subtitle: formatMessage({
1163
+ id: "content-releases.pages.Releases.header-subtitle",
1164
+ defaultMessage: "Create and manage content updates"
1165
+ }),
949
1166
  primaryAction: /* @__PURE__ */ jsx(CheckPermissions, { permissions: PERMISSIONS.create, children: /* @__PURE__ */ jsx(
950
1167
  Button,
951
1168
  {
@@ -961,7 +1178,7 @@ const ReleasesPage = () => {
961
1178
  }
962
1179
  ),
963
1180
  /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
964
- activeTab === "pending" && hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
1181
+ hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
965
1182
  StyledAlert,
966
1183
  {
967
1184
  marginBottom: 6,
@@ -999,10 +1216,15 @@ const ReleasesPage = () => {
999
1216
  children: [
1000
1217
  /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
1001
1218
  /* @__PURE__ */ jsxs(Tabs, { children: [
1002
- /* @__PURE__ */ jsx(Tab, { children: formatMessage({
1003
- id: "content-releases.pages.Releases.tab.pending",
1004
- defaultMessage: "Pending"
1005
- }) }),
1219
+ /* @__PURE__ */ jsx(Tab, { children: formatMessage(
1220
+ {
1221
+ id: "content-releases.pages.Releases.tab.pending",
1222
+ defaultMessage: "Pending ({count})"
1223
+ },
1224
+ {
1225
+ count: totalPendingReleases
1226
+ }
1227
+ ) }),
1006
1228
  /* @__PURE__ */ jsx(Tab, { children: formatMessage({
1007
1229
  id: "content-releases.pages.Releases.tab.done",
1008
1230
  defaultMessage: "Done"
@@ -1031,7 +1253,7 @@ const ReleasesPage = () => {
1031
1253
  ]
1032
1254
  }
1033
1255
  ),
1034
- totalReleases > 0 && /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1256
+ response.currentData?.meta?.pagination?.total ? /* @__PURE__ */ jsxs(Flex, { paddingTop: 4, alignItems: "flex-end", justifyContent: "space-between", children: [
1035
1257
  /* @__PURE__ */ jsx(
1036
1258
  PageSizeURLQuery,
1037
1259
  {
@@ -1047,7 +1269,7 @@ const ReleasesPage = () => {
1047
1269
  }
1048
1270
  }
1049
1271
  )
1050
- ] })
1272
+ ] }) : null
1051
1273
  ] }) }),
1052
1274
  releaseModalShown && /* @__PURE__ */ jsx(
1053
1275
  ReleaseModal,
@@ -1069,4 +1291,4 @@ const App = () => {
1069
1291
  export {
1070
1292
  App
1071
1293
  };
1072
- //# sourceMappingURL=App-8FCxPK8-.mjs.map
1294
+ //# sourceMappingURL=App-WMxox0mk.mjs.map