@strapi/content-releases 5.12.1 → 5.12.2

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 (259) hide show
  1. package/dist/admin/assets/purchase-page-illustration-dark.svg.js +6 -0
  2. package/dist/admin/assets/purchase-page-illustration-dark.svg.js.map +1 -0
  3. package/dist/admin/assets/purchase-page-illustration-dark.svg.mjs +4 -0
  4. package/dist/admin/assets/purchase-page-illustration-dark.svg.mjs.map +1 -0
  5. package/dist/admin/assets/purchase-page-illustration-light.svg.js +6 -0
  6. package/dist/admin/assets/purchase-page-illustration-light.svg.js.map +1 -0
  7. package/dist/admin/assets/purchase-page-illustration-light.svg.mjs +4 -0
  8. package/dist/admin/assets/purchase-page-illustration-light.svg.mjs.map +1 -0
  9. package/dist/admin/components/EntryValidationPopover.js +344 -0
  10. package/dist/admin/components/EntryValidationPopover.js.map +1 -0
  11. package/dist/admin/components/EntryValidationPopover.mjs +342 -0
  12. package/dist/admin/components/EntryValidationPopover.mjs.map +1 -0
  13. package/dist/admin/components/RelativeTime.js +76 -0
  14. package/dist/admin/components/RelativeTime.js.map +1 -0
  15. package/dist/admin/components/RelativeTime.mjs +55 -0
  16. package/dist/admin/components/RelativeTime.mjs.map +1 -0
  17. package/dist/admin/components/ReleaseAction.js +201 -0
  18. package/dist/admin/components/ReleaseAction.js.map +1 -0
  19. package/dist/admin/components/ReleaseAction.mjs +199 -0
  20. package/dist/admin/components/ReleaseAction.mjs.map +1 -0
  21. package/dist/admin/components/ReleaseActionMenu.js +243 -0
  22. package/dist/admin/components/ReleaseActionMenu.js.map +1 -0
  23. package/dist/admin/components/ReleaseActionMenu.mjs +222 -0
  24. package/dist/admin/components/ReleaseActionMenu.mjs.map +1 -0
  25. package/dist/admin/components/ReleaseActionModal.js +268 -0
  26. package/dist/admin/components/ReleaseActionModal.js.map +1 -0
  27. package/dist/admin/components/ReleaseActionModal.mjs +244 -0
  28. package/dist/admin/components/ReleaseActionModal.mjs.map +1 -0
  29. package/dist/admin/components/ReleaseActionOptions.js +104 -0
  30. package/dist/admin/components/ReleaseActionOptions.js.map +1 -0
  31. package/dist/admin/components/ReleaseActionOptions.mjs +102 -0
  32. package/dist/admin/components/ReleaseActionOptions.mjs.map +1 -0
  33. package/dist/admin/components/ReleaseListCell.js +103 -0
  34. package/dist/admin/components/ReleaseListCell.js.map +1 -0
  35. package/dist/admin/components/ReleaseListCell.mjs +100 -0
  36. package/dist/admin/components/ReleaseListCell.mjs.map +1 -0
  37. package/dist/admin/components/ReleaseModal.js +323 -0
  38. package/dist/admin/components/ReleaseModal.js.map +1 -0
  39. package/dist/admin/components/ReleaseModal.mjs +302 -0
  40. package/dist/admin/components/ReleaseModal.mjs.map +1 -0
  41. package/dist/admin/components/ReleasesPanel.js +138 -0
  42. package/dist/admin/components/ReleasesPanel.js.map +1 -0
  43. package/dist/admin/components/ReleasesPanel.mjs +136 -0
  44. package/dist/admin/components/ReleasesPanel.mjs.map +1 -0
  45. package/dist/admin/constants.js +77 -0
  46. package/dist/admin/constants.js.map +1 -0
  47. package/dist/admin/constants.mjs +75 -0
  48. package/dist/admin/constants.mjs.map +1 -0
  49. package/dist/admin/index.js +120 -14
  50. package/dist/admin/index.js.map +1 -1
  51. package/dist/admin/index.mjs +121 -13
  52. package/dist/admin/index.mjs.map +1 -1
  53. package/dist/admin/{chunks/hooks-DA5VbUAp.js → modules/hooks.js} +1 -1
  54. package/dist/admin/modules/hooks.js.map +1 -0
  55. package/dist/admin/{chunks/hooks-CFk_8Q0b.mjs → modules/hooks.mjs} +2 -2
  56. package/dist/admin/modules/hooks.mjs.map +1 -0
  57. package/dist/admin/pages/App.js +29 -0
  58. package/dist/admin/pages/App.js.map +1 -0
  59. package/dist/admin/pages/App.mjs +27 -0
  60. package/dist/admin/pages/App.mjs.map +1 -0
  61. package/dist/admin/pages/PurchaseContentReleases.js +192 -0
  62. package/dist/admin/pages/PurchaseContentReleases.js.map +1 -0
  63. package/dist/admin/pages/PurchaseContentReleases.mjs +190 -0
  64. package/dist/admin/pages/PurchaseContentReleases.mjs.map +1 -0
  65. package/dist/admin/pages/ReleaseDetailsPage.js +821 -0
  66. package/dist/admin/pages/ReleaseDetailsPage.js.map +1 -0
  67. package/dist/admin/pages/ReleaseDetailsPage.mjs +800 -0
  68. package/dist/admin/pages/ReleaseDetailsPage.mjs.map +1 -0
  69. package/dist/admin/pages/ReleasesPage.js +397 -0
  70. package/dist/admin/pages/ReleasesPage.js.map +1 -0
  71. package/dist/admin/pages/ReleasesPage.mjs +375 -0
  72. package/dist/admin/pages/ReleasesPage.mjs.map +1 -0
  73. package/dist/admin/{chunks/ReleasesSettingsPage-KRcoI1bC.js → pages/ReleasesSettingsPage.js} +9 -17
  74. package/dist/admin/pages/ReleasesSettingsPage.js.map +1 -0
  75. package/dist/admin/{chunks/ReleasesSettingsPage-DUKdFdvx.mjs → pages/ReleasesSettingsPage.mjs} +5 -13
  76. package/dist/admin/pages/ReleasesSettingsPage.mjs.map +1 -0
  77. package/dist/admin/pluginId.js +6 -0
  78. package/dist/admin/pluginId.js.map +1 -0
  79. package/dist/admin/pluginId.mjs +4 -0
  80. package/dist/admin/pluginId.mjs.map +1 -0
  81. package/dist/admin/services/release.js +464 -0
  82. package/dist/admin/services/release.js.map +1 -0
  83. package/dist/admin/services/release.mjs +447 -0
  84. package/dist/admin/services/release.mjs.map +1 -0
  85. package/dist/admin/store/hooks.js +8 -0
  86. package/dist/admin/store/hooks.js.map +1 -0
  87. package/dist/admin/store/hooks.mjs +6 -0
  88. package/dist/admin/store/hooks.mjs.map +1 -0
  89. package/dist/admin/{chunks/en-BOpqX2t_.js → translations/en.json.js} +2 -2
  90. package/dist/admin/translations/en.json.js.map +1 -0
  91. package/dist/admin/{chunks/en-aQo8Bn_U.mjs → translations/en.json.mjs} +1 -1
  92. package/dist/admin/translations/en.json.mjs.map +1 -0
  93. package/dist/admin/{chunks/uk-9T9su-bj.js → translations/uk.json.js} +2 -2
  94. package/dist/admin/translations/uk.json.js.map +1 -0
  95. package/dist/admin/{chunks/uk-Bp9HotPq.mjs → translations/uk.json.mjs} +1 -1
  96. package/dist/admin/translations/uk.json.mjs.map +1 -0
  97. package/dist/admin/utils/api.js +8 -0
  98. package/dist/admin/utils/api.js.map +1 -0
  99. package/dist/admin/utils/api.mjs +6 -0
  100. package/dist/admin/utils/api.mjs.map +1 -0
  101. package/dist/admin/utils/prefixPluginTranslations.js +11 -0
  102. package/dist/admin/utils/prefixPluginTranslations.js.map +1 -0
  103. package/dist/admin/utils/prefixPluginTranslations.mjs +9 -0
  104. package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -0
  105. package/dist/admin/utils/time.js +42 -0
  106. package/dist/admin/utils/time.js.map +1 -0
  107. package/dist/admin/utils/time.mjs +39 -0
  108. package/dist/admin/utils/time.mjs.map +1 -0
  109. package/dist/admin/{chunks/schemas-DS7NeFDN.js → validation/schemas.js} +1 -1
  110. package/dist/admin/validation/schemas.js.map +1 -0
  111. package/dist/admin/{chunks/schemas-DMt8h1z-.mjs → validation/schemas.mjs} +2 -2
  112. package/dist/admin/validation/schemas.mjs.map +1 -0
  113. package/dist/server/bootstrap.js +68 -0
  114. package/dist/server/bootstrap.js.map +1 -0
  115. package/dist/server/bootstrap.mjs +66 -0
  116. package/dist/server/bootstrap.mjs.map +1 -0
  117. package/dist/server/constants.js +74 -0
  118. package/dist/server/constants.js.map +1 -0
  119. package/dist/server/constants.mjs +69 -0
  120. package/dist/server/constants.mjs.map +1 -0
  121. package/dist/server/content-types/index.js +12 -0
  122. package/dist/server/content-types/index.js.map +1 -0
  123. package/dist/server/content-types/index.mjs +10 -0
  124. package/dist/server/content-types/index.mjs.map +1 -0
  125. package/dist/server/content-types/release/index.js +10 -0
  126. package/dist/server/content-types/release/index.js.map +1 -0
  127. package/dist/server/content-types/release/index.mjs +8 -0
  128. package/dist/server/content-types/release/index.mjs.map +1 -0
  129. package/dist/server/content-types/release/schema.js +58 -0
  130. package/dist/server/content-types/release/schema.js.map +1 -0
  131. package/dist/server/content-types/release/schema.mjs +56 -0
  132. package/dist/server/content-types/release/schema.mjs.map +1 -0
  133. package/dist/server/content-types/release-action/index.js +10 -0
  134. package/dist/server/content-types/release-action/index.js.map +1 -0
  135. package/dist/server/content-types/release-action/index.mjs +8 -0
  136. package/dist/server/content-types/release-action/index.mjs.map +1 -0
  137. package/dist/server/content-types/release-action/schema.js +55 -0
  138. package/dist/server/content-types/release-action/schema.js.map +1 -0
  139. package/dist/server/content-types/release-action/schema.mjs +53 -0
  140. package/dist/server/content-types/release-action/schema.mjs.map +1 -0
  141. package/dist/server/controllers/index.js +14 -0
  142. package/dist/server/controllers/index.js.map +1 -0
  143. package/dist/server/controllers/index.mjs +12 -0
  144. package/dist/server/controllers/index.mjs.map +1 -0
  145. package/dist/server/controllers/release-action.js +150 -0
  146. package/dist/server/controllers/release-action.js.map +1 -0
  147. package/dist/server/controllers/release-action.mjs +148 -0
  148. package/dist/server/controllers/release-action.mjs.map +1 -0
  149. package/dist/server/controllers/release.js +302 -0
  150. package/dist/server/controllers/release.js.map +1 -0
  151. package/dist/server/controllers/release.mjs +300 -0
  152. package/dist/server/controllers/release.mjs.map +1 -0
  153. package/dist/server/controllers/settings.js +37 -0
  154. package/dist/server/controllers/settings.js.map +1 -0
  155. package/dist/server/controllers/settings.mjs +35 -0
  156. package/dist/server/controllers/settings.mjs.map +1 -0
  157. package/dist/server/controllers/validation/release-action.js +34 -0
  158. package/dist/server/controllers/validation/release-action.js.map +1 -0
  159. package/dist/server/controllers/validation/release-action.mjs +30 -0
  160. package/dist/server/controllers/validation/release-action.mjs.map +1 -0
  161. package/dist/server/controllers/validation/release.js +26 -0
  162. package/dist/server/controllers/validation/release.js.map +1 -0
  163. package/dist/server/controllers/validation/release.mjs +22 -0
  164. package/dist/server/controllers/validation/release.mjs.map +1 -0
  165. package/dist/server/controllers/validation/settings.js +32 -0
  166. package/dist/server/controllers/validation/settings.js.map +1 -0
  167. package/dist/server/controllers/validation/settings.mjs +10 -0
  168. package/dist/server/controllers/validation/settings.mjs.map +1 -0
  169. package/dist/server/destroy.js +15 -0
  170. package/dist/server/destroy.js.map +1 -0
  171. package/dist/server/destroy.mjs +13 -0
  172. package/dist/server/destroy.mjs.map +1 -0
  173. package/dist/server/index.js +16 -2336
  174. package/dist/server/index.js.map +1 -1
  175. package/dist/server/index.mjs +7 -2308
  176. package/dist/server/index.mjs.map +1 -1
  177. package/dist/server/middlewares/documents.js +104 -0
  178. package/dist/server/middlewares/documents.js.map +1 -0
  179. package/dist/server/middlewares/documents.mjs +101 -0
  180. package/dist/server/middlewares/documents.mjs.map +1 -0
  181. package/dist/server/migrations/database/5.0.0-document-id-in-actions.js +51 -0
  182. package/dist/server/migrations/database/5.0.0-document-id-in-actions.js.map +1 -0
  183. package/dist/server/migrations/database/5.0.0-document-id-in-actions.mjs +49 -0
  184. package/dist/server/migrations/database/5.0.0-document-id-in-actions.mjs.map +1 -0
  185. package/dist/server/migrations/index.js +205 -0
  186. package/dist/server/migrations/index.js.map +1 -0
  187. package/dist/server/migrations/index.mjs +198 -0
  188. package/dist/server/migrations/index.mjs.map +1 -0
  189. package/dist/server/register.js +23 -0
  190. package/dist/server/register.js.map +1 -0
  191. package/dist/server/register.mjs +21 -0
  192. package/dist/server/register.mjs.map +1 -0
  193. package/dist/server/routes/index.js +14 -0
  194. package/dist/server/routes/index.js.map +1 -0
  195. package/dist/server/routes/index.mjs +12 -0
  196. package/dist/server/routes/index.mjs.map +1 -0
  197. package/dist/server/routes/release-action.js +100 -0
  198. package/dist/server/routes/release-action.js.map +1 -0
  199. package/dist/server/routes/release-action.mjs +98 -0
  200. package/dist/server/routes/release-action.mjs.map +1 -0
  201. package/dist/server/routes/release.js +154 -0
  202. package/dist/server/routes/release.js.map +1 -0
  203. package/dist/server/routes/release.mjs +152 -0
  204. package/dist/server/routes/release.mjs.map +1 -0
  205. package/dist/server/routes/settings.js +46 -0
  206. package/dist/server/routes/settings.js.map +1 -0
  207. package/dist/server/routes/settings.mjs +44 -0
  208. package/dist/server/routes/settings.mjs.map +1 -0
  209. package/dist/server/services/index.js +18 -0
  210. package/dist/server/services/index.js.map +1 -0
  211. package/dist/server/services/index.mjs +16 -0
  212. package/dist/server/services/index.mjs.map +1 -0
  213. package/dist/server/services/release-action.js +323 -0
  214. package/dist/server/services/release-action.js.map +1 -0
  215. package/dist/server/services/release-action.mjs +321 -0
  216. package/dist/server/services/release-action.mjs.map +1 -0
  217. package/dist/server/services/release.js +324 -0
  218. package/dist/server/services/release.js.map +1 -0
  219. package/dist/server/services/release.mjs +322 -0
  220. package/dist/server/services/release.mjs.map +1 -0
  221. package/dist/server/services/scheduling.js +70 -0
  222. package/dist/server/services/scheduling.js.map +1 -0
  223. package/dist/server/services/scheduling.mjs +68 -0
  224. package/dist/server/services/scheduling.mjs.map +1 -0
  225. package/dist/server/services/settings.js +34 -0
  226. package/dist/server/services/settings.js.map +1 -0
  227. package/dist/server/services/settings.mjs +32 -0
  228. package/dist/server/services/settings.mjs.map +1 -0
  229. package/dist/server/services/validation.js +91 -0
  230. package/dist/server/services/validation.js.map +1 -0
  231. package/dist/server/services/validation.mjs +86 -0
  232. package/dist/server/services/validation.mjs.map +1 -0
  233. package/dist/server/utils/index.js +93 -0
  234. package/dist/server/utils/index.js.map +1 -0
  235. package/dist/server/utils/index.mjs +87 -0
  236. package/dist/server/utils/index.mjs.map +1 -0
  237. package/package.json +7 -7
  238. package/dist/admin/chunks/App-BkWgp5q_.mjs +0 -1845
  239. package/dist/admin/chunks/App-BkWgp5q_.mjs.map +0 -1
  240. package/dist/admin/chunks/App-CJiqPP7-.js +0 -1866
  241. package/dist/admin/chunks/App-CJiqPP7-.js.map +0 -1
  242. package/dist/admin/chunks/PurchaseContentReleases-CzayeVUD.mjs +0 -193
  243. package/dist/admin/chunks/PurchaseContentReleases-CzayeVUD.mjs.map +0 -1
  244. package/dist/admin/chunks/PurchaseContentReleases-Z9uEPb5b.js +0 -195
  245. package/dist/admin/chunks/PurchaseContentReleases-Z9uEPb5b.js.map +0 -1
  246. package/dist/admin/chunks/ReleasesSettingsPage-DUKdFdvx.mjs.map +0 -1
  247. package/dist/admin/chunks/ReleasesSettingsPage-KRcoI1bC.js.map +0 -1
  248. package/dist/admin/chunks/en-BOpqX2t_.js.map +0 -1
  249. package/dist/admin/chunks/en-aQo8Bn_U.mjs.map +0 -1
  250. package/dist/admin/chunks/hooks-CFk_8Q0b.mjs.map +0 -1
  251. package/dist/admin/chunks/hooks-DA5VbUAp.js.map +0 -1
  252. package/dist/admin/chunks/index-DBUaMD56.mjs +0 -1619
  253. package/dist/admin/chunks/index-DBUaMD56.mjs.map +0 -1
  254. package/dist/admin/chunks/index-vjWrvGN3.js +0 -1658
  255. package/dist/admin/chunks/index-vjWrvGN3.js.map +0 -1
  256. package/dist/admin/chunks/schemas-DMt8h1z-.mjs.map +0 -1
  257. package/dist/admin/chunks/schemas-DS7NeFDN.js.map +0 -1
  258. package/dist/admin/chunks/uk-9T9su-bj.js.map +0 -1
  259. package/dist/admin/chunks/uk-Bp9HotPq.mjs.map +0 -1
