@strapi/admin 5.41.1 → 5.42.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.
Files changed (52) hide show
  1. package/dist/admin/admin/src/StrapiApp.js +1 -0
  2. package/dist/admin/admin/src/StrapiApp.js.map +1 -1
  3. package/dist/admin/admin/src/StrapiApp.mjs +1 -0
  4. package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/FormInputs/Time.js +6 -1
  6. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  7. package/dist/admin/admin/src/components/FormInputs/Time.mjs +6 -1
  8. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  9. package/dist/admin/admin/src/features/Auth.js +16 -1
  10. package/dist/admin/admin/src/features/Auth.js.map +1 -1
  11. package/dist/admin/admin/src/features/Auth.mjs +16 -1
  12. package/dist/admin/admin/src/features/Auth.mjs.map +1 -1
  13. package/dist/admin/admin/src/features/Widgets.js +1 -1
  14. package/dist/admin/admin/src/features/Widgets.js.map +1 -1
  15. package/dist/admin/admin/src/features/Widgets.mjs +1 -1
  16. package/dist/admin/admin/src/features/Widgets.mjs.map +1 -1
  17. package/dist/admin/admin/src/pages/ProfilePage.js +2 -2
  18. package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
  19. package/dist/admin/admin/src/pages/ProfilePage.mjs +2 -2
  20. package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
  21. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js +1 -1
  22. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js.map +1 -1
  23. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs +1 -1
  24. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs.map +1 -1
  25. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js +1 -1
  26. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js.map +1 -1
  27. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs +1 -1
  28. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs.map +1 -1
  29. package/dist/admin/admin/src/translations/fi.json.js +890 -0
  30. package/dist/admin/admin/src/translations/fi.json.js.map +1 -0
  31. package/dist/admin/admin/src/translations/fi.json.mjs +868 -0
  32. package/dist/admin/admin/src/translations/fi.json.mjs.map +1 -0
  33. package/dist/admin/admin/src/translations/languageNativeNames.js +2 -1
  34. package/dist/admin/admin/src/translations/languageNativeNames.js.map +1 -1
  35. package/dist/admin/admin/src/translations/languageNativeNames.mjs +2 -1
  36. package/dist/admin/admin/src/translations/languageNativeNames.mjs.map +1 -1
  37. package/dist/admin/admin/src/translations/pl.json.js +411 -37
  38. package/dist/admin/admin/src/translations/pl.json.js.map +1 -1
  39. package/dist/admin/admin/src/translations/pl.json.mjs +408 -38
  40. package/dist/admin/admin/src/translations/pl.json.mjs.map +1 -1
  41. package/dist/admin/src/pages/Settings/pages/Roles/utils/forms.d.ts +1 -1
  42. package/dist/admin/src/translations/languageNativeNames.d.ts +1 -0
  43. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +1 -1
  44. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +1 -1
  45. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  46. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +1 -1
  47. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  48. package/dist/server/ee/server/src/index.js +1 -1
  49. package/dist/server/ee/server/src/index.js.map +1 -1
  50. package/dist/server/ee/server/src/index.mjs +1 -1
  51. package/dist/server/ee/server/src/index.mjs.map +1 -1
  52. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.mjs","sources":["../../../../../admin/src/features/Auth.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nimport { Login } from '../../../shared/contracts/authentication';\nimport { createContext } from '../components/Context';\nimport { useTypedDispatch, useTypedSelector } from '../core/store/hooks';\nimport { useStrapiApp } from '../features/StrapiApp';\nimport { useQueryParams } from '../hooks/useQueryParams';\nimport { login as loginAction, logout as logoutAction, setLocale, setToken } from '../reducer';\nimport { adminApi } from '../services/api';\nimport {\n useGetMeQuery,\n useGetMyPermissionsQuery,\n useLazyCheckPermissionsQuery,\n useLoginMutation,\n useLogoutMutation,\n} from '../services/auth';\nimport { getOrCreateDeviceId } from '../utils/deviceId';\nimport { setOnTokenUpdate } from '../utils/getFetchClient';\n\nimport type {\n Permission as PermissionContract,\n SanitizedAdminUser,\n} from '../../../shared/contracts/shared';\n\ninterface Permission\n extends Pick<PermissionContract, 'action' | 'subject'>,\n Partial<Omit<PermissionContract, 'action' | 'subject'>> {}\n\ninterface User\n extends Pick<SanitizedAdminUser, 'email' | 'firstname' | 'lastname' | 'username' | 'roles'>,\n Partial<Omit<SanitizedAdminUser, 'email' | 'firstname' | 'lastname' | 'username' | 'roles'>> {}\n\ninterface AuthContextValue {\n login: (\n body: Login.Request['body'] & { rememberMe: boolean }\n ) => Promise<Awaited<ReturnType<ReturnType<typeof useLoginMutation>[0]>>>;\n logout: () => Promise<void>;\n /**\n * @alpha\n * @description given a list of permissions, this function checks\n * those against the current user's permissions or those passed as\n * the second argument, if the user has those permissions the complete\n * permission object form the API is returned. Therefore, if the list is\n * empty, the user does not have any of those permissions.\n */\n checkUserHasPermissions: (\n permissions?: Array<Pick<Permission, 'action'> & Partial<Omit<Permission, 'action'>>>,\n passedPermissions?: Permission[],\n rawQueryContext?: string\n ) => Promise<Permission[]>;\n isLoading: boolean;\n permissions: Permission[];\n refetchPermissions: () => Promise<void>;\n token: string | null;\n user?: User;\n}\n\nconst [Provider, useAuth] = createContext<AuthContextValue>('Auth');\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /**\n * @internal could be removed at any time.\n */\n _defaultPermissions?: Permission[];\n\n // NOTE: this is used for testing purposed only\n _disableRenewToken?: boolean;\n}\n\nconst STORAGE_KEYS = {\n TOKEN: 'jwtToken',\n STATUS: 'isLoggedIn',\n};\n\nconst AuthProvider = ({\n children,\n _defaultPermissions = [],\n _disableRenewToken = false,\n}: AuthProviderProps) => {\n const dispatch = useTypedDispatch();\n const runRbacMiddleware = useStrapiApp('AuthProvider', (state) => state.rbac.run);\n const location = useLocation();\n const [{ rawQuery }] = useQueryParams();\n\n const locationRef = React.useRef(location);\n\n // Update ref without causing re-render\n React.useEffect(() => {\n locationRef.current = location;\n }, [location]);\n\n const token = useTypedSelector((state) => state.admin_app.token ?? null);\n\n const { data: user, isLoading: isLoadingUser } = useGetMeQuery(undefined, {\n /**\n * If there's no token, we don't try to fetch\n * the user data because it will fail.\n */\n skip: !token,\n });\n\n const {\n data: userPermissions = _defaultPermissions,\n refetch,\n isUninitialized,\n isLoading: isLoadingPermissions,\n } = useGetMyPermissionsQuery(undefined, {\n skip: !token,\n });\n\n const navigate = useNavigate();\n\n const [loginMutation] = useLoginMutation();\n const [logoutMutation] = useLogoutMutation();\n\n const clearStateAndLogout = React.useCallback(() => {\n dispatch(adminApi.util.resetApiState());\n dispatch(logoutAction());\n navigate('/auth/login');\n }, [dispatch, navigate]);\n\n React.useEffect(() => {\n if (user) {\n if (user.preferedLanguage) {\n dispatch(setLocale(user.preferedLanguage));\n }\n }\n }, [dispatch, user]);\n\n /**\n * Register a callback to update Redux state when the token is refreshed.\n * This ensures the app state stays in sync with the token stored in localStorage/cookies.\n */\n React.useEffect(() => {\n setOnTokenUpdate((newToken) => {\n dispatch(setToken(newToken));\n });\n\n return () => {\n setOnTokenUpdate(null);\n };\n }, [dispatch]);\n\n React.useEffect(() => {\n /**\n * This will log a user out of all tabs if they log out in one tab.\n */\n const handleUserStorageChange = (event: StorageEvent) => {\n if (event.key === STORAGE_KEYS.STATUS && event.newValue === null) {\n clearStateAndLogout();\n }\n };\n\n window.addEventListener('storage', handleUserStorageChange);\n\n return () => {\n window.removeEventListener('storage', handleUserStorageChange);\n };\n });\n\n const login = React.useCallback<AuthContextValue['login']>(\n async ({ rememberMe, ...body }) => {\n const res = await loginMutation({ ...body, deviceId: getOrCreateDeviceId(), rememberMe });\n\n /**\n * There will always be a `data` key in the response\n * because if something fails, it will throw an error.\n */\n if ('data' in res) {\n const { token } = res.data;\n\n dispatch(\n loginAction({\n token,\n persist: rememberMe,\n })\n );\n }\n\n return res;\n },\n [dispatch, loginMutation]\n );\n\n const logout = React.useCallback(async () => {\n await logoutMutation({ deviceId: getOrCreateDeviceId() });\n clearStateAndLogout();\n }, [clearStateAndLogout, logoutMutation]);\n\n const refetchPermissions = React.useCallback(async () => {\n if (!isUninitialized) {\n await refetch();\n }\n }, [isUninitialized, refetch]);\n\n const [checkPermissions] = useLazyCheckPermissionsQuery();\n const checkUserHasPermissions: AuthContextValue['checkUserHasPermissions'] = React.useCallback(\n async (\n permissions,\n passedPermissions,\n // TODO:\n // Here we have parameterised checkUserHasPermissions in order to pass\n // query context from elsewhere in the application.\n // See packages/core/content-manager/admin/src/features/DocumentRBAC.tsx\n\n // This is in order to calculate permissions on accurate query params.\n // We should be able to rely on the query params in this provider\n // If we need to pass additional context to the RBAC middleware\n // we should define a better context type.\n rawQueryContext\n ) => {\n /**\n * If there's no permissions to check, then we allow it to\n * pass to preserve existing behaviours.\n *\n * TODO: should we review this? it feels more dangerous than useful.\n */\n if (!permissions || permissions.length === 0) {\n return [{ action: '', subject: '' }];\n }\n\n /**\n * Given the provided permissions, return the permissions from either passedPermissions\n * or userPermissions as this is expected to be the full permission entity.\n */\n const actualUserPermissions = passedPermissions ?? userPermissions;\n\n const matchingPermissions = actualUserPermissions.filter(\n (permission) =>\n permissions.findIndex(\n (perm) =>\n perm.action === permission.action &&\n // Only check the subject if it's provided\n (perm.subject == undefined || perm.subject === permission.subject)\n ) >= 0\n );\n\n const middlewaredPermissions = await runRbacMiddleware(\n {\n user,\n permissions: userPermissions,\n pathname: locationRef.current.pathname,\n search: (rawQueryContext || rawQuery).split('?')[1] ?? '',\n },\n matchingPermissions\n );\n\n const shouldCheckConditions = middlewaredPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n if (!shouldCheckConditions) {\n return middlewaredPermissions;\n }\n\n const { data, error } = await checkPermissions({\n permissions: middlewaredPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n });\n\n if (error) {\n throw error;\n } else {\n return middlewaredPermissions.filter((_, index) => data?.data[index] === true);\n }\n },\n [checkPermissions, rawQuery, runRbacMiddleware, user, userPermissions]\n );\n\n const isLoading = isLoadingUser || isLoadingPermissions;\n\n return (\n <Provider\n token={token}\n user={user}\n login={login}\n logout={logout}\n permissions={userPermissions}\n checkUserHasPermissions={checkUserHasPermissions}\n refetchPermissions={refetchPermissions}\n isLoading={isLoading}\n >\n {children}\n </Provider>\n );\n};\n\nexport { AuthProvider, useAuth, STORAGE_KEYS };\nexport type { AuthContextValue, Permission, User };\n"],"names":["Provider","useAuth","createContext","STORAGE_KEYS","STATUS","AuthProvider","children","_defaultPermissions","_disableRenewToken","dispatch","useTypedDispatch","runRbacMiddleware","useStrapiApp","state","rbac","run","location","useLocation","rawQuery","useQueryParams","locationRef","React","useRef","useEffect","current","token","useTypedSelector","admin_app","data","user","isLoading","isLoadingUser","useGetMeQuery","undefined","skip","userPermissions","refetch","isUninitialized","isLoadingPermissions","useGetMyPermissionsQuery","navigate","useNavigate","loginMutation","useLoginMutation","logoutMutation","useLogoutMutation","clearStateAndLogout","useCallback","adminApi","util","resetApiState","logoutAction","preferedLanguage","setLocale","setOnTokenUpdate","newToken","setToken","handleUserStorageChange","event","key","newValue","window","addEventListener","removeEventListener","login","rememberMe","body","res","deviceId","getOrCreateDeviceId","loginAction","persist","logout","refetchPermissions","checkPermissions","useLazyCheckPermissionsQuery","checkUserHasPermissions","permissions","passedPermissions","rawQueryContext","length","action","subject","actualUserPermissions","matchingPermissions","filter","permission","findIndex","perm","middlewaredPermissions","pathname","search","split","shouldCheckConditions","some","Array","isArray","conditions","error","map","_","index","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Auth.mjs","sources":["../../../../../admin/src/features/Auth.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nimport { Login } from '../../../shared/contracts/authentication';\nimport { createContext } from '../components/Context';\nimport { useTypedDispatch, useTypedSelector } from '../core/store/hooks';\nimport { useStrapiApp } from '../features/StrapiApp';\nimport { useQueryParams } from '../hooks/useQueryParams';\nimport { login as loginAction, logout as logoutAction, setLocale, setToken } from '../reducer';\nimport { adminApi } from '../services/api';\nimport {\n useGetMeQuery,\n useGetMyPermissionsQuery,\n useLazyCheckPermissionsQuery,\n useLoginMutation,\n useLogoutMutation,\n} from '../services/auth';\nimport { getOrCreateDeviceId } from '../utils/deviceId';\nimport { setOnTokenUpdate } from '../utils/getFetchClient';\n\nimport type {\n Permission as PermissionContract,\n SanitizedAdminUser,\n} from '../../../shared/contracts/shared';\n\ninterface Permission\n extends Pick<PermissionContract, 'action' | 'subject'>,\n Partial<Omit<PermissionContract, 'action' | 'subject'>> {}\n\ninterface User\n extends Pick<SanitizedAdminUser, 'email' | 'firstname' | 'lastname' | 'username' | 'roles'>,\n Partial<Omit<SanitizedAdminUser, 'email' | 'firstname' | 'lastname' | 'username' | 'roles'>> {}\n\ninterface AuthContextValue {\n login: (\n body: Login.Request['body'] & { rememberMe: boolean }\n ) => Promise<Awaited<ReturnType<ReturnType<typeof useLoginMutation>[0]>>>;\n logout: () => Promise<void>;\n /**\n * @alpha\n * @description given a list of permissions, this function checks\n * those against the current user's permissions or those passed as\n * the second argument, if the user has those permissions the complete\n * permission object form the API is returned. Therefore, if the list is\n * empty, the user does not have any of those permissions.\n */\n checkUserHasPermissions: (\n permissions?: Array<Pick<Permission, 'action'> & Partial<Omit<Permission, 'action'>>>,\n passedPermissions?: Permission[],\n rawQueryContext?: string\n ) => Promise<Permission[]>;\n isLoading: boolean;\n permissions: Permission[];\n refetchPermissions: () => Promise<void>;\n token: string | null;\n user?: User;\n}\n\n/**\n * ensure the Auth context never exposes a non-function for checkUserHasPermissions.\n * When this is undefined (e.g. context timing in production builds), consumers would throw\n * \"p is not a function\" / \"checkUserHasPermissions is not a function\". By always passing\n * a function here, all current and future consumers are protected without per-call-site guards.\n *\n * When would the fallback run? Only if the real checkUserHasPermissions were ever undefined\n * when we pass to the Provider (e.g. a rare timing/build edge case). In normal runs it is\n * always defined (useCallback), so the real function is passed and behavior is unchanged.\n *\n * If the fallback ever did run: it returns [] so consumers (which use .length > 0) treat it\n * as \"no permission\" for that render—under-permissive. On the next AuthProvider re-render we\n * pass the real function again, so the context updates and the view corrects quickly.\n * @see https://github.com/strapi/strapi/issues/24384\n */\nconst NOOP_CHECK_USER_HAS_PERMISSIONS: AuthContextValue['checkUserHasPermissions'] = async () => [];\n\nconst [Provider, useAuth] = createContext<AuthContextValue>('Auth');\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n /**\n * @internal could be removed at any time.\n */\n _defaultPermissions?: Permission[];\n\n // NOTE: this is used for testing purposed only\n _disableRenewToken?: boolean;\n}\n\nconst STORAGE_KEYS = {\n TOKEN: 'jwtToken',\n STATUS: 'isLoggedIn',\n};\n\nconst AuthProvider = ({\n children,\n _defaultPermissions = [],\n _disableRenewToken = false,\n}: AuthProviderProps) => {\n const dispatch = useTypedDispatch();\n const runRbacMiddleware = useStrapiApp('AuthProvider', (state) => state.rbac.run);\n const location = useLocation();\n const [{ rawQuery }] = useQueryParams();\n\n const locationRef = React.useRef(location);\n\n // Update ref without causing re-render\n React.useEffect(() => {\n locationRef.current = location;\n }, [location]);\n\n const token = useTypedSelector((state) => state.admin_app.token ?? null);\n\n const { data: user, isLoading: isLoadingUser } = useGetMeQuery(undefined, {\n /**\n * If there's no token, we don't try to fetch\n * the user data because it will fail.\n */\n skip: !token,\n });\n\n const {\n data: userPermissions = _defaultPermissions,\n refetch,\n isUninitialized,\n isLoading: isLoadingPermissions,\n } = useGetMyPermissionsQuery(undefined, {\n skip: !token,\n });\n\n const navigate = useNavigate();\n\n const [loginMutation] = useLoginMutation();\n const [logoutMutation] = useLogoutMutation();\n\n const clearStateAndLogout = React.useCallback(() => {\n dispatch(adminApi.util.resetApiState());\n dispatch(logoutAction());\n navigate('/auth/login');\n }, [dispatch, navigate]);\n\n React.useEffect(() => {\n if (user) {\n if (user.preferedLanguage) {\n dispatch(setLocale(user.preferedLanguage));\n }\n }\n }, [dispatch, user]);\n\n /**\n * Register a callback to update Redux state when the token is refreshed.\n * This ensures the app state stays in sync with the token stored in localStorage/cookies.\n */\n React.useEffect(() => {\n setOnTokenUpdate((newToken) => {\n dispatch(setToken(newToken));\n });\n\n return () => {\n setOnTokenUpdate(null);\n };\n }, [dispatch]);\n\n React.useEffect(() => {\n /**\n * This will log a user out of all tabs if they log out in one tab.\n */\n const handleUserStorageChange = (event: StorageEvent) => {\n if (event.key === STORAGE_KEYS.STATUS && event.newValue === null) {\n clearStateAndLogout();\n }\n };\n\n window.addEventListener('storage', handleUserStorageChange);\n\n return () => {\n window.removeEventListener('storage', handleUserStorageChange);\n };\n });\n\n const login = React.useCallback<AuthContextValue['login']>(\n async ({ rememberMe, ...body }) => {\n const res = await loginMutation({ ...body, deviceId: getOrCreateDeviceId(), rememberMe });\n\n /**\n * There will always be a `data` key in the response\n * because if something fails, it will throw an error.\n */\n if ('data' in res) {\n const { token } = res.data;\n\n dispatch(\n loginAction({\n token,\n persist: rememberMe,\n })\n );\n }\n\n return res;\n },\n [dispatch, loginMutation]\n );\n\n const logout = React.useCallback(async () => {\n await logoutMutation({ deviceId: getOrCreateDeviceId() });\n clearStateAndLogout();\n }, [clearStateAndLogout, logoutMutation]);\n\n const refetchPermissions = React.useCallback(async () => {\n if (!isUninitialized) {\n await refetch();\n }\n }, [isUninitialized, refetch]);\n\n const [checkPermissions] = useLazyCheckPermissionsQuery();\n const checkUserHasPermissions: AuthContextValue['checkUserHasPermissions'] = React.useCallback(\n async (\n permissions,\n passedPermissions,\n // TODO:\n // Here we have parameterised checkUserHasPermissions in order to pass\n // query context from elsewhere in the application.\n // See packages/core/content-manager/admin/src/features/DocumentRBAC.tsx\n\n // This is in order to calculate permissions on accurate query params.\n // We should be able to rely on the query params in this provider\n // If we need to pass additional context to the RBAC middleware\n // we should define a better context type.\n rawQueryContext\n ) => {\n /**\n * If there's no permissions to check, then we allow it to\n * pass to preserve existing behaviours.\n *\n * TODO: should we review this? it feels more dangerous than useful.\n */\n if (!permissions || permissions.length === 0) {\n return [{ action: '', subject: '' }];\n }\n\n /**\n * Given the provided permissions, return the permissions from either passedPermissions\n * or userPermissions as this is expected to be the full permission entity.\n */\n const actualUserPermissions = passedPermissions ?? userPermissions;\n\n const matchingPermissions = actualUserPermissions.filter(\n (permission) =>\n permissions.findIndex(\n (perm) =>\n perm.action === permission.action &&\n // Only check the subject if it's provided\n (perm.subject == undefined || perm.subject === permission.subject)\n ) >= 0\n );\n\n const middlewaredPermissions = await runRbacMiddleware(\n {\n user,\n permissions: userPermissions,\n pathname: locationRef.current.pathname,\n search: (rawQueryContext || rawQuery).split('?')[1] ?? '',\n },\n matchingPermissions\n );\n\n const shouldCheckConditions = middlewaredPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n if (!shouldCheckConditions) {\n return middlewaredPermissions;\n }\n\n const { data, error } = await checkPermissions({\n permissions: middlewaredPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n });\n\n if (error) {\n throw error;\n } else {\n return middlewaredPermissions.filter((_, index) => data?.data[index] === true);\n }\n },\n [checkPermissions, rawQuery, runRbacMiddleware, user, userPermissions]\n );\n\n const isLoading = isLoadingUser || isLoadingPermissions;\n\n return (\n <Provider\n token={token}\n user={user}\n login={login}\n logout={logout}\n permissions={userPermissions}\n checkUserHasPermissions={checkUserHasPermissions ?? NOOP_CHECK_USER_HAS_PERMISSIONS}\n refetchPermissions={refetchPermissions}\n isLoading={isLoading}\n >\n {children}\n </Provider>\n );\n};\n\nexport { AuthProvider, useAuth, STORAGE_KEYS };\nexport type { AuthContextValue, Permission, User };\n"],"names":["NOOP_CHECK_USER_HAS_PERMISSIONS","Provider","useAuth","createContext","STORAGE_KEYS","STATUS","AuthProvider","children","_defaultPermissions","_disableRenewToken","dispatch","useTypedDispatch","runRbacMiddleware","useStrapiApp","state","rbac","run","location","useLocation","rawQuery","useQueryParams","locationRef","React","useRef","useEffect","current","token","useTypedSelector","admin_app","data","user","isLoading","isLoadingUser","useGetMeQuery","undefined","skip","userPermissions","refetch","isUninitialized","isLoadingPermissions","useGetMyPermissionsQuery","navigate","useNavigate","loginMutation","useLoginMutation","logoutMutation","useLogoutMutation","clearStateAndLogout","useCallback","adminApi","util","resetApiState","logoutAction","preferedLanguage","setLocale","setOnTokenUpdate","newToken","setToken","handleUserStorageChange","event","key","newValue","window","addEventListener","removeEventListener","login","rememberMe","body","res","deviceId","getOrCreateDeviceId","loginAction","persist","logout","refetchPermissions","checkPermissions","useLazyCheckPermissionsQuery","checkUserHasPermissions","permissions","passedPermissions","rawQueryContext","length","action","subject","actualUserPermissions","matchingPermissions","filter","permission","findIndex","perm","middlewaredPermissions","pathname","search","split","shouldCheckConditions","some","Array","isArray","conditions","error","map","_","index","_jsx"],"mappings":"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"}
