@strapi/admin 5.30.0 → 5.31.0

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 (342) hide show
  1. package/dist/admin/admin/src/StrapiApp.js.map +1 -1
  2. package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
  3. package/dist/admin/admin/src/components/ContentBox.js.map +1 -1
  4. package/dist/admin/admin/src/components/ContentBox.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/DescriptionComponentRenderer.js.map +1 -1
  6. package/dist/admin/admin/src/components/DescriptionComponentRenderer.mjs.map +1 -1
  7. package/dist/admin/admin/src/components/Filters.js +1 -1
  8. package/dist/admin/admin/src/components/Filters.js.map +1 -1
  9. package/dist/admin/admin/src/components/Filters.mjs +1 -1
  10. package/dist/admin/admin/src/components/Filters.mjs.map +1 -1
  11. package/dist/admin/admin/src/components/Form.js +8 -3
  12. package/dist/admin/admin/src/components/Form.js.map +1 -1
  13. package/dist/admin/admin/src/components/Form.mjs +8 -3
  14. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/Enumeration.js +1 -1
  16. package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
  17. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +1 -1
  18. package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
  19. package/dist/admin/admin/src/components/FormInputs/Number.js +1 -1
  20. package/dist/admin/admin/src/components/FormInputs/Number.js.map +1 -1
  21. package/dist/admin/admin/src/components/FormInputs/Number.mjs +1 -1
  22. package/dist/admin/admin/src/components/FormInputs/Number.mjs.map +1 -1
  23. package/dist/admin/admin/src/components/FormInputs/Renderer.js.map +1 -1
  24. package/dist/admin/admin/src/components/FormInputs/Renderer.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  26. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  27. package/dist/admin/admin/src/components/GapDropZone.js.map +1 -1
  28. package/dist/admin/admin/src/components/GapDropZone.mjs.map +1 -1
  29. package/dist/admin/admin/src/components/GuidedTour/Overview.js.map +1 -1
  30. package/dist/admin/admin/src/components/GuidedTour/Overview.mjs.map +1 -1
  31. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.js.map +1 -1
  32. package/dist/admin/admin/src/components/GuidedTour/Steps/ContentTypeBuilderSteps.mjs.map +1 -1
  33. package/dist/admin/admin/src/components/GuidedTour/Steps/Step.js.map +1 -1
  34. package/dist/admin/admin/src/components/GuidedTour/Steps/Step.mjs.map +1 -1
  35. package/dist/admin/admin/src/components/Layouts/GridLayout.js.map +1 -1
  36. package/dist/admin/admin/src/components/Layouts/GridLayout.mjs.map +1 -1
  37. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js +8 -4
  38. package/dist/admin/admin/src/components/Layouts/HeaderLayout.js.map +1 -1
  39. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs +8 -4
  40. package/dist/admin/admin/src/components/Layouts/HeaderLayout.mjs.map +1 -1
  41. package/dist/admin/admin/src/components/NpsSurvey.js +5 -3
  42. package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
  43. package/dist/admin/admin/src/components/NpsSurvey.mjs +5 -3
  44. package/dist/admin/admin/src/components/NpsSurvey.mjs.map +1 -1
  45. package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
  46. package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
  47. package/dist/admin/admin/src/components/PrivateRoute.js.map +1 -1
  48. package/dist/admin/admin/src/components/PrivateRoute.mjs.map +1 -1
  49. package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
  50. package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
  51. package/dist/admin/admin/src/components/ResizeIndicator.js.map +1 -1
  52. package/dist/admin/admin/src/components/ResizeIndicator.mjs.map +1 -1
  53. package/dist/admin/admin/src/components/Table.js +1 -1
  54. package/dist/admin/admin/src/components/Table.js.map +1 -1
  55. package/dist/admin/admin/src/components/Table.mjs +1 -1
  56. package/dist/admin/admin/src/components/Table.mjs.map +1 -1
  57. package/dist/admin/admin/src/components/Widgets.js.map +1 -1
  58. package/dist/admin/admin/src/components/Widgets.mjs.map +1 -1
  59. package/dist/admin/admin/src/core/apis/CustomFields.js.map +1 -1
  60. package/dist/admin/admin/src/core/apis/CustomFields.mjs.map +1 -1
  61. package/dist/admin/admin/src/core/apis/Plugin.js +0 -1
  62. package/dist/admin/admin/src/core/apis/Plugin.js.map +1 -1
  63. package/dist/admin/admin/src/core/apis/Plugin.mjs +0 -1
  64. package/dist/admin/admin/src/core/apis/Plugin.mjs.map +1 -1
  65. package/dist/admin/admin/src/core/apis/Widgets.js.map +1 -1
  66. package/dist/admin/admin/src/core/apis/Widgets.mjs.map +1 -1
  67. package/dist/admin/admin/src/core/apis/rbac.js.map +1 -1
  68. package/dist/admin/admin/src/core/apis/rbac.mjs.map +1 -1
  69. package/dist/admin/admin/src/core/apis/router.js.map +1 -1
  70. package/dist/admin/admin/src/core/apis/router.mjs.map +1 -1
  71. package/dist/admin/admin/src/features/BackButton.js.map +1 -1
  72. package/dist/admin/admin/src/features/BackButton.mjs.map +1 -1
  73. package/dist/admin/admin/src/features/Tracking.js.map +1 -1
  74. package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
  75. package/dist/admin/admin/src/features/Widgets.js.map +1 -1
  76. package/dist/admin/admin/src/features/Widgets.mjs.map +1 -1
  77. package/dist/admin/admin/src/hooks/usePersistentState.js.map +1 -1
  78. package/dist/admin/admin/src/hooks/usePersistentState.mjs.map +1 -1
  79. package/dist/admin/admin/src/hooks/useRBAC.js.map +1 -1
  80. package/dist/admin/admin/src/hooks/useRBAC.mjs.map +1 -1
  81. package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
  82. package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
  83. package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
  84. package/dist/admin/admin/src/pages/Home/HomePage.mjs.map +1 -1
  85. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js +2 -2
  86. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.js.map +1 -1
  87. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs +2 -2
  88. package/dist/admin/admin/src/pages/Marketplace/MarketplacePage.mjs.map +1 -1
  89. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.js.map +1 -1
  90. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackageCard.mjs.map +1 -1
  91. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.js.map +1 -1
  92. package/dist/admin/admin/src/pages/Marketplace/components/NpmPackagesFilters.mjs.map +1 -1
  93. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.js.map +1 -1
  94. package/dist/admin/admin/src/pages/Marketplace/components/PageHeader.mjs.map +1 -1
  95. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.js.map +1 -1
  96. package/dist/admin/admin/src/pages/Marketplace/hooks/useMarketplaceData.mjs.map +1 -1
  97. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
  98. package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
  99. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +8 -1
  100. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
  101. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs +9 -2
  102. package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.mjs.map +1 -1
  103. package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.js.map +1 -1
  104. package/dist/admin/admin/src/pages/Settings/components/Tokens/LifeSpanInput.mjs.map +1 -1
  105. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
  106. package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.mjs.map +1 -1
  107. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.js.map +1 -1
  108. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/EditViewPage.mjs.map +1 -1
  109. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
  110. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.mjs.map +1 -1
  111. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.js.map +1 -1
  112. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/utils/transformPermissionsData.mjs.map +1 -1
  113. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js +2 -0
  114. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.js.map +1 -1
  115. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs +2 -0
  116. package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/ListView.mjs.map +1 -1
  117. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
  118. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
  119. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
  120. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
  121. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/utils/files.js.map +1 -1
  122. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/utils/files.mjs.map +1 -1
  123. package/dist/admin/admin/src/pages/Settings/pages/InstalledPlugins.js.map +1 -1
  124. package/dist/admin/admin/src/pages/Settings/pages/InstalledPlugins.mjs.map +1 -1
  125. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js +9 -2
  126. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js.map +1 -1
  127. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs +9 -2
  128. package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs.map +1 -1
  129. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js +9 -2
  130. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js.map +1 -1
  131. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs +9 -2
  132. package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs.map +1 -1
  133. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.js.map +1 -1
  134. package/dist/admin/admin/src/pages/Settings/pages/Roles/ListPage.mjs.map +1 -1
  135. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
  136. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
  137. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.js.map +1 -1
  138. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsModal.mjs.map +1 -1
  139. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
  140. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.mjs.map +1 -1
  141. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.js.map +1 -1
  142. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/GlobalActions.mjs.map +1 -1
  143. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
  144. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
  145. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
  146. package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.mjs.map +1 -1
  147. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js.map +1 -1
  148. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs.map +1 -1
  149. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/permissions.js.map +1 -1
  150. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/permissions.mjs.map +1 -1
  151. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.js.map +1 -1
  152. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/EditView.mjs.map +1 -1
  153. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js +2 -0
  154. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js.map +1 -1
  155. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs +2 -0
  156. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs.map +1 -1
  157. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js +9 -2
  158. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.js.map +1 -1
  159. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs +9 -2
  160. package/dist/admin/admin/src/pages/Settings/pages/Users/EditPage.mjs.map +1 -1
  161. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js +3 -1
  162. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js.map +1 -1
  163. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs +3 -1
  164. package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs.map +1 -1
  165. package/dist/admin/admin/src/pages/Settings/pages/Users/components/MagicLinkCE.js.map +1 -1
  166. package/dist/admin/admin/src/pages/Settings/pages/Users/components/MagicLinkCE.mjs.map +1 -1
  167. package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.js.map +1 -1
  168. package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.mjs.map +1 -1
  169. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.js.map +1 -1
  170. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.mjs.map +1 -1
  171. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.js.map +1 -1
  172. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/ListPage.mjs.map +1 -1
  173. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
  174. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
  175. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js +9 -2
  176. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.js.map +1 -1
  177. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs +9 -2
  178. package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs.map +1 -1
  179. package/dist/admin/admin/src/pages/UseCasePage.js.map +1 -1
  180. package/dist/admin/admin/src/pages/UseCasePage.mjs.map +1 -1
  181. package/dist/admin/admin/src/services/api.js +2 -1
  182. package/dist/admin/admin/src/services/api.js.map +1 -1
  183. package/dist/admin/admin/src/services/api.mjs +2 -1
  184. package/dist/admin/admin/src/services/api.mjs.map +1 -1
  185. package/dist/admin/admin/src/services/apiTokens.js.map +1 -1
  186. package/dist/admin/admin/src/services/apiTokens.mjs.map +1 -1
  187. package/dist/admin/admin/src/services/transferTokens.js.map +1 -1
  188. package/dist/admin/admin/src/services/transferTokens.mjs.map +1 -1
  189. package/dist/admin/admin/src/services/users.js.map +1 -1
  190. package/dist/admin/admin/src/services/users.mjs.map +1 -1
  191. package/dist/admin/admin/src/services/webhooks.js.map +1 -1
  192. package/dist/admin/admin/src/services/webhooks.mjs.map +1 -1
  193. package/dist/admin/admin/src/utils/cookies.js.map +1 -1
  194. package/dist/admin/admin/src/utils/cookies.mjs.map +1 -1
  195. package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
  196. package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
  197. package/dist/admin/admin/src/utils/getPrefixedId.js.map +1 -1
  198. package/dist/admin/admin/src/utils/getPrefixedId.mjs.map +1 -1
  199. package/dist/admin/admin/src/utils/rulesEngine.js.map +1 -1
  200. package/dist/admin/admin/src/utils/rulesEngine.mjs.map +1 -1
  201. package/dist/admin/admin/src/utils/urls.js.map +1 -1
  202. package/dist/admin/admin/src/utils/urls.mjs.map +1 -1
  203. package/dist/admin/admin/src/utils/users.js.map +1 -1
  204. package/dist/admin/admin/src/utils/users.mjs.map +1 -1
  205. package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.js.map +1 -1
  206. package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.mjs.map +1 -1
  207. package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.js.map +1 -1
  208. package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.mjs.map +1 -1
  209. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js.map +1 -1
  210. package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.mjs.map +1 -1
  211. package/dist/admin/ee/admin/src/pages/AuthResponse.js.map +1 -1
  212. package/dist/admin/ee/admin/src/pages/AuthResponse.mjs.map +1 -1
  213. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  214. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  215. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +3 -3
  216. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
  217. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +3 -3
  218. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
  219. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.js.map +1 -1
  220. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.mjs.map +1 -1
  221. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useFormatTimeStamp.js.map +1 -1
  222. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useFormatTimeStamp.mjs.map +1 -1
  223. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.js.map +1 -1
  224. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.mjs.map +1 -1
  225. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/MagicLinkEE.js.map +1 -1
  226. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/Users/components/MagicLinkEE.mjs.map +1 -1
  227. package/dist/admin/ee/admin/src/services/ai.js +14 -1
  228. package/dist/admin/ee/admin/src/services/ai.js.map +1 -1
  229. package/dist/admin/ee/admin/src/services/ai.mjs +14 -2
  230. package/dist/admin/ee/admin/src/services/ai.mjs.map +1 -1
  231. package/dist/admin/ee/admin/src/services/auditLogs.js.map +1 -1
  232. package/dist/admin/ee/admin/src/services/auditLogs.mjs.map +1 -1
  233. package/dist/admin/ee.js +1 -0
  234. package/dist/admin/ee.js.map +1 -1
  235. package/dist/admin/ee.mjs +1 -1
  236. package/dist/admin/src/components/Form.d.ts +1 -1
  237. package/dist/admin/src/core/store/configure.d.ts +2 -2
  238. package/dist/admin/src/core/store/hooks.d.ts +2 -2
  239. package/dist/admin/src/ee.d.ts +1 -1
  240. package/dist/admin/src/hooks/useAdminRoles.d.ts +1 -1
  241. package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +4 -4
  242. package/dist/admin/src/selectors.d.ts +2 -2
  243. package/dist/admin/src/services/admin.d.ts +6 -6
  244. package/dist/admin/src/services/api.d.ts +1 -1
  245. package/dist/admin/src/services/apiTokens.d.ts +1 -1
  246. package/dist/admin/src/services/auth.d.ts +13 -13
  247. package/dist/admin/src/services/contentApi.d.ts +1 -1
  248. package/dist/admin/src/services/contentManager.d.ts +1 -1
  249. package/dist/admin/src/services/homepage.d.ts +3 -3
  250. package/dist/admin/src/services/transferTokens.d.ts +1 -1
  251. package/dist/admin/src/services/users.d.ts +8 -8
  252. package/dist/admin/src/services/webhooks.d.ts +2 -2
  253. package/dist/admin/tests/utils.d.ts +1 -1
  254. package/dist/ee/admin/src/services/ai.d.ts +6 -3
  255. package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
  256. package/dist/ee/server/src/ai/containers/ai.d.ts +11 -0
  257. package/dist/ee/server/src/ai/containers/ai.d.ts.map +1 -0
  258. package/dist/ee/server/src/ai/controllers/ai.d.ts +1 -0
  259. package/dist/ee/server/src/ai/controllers/ai.d.ts.map +1 -1
  260. package/dist/ee/server/src/ai/routes/ai.d.ts.map +1 -1
  261. package/dist/ee/server/src/index.d.ts +1 -0
  262. package/dist/ee/server/src/index.d.ts.map +1 -1
  263. package/dist/server/ee/server/src/ai/containers/ai.js +18 -0
  264. package/dist/server/ee/server/src/ai/containers/ai.js.map +1 -0
  265. package/dist/server/ee/server/src/ai/containers/ai.mjs +16 -0
  266. package/dist/server/ee/server/src/ai/containers/ai.mjs.map +1 -0
  267. package/dist/server/ee/server/src/ai/controllers/ai.js +6 -0
  268. package/dist/server/ee/server/src/ai/controllers/ai.js.map +1 -1
  269. package/dist/server/ee/server/src/ai/controllers/ai.mjs +6 -0
  270. package/dist/server/ee/server/src/ai/controllers/ai.mjs.map +1 -1
  271. package/dist/server/ee/server/src/ai/routes/ai.js +11 -0
  272. package/dist/server/ee/server/src/ai/routes/ai.js.map +1 -1
  273. package/dist/server/ee/server/src/ai/routes/ai.mjs +11 -0
  274. package/dist/server/ee/server/src/ai/routes/ai.mjs.map +1 -1
  275. package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
  276. package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
  277. package/dist/server/ee/server/src/controllers/authentication-utils/constants.js.map +1 -1
  278. package/dist/server/ee/server/src/controllers/authentication-utils/constants.mjs.map +1 -1
  279. package/dist/server/ee/server/src/controllers/authentication-utils/utils.js.map +1 -1
  280. package/dist/server/ee/server/src/controllers/authentication-utils/utils.mjs.map +1 -1
  281. package/dist/server/ee/server/src/controllers/authentication.js.map +1 -1
  282. package/dist/server/ee/server/src/controllers/authentication.mjs.map +1 -1
  283. package/dist/server/ee/server/src/controllers/user.js.map +1 -1
  284. package/dist/server/ee/server/src/controllers/user.mjs.map +1 -1
  285. package/dist/server/ee/server/src/index.js +7 -0
  286. package/dist/server/ee/server/src/index.js.map +1 -1
  287. package/dist/server/ee/server/src/index.mjs +7 -0
  288. package/dist/server/ee/server/src/index.mjs.map +1 -1
  289. package/dist/server/ee/server/src/services/auth.js.map +1 -1
  290. package/dist/server/ee/server/src/services/auth.mjs.map +1 -1
  291. package/dist/server/ee/server/src/services/passport/sso.js.map +1 -1
  292. package/dist/server/ee/server/src/services/passport/sso.mjs.map +1 -1
  293. package/dist/server/ee/server/src/utils/index.js.map +1 -1
  294. package/dist/server/ee/server/src/utils/index.mjs.map +1 -1
  295. package/dist/server/server/src/controllers/transfer/index.js.map +1 -1
  296. package/dist/server/server/src/controllers/transfer/index.mjs.map +1 -1
  297. package/dist/server/server/src/controllers/user.js +10 -0
  298. package/dist/server/server/src/controllers/user.js.map +1 -1
  299. package/dist/server/server/src/controllers/user.mjs +10 -0
  300. package/dist/server/server/src/controllers/user.mjs.map +1 -1
  301. package/dist/server/server/src/domain/action/index.js.map +1 -1
  302. package/dist/server/server/src/domain/action/index.mjs.map +1 -1
  303. package/dist/server/server/src/domain/condition/index.js.map +1 -1
  304. package/dist/server/server/src/domain/condition/index.mjs.map +1 -1
  305. package/dist/server/server/src/domain/permission/index.js.map +1 -1
  306. package/dist/server/server/src/domain/permission/index.mjs.map +1 -1
  307. package/dist/server/server/src/middlewares/rateLimit.js.map +1 -1
  308. package/dist/server/server/src/middlewares/rateLimit.mjs.map +1 -1
  309. package/dist/server/server/src/routes/serve-admin-panel.js.map +1 -1
  310. package/dist/server/server/src/routes/serve-admin-panel.mjs.map +1 -1
  311. package/dist/server/server/src/services/api-token.js.map +1 -1
  312. package/dist/server/server/src/services/api-token.mjs.map +1 -1
  313. package/dist/server/server/src/services/auth.js.map +1 -1
  314. package/dist/server/server/src/services/auth.mjs.map +1 -1
  315. package/dist/server/server/src/services/content-type.js.map +1 -1
  316. package/dist/server/server/src/services/content-type.mjs.map +1 -1
  317. package/dist/server/server/src/services/encryption.js.map +1 -1
  318. package/dist/server/server/src/services/encryption.mjs.map +1 -1
  319. package/dist/server/server/src/services/homepage.js.map +1 -1
  320. package/dist/server/server/src/services/homepage.mjs.map +1 -1
  321. package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
  322. package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
  323. package/dist/server/server/src/services/permission/permissions-manager/validate.js.map +1 -1
  324. package/dist/server/server/src/services/permission/permissions-manager/validate.mjs.map +1 -1
  325. package/dist/server/server/src/services/role.js.map +1 -1
  326. package/dist/server/server/src/services/role.mjs.map +1 -1
  327. package/dist/server/server/src/services/transfer/token.js.map +1 -1
  328. package/dist/server/server/src/services/transfer/token.mjs.map +1 -1
  329. package/dist/server/server/src/services/user.js.map +1 -1
  330. package/dist/server/server/src/services/user.mjs.map +1 -1
  331. package/dist/server/server/src/utils/index.js.map +1 -1
  332. package/dist/server/server/src/utils/index.mjs.map +1 -1
  333. package/dist/server/server/src/validation/action-provider.js.map +1 -1
  334. package/dist/server/server/src/validation/action-provider.mjs.map +1 -1
  335. package/dist/server/server/src/validation/common-functions/check-fields-are-correctly-nested.js.map +1 -1
  336. package/dist/server/server/src/validation/common-functions/check-fields-are-correctly-nested.mjs.map +1 -1
  337. package/dist/server/server/src/validation/common-validators.js.map +1 -1
  338. package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
  339. package/dist/server/src/controllers/user.d.ts.map +1 -1
  340. package/dist/shared/contracts/ai.d.ts +16 -0
  341. package/dist/shared/contracts/ai.d.ts.map +1 -1
  342. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"BackButton.mjs","sources":["../../../../../admin/src/features/BackButton.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Link, LinkProps } from '@strapi/design-system';\nimport { ArrowLeft } from '@strapi/icons';\nimport { produce } from 'immer';\nimport { useIntl } from 'react-intl';\nimport { NavLink, type To, useLocation, useNavigate, useNavigationType } from 'react-router-dom';\n\nimport { createContext } from '../components/Context';\n\n/* -------------------------------------------------------------------------------------------------\n * HistoryProvider\n * -----------------------------------------------------------------------------------------------*/\ninterface HistoryState {\n /**\n * The history of the user's navigation within our application\n * during their current session.\n */\n history: string[];\n /**\n * The index of the current location in the history array.\n */\n currentLocationIndex: number;\n /**\n * The current location of the user within our application.\n */\n currentLocation: string;\n /**\n * Whether the user can go back in the history.\n */\n canGoBack: boolean;\n}\n\ninterface HistoryContextValue extends HistoryState {\n /**\n * @description Push a new state to the history. You can\n * either pass a string or an object.\n */\n pushState: (\n path:\n | {\n to: string;\n search: string;\n }\n | string\n ) => void;\n /**\n * @description Go back in the history. This calls `navigate(-1)` internally\n * to keep the browser in sync with the application state.\n */\n goBack: () => void;\n}\n\nconst [Provider, useHistory] = createContext<HistoryContextValue>('History', {\n history: [],\n currentLocationIndex: 0,\n currentLocation: '',\n canGoBack: false,\n pushState: () => {\n throw new Error('You must use the `HistoryProvider` to access the `pushState` function.');\n },\n goBack: () => {\n throw new Error('You must use the `HistoryProvider` to access the `goBack` function.');\n },\n});\n\ninterface HistoryProviderProps {\n children: React.ReactNode;\n}\n\nconst HistoryProvider = ({ children }: HistoryProviderProps) => {\n const location = useLocation();\n const navigationType = useNavigationType();\n const navigate = useNavigate();\n const [state, dispatch] = React.useReducer(reducer, {\n history: [],\n currentLocationIndex: 0,\n currentLocation: '',\n canGoBack: false,\n });\n\n const isGoingBack = React.useRef(false);\n\n const pushState: HistoryContextValue['pushState'] = React.useCallback((path) => {\n dispatch({\n type: 'PUSH_STATE',\n payload: typeof path === 'string' ? { to: path, search: '' } : path,\n });\n }, []);\n\n const goBack: HistoryContextValue['goBack'] = React.useCallback(() => {\n /**\n * Perform the browser back action, dispatch the goBack action to keep the state in sync\n * and set the ref to avoid an infinite loop and incorrect state pushing\n */\n navigate(-1);\n dispatch({ type: 'GO_BACK' });\n isGoingBack.current = true;\n }, [navigate]);\n\n /**\n * This is a semi-listener pattern to keep the `canGoBack` state in sync.\n */\n const prevIndex = React.useRef(state.currentLocationIndex);\n React.useEffect(() => {\n if (state.currentLocationIndex !== prevIndex.current) {\n dispatch({\n type: 'SET_CAN_GO_BACK',\n payload: state.currentLocationIndex > 1 && state.history.length > 1,\n });\n prevIndex.current = state.currentLocationIndex;\n }\n }, [prevIndex, state.currentLocationIndex, state.history.length]);\n\n /**\n * This effect is responsible for pushing the new state to the history\n * when the user navigates to a new location assuming they're not going back.\n */\n React.useLayoutEffect(() => {\n if (isGoingBack.current) {\n isGoingBack.current = false;\n } else if (navigationType === 'REPLACE') {\n // Prevent appending to the history when the location changes via a replace:true navigation\n dispatch({\n type: 'REPLACE_STATE',\n payload: { to: location.pathname, search: location.search },\n });\n } else {\n // this should only occur on link movements, not back/forward clicks\n dispatch({\n type: 'PUSH_STATE',\n payload: { to: location.pathname, search: location.search },\n });\n }\n }, [dispatch, location.pathname, location.search, navigationType]);\n\n return (\n <Provider pushState={pushState} goBack={goBack} {...state}>\n {children}\n </Provider>\n );\n};\n\ntype HistoryActions =\n | {\n type: 'PUSH_STATE';\n payload: {\n to: string;\n search: string;\n };\n }\n | {\n type: 'REPLACE_STATE';\n payload: {\n to: string;\n search: string;\n };\n }\n | {\n type: 'GO_BACK';\n }\n | {\n type: 'SET_CAN_GO_BACK';\n payload: boolean;\n };\n\nconst reducer = (state: HistoryState, action: HistoryActions) =>\n produce(state, (draft) => {\n switch (action.type) {\n case 'PUSH_STATE': {\n const path = `${action.payload.to}${action.payload.search}`;\n if (state.currentLocationIndex === state.history.length) {\n // add the new place\n draft.history = [...state.history, path];\n } else {\n // delete all the history after the current place and then add the new place\n draft.history = [...state.history.slice(0, state.currentLocationIndex), path];\n }\n\n draft.currentLocation = path;\n draft.currentLocationIndex += 1;\n\n break;\n }\n case 'REPLACE_STATE': {\n const path = `${action.payload.to}${action.payload.search}`;\n draft.history = [...state.history.slice(0, state.currentLocationIndex - 1), path];\n draft.currentLocation = path;\n break;\n }\n case 'GO_BACK': {\n const newIndex = state.currentLocationIndex - 1;\n\n draft.currentLocation = state.history[newIndex - 1];\n draft.currentLocationIndex = newIndex;\n break;\n }\n case 'SET_CAN_GO_BACK': {\n draft.canGoBack = action.payload;\n break;\n }\n default:\n break;\n }\n });\n\n/* -------------------------------------------------------------------------------------------------\n * BackButton\n * -----------------------------------------------------------------------------------------------*/\ninterface BackButtonProps extends Pick<LinkProps, 'disabled'> {\n fallback?: To;\n}\n\n/**\n * @beta\n * @description The universal back button for the Strapi application. This uses the internal history\n * context to navigate the user back to the previous location. It can be completely disabled in a\n * specific user case. When no history is available, you can provide a fallback destination,\n * otherwise the link will be disabled.\n */\nconst BackButton = React.forwardRef<HTMLAnchorElement, BackButtonProps>(\n ({ disabled, fallback = '' }, ref) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n\n const canGoBack = useHistory('BackButton', (state) => state.canGoBack);\n const goBack = useHistory('BackButton', (state) => state.goBack);\n const history = useHistory('BackButton', (state) => state.history);\n const currentLocationIndex = useHistory('BackButton', (state) => state.currentLocationIndex);\n const hasFallback = fallback !== '';\n const shouldBeDisabled = disabled || (!canGoBack && !hasFallback);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n\n if (canGoBack) {\n goBack();\n } else if (hasFallback) {\n navigate(fallback);\n }\n };\n\n // The link destination from the history. Undefined if there is only 1 location in the history.\n const historyTo = canGoBack ? history.at(currentLocationIndex - 2) : undefined;\n // If no link destination from the history, use the fallback.\n const toWithFallback = historyTo ?? fallback;\n\n return (\n <Link\n ref={ref}\n tag={NavLink}\n to={toWithFallback}\n onClick={handleClick}\n disabled={shouldBeDisabled}\n aria-disabled={shouldBeDisabled}\n startIcon={<ArrowLeft />}\n >\n {formatMessage({\n id: 'global.back',\n defaultMessage: 'Back',\n })}\n </Link>\n );\n }\n);\n\nexport { BackButton, HistoryProvider, useHistory };\nexport type { BackButtonProps, HistoryProviderProps, HistoryContextValue, HistoryState };\n"],"names":["Provider","useHistory","createContext","history","currentLocationIndex","currentLocation","canGoBack","pushState","Error","goBack","HistoryProvider","children","location","useLocation","navigationType","useNavigationType","navigate","useNavigate","state","dispatch","React","useReducer","reducer","isGoingBack","useRef","useCallback","path","type","payload","to","search","current","prevIndex","useEffect","length","useLayoutEffect","pathname","_jsx","action","produce","draft","slice","newIndex","BackButton","forwardRef","disabled","fallback","ref","formatMessage","useIntl","hasFallback","shouldBeDisabled","handleClick","e","preventDefault","historyTo","at","undefined","toWithFallback","Link","tag","NavLink","onClick","aria-disabled","startIcon","ArrowLeft","id","defaultMessage"],"mappings":"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"}
