@strapi/content-manager 0.0.0-experimental.bd712ad3930045f4a5d2144c119e0b7856e97fc4 → 0.0.0-experimental.be7746d32e70ba7219186219896ff4ae64735740

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