@strapi/content-releases 0.0.0-next.f8af92b375dc730ba47ed2117f25df893aae696c → 0.0.0-next.fc1775f7731f8999840e56e298a216b9a6c5c4ad

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 (143) hide show
  1. package/LICENSE +17 -1
  2. package/dist/_chunks/App-CiZCkScI.mjs +1558 -0
  3. package/dist/_chunks/App-CiZCkScI.mjs.map +1 -0
  4. package/dist/_chunks/App-SGjO5UPV.js +1578 -0
  5. package/dist/_chunks/App-SGjO5UPV.js.map +1 -0
  6. package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases--qQepXpP.js} +9 -8
  7. package/dist/_chunks/PurchaseContentReleases--qQepXpP.js.map +1 -0
  8. package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-D-n-w-st.mjs} +10 -9
  9. package/dist/_chunks/PurchaseContentReleases-D-n-w-st.mjs.map +1 -0
  10. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js +178 -0
  11. package/dist/_chunks/ReleasesSettingsPage-Cto_NLUd.js.map +1 -0
  12. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs +178 -0
  13. package/dist/_chunks/ReleasesSettingsPage-DQT8N3A-.mjs.map +1 -0
  14. package/dist/_chunks/{en-r0otWaln.js → en-BWPPsSH-.js} +31 -6
  15. package/dist/_chunks/en-BWPPsSH-.js.map +1 -0
  16. package/dist/_chunks/{en-veqvqeEr.mjs → en-D9Q4YW03.mjs} +31 -6
  17. package/dist/_chunks/en-D9Q4YW03.mjs.map +1 -0
  18. package/dist/_chunks/index-BjvFfTtA.mjs +1386 -0
  19. package/dist/_chunks/index-BjvFfTtA.mjs.map +1 -0
  20. package/dist/_chunks/index-CyU534vL.js +1404 -0
  21. package/dist/_chunks/index-CyU534vL.js.map +1 -0
  22. package/dist/_chunks/schemas-DBYv9gK8.js +61 -0
  23. package/dist/_chunks/schemas-DBYv9gK8.js.map +1 -0
  24. package/dist/_chunks/schemas-DdA2ic2U.mjs +44 -0
  25. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +1 -0
  26. package/dist/admin/index.js +1 -15
  27. package/dist/admin/index.js.map +1 -1
  28. package/dist/admin/index.mjs +2 -16
  29. package/dist/admin/index.mjs.map +1 -1
  30. package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
  31. package/dist/admin/src/components/RelativeTime.d.ts +28 -0
  32. package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
  33. package/dist/admin/src/components/ReleaseActionMenu.d.ts +26 -0
  34. package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
  35. package/dist/admin/src/components/ReleaseActionOptions.d.ts +9 -0
  36. package/dist/admin/src/components/ReleaseListCell.d.ts +28 -0
  37. package/dist/admin/src/components/ReleaseModal.d.ts +17 -0
  38. package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
  39. package/dist/admin/src/constants.d.ts +76 -0
  40. package/dist/admin/src/index.d.ts +3 -0
  41. package/dist/admin/src/modules/hooks.d.ts +7 -0
  42. package/dist/admin/src/pages/App.d.ts +1 -0
  43. package/dist/admin/src/pages/PurchaseContentReleases.d.ts +2 -0
  44. package/dist/admin/src/pages/ReleaseDetailsPage.d.ts +2 -0
  45. package/dist/admin/src/pages/ReleasesPage.d.ts +8 -0
  46. package/dist/admin/src/pages/ReleasesSettingsPage.d.ts +1 -0
  47. package/dist/admin/src/pages/tests/mockReleaseDetailsPageData.d.ts +181 -0
  48. package/dist/admin/src/pages/tests/mockReleasesPageData.d.ts +39 -0
  49. package/dist/admin/src/pluginId.d.ts +1 -0
  50. package/dist/admin/src/services/release.d.ts +112 -0
  51. package/dist/admin/src/store/hooks.d.ts +7 -0
  52. package/dist/admin/src/utils/api.d.ts +6 -0
  53. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +3 -0
  54. package/dist/admin/src/utils/time.d.ts +10 -0
  55. package/dist/admin/src/validation/schemas.d.ts +6 -0
  56. package/dist/server/index.js +1233 -515
  57. package/dist/server/index.js.map +1 -1
  58. package/dist/server/index.mjs +1232 -513
  59. package/dist/server/index.mjs.map +1 -1
  60. package/dist/server/src/bootstrap.d.ts +5 -0
  61. package/dist/server/src/bootstrap.d.ts.map +1 -0
  62. package/dist/server/src/constants.d.ts +21 -0
  63. package/dist/server/src/constants.d.ts.map +1 -0
  64. package/dist/server/src/content-types/index.d.ts +97 -0
  65. package/dist/server/src/content-types/index.d.ts.map +1 -0
  66. package/dist/server/src/content-types/release/index.d.ts +48 -0
  67. package/dist/server/src/content-types/release/index.d.ts.map +1 -0
  68. package/dist/server/src/content-types/release/schema.d.ts +47 -0
  69. package/dist/server/src/content-types/release/schema.d.ts.map +1 -0
  70. package/dist/server/src/content-types/release-action/index.d.ts +48 -0
  71. package/dist/server/src/content-types/release-action/index.d.ts.map +1 -0
  72. package/dist/server/src/content-types/release-action/schema.d.ts +47 -0
  73. package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -0
  74. package/dist/server/src/controllers/index.d.ts +25 -0
  75. package/dist/server/src/controllers/index.d.ts.map +1 -0
  76. package/dist/server/src/controllers/release-action.d.ts +10 -0
  77. package/dist/server/src/controllers/release-action.d.ts.map +1 -0
  78. package/dist/server/src/controllers/release.d.ts +18 -0
  79. package/dist/server/src/controllers/release.d.ts.map +1 -0
  80. package/dist/server/src/controllers/settings.d.ts +11 -0
  81. package/dist/server/src/controllers/settings.d.ts.map +1 -0
  82. package/dist/server/src/controllers/validation/release-action.d.ts +14 -0
  83. package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -0
  84. package/dist/server/src/controllers/validation/release.d.ts +4 -0
  85. package/dist/server/src/controllers/validation/release.d.ts.map +1 -0
  86. package/dist/server/src/controllers/validation/settings.d.ts +3 -0
  87. package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
  88. package/dist/server/src/destroy.d.ts +5 -0
  89. package/dist/server/src/destroy.d.ts.map +1 -0
  90. package/dist/server/src/index.d.ts +2111 -0
  91. package/dist/server/src/index.d.ts.map +1 -0
  92. package/dist/server/src/middlewares/documents.d.ts +6 -0
  93. package/dist/server/src/middlewares/documents.d.ts.map +1 -0
  94. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
  95. package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
  96. package/dist/server/src/migrations/index.d.ts +13 -0
  97. package/dist/server/src/migrations/index.d.ts.map +1 -0
  98. package/dist/server/src/register.d.ts +5 -0
  99. package/dist/server/src/register.d.ts.map +1 -0
  100. package/dist/server/src/routes/index.d.ts +51 -0
  101. package/dist/server/src/routes/index.d.ts.map +1 -0
  102. package/dist/server/src/routes/release-action.d.ts +18 -0
  103. package/dist/server/src/routes/release-action.d.ts.map +1 -0
  104. package/dist/server/src/routes/release.d.ts +18 -0
  105. package/dist/server/src/routes/release.d.ts.map +1 -0
  106. package/dist/server/src/routes/settings.d.ts +18 -0
  107. package/dist/server/src/routes/settings.d.ts.map +1 -0
  108. package/dist/server/src/services/index.d.ts +1824 -0
  109. package/dist/server/src/services/index.d.ts.map +1 -0
  110. package/dist/server/src/services/release-action.d.ts +34 -0
  111. package/dist/server/src/services/release-action.d.ts.map +1 -0
  112. package/dist/server/src/services/release.d.ts +31 -0
  113. package/dist/server/src/services/release.d.ts.map +1 -0
  114. package/dist/server/src/services/scheduling.d.ts +18 -0
  115. package/dist/server/src/services/scheduling.d.ts.map +1 -0
  116. package/dist/server/src/services/settings.d.ts +13 -0
  117. package/dist/server/src/services/settings.d.ts.map +1 -0
  118. package/dist/server/src/services/validation.d.ts +18 -0
  119. package/dist/server/src/services/validation.d.ts.map +1 -0
  120. package/dist/server/src/utils/index.d.ts +35 -0
  121. package/dist/server/src/utils/index.d.ts.map +1 -0
  122. package/dist/shared/contracts/release-actions.d.ts +137 -0
  123. package/dist/shared/contracts/release-actions.d.ts.map +1 -0
  124. package/dist/shared/contracts/releases.d.ts +184 -0
  125. package/dist/shared/contracts/releases.d.ts.map +1 -0
  126. package/dist/shared/contracts/settings.d.ts +39 -0
  127. package/dist/shared/contracts/settings.d.ts.map +1 -0
  128. package/dist/shared/types.d.ts +24 -0
  129. package/dist/shared/types.d.ts.map +1 -0
  130. package/package.json +35 -40
  131. package/dist/_chunks/App-OK4Xac-O.js +0 -1315
  132. package/dist/_chunks/App-OK4Xac-O.js.map +0 -1
  133. package/dist/_chunks/App-xAkiD42p.mjs +0 -1292
  134. package/dist/_chunks/App-xAkiD42p.mjs.map +0 -1
  135. package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
  136. package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
  137. package/dist/_chunks/en-r0otWaln.js.map +0 -1
  138. package/dist/_chunks/en-veqvqeEr.mjs.map +0 -1
  139. package/dist/_chunks/index-JvA2_26n.js +0 -1015
  140. package/dist/_chunks/index-JvA2_26n.js.map +0 -1
  141. package/dist/_chunks/index-exoiSU3V.mjs +0 -994
  142. package/dist/_chunks/index-exoiSU3V.mjs.map +0 -1
  143. package/strapi-server.js +0 -3
