@strapi/content-releases 0.0.0-next.f5312617ca16b870c2bf1adcea2c69b676979e29 → 0.0.0-next.f5d21551ed005f524bfc4760b274f1be154e26a8

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 (321) 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 +310 -0
  10. package/dist/admin/components/EntryValidationPopover.js.map +1 -0
  11. package/dist/admin/components/EntryValidationPopover.mjs +308 -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 +203 -0
  18. package/dist/admin/components/ReleaseAction.js.map +1 -0
  19. package/dist/admin/components/ReleaseAction.mjs +201 -0
  20. package/dist/admin/components/ReleaseAction.mjs.map +1 -0
  21. package/dist/admin/components/ReleaseActionMenu.js +194 -0
  22. package/dist/admin/components/ReleaseActionMenu.js.map +1 -0
  23. package/dist/admin/components/ReleaseActionMenu.mjs +173 -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/components/Widgets.js +122 -0
  46. package/dist/admin/components/Widgets.js.map +1 -0
  47. package/dist/admin/components/Widgets.mjs +120 -0
  48. package/dist/admin/components/Widgets.mjs.map +1 -0
  49. package/dist/admin/constants.js +79 -0
  50. package/dist/admin/constants.js.map +1 -0
  51. package/dist/admin/constants.mjs +76 -0
  52. package/dist/admin/constants.mjs.map +1 -0
  53. package/dist/admin/index.js +148 -4
  54. package/dist/admin/index.js.map +1 -1
  55. package/dist/admin/index.mjs +143 -4
  56. package/dist/admin/index.mjs.map +1 -1
  57. package/dist/admin/modules/hooks.js +8 -0
  58. package/dist/admin/modules/hooks.js.map +1 -0
  59. package/dist/admin/modules/hooks.mjs +6 -0
  60. package/dist/admin/modules/hooks.mjs.map +1 -0
  61. package/dist/admin/pages/App.js +29 -0
  62. package/dist/admin/pages/App.js.map +1 -0
  63. package/dist/admin/pages/App.mjs +27 -0
  64. package/dist/admin/pages/App.mjs.map +1 -0
  65. package/dist/admin/pages/PurchaseContentReleases.js +192 -0
  66. package/dist/admin/pages/PurchaseContentReleases.js.map +1 -0
  67. package/dist/admin/pages/PurchaseContentReleases.mjs +190 -0
  68. package/dist/admin/pages/PurchaseContentReleases.mjs.map +1 -0
  69. package/dist/admin/pages/ReleaseDetailsPage.js +772 -0
  70. package/dist/admin/pages/ReleaseDetailsPage.js.map +1 -0
  71. package/dist/admin/pages/ReleaseDetailsPage.mjs +751 -0
  72. package/dist/admin/pages/ReleaseDetailsPage.mjs.map +1 -0
  73. package/dist/admin/pages/ReleasesPage.js +403 -0
  74. package/dist/admin/pages/ReleasesPage.js.map +1 -0
  75. package/dist/admin/pages/ReleasesPage.mjs +381 -0
  76. package/dist/admin/pages/ReleasesPage.mjs.map +1 -0
  77. package/dist/admin/pages/ReleasesSettingsPage.js +225 -0
  78. package/dist/admin/pages/ReleasesSettingsPage.js.map +1 -0
  79. package/dist/admin/pages/ReleasesSettingsPage.mjs +223 -0
  80. package/dist/admin/pages/ReleasesSettingsPage.mjs.map +1 -0
  81. package/dist/admin/pluginId.js +6 -0
  82. package/dist/admin/pluginId.js.map +1 -0
  83. package/dist/admin/pluginId.mjs +4 -0
  84. package/dist/admin/pluginId.mjs.map +1 -0
  85. package/dist/admin/services/homepage.js +24 -0
  86. package/dist/admin/services/homepage.js.map +1 -0
  87. package/dist/admin/services/homepage.mjs +22 -0
  88. package/dist/admin/services/homepage.mjs.map +1 -0
  89. package/dist/admin/services/release.js +474 -0
  90. package/dist/admin/services/release.js.map +1 -0
  91. package/dist/admin/services/release.mjs +457 -0
  92. package/dist/admin/services/release.mjs.map +1 -0
  93. package/dist/admin/src/components/EntryValidationPopover.d.ts +13 -0
  94. package/dist/admin/src/components/ReleaseListCell.d.ts +1 -1
  95. package/dist/admin/src/components/Widgets.d.ts +2 -0
  96. package/dist/admin/src/constants.d.ts +1 -0
  97. package/dist/admin/src/services/homepage.d.ts +9 -0
  98. package/dist/admin/src/services/release.d.ts +28 -28
  99. package/dist/admin/store/hooks.js +8 -0
  100. package/dist/admin/store/hooks.js.map +1 -0
  101. package/dist/admin/store/hooks.mjs +6 -0
  102. package/dist/admin/store/hooks.mjs.map +1 -0
  103. package/dist/admin/translations/en.json.js +111 -0
  104. package/dist/admin/translations/en.json.js.map +1 -0
  105. package/dist/admin/translations/en.json.mjs +109 -0
  106. package/dist/admin/translations/en.json.mjs.map +1 -0
  107. package/dist/admin/translations/uk.json.js +103 -0
  108. package/dist/admin/translations/uk.json.js.map +1 -0
  109. package/dist/admin/translations/uk.json.mjs +101 -0
  110. package/dist/admin/translations/uk.json.mjs.map +1 -0
  111. package/dist/admin/utils/api.js +8 -0
  112. package/dist/admin/utils/api.js.map +1 -0
  113. package/dist/admin/utils/api.mjs +6 -0
  114. package/dist/admin/utils/api.mjs.map +1 -0
  115. package/dist/admin/utils/prefixPluginTranslations.js +11 -0
  116. package/dist/admin/utils/prefixPluginTranslations.js.map +1 -0
  117. package/dist/admin/utils/prefixPluginTranslations.mjs +9 -0
  118. package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -0
  119. package/dist/admin/utils/time.js +42 -0
  120. package/dist/admin/utils/time.js.map +1 -0
  121. package/dist/admin/utils/time.mjs +39 -0
  122. package/dist/admin/utils/time.mjs.map +1 -0
  123. package/dist/admin/validation/schemas.js +65 -0
  124. package/dist/admin/validation/schemas.js.map +1 -0
  125. package/dist/admin/validation/schemas.mjs +43 -0
  126. package/dist/admin/validation/schemas.mjs.map +1 -0
  127. package/dist/server/bootstrap.js +68 -0
  128. package/dist/server/bootstrap.js.map +1 -0
  129. package/dist/server/bootstrap.mjs +66 -0
  130. package/dist/server/bootstrap.mjs.map +1 -0
  131. package/dist/server/constants.js +74 -0
  132. package/dist/server/constants.js.map +1 -0
  133. package/dist/server/constants.mjs +69 -0
  134. package/dist/server/constants.mjs.map +1 -0
  135. package/dist/server/content-types/index.js +12 -0
  136. package/dist/server/content-types/index.js.map +1 -0
  137. package/dist/server/content-types/index.mjs +10 -0
  138. package/dist/server/content-types/index.mjs.map +1 -0
  139. package/dist/server/content-types/release/index.js +10 -0
  140. package/dist/server/content-types/release/index.js.map +1 -0
  141. package/dist/server/content-types/release/index.mjs +8 -0
  142. package/dist/server/content-types/release/index.mjs.map +1 -0
  143. package/dist/server/content-types/release/schema.js +58 -0
  144. package/dist/server/content-types/release/schema.js.map +1 -0
  145. package/dist/server/content-types/release/schema.mjs +56 -0
  146. package/dist/server/content-types/release/schema.mjs.map +1 -0
  147. package/dist/server/content-types/release-action/index.js +10 -0
  148. package/dist/server/content-types/release-action/index.js.map +1 -0
  149. package/dist/server/content-types/release-action/index.mjs +8 -0
  150. package/dist/server/content-types/release-action/index.mjs.map +1 -0
  151. package/dist/server/content-types/release-action/schema.js +55 -0
  152. package/dist/server/content-types/release-action/schema.js.map +1 -0
  153. package/dist/server/content-types/release-action/schema.mjs +53 -0
  154. package/dist/server/content-types/release-action/schema.mjs.map +1 -0
  155. package/dist/server/controllers/homepage.js +15 -0
  156. package/dist/server/controllers/homepage.js.map +1 -0
  157. package/dist/server/controllers/homepage.mjs +13 -0
  158. package/dist/server/controllers/homepage.mjs.map +1 -0
  159. package/dist/server/controllers/index.js +16 -0
  160. package/dist/server/controllers/index.js.map +1 -0
  161. package/dist/server/controllers/index.mjs +14 -0
  162. package/dist/server/controllers/index.mjs.map +1 -0
  163. package/dist/server/controllers/release-action.js +150 -0
  164. package/dist/server/controllers/release-action.js.map +1 -0
  165. package/dist/server/controllers/release-action.mjs +148 -0
  166. package/dist/server/controllers/release-action.mjs.map +1 -0
  167. package/dist/server/controllers/release.js +302 -0
  168. package/dist/server/controllers/release.js.map +1 -0
  169. package/dist/server/controllers/release.mjs +300 -0
  170. package/dist/server/controllers/release.mjs.map +1 -0
  171. package/dist/server/controllers/settings.js +37 -0
  172. package/dist/server/controllers/settings.js.map +1 -0
  173. package/dist/server/controllers/settings.mjs +35 -0
  174. package/dist/server/controllers/settings.mjs.map +1 -0
  175. package/dist/server/controllers/validation/release-action.js +34 -0
  176. package/dist/server/controllers/validation/release-action.js.map +1 -0
  177. package/dist/server/controllers/validation/release-action.mjs +30 -0
  178. package/dist/server/controllers/validation/release-action.mjs.map +1 -0
  179. package/dist/server/controllers/validation/release.js +26 -0
  180. package/dist/server/controllers/validation/release.js.map +1 -0
  181. package/dist/server/controllers/validation/release.mjs +22 -0
  182. package/dist/server/controllers/validation/release.mjs.map +1 -0
  183. package/dist/server/controllers/validation/settings.js +32 -0
  184. package/dist/server/controllers/validation/settings.js.map +1 -0
  185. package/dist/server/controllers/validation/settings.mjs +10 -0
  186. package/dist/server/controllers/validation/settings.mjs.map +1 -0
  187. package/dist/server/destroy.js +15 -0
  188. package/dist/server/destroy.js.map +1 -0
  189. package/dist/server/destroy.mjs +13 -0
  190. package/dist/server/destroy.mjs.map +1 -0
  191. package/dist/server/index.js +25 -1984
  192. package/dist/server/index.js.map +1 -1
  193. package/dist/server/index.mjs +24 -1964
  194. package/dist/server/index.mjs.map +1 -1
  195. package/dist/server/middlewares/documents.js +104 -0
  196. package/dist/server/middlewares/documents.js.map +1 -0
  197. package/dist/server/middlewares/documents.mjs +101 -0
  198. package/dist/server/middlewares/documents.mjs.map +1 -0
  199. package/dist/server/migrations/database/5.0.0-document-id-in-actions.js +51 -0
  200. package/dist/server/migrations/database/5.0.0-document-id-in-actions.js.map +1 -0
  201. package/dist/server/migrations/database/5.0.0-document-id-in-actions.mjs +49 -0
  202. package/dist/server/migrations/database/5.0.0-document-id-in-actions.mjs.map +1 -0
  203. package/dist/server/migrations/index.js +205 -0
  204. package/dist/server/migrations/index.js.map +1 -0
  205. package/dist/server/migrations/index.mjs +198 -0
  206. package/dist/server/migrations/index.mjs.map +1 -0
  207. package/dist/server/register.js +23 -0
  208. package/dist/server/register.js.map +1 -0
  209. package/dist/server/register.mjs +21 -0
  210. package/dist/server/register.mjs.map +1 -0
  211. package/dist/server/routes/homepage.js +25 -0
  212. package/dist/server/routes/homepage.js.map +1 -0
  213. package/dist/server/routes/homepage.mjs +23 -0
  214. package/dist/server/routes/homepage.mjs.map +1 -0
  215. package/dist/server/routes/index.js +16 -0
  216. package/dist/server/routes/index.js.map +1 -0
  217. package/dist/server/routes/index.mjs +14 -0
  218. package/dist/server/routes/index.mjs.map +1 -0
  219. package/dist/server/routes/release-action.js +100 -0
  220. package/dist/server/routes/release-action.js.map +1 -0
  221. package/dist/server/routes/release-action.mjs +98 -0
  222. package/dist/server/routes/release-action.mjs.map +1 -0
  223. package/dist/server/routes/release.js +154 -0
  224. package/dist/server/routes/release.js.map +1 -0
  225. package/dist/server/routes/release.mjs +152 -0
  226. package/dist/server/routes/release.mjs.map +1 -0
  227. package/dist/server/routes/settings.js +46 -0
  228. package/dist/server/routes/settings.js.map +1 -0
  229. package/dist/server/routes/settings.mjs +44 -0
  230. package/dist/server/routes/settings.mjs.map +1 -0
  231. package/dist/server/services/homepage.js +26 -0
  232. package/dist/server/services/homepage.js.map +1 -0
  233. package/dist/server/services/homepage.mjs +24 -0
  234. package/dist/server/services/homepage.mjs.map +1 -0
  235. package/dist/server/services/index.js +20 -0
  236. package/dist/server/services/index.js.map +1 -0
  237. package/dist/server/services/index.mjs +18 -0
  238. package/dist/server/services/index.mjs.map +1 -0
  239. package/dist/server/services/release-action.js +324 -0
  240. package/dist/server/services/release-action.js.map +1 -0
  241. package/dist/server/services/release-action.mjs +322 -0
  242. package/dist/server/services/release-action.mjs.map +1 -0
  243. package/dist/server/services/release.js +324 -0
  244. package/dist/server/services/release.js.map +1 -0
  245. package/dist/server/services/release.mjs +322 -0
  246. package/dist/server/services/release.mjs.map +1 -0
  247. package/dist/server/services/scheduling.js +74 -0
  248. package/dist/server/services/scheduling.js.map +1 -0
  249. package/dist/server/services/scheduling.mjs +72 -0
  250. package/dist/server/services/scheduling.mjs.map +1 -0
  251. package/dist/server/services/settings.js +34 -0
  252. package/dist/server/services/settings.js.map +1 -0
  253. package/dist/server/services/settings.mjs +32 -0
  254. package/dist/server/services/settings.mjs.map +1 -0
  255. package/dist/server/services/validation.js +91 -0
  256. package/dist/server/services/validation.js.map +1 -0
  257. package/dist/server/services/validation.mjs +86 -0
  258. package/dist/server/services/validation.mjs.map +1 -0
  259. package/dist/server/src/controllers/homepage.d.ts +6 -0
  260. package/dist/server/src/controllers/homepage.d.ts.map +1 -0
  261. package/dist/server/src/controllers/index.d.ts +3 -0
  262. package/dist/server/src/controllers/index.d.ts.map +1 -1
  263. package/dist/server/src/destroy.d.ts +1 -1
  264. package/dist/server/src/destroy.d.ts.map +1 -1
  265. package/dist/server/src/index.d.ts +15 -10
  266. package/dist/server/src/index.d.ts.map +1 -1
  267. package/dist/server/src/middlewares/documents.d.ts +1 -1
  268. package/dist/server/src/middlewares/documents.d.ts.map +1 -1
  269. package/dist/server/src/routes/homepage.d.ts +4 -0
  270. package/dist/server/src/routes/homepage.d.ts.map +1 -0
  271. package/dist/server/src/routes/index.d.ts +1 -0
  272. package/dist/server/src/routes/index.d.ts.map +1 -1
  273. package/dist/server/src/services/homepage.d.ts +9 -0
  274. package/dist/server/src/services/homepage.d.ts.map +1 -0
  275. package/dist/server/src/services/index.d.ts +11 -10
  276. package/dist/server/src/services/index.d.ts.map +1 -1
  277. package/dist/server/src/services/release-action.d.ts +3 -7
  278. package/dist/server/src/services/release-action.d.ts.map +1 -1
  279. package/dist/server/src/services/scheduling.d.ts +5 -6
  280. package/dist/server/src/services/scheduling.d.ts.map +1 -1
  281. package/dist/server/src/services/validation.d.ts +1 -1
  282. package/dist/server/src/services/validation.d.ts.map +1 -1
  283. package/dist/server/src/utils/index.d.ts.map +1 -1
  284. package/dist/server/utils/index.js +94 -0
  285. package/dist/server/utils/index.js.map +1 -0
  286. package/dist/server/utils/index.mjs +88 -0
  287. package/dist/server/utils/index.mjs.map +1 -0
  288. package/dist/shared/contracts/homepage.d.ts +11 -0
  289. package/dist/shared/contracts/homepage.d.ts.map +1 -0
  290. package/dist/shared/contracts/release-actions.d.ts +8 -2
  291. package/dist/shared/contracts/release-actions.d.ts.map +1 -1
  292. package/dist/shared/contracts/releases.d.ts +0 -1
  293. package/dist/shared/contracts/settings.d.ts +1 -2
  294. package/dist/shared/contracts/settings.d.ts.map +1 -1
  295. package/dist/shared/types.d.ts +1 -1
  296. package/dist/shared/types.d.ts.map +1 -1
  297. package/package.json +19 -17
  298. package/dist/_chunks/App-BKB1esYS.js +0 -1395
  299. package/dist/_chunks/App-BKB1esYS.js.map +0 -1
  300. package/dist/_chunks/App-Cne--1Z8.mjs +0 -1374
  301. package/dist/_chunks/App-Cne--1Z8.mjs.map +0 -1
  302. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js +0 -52
  303. package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +0 -1
  304. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs +0 -52
  305. package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +0 -1
  306. package/dist/_chunks/ReleasesSettingsPage-C1WwGWIH.mjs +0 -178
  307. package/dist/_chunks/ReleasesSettingsPage-C1WwGWIH.mjs.map +0 -1
  308. package/dist/_chunks/ReleasesSettingsPage-kuXIwpWp.js +0 -178
  309. package/dist/_chunks/ReleasesSettingsPage-kuXIwpWp.js.map +0 -1
  310. package/dist/_chunks/en-CmYoEnA7.js +0 -93
  311. package/dist/_chunks/en-CmYoEnA7.js.map +0 -1
  312. package/dist/_chunks/en-D0yVZFqf.mjs +0 -93
  313. package/dist/_chunks/en-D0yVZFqf.mjs.map +0 -1
  314. package/dist/_chunks/index-5Odi61vw.js +0 -1381
  315. package/dist/_chunks/index-5Odi61vw.js.map +0 -1
  316. package/dist/_chunks/index-Cy7qwpaU.mjs +0 -1362
  317. package/dist/_chunks/index-Cy7qwpaU.mjs.map +0 -1
  318. package/dist/_chunks/schemas-BE1LxE9J.js +0 -62
  319. package/dist/_chunks/schemas-BE1LxE9J.js.map +0 -1
  320. package/dist/_chunks/schemas-DdA2ic2U.mjs +0 -44
  321. package/dist/_chunks/schemas-DdA2ic2U.mjs.map +0 -1