1
+ {"version":3,"file":"BackButton.mjs","sources":["../../../../../admin/src/features/BackButton.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Link, LinkProps } from '@strapi/design-system';\nimport { ArrowLeft } from '@strapi/icons';\nimport { produce } from 'immer';\nimport { useIntl } from 'react-intl';\nimport { NavLink, type To, useLocation, useNavigate, useNavigationType } from 'react-router-dom';\n\nimport { createContext } from '../components/Context';\n\n/* -------------------------------------------------------------------------------------------------\n * HistoryProvider\n * -----------------------------------------------------------------------------------------------*/\ninterface HistoryState {\n /**\n * The history of the user's navigation within our application\n * during their current session.\n */\n history: string[];\n /**\n * The index of the current location in the history array.\n */\n currentLocationIndex: number;\n /**\n * The current location of the user within our application.\n */\n currentLocation: string;\n /**\n * Whether the user can go back in the history.\n */\n canGoBack: boolean;\n}\n\ninterface HistoryContextValue extends HistoryState {\n /**\n * @description Push a new state to the history. You can\n * either pass a string or an object.\n */\n pushState: (\n path:\n | {\n to: string;\n search: string;\n }\n | string\n ) => void;\n /**\n * @description Go back in the history. This calls `navigate(-1)` internally\n * to keep the browser in sync with the application state.\n */\n goBack: () => void;\n}\n\nconst [Provider, useHistory] = createContext<HistoryContextValue>('History', {\n history: [],\n currentLocationIndex: 0,\n currentLocation: '',\n canGoBack: false,\n pushState: () => {\n throw new Error('You must use the `HistoryProvider` to access the `pushState` function.');\n },\n goBack: () => {\n throw new Error('You must use the `HistoryProvider` to access the `goBack` function.');\n },\n});\n\ninterface HistoryProviderProps {\n children: React.ReactNode;\n}\n\nconst HistoryProvider = ({ children }: HistoryProviderProps) => {\n const location = useLocation();\n const navigationType = useNavigationType();\n const navigate = useNavigate();\n const [state, dispatch] = React.useReducer(reducer, {\n history: [],\n currentLocationIndex: 0,\n currentLocation: '',\n canGoBack: false,\n });\n\n const isGoingBack = React.useRef(false);\n\n const pushState: HistoryContextValue['pushState'] = React.useCallback((path) => {\n dispatch({\n type: 'PUSH_STATE',\n payload: typeof path === 'string' ? { to: path, search: '' } : path,\n });\n }, []);\n\n const goBack: HistoryContextValue['goBack'] = React.useCallback(() => {\n /**\n * Perform the browser back action, dispatch the goBack action to keep the state in sync\n * and set the ref to avoid an infinite loop and incorrect state pushing\n */\n navigate(-1);\n dispatch({ type: 'GO_BACK' });\n isGoingBack.current = true;\n }, [navigate]);\n\n /**\n * This is a semi-listener pattern to keep the `canGoBack` state in sync.\n */\n const prevIndex = React.useRef(state.currentLocationIndex);\n React.useEffect(() => {\n if (state.currentLocationIndex !== prevIndex.current) {\n dispatch({\n type: 'SET_CAN_GO_BACK',\n payload: state.currentLocationIndex > 1 && state.history.length > 1,\n });\n prevIndex.current = state.currentLocationIndex;\n }\n }, [prevIndex, state.currentLocationIndex, state.history.length]);\n\n /**\n * This effect is responsible for pushing the new state to the history\n * when the user navigates to a new location assuming they're not going back.\n */\n React.useLayoutEffect(() => {\n if (isGoingBack.current) {\n isGoingBack.current = false;\n } else if (navigationType === 'REPLACE') {\n // Prevent appending to the history when the location changes via a replace:true navigation\n dispatch({\n type: 'REPLACE_STATE',\n payload: { to: location.pathname, search: location.search },\n });\n } else {\n // this should only occur on link movements, not back/forward clicks\n dispatch({\n type: 'PUSH_STATE',\n payload: { to: location.pathname, search: location.search },\n });\n }\n }, [dispatch, location.pathname, location.search, navigationType]);\n\n return (\n <Provider pushState={pushState} goBack={goBack} {...state}>\n {children}\n </Provider>\n );\n};\n\ntype HistoryActions =\n | {\n type: 'PUSH_STATE';\n payload: {\n to: string;\n search: string;\n };\n }\n | {\n type: 'REPLACE_STATE';\n payload: {\n to: string;\n search: string;\n };\n }\n | {\n type: 'GO_BACK';\n }\n | {\n type: 'SET_CAN_GO_BACK';\n payload: boolean;\n };\n\nconst reducer = (state: HistoryState, action: HistoryActions) =>\n produce(state, (draft) => {\n switch (action.type) {\n case 'PUSH_STATE': {\n const path = `${action.payload.to}${action.payload.search}`;\n if (state.currentLocationIndex === state.history.length) {\n // add the new place\n draft.history = [...state.history, path];\n } else {\n // delete all the history after the current place and then add the new place\n draft.history = [...state.history.slice(0, state.currentLocationIndex), path];\n }\n\n draft.currentLocation = path;\n draft.currentLocationIndex += 1;\n\n break;\n }\n case 'REPLACE_STATE': {\n const path = `${action.payload.to}${action.payload.search}`;\n draft.history = [...state.history.slice(0, state.currentLocationIndex - 1), path];\n draft.currentLocation = path;\n break;\n }\n case 'GO_BACK': {\n const newIndex = state.currentLocationIndex - 1;\n\n draft.currentLocation = state.history[newIndex - 1];\n draft.currentLocationIndex = newIndex;\n break;\n }\n case 'SET_CAN_GO_BACK': {\n draft.canGoBack = action.payload;\n break;\n }\n default:\n break;\n }\n });\n\n/* -------------------------------------------------------------------------------------------------\n * BackButton\n * -----------------------------------------------------------------------------------------------*/\ninterface BackButtonProps extends Pick<LinkProps, 'disabled'> {\n fallback?: To;\n}\n\n/**\n * @beta\n * @description The universal back button for the Strapi application. This uses the internal history\n * context to navigate the user back to the previous location. It can be completely disabled in a\n * specific user case. When no history is available, you can provide a fallback destination,\n * otherwise the link will be disabled.\n */\nconst BackButton = React.forwardRef<HTMLAnchorElement, BackButtonProps>(\n ({ disabled, fallback = '' }, ref) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n\n const canGoBack = useHistory('BackButton', (state) => state.canGoBack);\n const goBack = useHistory('BackButton', (state) => state.goBack);\n const history = useHistory('BackButton', (state) => state.history);\n const currentLocationIndex = useHistory('BackButton', (state) => state.currentLocationIndex);\n const hasFallback = fallback !== '';\n const shouldBeDisabled = disabled || (!canGoBack && !hasFallback);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n\n if (canGoBack) {\n goBack();\n } else if (hasFallback) {\n navigate(fallback);\n }\n };\n\n // The link destination from the history. Undefined if there is only 1 location in the history.\n const historyTo = canGoBack ? history.at(currentLocationIndex - 2) : undefined;\n // If no link destination from the history, use the fallback.\n const toWithFallback = historyTo ?? fallback;\n\n return (\n <Link\n ref={ref}\n tag={NavLink}\n to={toWithFallback}\n onClick={handleClick}\n disabled={shouldBeDisabled}\n aria-disabled={shouldBeDisabled}\n startIcon={<ArrowLeft />}\n >\n {formatMessage({\n id: 'global.back',\n defaultMessage: 'Back',\n })}\n </Link>\n );\n }\n);\n\nexport { BackButton, HistoryProvider, useHistory };\nexport type { BackButtonProps, HistoryProviderProps, HistoryContextValue, HistoryState };\n"],"names":["Provider","useHistory","createContext","history","currentLocationIndex","currentLocation","canGoBack","pushState","Error","goBack","HistoryProvider","children","location","useLocation","navigationType","useNavigationType","navigate","useNavigate","state","dispatch","React","useReducer","reducer","isGoingBack","useRef","useCallback","path","type","payload","to","search","current","prevIndex","useEffect","length","useLayoutEffect","pathname","_jsx","action","produce","draft","slice","newIndex","BackButton","forwardRef","disabled","fallback","ref","formatMessage","useIntl","hasFallback","shouldBeDisabled","handleClick","e","preventDefault","historyTo","at","undefined","toWithFallback","Link","tag","NavLink","onClick","aria-disabled","startIcon","ArrowLeft","id","defaultMessage"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tracking.js","sources":["../../../../../admin/src/features/Tracking.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport axios, { AxiosResponse } from 'axios';\n\nimport { Tours } from '../components/GuidedTour/Tours';\nimport { useDeviceType } from '../hooks/useDeviceType';\nimport { useInitQuery, useTelemetryPropertiesQuery } from '../services/admin';\n\nimport { useAppInfo } from './AppInfo';\nimport { useAuth } from './Auth';\nimport { useStrapiApp } from './StrapiApp';\n\nexport interface TelemetryProperties {\n useTypescriptOnServer?: boolean;\n useTypescriptOnAdmin?: boolean;\n isHostedOnStrapiCloud?: boolean;\n aiLicenseKey?: string;\n numberOfAllContentTypes?: number;\n numberOfComponents?: number;\n numberOfDynamicZones?: number;\n}\n\nexport interface TrackingContextValue {\n uuid?: string | boolean;\n telemetryProperties?: TelemetryProperties;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst TrackingContext = React.createContext<TrackingContextValue>({\n uuid: false,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface TrackingProviderProps {\n children: React.ReactNode;\n}\n\nconst TrackingProvider = ({ children }: TrackingProviderProps) => {\n const token = useAuth('App', (state) => state.token);\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n const getAllWidgets = useStrapiApp('TrackingProvider', (state) => state.widgets.getAll);\n\n const { data } = useTelemetryPropertiesQuery(undefined, {\n skip: !initData?.uuid || !token,\n });\n React.useEffect(() => {\n if (uuid && data) {\n const event = 'didInitializeAdministration';\n try {\n fetch(`${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`, {\n method: 'POST',\n body: JSON.stringify({\n // This event is anonymous\n event,\n userId: '',\n eventPropeties: {},\n groupProperties: {\n ...data,\n projectId: uuid,\n registeredWidgets: getAllWidgets().map((widget) => widget.uid),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n });\n } catch {\n // silence is golden\n }\n }\n }, [data, uuid, getAllWidgets]);\n const value = React.useMemo(\n () => ({\n uuid,\n telemetryProperties: data,\n }),\n [uuid, data]\n );\n\n return <TrackingContext.Provider value={value}>{children}</TrackingContext.Provider>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * We can group these events together because none have properties so there's no benefit\n * to having them as separate types.\n *\n * Meanwhile those with properties have different property shapes corresponding to the specific\n * event so understanding which properties go with which event is very helpful.\n */\nexport interface EventWithoutProperties {\n name:\n | 'changeComponentsOrder'\n | 'didAddComponentToDynamicZone'\n | 'didBulkDeleteEntries'\n | 'didNotBulkDeleteEntries'\n | 'didChangeDisplayedFields'\n | 'didCheckDraftRelations'\n | 'didClickGuidedTourHomepageApiTokens'\n | 'didClickGuidedTourHomepageContentManager'\n | 'didClickGuidedTourHomepageContentTypeBuilder'\n | 'didClickGuidedTourStep1CollectionType'\n | 'didClickGuidedTourStep2ContentManager'\n | 'didClickGuidedTourStep3ApiTokens'\n | 'didClickonBlogSection'\n | 'didClickonCodeExampleSection'\n | 'didClickonReadTheDocumentationSection'\n | 'didClickOnTryStrapiCloudSection'\n | 'didClickonTutorialSection'\n | 'didCreateGuidedTourCollectionType'\n | 'didCreateGuidedTourEntry'\n | 'didCreateNewRole'\n | 'didCreateRole'\n | 'didDeleteToken'\n | 'didDuplicateRole'\n | 'didEditEditSettings'\n | 'didEditEmailTemplates'\n | 'didEditFieldNameOnContentType'\n | 'didEditListSettings'\n | 'didEditMediaLibraryConfig'\n | 'didEditNameOfContentType'\n | 'didGenerateGuidedTourApiTokens'\n | 'didGoToMarketplace'\n | 'didLaunchGuidedtour'\n | 'didMissMarketplacePlugin'\n | 'didNotCreateFirstAdmin'\n | 'didNotSaveComponent'\n | 'didPluginLearnMore'\n | 'didBulkPublishEntries'\n | 'didNotBulkPublishEntries'\n | 'didUnpublishEntry'\n | 'didBulkUnpublishEntries'\n | 'didNotBulkUnpublishEntries'\n | 'didSaveComponent'\n | 'didSaveContentType'\n | 'didSearch'\n | 'didSkipGuidedtour'\n | 'didSubmitPlugin'\n | 'didSubmitProvider'\n | 'didUpdateConditions'\n | 'didSelectAllMediaLibraryElements'\n | 'didSelectContentTypeFieldSettings'\n | 'didSelectContentTypeSettings'\n | 'didEditAuthenticationProvider'\n | 'didRestoreHistoryVersion'\n | 'hasClickedCTBAddFieldBanner'\n | 'removeComponentFromDynamicZone'\n | 'willAddMoreFieldToContentType'\n | 'willBulkDeleteEntries'\n | 'willBulkPublishEntries'\n | 'willBulkUnpublishEntries'\n | 'willChangeNumberOfEntriesPerPage'\n | 'willCheckDraftRelations'\n | 'willCreateComponent'\n | 'willCreateComponentFromAttributesModal'\n | 'willCreateContentType'\n | 'willCreateFirstAdmin'\n | 'willCreateNewRole'\n | 'willCreateRole'\n | 'willCreateSingleType'\n | 'willCreateStage'\n | 'willCreateWorkflow'\n | 'willDeleteEntryFromList'\n | 'willDeleteFieldOfContentType'\n | 'willDuplicateRole'\n | 'willEditEditLayout'\n | 'willEditEmailTemplates'\n | 'willEditEntryFromButton'\n | 'willEditEntryFromList'\n | 'willEditReleaseFromHome'\n | 'willEditFieldOfContentType'\n | 'willEditMediaLibraryConfig'\n | 'willEditNameOfContentType'\n | 'willEditNameOfSingleType'\n | 'willEditAuthenticationProvider'\n | 'willEditFieldNameOnContentType'\n | 'willEditStage'\n | 'willFilterEntries'\n | 'willInstallPlugin'\n | 'willOpenAuditLogDetailsFromHome'\n | 'willUnpublishEntry'\n | 'willSaveComponent'\n | 'willSaveContentType'\n | 'willSaveContentTypeLayout'\n | 'didEditFieldNameOnContentType'\n | 'didCreateRelease'\n | 'didStartNewChat'\n | 'didLaunchGuidedtour'\n | 'didEditAICaption'\n | 'didEditAIAlternativeText';\n properties?: never;\n}\n\ninterface DidAccessAuthenticatedAdministrationEvent {\n name: 'didAccessAuthenticatedAdministration';\n properties: {\n registeredWidgets: string[];\n projectId: string;\n };\n}\n\ninterface DidFilterMediaLibraryElementsEvent {\n name: 'didFilterMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n filter: string;\n };\n}\n\ninterface DidSortMediaLibraryElementsEvent {\n name: 'didSortMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n sort: string;\n };\n}\n\ninterface DidCropFileEvent {\n name: 'didCropFile';\n properties: MediaEvents['properties'] & {\n duplicatedFile: null | boolean;\n };\n}\n\ninterface DidSelectFile {\n name: 'didSelectFile';\n properties: MediaEvents['properties'] & {\n source: 'url' | 'computer';\n };\n}\n\ninterface DidEditMediaLibraryElementsEvent {\n name: 'didEditMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n type: string;\n changeLocation: string | boolean;\n };\n}\n\ninterface MediaEvents {\n name:\n | 'didSearchMediaLibraryElements'\n | 'didReplaceMedia'\n | 'didAddMediaLibraryFolders'\n | 'willAddMediaLibraryAssets';\n properties: {\n location: string;\n };\n}\n\ninterface DidSelectContentTypeFieldTypeEvent {\n name: 'didSelectContentTypeFieldType';\n properties: {\n type?: string;\n };\n}\n\ninterface DidChangeModeEvent {\n name: 'didChangeMode';\n properties: {\n newMode: string;\n };\n}\ninterface DidSubmitWithErrorsFirstAdminEvent {\n name: 'didSubmitWithErrorsFirstAdmin';\n properties: {\n count: string;\n };\n}\n\ninterface WillNavigateEvent {\n name: 'willNavigate';\n properties: {\n from: string;\n to: string;\n };\n}\n\ninterface DidAccessTokenListEvent {\n name: 'didAccessTokenList';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n number: number;\n };\n}\ninterface LogoEvent {\n name: 'didChangeLogo' | 'didClickResetLogo';\n properties: {\n logo: 'menu' | 'auth';\n };\n}\n\ninterface TokenEvents {\n name:\n | 'didCopyTokenKey'\n | 'didAddTokenFromList'\n | 'didEditTokenFromList'\n | 'willAccessTokenList'\n | 'willAddTokenFromList'\n | 'willCreateToken'\n | 'willDeleteToken'\n | 'willEditToken'\n | 'willEditTokenFromList';\n properties: {\n tokenType: 'api-token' | 'transfer-token';\n };\n}\n\ninterface WillModifyTokenEvent {\n name: 'didCreateToken' | 'didEditToken';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n type: 'custom' | 'full-access' | 'read-only' | Array<'push' | 'pull' | 'push-pull'>;\n };\n}\n\ninterface DeleteEntryEvents {\n name: 'willDeleteEntry' | 'didDeleteEntry' | 'didNotDeleteEntry';\n properties: {\n status?: string;\n error?: unknown;\n };\n}\n\ninterface CreateEntryEvents {\n name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface PublishEntryEvents {\n name: 'willPublishEntry' | 'didPublishEntry';\n properties: {\n documentId?: string;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface UpdateEntryEvents {\n name: 'willEditEntry' | 'didEditEntry' | 'didNotEditEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface DidFilterEntriesEvent {\n name: 'didFilterEntries';\n properties: {\n useRelation: boolean;\n };\n}\n\ninterface DidPublishRelease {\n name: 'didPublishRelease';\n properties: {\n totalEntries: number;\n totalPublishedEntries: number;\n totalUnpublishedEntries: number;\n };\n}\n\ninterface DidUsePresetPromptEvent {\n name: 'didUsePresetPrompt';\n properties: {\n promptType:\n | 'generate-product-schema'\n | 'tell-me-about-the-content-type-builder'\n | 'tell-me-about-strapi';\n };\n}\n\ninterface DidAnswerMessageEvent {\n name: 'didAnswerMessage';\n properties: {\n successful: boolean;\n };\n}\n\ninterface DidVoteAnswerEvent {\n name: 'didVoteAnswer';\n properties: {\n value: 'positive' | 'negative';\n };\n}\n\ninterface DidUpdateCTBSchema {\n name: 'didUpdateCTBSchema';\n properties: {\n success: boolean;\n newContentTypes: number;\n editedContentTypes: number;\n deletedContentTypes: number;\n newComponents: number;\n editedComponents: number;\n deletedComponents: number;\n newFields: number;\n editedFields: number;\n deletedFields: number;\n };\n}\n\ninterface DidSkipGuidedTour {\n name: 'didSkipGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidCompleteGuidedTour {\n name: 'didCompleteGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidStartGuidedTour {\n name: 'didStartGuidedTour';\n properties: {\n name: keyof Tours;\n fromHomepage?: boolean;\n };\n}\n\ninterface WillEditEntryFromHome {\n name: 'willEditEntryFromHome';\n properties: {\n entryType: 'edited' | 'published' | 'assigned';\n };\n}\n\ninterface DidOpenHomeWidgetLink {\n name: 'didOpenHomeWidgetLink';\n properties: {\n widgetUID: string;\n };\n}\n\ninterface DidOpenKeyStatisticsWidgetLink {\n name: 'didOpenKeyStatisticsWidgetLink';\n properties: {\n itemKey: string;\n };\n}\n\ntype EventsWithProperties =\n | CreateEntryEvents\n | PublishEntryEvents\n | DidAccessAuthenticatedAdministrationEvent\n | DidAccessTokenListEvent\n | DidChangeModeEvent\n | DidCropFileEvent\n | DeleteEntryEvents\n | DidEditMediaLibraryElementsEvent\n | DidFilterMediaLibraryElementsEvent\n | DidFilterEntriesEvent\n | DidSelectContentTypeFieldTypeEvent\n | DidSelectFile\n | DidSortMediaLibraryElementsEvent\n | DidSubmitWithErrorsFirstAdminEvent\n | DidUsePresetPromptEvent\n | DidAnswerMessageEvent\n | DidVoteAnswerEvent\n | LogoEvent\n | TokenEvents\n | UpdateEntryEvents\n | WillModifyTokenEvent\n | WillNavigateEvent\n | DidPublishRelease\n | MediaEvents\n | DidUpdateCTBSchema\n | DidSkipGuidedTour\n | DidCompleteGuidedTour\n | DidStartGuidedTour\n | DidOpenHomeWidgetLink\n | DidOpenKeyStatisticsWidgetLink\n | WillEditEntryFromHome;\n\nexport type TrackingEvent = EventWithoutProperties | EventsWithProperties;\nexport interface UseTrackingReturn {\n /**\n * This type helps show all the available event names before you start typing,\n * however autocomplete isn't great.\n */\n trackUsage<TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n trackUsage<TEvent extends Extract<TrackingEvent, { properties?: never }>>(\n event: TEvent['name'],\n properties?: never\n ): Promise<null | AxiosResponse<string>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trackUsage<TEvent extends Extract<TrackingEvent, { properties: object }>>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n}\n\n/**\n * @description Used to send amplitude events to the Strapi Tracking hub.\n *\n * @example\n * ```tsx\n * import { useTracking } from '@strapi/strapi/admin';\n *\n * const MyComponent = () => {\n * const { trackUsage } = useTracking();\n *\n * const handleClick = () => {\n * trackUsage('my-event', { myProperty: 'myValue' });\n * }\n *\n * return <button onClick={handleClick}>Send Event</button>\n * }\n * ```\n */\nconst useTracking = (): UseTrackingReturn => {\n const deviceType = useDeviceType();\n const { uuid, telemetryProperties } = React.useContext(TrackingContext);\n const userId = useAppInfo('useTracking', (state) => state.userId);\n const trackUsage = React.useCallback(\n async <TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties?: TEvent['properties']\n ) => {\n try {\n if (uuid && !window.strapi.telemetryDisabled) {\n const res = await axios.post<string>(\n `${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`,\n {\n event,\n userId,\n eventProperties: { ...properties },\n userProperties: {\n deviceType,\n },\n groupProperties: {\n ...telemetryProperties,\n projectId: uuid,\n projectType: window.strapi.projectType,\n aiLicenseKey: window.strapi.aiLicenseKey,\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n }\n );\n\n return res;\n }\n } catch (err) {\n // Silence is golden\n }\n\n return null;\n },\n [telemetryProperties, userId, uuid]\n );\n\n return { trackUsage };\n};\n\nexport { TrackingProvider, useTracking };\n"],"names":["TrackingContext","React","createContext","uuid","TrackingProvider","children","token","useAuth","state","data","initData","useInitQuery","getAllWidgets","useStrapiApp","widgets","getAll","useTelemetryPropertiesQuery","undefined","skip","useEffect","event","fetch","process","env","STRAPI_ANALYTICS_URL","method","body","JSON","stringify","userId","eventPropeties","groupProperties","projectId","registeredWidgets","map","widget","uid","headers","value","useMemo","telemetryProperties","_jsx","Provider","useTracking","deviceType","useDeviceType","useContext","useAppInfo","trackUsage","useCallback","properties","window","strapi","telemetryDisabled","res","axios","post","eventProperties","userProperties","projectType","aiLicenseKey","err"],"mappings":"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"}
1
+ {"version":3,"file":"Tracking.js","sources":["../../../../../admin/src/features/Tracking.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport axios, { AxiosResponse } from 'axios';\n\nimport { Tours } from '../components/GuidedTour/Tours';\nimport { useDeviceType } from '../hooks/useDeviceType';\nimport { useInitQuery, useTelemetryPropertiesQuery } from '../services/admin';\n\nimport { useAppInfo } from './AppInfo';\nimport { useAuth } from './Auth';\nimport { useStrapiApp } from './StrapiApp';\n\nexport interface TelemetryProperties {\n useTypescriptOnServer?: boolean;\n useTypescriptOnAdmin?: boolean;\n isHostedOnStrapiCloud?: boolean;\n aiLicenseKey?: string;\n numberOfAllContentTypes?: number;\n numberOfComponents?: number;\n numberOfDynamicZones?: number;\n}\n\nexport interface TrackingContextValue {\n uuid?: string | boolean;\n telemetryProperties?: TelemetryProperties;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst TrackingContext = React.createContext<TrackingContextValue>({\n uuid: false,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface TrackingProviderProps {\n children: React.ReactNode;\n}\n\nconst TrackingProvider = ({ children }: TrackingProviderProps) => {\n const token = useAuth('App', (state) => state.token);\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n const getAllWidgets = useStrapiApp('TrackingProvider', (state) => state.widgets.getAll);\n\n const { data } = useTelemetryPropertiesQuery(undefined, {\n skip: !initData?.uuid || !token,\n });\n React.useEffect(() => {\n if (uuid && data) {\n const event = 'didInitializeAdministration';\n try {\n fetch(`${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`, {\n method: 'POST',\n body: JSON.stringify({\n // This event is anonymous\n event,\n userId: '',\n eventPropeties: {},\n groupProperties: {\n ...data,\n projectId: uuid,\n registeredWidgets: getAllWidgets().map((widget) => widget.uid),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n });\n } catch {\n // silence is golden\n }\n }\n }, [data, uuid, getAllWidgets]);\n const value = React.useMemo(\n () => ({\n uuid,\n telemetryProperties: data,\n }),\n [uuid, data]\n );\n\n return <TrackingContext.Provider value={value}>{children}</TrackingContext.Provider>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * We can group these events together because none have properties so there's no benefit\n * to having them as separate types.\n *\n * Meanwhile those with properties have different property shapes corresponding to the specific\n * event so understanding which properties go with which event is very helpful.\n */\nexport interface EventWithoutProperties {\n name:\n | 'changeComponentsOrder'\n | 'didAddComponentToDynamicZone'\n | 'didBulkDeleteEntries'\n | 'didNotBulkDeleteEntries'\n | 'didChangeDisplayedFields'\n | 'didCheckDraftRelations'\n | 'didClickGuidedTourHomepageApiTokens'\n | 'didClickGuidedTourHomepageContentManager'\n | 'didClickGuidedTourHomepageContentTypeBuilder'\n | 'didClickGuidedTourStep1CollectionType'\n | 'didClickGuidedTourStep2ContentManager'\n | 'didClickGuidedTourStep3ApiTokens'\n | 'didClickonBlogSection'\n | 'didClickonCodeExampleSection'\n | 'didClickonReadTheDocumentationSection'\n | 'didClickOnTryStrapiCloudSection'\n | 'didClickonTutorialSection'\n | 'didCreateGuidedTourCollectionType'\n | 'didCreateGuidedTourEntry'\n | 'didCreateNewRole'\n | 'didCreateRole'\n | 'didDeleteToken'\n | 'didDuplicateRole'\n | 'didEditEditSettings'\n | 'didEditEmailTemplates'\n | 'didEditFieldNameOnContentType'\n | 'didEditListSettings'\n | 'didEditMediaLibraryConfig'\n | 'didEditNameOfContentType'\n | 'didGenerateGuidedTourApiTokens'\n | 'didGoToMarketplace'\n | 'didLaunchGuidedtour'\n | 'didMissMarketplacePlugin'\n | 'didNotCreateFirstAdmin'\n | 'didNotSaveComponent'\n | 'didPluginLearnMore'\n | 'didBulkPublishEntries'\n | 'didNotBulkPublishEntries'\n | 'didUnpublishEntry'\n | 'didBulkUnpublishEntries'\n | 'didNotBulkUnpublishEntries'\n | 'didSaveComponent'\n | 'didSaveContentType'\n | 'didSearch'\n | 'didSkipGuidedtour'\n | 'didSubmitPlugin'\n | 'didSubmitProvider'\n | 'didUpdateConditions'\n | 'didSelectAllMediaLibraryElements'\n | 'didSelectContentTypeFieldSettings'\n | 'didSelectContentTypeSettings'\n | 'didEditAuthenticationProvider'\n | 'didRestoreHistoryVersion'\n | 'hasClickedCTBAddFieldBanner'\n | 'removeComponentFromDynamicZone'\n | 'willAddMoreFieldToContentType'\n | 'willBulkDeleteEntries'\n | 'willBulkPublishEntries'\n | 'willBulkUnpublishEntries'\n | 'willChangeNumberOfEntriesPerPage'\n | 'willCheckDraftRelations'\n | 'willCreateComponent'\n | 'willCreateComponentFromAttributesModal'\n | 'willCreateContentType'\n | 'willCreateFirstAdmin'\n | 'willCreateNewRole'\n | 'willCreateRole'\n | 'willCreateSingleType'\n | 'willCreateStage'\n | 'willCreateWorkflow'\n | 'willDeleteEntryFromList'\n | 'willDeleteFieldOfContentType'\n | 'willDuplicateRole'\n | 'willEditEditLayout'\n | 'willEditEmailTemplates'\n | 'willEditEntryFromButton'\n | 'willEditEntryFromList'\n | 'willEditReleaseFromHome'\n | 'willEditFieldOfContentType'\n | 'willEditMediaLibraryConfig'\n | 'willEditNameOfContentType'\n | 'willEditNameOfSingleType'\n | 'willEditAuthenticationProvider'\n | 'willEditFieldNameOnContentType'\n | 'willEditStage'\n | 'willFilterEntries'\n | 'willInstallPlugin'\n | 'willOpenAuditLogDetailsFromHome'\n | 'willUnpublishEntry'\n | 'willSaveComponent'\n | 'willSaveContentType'\n | 'willSaveContentTypeLayout'\n | 'didEditFieldNameOnContentType'\n | 'didCreateRelease'\n | 'didStartNewChat'\n | 'didLaunchGuidedtour'\n | 'didEditAICaption'\n | 'didEditAIAlternativeText';\n properties?: never;\n}\n\ninterface DidAccessAuthenticatedAdministrationEvent {\n name: 'didAccessAuthenticatedAdministration';\n properties: {\n registeredWidgets: string[];\n projectId: string;\n };\n}\n\ninterface DidFilterMediaLibraryElementsEvent {\n name: 'didFilterMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n filter: string;\n };\n}\n\ninterface DidSortMediaLibraryElementsEvent {\n name: 'didSortMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n sort: string;\n };\n}\n\ninterface DidCropFileEvent {\n name: 'didCropFile';\n properties: MediaEvents['properties'] & {\n duplicatedFile: null | boolean;\n };\n}\n\ninterface DidSelectFile {\n name: 'didSelectFile';\n properties: MediaEvents['properties'] & {\n source: 'url' | 'computer';\n };\n}\n\ninterface DidEditMediaLibraryElementsEvent {\n name: 'didEditMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n type: string;\n changeLocation: string | boolean;\n };\n}\n\ninterface MediaEvents {\n name:\n | 'didSearchMediaLibraryElements'\n | 'didReplaceMedia'\n | 'didAddMediaLibraryFolders'\n | 'willAddMediaLibraryAssets';\n properties: {\n location: string;\n };\n}\n\ninterface DidSelectContentTypeFieldTypeEvent {\n name: 'didSelectContentTypeFieldType';\n properties: {\n type?: string;\n };\n}\n\ninterface DidChangeModeEvent {\n name: 'didChangeMode';\n properties: {\n newMode: string;\n };\n}\ninterface DidSubmitWithErrorsFirstAdminEvent {\n name: 'didSubmitWithErrorsFirstAdmin';\n properties: {\n count: string;\n };\n}\n\ninterface WillNavigateEvent {\n name: 'willNavigate';\n properties: {\n from: string;\n to: string;\n };\n}\n\ninterface DidAccessTokenListEvent {\n name: 'didAccessTokenList';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n number: number;\n };\n}\ninterface LogoEvent {\n name: 'didChangeLogo' | 'didClickResetLogo';\n properties: {\n logo: 'menu' | 'auth';\n };\n}\n\ninterface TokenEvents {\n name:\n | 'didCopyTokenKey'\n | 'didAddTokenFromList'\n | 'didEditTokenFromList'\n | 'willAccessTokenList'\n | 'willAddTokenFromList'\n | 'willCreateToken'\n | 'willDeleteToken'\n | 'willEditToken'\n | 'willEditTokenFromList';\n properties: {\n tokenType: 'api-token' | 'transfer-token';\n };\n}\n\ninterface WillModifyTokenEvent {\n name: 'didCreateToken' | 'didEditToken';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n type: 'custom' | 'full-access' | 'read-only' | Array<'push' | 'pull' | 'push-pull'>;\n };\n}\n\ninterface DeleteEntryEvents {\n name: 'willDeleteEntry' | 'didDeleteEntry' | 'didNotDeleteEntry';\n properties: {\n status?: string;\n error?: unknown;\n };\n}\n\ninterface CreateEntryEvents {\n name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface PublishEntryEvents {\n name: 'willPublishEntry' | 'didPublishEntry';\n properties: {\n documentId?: string;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface UpdateEntryEvents {\n name: 'willEditEntry' | 'didEditEntry' | 'didNotEditEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface DidFilterEntriesEvent {\n name: 'didFilterEntries';\n properties: {\n useRelation: boolean;\n };\n}\n\ninterface DidPublishRelease {\n name: 'didPublishRelease';\n properties: {\n totalEntries: number;\n totalPublishedEntries: number;\n totalUnpublishedEntries: number;\n };\n}\n\ninterface DidUsePresetPromptEvent {\n name: 'didUsePresetPrompt';\n properties: {\n promptType:\n | 'generate-product-schema'\n | 'tell-me-about-the-content-type-builder'\n | 'tell-me-about-strapi';\n };\n}\n\ninterface DidAnswerMessageEvent {\n name: 'didAnswerMessage';\n properties: {\n successful: boolean;\n };\n}\n\ninterface DidVoteAnswerEvent {\n name: 'didVoteAnswer';\n properties: {\n value: 'positive' | 'negative';\n };\n}\n\ninterface DidUpdateCTBSchema {\n name: 'didUpdateCTBSchema';\n properties: {\n success: boolean;\n newContentTypes: number;\n editedContentTypes: number;\n deletedContentTypes: number;\n newComponents: number;\n editedComponents: number;\n deletedComponents: number;\n newFields: number;\n editedFields: number;\n deletedFields: number;\n };\n}\n\ninterface DidSkipGuidedTour {\n name: 'didSkipGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidCompleteGuidedTour {\n name: 'didCompleteGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidStartGuidedTour {\n name: 'didStartGuidedTour';\n properties: {\n name: keyof Tours;\n fromHomepage?: boolean;\n };\n}\n\ninterface WillEditEntryFromHome {\n name: 'willEditEntryFromHome';\n properties: {\n entryType: 'edited' | 'published' | 'assigned';\n };\n}\n\ninterface DidOpenHomeWidgetLink {\n name: 'didOpenHomeWidgetLink';\n properties: {\n widgetUID: string;\n };\n}\n\ninterface DidOpenKeyStatisticsWidgetLink {\n name: 'didOpenKeyStatisticsWidgetLink';\n properties: {\n itemKey: string;\n };\n}\n\ntype EventsWithProperties =\n | CreateEntryEvents\n | PublishEntryEvents\n | DidAccessAuthenticatedAdministrationEvent\n | DidAccessTokenListEvent\n | DidChangeModeEvent\n | DidCropFileEvent\n | DeleteEntryEvents\n | DidEditMediaLibraryElementsEvent\n | DidFilterMediaLibraryElementsEvent\n | DidFilterEntriesEvent\n | DidSelectContentTypeFieldTypeEvent\n | DidSelectFile\n | DidSortMediaLibraryElementsEvent\n | DidSubmitWithErrorsFirstAdminEvent\n | DidUsePresetPromptEvent\n | DidAnswerMessageEvent\n | DidVoteAnswerEvent\n | LogoEvent\n | TokenEvents\n | UpdateEntryEvents\n | WillModifyTokenEvent\n | WillNavigateEvent\n | DidPublishRelease\n | MediaEvents\n | DidUpdateCTBSchema\n | DidSkipGuidedTour\n | DidCompleteGuidedTour\n | DidStartGuidedTour\n | DidOpenHomeWidgetLink\n | DidOpenKeyStatisticsWidgetLink\n | WillEditEntryFromHome;\n\nexport type TrackingEvent = EventWithoutProperties | EventsWithProperties;\nexport interface UseTrackingReturn {\n /**\n * This type helps show all the available event names before you start typing,\n * however autocomplete isn't great.\n */\n trackUsage<TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n trackUsage<TEvent extends Extract<TrackingEvent, { properties?: never }>>(\n event: TEvent['name'],\n properties?: never\n ): Promise<null | AxiosResponse<string>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trackUsage<TEvent extends Extract<TrackingEvent, { properties: object }>>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n}\n\n/**\n * @description Used to send amplitude events to the Strapi Tracking hub.\n *\n * @example\n * ```tsx\n * import { useTracking } from '@strapi/strapi/admin';\n *\n * const MyComponent = () => {\n * const { trackUsage } = useTracking();\n *\n * const handleClick = () => {\n * trackUsage('my-event', { myProperty: 'myValue' });\n * }\n *\n * return <button onClick={handleClick}>Send Event</button>\n * }\n * ```\n */\nconst useTracking = (): UseTrackingReturn => {\n const deviceType = useDeviceType();\n const { uuid, telemetryProperties } = React.useContext(TrackingContext);\n const userId = useAppInfo('useTracking', (state) => state.userId);\n const trackUsage = React.useCallback(\n async <TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties?: TEvent['properties']\n ) => {\n try {\n if (uuid && !window.strapi.telemetryDisabled) {\n const res = await axios.post<string>(\n `${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`,\n {\n event,\n userId,\n eventProperties: { ...properties },\n userProperties: {\n deviceType,\n },\n groupProperties: {\n ...telemetryProperties,\n projectId: uuid,\n projectType: window.strapi.projectType,\n aiLicenseKey: window.strapi.aiLicenseKey,\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n }\n );\n\n return res;\n }\n } catch (err) {\n // Silence is golden\n }\n\n return null;\n },\n [telemetryProperties, userId, uuid]\n );\n\n return { trackUsage };\n};\n\nexport { TrackingProvider, useTracking };\n"],"names":["TrackingContext","React","createContext","uuid","TrackingProvider","children","token","useAuth","state","data","initData","useInitQuery","getAllWidgets","useStrapiApp","widgets","getAll","useTelemetryPropertiesQuery","undefined","skip","useEffect","event","fetch","process","env","STRAPI_ANALYTICS_URL","method","body","JSON","stringify","userId","eventPropeties","groupProperties","projectId","registeredWidgets","map","widget","uid","headers","value","useMemo","telemetryProperties","_jsx","Provider","useTracking","deviceType","useDeviceType","useContext","useAppInfo","trackUsage","useCallback","properties","window","strapi","telemetryDisabled","res","axios","post","eventProperties","userProperties","projectType","aiLicenseKey","err"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Tracking.mjs","sources":["../../../../../admin/src/features/Tracking.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport axios, { AxiosResponse } from 'axios';\n\nimport { Tours } from '../components/GuidedTour/Tours';\nimport { useDeviceType } from '../hooks/useDeviceType';\nimport { useInitQuery, useTelemetryPropertiesQuery } from '../services/admin';\n\nimport { useAppInfo } from './AppInfo';\nimport { useAuth } from './Auth';\nimport { useStrapiApp } from './StrapiApp';\n\nexport interface TelemetryProperties {\n useTypescriptOnServer?: boolean;\n useTypescriptOnAdmin?: boolean;\n isHostedOnStrapiCloud?: boolean;\n aiLicenseKey?: string;\n numberOfAllContentTypes?: number;\n numberOfComponents?: number;\n numberOfDynamicZones?: number;\n}\n\nexport interface TrackingContextValue {\n uuid?: string | boolean;\n telemetryProperties?: TelemetryProperties;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst TrackingContext = React.createContext<TrackingContextValue>({\n uuid: false,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface TrackingProviderProps {\n children: React.ReactNode;\n}\n\nconst TrackingProvider = ({ children }: TrackingProviderProps) => {\n const token = useAuth('App', (state) => state.token);\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n const getAllWidgets = useStrapiApp('TrackingProvider', (state) => state.widgets.getAll);\n\n const { data } = useTelemetryPropertiesQuery(undefined, {\n skip: !initData?.uuid || !token,\n });\n React.useEffect(() => {\n if (uuid && data) {\n const event = 'didInitializeAdministration';\n try {\n fetch(`${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`, {\n method: 'POST',\n body: JSON.stringify({\n // This event is anonymous\n event,\n userId: '',\n eventPropeties: {},\n groupProperties: {\n ...data,\n projectId: uuid,\n registeredWidgets: getAllWidgets().map((widget) => widget.uid),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n });\n } catch {\n // silence is golden\n }\n }\n }, [data, uuid, getAllWidgets]);\n const value = React.useMemo(\n () => ({\n uuid,\n telemetryProperties: data,\n }),\n [uuid, data]\n );\n\n return <TrackingContext.Provider value={value}>{children}</TrackingContext.Provider>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * We can group these events together because none have properties so there's no benefit\n * to having them as separate types.\n *\n * Meanwhile those with properties have different property shapes corresponding to the specific\n * event so understanding which properties go with which event is very helpful.\n */\nexport interface EventWithoutProperties {\n name:\n | 'changeComponentsOrder'\n | 'didAddComponentToDynamicZone'\n | 'didBulkDeleteEntries'\n | 'didNotBulkDeleteEntries'\n | 'didChangeDisplayedFields'\n | 'didCheckDraftRelations'\n | 'didClickGuidedTourHomepageApiTokens'\n | 'didClickGuidedTourHomepageContentManager'\n | 'didClickGuidedTourHomepageContentTypeBuilder'\n | 'didClickGuidedTourStep1CollectionType'\n | 'didClickGuidedTourStep2ContentManager'\n | 'didClickGuidedTourStep3ApiTokens'\n | 'didClickonBlogSection'\n | 'didClickonCodeExampleSection'\n | 'didClickonReadTheDocumentationSection'\n | 'didClickOnTryStrapiCloudSection'\n | 'didClickonTutorialSection'\n | 'didCreateGuidedTourCollectionType'\n | 'didCreateGuidedTourEntry'\n | 'didCreateNewRole'\n | 'didCreateRole'\n | 'didDeleteToken'\n | 'didDuplicateRole'\n | 'didEditEditSettings'\n | 'didEditEmailTemplates'\n | 'didEditFieldNameOnContentType'\n | 'didEditListSettings'\n | 'didEditMediaLibraryConfig'\n | 'didEditNameOfContentType'\n | 'didGenerateGuidedTourApiTokens'\n | 'didGoToMarketplace'\n | 'didLaunchGuidedtour'\n | 'didMissMarketplacePlugin'\n | 'didNotCreateFirstAdmin'\n | 'didNotSaveComponent'\n | 'didPluginLearnMore'\n | 'didBulkPublishEntries'\n | 'didNotBulkPublishEntries'\n | 'didUnpublishEntry'\n | 'didBulkUnpublishEntries'\n | 'didNotBulkUnpublishEntries'\n | 'didSaveComponent'\n | 'didSaveContentType'\n | 'didSearch'\n | 'didSkipGuidedtour'\n | 'didSubmitPlugin'\n | 'didSubmitProvider'\n | 'didUpdateConditions'\n | 'didSelectAllMediaLibraryElements'\n | 'didSelectContentTypeFieldSettings'\n | 'didSelectContentTypeSettings'\n | 'didEditAuthenticationProvider'\n | 'didRestoreHistoryVersion'\n | 'hasClickedCTBAddFieldBanner'\n | 'removeComponentFromDynamicZone'\n | 'willAddMoreFieldToContentType'\n | 'willBulkDeleteEntries'\n | 'willBulkPublishEntries'\n | 'willBulkUnpublishEntries'\n | 'willChangeNumberOfEntriesPerPage'\n | 'willCheckDraftRelations'\n | 'willCreateComponent'\n | 'willCreateComponentFromAttributesModal'\n | 'willCreateContentType'\n | 'willCreateFirstAdmin'\n | 'willCreateNewRole'\n | 'willCreateRole'\n | 'willCreateSingleType'\n | 'willCreateStage'\n | 'willCreateWorkflow'\n | 'willDeleteEntryFromList'\n | 'willDeleteFieldOfContentType'\n | 'willDuplicateRole'\n | 'willEditEditLayout'\n | 'willEditEmailTemplates'\n | 'willEditEntryFromButton'\n | 'willEditEntryFromList'\n | 'willEditReleaseFromHome'\n | 'willEditFieldOfContentType'\n | 'willEditMediaLibraryConfig'\n | 'willEditNameOfContentType'\n | 'willEditNameOfSingleType'\n | 'willEditAuthenticationProvider'\n | 'willEditFieldNameOnContentType'\n | 'willEditStage'\n | 'willFilterEntries'\n | 'willInstallPlugin'\n | 'willOpenAuditLogDetailsFromHome'\n | 'willUnpublishEntry'\n | 'willSaveComponent'\n | 'willSaveContentType'\n | 'willSaveContentTypeLayout'\n | 'didEditFieldNameOnContentType'\n | 'didCreateRelease'\n | 'didStartNewChat'\n | 'didLaunchGuidedtour'\n | 'didEditAICaption'\n | 'didEditAIAlternativeText';\n properties?: never;\n}\n\ninterface DidAccessAuthenticatedAdministrationEvent {\n name: 'didAccessAuthenticatedAdministration';\n properties: {\n registeredWidgets: string[];\n projectId: string;\n };\n}\n\ninterface DidFilterMediaLibraryElementsEvent {\n name: 'didFilterMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n filter: string;\n };\n}\n\ninterface DidSortMediaLibraryElementsEvent {\n name: 'didSortMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n sort: string;\n };\n}\n\ninterface DidCropFileEvent {\n name: 'didCropFile';\n properties: MediaEvents['properties'] & {\n duplicatedFile: null | boolean;\n };\n}\n\ninterface DidSelectFile {\n name: 'didSelectFile';\n properties: MediaEvents['properties'] & {\n source: 'url' | 'computer';\n };\n}\n\ninterface DidEditMediaLibraryElementsEvent {\n name: 'didEditMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n type: string;\n changeLocation: string | boolean;\n };\n}\n\ninterface MediaEvents {\n name:\n | 'didSearchMediaLibraryElements'\n | 'didReplaceMedia'\n | 'didAddMediaLibraryFolders'\n | 'willAddMediaLibraryAssets';\n properties: {\n location: string;\n };\n}\n\ninterface DidSelectContentTypeFieldTypeEvent {\n name: 'didSelectContentTypeFieldType';\n properties: {\n type?: string;\n };\n}\n\ninterface DidChangeModeEvent {\n name: 'didChangeMode';\n properties: {\n newMode: string;\n };\n}\ninterface DidSubmitWithErrorsFirstAdminEvent {\n name: 'didSubmitWithErrorsFirstAdmin';\n properties: {\n count: string;\n };\n}\n\ninterface WillNavigateEvent {\n name: 'willNavigate';\n properties: {\n from: string;\n to: string;\n };\n}\n\ninterface DidAccessTokenListEvent {\n name: 'didAccessTokenList';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n number: number;\n };\n}\ninterface LogoEvent {\n name: 'didChangeLogo' | 'didClickResetLogo';\n properties: {\n logo: 'menu' | 'auth';\n };\n}\n\ninterface TokenEvents {\n name:\n | 'didCopyTokenKey'\n | 'didAddTokenFromList'\n | 'didEditTokenFromList'\n | 'willAccessTokenList'\n | 'willAddTokenFromList'\n | 'willCreateToken'\n | 'willDeleteToken'\n | 'willEditToken'\n | 'willEditTokenFromList';\n properties: {\n tokenType: 'api-token' | 'transfer-token';\n };\n}\n\ninterface WillModifyTokenEvent {\n name: 'didCreateToken' | 'didEditToken';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n type: 'custom' | 'full-access' | 'read-only' | Array<'push' | 'pull' | 'push-pull'>;\n };\n}\n\ninterface DeleteEntryEvents {\n name: 'willDeleteEntry' | 'didDeleteEntry' | 'didNotDeleteEntry';\n properties: {\n status?: string;\n error?: unknown;\n };\n}\n\ninterface CreateEntryEvents {\n name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface PublishEntryEvents {\n name: 'willPublishEntry' | 'didPublishEntry';\n properties: {\n documentId?: string;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface UpdateEntryEvents {\n name: 'willEditEntry' | 'didEditEntry' | 'didNotEditEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface DidFilterEntriesEvent {\n name: 'didFilterEntries';\n properties: {\n useRelation: boolean;\n };\n}\n\ninterface DidPublishRelease {\n name: 'didPublishRelease';\n properties: {\n totalEntries: number;\n totalPublishedEntries: number;\n totalUnpublishedEntries: number;\n };\n}\n\ninterface DidUsePresetPromptEvent {\n name: 'didUsePresetPrompt';\n properties: {\n promptType:\n | 'generate-product-schema'\n | 'tell-me-about-the-content-type-builder'\n | 'tell-me-about-strapi';\n };\n}\n\ninterface DidAnswerMessageEvent {\n name: 'didAnswerMessage';\n properties: {\n successful: boolean;\n };\n}\n\ninterface DidVoteAnswerEvent {\n name: 'didVoteAnswer';\n properties: {\n value: 'positive' | 'negative';\n };\n}\n\ninterface DidUpdateCTBSchema {\n name: 'didUpdateCTBSchema';\n properties: {\n success: boolean;\n newContentTypes: number;\n editedContentTypes: number;\n deletedContentTypes: number;\n newComponents: number;\n editedComponents: number;\n deletedComponents: number;\n newFields: number;\n editedFields: number;\n deletedFields: number;\n };\n}\n\ninterface DidSkipGuidedTour {\n name: 'didSkipGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidCompleteGuidedTour {\n name: 'didCompleteGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidStartGuidedTour {\n name: 'didStartGuidedTour';\n properties: {\n name: keyof Tours;\n fromHomepage?: boolean;\n };\n}\n\ninterface WillEditEntryFromHome {\n name: 'willEditEntryFromHome';\n properties: {\n entryType: 'edited' | 'published' | 'assigned';\n };\n}\n\ninterface DidOpenHomeWidgetLink {\n name: 'didOpenHomeWidgetLink';\n properties: {\n widgetUID: string;\n };\n}\n\ninterface DidOpenKeyStatisticsWidgetLink {\n name: 'didOpenKeyStatisticsWidgetLink';\n properties: {\n itemKey: string;\n };\n}\n\ntype EventsWithProperties =\n | CreateEntryEvents\n | PublishEntryEvents\n | DidAccessAuthenticatedAdministrationEvent\n | DidAccessTokenListEvent\n | DidChangeModeEvent\n | DidCropFileEvent\n | DeleteEntryEvents\n | DidEditMediaLibraryElementsEvent\n | DidFilterMediaLibraryElementsEvent\n | DidFilterEntriesEvent\n | DidSelectContentTypeFieldTypeEvent\n | DidSelectFile\n | DidSortMediaLibraryElementsEvent\n | DidSubmitWithErrorsFirstAdminEvent\n | DidUsePresetPromptEvent\n | DidAnswerMessageEvent\n | DidVoteAnswerEvent\n | LogoEvent\n | TokenEvents\n | UpdateEntryEvents\n | WillModifyTokenEvent\n | WillNavigateEvent\n | DidPublishRelease\n | MediaEvents\n | DidUpdateCTBSchema\n | DidSkipGuidedTour\n | DidCompleteGuidedTour\n | DidStartGuidedTour\n | DidOpenHomeWidgetLink\n | DidOpenKeyStatisticsWidgetLink\n | WillEditEntryFromHome;\n\nexport type TrackingEvent = EventWithoutProperties | EventsWithProperties;\nexport interface UseTrackingReturn {\n /**\n * This type helps show all the available event names before you start typing,\n * however autocomplete isn't great.\n */\n trackUsage<TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n trackUsage<TEvent extends Extract<TrackingEvent, { properties?: never }>>(\n event: TEvent['name'],\n properties?: never\n ): Promise<null | AxiosResponse<string>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trackUsage<TEvent extends Extract<TrackingEvent, { properties: object }>>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n}\n\n/**\n * @description Used to send amplitude events to the Strapi Tracking hub.\n *\n * @example\n * ```tsx\n * import { useTracking } from '@strapi/strapi/admin';\n *\n * const MyComponent = () => {\n * const { trackUsage } = useTracking();\n *\n * const handleClick = () => {\n * trackUsage('my-event', { myProperty: 'myValue' });\n * }\n *\n * return <button onClick={handleClick}>Send Event</button>\n * }\n * ```\n */\nconst useTracking = (): UseTrackingReturn => {\n const deviceType = useDeviceType();\n const { uuid, telemetryProperties } = React.useContext(TrackingContext);\n const userId = useAppInfo('useTracking', (state) => state.userId);\n const trackUsage = React.useCallback(\n async <TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties?: TEvent['properties']\n ) => {\n try {\n if (uuid && !window.strapi.telemetryDisabled) {\n const res = await axios.post<string>(\n `${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`,\n {\n event,\n userId,\n eventProperties: { ...properties },\n userProperties: {\n deviceType,\n },\n groupProperties: {\n ...telemetryProperties,\n projectId: uuid,\n projectType: window.strapi.projectType,\n aiLicenseKey: window.strapi.aiLicenseKey,\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n }\n );\n\n return res;\n }\n } catch (err) {\n // Silence is golden\n }\n\n return null;\n },\n [telemetryProperties, userId, uuid]\n );\n\n return { trackUsage };\n};\n\nexport { TrackingProvider, useTracking };\n"],"names":["TrackingContext","React","createContext","uuid","TrackingProvider","children","token","useAuth","state","data","initData","useInitQuery","getAllWidgets","useStrapiApp","widgets","getAll","useTelemetryPropertiesQuery","undefined","skip","useEffect","event","fetch","process","env","STRAPI_ANALYTICS_URL","method","body","JSON","stringify","userId","eventPropeties","groupProperties","projectId","registeredWidgets","map","widget","uid","headers","value","useMemo","telemetryProperties","_jsx","Provider","useTracking","deviceType","useDeviceType","useContext","useAppInfo","trackUsage","useCallback","properties","window","strapi","telemetryDisabled","res","axios","post","eventProperties","userProperties","projectType","aiLicenseKey","err"],"mappings":"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"}
1
+ {"version":3,"file":"Tracking.mjs","sources":["../../../../../admin/src/features/Tracking.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport axios, { AxiosResponse } from 'axios';\n\nimport { Tours } from '../components/GuidedTour/Tours';\nimport { useDeviceType } from '../hooks/useDeviceType';\nimport { useInitQuery, useTelemetryPropertiesQuery } from '../services/admin';\n\nimport { useAppInfo } from './AppInfo';\nimport { useAuth } from './Auth';\nimport { useStrapiApp } from './StrapiApp';\n\nexport interface TelemetryProperties {\n useTypescriptOnServer?: boolean;\n useTypescriptOnAdmin?: boolean;\n isHostedOnStrapiCloud?: boolean;\n aiLicenseKey?: string;\n numberOfAllContentTypes?: number;\n numberOfComponents?: number;\n numberOfDynamicZones?: number;\n}\n\nexport interface TrackingContextValue {\n uuid?: string | boolean;\n telemetryProperties?: TelemetryProperties;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Context\n * -----------------------------------------------------------------------------------------------*/\n\nconst TrackingContext = React.createContext<TrackingContextValue>({\n uuid: false,\n});\n\n/* -------------------------------------------------------------------------------------------------\n * Provider\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface TrackingProviderProps {\n children: React.ReactNode;\n}\n\nconst TrackingProvider = ({ children }: TrackingProviderProps) => {\n const token = useAuth('App', (state) => state.token);\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n const getAllWidgets = useStrapiApp('TrackingProvider', (state) => state.widgets.getAll);\n\n const { data } = useTelemetryPropertiesQuery(undefined, {\n skip: !initData?.uuid || !token,\n });\n React.useEffect(() => {\n if (uuid && data) {\n const event = 'didInitializeAdministration';\n try {\n fetch(`${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`, {\n method: 'POST',\n body: JSON.stringify({\n // This event is anonymous\n event,\n userId: '',\n eventPropeties: {},\n groupProperties: {\n ...data,\n projectId: uuid,\n registeredWidgets: getAllWidgets().map((widget) => widget.uid),\n },\n }),\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n });\n } catch {\n // silence is golden\n }\n }\n }, [data, uuid, getAllWidgets]);\n const value = React.useMemo(\n () => ({\n uuid,\n telemetryProperties: data,\n }),\n [uuid, data]\n );\n\n return <TrackingContext.Provider value={value}>{children}</TrackingContext.Provider>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Hook\n * -----------------------------------------------------------------------------------------------*/\n\n/**\n * We can group these events together because none have properties so there's no benefit\n * to having them as separate types.\n *\n * Meanwhile those with properties have different property shapes corresponding to the specific\n * event so understanding which properties go with which event is very helpful.\n */\nexport interface EventWithoutProperties {\n name:\n | 'changeComponentsOrder'\n | 'didAddComponentToDynamicZone'\n | 'didBulkDeleteEntries'\n | 'didNotBulkDeleteEntries'\n | 'didChangeDisplayedFields'\n | 'didCheckDraftRelations'\n | 'didClickGuidedTourHomepageApiTokens'\n | 'didClickGuidedTourHomepageContentManager'\n | 'didClickGuidedTourHomepageContentTypeBuilder'\n | 'didClickGuidedTourStep1CollectionType'\n | 'didClickGuidedTourStep2ContentManager'\n | 'didClickGuidedTourStep3ApiTokens'\n | 'didClickonBlogSection'\n | 'didClickonCodeExampleSection'\n | 'didClickonReadTheDocumentationSection'\n | 'didClickOnTryStrapiCloudSection'\n | 'didClickonTutorialSection'\n | 'didCreateGuidedTourCollectionType'\n | 'didCreateGuidedTourEntry'\n | 'didCreateNewRole'\n | 'didCreateRole'\n | 'didDeleteToken'\n | 'didDuplicateRole'\n | 'didEditEditSettings'\n | 'didEditEmailTemplates'\n | 'didEditFieldNameOnContentType'\n | 'didEditListSettings'\n | 'didEditMediaLibraryConfig'\n | 'didEditNameOfContentType'\n | 'didGenerateGuidedTourApiTokens'\n | 'didGoToMarketplace'\n | 'didLaunchGuidedtour'\n | 'didMissMarketplacePlugin'\n | 'didNotCreateFirstAdmin'\n | 'didNotSaveComponent'\n | 'didPluginLearnMore'\n | 'didBulkPublishEntries'\n | 'didNotBulkPublishEntries'\n | 'didUnpublishEntry'\n | 'didBulkUnpublishEntries'\n | 'didNotBulkUnpublishEntries'\n | 'didSaveComponent'\n | 'didSaveContentType'\n | 'didSearch'\n | 'didSkipGuidedtour'\n | 'didSubmitPlugin'\n | 'didSubmitProvider'\n | 'didUpdateConditions'\n | 'didSelectAllMediaLibraryElements'\n | 'didSelectContentTypeFieldSettings'\n | 'didSelectContentTypeSettings'\n | 'didEditAuthenticationProvider'\n | 'didRestoreHistoryVersion'\n | 'hasClickedCTBAddFieldBanner'\n | 'removeComponentFromDynamicZone'\n | 'willAddMoreFieldToContentType'\n | 'willBulkDeleteEntries'\n | 'willBulkPublishEntries'\n | 'willBulkUnpublishEntries'\n | 'willChangeNumberOfEntriesPerPage'\n | 'willCheckDraftRelations'\n | 'willCreateComponent'\n | 'willCreateComponentFromAttributesModal'\n | 'willCreateContentType'\n | 'willCreateFirstAdmin'\n | 'willCreateNewRole'\n | 'willCreateRole'\n | 'willCreateSingleType'\n | 'willCreateStage'\n | 'willCreateWorkflow'\n | 'willDeleteEntryFromList'\n | 'willDeleteFieldOfContentType'\n | 'willDuplicateRole'\n | 'willEditEditLayout'\n | 'willEditEmailTemplates'\n | 'willEditEntryFromButton'\n | 'willEditEntryFromList'\n | 'willEditReleaseFromHome'\n | 'willEditFieldOfContentType'\n | 'willEditMediaLibraryConfig'\n | 'willEditNameOfContentType'\n | 'willEditNameOfSingleType'\n | 'willEditAuthenticationProvider'\n | 'willEditFieldNameOnContentType'\n | 'willEditStage'\n | 'willFilterEntries'\n | 'willInstallPlugin'\n | 'willOpenAuditLogDetailsFromHome'\n | 'willUnpublishEntry'\n | 'willSaveComponent'\n | 'willSaveContentType'\n | 'willSaveContentTypeLayout'\n | 'didEditFieldNameOnContentType'\n | 'didCreateRelease'\n | 'didStartNewChat'\n | 'didLaunchGuidedtour'\n | 'didEditAICaption'\n | 'didEditAIAlternativeText';\n properties?: never;\n}\n\ninterface DidAccessAuthenticatedAdministrationEvent {\n name: 'didAccessAuthenticatedAdministration';\n properties: {\n registeredWidgets: string[];\n projectId: string;\n };\n}\n\ninterface DidFilterMediaLibraryElementsEvent {\n name: 'didFilterMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n filter: string;\n };\n}\n\ninterface DidSortMediaLibraryElementsEvent {\n name: 'didSortMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n sort: string;\n };\n}\n\ninterface DidCropFileEvent {\n name: 'didCropFile';\n properties: MediaEvents['properties'] & {\n duplicatedFile: null | boolean;\n };\n}\n\ninterface DidSelectFile {\n name: 'didSelectFile';\n properties: MediaEvents['properties'] & {\n source: 'url' | 'computer';\n };\n}\n\ninterface DidEditMediaLibraryElementsEvent {\n name: 'didEditMediaLibraryElements';\n properties: MediaEvents['properties'] & {\n type: string;\n changeLocation: string | boolean;\n };\n}\n\ninterface MediaEvents {\n name:\n | 'didSearchMediaLibraryElements'\n | 'didReplaceMedia'\n | 'didAddMediaLibraryFolders'\n | 'willAddMediaLibraryAssets';\n properties: {\n location: string;\n };\n}\n\ninterface DidSelectContentTypeFieldTypeEvent {\n name: 'didSelectContentTypeFieldType';\n properties: {\n type?: string;\n };\n}\n\ninterface DidChangeModeEvent {\n name: 'didChangeMode';\n properties: {\n newMode: string;\n };\n}\ninterface DidSubmitWithErrorsFirstAdminEvent {\n name: 'didSubmitWithErrorsFirstAdmin';\n properties: {\n count: string;\n };\n}\n\ninterface WillNavigateEvent {\n name: 'willNavigate';\n properties: {\n from: string;\n to: string;\n };\n}\n\ninterface DidAccessTokenListEvent {\n name: 'didAccessTokenList';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n number: number;\n };\n}\ninterface LogoEvent {\n name: 'didChangeLogo' | 'didClickResetLogo';\n properties: {\n logo: 'menu' | 'auth';\n };\n}\n\ninterface TokenEvents {\n name:\n | 'didCopyTokenKey'\n | 'didAddTokenFromList'\n | 'didEditTokenFromList'\n | 'willAccessTokenList'\n | 'willAddTokenFromList'\n | 'willCreateToken'\n | 'willDeleteToken'\n | 'willEditToken'\n | 'willEditTokenFromList';\n properties: {\n tokenType: 'api-token' | 'transfer-token';\n };\n}\n\ninterface WillModifyTokenEvent {\n name: 'didCreateToken' | 'didEditToken';\n properties: {\n tokenType: TokenEvents['properties']['tokenType'];\n type: 'custom' | 'full-access' | 'read-only' | Array<'push' | 'pull' | 'push-pull'>;\n };\n}\n\ninterface DeleteEntryEvents {\n name: 'willDeleteEntry' | 'didDeleteEntry' | 'didNotDeleteEntry';\n properties: {\n status?: string;\n error?: unknown;\n };\n}\n\ninterface CreateEntryEvents {\n name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface PublishEntryEvents {\n name: 'willPublishEntry' | 'didPublishEntry';\n properties: {\n documentId?: string;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface UpdateEntryEvents {\n name: 'willEditEntry' | 'didEditEntry' | 'didNotEditEntry';\n properties: {\n documentId?: string;\n status?: string;\n error?: unknown;\n fromPreview?: boolean;\n fromRelationModal?: boolean;\n };\n}\n\ninterface DidFilterEntriesEvent {\n name: 'didFilterEntries';\n properties: {\n useRelation: boolean;\n };\n}\n\ninterface DidPublishRelease {\n name: 'didPublishRelease';\n properties: {\n totalEntries: number;\n totalPublishedEntries: number;\n totalUnpublishedEntries: number;\n };\n}\n\ninterface DidUsePresetPromptEvent {\n name: 'didUsePresetPrompt';\n properties: {\n promptType:\n | 'generate-product-schema'\n | 'tell-me-about-the-content-type-builder'\n | 'tell-me-about-strapi';\n };\n}\n\ninterface DidAnswerMessageEvent {\n name: 'didAnswerMessage';\n properties: {\n successful: boolean;\n };\n}\n\ninterface DidVoteAnswerEvent {\n name: 'didVoteAnswer';\n properties: {\n value: 'positive' | 'negative';\n };\n}\n\ninterface DidUpdateCTBSchema {\n name: 'didUpdateCTBSchema';\n properties: {\n success: boolean;\n newContentTypes: number;\n editedContentTypes: number;\n deletedContentTypes: number;\n newComponents: number;\n editedComponents: number;\n deletedComponents: number;\n newFields: number;\n editedFields: number;\n deletedFields: number;\n };\n}\n\ninterface DidSkipGuidedTour {\n name: 'didSkipGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidCompleteGuidedTour {\n name: 'didCompleteGuidedTour';\n properties: {\n name: keyof Tours | 'all';\n };\n}\n\ninterface DidStartGuidedTour {\n name: 'didStartGuidedTour';\n properties: {\n name: keyof Tours;\n fromHomepage?: boolean;\n };\n}\n\ninterface WillEditEntryFromHome {\n name: 'willEditEntryFromHome';\n properties: {\n entryType: 'edited' | 'published' | 'assigned';\n };\n}\n\ninterface DidOpenHomeWidgetLink {\n name: 'didOpenHomeWidgetLink';\n properties: {\n widgetUID: string;\n };\n}\n\ninterface DidOpenKeyStatisticsWidgetLink {\n name: 'didOpenKeyStatisticsWidgetLink';\n properties: {\n itemKey: string;\n };\n}\n\ntype EventsWithProperties =\n | CreateEntryEvents\n | PublishEntryEvents\n | DidAccessAuthenticatedAdministrationEvent\n | DidAccessTokenListEvent\n | DidChangeModeEvent\n | DidCropFileEvent\n | DeleteEntryEvents\n | DidEditMediaLibraryElementsEvent\n | DidFilterMediaLibraryElementsEvent\n | DidFilterEntriesEvent\n | DidSelectContentTypeFieldTypeEvent\n | DidSelectFile\n | DidSortMediaLibraryElementsEvent\n | DidSubmitWithErrorsFirstAdminEvent\n | DidUsePresetPromptEvent\n | DidAnswerMessageEvent\n | DidVoteAnswerEvent\n | LogoEvent\n | TokenEvents\n | UpdateEntryEvents\n | WillModifyTokenEvent\n | WillNavigateEvent\n | DidPublishRelease\n | MediaEvents\n | DidUpdateCTBSchema\n | DidSkipGuidedTour\n | DidCompleteGuidedTour\n | DidStartGuidedTour\n | DidOpenHomeWidgetLink\n | DidOpenKeyStatisticsWidgetLink\n | WillEditEntryFromHome;\n\nexport type TrackingEvent = EventWithoutProperties | EventsWithProperties;\nexport interface UseTrackingReturn {\n /**\n * This type helps show all the available event names before you start typing,\n * however autocomplete isn't great.\n */\n trackUsage<TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n trackUsage<TEvent extends Extract<TrackingEvent, { properties?: never }>>(\n event: TEvent['name'],\n properties?: never\n ): Promise<null | AxiosResponse<string>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trackUsage<TEvent extends Extract<TrackingEvent, { properties: object }>>(\n event: TEvent['name'],\n properties: TEvent['properties']\n ): Promise<null | AxiosResponse<string>>;\n}\n\n/**\n * @description Used to send amplitude events to the Strapi Tracking hub.\n *\n * @example\n * ```tsx\n * import { useTracking } from '@strapi/strapi/admin';\n *\n * const MyComponent = () => {\n * const { trackUsage } = useTracking();\n *\n * const handleClick = () => {\n * trackUsage('my-event', { myProperty: 'myValue' });\n * }\n *\n * return <button onClick={handleClick}>Send Event</button>\n * }\n * ```\n */\nconst useTracking = (): UseTrackingReturn => {\n const deviceType = useDeviceType();\n const { uuid, telemetryProperties } = React.useContext(TrackingContext);\n const userId = useAppInfo('useTracking', (state) => state.userId);\n const trackUsage = React.useCallback(\n async <TEvent extends TrackingEvent>(\n event: TEvent['name'],\n properties?: TEvent['properties']\n ) => {\n try {\n if (uuid && !window.strapi.telemetryDisabled) {\n const res = await axios.post<string>(\n `${process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io'}/api/v2/track`,\n {\n event,\n userId,\n eventProperties: { ...properties },\n userProperties: {\n deviceType,\n },\n groupProperties: {\n ...telemetryProperties,\n projectId: uuid,\n projectType: window.strapi.projectType,\n aiLicenseKey: window.strapi.aiLicenseKey,\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'X-Strapi-Event': event,\n },\n }\n );\n\n return res;\n }\n } catch (err) {\n // Silence is golden\n }\n\n return null;\n },\n [telemetryProperties, userId, uuid]\n );\n\n return { trackUsage };\n};\n\nexport { TrackingProvider, useTracking };\n"],"names":["TrackingContext","React","createContext","uuid","TrackingProvider","children","token","useAuth","state","data","initData","useInitQuery","getAllWidgets","useStrapiApp","widgets","getAll","useTelemetryPropertiesQuery","undefined","skip","useEffect","event","fetch","process","env","STRAPI_ANALYTICS_URL","method","body","JSON","stringify","userId","eventPropeties","groupProperties","projectId","registeredWidgets","map","widget","uid","headers","value","useMemo","telemetryProperties","_jsx","Provider","useTracking","deviceType","useDeviceType","useContext","useAppInfo","trackUsage","useCallback","properties","window","strapi","telemetryDisabled","res","axios","post","eventProperties","userProperties","projectType","aiLicenseKey","err"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.js","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.js","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.mjs","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.mjs","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePersistentState.js","sources":["../../../../../admin/src/hooks/usePersistentState.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useInitQuery } from '../services/admin';\n\nconst usePersistentState = <T>(key: string, defaultValue: T) => {\n const [value, setValue] = useState<T>(() => {\n const stickyValue = window.localStorage.getItem(key);\n\n if (stickyValue !== null) {\n try {\n return JSON.parse(stickyValue);\n } catch {\n // JSON.parse fails when the stored value is a primitive\n return stickyValue;\n }\n }\n\n return defaultValue;\n });\n\n useEffect(() => {\n window.localStorage.setItem(key, JSON.stringify(value));\n }, [key, value]);\n\n return [value, setValue] as const;\n};\n\n// Same as usePersistentState, but scoped to the current instance of Strapi\n// useful for storing state that should not be shared across different instances of Strapi running on localhost\nconst useScopedPersistentState = <T>(key: string, defaultValue: T) => {\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n\n const namespacedKey = `${key}:${uuid}`;\n return usePersistentState<T>(namespacedKey, defaultValue);\n};\n\nexport { usePersistentState, useScopedPersistentState };\n"],"names":["usePersistentState","key","defaultValue","value","setValue","useState","stickyValue","window","localStorage","getItem","JSON","parse","useEffect","setItem","stringify","useScopedPersistentState","data","initData","useInitQuery","uuid","namespacedKey"],"mappings":";;;;;AAIMA,MAAAA,kBAAAA,GAAqB,CAAIC,GAAaC,EAAAA,YAAAA,GAAAA;AAC1C,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAS,CAAA,GAAGC,cAAY,CAAA,IAAA;AACpC,QAAA,MAAMC,WAAcC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACR,GAAAA,CAAAA;AAEhD,QAAA,IAAIK,gBAAgB,IAAM,EAAA;YACxB,IAAI;gBACF,OAAOI,IAAAA,CAAKC,KAAK,CAACL,WAAAA,CAAAA;AACpB,aAAA,CAAE,OAAM;;gBAEN,OAAOA,WAAAA;AACT;AACF;QAEA,OAAOJ,YAAAA;AACT,KAAA,CAAA;IAEAU,eAAU,CAAA,IAAA;AACRL,QAAAA,MAAAA,CAAOC,YAAY,CAACK,OAAO,CAACZ,GAAKS,EAAAA,IAAAA,CAAKI,SAAS,CAACX,KAAAA,CAAAA,CAAAA;KAC/C,EAAA;AAACF,QAAAA,GAAAA;AAAKE,QAAAA;AAAM,KAAA,CAAA;IAEf,OAAO;AAACA,QAAAA,KAAAA;AAAOC,QAAAA;AAAS,KAAA;AAC1B;AAEA;AACA;AACMW,MAAAA,wBAAAA,GAA2B,CAAId,GAAaC,EAAAA,YAAAA,GAAAA;AAChD,IAAA,MAAM,EAAEc,IAAAA,EAAMC,QAAQ,EAAE,GAAGC,kBAAAA,EAAAA;AAC3B,IAAA,MAAM,EAAEC,IAAI,EAAE,GAAGF,YAAY,EAAC;AAE9B,IAAA,MAAMG,gBAAgB,CAAC,EAAEnB,IAAI,CAAC,EAAEkB,KAAK,CAAC;AACtC,IAAA,OAAOnB,mBAAsBoB,aAAelB,EAAAA,YAAAA,CAAAA;AAC9C;;;;;"}
1
+ {"version":3,"file":"usePersistentState.js","sources":["../../../../../admin/src/hooks/usePersistentState.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useInitQuery } from '../services/admin';\n\nconst usePersistentState = <T>(key: string, defaultValue: T) => {\n const [value, setValue] = useState<T>(() => {\n const stickyValue = window.localStorage.getItem(key);\n\n if (stickyValue !== null) {\n try {\n return JSON.parse(stickyValue);\n } catch {\n // JSON.parse fails when the stored value is a primitive\n return stickyValue;\n }\n }\n\n return defaultValue;\n });\n\n useEffect(() => {\n window.localStorage.setItem(key, JSON.stringify(value));\n }, [key, value]);\n\n return [value, setValue] as const;\n};\n\n// Same as usePersistentState, but scoped to the current instance of Strapi\n// useful for storing state that should not be shared across different instances of Strapi running on localhost\nconst useScopedPersistentState = <T>(key: string, defaultValue: T) => {\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n\n const namespacedKey = `${key}:${uuid}`;\n return usePersistentState<T>(namespacedKey, defaultValue);\n};\n\nexport { usePersistentState, useScopedPersistentState };\n"],"names":["usePersistentState","key","defaultValue","value","setValue","useState","stickyValue","window","localStorage","getItem","JSON","parse","useEffect","setItem","stringify","useScopedPersistentState","data","initData","useInitQuery","uuid","namespacedKey"],"mappings":";;;;;AAIMA,MAAAA,kBAAAA,GAAqB,CAAIC,GAAaC,EAAAA,YAAAA,GAAAA;AAC1C,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAS,CAAA,GAAGC,cAAY,CAAA,IAAA;AACpC,QAAA,MAAMC,WAAcC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACR,GAAAA,CAAAA;AAEhD,QAAA,IAAIK,gBAAgB,IAAM,EAAA;YACxB,IAAI;gBACF,OAAOI,IAAAA,CAAKC,KAAK,CAACL,WAAAA,CAAAA;AACpB,aAAA,CAAE,OAAM;;gBAEN,OAAOA,WAAAA;AACT;AACF;QAEA,OAAOJ,YAAAA;AACT,KAAA,CAAA;IAEAU,eAAU,CAAA,IAAA;AACRL,QAAAA,MAAAA,CAAOC,YAAY,CAACK,OAAO,CAACZ,GAAKS,EAAAA,IAAAA,CAAKI,SAAS,CAACX,KAAAA,CAAAA,CAAAA;KAC/C,EAAA;AAACF,QAAAA,GAAAA;AAAKE,QAAAA;AAAM,KAAA,CAAA;IAEf,OAAO;AAACA,QAAAA,KAAAA;AAAOC,QAAAA;AAAS,KAAA;AAC1B;AAEA;AACA;AACMW,MAAAA,wBAAAA,GAA2B,CAAId,GAAaC,EAAAA,YAAAA,GAAAA;AAChD,IAAA,MAAM,EAAEc,IAAAA,EAAMC,QAAQ,EAAE,GAAGC,kBAAAA,EAAAA;AAC3B,IAAA,MAAM,EAAEC,IAAI,EAAE,GAAGF,YAAY,EAAC;AAE9B,IAAA,MAAMG,aAAgB,GAAA,CAAA,EAAGnB,GAAI,CAAA,CAAC,EAAEkB,IAAM,CAAA,CAAA;AACtC,IAAA,OAAOnB,mBAAsBoB,aAAelB,EAAAA,YAAAA,CAAAA;AAC9C;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePersistentState.mjs","sources":["../../../../../admin/src/hooks/usePersistentState.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useInitQuery } from '../services/admin';\n\nconst usePersistentState = <T>(key: string, defaultValue: T) => {\n const [value, setValue] = useState<T>(() => {\n const stickyValue = window.localStorage.getItem(key);\n\n if (stickyValue !== null) {\n try {\n return JSON.parse(stickyValue);\n } catch {\n // JSON.parse fails when the stored value is a primitive\n return stickyValue;\n }\n }\n\n return defaultValue;\n });\n\n useEffect(() => {\n window.localStorage.setItem(key, JSON.stringify(value));\n }, [key, value]);\n\n return [value, setValue] as const;\n};\n\n// Same as usePersistentState, but scoped to the current instance of Strapi\n// useful for storing state that should not be shared across different instances of Strapi running on localhost\nconst useScopedPersistentState = <T>(key: string, defaultValue: T) => {\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n\n const namespacedKey = `${key}:${uuid}`;\n return usePersistentState<T>(namespacedKey, defaultValue);\n};\n\nexport { usePersistentState, useScopedPersistentState };\n"],"names":["usePersistentState","key","defaultValue","value","setValue","useState","stickyValue","window","localStorage","getItem","JSON","parse","useEffect","setItem","stringify","useScopedPersistentState","data","initData","useInitQuery","uuid","namespacedKey"],"mappings":";;;AAIMA,MAAAA,kBAAAA,GAAqB,CAAIC,GAAaC,EAAAA,YAAAA,GAAAA;AAC1C,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAS,CAAA,GAAGC,QAAY,CAAA,IAAA;AACpC,QAAA,MAAMC,WAAcC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACR,GAAAA,CAAAA;AAEhD,QAAA,IAAIK,gBAAgB,IAAM,EAAA;YACxB,IAAI;gBACF,OAAOI,IAAAA,CAAKC,KAAK,CAACL,WAAAA,CAAAA;AACpB,aAAA,CAAE,OAAM;;gBAEN,OAAOA,WAAAA;AACT;AACF;QAEA,OAAOJ,YAAAA;AACT,KAAA,CAAA;IAEAU,SAAU,CAAA,IAAA;AACRL,QAAAA,MAAAA,CAAOC,YAAY,CAACK,OAAO,CAACZ,GAAKS,EAAAA,IAAAA,CAAKI,SAAS,CAACX,KAAAA,CAAAA,CAAAA;KAC/C,EAAA;AAACF,QAAAA,GAAAA;AAAKE,QAAAA;AAAM,KAAA,CAAA;IAEf,OAAO;AAACA,QAAAA,KAAAA;AAAOC,QAAAA;AAAS,KAAA;AAC1B;AAEA;AACA;AACMW,MAAAA,wBAAAA,GAA2B,CAAId,GAAaC,EAAAA,YAAAA,GAAAA;AAChD,IAAA,MAAM,EAAEc,IAAAA,EAAMC,QAAQ,EAAE,GAAGC,YAAAA,EAAAA;AAC3B,IAAA,MAAM,EAAEC,IAAI,EAAE,GAAGF,YAAY,EAAC;AAE9B,IAAA,MAAMG,gBAAgB,CAAC,EAAEnB,IAAI,CAAC,EAAEkB,KAAK,CAAC;AACtC,IAAA,OAAOnB,mBAAsBoB,aAAelB,EAAAA,YAAAA,CAAAA;AAC9C;;;;"}
1
+ {"version":3,"file":"usePersistentState.mjs","sources":["../../../../../admin/src/hooks/usePersistentState.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { useInitQuery } from '../services/admin';\n\nconst usePersistentState = <T>(key: string, defaultValue: T) => {\n const [value, setValue] = useState<T>(() => {\n const stickyValue = window.localStorage.getItem(key);\n\n if (stickyValue !== null) {\n try {\n return JSON.parse(stickyValue);\n } catch {\n // JSON.parse fails when the stored value is a primitive\n return stickyValue;\n }\n }\n\n return defaultValue;\n });\n\n useEffect(() => {\n window.localStorage.setItem(key, JSON.stringify(value));\n }, [key, value]);\n\n return [value, setValue] as const;\n};\n\n// Same as usePersistentState, but scoped to the current instance of Strapi\n// useful for storing state that should not be shared across different instances of Strapi running on localhost\nconst useScopedPersistentState = <T>(key: string, defaultValue: T) => {\n const { data: initData } = useInitQuery();\n const { uuid } = initData ?? {};\n\n const namespacedKey = `${key}:${uuid}`;\n return usePersistentState<T>(namespacedKey, defaultValue);\n};\n\nexport { usePersistentState, useScopedPersistentState };\n"],"names":["usePersistentState","key","defaultValue","value","setValue","useState","stickyValue","window","localStorage","getItem","JSON","parse","useEffect","setItem","stringify","useScopedPersistentState","data","initData","useInitQuery","uuid","namespacedKey"],"mappings":";;;AAIMA,MAAAA,kBAAAA,GAAqB,CAAIC,GAAaC,EAAAA,YAAAA,GAAAA;AAC1C,IAAA,MAAM,CAACC,KAAAA,EAAOC,QAAS,CAAA,GAAGC,QAAY,CAAA,IAAA;AACpC,QAAA,MAAMC,WAAcC,GAAAA,MAAAA,CAAOC,YAAY,CAACC,OAAO,CAACR,GAAAA,CAAAA;AAEhD,QAAA,IAAIK,gBAAgB,IAAM,EAAA;YACxB,IAAI;gBACF,OAAOI,IAAAA,CAAKC,KAAK,CAACL,WAAAA,CAAAA;AACpB,aAAA,CAAE,OAAM;;gBAEN,OAAOA,WAAAA;AACT;AACF;QAEA,OAAOJ,YAAAA;AACT,KAAA,CAAA;IAEAU,SAAU,CAAA,IAAA;AACRL,QAAAA,MAAAA,CAAOC,YAAY,CAACK,OAAO,CAACZ,GAAKS,EAAAA,IAAAA,CAAKI,SAAS,CAACX,KAAAA,CAAAA,CAAAA;KAC/C,EAAA;AAACF,QAAAA,GAAAA;AAAKE,QAAAA;AAAM,KAAA,CAAA;IAEf,OAAO;AAACA,QAAAA,KAAAA;AAAOC,QAAAA;AAAS,KAAA;AAC1B;AAEA;AACA;AACMW,MAAAA,wBAAAA,GAA2B,CAAId,GAAaC,EAAAA,YAAAA,GAAAA;AAChD,IAAA,MAAM,EAAEc,IAAAA,EAAMC,QAAQ,EAAE,GAAGC,YAAAA,EAAAA;AAC3B,IAAA,MAAM,EAAEC,IAAI,EAAE,GAAGF,YAAY,EAAC;AAE9B,IAAA,MAAMG,aAAgB,GAAA,CAAA,EAAGnB,GAAI,CAAA,CAAC,EAAEkB,IAAM,CAAA,CAAA;AACtC,IAAA,OAAOnB,mBAAsBoB,aAAelB,EAAAA,YAAAA,CAAAA;AAC9C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRBAC.js","sources":["../../../../../admin/src/hooks/useRBAC.ts"],"sourcesContent":["import * as React from 'react';\n\nimport isEqual from 'lodash/isEqual';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { once } from '../utils/once';\nimport { capitalise } from '../utils/strings';\n\nimport { usePrev } from './usePrev';\n\ntype AllowedActions = Record<string, boolean>;\n\n/**\n * @public\n * @description This hooks takes an object or array of permissions (the latter preferred) and\n * runs through them to match against the current user's permissions as well as the RBAC middleware\n * system checking any conditions that may be present. It returns the filtered permissions as the complete\n * object from the API and a set of actions that can be performed. An action is derived from the last part\n * of the permission action e.g. `admin::roles.create` would be `canCreate`. If there's a hyphen in the action\n * this is removed and capitalised e.g `admin::roles.create-draft` would be `canCreateDraft`.\n * @example\n * ```tsx\n * import { Page, useRBAC } from '@strapi/strapi/admin'\n *\n * const MyProtectedPage = () => {\n * const { allowedActions, isLoading, error, permissions } = useRBAC([{ action: 'admin::roles.create' }])\n *\n * if(isLoading) {\n * return <Page.Loading />\n * }\n *\n * if(error){\n * return <Page.Error />\n * }\n *\n * if(!allowedActions.canCreate) {\n * return null\n * }\n *\n * return <MyPage permissions={permissions} />\n * }\n * ```\n */\nconst useRBAC = (\n permissionsToCheck: Record<string, Permission[]> | Permission[] = [],\n passedPermissions?: Permission[],\n rawQueryContext?: string\n): {\n allowedActions: AllowedActions;\n isLoading: boolean;\n error?: unknown;\n permissions: Permission[];\n} => {\n const isLoadingAuth = useAuth('useRBAC', (state) => state.isLoading);\n const [isLoading, setIsLoading] = React.useState(true);\n const [error, setError] = React.useState<unknown>();\n const [data, setData] = React.useState<Record<string, boolean>>();\n\n const warnOnce = React.useMemo(() => once(console.warn), []);\n\n const actualPermissionsToCheck: Permission[] = React.useMemo(() => {\n if (Array.isArray(permissionsToCheck)) {\n return permissionsToCheck;\n } else {\n warnOnce(\n 'useRBAC: The first argument should be an array of permissions, not an object. This will be deprecated in the future.'\n );\n\n return Object.values(permissionsToCheck).flat();\n }\n }, [permissionsToCheck, warnOnce]);\n\n /**\n * This is the default value we return until the queryResults[i].data\n * are all resolved with data. This preserves the original behaviour.\n */\n const defaultAllowedActions = React.useMemo(() => {\n return actualPermissionsToCheck.reduce<Record<string, boolean>>((acc, permission) => {\n return {\n ...acc,\n [getActionName(permission)]: false,\n };\n }, {});\n }, [actualPermissionsToCheck]);\n\n const checkUserHasPermissions = useAuth('useRBAC', (state) => state.checkUserHasPermissions);\n\n const permssionsChecked = usePrev(actualPermissionsToCheck);\n const contextChecked = usePrev(rawQueryContext);\n\n React.useEffect(() => {\n if (\n !isEqual(permssionsChecked, actualPermissionsToCheck) ||\n // TODO: also run this when the query context changes\n contextChecked !== rawQueryContext\n ) {\n setIsLoading(true);\n setData(undefined);\n setError(undefined);\n\n checkUserHasPermissions(actualPermissionsToCheck, passedPermissions, rawQueryContext)\n .then((res) => {\n if (res) {\n setData(\n res.reduce<Record<string, boolean>>((acc, permission) => {\n return {\n ...acc,\n [getActionName(permission)]: true,\n };\n }, {})\n );\n }\n })\n .catch((err) => {\n setError(err);\n })\n .finally(() => {\n setIsLoading(false);\n });\n }\n }, [\n actualPermissionsToCheck,\n checkUserHasPermissions,\n passedPermissions,\n permissionsToCheck,\n permssionsChecked,\n contextChecked,\n rawQueryContext,\n ]);\n\n /**\n * This hook originally would not return allowedActions\n * until all the checks were complete.\n */\n const allowedActions = Object.entries({\n ...defaultAllowedActions,\n ...data,\n }).reduce((acc, [name, allowed]) => {\n acc[`can${capitalise(name)}`] = allowed;\n\n return acc;\n }, {} as AllowedActions);\n\n return {\n allowedActions,\n permissions: actualPermissionsToCheck,\n isLoading: isLoading || isLoadingAuth,\n error,\n };\n};\n\nconst getActionName = (permission: Permission): string => {\n const [action = ''] = permission.action.split('.').slice(-1);\n return action.split('-').map(capitalise).join('');\n};\n\nexport { useRBAC };\nexport type { AllowedActions };\n"],"names":["useRBAC","permissionsToCheck","passedPermissions","rawQueryContext","isLoadingAuth","useAuth","state","isLoading","setIsLoading","React","useState","error","setError","data","setData","warnOnce","useMemo","once","console","warn","actualPermissionsToCheck","Array","isArray","Object","values","flat","defaultAllowedActions","reduce","acc","permission","getActionName","checkUserHasPermissions","permssionsChecked","usePrev","contextChecked","useEffect","isEqual","undefined","then","res","catch","err","finally","allowedActions","entries","name","allowed","capitalise","permissions","action","split","slice","map","join"],"mappings":"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"}
1
+ {"version":3,"file":"useRBAC.js","sources":["../../../../../admin/src/hooks/useRBAC.ts"],"sourcesContent":["import * as React from 'react';\n\nimport isEqual from 'lodash/isEqual';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { once } from '../utils/once';\nimport { capitalise } from '../utils/strings';\n\nimport { usePrev } from './usePrev';\n\ntype AllowedActions = Record<string, boolean>;\n\n/**\n * @public\n * @description This hooks takes an object or array of permissions (the latter preferred) and\n * runs through them to match against the current user's permissions as well as the RBAC middleware\n * system checking any conditions that may be present. It returns the filtered permissions as the complete\n * object from the API and a set of actions that can be performed. An action is derived from the last part\n * of the permission action e.g. `admin::roles.create` would be `canCreate`. If there's a hyphen in the action\n * this is removed and capitalised e.g `admin::roles.create-draft` would be `canCreateDraft`.\n * @example\n * ```tsx\n * import { Page, useRBAC } from '@strapi/strapi/admin'\n *\n * const MyProtectedPage = () => {\n * const { allowedActions, isLoading, error, permissions } = useRBAC([{ action: 'admin::roles.create' }])\n *\n * if(isLoading) {\n * return <Page.Loading />\n * }\n *\n * if(error){\n * return <Page.Error />\n * }\n *\n * if(!allowedActions.canCreate) {\n * return null\n * }\n *\n * return <MyPage permissions={permissions} />\n * }\n * ```\n */\nconst useRBAC = (\n permissionsToCheck: Record<string, Permission[]> | Permission[] = [],\n passedPermissions?: Permission[],\n rawQueryContext?: string\n): {\n allowedActions: AllowedActions;\n isLoading: boolean;\n error?: unknown;\n permissions: Permission[];\n} => {\n const isLoadingAuth = useAuth('useRBAC', (state) => state.isLoading);\n const [isLoading, setIsLoading] = React.useState(true);\n const [error, setError] = React.useState<unknown>();\n const [data, setData] = React.useState<Record<string, boolean>>();\n\n const warnOnce = React.useMemo(() => once(console.warn), []);\n\n const actualPermissionsToCheck: Permission[] = React.useMemo(() => {\n if (Array.isArray(permissionsToCheck)) {\n return permissionsToCheck;\n } else {\n warnOnce(\n 'useRBAC: The first argument should be an array of permissions, not an object. This will be deprecated in the future.'\n );\n\n return Object.values(permissionsToCheck).flat();\n }\n }, [permissionsToCheck, warnOnce]);\n\n /**\n * This is the default value we return until the queryResults[i].data\n * are all resolved with data. This preserves the original behaviour.\n */\n const defaultAllowedActions = React.useMemo(() => {\n return actualPermissionsToCheck.reduce<Record<string, boolean>>((acc, permission) => {\n return {\n ...acc,\n [getActionName(permission)]: false,\n };\n }, {});\n }, [actualPermissionsToCheck]);\n\n const checkUserHasPermissions = useAuth('useRBAC', (state) => state.checkUserHasPermissions);\n\n const permssionsChecked = usePrev(actualPermissionsToCheck);\n const contextChecked = usePrev(rawQueryContext);\n\n React.useEffect(() => {\n if (\n !isEqual(permssionsChecked, actualPermissionsToCheck) ||\n // TODO: also run this when the query context changes\n contextChecked !== rawQueryContext\n ) {\n setIsLoading(true);\n setData(undefined);\n setError(undefined);\n\n checkUserHasPermissions(actualPermissionsToCheck, passedPermissions, rawQueryContext)\n .then((res) => {\n if (res) {\n setData(\n res.reduce<Record<string, boolean>>((acc, permission) => {\n return {\n ...acc,\n [getActionName(permission)]: true,\n };\n }, {})\n );\n }\n })\n .catch((err) => {\n setError(err);\n })\n .finally(() => {\n setIsLoading(false);\n });\n }\n }, [\n actualPermissionsToCheck,\n checkUserHasPermissions,\n passedPermissions,\n permissionsToCheck,\n permssionsChecked,\n contextChecked,\n rawQueryContext,\n ]);\n\n /**\n * This hook originally would not return allowedActions\n * until all the checks were complete.\n */\n const allowedActions = Object.entries({\n ...defaultAllowedActions,\n ...data,\n }).reduce((acc, [name, allowed]) => {\n acc[`can${capitalise(name)}`] = allowed;\n\n return acc;\n }, {} as AllowedActions);\n\n return {\n allowedActions,\n permissions: actualPermissionsToCheck,\n isLoading: isLoading || isLoadingAuth,\n error,\n };\n};\n\nconst getActionName = (permission: Permission): string => {\n const [action = ''] = permission.action.split('.').slice(-1);\n return action.split('-').map(capitalise).join('');\n};\n\nexport { useRBAC };\nexport type { AllowedActions };\n"],"names":["useRBAC","permissionsToCheck","passedPermissions","rawQueryContext","isLoadingAuth","useAuth","state","isLoading","setIsLoading","React","useState","error","setError","data","setData","warnOnce","useMemo","once","console","warn","actualPermissionsToCheck","Array","isArray","Object","values","flat","defaultAllowedActions","reduce","acc","permission","getActionName","checkUserHasPermissions","permssionsChecked","usePrev","contextChecked","useEffect","isEqual","undefined","then","res","catch","err","finally","allowedActions","entries","name","allowed","capitalise","permissions","action","split","slice","map","join"],"mappings":"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"}