@@ -0,0 +1,178 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { Page, useAPIErrorHandler, useNotification, useRBAC, Layouts, Form, useField, isFetchError } from "@strapi/admin/strapi-admin";
3
+ import { Button, Flex, Typography, Grid, Field, Combobox, ComboboxOption } from "@strapi/design-system";
4
+ import { Check } from "@strapi/icons";
5
+ import { useIntl } from "react-intl";
6
+ import { useSelector } from "react-redux";
7
+ import { a as useGetReleaseSettingsQuery, l as useUpdateReleaseSettingsMutation, g as getTimezones } from "./index-BjvFfTtA.mjs";
8
+ import { S as SETTINGS_SCHEMA } from "./schemas-DdA2ic2U.mjs";
9
+ const useTypedSelector = useSelector;
10
+ const ReleasesSettingsPage = () => {
11
+ const { formatMessage } = useIntl();
12
+ const { formatAPIError } = useAPIErrorHandler();
13
+ const { toggleNotification } = useNotification();
14
+ const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
15
+ const [updateReleaseSettings, { isLoading: isSubmittingForm }] = useUpdateReleaseSettingsMutation();
16
+ const permissions = useTypedSelector(
17
+ (state) => state.admin_app.permissions["settings"]?.["releases"]
18
+ );
19
+ const {
20
+ allowedActions: { canUpdate }
21
+ } = useRBAC(permissions);
22
+ const { timezoneList } = getTimezones(/* @__PURE__ */ new Date());
23
+ const handleSubmit = async (body) => {
24
+ const { defaultTimezone } = body;
25
+ const isBodyTimezoneValid = timezoneList.some((timezone) => timezone.value === defaultTimezone);
26
+ const newBody = !defaultTimezone || !isBodyTimezoneValid ? { defaultTimezone: null } : { ...body };
27
+ try {
28
+ const response = await updateReleaseSettings(newBody);
29
+ if ("data" in response) {
30
+ toggleNotification({
31
+ type: "success",
32
+ message: formatMessage({
33
+ id: "content-releases.pages.Settings.releases.setting.default-timezone-notification-success",
34
+ defaultMessage: "Default timezone updated."
35
+ })
36
+ });
37
+ } else if (isFetchError(response.error)) {
38
+ toggleNotification({
39
+ type: "danger",
40
+ message: formatAPIError(response.error)
41
+ });
42
+ } else {
43
+ toggleNotification({
44
+ type: "danger",
45
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
46
+ });
47
+ }
48
+ } catch (error) {
49
+ toggleNotification({
50
+ type: "danger",
51
+ message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
52
+ });
53
+ }
54
+ };
55
+ if (isLoadingSettings) {
56
+ return /* @__PURE__ */ jsx(Page.Loading, {});
57
+ }
58
+ return /* @__PURE__ */ jsxs(Layouts.Root, { children: [
59
+ /* @__PURE__ */ jsx(Page.Title, { children: formatMessage(
60
+ { id: "Settings.PageTitle", defaultMessage: "Settings - {name}" },
61
+ {
62
+ name: "Releases"
63
+ }
64
+ ) }),
65
+ /* @__PURE__ */ jsx(Page.Main, { "aria-busy": isLoadingSettings, tabIndex: -1, children: /* @__PURE__ */ jsx(
66
+ Form,
67
+ {
68
+ method: "PUT",
69
+ initialValues: {
70
+ defaultTimezone: data?.data.defaultTimezone
71
+ },
72
+ onSubmit: handleSubmit,
73
+ validationSchema: SETTINGS_SCHEMA,
74
+ children: ({ modified, isSubmitting }) => {
75
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
76
+ /* @__PURE__ */ jsx(
77
+ Layouts.Header,
78
+ {
79
+ primaryAction: canUpdate ? /* @__PURE__ */ jsx(
80
+ Button,
81
+ {
82
+ disabled: !modified || isSubmittingForm,
83
+ loading: isSubmitting,
84
+ startIcon: /* @__PURE__ */ jsx(Check, {}),
85
+ type: "submit",
86
+ children: formatMessage({
87
+ id: "global.save",
88
+ defaultMessage: "Save"
89
+ })
90
+ }
91
+ ) : null,
92
+ title: formatMessage({
93
+ id: "content-releases.pages.Settings.releases.title",
94
+ defaultMessage: "Releases"
95
+ }),
96
+ subtitle: formatMessage({
97
+ id: "content-releases.pages.Settings.releases.description",
98
+ defaultMessage: "Create and manage content updates"
99
+ })
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(
103
+ Flex,
104
+ {
105
+ direction: "column",
106
+ background: "neutral0",
107
+ alignItems: "stretch",
108
+ padding: 6,
109
+ gap: 6,
110
+ shadow: "filterShadow",
111
+ hasRadius: true,
112
+ children: [
113
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: formatMessage({
114
+ id: "content-releases.pages.Settings.releases.preferences.title",
115
+ defaultMessage: "Preferences"
116
+ }) }),
117
+ /* @__PURE__ */ jsx(Grid.Root, { children: /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(TimezoneDropdown, {}) }) })
118
+ ]
119
+ }
120
+ ) })
121
+ ] });
122
+ }
123
+ }
124
+ ) })
125
+ ] });
126
+ };
127
+ const TimezoneDropdown = () => {
128
+ const permissions = useTypedSelector(
129
+ (state) => state.admin_app.permissions["settings"]?.["releases"]
130
+ );
131
+ const {
132
+ allowedActions: { canUpdate }
133
+ } = useRBAC(permissions);
134
+ const { formatMessage } = useIntl();
135
+ const { timezoneList } = getTimezones(/* @__PURE__ */ new Date());
136
+ const field = useField("defaultTimezone");
137
+ return /* @__PURE__ */ jsxs(
138
+ Field.Root,
139
+ {
140
+ name: "defaultTimezone",
141
+ hint: formatMessage({
142
+ id: "content-releases.pages.Settings.releases.timezone.hint",
143
+ defaultMessage: "The timezone of every release can still be changed individually. "
144
+ }),
145
+ error: field.error,
146
+ children: [
147
+ /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
148
+ id: "content-releases.pages.Settings.releases.timezone.label",
149
+ defaultMessage: "Default timezone"
150
+ }) }),
151
+ /* @__PURE__ */ jsx(
152
+ Combobox,
153
+ {
154
+ autocomplete: { type: "list", filter: "contains" },
155
+ onChange: (value) => field.onChange("defaultTimezone", value),
156
+ onTextValueChange: (value) => field.onChange("defaultTimezone", value),
157
+ onClear: () => field.onChange("defaultTimezone", ""),
158
+ value: field.value,
159
+ disabled: !canUpdate,
160
+ children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
161
+ }
162
+ ),
163
+ /* @__PURE__ */ jsx(Field.Hint, {}),
164
+ /* @__PURE__ */ jsx(Field.Error, {})
165
+ ]
166
+ }
167
+ );
168
+ };
169
+ const ProtectedReleasesSettingsPage = () => {
170
+ const permissions = useTypedSelector(
171
+ (state) => state.admin_app.permissions["settings"]?.["releases"]?.read
172
+ );
173
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions, children: /* @__PURE__ */ jsx(ReleasesSettingsPage, {}) });
174
+ };
175
+ export {
176
+ ProtectedReleasesSettingsPage
177
+ };
178
+ //# sourceMappingURL=ReleasesSettingsPage-DQT8N3A-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleasesSettingsPage-DQT8N3A-.mjs","sources":["../../admin/src/modules/hooks.ts","../../admin/src/pages/ReleasesSettingsPage.tsx"],"sourcesContent":["import { Dispatch } from '@reduxjs/toolkit';\nimport { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';\n\nimport type { Store } from '@strapi/admin/strapi-admin';\n\ntype RootState = ReturnType<Store['getState']>;\n\nconst useTypedDispatch: () => Dispatch = useDispatch;\nconst useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;\n\nexport { useTypedSelector, useTypedDispatch };\n","import {\n Form,\n Layouts,\n Page,\n useAPIErrorHandler,\n isFetchError,\n useNotification,\n useField,\n useRBAC,\n} from '@strapi/admin/strapi-admin';\nimport {\n Button,\n Combobox,\n ComboboxOption,\n Field,\n Flex,\n Grid,\n Typography,\n} from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useTypedSelector } from '../modules/hooks';\nimport { useGetReleaseSettingsQuery, useUpdateReleaseSettingsMutation } from '../services/release';\nimport { getTimezones } from '../utils/time';\nimport { SETTINGS_SCHEMA } from '../validation/schemas';\n\nimport type { UpdateSettings } from '../../../shared/contracts/settings';\n\nconst ReleasesSettingsPage = () => {\n const { formatMessage } = useIntl();\n const { formatAPIError } = useAPIErrorHandler();\n const { toggleNotification } = useNotification();\n const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();\n const [updateReleaseSettings, { isLoading: isSubmittingForm }] =\n useUpdateReleaseSettingsMutation();\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions['settings']?.['releases']\n );\n const {\n allowedActions: { canUpdate },\n } = useRBAC(permissions);\n\n const { timezoneList } = getTimezones(new Date());\n\n const handleSubmit = async (body: UpdateSettings.Request['body']) => {\n const { defaultTimezone } = body;\n const isBodyTimezoneValid = timezoneList.some((timezone) => timezone.value === defaultTimezone);\n const newBody =\n !defaultTimezone || !isBodyTimezoneValid ? { defaultTimezone: null } : { ...body };\n try {\n const response = await updateReleaseSettings(newBody);\n\n if ('data' in response) {\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'content-releases.pages.Settings.releases.setting.default-timezone-notification-success',\n defaultMessage: 'Default timezone updated.',\n }),\n });\n } else if (isFetchError(response.error)) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(response.error),\n });\n } else {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n };\n\n if (isLoadingSettings) {\n return <Page.Loading />;\n }\n\n return (\n <Layouts.Root>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: 'Releases',\n }\n )}\n </Page.Title>\n <Page.Main aria-busy={isLoadingSettings} tabIndex={-1}>\n <Form\n method=\"PUT\"\n initialValues={{\n defaultTimezone: data?.data.defaultTimezone,\n }}\n onSubmit={handleSubmit}\n validationSchema={SETTINGS_SCHEMA}\n >\n {({ modified, isSubmitting }: { modified: boolean; isSubmitting: boolean }) => {\n return (\n <>\n <Layouts.Header\n primaryAction={\n canUpdate ? (\n <Button\n disabled={!modified || isSubmittingForm}\n loading={isSubmitting}\n startIcon={<Check />}\n type=\"submit\"\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n ) : null\n }\n title={formatMessage({\n id: 'content-releases.pages.Settings.releases.title',\n defaultMessage: 'Releases',\n })}\n subtitle={formatMessage({\n id: 'content-releases.pages.Settings.releases.description',\n defaultMessage: 'Create and manage content updates',\n })}\n />\n <Layouts.Content>\n <Flex\n direction=\"column\"\n background=\"neutral0\"\n alignItems=\"stretch\"\n padding={6}\n gap={6}\n shadow=\"filterShadow\"\n hasRadius\n >\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'content-releases.pages.Settings.releases.preferences.title',\n defaultMessage: 'Preferences',\n })}\n </Typography>\n <Grid.Root>\n <Grid.Item col={6} s={12} direction=\"column\" alignItems=\"stretch\">\n <TimezoneDropdown />\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Layouts.Content>\n </>\n );\n }}\n </Form>\n </Page.Main>\n </Layouts.Root>\n );\n};\n\nconst TimezoneDropdown = () => {\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions['settings']?.['releases']\n );\n const {\n allowedActions: { canUpdate },\n } = useRBAC(permissions);\n const { formatMessage } = useIntl();\n const { timezoneList } = getTimezones(new Date());\n const field = useField('defaultTimezone');\n return (\n <Field.Root\n name=\"defaultTimezone\"\n hint={formatMessage({\n id: 'content-releases.pages.Settings.releases.timezone.hint',\n defaultMessage: 'The timezone of every release can still be changed individually. ',\n })}\n error={field.error}\n >\n <Field.Label>\n {formatMessage({\n id: 'content-releases.pages.Settings.releases.timezone.label',\n defaultMessage: 'Default timezone',\n })}\n </Field.Label>\n <Combobox\n autocomplete={{ type: 'list', filter: 'contains' }}\n onChange={(value) => field.onChange('defaultTimezone', value)}\n onTextValueChange={(value) => field.onChange('defaultTimezone', value)}\n onClear={() => field.onChange('defaultTimezone', '')}\n value={field.value}\n disabled={!canUpdate}\n >\n {timezoneList.map((timezone) => (\n <ComboboxOption key={timezone.value} value={timezone.value}>\n {timezone.value.replace(/&/, ' ')}\n </ComboboxOption>\n ))}\n </Combobox>\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ProtectedSettingsPage\n * -----------------------------------------------------------------------------------------------*/\n\nexport const ProtectedReleasesSettingsPage = () => {\n const permissions = useTypedSelector(\n (state) => state.admin_app.permissions['settings']?.['releases']?.read\n );\n\n return (\n <Page.Protect permissions={permissions}>\n <ReleasesSettingsPage />\n </Page.Protect>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -13,18 +13,29 @@ const en = {
13
13
  "content-manager-edit-view.list-releases.title": "{isPublish, select, true {Will be published in} other {Will be unpublished in}}",