@@ -1,1374 +0,0 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { useNotification, useAPIErrorHandler, useQueryParams, useTracking, useRBAC, Page, Layouts, Pagination, isFetchError, ConfirmDialog, BackButton, useStrapiApp, Table } from "@strapi/admin/strapi-admin";
3
- import { useLocation, useNavigate, NavLink, useParams, Navigate, Link as Link$1, Routes, Route } from "react-router-dom";
4
- import { g as getTimezones, p as pluginId, u as useGetReleasesQuery, a as useGetReleaseSettingsQuery, b as useCreateReleaseMutation, P as PERMISSIONS, c as useGetReleaseQuery, d as useUpdateReleaseMutation, e as useDeleteReleaseMutation, f as usePublishReleaseMutation, h as getTimezoneOffset, i as useGetReleaseActionsQuery, j as useUpdateReleaseActionMutation, R as ReleaseActionOptions, k as ReleaseActionMenu, r as releaseApi } from "./index-Cy7qwpaU.mjs";
5
- import * as React from "react";
6
- import { unstable_useDocument } from "@strapi/content-manager/strapi-admin";
7
- import { Modal, Flex, Field, TextInput, Box, Checkbox, Typography, DatePicker, TimePicker, Button, Combobox, ComboboxOption, Link, Alert, Main, Tabs, Divider, EmptyStateLayout, Grid, Badge, MenuItem, SimpleMenu, Dialog, LinkButton, SingleSelect, SingleSelectOption, Tr, Td, Tooltip } from "@strapi/design-system";
8
- import { Plus, Pencil, Trash, More, CrossCircle, CheckCircle, ArrowsCounterClockwise } from "@strapi/icons";
9
- import { EmptyDocuments } from "@strapi/icons/symbols";
10
- import format$1 from "date-fns/format";
11
- import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";
12
- import { useIntl } from "react-intl";
13
- import { styled } from "styled-components";
14
- import { intervalToDuration, isPast, formatISO, format } from "date-fns";
15
- import { Formik, Form, useFormikContext } from "formik";
16
- import { R as RELEASE_SCHEMA } from "./schemas-DdA2ic2U.mjs";
17
- import { useDispatch } from "react-redux";
18
- import { useLicenseLimits } from "@strapi/admin/strapi-admin/ee";
19
- const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
20
- const RelativeTime$1 = React.forwardRef(
21
- ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
22
- const { formatRelativeTime, formatDate, formatTime } = useIntl();
23
- const interval = intervalToDuration({
24
- start: timestamp,
25
- end: Date.now()
26
- // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
27
- });
28
- const unit = intervals.find((intervalUnit) => {
29
- return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
30
- });
31
- const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
32
- const customInterval = customIntervals.find(
33
- (custom) => interval[custom.unit] < custom.threshold
34
- );
35
- const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
36
- return /* @__PURE__ */ jsx(
37
- "time",
38
- {
39
- ref: forwardedRef,
40
- dateTime: timestamp.toISOString(),
41
- role: "time",
42
- title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
43
- ...restProps,
44
- children: displayText
45
- }
46
- );
47
- }
48
- );
49
- const ReleaseModal = ({
50
- handleClose,
51
- open,
52
- handleSubmit,
53
- initialValues,
54
- isLoading = false
55
- }) => {
56
- const { formatMessage } = useIntl();
57
- const { pathname } = useLocation();
58
- const isCreatingRelease = pathname === `/plugins/${pluginId}`;
59
- const { timezoneList, systemTimezone = { value: "UTC+00:00-Africa/Abidjan " } } = getTimezones(
60
- initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : /* @__PURE__ */ new Date()
61
- );
62
- const getScheduledTimestamp = (values) => {
63
- const { date, time, timezone } = values;
64
- if (!date || !time || !timezone)
65
- return null;
66
- const timezoneWithoutOffset = timezone.split("&")[1];
67
- return zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);
68
- };
69
- const getTimezoneWithOffset = () => {
70
- const currentTimezone = timezoneList.find(
71
- (timezone) => timezone.value.split("&")[1] === initialValues.timezone
72
- );
73
- return currentTimezone?.value || systemTimezone.value;
74
- };
75
- return /* @__PURE__ */ jsx(Modal.Root, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
76
- /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: formatMessage(
77
- {
78
- id: "content-releases.modal.title",
79
- defaultMessage: "{isCreatingRelease, select, true {New release} other {Edit release}}"
80
- },
81
- { isCreatingRelease }
82
- ) }) }),
83
- /* @__PURE__ */ jsx(
84
- Formik,
85
- {
86
- onSubmit: (values) => {
87
- handleSubmit({
88
- ...values,
89
- timezone: values.timezone ? values.timezone.split("&")[1] : null,
90
- scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
91
- });
92
- },
93
- initialValues: {
94
- ...initialValues,
95
- timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
96
- },
97
- validationSchema: RELEASE_SCHEMA,
98
- validateOnChange: false,
99
- children: ({ values, errors, handleChange, setFieldValue }) => {
100
- return /* @__PURE__ */ jsxs(Form, { children: [
101
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
102
- /* @__PURE__ */ jsxs(
103
- Field.Root,
104
- {
105
- name: "name",
106
- error: errors.name && formatMessage({ id: errors.name, defaultMessage: errors.name }),
107
- required: true,
108
- children: [
109
- /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
110
- id: "content-releases.modal.form.input.label.release-name",
111
- defaultMessage: "Name"
112
- }) }),
113
- /* @__PURE__ */ jsx(TextInput, { value: values.name, onChange: handleChange }),
114
- /* @__PURE__ */ jsx(Field.Error, {})
115
- ]
116
- }
117
- ),
118
- /* @__PURE__ */ jsx(Box, { width: "max-content", children: /* @__PURE__ */ jsx(
119
- Checkbox,
120
- {
121
- name: "isScheduled",
122
- checked: values.isScheduled,
123
- onCheckedChange: (checked) => {
124
- setFieldValue("isScheduled", checked);
125
- if (!checked) {
126
- setFieldValue("date", null);
127
- setFieldValue("time", "");
128
- setFieldValue("timezone", null);
129
- } else {
130
- setFieldValue("date", initialValues.date);
131
- setFieldValue("time", initialValues.time);
132
- setFieldValue(
133
- "timezone",
134
- initialValues.timezone ?? systemTimezone?.value
135
- );
136
- }
137
- },
138
- children: /* @__PURE__ */ jsx(
139
- Typography,
140
- {
141
- textColor: values.isScheduled ? "primary600" : "neutral800",
142
- fontWeight: values.isScheduled ? "semiBold" : "regular",
143
- children: formatMessage({
144
- id: "modal.form.input.label.schedule-release",
145
- defaultMessage: "Schedule release"
146
- })
147
- }
148
- )
149
- }
150
- ) }),
151
- values.isScheduled && /* @__PURE__ */ jsxs(Fragment, { children: [
152
- /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "start", children: [
153
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
154
- Field.Root,
155
- {
156
- name: "date",
157
- error: errors.date && formatMessage({ id: errors.date, defaultMessage: errors.date }),
158
- required: true,
159
- children: [
160
- /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
161
- id: "content-releases.modal.form.input.label.date",
162
- defaultMessage: "Date"
163
- }) }),
164
- /* @__PURE__ */ jsx(
165
- DatePicker,
166
- {
167
- onChange: (date) => {
168
- const isoFormatDate = date ? formatISO(date, { representation: "date" }) : null;
169
- setFieldValue("date", isoFormatDate);
170
- },
171
- clearLabel: formatMessage({
172
- id: "content-releases.modal.form.input.clearLabel",
173
- defaultMessage: "Clear"
174
- }),
175
- onClear: () => {
176
- setFieldValue("date", null);
177
- },
178
- value: values.date ? new Date(values.date) : /* @__PURE__ */ new Date(),
179
- minDate: utcToZonedTime(/* @__PURE__ */ new Date(), values.timezone.split("&")[1])
180
- }
181
- ),
182
- /* @__PURE__ */ jsx(Field.Error, {})
183
- ]
184
- }
185
- ) }),
186
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsxs(
187
- Field.Root,
188
- {
189
- name: "time",
190
- error: errors.time && formatMessage({ id: errors.time, defaultMessage: errors.time }),
191
- required: true,
192
- children: [
193
- /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
194
- id: "content-releases.modal.form.input.label.time",
195
- defaultMessage: "Time"
196
- }) }),
197
- /* @__PURE__ */ jsx(
198
- TimePicker,
199
- {
200
- onChange: (time) => {
201
- setFieldValue("time", time);
202
- },
203
- clearLabel: formatMessage({
204
- id: "content-releases.modal.form.input.clearLabel",
205
- defaultMessage: "Clear"
206
- }),
207
- onClear: () => {
208
- setFieldValue("time", "");
209
- },
210
- value: values.time || void 0
211
- }
212
- ),
213
- /* @__PURE__ */ jsx(Field.Error, {})
214
- ]
215
- }
216
- ) })
217
- ] }),
218
- /* @__PURE__ */ jsx(TimezoneComponent, { timezoneOptions: timezoneList })
219
- ] })
220
- ] }) }),
221
- /* @__PURE__ */ jsxs(Modal.Footer, { children: [
222
- /* @__PURE__ */ jsx(Modal.Close, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", name: "cancel", children: formatMessage({ id: "cancel", defaultMessage: "Cancel" }) }) }),
223
- /* @__PURE__ */ jsx(Button, { name: "submit", loading: isLoading, type: "submit", children: formatMessage(
224
- {
225
- id: "content-releases.modal.form.button.submit",
226
- defaultMessage: "{isCreatingRelease, select, true {Continue} other {Save}}"
227
- },
228
- { isCreatingRelease }
229
- ) })
230
- ] })
231
- ] });
232
- }
233
- }
234
- )
235
- ] }) });
236
- };
237
- const TimezoneComponent = ({ timezoneOptions }) => {
238
- const { values, errors, setFieldValue } = useFormikContext();
239
- const { formatMessage } = useIntl();
240
- const [timezoneList, setTimezoneList] = React.useState(timezoneOptions);
241
- React.useEffect(() => {
242
- if (values.date) {
243
- const { timezoneList: timezoneList2 } = getTimezones(new Date(values.date));
244
- setTimezoneList(timezoneList2);
245
- const updatedTimezone = values.timezone && timezoneList2.find((tz) => tz.value.split("&")[1] === values.timezone.split("&")[1]);
246
- if (updatedTimezone) {
247
- setFieldValue("timezone", updatedTimezone.value);
248
- }
249
- }
250
- }, [setFieldValue, values.date, values.timezone]);
251
- return /* @__PURE__ */ jsxs(
252
- Field.Root,
253
- {
254
- name: "timezone",
255
- error: errors.timezone && formatMessage({ id: errors.timezone, defaultMessage: errors.timezone }),
256
- required: true,
257
- children: [
258
- /* @__PURE__ */ jsx(Field.Label, { children: formatMessage({
259
- id: "content-releases.modal.form.input.label.timezone",
260
- defaultMessage: "Timezone"
261
- }) }),
262
- /* @__PURE__ */ jsx(
263
- Combobox,
264
- {
265
- autocomplete: { type: "list", filter: "contains" },
266
- value: values.timezone || void 0,
267
- textValue: values.timezone ? values.timezone.replace(/&/, " ") : void 0,
268
- onChange: (timezone) => {
269
- setFieldValue("timezone", timezone);
270
- },
271
- onTextValueChange: (timezone) => {
272
- setFieldValue("timezone", timezone);
273
- },
274
- onClear: () => {
275
- setFieldValue("timezone", "");
276
- },
277
- children: timezoneList.map((timezone) => /* @__PURE__ */ jsx(ComboboxOption, { value: timezone.value, children: timezone.value.replace(/&/, " ") }, timezone.value))
278
- }
279
- ),
280
- /* @__PURE__ */ jsx(Field.Error, {})
281
- ]
282
- }
283
- );
284
- };
285
- const useTypedDispatch = useDispatch;
286
- const isBaseQueryError = (error) => {
287
- return typeof error !== "undefined" && error.name !== void 0;
288
- };
289
- const LinkCard = styled(Link)`
290
- display: block;
291
- `;
292
- const RelativeTime = styled(RelativeTime$1)`
293
- display: inline-block;
294
- &::first-letter {
295
- text-transform: uppercase;
296
- }
297
- `;
298
- const getBadgeProps = (status) => {
299
- let color;
300
- switch (status) {
301
- case "ready":
302
- color = "success";
303
- break;
304
- case "blocked":
305
- color = "warning";
306
- break;
307
- case "failed":
308
- color = "danger";
309
- break;
310
- case "done":
311
- color = "primary";
312
- break;
313
- case "empty":
314
- default:
315
- color = "neutral";
316
- }
317
- return {
318
- textColor: `${color}600`,
319
- backgroundColor: `${color}100`,
320
- borderColor: `${color}200`
321
- };
322
- };
323
- const ReleasesGrid = ({ sectionTitle, releases = [], isError = false }) => {
324
- const { formatMessage } = useIntl();
325
- if (isError) {
326
- return /* @__PURE__ */ jsx(Page.Error, {});
327
- }
328
- if (releases?.length === 0) {
329
- return /* @__PURE__ */ jsx(
330
- EmptyStateLayout,
331
- {
332
- content: formatMessage(
333
- {
334
- id: "content-releases.page.Releases.tab.emptyEntries",
335
- defaultMessage: "No releases"
336
- },
337
- {
338
- target: sectionTitle
339
- }
340
- ),
341
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" })
342
- }
343
- );
344
- }
345
- return /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: releases.map(({ id, name, scheduledAt, status }) => /* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 6, xs: 12, direction: "column", alignItems: "stretch", children: /* @__PURE__ */ jsx(LinkCard, { tag: NavLink, to: `${id}`, isExternal: false, children: /* @__PURE__ */ jsxs(
346
- Flex,
347
- {
348
- direction: "column",
349
- justifyContent: "space-between",
350
- padding: 4,
351
- hasRadius: true,
352
- background: "neutral0",
353
- shadow: "tableShadow",
354
- height: "100%",
355
- width: "100%",
356
- alignItems: "start",
357
- gap: 4,
358
- children: [
359
- /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
360
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", tag: "h3", variant: "delta", fontWeight: "bold", children: name }),
361
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: scheduledAt ? /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(scheduledAt) }) : formatMessage({
362
- id: "content-releases.pages.Releases.not-scheduled",
363
- defaultMessage: "Not scheduled"
364
- }) })
365
- ] }),
366
- /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(status), children: status })
367
- ]
368
- }
369
- ) }) }, id)) });
370
- };
371
- const StyledAlert = styled(Alert)`
372
- button {
373
- display: none;
374
- }
375
- p + div {
376
- margin-left: auto;
377
- }
378
- `;
379
- const INITIAL_FORM_VALUES = {
380
- name: "",
381
- date: format(/* @__PURE__ */ new Date(), "yyyy-MM-dd"),
382
- time: "",
383
- isScheduled: true,
384
- scheduledAt: null,
385
- timezone: null
386
- };
387
- const ReleasesPage = () => {
388
- const location = useLocation();
389
- const [releaseModalShown, setReleaseModalShown] = React.useState(false);
390
- const { toggleNotification } = useNotification();
391
- const { formatMessage } = useIntl();
392
- const navigate = useNavigate();
393
- const { formatAPIError } = useAPIErrorHandler();
394
- const [{ query }, setQuery] = useQueryParams();
395
- const response = useGetReleasesQuery(query);
396
- const { data, isLoading: isLoadingSettings } = useGetReleaseSettingsQuery();
397
- const [createRelease, { isLoading: isSubmittingForm }] = useCreateReleaseMutation();
398
- const { getFeature } = useLicenseLimits();
399
- const { maximumReleases = 3 } = getFeature("cms-content-releases");
400
- const { trackUsage } = useTracking();
401
- const {
402
- allowedActions: { canCreate }
403
- } = useRBAC(PERMISSIONS);
404
- const { isLoading: isLoadingReleases, isSuccess, isError } = response;
405
- const activeTab = response?.currentData?.meta?.activeTab || "pending";
406
- React.useEffect(() => {
407
- if (location?.state?.errors) {
408
- toggleNotification({
409
- type: "danger",
410
- title: formatMessage({
411
- id: "content-releases.pages.Releases.notification.error.title",
412
- defaultMessage: "Your request could not be processed."
413
- }),
414
- message: formatMessage({
415
- id: "content-releases.pages.Releases.notification.error.message",
416
- defaultMessage: "Please try again or open another release."
417
- })
418
- });
419
- navigate("", { replace: true, state: null });
420
- }
421
- }, [formatMessage, location?.state?.errors, navigate, toggleNotification]);
422
- const toggleAddReleaseModal = () => {
423
- setReleaseModalShown((prev) => !prev);
424
- };
425
- if (isLoadingReleases || isLoadingSettings) {
426
- return /* @__PURE__ */ jsx(Page.Loading, {});
427
- }
428
- const totalPendingReleases = isSuccess && response.currentData?.meta?.pendingReleasesCount || 0;
429
- const hasReachedMaximumPendingReleases = totalPendingReleases >= maximumReleases;
430
- const handleTabChange = (tabValue) => {
431
- setQuery({
432
- ...query,
433
- page: 1,
434
- pageSize: response?.currentData?.meta?.pagination?.pageSize || 16,
435
- filters: {
436
- releasedAt: {
437
- $notNull: tabValue !== "pending"
438
- }
439
- }
440
- });
441
- };
442
- const handleAddRelease = async ({ name, scheduledAt, timezone }) => {
443
- const response2 = await createRelease({
444
- name,
445
- scheduledAt,
446
- timezone
447
- });
448
- if ("data" in response2) {
449
- toggleNotification({
450
- type: "success",
451
- message: formatMessage({
452
- id: "content-releases.modal.release-created-notification-success",
453
- defaultMessage: "Release created."
454
- })
455
- });
456
- trackUsage("didCreateRelease");
457
- navigate(response2.data.data.id.toString());
458
- } else if (isFetchError(response2.error)) {
459
- toggleNotification({
460
- type: "danger",
461
- message: formatAPIError(response2.error)
462
- });
463
- } else {
464
- toggleNotification({
465
- type: "danger",
466
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
467
- });
468
- }
469
- };
470
- return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingReleases || isLoadingSettings, children: [
471
- /* @__PURE__ */ jsx(
472
- Layouts.Header,
473
- {
474
- title: formatMessage({
475
- id: "content-releases.pages.Releases.title",
476
- defaultMessage: "Releases"
477
- }),
478
- subtitle: formatMessage({
479
- id: "content-releases.pages.Releases.header-subtitle",
480
- defaultMessage: "Create and manage content updates"
481
- }),
482
- primaryAction: canCreate ? /* @__PURE__ */ jsx(
483
- Button,
484
- {
485
- startIcon: /* @__PURE__ */ jsx(Plus, {}),
486
- onClick: toggleAddReleaseModal,
487
- disabled: hasReachedMaximumPendingReleases,
488
- children: formatMessage({
489
- id: "content-releases.header.actions.add-release",
490
- defaultMessage: "New release"
491
- })
492
- }
493
- ) : null
494
- }
495
- ),
496
- /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Fragment, { children: [
497
- hasReachedMaximumPendingReleases && /* @__PURE__ */ jsx(
498
- StyledAlert,
499
- {
500
- marginBottom: 6,
501
- action: /* @__PURE__ */ jsx(Link, { href: "https://strapi.io/pricing-cloud", isExternal: true, children: formatMessage({
502
- id: "content-releases.pages.Releases.max-limit-reached.action",
503
- defaultMessage: "Explore plans"
504
- }) }),
505
- title: formatMessage(
506
- {
507
- id: "content-releases.pages.Releases.max-limit-reached.title",
508
- defaultMessage: "You have reached the {number} pending {number, plural, one {release} other {releases}} limit."
509
- },
510
- { number: maximumReleases }
511
- ),
512
- onClose: () => {
513
- },
514
- closeLabel: "",
515
- children: formatMessage({
516
- id: "content-releases.pages.Releases.max-limit-reached.message",
517
- defaultMessage: "Upgrade to manage an unlimited number of releases."
518
- })
519
- }
520
- ),
521
- /* @__PURE__ */ jsxs(Tabs.Root, { variant: "simple", onValueChange: handleTabChange, value: activeTab, children: [
522
- /* @__PURE__ */ jsxs(Box, { paddingBottom: 8, children: [
523
- /* @__PURE__ */ jsxs(
524
- Tabs.List,
525
- {
526
- "aria-label": formatMessage({
527
- id: "content-releases.pages.Releases.tab-group.label",
528
- defaultMessage: "Releases list"
529
- }),
530
- children: [
531
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "pending", children: formatMessage(
532
- {
533
- id: "content-releases.pages.Releases.tab.pending",
534
- defaultMessage: "Pending ({count})"
535
- },
536
- {
537
- count: totalPendingReleases
538
- }
539
- ) }),
540
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "done", children: formatMessage({
541
- id: "content-releases.pages.Releases.tab.done",
542
- defaultMessage: "Done"
543
- }) })
544
- ]
545
- }
546
- ),
547
- /* @__PURE__ */ jsx(Divider, {})
548
- ] }),
549
- /* @__PURE__ */ jsx(Tabs.Content, { value: "pending", children: /* @__PURE__ */ jsx(
550
- ReleasesGrid,
551
- {
552
- sectionTitle: "pending",
553
- releases: response?.currentData?.data,
554
- isError
555
- }
556
- ) }),
557
- /* @__PURE__ */ jsx(Tabs.Content, { value: "done", children: /* @__PURE__ */ jsx(
558
- ReleasesGrid,
559
- {
560
- sectionTitle: "done",
561
- releases: response?.currentData?.data,
562
- isError
563
- }
564
- ) })
565
- ] }),
566
- /* @__PURE__ */ jsxs(
567
- Pagination.Root,
568
- {
569
- ...response?.currentData?.meta?.pagination,
570
- defaultPageSize: response?.currentData?.meta?.pagination?.pageSize,
571
- children: [
572
- /* @__PURE__ */ jsx(Pagination.PageSize, { options: ["8", "16", "32", "64"] }),
573
- /* @__PURE__ */ jsx(Pagination.Links, {})
574
- ]
575
- }
576
- )
577
- ] }) }),
578
- /* @__PURE__ */ jsx(
579
- ReleaseModal,
580
- {
581
- open: releaseModalShown,
582
- handleClose: toggleAddReleaseModal,
583
- handleSubmit: handleAddRelease,
584
- isLoading: isSubmittingForm,
585
- initialValues: {
586
- ...INITIAL_FORM_VALUES,
587
- timezone: data?.data.defaultTimezone ? data.data.defaultTimezone.split("&")[1] : null
588
- }
589
- }
590
- )
591
- ] });
592
- };
593
- const ReleaseInfoWrapper = styled(Flex)`
594
- align-self: stretch;
595
- border-bottom-right-radius: ${({ theme }) => theme.borderRadius};
596
- border-bottom-left-radius: ${({ theme }) => theme.borderRadius};
597
- border-top: 1px solid ${({ theme }) => theme.colors.neutral150};
598
- `;
599
- const StyledMenuItem = styled(MenuItem)`
600
- svg path {
601
- fill: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
602
- }
603
- span {
604
- color: ${({ theme, disabled }) => disabled && theme.colors.neutral500};
605
- }
606
-
607
- &:hover {
608
- background: ${({ theme, $variant = "neutral" }) => theme.colors[`${$variant}100`]};
609
- }
610
- `;
611
- const PencilIcon = styled(Pencil)`
612
- width: ${({ theme }) => theme.spaces[4]};
613
- height: ${({ theme }) => theme.spaces[4]};
614
- path {
615
- fill: ${({ theme }) => theme.colors.neutral600};
616
- }
617
- `;
618
- const TrashIcon = styled(Trash)`
619
- width: ${({ theme }) => theme.spaces[4]};
620
- height: ${({ theme }) => theme.spaces[4]};
621
- path {
622
- fill: ${({ theme }) => theme.colors.danger600};
623
- }
624
- `;
625
- const TypographyMaxWidth = styled(Typography)`
626
- max-width: 300px;
627
- `;
628
- const EntryValidationText = ({ action, schema, entry, status }) => {
629
- const { formatMessage } = useIntl();
630
- const { validate, isLoading } = unstable_useDocument(
631
- {
632
- collectionType: schema?.kind ?? "",
633
- model: schema?.uid ?? ""
634
- },
635
- {
636
- // useDocument makes a request to get more data about the entry, but we only want to have the validation function so we skip the request
637
- skip: true
638
- }
639
- );
640
- const errorsToString = (errors2, prefix = "") => {
641
- if (Object.keys(errors2).length === 0) {
642
- return "";
643
- }
644
- return Object.entries(errors2).map(([key, value]) => {
645
- if (value === void 0 || value === null) {
646
- return "";
647
- }
648
- if (typeof value === "string") {
649
- return formatMessage(
650
- { id: value, defaultMessage: value },
651
- { field: prefix ? `${prefix}.${key}` : key }
652
- );
653
- }
654
- if (typeof value === "object" && value !== null && "id" in value && "defaultMessage" in value) {
655
- return formatMessage(
656
- // @ts-expect-error – TODO: default message will be a string
657
- { id: `${value.id}.withField`, defaultMessage: value.defaultMessage },
658
- { field: prefix ? `${prefix}.${key}` : key }
659
- );
660
- }
661
- return errorsToString(value, key);
662
- }).join(" ");
663
- };
664
- if (isLoading) {
665
- return null;
666
- }
667
- const errors = validate(entry) ?? {};
668
- if (action === "publish") {
669
- if (Object.keys(errors).length > 0) {
670
- const validationErrorsMessages = errorsToString(errors);
671
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
672
- /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
673
- /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(
674
- TypographyMaxWidth,
675
- {
676
- textColor: "danger600",
677
- variant: "omega",
678
- fontWeight: "semiBold",
679
- ellipsis: true,
680
- children: validationErrorsMessages
681
- }
682
- ) })
683
- ] });
684
- }
685
- if (status === "draft") {
686
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
687
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
688
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
689
- id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-publish",
690
- defaultMessage: "Ready to publish"
691
- }) })
692
- ] });
693
- }
694
- if (status === "modified") {
695
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
696
- /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
697
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
698
- id: "content-releases.pages.ReleaseDetails.entry-validation.modified",
699
- defaultMessage: "Ready to publish changes"
700
- }) })
701
- ] });
702
- }
703
- if (status === "published") {
704
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
705
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
706
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
707
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-published",
708
- defaultMessage: "Already published"
709
- }) })
710
- ] });
711
- }
712
- }
713
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
714
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
715
- !entry.publishedAt ? /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
716
- id: "content-releases.pages.ReleaseDetails.entry-validation.already-unpublished",
717
- defaultMessage: "Already unpublished"
718
- }) }) : /* @__PURE__ */ jsx(Typography, { children: formatMessage({
719
- id: "content-releases.pages.ReleaseDetails.entry-validation.ready-to-unpublish",
720
- defaultMessage: "Ready to unpublish"
721
- }) })
722
- ] });
723
- };
724
- const ReleaseDetailsLayout = ({
725
- toggleEditReleaseModal,
726
- toggleWarningSubmit,
727
- children
728
- }) => {
729
- const { formatMessage, formatDate, formatTime } = useIntl();
730
- const { releaseId } = useParams();
731
- const {
732
- data,
733
- isLoading: isLoadingDetails,
734
- error
735
- } = useGetReleaseQuery(
736
- { id: releaseId },
737
- {
738
- skip: !releaseId
739
- }
740
- );
741
- const [publishRelease, { isLoading: isPublishing }] = usePublishReleaseMutation();
742
- const { toggleNotification } = useNotification();
743
- const { formatAPIError } = useAPIErrorHandler();
744
- const { allowedActions } = useRBAC(PERMISSIONS);
745
- const { canUpdate, canDelete, canPublish } = allowedActions;
746
- const dispatch = useTypedDispatch();
747
- const { trackUsage } = useTracking();
748
- const release = data?.data;
749
- const handlePublishRelease = (id) => async () => {
750
- const response = await publishRelease({ id });
751
- if ("data" in response) {
752
- toggleNotification({
753
- type: "success",
754
- message: formatMessage({
755
- id: "content-releases.pages.ReleaseDetails.publish-notification-success",
756
- defaultMessage: "Release was published successfully."
757
- })
758
- });
759
- const { totalEntries: totalEntries2, totalPublishedEntries, totalUnpublishedEntries } = response.data.meta;
760
- trackUsage("didPublishRelease", {
761
- totalEntries: totalEntries2,
762
- totalPublishedEntries,
763
- totalUnpublishedEntries
764
- });
765
- } else if (isFetchError(response.error)) {
766
- toggleNotification({
767
- type: "danger",
768
- message: formatAPIError(response.error)
769
- });
770
- } else {
771
- toggleNotification({
772
- type: "danger",
773
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
774
- });
775
- }
776
- };
777
- const handleRefresh = () => {
778
- dispatch(
779
- releaseApi.util.invalidateTags([
780
- { type: "ReleaseAction", id: "LIST" },
781
- { type: "Release", id: releaseId }
782
- ])
783
- );
784
- };
785
- const getCreatedByUser = () => {
786
- if (!release?.createdBy) {
787
- return null;
788
- }
789
- if (release.createdBy.username) {
790
- return release.createdBy.username;
791
- }
792
- if (release.createdBy.firstname) {
793
- return `${release.createdBy.firstname} ${release.createdBy.lastname || ""}`.trim();
794
- }
795
- return release.createdBy.email;
796
- };
797
- if (isLoadingDetails) {
798
- return /* @__PURE__ */ jsx(Page.Loading, {});
799
- }
800
- if (isBaseQueryError(error) && "code" in error || !release) {
801
- return /* @__PURE__ */ jsx(
802
- Navigate,
803
- {
804
- to: "..",
805
- state: {
806
- errors: [
807
- {
808
- // @ts-expect-error – TODO: fix this weird error flow
809
- code: error?.code
810
- }
811
- ]
812
- }
813
- }
814
- );
815
- }
816
- const totalEntries = release.actions.meta.count || 0;
817
- const hasCreatedByUser = Boolean(getCreatedByUser());
818
- const isScheduled = release.scheduledAt && release.timezone;
819
- const numberOfEntriesText = formatMessage(
820
- {
821
- id: "content-releases.pages.Details.header-subtitle",
822
- defaultMessage: "{number, plural, =0 {No entries} one {# entry} other {# entries}}"
823
- },
824
- { number: totalEntries }
825
- );
826
- const scheduledText = isScheduled ? formatMessage(
827
- {
828
- id: "content-releases.pages.ReleaseDetails.header-subtitle.scheduled",
829
- defaultMessage: "Scheduled for {date} at {time} ({offset})"
830
- },
831
- {
832
- date: formatDate(new Date(release.scheduledAt), {
833
- weekday: "long",
834
- day: "numeric",
835
- month: "long",
836
- year: "numeric",
837
- timeZone: release.timezone
838
- }),
839
- time: formatTime(new Date(release.scheduledAt), {
840
- timeZone: release.timezone,
841
- hourCycle: "h23"
842
- }),
843
- offset: getTimezoneOffset(release.timezone, new Date(release.scheduledAt))
844
- }
845
- ) : "";
846
- return /* @__PURE__ */ jsxs(Main, { "aria-busy": isLoadingDetails, children: [
847
- /* @__PURE__ */ jsx(
848
- Layouts.Header,
849
- {
850
- title: release.name,
851
- subtitle: /* @__PURE__ */ jsxs(Flex, { gap: 2, lineHeight: 6, children: [
852
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: numberOfEntriesText + (isScheduled ? ` - ${scheduledText}` : "") }),
853
- /* @__PURE__ */ jsx(Badge, { ...getBadgeProps(release.status), children: release.status })
854
- ] }),
855
- navigationAction: /* @__PURE__ */ jsx(BackButton, {}),
856
- primaryAction: !release.releasedAt && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
857
- /* @__PURE__ */ jsxs(
858
- SimpleMenuButton,
859
- {
860
- label: /* @__PURE__ */ jsx(More, {}),
861
- variant: "tertiary",
862
- endIcon: null,
863
- paddingLeft: "7px",
864
- paddingRight: "7px",
865
- "aria-label": formatMessage({
866
- id: "content-releases.header.actions.open-release-actions",
867
- defaultMessage: "Release edit and delete menu"
868
- }),
869
- popoverPlacement: "bottom-end",
870
- children: [
871
- /* @__PURE__ */ jsx(StyledMenuItem, { disabled: !canUpdate, onSelect: toggleEditReleaseModal, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
872
- /* @__PURE__ */ jsx(PencilIcon, {}),
873
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: formatMessage({
874
- id: "content-releases.header.actions.edit",
875
- defaultMessage: "Edit"
876
- }) })
877
- ] }) }),
878
- /* @__PURE__ */ jsx(
879
- StyledMenuItem,
880
- {
881
- disabled: !canDelete,
882
- onSelect: toggleWarningSubmit,
883
- $variant: "danger",
884
- children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, hasRadius: true, width: "100%", children: [
885
- /* @__PURE__ */ jsx(TrashIcon, {}),
886
- /* @__PURE__ */ jsx(Typography, { ellipsis: true, textColor: "danger600", children: formatMessage({
887
- id: "content-releases.header.actions.delete",
888
- defaultMessage: "Delete"
889
- }) })
890
- ] })
891
- }
892
- ),
893
- /* @__PURE__ */ jsxs(
894
- ReleaseInfoWrapper,
895
- {
896
- direction: "column",
897
- justifyContent: "center",
898
- alignItems: "flex-start",
899
- gap: 1,
900
- padding: 4,
901
- children: [
902
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
903
- id: "content-releases.header.actions.created",
904
- defaultMessage: "Created"
905
- }) }),
906
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", color: "neutral300", children: [
907
- /* @__PURE__ */ jsx(RelativeTime$1, { timestamp: new Date(release.createdAt) }),
908
- formatMessage(
909
- {
910
- id: "content-releases.header.actions.created.description",
911
- defaultMessage: "{hasCreatedByUser, select, true { by {createdBy}} other { by deleted user}}"
912
- },
913
- { createdBy: getCreatedByUser(), hasCreatedByUser }
914
- )
915
- ] })
916
- ]
917
- }
918
- )
919
- ]
920
- }
921
- ),
922
- /* @__PURE__ */ jsx(Button, { size: "S", variant: "tertiary", onClick: handleRefresh, children: formatMessage({
923
- id: "content-releases.header.actions.refresh",
924
- defaultMessage: "Refresh"
925
- }) }),
926
- canPublish ? /* @__PURE__ */ jsx(
927
- Button,
928
- {
929
- size: "S",
930
- variant: "default",
931
- onClick: handlePublishRelease(release.id.toString()),
932
- loading: isPublishing,
933
- disabled: release.actions.meta.count === 0,
934
- children: formatMessage({
935
- id: "content-releases.header.actions.publish",
936
- defaultMessage: "Publish"
937
- })
938
- }
939
- ) : null
940
- ] })
941
- }
942
- ),
943
- children
944
- ] });
945
- };
946
- const SimpleMenuButton = styled(SimpleMenu)`
947
- & > span {
948
- display: flex;
949
- }
950
- `;
951
- const GROUP_BY_OPTIONS = ["contentType", "locale", "action"];
952
- const GROUP_BY_OPTIONS_NO_LOCALE = ["contentType", "action"];
953
- const getGroupByOptionLabel = (value) => {
954
- if (value === "locale") {
955
- return {
956
- id: "content-releases.pages.ReleaseDetails.groupBy.option.locales",
957
- defaultMessage: "Locales"
958
- };
959
- }
960
- if (value === "action") {
961
- return {
962
- id: "content-releases.pages.ReleaseDetails.groupBy.option.actions",
963
- defaultMessage: "Actions"
964
- };
965
- }
966
- return {
967
- id: "content-releases.pages.ReleaseDetails.groupBy.option.content-type",
968
- defaultMessage: "Content-Types"
969
- };
970
- };
971
- const ReleaseDetailsBody = ({ releaseId }) => {
972
- const { formatMessage } = useIntl();
973
- const [{ query }, setQuery] = useQueryParams();
974
- const { toggleNotification } = useNotification();
975
- const { formatAPIError } = useAPIErrorHandler();
976
- const {
977
- data: releaseData,
978
- isLoading: isReleaseLoading,
979
- error: releaseError
980
- } = useGetReleaseQuery({ id: releaseId });
981
- const {
982
- allowedActions: { canUpdate }
983
- } = useRBAC(PERMISSIONS);
984
- const runHookWaterfall = useStrapiApp("ReleaseDetailsPage", (state) => state.runHookWaterfall);
985
- const { displayedHeaders, hasI18nEnabled } = runHookWaterfall("ContentReleases/pages/ReleaseDetails/add-locale-in-releases", {
986
- displayedHeaders: [
987
- {
988
- label: {
989
- id: "content-releases.page.ReleaseDetails.table.header.label.name",
990
- defaultMessage: "name"
991
- },
992
- name: "name"
993
- }
994
- ],
995
- hasI18nEnabled: false
996
- });
997
- const release = releaseData?.data;
998
- const selectedGroupBy = query?.groupBy || "contentType";
999
- const {
1000
- isLoading,
1001
- isFetching,
1002
- isError,
1003
- data,
1004
- error: releaseActionsError
1005
- } = useGetReleaseActionsQuery({
1006
- ...query,
1007
- releaseId
1008
- });
1009
- const [updateReleaseAction] = useUpdateReleaseActionMutation();
1010
- const handleChangeType = async (e, actionId, actionPath) => {
1011
- const response = await updateReleaseAction({
1012
- params: {
1013
- releaseId,
1014
- actionId
1015
- },
1016
- body: {
1017
- type: e.target.value
1018
- },
1019
- query,
1020
- // We are passing the query params to make optimistic updates
1021
- actionPath
1022
- // We are passing the action path to found the position in the cache of the action for optimistic updates
1023
- });
1024
- if ("error" in response) {
1025
- if (isFetchError(response.error)) {
1026
- toggleNotification({
1027
- type: "danger",
1028
- message: formatAPIError(response.error)
1029
- });
1030
- } else {
1031
- toggleNotification({
1032
- type: "danger",
1033
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1034
- });
1035
- }
1036
- }
1037
- };
1038
- if (isLoading || isReleaseLoading) {
1039
- return /* @__PURE__ */ jsx(Page.Loading, {});
1040
- }
1041
- const releaseActions = data?.data;
1042
- const releaseMeta = data?.meta;
1043
- const contentTypes = releaseMeta?.contentTypes || {};
1044
- const components = releaseMeta?.components || {};
1045
- if (isBaseQueryError(releaseError) || !release) {
1046
- const errorsArray = [];
1047
- if (releaseError && "code" in releaseError) {
1048
- errorsArray.push({
1049
- code: releaseError.code
1050
- });
1051
- }
1052
- if (releaseActionsError && "code" in releaseActionsError) {
1053
- errorsArray.push({
1054
- code: releaseActionsError.code
1055
- });
1056
- }
1057
- return /* @__PURE__ */ jsx(
1058
- Navigate,
1059
- {
1060
- to: "..",
1061
- state: {
1062
- errors: errorsArray
1063
- }
1064
- }
1065
- );
1066
- }
1067
- if (isError || !releaseActions) {
1068
- return /* @__PURE__ */ jsx(Page.Error, {});
1069
- }
1070
- if (Object.keys(releaseActions).length === 0) {
1071
- return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsx(
1072
- EmptyStateLayout,
1073
- {
1074
- action: /* @__PURE__ */ jsx(
1075
- LinkButton,
1076
- {
1077
- tag: Link$1,
1078
- to: {
1079
- pathname: "/content-manager"
1080
- },
1081
- style: { textDecoration: "none" },
1082
- variant: "secondary",
1083
- children: formatMessage({
1084
- id: "content-releases.page.Details.button.openContentManager",
1085
- defaultMessage: "Open the Content Manager"
1086
- })
1087
- }
1088
- ),
1089
- icon: /* @__PURE__ */ jsx(EmptyDocuments, { width: "16rem" }),
1090
- content: formatMessage({
1091
- id: "content-releases.pages.Details.tab.emptyEntries",
1092
- defaultMessage: "This release is empty. Open the Content Manager, select an entry and add it to the release."
1093
- })
1094
- }
1095
- ) });
1096
- }
1097
- const groupByLabel = formatMessage({
1098
- id: "content-releases.pages.ReleaseDetails.groupBy.aria-label",
1099
- defaultMessage: "Group by"
1100
- });
1101
- const headers = [
1102
- ...displayedHeaders,
1103
- {
1104
- label: {
1105
- id: "content-releases.page.ReleaseDetails.table.header.label.content-type",
1106
- defaultMessage: "content-type"
1107
- },
1108
- name: "content-type"
1109
- },
1110
- {
1111
- label: {
1112
- id: "content-releases.page.ReleaseDetails.table.header.label.action",
1113
- defaultMessage: "action"
1114
- },
1115
- name: "action"
1116
- },
1117
- ...!release.releasedAt ? [
1118
- {
1119
- label: {
1120
- id: "content-releases.page.ReleaseDetails.table.header.label.status",
1121
- defaultMessage: "status"
1122
- },
1123
- name: "status"
1124
- }
1125
- ] : []
1126
- ];
1127
- const options = hasI18nEnabled ? GROUP_BY_OPTIONS : GROUP_BY_OPTIONS_NO_LOCALE;
1128
- return /* @__PURE__ */ jsx(Layouts.Content, { children: /* @__PURE__ */ jsxs(Flex, { gap: 8, direction: "column", alignItems: "stretch", children: [
1129
- /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
1130
- SingleSelect,
1131
- {
1132
- placeholder: groupByLabel,
1133
- "aria-label": groupByLabel,
1134
- customizeContent: (value) => formatMessage(
1135
- {
1136
- id: `content-releases.pages.ReleaseDetails.groupBy.label`,
1137
- defaultMessage: `Group by {groupBy}`
1138
- },
1139
- {
1140
- groupBy: value
1141
- }
1142
- ),
1143
- value: formatMessage(getGroupByOptionLabel(selectedGroupBy)),
1144
- onChange: (value) => setQuery({ groupBy: value }),
1145
- children: options.map((option) => /* @__PURE__ */ jsx(SingleSelectOption, { value: option, children: formatMessage(getGroupByOptionLabel(option)) }, option))
1146
- }
1147
- ) }),
1148
- Object.keys(releaseActions).map((key) => /* @__PURE__ */ jsxs(Flex, { gap: 4, direction: "column", alignItems: "stretch", children: [
1149
- /* @__PURE__ */ jsx(Flex, { role: "separator", "aria-label": key, children: /* @__PURE__ */ jsx(Badge, { children: key }) }),
1150
- /* @__PURE__ */ jsx(
1151
- Table.Root,
1152
- {
1153
- rows: releaseActions[key].map((item) => ({
1154
- ...item,
1155
- id: Number(item.entry.id)
1156
- })),
1157
- headers,
1158
- isLoading: isLoading || isFetching,
1159
- children: /* @__PURE__ */ jsxs(Table.Content, { children: [
1160
- /* @__PURE__ */ jsx(Table.Head, { children: headers.map(({ label, name }) => /* @__PURE__ */ jsx(Table.HeaderCell, { label: formatMessage(label), name }, name)) }),
1161
- /* @__PURE__ */ jsx(Table.Loading, {}),
1162
- /* @__PURE__ */ jsx(Table.Body, { children: releaseActions[key].map(
1163
- ({ id, contentType, locale, type, entry, status }, actionIndex) => /* @__PURE__ */ jsxs(Tr, { children: [
1164
- /* @__PURE__ */ jsx(Td, { width: "25%", maxWidth: "200px", children: /* @__PURE__ */ jsx(Typography, { ellipsis: true, children: `${contentType.mainFieldValue || entry.id}` }) }),
1165
- hasI18nEnabled && /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: `${locale?.name ? locale.name : "-"}` }) }),
1166
- /* @__PURE__ */ jsx(Td, { width: "10%", children: /* @__PURE__ */ jsx(Typography, { children: contentType.displayName || "" }) }),
1167
- /* @__PURE__ */ jsx(Td, { width: "20%", children: release.releasedAt ? /* @__PURE__ */ jsx(Typography, { children: formatMessage(
1168
- {
1169
- id: "content-releases.page.ReleaseDetails.table.action-published",
1170
- defaultMessage: "This entry was <b>{isPublish, select, true {published} other {unpublished}}</b>."
1171
- },
1172
- {
1173
- isPublish: type === "publish",
1174
- b: (children) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children })
1175
- }
1176
- ) }) : /* @__PURE__ */ jsx(
1177
- ReleaseActionOptions,
1178
- {
1179
- selected: type,
1180
- handleChange: (e) => handleChangeType(e, id, [key, actionIndex]),
1181
- name: `release-action-${id}-type`,
1182
- disabled: !canUpdate
1183
- }
1184
- ) }),
1185
- !release.releasedAt && /* @__PURE__ */ jsxs(Fragment, { children: [
1186
- /* @__PURE__ */ jsx(Td, { width: "20%", minWidth: "200px", children: /* @__PURE__ */ jsx(
1187
- EntryValidationText,
1188
- {
1189
- action: type,
1190
- schema: contentTypes?.[contentType.uid],
1191
- components,
1192
- entry,
1193
- status
1194
- }
1195
- ) }),
1196
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxs(ReleaseActionMenu.Root, { children: [
1197
- /* @__PURE__ */ jsx(
1198
- ReleaseActionMenu.ReleaseActionEntryLinkItem,
1199
- {
1200
- contentTypeUid: contentType.uid,
1201
- documentId: entry.documentId,
1202
- locale: locale?.code
1203
- }
1204
- ),
1205
- /* @__PURE__ */ jsx(
1206
- ReleaseActionMenu.DeleteReleaseActionItem,
1207
- {
1208
- releaseId: release.id,
1209
- actionId: id
1210
- }
1211
- )
1212
- ] }) }) })
1213
- ] })
1214
- ] }, id)
1215
- ) })
1216
- ] })
1217
- }
1218
- )
1219
- ] }, `releases-group-${key}`)),
1220
- /* @__PURE__ */ jsxs(
1221
- Pagination.Root,
1222
- {
1223
- ...releaseMeta?.pagination,
1224
- defaultPageSize: releaseMeta?.pagination?.pageSize,
1225
- children: [
1226
- /* @__PURE__ */ jsx(Pagination.PageSize, {}),
1227
- /* @__PURE__ */ jsx(Pagination.Links, {})
1228
- ]
1229
- }
1230
- )
1231
- ] }) });
1232
- };
1233
- const ReleaseDetailsPage = () => {
1234
- const { formatMessage } = useIntl();
1235
- const { releaseId } = useParams();
1236
- const { toggleNotification } = useNotification();
1237
- const { formatAPIError } = useAPIErrorHandler();
1238
- const navigate = useNavigate();
1239
- const [releaseModalShown, setReleaseModalShown] = React.useState(false);
1240
- const [showWarningSubmit, setWarningSubmit] = React.useState(false);
1241
- const {
1242
- isLoading: isLoadingDetails,
1243
- data,
1244
- isSuccess: isSuccessDetails
1245
- } = useGetReleaseQuery(
1246
- { id: releaseId },
1247
- {
1248
- skip: !releaseId
1249
- }
1250
- );
1251
- const { data: dataTimezone, isLoading: isLoadingTimezone } = useGetReleaseSettingsQuery();
1252
- const [updateRelease, { isLoading: isSubmittingForm }] = useUpdateReleaseMutation();
1253
- const [deleteRelease] = useDeleteReleaseMutation();
1254
- const toggleEditReleaseModal = () => {
1255
- setReleaseModalShown((prev) => !prev);
1256
- };
1257
- const getTimezoneValue = () => {
1258
- if (releaseData?.timezone) {
1259
- return releaseData.timezone;
1260
- } else {
1261
- if (dataTimezone?.data.defaultTimezone) {
1262
- return dataTimezone.data.defaultTimezone;
1263
- }
1264
- return null;
1265
- }
1266
- };
1267
- const toggleWarningSubmit = () => setWarningSubmit((prevState) => !prevState);
1268
- if (isLoadingDetails || isLoadingTimezone) {
1269
- return /* @__PURE__ */ jsx(
1270
- ReleaseDetailsLayout,
1271
- {
1272
- toggleEditReleaseModal,
1273
- toggleWarningSubmit,
1274
- children: /* @__PURE__ */ jsx(Page.Loading, {})
1275
- }
1276
- );
1277
- }
1278
- if (!releaseId) {
1279
- return /* @__PURE__ */ jsx(Navigate, { to: ".." });
1280
- }
1281
- const releaseData = isSuccessDetails && data?.data || null;
1282
- const title = releaseData?.name || "";
1283
- const timezone = getTimezoneValue();
1284
- const scheduledAt = releaseData?.scheduledAt && timezone ? utcToZonedTime(releaseData.scheduledAt, timezone) : null;
1285
- const date = scheduledAt ? format$1(scheduledAt, "yyyy-MM-dd") : void 0;
1286
- const time = scheduledAt ? format$1(scheduledAt, "HH:mm") : "";
1287
- const handleEditRelease = async (values) => {
1288
- const response = await updateRelease({
1289
- id: releaseId,
1290
- name: values.name,
1291
- scheduledAt: values.scheduledAt,
1292
- timezone: values.timezone
1293
- });
1294
- if ("data" in response) {
1295
- toggleNotification({
1296
- type: "success",
1297
- message: formatMessage({
1298
- id: "content-releases.modal.release-updated-notification-success",
1299
- defaultMessage: "Release updated."
1300
- })
1301
- });
1302
- toggleEditReleaseModal();
1303
- } else if (isFetchError(response.error)) {
1304
- toggleNotification({
1305
- type: "danger",
1306
- message: formatAPIError(response.error)
1307
- });
1308
- } else {
1309
- toggleNotification({
1310
- type: "danger",
1311
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1312
- });
1313
- }
1314
- };
1315
- const handleDeleteRelease = async () => {
1316
- const response = await deleteRelease({
1317
- id: releaseId
1318
- });
1319
- if ("data" in response) {
1320
- navigate("..");
1321
- } else if (isFetchError(response.error)) {
1322
- toggleNotification({
1323
- type: "danger",
1324
- message: formatAPIError(response.error)
1325
- });
1326
- } else {
1327
- toggleNotification({
1328
- type: "danger",
1329
- message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" })
1330
- });
1331
- }
1332
- };
1333
- return /* @__PURE__ */ jsxs(
1334
- ReleaseDetailsLayout,
1335
- {
1336
- toggleEditReleaseModal,
1337
- toggleWarningSubmit,
1338
- children: [
1339
- /* @__PURE__ */ jsx(ReleaseDetailsBody, { releaseId }),
1340
- /* @__PURE__ */ jsx(
1341
- ReleaseModal,
1342
- {
1343
- open: releaseModalShown,
1344
- handleClose: toggleEditReleaseModal,
1345
- handleSubmit: handleEditRelease,
1346
- isLoading: isLoadingDetails || isSubmittingForm,
1347
- initialValues: {
1348
- name: title || "",
1349
- scheduledAt,
1350
- date,
1351
- time,
1352
- isScheduled: Boolean(scheduledAt),
1353
- timezone
1354
- }
1355
- }
1356
- ),
1357
- /* @__PURE__ */ jsx(Dialog.Root, { open: showWarningSubmit, onOpenChange: toggleWarningSubmit, children: /* @__PURE__ */ jsx(ConfirmDialog, { onConfirm: handleDeleteRelease, children: formatMessage({
1358
- id: "content-releases.dialog.confirmation-message",
1359
- defaultMessage: "Are you sure you want to delete this release?"
1360
- }) }) })
1361
- ]
1362
- }
1363
- );
1364
- };
1365
- const App = () => {
1366
- return /* @__PURE__ */ jsx(Page.Protect, { permissions: PERMISSIONS.main, children: /* @__PURE__ */ jsxs(Routes, { children: [
1367
- /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ReleasesPage, {}) }),
1368
- /* @__PURE__ */ jsx(Route, { path: ":releaseId", element: /* @__PURE__ */ jsx(ReleaseDetailsPage, {}) })
1369
- ] }) });
1370
- };
1371
- export {
1372
- App
1373
- };
1374
- //# sourceMappingURL=App-Cne--1Z8.mjs.map