@@ -1,1866 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var strapiAdmin$1 = require('@strapi/admin/strapi-admin');
5
- var reactRouterDom = require('react-router-dom');
6
- var index = require('./index-vjWrvGN3.js');
7
- var React = require('react');
8
- var designSystem = require('@strapi/design-system');
9
- var icons = require('@strapi/icons');
10
- var symbols = require('@strapi/icons/symbols');
11
- var format = require('date-fns/format');
12
- var dateFnsTz = require('date-fns-tz');
13
- var reactIntl = require('react-intl');
14
- var styledComponents = require('styled-components');
15
- var strapiAdmin = require('@strapi/content-manager/strapi-admin');
16
- var qs = require('qs');
17
- var dateFns = require('date-fns');
18
- var formik = require('formik');
19
- var schemas = require('./schemas-DS7NeFDN.js');
20
- var reactRedux = require('react-redux');
21
- var ee = require('@strapi/admin/strapi-admin/ee');
22
- require('yup');
23
-
24
- function _interopNamespaceDefault(e) {
25
- var n = Object.create(null);
26
- if (e) {
27
- Object.keys(e).forEach(function (k) {
28
- if (k !== 'default') {
29
- var d = Object.getOwnPropertyDescriptor(e, k);
30
- Object.defineProperty(n, k, d.get ? d : {
31
- enumerable: true,
32
- get: function () { return e[k]; }
33
- });
34
- }
35
- });
36
- }
37
- n.default = e;
38
- return Object.freeze(n);
39
- }
40
-
41
- var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
42
-
43
- const StyledPopoverFlex = styledComponents.styled(designSystem.Flex)`
44
- width: 100%;
45
- max-width: 256px;
46
-
47
- & > * {
48
- border-bottom: 1px solid ${({ theme })=>theme.colors.neutral150};
49
- }
50
-
51
- & > *:last-child {
52
- border-bottom: none;
53
- }
54
- `;
55
- const EntryStatusTrigger = ({ action, status, hasErrors, requiredStage, entryStage })=>{
56
- const { formatMessage } = reactIntl.useIntl();
57
- if (action === 'publish') {
58
- if (hasErrors || requiredStage && requiredStage.id !== entryStage?.id) {
59
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
60
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
61
- variant: "ghost",
62
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CrossCircle, {
63
- fill: "danger600"
64
- }),
65
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
66
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
67
- textColor: "danger600",
68
- variant: "omega",
69
- fontWeight: "bold",
70
- children: formatMessage({
71
- id: 'content-releases.pages.ReleaseDetails.entry-validation.not-ready',
72
- defaultMessage: 'Not ready to publish'
73
- })
74
- })
75
- })
76
- });
77
- }
78
- if (status === 'draft') {
79
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
80
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
81
- variant: "ghost",
82
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
83
- fill: "success600"
84
- }),
85
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
86
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
87
- textColor: "success600",
88
- variant: "omega",
89
- fontWeight: "bold",
90
- children: formatMessage({
91
- id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',
92
- defaultMessage: 'Ready to publish'
93
- })
94
- })
95
- })
96
- });
97
- }
98
- if (status === 'modified') {
99
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
100
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
101
- variant: "ghost",
102
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.ArrowsCounterClockwise, {
103
- fill: "alternative600"
104
- }),
105
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
106
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
107
- variant: "omega",
108
- fontWeight: "bold",
109
- textColor: "alternative600",
110
- children: formatMessage({
111
- id: 'content-releases.pages.ReleaseDetails.entry-validation.modified',
112
- defaultMessage: 'Ready to publish changes'
113
- })
114
- })
115
- })
116
- });
117
- }
118
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
119
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
120
- variant: "ghost",
121
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
122
- fill: "success600"
123
- }),
124
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
125
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
126
- textColor: "success600",
127
- variant: "omega",
128
- fontWeight: "bold",
129
- children: formatMessage({
130
- id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',
131
- defaultMessage: 'Already published'
132
- })
133
- })
134
- })
135
- });
136
- }
137
- if (status === 'published') {
138
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
139
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
140
- variant: "ghost",
141
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
142
- fill: "success600"
143
- }),
144
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
145
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
146
- textColor: "success600",
147
- variant: "omega",
148
- fontWeight: "bold",
149
- children: formatMessage({
150
- id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish',
151
- defaultMessage: 'Ready to unpublish'
152
- })
153
- })
154
- })
155
- });
156
- }
157
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Trigger, {
158
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
159
- variant: "ghost",
160
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
161
- fill: "success600"
162
- }),
163
- endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.CaretDown, {}),
164
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
165
- textColor: "success600",
166
- variant: "omega",
167
- fontWeight: "bold",
168
- children: formatMessage({
169
- id: 'content-releases.pages.ReleaseDetails.entry-validation.already-unpublished',
170
- defaultMessage: 'Already unpublished'
171
- })
172
- })
173
- })
174
- });
175
- };
176
- const FieldsValidation = ({ hasErrors, errors, kind, contentTypeUid, documentId, locale })=>{
177
- const { formatMessage } = reactIntl.useIntl();
178
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
179
- direction: "column",
180
- gap: 1,
181
- width: "100%",
182
- padding: 5,
183
- children: [
184
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
185
- gap: 2,
186
- width: "100%",
187
- children: [
188
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
189
- fontWeight: "bold",
190
- children: formatMessage({
191
- id: 'content-releases.pages.ReleaseDetails.entry-validation.fields',
192
- defaultMessage: 'Fields'
193
- })
194
- }),
195
- hasErrors ? /*#__PURE__*/ jsxRuntime.jsx(icons.CrossCircle, {
196
- fill: "danger600"
197
- }) : /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
198
- fill: "success600"
199
- })
200
- ]
201
- }),
202
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
203
- width: "100%",
204
- textColor: "neutral600",
205
- children: hasErrors ? formatMessage({
206
- id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.error',
207
- defaultMessage: '{errors} errors on fields.'
208
- }, {
209
- errors: errors ? Object.keys(errors).length : 0
210
- }) : formatMessage({
211
- id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.success',
212
- defaultMessage: 'All fields are filled correctly.'
213
- })
214
- }),
215
- hasErrors && /*#__PURE__*/ jsxRuntime.jsx(designSystem.LinkButton, {
216
- tag: reactRouterDom.Link,
217
- to: {
218
- pathname: `/content-manager/${kind === 'collectionType' ? 'collection-types' : 'single-types'}/${contentTypeUid}/${documentId}`,
219
- search: locale ? qs.stringify({
220
- plugins: {
221
- i18n: {
222
- locale
223
- }
224
- }
225
- }) : ''
226
- },
227
- variant: "secondary",
228
- fullWidth: true,
229
- state: {
230
- forceValidation: true
231
- },
232
- children: formatMessage({
233
- id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.see-errors',
234
- defaultMessage: 'See errors'
235
- })
236
- })
237
- ]
238
- });
239
- };
240
- const getReviewStageIcon = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage })=>{
241
- if (!contentTypeHasReviewWorkflow) {
242
- return /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
243
- fill: "neutral200"
244
- });
245
- }
246
- if (requiredStage && requiredStage.id !== entryStage?.id) {
247
- return /*#__PURE__*/ jsxRuntime.jsx(icons.CrossCircle, {
248
- fill: "danger600"
249
- });
250
- }
251
- return /*#__PURE__*/ jsxRuntime.jsx(icons.CheckCircle, {
252
- fill: "success600"
253
- });
254
- };
255
- const getReviewStageMessage = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage, formatMessage })=>{
256
- if (!contentTypeHasReviewWorkflow) {
257
- return formatMessage({
258
- id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-enabled',
259
- defaultMessage: 'This entry is not associated to any workflow.'
260
- });
261
- }
262
- if (requiredStage && requiredStage.id !== entryStage?.id) {
263
- return formatMessage({
264
- id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-ready',
265
- defaultMessage: 'This entry is not at the required stage for publishing. ({stageName})'
266
- }, {
267
- stageName: requiredStage?.name ?? ''
268
- });
269
- }
270
- if (requiredStage && requiredStage.id === entryStage?.id) {
271
- return formatMessage({
272
- id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.ready',
273
- defaultMessage: 'This entry is at the required stage for publishing. ({stageName})'
274
- }, {
275
- stageName: requiredStage?.name ?? ''
276
- });
277
- }
278
- return formatMessage({
279
- id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.stage-not-required',
280
- defaultMessage: 'No required stage for publication'
281
- });
282
- };
283
- const ReviewStageValidation = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage })=>{
284
- const { formatMessage } = reactIntl.useIntl();
285
- const Icon = getReviewStageIcon({
286
- contentTypeHasReviewWorkflow,
287
- requiredStage,
288
- entryStage
289
- });
290
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
291
- direction: "column",
292
- gap: 1,
293
- width: "100%",
294
- padding: 5,
295
- children: [
296
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
297
- gap: 2,
298
- width: "100%",
299
- children: [
300
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
301
- fontWeight: "bold",
302
- children: formatMessage({
303
- id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage',
304
- defaultMessage: 'Review stage'
305
- })
306
- }),
307
- Icon
308
- ]
309
- }),
310
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
311
- textColor: "neutral600",
312
- children: getReviewStageMessage({
313
- contentTypeHasReviewWorkflow,
314
- requiredStage,
315
- entryStage,
316
- formatMessage
317
- })
318
- })
319
- ]
320
- });
321
- };
322
- const EntryValidationPopover = ({ schema, entry, status, action })=>{
323
- const { validate, isLoading } = strapiAdmin.unstable_useDocument({
324
- collectionType: schema?.kind ?? '',
325
- model: schema?.uid ?? ''
326
- }, {
327
- // 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
328
- skip: true
329
- });
330
- // Validation errors
331
- const errors = isLoading ? null : validate(entry);
332
- const hasErrors = errors ? Object.keys(errors).length > 0 : false;
333
- // Entry stage
334
- const contentTypeHasReviewWorkflow = schema?.hasReviewWorkflow ?? false;
335
- const requiredStage = schema?.stageRequiredToPublish;
336
- const entryStage = entry.strapi_stage;
337
- if (isLoading) {
338
- return null;
339
- }
340
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Popover.Root, {
341
- children: [
342
- /*#__PURE__*/ jsxRuntime.jsx(EntryStatusTrigger, {
343
- action: action,
344
- status: status,
345
- hasErrors: hasErrors,
346
- requiredStage: requiredStage,
347
- entryStage: entryStage
348
- }),
349
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Popover.Content, {
350
- children: /*#__PURE__*/ jsxRuntime.jsxs(StyledPopoverFlex, {
351
- direction: "column",
352
- children: [
353
- /*#__PURE__*/ jsxRuntime.jsx(FieldsValidation, {
354
- hasErrors: hasErrors,
355
- errors: errors,
356
- contentTypeUid: schema?.uid,
357
- kind: schema?.kind,
358
- documentId: entry.documentId,
359
- locale: entry.locale
360
- }),
361
- /*#__PURE__*/ jsxRuntime.jsx(ReviewStageValidation, {
362
- contentTypeHasReviewWorkflow: contentTypeHasReviewWorkflow,
363
- requiredStage: requiredStage,
364
- entryStage: entryStage
365
- })
366
- ]
367
- })
368
- })
369
- ]
370
- });
371
- };
372
-
373
- const intervals = [
374
- 'years',
375
- 'months',
376
- 'days',
377
- 'hours',
378
- 'minutes',
379
- 'seconds'
380
- ];
381
- /**
382
- * Displays the relative time between a given timestamp and the current time.
383
- * You can display a custom message for given time intervals by passing an array of custom intervals.
384
- *
385
- * @example
386
- * ```jsx
387
- * <caption>Display "last hour" if the timestamp is less than an hour ago</caption>
388
- * <RelativeTime
389
- * timestamp={new Date('2021-01-01')}
390
- * customIntervals={[
391
- * { unit: 'hours', threshold: 1, text: 'last hour' },
392
- * ]}
393
- * ```
394
- */ const RelativeTime$1 = /*#__PURE__*/ React__namespace.forwardRef(({ timestamp, customIntervals = [], ...restProps }, forwardedRef)=>{
395
- const { formatRelativeTime, formatDate, formatTime } = reactIntl.useIntl();
396
- /**
397
- * TODO: make this auto-update, like a clock.
398
- */ const interval = dateFns.intervalToDuration({
399
- start: timestamp,
400
- end: Date.now()
401
- });
402
- const unit = intervals.find((intervalUnit)=>{
403
- return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
404
- });
405
- const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
406
- // Display custom text if interval is less than the threshold
407
- const customInterval = customIntervals.find((custom)=>interval[custom.unit] < custom.threshold);
408
- const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, {
409
- numeric: 'auto'
410
- });
411
- return /*#__PURE__*/ jsxRuntime.jsx("time", {
412
- ref: forwardedRef,
413
- dateTime: timestamp.toISOString(),
414
- role: "time",
415
- title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
416
- ...restProps,
417
- children: displayText
418
- });
419
- });
420
-
421
- const ReleaseModal = ({ handleClose, open, handleSubmit, initialValues, isLoading = false })=>{
422
- const { formatMessage } = reactIntl.useIntl();
423
- const { pathname } = reactRouterDom.useLocation();
424
- const isCreatingRelease = pathname === `/plugins/${index.pluginId}`;
425
- // Set default first timezone from the list if no system timezone detected
426
- const { timezoneList, systemTimezone = {
427
- value: 'UTC+00:00-Africa/Abidjan '
428
- } } = index.getTimezones(initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : new Date());
429
- /**
430
- * Generate scheduled time using selected date, time and timezone
431
- */ const getScheduledTimestamp = (values)=>{
432
- const { date, time, timezone } = values;
433
- if (!date || !time || !timezone) return null;
434
- const timezoneWithoutOffset = timezone.split('&')[1];
435
- return dateFnsTz.zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);
436
- };
437
- /**
438
- * Get timezone with offset to show the selected value in the dropdown
439
- */ const getTimezoneWithOffset = ()=>{
440
- const currentTimezone = timezoneList.find((timezone)=>timezone.value.split('&')[1] === initialValues.timezone);
441
- return currentTimezone?.value || systemTimezone.value;
442
- };
443
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Root, {
444
- open: open,
445
- onOpenChange: handleClose,
446
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Content, {
447
- children: [
448
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Header, {
449
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Title, {
450
- children: formatMessage({
451
- id: 'content-releases.modal.title',
452
- defaultMessage: '{isCreatingRelease, select, true {New release} other {Edit release}}'
453
- }, {
454
- isCreatingRelease: isCreatingRelease
455
- })
456
- })
457
- }),
458
- /*#__PURE__*/ jsxRuntime.jsx(formik.Formik, {
459
- onSubmit: (values)=>{
460
- handleSubmit({
461
- ...values,
462
- timezone: values.timezone ? values.timezone.split('&')[1] : null,
463
- scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
464
- });
465
- },
466
- initialValues: {
467
- ...initialValues,
468
- timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
469
- },
470
- validationSchema: schemas.RELEASE_SCHEMA,
471
- validateOnChange: false,
472
- children: ({ values, errors, handleChange, setFieldValue })=>{
473
- return /*#__PURE__*/ jsxRuntime.jsxs(formik.Form, {
474
- children: [
475
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
476
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
477
- direction: "column",
478
- alignItems: "stretch",
479
- gap: 6,
480
- children: [
481
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
482
- name: "name",
483
- error: errors.name && formatMessage({
484
- id: errors.name,
485
- defaultMessage: errors.name
486
- }),
487
- required: true,
488
- children: [
489
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
490
- children: formatMessage({
491
- id: 'content-releases.modal.form.input.label.release-name',
492
- defaultMessage: 'Name'
493
- })
494
- }),
495
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
496
- value: values.name,
497
- onChange: handleChange
498
- }),
499
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
500
- ]
501
- }),
502
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
503
- width: "max-content",
504
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Checkbox, {
505
- name: "isScheduled",
506
- checked: values.isScheduled,
507
- onCheckedChange: (checked)=>{
508
- setFieldValue('isScheduled', checked);
509
- if (!checked) {
510
- // Clear scheduling info from a release on unchecking schedule release, which reset scheduling info in DB
511
- setFieldValue('date', null);
512
- setFieldValue('time', '');
513
- setFieldValue('timezone', null);
514
- } else {
515
- // On ticking back schedule release date, time and timezone should be restored to the initial state
516
- setFieldValue('date', initialValues.date);
517
- setFieldValue('time', initialValues.time);
518
- setFieldValue('timezone', initialValues.timezone ?? systemTimezone?.value);
519
- }
520
- },
521
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
522
- textColor: values.isScheduled ? 'primary600' : 'neutral800',
523
- fontWeight: values.isScheduled ? 'semiBold' : 'regular',
524
- children: formatMessage({
525
- id: 'modal.form.input.label.schedule-release',
526
- defaultMessage: 'Schedule release'
527
- })
528
- })
529
- })
530
- }),
531
- values.isScheduled && /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
532
- children: [
533
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
534
- gap: 4,
535
- alignItems: "start",
536
- children: [
537
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
538
- width: "100%",
539
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
540
- name: "date",
541
- error: errors.date && formatMessage({
542
- id: errors.date,
543
- defaultMessage: errors.date
544
- }),
545
- required: true,
546
- children: [
547
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
548
- children: formatMessage({
549
- id: 'content-releases.modal.form.input.label.date',
550
- defaultMessage: 'Date'
551
- })
552
- }),
553
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.DatePicker, {
554
- onChange: (date)=>{
555
- const isoFormatDate = date ? dateFns.formatISO(date, {
556
- representation: 'date'
557
- }) : null;
558
- setFieldValue('date', isoFormatDate);
559
- },
560
- clearLabel: formatMessage({
561
- id: 'content-releases.modal.form.input.clearLabel',
562
- defaultMessage: 'Clear'
563
- }),
564
- onClear: ()=>{
565
- setFieldValue('date', null);
566
- },
567
- value: values.date ? new Date(values.date) : new Date(),
568
- minDate: dateFnsTz.utcToZonedTime(new Date(), values.timezone.split('&')[1])
569
- }),
570
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
571
- ]
572
- })
573
- }),
574
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
575
- width: "100%",
576
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
577
- name: "time",
578
- error: errors.time && formatMessage({
579
- id: errors.time,
580
- defaultMessage: errors.time
581
- }),
582
- required: true,
583
- children: [
584
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
585
- children: formatMessage({
586
- id: 'content-releases.modal.form.input.label.time',
587
- defaultMessage: 'Time'
588
- })
589
- }),
590
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.TimePicker, {
591
- onChange: (time)=>{
592
- setFieldValue('time', time);
593
- },
594
- clearLabel: formatMessage({
595
- id: 'content-releases.modal.form.input.clearLabel',
596
- defaultMessage: 'Clear'
597
- }),
598
- onClear: ()=>{
599
- setFieldValue('time', '');
600
- },
601
- value: values.time || undefined
602
- }),
603
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
604
- ]
605
- })
606
- })
607
- ]
608
- }),
609
- /*#__PURE__*/ jsxRuntime.jsx(TimezoneComponent, {
610
- timezoneOptions: timezoneList
611
- })
612
- ]
613
- })
614
- ]
615
- })
616
- }),
617
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Footer, {
618
- children: [
619
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Close, {
620
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
621
- variant: "tertiary",
622
- name: "cancel",
623
- children: formatMessage({
624
- id: 'cancel',
625
- defaultMessage: 'Cancel'
626
- })
627
- })
628
- }),
629
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
630
- name: "submit",
631
- loading: isLoading,
632
- type: "submit",
633
- children: formatMessage({
634
- id: 'content-releases.modal.form.button.submit',
635
- defaultMessage: '{isCreatingRelease, select, true {Continue} other {Save}}'
636
- }, {
637
- isCreatingRelease: isCreatingRelease
638
- })
639
- })
640
- ]
641
- })
642
- ]
643
- });
644
- }
645
- })
646
- ]
647
- })
648
- });
649
- };
650
- const TimezoneComponent = ({ timezoneOptions })=>{
651
- const { values, errors, setFieldValue } = formik.useFormikContext();
652
- const { formatMessage } = reactIntl.useIntl();
653
- const [timezoneList, setTimezoneList] = React__namespace.useState(timezoneOptions);
654
- React__namespace.useEffect(()=>{
655
- if (values.date) {
656
- // Update the timezone offset which varies with DST based on the date selected
657
- const { timezoneList } = index.getTimezones(new Date(values.date));
658
- setTimezoneList(timezoneList);
659
- const updatedTimezone = values.timezone && timezoneList.find((tz)=>tz.value.split('&')[1] === values.timezone.split('&')[1]);
660
- if (updatedTimezone) {
661
- setFieldValue('timezone', updatedTimezone.value);
662
- }
663
- }
664
- }, [
665
- setFieldValue,
666
- values.date,
667
- values.timezone
668
- ]);
669
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
670
- name: "timezone",
671
- error: errors.timezone && formatMessage({
672
- id: errors.timezone,
673
- defaultMessage: errors.timezone
674
- }),
675
- required: true,
676
- children: [
677
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
678
- children: formatMessage({
679
- id: 'content-releases.modal.form.input.label.timezone',
680
- defaultMessage: 'Timezone'
681
- })
682
- }),
683
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Combobox, {
684
- autocomplete: {
685
- type: 'list',
686
- filter: 'contains'
687
- },
688
- value: values.timezone || undefined,
689
- textValue: values.timezone ? values.timezone.replace(/&/, ' ') : undefined,
690
- onChange: (timezone)=>{
691
- setFieldValue('timezone', timezone);
692
- },
693
- onTextValueChange: (timezone)=>{
694
- setFieldValue('timezone', timezone);
695
- },
696
- onClear: ()=>{
697
- setFieldValue('timezone', '');
698
- },
699
- children: timezoneList.map((timezone)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.ComboboxOption, {
700
- value: timezone.value,
701
- children: timezone.value.replace(/&/, ' ')
702
- }, timezone.value))
703
- }),
704
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
705
- ]
706
- });
707
- };
708
-
709
- const useTypedDispatch = reactRedux.useDispatch;
710
-
711
- const isBaseQueryError = (error)=>{
712
- return typeof error !== 'undefined' && error.name !== undefined;
713
- };
714
-
715
- const LinkCard = styledComponents.styled(designSystem.Link)`
716
- display: block;
717
- `;
718
- const RelativeTime = styledComponents.styled(RelativeTime$1)`
719
- display: inline-block;
720
- &::first-letter {
721
- text-transform: uppercase;
722
- }
723
- `;
724
- const getBadgeProps = (status)=>{
725
- let color;
726
- switch(status){
727
- case 'ready':
728
- color = 'success';
729
- break;
730
- case 'blocked':
731
- color = 'warning';
732
- break;
733
- case 'failed':
734
- color = 'danger';
735
- break;
736
- case 'done':
737
- color = 'primary';
738
- break;
739
- case 'empty':
740
- default:
741
- color = 'neutral';
742
- }
743
- return {
744
- textColor: `${color}600`,
745
- backgroundColor: `${color}100`,
746
- borderColor: `${color}200`
747
- };
748
- };
749
- const ReleasesGrid = ({ sectionTitle, releases = [], isError = false })=>{
750
- const { formatMessage } = reactIntl.useIntl();
751
- if (isError) {
752
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Error, {});
753
- }
754
- if (releases?.length === 0) {
755
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.EmptyStateLayout, {
756
- content: formatMessage({
757
- id: 'content-releases.page.Releases.tab.emptyEntries',
758
- defaultMessage: 'No releases'
759
- }, {
760
- target: sectionTitle
761
- }),
762
- icon: /*#__PURE__*/ jsxRuntime.jsx(symbols.EmptyDocuments, {
763
- width: "16rem"
764
- })
765
- });
766
- }
767
- return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
768
- gap: 4,
769
- children: releases.map(({ id, name, scheduledAt, status })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
770
- col: 3,
771
- s: 6,
772
- xs: 12,
773
- direction: "column",
774
- alignItems: "stretch",
775
- children: /*#__PURE__*/ jsxRuntime.jsx(LinkCard, {
776
- tag: reactRouterDom.NavLink,
777
- to: `${id}`,
778
- isExternal: false,
779
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
780
- direction: "column",
781
- justifyContent: "space-between",
782
- padding: 4,
783
- hasRadius: true,
784
- background: "neutral0",
785
- shadow: "tableShadow",
786
- height: "100%",
787
- width: "100%",
788
- alignItems: "start",
789
- gap: 4,
790
- children: [
791
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
792
- direction: "column",
793
- alignItems: "start",
794
- gap: 1,
795
- children: [
796
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
797
- textColor: "neutral800",
798
- tag: "h3",
799
- variant: "delta",
800
- fontWeight: "bold",
801
- children: name
802
- }),
803
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
804
- variant: "pi",
805
- textColor: "neutral600",
806
- children: scheduledAt ? /*#__PURE__*/ jsxRuntime.jsx(RelativeTime, {
807
- timestamp: new Date(scheduledAt)
808
- }) : formatMessage({
809
- id: 'content-releases.pages.Releases.not-scheduled',
810
- defaultMessage: 'Not scheduled'
811
- })
812
- })
813
- ]
814
- }),
815
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Badge, {
816
- ...getBadgeProps(status),
817
- children: status
818
- })
819
- ]
820
- })
821
- })
822
- }, id))
823
- });
824
- };
825
- /* -------------------------------------------------------------------------------------------------
826
- * ReleasesPage
827
- * -----------------------------------------------------------------------------------------------*/ const StyledAlert = styledComponents.styled(designSystem.Alert)`
828
- button {
829
- display: none;
830
- }
831
- p + div {
832
- margin-left: auto;
833
- }
834
- `;
835
- const INITIAL_FORM_VALUES = {
836
- name: '',
837
- date: dateFns.format(new Date(), 'yyyy-MM-dd'),
838
- time: '',
839
- isScheduled: true,
840
- scheduledAt: null,
841
- timezone: null
842
- };
843
- const ReleasesPage = ()=>{
844
- const location = reactRouterDom.useLocation();
845
- const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
846
- const { toggleNotification } = strapiAdmin$1.useNotification();
847
- const { formatMessage } = reactIntl.useIntl();
848
- const navigate = reactRouterDom.useNavigate();
849
- const { formatAPIError } = strapiAdmin$1.useAPIErrorHandler();
850
- const [{ query }, setQuery] = strapiAdmin$1.useQueryParams();
851
- const response = index.useGetReleasesQuery(query);
852
- const { data, isLoading: isLoadingSettings } = index.useGetReleaseSettingsQuery();
853
- const [createRelease, { isLoading: isSubmittingForm }] = index.useCreateReleaseMutation();
854
- const { getFeature } = ee.useLicenseLimits();
855
- const { maximumReleases = 3 } = getFeature('cms-content-releases');
856
- const { trackUsage } = strapiAdmin$1.useTracking();
857
- const { allowedActions: { canCreate } } = strapiAdmin$1.useRBAC(index.PERMISSIONS);
858
- const { isLoading: isLoadingReleases, isSuccess, isError } = response;
859
- const activeTab = response?.currentData?.meta?.activeTab || 'pending';
860
- // Check if we have some errors and show a notification to the user to explain the error
861
- React__namespace.useEffect(()=>{
862
- if (location?.state?.errors) {
863
- toggleNotification({
864
- type: 'danger',
865
- title: formatMessage({
866
- id: 'content-releases.pages.Releases.notification.error.title',
867
- defaultMessage: 'Your request could not be processed.'
868
- }),
869
- message: formatMessage({
870
- id: 'content-releases.pages.Releases.notification.error.message',
871
- defaultMessage: 'Please try again or open another release.'
872
- })
873
- });
874
- navigate('', {
875
- replace: true,
876
- state: null
877
- });
878
- }
879
- }, [
880
- formatMessage,
881
- location?.state?.errors,
882
- navigate,
883
- toggleNotification
884
- ]);
885
- const toggleAddReleaseModal = ()=>{
886
- setReleaseModalShown((prev)=>!prev);
887
- };
888
- if (isLoadingReleases || isLoadingSettings) {
889
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Loading, {});
890
- }
891
- const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
892
- const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
893
- const handleTabChange = (tabValue)=>{
894
- setQuery({
895
- ...query,
896
- page: 1,
897
- pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
898
- filters: {
899
- releasedAt: {
900
- $notNull: tabValue !== 'pending'
901
- }
902
- }
903
- });
904
- };
905
- const handleAddRelease = async ({ name, scheduledAt, timezone })=>{
906
- const response = await createRelease({
907
- name,
908
- scheduledAt,
909
- timezone
910
- });
911
- if ('data' in response) {
912
- // When the response returns an object with 'data', handle success
913
- toggleNotification({
914
- type: 'success',
915
- message: formatMessage({
916
- id: 'content-releases.modal.release-created-notification-success',
917
- defaultMessage: 'Release created.'
918
- })
919
- });
920
- trackUsage('didCreateRelease');
921
- navigate(response.data.data.id.toString());
922
- } else if (strapiAdmin$1.isFetchError(response.error)) {
923
- // When the response returns an object with 'error', handle fetch error
924
- toggleNotification({
925
- type: 'danger',
926
- message: formatAPIError(response.error)
927
- });
928
- } else {
929
- // Otherwise, the response returns an object with 'error', handle a generic error
930
- toggleNotification({
931
- type: 'danger',
932
- message: formatMessage({
933
- id: 'notification.error',
934
- defaultMessage: 'An error occurred'
935
- })
936
- });
937
- }
938
- };
939
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Main, {
940
- "aria-busy": isLoadingReleases || isLoadingSettings,
941
- children: [
942
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Layouts.Header, {
943
- title: formatMessage({
944
- id: 'content-releases.pages.Releases.title',
945
- defaultMessage: 'Releases'
946
- }),
947
- subtitle: formatMessage({
948
- id: 'content-releases.pages.Releases.header-subtitle',
949
- defaultMessage: 'Create and manage content updates'
950
- }),
951
- primaryAction: canCreate ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
952
- startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}),
953
- onClick: toggleAddReleaseModal,
954
- disabled: hasReachedMaximumPendingReleases,
955
- children: formatMessage({
956
- id: 'content-releases.header.actions.add-release',
957
- defaultMessage: 'New release'
958
- })
959
- }) : null
960
- }),
961
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Layouts.Content, {
962
- children: /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
963
- children: [
964
- hasReachedMaximumPendingReleases && /*#__PURE__*/ jsxRuntime.jsx(StyledAlert, {
965
- marginBottom: 6,
966
- action: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Link, {
967
- href: "https://strapi.io/pricing-cloud",
968
- isExternal: true,
969
- children: formatMessage({
970
- id: 'content-releases.pages.Releases.max-limit-reached.action',
971
- defaultMessage: 'Explore plans'
972
- })
973
- }),
974
- title: formatMessage({
975
- id: 'content-releases.pages.Releases.max-limit-reached.title',
976
- defaultMessage: 'You have reached the {number} pending {number, plural, one {release} other {releases}} limit.'
977
- }, {
978
- number: maximumReleases
979
- }),
980
- onClose: ()=>{},
981
- closeLabel: "",
982
- children: formatMessage({
983
- id: 'content-releases.pages.Releases.max-limit-reached.message',
984
- defaultMessage: 'Upgrade to manage an unlimited number of releases.'
985
- })
986
- }),
987
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.Root, {
988
- variant: "simple",
989
- onValueChange: handleTabChange,
990
- value: activeTab,
991
- children: [
992
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Box, {
993
- paddingBottom: 8,
994
- children: [
995
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tabs.List, {
996
- "aria-label": formatMessage({
997
- id: 'content-releases.pages.Releases.tab-group.label',
998
- defaultMessage: 'Releases list'
999
- }),
1000
- children: [
1001
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
1002
- value: "pending",
1003
- children: formatMessage({
1004
- id: 'content-releases.pages.Releases.tab.pending',
1005
- defaultMessage: 'Pending ({count})'
1006
- }, {
1007
- count: totalPendingReleases
1008
- })
1009
- }),
1010
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Trigger, {
1011
- value: "done",
1012
- children: formatMessage({
1013
- id: 'content-releases.pages.Releases.tab.done',
1014
- defaultMessage: 'Done'
1015
- })
1016
- })
1017
- ]
1018
- }),
1019
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Divider, {})
1020
- ]
1021
- }),
1022
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
1023
- value: "pending",
1024
- children: /*#__PURE__*/ jsxRuntime.jsx(ReleasesGrid, {
1025
- sectionTitle: "pending",
1026
- releases: response?.currentData?.data,
1027
- isError: isError
1028
- })
1029
- }),
1030
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tabs.Content, {
1031
- value: "done",
1032
- children: /*#__PURE__*/ jsxRuntime.jsx(ReleasesGrid, {
1033
- sectionTitle: "done",
1034
- releases: response?.currentData?.data,
1035
- isError: isError
1036
- })
1037
- })
1038
- ]
1039
- }),
1040
- /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin$1.Pagination.Root, {
1041
- ...response?.currentData?.meta?.pagination,
1042
- defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
1043
- children: [
1044
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Pagination.PageSize, {
1045
- options: [
1046
- '8',
1047
- '16',
1048
- '32',
1049
- '64'
1050
- ]
1051
- }),
1052
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Pagination.Links, {})
1053
- ]
1054
- })
1055
- ]
1056
- })
1057
- }),
1058
- /*#__PURE__*/ jsxRuntime.jsx(ReleaseModal, {
1059
- open: releaseModalShown,
1060
- handleClose: toggleAddReleaseModal,
1061
- handleSubmit: handleAddRelease,
1062
- isLoading: isSubmittingForm,
1063
- initialValues: {
1064
- ...INITIAL_FORM_VALUES,
1065
- timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split('&')[1] : null
1066
- }
1067
- })
1068
- ]
1069
- });
1070
- };
1071
-
1072
- /* -------------------------------------------------------------------------------------------------
1073
- * ReleaseDetailsLayout
1074
- * -----------------------------------------------------------------------------------------------*/ const ReleaseInfoWrapper = styledComponents.styled(designSystem.Flex)`
1075
- align-self: stretch;
1076
- border-bottom-right-radius: ${({ theme })=>theme.borderRadius};
1077
- border-bottom-left-radius: ${({ theme })=>theme.borderRadius};
1078
- border-top: 1px solid ${({ theme })=>theme.colors.neutral150};
1079
- `;
1080
- const StyledMenuItem = styledComponents.styled(designSystem.MenuItem)`
1081
- svg path {
1082
- fill: ${({ theme, disabled })=>disabled && theme.colors.neutral500};
1083
- }
1084
- span {
1085
- color: ${({ theme, disabled })=>disabled && theme.colors.neutral500};
1086
- }
1087
-
1088
- &:hover {
1089
- background: ${({ theme, $variant = 'neutral' })=>theme.colors[`${$variant}100`]};
1090
- }
1091
- `;
1092
- const PencilIcon = styledComponents.styled(icons.Pencil)`
1093
- width: ${({ theme })=>theme.spaces[4]};
1094
- height: ${({ theme })=>theme.spaces[4]};
1095
- path {
1096
- fill: ${({ theme })=>theme.colors.neutral600};
1097
- }
1098
- `;
1099
- const TrashIcon = styledComponents.styled(icons.Trash)`
1100
- width: ${({ theme })=>theme.spaces[4]};
1101
- height: ${({ theme })=>theme.spaces[4]};
1102
- path {
1103
- fill: ${({ theme })=>theme.colors.danger600};
1104
- }
1105
- `;
1106
- const ReleaseDetailsLayout = ({ toggleEditReleaseModal, toggleWarningSubmit, children })=>{
1107
- const { formatMessage, formatDate, formatTime } = reactIntl.useIntl();
1108
- const { releaseId } = reactRouterDom.useParams();
1109
- const { data, isLoading: isLoadingDetails, error } = index.useGetReleaseQuery({
1110
- id: releaseId
1111
- }, {
1112
- skip: !releaseId
1113
- });
1114
- const [publishRelease, { isLoading: isPublishing }] = index.usePublishReleaseMutation();
1115
- const { toggleNotification } = strapiAdmin$1.useNotification();
1116
- const { formatAPIError } = strapiAdmin$1.useAPIErrorHandler();
1117
- const { allowedActions } = strapiAdmin$1.useRBAC(index.PERMISSIONS);
1118
- const { canUpdate, canDelete, canPublish } = allowedActions;
1119
- const dispatch = useTypedDispatch();
1120
- const { trackUsage } = strapiAdmin$1.useTracking();
1121
- const release = data?.data;
1122
- const handlePublishRelease = (id)=>async ()=>{
1123
- const response = await publishRelease({
1124
- id
1125
- });
1126
- if ('data' in response) {
1127
- // When the response returns an object with 'data', handle success
1128
- toggleNotification({
1129
- type: 'success',
1130
- message: formatMessage({
1131
- id: 'content-releases.pages.ReleaseDetails.publish-notification-success',
1132
- defaultMessage: 'Release was published successfully.'
1133
- })
1134
- });
1135
- const { totalEntries, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;
1136
- trackUsage('didPublishRelease', {
1137
- totalEntries,
1138
- totalPublishedEntries,
1139
- totalUnpublishedEntries
1140
- });
1141
- } else if (strapiAdmin$1.isFetchError(response.error)) {
1142
- // When the response returns an object with 'error', handle fetch error
1143
- toggleNotification({
1144
- type: 'danger',
1145
- message: formatAPIError(response.error)
1146
- });
1147
- } else {
1148
- // Otherwise, the response returns an object with 'error', handle a generic error
1149
- toggleNotification({
1150
- type: 'danger',
1151
- message: formatMessage({
1152
- id: 'notification.error',
1153
- defaultMessage: 'An error occurred'
1154
- })
1155
- });
1156
- }
1157
- };
1158
- const handleRefresh = ()=>{
1159
- dispatch(index.releaseApi.util.invalidateTags([
1160
- {
1161
- type: 'ReleaseAction',
1162
- id: 'LIST'
1163
- },
1164
- {
1165
- type: 'Release',
1166
- id: releaseId
1167
- }
1168
- ]));
1169
- };
1170
- const getCreatedByUser = ()=>{
1171
- if (!release?.createdBy) {
1172
- return null;
1173
- }
1174
- // Favor the username
1175
- if (release.createdBy.username) {
1176
- return release.createdBy.username;
1177
- }
1178
- // Firstname may not exist if created with SSO
1179
- if (release.createdBy.firstname) {
1180
- return `${release.createdBy.firstname} ${release.createdBy.lastname || ''}`.trim();
1181
- }
1182
- // All users must have at least an email
1183
- return release.createdBy.email;
1184
- };
1185
- if (isLoadingDetails) {
1186
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Loading, {});
1187
- }
1188
- if (isBaseQueryError(error) && 'code' in error || !release) {
1189
- return /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Navigate, {
1190
- to: "..",
1191
- state: {
1192
- errors: [
1193
- {
1194
- // @ts-expect-error – TODO: fix this weird error flow
1195
- code: error?.code
1196
- }
1197
- ]
1198
- }
1199
- });
1200
- }
1201
- const totalEntries = release.actions.meta.count || 0;
1202
- const hasCreatedByUser = Boolean(getCreatedByUser());
1203
- const isScheduled = release.scheduledAt && release.timezone;
1204
- const numberOfEntriesText = formatMessage({
1205
- id: 'content-releases.pages.Details.header-subtitle',
1206
- defaultMessage: '{number, plural, =0 {No entries} one {# entry} other {# entries}}'
1207
- }, {
1208
- number: totalEntries
1209
- });
1210
- const scheduledText = isScheduled ? formatMessage({
1211
- id: 'content-releases.pages.ReleaseDetails.header-subtitle.scheduled',
1212
- defaultMessage: 'Scheduled for {date} at {time} ({offset})'
1213
- }, {
1214
- date: formatDate(new Date(release.scheduledAt), {
1215
- weekday: 'long',
1216
- day: 'numeric',
1217
- month: 'long',
1218
- year: 'numeric',
1219
- timeZone: release.timezone
1220
- }),
1221
- time: formatTime(new Date(release.scheduledAt), {
1222
- timeZone: release.timezone,
1223
- hourCycle: 'h23'
1224
- }),
1225
- offset: index.getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
1226
- }) : '';
1227
- return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Main, {
1228
- "aria-busy": isLoadingDetails,
1229
- children: [
1230
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Layouts.Header, {
1231
- title: release.name,
1232
- subtitle: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1233
- gap: 2,
1234
- lineHeight: 6,
1235
- children: [
1236
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1237
- textColor: "neutral600",
1238
- variant: "epsilon",
1239
- children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : '')
1240
- }),
1241
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Badge, {
1242
- ...getBadgeProps(release.status),
1243
- children: release.status
1244
- })
1245
- ]
1246
- }),
1247
- navigationAction: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.BackButton, {
1248
- fallback: ".."
1249
- }),
1250
- primaryAction: !release.releasedAt && /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1251
- gap: 2,
1252
- children: [
1253
- /*#__PURE__*/ jsxRuntime.jsxs(SimpleMenuButton, {
1254
- label: /*#__PURE__*/ jsxRuntime.jsx(icons.More, {}),
1255
- variant: "tertiary",
1256
- endIcon: null,
1257
- paddingLeft: "7px",
1258
- paddingRight: "7px",
1259
- "aria-label": formatMessage({
1260
- id: 'content-releases.header.actions.open-release-actions',
1261
- defaultMessage: 'Release edit and delete menu'
1262
- }),
1263
- popoverPlacement: "bottom-end",
1264
- children: [
1265
- /*#__PURE__*/ jsxRuntime.jsx(StyledMenuItem, {
1266
- disabled: !canUpdate,
1267
- onSelect: toggleEditReleaseModal,
1268
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1269
- alignItems: "center",
1270
- gap: 2,
1271
- hasRadius: true,
1272
- width: "100%",
1273
- children: [
1274
- /*#__PURE__*/ jsxRuntime.jsx(PencilIcon, {}),
1275
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1276
- ellipsis: true,
1277
- children: formatMessage({
1278
- id: 'content-releases.header.actions.edit',
1279
- defaultMessage: 'Edit'
1280
- })
1281
- })
1282
- ]
1283
- })
1284
- }),
1285
- /*#__PURE__*/ jsxRuntime.jsx(StyledMenuItem, {
1286
- disabled: !canDelete,
1287
- onSelect: toggleWarningSubmit,
1288
- $variant: "danger",
1289
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1290
- alignItems: "center",
1291
- gap: 2,
1292
- hasRadius: true,
1293
- width: "100%",
1294
- children: [
1295
- /*#__PURE__*/ jsxRuntime.jsx(TrashIcon, {}),
1296
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1297
- ellipsis: true,
1298
- textColor: "danger600",
1299
- children: formatMessage({
1300
- id: 'content-releases.header.actions.delete',
1301
- defaultMessage: 'Delete'
1302
- })
1303
- })
1304
- ]
1305
- })
1306
- }),
1307
- /*#__PURE__*/ jsxRuntime.jsxs(ReleaseInfoWrapper, {
1308
- direction: "column",
1309
- justifyContent: "center",
1310
- alignItems: "flex-start",
1311
- gap: 1,
1312
- padding: 4,
1313
- children: [
1314
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1315
- variant: "pi",
1316
- fontWeight: "bold",
1317
- children: formatMessage({
1318
- id: 'content-releases.header.actions.created',
1319
- defaultMessage: 'Created'
1320
- })
1321
- }),
1322
- /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Typography, {
1323
- variant: "pi",
1324
- color: "neutral300",
1325
- children: [
1326
- /*#__PURE__*/ jsxRuntime.jsx(RelativeTime$1, {
1327
- timestamp: new Date(release.createdAt)
1328
- }),
1329
- formatMessage({
1330
- id: 'content-releases.header.actions.created.description',
1331
- defaultMessage: '{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}'
1332
- }, {
1333
- createdBy: getCreatedByUser(),
1334
- hasCreatedByUser
1335
- })
1336
- ]
1337
- })
1338
- ]
1339
- })
1340
- ]
1341
- }),
1342
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
1343
- size: "S",
1344
- variant: "tertiary",
1345
- onClick: handleRefresh,
1346
- children: formatMessage({
1347
- id: 'content-releases.header.actions.refresh',
1348
- defaultMessage: 'Refresh'
1349
- })
1350
- }),
1351
- canPublish ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
1352
- size: "S",
1353
- variant: "default",
1354
- onClick: handlePublishRelease(release.id.toString()),
1355
- loading: isPublishing,
1356
- disabled: release.actions.meta.count === 0,
1357
- children: formatMessage({
1358
- id: 'content-releases.header.actions.publish',
1359
- defaultMessage: 'Publish'
1360
- })
1361
- }) : null
1362
- ]
1363
- })
1364
- }),
1365
- children
1366
- ]
1367
- });
1368
- };
1369
- const SimpleMenuButton = styledComponents.styled(designSystem.SimpleMenu)`
1370
- & > span {
1371
- display: flex;
1372
- }
1373
- `;
1374
- /* -------------------------------------------------------------------------------------------------
1375
- * ReleaseDetailsBody
1376
- * -----------------------------------------------------------------------------------------------*/ const GROUP_BY_OPTIONS = [
1377
- 'contentType',
1378
- 'locale',
1379
- 'action'
1380
- ];
1381
- const GROUP_BY_OPTIONS_NO_LOCALE = [
1382
- 'contentType',
1383
- 'action'
1384
- ];
1385
- const getGroupByOptionLabel = (value)=>{
1386
- if (value === 'locale') {
1387
- return {
1388
- id: 'content-releases.pages.ReleaseDetails.groupBy.option.locales',
1389
- defaultMessage: 'Locales'
1390
- };
1391
- }
1392
- if (value === 'action') {
1393
- return {
1394
- id: 'content-releases.pages.ReleaseDetails.groupBy.option.actions',
1395
- defaultMessage: 'Actions'
1396
- };
1397
- }
1398
- return {
1399
- id: 'content-releases.pages.ReleaseDetails.groupBy.option.content-type',
1400
- defaultMessage: 'Content-Types'
1401
- };
1402
- };
1403
- const ReleaseDetailsBody = ({ releaseId })=>{
1404
- const { formatMessage } = reactIntl.useIntl();
1405
- const [{ query }, setQuery] = strapiAdmin$1.useQueryParams();
1406
- const { toggleNotification } = strapiAdmin$1.useNotification();
1407
- const { formatAPIError } = strapiAdmin$1.useAPIErrorHandler();
1408
- const { data: releaseData, isLoading: isReleaseLoading, error: releaseError } = index.useGetReleaseQuery({
1409
- id: releaseId
1410
- });
1411
- const { allowedActions: { canUpdate } } = strapiAdmin$1.useRBAC(index.PERMISSIONS);
1412
- const runHookWaterfall = strapiAdmin$1.useStrapiApp('ReleaseDetailsPage', (state)=>state.runHookWaterfall);
1413
- // TODO: Migrated displayedHeader to v5
1414
- const { displayedHeaders, hasI18nEnabled } = runHookWaterfall('ContentReleases/pages/ReleaseDetails/add-locale-in-releases', {
1415
- displayedHeaders: [
1416
- {
1417
- label: {
1418
- id: 'content-releases.page.ReleaseDetails.table.header.label.name',
1419
- defaultMessage: 'name'
1420
- },
1421
- name: 'name'
1422
- }
1423
- ],
1424
- hasI18nEnabled: false
1425
- });
1426
- const release = releaseData?.data;
1427
- const selectedGroupBy = query?.groupBy || 'contentType';
1428
- const { isLoading, isFetching, isError, data, error: releaseActionsError } = index.useGetReleaseActionsQuery({
1429
- ...query,
1430
- releaseId
1431
- });
1432
- const [updateReleaseAction] = index.useUpdateReleaseActionMutation();
1433
- const handleChangeType = async (e, actionId, actionPath)=>{
1434
- const response = await updateReleaseAction({
1435
- params: {
1436
- releaseId,
1437
- actionId
1438
- },
1439
- body: {
1440
- type: e.target.value
1441
- },
1442
- query,
1443
- actionPath
1444
- });
1445
- if ('error' in response) {
1446
- if (strapiAdmin$1.isFetchError(response.error)) {
1447
- // When the response returns an object with 'error', handle fetch error
1448
- toggleNotification({
1449
- type: 'danger',
1450
- message: formatAPIError(response.error)
1451
- });
1452
- } else {
1453
- // Otherwise, the response returns an object with 'error', handle a generic error
1454
- toggleNotification({
1455
- type: 'danger',
1456
- message: formatMessage({
1457
- id: 'notification.error',
1458
- defaultMessage: 'An error occurred'
1459
- })
1460
- });
1461
- }
1462
- }
1463
- };
1464
- if (isLoading || isReleaseLoading) {
1465
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Loading, {});
1466
- }
1467
- const releaseActions = data?.data;
1468
- const releaseMeta = data?.meta;
1469
- const contentTypes = releaseMeta?.contentTypes || {};
1470
- releaseMeta?.components || {};
1471
- if (isBaseQueryError(releaseError) || !release) {
1472
- const errorsArray = [];
1473
- if (releaseError && 'code' in releaseError) {
1474
- errorsArray.push({
1475
- code: releaseError.code
1476
- });
1477
- }
1478
- if (releaseActionsError && 'code' in releaseActionsError) {
1479
- errorsArray.push({
1480
- code: releaseActionsError.code
1481
- });
1482
- }
1483
- return /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Navigate, {
1484
- to: "..",
1485
- state: {
1486
- errors: errorsArray
1487
- }
1488
- });
1489
- }
1490
- if (isError || !releaseActions) {
1491
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Error, {});
1492
- }
1493
- if (Object.keys(releaseActions).length === 0) {
1494
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Layouts.Content, {
1495
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.EmptyStateLayout, {
1496
- action: /*#__PURE__*/ jsxRuntime.jsx(designSystem.LinkButton, {
1497
- tag: reactRouterDom.Link,
1498
- to: {
1499
- pathname: '/content-manager'
1500
- },
1501
- style: {
1502
- textDecoration: 'none'
1503
- },
1504
- variant: "secondary",
1505
- children: formatMessage({
1506
- id: 'content-releases.page.Details.button.openContentManager',
1507
- defaultMessage: 'Open the Content Manager'
1508
- })
1509
- }),
1510
- icon: /*#__PURE__*/ jsxRuntime.jsx(symbols.EmptyDocuments, {
1511
- width: "16rem"
1512
- }),
1513
- content: formatMessage({
1514
- id: 'content-releases.pages.Details.tab.emptyEntries',
1515
- defaultMessage: 'This release is empty. Open the Content Manager, select an entry and add it to the release.'
1516
- })
1517
- })
1518
- });
1519
- }
1520
- const groupByLabel = formatMessage({
1521
- id: 'content-releases.pages.ReleaseDetails.groupBy.aria-label',
1522
- defaultMessage: 'Group by'
1523
- });
1524
- const headers = [
1525
- ...displayedHeaders,
1526
- {
1527
- label: {
1528
- id: 'content-releases.page.ReleaseDetails.table.header.label.content-type',
1529
- defaultMessage: 'content-type'
1530
- },
1531
- name: 'content-type'
1532
- },
1533
- {
1534
- label: {
1535
- id: 'content-releases.page.ReleaseDetails.table.header.label.action',
1536
- defaultMessage: 'action'
1537
- },
1538
- name: 'action'
1539
- },
1540
- ...!release.releasedAt ? [
1541
- {
1542
- label: {
1543
- id: 'content-releases.page.ReleaseDetails.table.header.label.status',
1544
- defaultMessage: 'status'
1545
- },
1546
- name: 'status'
1547
- }
1548
- ] : []
1549
- ];
1550
- const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1551
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Layouts.Content, {
1552
- children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1553
- gap: 8,
1554
- direction: "column",
1555
- alignItems: "stretch",
1556
- children: [
1557
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
1558
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelect, {
1559
- placeholder: groupByLabel,
1560
- "aria-label": groupByLabel,
1561
- customizeContent: (value)=>formatMessage({
1562
- id: `content-releases.pages.ReleaseDetails.groupBy.label`,
1563
- defaultMessage: `Group by {groupBy}`
1564
- }, {
1565
- groupBy: value
1566
- }),
1567
- value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
1568
- onChange: (value)=>setQuery({
1569
- groupBy: value
1570
- }),
1571
- children: options.map((option)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.SingleSelectOption, {
1572
- value: option,
1573
- children: formatMessage(getGroupByOptionLabel(option))
1574
- }, option))
1575
- })
1576
- }),
1577
- Object.keys(releaseActions).map((key)=>/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
1578
- gap: 4,
1579
- direction: "column",
1580
- alignItems: "stretch",
1581
- children: [
1582
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
1583
- role: "separator",
1584
- "aria-label": key,
1585
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Badge, {
1586
- children: key
1587
- })
1588
- }),
1589
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Table.Root, {
1590
- rows: releaseActions[key].map((item)=>({
1591
- ...item,
1592
- id: Number(item.entry.id)
1593
- })),
1594
- headers: headers,
1595
- isLoading: isLoading || isFetching,
1596
- children: /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin$1.Table.Content, {
1597
- children: [
1598
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Table.Head, {
1599
- children: headers.map(({ label, name })=>/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Table.HeaderCell, {
1600
- label: formatMessage(label),
1601
- name: name
1602
- }, name))
1603
- }),
1604
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Table.Loading, {}),
1605
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Table.Body, {
1606
- children: releaseActions[key].map(({ id, contentType, locale, type, entry, status }, actionIndex)=>/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
1607
- children: [
1608
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1609
- width: "25%",
1610
- maxWidth: "200px",
1611
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1612
- ellipsis: true,
1613
- children: `${contentType.mainFieldValue || entry.id}`
1614
- })
1615
- }),
1616
- hasI18nEnabled && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1617
- width: "10%",
1618
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1619
- children: `${locale?.name ? locale.name : '-'}`
1620
- })
1621
- }),
1622
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1623
- width: "10%",
1624
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1625
- children: contentType.displayName || ''
1626
- })
1627
- }),
1628
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1629
- width: "20%",
1630
- children: release.releasedAt ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1631
- children: formatMessage({
1632
- id: 'content-releases.page.ReleaseDetails.table.action-published',
1633
- defaultMessage: 'This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>.'
1634
- }, {
1635
- isPublish: type === 'publish',
1636
- b: (children)=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
1637
- fontWeight: "bold",
1638
- children: children
1639
- })
1640
- })
1641
- }) : /*#__PURE__*/ jsxRuntime.jsx(index.ReleaseActionOptions, {
1642
- selected: type,
1643
- handleChange: (e)=>handleChangeType(e, id, [
1644
- key,
1645
- actionIndex
1646
- ]),
1647
- name: `release-action-${id}-type`,
1648
- disabled: !canUpdate
1649
- })
1650
- }),
1651
- !release.releasedAt && /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
1652
- children: [
1653
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1654
- width: "20%",
1655
- minWidth: "200px",
1656
- children: /*#__PURE__*/ jsxRuntime.jsx(EntryValidationPopover, {
1657
- action: type,
1658
- schema: contentTypes?.[contentType.uid],
1659
- entry: entry,
1660
- status: status
1661
- })
1662
- }),
1663
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
1664
- children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
1665
- justifyContent: "flex-end",
1666
- children: /*#__PURE__*/ jsxRuntime.jsxs(index.ReleaseActionMenu.Root, {
1667
- children: [
1668
- /*#__PURE__*/ jsxRuntime.jsx(index.ReleaseActionMenu.ReleaseActionEntryLinkItem, {
1669
- contentTypeUid: contentType.uid,
1670
- documentId: entry.documentId,
1671
- locale: locale?.code
1672
- }),
1673
- /*#__PURE__*/ jsxRuntime.jsx(index.ReleaseActionMenu.DeleteReleaseActionItem, {
1674
- releaseId: release.id,
1675
- actionId: id
1676
- })
1677
- ]
1678
- })
1679
- })
1680
- })
1681
- ]
1682
- })
1683
- ]
1684
- }, id))
1685
- })
1686
- ]
1687
- })
1688
- })
1689
- ]
1690
- }, `releases-group-${key}`)),
1691
- /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin$1.Pagination.Root, {
1692
- ...releaseMeta?.pagination,
1693
- defaultPageSize: releaseMeta?.pagination?.pageSize,
1694
- children: [
1695
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Pagination.PageSize, {}),
1696
- /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Pagination.Links, {})
1697
- ]
1698
- })
1699
- ]
1700
- })
1701
- });
1702
- };
1703
- /* -------------------------------------------------------------------------------------------------
1704
- * ReleaseDetailsPage
1705
- * -----------------------------------------------------------------------------------------------*/ const ReleaseDetailsPage = ()=>{
1706
- const { formatMessage } = reactIntl.useIntl();
1707
- const { releaseId } = reactRouterDom.useParams();
1708
- const { toggleNotification } = strapiAdmin$1.useNotification();
1709
- const { formatAPIError } = strapiAdmin$1.useAPIErrorHandler();
1710
- const navigate = reactRouterDom.useNavigate();
1711
- const [releaseModalShown, setReleaseModalShown] = React__namespace.useState(false);
1712
- const [showWarningSubmit, setWarningSubmit] = React__namespace.useState(false);
1713
- const { isLoading: isLoadingDetails, data, isSuccess: isSuccessDetails } = index.useGetReleaseQuery({
1714
- id: releaseId
1715
- }, {
1716
- skip: !releaseId
1717
- });
1718
- const { data: dataTimezone, isLoading: isLoadingTimezone } = index.useGetReleaseSettingsQuery();
1719
- const [updateRelease, { isLoading: isSubmittingForm }] = index.useUpdateReleaseMutation();
1720
- const [deleteRelease] = index.useDeleteReleaseMutation();
1721
- const toggleEditReleaseModal = ()=>{
1722
- setReleaseModalShown((prev)=>!prev);
1723
- };
1724
- const getTimezoneValue = ()=>{
1725
- if (releaseData?.timezone) {
1726
- return releaseData.timezone;
1727
- } else {
1728
- if (dataTimezone?.data.defaultTimezone) {
1729
- return dataTimezone.data.defaultTimezone;
1730
- }
1731
- return null;
1732
- }
1733
- };
1734
- const toggleWarningSubmit = ()=>setWarningSubmit((prevState)=>!prevState);
1735
- if (isLoadingDetails || isLoadingTimezone) {
1736
- return /*#__PURE__*/ jsxRuntime.jsx(ReleaseDetailsLayout, {
1737
- toggleEditReleaseModal: toggleEditReleaseModal,
1738
- toggleWarningSubmit: toggleWarningSubmit,
1739
- children: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Loading, {})
1740
- });
1741
- }
1742
- if (!releaseId) {
1743
- return /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Navigate, {
1744
- to: ".."
1745
- });
1746
- }
1747
- const releaseData = isSuccessDetails && data?.data || null;
1748
- const title = releaseData?.name || '';
1749
- const timezone = getTimezoneValue();
1750
- const scheduledAt = releaseData?.scheduledAt && timezone ? dateFnsTz.utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1751
- // Just get the date and time to display without considering updated timezone time
1752
- const date = scheduledAt ? format(scheduledAt, 'yyyy-MM-dd') : undefined;
1753
- const time = scheduledAt ? format(scheduledAt, 'HH:mm') : '';
1754
- const handleEditRelease = async (values)=>{
1755
- const response = await updateRelease({
1756
- id: releaseId,
1757
- name: values.name,
1758
- scheduledAt: values.scheduledAt,
1759
- timezone: values.timezone
1760
- });
1761
- if ('data' in response) {
1762
- // When the response returns an object with 'data', handle success
1763
- toggleNotification({
1764
- type: 'success',
1765
- message: formatMessage({
1766
- id: 'content-releases.modal.release-updated-notification-success',
1767
- defaultMessage: 'Release updated.'
1768
- })
1769
- });
1770
- toggleEditReleaseModal();
1771
- } else if (strapiAdmin$1.isFetchError(response.error)) {
1772
- // When the response returns an object with 'error', handle fetch error
1773
- toggleNotification({
1774
- type: 'danger',
1775
- message: formatAPIError(response.error)
1776
- });
1777
- } else {
1778
- // Otherwise, the response returns an object with 'error', handle a generic error
1779
- toggleNotification({
1780
- type: 'danger',
1781
- message: formatMessage({
1782
- id: 'notification.error',
1783
- defaultMessage: 'An error occurred'
1784
- })
1785
- });
1786
- }
1787
- };
1788
- const handleDeleteRelease = async ()=>{
1789
- const response = await deleteRelease({
1790
- id: releaseId
1791
- });
1792
- if ('data' in response) {
1793
- navigate('..');
1794
- } else if (strapiAdmin$1.isFetchError(response.error)) {
1795
- // When the response returns an object with 'error', handle fetch error
1796
- toggleNotification({
1797
- type: 'danger',
1798
- message: formatAPIError(response.error)
1799
- });
1800
- } else {
1801
- // Otherwise, the response returns an object with 'error', handle a generic error
1802
- toggleNotification({
1803
- type: 'danger',
1804
- message: formatMessage({
1805
- id: 'notification.error',
1806
- defaultMessage: 'An error occurred'
1807
- })
1808
- });
1809
- }
1810
- };
1811
- return /*#__PURE__*/ jsxRuntime.jsxs(ReleaseDetailsLayout, {
1812
- toggleEditReleaseModal: toggleEditReleaseModal,
1813
- toggleWarningSubmit: toggleWarningSubmit,
1814
- children: [
1815
- /*#__PURE__*/ jsxRuntime.jsx(ReleaseDetailsBody, {
1816
- releaseId: releaseId
1817
- }),
1818
- /*#__PURE__*/ jsxRuntime.jsx(ReleaseModal, {
1819
- open: releaseModalShown,
1820
- handleClose: toggleEditReleaseModal,
1821
- handleSubmit: handleEditRelease,
1822
- isLoading: isLoadingDetails || isSubmittingForm,
1823
- initialValues: {
1824
- name: title || '',
1825
- scheduledAt,
1826
- date,
1827
- time,
1828
- isScheduled: Boolean(scheduledAt),
1829
- timezone
1830
- }
1831
- }),
1832
- /*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Root, {
1833
- open: showWarningSubmit,
1834
- onOpenChange: toggleWarningSubmit,
1835
- children: /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.ConfirmDialog, {
1836
- onConfirm: handleDeleteRelease,
1837
- children: formatMessage({
1838
- id: 'content-releases.dialog.confirmation-message',
1839
- defaultMessage: 'Are you sure you want to delete this release?'
1840
- })
1841
- })
1842
- })
1843
- ]
1844
- });
1845
- };
1846
-
1847
- const App = ()=>{
1848
- return /*#__PURE__*/ jsxRuntime.jsx(strapiAdmin$1.Page.Protect, {
1849
- permissions: index.PERMISSIONS.main,
1850
- children: /*#__PURE__*/ jsxRuntime.jsxs(reactRouterDom.Routes, {
1851
- children: [
1852
- /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
1853
- index: true,
1854
- element: /*#__PURE__*/ jsxRuntime.jsx(ReleasesPage, {})
1855
- }),
1856
- /*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
1857
- path: ':releaseId',
1858
- element: /*#__PURE__*/ jsxRuntime.jsx(ReleaseDetailsPage, {})
1859
- })
1860
- ]
1861
- })
1862
- });
1863
- };
1864
-
1865
- exports.App = App;
1866
- //# sourceMappingURL=App-CJiqPP7-.js.map