@@ -61,7 +61,7 @@ const saveLayout = async ({ widgets, widths, updateHomepageLayout, toggleNotific
61
61
  type: 'danger',
62
62
  message: formatMessage({
63
63
  id: 'notification.error',
64
- defaultMessage: 'An error occured'
64
+ defaultMessage: 'An error occurred'
65
65
  })
66
66
  });
67
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.js","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.js","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error 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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"}
@@ -40,7 +40,7 @@ const saveLayout = async ({ widgets, widths, updateHomepageLayout, toggleNotific
40
40
  type: 'danger',
41
41
  message: formatMessage({
42
42
  id: 'notification.error',
43
- defaultMessage: 'An error occured'
43
+ defaultMessage: 'An error occurred'
44
44
  })
45
45
  });
46
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.mjs","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n};\n\nconst moveWidget = ({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n}: MoveWidgetOptions) => {\n const widget = filteredWidgets.find((w) => w.uid === widgetId);\n if (!widget) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n // Move widget in the array\n const newWidgets = moveWidgetInArray(filteredWidgets, widgetId, insertIndex);\n\n // Calculate optimal widths for both source and target rows\n const newWidths = { ...columnWidths };\n\n // Find the source row (where the widget was removed from)\n const sourceRow = findRowContainingWidget(widgetRows, widgetId, filteredWidgets);\n\n if (isHorizontalDrop) {\n // This is a horizontal drop zone - widget gets full width in its own row\n newWidths[widgetId] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n } else {\n // This is a vertical drop zone within a row\n const targetRow = widgetRows[targetRowIndex!];\n\n // Check if we're reordering within the same row\n const isSameRowReorder =\n sourceRow && targetRow && sourceRow.startIndex === targetRow.startIndex;\n\n if (isSameRowReorder) {\n // For same-row reordering, just preserve the existing widths\n return { newWidgets, newWidths };\n }\n\n // Different rows - resize both source and target rows\n // Resize source row (after widget removal)\n const sourceRowResize = resizeRowAfterRemoval(sourceRow, widgetId, newWidths);\n Object.assign(newWidths, sourceRowResize);\n\n // Resize target row (after widget addition)\n const targetRowResize = resizeRowAfterAddition(targetRow, widget, insertIndex, newWidths);\n Object.assign(newWidths, targetRowResize);\n }\n\n return { newWidgets, newWidths };\n};\n\nconst deleteWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n const widgetRows = calculateWidgetRows(filteredWidgets, columnWidths);\n\n return (widgetId: string) => {\n const { [widgetId]: _removed, ...newWidths } = columnWidths;\n\n // Find the row containing the deleted widget\n const deletedWidgetIndex = filteredWidgets.findIndex((w) => w.uid === widgetId);\n if (deletedWidgetIndex === -1) return { newWidgets: filteredWidgets, newWidths };\n const affectedRow = widgetRows.find(\n (row) => deletedWidgetIndex >= row.startIndex && deletedWidgetIndex <= row.endIndex\n );\n\n // Use resizeRowAfterRemoval to resize the affected row\n const finalWidths = resizeRowAfterRemoval(affectedRow, widgetId, newWidths);\n const newWidgets = filteredWidgets.filter((w) => w.uid !== widgetId);\n\n return { newWidgets, newWidths: finalWidths };\n };\n};\n\nconst addWidget = (filteredWidgets: WidgetWithUID[], columnWidths: Record<string, number>) => {\n return (widget: WidgetWithUID) => {\n // Check if widget is already added\n const index = filteredWidgets.findIndex((w) => w.uid === widget.uid);\n if (index !== -1) return { newWidgets: filteredWidgets, newWidths: columnWidths };\n\n const newWidgets = [...filteredWidgets, widget];\n const newWidths = { ...columnWidths };\n // New widget always takes full width in its own row\n newWidths[widget.uid] = WIDGET_SIZING.TOTAL_COLUMNS;\n\n return { newWidgets, newWidths };\n };\n};\n\nconst handleWidgetResize = ({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n}: HandleWidgetResizeOptions) => {\n // Check if widgets can be resized (adjacent, same row, valid sizes)\n if (!canResizeBetweenWidgets(leftWidgetId, rightWidgetId, columnWidths, filteredWidgets)) {\n return columnWidths;\n }\n\n if (!isValidResizeOperation(newLeftWidth, newRightWidth)) {\n // Resize would violate constraints, don't allow it\n return columnWidths;\n }\n\n return {\n ...columnWidths,\n [leftWidgetId]: newLeftWidth,\n [rightWidgetId]: newRightWidth,\n };\n};\n\ninterface UseWidgetsOptions {\n filteredWidgets: WidgetWithUID[];\n setFilteredWidgets: (\n widgets: WidgetWithUID[] | ((prev: WidgetWithUID[]) => WidgetWithUID[])\n ) => void;\n}\n\nexport const useWidgets = ({ filteredWidgets, setFilteredWidgets }: UseWidgetsOptions) => {\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>({});\n const [isDraggingWidget, setIsDraggingWidget] = React.useState(false);\n const [draggedWidgetId, setDraggedWidgetId] = React.useState<string | undefined>();\n\n const [updateHomepageLayout] = useUpdateHomepageLayoutMutation();\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n const { formatMessage } = useIntl();\n\n const findWidgetFn: FindWidgetFunction = (widgetId: string) =>\n findWidget(filteredWidgets, widgetId);\n\n const moveWidgetFn = (\n widgetId: string,\n insertIndex: number,\n targetRowIndex?: number,\n isHorizontalDrop?: boolean\n ) => {\n const result = moveWidget({\n filteredWidgets,\n columnWidths,\n widgetId,\n insertIndex,\n targetRowIndex,\n isHorizontalDrop,\n });\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const deleteWidgetFn: WidgetIdFunction = (widgetId: string) => {\n const deleteWidgetOperation = deleteWidget(filteredWidgets, columnWidths);\n const result = deleteWidgetOperation(widgetId);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const addWidgetFn = (widget: WidgetWithUID) => {\n const addWidgetOperation = addWidget(filteredWidgets, columnWidths);\n const result = addWidgetOperation(widget);\n\n setFilteredWidgets(result.newWidgets);\n setColumnWidths(result.newWidths);\n\n saveLayout({\n widgets: result.newWidgets,\n widths: result.newWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n const handleWidgetResizeFn = (\n leftWidgetId: string,\n rightWidgetId: string,\n newLeftWidth: number,\n newRightWidth: number\n ) => {\n const newWidths = handleWidgetResize({\n filteredWidgets,\n columnWidths,\n leftWidgetId,\n rightWidgetId,\n newLeftWidth,\n newRightWidth,\n });\n\n setColumnWidths(newWidths);\n };\n\n const handleDragStart: WidgetIdFunction = React.useCallback((widgetId: string) => {\n setIsDraggingWidget(true);\n setDraggedWidgetId(widgetId);\n }, []);\n\n const handleDragEnd: DragEndFunction = React.useCallback(() => {\n setIsDraggingWidget(false);\n setDraggedWidgetId(undefined);\n }, []);\n\n const saveLayoutFn = () => {\n saveLayout({\n widgets: filteredWidgets,\n widths: columnWidths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n });\n };\n\n return {\n findWidget: findWidgetFn,\n deleteWidget: deleteWidgetFn,\n addWidget: addWidgetFn,\n moveWidget: moveWidgetFn,\n columnWidths,\n setColumnWidths,\n handleWidgetResize: handleWidgetResizeFn,\n saveLayout: saveLayoutFn,\n isDraggingWidget,\n draggedWidgetId,\n handleDragStart,\n handleDragEnd,\n };\n};\n"],"names":["findWidget","filteredWidgets","widgetId","widget","find","c","uid","undefined","index","indexOf","saveLayout","widgets","widths","updateHomepageLayout","toggleNotification","formatAPIError","formatMessage","layoutData","map","width","WIDGET_SIZING","TOTAL_COLUMNS","res","type","message","error","id","defaultMessage","moveWidget","columnWidths","insertIndex","targetRowIndex","isHorizontalDrop","w","newWidgets","newWidths","widgetRows","calculateWidgetRows","moveWidgetInArray","sourceRow","findRowContainingWidget","sourceRowResize","resizeRowAfterRemoval","Object","assign","targetRow","isSameRowReorder","startIndex","targetRowResize","resizeRowAfterAddition","deleteWidget","_removed","deletedWidgetIndex","findIndex","affectedRow","row","endIndex","finalWidths","filter","addWidget","handleWidgetResize","leftWidgetId","rightWidgetId","newLeftWidth","newRightWidth","canResizeBetweenWidgets","isValidResizeOperation","useWidgets","setFilteredWidgets","setColumnWidths","React","useState","isDraggingWidget","setIsDraggingWidget","draggedWidgetId","setDraggedWidgetId","useUpdateHomepageLayoutMutation","useNotification","_unstableFormatAPIError","useAPIErrorHandler","useIntl","findWidgetFn","moveWidgetFn","result","deleteWidgetFn","deleteWidgetOperation","addWidgetFn","addWidgetOperation","handleWidgetResizeFn","handleDragStart","useCallback","handleDragEnd","saveLayoutFn"],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.mjs","sources":["../../../../../admin/src/features/Widgets.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useUpdateHomepageLayoutMutation } from '../services/homepage';\nimport {\n calculateWidgetRows,\n moveWidgetInArray,\n findRowContainingWidget,\n resizeRowAfterRemoval,\n resizeRowAfterAddition,\n isValidResizeOperation,\n canResizeBetweenWidgets,\n WIDGET_SIZING,\n} from '../utils/widgetLayout';\n\nimport { useNotification } from './Notifications';\n\nimport type { WidgetWithUID } from '../core/apis/Widgets';\nimport type { WidgetType } from '@strapi/admin/strapi-admin';\n\nexport interface WidgetInfo {\n widget: WidgetType | undefined;\n index: number;\n}\n\nexport type FindWidgetFunction = (id: string) => WidgetInfo;\nexport type WidgetIdFunction = (id: string) => void;\nexport type DragEndFunction = () => void;\n\ninterface BaseWidgetContext {\n filteredWidgets: WidgetWithUID[];\n columnWidths: Record<string, number>;\n}\n\ninterface MoveWidgetOptions extends BaseWidgetContext {\n widgetId: string;\n insertIndex: number;\n targetRowIndex?: number;\n isHorizontalDrop?: boolean;\n}\n\ninterface SaveLayoutOptions {\n widgets: WidgetWithUID[];\n widths: Record<string, number>;\n updateHomepageLayout: (data: {\n widgets: Array<{ uid: string; width: (typeof WIDGET_SIZING.DISCRETE_SIZES)[number] }>;\n }) => Promise<any>;\n toggleNotification: (config: { type: 'danger'; message: string }) => void;\n formatAPIError: (error: any) => string;\n formatMessage: (descriptor: { id: string; defaultMessage: string }) => string;\n}\n\ninterface HandleWidgetResizeOptions extends BaseWidgetContext {\n leftWidgetId: string;\n rightWidgetId: string;\n newLeftWidth: number;\n newRightWidth: number;\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Widget Management\n * -----------------------------------------------------------------------------------------------*/\n\nconst findWidget = (filteredWidgets: WidgetWithUID[], widgetId: string): WidgetInfo => {\n const widget = filteredWidgets.find((c) => `${c.uid}` === widgetId);\n if (!widget) {\n return {\n widget: undefined,\n index: -1,\n };\n }\n return {\n widget,\n index: filteredWidgets.indexOf(widget),\n };\n};\n\nconst saveLayout = async ({\n widgets,\n widths,\n updateHomepageLayout,\n toggleNotification,\n formatAPIError,\n formatMessage,\n}: SaveLayoutOptions) => {\n try {\n const layoutData = {\n widgets: widgets.map((widget) => ({\n uid: widget.uid,\n width: (widths[widget.uid] ||\n WIDGET_SIZING.TOTAL_COLUMNS) as (typeof WIDGET_SIZING.DISCRETE_SIZES)[number],\n })),\n };\n\n const res = await updateHomepageLayout(layoutData);\n\n if ('error' in res) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(res.error),\n });\n }\n } catch {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error 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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"}
@@ -101,7 +101,7 @@ const ProfilePage = ()=>{
101
101
  type: 'danger',
102
102
  message: formatMessage({
103
103
  id: 'notification.error',
104
- defaultMessage: 'An error occured'
104
+ defaultMessage: 'An error occurred'
105
105
  })
106
106
  });