14
14
  "content-manager-edit-view.remove-from-release": "Remove from release",
15
15
  "content-manager-edit-view.scheduled.date": "{date} at {time} ({offset})",
16
+ "content-manager-edit-view.edit-release": "Edit release",
16
17
  "content-releases.content-manager-edit-view.edit-entry": "Edit entry",
17
18
  "content-manager-edit-view.remove-from-release.notification.success": "Entry removed from release",
18
19
  "content-manager-edit-view.release-action-menu": "Release action options",
20
+ "content-manager.list-view.releases.header": "To be released in",
21
+ "content-manager-list-view.add-to-release": "Add to release",
22
+ "content-manager-list-view.add-to-release.cancel-button": "Cancel",
23
+ "content-manager-list-view.add-to-release.continue-button": "Continue",
24
+ "content-manager-list-view.add-to-release.select-label": "Select a release",
25
+ "content-manager-list-view.add-to-release.select-placeholder": "Select",
26
+ "content-manager-list-view.add-to-release.action-type-label": "What do you want to do with these entries?",
27
+ "content-manager-list-view.add-to-release.notification.success.title": "Successfully added to release.",
28
+ "content-manager-list-view.add-to-release.notification.success.message": "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release.",
19
29
  "content-manager.notification.entry-error": "Failed to get entry data",
