@strapi/admin 5.49.0 → 5.50.1
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.
- package/dist/admin/admin/src/components/ConfirmDialog.js +2 -2
- package/dist/admin/admin/src/components/ConfirmDialog.js.map +1 -1
- package/dist/admin/admin/src/components/ContentBox.js +3 -3
- package/dist/admin/admin/src/components/ContentBox.js.map +1 -1
- package/dist/admin/admin/src/components/DescriptionComponentRenderer.js +8 -8
- package/dist/admin/admin/src/components/DescriptionComponentRenderer.js.map +1 -1
- package/dist/admin/admin/src/components/DescriptionComponentRenderer.mjs +8 -8
- package/dist/admin/admin/src/components/DescriptionComponentRenderer.mjs.map +1 -1
- package/dist/admin/admin/src/components/ErrorElement.js +100 -5
- package/dist/admin/admin/src/components/ErrorElement.js.map +1 -1
- package/dist/admin/admin/src/components/ErrorElement.mjs +99 -4
- package/dist/admin/admin/src/components/ErrorElement.mjs.map +1 -1
- package/dist/admin/admin/src/components/Form.js +41 -27
- package/dist/admin/admin/src/components/Form.js.map +1 -1
- package/dist/admin/admin/src/components/Form.mjs +41 -27
- package/dist/admin/admin/src/components/Form.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Boolean.js +3 -2
- package/dist/admin/admin/src/components/FormInputs/Boolean.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Boolean.mjs +3 -2
- package/dist/admin/admin/src/components/FormInputs/Boolean.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.js +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.mjs +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Email.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Email.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js +4 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs +4 -1
- package/dist/admin/admin/src/components/FormInputs/Enumeration.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Json.js +2 -1
- package/dist/admin/admin/src/components/FormInputs/Json.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Json.mjs +2 -1
- package/dist/admin/admin/src/components/FormInputs/Json.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Password.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Password.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Renderer.js +18 -26
- package/dist/admin/admin/src/components/FormInputs/Renderer.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Renderer.mjs +20 -28
- package/dist/admin/admin/src/components/FormInputs/Renderer.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/String.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/String.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Textarea.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Textarea.mjs.map +1 -1
- package/dist/admin/admin/src/components/GapDropZone.js +2 -2
- package/dist/admin/admin/src/components/GapDropZone.js.map +1 -1
- package/dist/admin/admin/src/components/GradientBadge.js +3 -3
- package/dist/admin/admin/src/components/GradientBadge.js.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Overview.js +8 -8
- package/dist/admin/admin/src/components/GuidedTour/Overview.js.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Steps/Step.js +4 -4
- package/dist/admin/admin/src/components/GuidedTour/Steps/Step.js.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Steps/Step.mjs.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Tours.js +2 -2
- package/dist/admin/admin/src/components/GuidedTour/Tours.js.map +1 -1
- package/dist/admin/admin/src/components/Layouts/ActionLayout.js +2 -2
- package/dist/admin/admin/src/components/Layouts/ActionLayout.js.map +1 -1
- package/dist/admin/admin/src/components/Layouts/GridLayout.js +2 -2
- package/dist/admin/admin/src/components/Layouts/GridLayout.js.map +1 -1
- package/dist/admin/admin/src/components/Layouts/Layout.js +4 -4
- package/dist/admin/admin/src/components/Layouts/Layout.js.map +1 -1
- package/dist/admin/admin/src/components/LazyOutlet.js +57 -0
- package/dist/admin/admin/src/components/LazyOutlet.js.map +1 -0
- package/dist/admin/admin/src/components/LazyOutlet.mjs +35 -0
- package/dist/admin/admin/src/components/LazyOutlet.mjs.map +1 -0
- package/dist/admin/admin/src/components/LeftMenu.js +3 -3
- package/dist/admin/admin/src/components/LeftMenu.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/MainNav.js +2 -2
- package/dist/admin/admin/src/components/MainNav/MainNav.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/MainNavLinks.js +4 -4
- package/dist/admin/admin/src/components/MainNav/MainNavLinks.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavBrand.js +2 -2
- package/dist/admin/admin/src/components/MainNav/NavBrand.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavBurgerMenu.js +3 -3
- package/dist/admin/admin/src/components/MainNav/NavBurgerMenu.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavLink.js +8 -8
- package/dist/admin/admin/src/components/MainNav/NavLink.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavUser.js +17 -7
- package/dist/admin/admin/src/components/MainNav/NavUser.js.map +1 -1
- package/dist/admin/admin/src/components/MainNav/NavUser.mjs +10 -0
- package/dist/admin/admin/src/components/MainNav/NavUser.mjs.map +1 -1
- package/dist/admin/admin/src/components/MainNav/TrialCountdown.js +3 -3
- package/dist/admin/admin/src/components/MainNav/TrialCountdown.js.map +1 -1
- package/dist/admin/admin/src/components/NpsSurvey.js +2 -2
- package/dist/admin/admin/src/components/NpsSurvey.js.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.js +3 -2
- package/dist/admin/admin/src/components/RelativeTime.js.map +1 -1
- package/dist/admin/admin/src/components/RelativeTime.mjs +3 -2
- package/dist/admin/admin/src/components/RelativeTime.mjs.map +1 -1
- package/dist/admin/admin/src/components/ResizeIndicator.js +6 -6
- package/dist/admin/admin/src/components/ResizeIndicator.js.map +1 -1
- package/dist/admin/admin/src/components/SubNav.js +11 -9
- package/dist/admin/admin/src/components/SubNav.js.map +1 -1
- package/dist/admin/admin/src/components/SubNav.mjs +4 -2
- package/dist/admin/admin/src/components/SubNav.mjs.map +1 -1
- package/dist/admin/admin/src/components/Table.js +9 -5
- package/dist/admin/admin/src/components/Table.js.map +1 -1
- package/dist/admin/admin/src/components/Table.mjs +6 -2
- package/dist/admin/admin/src/components/Table.mjs.map +1 -1
- package/dist/admin/admin/src/components/Theme.js +2 -2
- package/dist/admin/admin/src/components/Theme.js.map +1 -1
- package/dist/admin/admin/src/components/UnauthenticatedLogo.js +2 -2
- package/dist/admin/admin/src/components/UnauthenticatedLogo.js.map +1 -1
- package/dist/admin/admin/src/components/UpsellBanner.js +3 -3
- package/dist/admin/admin/src/components/UpsellBanner.js.map +1 -1
- package/dist/admin/admin/src/components/WidgetRoot.js +4 -7
- package/dist/admin/admin/src/components/WidgetRoot.js.map +1 -1
- package/dist/admin/admin/src/components/WidgetRoot.mjs +1 -1
- package/dist/admin/admin/src/components/WidgetRoot.mjs.map +1 -1
- package/dist/admin/admin/src/components/Widgets.js +5 -5
- package/dist/admin/admin/src/components/Widgets.js.map +1 -1
- package/dist/admin/admin/src/core/apis/Plugin.js.map +1 -1
- package/dist/admin/admin/src/core/apis/Plugin.mjs.map +1 -1
- package/dist/admin/admin/src/core/apis/Widgets.js +1 -1
- package/dist/admin/admin/src/core/apis/Widgets.js.map +1 -1
- package/dist/admin/admin/src/core/apis/Widgets.mjs +1 -1
- package/dist/admin/admin/src/core/apis/Widgets.mjs.map +1 -1
- package/dist/admin/admin/src/core/apis/router.js +19 -17
- package/dist/admin/admin/src/core/apis/router.js.map +1 -1
- package/dist/admin/admin/src/core/apis/router.mjs +19 -17
- package/dist/admin/admin/src/core/apis/router.mjs.map +1 -1
- package/dist/admin/admin/src/core/store/configure.js.map +1 -1
- package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
- package/dist/admin/admin/src/core/utils/createHook.js.map +1 -1
- package/dist/admin/admin/src/core/utils/createHook.mjs.map +1 -1
- package/dist/admin/admin/src/features/Tracking.js +3 -1
- package/dist/admin/admin/src/features/Tracking.js.map +1 -1
- package/dist/admin/admin/src/features/Tracking.mjs +3 -1
- package/dist/admin/admin/src/features/Tracking.mjs.map +1 -1
- package/dist/admin/admin/src/features/Widgets.js.map +1 -1
- package/dist/admin/admin/src/features/Widgets.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/useMediaQuery.js +4 -4
- package/dist/admin/admin/src/hooks/useMediaQuery.js.map +1 -1
- package/dist/admin/admin/src/hooks/useMenu.js +5 -3
- package/dist/admin/admin/src/hooks/useMenu.js.map +1 -1
- package/dist/admin/admin/src/hooks/useMenu.mjs +5 -3
- package/dist/admin/admin/src/hooks/useMenu.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/useQueryParams.js +0 -1
- package/dist/admin/admin/src/hooks/useQueryParams.js.map +1 -1
- package/dist/admin/admin/src/hooks/useQueryParams.mjs +0 -1
- package/dist/admin/admin/src/hooks/useQueryParams.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/useThrottledCallback.js.map +1 -1
- package/dist/admin/admin/src/hooks/useThrottledCallback.mjs.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js +5 -3
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.js.map +1 -1
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs +5 -3
- package/dist/admin/admin/src/layouts/AuthenticatedLayout.mjs.map +1 -1
- package/dist/admin/admin/src/layouts/UnauthenticatedLayout.js +3 -3
- package/dist/admin/admin/src/layouts/UnauthenticatedLayout.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/AuthPage.js +3 -2
- package/dist/admin/admin/src/pages/Auth/AuthPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/AuthPage.mjs +3 -2
- package/dist/admin/admin/src/pages/Auth/AuthPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.js +17 -9
- package/dist/admin/admin/src/pages/Auth/components/Register.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs +15 -7
- package/dist/admin/admin/src/pages/Auth/components/Register.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Home/HomePage.js +2 -2
- package/dist/admin/admin/src/pages/Home/HomePage.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/AddWidgetModal.js +3 -6
- package/dist/admin/admin/src/pages/Home/components/AddWidgetModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/AddWidgetModal.mjs +1 -1
- package/dist/admin/admin/src/pages/Home/components/AddWidgetModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.js +4 -8
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.mjs +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialEndedModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialWelcomeModal.js +4 -8
- package/dist/admin/admin/src/pages/Home/components/FreeTrialWelcomeModal.js.map +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialWelcomeModal.mjs +1 -1
- package/dist/admin/admin/src/pages/Home/components/FreeTrialWelcomeModal.mjs.map +1 -1
- package/dist/admin/admin/src/pages/SessionsPage.js +318 -0
- package/dist/admin/admin/src/pages/SessionsPage.js.map +1 -0
- package/dist/admin/admin/src/pages/SessionsPage.mjs +296 -0
- package/dist/admin/admin/src/pages/SessionsPage.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/Layout.js +4 -1
- package/dist/admin/admin/src/pages/Settings/Layout.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/Layout.mjs +5 -2
- package/dist/admin/admin/src/pages/Settings/Layout.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js +2 -2
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js +2 -2
- package/dist/admin/admin/src/pages/Settings/components/Tokens/FormHead.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js +2 -2
- package/dist/admin/admin/src/pages/Settings/components/Tokens/Table.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js +2 -2
- package/dist/admin/admin/src/pages/Settings/components/Tokens/TokenBox.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/BoundRoute.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js +4 -4
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/components/CollapsableContentType.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/reducer.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApiTokens/EditView/reducer.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +1 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +1 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js +9 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs +7 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/CreatePage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js +7 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs +7 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/EditPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapseLabel.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapseLabel.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js +44 -10
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs +34 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/CollapsePropertyMatrix.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsButton.js +3 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ConditionsButton.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js +5 -5
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/ContentTypeCollapses.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/HiddenAction.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/HiddenAction.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js +38 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs +38 -2
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/Permissions.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js +3 -3
- package/dist/admin/admin/src/pages/Settings/pages/Roles/components/PluginsAndSettings.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createArrayOfValues.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/createArrayOfValues.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js +18 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs +18 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/localePermissionValidation.js +59 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/localePermissionValidation.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/localePermissionValidation.mjs +52 -0
- package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/localePermissionValidation.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/ListPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.js +3 -3
- package/dist/admin/admin/src/pages/Settings/pages/Users/components/SelectRoles.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/Events.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js +2 -2
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs.map +1 -1
- package/dist/admin/admin/src/router.js +9 -0
- package/dist/admin/admin/src/router.js.map +1 -1
- package/dist/admin/admin/src/router.mjs +9 -0
- package/dist/admin/admin/src/router.mjs.map +1 -1
- package/dist/admin/admin/src/services/auth.js +43 -2
- package/dist/admin/admin/src/services/auth.js.map +1 -1
- package/dist/admin/admin/src/services/auth.mjs +41 -3
- package/dist/admin/admin/src/services/auth.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +22 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +22 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/ja.json.js +726 -237
- package/dist/admin/admin/src/translations/ja.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ja.json.mjs +723 -238
- package/dist/admin/admin/src/translations/ja.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/languageNativeNames.js +1 -0
- package/dist/admin/admin/src/translations/languageNativeNames.js.map +1 -1
- package/dist/admin/admin/src/translations/languageNativeNames.mjs +1 -0
- package/dist/admin/admin/src/translations/languageNativeNames.mjs.map +1 -1
- package/dist/admin/admin/src/translations/pl.json.js +22 -0
- package/dist/admin/admin/src/translations/pl.json.js.map +1 -1
- package/dist/admin/admin/src/translations/pl.json.mjs +22 -0
- package/dist/admin/admin/src/translations/pl.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/arrays.js.map +1 -1
- package/dist/admin/admin/src/utils/arrays.mjs.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.js +1 -1
- package/dist/admin/admin/src/utils/baseQuery.js.map +1 -1
- package/dist/admin/admin/src/utils/baseQuery.mjs +1 -1
- package/dist/admin/admin/src/utils/baseQuery.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/admin/src/utils/objects.js +43 -11
- package/dist/admin/admin/src/utils/objects.js.map +1 -1
- package/dist/admin/admin/src/utils/objects.mjs +43 -11
- package/dist/admin/admin/src/utils/objects.mjs.map +1 -1
- package/dist/admin/admin/src/utils/once.js.map +1 -1
- package/dist/admin/admin/src/utils/once.mjs.map +1 -1
- package/dist/admin/admin/src/utils/retryDynamicImport.js +85 -0
- package/dist/admin/admin/src/utils/retryDynamicImport.js.map +1 -0
- package/dist/admin/admin/src/utils/retryDynamicImport.mjs +80 -0
- package/dist/admin/admin/src/utils/retryDynamicImport.mjs.map +1 -0
- package/dist/admin/admin/src/utils/rulesEngine.js +2 -1
- package/dist/admin/admin/src/utils/rulesEngine.js.map +1 -1
- package/dist/admin/admin/src/utils/rulesEngine.mjs +2 -1
- package/dist/admin/admin/src/utils/rulesEngine.mjs.map +1 -1
- package/dist/admin/admin/src/utils/shims.js.map +1 -1
- package/dist/admin/admin/src/utils/shims.mjs.map +1 -1
- package/dist/admin/admin/src/utils/widgetVisibility.js +16 -1
- package/dist/admin/admin/src/utils/widgetVisibility.js.map +1 -1
- package/dist/admin/admin/src/utils/widgetVisibility.mjs +14 -2
- package/dist/admin/admin/src/utils/widgetVisibility.mjs.map +1 -1
- package/dist/admin/admin/tests/server.js +25 -0
- package/dist/admin/admin/tests/server.js.map +1 -1
- package/dist/admin/admin/tests/server.mjs +25 -0
- package/dist/admin/admin/tests/server.mjs.map +1 -1
- package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.js +2 -2
- package/dist/admin/ee/admin/src/components/AuditLogs/Widgets.js.map +1 -1
- package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.js +2 -2
- package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.js.map +1 -1
- package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.mjs +2 -2
- package/dist/admin/ee/admin/src/hooks/useLicenseLimitNotification.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/AuthPage/components/Login.js +2 -2
- package/dist/admin/ee/admin/src/pages/AuthPage/components/Login.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/AuthPage/components/Providers.js +2 -2
- package/dist/admin/ee/admin/src/pages/AuthPage/components/Providers.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js +3 -3
- package/dist/admin/ee/admin/src/pages/AuthPage/components/SSOProviders.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +3 -3
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ComboboxFilter.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ComboboxFilter.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.js +2 -2
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/Modal.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/SingleSignOnPage.mjs.map +1 -1
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -0
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/src/StrapiApp.d.ts +7 -7
- package/dist/admin/src/components/DescriptionComponentRenderer.d.ts +2 -1
- package/dist/admin/src/components/Form.d.ts +14 -12
- package/dist/admin/src/components/FormInputs/Boolean.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Checkbox.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/DateTime.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Email.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Enumeration.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Number.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Password.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Renderer.d.ts +1 -2
- package/dist/admin/src/components/FormInputs/String.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Textarea.d.ts +0 -1
- package/dist/admin/src/components/FormInputs/Time.d.ts +0 -1
- package/dist/admin/src/components/GuidedTour/GuidedTourProvider.d.ts +0 -1
- package/dist/admin/src/components/GuidedTour/Steps/Step.d.ts +1 -1
- package/dist/admin/src/components/LazyOutlet.d.ts +20 -0
- package/dist/admin/src/components/MainNav/MainNav.d.ts +1 -1
- package/dist/admin/src/components/MainNav/NavUser.d.ts +0 -1
- package/dist/admin/src/components/SubNav.d.ts +6 -7
- package/dist/admin/src/components/Table.d.ts +3 -2
- package/dist/admin/src/core/apis/Plugin.d.ts +2 -2
- package/dist/admin/src/core/apis/Widgets.d.ts +0 -1
- package/dist/admin/src/core/apis/router.d.ts +1 -1
- package/dist/admin/src/core/store/configure.d.ts +2 -2
- package/dist/admin/src/core/utils/createHook.d.ts +7 -7
- package/dist/admin/src/features/AppInfo.d.ts +1 -2
- package/dist/admin/src/features/StrapiApp.d.ts +1 -2
- package/dist/admin/src/hooks/useAPIErrorHandler.d.ts +1 -1
- package/dist/admin/src/hooks/useAdminRoles.d.ts +3 -3
- package/dist/admin/src/hooks/useFetchClient.d.ts +1 -1
- package/dist/admin/src/hooks/useMenu.d.ts +1 -1
- package/dist/admin/src/hooks/usePersistentState.d.ts +0 -1
- package/dist/admin/src/hooks/useQueryParams.d.ts +3 -2
- package/dist/admin/src/hooks/useThrottledCallback.d.ts +1 -2
- package/dist/admin/src/index.d.ts +1 -0
- package/dist/admin/src/layouts/UnauthenticatedLayout.d.ts +2 -2
- package/dist/admin/src/pages/SessionsPage.d.ts +2 -0
- package/dist/admin/src/pages/Settings/pages/ApiTokens/EditView/reducer.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/Roles/components/CollapseLabel.d.ts +2 -3
- package/dist/admin/src/pages/Settings/pages/Roles/components/ConditionsButton.d.ts +2 -2
- package/dist/admin/src/pages/Settings/pages/Roles/components/HiddenAction.d.ts +0 -1
- package/dist/admin/src/pages/Settings/pages/Roles/components/Permissions.d.ts +2 -0
- package/dist/admin/src/pages/Settings/pages/Roles/utils/createArrayOfValues.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/Roles/utils/forms.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/Roles/utils/localePermissionValidation.d.ts +5 -0
- package/dist/admin/src/pages/Settings/pages/Roles/utils/permissions.d.ts +3 -1
- package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +8 -8
- package/dist/admin/src/reducer.d.ts +1 -1
- package/dist/admin/src/services/admin.d.ts +8 -8
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/apiTokens.d.ts +3 -3
- package/dist/admin/src/services/auth.d.ts +29 -27
- package/dist/admin/src/services/contentApi.d.ts +2 -2
- package/dist/admin/src/services/contentManager.d.ts +1 -1
- package/dist/admin/src/services/homepage.d.ts +3 -3
- package/dist/admin/src/services/transferTokens.d.ts +1 -1
- package/dist/admin/src/services/users.d.ts +15 -15
- package/dist/admin/src/services/webhooks.d.ts +4 -4
- package/dist/admin/src/translations/languageNativeNames.d.ts +1 -0
- package/dist/admin/src/utils/arrays.d.ts +1 -1
- package/dist/admin/src/utils/baseQuery.d.ts +1 -1
- package/dist/admin/src/utils/getFetchClient.d.ts +7 -7
- package/dist/admin/src/utils/locales.d.ts +0 -1
- package/dist/admin/src/utils/objects.d.ts +6 -4
- package/dist/admin/src/utils/once.d.ts +1 -1
- package/dist/admin/src/utils/retryDynamicImport.d.ts +19 -0
- package/dist/admin/src/utils/shims.d.ts +1 -1
- package/dist/admin/src/utils/widgetVisibility.d.ts +11 -0
- package/dist/admin/tests/store.d.ts +4 -4
- package/dist/admin/tests/utils.d.ts +5 -5
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getDisplayedFilters.d.ts +1 -1
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/tableHeaders.d.ts +2 -1
- package/dist/ee/admin/src/services/ai.d.ts +5 -5
- package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +3 -3
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -2
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/bootstrap.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts +30 -31
- package/dist/ee/server/src/controllers/authentication-utils/utils.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/index.d.ts +1 -2
- package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/user.d.ts +1 -1
- package/dist/ee/server/src/destroy.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +2 -3
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/ee/server/src/register.d.ts.map +1 -1
- package/dist/ee/server/src/routes/utils.d.ts.map +1 -1
- package/dist/ee/server/src/services/auth.d.ts.map +1 -1
- package/dist/ee/server/src/services/index.d.ts +1 -1
- package/dist/ee/server/src/services/metrics.d.ts.map +1 -1
- package/dist/ee/server/src/services/passport/sso.d.ts.map +1 -1
- package/dist/ee/server/src/services/persist-tables.d.ts +1 -1
- package/dist/ee/server/src/services/persist-tables.d.ts.map +1 -1
- package/dist/ee/server/src/services/role.d.ts.map +1 -1
- package/dist/ee/server/src/services/user.d.ts.map +1 -1
- package/dist/ee/server/src/utils/index.d.ts.map +1 -1
- package/dist/ee/server/src/utils/sso-lock.d.ts.map +1 -1
- package/dist/ee/server/src/validation/authentication.d.ts +2 -2
- package/dist/ee/server/src/validation/role.d.ts +6 -6
- package/dist/ee/server/src/validation/role.d.ts.map +1 -1
- package/dist/ee/server/src/validation/user.d.ts.map +1 -1
- package/dist/server/server/src/content-types/session.js +6 -0
- package/dist/server/server/src/content-types/session.js.map +1 -1
- package/dist/server/server/src/content-types/session.mjs +6 -0
- package/dist/server/server/src/content-types/session.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin.js.map +1 -1
- package/dist/server/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/server/src/controllers/authenticated-session.js +61 -0
- package/dist/server/server/src/controllers/authenticated-session.js.map +1 -0
- package/dist/server/server/src/controllers/authenticated-session.mjs +59 -0
- package/dist/server/server/src/controllers/authenticated-session.mjs.map +1 -0
- package/dist/server/server/src/controllers/authentication.js +11 -4
- package/dist/server/server/src/controllers/authentication.js.map +1 -1
- package/dist/server/server/src/controllers/authentication.mjs +12 -5
- package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
- package/dist/server/server/src/controllers/index.js +2 -0
- package/dist/server/server/src/controllers/index.js.map +1 -1
- package/dist/server/server/src/controllers/index.mjs +2 -0
- package/dist/server/server/src/controllers/index.mjs.map +1 -1
- package/dist/server/server/src/controllers/role.js +2 -4
- package/dist/server/server/src/controllers/role.js.map +1 -1
- package/dist/server/server/src/controllers/role.mjs +2 -4
- package/dist/server/server/src/controllers/role.mjs.map +1 -1
- package/dist/server/server/src/routes/serve-admin-panel.js +1 -1
- package/dist/server/server/src/routes/serve-admin-panel.js.map +1 -1
- package/dist/server/server/src/routes/serve-admin-panel.mjs +1 -1
- package/dist/server/server/src/routes/serve-admin-panel.mjs.map +1 -1
- package/dist/server/server/src/routes/users.js +12 -26
- package/dist/server/server/src/routes/users.js.map +1 -1
- package/dist/server/server/src/routes/users.mjs +12 -26
- package/dist/server/server/src/routes/users.mjs.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.js +0 -2
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.js.map +1 -1
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs +0 -2
- package/dist/server/server/src/services/permission/permissions-manager/sanitize.mjs.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/handlers.js +9 -2
- package/dist/server/server/src/services/permission/sections-builder/handlers.js.map +1 -1
- package/dist/server/server/src/services/permission/sections-builder/handlers.mjs +9 -2
- package/dist/server/server/src/services/permission/sections-builder/handlers.mjs.map +1 -1
- package/dist/server/server/src/services/role.js +7 -2
- package/dist/server/server/src/services/role.js.map +1 -1
- package/dist/server/server/src/services/role.mjs +7 -2
- package/dist/server/server/src/services/role.mjs.map +1 -1
- package/dist/server/server/src/strategies/admin.js +4 -0
- package/dist/server/server/src/strategies/admin.js.map +1 -1
- package/dist/server/server/src/strategies/admin.mjs +4 -0
- package/dist/server/server/src/strategies/admin.mjs.map +1 -1
- package/dist/server/server/src/validation/common-validators.js +19 -11
- package/dist/server/server/src/validation/common-validators.js.map +1 -1
- package/dist/server/server/src/validation/common-validators.mjs +19 -11
- package/dist/server/server/src/validation/common-validators.mjs.map +1 -1
- package/dist/server/server/src/validation/permission.js +1 -1
- package/dist/server/server/src/validation/permission.js.map +1 -1
- package/dist/server/server/src/validation/permission.mjs +1 -1
- package/dist/server/server/src/validation/permission.mjs.map +1 -1
- package/dist/server/server/src/validation/role.js +2 -2
- package/dist/server/server/src/validation/role.js.map +1 -1
- package/dist/server/server/src/validation/role.mjs +2 -2
- package/dist/server/server/src/validation/role.mjs.map +1 -1
- package/dist/server/src/ai/controllers/ai.d.ts +3 -3
- package/dist/server/src/ai/services/ai.d.ts.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/config/admin-conditions.d.ts +2 -2
- package/dist/server/src/config/admin-conditions.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +6 -0
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/session.d.ts +6 -0
- package/dist/server/src/content-types/session.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-token.d.ts +5 -5
- package/dist/server/src/controllers/api-token.d.ts +1 -1
- package/dist/server/src/controllers/authenticated-session.d.ts +8 -0
- package/dist/server/src/controllers/authenticated-session.d.ts.map +1 -0
- package/dist/server/src/controllers/authenticated-user.d.ts +1 -1
- package/dist/server/src/controllers/authentication.d.ts +4 -4
- package/dist/server/src/controllers/authentication.d.ts.map +1 -1
- package/dist/server/src/controllers/formatters/conditions.d.ts +0 -1
- package/dist/server/src/controllers/formatters/conditions.d.ts.map +1 -1
- package/dist/server/src/controllers/formatters/format-actions-by-sections.d.ts.map +1 -1
- package/dist/server/src/controllers/homepage.d.ts +2 -2
- package/dist/server/src/controllers/homepage.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +33 -43
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/role.d.ts +4 -4
- package/dist/server/src/controllers/transfer/runner.d.ts +4 -4
- package/dist/server/src/controllers/transfer/runner.d.ts.map +1 -1
- package/dist/server/src/controllers/transfer/token.d.ts +1 -1
- package/dist/server/src/controllers/user.d.ts +2 -2
- package/dist/server/src/controllers/webhooks.d.ts +4 -4
- package/dist/server/src/domain/action/index.d.ts +4 -65
- package/dist/server/src/domain/action/index.d.ts.map +1 -1
- package/dist/server/src/domain/action/provider.d.ts +30 -3
- package/dist/server/src/domain/action/provider.d.ts.map +1 -1
- package/dist/server/src/domain/condition/index.d.ts.map +1 -1
- package/dist/server/src/domain/condition/provider.d.ts +19 -2
- package/dist/server/src/domain/condition/provider.d.ts.map +1 -1
- package/dist/server/src/domain/permission/index.d.ts +0 -1
- package/dist/server/src/domain/permission/index.d.ts.map +1 -1
- package/dist/server/src/domain/user.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +51 -63
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/data-transfer.d.ts.map +1 -1
- package/dist/server/src/middlewares/index.d.ts +0 -1
- package/dist/server/src/middlewares/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/rateLimit.d.ts.map +1 -1
- package/dist/server/src/policies/hasPermissions.d.ts.map +1 -1
- package/dist/server/src/policies/index.d.ts.map +1 -1
- package/dist/server/src/policies/isAuthenticatedAdmin.d.ts.map +1 -1
- package/dist/server/src/policies/isTelemetryEnabled.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts +0 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/routes/serve-admin-panel.d.ts.map +1 -1
- package/dist/server/src/routes/transfer.d.ts +0 -1
- package/dist/server/src/routes/transfer.d.ts.map +1 -1
- package/dist/server/src/routes/users.d.ts.map +1 -1
- package/dist/server/src/services/action.d.ts.map +1 -1
- package/dist/server/src/services/api-token.d.ts +5 -6
- package/dist/server/src/services/api-token.d.ts.map +1 -1
- package/dist/server/src/services/auth.d.ts.map +1 -1
- package/dist/server/src/services/condition.d.ts.map +1 -1
- package/dist/server/src/services/content-type.d.ts.map +1 -1
- package/dist/server/src/services/encryption.d.ts.map +1 -1
- package/dist/server/src/services/homepage.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +12 -21
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/metrics.d.ts.map +1 -1
- package/dist/server/src/services/passport/local-strategy.d.ts.map +1 -1
- package/dist/server/src/services/passport.d.ts +0 -1
- package/dist/server/src/services/passport.d.ts.map +1 -1
- package/dist/server/src/services/permission/engine.d.ts +1 -2
- package/dist/server/src/services/permission/engine.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/index.d.ts +5 -5
- package/dist/server/src/services/permission/permissions-manager/index.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/permission-fields.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/query-builders.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts +3 -3
- package/dist/server/src/services/permission/permissions-manager/sanitize.d.ts.map +1 -1
- package/dist/server/src/services/permission/permissions-manager/validate.d.ts.map +1 -1
- package/dist/server/src/services/permission/queries.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/builder.d.ts +4 -4
- package/dist/server/src/services/permission/sections-builder/builder.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/handlers.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/index.d.ts +4 -4
- package/dist/server/src/services/permission/sections-builder/section.d.ts.map +1 -1
- package/dist/server/src/services/permission/sections-builder/utils.d.ts +0 -1
- package/dist/server/src/services/permission/sections-builder/utils.d.ts.map +1 -1
- package/dist/server/src/services/permission.d.ts +13 -38
- package/dist/server/src/services/permission.d.ts.map +1 -1
- package/dist/server/src/services/project-settings.d.ts +2 -4
- package/dist/server/src/services/project-settings.d.ts.map +1 -1
- package/dist/server/src/services/role.d.ts +7 -1
- package/dist/server/src/services/role.d.ts.map +1 -1
- package/dist/server/src/services/token.d.ts +1 -1
- package/dist/server/src/services/token.d.ts.map +1 -1
- package/dist/server/src/services/transfer/token.d.ts +11 -11
- package/dist/server/src/services/transfer/token.d.ts.map +1 -1
- package/dist/server/src/services/user.d.ts +3 -3
- package/dist/server/src/services/user.d.ts.map +1 -1
- package/dist/server/src/strategies/admin-token.d.ts +4 -4
- package/dist/server/src/strategies/admin-token.d.ts.map +1 -1
- package/dist/server/src/strategies/admin.d.ts.map +1 -1
- package/dist/server/src/strategies/api-token-utils.d.ts.map +1 -1
- package/dist/server/src/strategies/content-api-token.d.ts.map +1 -1
- package/dist/server/src/strategies/data-transfer.d.ts.map +1 -1
- package/dist/server/src/utils/normalize-email.d.ts.map +1 -1
- package/dist/server/src/validation/action-provider.d.ts +2 -2
- package/dist/server/src/validation/action-provider.d.ts.map +1 -1
- package/dist/server/src/validation/admin-tokens.d.ts +2 -2
- package/dist/server/src/validation/api-tokens.d.ts +4 -4
- package/dist/server/src/validation/authentication/forgot-password.d.ts +1 -1
- package/dist/server/src/validation/authentication/login.d.ts +1 -1
- package/dist/server/src/validation/authentication/register.d.ts +6 -6
- package/dist/server/src/validation/authentication/register.d.ts.map +1 -1
- package/dist/server/src/validation/authentication/reset-password.d.ts +1 -1
- package/dist/server/src/validation/common-functions/check-fields-are-correctly-nested.d.ts.map +1 -1
- package/dist/server/src/validation/common-functions/check-fields-dont-have-duplicates.d.ts.map +1 -1
- package/dist/server/src/validation/common-validators.d.ts.map +1 -1
- package/dist/server/src/validation/permission.d.ts +6 -6
- package/dist/server/src/validation/permission.d.ts.map +1 -1
- package/dist/server/src/validation/policies/hasPermissions.d.ts +2 -2
- package/dist/server/src/validation/project-settings.d.ts +6 -6
- package/dist/server/src/validation/role.d.ts +8 -8
- package/dist/server/src/validation/role.d.ts.map +1 -1
- package/dist/server/src/validation/transfer/token.d.ts +4 -4
- package/dist/server/src/validation/user.d.ts +8 -8
- package/dist/shared/contracts/permissions.d.ts +1 -0
- package/dist/shared/contracts/permissions.d.ts.map +1 -1
- package/dist/shared/contracts/sessions.d.ts +62 -0
- package/dist/shared/contracts/sessions.d.ts.map +1 -0
- package/dist/shared/contracts/shared.d.ts +1 -1
- package/dist/shared/contracts/shared.d.ts.map +1 -1
- package/dist/shared/utils/session-auth.d.ts +1 -1
- package/dist/shared/utils/session-auth.d.ts.map +1 -1
- package/package.json +12 -12
|
@@ -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 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 | 'didLaunchGuidedtour'\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 | 'didGenerateMetadataRetroactively';\n\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 DidClickOnDocLink {\n name: 'didClickOnDocLink';\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 kind?: 'admin' | 'content-api';\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 | DidClickOnDocLink\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 },\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","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 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 | 'didLaunchGuidedtour'\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 | 'didGenerateMetadataRetroactively';\n\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 DidClickOnDocLink {\n name: 'didClickOnDocLink';\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 kind?: 'admin' | 'content-api';\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 | DidClickOnDocLink\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 deviceTypeRef = React.useRef(deviceType);\n deviceTypeRef.current = deviceType;\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: deviceTypeRef.current,\n },\n groupProperties: {\n ...telemetryProperties,\n projectId: uuid,\n projectType: window.strapi.projectType,\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","deviceTypeRef","useRef","current","useContext","useAppInfo","trackUsage","useCallback","properties","window","strapi","telemetryDisabled","res","axios","post","eventProperties","userProperties","projectType","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 occurred' }),\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: ReturnType<typeof useUpdateHomepageLayoutMutation>[0];\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: ReturnType<typeof useAPIErrorHandler>['_unstableFormatAPIError'];\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 occurred' }),\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 occurred' }),\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: ReturnType<typeof useUpdateHomepageLayoutMutation>[0];\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: ReturnType<typeof useAPIErrorHandler>['_unstableFormatAPIError'];\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 occurred' }),\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,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
-
var
|
|
4
|
+
var styledComponents = require('styled-components');
|
|
5
5
|
|
|
6
6
|
function _interopNamespace(e) {
|
|
7
7
|
if (e && e.__esModule) return e;
|
|
@@ -44,14 +44,14 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
44
44
|
* Hook to detect if the current viewport is desktop size
|
|
45
45
|
* Uses the theme's large breakpoint
|
|
46
46
|
*/ const useIsDesktop = ()=>{
|
|
47
|
-
const theme =
|
|
47
|
+
const theme = styledComponents.useTheme();
|
|
48
48
|
return useMediaQuery(theme.breakpoints.large);
|
|
49
49
|
};
|
|
50
50
|
/**
|
|
51
51
|
* Hook to detect if the current viewport is tablet size
|
|
52
52
|
* Uses the theme's medium breakpoint
|
|
53
53
|
*/ const useIsTablet = ()=>{
|
|
54
|
-
const theme =
|
|
54
|
+
const theme = styledComponents.useTheme();
|
|
55
55
|
const isTabletOrAbove = useMediaQuery(theme.breakpoints.medium);
|
|
56
56
|
const isDesktop = useMediaQuery(theme.breakpoints.large);
|
|
57
57
|
return isTabletOrAbove && !isDesktop;
|
|
@@ -60,7 +60,7 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
60
60
|
* Hook to detect if the current viewport is mobile size
|
|
61
61
|
* Uses the theme's medium breakpoint (inverted)
|
|
62
62
|
*/ const useIsMobile = ()=>{
|
|
63
|
-
const theme =
|
|
63
|
+
const theme = styledComponents.useTheme();
|
|
64
64
|
return !useMediaQuery(theme.breakpoints.medium);
|
|
65
65
|
};
|
|
66
66
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMediaQuery.js","sources":["../../../../../admin/src/hooks/useMediaQuery.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useTheme } from 'styled-components';\n\n/**\n * Hook to detect if a media query matches\n * @param query - Media query string (e.g., '(min-width: 768px)' or theme.breakpoints.large)\n * @returns boolean indicating if the media query matches\n */\nexport const useMediaQuery = (query: string): boolean => {\n const cleanQuery = query.replace('@media', '').trim();\n\n const [matches, setMatches] = React.useState(() => window.matchMedia(cleanQuery).matches);\n\n React.useEffect(() => {\n const mediaQuery = window.matchMedia(cleanQuery);\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches);\n\n mediaQuery.addEventListener('change', handler);\n\n return () => mediaQuery.removeEventListener('change', handler);\n }, [cleanQuery]);\n\n return matches;\n};\n\n/**\n * Hook to detect if the current viewport is desktop size\n * Uses the theme's large breakpoint\n */\nexport const useIsDesktop = (): boolean => {\n const theme = useTheme();\n return useMediaQuery(theme.breakpoints.large);\n};\n\n/**\n * Hook to detect if the current viewport is tablet size\n * Uses the theme's medium breakpoint\n */\nexport const useIsTablet = (): boolean => {\n const theme = useTheme();\n const isTabletOrAbove = useMediaQuery(theme.breakpoints.medium);\n const isDesktop = useMediaQuery(theme.breakpoints.large);\n return isTabletOrAbove && !isDesktop;\n};\n\n/**\n * Hook to detect if the current viewport is mobile size\n * Uses the theme's medium breakpoint (inverted)\n */\nexport const useIsMobile = (): boolean => {\n const theme = useTheme();\n return !useMediaQuery(theme.breakpoints.medium);\n};\n"],"names":["useMediaQuery","query","cleanQuery","replace","trim","matches","setMatches","React","useState","window","matchMedia","useEffect","mediaQuery","handler","e","addEventListener","removeEventListener","useIsDesktop","theme","useTheme","breakpoints","large","useIsTablet","isTabletOrAbove","medium","isDesktop","useIsMobile"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;IAKO,MAAMA,aAAAA,GAAgB,CAACC,KAAAA,GAAAA;AAC5B,IAAA,MAAMC,aAAaD,KAAAA,CAAME,OAAO,CAAC,QAAA,EAAU,IAAIC,IAAI,EAAA;AAEnD,IAAA,MAAM,CAACC,OAAAA,EAASC,UAAAA,CAAW,GAAGC,gBAAAA,CAAMC,QAAQ,CAAC,IAAMC,MAAAA,CAAOC,UAAU,CAACR,UAAAA,CAAAA,CAAYG,OAAO,CAAA;AAExFE,IAAAA,gBAAAA,CAAMI,SAAS,CAAC,IAAA;QACd,MAAMC,UAAAA,GAAaH,MAAAA,CAAOC,UAAU,CAACR,UAAAA,CAAAA;AACrC,QAAA,MAAMW,OAAAA,GAAU,CAACC,CAAAA,GAA2BR,UAAAA,CAAWQ,EAAET,OAAO,CAAA;QAEhEO,UAAAA,CAAWG,gBAAgB,CAAC,QAAA,EAAUF,OAAAA,CAAAA;AAEtC,QAAA,OAAO,IAAMD,UAAAA,CAAWI,mBAAmB,CAAC,QAAA,EAAUH,OAAAA,CAAAA;IACxD,CAAA,EAAG;AAACX,QAAAA;AAAW,KAAA,CAAA;IAEf,OAAOG,OAAAA;AACT;AAEA;;;UAIaY,YAAAA,GAAe,IAAA;AAC1B,IAAA,MAAMC,KAAAA,GAAQC,
|
|
1
|
+
{"version":3,"file":"useMediaQuery.js","sources":["../../../../../admin/src/hooks/useMediaQuery.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useTheme } from 'styled-components';\n\n/**\n * Hook to detect if a media query matches\n * @param query - Media query string (e.g., '(min-width: 768px)' or theme.breakpoints.large)\n * @returns boolean indicating if the media query matches\n */\nexport const useMediaQuery = (query: string): boolean => {\n const cleanQuery = query.replace('@media', '').trim();\n\n const [matches, setMatches] = React.useState(() => window.matchMedia(cleanQuery).matches);\n\n React.useEffect(() => {\n const mediaQuery = window.matchMedia(cleanQuery);\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches);\n\n mediaQuery.addEventListener('change', handler);\n\n return () => mediaQuery.removeEventListener('change', handler);\n }, [cleanQuery]);\n\n return matches;\n};\n\n/**\n * Hook to detect if the current viewport is desktop size\n * Uses the theme's large breakpoint\n */\nexport const useIsDesktop = (): boolean => {\n const theme = useTheme();\n return useMediaQuery(theme.breakpoints.large);\n};\n\n/**\n * Hook to detect if the current viewport is tablet size\n * Uses the theme's medium breakpoint\n */\nexport const useIsTablet = (): boolean => {\n const theme = useTheme();\n const isTabletOrAbove = useMediaQuery(theme.breakpoints.medium);\n const isDesktop = useMediaQuery(theme.breakpoints.large);\n return isTabletOrAbove && !isDesktop;\n};\n\n/**\n * Hook to detect if the current viewport is mobile size\n * Uses the theme's medium breakpoint (inverted)\n */\nexport const useIsMobile = (): boolean => {\n const theme = useTheme();\n return !useMediaQuery(theme.breakpoints.medium);\n};\n"],"names":["useMediaQuery","query","cleanQuery","replace","trim","matches","setMatches","React","useState","window","matchMedia","useEffect","mediaQuery","handler","e","addEventListener","removeEventListener","useIsDesktop","theme","useTheme","breakpoints","large","useIsTablet","isTabletOrAbove","medium","isDesktop","useIsMobile"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;IAKO,MAAMA,aAAAA,GAAgB,CAACC,KAAAA,GAAAA;AAC5B,IAAA,MAAMC,aAAaD,KAAAA,CAAME,OAAO,CAAC,QAAA,EAAU,IAAIC,IAAI,EAAA;AAEnD,IAAA,MAAM,CAACC,OAAAA,EAASC,UAAAA,CAAW,GAAGC,gBAAAA,CAAMC,QAAQ,CAAC,IAAMC,MAAAA,CAAOC,UAAU,CAACR,UAAAA,CAAAA,CAAYG,OAAO,CAAA;AAExFE,IAAAA,gBAAAA,CAAMI,SAAS,CAAC,IAAA;QACd,MAAMC,UAAAA,GAAaH,MAAAA,CAAOC,UAAU,CAACR,UAAAA,CAAAA;AACrC,QAAA,MAAMW,OAAAA,GAAU,CAACC,CAAAA,GAA2BR,UAAAA,CAAWQ,EAAET,OAAO,CAAA;QAEhEO,UAAAA,CAAWG,gBAAgB,CAAC,QAAA,EAAUF,OAAAA,CAAAA;AAEtC,QAAA,OAAO,IAAMD,UAAAA,CAAWI,mBAAmB,CAAC,QAAA,EAAUH,OAAAA,CAAAA;IACxD,CAAA,EAAG;AAACX,QAAAA;AAAW,KAAA,CAAA;IAEf,OAAOG,OAAAA;AACT;AAEA;;;UAIaY,YAAAA,GAAe,IAAA;AAC1B,IAAA,MAAMC,KAAAA,GAAQC,yBAAAA,EAAAA;AACd,IAAA,OAAOnB,aAAAA,CAAckB,KAAAA,CAAME,WAAW,CAACC,KAAK,CAAA;AAC9C;AAEA;;;UAIaC,WAAAA,GAAc,IAAA;AACzB,IAAA,MAAMJ,KAAAA,GAAQC,yBAAAA,EAAAA;AACd,IAAA,MAAMI,eAAAA,GAAkBvB,aAAAA,CAAckB,KAAAA,CAAME,WAAW,CAACI,MAAM,CAAA;AAC9D,IAAA,MAAMC,SAAAA,GAAYzB,aAAAA,CAAckB,KAAAA,CAAME,WAAW,CAACC,KAAK,CAAA;AACvD,IAAA,OAAOE,mBAAmB,CAACE,SAAAA;AAC7B;AAEA;;;UAIaC,WAAAA,GAAc,IAAA;AACzB,IAAA,MAAMR,KAAAA,GAAQC,yBAAAA,EAAAA;AACd,IAAA,OAAO,CAACnB,aAAAA,CAAckB,KAAAA,CAAME,WAAW,CAACI,MAAM,CAAA;AAChD;;;;;;;"}
|
|
@@ -6,6 +6,7 @@ var cloneDeep = require('lodash/cloneDeep');
|
|
|
6
6
|
var hooks = require('../core/store/hooks.js');
|
|
7
7
|
var Auth = require('../features/Auth.js');
|
|
8
8
|
var StrapiApp = require('../features/StrapiApp.js');
|
|
9
|
+
var widgetVisibility = require('../utils/widgetVisibility.js');
|
|
9
10
|
|
|
10
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
12
|
|
|
@@ -30,7 +31,7 @@ function _interopNamespace(e) {
|
|
|
30
31
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
31
32
|
var cloneDeep__default = /*#__PURE__*/_interopDefault(cloneDeep);
|
|
32
33
|
|
|
33
|
-
const useMenu = (shouldUpdateStrapi)=>{
|
|
34
|
+
const useMenu = (shouldUpdateStrapi, currentEnvironment)=>{
|
|
34
35
|
const checkUserHasPermissions = Auth.useAuth('useMenu', (state)=>state.checkUserHasPermissions);
|
|
35
36
|
const rawMenu = StrapiApp.useStrapiApp('useMenu', (state)=>state.menu);
|
|
36
37
|
const menu = React__namespace.useMemo(()=>normalizeMenuLinks(rawMenu), [
|
|
@@ -104,7 +105,7 @@ const useMenu = (shouldUpdateStrapi)=>{
|
|
|
104
105
|
setMenuWithUserPermissions((state)=>({
|
|
105
106
|
...state,
|
|
106
107
|
generalSectionLinks: authorizedGeneralSectionLinks,
|
|
107
|
-
pluginsSectionLinks: authorizedPluginSectionLinks,
|
|
108
|
+
pluginsSectionLinks: widgetVisibility.hideCloudDeployMenuLinkInProduction(authorizedPluginSectionLinks, currentEnvironment),
|
|
108
109
|
isLoading: false
|
|
109
110
|
}));
|
|
110
111
|
}
|
|
@@ -115,7 +116,8 @@ const useMenu = (shouldUpdateStrapi)=>{
|
|
|
115
116
|
menu,
|
|
116
117
|
permissions,
|
|
117
118
|
shouldUpdateStrapi,
|
|
118
|
-
checkUserHasPermissions
|
|
119
|
+
checkUserHasPermissions,
|
|
120
|
+
currentEnvironment
|
|
119
121
|
]);
|
|
120
122
|
return menuWithUserPermissions;
|
|
121
123
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMenu.js","sources":["../../../../../admin/src/hooks/useMenu.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { Cog, ShoppingCart, House } from '@strapi/icons';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { useTypedSelector } from '../core/store/hooks';\nimport { useAuth, AuthContextValue } from '../features/Auth';\nimport { StrapiAppContextValue, useStrapiApp } from '../features/StrapiApp';\n\n/* -------------------------------------------------------------------------------------------------\n * useMenu\n * -----------------------------------------------------------------------------------------------*/\n\nexport type MenuItem = Omit<StrapiAppContextValue['menu'][number], 'Component'> & {\n navigationLink?: string;\n};\nexport type MobileMenuItem = {\n to: string;\n target?: string;\n link?: string;\n};\n\nexport interface Menu {\n generalSectionLinks: MenuItem[];\n pluginsSectionLinks: MenuItem[];\n topMobileNavigation: MobileMenuItem[];\n burgerMobileNavigation: MobileMenuItem[];\n isLoading: boolean;\n}\n\nconst useMenu = (shouldUpdateStrapi: boolean) => {\n const checkUserHasPermissions = useAuth('useMenu', (state) => state.checkUserHasPermissions);\n const rawMenu = useStrapiApp('useMenu', (state) => state.menu);\n const menu = React.useMemo(() => normalizeMenuLinks(rawMenu), [rawMenu]);\n const permissions = useTypedSelector((state) => state.admin_app.permissions);\n const [menuWithUserPermissions, setMenuWithUserPermissions] = React.useState<Menu>({\n generalSectionLinks: [\n {\n icon: House,\n intlLabel: {\n id: 'global.home',\n defaultMessage: 'Home',\n },\n to: '/',\n permissions: [],\n position: 0,\n },\n {\n icon: ShoppingCart,\n intlLabel: {\n id: 'global.marketplace',\n defaultMessage: 'Marketplace',\n },\n to: 'https://market.strapi.io',\n target: '_blank',\n permissions: permissions.marketplace?.main ?? [],\n position: 7,\n },\n {\n icon: Cog,\n intlLabel: {\n id: 'global.settings',\n defaultMessage: 'Settings',\n },\n to: '/settings',\n // Permissions of this link are retrieved in the init phase\n // using the settings menu\n permissions: [],\n notificationsCount: 0,\n position: 9,\n },\n ],\n pluginsSectionLinks: [],\n topMobileNavigation: [\n {\n to: '/',\n },\n {\n to: 'content-manager',\n },\n {\n to: 'plugins/content-releases',\n },\n {\n to: 'plugins/upload',\n },\n ],\n burgerMobileNavigation: [\n {\n to: '/settings',\n },\n ],\n isLoading: true,\n });\n const generalSectionLinksRef = React.useRef(menuWithUserPermissions.generalSectionLinks);\n\n React.useEffect(() => {\n async function applyMenuPermissions() {\n const authorizedPluginSectionLinks = await getPluginSectionLinks(\n menu,\n checkUserHasPermissions\n );\n\n const authorizedGeneralSectionLinks = await getGeneralLinks(\n generalSectionLinksRef.current,\n shouldUpdateStrapi,\n checkUserHasPermissions\n );\n\n setMenuWithUserPermissions((state) => ({\n ...state,\n generalSectionLinks: authorizedGeneralSectionLinks,\n pluginsSectionLinks: authorizedPluginSectionLinks,\n isLoading: false,\n }));\n }\n\n applyMenuPermissions();\n }, [\n setMenuWithUserPermissions,\n generalSectionLinksRef,\n menu,\n permissions,\n shouldUpdateStrapi,\n checkUserHasPermissions,\n ]);\n\n return menuWithUserPermissions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Utils\n * -----------------------------------------------------------------------------------------------*/\n\nconst getGeneralLinks = async (\n generalSectionRawLinks: MenuItem[],\n shouldUpdateStrapi: boolean = false,\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const generalSectionLinks = normalizeMenuLinks(generalSectionRawLinks);\n const generalSectionLinksPermissions = await Promise.all(\n generalSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedGeneralSectionLinks = generalSectionLinks.filter(\n (_, index) => generalSectionLinksPermissions[index].length > 0\n );\n\n const settingsLinkIndex = authorizedGeneralSectionLinks.findIndex(\n (obj) => obj.to === '/settings'\n );\n\n if (settingsLinkIndex === -1) {\n return [];\n }\n\n const authorizedGeneralLinksClone = cloneDeep(authorizedGeneralSectionLinks);\n\n authorizedGeneralLinksClone[settingsLinkIndex].notificationsCount = shouldUpdateStrapi ? 1 : 0;\n\n return authorizedGeneralLinksClone;\n};\n\nconst getPluginSectionLinks = async (\n pluginsSectionRawLinks: MenuItem[],\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const pluginSectionLinks = normalizeMenuLinks(pluginsSectionRawLinks);\n const pluginSectionLinksPermissions = await Promise.all(\n pluginSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedPluginSectionLinks = pluginSectionLinks.filter(\n (_, index) => pluginSectionLinksPermissions[index].length > 0\n );\n\n return authorizedPluginSectionLinks;\n};\n\nconst normalizeMenuLinks = (links: unknown): MenuItem[] => {\n if (!Array.isArray(links)) {\n return [];\n }\n\n const isValidIcon = (icon: unknown) => {\n if (typeof icon === 'string' || typeof icon === 'function' || React.isValidElement(icon)) {\n return true;\n }\n\n if (!icon || typeof icon !== 'object') {\n return false;\n }\n\n const reactType = (icon as { $$typeof?: symbol }).$$typeof;\n\n return (\n reactType === Symbol.for('react.forward_ref') ||\n reactType === Symbol.for('react.memo') ||\n reactType === Symbol.for('react.lazy')\n );\n };\n\n return links.reduce<MenuItem[]>((acc, link) => {\n if (!link || typeof link !== 'object') {\n return acc;\n }\n\n const candidate = link as Partial<MenuItem>;\n\n if (\n typeof candidate.to !== 'string' ||\n !isValidIcon(candidate.icon) ||\n typeof candidate.intlLabel?.id !== 'string' ||\n typeof candidate.intlLabel.defaultMessage !== 'string'\n ) {\n return acc;\n }\n\n acc.push({\n ...candidate,\n permissions: Array.isArray(candidate.permissions) ? candidate.permissions : [],\n } as MenuItem);\n\n return acc;\n }, []);\n};\n\nexport { useMenu, normalizeMenuLinks };\n"],"names":["useMenu","shouldUpdateStrapi","checkUserHasPermissions","useAuth","state","rawMenu","useStrapiApp","menu","React","useMemo","normalizeMenuLinks","permissions","useTypedSelector","admin_app","menuWithUserPermissions","setMenuWithUserPermissions","useState","generalSectionLinks","icon","House","intlLabel","id","defaultMessage","to","position","ShoppingCart","target","marketplace","main","Cog","notificationsCount","pluginsSectionLinks","topMobileNavigation","burgerMobileNavigation","isLoading","generalSectionLinksRef","useRef","useEffect","applyMenuPermissions","authorizedPluginSectionLinks","getPluginSectionLinks","authorizedGeneralSectionLinks","getGeneralLinks","current","generalSectionRawLinks","generalSectionLinksPermissions","Promise","all","map","filter","_","index","length","settingsLinkIndex","findIndex","obj","authorizedGeneralLinksClone","cloneDeep","pluginsSectionRawLinks","pluginSectionLinks","pluginSectionLinksPermissions","links","Array","isArray","isValidIcon","isValidElement","reactType","$$typeof","Symbol","for","reduce","acc","link","candidate","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useMenu.js","sources":["../../../../../admin/src/hooks/useMenu.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { Cog, ShoppingCart, House } from '@strapi/icons';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { useTypedSelector } from '../core/store/hooks';\nimport { useAuth, AuthContextValue } from '../features/Auth';\nimport { StrapiAppContextValue, useStrapiApp } from '../features/StrapiApp';\nimport { hideCloudDeployMenuLinkInProduction } from '../utils/widgetVisibility';\n\n/* -------------------------------------------------------------------------------------------------\n * useMenu\n * -----------------------------------------------------------------------------------------------*/\n\nexport type MenuItem = Omit<StrapiAppContextValue['menu'][number], 'Component'> & {\n navigationLink?: string;\n};\nexport type MobileMenuItem = {\n to: string;\n target?: string;\n link?: string;\n};\n\nexport interface Menu {\n generalSectionLinks: MenuItem[];\n pluginsSectionLinks: MenuItem[];\n topMobileNavigation: MobileMenuItem[];\n burgerMobileNavigation: MobileMenuItem[];\n isLoading: boolean;\n}\n\nconst useMenu = (shouldUpdateStrapi: boolean, currentEnvironment?: string) => {\n const checkUserHasPermissions = useAuth('useMenu', (state) => state.checkUserHasPermissions);\n const rawMenu = useStrapiApp('useMenu', (state) => state.menu);\n const menu = React.useMemo(() => normalizeMenuLinks(rawMenu), [rawMenu]);\n const permissions = useTypedSelector((state) => state.admin_app.permissions);\n const [menuWithUserPermissions, setMenuWithUserPermissions] = React.useState<Menu>({\n generalSectionLinks: [\n {\n icon: House,\n intlLabel: {\n id: 'global.home',\n defaultMessage: 'Home',\n },\n to: '/',\n permissions: [],\n position: 0,\n },\n {\n icon: ShoppingCart,\n intlLabel: {\n id: 'global.marketplace',\n defaultMessage: 'Marketplace',\n },\n to: 'https://market.strapi.io',\n target: '_blank',\n permissions: permissions.marketplace?.main ?? [],\n position: 7,\n },\n {\n icon: Cog,\n intlLabel: {\n id: 'global.settings',\n defaultMessage: 'Settings',\n },\n to: '/settings',\n // Permissions of this link are retrieved in the init phase\n // using the settings menu\n permissions: [],\n notificationsCount: 0,\n position: 9,\n },\n ],\n pluginsSectionLinks: [],\n topMobileNavigation: [\n {\n to: '/',\n },\n {\n to: 'content-manager',\n },\n {\n to: 'plugins/content-releases',\n },\n {\n to: 'plugins/upload',\n },\n ],\n burgerMobileNavigation: [\n {\n to: '/settings',\n },\n ],\n isLoading: true,\n });\n const generalSectionLinksRef = React.useRef(menuWithUserPermissions.generalSectionLinks);\n\n React.useEffect(() => {\n async function applyMenuPermissions() {\n const authorizedPluginSectionLinks = await getPluginSectionLinks(\n menu,\n checkUserHasPermissions\n );\n\n const authorizedGeneralSectionLinks = await getGeneralLinks(\n generalSectionLinksRef.current,\n shouldUpdateStrapi,\n checkUserHasPermissions\n );\n\n setMenuWithUserPermissions((state) => ({\n ...state,\n generalSectionLinks: authorizedGeneralSectionLinks,\n pluginsSectionLinks: hideCloudDeployMenuLinkInProduction(\n authorizedPluginSectionLinks,\n currentEnvironment\n ),\n isLoading: false,\n }));\n }\n\n applyMenuPermissions();\n }, [\n setMenuWithUserPermissions,\n generalSectionLinksRef,\n menu,\n permissions,\n shouldUpdateStrapi,\n checkUserHasPermissions,\n currentEnvironment,\n ]);\n\n return menuWithUserPermissions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Utils\n * -----------------------------------------------------------------------------------------------*/\n\nconst getGeneralLinks = async (\n generalSectionRawLinks: MenuItem[],\n shouldUpdateStrapi: boolean = false,\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const generalSectionLinks = normalizeMenuLinks(generalSectionRawLinks);\n const generalSectionLinksPermissions = await Promise.all(\n generalSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedGeneralSectionLinks = generalSectionLinks.filter(\n (_, index) => generalSectionLinksPermissions[index].length > 0\n );\n\n const settingsLinkIndex = authorizedGeneralSectionLinks.findIndex(\n (obj) => obj.to === '/settings'\n );\n\n if (settingsLinkIndex === -1) {\n return [];\n }\n\n const authorizedGeneralLinksClone = cloneDeep(authorizedGeneralSectionLinks);\n\n authorizedGeneralLinksClone[settingsLinkIndex].notificationsCount = shouldUpdateStrapi ? 1 : 0;\n\n return authorizedGeneralLinksClone;\n};\n\nconst getPluginSectionLinks = async (\n pluginsSectionRawLinks: MenuItem[],\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const pluginSectionLinks = normalizeMenuLinks(pluginsSectionRawLinks);\n const pluginSectionLinksPermissions = await Promise.all(\n pluginSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedPluginSectionLinks = pluginSectionLinks.filter(\n (_, index) => pluginSectionLinksPermissions[index].length > 0\n );\n\n return authorizedPluginSectionLinks;\n};\n\nconst normalizeMenuLinks = (links: unknown): MenuItem[] => {\n if (!Array.isArray(links)) {\n return [];\n }\n\n const isValidIcon = (icon: unknown) => {\n if (typeof icon === 'string' || typeof icon === 'function' || React.isValidElement(icon)) {\n return true;\n }\n\n if (!icon || typeof icon !== 'object') {\n return false;\n }\n\n const reactType = (icon as { $$typeof?: symbol }).$$typeof;\n\n return (\n reactType === Symbol.for('react.forward_ref') ||\n reactType === Symbol.for('react.memo') ||\n reactType === Symbol.for('react.lazy')\n );\n };\n\n return links.reduce<MenuItem[]>((acc, link) => {\n if (!link || typeof link !== 'object') {\n return acc;\n }\n\n const candidate = link as Partial<MenuItem>;\n\n if (\n typeof candidate.to !== 'string' ||\n !isValidIcon(candidate.icon) ||\n typeof candidate.intlLabel?.id !== 'string' ||\n typeof candidate.intlLabel.defaultMessage !== 'string'\n ) {\n return acc;\n }\n\n acc.push({\n ...candidate,\n permissions: Array.isArray(candidate.permissions) ? candidate.permissions : [],\n } as MenuItem);\n\n return acc;\n }, []);\n};\n\nexport { useMenu, normalizeMenuLinks };\n"],"names":["useMenu","shouldUpdateStrapi","currentEnvironment","checkUserHasPermissions","useAuth","state","rawMenu","useStrapiApp","menu","React","useMemo","normalizeMenuLinks","permissions","useTypedSelector","admin_app","menuWithUserPermissions","setMenuWithUserPermissions","useState","generalSectionLinks","icon","House","intlLabel","id","defaultMessage","to","position","ShoppingCart","target","marketplace","main","Cog","notificationsCount","pluginsSectionLinks","topMobileNavigation","burgerMobileNavigation","isLoading","generalSectionLinksRef","useRef","useEffect","applyMenuPermissions","authorizedPluginSectionLinks","getPluginSectionLinks","authorizedGeneralSectionLinks","getGeneralLinks","current","hideCloudDeployMenuLinkInProduction","generalSectionRawLinks","generalSectionLinksPermissions","Promise","all","map","filter","_","index","length","settingsLinkIndex","findIndex","obj","authorizedGeneralLinksClone","cloneDeep","pluginsSectionRawLinks","pluginSectionLinks","pluginSectionLinksPermissions","links","Array","isArray","isValidIcon","isValidElement","reactType","$$typeof","Symbol","for","reduce","acc","link","candidate","push"],"mappings":"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"}
|
|
@@ -4,8 +4,9 @@ import cloneDeep from 'lodash/cloneDeep';
|
|
|
4
4
|
import { useTypedSelector } from '../core/store/hooks.mjs';
|
|
5
5
|
import { useAuth } from '../features/Auth.mjs';
|
|
6
6
|
import { useStrapiApp } from '../features/StrapiApp.mjs';
|
|
7
|
+
import { hideCloudDeployMenuLinkInProduction } from '../utils/widgetVisibility.mjs';
|
|
7
8
|
|
|
8
|
-
const useMenu = (shouldUpdateStrapi)=>{
|
|
9
|
+
const useMenu = (shouldUpdateStrapi, currentEnvironment)=>{
|
|
9
10
|
const checkUserHasPermissions = useAuth('useMenu', (state)=>state.checkUserHasPermissions);
|
|
10
11
|
const rawMenu = useStrapiApp('useMenu', (state)=>state.menu);
|
|
11
12
|
const menu = React.useMemo(()=>normalizeMenuLinks(rawMenu), [
|
|
@@ -79,7 +80,7 @@ const useMenu = (shouldUpdateStrapi)=>{
|
|
|
79
80
|
setMenuWithUserPermissions((state)=>({
|
|
80
81
|
...state,
|
|
81
82
|
generalSectionLinks: authorizedGeneralSectionLinks,
|
|
82
|
-
pluginsSectionLinks: authorizedPluginSectionLinks,
|
|
83
|
+
pluginsSectionLinks: hideCloudDeployMenuLinkInProduction(authorizedPluginSectionLinks, currentEnvironment),
|
|
83
84
|
isLoading: false
|
|
84
85
|
}));
|
|
85
86
|
}
|
|
@@ -90,7 +91,8 @@ const useMenu = (shouldUpdateStrapi)=>{
|
|
|
90
91
|
menu,
|
|
91
92
|
permissions,
|
|
92
93
|
shouldUpdateStrapi,
|
|
93
|
-
checkUserHasPermissions
|
|
94
|
+
checkUserHasPermissions,
|
|
95
|
+
currentEnvironment
|
|
94
96
|
]);
|
|
95
97
|
return menuWithUserPermissions;
|
|
96
98
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMenu.mjs","sources":["../../../../../admin/src/hooks/useMenu.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { Cog, ShoppingCart, House } from '@strapi/icons';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { useTypedSelector } from '../core/store/hooks';\nimport { useAuth, AuthContextValue } from '../features/Auth';\nimport { StrapiAppContextValue, useStrapiApp } from '../features/StrapiApp';\n\n/* -------------------------------------------------------------------------------------------------\n * useMenu\n * -----------------------------------------------------------------------------------------------*/\n\nexport type MenuItem = Omit<StrapiAppContextValue['menu'][number], 'Component'> & {\n navigationLink?: string;\n};\nexport type MobileMenuItem = {\n to: string;\n target?: string;\n link?: string;\n};\n\nexport interface Menu {\n generalSectionLinks: MenuItem[];\n pluginsSectionLinks: MenuItem[];\n topMobileNavigation: MobileMenuItem[];\n burgerMobileNavigation: MobileMenuItem[];\n isLoading: boolean;\n}\n\nconst useMenu = (shouldUpdateStrapi: boolean) => {\n const checkUserHasPermissions = useAuth('useMenu', (state) => state.checkUserHasPermissions);\n const rawMenu = useStrapiApp('useMenu', (state) => state.menu);\n const menu = React.useMemo(() => normalizeMenuLinks(rawMenu), [rawMenu]);\n const permissions = useTypedSelector((state) => state.admin_app.permissions);\n const [menuWithUserPermissions, setMenuWithUserPermissions] = React.useState<Menu>({\n generalSectionLinks: [\n {\n icon: House,\n intlLabel: {\n id: 'global.home',\n defaultMessage: 'Home',\n },\n to: '/',\n permissions: [],\n position: 0,\n },\n {\n icon: ShoppingCart,\n intlLabel: {\n id: 'global.marketplace',\n defaultMessage: 'Marketplace',\n },\n to: 'https://market.strapi.io',\n target: '_blank',\n permissions: permissions.marketplace?.main ?? [],\n position: 7,\n },\n {\n icon: Cog,\n intlLabel: {\n id: 'global.settings',\n defaultMessage: 'Settings',\n },\n to: '/settings',\n // Permissions of this link are retrieved in the init phase\n // using the settings menu\n permissions: [],\n notificationsCount: 0,\n position: 9,\n },\n ],\n pluginsSectionLinks: [],\n topMobileNavigation: [\n {\n to: '/',\n },\n {\n to: 'content-manager',\n },\n {\n to: 'plugins/content-releases',\n },\n {\n to: 'plugins/upload',\n },\n ],\n burgerMobileNavigation: [\n {\n to: '/settings',\n },\n ],\n isLoading: true,\n });\n const generalSectionLinksRef = React.useRef(menuWithUserPermissions.generalSectionLinks);\n\n React.useEffect(() => {\n async function applyMenuPermissions() {\n const authorizedPluginSectionLinks = await getPluginSectionLinks(\n menu,\n checkUserHasPermissions\n );\n\n const authorizedGeneralSectionLinks = await getGeneralLinks(\n generalSectionLinksRef.current,\n shouldUpdateStrapi,\n checkUserHasPermissions\n );\n\n setMenuWithUserPermissions((state) => ({\n ...state,\n generalSectionLinks: authorizedGeneralSectionLinks,\n pluginsSectionLinks: authorizedPluginSectionLinks,\n isLoading: false,\n }));\n }\n\n applyMenuPermissions();\n }, [\n setMenuWithUserPermissions,\n generalSectionLinksRef,\n menu,\n permissions,\n shouldUpdateStrapi,\n checkUserHasPermissions,\n ]);\n\n return menuWithUserPermissions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Utils\n * -----------------------------------------------------------------------------------------------*/\n\nconst getGeneralLinks = async (\n generalSectionRawLinks: MenuItem[],\n shouldUpdateStrapi: boolean = false,\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const generalSectionLinks = normalizeMenuLinks(generalSectionRawLinks);\n const generalSectionLinksPermissions = await Promise.all(\n generalSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedGeneralSectionLinks = generalSectionLinks.filter(\n (_, index) => generalSectionLinksPermissions[index].length > 0\n );\n\n const settingsLinkIndex = authorizedGeneralSectionLinks.findIndex(\n (obj) => obj.to === '/settings'\n );\n\n if (settingsLinkIndex === -1) {\n return [];\n }\n\n const authorizedGeneralLinksClone = cloneDeep(authorizedGeneralSectionLinks);\n\n authorizedGeneralLinksClone[settingsLinkIndex].notificationsCount = shouldUpdateStrapi ? 1 : 0;\n\n return authorizedGeneralLinksClone;\n};\n\nconst getPluginSectionLinks = async (\n pluginsSectionRawLinks: MenuItem[],\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const pluginSectionLinks = normalizeMenuLinks(pluginsSectionRawLinks);\n const pluginSectionLinksPermissions = await Promise.all(\n pluginSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedPluginSectionLinks = pluginSectionLinks.filter(\n (_, index) => pluginSectionLinksPermissions[index].length > 0\n );\n\n return authorizedPluginSectionLinks;\n};\n\nconst normalizeMenuLinks = (links: unknown): MenuItem[] => {\n if (!Array.isArray(links)) {\n return [];\n }\n\n const isValidIcon = (icon: unknown) => {\n if (typeof icon === 'string' || typeof icon === 'function' || React.isValidElement(icon)) {\n return true;\n }\n\n if (!icon || typeof icon !== 'object') {\n return false;\n }\n\n const reactType = (icon as { $$typeof?: symbol }).$$typeof;\n\n return (\n reactType === Symbol.for('react.forward_ref') ||\n reactType === Symbol.for('react.memo') ||\n reactType === Symbol.for('react.lazy')\n );\n };\n\n return links.reduce<MenuItem[]>((acc, link) => {\n if (!link || typeof link !== 'object') {\n return acc;\n }\n\n const candidate = link as Partial<MenuItem>;\n\n if (\n typeof candidate.to !== 'string' ||\n !isValidIcon(candidate.icon) ||\n typeof candidate.intlLabel?.id !== 'string' ||\n typeof candidate.intlLabel.defaultMessage !== 'string'\n ) {\n return acc;\n }\n\n acc.push({\n ...candidate,\n permissions: Array.isArray(candidate.permissions) ? candidate.permissions : [],\n } as MenuItem);\n\n return acc;\n }, []);\n};\n\nexport { useMenu, normalizeMenuLinks };\n"],"names":["useMenu","shouldUpdateStrapi","checkUserHasPermissions","useAuth","state","rawMenu","useStrapiApp","menu","React","useMemo","normalizeMenuLinks","permissions","useTypedSelector","admin_app","menuWithUserPermissions","setMenuWithUserPermissions","useState","generalSectionLinks","icon","House","intlLabel","id","defaultMessage","to","position","ShoppingCart","target","marketplace","main","Cog","notificationsCount","pluginsSectionLinks","topMobileNavigation","burgerMobileNavigation","isLoading","generalSectionLinksRef","useRef","useEffect","applyMenuPermissions","authorizedPluginSectionLinks","getPluginSectionLinks","authorizedGeneralSectionLinks","getGeneralLinks","current","generalSectionRawLinks","generalSectionLinksPermissions","Promise","all","map","filter","_","index","length","settingsLinkIndex","findIndex","obj","authorizedGeneralLinksClone","cloneDeep","pluginsSectionRawLinks","pluginSectionLinks","pluginSectionLinksPermissions","links","Array","isArray","isValidIcon","isValidElement","reactType","$$typeof","Symbol","for","reduce","acc","link","candidate","push"],"mappings":";;;;;;;AA8BA,MAAMA,UAAU,CAACC,kBAAAA,GAAAA;AACf,IAAA,MAAMC,0BAA0BC,OAAAA,CAAQ,SAAA,EAAW,CAACC,KAAAA,GAAUA,MAAMF,uBAAuB,CAAA;AAC3F,IAAA,MAAMG,UAAUC,YAAAA,CAAa,SAAA,EAAW,CAACF,KAAAA,GAAUA,MAAMG,IAAI,CAAA;AAC7D,IAAA,MAAMA,OAAOC,KAAAA,CAAMC,OAAO,CAAC,IAAMC,mBAAmBL,OAAAA,CAAAA,EAAU;AAACA,QAAAA;AAAQ,KAAA,CAAA;AACvE,IAAA,MAAMM,cAAcC,gBAAAA,CAAiB,CAACR,QAAUA,KAAAA,CAAMS,SAAS,CAACF,WAAW,CAAA;AAC3E,IAAA,MAAM,CAACG,uBAAAA,EAAyBC,0BAAAA,CAA2B,GAAGP,KAAAA,CAAMQ,QAAQ,CAAO;QACjFC,mBAAAA,EAAqB;AACnB,YAAA;gBACEC,IAAAA,EAAMC,KAAAA;gBACNC,SAAAA,EAAW;oBACTC,EAAAA,EAAI,aAAA;oBACJC,cAAAA,EAAgB;AAClB,iBAAA;gBACAC,EAAAA,EAAI,GAAA;AACJZ,gBAAAA,WAAAA,EAAa,EAAE;gBACfa,QAAAA,EAAU;AACZ,aAAA;AACA,YAAA;gBACEN,IAAAA,EAAMO,YAAAA;gBACNL,SAAAA,EAAW;oBACTC,EAAAA,EAAI,oBAAA;oBACJC,cAAAA,EAAgB;AAClB,iBAAA;gBACAC,EAAAA,EAAI,0BAAA;gBACJG,MAAAA,EAAQ,QAAA;AACRf,gBAAAA,WAAAA,EAAaA,WAAAA,CAAYgB,WAAW,EAAEC,IAAAA,IAAQ,EAAE;gBAChDJ,QAAAA,EAAU;AACZ,aAAA;AACA,YAAA;gBACEN,IAAAA,EAAMW,GAAAA;gBACNT,SAAAA,EAAW;oBACTC,EAAAA,EAAI,iBAAA;oBACJC,cAAAA,EAAgB;AAClB,iBAAA;gBACAC,EAAAA,EAAI,WAAA;;;AAGJZ,gBAAAA,WAAAA,EAAa,EAAE;gBACfmB,kBAAAA,EAAoB,CAAA;gBACpBN,QAAAA,EAAU;AACZ;AACD,SAAA;AACDO,QAAAA,mBAAAA,EAAqB,EAAE;QACvBC,mBAAAA,EAAqB;AACnB,YAAA;gBACET,EAAAA,EAAI;AACN,aAAA;AACA,YAAA;gBACEA,EAAAA,EAAI;AACN,aAAA;AACA,YAAA;gBACEA,EAAAA,EAAI;AACN,aAAA;AACA,YAAA;gBACEA,EAAAA,EAAI;AACN;AACD,SAAA;QACDU,sBAAAA,EAAwB;AACtB,YAAA;gBACEV,EAAAA,EAAI;AACN;AACD,SAAA;QACDW,SAAAA,EAAW;AACb,KAAA,CAAA;AACA,IAAA,MAAMC,sBAAAA,GAAyB3B,KAAAA,CAAM4B,MAAM,CAACtB,wBAAwBG,mBAAmB,CAAA;AAEvFT,IAAAA,KAAAA,CAAM6B,SAAS,CAAC,IAAA;QACd,eAAeC,oBAAAA,GAAAA;YACb,MAAMC,4BAAAA,GAA+B,MAAMC,qBAAAA,CACzCjC,IAAAA,EACAL,uBAAAA,CAAAA;AAGF,YAAA,MAAMuC,gCAAgC,MAAMC,eAAAA,CAC1CP,sBAAAA,CAAuBQ,OAAO,EAC9B1C,kBAAAA,EACAC,uBAAAA,CAAAA;YAGFa,0BAAAA,CAA2B,CAACX,SAAW;AACrC,oBAAA,GAAGA,KAAK;oBACRa,mBAAAA,EAAqBwB,6BAAAA;oBACrBV,mBAAAA,EAAqBQ,4BAAAA;oBACrBL,SAAAA,EAAW;iBACb,CAAA,CAAA;AACF,QAAA;AAEAI,QAAAA,oBAAAA,EAAAA;IACF,CAAA,EAAG;AACDvB,QAAAA,0BAAAA;AACAoB,QAAAA,sBAAAA;AACA5B,QAAAA,IAAAA;AACAI,QAAAA,WAAAA;AACAV,QAAAA,kBAAAA;AACAC,QAAAA;AACD,KAAA,CAAA;IAED,OAAOY,uBAAAA;AACT;AAEA;;AAEkG,qGAElG,MAAM4B,eAAAA,GAAkB,OACtBE,sBAAAA,EACA3C,kBAAAA,GAA8B,KAAK,EACnCC,uBAAAA,GAAAA;AAEA,IAAA,MAAMe,sBAAsBP,kBAAAA,CAAmBkC,sBAAAA,CAAAA;AAC/C,IAAA,MAAMC,8BAAAA,GAAiC,MAAMC,OAAAA,CAAQC,GAAG,CACtD9B,mBAAAA,CAAoB+B,GAAG,CAAC,CAAC,EAAErC,WAAW,EAAE,GAAKT,uBAAAA,CAAwBS,WAAAA,CAAAA,CAAAA,CAAAA;AAGvE,IAAA,MAAM8B,6BAAAA,GAAgCxB,mBAAAA,CAAoBgC,MAAM,CAC9D,CAACC,CAAAA,EAAGC,KAAAA,GAAUN,8BAA8B,CAACM,KAAAA,CAAM,CAACC,MAAM,GAAG,CAAA,CAAA;IAG/D,MAAMC,iBAAAA,GAAoBZ,8BAA8Ba,SAAS,CAC/D,CAACC,GAAAA,GAAQA,GAAAA,CAAIhC,EAAE,KAAK,WAAA,CAAA;IAGtB,IAAI8B,iBAAAA,KAAsB,EAAC,EAAG;AAC5B,QAAA,OAAO,EAAE;AACX,IAAA;AAEA,IAAA,MAAMG,8BAA8BC,SAAAA,CAAUhB,6BAAAA,CAAAA;AAE9Ce,IAAAA,2BAA2B,CAACH,iBAAAA,CAAkB,CAACvB,kBAAkB,GAAG7B,qBAAqB,CAAA,GAAI,CAAA;IAE7F,OAAOuD,2BAAAA;AACT,CAAA;AAEA,MAAMhB,qBAAAA,GAAwB,OAC5BkB,sBAAAA,EACAxD,uBAAAA,GAAAA;AAEA,IAAA,MAAMyD,qBAAqBjD,kBAAAA,CAAmBgD,sBAAAA,CAAAA;AAC9C,IAAA,MAAME,6BAAAA,GAAgC,MAAMd,OAAAA,CAAQC,GAAG,CACrDY,kBAAAA,CAAmBX,GAAG,CAAC,CAAC,EAAErC,WAAW,EAAE,GAAKT,uBAAAA,CAAwBS,WAAAA,CAAAA,CAAAA,CAAAA;AAGtE,IAAA,MAAM4B,4BAAAA,GAA+BoB,kBAAAA,CAAmBV,MAAM,CAC5D,CAACC,CAAAA,EAAGC,KAAAA,GAAUS,6BAA6B,CAACT,KAAAA,CAAM,CAACC,MAAM,GAAG,CAAA,CAAA;IAG9D,OAAOb,4BAAAA;AACT,CAAA;AAEA,MAAM7B,qBAAqB,CAACmD,KAAAA,GAAAA;AAC1B,IAAA,IAAI,CAACC,KAAAA,CAAMC,OAAO,CAACF,KAAAA,CAAAA,EAAQ;AACzB,QAAA,OAAO,EAAE;AACX,IAAA;AAEA,IAAA,MAAMG,cAAc,CAAC9C,IAAAA,GAAAA;QACnB,IAAI,OAAOA,SAAS,QAAA,IAAY,OAAOA,SAAS,UAAA,IAAcV,KAAAA,CAAMyD,cAAc,CAAC/C,IAAAA,CAAAA,EAAO;YACxF,OAAO,IAAA;AACT,QAAA;AAEA,QAAA,IAAI,CAACA,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;YACrC,OAAO,KAAA;AACT,QAAA;QAEA,MAAMgD,SAAAA,GAAY,IAAChD,CAA+BiD,QAAQ;AAE1D,QAAA,OACED,SAAAA,KAAcE,MAAAA,CAAOC,GAAG,CAAC,mBAAA,CAAA,IACzBH,SAAAA,KAAcE,MAAAA,CAAOC,GAAG,CAAC,YAAA,CAAA,IACzBH,SAAAA,KAAcE,MAAAA,CAAOC,GAAG,CAAC,YAAA,CAAA;AAE7B,IAAA,CAAA;AAEA,IAAA,OAAOR,KAAAA,CAAMS,MAAM,CAAa,CAACC,GAAAA,EAAKC,IAAAA,GAAAA;AACpC,QAAA,IAAI,CAACA,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;YACrC,OAAOD,GAAAA;AACT,QAAA;AAEA,QAAA,MAAME,SAAAA,GAAYD,IAAAA;QAElB,IACE,OAAOC,UAAUlD,EAAE,KAAK,YACxB,CAACyC,WAAAA,CAAYS,SAAAA,CAAUvD,IAAI,CAAA,IAC3B,OAAOuD,UAAUrD,SAAS,EAAEC,OAAO,QAAA,IACnC,OAAOoD,UAAUrD,SAAS,CAACE,cAAc,KAAK,QAAA,EAC9C;YACA,OAAOiD,GAAAA;AACT,QAAA;AAEAA,QAAAA,GAAAA,CAAIG,IAAI,CAAC;AACP,YAAA,GAAGD,SAAS;YACZ9D,WAAAA,EAAamD,KAAAA,CAAMC,OAAO,CAACU,SAAAA,CAAU9D,WAAW,CAAA,GAAI8D,SAAAA,CAAU9D,WAAW,GAAG;AAC9E,SAAA,CAAA;QAEA,OAAO4D,GAAAA;AACT,IAAA,CAAA,EAAG,EAAE,CAAA;AACP;;;;"}
|
|
1
|
+
{"version":3,"file":"useMenu.mjs","sources":["../../../../../admin/src/hooks/useMenu.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { Cog, ShoppingCart, House } from '@strapi/icons';\nimport cloneDeep from 'lodash/cloneDeep';\n\nimport { useTypedSelector } from '../core/store/hooks';\nimport { useAuth, AuthContextValue } from '../features/Auth';\nimport { StrapiAppContextValue, useStrapiApp } from '../features/StrapiApp';\nimport { hideCloudDeployMenuLinkInProduction } from '../utils/widgetVisibility';\n\n/* -------------------------------------------------------------------------------------------------\n * useMenu\n * -----------------------------------------------------------------------------------------------*/\n\nexport type MenuItem = Omit<StrapiAppContextValue['menu'][number], 'Component'> & {\n navigationLink?: string;\n};\nexport type MobileMenuItem = {\n to: string;\n target?: string;\n link?: string;\n};\n\nexport interface Menu {\n generalSectionLinks: MenuItem[];\n pluginsSectionLinks: MenuItem[];\n topMobileNavigation: MobileMenuItem[];\n burgerMobileNavigation: MobileMenuItem[];\n isLoading: boolean;\n}\n\nconst useMenu = (shouldUpdateStrapi: boolean, currentEnvironment?: string) => {\n const checkUserHasPermissions = useAuth('useMenu', (state) => state.checkUserHasPermissions);\n const rawMenu = useStrapiApp('useMenu', (state) => state.menu);\n const menu = React.useMemo(() => normalizeMenuLinks(rawMenu), [rawMenu]);\n const permissions = useTypedSelector((state) => state.admin_app.permissions);\n const [menuWithUserPermissions, setMenuWithUserPermissions] = React.useState<Menu>({\n generalSectionLinks: [\n {\n icon: House,\n intlLabel: {\n id: 'global.home',\n defaultMessage: 'Home',\n },\n to: '/',\n permissions: [],\n position: 0,\n },\n {\n icon: ShoppingCart,\n intlLabel: {\n id: 'global.marketplace',\n defaultMessage: 'Marketplace',\n },\n to: 'https://market.strapi.io',\n target: '_blank',\n permissions: permissions.marketplace?.main ?? [],\n position: 7,\n },\n {\n icon: Cog,\n intlLabel: {\n id: 'global.settings',\n defaultMessage: 'Settings',\n },\n to: '/settings',\n // Permissions of this link are retrieved in the init phase\n // using the settings menu\n permissions: [],\n notificationsCount: 0,\n position: 9,\n },\n ],\n pluginsSectionLinks: [],\n topMobileNavigation: [\n {\n to: '/',\n },\n {\n to: 'content-manager',\n },\n {\n to: 'plugins/content-releases',\n },\n {\n to: 'plugins/upload',\n },\n ],\n burgerMobileNavigation: [\n {\n to: '/settings',\n },\n ],\n isLoading: true,\n });\n const generalSectionLinksRef = React.useRef(menuWithUserPermissions.generalSectionLinks);\n\n React.useEffect(() => {\n async function applyMenuPermissions() {\n const authorizedPluginSectionLinks = await getPluginSectionLinks(\n menu,\n checkUserHasPermissions\n );\n\n const authorizedGeneralSectionLinks = await getGeneralLinks(\n generalSectionLinksRef.current,\n shouldUpdateStrapi,\n checkUserHasPermissions\n );\n\n setMenuWithUserPermissions((state) => ({\n ...state,\n generalSectionLinks: authorizedGeneralSectionLinks,\n pluginsSectionLinks: hideCloudDeployMenuLinkInProduction(\n authorizedPluginSectionLinks,\n currentEnvironment\n ),\n isLoading: false,\n }));\n }\n\n applyMenuPermissions();\n }, [\n setMenuWithUserPermissions,\n generalSectionLinksRef,\n menu,\n permissions,\n shouldUpdateStrapi,\n checkUserHasPermissions,\n currentEnvironment,\n ]);\n\n return menuWithUserPermissions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Utils\n * -----------------------------------------------------------------------------------------------*/\n\nconst getGeneralLinks = async (\n generalSectionRawLinks: MenuItem[],\n shouldUpdateStrapi: boolean = false,\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const generalSectionLinks = normalizeMenuLinks(generalSectionRawLinks);\n const generalSectionLinksPermissions = await Promise.all(\n generalSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedGeneralSectionLinks = generalSectionLinks.filter(\n (_, index) => generalSectionLinksPermissions[index].length > 0\n );\n\n const settingsLinkIndex = authorizedGeneralSectionLinks.findIndex(\n (obj) => obj.to === '/settings'\n );\n\n if (settingsLinkIndex === -1) {\n return [];\n }\n\n const authorizedGeneralLinksClone = cloneDeep(authorizedGeneralSectionLinks);\n\n authorizedGeneralLinksClone[settingsLinkIndex].notificationsCount = shouldUpdateStrapi ? 1 : 0;\n\n return authorizedGeneralLinksClone;\n};\n\nconst getPluginSectionLinks = async (\n pluginsSectionRawLinks: MenuItem[],\n checkUserHasPermissions: AuthContextValue['checkUserHasPermissions']\n) => {\n const pluginSectionLinks = normalizeMenuLinks(pluginsSectionRawLinks);\n const pluginSectionLinksPermissions = await Promise.all(\n pluginSectionLinks.map(({ permissions }) => checkUserHasPermissions(permissions))\n );\n\n const authorizedPluginSectionLinks = pluginSectionLinks.filter(\n (_, index) => pluginSectionLinksPermissions[index].length > 0\n );\n\n return authorizedPluginSectionLinks;\n};\n\nconst normalizeMenuLinks = (links: unknown): MenuItem[] => {\n if (!Array.isArray(links)) {\n return [];\n }\n\n const isValidIcon = (icon: unknown) => {\n if (typeof icon === 'string' || typeof icon === 'function' || React.isValidElement(icon)) {\n return true;\n }\n\n if (!icon || typeof icon !== 'object') {\n return false;\n }\n\n const reactType = (icon as { $$typeof?: symbol }).$$typeof;\n\n return (\n reactType === Symbol.for('react.forward_ref') ||\n reactType === Symbol.for('react.memo') ||\n reactType === Symbol.for('react.lazy')\n );\n };\n\n return links.reduce<MenuItem[]>((acc, link) => {\n if (!link || typeof link !== 'object') {\n return acc;\n }\n\n const candidate = link as Partial<MenuItem>;\n\n if (\n typeof candidate.to !== 'string' ||\n !isValidIcon(candidate.icon) ||\n typeof candidate.intlLabel?.id !== 'string' ||\n typeof candidate.intlLabel.defaultMessage !== 'string'\n ) {\n return acc;\n }\n\n acc.push({\n ...candidate,\n permissions: Array.isArray(candidate.permissions) ? candidate.permissions : [],\n } as MenuItem);\n\n return acc;\n }, []);\n};\n\nexport { useMenu, normalizeMenuLinks };\n"],"names":["useMenu","shouldUpdateStrapi","currentEnvironment","checkUserHasPermissions","useAuth","state","rawMenu","useStrapiApp","menu","React","useMemo","normalizeMenuLinks","permissions","useTypedSelector","admin_app","menuWithUserPermissions","setMenuWithUserPermissions","useState","generalSectionLinks","icon","House","intlLabel","id","defaultMessage","to","position","ShoppingCart","target","marketplace","main","Cog","notificationsCount","pluginsSectionLinks","topMobileNavigation","burgerMobileNavigation","isLoading","generalSectionLinksRef","useRef","useEffect","applyMenuPermissions","authorizedPluginSectionLinks","getPluginSectionLinks","authorizedGeneralSectionLinks","getGeneralLinks","current","hideCloudDeployMenuLinkInProduction","generalSectionRawLinks","generalSectionLinksPermissions","Promise","all","map","filter","_","index","length","settingsLinkIndex","findIndex","obj","authorizedGeneralLinksClone","cloneDeep","pluginsSectionRawLinks","pluginSectionLinks","pluginSectionLinksPermissions","links","Array","isArray","isValidIcon","isValidElement","reactType","$$typeof","Symbol","for","reduce","acc","link","candidate","push"],"mappings":"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"}
|
|
@@ -34,7 +34,6 @@ const useQueryParams = (initialParams)=>{
|
|
|
34
34
|
if (method === 'remove') {
|
|
35
35
|
Object.keys(nextParams).forEach((key)=>{
|
|
36
36
|
if (Object.prototype.hasOwnProperty.call(nextQuery, key)) {
|
|
37
|
-
// @ts-expect-error – this is fine, if you want to fix it, please do.
|
|
38
37
|
delete nextQuery[key];
|
|
39
38
|
}
|
|
40
39
|
});
|