@strapi/content-releases 0.0.0-experimental.d362bf200f5f9359a4bbd4a549603de5ee1f04ca → 0.0.0-experimental.d4b8dd9e74eefeba4fc0574502c919ba4d091e1e

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