@strapi/content-manager 0.0.0-experimental.e02b4637b3906c6d31048d00600d09a23a0edc3d → 0.0.0-experimental.e0df4d50334a17a1beb3d203bff414fbbff62f7b

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 (491) hide show
  1. package/dist/admin/chunks/CardDragPreview-DwuraT0K.mjs +80 -0
  2. package/dist/admin/chunks/CardDragPreview-DwuraT0K.mjs.map +1 -0
  3. package/dist/admin/chunks/CardDragPreview-_dubYgXO.js +82 -0
  4. package/dist/admin/chunks/CardDragPreview-_dubYgXO.js.map +1 -0
  5. package/dist/admin/chunks/ComponentConfigurationPage-BN2kOtDm.mjs +277 -0
  6. package/dist/admin/chunks/ComponentConfigurationPage-BN2kOtDm.mjs.map +1 -0
  7. package/dist/admin/chunks/ComponentConfigurationPage-C5H-5L1u.js +299 -0
  8. package/dist/admin/chunks/ComponentConfigurationPage-C5H-5L1u.js.map +1 -0
  9. package/dist/admin/chunks/ComponentIcon-BZcTc4rj.mjs +153 -0
  10. package/dist/admin/chunks/ComponentIcon-BZcTc4rj.mjs.map +1 -0
  11. package/dist/admin/chunks/ComponentIcon-C-EjOUPA.js +176 -0
  12. package/dist/admin/chunks/ComponentIcon-C-EjOUPA.js.map +1 -0
  13. package/dist/admin/chunks/EditConfigurationPage-BExtZuB7.js +181 -0
  14. package/dist/admin/chunks/EditConfigurationPage-BExtZuB7.js.map +1 -0
  15. package/dist/admin/chunks/EditConfigurationPage-tMgOELQG.mjs +159 -0
  16. package/dist/admin/chunks/EditConfigurationPage-tMgOELQG.mjs.map +1 -0
  17. package/dist/admin/chunks/EditViewPage-CYe7wAXF.mjs +314 -0
  18. package/dist/admin/chunks/EditViewPage-CYe7wAXF.mjs.map +1 -0
  19. package/dist/admin/chunks/EditViewPage-DFkloeMZ.js +337 -0
  20. package/dist/admin/chunks/EditViewPage-DFkloeMZ.js.map +1 -0
  21. package/dist/admin/chunks/FieldTypeIcon-BY6MrVF4.mjs +56 -0
  22. package/dist/admin/chunks/FieldTypeIcon-BY6MrVF4.mjs.map +1 -0
  23. package/dist/admin/chunks/FieldTypeIcon-Bxh-7Jin.js +58 -0
  24. package/dist/admin/chunks/FieldTypeIcon-Bxh-7Jin.js.map +1 -0
  25. package/dist/admin/chunks/Form-DGUP3zQO.js +978 -0
  26. package/dist/admin/chunks/Form-DGUP3zQO.js.map +1 -0
  27. package/dist/admin/chunks/Form-DTO0ZIaB.mjs +955 -0
  28. package/dist/admin/chunks/Form-DTO0ZIaB.mjs.map +1 -0
  29. package/dist/admin/chunks/History-C333pgXF.mjs +1357 -0
  30. package/dist/admin/chunks/History-C333pgXF.mjs.map +1 -0
  31. package/dist/admin/chunks/History-CQznK1pG.js +1380 -0
  32. package/dist/admin/chunks/History-CQznK1pG.js.map +1 -0
  33. package/dist/admin/chunks/Input-BexkC_pp.mjs +7190 -0
  34. package/dist/admin/chunks/Input-BexkC_pp.mjs.map +1 -0
  35. package/dist/admin/chunks/Input-DLJZHw9Y.js +7221 -0
  36. package/dist/admin/chunks/Input-DLJZHw9Y.js.map +1 -0
  37. package/dist/admin/chunks/ListConfigurationPage-71I_stAM.js +819 -0
  38. package/dist/admin/chunks/ListConfigurationPage-71I_stAM.js.map +1 -0
  39. package/dist/admin/chunks/ListConfigurationPage-BX2WR7MI.mjs +796 -0
  40. package/dist/admin/chunks/ListConfigurationPage-BX2WR7MI.mjs.map +1 -0
  41. package/dist/admin/chunks/ListViewPage-BDeT3Dkk.mjs +1133 -0
  42. package/dist/admin/chunks/ListViewPage-BDeT3Dkk.mjs.map +1 -0
  43. package/dist/admin/chunks/ListViewPage-DV3heO4F.js +1155 -0
  44. package/dist/admin/chunks/ListViewPage-DV3heO4F.js.map +1 -0
  45. package/dist/admin/chunks/NoContentTypePage-9JHYpYVX.mjs +58 -0
  46. package/dist/admin/chunks/NoContentTypePage-9JHYpYVX.mjs.map +1 -0
  47. package/dist/admin/chunks/NoContentTypePage-COih9y2J.js +60 -0
  48. package/dist/admin/chunks/NoContentTypePage-COih9y2J.js.map +1 -0
  49. package/dist/admin/chunks/NoPermissionsPage-DGAwRIlN.js +39 -0
  50. package/dist/admin/chunks/NoPermissionsPage-DGAwRIlN.js.map +1 -0
  51. package/dist/admin/chunks/NoPermissionsPage-DTe9I47q.mjs +37 -0
  52. package/dist/admin/chunks/NoPermissionsPage-DTe9I47q.mjs.map +1 -0
  53. package/dist/admin/chunks/Preview-BEq0FXda.mjs +551 -0
  54. package/dist/admin/chunks/Preview-BEq0FXda.mjs.map +1 -0
  55. package/dist/admin/chunks/Preview-CXtc9yEV.js +573 -0
  56. package/dist/admin/chunks/Preview-CXtc9yEV.js.map +1 -0
  57. package/dist/admin/chunks/Relations-o7_hVGyK.js +1318 -0
  58. package/dist/admin/chunks/Relations-o7_hVGyK.js.map +1 -0
  59. package/dist/admin/chunks/Relations-qeZyLDgQ.mjs +1291 -0
  60. package/dist/admin/chunks/Relations-qeZyLDgQ.mjs.map +1 -0
  61. package/dist/admin/chunks/ar-DckYq_WK.mjs +222 -0
  62. package/dist/{_chunks/ar-CCEVvqGG.mjs.map → admin/chunks/ar-DckYq_WK.mjs.map} +1 -1
  63. package/dist/admin/chunks/ar-DeQBSsfl.js +227 -0
  64. package/dist/{_chunks/ru-BT3ybNny.js.map → admin/chunks/ar-DeQBSsfl.js.map} +1 -1
  65. package/dist/admin/chunks/ca-ClDTvatJ.js +202 -0
  66. package/dist/admin/chunks/ca-ClDTvatJ.js.map +1 -0
  67. package/dist/admin/chunks/ca-DviY7mRj.mjs +197 -0
  68. package/dist/admin/chunks/ca-DviY7mRj.mjs.map +1 -0
  69. package/dist/admin/chunks/cs-BJFxwIWj.js +126 -0
  70. package/dist/{_chunks/cs-CkJy6B2v.js.map → admin/chunks/cs-BJFxwIWj.js.map} +1 -1
  71. package/dist/admin/chunks/cs-C7OSYFQ7.mjs +122 -0
  72. package/dist/{_chunks/cs-CM2aBUar.mjs.map → admin/chunks/cs-C7OSYFQ7.mjs.map} +1 -1
  73. package/dist/admin/chunks/de-5QRlDHyR.mjs +195 -0
  74. package/dist/{_chunks/eu-CdALomew.mjs.map → admin/chunks/de-5QRlDHyR.mjs.map} +1 -1
  75. package/dist/admin/chunks/de-CbImAUA5.js +200 -0
  76. package/dist/{_chunks/gu-BRmF601H.js.map → admin/chunks/de-CbImAUA5.js.map} +1 -1
  77. package/dist/admin/chunks/en-C1CjdAtC.js +313 -0
  78. package/dist/{_chunks/en-Bm0D0IWz.js.map → admin/chunks/en-C1CjdAtC.js.map} +1 -1
  79. package/dist/admin/chunks/en-LfhocNG2.mjs +308 -0
  80. package/dist/{_chunks/en-DKV44jRb.mjs.map → admin/chunks/en-LfhocNG2.mjs.map} +1 -1
  81. package/dist/admin/chunks/es-C8vLuvZL.js +197 -0
  82. package/dist/{_chunks/es-EUonQTon.js.map → admin/chunks/es-C8vLuvZL.js.map} +1 -1
  83. package/dist/admin/chunks/es-DkoWSExG.mjs +192 -0
  84. package/dist/{_chunks/ja-CtsUxOvk.mjs.map → admin/chunks/es-DkoWSExG.mjs.map} +1 -1
  85. package/dist/admin/chunks/eu-BG1xX7HK.mjs +198 -0
  86. package/dist/admin/chunks/eu-BG1xX7HK.mjs.map +1 -0
  87. package/dist/admin/chunks/eu-BJW3AvXu.js +203 -0
  88. package/dist/admin/chunks/eu-BJW3AvXu.js.map +1 -0
  89. package/dist/admin/chunks/fr-CFdRaRVj.mjs +215 -0
  90. package/dist/admin/chunks/fr-CFdRaRVj.mjs.map +1 -0
  91. package/dist/admin/chunks/fr-gQSilC7w.js +220 -0
  92. package/dist/admin/chunks/fr-gQSilC7w.js.map +1 -0
  93. package/dist/admin/chunks/gu-D5MMMXRs.mjs +196 -0
  94. package/dist/admin/chunks/gu-D5MMMXRs.mjs.map +1 -0
  95. package/dist/admin/chunks/gu-DPU4wyx7.js +201 -0
  96. package/dist/{_chunks/eu-VDH-3ovk.js.map → admin/chunks/gu-DPU4wyx7.js.map} +1 -1
  97. package/dist/admin/chunks/hi-Dp4omeBb.js +201 -0
  98. package/dist/admin/chunks/hi-Dp4omeBb.js.map +1 -0
  99. package/dist/admin/chunks/hi-lp17SCjr.mjs +196 -0
  100. package/dist/admin/chunks/hi-lp17SCjr.mjs.map +1 -0
  101. package/dist/{_chunks/hooks-BAaaKPS_.js → admin/chunks/hooks-D-sOYd1s.js} +6 -3
  102. package/dist/admin/chunks/hooks-D-sOYd1s.js.map +1 -0
  103. package/dist/admin/chunks/hooks-DMvik5y_.mjs +7 -0
  104. package/dist/admin/chunks/hooks-DMvik5y_.mjs.map +1 -0
  105. package/dist/admin/chunks/hu-CLka1U2C.mjs +198 -0
  106. package/dist/admin/chunks/hu-CLka1U2C.mjs.map +1 -0
  107. package/dist/admin/chunks/hu-CtFJuhTd.js +203 -0
  108. package/dist/admin/chunks/hu-CtFJuhTd.js.map +1 -0
  109. package/dist/admin/chunks/id-D7V5S1rB.js +161 -0
  110. package/dist/{_chunks/it-DkBIs7vD.js.map → admin/chunks/id-D7V5S1rB.js.map} +1 -1
  111. package/dist/admin/chunks/id-USfY9m1g.mjs +156 -0
  112. package/dist/{_chunks/id-BtwA9WJT.mjs.map → admin/chunks/id-USfY9m1g.mjs.map} +1 -1
  113. package/dist/admin/chunks/index-BHimg6jW.js +5417 -0
  114. package/dist/admin/chunks/index-BHimg6jW.js.map +1 -0
  115. package/dist/admin/chunks/index-Cs6qwFQu.mjs +5351 -0
  116. package/dist/admin/chunks/index-Cs6qwFQu.mjs.map +1 -0
  117. package/dist/admin/chunks/it-BAHrwmYS.mjs +158 -0
  118. package/dist/{_chunks/it-BrVPqaf1.mjs.map → admin/chunks/it-BAHrwmYS.mjs.map} +1 -1
  119. package/dist/admin/chunks/it-CQFpa_Dc.js +163 -0
  120. package/dist/{_chunks/ko-woFZPmLk.js.map → admin/chunks/it-CQFpa_Dc.js.map} +1 -1
  121. package/dist/admin/chunks/ja-BWKmBJFT.mjs +192 -0
  122. package/dist/{_chunks/ko-HVQRlfUI.mjs.map → admin/chunks/ja-BWKmBJFT.mjs.map} +1 -1
  123. package/dist/admin/chunks/ja-jdQM-B79.js +197 -0
  124. package/dist/{_chunks/de-CCEmbAah.js.map → admin/chunks/ja-jdQM-B79.js.map} +1 -1
  125. package/dist/admin/chunks/ko-CgADGBNt.mjs +191 -0
  126. package/dist/{_chunks/es-CeXiYflN.mjs.map → admin/chunks/ko-CgADGBNt.mjs.map} +1 -1
  127. package/dist/admin/chunks/ko-k46sEyzt.js +196 -0
  128. package/dist/{_chunks/ja-CcFe8diO.js.map → admin/chunks/ko-k46sEyzt.js.map} +1 -1
  129. package/dist/admin/chunks/layout-DStNia_P.mjs +599 -0
  130. package/dist/admin/chunks/layout-DStNia_P.mjs.map +1 -0
  131. package/dist/admin/chunks/layout-Dtahn4Ue.js +619 -0
  132. package/dist/admin/chunks/layout-Dtahn4Ue.js.map +1 -0
  133. package/dist/admin/chunks/ml-CnhCfOn_.mjs +196 -0
  134. package/dist/admin/chunks/ml-CnhCfOn_.mjs.map +1 -0
  135. package/dist/admin/chunks/ml-DqxPwODx.js +201 -0
  136. package/dist/admin/chunks/ml-DqxPwODx.js.map +1 -0
  137. package/dist/admin/chunks/ms-Bh09NFff.mjs +140 -0
  138. package/dist/{_chunks/ms-m_WjyWx7.mjs.map → admin/chunks/ms-Bh09NFff.mjs.map} +1 -1
  139. package/dist/admin/chunks/ms-CvSC0OdG.js +145 -0
  140. package/dist/{_chunks/ms-BuFotyP_.js.map → admin/chunks/ms-CvSC0OdG.js.map} +1 -1
  141. package/dist/admin/chunks/nl-BEubhS8C.js +203 -0
  142. package/dist/admin/chunks/nl-BEubhS8C.js.map +1 -0
  143. package/dist/admin/chunks/nl-C8HYflTc.mjs +198 -0
  144. package/dist/admin/chunks/nl-C8HYflTc.mjs.map +1 -0
  145. package/dist/admin/chunks/objects-C3EebVVe.js +76 -0
  146. package/dist/admin/chunks/objects-C3EebVVe.js.map +1 -0
  147. package/dist/admin/chunks/objects-wl73iEma.mjs +73 -0
  148. package/dist/admin/chunks/objects-wl73iEma.mjs.map +1 -0
  149. package/dist/admin/chunks/pl-DWhGDzmM.js +200 -0
  150. package/dist/{_chunks/ca-Cmk45QO6.js.map → admin/chunks/pl-DWhGDzmM.js.map} +1 -1
  151. package/dist/admin/chunks/pl-MFCZJZuZ.mjs +195 -0
  152. package/dist/{_chunks/ca-5U32ON2v.mjs.map → admin/chunks/pl-MFCZJZuZ.mjs.map} +1 -1
  153. package/dist/admin/chunks/pt-BR-CPtAXD-4.js +202 -0
  154. package/dist/{_chunks/pt-BR-BiOz37D9.js.map → admin/chunks/pt-BR-CPtAXD-4.js.map} +1 -1
  155. package/dist/admin/chunks/pt-BR-CcotyBGJ.mjs +197 -0
  156. package/dist/{_chunks/pt-BR-C71iDxnh.mjs.map → admin/chunks/pt-BR-CcotyBGJ.mjs.map} +1 -1
  157. package/dist/admin/chunks/pt-BoPxN80n.js +96 -0
  158. package/dist/admin/chunks/pt-BoPxN80n.js.map +1 -0
  159. package/dist/admin/chunks/pt-HbmgeiYO.mjs +93 -0
  160. package/dist/admin/chunks/pt-HbmgeiYO.mjs.map +1 -0
  161. package/dist/admin/chunks/relations-Cq8NRUto.mjs +173 -0
  162. package/dist/admin/chunks/relations-Cq8NRUto.mjs.map +1 -0
  163. package/dist/admin/chunks/relations-XOYEEqMz.js +178 -0
  164. package/dist/admin/chunks/relations-XOYEEqMz.js.map +1 -0
  165. package/dist/admin/chunks/ru-C0op0ALG.js +232 -0
  166. package/dist/admin/chunks/ru-C0op0ALG.js.map +1 -0
  167. package/dist/admin/chunks/ru-CB4BUyQp.mjs +230 -0
  168. package/dist/{_chunks/ru-BE6A4Exp.mjs.map → admin/chunks/ru-CB4BUyQp.mjs.map} +1 -1
  169. package/dist/admin/chunks/sa-B_FuPyMw.js +201 -0
  170. package/dist/admin/chunks/sa-B_FuPyMw.js.map +1 -0
  171. package/dist/admin/chunks/sa-n_aPA-pU.mjs +196 -0
  172. package/dist/admin/chunks/sa-n_aPA-pU.mjs.map +1 -0
  173. package/dist/admin/chunks/sk-D_iXML2C.js +203 -0
  174. package/dist/admin/chunks/sk-D_iXML2C.js.map +1 -0
  175. package/dist/admin/chunks/sk-tn_BDjE2.mjs +198 -0
  176. package/dist/admin/chunks/sk-tn_BDjE2.mjs.map +1 -0
  177. package/dist/admin/chunks/sv-BstBC1Yp.js +203 -0
  178. package/dist/admin/chunks/sv-BstBC1Yp.js.map +1 -0
  179. package/dist/admin/chunks/sv-cq4ZrQRd.mjs +198 -0
  180. package/dist/admin/chunks/sv-cq4ZrQRd.mjs.map +1 -0
  181. package/dist/admin/chunks/th-lXoOCqPC.js +149 -0
  182. package/dist/{_chunks/th-D9_GfAjc.js.map → admin/chunks/th-lXoOCqPC.js.map} +1 -1
  183. package/dist/admin/chunks/th-mUH7hEtc.mjs +144 -0
  184. package/dist/{_chunks/th-BqbI8lIT.mjs.map → admin/chunks/th-mUH7hEtc.mjs.map} +1 -1
  185. package/dist/admin/chunks/tr-CkS6sLIE.js +200 -0
  186. package/dist/admin/chunks/tr-CkS6sLIE.js.map +1 -0
  187. package/dist/admin/chunks/tr-Yt38daxh.mjs +195 -0
  188. package/dist/{_chunks/de-C72KDNOl.mjs.map → admin/chunks/tr-Yt38daxh.mjs.map} +1 -1
  189. package/dist/admin/chunks/uk-B24MoTVg.js +145 -0
  190. package/dist/{_chunks/uk-C8EiqJY7.js.map → admin/chunks/uk-B24MoTVg.js.map} +1 -1
  191. package/dist/admin/chunks/uk-Cpgmm7gE.mjs +140 -0
  192. package/dist/{_chunks/uk-CR-zDhAY.mjs.map → admin/chunks/uk-Cpgmm7gE.mjs.map} +1 -1
  193. package/dist/admin/chunks/useDragAndDrop-HYwNDExe.mjs +247 -0
  194. package/dist/admin/chunks/useDragAndDrop-HYwNDExe.mjs.map +1 -0
  195. package/dist/admin/chunks/useDragAndDrop-gcqEJMnO.js +271 -0
  196. package/dist/admin/chunks/useDragAndDrop-gcqEJMnO.js.map +1 -0
  197. package/dist/admin/chunks/usePrev-Bjw2dhmq.mjs +18 -0
  198. package/dist/admin/chunks/usePrev-Bjw2dhmq.mjs.map +1 -0
  199. package/dist/admin/chunks/usePrev-DIYl-IAL.js +21 -0
  200. package/dist/admin/chunks/usePrev-DIYl-IAL.js.map +1 -0
  201. package/dist/admin/chunks/vi-BGr1X_HZ.js +112 -0
  202. package/dist/{_chunks/vi-CJlYDheJ.js.map → admin/chunks/vi-BGr1X_HZ.js.map} +1 -1
  203. package/dist/admin/chunks/vi-CvBGlTjr.mjs +108 -0
  204. package/dist/{_chunks/vi-DUXIk_fw.mjs.map → admin/chunks/vi-CvBGlTjr.mjs.map} +1 -1
  205. package/dist/admin/chunks/zh-BmF-sHaT.mjs +205 -0
  206. package/dist/admin/chunks/zh-BmF-sHaT.mjs.map +1 -0
  207. package/dist/admin/chunks/zh-DwFu_Kfj.js +210 -0
  208. package/dist/admin/chunks/zh-DwFu_Kfj.js.map +1 -0
  209. package/dist/admin/chunks/zh-Hans-CI0HKio3.mjs +934 -0
  210. package/dist/{_chunks/zh-Hans-BPQcRIyH.mjs.map → admin/chunks/zh-Hans-CI0HKio3.mjs.map} +1 -1
  211. package/dist/admin/chunks/zh-Hans-JVK9x7xr.js +953 -0
  212. package/dist/{_chunks/zh-Hans-9kOncHGw.js.map → admin/chunks/zh-Hans-JVK9x7xr.js.map} +1 -1
  213. package/dist/admin/index.js +25 -4
  214. package/dist/admin/index.js.map +1 -1
  215. package/dist/admin/index.mjs +17 -12
  216. package/dist/admin/index.mjs.map +1 -1
  217. package/dist/admin/src/content-manager.d.ts +3 -2
  218. package/dist/admin/src/exports.d.ts +1 -0
  219. package/dist/admin/src/history/services/historyVersion.d.ts +2 -2
  220. package/dist/admin/src/hooks/useDocument.d.ts +21 -4
  221. package/dist/admin/src/index.d.ts +1 -0
  222. package/dist/admin/src/pages/EditView/EditViewPage.d.ts +9 -1
  223. package/dist/admin/src/pages/EditView/components/DocumentActions.d.ts +1 -1
  224. package/dist/admin/src/pages/EditView/components/DocumentStatus.d.ts +3 -3
  225. package/dist/admin/src/pages/EditView/components/EditorToolbarObserver.d.ts +11 -0
  226. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Code.d.ts +55 -0
  227. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/utils/constants.d.ts +1 -0
  228. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.d.ts +4 -1
  229. package/dist/admin/src/pages/EditView/components/FormInputs/DynamicZone/Field.d.ts +4 -1
  230. package/dist/admin/src/pages/EditView/components/FormInputs/Relations.d.ts +2 -1
  231. package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.d.ts +1 -2
  232. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +29 -1
  233. package/dist/admin/src/pages/EditView/utils/data.d.ts +1 -0
  234. package/dist/admin/src/preview/components/PreviewContent.d.ts +3 -0
  235. package/dist/admin/src/preview/components/PreviewHeader.d.ts +3 -0
  236. package/dist/admin/src/preview/components/PreviewSidePanel.d.ts +3 -0
  237. package/dist/admin/src/preview/index.d.ts +3 -0
  238. package/dist/admin/src/preview/pages/Preview.d.ts +13 -0
  239. package/dist/admin/src/preview/routes.d.ts +3 -0
  240. package/dist/admin/src/preview/services/preview.d.ts +3 -0
  241. package/dist/admin/src/router.d.ts +1 -1
  242. package/dist/admin/src/services/api.d.ts +1 -1
  243. package/dist/admin/src/services/components.d.ts +2 -2
  244. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  245. package/dist/admin/src/services/documents.d.ts +16 -19
  246. package/dist/admin/src/services/init.d.ts +1 -1
  247. package/dist/admin/src/services/relations.d.ts +2 -2
  248. package/dist/admin/src/services/uid.d.ts +3 -3
  249. package/dist/server/index.js +5472 -4157
  250. package/dist/server/index.js.map +1 -1
  251. package/dist/server/index.mjs +5457 -4139
  252. package/dist/server/index.mjs.map +1 -1
  253. package/dist/server/src/bootstrap.d.ts.map +1 -1
  254. package/dist/server/src/controllers/index.d.ts.map +1 -1
  255. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  256. package/dist/server/src/controllers/utils/metadata.d.ts +17 -2
  257. package/dist/server/src/controllers/utils/metadata.d.ts.map +1 -1
  258. package/dist/server/src/history/controllers/history-version.d.ts +1 -1
  259. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  260. package/dist/server/src/history/services/history.d.ts +3 -3
  261. package/dist/server/src/history/services/history.d.ts.map +1 -1
  262. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  263. package/dist/server/src/history/services/utils.d.ts +6 -11
  264. package/dist/server/src/history/services/utils.d.ts.map +1 -1
  265. package/dist/server/src/index.d.ts +7 -6
  266. package/dist/server/src/index.d.ts.map +1 -1
  267. package/dist/server/src/preview/controllers/index.d.ts +2 -0
  268. package/dist/server/src/preview/controllers/index.d.ts.map +1 -0
  269. package/dist/server/src/preview/controllers/preview.d.ts +13 -0
  270. package/dist/server/src/preview/controllers/preview.d.ts.map +1 -0
  271. package/dist/server/src/preview/controllers/validation/preview.d.ts +6 -0
  272. package/dist/server/src/preview/controllers/validation/preview.d.ts.map +1 -0
  273. package/dist/server/src/preview/index.d.ts +4 -0
  274. package/dist/server/src/preview/index.d.ts.map +1 -0
  275. package/dist/server/src/preview/routes/index.d.ts +8 -0
  276. package/dist/server/src/preview/routes/index.d.ts.map +1 -0
  277. package/dist/server/src/preview/routes/preview.d.ts +4 -0
  278. package/dist/server/src/preview/routes/preview.d.ts.map +1 -0
  279. package/dist/server/src/preview/services/index.d.ts +16 -0
  280. package/dist/server/src/preview/services/index.d.ts.map +1 -0
  281. package/dist/server/src/preview/services/preview-config.d.ts +32 -0
  282. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -0
  283. package/dist/server/src/preview/services/preview.d.ts +12 -0
  284. package/dist/server/src/preview/services/preview.d.ts.map +1 -0
  285. package/dist/server/src/preview/utils.d.ts +19 -0
  286. package/dist/server/src/preview/utils.d.ts.map +1 -0
  287. package/dist/server/src/register.d.ts.map +1 -1
  288. package/dist/server/src/routes/index.d.ts.map +1 -1
  289. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  290. package/dist/server/src/services/document-metadata.d.ts +12 -10
  291. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  292. package/dist/server/src/services/index.d.ts +7 -6
  293. package/dist/server/src/services/index.d.ts.map +1 -1
  294. package/dist/server/src/services/utils/count.d.ts +1 -1
  295. package/dist/server/src/services/utils/count.d.ts.map +1 -1
  296. package/dist/server/src/services/utils/populate.d.ts +3 -3
  297. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  298. package/dist/server/src/utils/index.d.ts +2 -0
  299. package/dist/server/src/utils/index.d.ts.map +1 -1
  300. package/dist/shared/contracts/collection-types.d.ts +0 -1
  301. package/dist/shared/contracts/components.d.ts +0 -1
  302. package/dist/shared/contracts/content-types.d.ts +0 -1
  303. package/dist/shared/contracts/history-versions.d.ts +0 -1
  304. package/dist/shared/contracts/index.d.ts +1 -1
  305. package/dist/shared/contracts/index.d.ts.map +1 -1
  306. package/dist/shared/contracts/init.d.ts +0 -1
  307. package/dist/shared/contracts/preview.d.ts +26 -0
  308. package/dist/shared/contracts/preview.d.ts.map +1 -0
  309. package/dist/shared/contracts/relations.d.ts +1 -2
  310. package/dist/shared/contracts/relations.d.ts.map +1 -1
  311. package/dist/shared/contracts/review-workflows.d.ts +0 -1
  312. package/dist/shared/contracts/single-types.d.ts +0 -1
  313. package/dist/shared/contracts/uid.d.ts +0 -1
  314. package/dist/shared/index.d.ts +0 -1
  315. package/dist/shared/index.js +37 -22
  316. package/dist/shared/index.js.map +1 -1
  317. package/dist/shared/index.mjs +36 -23
  318. package/dist/shared/index.mjs.map +1 -1
  319. package/package.json +20 -16
  320. package/dist/_chunks/CardDragPreview-C0QyJgRA.js +0 -69
  321. package/dist/_chunks/CardDragPreview-C0QyJgRA.js.map +0 -1
  322. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs +0 -70
  323. package/dist/_chunks/CardDragPreview-DOxamsuj.mjs.map +0 -1
  324. package/dist/_chunks/ComponentConfigurationPage-DfFSZQxe.mjs +0 -236
  325. package/dist/_chunks/ComponentConfigurationPage-DfFSZQxe.mjs.map +0 -1
  326. package/dist/_chunks/ComponentConfigurationPage-FqfsxQ1j.js +0 -255
  327. package/dist/_chunks/ComponentConfigurationPage-FqfsxQ1j.js.map +0 -1
  328. package/dist/_chunks/ComponentIcon-BXdiCGQp.js +0 -176
  329. package/dist/_chunks/ComponentIcon-BXdiCGQp.js.map +0 -1
  330. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs +0 -157
  331. package/dist/_chunks/ComponentIcon-u4bIXTFY.mjs.map +0 -1
  332. package/dist/_chunks/EditConfigurationPage-Cn0e8t3I.js +0 -151
  333. package/dist/_chunks/EditConfigurationPage-Cn0e8t3I.js.map +0 -1
  334. package/dist/_chunks/EditConfigurationPage-DdPNAbl3.mjs +0 -132
  335. package/dist/_chunks/EditConfigurationPage-DdPNAbl3.mjs.map +0 -1
  336. package/dist/_chunks/EditViewPage-B82x_x1b.mjs +0 -224
  337. package/dist/_chunks/EditViewPage-B82x_x1b.mjs.map +0 -1
  338. package/dist/_chunks/EditViewPage-DlxEHhUt.js +0 -243
  339. package/dist/_chunks/EditViewPage-DlxEHhUt.js.map +0 -1
  340. package/dist/_chunks/Field-COL25JiC.js +0 -5595
  341. package/dist/_chunks/Field-COL25JiC.js.map +0 -1
  342. package/dist/_chunks/Field-DufHXW17.mjs +0 -5563
  343. package/dist/_chunks/Field-DufHXW17.mjs.map +0 -1
  344. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs +0 -50
  345. package/dist/_chunks/FieldTypeIcon-CMlNO8PE.mjs.map +0 -1
  346. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js +0 -49
  347. package/dist/_chunks/FieldTypeIcon-Dnwq_IRF.js.map +0 -1
  348. package/dist/_chunks/Form-BssUwrTO.js +0 -779
  349. package/dist/_chunks/Form-BssUwrTO.js.map +0 -1
  350. package/dist/_chunks/Form-u_kAOhwB.mjs +0 -758
  351. package/dist/_chunks/Form-u_kAOhwB.mjs.map +0 -1
  352. package/dist/_chunks/History-C9t9UqpO.js +0 -1066
  353. package/dist/_chunks/History-C9t9UqpO.js.map +0 -1
  354. package/dist/_chunks/History-DRwA3oMM.mjs +0 -1045
  355. package/dist/_chunks/History-DRwA3oMM.mjs.map +0 -1
  356. package/dist/_chunks/ListConfigurationPage-BXYPohh-.js +0 -652
  357. package/dist/_chunks/ListConfigurationPage-BXYPohh-.js.map +0 -1
  358. package/dist/_chunks/ListConfigurationPage-BxfQJzPk.mjs +0 -632
  359. package/dist/_chunks/ListConfigurationPage-BxfQJzPk.mjs.map +0 -1
  360. package/dist/_chunks/ListViewPage-CELx2ysp.mjs +0 -828
  361. package/dist/_chunks/ListViewPage-CELx2ysp.mjs.map +0 -1
  362. package/dist/_chunks/ListViewPage-D2VD8Szg.js +0 -852
  363. package/dist/_chunks/ListViewPage-D2VD8Szg.js.map +0 -1
  364. package/dist/_chunks/NoContentTypePage-BV9IjJSM.js +0 -51
  365. package/dist/_chunks/NoContentTypePage-BV9IjJSM.js.map +0 -1
  366. package/dist/_chunks/NoContentTypePage-DtJ9jcfk.mjs +0 -51
  367. package/dist/_chunks/NoContentTypePage-DtJ9jcfk.mjs.map +0 -1
  368. package/dist/_chunks/NoPermissionsPage-DWleVYK7.mjs +0 -23
  369. package/dist/_chunks/NoPermissionsPage-DWleVYK7.mjs.map +0 -1
  370. package/dist/_chunks/NoPermissionsPage-Dp8NpF9I.js +0 -23
  371. package/dist/_chunks/NoPermissionsPage-Dp8NpF9I.js.map +0 -1
  372. package/dist/_chunks/Relations-BTcf5xaw.mjs +0 -703
  373. package/dist/_chunks/Relations-BTcf5xaw.mjs.map +0 -1
  374. package/dist/_chunks/Relations-DR7EUgyC.js +0 -723
  375. package/dist/_chunks/Relations-DR7EUgyC.js.map +0 -1
  376. package/dist/_chunks/ar-BUUWXIYu.js +0 -226
  377. package/dist/_chunks/ar-BUUWXIYu.js.map +0 -1
  378. package/dist/_chunks/ar-CCEVvqGG.mjs +0 -226
  379. package/dist/_chunks/ca-5U32ON2v.mjs +0 -201
  380. package/dist/_chunks/ca-Cmk45QO6.js +0 -201
  381. package/dist/_chunks/cs-CM2aBUar.mjs +0 -125
  382. package/dist/_chunks/cs-CkJy6B2v.js +0 -125
  383. package/dist/_chunks/de-C72KDNOl.mjs +0 -199
  384. package/dist/_chunks/de-CCEmbAah.js +0 -199
  385. package/dist/_chunks/en-Bm0D0IWz.js +0 -293
  386. package/dist/_chunks/en-DKV44jRb.mjs +0 -293
  387. package/dist/_chunks/es-CeXiYflN.mjs +0 -196
  388. package/dist/_chunks/es-EUonQTon.js +0 -196
  389. package/dist/_chunks/eu-CdALomew.mjs +0 -202
  390. package/dist/_chunks/eu-VDH-3ovk.js +0 -202
  391. package/dist/_chunks/fr-B7kGGg3E.js +0 -206
  392. package/dist/_chunks/fr-B7kGGg3E.js.map +0 -1
  393. package/dist/_chunks/fr-CD9VFbPM.mjs +0 -206
  394. package/dist/_chunks/fr-CD9VFbPM.mjs.map +0 -1
  395. package/dist/_chunks/gu-BRmF601H.js +0 -200
  396. package/dist/_chunks/gu-CNpaMDpH.mjs +0 -200
  397. package/dist/_chunks/gu-CNpaMDpH.mjs.map +0 -1
  398. package/dist/_chunks/hi-CCJBptSq.js +0 -200
  399. package/dist/_chunks/hi-CCJBptSq.js.map +0 -1
  400. package/dist/_chunks/hi-Dwvd04m3.mjs +0 -200
  401. package/dist/_chunks/hi-Dwvd04m3.mjs.map +0 -1
  402. package/dist/_chunks/hooks-BAaaKPS_.js.map +0 -1
  403. package/dist/_chunks/hooks-E5u1mcgM.mjs +0 -8
  404. package/dist/_chunks/hooks-E5u1mcgM.mjs.map +0 -1
  405. package/dist/_chunks/hu-CeYvaaO0.mjs +0 -202
  406. package/dist/_chunks/hu-CeYvaaO0.mjs.map +0 -1
  407. package/dist/_chunks/hu-sNV_yLYy.js +0 -202
  408. package/dist/_chunks/hu-sNV_yLYy.js.map +0 -1
  409. package/dist/_chunks/id-B5Ser98A.js +0 -160
  410. package/dist/_chunks/id-B5Ser98A.js.map +0 -1
  411. package/dist/_chunks/id-BtwA9WJT.mjs +0 -160
  412. package/dist/_chunks/index-BdMf2lfT.js +0 -4109
  413. package/dist/_chunks/index-BdMf2lfT.js.map +0 -1
  414. package/dist/_chunks/index-wnqzm4Q8.mjs +0 -4090
  415. package/dist/_chunks/index-wnqzm4Q8.mjs.map +0 -1
  416. package/dist/_chunks/it-BrVPqaf1.mjs +0 -162
  417. package/dist/_chunks/it-DkBIs7vD.js +0 -162
  418. package/dist/_chunks/ja-CcFe8diO.js +0 -196
  419. package/dist/_chunks/ja-CtsUxOvk.mjs +0 -196
  420. package/dist/_chunks/ko-HVQRlfUI.mjs +0 -195
  421. package/dist/_chunks/ko-woFZPmLk.js +0 -195
  422. package/dist/_chunks/layout-2CfjL0T9.mjs +0 -471
  423. package/dist/_chunks/layout-2CfjL0T9.mjs.map +0 -1
  424. package/dist/_chunks/layout-B2MyZU-_.js +0 -489
  425. package/dist/_chunks/layout-B2MyZU-_.js.map +0 -1
  426. package/dist/_chunks/ml-BihZwQit.mjs +0 -200
  427. package/dist/_chunks/ml-BihZwQit.mjs.map +0 -1
  428. package/dist/_chunks/ml-C2W8N8k1.js +0 -200
  429. package/dist/_chunks/ml-C2W8N8k1.js.map +0 -1
  430. package/dist/_chunks/ms-BuFotyP_.js +0 -144
  431. package/dist/_chunks/ms-m_WjyWx7.mjs +0 -144
  432. package/dist/_chunks/nl-D4R9gHx5.mjs +0 -202
  433. package/dist/_chunks/nl-D4R9gHx5.mjs.map +0 -1
  434. package/dist/_chunks/nl-bbEOHChV.js +0 -202
  435. package/dist/_chunks/nl-bbEOHChV.js.map +0 -1
  436. package/dist/_chunks/objects-gigeqt7s.js +0 -49
  437. package/dist/_chunks/objects-gigeqt7s.js.map +0 -1
  438. package/dist/_chunks/objects-mKMAmfec.mjs +0 -47
  439. package/dist/_chunks/objects-mKMAmfec.mjs.map +0 -1
  440. package/dist/_chunks/pl-sbx9mSt_.mjs +0 -199
  441. package/dist/_chunks/pl-sbx9mSt_.mjs.map +0 -1
  442. package/dist/_chunks/pl-uzwG-hk7.js +0 -199
  443. package/dist/_chunks/pl-uzwG-hk7.js.map +0 -1
  444. package/dist/_chunks/pt-BR-BiOz37D9.js +0 -201
  445. package/dist/_chunks/pt-BR-C71iDxnh.mjs +0 -201
  446. package/dist/_chunks/pt-BsaFvS8-.mjs +0 -95
  447. package/dist/_chunks/pt-BsaFvS8-.mjs.map +0 -1
  448. package/dist/_chunks/pt-CeXQuq50.js +0 -95
  449. package/dist/_chunks/pt-CeXQuq50.js.map +0 -1
  450. package/dist/_chunks/relations-BH7JJGGe.js +0 -134
  451. package/dist/_chunks/relations-BH7JJGGe.js.map +0 -1
  452. package/dist/_chunks/relations-C0w0GcXi.mjs +0 -135
  453. package/dist/_chunks/relations-C0w0GcXi.mjs.map +0 -1
  454. package/dist/_chunks/ru-BE6A4Exp.mjs +0 -231
  455. package/dist/_chunks/ru-BT3ybNny.js +0 -231
  456. package/dist/_chunks/sa-CcvkYInH.js +0 -200
  457. package/dist/_chunks/sa-CcvkYInH.js.map +0 -1
  458. package/dist/_chunks/sa-Dag0k-Z8.mjs +0 -200
  459. package/dist/_chunks/sa-Dag0k-Z8.mjs.map +0 -1
  460. package/dist/_chunks/sk-BFg-R8qJ.mjs +0 -202
  461. package/dist/_chunks/sk-BFg-R8qJ.mjs.map +0 -1
  462. package/dist/_chunks/sk-CvY09Xjv.js +0 -202
  463. package/dist/_chunks/sk-CvY09Xjv.js.map +0 -1
  464. package/dist/_chunks/sv-CUnfWGsh.mjs +0 -202
  465. package/dist/_chunks/sv-CUnfWGsh.mjs.map +0 -1
  466. package/dist/_chunks/sv-MYDuzgvT.js +0 -202
  467. package/dist/_chunks/sv-MYDuzgvT.js.map +0 -1
  468. package/dist/_chunks/th-BqbI8lIT.mjs +0 -148
  469. package/dist/_chunks/th-D9_GfAjc.js +0 -148
  470. package/dist/_chunks/tr-CgeK3wJM.mjs +0 -199
  471. package/dist/_chunks/tr-CgeK3wJM.mjs.map +0 -1
  472. package/dist/_chunks/tr-D9UH-O_R.js +0 -199
  473. package/dist/_chunks/tr-D9UH-O_R.js.map +0 -1
  474. package/dist/_chunks/uk-C8EiqJY7.js +0 -144
  475. package/dist/_chunks/uk-CR-zDhAY.mjs +0 -144
  476. package/dist/_chunks/useDebounce-CtcjDB3L.js +0 -28
  477. package/dist/_chunks/useDebounce-CtcjDB3L.js.map +0 -1
  478. package/dist/_chunks/useDebounce-DmuSJIF3.mjs +0 -29
  479. package/dist/_chunks/useDebounce-DmuSJIF3.mjs.map +0 -1
  480. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs +0 -231
  481. package/dist/_chunks/useDragAndDrop-DdHgKsqq.mjs.map +0 -1
  482. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js +0 -249
  483. package/dist/_chunks/useDragAndDrop-J0TUUbR6.js.map +0 -1
  484. package/dist/_chunks/vi-CJlYDheJ.js +0 -111
  485. package/dist/_chunks/vi-DUXIk_fw.mjs +0 -111
  486. package/dist/_chunks/zh-BWZspA60.mjs +0 -209
  487. package/dist/_chunks/zh-BWZspA60.mjs.map +0 -1
  488. package/dist/_chunks/zh-CQQfszqR.js +0 -209
  489. package/dist/_chunks/zh-CQQfszqR.js.map +0 -1
  490. package/dist/_chunks/zh-Hans-9kOncHGw.js +0 -952
  491. package/dist/_chunks/zh-Hans-BPQcRIyH.mjs +0 -952
