@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
@@ -0,0 +1,342 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import 'react';
3
+ import { unstable_useDocument } from '@strapi/content-manager/strapi-admin';
4
+ import { Flex, Popover, Button, Typography, LinkButton } from '@strapi/design-system';
5
+ import { CrossCircle, CaretDown, CheckCircle, ArrowsCounterClockwise } from '@strapi/icons';
6
+ import { stringify } from 'qs';
7
+ import { useIntl } from 'react-intl';
8
+ import { Link } from 'react-router-dom';
9
+ import { styled } from 'styled-components';
10
+
11
+ const StyledPopoverFlex = styled(Flex)`
12
+ width: 100%;
13
+ max-width: 256px;
14
+
15
+ & > * {
16
+ border-bottom: 1px solid ${({ theme })=>theme.colors.neutral150};
17
+ }
18
+
19
+ & > *:last-child {
20
+ border-bottom: none;
21
+ }
22
+ `;
23
+ const EntryStatusTrigger = ({ action, status, hasErrors, requiredStage, entryStage })=>{
24
+ const { formatMessage } = useIntl();
25
+ if (action === 'publish') {
26
+ if (hasErrors || requiredStage && requiredStage.id !== entryStage?.id) {
27
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
28
+ children: /*#__PURE__*/ jsx(Button, {
29
+ variant: "ghost",
30
+ startIcon: /*#__PURE__*/ jsx(CrossCircle, {
31
+ fill: "danger600"
32
+ }),
33
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
34
+ children: /*#__PURE__*/ jsx(Typography, {
35
+ textColor: "danger600",
36
+ variant: "omega",
37
+ fontWeight: "bold",
38
+ children: formatMessage({
39
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.not-ready',
40
+ defaultMessage: 'Not ready to publish'
41
+ })
42
+ })
43
+ })
44
+ });
45
+ }
46
+ if (status === 'draft') {
47
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
48
+ children: /*#__PURE__*/ jsx(Button, {
49
+ variant: "ghost",
50
+ startIcon: /*#__PURE__*/ jsx(CheckCircle, {
51
+ fill: "success600"
52
+ }),
53
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
54
+ children: /*#__PURE__*/ jsx(Typography, {
55
+ textColor: "success600",
56
+ variant: "omega",
57
+ fontWeight: "bold",
58
+ children: formatMessage({
59
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',
60
+ defaultMessage: 'Ready to publish'
61
+ })
62
+ })
63
+ })
64
+ });
65
+ }
66
+ if (status === 'modified') {
67
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
68
+ children: /*#__PURE__*/ jsx(Button, {
69
+ variant: "ghost",
70
+ startIcon: /*#__PURE__*/ jsx(ArrowsCounterClockwise, {
71
+ fill: "alternative600"
72
+ }),
73
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
74
+ children: /*#__PURE__*/ jsx(Typography, {
75
+ variant: "omega",
76
+ fontWeight: "bold",
77
+ textColor: "alternative600",
78
+ children: formatMessage({
79
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.modified',
80
+ defaultMessage: 'Ready to publish changes'
81
+ })
82
+ })
83
+ })
84
+ });
85
+ }
86
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
87
+ children: /*#__PURE__*/ jsx(Button, {
88
+ variant: "ghost",
89
+ startIcon: /*#__PURE__*/ jsx(CheckCircle, {
90
+ fill: "success600"
91
+ }),
92
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
93
+ children: /*#__PURE__*/ jsx(Typography, {
94
+ textColor: "success600",
95
+ variant: "omega",
96
+ fontWeight: "bold",
97
+ children: formatMessage({
98
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',
99
+ defaultMessage: 'Already published'
100
+ })
101
+ })
102
+ })
103
+ });
104
+ }
105
+ if (status === 'published') {
106
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
107
+ children: /*#__PURE__*/ jsx(Button, {
108
+ variant: "ghost",
109
+ startIcon: /*#__PURE__*/ jsx(CheckCircle, {
110
+ fill: "success600"
111
+ }),
112
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
113
+ children: /*#__PURE__*/ jsx(Typography, {
114
+ textColor: "success600",
115
+ variant: "omega",
116
+ fontWeight: "bold",
117
+ children: formatMessage({
118
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish',
119
+ defaultMessage: 'Ready to unpublish'
120
+ })
121
+ })
122
+ })
123
+ });
124
+ }
125
+ return /*#__PURE__*/ jsx(Popover.Trigger, {
126
+ children: /*#__PURE__*/ jsx(Button, {
127
+ variant: "ghost",
128
+ startIcon: /*#__PURE__*/ jsx(CheckCircle, {
129
+ fill: "success600"
130
+ }),
131
+ endIcon: /*#__PURE__*/ jsx(CaretDown, {}),
132
+ children: /*#__PURE__*/ jsx(Typography, {
133
+ textColor: "success600",
134
+ variant: "omega",
135
+ fontWeight: "bold",
136
+ children: formatMessage({
137
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.already-unpublished',
138
+ defaultMessage: 'Already unpublished'
139
+ })
140
+ })
141
+ })
142
+ });
143
+ };
144
+ const FieldsValidation = ({ hasErrors, errors, kind, contentTypeUid, documentId, locale })=>{
145
+ const { formatMessage } = useIntl();
146
+ return /*#__PURE__*/ jsxs(Flex, {
147
+ direction: "column",
148
+ gap: 1,
149
+ width: "100%",
150
+ padding: 5,
151
+ children: [
152
+ /*#__PURE__*/ jsxs(Flex, {
153
+ gap: 2,
154
+ width: "100%",
155
+ children: [
156
+ /*#__PURE__*/ jsx(Typography, {
157
+ fontWeight: "bold",
158
+ children: formatMessage({
159
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.fields',
160
+ defaultMessage: 'Fields'
161
+ })
162
+ }),
163
+ hasErrors ? /*#__PURE__*/ jsx(CrossCircle, {
164
+ fill: "danger600"
165
+ }) : /*#__PURE__*/ jsx(CheckCircle, {
166
+ fill: "success600"
167
+ })
168
+ ]
169
+ }),
170
+ /*#__PURE__*/ jsx(Typography, {
171
+ width: "100%",
172
+ textColor: "neutral600",
173
+ children: hasErrors ? formatMessage({
174
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.error',
175
+ defaultMessage: '{errors} errors on fields.'
176
+ }, {
177
+ errors: errors ? Object.keys(errors).length : 0
178
+ }) : formatMessage({
179
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.success',
180
+ defaultMessage: 'All fields are filled correctly.'
181
+ })
182
+ }),
183
+ hasErrors && /*#__PURE__*/ jsx(LinkButton, {
184
+ tag: Link,
185
+ to: {
186
+ pathname: `/content-manager/${kind === 'collectionType' ? 'collection-types' : 'single-types'}/${contentTypeUid}/${documentId}`,
187
+ search: locale ? stringify({
188
+ plugins: {
189
+ i18n: {
190
+ locale
191
+ }
192
+ }
193
+ }) : ''
194
+ },
195
+ variant: "secondary",
196
+ fullWidth: true,
197
+ state: {
198
+ forceValidation: true
199
+ },
200
+ children: formatMessage({
201
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.see-errors',
202
+ defaultMessage: 'See errors'
203
+ })
204
+ })
205
+ ]
206
+ });
207
+ };
208
+ const getReviewStageIcon = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage })=>{
209
+ if (!contentTypeHasReviewWorkflow) {
210
+ return /*#__PURE__*/ jsx(CheckCircle, {
211
+ fill: "neutral200"
212
+ });
213
+ }
214
+ if (requiredStage && requiredStage.id !== entryStage?.id) {
215
+ return /*#__PURE__*/ jsx(CrossCircle, {
216
+ fill: "danger600"
217
+ });
218
+ }
219
+ return /*#__PURE__*/ jsx(CheckCircle, {
220
+ fill: "success600"
221
+ });
222
+ };
223
+ const getReviewStageMessage = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage, formatMessage })=>{
224
+ if (!contentTypeHasReviewWorkflow) {
225
+ return formatMessage({
226
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-enabled',
227
+ defaultMessage: 'This entry is not associated to any workflow.'
228
+ });
229
+ }
230
+ if (requiredStage && requiredStage.id !== entryStage?.id) {
231
+ return formatMessage({
232
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-ready',
233
+ defaultMessage: 'This entry is not at the required stage for publishing. ({stageName})'
234
+ }, {
235
+ stageName: requiredStage?.name ?? ''
236
+ });
237
+ }
238
+ if (requiredStage && requiredStage.id === entryStage?.id) {
239
+ return formatMessage({
240
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.ready',
241
+ defaultMessage: 'This entry is at the required stage for publishing. ({stageName})'
242
+ }, {
243
+ stageName: requiredStage?.name ?? ''
244
+ });
245
+ }
246
+ return formatMessage({
247
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.stage-not-required',
248
+ defaultMessage: 'No required stage for publication'
249
+ });
250
+ };
251
+ const ReviewStageValidation = ({ contentTypeHasReviewWorkflow, requiredStage, entryStage })=>{
252
+ const { formatMessage } = useIntl();
253
+ const Icon = getReviewStageIcon({
254
+ contentTypeHasReviewWorkflow,
255
+ requiredStage,
256
+ entryStage
257
+ });
258
+ return /*#__PURE__*/ jsxs(Flex, {
259
+ direction: "column",
260
+ gap: 1,
261
+ width: "100%",
262
+ padding: 5,
263
+ children: [
264
+ /*#__PURE__*/ jsxs(Flex, {
265
+ gap: 2,
266
+ width: "100%",
267
+ children: [
268
+ /*#__PURE__*/ jsx(Typography, {
269
+ fontWeight: "bold",
270
+ children: formatMessage({
271
+ id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage',
272
+ defaultMessage: 'Review stage'
273
+ })
274
+ }),
275
+ Icon
276
+ ]
277
+ }),
278
+ /*#__PURE__*/ jsx(Typography, {
279
+ textColor: "neutral600",
280
+ children: getReviewStageMessage({
281
+ contentTypeHasReviewWorkflow,
282
+ requiredStage,
283
+ entryStage,
284
+ formatMessage
285
+ })
286
+ })
287
+ ]
288
+ });
289
+ };
290
+ const EntryValidationPopover = ({ schema, entry, status, action })=>{
291
+ const { validate, isLoading } = unstable_useDocument({
292
+ collectionType: schema?.kind ?? '',
293
+ model: schema?.uid ?? ''
294
+ }, {
295
+ // 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
296
+ skip: true
297
+ });
298
+ // Validation errors
299
+ const errors = isLoading ? null : validate(entry);
300
+ const hasErrors = errors ? Object.keys(errors).length > 0 : false;
301
+ // Entry stage
302
+ const contentTypeHasReviewWorkflow = schema?.hasReviewWorkflow ?? false;
303
+ const requiredStage = schema?.stageRequiredToPublish;
304
+ const entryStage = entry.strapi_stage;
305
+ if (isLoading) {
306
+ return null;
307
+ }
308
+ return /*#__PURE__*/ jsxs(Popover.Root, {
309
+ children: [
310
+ /*#__PURE__*/ jsx(EntryStatusTrigger, {
311
+ action: action,
312
+ status: status,
313
+ hasErrors: hasErrors,
314
+ requiredStage: requiredStage,
315
+ entryStage: entryStage
316
+ }),
317
+ /*#__PURE__*/ jsx(Popover.Content, {
318
+ children: /*#__PURE__*/ jsxs(StyledPopoverFlex, {
319
+ direction: "column",
320
+ children: [
321
+ /*#__PURE__*/ jsx(FieldsValidation, {
322
+ hasErrors: hasErrors,
323
+ errors: errors,
324
+ contentTypeUid: schema?.uid,
325
+ kind: schema?.kind,
326
+ documentId: entry.documentId,
327
+ locale: entry.locale
328
+ }),
329
+ /*#__PURE__*/ jsx(ReviewStageValidation, {
330
+ contentTypeHasReviewWorkflow: contentTypeHasReviewWorkflow,
331
+ requiredStage: requiredStage,
332
+ entryStage: entryStage
333
+ })
334
+ ]
335
+ })
336
+ })
337
+ ]
338
+ });
339
+ };
340
+
341
+ export { EntryValidationPopover };
342
+ //# sourceMappingURL=EntryValidationPopover.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntryValidationPopover.mjs","sources":["../../../admin/src/components/EntryValidationPopover.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { FormErrors, FormValues } from '@strapi/admin/strapi-admin';\nimport { unstable_useDocument } from '@strapi/content-manager/strapi-admin';\nimport { Button, LinkButton, Flex, Typography, Popover } from '@strapi/design-system';\nimport { CheckCircle, CrossCircle, ArrowsCounterClockwise, CaretDown } from '@strapi/icons';\nimport { stringify } from 'qs';\nimport { useIntl, MessageDescriptor } from 'react-intl';\nimport { Link } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport type {\n ReleaseAction,\n ReleaseActionEntry,\n Stage,\n} from '../../../shared/contracts/release-actions';\nimport type { Struct } from '@strapi/types';\n\nconst StyledPopoverFlex = styled(Flex)`\n width: 100%;\n max-width: 256px;\n\n & > * {\n border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};\n }\n\n & > *:last-child {\n border-bottom: none;\n }\n`;\n\ninterface EntryValidationPopoverProps {\n action: ReleaseAction['type'];\n schema?: Struct.ContentTypeSchema & {\n hasReviewWorkflow: boolean;\n stageRequiredToPublish?: Stage;\n };\n entry: ReleaseActionEntry;\n status: ReleaseAction['status'];\n}\n\ninterface ValidationStatusProps {\n action: ReleaseAction['type'];\n status: ReleaseAction['status'];\n hasErrors: boolean | null;\n requiredStage?: Stage;\n entryStage?: Stage;\n}\n\nconst EntryStatusTrigger = ({\n action,\n status,\n hasErrors,\n requiredStage,\n entryStage,\n}: ValidationStatusProps) => {\n const { formatMessage } = useIntl();\n\n if (action === 'publish') {\n if (hasErrors || (requiredStage && requiredStage.id !== entryStage?.id)) {\n return (\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n startIcon={<CrossCircle fill=\"danger600\" />}\n endIcon={<CaretDown />}\n >\n <Typography textColor=\"danger600\" variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.not-ready',\n defaultMessage: 'Not ready to publish',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n }\n\n if (status === 'draft') {\n return (\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n startIcon={<CheckCircle fill=\"success600\" />}\n endIcon={<CaretDown />}\n >\n <Typography textColor=\"success600\" variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish',\n defaultMessage: 'Ready to publish',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n }\n\n if (status === 'modified') {\n return (\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n startIcon={<ArrowsCounterClockwise fill=\"alternative600\" />}\n endIcon={<CaretDown />}\n >\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor=\"alternative600\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.modified',\n defaultMessage: 'Ready to publish changes',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n }\n\n return (\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n startIcon={<CheckCircle fill=\"success600\" />}\n endIcon={<CaretDown />}\n >\n <Typography textColor=\"success600\" variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-published',\n defaultMessage: 'Already published',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n }\n\n if (status === 'published') {\n return (\n <Popover.Trigger>\n <Button\n variant=\"ghost\"\n startIcon={<CheckCircle fill=\"success600\" />}\n endIcon={<CaretDown />}\n >\n <Typography textColor=\"success600\" variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish',\n defaultMessage: 'Ready to unpublish',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n }\n\n return (\n <Popover.Trigger>\n <Button variant=\"ghost\" startIcon={<CheckCircle fill=\"success600\" />} endIcon={<CaretDown />}>\n <Typography textColor=\"success600\" variant=\"omega\" fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.already-unpublished',\n defaultMessage: 'Already unpublished',\n })}\n </Typography>\n </Button>\n </Popover.Trigger>\n );\n};\n\ninterface FieldsValidationProps {\n hasErrors: boolean;\n errors: FormErrors<FormValues> | null;\n kind?: string;\n contentTypeUid?: string;\n documentId?: string;\n locale?: string;\n}\n\nconst FieldsValidation = ({\n hasErrors,\n errors,\n kind,\n contentTypeUid,\n documentId,\n locale,\n}: FieldsValidationProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <Flex direction=\"column\" gap={1} width=\"100%\" padding={5}>\n <Flex gap={2} width=\"100%\">\n <Typography fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.fields',\n defaultMessage: 'Fields',\n })}\n </Typography>\n {hasErrors ? <CrossCircle fill=\"danger600\" /> : <CheckCircle fill=\"success600\" />}\n </Flex>\n <Typography width=\"100%\" textColor=\"neutral600\">\n {hasErrors\n ? formatMessage(\n {\n id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.error',\n defaultMessage: '{errors} errors on fields.',\n },\n { errors: errors ? Object.keys(errors).length : 0 }\n )\n : formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.success',\n defaultMessage: 'All fields are filled correctly.',\n })}\n </Typography>\n {hasErrors && (\n <LinkButton\n tag={Link}\n to={{\n pathname: `/content-manager/${kind === 'collectionType' ? 'collection-types' : 'single-types'}/${contentTypeUid}/${documentId}`,\n search: locale\n ? stringify({\n plugins: {\n i18n: {\n locale,\n },\n },\n })\n : '',\n }}\n variant=\"secondary\"\n fullWidth\n state={{ forceValidation: true }}\n >\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.fields.see-errors',\n defaultMessage: 'See errors',\n })}\n </LinkButton>\n )}\n </Flex>\n );\n};\n\nconst getReviewStageIcon = ({\n contentTypeHasReviewWorkflow,\n requiredStage,\n entryStage,\n}: {\n contentTypeHasReviewWorkflow: boolean;\n requiredStage?: Stage;\n entryStage?: Stage;\n}) => {\n if (!contentTypeHasReviewWorkflow) {\n return <CheckCircle fill=\"neutral200\" />;\n }\n if (requiredStage && requiredStage.id !== entryStage?.id) {\n return <CrossCircle fill=\"danger600\" />;\n }\n return <CheckCircle fill=\"success600\" />;\n};\n\nconst getReviewStageMessage = ({\n contentTypeHasReviewWorkflow,\n requiredStage,\n entryStage,\n formatMessage,\n}: {\n contentTypeHasReviewWorkflow: boolean;\n requiredStage?: Stage;\n entryStage?: Stage;\n formatMessage: (messageDescriptor: MessageDescriptor, values?: Record<string, string>) => string;\n}) => {\n if (!contentTypeHasReviewWorkflow) {\n return formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-enabled',\n defaultMessage: 'This entry is not associated to any workflow.',\n });\n }\n\n if (requiredStage && requiredStage.id !== entryStage?.id) {\n return formatMessage(\n {\n id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.not-ready',\n defaultMessage: 'This entry is not at the required stage for publishing. ({stageName})',\n },\n {\n stageName: requiredStage?.name ?? '',\n }\n );\n }\n\n if (requiredStage && requiredStage.id === entryStage?.id) {\n return formatMessage(\n {\n id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.ready',\n defaultMessage: 'This entry is at the required stage for publishing. ({stageName})',\n },\n {\n stageName: requiredStage?.name ?? '',\n }\n );\n }\n\n return formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage.stage-not-required',\n defaultMessage: 'No required stage for publication',\n });\n};\n\nconst ReviewStageValidation = ({\n contentTypeHasReviewWorkflow,\n requiredStage,\n entryStage,\n}: {\n contentTypeHasReviewWorkflow: boolean;\n requiredStage?: Stage;\n entryStage?: Stage;\n}) => {\n const { formatMessage } = useIntl();\n\n const Icon = getReviewStageIcon({\n contentTypeHasReviewWorkflow,\n requiredStage,\n entryStage,\n });\n\n return (\n <Flex direction=\"column\" gap={1} width=\"100%\" padding={5}>\n <Flex gap={2} width=\"100%\">\n <Typography fontWeight=\"bold\">\n {formatMessage({\n id: 'content-releases.pages.ReleaseDetails.entry-validation.review-stage',\n defaultMessage: 'Review stage',\n })}\n </Typography>\n {Icon}\n </Flex>\n <Typography textColor=\"neutral600\">\n {getReviewStageMessage({\n contentTypeHasReviewWorkflow,\n requiredStage,\n entryStage,\n formatMessage,\n })}\n </Typography>\n </Flex>\n );\n};\n\nexport const EntryValidationPopover = ({\n schema,\n entry,\n status,\n action,\n}: EntryValidationPopoverProps) => {\n const { validate, isLoading } = unstable_useDocument(\n {\n collectionType: schema?.kind ?? '',\n model: schema?.uid ?? '',\n },\n {\n // 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\n skip: true,\n }\n );\n\n // Validation errors\n const errors = isLoading ? null : validate(entry);\n const hasErrors = errors ? Object.keys(errors).length > 0 : false;\n\n // Entry stage\n const contentTypeHasReviewWorkflow = schema?.hasReviewWorkflow ?? false;\n const requiredStage = schema?.stageRequiredToPublish;\n const entryStage = entry.strapi_stage;\n\n if (isLoading) {\n return null;\n }\n\n return (\n <Popover.Root>\n <EntryStatusTrigger\n action={action}\n status={status}\n hasErrors={hasErrors}\n requiredStage={requiredStage}\n entryStage={entryStage}\n />\n <Popover.Content>\n <StyledPopoverFlex direction=\"column\">\n <FieldsValidation\n hasErrors={hasErrors}\n errors={errors}\n contentTypeUid={schema?.uid}\n kind={schema?.kind}\n documentId={entry.documentId}\n locale={entry.locale}\n />\n <ReviewStageValidation\n contentTypeHasReviewWorkflow={contentTypeHasReviewWorkflow}\n requiredStage={requiredStage}\n entryStage={entryStage}\n />\n </StyledPopoverFlex>\n </Popover.Content>\n </Popover.Root>\n );\n};\n"],"names":["StyledPopoverFlex","styled","Flex","theme","colors","neutral150","EntryStatusTrigger","action","status","hasErrors","requiredStage","entryStage","formatMessage","useIntl","id","_jsx","Popover","Trigger","Button","variant","startIcon","CrossCircle","fill","endIcon","CaretDown","Typography","textColor","fontWeight","defaultMessage","CheckCircle","ArrowsCounterClockwise","FieldsValidation","errors","kind","contentTypeUid","documentId","locale","_jsxs","direction","gap","width","padding","Object","keys","length","LinkButton","tag","Link","to","pathname","search","stringify","plugins","i18n","fullWidth","state","forceValidation","getReviewStageIcon","contentTypeHasReviewWorkflow","getReviewStageMessage","stageName","name","ReviewStageValidation","Icon","EntryValidationPopover","schema","entry","validate","isLoading","unstable_useDocument","collectionType","model","uid","skip","hasReviewWorkflow","stageRequiredToPublish","strapi_stage","Root","Content"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var dateFns = require('date-fns');
6
+ var reactIntl = require('react-intl');
7
+
8
+ function _interopNamespaceDefault(e) {
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
+
27
+ const intervals = [
28
+ 'years',
29
+ 'months',
30
+ 'days',
31
+ 'hours',
32
+ 'minutes',
33
+ 'seconds'
34
+ ];
35
+ /**
36
+ * Displays the relative time between a given timestamp and the current time.
37
+ * You can display a custom message for given time intervals by passing an array of custom intervals.
38
+ *
39
+ * @example
40
+ * ```jsx
41
+ * <caption>Display "last hour" if the timestamp is less than an hour ago</caption>
42
+ * <RelativeTime
43
+ * timestamp={new Date('2021-01-01')}
44
+ * customIntervals={[
45
+ * { unit: 'hours', threshold: 1, text: 'last hour' },
46
+ * ]}
47
+ * ```
48
+ */ const RelativeTime = /*#__PURE__*/ React__namespace.forwardRef(({ timestamp, customIntervals = [], ...restProps }, forwardedRef)=>{
49
+ const { formatRelativeTime, formatDate, formatTime } = reactIntl.useIntl();
50
+ /**
51
+ * TODO: make this auto-update, like a clock.
52
+ */ const interval = dateFns.intervalToDuration({
53
+ start: timestamp,
54
+ end: Date.now()
55
+ });
56
+ const unit = intervals.find((intervalUnit)=>{
57
+ return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
58
+ });
59
+ const relativeTime = dateFns.isPast(timestamp) ? -interval[unit] : interval[unit];
60
+ // Display custom text if interval is less than the threshold
61
+ const customInterval = customIntervals.find((custom)=>interval[custom.unit] < custom.threshold);
62
+ const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, {
63
+ numeric: 'auto'
64
+ });
65
+ return /*#__PURE__*/ jsxRuntime.jsx("time", {
66
+ ref: forwardedRef,
67
+ dateTime: timestamp.toISOString(),
68
+ role: "time",
69
+ title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
70
+ ...restProps,
71
+ children: displayText
72
+ });
73
+ });
74
+
75
+ exports.RelativeTime = RelativeTime;
76
+ //# sourceMappingURL=RelativeTime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelativeTime.js","sources":["../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit = intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n })!;\n\n const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","_jsx","time","ref","dateTime","toISOString","role","title"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,SAAmC,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACKC,MAAAA,YAAAA,iBAAeC,gBAAMC,CAAAA,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAkB,GAAA,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,iBAAAA,EAAAA;AAEvD;;QAGA,MAAMC,WAAWC,0BAAmB,CAAA;QAClCC,KAAOV,EAAAA,SAAAA;AACPW,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAOlB,GAAAA,SAAAA,CAAUmB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QAC3B,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAUW,CAAAA,CAAAA,QAAQ,CAACH,YAAAA,CAAAA;AACtE,KAAA,CAAA;IAEA,MAAMI,YAAAA,GAAeC,cAAOrB,CAAAA,SAAAA,CAAAA,GAAa,CAACQ,QAAQ,CAACM,IAAK,CAAA,GAAGN,QAAQ,CAACM,IAAK,CAAA;;AAGzE,IAAA,MAAMQ,cAAiBrB,GAAAA,eAAAA,CAAgBc,IAAI,CACzC,CAACQ,MAAAA,GAAWf,QAAQ,CAACe,MAAOT,CAAAA,IAAI,CAAC,GAAGS,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAChBA,GAAAA,cAAAA,CAAeI,IAAI,GACnBtB,kBAAAA,CAAmBgB,cAAcN,IAAM,EAAA;QAAEa,OAAS,EAAA;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACEC,cAACC,CAAAA,MAAAA,EAAAA;QACCC,GAAK3B,EAAAA,YAAAA;AACL4B,QAAAA,QAAAA,EAAU/B,UAAUgC,WAAW,EAAA;QAC/BC,IAAK,EAAA,MAAA;QACLC,KAAO,EAAA,CAAC,EAAE7B,UAAWL,CAAAA,SAAAA,CAAAA,CAAW,CAAC,EAAEM,UAAAA,CAAWN,WAAW,CAAC;AACzD,QAAA,GAAGE,SAAS;AAEZuB,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}
@@ -0,0 +1,55 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { intervalToDuration, isPast } from 'date-fns';
4
+ import { useIntl } from 'react-intl';
5
+
6
+ const intervals = [
7
+ 'years',
8
+ 'months',
9
+ 'days',
10
+ 'hours',
11
+ 'minutes',
12
+ 'seconds'
13
+ ];
14
+ /**
15
+ * Displays the relative time between a given timestamp and the current time.
16
+ * You can display a custom message for given time intervals by passing an array of custom intervals.
17
+ *
18
+ * @example
19
+ * ```jsx
20
+ * <caption>Display "last hour" if the timestamp is less than an hour ago</caption>
21
+ * <RelativeTime
22
+ * timestamp={new Date('2021-01-01')}
23
+ * customIntervals={[
24
+ * { unit: 'hours', threshold: 1, text: 'last hour' },
25
+ * ]}
26
+ * ```
27
+ */ const RelativeTime = /*#__PURE__*/ React.forwardRef(({ timestamp, customIntervals = [], ...restProps }, forwardedRef)=>{
28
+ const { formatRelativeTime, formatDate, formatTime } = useIntl();
29
+ /**
30
+ * TODO: make this auto-update, like a clock.
31
+ */ const interval = intervalToDuration({
32
+ start: timestamp,
33
+ end: Date.now()
34
+ });
35
+ const unit = intervals.find((intervalUnit)=>{
36
+ return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
37
+ });
38
+ const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
39
+ // Display custom text if interval is less than the threshold
40
+ const customInterval = customIntervals.find((custom)=>interval[custom.unit] < custom.threshold);
41
+ const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, {
42
+ numeric: 'auto'
43
+ });
44
+ return /*#__PURE__*/ jsx("time", {
45
+ ref: forwardedRef,
46
+ dateTime: timestamp.toISOString(),
47
+ role: "time",
48
+ title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
49
+ ...restProps,
50
+ children: displayText
51
+ });
52
+ });
53
+
54
+ export { RelativeTime };
55
+ //# sourceMappingURL=RelativeTime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelativeTime.mjs","sources":["../../../admin/src/components/RelativeTime.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Duration, intervalToDuration, isPast } from 'date-fns';\nimport { useIntl } from 'react-intl';\n\nconst intervals: Array<keyof Duration> = ['years', 'months', 'days', 'hours', 'minutes', 'seconds'];\n\ninterface CustomInterval {\n unit: keyof Duration;\n text: string;\n threshold: number;\n}\n\ninterface RelativeTimeProps extends React.ComponentPropsWithoutRef<'time'> {\n timestamp: Date;\n customIntervals?: CustomInterval[];\n}\n\n/**\n * Displays the relative time between a given timestamp and the current time.\n * You can display a custom message for given time intervals by passing an array of custom intervals.\n *\n * @example\n * ```jsx\n * <caption>Display \"last hour\" if the timestamp is less than an hour ago</caption>\n * <RelativeTime\n * timestamp={new Date('2021-01-01')}\n * customIntervals={[\n * { unit: 'hours', threshold: 1, text: 'last hour' },\n * ]}\n * ```\n */\nconst RelativeTime = React.forwardRef<HTMLTimeElement, RelativeTimeProps>(\n ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {\n const { formatRelativeTime, formatDate, formatTime } = useIntl();\n\n /**\n * TODO: make this auto-update, like a clock.\n */\n const interval = intervalToDuration({\n start: timestamp,\n end: Date.now(),\n // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.\n }) as Required<Duration>;\n\n const unit = intervals.find((intervalUnit) => {\n return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);\n })!;\n\n const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];\n\n // Display custom text if interval is less than the threshold\n const customInterval = customIntervals.find(\n (custom) => interval[custom.unit] < custom.threshold\n );\n\n const displayText = customInterval\n ? customInterval.text\n : formatRelativeTime(relativeTime, unit, { numeric: 'auto' });\n\n return (\n <time\n ref={forwardedRef}\n dateTime={timestamp.toISOString()}\n role=\"time\"\n title={`${formatDate(timestamp)} ${formatTime(timestamp)}`}\n {...restProps}\n >\n {displayText}\n </time>\n );\n }\n);\n\nexport { RelativeTime };\nexport type { CustomInterval, RelativeTimeProps };\n"],"names":["intervals","RelativeTime","React","forwardRef","timestamp","customIntervals","restProps","forwardedRef","formatRelativeTime","formatDate","formatTime","useIntl","interval","intervalToDuration","start","end","Date","now","unit","find","intervalUnit","Object","keys","includes","relativeTime","isPast","customInterval","custom","threshold","displayText","text","numeric","_jsx","time","ref","dateTime","toISOString","role","title"],"mappings":";;;;;AAKA,MAAMA,SAAmC,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,MAAA;AAAQ,IAAA,OAAA;AAAS,IAAA,SAAA;AAAW,IAAA;AAAU,CAAA;AAanG;;;;;;;;;;;;;AAaC,IACKC,MAAAA,YAAAA,iBAAeC,KAAMC,CAAAA,UAAU,CACnC,CAAC,EAAEC,SAAS,EAAEC,eAAkB,GAAA,EAAE,EAAE,GAAGC,WAAW,EAAEC,YAAAA,GAAAA;AAClD,IAAA,MAAM,EAAEC,kBAAkB,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGC,OAAAA,EAAAA;AAEvD;;QAGA,MAAMC,WAAWC,kBAAmB,CAAA;QAClCC,KAAOV,EAAAA,SAAAA;AACPW,QAAAA,GAAAA,EAAKC,KAAKC,GAAG;AAEf,KAAA,CAAA;AAEA,IAAA,MAAMC,IAAOlB,GAAAA,SAAAA,CAAUmB,IAAI,CAAC,CAACC,YAAAA,GAAAA;QAC3B,OAAOR,QAAQ,CAACQ,YAAAA,CAAa,GAAG,CAAA,IAAKC,OAAOC,IAAI,CAACV,QAAUW,CAAAA,CAAAA,QAAQ,CAACH,YAAAA,CAAAA;AACtE,KAAA,CAAA;IAEA,MAAMI,YAAAA,GAAeC,MAAOrB,CAAAA,SAAAA,CAAAA,GAAa,CAACQ,QAAQ,CAACM,IAAK,CAAA,GAAGN,QAAQ,CAACM,IAAK,CAAA;;AAGzE,IAAA,MAAMQ,cAAiBrB,GAAAA,eAAAA,CAAgBc,IAAI,CACzC,CAACQ,MAAAA,GAAWf,QAAQ,CAACe,MAAOT,CAAAA,IAAI,CAAC,GAAGS,OAAOC,SAAS,CAAA;AAGtD,IAAA,MAAMC,cAAcH,cAChBA,GAAAA,cAAAA,CAAeI,IAAI,GACnBtB,kBAAAA,CAAmBgB,cAAcN,IAAM,EAAA;QAAEa,OAAS,EAAA;AAAO,KAAA,CAAA;AAE7D,IAAA,qBACEC,GAACC,CAAAA,MAAAA,EAAAA;QACCC,GAAK3B,EAAAA,YAAAA;AACL4B,QAAAA,QAAAA,EAAU/B,UAAUgC,WAAW,EAAA;QAC/BC,IAAK,EAAA,MAAA;QACLC,KAAO,EAAA,CAAC,EAAE7B,UAAWL,CAAAA,SAAAA,CAAAA,CAAW,CAAC,EAAEM,UAAAA,CAAWN,WAAW,CAAC;AACzD,QAAA,GAAGE,SAAS;AAEZuB,QAAAA,QAAAA,EAAAA;;AAGP,CAAA;;;;"}