30
+ "content-manager.list-view.releases-number": "{number} {number, plural, one {release} other {releases}}",
20
31
  "plugin.name": "Releases",
21
32
  "pages.Releases.title": "Releases",
22
- "pages.Releases.header-subtitle": "{number, plural, =0 {No releases} one {# release} other {# releases}}",
33
+ "pages.Releases.header-subtitle": "Create and manage content updates",
23
34
  "pages.Releases.max-limit-reached.title": "You have reached the {number} pending {number, plural, one {release} other {releases}} limit.",
24
35
  "pages.Releases.max-limit-reached.message": "Upgrade to manage an unlimited number of releases.",
25
36
  "pages.Releases.max-limit-reached.action": "Explore plans",
26
37
  "pages.PurchaseRelease.subTitle": "Manage content updates and releases.",
27
- "pages.PurchaseRelease.not-available": "Releases is only available as part of the Enterprise Edition. Upgrade to create and manage releases.",
38
+ "pages.PurchaseRelease.not-available": "Releases is only available as part of a paid plan. Upgrade to create and manage releases.",
28
39
  "header.actions.add-release": "New Release",
29
40
  "header.actions.refresh": "Refresh",
30
41
  "header.actions.publish": "Publish",
@@ -43,13 +54,13 @@ const en = {
43
54
  "modal.form.input.label.timezone": "Timezone",
44
55
  "modal.form.input.clearLabel": "Clear",
45
56
  "modal.form.button.submit": "{isCreatingRelease, select, true {Continue} other {Save}}",
57
+ "modal.form.time.has-passed": "Selected time has already passed.",
46
58
  "pages.Details.header-subtitle": "{number, plural, =0 {No entries} one {# entry} other {# entries}}",
47
59
  "pages.Releases.tab-group.label": "Releases list",
48
- "pages.Releases.tab.pending": "Pending",
60
+ "pages.Releases.tab.pending": "Pending ({count})",
49
61
  "pages.Releases.tab.done": "Done",
50
62
  "page.Releases.tab.emptyEntries": "No releases",
51
63
  "pages.Details.tab.emptyEntries": "This release is empty. Open the Content Manager, select an entry and add it to the release.",
52
- "page.Releases.release-item.entries": "{number, plural, =0 {No entries} one {# entry} other {# entries}}",
53
64
  "page.ReleaseDetails.table.header.label.name": "name",
54
65
  "page.ReleaseDetails.table.header.label.locale": "locale",
55
66
  "page.ReleaseDetails.table.header.label.content-type": "content-type",
@@ -66,12 +77,26 @@ const en = {
66
77
  "pages.ReleaseDetails.groupBy.aria-label": "Group by",
67
78
  "pages.ReleaseDetails.entry-validation.already-published": "Already published",
68
79
  "pages.ReleaseDetails.entry-validation.ready-to-publish": "Ready to publish",
80
+ "pages.ReleaseDetails.entry-validation.modified": "Ready to publish changes",
69
81
  "pages.ReleaseDetails.entry-validation.already-unpublished": "Already unpublished",
70
82
  "pages.ReleaseDetails.entry-validation.ready-to-unpublish": "Ready to unpublish",
83
+ "pages.ReleaseDetails.entry-validation.not-ready": "Not ready to publish",
71
84
  "pages.ReleaseDetails.groupBy.option.content-type": "Content-Types",
72
85
  "pages.ReleaseDetails.groupBy.option.locales": "Locales",
73
86
  "pages.ReleaseDetails.groupBy.option.actions": "Actions",
74
- "pages.ReleaseDetails.header-subtitle.scheduled": "Scheduled for {date} at {time} ({offset})"
87
+ "pages.ReleaseDetails.header-subtitle.scheduled": "Scheduled for {date} at {time} ({offset})",
88
+ "pages.ReleaseDetails.entry-validation.fields": "Fields",
89
+ "pages.Settings.releases.title": "Releases",
90
+ "pages.Settings.releases.description": "Create and manage content updates",
91
+ "pages.Settings.releases.timezone.label": "Default timezone",
92
+ "pages.Settings.releases.setting.default-timezone-notification-success": "Default timezone updated.",
93
+ "pages.ReleaseDetails.entry-validation.fields.error": "{errors} errors on fields.",
94
+ "pages.ReleaseDetails.entry-validation.fields.success": "All fields are filled correctly.",
95
+ "pages.ReleaseDetails.entry-validation.fields.see-errors": "See errors",
96
+ "pages.ReleaseDetails.entry-validation.review-stage.not-enabled": "This entry is not associated to any workflow.",
97
+ "pages.ReleaseDetails.entry-validation.review-stage.not-ready": "This entry is not at the required stage for publishing. ({stageName})",
98
+ "pages.ReleaseDetails.entry-validation.review-stage.ready": "This entry is at the required stage for publishing. ({stageName})",
99
+ "pages.ReleaseDetails.entry-validation.review-stage.stage-not-required": "No required stage for publication."
75
100
  };
76
101
  exports.default = en;
77
- //# sourceMappingURL=en-r0otWaln.js.map
102
+ //# sourceMappingURL=en-BWPPsSH-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-BWPPsSH-.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -11,18 +11,29 @@ const en = {
11
11
  "content-manager-edit-view.list-releases.title": "{isPublish, select, true {Will be published in} other {Will be unpublished in}}",
12
12
  "content-manager-edit-view.remove-from-release": "Remove from release",
13
13
  "content-manager-edit-view.scheduled.date": "{date} at {time} ({offset})",
14
+ "content-manager-edit-view.edit-release": "Edit release",
14
15
  "content-releases.content-manager-edit-view.edit-entry": "Edit entry",
15
16
  "content-manager-edit-view.remove-from-release.notification.success": "Entry removed from release",
16
17
  "content-manager-edit-view.release-action-menu": "Release action options",
18
+ "content-manager.list-view.releases.header": "To be released in",
19
+ "content-manager-list-view.add-to-release": "Add to release",
20
+ "content-manager-list-view.add-to-release.cancel-button": "Cancel",
21
+ "content-manager-list-view.add-to-release.continue-button": "Continue",
22
+ "content-manager-list-view.add-to-release.select-label": "Select a release",
23
+ "content-manager-list-view.add-to-release.select-placeholder": "Select",
24
+ "content-manager-list-view.add-to-release.action-type-label": "What do you want to do with these entries?",
25
+ "content-manager-list-view.add-to-release.notification.success.title": "Successfully added to release.",
26
+ "content-manager-list-view.add-to-release.notification.success.message": "{entriesAlreadyInRelease} out of {totalEntries} entries were already in the release.",
17
27
  "content-manager.notification.entry-error": "Failed to get entry data",
28
+ "content-manager.list-view.releases-number": "{number} {number, plural, one {release} other {releases}}",
18
29
  "plugin.name": "Releases",
19
30
  "pages.Releases.title": "Releases",
20
- "pages.Releases.header-subtitle": "{number, plural, =0 {No releases} one {# release} other {# releases}}",
31
+ "pages.Releases.header-subtitle": "Create and manage content updates",
21
32
  "pages.Releases.max-limit-reached.title": "You have reached the {number} pending {number, plural, one {release} other {releases}} limit.",
22
33
  "pages.Releases.max-limit-reached.message": "Upgrade to manage an unlimited number of releases.",
23
34
  "pages.Releases.max-limit-reached.action": "Explore plans",
24
35
  "pages.PurchaseRelease.subTitle": "Manage content updates and releases.",
25
- "pages.PurchaseRelease.not-available": "Releases is only available as part of the Enterprise Edition. Upgrade to create and manage releases.",
36
+ "pages.PurchaseRelease.not-available": "Releases is only available as part of a paid plan. Upgrade to create and manage releases.",
26
37
  "header.actions.add-release": "New Release",
27
38
  "header.actions.refresh": "Refresh",
28
39
  "header.actions.publish": "Publish",
@@ -41,13 +52,13 @@ const en = {
41
52
  "modal.form.input.label.timezone": "Timezone",
42
53
  "modal.form.input.clearLabel": "Clear",
43
54
  "modal.form.button.submit": "{isCreatingRelease, select, true {Continue} other {Save}}",
55
+ "modal.form.time.has-passed": "Selected time has already passed.",
44
56
  "pages.Details.header-subtitle": "{number, plural, =0 {No entries} one {# entry} other {# entries}}",
45
57
  "pages.Releases.tab-group.label": "Releases list",
46
- "pages.Releases.tab.pending": "Pending",
58
+ "pages.Releases.tab.pending": "Pending ({count})",
47
59
  "pages.Releases.tab.done": "Done",
48
60
  "page.Releases.tab.emptyEntries": "No releases",
49
61
  "pages.Details.tab.emptyEntries": "This release is empty. Open the Content Manager, select an entry and add it to the release.",
50
- "page.Releases.release-item.entries": "{number, plural, =0 {No entries} one {# entry} other {# entries}}",
51
62
  "page.ReleaseDetails.table.header.label.name": "name",
52
63
  "page.ReleaseDetails.table.header.label.locale": "locale",
53
64
  "page.ReleaseDetails.table.header.label.content-type": "content-type",
@@ -64,14 +75,28 @@ const en = {
64
75
  "pages.ReleaseDetails.groupBy.aria-label": "Group by",
65
76
  "pages.ReleaseDetails.entry-validation.already-published": "Already published",
66
77
  "pages.ReleaseDetails.entry-validation.ready-to-publish": "Ready to publish",
78
+ "pages.ReleaseDetails.entry-validation.modified": "Ready to publish changes",
67
79
  "pages.ReleaseDetails.entry-validation.already-unpublished": "Already unpublished",
68
80
  "pages.ReleaseDetails.entry-validation.ready-to-unpublish": "Ready to unpublish",
81
+ "pages.ReleaseDetails.entry-validation.not-ready": "Not ready to publish",
69
82
  "pages.ReleaseDetails.groupBy.option.content-type": "Content-Types",
70
83
  "pages.ReleaseDetails.groupBy.option.locales": "Locales",
71
84
  "pages.ReleaseDetails.groupBy.option.actions": "Actions",
72
- "pages.ReleaseDetails.header-subtitle.scheduled": "Scheduled for {date} at {time} ({offset})"
85
+ "pages.ReleaseDetails.header-subtitle.scheduled": "Scheduled for {date} at {time} ({offset})",
86
+ "pages.ReleaseDetails.entry-validation.fields": "Fields",
87
+ "pages.Settings.releases.title": "Releases",
88
+ "pages.Settings.releases.description": "Create and manage content updates",
89
+ "pages.Settings.releases.timezone.label": "Default timezone",
90
+ "pages.Settings.releases.setting.default-timezone-notification-success": "Default timezone updated.",
91
+ "pages.ReleaseDetails.entry-validation.fields.error": "{errors} errors on fields.",
92
+ "pages.ReleaseDetails.entry-validation.fields.success": "All fields are filled correctly.",
93
+ "pages.ReleaseDetails.entry-validation.fields.see-errors": "See errors",
94
+ "pages.ReleaseDetails.entry-validation.review-stage.not-enabled": "This entry is not associated to any workflow.",
95
+ "pages.ReleaseDetails.entry-validation.review-stage.not-ready": "This entry is not at the required stage for publishing. ({stageName})",
96
+ "pages.ReleaseDetails.entry-validation.review-stage.ready": "This entry is at the required stage for publishing. ({stageName})",
97
+ "pages.ReleaseDetails.entry-validation.review-stage.stage-not-required": "No required stage for publication."
73
98
  };
74
99
  export {
75
100
  en as default
76
101
  };
77
- //# sourceMappingURL=en-veqvqeEr.mjs.map
102
+ //# sourceMappingURL=en-D9Q4YW03.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en-D9Q4YW03.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}