@@ -1,4090 +0,0 @@
1
- import { More, Cross, WarningCircle, ListPlus, Pencil, Trash, Check, CrossCircle, CheckCircle, ArrowsCounterClockwise, ChevronRight, Duplicate, ClockCounterClockwise, Feather } from "@strapi/icons";
2
- import { jsx, Fragment, jsxs } from "react/jsx-runtime";
3
- import { useStrapiApp, createContext, useQueryParams, useAuth, useRBAC, Page, adminApi, translatedErrors, useNotification, useAPIErrorHandler, getYupValidationErrors, useForm, useTracking, useGuidedTour, BackButton, DescriptionComponentRenderer, useTable, Table } from "@strapi/admin/strapi-admin";
4
- import * as React from "react";
5
- import { lazy } from "react";
6
- import { Button, Menu, VisuallyHidden, Flex, Typography, Dialog, Modal, Radio, Status, Box, SingleSelect, SingleSelectOption, IconButton, Loader, Tooltip, LinkButton } from "@strapi/design-system";
7
- import { useIntl } from "react-intl";
8
- import { useParams, useNavigate, Navigate, useMatch, useLocation, Link, NavLink } from "react-router-dom";
9
- import * as yup from "yup";
10
- import { ValidationError } from "yup";
11
- import pipe from "lodash/fp/pipe";
12
- import { intervalToDuration, isPast } from "date-fns";
13
- import { styled } from "styled-components";
14
- import { stringify } from "qs";
15
- import { createSlice, combineReducers } from "@reduxjs/toolkit";
16
- const __variableDynamicImportRuntimeHelper = (glob, path) => {
17
- const v = glob[path];
18
- if (v) {
19
- return typeof v === "function" ? v() : Promise.resolve(v);
20
- }
21
- return new Promise((_, reject) => {
22
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(reject.bind(null, new Error("Unknown variable dynamic import: " + path)));
23
- });
24
- };
25
- const PLUGIN_ID = "content-manager";
26
- const PERMISSIONS = [
27
- "plugin::content-manager.explorer.create",
28
- "plugin::content-manager.explorer.read",
29
- "plugin::content-manager.explorer.update",
30
- "plugin::content-manager.explorer.delete",
31
- "plugin::content-manager.explorer.publish"
32
- ];
33
- const INJECTION_ZONES = {
34
- editView: { informations: [], "right-links": [] },
35
- listView: {
36
- actions: [],
37
- deleteModalAdditionalInfos: [],
38
- publishModalAdditionalInfos: [],
39
- unpublishModalAdditionalInfos: []
40
- }
41
- };
42
- const InjectionZone = ({ area, ...props }) => {
43
- const components = useInjectionZone(area);
44
- return /* @__PURE__ */ jsx(Fragment, { children: components.map((component) => /* @__PURE__ */ jsx(component.Component, { ...props }, component.name)) });
45
- };
46
- const useInjectionZone = (area) => {
47
- const getPlugin = useStrapiApp("useInjectionZone", (state) => state.getPlugin);
48
- const contentManagerPlugin = getPlugin(PLUGIN_ID);
49
- const [page, position] = area.split(".");
50
- return contentManagerPlugin.getInjectedComponents(page, position);
51
- };
52
- const ID = "id";
53
- const CREATED_BY_ATTRIBUTE_NAME = "createdBy";
54
- const UPDATED_BY_ATTRIBUTE_NAME = "updatedBy";
55
- const CREATOR_FIELDS = [CREATED_BY_ATTRIBUTE_NAME, UPDATED_BY_ATTRIBUTE_NAME];
56
- const PUBLISHED_BY_ATTRIBUTE_NAME = "publishedBy";
57
- const CREATED_AT_ATTRIBUTE_NAME = "createdAt";
58
- const UPDATED_AT_ATTRIBUTE_NAME = "updatedAt";
59
- const PUBLISHED_AT_ATTRIBUTE_NAME = "publishedAt";
60
- const DOCUMENT_META_FIELDS = [
61
- ID,
62
- ...CREATOR_FIELDS,
63
- PUBLISHED_BY_ATTRIBUTE_NAME,
64
- CREATED_AT_ATTRIBUTE_NAME,
65
- UPDATED_AT_ATTRIBUTE_NAME,
66
- PUBLISHED_AT_ATTRIBUTE_NAME
67
- ];
68
- const ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD = [
69
- "dynamiczone",
70
- "json",
71
- "text",
72
- "relation",
73
- "component",
74
- "boolean",
75
- "media",
76
- "password",
77
- "richtext",
78
- "timestamp",
79
- "blocks"
80
- ];
81
- const SINGLE_TYPES = "single-types";
82
- const COLLECTION_TYPES = "collection-types";
83
- const [DocumentRBACProvider, useDocumentRBAC] = createContext(
84
- "DocumentRBAC",
85
- {
86
- canCreate: false,
87
- canCreateFields: [],
88
- canDelete: false,
89
- canPublish: false,
90
- canRead: false,
91
- canReadFields: [],
92
- canUpdate: false,
93
- canUpdateFields: [],
94
- canUserAction: () => false,
95
- isLoading: false
96
- }
97
- );
98
- const DocumentRBAC = ({ children, permissions }) => {
99
- const { slug } = useParams();
100
- if (!slug) {
101
- throw new Error("Cannot find the slug param in the URL");
102
- }
103
- const [{ rawQuery }] = useQueryParams();
104
- const userPermissions = useAuth("DocumentRBAC", (state) => state.permissions);
105
- const contentTypePermissions = React.useMemo(() => {
106
- const contentTypePermissions2 = userPermissions.filter(
107
- (permission) => permission.subject === slug
108
- );
109
- return contentTypePermissions2.reduce((acc, permission) => {
110
- const [action] = permission.action.split(".").slice(-1);
111
- return { ...acc, [action]: [permission] };
112
- }, {});
113
- }, [slug, userPermissions]);
114
- const { isLoading, allowedActions } = useRBAC(
115
- contentTypePermissions,
116
- permissions ?? void 0,
117
- // TODO: useRBAC context should be typed and built differently
118
- // We are passing raw query as context to the hook so that it can
119
- // rely on the locale provided from DocumentRBAC for its permission calculations.
120
- rawQuery
121
- );
122
- const canCreateFields = !isLoading && allowedActions.canCreate ? extractAndDedupeFields(contentTypePermissions.create) : [];
123
- const canReadFields = !isLoading && allowedActions.canRead ? extractAndDedupeFields(contentTypePermissions.read) : [];
124
- const canUpdateFields = !isLoading && allowedActions.canUpdate ? extractAndDedupeFields(contentTypePermissions.update) : [];
125
- const canUserAction = React.useCallback(
126
- (fieldName, fieldsUserCanAction, fieldType) => {
127
- const name = removeNumericalStrings(fieldName.split("."));
128
- const componentFieldNames = fieldsUserCanAction.filter((field) => field.split(".").length > 1);
129
- if (fieldType === "component") {
130
- return componentFieldNames.some((field) => {
131
- return field.includes(name.join("."));
132
- });
133
- }
134
- if (name.length > 1) {
135
- return componentFieldNames.includes(name.join("."));
136
- }
137
- return fieldsUserCanAction.includes(fieldName);
138
- },
139
- []
140
- );
141
- if (isLoading) {
142
- return /* @__PURE__ */ jsx(Page.Loading, {});
143
- }
144
- return /* @__PURE__ */ jsx(
145
- DocumentRBACProvider,
146
- {
147
- isLoading,
148
- canCreateFields,
149
- canReadFields,
150
- canUpdateFields,
151
- canUserAction,
152
- ...allowedActions,
153
- children
154
- }
155
- );
156
- };
157
- const extractAndDedupeFields = (permissions = []) => permissions.flatMap((permission) => permission.properties?.fields).filter(
158
- (field, index2, arr) => arr.indexOf(field) === index2 && typeof field === "string"
159
- );
160
- const removeNumericalStrings = (arr) => arr.filter((item) => isNaN(Number(item)));
161
- const contentManagerApi = adminApi.enhanceEndpoints({
162
- addTagTypes: [
163
- "ComponentConfiguration",
164
- "ContentTypesConfiguration",
165
- "ContentTypeSettings",
166
- "Document",
167
- "InitialData",
168
- "HistoryVersion",
169
- "Relations",
170
- "UidAvailability"
171
- ]
172
- });
173
- const documentApi = contentManagerApi.injectEndpoints({
174
- overrideExisting: true,
175
- endpoints: (builder) => ({
176
- autoCloneDocument: builder.mutation({
177
- query: ({ model, sourceId, query }) => ({
178
- url: `/content-manager/collection-types/${model}/auto-clone/${sourceId}`,
179
- method: "POST",
180
- config: {
181
- params: query
182
- }
183
- }),
184
- invalidatesTags: (_result, error, { model }) => {
185
- if (error) {
186
- return [];
187
- }
188
- return [{ type: "Document", id: `${model}_LIST` }];
189
- }
190
- }),
191
- cloneDocument: builder.mutation({
192
- query: ({ model, sourceId, data, params }) => ({
193
- url: `/content-manager/collection-types/${model}/clone/${sourceId}`,
194
- method: "POST",
195
- data,
196
- config: {
197
- params
198
- }
199
- }),
200
- invalidatesTags: (_result, _error, { model }) => [
201
- { type: "Document", id: `${model}_LIST` },
202
- { type: "UidAvailability", id: model }
203
- ]
204
- }),
205
- /**
206
- * Creates a new collection-type document. This should ONLY be used for collection-types.
207
- * single-types should always be using `updateDocument` since they always exist.
208
- */
209
- createDocument: builder.mutation({
210
- query: ({ model, data, params }) => ({
211
- url: `/content-manager/collection-types/${model}`,
212
- method: "POST",
213
- data,
214
- config: {
215
- params
216
- }
217
- }),
218
- invalidatesTags: (result, _error, { model }) => [
219
- { type: "Document", id: `${model}_LIST` },
220
- "Relations",
221
- { type: "UidAvailability", id: model }
222
- ]
223
- }),
224
- deleteDocument: builder.mutation({
225
- query: ({ collectionType, model, documentId, params }) => ({
226
- url: `/content-manager/${collectionType}/${model}${collectionType !== SINGLE_TYPES && documentId ? `/${documentId}` : ""}`,
227
- method: "DELETE",
228
- config: {
229
- params
230
- }
231
- }),
232
- invalidatesTags: (_result, _error, { collectionType, model }) => [
233
- { type: "Document", id: collectionType !== SINGLE_TYPES ? `${model}_LIST` : model }
234
- ]
235
- }),
236
- deleteManyDocuments: builder.mutation({
237
- query: ({ model, params, ...body }) => ({
238
- url: `/content-manager/collection-types/${model}/actions/bulkDelete`,
239
- method: "POST",
240
- data: body,
241
- config: {
242
- params
243
- }
244
- }),
245
- invalidatesTags: (_res, _error, { model }) => [{ type: "Document", id: `${model}_LIST` }]
246
- }),
247
- discardDocument: builder.mutation({
248
- query: ({ collectionType, model, documentId, params }) => ({
249
- url: documentId ? `/content-manager/${collectionType}/${model}/${documentId}/actions/discard` : `/content-manager/${collectionType}/${model}/actions/discard`,
250
- method: "POST",
251
- config: {
252
- params
253
- }
254
- }),
255
- invalidatesTags: (_result, _error, { collectionType, model, documentId }) => {
256
- return [
257
- {
258
- type: "Document",
259
- id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
260
- },
261
- { type: "Document", id: `${model}_LIST` },
262
- "Relations",
263
- { type: "UidAvailability", id: model }
264
- ];
265
- }
266
- }),
267
- /**
268
- * Gets all documents of a collection type or single type.
269
- * By passing different params you can get different results e.g. only published documents or 'es' documents.
270
- */
271
- getAllDocuments: builder.query({
272
- query: ({ model, params }) => ({
273
- url: `/content-manager/collection-types/${model}`,
274
- method: "GET",
275
- config: {
276
- params
277
- }
278
- }),
279
- providesTags: (result, _error, arg) => {
280
- return [
281
- { type: "Document", id: `ALL_LIST` },
282
- { type: "Document", id: `${arg.model}_LIST` },
283
- ...result?.results.map(({ documentId }) => ({
284
- type: "Document",
285
- id: `${arg.model}_${documentId}`
286
- })) ?? []
287
- ];
288
- }
289
- }),
290
- getDraftRelationCount: builder.query({
291
- query: ({ collectionType, model, documentId, params }) => ({
292
- url: documentId ? `/content-manager/${collectionType}/${model}/${documentId}/actions/countDraftRelations` : `/content-manager/${collectionType}/${model}/actions/countDraftRelations`,
293
- method: "GET",
294
- config: {
295
- params
296
- }
297
- })
298
- }),
299
- getDocument: builder.query({
300
- // @ts-expect-error – TODO: fix ts error where data unknown doesn't work with response via an assertion?
301
- queryFn: async ({ collectionType, model, documentId, params }, _api, _extraOpts, baseQuery) => {
302
- const res = await baseQuery({
303
- url: `/content-manager/${collectionType}/${model}${documentId ? `/${documentId}` : ""}`,
304
- method: "GET",
305
- config: {
306
- params
307
- }
308
- });
309
- if (res.error && res.error.name === "NotFoundError" && collectionType === SINGLE_TYPES) {
310
- return { data: { document: void 0 }, error: void 0 };
311
- }
312
- return res;
313
- },
314
- providesTags: (result, _error, { collectionType, model, documentId }) => {
315
- return [
316
- // we prefer the result's id because we don't fetch single-types with an ID.
317
- {
318
- type: "Document",
319
- id: collectionType !== SINGLE_TYPES ? `${model}_${result && "documentId" in result ? result.documentId : documentId}` : model
320
- },
321
- // Make it easy to invalidate all individual documents queries for a model
322
- {
323
- type: "Document",
324
- id: `${model}_ALL_ITEMS`
325
- }
326
- ];
327
- }
328
- }),
329
- getManyDraftRelationCount: builder.query({
330
- query: ({ model, ...params }) => ({
331
- url: `/content-manager/collection-types/${model}/actions/countManyEntriesDraftRelations`,
332
- method: "GET",
333
- config: {
334
- params
335
- }
336
- }),
337
- transformResponse: (response) => response.data
338
- }),
339
- /**
340
- * This endpoint will either create or update documents at the same time as publishing.
341
- */
342
- publishDocument: builder.mutation({
343
- query: ({ collectionType, model, documentId, params, data }) => ({
344
- url: documentId ? `/content-manager/${collectionType}/${model}/${documentId}/actions/publish` : `/content-manager/${collectionType}/${model}/actions/publish`,
345
- method: "POST",
346
- data,
347
- config: {
348
- params
349
- }
350
- }),
351
- invalidatesTags: (_result, _error, { collectionType, model, documentId }) => {
352
- return [
353
- {
354
- type: "Document",
355
- id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
356
- },
357
- { type: "Document", id: `${model}_LIST` },
358
- "Relations"
359
- ];
360
- }
361
- }),
362
- publishManyDocuments: builder.mutation({
363
- query: ({ model, params, ...body }) => ({
364
- url: `/content-manager/collection-types/${model}/actions/bulkPublish`,
365
- method: "POST",
366
- data: body,
367
- config: {
368
- params
369
- }
370
- }),
371
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
372
- }),
373
- updateDocument: builder.mutation({
374
- query: ({ collectionType, model, documentId, data, params }) => ({
375
- url: `/content-manager/${collectionType}/${model}${documentId ? `/${documentId}` : ""}`,
376
- method: "PUT",
377
- data,
378
- config: {
379
- params
380
- }
381
- }),
382
- invalidatesTags: (_result, _error, { collectionType, model, documentId }) => {
383
- return [
384
- {
385
- type: "Document",
386
- id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
387
- },
388
- "Relations",
389
- { type: "UidAvailability", id: model }
390
- ];
391
- },
392
- async onQueryStarted({ data, ...patch }, { dispatch, queryFulfilled }) {
393
- const patchResult = dispatch(
394
- documentApi.util.updateQueryData("getDocument", patch, (draft) => {
395
- Object.assign(draft.data, data);
396
- })
397
- );
398
- try {
399
- await queryFulfilled;
400
- } catch {
401
- patchResult.undo();
402
- }
403
- }
404
- }),
405
- unpublishDocument: builder.mutation({
406
- query: ({ collectionType, model, documentId, params, data }) => ({
407
- url: documentId ? `/content-manager/${collectionType}/${model}/${documentId}/actions/unpublish` : `/content-manager/${collectionType}/${model}/actions/unpublish`,
408
- method: "POST",
409
- data,
410
- config: {
411
- params
412
- }
413
- }),
414
- invalidatesTags: (_result, _error, { collectionType, model, documentId }) => {
415
- return [
416
- {
417
- type: "Document",
418
- id: collectionType !== SINGLE_TYPES ? `${model}_${documentId}` : model
419
- }
420
- ];
421
- }
422
- }),
423
- unpublishManyDocuments: builder.mutation({
424
- query: ({ model, params, ...body }) => ({
425
- url: `/content-manager/collection-types/${model}/actions/bulkUnpublish`,
426
- method: "POST",
427
- data: body,
428
- config: {
429
- params
430
- }
431
- }),
432
- invalidatesTags: (_res, _error, { model, documentIds }) => documentIds.map((id) => ({ type: "Document", id: `${model}_${id}` }))
433
- })
434
- })
435
- });
436
- const {
437
- useAutoCloneDocumentMutation,
438
- useCloneDocumentMutation,
439
- useCreateDocumentMutation,
440
- useDeleteDocumentMutation,
441
- useDeleteManyDocumentsMutation,
442
- useDiscardDocumentMutation,
443
- useGetAllDocumentsQuery,
444
- useLazyGetDocumentQuery,
445
- useGetDocumentQuery,
446
- useLazyGetDraftRelationCountQuery,
447
- useGetManyDraftRelationCountQuery,
448
- usePublishDocumentMutation,
449
- usePublishManyDocumentsMutation,
450
- useUpdateDocumentMutation,
451
- useUnpublishDocumentMutation,
452
- useUnpublishManyDocumentsMutation
453
- } = documentApi;
454
- const buildValidParams = (query) => {
455
- if (!query)
456
- return query;
457
- const { plugins: _, ...validQueryParams } = {
458
- ...query,
459
- ...Object.values(query?.plugins ?? {}).reduce(
460
- (acc, current) => Object.assign(acc, current),
461
- {}
462
- )
463
- };
464
- if ("_q" in validQueryParams) {
465
- validQueryParams._q = encodeURIComponent(validQueryParams._q);
466
- }
467
- return validQueryParams;
468
- };
469
- const isBaseQueryError = (error) => {
470
- return error.name !== void 0;
471
- };
472
- const arrayValidator = (attribute, options) => ({
473
- message: translatedErrors.required,
474
- test(value) {
475
- if (options.status === "draft") {
476
- return true;
477
- }
478
- if (!attribute.required) {
479
- return true;
480
- }
481
- if (!value) {
482
- return false;
483
- }
484
- if (Array.isArray(value) && value.length === 0) {
485
- return false;
486
- }
487
- return true;
488
- }
489
- });
490
- const createYupSchema = (attributes = {}, components = {}, options = { status: null }) => {
491
- const createModelSchema = (attributes2) => yup.object().shape(
492
- Object.entries(attributes2).reduce((acc, [name, attribute]) => {
493
- if (DOCUMENT_META_FIELDS.includes(name)) {
494
- return acc;
495
- }
496
- const validations = [
497
- addNullableValidation,
498
- addRequiredValidation,
499
- addMinLengthValidation,
500
- addMaxLengthValidation,
501
- addMinValidation,
502
- addMaxValidation,
503
- addRegexValidation
504
- ].map((fn) => fn(attribute, options));
505
- const transformSchema = pipe(...validations);
506
- switch (attribute.type) {
507
- case "component": {
508
- const { attributes: attributes3 } = components[attribute.component];
509
- if (attribute.repeatable) {
510
- return {
511
- ...acc,
512
- [name]: transformSchema(
513
- yup.array().of(createModelSchema(attributes3).nullable(false))
514
- ).test(arrayValidator(attribute, options))
515
- };
516
- } else {
517
- return {
518
- ...acc,
519
- [name]: transformSchema(createModelSchema(attributes3).nullable())
520
- };
521
- }
522
- }
523
- case "dynamiczone":
524
- return {
525
- ...acc,
526
- [name]: transformSchema(
527
- yup.array().of(
528
- yup.lazy(
529
- (data) => {
530
- const attributes3 = components?.[data?.__component]?.attributes;
531
- const validation = yup.object().shape({
532
- __component: yup.string().required().oneOf(Object.keys(components))
533
- }).nullable(false);
534
- if (!attributes3) {
535
- return validation;
536
- }
537
- return validation.concat(createModelSchema(attributes3));
538
- }
539
- )
540
- )
541
- ).test(arrayValidator(attribute, options))
542
- };
543
- case "relation":
544
- return {
545
- ...acc,
546
- [name]: transformSchema(
547
- yup.lazy((value) => {
548
- if (!value) {
549
- return yup.mixed().nullable(true);
550
- } else if (Array.isArray(value)) {
551
- return yup.array().of(
552
- yup.object().shape({
553
- id: yup.number().required()
554
- })
555
- );
556
- } else if (typeof value === "object") {
557
- return yup.object();
558
- } else {
559
- return yup.mixed().test(
560
- "type-error",
561
- "Relation values must be either null, an array of objects with {id} or an object.",
562
- () => false
563
- );
564
- }
565
- })
566
- )
567
- };
568
- default:
569
- return {
570
- ...acc,
571
- [name]: transformSchema(createAttributeSchema(attribute))
572
- };
573
- }
574
- }, {})
575
- ).default(null);
576
- return createModelSchema(attributes);
577
- };
578
- const createAttributeSchema = (attribute) => {
579
- switch (attribute.type) {
580
- case "biginteger":
581
- return yup.string().matches(/^-?\d*$/);
582
- case "boolean":
583
- return yup.boolean();
584
- case "blocks":
585
- return yup.mixed().test("isBlocks", translatedErrors.json, (value) => {
586
- if (!value || Array.isArray(value)) {
587
- return true;
588
- } else {
589
- return false;
590
- }
591
- });
592
- case "decimal":
593
- case "float":
594
- case "integer":
595
- return yup.number();
596
- case "email":
597
- return yup.string().email(translatedErrors.email);
598
- case "enumeration":
599
- return yup.string().oneOf([...attribute.enum, null]);
600
- case "json":
601
- return yup.mixed().test("isJSON", translatedErrors.json, (value) => {
602
- if (!value || typeof value === "string" && value.length === 0) {
603
- return true;
604
- }
605
- if (typeof value === "object") {
606
- try {
607
- JSON.stringify(value);
608
- return true;
609
- } catch (err) {
610
- return false;
611
- }
612
- }
613
- try {
614
- JSON.parse(value);
615
- return true;
616
- } catch (err) {
617
- return false;
618
- }
619
- });
620
- case "password":
621
- case "richtext":
622
- case "string":
623
- case "text":
624
- return yup.string();
625
- case "uid":
626
- return yup.string().matches(/^[A-Za-z0-9-_.~]*$/);
627
- default:
628
- return yup.mixed();
629
- }
630
- };
631
- const nullableSchema = (schema) => {
632
- return schema?.nullable ? schema.nullable() : (
633
- // In some cases '.nullable' will not be available on the schema.
634
- // e.g. when the schema has been built using yup.lazy (e.g. for relations).
635
- // In these cases we should just return the schema as it is.
636
- schema
637
- );
638
- };
639
- const addNullableValidation = () => (schema) => {
640
- return nullableSchema(schema);
641
- };
642
- const addRequiredValidation = (attribute, options) => (schema) => {
643
- if (options.status === "draft" || !attribute.required) {
644
- return schema;
645
- }
646
- if (attribute.required && "required" in schema) {
647
- return schema.required(translatedErrors.required);
648
- }
649
- return schema;
650
- };
651
- const addMinLengthValidation = (attribute, options) => (schema) => {
652
- if (options.status === "draft") {
653
- return schema;
654
- }
655
- if ("minLength" in attribute && attribute.minLength && Number.isInteger(attribute.minLength) && "min" in schema) {
656
- return schema.min(attribute.minLength, {
657
- ...translatedErrors.minLength,
658
- values: {
659
- min: attribute.minLength
660
- }
661
- });
662
- }
663
- return schema;
664
- };
665
- const addMaxLengthValidation = (attribute) => (schema) => {
666
- if ("maxLength" in attribute && attribute.maxLength && Number.isInteger(attribute.maxLength) && "max" in schema) {
667
- return schema.max(attribute.maxLength, {
668
- ...translatedErrors.maxLength,
669
- values: {
670
- max: attribute.maxLength
671
- }
672
- });
673
- }
674
- return schema;
675
- };
676
- const addMinValidation = (attribute, options) => (schema) => {
677
- if (options.status === "draft") {
678
- return schema;
679
- }
680
- if ("min" in attribute && "min" in schema) {
681
- const min = toInteger(attribute.min);
682
- if (min) {
683
- return schema.min(min, {
684
- ...translatedErrors.min,
685
- values: {
686
- min
687
- }
688
- });
689
- }
690
- }
691
- return schema;
692
- };
693
- const addMaxValidation = (attribute) => (schema) => {
694
- if ("max" in attribute) {
695
- const max = toInteger(attribute.max);
696
- if ("max" in schema && max) {
697
- return schema.max(max, {
698
- ...translatedErrors.max,
699
- values: {
700
- max
701
- }
702
- });
703
- }
704
- }
705
- return schema;
706
- };
707
- const toInteger = (val) => {
708
- if (typeof val === "number" || val === void 0) {
709
- return val;
710
- } else {
711
- const num = Number(val);
712
- return isNaN(num) ? void 0 : num;
713
- }
714
- };
715
- const addRegexValidation = (attribute) => (schema) => {
716
- if ("regex" in attribute && attribute.regex && "matches" in schema) {
717
- return schema.matches(new RegExp(attribute.regex), {
718
- message: {
719
- id: translatedErrors.regex.id,
720
- defaultMessage: "The value does not match the defined pattern."
721
- },
722
- excludeEmptyString: !attribute.required
723
- });
724
- }
725
- return schema;
726
- };
727
- const initApi = contentManagerApi.injectEndpoints({
728
- endpoints: (builder) => ({
729
- getInitialData: builder.query({
730
- query: () => "/content-manager/init",
731
- transformResponse: (response) => response.data,
732
- providesTags: ["InitialData"]
733
- })
734
- })
735
- });
736
- const { useGetInitialDataQuery } = initApi;
737
- const useContentTypeSchema = (model) => {
738
- const { toggleNotification } = useNotification();
739
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
740
- const { data, error, isLoading, isFetching } = useGetInitialDataQuery(void 0);
741
- const { components, contentType, contentTypes } = React.useMemo(() => {
742
- const contentType2 = data?.contentTypes.find((ct) => ct.uid === model);
743
- const componentsByKey = data?.components.reduce((acc, component) => {
744
- acc[component.uid] = component;
745
- return acc;
746
- }, {});
747
- const components2 = extractContentTypeComponents(contentType2?.attributes, componentsByKey);
748
- return {
749
- components: Object.keys(components2).length === 0 ? void 0 : components2,
750
- contentType: contentType2,
751
- contentTypes: data?.contentTypes ?? []
752
- };
753
- }, [model, data]);
754
- React.useEffect(() => {
755
- if (error) {
756
- toggleNotification({
757
- type: "danger",
758
- message: formatAPIError(error)
759
- });
760
- }
761
- }, [toggleNotification, error, formatAPIError]);
762
- return {
763
- // This must be memoized to avoid inifiinite re-renders where the empty object is different everytime.
764
- components: React.useMemo(() => components ?? {}, [components]),
765
- schema: contentType,
766
- schemas: contentTypes,
767
- isLoading: isLoading || isFetching
768
- };
769
- };
770
- const extractContentTypeComponents = (attributes = {}, allComponents = {}) => {
771
- const getComponents = (attributes2) => {
772
- return attributes2.reduce((acc, attribute) => {
773
- if (attribute.type === "component") {
774
- const componentAttributes = Object.values(
775
- allComponents[attribute.component]?.attributes ?? {}
776
- );
777
- acc.push(attribute.component, ...getComponents(componentAttributes));
778
- } else if (attribute.type === "dynamiczone") {
779
- acc.push(
780
- ...attribute.components,
781
- ...attribute.components.flatMap((componentUid) => {
782
- const componentAttributes = Object.values(
783
- allComponents[componentUid]?.attributes ?? {}
784
- );
785
- return getComponents(componentAttributes);
786
- })
787
- );
788
- }
789
- return acc;
790
- }, []);
791
- };
792
- const componentUids = getComponents(Object.values(attributes));
793
- const uniqueComponentUids = [...new Set(componentUids)];
794
- const componentsByKey = uniqueComponentUids.reduce((acc, uid) => {
795
- acc[uid] = allComponents[uid];
796
- return acc;
797
- }, {});
798
- return componentsByKey;
799
- };
800
- const HOOKS = {
801
- /**
802
- * Hook that allows to mutate the displayed headers of the list view table
803
- * @constant
804
- * @type {string}
805
- */
806
- INJECT_COLUMN_IN_TABLE: "Admin/CM/pages/ListView/inject-column-in-table",
807
- /**
808
- * Hook that allows to mutate the CM's collection types links pre-set filters
809
- * @constant
810
- * @type {string}
811
- */
812
- MUTATE_COLLECTION_TYPES_LINKS: "Admin/CM/pages/App/mutate-collection-types-links",
813
- /**
814
- * Hook that allows to mutate the CM's edit view layout
815
- * @constant
816
- * @type {string}
817
- */
818
- MUTATE_EDIT_VIEW_LAYOUT: "Admin/CM/pages/EditView/mutate-edit-view-layout",
819
- /**
820
- * Hook that allows to mutate the CM's single types links pre-set filters
821
- * @constant
822
- * @type {string}
823
- */
824
- MUTATE_SINGLE_TYPES_LINKS: "Admin/CM/pages/App/mutate-single-types-links"
825
- };
826
- const contentTypesApi = contentManagerApi.injectEndpoints({
827
- endpoints: (builder) => ({
828
- getContentTypeConfiguration: builder.query({
829
- query: (uid) => ({
830
- url: `/content-manager/content-types/${uid}/configuration`,
831
- method: "GET"
832
- }),
833
- transformResponse: (response) => response.data,
834
- providesTags: (_result, _error, uid) => [
835
- { type: "ContentTypesConfiguration", id: uid },
836
- { type: "ContentTypeSettings", id: "LIST" }
837
- ]
838
- }),
839
- getAllContentTypeSettings: builder.query({
840
- query: () => "/content-manager/content-types-settings",
841
- transformResponse: (response) => response.data,
842
- providesTags: [{ type: "ContentTypeSettings", id: "LIST" }]
843
- }),
844
- updateContentTypeConfiguration: builder.mutation({
845
- query: ({ uid, ...body }) => ({
846
- url: `/content-manager/content-types/${uid}/configuration`,
847
- method: "PUT",
848
- data: body
849
- }),
850
- transformResponse: (response) => response.data,
851
- invalidatesTags: (_result, _error, { uid }) => [
852
- { type: "ContentTypesConfiguration", id: uid },
853
- { type: "ContentTypeSettings", id: "LIST" },
854
- // Is this necessary?
855
- { type: "InitialData" }
856
- ]
857
- })
858
- })
859
- });
860
- const {
861
- useGetContentTypeConfigurationQuery,
862
- useGetAllContentTypeSettingsQuery,
863
- useUpdateContentTypeConfigurationMutation
864
- } = contentTypesApi;
865
- const checkIfAttributeIsDisplayable = (attribute) => {
866
- const { type } = attribute;
867
- if (type === "relation") {
868
- return !attribute.relation.toLowerCase().includes("morph");
869
- }
870
- return !["json", "dynamiczone", "richtext", "password", "blocks"].includes(type) && !!type;
871
- };
872
- const getMainField = (attribute, mainFieldName, { schemas, components }) => {
873
- if (!mainFieldName) {
874
- return void 0;
875
- }
876
- const mainFieldType = attribute.type === "component" ? components[attribute.component].attributes[mainFieldName].type : (
877
- // @ts-expect-error – `targetModel` does exist on the attribute for a relation.
878
- schemas.find((schema) => schema.uid === attribute.targetModel)?.attributes[mainFieldName].type
879
- );
880
- return {
881
- name: mainFieldName,
882
- type: mainFieldType ?? "string"
883
- };
884
- };
885
- const DEFAULT_SETTINGS = {
886
- bulkable: false,
887
- filterable: false,
888
- searchable: false,
889
- pagination: false,
890
- defaultSortBy: "",
891
- defaultSortOrder: "asc",
892
- mainField: "id",
893
- pageSize: 10
894
- };
895
- const useDocumentLayout = (model) => {
896
- const { schema, components } = useDocument({ model, collectionType: "" }, { skip: true });
897
- const [{ query }] = useQueryParams();
898
- const runHookWaterfall = useStrapiApp("useDocumentLayout", (state) => state.runHookWaterfall);
899
- const { toggleNotification } = useNotification();
900
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
901
- const { isLoading: isLoadingSchemas, schemas } = useContentTypeSchema();
902
- const {
903
- data,
904
- isLoading: isLoadingConfigs,
905
- error,
906
- isFetching: isFetchingConfigs
907
- } = useGetContentTypeConfigurationQuery(model);
908
- const isLoading = isLoadingSchemas || isFetchingConfigs || isLoadingConfigs;
909
- React.useEffect(() => {
910
- if (error) {
911
- toggleNotification({
912
- type: "danger",
913
- message: formatAPIError(error)
914
- });
915
- }
916
- }, [error, formatAPIError, toggleNotification]);
917
- const editLayout = React.useMemo(
918
- () => data && !isLoading ? formatEditLayout(data, { schemas, schema, components }) : {
919
- layout: [],
920
- components: {},
921
- metadatas: {},
922
- options: {},
923
- settings: DEFAULT_SETTINGS
924
- },
925
- [data, isLoading, schemas, schema, components]
926
- );
927
- const listLayout = React.useMemo(() => {
928
- return data && !isLoading ? formatListLayout(data, { schemas, schema, components }) : {
929
- layout: [],
930
- metadatas: {},
931
- options: {},
932
- settings: DEFAULT_SETTINGS
933
- };
934
- }, [data, isLoading, schemas, schema, components]);
935
- const { layout: edit } = React.useMemo(
936
- () => runHookWaterfall(HOOKS.MUTATE_EDIT_VIEW_LAYOUT, {
937
- layout: editLayout,
938
- query
939
- }),
940
- [editLayout, query, runHookWaterfall]
941
- );
942
- return {
943
- error,
944
- isLoading,
945
- edit,
946
- list: listLayout
947
- };
948
- };
949
- const useDocLayout = () => {
950
- const { model } = useDoc();
951
- return useDocumentLayout(model);
952
- };
953
- const formatEditLayout = (data, {
954
- schemas,
955
- schema,
956
- components
957
- }) => {
958
- let currentPanelIndex = 0;
959
- const panelledEditAttributes = convertEditLayoutToFieldLayouts(
960
- data.contentType.layouts.edit,
961
- schema?.attributes,
962
- data.contentType.metadatas,
963
- { configurations: data.components, schemas: components },
964
- schemas
965
- ).reduce((panels, row) => {
966
- if (row.some((field) => field.type === "dynamiczone")) {
967
- panels.push([row]);
968
- currentPanelIndex += 2;
969
- } else {
970
- if (!panels[currentPanelIndex]) {
971
- panels.push([]);
972
- }
973
- panels[currentPanelIndex].push(row);
974
- }
975
- return panels;
976
- }, []);
977
- const componentEditAttributes = Object.entries(data.components).reduce(
978
- (acc, [uid, configuration]) => {
979
- acc[uid] = {
980
- layout: convertEditLayoutToFieldLayouts(
981
- configuration.layouts.edit,
982
- components[uid].attributes,
983
- configuration.metadatas,
984
- { configurations: data.components, schemas: components }
985
- ),
986
- settings: {
987
- ...configuration.settings,
988
- icon: components[uid].info.icon,
989
- displayName: components[uid].info.displayName
990
- }
991
- };
992
- return acc;
993
- },
994
- {}
995
- );
996
- const editMetadatas = Object.entries(data.contentType.metadatas).reduce(
997
- (acc, [attribute, metadata]) => {
998
- return {
999
- ...acc,
1000
- [attribute]: metadata.edit
1001
- };
1002
- },
1003
- {}
1004
- );
1005
- return {
1006
- layout: panelledEditAttributes,
1007
- components: componentEditAttributes,
1008
- metadatas: editMetadatas,
1009
- settings: {
1010
- ...data.contentType.settings,
1011
- displayName: schema?.info.displayName
1012
- },
1013
- options: {
1014
- ...schema?.options,
1015
- ...schema?.pluginOptions,
1016
- ...data.contentType.options
1017
- }
1018
- };
1019
- };
1020
- const convertEditLayoutToFieldLayouts = (rows, attributes = {}, metadatas, components, schemas = []) => {
1021
- return rows.map(
1022
- (row) => row.map((field) => {
1023
- const attribute = attributes[field.name];
1024
- if (!attribute) {
1025
- return null;
1026
- }
1027
- const { edit: metadata } = metadatas[field.name];
1028
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1029
- return {
1030
- attribute,
1031
- disabled: !metadata.editable,
1032
- hint: metadata.description,
1033
- label: metadata.label ?? "",
1034
- name: field.name,
1035
- // @ts-expect-error – mainField does exist on the metadata for a relation.
1036
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1037
- schemas,
1038
- components: components?.schemas ?? {}
1039
- }),
1040
- placeholder: metadata.placeholder ?? "",
1041
- required: attribute.required ?? false,
1042
- size: field.size,
1043
- unique: "unique" in attribute ? attribute.unique : false,
1044
- visible: metadata.visible ?? true,
1045
- type: attribute.type
1046
- };
1047
- }).filter((field) => field !== null)
1048
- );
1049
- };
1050
- const formatListLayout = (data, {
1051
- schemas,
1052
- schema,
1053
- components
1054
- }) => {
1055
- const listMetadatas = Object.entries(data.contentType.metadatas).reduce(
1056
- (acc, [attribute, metadata]) => {
1057
- return {
1058
- ...acc,
1059
- [attribute]: metadata.list
1060
- };
1061
- },
1062
- {}
1063
- );
1064
- const listAttributes = convertListLayoutToFieldLayouts(
1065
- data.contentType.layouts.list,
1066
- schema?.attributes,
1067
- listMetadatas,
1068
- { configurations: data.components, schemas: components },
1069
- schemas
1070
- );
1071
- return {
1072
- layout: listAttributes,
1073
- settings: { ...data.contentType.settings, displayName: schema?.info.displayName },
1074
- metadatas: listMetadatas,
1075
- options: {
1076
- ...schema?.options,
1077
- ...schema?.pluginOptions,
1078
- ...data.contentType.options
1079
- }
1080
- };
1081
- };
1082
- const convertListLayoutToFieldLayouts = (columns, attributes = {}, metadatas, components, schemas = []) => {
1083
- return columns.map((name) => {
1084
- const attribute = attributes[name];
1085
- if (!attribute) {
1086
- return null;
1087
- }
1088
- const metadata = metadatas[name];
1089
- const settings = attribute.type === "component" && components ? components.configurations[attribute.component].settings : {};
1090
- return {
1091
- attribute,
1092
- label: metadata.label ?? "",
1093
- mainField: getMainField(attribute, metadata.mainField || settings.mainField, {
1094
- schemas,
1095
- components: components?.schemas ?? {}
1096
- }),
1097
- name,
1098
- searchable: metadata.searchable ?? true,
1099
- sortable: metadata.sortable ?? true
1100
- };
1101
- }).filter((field) => field !== null);
1102
- };
1103
- const useDocument = (args, opts) => {
1104
- const { toggleNotification } = useNotification();
1105
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1106
- const {
1107
- currentData: data,
1108
- isLoading: isLoadingDocument,
1109
- isFetching: isFetchingDocument,
1110
- error
1111
- } = useGetDocumentQuery(args, {
1112
- ...opts,
1113
- skip: !args.documentId && args.collectionType !== SINGLE_TYPES || opts?.skip
1114
- });
1115
- const {
1116
- components,
1117
- schema,
1118
- schemas,
1119
- isLoading: isLoadingSchema
1120
- } = useContentTypeSchema(args.model);
1121
- React.useEffect(() => {
1122
- if (error) {
1123
- toggleNotification({
1124
- type: "danger",
1125
- message: formatAPIError(error)
1126
- });
1127
- }
1128
- }, [toggleNotification, error, formatAPIError, args.collectionType]);
1129
- const validationSchema = React.useMemo(() => {
1130
- if (!schema) {
1131
- return null;
1132
- }
1133
- return createYupSchema(schema.attributes, components);
1134
- }, [schema, components]);
1135
- const validate = React.useCallback(
1136
- (document) => {
1137
- if (!validationSchema) {
1138
- throw new Error(
1139
- "There is no validation schema generated, this is likely due to the schema not being loaded yet."
1140
- );
1141
- }
1142
- try {
1143
- validationSchema.validateSync(document, { abortEarly: false, strict: true });
1144
- return null;
1145
- } catch (error2) {
1146
- if (error2 instanceof ValidationError) {
1147
- return getYupValidationErrors(error2);
1148
- }
1149
- throw error2;
1150
- }
1151
- },
1152
- [validationSchema]
1153
- );
1154
- const isLoading = isLoadingDocument || isFetchingDocument || isLoadingSchema;
1155
- const hasError = !!error;
1156
- return {
1157
- components,
1158
- document: data?.data,
1159
- meta: data?.meta,
1160
- isLoading,
1161
- hasError,
1162
- schema,
1163
- schemas,
1164
- validate
1165
- };
1166
- };
1167
- const useDoc = () => {
1168
- const { id, slug, collectionType, origin } = useParams();
1169
- const [{ query }] = useQueryParams();
1170
- const params = React.useMemo(() => buildValidParams(query), [query]);
1171
- if (!collectionType) {
1172
- throw new Error("Could not find collectionType in url params");
1173
- }
1174
- if (!slug) {
1175
- throw new Error("Could not find model in url params");
1176
- }
1177
- const document = useDocument(
1178
- { documentId: origin || id, model: slug, collectionType, params },
1179
- {
1180
- skip: id === "create" || !origin && !id && collectionType !== SINGLE_TYPES
1181
- }
1182
- );
1183
- const returnId = origin || id === "create" ? void 0 : id;
1184
- return {
1185
- collectionType,
1186
- model: slug,
1187
- id: returnId,
1188
- ...document
1189
- };
1190
- };
1191
- const useContentManagerContext = () => {
1192
- const {
1193
- collectionType,
1194
- model,
1195
- id,
1196
- components,
1197
- isLoading: isLoadingDoc,
1198
- schema,
1199
- schemas
1200
- } = useDoc();
1201
- const layout = useDocumentLayout(model);
1202
- const form = useForm("useContentManagerContext", (state) => state);
1203
- const isSingleType = collectionType === SINGLE_TYPES;
1204
- const slug = model;
1205
- const isCreatingEntry = id === "create";
1206
- useContentTypeSchema();
1207
- const isLoading = isLoadingDoc || layout.isLoading;
1208
- const error = layout.error;
1209
- return {
1210
- error,
1211
- isLoading,
1212
- // Base metadata
1213
- model,
1214
- collectionType,
1215
- id,
1216
- slug,
1217
- isCreatingEntry,
1218
- isSingleType,
1219
- hasDraftAndPublish: schema?.options?.draftAndPublish ?? false,
1220
- // All schema infos
1221
- components,
1222
- contentType: schema,
1223
- contentTypes: schemas,
1224
- // Form state
1225
- form,
1226
- // layout infos
1227
- layout
1228
- };
1229
- };
1230
- const prefixPluginTranslations = (trad, pluginId) => {
1231
- if (!pluginId) {
1232
- throw new TypeError("pluginId can't be empty");
1233
- }
1234
- return Object.keys(trad).reduce((acc, current) => {
1235
- acc[`${pluginId}.${current}`] = trad[current];
1236
- return acc;
1237
- }, {});
1238
- };
1239
- const getTranslation = (id) => `content-manager.${id}`;
1240
- const DEFAULT_UNEXPECTED_ERROR_MSG = {
1241
- id: "notification.error",
1242
- defaultMessage: "An error occurred, please try again"
1243
- };
1244
- const useDocumentActions = () => {
1245
- const { toggleNotification } = useNotification();
1246
- const { formatMessage } = useIntl();
1247
- const { trackUsage } = useTracking();
1248
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
1249
- const navigate = useNavigate();
1250
- const setCurrentStep = useGuidedTour("useDocumentActions", (state) => state.setCurrentStep);
1251
- const [deleteDocument] = useDeleteDocumentMutation();
1252
- const _delete = React.useCallback(
1253
- async ({ collectionType, model, documentId, params }, trackerProperty) => {
1254
- try {
1255
- trackUsage("willDeleteEntry", trackerProperty);
1256
- const res = await deleteDocument({
1257
- collectionType,
1258
- model,
1259
- documentId,
1260
- params
1261
- });
1262
- if ("error" in res) {
1263
- toggleNotification({
1264
- type: "danger",
1265
- message: formatAPIError(res.error)
1266
- });
1267
- return { error: res.error };
1268
- }
1269
- toggleNotification({
1270
- type: "success",
1271
- message: formatMessage({
1272
- id: getTranslation("success.record.delete"),
1273
- defaultMessage: "Deleted document"
1274
- })
1275
- });
1276
- trackUsage("didDeleteEntry", trackerProperty);
1277
- return res.data;
1278
- } catch (err) {
1279
- toggleNotification({
1280
- type: "danger",
1281
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1282
- });
1283
- trackUsage("didNotDeleteEntry", { error: err, ...trackerProperty });
1284
- throw err;
1285
- }
1286
- },
1287
- [trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
1288
- );
1289
- const [deleteManyDocuments] = useDeleteManyDocumentsMutation();
1290
- const deleteMany = React.useCallback(
1291
- async ({ model, documentIds, params }) => {
1292
- try {
1293
- trackUsage("willBulkDeleteEntries");
1294
- const res = await deleteManyDocuments({
1295
- model,
1296
- documentIds,
1297
- params
1298
- });
1299
- if ("error" in res) {
1300
- toggleNotification({
1301
- type: "danger",
1302
- message: formatAPIError(res.error)
1303
- });
1304
- return { error: res.error };
1305
- }
1306
- toggleNotification({
1307
- type: "success",
1308
- title: formatMessage({
1309
- id: getTranslation("success.records.delete"),
1310
- defaultMessage: "Successfully deleted."
1311
- }),
1312
- message: ""
1313
- });
1314
- trackUsage("didBulkDeleteEntries");
1315
- return res.data;
1316
- } catch (err) {
1317
- toggleNotification({
1318
- type: "danger",
1319
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1320
- });
1321
- trackUsage("didNotBulkDeleteEntries");
1322
- throw err;
1323
- }
1324
- },
1325
- [trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
1326
- );
1327
- const [discardDocument] = useDiscardDocumentMutation();
1328
- const discard = React.useCallback(
1329
- async ({ collectionType, model, documentId, params }) => {
1330
- try {
1331
- const res = await discardDocument({
1332
- collectionType,
1333
- model,
1334
- documentId,
1335
- params
1336
- });
1337
- if ("error" in res) {
1338
- toggleNotification({
1339
- type: "danger",
1340
- message: formatAPIError(res.error)
1341
- });
1342
- return { error: res.error };
1343
- }
1344
- toggleNotification({
1345
- type: "success",
1346
- message: formatMessage({
1347
- id: "content-manager.success.record.discard",
1348
- defaultMessage: "Changes discarded"
1349
- })
1350
- });
1351
- return res.data;
1352
- } catch (err) {
1353
- toggleNotification({
1354
- type: "danger",
1355
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1356
- });
1357
- throw err;
1358
- }
1359
- },
1360
- [discardDocument, formatAPIError, formatMessage, toggleNotification]
1361
- );
1362
- const [publishDocument] = usePublishDocumentMutation();
1363
- const publish = React.useCallback(
1364
- async ({ collectionType, model, documentId, params }, data) => {
1365
- try {
1366
- trackUsage("willPublishEntry");
1367
- const res = await publishDocument({
1368
- collectionType,
1369
- model,
1370
- documentId,
1371
- data,
1372
- params
1373
- });
1374
- if ("error" in res) {
1375
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1376
- return { error: res.error };
1377
- }
1378
- trackUsage("didPublishEntry");
1379
- toggleNotification({
1380
- type: "success",
1381
- message: formatMessage({
1382
- id: getTranslation("success.record.publish"),
1383
- defaultMessage: "Published document"
1384
- })
1385
- });
1386
- return res.data;
1387
- } catch (err) {
1388
- toggleNotification({
1389
- type: "danger",
1390
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1391
- });
1392
- throw err;
1393
- }
1394
- },
1395
- [trackUsage, publishDocument, toggleNotification, formatMessage, formatAPIError]
1396
- );
1397
- const [publishManyDocuments] = usePublishManyDocumentsMutation();
1398
- const publishMany = React.useCallback(
1399
- async ({ model, documentIds, params }) => {
1400
- try {
1401
- const res = await publishManyDocuments({
1402
- model,
1403
- documentIds,
1404
- params
1405
- });
1406
- if ("error" in res) {
1407
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1408
- return { error: res.error };
1409
- }
1410
- toggleNotification({
1411
- type: "success",
1412
- message: formatMessage({
1413
- id: getTranslation("success.record.publish"),
1414
- defaultMessage: "Published document"
1415
- })
1416
- });
1417
- return res.data;
1418
- } catch (err) {
1419
- toggleNotification({
1420
- type: "danger",
1421
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1422
- });
1423
- throw err;
1424
- }
1425
- },
1426
- [
1427
- // trackUsage,
1428
- publishManyDocuments,
1429
- toggleNotification,
1430
- formatMessage,
1431
- formatAPIError
1432
- ]
1433
- );
1434
- const [updateDocument] = useUpdateDocumentMutation();
1435
- const update = React.useCallback(
1436
- async ({ collectionType, model, documentId, params }, data, trackerProperty) => {
1437
- try {
1438
- trackUsage("willEditEntry", trackerProperty);
1439
- const res = await updateDocument({
1440
- collectionType,
1441
- model,
1442
- documentId,
1443
- data,
1444
- params
1445
- });
1446
- if ("error" in res) {
1447
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1448
- trackUsage("didNotEditEntry", { error: res.error, ...trackerProperty });
1449
- return { error: res.error };
1450
- }
1451
- trackUsage("didEditEntry", trackerProperty);
1452
- toggleNotification({
1453
- type: "success",
1454
- message: formatMessage({
1455
- id: getTranslation("success.record.save"),
1456
- defaultMessage: "Saved document"
1457
- })
1458
- });
1459
- return res.data;
1460
- } catch (err) {
1461
- trackUsage("didNotEditEntry", { error: err, ...trackerProperty });
1462
- toggleNotification({
1463
- type: "danger",
1464
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1465
- });
1466
- throw err;
1467
- }
1468
- },
1469
- [trackUsage, updateDocument, toggleNotification, formatMessage, formatAPIError]
1470
- );
1471
- const [unpublishDocument] = useUnpublishDocumentMutation();
1472
- const unpublish = React.useCallback(
1473
- async ({ collectionType, model, documentId, params }, discardDraft = false) => {
1474
- try {
1475
- trackUsage("willUnpublishEntry");
1476
- const res = await unpublishDocument({
1477
- collectionType,
1478
- model,
1479
- documentId,
1480
- params,
1481
- data: {
1482
- discardDraft
1483
- }
1484
- });
1485
- if ("error" in res) {
1486
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1487
- return { error: res.error };
1488
- }
1489
- trackUsage("didUnpublishEntry");
1490
- toggleNotification({
1491
- type: "success",
1492
- message: formatMessage({
1493
- id: getTranslation("success.record.unpublish"),
1494
- defaultMessage: "Unpublished document"
1495
- })
1496
- });
1497
- return res.data;
1498
- } catch (err) {
1499
- toggleNotification({
1500
- type: "danger",
1501
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1502
- });
1503
- throw err;
1504
- }
1505
- },
1506
- [trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
1507
- );
1508
- const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
1509
- const unpublishMany = React.useCallback(
1510
- async ({ model, documentIds, params }) => {
1511
- try {
1512
- trackUsage("willBulkUnpublishEntries");
1513
- const res = await unpublishManyDocuments({
1514
- model,
1515
- documentIds,
1516
- params
1517
- });
1518
- if ("error" in res) {
1519
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1520
- return { error: res.error };
1521
- }
1522
- trackUsage("didBulkUnpublishEntries");
1523
- toggleNotification({
1524
- type: "success",
1525
- title: formatMessage({
1526
- id: getTranslation("success.records.unpublish"),
1527
- defaultMessage: "Successfully unpublished."
1528
- }),
1529
- message: ""
1530
- });
1531
- return res.data;
1532
- } catch (err) {
1533
- toggleNotification({
1534
- type: "danger",
1535
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1536
- });
1537
- trackUsage("didNotBulkUnpublishEntries");
1538
- throw err;
1539
- }
1540
- },
1541
- [trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
1542
- );
1543
- const [createDocument] = useCreateDocumentMutation();
1544
- const create = React.useCallback(
1545
- async ({ model, params }, data, trackerProperty) => {
1546
- try {
1547
- const res = await createDocument({
1548
- model,
1549
- data,
1550
- params
1551
- });
1552
- if ("error" in res) {
1553
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1554
- trackUsage("didNotCreateEntry", { error: res.error, ...trackerProperty });
1555
- return { error: res.error };
1556
- }
1557
- trackUsage("didCreateEntry", trackerProperty);
1558
- toggleNotification({
1559
- type: "success",
1560
- message: formatMessage({
1561
- id: getTranslation("success.record.save"),
1562
- defaultMessage: "Saved document"
1563
- })
1564
- });
1565
- setCurrentStep("contentManager.success");
1566
- return res.data;
1567
- } catch (err) {
1568
- toggleNotification({
1569
- type: "danger",
1570
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1571
- });
1572
- trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
1573
- throw err;
1574
- }
1575
- },
1576
- [createDocument, formatAPIError, formatMessage, toggleNotification, trackUsage]
1577
- );
1578
- const [autoCloneDocument] = useAutoCloneDocumentMutation();
1579
- const autoClone = React.useCallback(
1580
- async ({ model, sourceId }) => {
1581
- try {
1582
- const res = await autoCloneDocument({
1583
- model,
1584
- sourceId
1585
- });
1586
- if ("error" in res) {
1587
- return { error: res.error };
1588
- }
1589
- toggleNotification({
1590
- type: "success",
1591
- message: formatMessage({
1592
- id: getTranslation("success.record.clone"),
1593
- defaultMessage: "Cloned document"
1594
- })
1595
- });
1596
- return res.data;
1597
- } catch (err) {
1598
- toggleNotification({
1599
- type: "danger",
1600
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1601
- });
1602
- throw err;
1603
- }
1604
- },
1605
- [autoCloneDocument, formatMessage, toggleNotification]
1606
- );
1607
- const [cloneDocument] = useCloneDocumentMutation();
1608
- const clone = React.useCallback(
1609
- async ({ model, documentId, params }, body, trackerProperty) => {
1610
- try {
1611
- const { id: _id, ...restBody } = body;
1612
- const res = await cloneDocument({
1613
- model,
1614
- sourceId: documentId,
1615
- data: restBody,
1616
- params
1617
- });
1618
- if ("error" in res) {
1619
- toggleNotification({ type: "danger", message: formatAPIError(res.error) });
1620
- trackUsage("didNotCreateEntry", { error: res.error, ...trackerProperty });
1621
- return { error: res.error };
1622
- }
1623
- trackUsage("didCreateEntry", trackerProperty);
1624
- toggleNotification({
1625
- type: "success",
1626
- message: formatMessage({
1627
- id: getTranslation("success.record.clone"),
1628
- defaultMessage: "Cloned document"
1629
- })
1630
- });
1631
- navigate(`../../${res.data.data.documentId}`, { relative: "path" });
1632
- return res.data;
1633
- } catch (err) {
1634
- toggleNotification({
1635
- type: "danger",
1636
- message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG)
1637
- });
1638
- trackUsage("didNotCreateEntry", { error: err, ...trackerProperty });
1639
- throw err;
1640
- }
1641
- },
1642
- [cloneDocument, trackUsage, toggleNotification, formatMessage, formatAPIError, navigate]
1643
- );
1644
- const [getDoc] = useLazyGetDocumentQuery();
1645
- const getDocument = React.useCallback(
1646
- async (args) => {
1647
- const { data } = await getDoc(args);
1648
- return data;
1649
- },
1650
- [getDoc]
1651
- );
1652
- return {
1653
- autoClone,
1654
- clone,
1655
- create,
1656
- delete: _delete,
1657
- deleteMany,
1658
- discard,
1659
- getDocument,
1660
- publish,
1661
- publishMany,
1662
- unpublish,
1663
- unpublishMany,
1664
- update
1665
- };
1666
- };
1667
- const ProtectedHistoryPage = lazy(
1668
- () => import("./History-DRwA3oMM.mjs").then((mod) => ({ default: mod.ProtectedHistoryPage }))
1669
- );
1670
- const routes$1 = [
1671
- {
1672
- path: ":collectionType/:slug/:id/history",
1673
- Component: ProtectedHistoryPage
1674
- },
1675
- {
1676
- path: ":collectionType/:slug/history",
1677
- Component: ProtectedHistoryPage
1678
- }
1679
- ];
1680
- const ProtectedEditViewPage = lazy(
1681
- () => import("./EditViewPage-B82x_x1b.mjs").then((mod) => ({ default: mod.ProtectedEditViewPage }))
1682
- );
1683
- const ProtectedListViewPage = lazy(
1684
- () => import("./ListViewPage-CELx2ysp.mjs").then((mod) => ({ default: mod.ProtectedListViewPage }))
1685
- );
1686
- const ProtectedListConfiguration = lazy(
1687
- () => import("./ListConfigurationPage-BxfQJzPk.mjs").then((mod) => ({
1688
- default: mod.ProtectedListConfiguration
1689
- }))
1690
- );
1691
- const ProtectedEditConfigurationPage = lazy(
1692
- () => import("./EditConfigurationPage-DdPNAbl3.mjs").then((mod) => ({
1693
- default: mod.ProtectedEditConfigurationPage
1694
- }))
1695
- );
1696
- const ProtectedComponentConfigurationPage = lazy(
1697
- () => import("./ComponentConfigurationPage-DfFSZQxe.mjs").then((mod) => ({
1698
- default: mod.ProtectedComponentConfigurationPage
1699
- }))
1700
- );
1701
- const NoPermissions = lazy(
1702
- () => import("./NoPermissionsPage-DWleVYK7.mjs").then((mod) => ({ default: mod.NoPermissions }))
1703
- );
1704
- const NoContentType = lazy(
1705
- () => import("./NoContentTypePage-DtJ9jcfk.mjs").then((mod) => ({ default: mod.NoContentType }))
1706
- );
1707
- const CollectionTypePages = () => {
1708
- const { collectionType } = useParams();
1709
- if (collectionType !== COLLECTION_TYPES && collectionType !== SINGLE_TYPES) {
1710
- return /* @__PURE__ */ jsx(Navigate, { to: "/404" });
1711
- }
1712
- return collectionType === COLLECTION_TYPES ? /* @__PURE__ */ jsx(ProtectedListViewPage, {}) : /* @__PURE__ */ jsx(ProtectedEditViewPage, {});
1713
- };
1714
- const CLONE_RELATIVE_PATH = ":collectionType/:slug/clone/:origin";
1715
- const CLONE_PATH = `/content-manager/${CLONE_RELATIVE_PATH}`;
1716
- const LIST_RELATIVE_PATH = ":collectionType/:slug";
1717
- const LIST_PATH = `/content-manager/${LIST_RELATIVE_PATH}`;
1718
- const routes = [
1719
- {
1720
- path: LIST_RELATIVE_PATH,
1721
- element: /* @__PURE__ */ jsx(CollectionTypePages, {})
1722
- },
1723
- {
1724
- path: ":collectionType/:slug/:id",
1725
- Component: ProtectedEditViewPage
1726
- },
1727
- {
1728
- path: CLONE_RELATIVE_PATH,
1729
- Component: ProtectedEditViewPage
1730
- },
1731
- {
1732
- path: ":collectionType/:slug/configurations/list",
1733
- Component: ProtectedListConfiguration
1734
- },
1735
- {
1736
- path: "components/:slug/configurations/edit",
1737
- Component: ProtectedComponentConfigurationPage
1738
- },
1739
- {
1740
- path: ":collectionType/:slug/configurations/edit",
1741
- Component: ProtectedEditConfigurationPage
1742
- },
1743
- {
1744
- path: "403",
1745
- Component: NoPermissions
1746
- },
1747
- {
1748
- path: "no-content-types",
1749
- Component: NoContentType
1750
- },
1751
- ...routes$1
1752
- ];
1753
- const DocumentActions = ({ actions: actions2 }) => {
1754
- const { formatMessage } = useIntl();
1755
- const [primaryAction, secondaryAction, ...restActions] = actions2.filter((action) => {
1756
- if (action.position === void 0) {
1757
- return true;
1758
- }
1759
- const positions = Array.isArray(action.position) ? action.position : [action.position];
1760
- return positions.includes("panel");
1761
- });
1762
- if (!primaryAction) {
1763
- return null;
1764
- }
1765
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "stretch", width: "100%", children: [
1766
- /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
1767
- /* @__PURE__ */ jsx(DocumentActionButton, { ...primaryAction, variant: primaryAction.variant || "default" }),
1768
- restActions.length > 0 ? /* @__PURE__ */ jsx(
1769
- DocumentActionsMenu,
1770
- {
1771
- actions: restActions,
1772
- label: formatMessage({
1773
- id: "content-manager.containers.edit.panels.default.more-actions",
1774
- defaultMessage: "More document actions"
1775
- })
1776
- }
1777
- ) : null
1778
- ] }),
1779
- secondaryAction ? /* @__PURE__ */ jsx(
1780
- DocumentActionButton,
1781
- {
1782
- ...secondaryAction,
1783
- variant: secondaryAction.variant || "secondary"
1784
- }
1785
- ) : null
1786
- ] });
1787
- };
1788
- const DocumentActionButton = (action) => {
1789
- const [dialogId, setDialogId] = React.useState(null);
1790
- const { toggleNotification } = useNotification();
1791
- const handleClick = (action2) => async (e) => {
1792
- const { onClick = () => false, dialog, id } = action2;
1793
- const muteDialog = await onClick(e);
1794
- if (dialog && !muteDialog) {
1795
- switch (dialog.type) {
1796
- case "notification":
1797
- toggleNotification({
1798
- title: dialog.title,
1799
- message: dialog.content,
1800
- type: dialog.status,
1801
- timeout: dialog.timeout,
1802
- onClose: dialog.onClose
1803
- });
1804
- break;
1805
- case "dialog":
1806
- case "modal":
1807
- e.preventDefault();
1808
- setDialogId(id);
1809
- }
1810
- }
1811
- };
1812
- const handleClose = () => {
1813
- setDialogId(null);
1814
- };
1815
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1816
- /* @__PURE__ */ jsx(
1817
- Button,
1818
- {
1819
- flex: "auto",
1820
- startIcon: action.icon,
1821
- disabled: action.disabled,
1822
- onClick: handleClick(action),
1823
- justifyContent: "center",
1824
- variant: action.variant || "default",
1825
- paddingTop: "7px",
1826
- paddingBottom: "7px",
1827
- children: action.label
1828
- }
1829
- ),
1830
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
1831
- DocumentActionConfirmDialog,
1832
- {
1833
- ...action.dialog,
1834
- variant: action.dialog?.variant ?? action.variant,
1835
- isOpen: dialogId === action.id,
1836
- onClose: handleClose
1837
- }
1838
- ) : null,
1839
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
1840
- DocumentActionModal,
1841
- {
1842
- ...action.dialog,
1843
- onModalClose: handleClose,
1844
- isOpen: dialogId === action.id
1845
- }
1846
- ) : null
1847
- ] });
1848
- };
1849
- const DocumentActionsMenu = ({
1850
- actions: actions2,
1851
- children,
1852
- label,
1853
- variant = "tertiary"
1854
- }) => {
1855
- const [isOpen, setIsOpen] = React.useState(false);
1856
- const [dialogId, setDialogId] = React.useState(null);
1857
- const { formatMessage } = useIntl();
1858
- const { toggleNotification } = useNotification();
1859
- const isDisabled = actions2.every((action) => action.disabled) || actions2.length === 0;
1860
- const handleClick = (action) => async (e) => {
1861
- const { onClick = () => false, dialog, id } = action;
1862
- const muteDialog = await onClick(e);
1863
- if (dialog && !muteDialog) {
1864
- switch (dialog.type) {
1865
- case "notification":
1866
- toggleNotification({
1867
- title: dialog.title,
1868
- message: dialog.content,
1869
- type: dialog.status,
1870
- timeout: dialog.timeout,
1871
- onClose: dialog.onClose
1872
- });
1873
- break;
1874
- case "dialog":
1875
- case "modal":
1876
- setDialogId(id);
1877
- }
1878
- }
1879
- };
1880
- const handleClose = () => {
1881
- setDialogId(null);
1882
- setIsOpen(false);
1883
- };
1884
- return /* @__PURE__ */ jsxs(Menu.Root, { open: isOpen, onOpenChange: setIsOpen, children: [
1885
- /* @__PURE__ */ jsxs(
1886
- Menu.Trigger,
1887
- {
1888
- disabled: isDisabled,
1889
- size: "S",
1890
- endIcon: null,
1891
- paddingTop: "4px",
1892
- paddingLeft: "7px",
1893
- paddingRight: "7px",
1894
- variant,
1895
- children: [
1896
- /* @__PURE__ */ jsx(More, { "aria-hidden": true, focusable: false }),
1897
- /* @__PURE__ */ jsx(VisuallyHidden, { tag: "span", children: label || formatMessage({
1898
- id: "content-manager.containers.edit.panels.default.more-actions",
1899
- defaultMessage: "More document actions"
1900
- }) })
1901
- ]
1902
- }
1903
- ),
1904
- /* @__PURE__ */ jsxs(Menu.Content, { maxHeight: void 0, popoverPlacement: "bottom-end", children: [
1905
- actions2.map((action) => {
1906
- return /* @__PURE__ */ jsx(
1907
- Menu.Item,
1908
- {
1909
- disabled: action.disabled,
1910
- onSelect: handleClick(action),
1911
- display: "block",
1912
- children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", gap: 4, children: [
1913
- /* @__PURE__ */ jsxs(
1914
- Flex,
1915
- {
1916
- color: !action.disabled ? convertActionVariantToColor(action.variant) : "inherit",
1917
- gap: 2,
1918
- tag: "span",
1919
- children: [
1920
- /* @__PURE__ */ jsx(
1921
- Flex,
1922
- {
1923
- tag: "span",
1924
- color: !action.disabled ? convertActionVariantToIconColor(action.variant) : "inherit",
1925
- children: action.icon
1926
- }
1927
- ),
1928
- action.label
1929
- ]
1930
- }
1931
- ),
1932
- action.id.startsWith("HistoryAction") && /* @__PURE__ */ jsx(
1933
- Flex,
1934
- {
1935
- alignItems: "center",
1936
- background: "alternative100",
1937
- borderStyle: "solid",
1938
- borderColor: "alternative200",
1939
- borderWidth: "1px",
1940
- height: 5,
1941
- paddingLeft: 2,
1942
- paddingRight: 2,
1943
- hasRadius: true,
1944
- color: "alternative600",
1945
- children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", fontWeight: "bold", lineHeight: 1, children: formatMessage({ id: "global.new", defaultMessage: "New" }) })
1946
- }
1947
- )
1948
- ] })
1949
- },
1950
- action.id
1951
- );
1952
- }),
1953
- children
1954
- ] }),
1955
- actions2.map((action) => {
1956
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
1957
- action.dialog?.type === "dialog" ? /* @__PURE__ */ jsx(
1958
- DocumentActionConfirmDialog,
1959
- {
1960
- ...action.dialog,
1961
- variant: action.variant,
1962
- isOpen: dialogId === action.id,
1963
- onClose: handleClose
1964
- }
1965
- ) : null,
1966
- action.dialog?.type === "modal" ? /* @__PURE__ */ jsx(
1967
- DocumentActionModal,
1968
- {
1969
- ...action.dialog,
1970
- onModalClose: handleClose,
1971
- isOpen: dialogId === action.id
1972
- }
1973
- ) : null
1974
- ] }, action.id);
1975
- })
1976
- ] });
1977
- };
1978
- const convertActionVariantToColor = (variant = "secondary") => {
1979
- switch (variant) {
1980
- case "danger":
1981
- return "danger600";
1982
- case "secondary":
1983
- return void 0;
1984
- case "success":
1985
- return "success600";
1986
- default:
1987
- return "primary600";
1988
- }
1989
- };
1990
- const convertActionVariantToIconColor = (variant = "secondary") => {
1991
- switch (variant) {
1992
- case "danger":
1993
- return "danger600";
1994
- case "secondary":
1995
- return "neutral500";
1996
- case "success":
1997
- return "success600";
1998
- default:
1999
- return "primary600";
2000
- }
2001
- };
2002
- const DocumentActionConfirmDialog = ({
2003
- onClose,
2004
- onCancel,
2005
- onConfirm,
2006
- title,
2007
- content,
2008
- isOpen,
2009
- variant = "secondary"
2010
- }) => {
2011
- const { formatMessage } = useIntl();
2012
- const handleClose = async () => {
2013
- if (onCancel) {
2014
- await onCancel();
2015
- }
2016
- onClose();
2017
- };
2018
- const handleConfirm = async () => {
2019
- if (onConfirm) {
2020
- await onConfirm();
2021
- }
2022
- onClose();
2023
- };
2024
- return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2025
- /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
2026
- /* @__PURE__ */ jsx(Dialog.Body, { children: content }),
2027
- /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
2028
- /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", fullWidth: true, children: formatMessage({
2029
- id: "app.components.Button.cancel",
2030
- defaultMessage: "Cancel"
2031
- }) }) }),
2032
- /* @__PURE__ */ jsx(Button, { onClick: handleConfirm, variant, fullWidth: true, children: formatMessage({
2033
- id: "app.components.Button.confirm",
2034
- defaultMessage: "Confirm"
2035
- }) })
2036
- ] })
2037
- ] }) });
2038
- };
2039
- const DocumentActionModal = ({
2040
- isOpen,
2041
- title,
2042
- onClose,
2043
- footer: Footer,
2044
- content: Content,
2045
- onModalClose
2046
- }) => {
2047
- const handleClose = () => {
2048
- if (onClose) {
2049
- onClose();
2050
- }
2051
- onModalClose();
2052
- };
2053
- return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Modal.Content, { children: [
2054
- /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: title }) }),
2055
- typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : /* @__PURE__ */ jsx(Modal.Body, { children: Content }),
2056
- typeof Footer === "function" ? /* @__PURE__ */ jsx(Footer, { onClose: handleClose }) : Footer
2057
- ] }) });
2058
- };
2059
- const PublishAction$1 = ({
2060
- activeTab,
2061
- documentId,
2062
- model,
2063
- collectionType,
2064
- meta,
2065
- document
2066
- }) => {
2067
- const { schema } = useDoc();
2068
- const navigate = useNavigate();
2069
- const { toggleNotification } = useNotification();
2070
- const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2071
- const isListView = useMatch(LIST_PATH) !== null;
2072
- const isCloning = useMatch(CLONE_PATH) !== null;
2073
- const { formatMessage } = useIntl();
2074
- const canPublish = useDocumentRBAC("PublishAction", ({ canPublish: canPublish2 }) => canPublish2);
2075
- const { publish } = useDocumentActions();
2076
- const [
2077
- countDraftRelations,
2078
- { isLoading: isLoadingDraftRelations, isError: isErrorDraftRelations }
2079
- ] = useLazyGetDraftRelationCountQuery();
2080
- const [localCountOfDraftRelations, setLocalCountOfDraftRelations] = React.useState(0);
2081
- const [serverCountOfDraftRelations, setServerCountOfDraftRelations] = React.useState(0);
2082
- const [{ query, rawQuery }] = useQueryParams();
2083
- const params = React.useMemo(() => buildValidParams(query), [query]);
2084
- const modified = useForm("PublishAction", ({ modified: modified2 }) => modified2);
2085
- const setSubmitting = useForm("PublishAction", ({ setSubmitting: setSubmitting2 }) => setSubmitting2);
2086
- const isSubmitting = useForm("PublishAction", ({ isSubmitting: isSubmitting2 }) => isSubmitting2);
2087
- const validate = useForm("PublishAction", (state) => state.validate);
2088
- const setErrors = useForm("PublishAction", (state) => state.setErrors);
2089
- const formValues = useForm("PublishAction", ({ values }) => values);
2090
- React.useEffect(() => {
2091
- if (isErrorDraftRelations) {
2092
- toggleNotification({
2093
- type: "danger",
2094
- message: formatMessage({
2095
- id: getTranslation("error.records.fetch-draft-relatons"),
2096
- defaultMessage: "An error occurred while fetching draft relations on this document."
2097
- })
2098
- });
2099
- }
2100
- }, [isErrorDraftRelations, toggleNotification, formatMessage]);
2101
- React.useEffect(() => {
2102
- const localDraftRelations = /* @__PURE__ */ new Set();
2103
- const extractDraftRelations = (data) => {
2104
- const relations = data.connect || [];
2105
- relations.forEach((relation) => {
2106
- if (relation.status === "draft") {
2107
- localDraftRelations.add(relation.id);
2108
- }
2109
- });
2110
- };
2111
- const traverseAndExtract = (data) => {
2112
- Object.entries(data).forEach(([key, value]) => {
2113
- if (key === "connect" && Array.isArray(value)) {
2114
- extractDraftRelations({ connect: value });
2115
- } else if (typeof value === "object" && value !== null) {
2116
- traverseAndExtract(value);
2117
- }
2118
- });
2119
- };
2120
- if (!documentId || modified) {
2121
- traverseAndExtract(formValues);
2122
- setLocalCountOfDraftRelations(localDraftRelations.size);
2123
- }
2124
- }, [documentId, modified, formValues, setLocalCountOfDraftRelations]);
2125
- React.useEffect(() => {
2126
- if (!document || !document.documentId || isListView) {
2127
- return;
2128
- }
2129
- const fetchDraftRelationsCount = async () => {
2130
- const { data, error } = await countDraftRelations({
2131
- collectionType,
2132
- model,
2133
- documentId,
2134
- params
2135
- });
2136
- if (error) {
2137
- throw error;
2138
- }
2139
- if (data) {
2140
- setServerCountOfDraftRelations(data.data);
2141
- }
2142
- };
2143
- fetchDraftRelationsCount();
2144
- }, [isListView, document, documentId, countDraftRelations, collectionType, model, params]);
2145
- const isDocumentPublished = (document?.[PUBLISHED_AT_ATTRIBUTE_NAME] || meta?.availableStatus.some((doc) => doc[PUBLISHED_AT_ATTRIBUTE_NAME] !== null)) && document?.status !== "modified";
2146
- if (!schema?.options?.draftAndPublish) {
2147
- return null;
2148
- }
2149
- const performPublish = async () => {
2150
- setSubmitting(true);
2151
- try {
2152
- const { errors } = await validate(true, {
2153
- status: "published"
2154
- });
2155
- if (errors) {
2156
- toggleNotification({
2157
- type: "danger",
2158
- message: formatMessage({
2159
- id: "content-manager.validation.error",
2160
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
2161
- })
2162
- });
2163
- return;
2164
- }
2165
- const res = await publish(
2166
- {
2167
- collectionType,
2168
- model,
2169
- documentId,
2170
- params
2171
- },
2172
- formValues
2173
- );
2174
- if ("data" in res && collectionType !== SINGLE_TYPES) {
2175
- navigate({
2176
- pathname: `../${collectionType}/${model}/${res.data.documentId}`,
2177
- search: rawQuery
2178
- });
2179
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2180
- setErrors(formatValidationErrors(res.error));
2181
- }
2182
- } finally {
2183
- setSubmitting(false);
2184
- }
2185
- };
2186
- const totalDraftRelations = localCountOfDraftRelations + serverCountOfDraftRelations;
2187
- const enableDraftRelationsCount = false;
2188
- const hasDraftRelations = enableDraftRelationsCount;
2189
- return {
2190
- /**
2191
- * Disabled when:
2192
- * - currently if you're cloning a document we don't support publish & clone at the same time.
2193
- * - the form is submitting
2194
- * - the active tab is the published tab
2195
- * - the document is already published & not modified
2196
- * - the document is being created & not modified
2197
- * - the user doesn't have the permission to publish
2198
- */
2199
- disabled: isCloning || isSubmitting || isLoadingDraftRelations || activeTab === "published" || !modified && isDocumentPublished || !modified && !document?.documentId || !canPublish,
2200
- label: formatMessage({
2201
- id: "app.utils.publish",
2202
- defaultMessage: "Publish"
2203
- }),
2204
- onClick: async () => {
2205
- await performPublish();
2206
- },
2207
- dialog: hasDraftRelations ? {
2208
- type: "dialog",
2209
- variant: "danger",
2210
- footer: null,
2211
- title: formatMessage({
2212
- id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.title`),
2213
- defaultMessage: "Confirmation"
2214
- }),
2215
- content: formatMessage(
2216
- {
2217
- id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
2218
- defaultMessage: "This entry is related to {count, plural, one {# draft entry} other {# draft entries}}. Publishing it could leave broken links in your app."
2219
- },
2220
- {
2221
- count: totalDraftRelations
2222
- }
2223
- ),
2224
- onConfirm: async () => {
2225
- await performPublish();
2226
- }
2227
- } : void 0
2228
- };
2229
- };
2230
- PublishAction$1.type = "publish";
2231
- const UpdateAction = ({
2232
- activeTab,
2233
- documentId,
2234
- model,
2235
- collectionType
2236
- }) => {
2237
- const navigate = useNavigate();
2238
- const { toggleNotification } = useNotification();
2239
- const { _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler();
2240
- const cloneMatch = useMatch(CLONE_PATH);
2241
- const isCloning = cloneMatch !== null;
2242
- const { formatMessage } = useIntl();
2243
- const { create, update, clone } = useDocumentActions();
2244
- const [{ query, rawQuery }] = useQueryParams();
2245
- const params = React.useMemo(() => buildValidParams(query), [query]);
2246
- const isSubmitting = useForm("UpdateAction", ({ isSubmitting: isSubmitting2 }) => isSubmitting2);
2247
- const modified = useForm("UpdateAction", ({ modified: modified2 }) => modified2);
2248
- const setSubmitting = useForm("UpdateAction", ({ setSubmitting: setSubmitting2 }) => setSubmitting2);
2249
- const document = useForm("UpdateAction", ({ values }) => values);
2250
- const validate = useForm("UpdateAction", (state) => state.validate);
2251
- const setErrors = useForm("UpdateAction", (state) => state.setErrors);
2252
- const resetForm = useForm("PublishAction", ({ resetForm: resetForm2 }) => resetForm2);
2253
- return {
2254
- /**
2255
- * Disabled when:
2256
- * - the form is submitting
2257
- * - the document is not modified & we're not cloning (you can save a clone entity straight away)
2258
- * - the active tab is the published tab
2259
- */
2260
- disabled: isSubmitting || !modified && !isCloning || activeTab === "published",
2261
- label: formatMessage({
2262
- id: "content-manager.containers.Edit.save",
2263
- defaultMessage: "Save"
2264
- }),
2265
- onClick: async () => {
2266
- setSubmitting(true);
2267
- try {
2268
- const { errors } = await validate(true, {
2269
- status: "draft"
2270
- });
2271
- if (errors) {
2272
- toggleNotification({
2273
- type: "danger",
2274
- message: formatMessage({
2275
- id: "content-manager.validation.error",
2276
- defaultMessage: "There are validation errors in your document. Please fix them before saving."
2277
- })
2278
- });
2279
- return;
2280
- }
2281
- if (isCloning) {
2282
- const res = await clone(
2283
- {
2284
- model,
2285
- documentId: cloneMatch.params.origin,
2286
- params
2287
- },
2288
- document
2289
- );
2290
- if ("data" in res) {
2291
- navigate(
2292
- {
2293
- pathname: `../${res.data.documentId}`,
2294
- search: rawQuery
2295
- },
2296
- { relative: "path" }
2297
- );
2298
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2299
- setErrors(formatValidationErrors(res.error));
2300
- }
2301
- } else if (documentId || collectionType === SINGLE_TYPES) {
2302
- const res = await update(
2303
- {
2304
- collectionType,
2305
- model,
2306
- documentId,
2307
- params
2308
- },
2309
- document
2310
- );
2311
- if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2312
- setErrors(formatValidationErrors(res.error));
2313
- } else {
2314
- resetForm();
2315
- }
2316
- } else {
2317
- const res = await create(
2318
- {
2319
- model,
2320
- params
2321
- },
2322
- document
2323
- );
2324
- if ("data" in res && collectionType !== SINGLE_TYPES) {
2325
- navigate(
2326
- {
2327
- pathname: `../${res.data.documentId}`,
2328
- search: rawQuery
2329
- },
2330
- { replace: true, relative: "path" }
2331
- );
2332
- } else if ("error" in res && isBaseQueryError(res.error) && res.error.name === "ValidationError") {
2333
- setErrors(formatValidationErrors(res.error));
2334
- }
2335
- }
2336
- } finally {
2337
- setSubmitting(false);
2338
- }
2339
- }
2340
- };
2341
- };
2342
- UpdateAction.type = "update";
2343
- const UNPUBLISH_DRAFT_OPTIONS = {
2344
- KEEP: "keep",
2345
- DISCARD: "discard"
2346
- };
2347
- const UnpublishAction$1 = ({
2348
- activeTab,
2349
- documentId,
2350
- model,
2351
- collectionType,
2352
- document
2353
- }) => {
2354
- const { formatMessage } = useIntl();
2355
- const { schema } = useDoc();
2356
- const canPublish = useDocumentRBAC("UnpublishAction", ({ canPublish: canPublish2 }) => canPublish2);
2357
- const { unpublish } = useDocumentActions();
2358
- const [{ query }] = useQueryParams();
2359
- const params = React.useMemo(() => buildValidParams(query), [query]);
2360
- const { toggleNotification } = useNotification();
2361
- const [shouldKeepDraft, setShouldKeepDraft] = React.useState(true);
2362
- const isDocumentModified = document?.status === "modified";
2363
- const handleChange = (value) => {
2364
- setShouldKeepDraft(value === UNPUBLISH_DRAFT_OPTIONS.KEEP);
2365
- };
2366
- if (!schema?.options?.draftAndPublish) {
2367
- return null;
2368
- }
2369
- return {
2370
- disabled: !canPublish || activeTab === "published" || document?.status !== "published" && document?.status !== "modified",
2371
- label: formatMessage({
2372
- id: "app.utils.unpublish",
2373
- defaultMessage: "Unpublish"
2374
- }),
2375
- icon: /* @__PURE__ */ jsx(Cross, {}),
2376
- onClick: async () => {
2377
- if (!documentId && collectionType !== SINGLE_TYPES || isDocumentModified) {
2378
- if (!documentId) {
2379
- console.error(
2380
- "You're trying to unpublish a document without an id, this is likely a bug with Strapi. Please open an issue."
2381
- );
2382
- toggleNotification({
2383
- message: formatMessage({
2384
- id: "content-manager.actions.unpublish.error",
2385
- defaultMessage: "An error occurred while trying to unpublish the document."
2386
- }),
2387
- type: "danger"
2388
- });
2389
- }
2390
- return;
2391
- }
2392
- await unpublish({
2393
- collectionType,
2394
- model,
2395
- documentId,
2396
- params
2397
- });
2398
- },
2399
- dialog: isDocumentModified ? {
2400
- type: "dialog",
2401
- title: formatMessage({
2402
- id: "app.components.ConfirmDialog.title",
2403
- defaultMessage: "Confirmation"
2404
- }),
2405
- content: /* @__PURE__ */ jsxs(Flex, { alignItems: "flex-start", direction: "column", gap: 6, children: [
2406
- /* @__PURE__ */ jsxs(Flex, { width: "100%", direction: "column", gap: 2, children: [
2407
- /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2408
- /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2409
- id: "content-manager.actions.unpublish.dialog.body",
2410
- defaultMessage: "Are you sure?"
2411
- }) })
2412
- ] }),
2413
- /* @__PURE__ */ jsxs(
2414
- Radio.Group,
2415
- {
2416
- defaultValue: UNPUBLISH_DRAFT_OPTIONS.KEEP,
2417
- name: "discard-options",
2418
- "aria-label": formatMessage({
2419
- id: "content-manager.actions.unpublish.dialog.radio-label",
2420
- defaultMessage: "Choose an option to unpublish the document."
2421
- }),
2422
- onValueChange: handleChange,
2423
- children: [
2424
- /* @__PURE__ */ jsx(Radio.Item, { checked: shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.KEEP, children: formatMessage({
2425
- id: "content-manager.actions.unpublish.dialog.option.keep-draft",
2426
- defaultMessage: "Keep draft"
2427
- }) }),
2428
- /* @__PURE__ */ jsx(Radio.Item, { checked: !shouldKeepDraft, value: UNPUBLISH_DRAFT_OPTIONS.DISCARD, children: formatMessage({
2429
- id: "content-manager.actions.unpublish.dialog.option.replace-draft",
2430
- defaultMessage: "Replace draft"
2431
- }) })
2432
- ]
2433
- }
2434
- )
2435
- ] }),
2436
- onConfirm: async () => {
2437
- if (!documentId && collectionType !== SINGLE_TYPES) {
2438
- console.error(
2439
- "You're trying to unpublish a document without an id, this is likely a bug with Strapi. Please open an issue."
2440
- );
2441
- toggleNotification({
2442
- message: formatMessage({
2443
- id: "content-manager.actions.unpublish.error",
2444
- defaultMessage: "An error occurred while trying to unpublish the document."
2445
- }),
2446
- type: "danger"
2447
- });
2448
- }
2449
- await unpublish(
2450
- {
2451
- collectionType,
2452
- model,
2453
- documentId,
2454
- params
2455
- },
2456
- !shouldKeepDraft
2457
- );
2458
- }
2459
- } : void 0,
2460
- variant: "danger",
2461
- position: ["panel", "table-row"]
2462
- };
2463
- };
2464
- UnpublishAction$1.type = "unpublish";
2465
- const DiscardAction = ({
2466
- activeTab,
2467
- documentId,
2468
- model,
2469
- collectionType,
2470
- document
2471
- }) => {
2472
- const { formatMessage } = useIntl();
2473
- const { schema } = useDoc();
2474
- const canUpdate = useDocumentRBAC("DiscardAction", ({ canUpdate: canUpdate2 }) => canUpdate2);
2475
- const { discard } = useDocumentActions();
2476
- const [{ query }] = useQueryParams();
2477
- const params = React.useMemo(() => buildValidParams(query), [query]);
2478
- if (!schema?.options?.draftAndPublish) {
2479
- return null;
2480
- }
2481
- return {
2482
- disabled: !canUpdate || activeTab === "published" || document?.status !== "modified",
2483
- label: formatMessage({
2484
- id: "content-manager.actions.discard.label",
2485
- defaultMessage: "Discard changes"
2486
- }),
2487
- icon: /* @__PURE__ */ jsx(Cross, {}),
2488
- position: ["panel", "table-row"],
2489
- variant: "danger",
2490
- dialog: {
2491
- type: "dialog",
2492
- title: formatMessage({
2493
- id: "app.components.ConfirmDialog.title",
2494
- defaultMessage: "Confirmation"
2495
- }),
2496
- content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2497
- /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2498
- /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2499
- id: "content-manager.actions.discard.dialog.body",
2500
- defaultMessage: "Are you sure?"
2501
- }) })
2502
- ] }),
2503
- onConfirm: async () => {
2504
- await discard({
2505
- collectionType,
2506
- model,
2507
- documentId,
2508
- params
2509
- });
2510
- }
2511
- }
2512
- };
2513
- };
2514
- DiscardAction.type = "discard";
2515
- const DEFAULT_ACTIONS = [PublishAction$1, UpdateAction, UnpublishAction$1, DiscardAction];
2516
- const intervals = ["years", "months", "days", "hours", "minutes", "seconds"];
2517
- const RelativeTime = React.forwardRef(
2518
- ({ timestamp, customIntervals = [], ...restProps }, forwardedRef) => {
2519
- const { formatRelativeTime, formatDate, formatTime } = useIntl();
2520
- const interval = intervalToDuration({
2521
- start: timestamp,
2522
- end: Date.now()
2523
- // see https://github.com/date-fns/date-fns/issues/2891 – No idea why it's all partial it returns it every time.
2524
- });
2525
- const unit = intervals.find((intervalUnit) => {
2526
- return interval[intervalUnit] > 0 && Object.keys(interval).includes(intervalUnit);
2527
- });
2528
- const relativeTime = isPast(timestamp) ? -interval[unit] : interval[unit];
2529
- const customInterval = customIntervals.find(
2530
- (custom) => interval[custom.unit] < custom.threshold
2531
- );
2532
- const displayText = customInterval ? customInterval.text : formatRelativeTime(relativeTime, unit, { numeric: "auto" });
2533
- return /* @__PURE__ */ jsx(
2534
- "time",
2535
- {
2536
- ref: forwardedRef,
2537
- dateTime: timestamp.toISOString(),
2538
- role: "time",
2539
- title: `${formatDate(timestamp)} ${formatTime(timestamp)}`,
2540
- ...restProps,
2541
- children: displayText
2542
- }
2543
- );
2544
- }
2545
- );
2546
- const getDisplayName = ({
2547
- firstname,
2548
- lastname,
2549
- username,
2550
- email
2551
- } = {}) => {
2552
- if (username) {
2553
- return username;
2554
- }
2555
- if (firstname) {
2556
- return `${firstname} ${lastname ?? ""}`.trim();
2557
- }
2558
- return email ?? "";
2559
- };
2560
- const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2561
- const DocumentStatus = ({ status = "draft", ...restProps }) => {
2562
- const statusVariant = status === "draft" ? "secondary" : status === "published" ? "success" : "alternative";
2563
- return /* @__PURE__ */ jsx(Status, { ...restProps, showBullet: false, size: "S", variant: statusVariant, children: /* @__PURE__ */ jsx(Typography, { tag: "span", variant: "omega", fontWeight: "bold", children: capitalise(status) }) });
2564
- };
2565
- const Header = ({ isCreating, status, title: documentTitle = "Untitled" }) => {
2566
- const { formatMessage } = useIntl();
2567
- const isCloning = useMatch(CLONE_PATH) !== null;
2568
- const title = isCreating ? formatMessage({
2569
- id: "content-manager.containers.edit.title.new",
2570
- defaultMessage: "Create an entry"
2571
- }) : documentTitle;
2572
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", paddingTop: 6, paddingBottom: 4, gap: 2, children: [
2573
- /* @__PURE__ */ jsx(BackButton, {}),
2574
- /* @__PURE__ */ jsxs(Flex, { width: "100%", justifyContent: "space-between", gap: "80px", alignItems: "flex-start", children: [
2575
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: title }),
2576
- /* @__PURE__ */ jsx(HeaderToolbar, {})
2577
- ] }),
2578
- status ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(DocumentStatus, { status: isCloning ? "draft" : status }) }) : null
2579
- ] });
2580
- };
2581
- const HeaderToolbar = () => {
2582
- const { formatMessage } = useIntl();
2583
- const isCloning = useMatch(CLONE_PATH) !== null;
2584
- const [
2585
- {
2586
- query: { status = "draft" }
2587
- }
2588
- ] = useQueryParams();
2589
- const { model, id, document, meta, collectionType } = useDoc();
2590
- const plugins = useStrapiApp("HeaderToolbar", (state) => state.plugins);
2591
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
2592
- /* @__PURE__ */ jsx(
2593
- DescriptionComponentRenderer,
2594
- {
2595
- props: {
2596
- activeTab: status,
2597
- model,
2598
- documentId: id,
2599
- document: isCloning ? void 0 : document,
2600
- meta: isCloning ? void 0 : meta,
2601
- collectionType
2602
- },
2603
- descriptions: plugins["content-manager"].apis.getHeaderActions(),
2604
- children: (actions2) => {
2605
- if (actions2.length > 0) {
2606
- return /* @__PURE__ */ jsx(HeaderActions, { actions: actions2 });
2607
- } else {
2608
- return null;
2609
- }
2610
- }
2611
- }
2612
- ),
2613
- /* @__PURE__ */ jsx(
2614
- DescriptionComponentRenderer,
2615
- {
2616
- props: {
2617
- activeTab: status,
2618
- model,
2619
- documentId: id,
2620
- document: isCloning ? void 0 : document,
2621
- meta: isCloning ? void 0 : meta,
2622
- collectionType
2623
- },
2624
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2625
- children: (actions2) => {
2626
- const headerActions = actions2.filter((action) => {
2627
- const positions = Array.isArray(action.position) ? action.position : [action.position];
2628
- return positions.includes("header");
2629
- });
2630
- return /* @__PURE__ */ jsx(
2631
- DocumentActionsMenu,
2632
- {
2633
- actions: headerActions,
2634
- label: formatMessage({
2635
- id: "content-manager.containers.edit.header.more-actions",
2636
- defaultMessage: "More actions"
2637
- }),
2638
- children: /* @__PURE__ */ jsx(Information, { activeTab: status })
2639
- }
2640
- );
2641
- }
2642
- }
2643
- )
2644
- ] });
2645
- };
2646
- const Information = ({ activeTab }) => {
2647
- const { formatMessage } = useIntl();
2648
- const { document, meta } = useDoc();
2649
- if (!document || !document.id) {
2650
- return null;
2651
- }
2652
- const createAndUpdateDocument = activeTab === "draft" ? document : meta?.availableStatus.find((status) => status.publishedAt === null);
2653
- const publishDocument = activeTab === "published" ? document : meta?.availableStatus.find((status) => status.publishedAt !== null);
2654
- const creator = createAndUpdateDocument?.[CREATED_BY_ATTRIBUTE_NAME] ? getDisplayName(createAndUpdateDocument[CREATED_BY_ATTRIBUTE_NAME]) : null;
2655
- const updator = createAndUpdateDocument?.[UPDATED_BY_ATTRIBUTE_NAME] ? getDisplayName(createAndUpdateDocument[UPDATED_BY_ATTRIBUTE_NAME]) : null;
2656
- const information = [
2657
- {
2658
- isDisplayed: !!publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME],
2659
- label: formatMessage({
2660
- id: "content-manager.containers.edit.information.last-published.label",
2661
- defaultMessage: "Published"
2662
- }),
2663
- value: formatMessage(
2664
- {
2665
- id: "content-manager.containers.edit.information.last-published.value",
2666
- defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2667
- },
2668
- {
2669
- time: /* @__PURE__ */ jsx(RelativeTime, { timestamp: new Date(publishDocument?.[PUBLISHED_AT_ATTRIBUTE_NAME]) }),
2670
- isAnonymous: !publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME],
2671
- author: publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME] ? getDisplayName(publishDocument?.[PUBLISHED_BY_ATTRIBUTE_NAME]) : null
2672
- }
2673
- )
2674
- },
2675
- {
2676
- isDisplayed: !!createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME],
2677
- label: formatMessage({
2678
- id: "content-manager.containers.edit.information.last-draft.label",
2679
- defaultMessage: "Updated"
2680
- }),
2681
- value: formatMessage(
2682
- {
2683
- id: "content-manager.containers.edit.information.last-draft.value",
2684
- defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2685
- },
2686
- {
2687
- time: /* @__PURE__ */ jsx(
2688
- RelativeTime,
2689
- {
2690
- timestamp: new Date(createAndUpdateDocument?.[UPDATED_AT_ATTRIBUTE_NAME])
2691
- }
2692
- ),
2693
- isAnonymous: !updator,
2694
- author: updator
2695
- }
2696
- )
2697
- },
2698
- {
2699
- isDisplayed: !!createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME],
2700
- label: formatMessage({
2701
- id: "content-manager.containers.edit.information.document.label",
2702
- defaultMessage: "Created"
2703
- }),
2704
- value: formatMessage(
2705
- {
2706
- id: "content-manager.containers.edit.information.document.value",
2707
- defaultMessage: `{time}{isAnonymous, select, true {} other { by {author}}}`
2708
- },
2709
- {
2710
- time: /* @__PURE__ */ jsx(
2711
- RelativeTime,
2712
- {
2713
- timestamp: new Date(createAndUpdateDocument?.[CREATED_AT_ATTRIBUTE_NAME])
2714
- }
2715
- ),
2716
- isAnonymous: !creator,
2717
- author: creator
2718
- }
2719
- )
2720
- }
2721
- ].filter((info) => info.isDisplayed);
2722
- return /* @__PURE__ */ jsx(
2723
- Flex,
2724
- {
2725
- borderWidth: "1px 0 0 0",
2726
- borderStyle: "solid",
2727
- borderColor: "neutral150",
2728
- direction: "column",
2729
- marginTop: 2,
2730
- tag: "dl",
2731
- padding: 5,
2732
- gap: 3,
2733
- alignItems: "flex-start",
2734
- marginLeft: "-0.4rem",
2735
- marginRight: "-0.4rem",
2736
- width: "calc(100% + 8px)",
2737
- children: information.map((info) => /* @__PURE__ */ jsxs(Flex, { gap: 1, direction: "column", alignItems: "flex-start", children: [
2738
- /* @__PURE__ */ jsx(Typography, { tag: "dt", variant: "pi", fontWeight: "bold", children: info.label }),
2739
- /* @__PURE__ */ jsx(Typography, { tag: "dd", variant: "pi", textColor: "neutral600", children: info.value })
2740
- ] }, info.label))
2741
- }
2742
- );
2743
- };
2744
- const HeaderActions = ({ actions: actions2 }) => {
2745
- const [dialogId, setDialogId] = React.useState(null);
2746
- const handleClick = (action) => async (e) => {
2747
- if (!("options" in action)) {
2748
- const { onClick = () => false, dialog, id } = action;
2749
- const muteDialog = await onClick(e);
2750
- if (dialog && !muteDialog) {
2751
- e.preventDefault();
2752
- setDialogId(id);
2753
- }
2754
- }
2755
- };
2756
- const handleClose = () => {
2757
- setDialogId(null);
2758
- };
2759
- return /* @__PURE__ */ jsx(Flex, { gap: 1, children: actions2.map((action) => {
2760
- if (action.options) {
2761
- return /* @__PURE__ */ jsx(
2762
- SingleSelect,
2763
- {
2764
- size: "S",
2765
- onChange: action.onSelect,
2766
- "aria-label": action.label,
2767
- ...action,
2768
- children: action.options.map(({ label, ...option }) => /* @__PURE__ */ jsx(SingleSelectOption, { ...option, children: label }, option.value))
2769
- },
2770
- action.id
2771
- );
2772
- } else {
2773
- if (action.type === "icon") {
2774
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
2775
- /* @__PURE__ */ jsx(
2776
- IconButton,
2777
- {
2778
- disabled: action.disabled,
2779
- label: action.label,
2780
- size: "S",
2781
- onClick: handleClick(action),
2782
- children: action.icon
2783
- }
2784
- ),
2785
- action.dialog ? /* @__PURE__ */ jsx(
2786
- HeaderActionDialog,
2787
- {
2788
- ...action.dialog,
2789
- isOpen: dialogId === action.id,
2790
- onClose: handleClose
2791
- }
2792
- ) : null
2793
- ] }, action.id);
2794
- }
2795
- }
2796
- }) });
2797
- };
2798
- const HeaderActionDialog = ({
2799
- onClose,
2800
- onCancel,
2801
- title,
2802
- content: Content,
2803
- isOpen
2804
- }) => {
2805
- const handleClose = async () => {
2806
- if (onCancel) {
2807
- await onCancel();
2808
- }
2809
- onClose();
2810
- };
2811
- return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
2812
- /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
2813
- typeof Content === "function" ? /* @__PURE__ */ jsx(Content, { onClose: handleClose }) : Content
2814
- ] }) });
2815
- };
2816
- const ConfigureTheViewAction = ({ collectionType, model }) => {
2817
- const navigate = useNavigate();
2818
- const { formatMessage } = useIntl();
2819
- return {
2820
- label: formatMessage({
2821
- id: "app.links.configure-view",
2822
- defaultMessage: "Configure the view"
2823
- }),
2824
- icon: /* @__PURE__ */ jsx(ListPlus, {}),
2825
- onClick: () => {
2826
- navigate(`../${collectionType}/${model}/configurations/edit`);
2827
- },
2828
- position: "header"
2829
- };
2830
- };
2831
- ConfigureTheViewAction.type = "configure-the-view";
2832
- const EditTheModelAction = ({ model }) => {
2833
- const navigate = useNavigate();
2834
- const { formatMessage } = useIntl();
2835
- return {
2836
- label: formatMessage({
2837
- id: "content-manager.link-to-ctb",
2838
- defaultMessage: "Edit the model"
2839
- }),
2840
- icon: /* @__PURE__ */ jsx(Pencil, {}),
2841
- onClick: () => {
2842
- navigate(`/plugins/content-type-builder/content-types/${model}`);
2843
- },
2844
- position: "header"
2845
- };
2846
- };
2847
- EditTheModelAction.type = "edit-the-model";
2848
- const DeleteAction$1 = ({ documentId, model, collectionType, document }) => {
2849
- const navigate = useNavigate();
2850
- const { formatMessage } = useIntl();
2851
- const listViewPathMatch = useMatch(LIST_PATH);
2852
- const canDelete = useDocumentRBAC("DeleteAction", (state) => state.canDelete);
2853
- const { delete: deleteAction } = useDocumentActions();
2854
- const { toggleNotification } = useNotification();
2855
- const setSubmitting = useForm("DeleteAction", (state) => state.setSubmitting);
2856
- const isLocalized = document?.locale != null;
2857
- return {
2858
- disabled: !canDelete || !document,
2859
- label: formatMessage(
2860
- {
2861
- id: "content-manager.actions.delete.label",
2862
- defaultMessage: "Delete entry{isLocalized, select, true { (all locales)} other {}}"
2863
- },
2864
- { isLocalized }
2865
- ),
2866
- icon: /* @__PURE__ */ jsx(Trash, {}),
2867
- dialog: {
2868
- type: "dialog",
2869
- title: formatMessage({
2870
- id: "app.components.ConfirmDialog.title",
2871
- defaultMessage: "Confirmation"
2872
- }),
2873
- content: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
2874
- /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }),
2875
- /* @__PURE__ */ jsx(Typography, { tag: "p", variant: "omega", textAlign: "center", children: formatMessage({
2876
- id: "content-manager.actions.delete.dialog.body",
2877
- defaultMessage: "Are you sure?"
2878
- }) })
2879
- ] }),
2880
- onConfirm: async () => {
2881
- if (!listViewPathMatch) {
2882
- setSubmitting(true);
2883
- }
2884
- try {
2885
- if (!documentId && collectionType !== SINGLE_TYPES) {
2886
- console.error(
2887
- "You're trying to delete a document without an id, this is likely a bug with Strapi. Please open an issue."
2888
- );
2889
- toggleNotification({
2890
- message: formatMessage({
2891
- id: "content-manager.actions.delete.error",
2892
- defaultMessage: "An error occurred while trying to delete the document."
2893
- }),
2894
- type: "danger"
2895
- });
2896
- return;
2897
- }
2898
- const res = await deleteAction({
2899
- documentId,
2900
- model,
2901
- collectionType,
2902
- params: {
2903
- locale: "*"
2904
- }
2905
- });
2906
- if (!("error" in res)) {
2907
- navigate({ pathname: `../${collectionType}/${model}` }, { replace: true });
2908
- }
2909
- } finally {
2910
- if (!listViewPathMatch) {
2911
- setSubmitting(false);
2912
- }
2913
- }
2914
- }
2915
- },
2916
- variant: "danger",
2917
- position: ["header", "table-row"]
2918
- };
2919
- };
2920
- DeleteAction$1.type = "delete";
2921
- const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction$1];
2922
- const Panels = () => {
2923
- const isCloning = useMatch(CLONE_PATH) !== null;
2924
- const [
2925
- {
2926
- query: { status }
2927
- }
2928
- ] = useQueryParams({
2929
- status: "draft"
2930
- });
2931
- const { model, id, document, meta, collectionType } = useDoc();
2932
- const plugins = useStrapiApp("Panels", (state) => state.plugins);
2933
- const props = {
2934
- activeTab: status,
2935
- model,
2936
- documentId: id,
2937
- document: isCloning ? void 0 : document,
2938
- meta: isCloning ? void 0 : meta,
2939
- collectionType
2940
- };
2941
- return /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: /* @__PURE__ */ jsx(
2942
- DescriptionComponentRenderer,
2943
- {
2944
- props,
2945
- descriptions: plugins["content-manager"].apis.getEditViewSidePanels(),
2946
- children: (panels) => panels.map(({ content, id: id2, ...description }) => /* @__PURE__ */ jsx(Panel, { ...description, children: content }, id2))
2947
- }
2948
- ) });
2949
- };
2950
- const ActionsPanel = () => {
2951
- const { formatMessage } = useIntl();
2952
- return {
2953
- title: formatMessage({
2954
- id: "content-manager.containers.edit.panels.default.title",
2955
- defaultMessage: "Entry"
2956
- }),
2957
- content: /* @__PURE__ */ jsx(ActionsPanelContent, {})
2958
- };
2959
- };
2960
- ActionsPanel.type = "actions";
2961
- const ActionsPanelContent = () => {
2962
- const isCloning = useMatch(CLONE_PATH) !== null;
2963
- const [
2964
- {
2965
- query: { status = "draft" }
2966
- }
2967
- ] = useQueryParams();
2968
- const { model, id, document, meta, collectionType } = useDoc();
2969
- const plugins = useStrapiApp("ActionsPanel", (state) => state.plugins);
2970
- const props = {
2971
- activeTab: status,
2972
- model,
2973
- documentId: id,
2974
- document: isCloning ? void 0 : document,
2975
- meta: isCloning ? void 0 : meta,
2976
- collectionType
2977
- };
2978
- return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
2979
- /* @__PURE__ */ jsx(
2980
- DescriptionComponentRenderer,
2981
- {
2982
- props,
2983
- descriptions: plugins["content-manager"].apis.getDocumentActions(),
2984
- children: (actions2) => /* @__PURE__ */ jsx(DocumentActions, { actions: actions2 })
2985
- }
2986
- ),
2987
- /* @__PURE__ */ jsx(InjectionZone, { area: "editView.right-links", slug: model })
2988
- ] });
2989
- };
2990
- const Panel = React.forwardRef(({ children, title }, ref) => {
2991
- return /* @__PURE__ */ jsxs(
2992
- Flex,
2993
- {
2994
- ref,
2995
- tag: "aside",
2996
- "aria-labelledby": "additional-information",
2997
- background: "neutral0",
2998
- borderColor: "neutral150",
2999
- hasRadius: true,
3000
- paddingBottom: 4,
3001
- paddingLeft: 4,
3002
- paddingRight: 4,
3003
- paddingTop: 4,
3004
- shadow: "tableShadow",
3005
- gap: 3,
3006
- direction: "column",
3007
- justifyContent: "stretch",
3008
- alignItems: "flex-start",
3009
- children: [
3010
- /* @__PURE__ */ jsx(Typography, { tag: "h2", variant: "sigma", textTransform: "uppercase", children: title }),
3011
- children
3012
- ]
3013
- }
3014
- );
3015
- });
3016
- const ConfirmBulkActionDialog = ({
3017
- onToggleDialog,
3018
- isOpen = false,
3019
- dialogBody,
3020
- endAction
3021
- }) => {
3022
- const { formatMessage } = useIntl();
3023
- return /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
3024
- /* @__PURE__ */ jsx(Dialog.Header, { children: formatMessage({
3025
- id: "app.components.ConfirmDialog.title",
3026
- defaultMessage: "Confirmation"
3027
- }) }),
3028
- /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3029
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3030
- dialogBody
3031
- ] }) }),
3032
- /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
3033
- /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, onClick: onToggleDialog, variant: "tertiary", children: formatMessage({
3034
- id: "app.components.Button.cancel",
3035
- defaultMessage: "Cancel"
3036
- }) }) }),
3037
- endAction
3038
- ] })
3039
- ] }) });
3040
- };
3041
- const BoldChunk$1 = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3042
- const ConfirmDialogPublishAll = ({
3043
- isOpen,
3044
- onToggleDialog,
3045
- isConfirmButtonLoading = false,
3046
- onConfirm
3047
- }) => {
3048
- const { formatMessage } = useIntl();
3049
- const selectedEntries = useTable("ConfirmDialogPublishAll", (state) => state.selectedRows);
3050
- const { toggleNotification } = useNotification();
3051
- const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler(getTranslation);
3052
- const { model, schema } = useDoc();
3053
- const [{ query }] = useQueryParams();
3054
- const enableDraftRelationsCount = false;
3055
- const {
3056
- data: countDraftRelations = 0,
3057
- isLoading,
3058
- error
3059
- } = useGetManyDraftRelationCountQuery(
3060
- {
3061
- model,
3062
- documentIds: selectedEntries.map((entry) => entry.documentId),
3063
- locale: query?.plugins?.i18n?.locale
3064
- },
3065
- {
3066
- skip: !enableDraftRelationsCount
3067
- }
3068
- );
3069
- React.useEffect(() => {
3070
- if (error) {
3071
- toggleNotification({ type: "danger", message: formatAPIError(error) });
3072
- }
3073
- }, [error, formatAPIError, toggleNotification]);
3074
- if (error) {
3075
- return null;
3076
- }
3077
- return /* @__PURE__ */ jsx(
3078
- ConfirmBulkActionDialog,
3079
- {
3080
- isOpen: isOpen && !isLoading,
3081
- onToggleDialog,
3082
- dialogBody: /* @__PURE__ */ jsxs(Fragment, { children: [
3083
- /* @__PURE__ */ jsxs(Typography, { id: "confirm-description", textAlign: "center", children: [
3084
- countDraftRelations > 0 && formatMessage(
3085
- {
3086
- id: getTranslation(`popUpwarning.warning.bulk-has-draft-relations.message`),
3087
- defaultMessage: "<b>{count} {count, plural, one { relation } other { relations } } out of {entities} { entities, plural, one { entry } other { entries } } {count, plural, one { is } other { are } }</b> not published yet and might lead to unexpected behavior. "
3088
- },
3089
- {
3090
- b: BoldChunk$1,
3091
- count: countDraftRelations,
3092
- entities: selectedEntries.length
3093
- }
3094
- ),
3095
- formatMessage({
3096
- id: getTranslation("popUpWarning.bodyMessage.contentType.publish.all"),
3097
- defaultMessage: "Are you sure you want to publish these entries?"
3098
- })
3099
- ] }),
3100
- schema?.pluginOptions && "i18n" in schema.pluginOptions && schema?.pluginOptions.i18n && /* @__PURE__ */ jsx(Typography, { textColor: "danger500", textAlign: "center", children: formatMessage(
3101
- {
3102
- id: getTranslation("Settings.list.actions.publishAdditionalInfos"),
3103
- defaultMessage: "This will publish the active locale versions <em>(from Internationalization)</em>"
3104
- },
3105
- {
3106
- em: Emphasis
3107
- }
3108
- ) })
3109
- ] }),
3110
- endAction: /* @__PURE__ */ jsx(
3111
- Button,
3112
- {
3113
- onClick: onConfirm,
3114
- variant: "secondary",
3115
- startIcon: /* @__PURE__ */ jsx(Check, {}),
3116
- loading: isConfirmButtonLoading,
3117
- children: formatMessage({
3118
- id: "app.utils.publish",
3119
- defaultMessage: "Publish"
3120
- })
3121
- }
3122
- )
3123
- }
3124
- );
3125
- };
3126
- const TypographyMaxWidth = styled(Typography)`
3127
- max-width: 300px;
3128
- `;
3129
- const formatErrorMessages = (errors, parentKey, formatMessage) => {
3130
- const messages = [];
3131
- Object.entries(errors).forEach(([key, value]) => {
3132
- const currentKey = parentKey ? `${parentKey}.${key}` : key;
3133
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3134
- if ("id" in value && "defaultMessage" in value) {
3135
- messages.push(
3136
- formatMessage(
3137
- {
3138
- id: `${value.id}.withField`,
3139
- defaultMessage: value.defaultMessage
3140
- },
3141
- { field: currentKey }
3142
- )
3143
- );
3144
- } else {
3145
- messages.push(
3146
- ...formatErrorMessages(
3147
- // @ts-expect-error TODO: check why value is not compatible with FormErrors
3148
- value,
3149
- currentKey,
3150
- formatMessage
3151
- )
3152
- );
3153
- }
3154
- } else {
3155
- messages.push(
3156
- formatMessage(
3157
- {
3158
- id: `${value}.withField`,
3159
- defaultMessage: value
3160
- },
3161
- { field: currentKey }
3162
- )
3163
- );
3164
- }
3165
- });
3166
- return messages;
3167
- };
3168
- const EntryValidationText = ({ validationErrors, status }) => {
3169
- const { formatMessage } = useIntl();
3170
- if (validationErrors) {
3171
- const validationErrorsMessages = formatErrorMessages(validationErrors, "", formatMessage).join(
3172
- " "
3173
- );
3174
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3175
- /* @__PURE__ */ jsx(CrossCircle, { fill: "danger600" }),
3176
- /* @__PURE__ */ jsx(Tooltip, { description: validationErrorsMessages, children: /* @__PURE__ */ jsx(TypographyMaxWidth, { textColor: "danger600", variant: "omega", fontWeight: "semiBold", ellipsis: true, children: validationErrorsMessages }) })
3177
- ] });
3178
- }
3179
- if (status === "published") {
3180
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3181
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
3182
- /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "bold", children: formatMessage({
3183
- id: "content-manager.bulk-publish.already-published",
3184
- defaultMessage: "Already Published"
3185
- }) })
3186
- ] });
3187
- }
3188
- if (status === "modified") {
3189
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3190
- /* @__PURE__ */ jsx(ArrowsCounterClockwise, { fill: "alternative600" }),
3191
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
3192
- id: "content-manager.bulk-publish.modified",
3193
- defaultMessage: "Ready to publish changes"
3194
- }) })
3195
- ] });
3196
- }
3197
- return /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3198
- /* @__PURE__ */ jsx(CheckCircle, { fill: "success600" }),
3199
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
3200
- id: "app.utils.ready-to-publish",
3201
- defaultMessage: "Ready to publish"
3202
- }) })
3203
- ] });
3204
- };
3205
- const TABLE_HEADERS = [
3206
- { name: "id", label: "id" },
3207
- { name: "name", label: "name" },
3208
- { name: "status", label: "status" },
3209
- { name: "publicationStatus", label: "Publication status" }
3210
- ];
3211
- const SelectedEntriesTableContent = ({
3212
- isPublishing,
3213
- rowsToDisplay = [],
3214
- entriesToPublish = [],
3215
- validationErrors = {}
3216
- }) => {
3217
- const { pathname } = useLocation();
3218
- const { formatMessage } = useIntl();
3219
- const {
3220
- list: {
3221
- settings: { mainField }
3222
- }
3223
- } = useDocLayout();
3224
- const shouldDisplayMainField = mainField != null && mainField !== "id";
3225
- return /* @__PURE__ */ jsxs(Table.Content, { children: [
3226
- /* @__PURE__ */ jsxs(Table.Head, { children: [
3227
- /* @__PURE__ */ jsx(Table.HeaderCheckboxCell, {}),
3228
- TABLE_HEADERS.filter((head) => head.name !== "name" || shouldDisplayMainField).map(
3229
- (head) => /* @__PURE__ */ jsx(Table.HeaderCell, { ...head }, head.name)
3230
- )
3231
- ] }),
3232
- /* @__PURE__ */ jsx(Table.Loading, {}),
3233
- /* @__PURE__ */ jsx(Table.Body, { children: rowsToDisplay.map((row, index2) => /* @__PURE__ */ jsxs(Table.Row, { children: [
3234
- /* @__PURE__ */ jsx(Table.CheckboxCell, { id: row.id }),
3235
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row.id }) }),
3236
- shouldDisplayMainField && /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Typography, { children: row[mainField] }) }),
3237
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(DocumentStatus, { status: row.status, maxWidth: "min-content" }) }),
3238
- /* @__PURE__ */ jsx(Table.Cell, { children: isPublishing && entriesToPublish.includes(row.documentId) ? /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3239
- /* @__PURE__ */ jsx(Typography, { children: formatMessage({
3240
- id: "content-manager.success.record.publishing",
3241
- defaultMessage: "Publishing..."
3242
- }) }),
3243
- /* @__PURE__ */ jsx(Loader, { small: true })
3244
- ] }) : /* @__PURE__ */ jsx(
3245
- EntryValidationText,
3246
- {
3247
- validationErrors: validationErrors[row.documentId],
3248
- status: row.status
3249
- }
3250
- ) }),
3251
- /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(
3252
- IconButton,
3253
- {
3254
- tag: Link,
3255
- to: {
3256
- pathname: `${pathname}/${row.documentId}`,
3257
- search: row.locale && `?plugins[i18n][locale]=${row.locale}`
3258
- },
3259
- state: { from: pathname },
3260
- label: formatMessage(
3261
- { id: "app.component.HelperPluginTable.edit", defaultMessage: "Edit {target}" },
3262
- {
3263
- target: formatMessage(
3264
- {
3265
- id: "content-manager.components.ListViewHelperPluginTable.row-line",
3266
- defaultMessage: "item line {number}"
3267
- },
3268
- { number: index2 + 1 }
3269
- )
3270
- }
3271
- ),
3272
- target: "_blank",
3273
- marginLeft: "auto",
3274
- variant: "ghost",
3275
- children: /* @__PURE__ */ jsx(Pencil, { width: "1.6rem", height: "1.6rem" })
3276
- }
3277
- ) }) })
3278
- ] }, row.id)) })
3279
- ] });
3280
- };
3281
- const BoldChunk = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: chunks });
3282
- const SelectedEntriesModalContent = ({
3283
- listViewSelectedEntries,
3284
- toggleModal,
3285
- setListViewSelectedDocuments,
3286
- model
3287
- }) => {
3288
- const { formatMessage } = useIntl();
3289
- const { schema, components } = useContentTypeSchema(model);
3290
- const documentIds = listViewSelectedEntries.map(({ documentId }) => documentId);
3291
- const [{ query }] = useQueryParams();
3292
- const params = React.useMemo(() => buildValidParams(query), [query]);
3293
- const { data, isLoading, isFetching, refetch } = useGetAllDocumentsQuery(
3294
- {
3295
- model,
3296
- params: {
3297
- page: "1",
3298
- pageSize: documentIds.length.toString(),
3299
- sort: query.sort,
3300
- filters: {
3301
- documentId: {
3302
- $in: documentIds
3303
- }
3304
- },
3305
- locale: query.plugins?.i18n?.locale
3306
- }
3307
- },
3308
- {
3309
- selectFromResult: ({ data: data2, ...restRes }) => ({ data: data2?.results ?? [], ...restRes })
3310
- }
3311
- );
3312
- const { rows, validationErrors } = React.useMemo(() => {
3313
- if (data.length > 0 && schema) {
3314
- const validate = createYupSchema(
3315
- schema.attributes,
3316
- components,
3317
- // Since this is the "Publish" action, the validation
3318
- // schema must enforce the rules for published entities
3319
- { status: "published" }
3320
- );
3321
- const validationErrors2 = {};
3322
- const rows2 = data.map((entry) => {
3323
- try {
3324
- validate.validateSync(entry, { abortEarly: false });
3325
- return entry;
3326
- } catch (e) {
3327
- if (e instanceof ValidationError) {
3328
- validationErrors2[entry.documentId] = getYupValidationErrors(e);
3329
- }
3330
- return entry;
3331
- }
3332
- });
3333
- return { rows: rows2, validationErrors: validationErrors2 };
3334
- }
3335
- return {
3336
- rows: [],
3337
- validationErrors: {}
3338
- };
3339
- }, [components, data, schema]);
3340
- const [publishedCount, setPublishedCount] = React.useState(0);
3341
- const [isDialogOpen, setIsDialogOpen] = React.useState(false);
3342
- const { publishMany: bulkPublishAction } = useDocumentActions();
3343
- const [, { isLoading: isSubmittingForm }] = usePublishManyDocumentsMutation();
3344
- const selectedRows = useTable("publishAction", (state) => state.selectedRows);
3345
- const selectedEntries = rows.filter(
3346
- (entry) => selectedRows.some((selectedEntry) => selectedEntry.documentId === entry.documentId)
3347
- );
3348
- const entriesToPublish = selectedEntries.filter((entry) => !validationErrors[entry.documentId]).map((entry) => entry.documentId);
3349
- const selectedEntriesWithErrorsCount = selectedEntries.filter(
3350
- ({ documentId }) => validationErrors[documentId]
3351
- ).length;
3352
- const selectedEntriesPublished = selectedEntries.filter(
3353
- ({ status }) => status === "published"
3354
- ).length;
3355
- const selectedEntriesWithNoErrorsCount = selectedEntries.length - selectedEntriesWithErrorsCount - selectedEntriesPublished;
3356
- const toggleDialog = () => setIsDialogOpen((prev) => !prev);
3357
- const handleConfirmBulkPublish = async () => {
3358
- toggleDialog();
3359
- const res = await bulkPublishAction({ model, documentIds: entriesToPublish, params });
3360
- if (!("error" in res)) {
3361
- setPublishedCount(res.count);
3362
- const unpublishedEntries = rows.filter((row) => {
3363
- return !entriesToPublish.includes(row.documentId);
3364
- });
3365
- setListViewSelectedDocuments(unpublishedEntries);
3366
- }
3367
- };
3368
- const getFormattedCountMessage = () => {
3369
- if (publishedCount) {
3370
- return formatMessage(
3371
- {
3372
- id: getTranslation("containers.list.selectedEntriesModal.publishedCount"),
3373
- defaultMessage: "<b>{publishedCount}</b> {publishedCount, plural, =0 {entries} one {entry} other {entries}} published. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3374
- },
3375
- {
3376
- publishedCount,
3377
- withErrorsCount: selectedEntriesWithErrorsCount,
3378
- b: BoldChunk
3379
- }
3380
- );
3381
- }
3382
- return formatMessage(
3383
- {
3384
- id: getTranslation("containers.list.selectedEntriesModal.selectedCount"),
3385
- defaultMessage: "<b>{alreadyPublishedCount}</b> {alreadyPublishedCount, plural, =0 {entries} one {entry} other {entries}} already published. <b>{readyToPublishCount}</b> {readyToPublishCount, plural, =0 {entries} one {entry} other {entries}} ready to publish. <b>{withErrorsCount}</b> {withErrorsCount, plural, =0 {entries} one {entry} other {entries}} waiting for action."
3386
- },
3387
- {
3388
- readyToPublishCount: selectedEntriesWithNoErrorsCount,
3389
- withErrorsCount: selectedEntriesWithErrorsCount,
3390
- alreadyPublishedCount: selectedEntriesPublished,
3391
- b: BoldChunk
3392
- }
3393
- );
3394
- };
3395
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3396
- /* @__PURE__ */ jsxs(Modal.Body, { children: [
3397
- /* @__PURE__ */ jsx(Typography, { children: getFormattedCountMessage() }),
3398
- /* @__PURE__ */ jsx(Box, { marginTop: 5, children: /* @__PURE__ */ jsx(
3399
- SelectedEntriesTableContent,
3400
- {
3401
- isPublishing: isSubmittingForm,
3402
- rowsToDisplay: rows,
3403
- entriesToPublish,
3404
- validationErrors
3405
- }
3406
- ) })
3407
- ] }),
3408
- /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3409
- /* @__PURE__ */ jsx(Button, { onClick: toggleModal, variant: "tertiary", children: formatMessage({
3410
- id: "app.components.Button.cancel",
3411
- defaultMessage: "Cancel"
3412
- }) }),
3413
- /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
3414
- /* @__PURE__ */ jsx(Button, { onClick: refetch, variant: "tertiary", loading: isFetching, children: formatMessage({ id: "app.utils.refresh", defaultMessage: "Refresh" }) }),
3415
- /* @__PURE__ */ jsx(
3416
- Button,
3417
- {
3418
- onClick: toggleDialog,
3419
- disabled: selectedEntries.length === 0 || selectedEntries.length === selectedEntriesWithErrorsCount || selectedEntriesPublished === selectedEntries.length || isLoading,
3420
- loading: isSubmittingForm,
3421
- children: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" })
3422
- }
3423
- )
3424
- ] })
3425
- ] }),
3426
- /* @__PURE__ */ jsx(
3427
- ConfirmDialogPublishAll,
3428
- {
3429
- isOpen: isDialogOpen,
3430
- onToggleDialog: toggleDialog,
3431
- isConfirmButtonLoading: isSubmittingForm,
3432
- onConfirm: handleConfirmBulkPublish
3433
- }
3434
- )
3435
- ] });
3436
- };
3437
- const PublishAction = ({ documents, model }) => {
3438
- const { formatMessage } = useIntl();
3439
- const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3440
- const showPublishButton = hasPublishPermission && documents.some(({ status }) => status !== "published");
3441
- const setListViewSelectedDocuments = useTable("publishAction", (state) => state.selectRow);
3442
- const refetchList = () => {
3443
- contentManagerApi.util.invalidateTags([{ type: "Document", id: `${model}_LIST` }]);
3444
- };
3445
- if (!showPublishButton)
3446
- return null;
3447
- return {
3448
- actionType: "publish",
3449
- variant: "tertiary",
3450
- label: formatMessage({ id: "app.utils.publish", defaultMessage: "Publish" }),
3451
- dialog: {
3452
- type: "modal",
3453
- title: formatMessage({
3454
- id: getTranslation("containers.ListPage.selectedEntriesModal.title"),
3455
- defaultMessage: "Publish entries"
3456
- }),
3457
- content: ({ onClose }) => {
3458
- return /* @__PURE__ */ jsx(Table.Root, { rows: documents, defaultSelectedRows: documents, headers: TABLE_HEADERS, children: /* @__PURE__ */ jsx(
3459
- SelectedEntriesModalContent,
3460
- {
3461
- listViewSelectedEntries: documents,
3462
- toggleModal: () => {
3463
- onClose();
3464
- refetchList();
3465
- },
3466
- setListViewSelectedDocuments,
3467
- model
3468
- }
3469
- ) });
3470
- },
3471
- onClose: () => {
3472
- refetchList();
3473
- }
3474
- }
3475
- };
3476
- };
3477
- const BulkActionsRenderer = () => {
3478
- const plugins = useStrapiApp("BulkActionsRenderer", (state) => state.plugins);
3479
- const { model, collectionType } = useDoc();
3480
- const { selectedRows } = useTable("BulkActionsRenderer", (state) => state);
3481
- return /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(
3482
- DescriptionComponentRenderer,
3483
- {
3484
- props: {
3485
- model,
3486
- collectionType,
3487
- documents: selectedRows
3488
- },
3489
- descriptions: plugins["content-manager"].apis.getBulkActions(),
3490
- children: (actions2) => actions2.map((action) => /* @__PURE__ */ jsx(DocumentActionButton, { ...action }, action.id))
3491
- }
3492
- ) });
3493
- };
3494
- const DeleteAction = ({ documents, model }) => {
3495
- const { formatMessage } = useIntl();
3496
- const { schema: contentType } = useDoc();
3497
- const selectRow = useTable("DeleteAction", (state) => state.selectRow);
3498
- const hasI18nEnabled = Boolean(contentType?.pluginOptions?.i18n);
3499
- const [{ query }] = useQueryParams();
3500
- const params = React.useMemo(() => buildValidParams(query), [query]);
3501
- const hasDeletePermission = useDocumentRBAC("deleteAction", (state) => state.canDelete);
3502
- const { deleteMany: bulkDeleteAction } = useDocumentActions();
3503
- const documentIds = documents.map(({ documentId }) => documentId);
3504
- const handleConfirmBulkDelete = async () => {
3505
- const res = await bulkDeleteAction({
3506
- documentIds,
3507
- model,
3508
- params
3509
- });
3510
- if (!("error" in res)) {
3511
- selectRow([]);
3512
- }
3513
- };
3514
- if (!hasDeletePermission)
3515
- return null;
3516
- return {
3517
- variant: "danger-light",
3518
- label: formatMessage({ id: "global.delete", defaultMessage: "Delete" }),
3519
- dialog: {
3520
- type: "dialog",
3521
- title: formatMessage({
3522
- id: "app.components.ConfirmDialog.title",
3523
- defaultMessage: "Confirmation"
3524
- }),
3525
- content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3526
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3527
- /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3528
- id: "popUpWarning.bodyMessage.contentType.delete.all",
3529
- defaultMessage: "Are you sure you want to delete these entries?"
3530
- }) }),
3531
- hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
3532
- {
3533
- id: getTranslation("Settings.list.actions.deleteAdditionalInfos"),
3534
- defaultMessage: "This will delete the active locale versions <em>(from Internationalization)</em>"
3535
- },
3536
- {
3537
- em: Emphasis
3538
- }
3539
- ) }) })
3540
- ] }),
3541
- onConfirm: handleConfirmBulkDelete
3542
- }
3543
- };
3544
- };
3545
- DeleteAction.type = "delete";
3546
- const UnpublishAction = ({ documents, model }) => {
3547
- const { formatMessage } = useIntl();
3548
- const { schema } = useDoc();
3549
- const selectRow = useTable("UnpublishAction", (state) => state.selectRow);
3550
- const hasPublishPermission = useDocumentRBAC("unpublishAction", (state) => state.canPublish);
3551
- const hasI18nEnabled = Boolean(schema?.pluginOptions?.i18n);
3552
- const hasDraftAndPublishEnabled = Boolean(schema?.options?.draftAndPublish);
3553
- const { unpublishMany: bulkUnpublishAction } = useDocumentActions();
3554
- const documentIds = documents.map(({ documentId }) => documentId);
3555
- const [{ query }] = useQueryParams();
3556
- const params = React.useMemo(() => buildValidParams(query), [query]);
3557
- const handleConfirmBulkUnpublish = async () => {
3558
- const data = await bulkUnpublishAction({ documentIds, model, params });
3559
- if (!("error" in data)) {
3560
- selectRow([]);
3561
- }
3562
- };
3563
- const showUnpublishButton = hasDraftAndPublishEnabled && hasPublishPermission && documents.some((entry) => entry.status === "published" || entry.status === "modified");
3564
- if (!showUnpublishButton)
3565
- return null;
3566
- return {
3567
- variant: "tertiary",
3568
- label: formatMessage({ id: "app.utils.unpublish", defaultMessage: "Unpublish" }),
3569
- dialog: {
3570
- type: "dialog",
3571
- title: formatMessage({
3572
- id: "app.components.ConfirmDialog.title",
3573
- defaultMessage: "Confirmation"
3574
- }),
3575
- content: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
3576
- /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsx(WarningCircle, { width: "24px", height: "24px", fill: "danger600" }) }),
3577
- /* @__PURE__ */ jsx(Typography, { id: "confirm-description", textAlign: "center", children: formatMessage({
3578
- id: "popUpWarning.bodyMessage.contentType.unpublish.all",
3579
- defaultMessage: "Are you sure you want to unpublish these entries?"
3580
- }) }),
3581
- hasI18nEnabled && /* @__PURE__ */ jsx(Box, { textAlign: "center", padding: 3, children: /* @__PURE__ */ jsx(Typography, { textColor: "danger500", children: formatMessage(
3582
- {
3583
- id: getTranslation("Settings.list.actions.unpublishAdditionalInfos"),
3584
- defaultMessage: "This will unpublish the active locale versions <em>(from Internationalization)</em>"
3585
- },
3586
- {
3587
- em: Emphasis
3588
- }
3589
- ) }) })
3590
- ] }),
3591
- confirmButton: formatMessage({
3592
- id: "app.utils.unpublish",
3593
- defaultMessage: "Unpublish"
3594
- }),
3595
- onConfirm: handleConfirmBulkUnpublish
3596
- }
3597
- };
3598
- };
3599
- UnpublishAction.type = "unpublish";
3600
- const Emphasis = (chunks) => /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", textColor: "danger500", children: chunks });
3601
- const DEFAULT_BULK_ACTIONS = [PublishAction, UnpublishAction, DeleteAction];
3602
- const AutoCloneFailureModalBody = ({ prohibitedFields }) => {
3603
- const { formatMessage } = useIntl();
3604
- const getDefaultErrorMessage = (reason) => {
3605
- switch (reason) {
3606
- case "relation":
3607
- return "Duplicating the relation could remove it from the original entry.";
3608
- case "unique":
3609
- return "Identical values in a unique field are not allowed";
3610
- default:
3611
- return reason;
3612
- }
3613
- };
3614
- return /* @__PURE__ */ jsxs(Fragment, { children: [
3615
- /* @__PURE__ */ jsx(Typography, { variant: "beta", children: formatMessage({
3616
- id: getTranslation("containers.list.autoCloneModal.title"),
3617
- defaultMessage: "This entry can't be duplicated directly."
3618
- }) }),
3619
- /* @__PURE__ */ jsx(Box, { marginTop: 2, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatMessage({
3620
- id: getTranslation("containers.list.autoCloneModal.description"),
3621
- defaultMessage: "A new entry will be created with the same content, but you'll have to change the following fields to save it."
3622
- }) }) }),
3623
- /* @__PURE__ */ jsx(Flex, { marginTop: 6, gap: 2, direction: "column", alignItems: "stretch", children: prohibitedFields.map(([fieldPath, reason]) => /* @__PURE__ */ jsxs(
3624
- Flex,
3625
- {
3626
- direction: "column",
3627
- gap: 2,
3628
- alignItems: "flex-start",
3629
- borderColor: "neutral200",
3630
- hasRadius: true,
3631
- padding: 6,
3632
- children: [
3633
- /* @__PURE__ */ jsx(Flex, { direction: "row", tag: "ol", children: fieldPath.map((pathSegment, index2) => /* @__PURE__ */ jsxs(Typography, { fontWeight: "semiBold", tag: "li", children: [
3634
- pathSegment,
3635
- index2 !== fieldPath.length - 1 && /* @__PURE__ */ jsx(
3636
- ChevronRight,
3637
- {
3638
- fill: "neutral500",
3639
- height: "0.8rem",
3640
- width: "0.8rem",
3641
- style: { margin: "0 0.8rem" }
3642
- }
3643
- )
3644
- ] }, index2)) }),
3645
- /* @__PURE__ */ jsx(Typography, { tag: "p", textColor: "neutral600", children: formatMessage({
3646
- id: getTranslation(`containers.list.autoCloneModal.error.${reason}`),
3647
- defaultMessage: getDefaultErrorMessage(reason)
3648
- }) })
3649
- ]
3650
- },
3651
- fieldPath.join()
3652
- )) })
3653
- ] });
3654
- };
3655
- const TableActions = ({ document }) => {
3656
- const { formatMessage } = useIntl();
3657
- const { model, collectionType } = useDoc();
3658
- const plugins = useStrapiApp("TableActions", (state) => state.plugins);
3659
- const props = {
3660
- activeTab: null,
3661
- model,
3662
- documentId: document.documentId,
3663
- collectionType,
3664
- document
3665
- };
3666
- return /* @__PURE__ */ jsx(
3667
- DescriptionComponentRenderer,
3668
- {
3669
- props,
3670
- descriptions: plugins["content-manager"].apis.getDocumentActions().filter((action) => action.name !== "PublishAction"),
3671
- children: (actions2) => {
3672
- const tableRowActions = actions2.filter((action) => {
3673
- const positions = Array.isArray(action.position) ? action.position : [action.position];
3674
- return positions.includes("table-row");
3675
- });
3676
- return /* @__PURE__ */ jsx(
3677
- DocumentActionsMenu,
3678
- {
3679
- actions: tableRowActions,
3680
- label: formatMessage({
3681
- id: "content-manager.containers.list.table.row-actions",
3682
- defaultMessage: "Row action"
3683
- }),
3684
- variant: "ghost"
3685
- }
3686
- );
3687
- }
3688
- }
3689
- );
3690
- };
3691
- const EditAction = ({ documentId }) => {
3692
- const navigate = useNavigate();
3693
- const { formatMessage } = useIntl();
3694
- const { canRead } = useDocumentRBAC("EditAction", ({ canRead: canRead2 }) => ({ canRead: canRead2 }));
3695
- const { toggleNotification } = useNotification();
3696
- const [{ query }] = useQueryParams();
3697
- return {
3698
- disabled: !canRead,
3699
- icon: /* @__PURE__ */ jsx(StyledPencil, {}),
3700
- label: formatMessage({
3701
- id: "content-manager.actions.edit.label",
3702
- defaultMessage: "Edit"
3703
- }),
3704
- position: "table-row",
3705
- onClick: async () => {
3706
- if (!documentId) {
3707
- console.error(
3708
- "You're trying to edit a document without an id, this is likely a bug with Strapi. Please open an issue."
3709
- );
3710
- toggleNotification({
3711
- message: formatMessage({
3712
- id: "content-manager.actions.edit.error",
3713
- defaultMessage: "An error occurred while trying to edit the document."
3714
- }),
3715
- type: "danger"
3716
- });
3717
- return;
3718
- }
3719
- navigate({
3720
- pathname: documentId,
3721
- search: stringify({
3722
- plugins: query.plugins
3723
- })
3724
- });
3725
- }
3726
- };
3727
- };
3728
- EditAction.type = "edit";
3729
- const StyledPencil = styled(Pencil)`
3730
- path {
3731
- fill: currentColor;
3732
- }
3733
- `;
3734
- const CloneAction = ({ model, documentId }) => {
3735
- const navigate = useNavigate();
3736
- const { formatMessage } = useIntl();
3737
- const { canCreate } = useDocumentRBAC("CloneAction", ({ canCreate: canCreate2 }) => ({ canCreate: canCreate2 }));
3738
- const { toggleNotification } = useNotification();
3739
- const { autoClone } = useDocumentActions();
3740
- const [prohibitedFields, setProhibitedFields] = React.useState([]);
3741
- return {
3742
- disabled: !canCreate,
3743
- icon: /* @__PURE__ */ jsx(StyledDuplicate, {}),
3744
- label: formatMessage({
3745
- id: "content-manager.actions.clone.label",
3746
- defaultMessage: "Duplicate"
3747
- }),
3748
- position: "table-row",
3749
- onClick: async () => {
3750
- if (!documentId) {
3751
- console.error(
3752
- "You're trying to clone a document in the table without an id, this is likely a bug with Strapi. Please open an issue."
3753
- );
3754
- toggleNotification({
3755
- message: formatMessage({
3756
- id: "content-manager.actions.clone.error",
3757
- defaultMessage: "An error occurred while trying to clone the document."
3758
- }),
3759
- type: "danger"
3760
- });
3761
- return;
3762
- }
3763
- const res = await autoClone({ model, sourceId: documentId });
3764
- if ("data" in res) {
3765
- navigate(res.data.documentId);
3766
- return true;
3767
- }
3768
- if (isBaseQueryError(res.error) && res.error.details && typeof res.error.details === "object" && "prohibitedFields" in res.error.details && Array.isArray(res.error.details.prohibitedFields)) {
3769
- const prohibitedFields2 = res.error.details.prohibitedFields;
3770
- setProhibitedFields(prohibitedFields2);
3771
- }
3772
- },
3773
- dialog: {
3774
- type: "modal",
3775
- title: formatMessage({
3776
- id: "content-manager.containers.list.autoCloneModal.header",
3777
- defaultMessage: "Duplicate"
3778
- }),
3779
- content: /* @__PURE__ */ jsx(AutoCloneFailureModalBody, { prohibitedFields }),
3780
- footer: ({ onClose }) => {
3781
- return /* @__PURE__ */ jsxs(Modal.Footer, { children: [
3782
- /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
3783
- id: "cancel",
3784
- defaultMessage: "Cancel"
3785
- }) }),
3786
- /* @__PURE__ */ jsx(
3787
- LinkButton,
3788
- {
3789
- tag: NavLink,
3790
- to: {
3791
- pathname: `clone/${documentId}`
3792
- },
3793
- children: formatMessage({
3794
- id: "content-manager.containers.list.autoCloneModal.create",
3795
- defaultMessage: "Create"
3796
- })
3797
- }
3798
- )
3799
- ] });
3800
- }
3801
- }
3802
- };
3803
- };
3804
- CloneAction.type = "clone";
3805
- const StyledDuplicate = styled(Duplicate)`
3806
- path {
3807
- fill: currentColor;
3808
- }
3809
- `;
3810
- const DEFAULT_TABLE_ROW_ACTIONS = [EditAction, CloneAction];
3811
- class ContentManagerPlugin {
3812
- /**
3813
- * The following properties are the stored ones provided by any plugins registering with
3814
- * the content-manager. The function calls however, need to be called at runtime in the
3815
- * application, so instead we collate them and run them later with the complete list incl.
3816
- * ones already registered & the context of the view.
3817
- */
3818
- bulkActions = [...DEFAULT_BULK_ACTIONS];
3819
- documentActions = [
3820
- ...DEFAULT_ACTIONS,
3821
- ...DEFAULT_TABLE_ROW_ACTIONS,
3822
- ...DEFAULT_HEADER_ACTIONS
3823
- ];
3824
- editViewSidePanels = [ActionsPanel];
3825
- headerActions = [];
3826
- constructor() {
3827
- }
3828
- addEditViewSidePanel(panels) {
3829
- if (Array.isArray(panels)) {
3830
- this.editViewSidePanels = [...this.editViewSidePanels, ...panels];
3831
- } else if (typeof panels === "function") {
3832
- this.editViewSidePanels = panels(this.editViewSidePanels);
3833
- } else {
3834
- throw new Error(
3835
- `Expected the \`panels\` passed to \`addEditViewSidePanel\` to be an array or a function, but received ${getPrintableType(
3836
- panels
3837
- )}`
3838
- );
3839
- }
3840
- }
3841
- addDocumentAction(actions2) {
3842
- if (Array.isArray(actions2)) {
3843
- this.documentActions = [...this.documentActions, ...actions2];
3844
- } else if (typeof actions2 === "function") {
3845
- this.documentActions = actions2(this.documentActions);
3846
- } else {
3847
- throw new Error(
3848
- `Expected the \`actions\` passed to \`addDocumentAction\` to be an array or a function, but received ${getPrintableType(
3849
- actions2
3850
- )}`
3851
- );
3852
- }
3853
- }
3854
- addDocumentHeaderAction(actions2) {
3855
- if (Array.isArray(actions2)) {
3856
- this.headerActions = [...this.headerActions, ...actions2];
3857
- } else if (typeof actions2 === "function") {
3858
- this.headerActions = actions2(this.headerActions);
3859
- } else {
3860
- throw new Error(
3861
- `Expected the \`actions\` passed to \`addDocumentHeaderAction\` to be an array or a function, but received ${getPrintableType(
3862
- actions2
3863
- )}`
3864
- );
3865
- }
3866
- }
3867
- addBulkAction(actions2) {
3868
- if (Array.isArray(actions2)) {
3869
- this.bulkActions = [...this.bulkActions, ...actions2];
3870
- } else if (typeof actions2 === "function") {
3871
- this.bulkActions = actions2(this.bulkActions);
3872
- } else {
3873
- throw new Error(
3874
- `Expected the \`actions\` passed to \`addBulkAction\` to be an array or a function, but received ${getPrintableType(
3875
- actions2
3876
- )}`
3877
- );
3878
- }
3879
- }
3880
- get config() {
3881
- return {
3882
- id: PLUGIN_ID,
3883
- name: "Content Manager",
3884
- injectionZones: INJECTION_ZONES,
3885
- apis: {
3886
- addBulkAction: this.addBulkAction.bind(this),
3887
- addDocumentAction: this.addDocumentAction.bind(this),
3888
- addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
3889
- addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
3890
- getBulkActions: () => this.bulkActions,
3891
- getDocumentActions: () => this.documentActions,
3892
- getEditViewSidePanels: () => this.editViewSidePanels,
3893
- getHeaderActions: () => this.headerActions
3894
- }
3895
- };
3896
- }
3897
- }
3898
- const getPrintableType = (value) => {
3899
- const nativeType = typeof value;
3900
- if (nativeType === "object") {
3901
- if (value === null)
3902
- return "null";
3903
- if (Array.isArray(value))
3904
- return "array";
3905
- if (value instanceof Object && value.constructor.name !== "Object") {
3906
- return value.constructor.name;
3907
- }
3908
- }
3909
- return nativeType;
3910
- };
3911
- const HistoryAction = ({ model, document }) => {
3912
- const { formatMessage } = useIntl();
3913
- const [{ query }] = useQueryParams();
3914
- const navigate = useNavigate();
3915
- const pluginsQueryParams = stringify({ plugins: query.plugins }, { encode: false });
3916
- if (!window.strapi.features.isEnabled("cms-content-history")) {
3917
- return null;
3918
- }
3919
- return {
3920
- icon: /* @__PURE__ */ jsx(ClockCounterClockwise, {}),
3921
- label: formatMessage({
3922
- id: "content-manager.history.document-action",
3923
- defaultMessage: "Content History"
3924
- }),
3925
- onClick: () => navigate({ pathname: "history", search: pluginsQueryParams }),
3926
- disabled: (
3927
- /**
3928
- * The user is creating a new document.
3929
- * It hasn't been saved yet, so there's no history to go to
3930
- */
3931
- !document || /**
3932
- * The document has been created but the current dimension has never been saved.
3933
- * For example, the user is creating a new locale in an existing document,
3934
- * so there's no history for the document in that locale
3935
- */
3936
- !document.id || /**
3937
- * History is only available for content types created by the user.
3938
- * These have the `api::` prefix, as opposed to the ones created by Strapi or plugins,
3939
- * which start with `admin::` or `plugin::`
3940
- */
3941
- !model.startsWith("api::")
3942
- ),
3943
- position: "header"
3944
- };
3945
- };
3946
- HistoryAction.type = "history";
3947
- const historyAdmin = {
3948
- bootstrap(app) {
3949
- const { addDocumentAction } = app.getPlugin("content-manager").apis;
3950
- addDocumentAction((actions2) => {
3951
- const indexOfDeleteAction = actions2.findIndex((action) => action.type === "delete");
3952
- actions2.splice(indexOfDeleteAction, 0, HistoryAction);
3953
- return actions2;
3954
- });
3955
- }
3956
- };
3957
- const initialState = {
3958
- collectionTypeLinks: [],
3959
- components: [],
3960
- fieldSizes: {},
3961
- models: [],
3962
- singleTypeLinks: [],
3963
- isLoading: true
3964
- };
3965
- const appSlice = createSlice({
3966
- name: "app",
3967
- initialState,
3968
- reducers: {
3969
- setInitialData(state, action) {
3970
- const {
3971
- authorizedCollectionTypeLinks,
3972
- authorizedSingleTypeLinks,
3973
- components,
3974
- contentTypeSchemas,
3975
- fieldSizes
3976
- } = action.payload;
3977
- state.collectionTypeLinks = authorizedCollectionTypeLinks.filter(
3978
- ({ isDisplayed }) => isDisplayed
3979
- );
3980
- state.singleTypeLinks = authorizedSingleTypeLinks.filter(({ isDisplayed }) => isDisplayed);
3981
- state.components = components;
3982
- state.models = contentTypeSchemas;
3983
- state.fieldSizes = fieldSizes;
3984
- state.isLoading = false;
3985
- }
3986
- }
3987
- });
3988
- const { actions, reducer: reducer$1 } = appSlice;
3989
- const { setInitialData } = actions;
3990
- const reducer = combineReducers({
3991
- app: reducer$1
3992
- });
3993
- const index = {
3994
- register(app) {
3995
- const cm = new ContentManagerPlugin();
3996
- app.addReducers({
3997
- [PLUGIN_ID]: reducer
3998
- });
3999
- app.addMenuLink({
4000
- to: PLUGIN_ID,
4001
- icon: Feather,
4002
- intlLabel: {
4003
- id: `content-manager.plugin.name`,
4004
- defaultMessage: "Content Manager"
4005
- },
4006
- permissions: [],
4007
- position: 1
4008
- });
4009
- app.router.addRoute({
4010
- path: "content-manager/*",
4011
- lazy: async () => {
4012
- const { Layout } = await import("./layout-2CfjL0T9.mjs");
4013
- return {
4014
- Component: Layout
4015
- };
4016
- },
4017
- children: routes
4018
- });
4019
- app.registerPlugin(cm.config);
4020
- },
4021
- bootstrap(app) {
4022
- if (typeof historyAdmin.bootstrap === "function") {
4023
- historyAdmin.bootstrap(app);
4024
- }
4025
- },
4026
- async registerTrads({ locales }) {
4027
- const importedTrads = await Promise.all(
4028
- locales.map((locale) => {
4029
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/ar.json": () => import("./ar-CCEVvqGG.mjs"), "./translations/ca.json": () => import("./ca-5U32ON2v.mjs"), "./translations/cs.json": () => import("./cs-CM2aBUar.mjs"), "./translations/de.json": () => import("./de-C72KDNOl.mjs"), "./translations/en.json": () => import("./en-DKV44jRb.mjs"), "./translations/es.json": () => import("./es-CeXiYflN.mjs"), "./translations/eu.json": () => import("./eu-CdALomew.mjs"), "./translations/fr.json": () => import("./fr-CD9VFbPM.mjs"), "./translations/gu.json": () => import("./gu-CNpaMDpH.mjs"), "./translations/hi.json": () => import("./hi-Dwvd04m3.mjs"), "./translations/hu.json": () => import("./hu-CeYvaaO0.mjs"), "./translations/id.json": () => import("./id-BtwA9WJT.mjs"), "./translations/it.json": () => import("./it-BrVPqaf1.mjs"), "./translations/ja.json": () => import("./ja-CtsUxOvk.mjs"), "./translations/ko.json": () => import("./ko-HVQRlfUI.mjs"), "./translations/ml.json": () => import("./ml-BihZwQit.mjs"), "./translations/ms.json": () => import("./ms-m_WjyWx7.mjs"), "./translations/nl.json": () => import("./nl-D4R9gHx5.mjs"), "./translations/pl.json": () => import("./pl-sbx9mSt_.mjs"), "./translations/pt-BR.json": () => import("./pt-BR-C71iDxnh.mjs"), "./translations/pt.json": () => import("./pt-BsaFvS8-.mjs"), "./translations/ru.json": () => import("./ru-BE6A4Exp.mjs"), "./translations/sa.json": () => import("./sa-Dag0k-Z8.mjs"), "./translations/sk.json": () => import("./sk-BFg-R8qJ.mjs"), "./translations/sv.json": () => import("./sv-CUnfWGsh.mjs"), "./translations/th.json": () => import("./th-BqbI8lIT.mjs"), "./translations/tr.json": () => import("./tr-CgeK3wJM.mjs"), "./translations/uk.json": () => import("./uk-CR-zDhAY.mjs"), "./translations/vi.json": () => import("./vi-DUXIk_fw.mjs"), "./translations/zh-Hans.json": () => import("./zh-Hans-BPQcRIyH.mjs"), "./translations/zh.json": () => import("./zh-BWZspA60.mjs") }), `./translations/${locale}.json`).then(({ default: data }) => {
4030
- return {
4031
- data: prefixPluginTranslations(data, PLUGIN_ID),
4032
- locale
4033
- };
4034
- }).catch(() => {
4035
- return {
4036
- data: {},
4037
- locale
4038
- };
4039
- });
4040
- })
4041
- );
4042
- return Promise.resolve(importedTrads);
4043
- }
4044
- };
4045
- export {
4046
- ATTRIBUTE_TYPES_THAT_CANNOT_BE_MAIN_FIELD as A,
4047
- BulkActionsRenderer as B,
4048
- COLLECTION_TYPES as C,
4049
- DocumentStatus as D,
4050
- extractContentTypeComponents as E,
4051
- DEFAULT_SETTINGS as F,
4052
- convertEditLayoutToFieldLayouts as G,
4053
- HOOKS as H,
4054
- InjectionZone as I,
4055
- useDocument as J,
4056
- index as K,
4057
- useContentManagerContext as L,
4058
- useDocumentActions as M,
4059
- Panels as P,
4060
- RelativeTime as R,
4061
- SINGLE_TYPES as S,
4062
- TableActions as T,
4063
- useGetInitialDataQuery as a,
4064
- useGetAllContentTypeSettingsQuery as b,
4065
- useDoc as c,
4066
- buildValidParams as d,
4067
- contentManagerApi as e,
4068
- useDocumentRBAC as f,
4069
- getTranslation as g,
4070
- useDocumentLayout as h,
4071
- createYupSchema as i,
4072
- Header as j,
4073
- PERMISSIONS as k,
4074
- DocumentRBAC as l,
4075
- DOCUMENT_META_FIELDS as m,
4076
- CLONE_PATH as n,
4077
- useDocLayout as o,
4078
- useGetContentTypeConfigurationQuery as p,
4079
- CREATOR_FIELDS as q,
4080
- getMainField as r,
4081
- setInitialData as s,
4082
- getDisplayName as t,
4083
- useContentTypeSchema as u,
4084
- checkIfAttributeIsDisplayable as v,
4085
- useGetAllDocumentsQuery as w,
4086
- convertListLayoutToFieldLayouts as x,
4087
- capitalise as y,
4088
- useUpdateContentTypeConfigurationMutation as z
4089
- };
4090
- //# sourceMappingURL=index-wnqzm4Q8.mjs.map