107
107
  }
@@ -165,7 +165,7 @@ const ProfilePage = ()=>{
165
165
  type: 'danger',
166
166
  message: formatMessage({
167
167
  id: 'notification.error',
168
- defaultMessage: 'An error occured'
168
+ defaultMessage: 'An error occurred'
169
169
  })
170
170
  });
171
171
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProfilePage.js","sources":["../../../../../admin/src/pages/ProfilePage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, useNotifyAT, Grid, Typography, FlexProps } from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport upperFirst from 'lodash/upperFirst';\nimport { useIntl } from 'react-intl';\nimport * as yup from 'yup';\n\nimport { Form, FormHelpers } from '../components/Form';\nimport { InputRenderer } from '../components/FormInputs/Renderer';\nimport { useGuidedTour } from '../components/GuidedTour/Context';\nimport { Layouts } from '../components/Layouts/Layout';\nimport { Page } from '../components/PageHelpers';\nimport { useTypedDispatch, useTypedSelector } from '../core/store/hooks';\nimport { useAuth } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useTracking } from '../features/Tracking';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useIsDesktop } from '../hooks/useMediaQuery';\nimport { AppState, setAppTheme } from '../reducer';\nimport { useIsSSOLockedQuery, useUpdateMeMutation } from '../services/auth';\nimport { isBaseQueryError } from '../utils/baseQuery';\nimport { translatedErrors } from '../utils/translatedErrors';\nimport { getDisplayName } from '../utils/users';\n\nimport { COMMON_USER_SCHEMA } from './Settings/pages/Users/utils/validation';\n\nimport type { UpdateMe } from '../../../shared/contracts/users';\n\nconst PROFILE_VALIDTION_SCHEMA = yup.object().shape({\n ...COMMON_USER_SCHEMA,\n currentPassword: yup\n .string()\n // @ts-expect-error – no idea why this is failing.\n .when(['password', 'confirmPassword'], (password, confirmPassword, passSchema) => {\n return password || confirmPassword\n ? passSchema\n .required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n })\n .nullable()\n : passSchema;\n }),\n preferedLanguage: yup.string().nullable(),\n});\n\n/* -------------------------------------------------------------------------------------------------\n * ProfilePage\n * -----------------------------------------------------------------------------------------------*/\n\nconst Panel = ({ children, ...flexProps }: FlexProps) => {\n return (\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4} {...flexProps}>\n {children}\n </Flex>\n </Box>\n );\n};\n\nconst ProfilePage = () => {\n const isDesktop = useIsDesktop();\n const localeNames = useTypedSelector((state) => state.admin_app.language.localeNames);\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const currentTheme = useTypedSelector((state) => state.admin_app.theme.currentTheme);\n const dispatch = useTypedDispatch();\n const {\n _unstableFormatValidationErrors: formatValidationErrors,\n _unstableFormatAPIError: formatApiError,\n } = useAPIErrorHandler();\n\n const user = useAuth('ProfilePage', (state) => state.user);\n\n React.useEffect(() => {\n if (user) {\n notifyStatus(\n formatMessage({\n id: 'Settings.profile.form.notify.data.loaded',\n defaultMessage: 'Your profile data has been loaded',\n })\n );\n } else {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n }, [formatMessage, notifyStatus, toggleNotification, user]);\n\n const [updateMe, { isLoading: isSubmittingForm }] = useUpdateMeMutation();\n\n const {\n isLoading,\n data: dataSSO,\n error,\n } = useIsSSOLockedQuery(undefined, {\n skip: !(window.strapi.isEE && window.strapi.features.isEnabled('sso')),\n });\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'Settings.permissions.users.sso.provider.error' }),\n });\n }\n }, [error, formatMessage, toggleNotification]);\n\n type UpdateUsersMeBody = UpdateMe.Request['body'] & {\n confirmPassword: string;\n currentTheme: AppState['theme']['currentTheme'];\n };\n\n const handleSubmit = async (\n body: UpdateUsersMeBody,\n { setErrors }: FormHelpers<UpdateUsersMeBody>\n ) => {\n const { confirmPassword: _confirmPassword, currentTheme, ...bodyRest } = body;\n let dataToSend = bodyRest;\n\n // The password fields are optional. If the user didn't touch them, don't send any password\n // to the API, because an empty string would throw a validation error\n if (dataToSend.password === '') {\n const {\n password: _password,\n currentPassword: _currentPassword,\n ...passwordRequestBodyRest\n } = dataToSend;\n dataToSend = passwordRequestBodyRest;\n }\n\n const res = await updateMe(dataToSend);\n\n if ('data' in res) {\n dispatch(setAppTheme(currentTheme));\n\n trackUsage('didChangeMode', { newMode: currentTheme });\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),\n });\n }\n\n if ('error' in res) {\n if (isBaseQueryError(res.error) && res.error.name === 'ValidationError') {\n setErrors(formatValidationErrors(res.error));\n } else if (isBaseQueryError(res.error)) {\n toggleNotification({\n type: 'danger',\n message: formatApiError(res.error),\n });\n } else {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n }\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n const hasLockedRole = dataSSO?.isSSOLocked ?? false;\n const { email, firstname, lastname, username, preferedLanguage } = user ?? {};\n const initialData = {\n email: email ?? '',\n firstname: firstname ?? '',\n lastname: lastname ?? '',\n username: username ?? '',\n preferedLanguage,\n currentTheme,\n confirmPassword: '',\n password: '',\n };\n\n return (\n <>\n <Page.Main aria-busy={isSubmittingForm}>\n <Page.Title>\n {formatMessage({\n id: 'Settings.profile.form.section.head.title',\n defaultMessage: 'User profile',\n })}\n </Page.Title>\n <Form\n method=\"PUT\"\n onSubmit={handleSubmit}\n initialValues={initialData}\n validationSchema={PROFILE_VALIDTION_SCHEMA}\n >\n {({ isSubmitting, modified }) => (\n <>\n <Layouts.Header\n title={getDisplayName(user)}\n primaryAction={\n <Button\n startIcon={<Check />}\n loading={isSubmitting}\n type=\"submit\"\n disabled={!modified}\n fullWidth\n >\n {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}\n </Button>\n }\n />\n <Box paddingBottom={6}>\n <Layouts.Content>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6}>\n <UserInfoSection />\n {!hasLockedRole && <PasswordSection />}\n <PreferencesSection localeNames={localeNames} />\n </Flex>\n </Layouts.Content>\n </Box>\n </>\n )}\n </Form>\n {isDesktop && process.env.NODE_ENV === 'development' && (\n <Box paddingBottom={6}>\n <Layouts.Content>\n <GuidedTourSection />\n </Layouts.Content>\n </Box>\n )}\n </Page.Main>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * PasswordSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst PasswordSection = () => {\n const { formatMessage } = useIntl();\n\n return (\n <Panel>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.change-password',\n defaultMessage: 'Change password',\n })}\n </Typography>\n {[\n [\n {\n label: formatMessage({\n id: 'Auth.form.currentPassword.label',\n defaultMessage: 'Current Password',\n }),\n name: 'currentPassword',\n size: 6,\n type: 'password' as const,\n },\n ],\n [\n {\n autoComplete: 'new-password',\n label: formatMessage({\n id: 'global.password',\n defaultMessage: 'Password',\n }),\n name: 'password',\n size: 6,\n type: 'password' as const,\n },\n {\n autoComplete: 'new-password',\n label: formatMessage({\n id: 'Auth.form.confirmPassword.label',\n defaultMessage: 'Confirm Password',\n }),\n name: 'confirmPassword',\n size: 6,\n type: 'password' as const,\n },\n ],\n ].map((row, index) => (\n <Grid.Root key={index} gap={5}>\n {row.map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n ))}\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * PreferencesSection\n * -----------------------------------------------------------------------------------------------*/\n\ninterface PreferencesSectionProps {\n localeNames: Record<string, string>;\n}\n\nconst PreferencesSection = ({ localeNames }: PreferencesSectionProps) => {\n const { formatMessage } = useIntl();\n const themesToDisplay = useTypedSelector((state) => state.admin_app.theme.availableThemes);\n\n return (\n <Panel>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'Settings.profile.form.section.experience.title',\n defaultMessage: 'Experience',\n })}\n </Typography>\n <Typography>\n {formatMessage(\n {\n id: 'Settings.profile.form.section.experience.interfaceLanguageHelp',\n defaultMessage:\n 'Preference changes will apply only to you. More information is available {here}.',\n },\n {\n here: (\n <Box\n tag=\"a\"\n color=\"primary600\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n href=\"https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#locales\"\n >\n {formatMessage({\n id: 'Settings.profile.form.section.experience.here',\n defaultMessage: 'here',\n })}\n </Box>\n ),\n }\n )}\n </Typography>\n </Flex>\n <Grid.Root gap={5}>\n {[\n {\n hint: formatMessage({\n id: 'Settings.profile.form.section.experience.interfaceLanguage.hint',\n defaultMessage: 'This will only display your own interface in the chosen language.',\n }),\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.interfaceLanguage',\n defaultMessage: 'Interface language',\n }),\n name: 'preferedLanguage',\n options: Object.entries(localeNames).map(([value, label]) => ({\n label,\n value,\n })),\n placeholder: formatMessage({\n id: 'global.select',\n defaultMessage: 'Select',\n }),\n size: 6,\n type: 'enumeration' as const,\n },\n {\n hint: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.hint',\n defaultMessage: 'Displays your interface in the chosen mode.',\n }),\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.label',\n defaultMessage: 'Interface mode',\n }),\n name: 'currentTheme',\n options: [\n {\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.option-system-label',\n defaultMessage: 'Use system settings',\n }),\n value: 'system',\n },\n ...themesToDisplay.map((theme) => ({\n label: formatMessage(\n {\n id: 'Settings.profile.form.section.experience.mode.option-label',\n defaultMessage: '{name} mode',\n },\n {\n name: formatMessage({\n id: theme,\n defaultMessage: upperFirst(theme),\n }),\n }\n ),\n value: theme,\n })),\n ],\n placeholder: formatMessage({\n id: 'components.Select.placeholder',\n defaultMessage: 'Select',\n }),\n size: 6,\n type: 'enumeration' as const,\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * UserInfoSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst UserInfoSection = () => {\n const { formatMessage } = useIntl();\n\n return (\n <Panel>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.profile',\n defaultMessage: 'Profile',\n })}\n </Typography>\n <Grid.Root gap={5}>\n {[\n {\n label: formatMessage({\n id: 'Auth.form.firstname.label',\n defaultMessage: 'First name',\n }),\n name: 'firstname',\n required: true,\n size: 6,\n type: 'string' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.lastname.label',\n defaultMessage: 'Last name',\n }),\n name: 'lastname',\n size: 6,\n type: 'string' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.email.label',\n defaultMessage: 'Email',\n }),\n name: 'email',\n required: true,\n size: 6,\n type: 'email' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.username.label',\n defaultMessage: 'Username',\n }),\n name: 'username',\n size: 6,\n type: 'string' as const,\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst GuidedTourSection = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const dispatch = useGuidedTour('ProfilePage', (s) => s.dispatch);\n\n const onClickReset = () => {\n dispatch({ type: 'reset_all_tours' });\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'tours.profile.notification.success.reset',\n defaultMessage: 'Guided tour reset',\n }),\n });\n };\n\n return (\n <Panel alignItems=\"start\">\n <Flex direction=\"column\" alignItems=\"start\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'tours.profile.title',\n defaultMessage: 'Guided tour',\n })}\n </Typography>\n <Typography variant=\"pi\">\n {formatMessage({\n id: 'tours.profile.description',\n defaultMessage: 'You can reset the guided tour at any time.',\n })}\n </Typography>\n </Flex>\n <Button variant=\"tertiary\" onClick={onClickReset}>\n {formatMessage({\n id: 'tours.profile.reset',\n defaultMessage: 'Reset guided tour',\n })}\n </Button>\n </Panel>\n );\n};\n\nexport { ProfilePage };\n"],"names":["PROFILE_VALIDTION_SCHEMA","yup","object","shape","COMMON_USER_SCHEMA","currentPassword","string","when","password","confirmPassword","passSchema","required","id","translatedErrors","defaultMessage","nullable","preferedLanguage","Panel","children","flexProps","_jsx","Box","background","hasRadius","shadow","paddingTop","paddingBottom","paddingLeft","paddingRight","Flex","direction","alignItems","gap","ProfilePage","isDesktop","useIsDesktop","localeNames","useTypedSelector","state","admin_app","language","formatMessage","useIntl","trackUsage","useTracking","toggleNotification","useNotification","notifyStatus","useNotifyAT","currentTheme","theme","dispatch","useTypedDispatch","_unstableFormatValidationErrors","formatValidationErrors","_unstableFormatAPIError","formatApiError","useAPIErrorHandler","user","useAuth","React","useEffect","type","message","updateMe","isLoading","isSubmittingForm","useUpdateMeMutation","data","dataSSO","error","useIsSSOLockedQuery","undefined","skip","window","strapi","isEE","features","isEnabled","handleSubmit","body","setErrors","_confirmPassword","bodyRest","dataToSend","_password","_currentPassword","passwordRequestBodyRest","res","setAppTheme","newMode","isBaseQueryError","name","Page","Loading","hasLockedRole","isSSOLocked","email","firstname","lastname","username","initialData","_Fragment","_jsxs","Main","aria-busy","Title","Form","method","onSubmit","initialValues","validationSchema","isSubmitting","modified","Layouts","Header","title","getDisplayName","primaryAction","Button","startIcon","Check","loading","disabled","fullWidth","Content","UserInfoSection","PasswordSection","PreferencesSection","process","env","NODE_ENV","GuidedTourSection","Typography","variant","tag","label","size","autoComplete","map","row","index","Grid","Root","field","Item","xs","m","col","InputRenderer","themesToDisplay","availableThemes","here","color","target","rel","href","hint","options","Object","entries","value","placeholder","upperFirst","useGuidedTour","s","onClickReset","onClick"],"mappings":"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"}
1
+ {"version":3,"file":"ProfilePage.js","sources":["../../../../../admin/src/pages/ProfilePage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, useNotifyAT, Grid, Typography, FlexProps } from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport upperFirst from 'lodash/upperFirst';\nimport { useIntl } from 'react-intl';\nimport * as yup from 'yup';\n\nimport { Form, FormHelpers } from '../components/Form';\nimport { InputRenderer } from '../components/FormInputs/Renderer';\nimport { useGuidedTour } from '../components/GuidedTour/Context';\nimport { Layouts } from '../components/Layouts/Layout';\nimport { Page } from '../components/PageHelpers';\nimport { useTypedDispatch, useTypedSelector } from '../core/store/hooks';\nimport { useAuth } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useTracking } from '../features/Tracking';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useIsDesktop } from '../hooks/useMediaQuery';\nimport { AppState, setAppTheme } from '../reducer';\nimport { useIsSSOLockedQuery, useUpdateMeMutation } from '../services/auth';\nimport { isBaseQueryError } from '../utils/baseQuery';\nimport { translatedErrors } from '../utils/translatedErrors';\nimport { getDisplayName } from '../utils/users';\n\nimport { COMMON_USER_SCHEMA } from './Settings/pages/Users/utils/validation';\n\nimport type { UpdateMe } from '../../../shared/contracts/users';\n\nconst PROFILE_VALIDTION_SCHEMA = yup.object().shape({\n ...COMMON_USER_SCHEMA,\n currentPassword: yup\n .string()\n // @ts-expect-error – no idea why this is failing.\n .when(['password', 'confirmPassword'], (password, confirmPassword, passSchema) => {\n return password || confirmPassword\n ? passSchema\n .required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n })\n .nullable()\n : passSchema;\n }),\n preferedLanguage: yup.string().nullable(),\n});\n\n/* -------------------------------------------------------------------------------------------------\n * ProfilePage\n * -----------------------------------------------------------------------------------------------*/\n\nconst Panel = ({ children, ...flexProps }: FlexProps) => {\n return (\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4} {...flexProps}>\n {children}\n </Flex>\n </Box>\n );\n};\n\nconst ProfilePage = () => {\n const isDesktop = useIsDesktop();\n const localeNames = useTypedSelector((state) => state.admin_app.language.localeNames);\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const currentTheme = useTypedSelector((state) => state.admin_app.theme.currentTheme);\n const dispatch = useTypedDispatch();\n const {\n _unstableFormatValidationErrors: formatValidationErrors,\n _unstableFormatAPIError: formatApiError,\n } = useAPIErrorHandler();\n\n const user = useAuth('ProfilePage', (state) => state.user);\n\n React.useEffect(() => {\n if (user) {\n notifyStatus(\n formatMessage({\n id: 'Settings.profile.form.notify.data.loaded',\n defaultMessage: 'Your profile data has been loaded',\n })\n );\n } else {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }, [formatMessage, notifyStatus, toggleNotification, user]);\n\n const [updateMe, { isLoading: isSubmittingForm }] = useUpdateMeMutation();\n\n const {\n isLoading,\n data: dataSSO,\n error,\n } = useIsSSOLockedQuery(undefined, {\n skip: !(window.strapi.isEE && window.strapi.features.isEnabled('sso')),\n });\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'Settings.permissions.users.sso.provider.error' }),\n });\n }\n }, [error, formatMessage, toggleNotification]);\n\n type UpdateUsersMeBody = UpdateMe.Request['body'] & {\n confirmPassword: string;\n currentTheme: AppState['theme']['currentTheme'];\n };\n\n const handleSubmit = async (\n body: UpdateUsersMeBody,\n { setErrors }: FormHelpers<UpdateUsersMeBody>\n ) => {\n const { confirmPassword: _confirmPassword, currentTheme, ...bodyRest } = body;\n let dataToSend = bodyRest;\n\n // The password fields are optional. If the user didn't touch them, don't send any password\n // to the API, because an empty string would throw a validation error\n if (dataToSend.password === '') {\n const {\n password: _password,\n currentPassword: _currentPassword,\n ...passwordRequestBodyRest\n } = dataToSend;\n dataToSend = passwordRequestBodyRest;\n }\n\n const res = await updateMe(dataToSend);\n\n if ('data' in res) {\n dispatch(setAppTheme(currentTheme));\n\n trackUsage('didChangeMode', { newMode: currentTheme });\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),\n });\n }\n\n if ('error' in res) {\n if (isBaseQueryError(res.error) && res.error.name === 'ValidationError') {\n setErrors(formatValidationErrors(res.error));\n } else if (isBaseQueryError(res.error)) {\n toggleNotification({\n type: 'danger',\n message: formatApiError(res.error),\n });\n } else {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n }\n }\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n const hasLockedRole = dataSSO?.isSSOLocked ?? false;\n const { email, firstname, lastname, username, preferedLanguage } = user ?? {};\n const initialData = {\n email: email ?? '',\n firstname: firstname ?? '',\n lastname: lastname ?? '',\n username: username ?? '',\n preferedLanguage,\n currentTheme,\n confirmPassword: '',\n password: '',\n };\n\n return (\n <>\n <Page.Main aria-busy={isSubmittingForm}>\n <Page.Title>\n {formatMessage({\n id: 'Settings.profile.form.section.head.title',\n defaultMessage: 'User profile',\n })}\n </Page.Title>\n <Form\n method=\"PUT\"\n onSubmit={handleSubmit}\n initialValues={initialData}\n validationSchema={PROFILE_VALIDTION_SCHEMA}\n >\n {({ isSubmitting, modified }) => (\n <>\n <Layouts.Header\n title={getDisplayName(user)}\n primaryAction={\n <Button\n startIcon={<Check />}\n loading={isSubmitting}\n type=\"submit\"\n disabled={!modified}\n fullWidth\n >\n {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}\n </Button>\n }\n />\n <Box paddingBottom={6}>\n <Layouts.Content>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={6}>\n <UserInfoSection />\n {!hasLockedRole && <PasswordSection />}\n <PreferencesSection localeNames={localeNames} />\n </Flex>\n </Layouts.Content>\n </Box>\n </>\n )}\n </Form>\n {isDesktop && process.env.NODE_ENV === 'development' && (\n <Box paddingBottom={6}>\n <Layouts.Content>\n <GuidedTourSection />\n </Layouts.Content>\n </Box>\n )}\n </Page.Main>\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * PasswordSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst PasswordSection = () => {\n const { formatMessage } = useIntl();\n\n return (\n <Panel>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.change-password',\n defaultMessage: 'Change password',\n })}\n </Typography>\n {[\n [\n {\n label: formatMessage({\n id: 'Auth.form.currentPassword.label',\n defaultMessage: 'Current Password',\n }),\n name: 'currentPassword',\n size: 6,\n type: 'password' as const,\n },\n ],\n [\n {\n autoComplete: 'new-password',\n label: formatMessage({\n id: 'global.password',\n defaultMessage: 'Password',\n }),\n name: 'password',\n size: 6,\n type: 'password' as const,\n },\n {\n autoComplete: 'new-password',\n label: formatMessage({\n id: 'Auth.form.confirmPassword.label',\n defaultMessage: 'Confirm Password',\n }),\n name: 'confirmPassword',\n size: 6,\n type: 'password' as const,\n },\n ],\n ].map((row, index) => (\n <Grid.Root key={index} gap={5}>\n {row.map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n ))}\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * PreferencesSection\n * -----------------------------------------------------------------------------------------------*/\n\ninterface PreferencesSectionProps {\n localeNames: Record<string, string>;\n}\n\nconst PreferencesSection = ({ localeNames }: PreferencesSectionProps) => {\n const { formatMessage } = useIntl();\n const themesToDisplay = useTypedSelector((state) => state.admin_app.theme.availableThemes);\n\n return (\n <Panel>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'Settings.profile.form.section.experience.title',\n defaultMessage: 'Experience',\n })}\n </Typography>\n <Typography>\n {formatMessage(\n {\n id: 'Settings.profile.form.section.experience.interfaceLanguageHelp',\n defaultMessage:\n 'Preference changes will apply only to you. More information is available {here}.',\n },\n {\n here: (\n <Box\n tag=\"a\"\n color=\"primary600\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n href=\"https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#locales\"\n >\n {formatMessage({\n id: 'Settings.profile.form.section.experience.here',\n defaultMessage: 'here',\n })}\n </Box>\n ),\n }\n )}\n </Typography>\n </Flex>\n <Grid.Root gap={5}>\n {[\n {\n hint: formatMessage({\n id: 'Settings.profile.form.section.experience.interfaceLanguage.hint',\n defaultMessage: 'This will only display your own interface in the chosen language.',\n }),\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.interfaceLanguage',\n defaultMessage: 'Interface language',\n }),\n name: 'preferedLanguage',\n options: Object.entries(localeNames).map(([value, label]) => ({\n label,\n value,\n })),\n placeholder: formatMessage({\n id: 'global.select',\n defaultMessage: 'Select',\n }),\n size: 6,\n type: 'enumeration' as const,\n },\n {\n hint: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.hint',\n defaultMessage: 'Displays your interface in the chosen mode.',\n }),\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.label',\n defaultMessage: 'Interface mode',\n }),\n name: 'currentTheme',\n options: [\n {\n label: formatMessage({\n id: 'Settings.profile.form.section.experience.mode.option-system-label',\n defaultMessage: 'Use system settings',\n }),\n value: 'system',\n },\n ...themesToDisplay.map((theme) => ({\n label: formatMessage(\n {\n id: 'Settings.profile.form.section.experience.mode.option-label',\n defaultMessage: '{name} mode',\n },\n {\n name: formatMessage({\n id: theme,\n defaultMessage: upperFirst(theme),\n }),\n }\n ),\n value: theme,\n })),\n ],\n placeholder: formatMessage({\n id: 'components.Select.placeholder',\n defaultMessage: 'Select',\n }),\n size: 6,\n type: 'enumeration' as const,\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * UserInfoSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst UserInfoSection = () => {\n const { formatMessage } = useIntl();\n\n return (\n <Panel>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.profile',\n defaultMessage: 'Profile',\n })}\n </Typography>\n <Grid.Root gap={5}>\n {[\n {\n label: formatMessage({\n id: 'Auth.form.firstname.label',\n defaultMessage: 'First name',\n }),\n name: 'firstname',\n required: true,\n size: 6,\n type: 'string' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.lastname.label',\n defaultMessage: 'Last name',\n }),\n name: 'lastname',\n size: 6,\n type: 'string' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.email.label',\n defaultMessage: 'Email',\n }),\n name: 'email',\n required: true,\n size: 6,\n type: 'email' as const,\n },\n {\n label: formatMessage({\n id: 'Auth.form.username.label',\n defaultMessage: 'Username',\n }),\n name: 'username',\n size: 6,\n type: 'string' as const,\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n xs={12}\n m={6}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Panel>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourSection\n * -----------------------------------------------------------------------------------------------*/\n\nconst GuidedTourSection = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const dispatch = useGuidedTour('ProfilePage', (s) => s.dispatch);\n\n const onClickReset = () => {\n dispatch({ type: 'reset_all_tours' });\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: 'tours.profile.notification.success.reset',\n defaultMessage: 'Guided tour reset',\n }),\n });\n };\n\n return (\n <Panel alignItems=\"start\">\n <Flex direction=\"column\" alignItems=\"start\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'tours.profile.title',\n defaultMessage: 'Guided tour',\n })}\n </Typography>\n <Typography variant=\"pi\">\n {formatMessage({\n id: 'tours.profile.description',\n defaultMessage: 'You can reset the guided tour at any time.',\n })}\n </Typography>\n </Flex>\n <Button variant=\"tertiary\" onClick={onClickReset}>\n {formatMessage({\n id: 'tours.profile.reset',\n defaultMessage: 'Reset guided tour',\n })}\n </Button>\n </Panel>\n );\n};\n\nexport { ProfilePage };\n"],"names":["PROFILE_VALIDTION_SCHEMA","yup","object","shape","COMMON_USER_SCHEMA","currentPassword","string","when","password","confirmPassword","passSchema","required","id","translatedErrors","defaultMessage","nullable","preferedLanguage","Panel","children","flexProps","_jsx","Box","background","hasRadius","shadow","paddingTop","paddingBottom","paddingLeft","paddingRight","Flex","direction","alignItems","gap","ProfilePage","isDesktop","useIsDesktop","localeNames","useTypedSelector","state","admin_app","language","formatMessage","useIntl","trackUsage","useTracking","toggleNotification","useNotification","notifyStatus","useNotifyAT","currentTheme","theme","dispatch","useTypedDispatch","_unstableFormatValidationErrors","formatValidationErrors","_unstableFormatAPIError","formatApiError","useAPIErrorHandler","user","useAuth","React","useEffect","type","message","updateMe","isLoading","isSubmittingForm","useUpdateMeMutation","data","dataSSO","error","useIsSSOLockedQuery","undefined","skip","window","strapi","isEE","features","isEnabled","handleSubmit","body","setErrors","_confirmPassword","bodyRest","dataToSend","_password","_currentPassword","passwordRequestBodyRest","res","setAppTheme","newMode","isBaseQueryError","name","Page","Loading","hasLockedRole","isSSOLocked","email","firstname","lastname","username","initialData","_Fragment","_jsxs","Main","aria-busy","Title","Form","method","onSubmit","initialValues","validationSchema","isSubmitting","modified","Layouts","Header","title","getDisplayName","primaryAction","Button","startIcon","Check","loading","disabled","fullWidth","Content","UserInfoSection","PasswordSection","PreferencesSection","process","env","NODE_ENV","GuidedTourSection","Typography","variant","tag","label","size","autoComplete","map","row","index","Grid","Root","field","Item","xs","m","col","InputRenderer","themesToDisplay","availableThemes","here","color","target","rel","href","hint","options","Object","entries","value","placeholder","upperFirst","useGuidedTour","s","onClickReset","onClick"],"mappings":"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"}
@@ -79,7 +79,7 @@ const ProfilePage = ()=>{
79
79
  type: 'danger',
80
80
  message: formatMessage({
81
81
  id: 'notification.error',
82
- defaultMessage: 'An error occured'
82
+ defaultMessage: 'An error occurred'
83
83
  })
84
84
  });
85
85
  }
@@ -143,7 +143,7 @@ const ProfilePage = ()=>{
143
143
  type: 'danger',
144
144
  message: formatMessage({
145
145
  id: 'notification.error',
146
- defaultMessage: 'An error occured'
146
+ defaultMessage: 'An error occurred'
147
147
  })
148
148
  });
149
149
  }