udp-react-enterprise-component-library 25.18.1-beta.46 → 25.18.1-beta.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AuthProvider-BM2MdXcx.js → AuthProvider-qWjJiYSg.js} +2 -2
- package/dist/{AuthProvider-BM2MdXcx.js.map → AuthProvider-qWjJiYSg.js.map} +1 -1
- package/dist/{Shell-N3oRzrDU.js → Shell-DFCf3oVf.js} +4 -4
- package/dist/Shell-DFCf3oVf.js.map +1 -0
- package/dist/{TenantProvider-YjlC8AtM.js → TenantProvider-C-3eqCA3.js} +3 -2
- package/dist/{TenantProvider-YjlC8AtM.js.map → TenantProvider-C-3eqCA3.js.map} +1 -1
- package/dist/{UdpAppProvider-C0VlxSna.js → UdpAppProvider-NHkopZ-S.js} +5 -4
- package/dist/{UdpAppProvider-C0VlxSna.js.map → UdpAppProvider-NHkopZ-S.js.map} +1 -1
- package/dist/{UdpFormsSubmissionGrid-C5CDtEVR.js → UdpFormsSubmissionGrid-B2V--6Rl.js} +3 -2
- package/dist/{UdpFormsSubmissionGrid-C5CDtEVR.js.map → UdpFormsSubmissionGrid-B2V--6Rl.js.map} +1 -1
- package/dist/{auth-DUOUsM9U.js → auth-DX4sNV3x.js} +2 -2
- package/dist/{auth-DUOUsM9U.js.map → auth-DX4sNV3x.js.map} +1 -1
- package/dist/index.js +7 -7
- package/dist/{profile-C0_f9put.js → profile-CXlla7mZ.js} +3 -3
- package/dist/{profile-C0_f9put.js.map → profile-CXlla7mZ.js.map} +1 -1
- package/dist/providers/index.js +1 -1
- package/dist/shell/index.js +1 -1
- package/dist/shell/ui/profile/index.js +1 -1
- package/dist/types/src/providers/UdpAppProvider.d.ts.map +1 -1
- package/dist/types/src/shell/Shell.d.ts.map +1 -1
- package/dist/types/src/udp/pages/UdpFormsSubmissionGrid/UdpFormsSubmissionGrid.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/udp/pages/UdpFormsSubmissionGrid/index.js +1 -1
- package/dist/utilities/auth/index.js +3 -3
- package/dist/utilities/tenant/index.js +1 -1
- package/export-map.json +1 -1
- package/package.json +1 -1
- package/dist/Shell-N3oRzrDU.js.map +0 -1
|
@@ -4,7 +4,7 @@ import { i as storeTenant, n as getStoredTenant } from "./UnitySessionStorage-CU
|
|
|
4
4
|
import { n as UserContext, r as UserDispatchContext } from "./useUser-wpHGo6jU.js";
|
|
5
5
|
import { w as RoleIdEnums } from "./unitySystemEnums-e5F9Jr7m.js";
|
|
6
6
|
import { t as useAxiosGet } from "./useAxiosGet-CYnt6Hd0.js";
|
|
7
|
-
import { t as TenantProvider } from "./TenantProvider-
|
|
7
|
+
import { t as TenantProvider } from "./TenantProvider-C-3eqCA3.js";
|
|
8
8
|
import { t as LoadingIndicator } from "./LoadingIndicator-BBIwYBt5.js";
|
|
9
9
|
import { t as CustomNavigationClient_default } from "./CustomNavigationClient-CwXe-ZC7.js";
|
|
10
10
|
import { t as PasswordResetRedirect } from "./PasswordResetRedirect-DDOsXDPA.js";
|
|
@@ -216,4 +216,4 @@ const AuthProvider = ({ children, doNotWaitForTenant = true }) => {
|
|
|
216
216
|
|
|
217
217
|
//#endregion
|
|
218
218
|
export { createUser as n, AuthProvider as t };
|
|
219
|
-
//# sourceMappingURL=AuthProvider-
|
|
219
|
+
//# sourceMappingURL=AuthProvider-qWjJiYSg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider-BM2MdXcx.js","names":["tenantId: any","userTenantPermissions: any","userTenantRoles: any","userTenantProducts: any","roleIds: any","useLocation","CustomNavigationClient","UserProvider"],"sources":["../src/utilities/auth/user.ts","../src/utilities/auth/UserProvider.jsx","../src/utilities/auth/AuthProvider.jsx"],"sourcesContent":["import { ConfigService } from '../../configService';\nimport { RoleIdEnums } from '../../enums/unitySystemEnums';\nimport { getStoredTenant } from '../storage/UnitySessionStorage';\n\nexport interface User {\n name: string | undefined;\n firstName: string | undefined;\n familyName: string | undefined;\n jobTitle: string | undefined;\n email: string | undefined;\n mobile: string | undefined;\n phone: string | undefined;\n id: string | undefined;\n location: string | undefined;\n aadId: string | undefined;\n accessToken: string | undefined;\n defaultTenantId: string | undefined;\n currentTenantId: string | undefined;\n tenantIds: Array<string> | undefined;\n roleIds: Array<string> | undefined;\n products: Array<object> | undefined;\n permissions: Array<object> | undefined;\n can: any | undefined;\n statusCode: number | undefined;\n unityId: string | undefined;\n additionalProperties: any | undefined;\n roleNames: Array<string> | undefined;\n isUnitySystemAdmin: boolean | undefined;\n}\n\n/**\n * Create a \"unified\" user object from MSAL account info and Univerus user data (in the future)\n */\nexport function createUser(userInfo: any): User {\n const tenantId: any =\n getStoredTenant() ||\n (userInfo?.defaultTenantId ??\n (userInfo?.tenantIds ? userInfo?.tenantIds[0] : ''));\n let userTenantPermissions: any = [];\n let userTenantRoles: any = [];\n let userTenantProducts: any = [];\n const currentUserTenantProperties = userInfo?.userTenantPropertiesView?.find(\n (propertyView: any) => propertyView?.tenantId === tenantId\n );\n userTenantPermissions = currentUserTenantProperties\n ? currentUserTenantProperties.permissions\n : [];\n userTenantRoles = currentUserTenantProperties\n ? currentUserTenantProperties.securityRoles\n : [];\n userTenantProducts = currentUserTenantProperties\n ? currentUserTenantProperties.products\n : [];\n\n let roleIds: any = userTenantRoles.map((role: any) => role.roleId) ?? [];\n\n return {\n name: userInfo?.displayName ?? '',\n firstName: userInfo?.givenName ?? '',\n familyName: userInfo?.surname ?? '',\n jobTitle: userInfo?.jobTitle ?? '',\n email: userInfo?.email ?? '',\n mobile: userInfo?.mobilePhone ?? '',\n phone: userInfo?.officePhone ?? '',\n id: userInfo?.userId ?? '',\n location: userInfo?.location ?? '',\n aadId: userInfo?.externalUUID ?? '',\n accessToken: userInfo?.accessToken ?? '',\n tenantIds: userInfo?.tenantIds ?? [],\n defaultTenantId: userInfo?.defaultTenantId ?? '',\n currentTenantId: ConfigService.config.UNITY_TENANT_ID\n ? ConfigService.config.UNITY_TENANT_ID\n : tenantId,\n roleIds: roleIds,\n products: userTenantProducts,\n permissions: userTenantPermissions,\n can:\n userTenantPermissions.reduce((can: any, permission: any) => {\n if (permission.value === 'false') {\n can[permission.name] = false;\n } else if (permission.value === 'true') {\n can[permission.name] = true;\n } else {\n can[permission.name] = permission.value;\n }\n return can;\n }, {}) ?? {},\n statusCode: userInfo?.statusCode ?? 200,\n unityId: userInfo?.userId ?? '',\n additionalProperties: userInfo?.additionalProperties ?? undefined,\n roleNames: userTenantRoles.map((role) => role.name) ?? [],\n isUnitySystemAdmin: !!roleIds.find(\n (id: string) => id === RoleIdEnums.Unity_System_Administrator\n )\n };\n}\n","import React, { useReducer, useEffect } from 'react';\nimport { UserContext, UserDispatchContext } from './internal';\nimport { createUser } from './user';\nimport { LoadingIndicator } from '../../UI/loading/LoadingIndicator';\nimport { useAccount } from '@azure/msal-react';\nimport { storeTenant, getStoredTenant } from '../storage/UnitySessionStorage';\nimport { useAxiosGet } from '../useAxiosGet';\nimport { TenantProvider } from '../tenant/TenantProvider';\nimport { acquireAccessToken } from './authActions';\nimport { ConfigService } from '../../configService';\nconst emptyUser = {\n name: '',\n firstName: '',\n familyName: '',\n jobTitle: '',\n email: '',\n mobile: '',\n phone: '',\n id: '',\n location: '',\n aadId: '',\n accessToken: '',\n defaultTenantId: '',\n currentTenantId: '',\n tenantIds: [],\n roleIds: [],\n products: [],\n permissions: [],\n can: {},\n statusCode: undefined,\n unityId: undefined,\n additionalProperties: undefined,\n roleNames: [],\n isUnitySystemAdmin: undefined\n};\n\nconst UserProvider = (props) => {\n const {\n children,\n setSessionExpiredModalOpen,\n setNonExistingUserModalOpen,\n setErrorMessage,\n isWhiteListed,\n doNotWaitForTenant = false,\n unityTenantId\n } = props;\n const activeAccount = useAccount();\n const idTokenClaims = activeAccount?.idTokenClaims;\n const sub = idTokenClaims?.sub;\n\n //Get user info\n const [{ data: userInfo, error: userError }] = useAxiosGet(\n ConfigService.securityV1ApiUrl,\n `users/unityuser`,\n {},\n false,\n false\n );\n\n useEffect(() => {\n if (userError) {\n setErrorMessage('Unable to get user details. Please try again.');\n setNonExistingUserModalOpen(true);\n }\n }, [setErrorMessage, setNonExistingUserModalOpen, userError]);\n\n // const [{ data: aadUserInfo }] = useAxiosGet(\n // ConfigService.securityV1ApiUrl,\n // `users/${sub}`,\n // {},\n // false,\n // false\n // );\n\n const [userState, dispatch] = useReducer((state, action) => {\n switch (action.type) {\n case 'SET_USER':\n state = {\n ...state,\n user: action.user\n };\n break;\n case 'CHANGE_TENANT':\n let userTenantPermissions = [];\n let userTenantRoles = [];\n let userTenantProducts = [];\n if (state.tenantIds) {\n const currentUserTenantProperties =\n userInfo.userTenantPropertiesView?.find(\n (propertyView) => propertyView?.tenantId === action.tenantId\n );\n userTenantPermissions = currentUserTenantProperties\n ? currentUserTenantProperties.permissions\n : [];\n userTenantRoles = currentUserTenantProperties\n ? currentUserTenantProperties.securityRoles\n : [];\n userTenantProducts = currentUserTenantProperties\n ? currentUserTenantProperties.products\n : [];\n }\n state = {\n user: {\n ...state,\n currentTenantId: action.tenantId,\n products: userTenantProducts,\n permissions: userTenantPermissions,\n roleIds: userTenantRoles.map((role) => role.roleId) ?? [],\n roleNames: userTenantRoles.map((role) => role.name) ?? []\n }\n };\n break;\n default:\n throw new Error(`Unknown action type ${action.type}`);\n }\n\n return state.user;\n }, emptyUser);\n\n useEffect(() => {\n if (userInfo?.userId) {\n const user = createUser({\n ...userInfo,\n displayName: idTokenClaims?.name,\n givenName: idTokenClaims?.given_name ?? idTokenClaims?.name,\n accessToken: activeAccount.idToken ?? '',\n surname: idTokenClaims?.family_name\n });\n sessionStorage.setItem('user-id', userInfo?.userId);\n\n dispatch({ type: 'SET_USER', user });\n }\n }, [\n userInfo,\n idTokenClaims?.name,\n idTokenClaims?.given_name,\n idTokenClaims?.family_name,\n activeAccount.idToken\n ]);\n\n useEffect(() => {\n if (userInfo?.defaultTenantId) {\n if (!getStoredTenant()) {\n if (unityTenantId) {\n storeTenant(unityTenantId);\n } else {\n storeTenant(userInfo.defaultTenantId);\n }\n }\n }\n }, [userInfo]);\n\n return (\n <div>\n {!doNotWaitForTenant &&\n !userState?.currentTenantId &&\n !isWhiteListed ? (\n <LoadingIndicator />\n ) : (\n <UserContext.Provider value={userState}>\n <UserDispatchContext.Provider value={dispatch}>\n <TenantProvider>{children}</TenantProvider>\n </UserDispatchContext.Provider>\n </UserContext.Provider>\n )}\n </div>\n );\n};\n\nexport default UserProvider;\n","import React, { useEffect, useMemo, useState } from 'react';\nimport {\n initSignInAuthProvider,\n getSignInAuthProvider,\n getLoginRequest,\n} from './signInAuthProvider';\nimport { LoadingIndicator } from '../../UI/loading/LoadingIndicator';\nimport { whitelistedPaths } from './whitelistedPaths';\nimport { InteractionType } from '@azure/msal-browser';\nimport {\n MsalProvider,\n MsalAuthenticationTemplate,\n} from '@azure/msal-react';\nimport { useHistory } from 'react-router-dom';\nimport CustomNavigationClient from '../CustomNavigationClient';\nimport { useLocation } from 'react-use';\nimport UserProvider from './UserProvider';\nimport { PasswordResetRedirect } from '../../routes/components/PasswordResetRedirect';\n\nexport const AuthProvider = ({ children, doNotWaitForTenant = true }) => {\n const [msalInstance, setMsalInstance] = useState(null);\n const [loginRequestInstance, setLoginRequestInstance] = useState(null);\n const [isInitialized, setIsInitialized] = useState(false);\n\n const history = useHistory();\n const location = useLocation();\n\n useEffect(() => {\n const initialize = async () => {\n try {\n await initSignInAuthProvider();\n const authProvider = getSignInAuthProvider();\n const navigationClient = new CustomNavigationClient(history);\n authProvider.setNavigationClient(navigationClient);\n setMsalInstance(authProvider);\n setLoginRequestInstance(getLoginRequest());\n setIsInitialized(true);\n } catch (error) {\n console.error('Failed to initialize AuthProvider:', error);\n // Handle initialization error, maybe show an error message\n }\n };\n initialize();\n }, [history]);\n\n const [sessionExpiredModalOpen, setSessionExpiredModalOpen] = useState(false);\n const [nonExistingUserModalOpen, setNonExistingUserModalOpen] =\n useState(false);\n const [errorMessage, setErrorMessage] = useState('');\n\n const isWhiteListed = useMemo(() => {\n const url = location.pathname;\n return whitelistedPaths.includes(url ?? '');\n }, [location]);\n\n if (!isInitialized) {\n return <LoadingIndicator />;\n }\n\n if (isWhiteListed) {\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\n }\n\n return (\n <MsalProvider instance={msalInstance}>\n <MsalAuthenticationTemplate\n interactionType={InteractionType.Redirect}\n authenticationRequest={loginRequestInstance}\n loadingComponent={() => <LoadingIndicator />}\n errorComponent={(props) => <PasswordResetRedirect {...props} />}\n >\n <UserProvider\n sessionExpiredModalOpen={sessionExpiredModalOpen}\n setSessionExpiredModalOpen={setSessionExpiredModalOpen}\n setNonExistingUserModalOpen={setNonExistingUserModalOpen}\n setErrorMessage={setErrorMessage}\n isWhiteListed={isWhiteListed}\n doNotWaitForTenant={doNotWaitForTenant}\n >\n {children}\n </UserProvider>\n </MsalAuthenticationTemplate>\n </MsalProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AuthProvider-qWjJiYSg.js","names":["tenantId: any","userTenantPermissions: any","userTenantRoles: any","userTenantProducts: any","roleIds: any","useLocation","CustomNavigationClient","UserProvider"],"sources":["../src/utilities/auth/user.ts","../src/utilities/auth/UserProvider.jsx","../src/utilities/auth/AuthProvider.jsx"],"sourcesContent":["import { ConfigService } from '../../configService';\nimport { RoleIdEnums } from '../../enums/unitySystemEnums';\nimport { getStoredTenant } from '../storage/UnitySessionStorage';\n\nexport interface User {\n name: string | undefined;\n firstName: string | undefined;\n familyName: string | undefined;\n jobTitle: string | undefined;\n email: string | undefined;\n mobile: string | undefined;\n phone: string | undefined;\n id: string | undefined;\n location: string | undefined;\n aadId: string | undefined;\n accessToken: string | undefined;\n defaultTenantId: string | undefined;\n currentTenantId: string | undefined;\n tenantIds: Array<string> | undefined;\n roleIds: Array<string> | undefined;\n products: Array<object> | undefined;\n permissions: Array<object> | undefined;\n can: any | undefined;\n statusCode: number | undefined;\n unityId: string | undefined;\n additionalProperties: any | undefined;\n roleNames: Array<string> | undefined;\n isUnitySystemAdmin: boolean | undefined;\n}\n\n/**\n * Create a \"unified\" user object from MSAL account info and Univerus user data (in the future)\n */\nexport function createUser(userInfo: any): User {\n const tenantId: any =\n getStoredTenant() ||\n (userInfo?.defaultTenantId ??\n (userInfo?.tenantIds ? userInfo?.tenantIds[0] : ''));\n let userTenantPermissions: any = [];\n let userTenantRoles: any = [];\n let userTenantProducts: any = [];\n const currentUserTenantProperties = userInfo?.userTenantPropertiesView?.find(\n (propertyView: any) => propertyView?.tenantId === tenantId\n );\n userTenantPermissions = currentUserTenantProperties\n ? currentUserTenantProperties.permissions\n : [];\n userTenantRoles = currentUserTenantProperties\n ? currentUserTenantProperties.securityRoles\n : [];\n userTenantProducts = currentUserTenantProperties\n ? currentUserTenantProperties.products\n : [];\n\n let roleIds: any = userTenantRoles.map((role: any) => role.roleId) ?? [];\n\n return {\n name: userInfo?.displayName ?? '',\n firstName: userInfo?.givenName ?? '',\n familyName: userInfo?.surname ?? '',\n jobTitle: userInfo?.jobTitle ?? '',\n email: userInfo?.email ?? '',\n mobile: userInfo?.mobilePhone ?? '',\n phone: userInfo?.officePhone ?? '',\n id: userInfo?.userId ?? '',\n location: userInfo?.location ?? '',\n aadId: userInfo?.externalUUID ?? '',\n accessToken: userInfo?.accessToken ?? '',\n tenantIds: userInfo?.tenantIds ?? [],\n defaultTenantId: userInfo?.defaultTenantId ?? '',\n currentTenantId: ConfigService.config.UNITY_TENANT_ID\n ? ConfigService.config.UNITY_TENANT_ID\n : tenantId,\n roleIds: roleIds,\n products: userTenantProducts,\n permissions: userTenantPermissions,\n can:\n userTenantPermissions.reduce((can: any, permission: any) => {\n if (permission.value === 'false') {\n can[permission.name] = false;\n } else if (permission.value === 'true') {\n can[permission.name] = true;\n } else {\n can[permission.name] = permission.value;\n }\n return can;\n }, {}) ?? {},\n statusCode: userInfo?.statusCode ?? 200,\n unityId: userInfo?.userId ?? '',\n additionalProperties: userInfo?.additionalProperties ?? undefined,\n roleNames: userTenantRoles.map((role) => role.name) ?? [],\n isUnitySystemAdmin: !!roleIds.find(\n (id: string) => id === RoleIdEnums.Unity_System_Administrator\n )\n };\n}\n","import React, { useReducer, useEffect } from 'react';\nimport { UserContext, UserDispatchContext } from './internal';\nimport { createUser } from './user';\nimport { LoadingIndicator } from '../../UI/loading/LoadingIndicator';\nimport { useAccount } from '@azure/msal-react';\nimport { storeTenant, getStoredTenant } from '../storage/UnitySessionStorage';\nimport { useAxiosGet } from '../useAxiosGet';\nimport { TenantProvider } from '../tenant/TenantProvider';\nimport { acquireAccessToken } from './authActions';\nimport { ConfigService } from '../../configService';\nconst emptyUser = {\n name: '',\n firstName: '',\n familyName: '',\n jobTitle: '',\n email: '',\n mobile: '',\n phone: '',\n id: '',\n location: '',\n aadId: '',\n accessToken: '',\n defaultTenantId: '',\n currentTenantId: '',\n tenantIds: [],\n roleIds: [],\n products: [],\n permissions: [],\n can: {},\n statusCode: undefined,\n unityId: undefined,\n additionalProperties: undefined,\n roleNames: [],\n isUnitySystemAdmin: undefined\n};\n\nconst UserProvider = (props) => {\n const {\n children,\n setSessionExpiredModalOpen,\n setNonExistingUserModalOpen,\n setErrorMessage,\n isWhiteListed,\n doNotWaitForTenant = false,\n unityTenantId\n } = props;\n const activeAccount = useAccount();\n const idTokenClaims = activeAccount?.idTokenClaims;\n const sub = idTokenClaims?.sub;\n\n //Get user info\n const [{ data: userInfo, error: userError }] = useAxiosGet(\n ConfigService.securityV1ApiUrl,\n `users/unityuser`,\n {},\n false,\n false\n );\n\n useEffect(() => {\n if (userError) {\n setErrorMessage('Unable to get user details. Please try again.');\n setNonExistingUserModalOpen(true);\n }\n }, [setErrorMessage, setNonExistingUserModalOpen, userError]);\n\n // const [{ data: aadUserInfo }] = useAxiosGet(\n // ConfigService.securityV1ApiUrl,\n // `users/${sub}`,\n // {},\n // false,\n // false\n // );\n\n const [userState, dispatch] = useReducer((state, action) => {\n switch (action.type) {\n case 'SET_USER':\n state = {\n ...state,\n user: action.user\n };\n break;\n case 'CHANGE_TENANT':\n let userTenantPermissions = [];\n let userTenantRoles = [];\n let userTenantProducts = [];\n if (state.tenantIds) {\n const currentUserTenantProperties =\n userInfo.userTenantPropertiesView?.find(\n (propertyView) => propertyView?.tenantId === action.tenantId\n );\n userTenantPermissions = currentUserTenantProperties\n ? currentUserTenantProperties.permissions\n : [];\n userTenantRoles = currentUserTenantProperties\n ? currentUserTenantProperties.securityRoles\n : [];\n userTenantProducts = currentUserTenantProperties\n ? currentUserTenantProperties.products\n : [];\n }\n state = {\n user: {\n ...state,\n currentTenantId: action.tenantId,\n products: userTenantProducts,\n permissions: userTenantPermissions,\n roleIds: userTenantRoles.map((role) => role.roleId) ?? [],\n roleNames: userTenantRoles.map((role) => role.name) ?? []\n }\n };\n break;\n default:\n throw new Error(`Unknown action type ${action.type}`);\n }\n\n return state.user;\n }, emptyUser);\n\n useEffect(() => {\n if (userInfo?.userId) {\n const user = createUser({\n ...userInfo,\n displayName: idTokenClaims?.name,\n givenName: idTokenClaims?.given_name ?? idTokenClaims?.name,\n accessToken: activeAccount.idToken ?? '',\n surname: idTokenClaims?.family_name\n });\n sessionStorage.setItem('user-id', userInfo?.userId);\n\n dispatch({ type: 'SET_USER', user });\n }\n }, [\n userInfo,\n idTokenClaims?.name,\n idTokenClaims?.given_name,\n idTokenClaims?.family_name,\n activeAccount.idToken\n ]);\n\n useEffect(() => {\n if (userInfo?.defaultTenantId) {\n if (!getStoredTenant()) {\n if (unityTenantId) {\n storeTenant(unityTenantId);\n } else {\n storeTenant(userInfo.defaultTenantId);\n }\n }\n }\n }, [userInfo]);\n\n return (\n <div>\n {!doNotWaitForTenant &&\n !userState?.currentTenantId &&\n !isWhiteListed ? (\n <LoadingIndicator />\n ) : (\n <UserContext.Provider value={userState}>\n <UserDispatchContext.Provider value={dispatch}>\n <TenantProvider>{children}</TenantProvider>\n </UserDispatchContext.Provider>\n </UserContext.Provider>\n )}\n </div>\n );\n};\n\nexport default UserProvider;\n","import React, { useEffect, useMemo, useState } from 'react';\nimport {\n initSignInAuthProvider,\n getSignInAuthProvider,\n getLoginRequest,\n} from './signInAuthProvider';\nimport { LoadingIndicator } from '../../UI/loading/LoadingIndicator';\nimport { whitelistedPaths } from './whitelistedPaths';\nimport { InteractionType } from '@azure/msal-browser';\nimport {\n MsalProvider,\n MsalAuthenticationTemplate,\n} from '@azure/msal-react';\nimport { useHistory } from 'react-router-dom';\nimport CustomNavigationClient from '../CustomNavigationClient';\nimport { useLocation } from 'react-use';\nimport UserProvider from './UserProvider';\nimport { PasswordResetRedirect } from '../../routes/components/PasswordResetRedirect';\n\nexport const AuthProvider = ({ children, doNotWaitForTenant = true }) => {\n const [msalInstance, setMsalInstance] = useState(null);\n const [loginRequestInstance, setLoginRequestInstance] = useState(null);\n const [isInitialized, setIsInitialized] = useState(false);\n\n const history = useHistory();\n const location = useLocation();\n\n useEffect(() => {\n const initialize = async () => {\n try {\n await initSignInAuthProvider();\n const authProvider = getSignInAuthProvider();\n const navigationClient = new CustomNavigationClient(history);\n authProvider.setNavigationClient(navigationClient);\n setMsalInstance(authProvider);\n setLoginRequestInstance(getLoginRequest());\n setIsInitialized(true);\n } catch (error) {\n console.error('Failed to initialize AuthProvider:', error);\n // Handle initialization error, maybe show an error message\n }\n };\n initialize();\n }, [history]);\n\n const [sessionExpiredModalOpen, setSessionExpiredModalOpen] = useState(false);\n const [nonExistingUserModalOpen, setNonExistingUserModalOpen] =\n useState(false);\n const [errorMessage, setErrorMessage] = useState('');\n\n const isWhiteListed = useMemo(() => {\n const url = location.pathname;\n return whitelistedPaths.includes(url ?? '');\n }, [location]);\n\n if (!isInitialized) {\n return <LoadingIndicator />;\n }\n\n if (isWhiteListed) {\n return <MsalProvider instance={msalInstance}>{children}</MsalProvider>;\n }\n\n return (\n <MsalProvider instance={msalInstance}>\n <MsalAuthenticationTemplate\n interactionType={InteractionType.Redirect}\n authenticationRequest={loginRequestInstance}\n loadingComponent={() => <LoadingIndicator />}\n errorComponent={(props) => <PasswordResetRedirect {...props} />}\n >\n <UserProvider\n sessionExpiredModalOpen={sessionExpiredModalOpen}\n setSessionExpiredModalOpen={setSessionExpiredModalOpen}\n setNonExistingUserModalOpen={setNonExistingUserModalOpen}\n setErrorMessage={setErrorMessage}\n isWhiteListed={isWhiteListed}\n doNotWaitForTenant={doNotWaitForTenant}\n >\n {children}\n </UserProvider>\n </MsalAuthenticationTemplate>\n </MsalProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ import { t as UtilityBar } from "./utilityDisplay-C6c73Efx.js";
|
|
|
14
14
|
import { t as FUIAppSwitcher_default } from "./FUIAppSwitcher-LKwANZkK.js";
|
|
15
15
|
import { t as ActionProvider } from "./ActionProvider-C_rohJIr.js";
|
|
16
16
|
import { t as ChatBotProvider } from "./ChatBotProvider-CmrKYl2I.js";
|
|
17
|
-
import { t as UserProfileMenuWrapper } from "./profile-
|
|
17
|
+
import { t as UserProfileMenuWrapper } from "./profile-CXlla7mZ.js";
|
|
18
18
|
import { t as LoadingIndicator } from "./LoadingIndicator-BBIwYBt5.js";
|
|
19
19
|
import React, { Suspense, useCallback, useEffect, useMemo, useState } from "react";
|
|
20
20
|
import { Drawer, makeStyles, useMediaQuery, useTheme } from "@material-ui/core";
|
|
@@ -156,7 +156,7 @@ const Shell = (props) => {
|
|
|
156
156
|
let enrichedChildren = children;
|
|
157
157
|
if (useNewRoutes) enrichedChildren = /* @__PURE__ */ React.createElement(Suspense, { fallback: /* @__PURE__ */ React.createElement(PageLoading, null) }, /* @__PURE__ */ React.createElement(Switch$1, null, children, /* @__PURE__ */ React.createElement(UdpRoutes, null)));
|
|
158
158
|
if (hideLayout) return /* @__PURE__ */ React.createElement("div", null, enrichedChildren);
|
|
159
|
-
return /* @__PURE__ */ React.createElement(
|
|
159
|
+
return /* @__PURE__ */ React.createElement(ChatBotProvider, null, /* @__PURE__ */ React.createElement(ActionProvider, null, /* @__PURE__ */ React.createElement("div", { className: classes.root }, !shellHidden && /* @__PURE__ */ React.createElement(SiteHeader_default, {
|
|
160
160
|
className: classes.header,
|
|
161
161
|
siteName,
|
|
162
162
|
appContent,
|
|
@@ -238,7 +238,7 @@ const Shell = (props) => {
|
|
|
238
238
|
unityUrl,
|
|
239
239
|
user,
|
|
240
240
|
header: appSwitcherHeader
|
|
241
|
-
})))))
|
|
241
|
+
})))));
|
|
242
242
|
};
|
|
243
243
|
Shell.propTypes = {
|
|
244
244
|
switcherData: PropTypes.array,
|
|
@@ -286,4 +286,4 @@ Shell.propTypes = {
|
|
|
286
286
|
|
|
287
287
|
//#endregion
|
|
288
288
|
export { Shell as t };
|
|
289
|
-
//# sourceMappingURL=Shell-
|
|
289
|
+
//# sourceMappingURL=Shell-DFCf3oVf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Shell-DFCf3oVf.js","names":["menus","Switch","SiteHeader","NavigationSidebar","FUIAppSwitcher"],"sources":["../src/shell/Shell.jsx"],"sourcesContent":["import React, { useState, useEffect, useMemo, useCallback, Suspense } from 'react';\nimport { makeStyles, Drawer, useMediaQuery, useTheme } from '@material-ui/core';\nimport NavigationSidebar from './ui/NavigationSidebar';\nimport SiteHeader from './ui/SiteHeader';\nimport { UtilityBar } from '../UI/utilityDisplay/UtilityBar';\nimport { useTranslation } from 'react-i18next';\nimport FUIAppSwitcher from './ui/appSwitcher/FUIAppSwitcher';\nimport { getMenuItemsRecursively } from '../utilities/menus/menuUtilities';\nimport clsx from 'clsx';\nimport { UtilitySideBar } from '../UI/utilityDisplay/UtilitySideBar';\nimport PropTypes from 'prop-types';\nimport { useUser } from '../utilities/auth/useUser';\nimport { ActionProvider } from '../utilities/provider/ActionProvider';\nimport { PageActionWrapper } from '../actions/PageActionWrapper';\nimport { useInquiryStore } from '../stores/inquiryStore';\nimport {\n useSetInitialShellVisibility,\n useShellStore\n} from '../stores/shellStore';\n\nimport { useBuildEnvironment, APP_RIBBON_SPACE } from './ui/useBuildEnvironment';\nimport { ChatBotProvider } from '../utilities/chatBot/ChatBotProvider';\nimport { UserProfileMenuWrapper } from '../shell/ui/profile';\nimport { useMenuContext } from '../utilities/menus/MenuProvider';\nimport { LoadingIndicator } from '../UI/loading/LoadingIndicator';\nimport { useTenant } from '../utilities/tenant';\nimport { BrowserRouter, Switch} from 'react-router-dom';\n//import { usePreloadPages } from '../hooks/usePreloadPages';\nimport { PageLoading } from '../UI';\nimport { UdpRoutes } from '../routes';\n// load the page container module so its loaded when we need it\nvoid import('../page/PageContainer');\nconst MenuTypeEnums = {\n Left_Menu: 1,\n Application_Menu: 2,\n Builders_Menu: 3,\n Favorites_Menu: 4\n};\n\nconst useStyles = makeStyles(\n (theme) => ({\n '@global': {\n html: {\n minHeight: '100%'\n },\n 'html, body, #root': {\n display: 'flex',\n flexDirection: 'column'\n },\n 'body, #root': {\n flex: 1\n }\n },\n root: {\n flex: 1,\n minHeight: '100vh',\n display: 'grid',\n gridTemplateAreas: ['sidebar header', 'sidebar content']\n .map((line) => `\"${line}\"`)\n .join(' '),\n gridTemplateColumns: 'auto 1fr',\n gridTemplateRows: 'auto 1fr'\n },\n header: {\n gridArea: 'header'\n },\n sidebar: {\n gridArea: 'sidebar'\n },\n content: {\n gridArea: 'content',\n display: 'flex',\n flexDirection: 'column',\n position: 'relative',\n zIndex: 1,\n height: ({ appRibbonSpace }) => `calc(100vh - ${56 + appRibbonSpace}px)`,\n overflowY: 'auto'\n },\n paper: {\n width: '100%',\n [theme.breakpoints.up('sm')]: {\n width: (props) => props.drawerWidth || 520\n }\n }\n }),\n { name: 'Layout' }\n);\n\n/**\n * Core site layout common to all pages\n */\nexport const Shell = (props) => {\n\n const buildEnv = useBuildEnvironment();\n const classes = useStyles({\n ...props,\n ribbonSpace: buildEnv ? APP_RIBBON_SPACE : 0\n });\n const {\n children,\n useNewRoutes,\n userAvatar = <UserProfileMenuWrapper />,\n appContent,\n leftMenu,\n appSelectorMenus,\n siteName,\n className,\n navRoot,\n hideToggle,\n useMockData,\n mockMenus,\n user: passedInUser,\n unityUrl,\n expander,\n sidebarTitle,\n navMenuHoverOn = true,\n secondExtended,\n toggleOne,\n toggleTwo,\n closePrimary,\n closeSecondary,\n panelExpanded,\n panelExpandedSecondary,\n setPanelExpanded = false,\n setPanelExpandedSecondary = false,\n breadCrumbAltLabelList = [],\n currentLocation,\n utilitySidebarResizable,\n utilitySidebarToggleOverride,\n onUtilitySidebarToggleExpandClick,\n hideLayout = false,\n getAccessToken,\n switcherData,\n selectedItem,\n switcherWidth,\n languages,\n projectSwitcherColor,\n getWidget,\n isValidWidget,\n appSwitcherHeader,\n hamburgerMenuAccessRole,\n hideLanguageSwitcher = false,\n subheader,\n hideHelpCenter = false\n } = props;\n const contextUser = useUser();\n const user = passedInUser ?? contextUser;\n const { setGetWidget, setIsValidWidget, shellHidden } = useShellStore();\n const [appSwitcherMobile, setAppSwitcherMobile] = useState(false);\n const [appSwitcherDesktop, setAppSwitcherDesktop] = useState(false);\n const { i18n } = useTranslation();\n const inquiryTitle = useInquiryStore((state) => state.title);\n useSetInitialShellVisibility();\n const tenant = useTenant();\n const activeTenant = tenant?.activeTenant ?? null;\n\n //usePreloadPages();\n\n const menuContext = useMenuContext?.();\n const resolvedLeftMenu = leftMenu ?? menuContext?.leftMenu;\n const resolvedAppSelectorMenus =\n appSelectorMenus ?? menuContext?.appSelectorMenus;\n const providedLanguages = languages ?? menuContext?.languages;\n const resolvedLanguages = Array.isArray(providedLanguages)\n ? providedLanguages\n : [];\n useEffect(() => {\n setGetWidget(getWidget);\n return () => setGetWidget(null);\n }, [getWidget, setGetWidget]);\n\n useEffect(() => {\n setIsValidWidget(isValidWidget);\n return () => setIsValidWidget(null);\n }, [isValidWidget, setIsValidWidget]);\n\n const getMenuItems = useCallback(\n (menuTypeId, menus) => {\n if (!menus && !useMockData) {\n return [];\n }\n const menusToFilter = useMockData ? mockMenus : menus;\n\n const foundMenus = menusToFilter.filter(\n (menu) => menu.menuTypeId === menuTypeId && menu.active\n );\n\n if (foundMenus) {\n return foundMenus.reduce((menuItemInstanceStructureViews, menu) => {\n return [\n ...menuItemInstanceStructureViews,\n ...menu.menuItemInstanceStructureViews\n ];\n }, []);\n } else {\n return [];\n }\n },\n [useMockData, mockMenus]\n );\n\n const menus = useMemo(() => {\n const menuItems = getMenuItems(1, resolvedLeftMenu);\n return getMenuItemsRecursively(menuItems, true, user);\n }, [getMenuItems, user, resolvedLeftMenu]);\n\n const theme = useTheme();\n const mobile = useMediaQuery(theme.breakpoints.up('sm'));\n\n const handleAppSwitcher = (type, bool) => {\n if (type === 'mobile') {\n setAppSwitcherMobile(bool);\n } else {\n setAppSwitcherDesktop(bool);\n }\n };\n\n const builderMenu = useMemo(() => {\n const menuItems = getMenuItems(\n MenuTypeEnums.Builders_Menu,\n resolvedAppSelectorMenus\n );\n return getMenuItemsRecursively(menuItems, true, user, getAccessToken);\n }, [getMenuItems, user, resolvedAppSelectorMenus, getAccessToken]);\n\n const favoriteMenu = useMemo(() => {\n const menuItems = getMenuItems(\n MenuTypeEnums.Favorites_Menu,\n resolvedAppSelectorMenus\n );\n return getMenuItemsRecursively(menuItems, true, user, getAccessToken);\n }, [getMenuItems, user, resolvedAppSelectorMenus, getAccessToken]);\n\n const appMenu = useMemo(() => {\n const menuItems = getMenuItems(\n MenuTypeEnums.Application_Menu,\n resolvedAppSelectorMenus\n );\n return getMenuItemsRecursively(menuItems, true, user, getAccessToken);\n }, [getMenuItems, user, resolvedAppSelectorMenus, getAccessToken]);\n\n const hideAppMenu = useMemo(\n () =>\n !resolvedAppSelectorMenus ||\n (hamburgerMenuAccessRole &&\n !user?.roleNames.includes(hamburgerMenuAccessRole)),\n [user, resolvedAppSelectorMenus, hamburgerMenuAccessRole]\n );\n\n useEffect(() => {\n i18n.changeLanguage('en-US');\n }, [i18n]);\n\n const isUserInitialized = Boolean(user?.id);\n const isTenantInitialized = Boolean(activeTenant?.tenantId);\n const isThemeInitialized = Boolean(theme?.isInitialized);\n\n if (!isUserInitialized || !isTenantInitialized || !isThemeInitialized) {\n return <LoadingIndicator />;\n }\n let enrichedChildren = children;\n if(useNewRoutes)\n enrichedChildren = <Suspense fallback={<PageLoading />}>\n <Switch>{children}<UdpRoutes/></Switch></Suspense>;\n if (hideLayout) {\n return <div>{enrichedChildren}</div>;\n }\n return (\n <ChatBotProvider>\n <ActionProvider>\n <div className={classes.root}>\n {!shellHidden && (\n <SiteHeader\n className={classes.header}\n siteName={siteName}\n appContent={appContent}\n userAvatar={userAvatar}\n breadCrumbRoot={navRoot}\n setAppSwitcherOpen={(type, bool) => handleAppSwitcher(type, bool)}\n breadCrumbAltLabelList={breadCrumbAltLabelList}\n currentLocation={currentLocation}\n switcherData={switcherData}\n selectedItem={selectedItem}\n switcherWidth={switcherWidth}\n hideAppLaunch={hideAppMenu}\n languages={resolvedLanguages}\n hideLanguageSwitcher={hideLanguageSwitcher}\n backgroundColor={projectSwitcherColor}\n hideHelpCenter={hideHelpCenter}\n />\n )}\n\n <div style={{ display: 'flex' }} className={classes.sidebar}>\n {!shellHidden && mobile && (\n <NavigationSidebar\n className={classes.sidebar}\n data={menus}\n navMenuHoverOn={navMenuHoverOn}\n user={user}\n useGlobalState={true}\n />\n )}\n {expander && (\n <div>\n <UtilitySideBar\n title={inquiryTitle || sidebarTitle}\n resizable={utilitySidebarResizable}\n utilitySidebarToggleOverride={utilitySidebarToggleOverride}\n onUtilitySidebarToggleExpandClick={\n onUtilitySidebarToggleExpandClick\n }\n sidebarHidden={shellHidden}\n {...props}\n />\n </div>\n )}\n </div>\n\n <div className={classes.content}>\n <UtilityBar\n className={clsx(className)}\n gutters={false}\n hideToggle={hideToggle}\n expander={expander}\n secondExtended={secondExtended}\n toggleOne={toggleOne}\n toggleTwo={toggleTwo}\n closePrimary={closePrimary}\n closeSecondary={closeSecondary}\n expanded={panelExpanded}\n expandedSecondary={panelExpandedSecondary}\n setExpanded={setPanelExpanded}\n setExpandedSecondary={setPanelExpandedSecondary}\n />\n\n <PageActionWrapper>{subheader}{enrichedChildren}</PageActionWrapper>\n </div>\n <Drawer\n variant='temporary'\n anchor='left'\n open={appSwitcherDesktop}\n classes={\n !mobile\n ? {}\n : !resolvedAppSelectorMenus\n ? {}\n : { paper: classes.paper }\n }\n onClose={() => handleAppSwitcher('desktop', false)}\n >\n {mobile && resolvedAppSelectorMenus && (\n <FUIAppSwitcher\n onClose={() => handleAppSwitcher('desktop', false)}\n favoriteMenu={favoriteMenu}\n builderMenu={builderMenu}\n appMenu={appMenu}\n unityUrl={unityUrl}\n user={user}\n header={appSwitcherHeader}\n />\n )}\n {(!mobile || (mobile && !resolvedAppSelectorMenus)) && (\n <NavigationSidebar\n toggle={false}\n className={classes.sidebar}\n data={menus}\n navMenuHoverOn={navMenuHoverOn}\n user={user}\n useGlobalState={true}\n />\n )}\n </Drawer>\n\n <Drawer\n variant='temporary'\n anchor='right'\n open={appSwitcherMobile}\n classes={{ paper: classes.paper }}\n onClose={() => handleAppSwitcher('mobile', false)}\n >\n <FUIAppSwitcher\n onClose={() => handleAppSwitcher('mobile', false)}\n favoriteMenu={favoriteMenu}\n builderMenu={builderMenu}\n appMenu={appMenu}\n unityUrl={unityUrl}\n user={user}\n header={appSwitcherHeader}\n />\n </Drawer>\n </div>\n </ActionProvider>\n </ChatBotProvider>\n );\n};\n\nShell.propTypes = {\n /**\n * The newest propTypes have been added but older ones are missing @todo: add missing propTypes for Shell.\n */\n\n /**\n * The array used to map for label and functions to list items.\n */\n switcherData: PropTypes.array,\n /**\n * The active label displayed.\n */\n selectedItem: PropTypes.string,\n /**\n * Provides a method set the selector width. Default is 100.\n */\n switcherWidth: PropTypes.number,\n /**\n * Children nodes\n */\n children: PropTypes.oneOfType([\n PropTypes.arrayOf(PropTypes.node),\n PropTypes.node\n ]).isRequired,\n\n /**\n * Name of site\n */\n siteName: PropTypes.string,\n\n /**\n * Component to render for the user Avatar\n */\n userAvatar: PropTypes.element,\n\n appContent: PropTypes.element,\n\n leftMenu: PropTypes.array,\n\n appSelectorMenus: PropTypes.array,\n\n className: PropTypes.object,\n\n navRoot: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.node]),\n\n /**\n * Should the shell use mock data\n */\n useMockData: PropTypes.bool,\n\n mockMenus: PropTypes.array,\n\n unityUrl: PropTypes.string,\n\n expander: PropTypes.bool,\n\n sidebarTitle: PropTypes.string,\n\n navMenuHoverOn: PropTypes.bool,\n\n toggleOne: PropTypes.bool,\n\n toggleTwo: PropTypes.bool,\n\n closePrimary: PropTypes.bool,\n\n closeSecondary: PropTypes.bool,\n\n panelExpanded: PropTypes.bool,\n\n panelExpandedSecondary: PropTypes.bool,\n\n setPanelExpanded: PropTypes.func,\n\n setPanelExpandedSecondary: PropTypes.func,\n\n breadCrumbAltLabelList: PropTypes.array,\n\n currentLocation: PropTypes.object,\n\n utilitySidebarResizable: PropTypes.bool,\n\n utilitySidebarToggleOverride: PropTypes.bool,\n\n onUtilitySidebarToggleExpandClick: PropTypes.func,\n\n hideLayout: PropTypes.bool,\n\n languages: PropTypes.arrayOf(PropTypes.object),\n\n /**\n * Passes the background color on the project switcher (default: theme secondary)\n */\n projectSwitcherColor: PropTypes.string,\n getWidget: PropTypes.func,\n isValidWidget: PropTypes.func,\n currentTenant: PropTypes.object,\n hamburgerMenuAccessRole: PropTypes.string\n};\n"],"mappings":"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"}
|
|
@@ -185,7 +185,8 @@ const useTenantData = (id, user) => {
|
|
|
185
185
|
};
|
|
186
186
|
const TenantProvider = ({ children }) => {
|
|
187
187
|
const user = useUser();
|
|
188
|
-
|
|
188
|
+
useAccount();
|
|
189
|
+
const id = user?.id;
|
|
189
190
|
const { changeTenant } = useUserActions();
|
|
190
191
|
const { tenantsList, filteredTenantsList, activeTenant, isProductTenant, refresh, noTenantsAvailable, zeroTenantAccess, shouldShowTenantMismatchDialog, allowedTenants, selectedTenantForDialog, unityProductName } = useTenantData(id, user);
|
|
191
192
|
useTenantStoreSync(activeTenant);
|
|
@@ -219,4 +220,4 @@ const TenantProvider = ({ children }) => {
|
|
|
219
220
|
|
|
220
221
|
//#endregion
|
|
221
222
|
export { useUserActions as a, useLocalUserActions as i, TenantAccessDialog as n, TenantSelect as r, TenantProvider as t };
|
|
222
|
-
//# sourceMappingURL=TenantProvider-
|
|
223
|
+
//# sourceMappingURL=TenantProvider-C-3eqCA3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TenantProvider-YjlC8AtM.js","names":["TenantAccessDialog: React.FC<TenantAccessDialogProps>"],"sources":["../src/utilities/auth/users.js","../src/utilities/tenant/TenantSelect.tsx","../src/utilities/tenant/TenantAccessDialog.tsx","../src/utilities/tenant/TenantProvider.jsx"],"sourcesContent":["import { useContext, useCallback } from 'react';\nimport { UserDispatchContext } from './internal';\n\nexport function useUserActions() {\n const dispatch = useContext(UserDispatchContext);\n const setUser = useCallback(\n (user) => {\n dispatch({ type: 'SET_USER', user });\n },\n [dispatch]\n );\n\n const changeTenant = useCallback(\n (tenantId) => {\n dispatch({ type: 'CHANGE_TENANT', tenantId });\n },\n [dispatch]\n );\n\n return { setUser, changeTenant };\n}\n\nexport function useLocalUserActions() {\n const dispatch = useContext(UserDispatchContext);\n const setUser = useCallback(\n (user) => {\n dispatch({ type: 'SET_USER', user });\n },\n [dispatch]\n );\n\n const setAccessToken = useCallback(\n (accessToken) => {\n dispatch({ type: 'SET_ACCESS_TOKEN', accessToken });\n },\n [dispatch]\n );\n\n return { setUser, setAccessToken };\n}\n","import React, { forwardRef, useMemo, useCallback } from 'react';\nimport { Autocomplete, AutocompleteChangeReason } from '@material-ui/lab';\nimport { TextField, TextFieldProps } from '@material-ui/core';\nimport { Tenant } from '../types';\n\ninterface TenantSelectProps {\n tenants?: Tenant[] | null;\n value: Tenant | null;\n onTenantChange?: (tenant: Tenant) => void;\n id?: string;\n label?: string;\n className?: string;\n disableClearable?: boolean;\n textFieldProps?: TextFieldProps;\n recordIdPrefix?: string;\n}\n\nconst sanitizeRecordId = (tenantName: string) =>\n tenantName.replace(/\\s+/g, '');\n\nexport const TenantSelect = forwardRef<HTMLDivElement, TenantSelectProps>(\n (props, ref) => {\n const {\n tenants,\n value,\n onTenantChange,\n id = 'tenant-select',\n label = 'Current Tenant',\n className,\n disableClearable = true,\n textFieldProps,\n recordIdPrefix = 'udpRecord-TenantSelect'\n } = props;\n\n const options = useMemo(() => tenants ?? [], [tenants]);\n\n const handleChange = useCallback(\n (\n event: React.ChangeEvent<object>,\n newValue: Tenant | null,\n reason: AutocompleteChangeReason\n ) => {\n if (reason !== 'select-option' || !newValue) {\n return;\n }\n onTenantChange?.(newValue);\n },\n [onTenantChange]\n );\n\n return (\n <Autocomplete\n ref={ref}\n className={className}\n id={id}\n value={value}\n options={options}\n disableClearable={disableClearable}\n getOptionSelected={(option, selected) =>\n option?.tenantId === selected?.tenantId\n }\n getOptionLabel={(option) => option?.tenantName ?? ''}\n onChange={handleChange}\n renderInput={(params) => (\n <TextField\n {...params}\n label={label}\n variant='standard'\n {...textFieldProps}\n />\n )}\n renderOption={(option) => (\n <li\n style={{ width: '100%', height: '100%' }}\n // @ts-expect-error udpRecordId is used for automation tagging\n udprecordid={`${recordIdPrefix}-${sanitizeRecordId(\n option?.tenantName ?? ''\n )}`}\n >\n {option?.tenantName ?? ''}\n </li>\n )}\n />\n );\n }\n);\n\nTenantSelect.displayName = 'TenantSelect';\n","import React from 'react';\nimport { FluentDialog } from '../../UI/feedback/FluentDialog';\nimport { TenantSelect } from './TenantSelect';\nimport { Tenant } from '../types';\n\ninterface TenantAccessDialogProps {\n open: boolean;\n tenants: Tenant[];\n currentTenant: Tenant | null;\n onTenantChange: (tenant: Tenant) => void;\n productName?: string | null;\n}\n\nexport const TenantAccessDialog: React.FC<TenantAccessDialogProps> = ({\n tenants,\n onTenantChange,\n productName\n}) => {\n const message = productName\n ? `Your current tenant does not have access to ${productName}. Please select another tenant to continue.`\n : 'Your current tenant does not have access to this application. Please select another tenant to continue.';\n\n return (\n <FluentDialog\n open={true}\n title='Tenant Access Required'\n message={message}\n buttonOneHidden={true}\n buttonTwoHidden={true}\n disableEscapeKeyDown\n disableBackdropClick\n >\n <TenantSelect\n tenants={tenants}\n value={null}\n onTenantChange={onTenantChange}\n label='Available Tenants'\n id='tenant-access-dialog-select'\n disableClearable={false}\n recordIdPrefix='udpRecord-TenantAccessDialog'\n />\n </FluentDialog>\n );\n};\n","import React, { useCallback, useMemo, useEffect } from 'react';\nimport { useUser } from '../auth/useUser';\nimport { useAxiosGet } from '../useAxiosGet';\nimport { TenantContext } from './tenantContext';\nimport { ConfigService } from '../../configService';\nimport { FluentDialog } from '../../UI/feedback/FluentDialog';\nimport { useAccount } from '@azure/msal-react';\nimport { MenuProvider } from '../menus/MenuProvider';\nimport { TenantAccessDialog } from './TenantAccessDialog';\nimport { storeTenant } from '../storage/UnitySessionStorage';\nimport { useUserActions } from '../auth/users';\nimport { TenantTypeEnums } from '../../enums/unitySystemEnums';\nimport { useTenantStore } from '../../stores/tenantStore'; // <-- Imported for the sync hook\n\n/**\n * A hook to sync the derived active tenant with the Zustand store.\n * This is the \"necessary evil\" to keep the store updated.\n */\nconst useTenantStoreSync = (activeTenant) => {\n const {\n currentTenant: storeTenantValue,\n setCurrentTenant,\n } = useTenantStore((state) => ({\n currentTenant: state.currentTenant,\n setCurrentTenant: state.setCurrentTenant,\n }));\n\n // This effect syncs our correct activeTenant to the Zustand store.\n // This fixes the \"side-effect in render\" bug from the original code.\n useEffect(() => {\n if (\n activeTenant &&\n (storeTenantValue?.tenantId !== activeTenant.tenantId ||\n storeTenantValue?.name !== activeTenant.tenantName ||\n storeTenantValue?.tenantType !== activeTenant.tenantType)\n ) {\n setCurrentTenant({\n tenantId: activeTenant.tenantId,\n name: activeTenant.tenantName,\n tenantType: activeTenant.tenantType,\n });\n }\n }, [activeTenant, storeTenantValue, setCurrentTenant]);\n};\n\n/**\n * This hook fetches all data and derives the correct tenant state.\n * It is pure and has no knowledge of Zustand.\n */\nconst useTenantData = (id, user) => {\n // --- Data Fetching ---\n const [{ data: tenants }, refetchTenantsList] = useAxiosGet(\n ConfigService.securityV1ApiUrl,\n `users/${id ?? ''}/unitytenants`,\n {},\n !id\n );\n\n const [{ data: products }] = useAxiosGet(\n ConfigService.tenantV1ApiUrl,\n `products`,\n {},\n !id\n );\n\n // --- State Derivation ---\n const unityProductIdString = ConfigService.config.UNITY_PRODUCT_ID;\n const unityProductId = unityProductIdString\n ? Number(unityProductIdString)\n : null;\n const shouldFilterByProduct =\n typeof unityProductId === 'number' && !Number.isNaN(unityProductId);\n\n const filteredTenantsList = useMemo(() => {\n if (!Array.isArray(tenants)) {\n return null;\n }\n if (!shouldFilterByProduct || unityProductId === null) {\n return tenants;\n }\n return tenants.filter((tenant) =>\n tenant?.products?.find(\n (product) => product?.productId === unityProductId\n )\n );\n }, [tenants, shouldFilterByProduct, unityProductId]);\n\n // This is the correctly derived tenant\n const activeTenant =\n user?.currentTenantId && Array.isArray(tenants)\n ? tenants.find((tenant) => tenant.tenantId === user.currentTenantId) ??\n null\n : null;\n\n // This is derived from the correct tenant\n const isProductTenant =\n activeTenant?.tenantType === TenantTypeEnums.Product;\n\n // --- Dialog Logic & Derived Flags ---\n const unityProductName = useMemo(() => {\n if (!shouldFilterByProduct || unityProductId === null) {\n return null;\n }\n if (!Array.isArray(products)) {\n return null;\n }\n return (\n products.find(\n (product) => product?.productId === unityProductId\n )?.name ?? null\n );\n }, [products, shouldFilterByProduct, unityProductId]);\n\n const userHasLoaded = user?.statusCode === 200;\n\n const noTenantsAvailable =\n Array.isArray(tenants) && tenants.length === 0 && userHasLoaded;\n\n const hasFilteredTenants =\n Array.isArray(filteredTenantsList) && filteredTenantsList.length > 0;\n\n const currentTenantAllowed = !shouldFilterByProduct\n ? true\n : filteredTenantsList?.some(\n (tenant) => tenant.tenantId === user?.currentTenantId\n ) ?? false;\n\n const zeroTenantAccess =\n userHasLoaded &&\n shouldFilterByProduct &&\n Array.isArray(filteredTenantsList) &&\n filteredTenantsList.length === 0;\n\n const shouldShowTenantMismatchDialog =\n userHasLoaded &&\n shouldFilterByProduct &&\n hasFilteredTenants &&\n !currentTenantAllowed;\n\n const allowedTenants = useMemo(\n () => (Array.isArray(filteredTenantsList) ? filteredTenantsList : []),\n [filteredTenantsList]\n );\n\n const selectedTenantForDialog = currentTenantAllowed\n ? activeTenant\n : allowedTenants[0] ?? null;\n\n // Return everything the Provider needs\n return {\n tenantsList: tenants ?? null,\n filteredTenantsList,\n activeTenant, // The correct tenant\n isProductTenant, // Derived from the correct tenant\n refresh: refetchTenantsList,\n noTenantsAvailable,\n zeroTenantAccess,\n shouldShowTenantMismatchDialog,\n allowedTenants,\n selectedTenantForDialog,\n unityProductName,\n };\n};\n\n\nexport const TenantProvider = ({ children }) => {\n const user = useUser();\n const activeAccount = useAccount();\n const id = activeAccount?.idTokenClaims?.unityUserId || user?.id;\n const { changeTenant } = useUserActions();\n\n // Call the main data hook to get the correct state\n const {\n tenantsList,\n filteredTenantsList,\n activeTenant, // This is the correct value\n isProductTenant,\n refresh,\n noTenantsAvailable,\n zeroTenantAccess,\n shouldShowTenantMismatchDialog,\n allowedTenants,\n selectedTenantForDialog,\n unityProductName,\n } = useTenantData(id, user);\n\n useTenantStoreSync(activeTenant);\n\n // Callback for changing the tenant (triggers API call)\n const handleTenantChange = useCallback(\n (tenant) => {\n if (!tenant) return;\n storeTenant(tenant.tenantId);\n changeTenant(tenant.tenantId); // This will cause `user` to update, re-running the hooks.\n },\n [changeTenant]\n );\n\n // Render blocking dialog if user has no access\n if (noTenantsAvailable || zeroTenantAccess) {\n return (\n <FluentDialog\n title='No Access'\n message='Your user does not have access to any tenants. Please contact your support team.'\n open={true}\n buttonOneHidden={true}\n buttonTwoHidden={true}\n />\n );\n }\n\n if (shouldShowTenantMismatchDialog) {\n return (\n\n <TenantAccessDialog\n open={true}\n tenants={allowedTenants}\n currentTenant={selectedTenantForDialog}\n onTenantChange={handleTenantChange}\n productName={unityProductName}\n />\n );\n }\n\n // Provide the correct values to the Context\n return (\n <TenantContext.Provider\n value={{\n tenantsList,\n filteredTenantsList,\n activeTenant,\n isProductTenant,\n refresh,\n }}\n >\n <MenuProvider>\n {children}\n </MenuProvider>\n </TenantContext.Provider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TenantProvider-C-3eqCA3.js","names":["TenantAccessDialog: React.FC<TenantAccessDialogProps>"],"sources":["../src/utilities/auth/users.js","../src/utilities/tenant/TenantSelect.tsx","../src/utilities/tenant/TenantAccessDialog.tsx","../src/utilities/tenant/TenantProvider.jsx"],"sourcesContent":["import { useContext, useCallback } from 'react';\nimport { UserDispatchContext } from './internal';\n\nexport function useUserActions() {\n const dispatch = useContext(UserDispatchContext);\n const setUser = useCallback(\n (user) => {\n dispatch({ type: 'SET_USER', user });\n },\n [dispatch]\n );\n\n const changeTenant = useCallback(\n (tenantId) => {\n dispatch({ type: 'CHANGE_TENANT', tenantId });\n },\n [dispatch]\n );\n\n return { setUser, changeTenant };\n}\n\nexport function useLocalUserActions() {\n const dispatch = useContext(UserDispatchContext);\n const setUser = useCallback(\n (user) => {\n dispatch({ type: 'SET_USER', user });\n },\n [dispatch]\n );\n\n const setAccessToken = useCallback(\n (accessToken) => {\n dispatch({ type: 'SET_ACCESS_TOKEN', accessToken });\n },\n [dispatch]\n );\n\n return { setUser, setAccessToken };\n}\n","import React, { forwardRef, useMemo, useCallback } from 'react';\nimport { Autocomplete, AutocompleteChangeReason } from '@material-ui/lab';\nimport { TextField, TextFieldProps } from '@material-ui/core';\nimport { Tenant } from '../types';\n\ninterface TenantSelectProps {\n tenants?: Tenant[] | null;\n value: Tenant | null;\n onTenantChange?: (tenant: Tenant) => void;\n id?: string;\n label?: string;\n className?: string;\n disableClearable?: boolean;\n textFieldProps?: TextFieldProps;\n recordIdPrefix?: string;\n}\n\nconst sanitizeRecordId = (tenantName: string) =>\n tenantName.replace(/\\s+/g, '');\n\nexport const TenantSelect = forwardRef<HTMLDivElement, TenantSelectProps>(\n (props, ref) => {\n const {\n tenants,\n value,\n onTenantChange,\n id = 'tenant-select',\n label = 'Current Tenant',\n className,\n disableClearable = true,\n textFieldProps,\n recordIdPrefix = 'udpRecord-TenantSelect'\n } = props;\n\n const options = useMemo(() => tenants ?? [], [tenants]);\n\n const handleChange = useCallback(\n (\n event: React.ChangeEvent<object>,\n newValue: Tenant | null,\n reason: AutocompleteChangeReason\n ) => {\n if (reason !== 'select-option' || !newValue) {\n return;\n }\n onTenantChange?.(newValue);\n },\n [onTenantChange]\n );\n\n return (\n <Autocomplete\n ref={ref}\n className={className}\n id={id}\n value={value}\n options={options}\n disableClearable={disableClearable}\n getOptionSelected={(option, selected) =>\n option?.tenantId === selected?.tenantId\n }\n getOptionLabel={(option) => option?.tenantName ?? ''}\n onChange={handleChange}\n renderInput={(params) => (\n <TextField\n {...params}\n label={label}\n variant='standard'\n {...textFieldProps}\n />\n )}\n renderOption={(option) => (\n <li\n style={{ width: '100%', height: '100%' }}\n // @ts-expect-error udpRecordId is used for automation tagging\n udprecordid={`${recordIdPrefix}-${sanitizeRecordId(\n option?.tenantName ?? ''\n )}`}\n >\n {option?.tenantName ?? ''}\n </li>\n )}\n />\n );\n }\n);\n\nTenantSelect.displayName = 'TenantSelect';\n","import React from 'react';\nimport { FluentDialog } from '../../UI/feedback/FluentDialog';\nimport { TenantSelect } from './TenantSelect';\nimport { Tenant } from '../types';\n\ninterface TenantAccessDialogProps {\n open: boolean;\n tenants: Tenant[];\n currentTenant: Tenant | null;\n onTenantChange: (tenant: Tenant) => void;\n productName?: string | null;\n}\n\nexport const TenantAccessDialog: React.FC<TenantAccessDialogProps> = ({\n tenants,\n onTenantChange,\n productName\n}) => {\n const message = productName\n ? `Your current tenant does not have access to ${productName}. Please select another tenant to continue.`\n : 'Your current tenant does not have access to this application. Please select another tenant to continue.';\n\n return (\n <FluentDialog\n open={true}\n title='Tenant Access Required'\n message={message}\n buttonOneHidden={true}\n buttonTwoHidden={true}\n disableEscapeKeyDown\n disableBackdropClick\n >\n <TenantSelect\n tenants={tenants}\n value={null}\n onTenantChange={onTenantChange}\n label='Available Tenants'\n id='tenant-access-dialog-select'\n disableClearable={false}\n recordIdPrefix='udpRecord-TenantAccessDialog'\n />\n </FluentDialog>\n );\n};\n","import React, { useCallback, useMemo, useEffect } from 'react';\nimport { useUser } from '../auth/useUser';\nimport { useAxiosGet } from '../useAxiosGet';\nimport { TenantContext } from './tenantContext';\nimport { ConfigService } from '../../configService';\nimport { FluentDialog } from '../../UI/feedback/FluentDialog';\nimport { useAccount } from '@azure/msal-react';\nimport { MenuProvider } from '../menus/MenuProvider';\nimport { TenantAccessDialog } from './TenantAccessDialog';\nimport { storeTenant } from '../storage/UnitySessionStorage';\nimport { useUserActions } from '../auth/users';\nimport { TenantTypeEnums } from '../../enums/unitySystemEnums';\nimport { useTenantStore } from '../../stores/tenantStore'; // <-- Imported for the sync hook\n\n/**\n * A hook to sync the derived active tenant with the Zustand store.\n * This is the \"necessary evil\" to keep the store updated.\n */\nconst useTenantStoreSync = (activeTenant) => {\n const {\n currentTenant: storeTenantValue,\n setCurrentTenant,\n } = useTenantStore((state) => ({\n currentTenant: state.currentTenant,\n setCurrentTenant: state.setCurrentTenant,\n }));\n\n // This effect syncs our correct activeTenant to the Zustand store.\n // This fixes the \"side-effect in render\" bug from the original code.\n useEffect(() => {\n if (\n activeTenant &&\n (storeTenantValue?.tenantId !== activeTenant.tenantId ||\n storeTenantValue?.name !== activeTenant.tenantName ||\n storeTenantValue?.tenantType !== activeTenant.tenantType)\n ) {\n setCurrentTenant({\n tenantId: activeTenant.tenantId,\n name: activeTenant.tenantName,\n tenantType: activeTenant.tenantType,\n });\n }\n }, [activeTenant, storeTenantValue, setCurrentTenant]);\n};\n\n/**\n * This hook fetches all data and derives the correct tenant state.\n * It is pure and has no knowledge of Zustand.\n */\nconst useTenantData = (id, user) => {\n // --- Data Fetching ---\n const [{ data: tenants }, refetchTenantsList] = useAxiosGet(\n ConfigService.securityV1ApiUrl,\n `users/${id ?? ''}/unitytenants`,\n {},\n !id\n );\n\n const [{ data: products }] = useAxiosGet(\n ConfigService.tenantV1ApiUrl,\n `products`,\n {},\n !id\n );\n\n // --- State Derivation ---\n const unityProductIdString = ConfigService.config.UNITY_PRODUCT_ID;\n const unityProductId = unityProductIdString\n ? Number(unityProductIdString)\n : null;\n const shouldFilterByProduct =\n typeof unityProductId === 'number' && !Number.isNaN(unityProductId);\n\n const filteredTenantsList = useMemo(() => {\n if (!Array.isArray(tenants)) {\n return null;\n }\n if (!shouldFilterByProduct || unityProductId === null) {\n return tenants;\n }\n return tenants.filter((tenant) =>\n tenant?.products?.find(\n (product) => product?.productId === unityProductId\n )\n );\n }, [tenants, shouldFilterByProduct, unityProductId]);\n\n // This is the correctly derived tenant\n const activeTenant =\n user?.currentTenantId && Array.isArray(tenants)\n ? tenants.find((tenant) => tenant.tenantId === user.currentTenantId) ??\n null\n : null;\n\n // This is derived from the correct tenant\n const isProductTenant =\n activeTenant?.tenantType === TenantTypeEnums.Product;\n\n // --- Dialog Logic & Derived Flags ---\n const unityProductName = useMemo(() => {\n if (!shouldFilterByProduct || unityProductId === null) {\n return null;\n }\n if (!Array.isArray(products)) {\n return null;\n }\n return (\n products.find(\n (product) => product?.productId === unityProductId\n )?.name ?? null\n );\n }, [products, shouldFilterByProduct, unityProductId]);\n\n const userHasLoaded = user?.statusCode === 200;\n\n const noTenantsAvailable =\n Array.isArray(tenants) && tenants.length === 0 && userHasLoaded;\n\n const hasFilteredTenants =\n Array.isArray(filteredTenantsList) && filteredTenantsList.length > 0;\n\n const currentTenantAllowed = !shouldFilterByProduct\n ? true\n : filteredTenantsList?.some(\n (tenant) => tenant.tenantId === user?.currentTenantId\n ) ?? false;\n\n const zeroTenantAccess =\n userHasLoaded &&\n shouldFilterByProduct &&\n Array.isArray(filteredTenantsList) &&\n filteredTenantsList.length === 0;\n\n const shouldShowTenantMismatchDialog =\n userHasLoaded &&\n shouldFilterByProduct &&\n hasFilteredTenants &&\n !currentTenantAllowed;\n\n const allowedTenants = useMemo(\n () => (Array.isArray(filteredTenantsList) ? filteredTenantsList : []),\n [filteredTenantsList]\n );\n\n const selectedTenantForDialog = currentTenantAllowed\n ? activeTenant\n : allowedTenants[0] ?? null;\n\n // Return everything the Provider needs\n return {\n tenantsList: tenants ?? null,\n filteredTenantsList,\n activeTenant, // The correct tenant\n isProductTenant, // Derived from the correct tenant\n refresh: refetchTenantsList,\n noTenantsAvailable,\n zeroTenantAccess,\n shouldShowTenantMismatchDialog,\n allowedTenants,\n selectedTenantForDialog,\n unityProductName,\n };\n};\n\n\nexport const TenantProvider = ({ children }) => {\n const user = useUser();\n const activeAccount = useAccount();\n const id = user?.id;\n const { changeTenant } = useUserActions();\n\n // Call the main data hook to get the correct state\n const {\n tenantsList,\n filteredTenantsList,\n activeTenant, // This is the correct value\n isProductTenant,\n refresh,\n noTenantsAvailable,\n zeroTenantAccess,\n shouldShowTenantMismatchDialog,\n allowedTenants,\n selectedTenantForDialog,\n unityProductName,\n } = useTenantData(id, user);\n\n useTenantStoreSync(activeTenant);\n\n // Callback for changing the tenant (triggers API call)\n const handleTenantChange = useCallback(\n (tenant) => {\n if (!tenant) return;\n storeTenant(tenant.tenantId);\n changeTenant(tenant.tenantId); // This will cause `user` to update, re-running the hooks.\n },\n [changeTenant]\n );\n\n // Render blocking dialog if user has no access\n if (noTenantsAvailable || zeroTenantAccess) {\n return (\n <FluentDialog\n title='No Access'\n message='Your user does not have access to any tenants. Please contact your support team.'\n open={true}\n buttonOneHidden={true}\n buttonTwoHidden={true}\n />\n );\n }\n\n if (shouldShowTenantMismatchDialog) {\n return (\n\n <TenantAccessDialog\n open={true}\n tenants={allowedTenants}\n currentTenant={selectedTenantForDialog}\n onTenantChange={handleTenantChange}\n productName={unityProductName}\n />\n );\n }\n\n // Provide the correct values to the Context\n return (\n <TenantContext.Provider\n value={{\n tenantsList,\n filteredTenantsList,\n activeTenant,\n isProductTenant,\n refresh,\n }}\n >\n <MenuProvider>\n {children}\n </MenuProvider>\n </TenantContext.Provider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -2,10 +2,11 @@ import { t as ConfigService } from "./configService-C4uoG3wj.js";
|
|
|
2
2
|
import { r as storeInitialTenant } from "./UnitySessionStorage-CUDx9YWR.js";
|
|
3
3
|
import { t as apiMutate } from "./useAxiosMutate-DeqKSi5z.js";
|
|
4
4
|
import { i as storeInitialPath } from "./LocalRedirectUrlStorage-Bxz8TI-X.js";
|
|
5
|
-
import { t as AuthProvider } from "./AuthProvider-
|
|
5
|
+
import { t as AuthProvider } from "./AuthProvider-qWjJiYSg.js";
|
|
6
6
|
import { n as ThemeProvider } from "./theme-Bb8h8tjE.js";
|
|
7
7
|
import React, { useEffect } from "react";
|
|
8
8
|
import { SnackbarProvider } from "notistack";
|
|
9
|
+
import { BrowserRouter } from "react-router-dom";
|
|
9
10
|
import { initReactI18next } from "react-i18next";
|
|
10
11
|
import i18n from "i18next";
|
|
11
12
|
import LanguageDetector from "i18next-browser-languagedetector";
|
|
@@ -103,12 +104,12 @@ const UdpAppProvider = ({ children, snackbarProps, authProps, i18nOptions }) =>
|
|
|
103
104
|
}, [i18nOptions]);
|
|
104
105
|
storeInitialPath();
|
|
105
106
|
storeInitialTenant();
|
|
106
|
-
return /* @__PURE__ */ React.createElement(AuthProvider, authProps, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(SnackbarProvider, {
|
|
107
|
+
return /* @__PURE__ */ React.createElement(AuthProvider, authProps, /* @__PURE__ */ React.createElement(ThemeProvider, null, /* @__PURE__ */ React.createElement(BrowserRouter, null, /* @__PURE__ */ React.createElement(SnackbarProvider, {
|
|
107
108
|
maxSnack: 3,
|
|
108
109
|
...snackbarProps
|
|
109
|
-
}, children)));
|
|
110
|
+
}, children))));
|
|
110
111
|
};
|
|
111
112
|
|
|
112
113
|
//#endregion
|
|
113
114
|
export { getI18nInstance as n, initializeUnityI18n as r, UdpAppProvider as t };
|
|
114
|
-
//# sourceMappingURL=UdpAppProvider-
|
|
115
|
+
//# sourceMappingURL=UdpAppProvider-NHkopZ-S.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UdpAppProvider-
|
|
1
|
+
{"version":3,"file":"UdpAppProvider-NHkopZ-S.js","names":["UdpAppProvider: React.FC<UdpAppProviderProps>"],"sources":["../src/utilities/i18n/initializeI18n.js","../src/providers/UdpAppProvider.tsx"],"sourcesContent":["import i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport LanguageDetector from 'i18next-browser-languagedetector';\nimport { apiMutate } from '../useAxiosMutate';\nimport { ConfigService } from '../../configService';\n\n/**\n * @typedef {Object} TenantTranslationItem\n * @property {string} label\n * @property {string} value\n */\n\n/**\n * @callback TranslationLoader\n * @param {string} language\n * @returns {Promise<Record<string, string>>}\n */\n\n/**\n * @typedef {Object} InitializeI18nOptions\n * @property {TranslationLoader} [loadTranslations]\n * @property {Partial<import('i18next').InitOptions>} [i18nConfig]\n * @property {string} [fallbackLanguage]\n */\n\nlet isInitialized = false;\n\n/**\n * Convert the API response into an i18next resource bundle.\n * @param {TenantTranslationItem[]} languageData\n * @returns {Record<string, string>}\n */\nconst buildTranslationMap = (languageData = []) => {\n return languageData.reduce((acc, item) => {\n if (item?.label) {\n acc[item.label] = item?.value ?? '';\n }\n return acc;\n }, /** @type {Record<string, string>} */ ({}));\n};\n\n/** @type {TranslationLoader} */\nconst defaultTranslationLoader = async (language) => {\n await ConfigService.waitForConfig?.();\n const response = await apiMutate(\n ConfigService.tenantV1ApiUrl,\n `translation/language/${language}`,\n { method: 'get' }\n );\n\n const languageData = Array.isArray(response?.data) ? response.data : [];\n return buildTranslationMap(languageData);\n};\n\n/**\n * Initializes the shared i18n instance used across UDP React applications.\n * Safe to call multiple times – initialization will only occur once per runtime.\n * @param {InitializeI18nOptions} [options]\n * @returns {import('i18next').i18n}\n */\nexport const initializeUnityI18n = (options = {}) => {\n if (isInitialized) {\n return i18n;\n }\n\n const fallbackLanguage = options.fallbackLanguage ?? 'en-US';\n const loadTranslations = options.loadTranslations ?? defaultTranslationLoader;\n\n /**\n * Lazy-load translations when the language changes.\n * @param {string} language\n */\n const handleLanguageChanged = async (language) => {\n if (i18n.hasResourceBundle(language, 'translation')) {\n return;\n }\n\n try {\n const bundle = await loadTranslations(language);\n i18n.addResourceBundle(language, 'translation', bundle, true, true);\n i18n.changeLanguage(language);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Failed to load translations', error);\n }\n };\n\n i18n.on('languageChanged', handleLanguageChanged);\n\n i18n\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n fallbackLng: fallbackLanguage,\n debug: false,\n detection: {\n order: ['queryString', 'cookie'],\n cache: ['cookie']\n },\n interpolation: {\n escapeValue: false\n },\n backend: {\n loadPath: ''\n },\n ...(options.i18nConfig ?? {})\n });\n\n isInitialized = true;\n return i18n;\n};\n\n/**\n * Convenience accessor for the shared i18n instance.\n * @returns {import('i18next').i18n}\n */\nexport const getI18nInstance = () => i18n;\n","import React, { ReactNode, useEffect } from 'react';\nimport { SnackbarProvider, SnackbarProviderProps } from 'notistack';\nimport { ThemeProvider } from '../utilities/theme';\nimport { AuthProvider } from '../utilities/auth/AuthProvider';\nimport {\n initializeUnityI18n,\n InitializeI18nOptions\n} from '../utilities/i18n/initializeI18n';\nimport { storeInitialPath } from '../utilities/redirect';\nimport { storeInitialTenant } from '../utilities/storage';\nimport { BrowserRouter } from 'react-router-dom';\n\nexport interface UdpAppProviderProps {\n children: ReactNode;\n /**\n * Props forwarded to the SnackbarProvider from notistack.\n */\n snackbarProps?: SnackbarProviderProps;\n /**\n * Props forwarded to the AuthProviderWrapper.\n */\n authProps?: {\n doNotWaitForTenant?: boolean;\n };\n /**\n * Optional configuration overrides for the shared i18n instance.\n */\n i18nOptions?: InitializeI18nOptions;\n}\n\n/**\n * Bundles the core UDP providers (theme, snackbar, auth) and ensures the shared\n * i18n instance is initialised exactly once. Intended to be rendered beneath a\n * react-router <Router /> so the auth provider has access to history.\n */\nexport const UdpAppProvider: React.FC<UdpAppProviderProps> = ({\n children,\n snackbarProps,\n authProps,\n i18nOptions\n}) => {\n useEffect(() => {\n initializeUnityI18n(i18nOptions);\n }, [i18nOptions]);\n storeInitialPath();\n storeInitialTenant();\n return (\n <AuthProvider {...authProps}>\n <ThemeProvider>\n <BrowserRouter>\n <SnackbarProvider maxSnack={3} {...snackbarProps}>\n {children}\n </SnackbarProvider>\n </BrowserRouter>\n </ThemeProvider>\n </AuthProvider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAI,gBAAgB;;;;;;AAOpB,MAAM,uBAAuB,eAAe,EAAE,KAAK;AACjD,QAAO,aAAa,QAAQ,KAAK,SAAS;AACxC,MAAI,MAAM,MACR,KAAI,KAAK,SAAS,MAAM,SAAS;AAEnC,SAAO;IACiC,EAAE,CAAE;;;AAIhD,MAAM,2BAA2B,OAAO,aAAa;AACnD,OAAM,cAAc,iBAAiB;CACrC,MAAM,WAAW,MAAM,UACrB,cAAc,gBACd,wBAAwB,YACxB,EAAE,QAAQ,OAAO,CAClB;AAGD,QAAO,oBADc,MAAM,QAAQ,UAAU,KAAK,GAAG,SAAS,OAAO,EAAE,CAC/B;;;;;;;;AAS1C,MAAa,uBAAuB,UAAU,EAAE,KAAK;AACnD,KAAI,cACF,QAAO;CAGT,MAAM,mBAAmB,QAAQ,oBAAoB;CACrD,MAAM,mBAAmB,QAAQ,oBAAoB;;;;;CAMrD,MAAM,wBAAwB,OAAO,aAAa;AAChD,MAAI,KAAK,kBAAkB,UAAU,cAAc,CACjD;AAGF,MAAI;GACF,MAAM,SAAS,MAAM,iBAAiB,SAAS;AAC/C,QAAK,kBAAkB,UAAU,eAAe,QAAQ,MAAM,KAAK;AACnE,QAAK,eAAe,SAAS;WACtB,OAAO;AAEd,WAAQ,MAAM,+BAA+B,MAAM;;;AAIvD,MAAK,GAAG,mBAAmB,sBAAsB;AAEjD,MACG,IAAI,iBAAiB,CACrB,IAAI,iBAAiB,CACrB,KAAK;EACJ,aAAa;EACb,OAAO;EACP,WAAW;GACT,OAAO,CAAC,eAAe,SAAS;GAChC,OAAO,CAAC,SAAS;GAClB;EACD,eAAe,EACb,aAAa,OACd;EACD,SAAS,EACP,UAAU,IACX;EACD,GAAI,QAAQ,cAAc,EAAE;EAC7B,CAAC;AAEJ,iBAAgB;AAChB,QAAO;;;;;;AAOT,MAAa,wBAAwB;;;;;;;;;ACjFrC,MAAaA,kBAAiD,EAC5D,UACA,eACA,WACA,kBACI;AACJ,iBAAgB;AACd,sBAAoB,YAAY;IAC/B,CAAC,YAAY,CAAC;AACjB,mBAAkB;AAClB,qBAAoB;AACpB,QACE,oCAAC,cAAiB,WAChB,oCAAC,qBACC,oCAAC,qBACC,oCAAC;EAAiB,UAAU;EAAG,GAAI;IAChC,SACgB,CACL,CACF,CACH"}
|
|
@@ -23,7 +23,8 @@ const UdpFormsSubmissionStatusEnum = Object.freeze({
|
|
|
23
23
|
});
|
|
24
24
|
const dateFormatter = (dateString) => {
|
|
25
25
|
let normalizedDateString = dateString;
|
|
26
|
-
if (dateString.includes(" ")
|
|
26
|
+
if (dateString.includes(" ")) normalizedDateString = dateString.replace(" ", "T");
|
|
27
|
+
if (!dateString.toUpperCase().endsWith("Z")) normalizedDateString = normalizedDateString + "Z";
|
|
27
28
|
return new Date(normalizedDateString).toLocaleString(void 0, {
|
|
28
29
|
year: "numeric",
|
|
29
30
|
month: "short",
|
|
@@ -717,4 +718,4 @@ const UdpFormsSubmissionGrid = ({ isManagerMode = false, generic1 = void 0, gene
|
|
|
717
718
|
|
|
718
719
|
//#endregion
|
|
719
720
|
export { UdpFormsSubmissionGrid as t };
|
|
720
|
-
//# sourceMappingURL=UdpFormsSubmissionGrid-
|
|
721
|
+
//# sourceMappingURL=UdpFormsSubmissionGrid-B2V--6Rl.js.map
|
package/dist/{UdpFormsSubmissionGrid-C5CDtEVR.js.map → UdpFormsSubmissionGrid-B2V--6Rl.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UdpFormsSubmissionGrid-C5CDtEVR.js","names":["CustomMenuPage"],"sources":["../src/udp/pages/UdpFormsSubmissionGrid/UdpFormsSubmissionGrid.jsx"],"sourcesContent":["import React, {\n useMemo,\n useState,\n useEffect,\n useCallback,\n useRef\n} from 'react';\nimport { useUser } from '../../../utilities/auth/useUser';\nimport { useTenant } from '../../../utilities/tenant/useTenant';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { useSnackbar } from 'notistack';\nimport { CustomMenuPage } from '../../../menuPage';\nimport { useTranslation } from 'react-i18next';\nimport { apiMutate } from '../../../utilities';\nimport { ConfigService } from '../../../configService';\nimport { SearchMethodUdpGrid } from '../../../UI/templates/newGrid';\nimport { LoadingIndicator } from '../../../UI/loading/LoadingIndicator';\nimport { UdpPageEnums } from '../../../enums';\nimport { StatusCellRenderer } from '../../../UI/templates/ui/renderers';\nimport { SqlFilterOperators } from '../../../enums/aggridEnums';\nimport { SideSheet } from '../../../UI/surfaces/SideSheet';\nimport { Autocomplete } from '@material-ui/lab';\nimport { TextField } from '@material-ui/core';\nimport { PageLoading } from '../../../UI';\n\nconst UdpFormsSubmissionStatusEnum = Object.freeze({\n InProgress: 1,\n Submitted: 2,\n Created: 3\n});\n\nconst dateFormatter = (dateString) => {\n let normalizedDateString = dateString;\n\n // Check if the string is in the 'YYYY-MM-DD HH:mm:ss.sss' format (i.e., contains a space, not 'T')\n // If the input is '2025-12-10T20:23:23.055Z', it passes straight through.\n // This format is assumed to be missing timezone info and needs to be treated as UTC.\n if (dateString.includes(' ') && !dateString.includes('Z')) {\n // Replace the space with 'T' and append 'Z' to enforce UTC interpretation\n normalizedDateString = dateString.replace(' ', 'T') + 'Z';\n }\n\n const date = new Date(normalizedDateString);\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\nconst filterConfigByUrlField = {\n form_name: { agGridField: 'form_Name', filterType: 'text' },\n formsubmission_formversion: {\n agGridField: 'formSubmission_FormVersion',\n filterType: 'number'\n },\n form_description: { agGridField: 'form_Description', filterType: 'text' },\n formsubmission_userdisplayname: {\n agGridField: 'formSubmission_UserDisplayName',\n filterType: 'text'\n },\n formsubmission_status: {\n agGridField: 'formSubmission_Status',\n filterType: 'number'\n },\n formsubmission_initialcreatedon: {\n agGridField: 'formSubmission_InitialCreatedOn',\n filterType: 'date'\n },\n formsubmission_lastmodifiedon: {\n agGridField: 'formSubmission_LastModifiedOn',\n filterType: 'date'\n },\n formsubmission_submittedon: {\n agGridField: 'formSubmission_SubmittedOn',\n filterType: 'date'\n },\n formsubmission_duedate: {\n agGridField: 'formSubmission_DueDate',\n filterType: 'date'\n },\n formsubmission_isoverdue: {\n agGridField: 'formSubmission_IsOverdue',\n filterType: 'text'\n }\n};\n\n// --- NEW HELPER FUNCTION ---\n/**\n * Maps your internal filter object structure (from URL processing)\n * to the ag-Grid Filter Model structure.\n * * @param {Array<{searchField: string, searchOperator: number, searchValue: string}>} filterObjects\n * @returns {object} ag-Grid Filter Model\n */\n/**\n * Maps your internal filter object structure (from URL processing)\n * to the ag-Grid Filter Model structure.\n * @param {Array<{searchField: string, searchOperator: number, searchValue: string}>} filterObjects\n * @returns {object} ag-Grid Filter Model\n */\nconst mapUrlFiltersToAgGridModel = (filterObjects) => {\n if (!filterObjects || filterObjects.length === 0) {\n return null;\n }\n\n const agGridModel = {};\n\n filterObjects.forEach((filter) => {\n const { searchField, searchOperator, searchValue } = filter;\n\n const searchKey = searchField.toLocaleLowerCase();\n const config = filterConfigByUrlField[searchKey];\n\n if (!config) {\n console.warn(\n `No configuration found for URL filter field: ${searchField}. Filter ignored.`\n );\n return;\n }\n\n const agGridField = config.agGridField;\n const filterType = config.filterType;\n\n let type = 'equals';\n switch (searchOperator) {\n case SqlFilterOperators.EQUALS:\n type = 'equals';\n break;\n case SqlFilterOperators.NOT_EQUALS:\n type = 'notEqual';\n break;\n case SqlFilterOperators.GREATER_THAN:\n type = 'greaterThan';\n break;\n case SqlFilterOperators.LESS_THAN:\n type = 'lessThan';\n break;\n case SqlFilterOperators.LIKE:\n type = 'contains';\n break;\n default:\n type = 'equals';\n }\n\n let filterValue = searchValue;\n\n if (\n !filterValue ||\n filterValue.toLowerCase() === 'undefined' ||\n filterValue.toLowerCase() === 'null'\n ) {\n console.warn(\n `Skipping filter for ${agGridField} due to invalid value: ${searchValue}`\n );\n return; \n }\n\n if (filterType == 'date'){\n agGridModel[agGridField] = {\n filterType,\n type,\n dateFrom: filterValue \n };\n } else if (filterType == 'text' && agGridField.toLocaleLowerCase() == 'formsubmission_isoverdue') {\n agGridModel[agGridField] = {\n filterType,\n type: filterValue,\n };\n } else {\n agGridModel[agGridField] = {\n filterType,\n type,\n filter: filterValue \n };\n }\n\n });\n\n return agGridModel;\n};\n\nexport const UdpFormsSubmissionGrid = ({\n isManagerMode = false,\n generic1 = undefined,\n generic2 = undefined,\n generic3 = undefined,\n formsRendererUrlPath = undefined\n}) => {\n const user = useUser();\n const tenant = useTenant();\n const history = useHistory();\n const location = useLocation();\n const { t } = useTranslation();\n const { enqueueSnackbar, closeSnackbar } = useSnackbar();\n const [innerMenuItemList, setInnerMenuItemList] = useState([]);\n const [formSubmissionViewDataRaw, setFormSubmissionViewDataRaw] = useState([]);\n const [formDataRaw, setFormDataRaw] = useState([]);\n const [isSidesheetOpen, setIsSidesheetOpen] = useState(false);\n const [selectedUdpFormInSideSheet, setSelectedUdpFormInSideSheet] = useState({});\n const [formSubmissionUrlSearchObjs, setFormSubmissionUrlSearchObjs] = useState([]);\n\n const [gridApi, setGridApi] = useState(null); \n const handleGridApiCallback = useCallback((api) => {setGridApi(api); }, []);\n\n const initialFilterModel = useMemo(() => {\n return mapUrlFiltersToAgGridModel(formSubmissionUrlSearchObjs);\n }, [formSubmissionUrlSearchObjs]); \n\n useEffect(() => {\n if (gridApi && initialFilterModel) {\n gridApi.setFilterModel(initialFilterModel);\n gridApi.onFilterChanged();\n }\n }, [gridApi, initialFilterModel]);\n\n const buildFormSubmissionSearchParams = useCallback((search) => {\n const qs = new URLSearchParams(search);\n const filterObjects = [];\n qs.forEach((value, key) => {\n if (key.startsWith('udp_search')) {\n const keyParts = key.split('-');\n const searchField = keyParts[1] || undefined;\n const searchOperatorRaw = keyParts[2] || undefined;\n const searchOperator =\n SqlFilterOperators[searchOperatorRaw?.toUpperCase()] || undefined;\n const searchValue = value || undefined;\n if (searchField && searchOperator && searchValue) {\n filterObjects.push({\n searchField,\n searchOperator,\n searchValue\n });\n }\n }\n });\n return filterObjects;\n }, []);\n\n const handleSideSheetClosed = () => {\n setSelectedUdpFormInSideSheet({});\n setIsSidesheetOpen(false);\n };\n\n const consolidateAndSortFormsByFormId = useCallback(\n (forms, submissions = []) => {\n const resultMap = new Map();\n for (const item of forms) {\n const {\n id: formId,\n version: formVersion,\n name: formName,\n description: formDescription,\n initialCreatedOn: initialCreatedOn\n } = item;\n if (!formId || formVersion == null) continue;\n\n const key = String(formId);\n const existing = resultMap.get(key);\n\n // normalize version and timestamp\n const versionNum = Number(formVersion) || 0;\n const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;\n\n // robust comparison (coerce to string)\n const submissionCount = (submissions || []).filter(\n (sub) => String(sub?.formSubmission_FormId) === key\n ).length;\n\n if (!existing) {\n resultMap.set(key, {\n id: key,\n formId,\n formVersion: versionNum,\n name: formName || t('Untitled Form'),\n submissionCount,\n description: formDescription || '',\n mostRecentCreatedOn: ts\n });\n } else {\n // keep metadata (name/description/formVersion) from the highest version seen\n if (versionNum > (existing.formVersion || 0)) {\n existing.formVersion = versionNum;\n if (formName) existing.name = formName;\n if (formDescription) existing.description = formDescription;\n }\n }\n }\n\n const sortedOptions = Array.from(resultMap.values()).sort((a, b) =>\n b.name.localeCompare(a.name)\n );\n return sortedOptions;\n },\n [t]\n );\n\n const consolidateAndSortFormSubmissionsByFormId = useCallback(\n (submissions) => {\n const resultMap = new Map();\n for (const item of submissions) {\n const {\n formSubmission_FormId: formId,\n formSubmission_FormVersion: formVersion,\n form_Name: formName,\n form_Description: formDescription,\n formSubmission_InitialCreatedOn: initialCreatedOn\n } = item;\n if (!formId || formVersion == null) continue;\n\n const key = `${formId}`;\n const existing = resultMap.get(key);\n\n // normalize version and timestamp\n const versionNum = Number(formVersion) || 0;\n const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;\n\n if (!existing) {\n resultMap.set(key, {\n id: key,\n formId,\n formVersion: versionNum,\n name: formName || t('Untitled Form'),\n submissionCount: 1,\n description: formDescription || '',\n mostRecentCreatedOn: ts\n });\n } else {\n existing.submissionCount += 1;\n existing.mostRecentCreatedOn = Math.max(\n existing.mostRecentCreatedOn || 0,\n ts\n );\n\n // keep metadata (name/description/formVersion) from the highest version seen\n if (versionNum > (existing.formVersion || 0)) {\n existing.formVersion = versionNum;\n if (formName) existing.name = formName;\n if (formDescription) existing.description = formDescription;\n }\n }\n }\n\n const sortedOptions = Array.from(resultMap.values()).sort(\n (a, b) => b.mostRecentCreatedOn - a.mostRecentCreatedOn\n );\n return sortedOptions;\n },\n [t]\n );\n\n const filterSubmissionByTenantId = useCallback((submissions, tenantId) => {\n return submissions.filter(\n (submission) => submission.form_TenantId === tenantId\n );\n }, []);\n\n const fetchSubmissions = useCallback(async () => {\n try {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n filterElements.push({\n searchField: 'Form_TenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'FormSubmission_UnityUserId',\n searchOperator: '=',\n searchValue: user.id\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n const formSubmissionViewSearchResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpFormWithSubmissionsView/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n const submissions = formSubmissionViewSearchResponse?.data.pageList || [];\n const processedSubmissions = filterSubmissionByTenantId(\n submissions,\n tenant.activeTenant.tenantId\n );\n setFormSubmissionViewDataRaw(processedSubmissions);\n } catch (e) {\n console.error('fetchSubmissions error:', e);\n }\n }, [\n user,\n tenant,\n isManagerMode,\n consolidateAndSortFormSubmissionsByFormId,\n t,\n generic1,\n generic2,\n generic3,\n filterSubmissionByTenantId\n ]);\n\n const fetchForms = useCallback(async () => {\n try {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n filterElements.push({\n searchField: 'tenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n const formResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpForm/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n const forms = formResponse?.data.pageList || [];\n setFormDataRaw(forms);\n } catch (e) {\n console.error('fetchForms error:', e);\n }\n }, [user, tenant, consolidateAndSortFormSubmissionsByFormId]);\n\n const parseIdAndVersion = useCallback((input) => {\n const formSubmissionId = input.replace(/^form-submission-/, '');\n // Check for \"all forms\" special case\n if (formSubmissionId.includes('all-forms-key')) {\n return null;\n }\n return formSubmissionId;\n }, []);\n\n const getSearchMethodConfig = useCallback(\n (formId) => {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'formSubmission_unityUserId',\n searchOperator: '=',\n searchValue: user.id || ''\n });\n }\n\n if (formId) {\n filterElements.push({\n searchField: 'formSubmission_formId',\n searchOperator: '=',\n searchValue: formId\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n filterElements.push({\n searchField: 'form_tenantId',\n searchOperator: '=',\n searchValue: tenant?.activeTenant?.tenantId || ''\n });\n\n return {\n requestUrl: `${ConfigService.productV1ApiUrl}/UdpFormWithSubmissionsView/search`,\n customSearchObject: {\n eagerLoad: false,\n filterElements,\n orderElements: [\n {\n sortColumn: 'initialCreatedOn',\n sortDirection: 'DESC'\n }\n ]\n }\n // logicalSearchOperator: 1,\n // groupingType: '',\n // groupProperty: [],\n // groupOperationList: [],\n // type: 'advanced',\n // pageNumber: 1,\n // pageSize: 20,\n };\n },\n [user, isManagerMode, tenant, generic1, generic2, generic3]\n );\n\n const generateFormRendererUrlPath = useCallback(\n (formId, formVersion) => {\n const baseRoute = formsRendererUrlPath\n ? formsRendererUrlPath\n : 'page/' + UdpPageEnums.Udp_Form_Renderer_Page;\n\n return `${baseRoute}?udpf_formId=${encodeURIComponent(\n formId\n )}&udpf_version=${encodeURIComponent(formVersion)}`;\n },\n [generic1, generic2, generic3, formsRendererUrlPath]\n );\n\n const getGridHeaderConfig = useCallback(\n (formId, formVersion, formTitle) => {\n const config = {\n title: formTitle\n };\n\n if (!isManagerMode) {\n config.primaryActionButton = {\n label: t('Submit New Form'),\n onClick: () => {\n // Only show submit button when we have a specific form id and version\n if (formId && formVersion) {\n const urlPath = generateFormRendererUrlPath(formId, formVersion);\n history.push(urlPath);\n } else {\n setIsSidesheetOpen(true);\n }\n }\n };\n }\n\n return config;\n },\n [history, t, isManagerMode, generateFormRendererUrlPath]\n );\n\n const getGridOptions = useCallback(() => {\n return {\n pagination: true,\n defaultColDef: {\n sortable: true,\n filter: true,\n resizable: true\n },\n };\n }, []);\n\n const getStatus = useMemo(() => {\n return {\n Created: 'info',\n InProgress: 'warning',\n Submitted: 'success',\n Overdue: 'error'\n };\n }, []);\n\n const getSubmissionStatusLabel = (node) => {\n const formStatus = node?.data?.formSubmission_Status;\n switch (formStatus) {\n case UdpFormsSubmissionStatusEnum.InProgress:\n return 'InProgress';\n case UdpFormsSubmissionStatusEnum.Created:\n return 'Created';\n case UdpFormsSubmissionStatusEnum.Submitted:\n return 'Submitted';\n default:\n return '';\n }\n };\n\n const getOverdueStatusLabel = (node) => {\n const overdueStatus = node?.data?.formSubmission_IsOverdue;\n switch (overdueStatus) {\n case true:\n return 'Overdue';\n default:\n return '';\n }\n };\n\n const columnDefs = useMemo(\n () => [\n { headerName: 'Form ID', field: 'formSubmission_FormId', hide: true },\n {\n headerName: t('Form Name'),\n field: 'form_Name',\n type: 'text',\n sortable: true\n },\n {\n headerName: t('Form Version'),\n field: 'formSubmission_FormVersion',\n type: 'number',\n sortable: true\n },\n {\n headerName: t('Description'),\n field: 'form_Description',\n type: 'text',\n sortable: true,\n hide: true\n },\n {\n headerName: t('Submitted By'),\n field: 'formSubmission_UserDisplayName',\n type: 'text',\n sortable: true\n },\n {\n headerName: t('Form Status'),\n filter: true,\n field: 'formSubmission_Status',\n cellRenderer: 'statusRenderer',\n cellRendererParams: {\n statusMappingConfig: getStatus,\n getStatusValue: getSubmissionStatusLabel\n }\n },\n {\n headerName: t('Overdue Status'),\n field: 'formSubmission_IsOverdue',\n cellDataType : \"boolean\",\n sortable: true,\n cellRenderer: 'statusRenderer',\n cellRendererParams: {\n statusMappingConfig: getStatus,\n getStatusValue: getOverdueStatusLabel\n }\n },\n {\n headerName: t('Created On'),\n field: 'formSubmission_InitialCreatedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Last Modified On'),\n field: 'formSubmission_LastModifiedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Submitted On'),\n field: 'formSubmission_SubmittedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Due On'),\n field: 'formSubmission_DueDate',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n field: 'actions',\n cellRenderer: 'actionsRenderer',\n cellRendererParams: {\n actionList: [\n {\n id: 0,\n iconName: 'view',\n title: t('Open This Submission'),\n handleOnClick: (e, params) => {\n history.push(\n `${\n formsRendererUrlPath\n ? formsRendererUrlPath\n : '/page/' + UdpPageEnums.Udp_Form_Renderer_Page\n }?udpf_submissionId=${params?.data?.formSubmission_Id}`\n );\n }\n }\n ]\n }\n }\n ],\n [history, t, formsRendererUrlPath]\n );\n\n const gridFunctions = useMemo(\n () => [\n { name: 'agGridSizeColumnsToFit' },\n { name: 'agGridAutoSizeColumns' },\n { name: 'agGridResetColumns' },\n { name: 'agGridHideShowColumns' }\n ],\n []\n );\n\n const handleSidesheetPrimaryClick = useCallback(() => {\n // selectedUdpFormInSideSheet format is \"formId|formVersion\"\n const raw = selectedUdpFormInSideSheet.value || '';\n const [id, versionStr] = raw.split('|');\n const version = Number(versionStr || 0);\n if (!id || !version) {\n console.warn('Invalid selection:', selectedUdpFormInSideSheet);\n setIsSidesheetOpen(false);\n return;\n }\n\n setIsSidesheetOpen(false);\n const urlPath = generateFormRendererUrlPath(id, version);\n history.push(urlPath);\n }, [selectedUdpFormInSideSheet, history, generateFormRendererUrlPath]);\n\n const selectableItems = useMemo(() => {\n const map = new Map();\n\n for (const f of formDataRaw || []) {\n const formType = f.form_Type ?? f.formType ?? f.type;\n if (Number(formType) !== 1) continue;\n\n const formId = f.id ?? f.form_Id ?? f.formId ?? String(f?.Id ?? '');\n const version = Number(f.version ?? f.form_Version ?? f.formVersion ?? 0);\n const name =\n f.name ??\n f.form_Name ??\n f.formName ??\n f.Form_Name ??\n f.displayName ??\n t('Untitled Form');\n const description = f.description ?? f.form_Description ?? '';\n\n const existing = map.get(formId);\n if (!existing || version > existing.version) {\n map.set(formId, { id: formId, name, version, description });\n }\n }\n\n return Array.from(map.values()).sort((a, b) => b.version - a.version);\n }, [formDataRaw, t]);\n\n const selectorOptions = useMemo(() => {\n return (selectableItems || []).map((s) => ({\n value: `${s.id}|${s.version}`,\n label: s.version ? `${s.name} (v${s.version})` : s.name\n }));\n }, [selectableItems]);\n\n const handleSelectedUdpFormInSideSheetChange = (event, newValue) => {\n if (newValue !== null) {\n setSelectedUdpFormInSideSheet(newValue);\n }\n };\n\n const getMainGridContent = ({\n selectedNode,\n menuItemsList,\n idMap,\n classes\n }) => {\n if (!selectedNode) {\n return <PageLoading />;\n }\n const formId = parseIdAndVersion(selectedNode.id);\n const found = innerMenuItemList.find((form) => form.formId == formId);\n const formTitle = `${found?.name}` || 'Unknown Form';\n const newestFormVersion = formDataRaw\n .filter((formObj) => formObj.id == formId)\n .reduce((acc, curr) => {\n return Math.max(acc, curr.version);\n }, 0);\n\n return (\n <>\n <SideSheet\n open={isSidesheetOpen}\n title={t('Submit New Form')}\n position='right'\n width={'30%'}\n buttonLabel={t('New')}\n buttonOneDisabled={!selectedUdpFormInSideSheet.value}\n onSubmit={handleSidesheetPrimaryClick}\n onClose={handleSideSheetClosed}\n >\n <Autocomplete\n options={selectorOptions}\n getOptionLabel={(selectedOption) => selectedOption.label}\n onChange={handleSelectedUdpFormInSideSheetChange}\n value={selectedUdpFormInSideSheet.value}\n size='small'\n renderInput={(params) => (\n <TextField {...params} label='Choose a Form' variant='outlined' />\n )}\n />\n </SideSheet>\n <SearchMethodUdpGrid\n searchMethodConfig={getSearchMethodConfig(formId)}\n columnDefs={columnDefs}\n gridOptions={getGridOptions()}\n gridHeaderConfig={getGridHeaderConfig(\n formId,\n newestFormVersion,\n formTitle\n )}\n gridFunctions={gridFunctions}\n gridApiCallback={handleGridApiCallback} // Pass the setter/ref handler\n />\n </>\n );\n };\n\n useEffect(() => {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const urlSearchObjs = buildFormSubmissionSearchParams(location.search);\n setFormSubmissionUrlSearchObjs(urlSearchObjs); // THIS LINE TRIGGERS initialFilterModel\n\n let cancelled = false;\n (async () => {\n try {\n // replicate fetchSubmissions logic but using local urlSearchObjs (avoids depending on the state)\n let filterElements = [];\n\n filterElements.push({\n searchField: 'Form_TenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'FormSubmission_UnityUserId',\n searchOperator: '=',\n searchValue: user.id\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n const formSubmissionViewSearchResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpFormWithSubmissionsView/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n if (cancelled) return;\n\n const submissions = formSubmissionViewSearchResponse?.data.pageList || [];\n const processedSubmissions = submissions.filter((submission) =>\n submission.form_TenantId === tenant.activeTenant.tenantId\n );\n setFormSubmissionViewDataRaw(processedSubmissions);\n await fetchForms();\n } catch (err) {\n console.error('fetching submissions/forms failed', err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [\n location.search,\n tenant?.activeTenant?.tenantId,\n generic1,\n generic2,\n generic3,\n isManagerMode,\n user?.id,\n fetchForms,\n buildFormSubmissionSearchParams\n ]);\n\n // derive menu items from fetched submissions (separate effect to avoid refetch loop)\n useEffect(() => {\n const innerMenuList = consolidateAndSortFormsByFormId(\n formDataRaw || [],\n formSubmissionViewDataRaw || []\n );\n\n innerMenuList.unshift({\n id: 'all-forms-key',\n name: t(\n isManagerMode ? t('All Form Submissions') : t('All My Form Submissions')\n ),\n submissionCount: formSubmissionViewDataRaw?.length || 0\n });\n setInnerMenuItemList(innerMenuList);\n }, [\n formSubmissionViewDataRaw,\n isManagerMode,\n consolidateAndSortFormsByFormId,\n formDataRaw,\n t\n ]);\n\n return (\n <div>\n <CustomMenuPage\n menuTitle={t('Forms')}\n items={innerMenuItemList}\n idPrefix='form-submission'\n showItemCount={true}\n itemCountAccessor={(item) => item?.submissionCount ?? 0}\n mainContent={({ selectedNode, menuItemsList, idMap, classes }) => {\n return (\n <div>\n {getMainGridContent({\n selectedNode,\n menuItemsList,\n idMap,\n classes\n })}\n </div>\n );\n }}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UdpFormsSubmissionGrid-B2V--6Rl.js","names":["CustomMenuPage"],"sources":["../src/udp/pages/UdpFormsSubmissionGrid/UdpFormsSubmissionGrid.jsx"],"sourcesContent":["import React, {\n useMemo,\n useState,\n useEffect,\n useCallback,\n useRef\n} from 'react';\nimport { useUser } from '../../../utilities/auth/useUser';\nimport { useTenant } from '../../../utilities/tenant/useTenant';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { useSnackbar } from 'notistack';\nimport { CustomMenuPage } from '../../../menuPage';\nimport { useTranslation } from 'react-i18next';\nimport { apiMutate } from '../../../utilities';\nimport { ConfigService } from '../../../configService';\nimport { SearchMethodUdpGrid } from '../../../UI/templates/newGrid';\nimport { LoadingIndicator } from '../../../UI/loading/LoadingIndicator';\nimport { UdpPageEnums } from '../../../enums';\nimport { StatusCellRenderer } from '../../../UI/templates/ui/renderers';\nimport { SqlFilterOperators } from '../../../enums/aggridEnums';\nimport { SideSheet } from '../../../UI/surfaces/SideSheet';\nimport { Autocomplete } from '@material-ui/lab';\nimport { TextField } from '@material-ui/core';\nimport { PageLoading } from '../../../UI';\n\nconst UdpFormsSubmissionStatusEnum = Object.freeze({\n InProgress: 1,\n Submitted: 2,\n Created: 3\n});\n\nconst dateFormatter = (dateString) => {\n let normalizedDateString = dateString;\n\n // Check if the string is in the 'YYYY-MM-DD HH:mm:ss.sss' format (i.e., contains a space, not 'T')\n // If the input is '2025-12-10T20:23:23.055Z', it passes straight through.\n // This format is assumed to be missing timezone info and needs to be treated as UTC.\n if (dateString.includes(' ')) {\n // Replace the space with 'T' \n normalizedDateString = dateString.replace(' ', 'T');\n }\n\n if (!dateString.toUpperCase().endsWith('Z')) {\n // append Z if not there\n normalizedDateString = normalizedDateString + 'Z';\n }\n\n const date = new Date(normalizedDateString);\n\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\nconst filterConfigByUrlField = {\n form_name: { agGridField: 'form_Name', filterType: 'text' },\n formsubmission_formversion: {\n agGridField: 'formSubmission_FormVersion',\n filterType: 'number'\n },\n form_description: { agGridField: 'form_Description', filterType: 'text' },\n formsubmission_userdisplayname: {\n agGridField: 'formSubmission_UserDisplayName',\n filterType: 'text'\n },\n formsubmission_status: {\n agGridField: 'formSubmission_Status',\n filterType: 'number'\n },\n formsubmission_initialcreatedon: {\n agGridField: 'formSubmission_InitialCreatedOn',\n filterType: 'date'\n },\n formsubmission_lastmodifiedon: {\n agGridField: 'formSubmission_LastModifiedOn',\n filterType: 'date'\n },\n formsubmission_submittedon: {\n agGridField: 'formSubmission_SubmittedOn',\n filterType: 'date'\n },\n formsubmission_duedate: {\n agGridField: 'formSubmission_DueDate',\n filterType: 'date'\n },\n formsubmission_isoverdue: {\n agGridField: 'formSubmission_IsOverdue',\n filterType: 'text'\n }\n};\n\n// --- NEW HELPER FUNCTION ---\n/**\n * Maps your internal filter object structure (from URL processing)\n * to the ag-Grid Filter Model structure.\n * * @param {Array<{searchField: string, searchOperator: number, searchValue: string}>} filterObjects\n * @returns {object} ag-Grid Filter Model\n */\n/**\n * Maps your internal filter object structure (from URL processing)\n * to the ag-Grid Filter Model structure.\n * @param {Array<{searchField: string, searchOperator: number, searchValue: string}>} filterObjects\n * @returns {object} ag-Grid Filter Model\n */\nconst mapUrlFiltersToAgGridModel = (filterObjects) => {\n if (!filterObjects || filterObjects.length === 0) {\n return null;\n }\n\n const agGridModel = {};\n\n filterObjects.forEach((filter) => {\n const { searchField, searchOperator, searchValue } = filter;\n\n const searchKey = searchField.toLocaleLowerCase();\n const config = filterConfigByUrlField[searchKey];\n\n if (!config) {\n console.warn(\n `No configuration found for URL filter field: ${searchField}. Filter ignored.`\n );\n return;\n }\n\n const agGridField = config.agGridField;\n const filterType = config.filterType;\n\n let type = 'equals';\n switch (searchOperator) {\n case SqlFilterOperators.EQUALS:\n type = 'equals';\n break;\n case SqlFilterOperators.NOT_EQUALS:\n type = 'notEqual';\n break;\n case SqlFilterOperators.GREATER_THAN:\n type = 'greaterThan';\n break;\n case SqlFilterOperators.LESS_THAN:\n type = 'lessThan';\n break;\n case SqlFilterOperators.LIKE:\n type = 'contains';\n break;\n default:\n type = 'equals';\n }\n\n let filterValue = searchValue;\n\n if (\n !filterValue ||\n filterValue.toLowerCase() === 'undefined' ||\n filterValue.toLowerCase() === 'null'\n ) {\n console.warn(\n `Skipping filter for ${agGridField} due to invalid value: ${searchValue}`\n );\n return; \n }\n\n if (filterType == 'date'){\n agGridModel[agGridField] = {\n filterType,\n type,\n dateFrom: filterValue \n };\n } else if (filterType == 'text' && agGridField.toLocaleLowerCase() == 'formsubmission_isoverdue') {\n agGridModel[agGridField] = {\n filterType,\n type: filterValue,\n };\n } else {\n agGridModel[agGridField] = {\n filterType,\n type,\n filter: filterValue \n };\n }\n\n });\n\n return agGridModel;\n};\n\nexport const UdpFormsSubmissionGrid = ({\n isManagerMode = false,\n generic1 = undefined,\n generic2 = undefined,\n generic3 = undefined,\n formsRendererUrlPath = undefined\n}) => {\n const user = useUser();\n const tenant = useTenant();\n const history = useHistory();\n const location = useLocation();\n const { t } = useTranslation();\n const { enqueueSnackbar, closeSnackbar } = useSnackbar();\n const [innerMenuItemList, setInnerMenuItemList] = useState([]);\n const [formSubmissionViewDataRaw, setFormSubmissionViewDataRaw] = useState([]);\n const [formDataRaw, setFormDataRaw] = useState([]);\n const [isSidesheetOpen, setIsSidesheetOpen] = useState(false);\n const [selectedUdpFormInSideSheet, setSelectedUdpFormInSideSheet] = useState({});\n const [formSubmissionUrlSearchObjs, setFormSubmissionUrlSearchObjs] = useState([]);\n\n const [gridApi, setGridApi] = useState(null); \n const handleGridApiCallback = useCallback((api) => {setGridApi(api); }, []);\n\n const initialFilterModel = useMemo(() => {\n return mapUrlFiltersToAgGridModel(formSubmissionUrlSearchObjs);\n }, [formSubmissionUrlSearchObjs]); \n\n useEffect(() => {\n if (gridApi && initialFilterModel) {\n gridApi.setFilterModel(initialFilterModel);\n gridApi.onFilterChanged();\n }\n }, [gridApi, initialFilterModel]);\n\n const buildFormSubmissionSearchParams = useCallback((search) => {\n const qs = new URLSearchParams(search);\n const filterObjects = [];\n qs.forEach((value, key) => {\n if (key.startsWith('udp_search')) {\n const keyParts = key.split('-');\n const searchField = keyParts[1] || undefined;\n const searchOperatorRaw = keyParts[2] || undefined;\n const searchOperator =\n SqlFilterOperators[searchOperatorRaw?.toUpperCase()] || undefined;\n const searchValue = value || undefined;\n if (searchField && searchOperator && searchValue) {\n filterObjects.push({\n searchField,\n searchOperator,\n searchValue\n });\n }\n }\n });\n return filterObjects;\n }, []);\n\n const handleSideSheetClosed = () => {\n setSelectedUdpFormInSideSheet({});\n setIsSidesheetOpen(false);\n };\n\n const consolidateAndSortFormsByFormId = useCallback(\n (forms, submissions = []) => {\n const resultMap = new Map();\n for (const item of forms) {\n const {\n id: formId,\n version: formVersion,\n name: formName,\n description: formDescription,\n initialCreatedOn: initialCreatedOn\n } = item;\n if (!formId || formVersion == null) continue;\n\n const key = String(formId);\n const existing = resultMap.get(key);\n\n // normalize version and timestamp\n const versionNum = Number(formVersion) || 0;\n const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;\n\n // robust comparison (coerce to string)\n const submissionCount = (submissions || []).filter(\n (sub) => String(sub?.formSubmission_FormId) === key\n ).length;\n\n if (!existing) {\n resultMap.set(key, {\n id: key,\n formId,\n formVersion: versionNum,\n name: formName || t('Untitled Form'),\n submissionCount,\n description: formDescription || '',\n mostRecentCreatedOn: ts\n });\n } else {\n // keep metadata (name/description/formVersion) from the highest version seen\n if (versionNum > (existing.formVersion || 0)) {\n existing.formVersion = versionNum;\n if (formName) existing.name = formName;\n if (formDescription) existing.description = formDescription;\n }\n }\n }\n\n const sortedOptions = Array.from(resultMap.values()).sort((a, b) =>\n b.name.localeCompare(a.name)\n );\n return sortedOptions;\n },\n [t]\n );\n\n const consolidateAndSortFormSubmissionsByFormId = useCallback(\n (submissions) => {\n const resultMap = new Map();\n for (const item of submissions) {\n const {\n formSubmission_FormId: formId,\n formSubmission_FormVersion: formVersion,\n form_Name: formName,\n form_Description: formDescription,\n formSubmission_InitialCreatedOn: initialCreatedOn\n } = item;\n if (!formId || formVersion == null) continue;\n\n const key = `${formId}`;\n const existing = resultMap.get(key);\n\n // normalize version and timestamp\n const versionNum = Number(formVersion) || 0;\n const ts = initialCreatedOn ? new Date(initialCreatedOn).getTime() : 0;\n\n if (!existing) {\n resultMap.set(key, {\n id: key,\n formId,\n formVersion: versionNum,\n name: formName || t('Untitled Form'),\n submissionCount: 1,\n description: formDescription || '',\n mostRecentCreatedOn: ts\n });\n } else {\n existing.submissionCount += 1;\n existing.mostRecentCreatedOn = Math.max(\n existing.mostRecentCreatedOn || 0,\n ts\n );\n\n // keep metadata (name/description/formVersion) from the highest version seen\n if (versionNum > (existing.formVersion || 0)) {\n existing.formVersion = versionNum;\n if (formName) existing.name = formName;\n if (formDescription) existing.description = formDescription;\n }\n }\n }\n\n const sortedOptions = Array.from(resultMap.values()).sort(\n (a, b) => b.mostRecentCreatedOn - a.mostRecentCreatedOn\n );\n return sortedOptions;\n },\n [t]\n );\n\n const filterSubmissionByTenantId = useCallback((submissions, tenantId) => {\n return submissions.filter(\n (submission) => submission.form_TenantId === tenantId\n );\n }, []);\n\n const fetchSubmissions = useCallback(async () => {\n try {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n filterElements.push({\n searchField: 'Form_TenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'FormSubmission_UnityUserId',\n searchOperator: '=',\n searchValue: user.id\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n const formSubmissionViewSearchResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpFormWithSubmissionsView/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n const submissions = formSubmissionViewSearchResponse?.data.pageList || [];\n const processedSubmissions = filterSubmissionByTenantId(\n submissions,\n tenant.activeTenant.tenantId\n );\n setFormSubmissionViewDataRaw(processedSubmissions);\n } catch (e) {\n console.error('fetchSubmissions error:', e);\n }\n }, [\n user,\n tenant,\n isManagerMode,\n consolidateAndSortFormSubmissionsByFormId,\n t,\n generic1,\n generic2,\n generic3,\n filterSubmissionByTenantId\n ]);\n\n const fetchForms = useCallback(async () => {\n try {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n filterElements.push({\n searchField: 'tenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n const formResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpForm/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n const forms = formResponse?.data.pageList || [];\n setFormDataRaw(forms);\n } catch (e) {\n console.error('fetchForms error:', e);\n }\n }, [user, tenant, consolidateAndSortFormSubmissionsByFormId]);\n\n const parseIdAndVersion = useCallback((input) => {\n const formSubmissionId = input.replace(/^form-submission-/, '');\n // Check for \"all forms\" special case\n if (formSubmissionId.includes('all-forms-key')) {\n return null;\n }\n return formSubmissionId;\n }, []);\n\n const getSearchMethodConfig = useCallback(\n (formId) => {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const filterElements = [];\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'formSubmission_unityUserId',\n searchOperator: '=',\n searchValue: user.id || ''\n });\n }\n\n if (formId) {\n filterElements.push({\n searchField: 'formSubmission_formId',\n searchOperator: '=',\n searchValue: formId\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n filterElements.push({\n searchField: 'form_tenantId',\n searchOperator: '=',\n searchValue: tenant?.activeTenant?.tenantId || ''\n });\n\n return {\n requestUrl: `${ConfigService.productV1ApiUrl}/UdpFormWithSubmissionsView/search`,\n customSearchObject: {\n eagerLoad: false,\n filterElements,\n orderElements: [\n {\n sortColumn: 'initialCreatedOn',\n sortDirection: 'DESC'\n }\n ]\n }\n // logicalSearchOperator: 1,\n // groupingType: '',\n // groupProperty: [],\n // groupOperationList: [],\n // type: 'advanced',\n // pageNumber: 1,\n // pageSize: 20,\n };\n },\n [user, isManagerMode, tenant, generic1, generic2, generic3]\n );\n\n const generateFormRendererUrlPath = useCallback(\n (formId, formVersion) => {\n const baseRoute = formsRendererUrlPath\n ? formsRendererUrlPath\n : 'page/' + UdpPageEnums.Udp_Form_Renderer_Page;\n\n return `${baseRoute}?udpf_formId=${encodeURIComponent(\n formId\n )}&udpf_version=${encodeURIComponent(formVersion)}`;\n },\n [generic1, generic2, generic3, formsRendererUrlPath]\n );\n\n const getGridHeaderConfig = useCallback(\n (formId, formVersion, formTitle) => {\n const config = {\n title: formTitle\n };\n\n if (!isManagerMode) {\n config.primaryActionButton = {\n label: t('Submit New Form'),\n onClick: () => {\n // Only show submit button when we have a specific form id and version\n if (formId && formVersion) {\n const urlPath = generateFormRendererUrlPath(formId, formVersion);\n history.push(urlPath);\n } else {\n setIsSidesheetOpen(true);\n }\n }\n };\n }\n\n return config;\n },\n [history, t, isManagerMode, generateFormRendererUrlPath]\n );\n\n const getGridOptions = useCallback(() => {\n return {\n pagination: true,\n defaultColDef: {\n sortable: true,\n filter: true,\n resizable: true\n },\n };\n }, []);\n\n const getStatus = useMemo(() => {\n return {\n Created: 'info',\n InProgress: 'warning',\n Submitted: 'success',\n Overdue: 'error'\n };\n }, []);\n\n const getSubmissionStatusLabel = (node) => {\n const formStatus = node?.data?.formSubmission_Status;\n switch (formStatus) {\n case UdpFormsSubmissionStatusEnum.InProgress:\n return 'InProgress';\n case UdpFormsSubmissionStatusEnum.Created:\n return 'Created';\n case UdpFormsSubmissionStatusEnum.Submitted:\n return 'Submitted';\n default:\n return '';\n }\n };\n\n const getOverdueStatusLabel = (node) => {\n const overdueStatus = node?.data?.formSubmission_IsOverdue;\n switch (overdueStatus) {\n case true:\n return 'Overdue';\n default:\n return '';\n }\n };\n\n const columnDefs = useMemo(\n () => [\n { headerName: 'Form ID', field: 'formSubmission_FormId', hide: true },\n {\n headerName: t('Form Name'),\n field: 'form_Name',\n type: 'text',\n sortable: true\n },\n {\n headerName: t('Form Version'),\n field: 'formSubmission_FormVersion',\n type: 'number',\n sortable: true\n },\n {\n headerName: t('Description'),\n field: 'form_Description',\n type: 'text',\n sortable: true,\n hide: true\n },\n {\n headerName: t('Submitted By'),\n field: 'formSubmission_UserDisplayName',\n type: 'text',\n sortable: true\n },\n {\n headerName: t('Form Status'),\n filter: true,\n field: 'formSubmission_Status',\n cellRenderer: 'statusRenderer',\n cellRendererParams: {\n statusMappingConfig: getStatus,\n getStatusValue: getSubmissionStatusLabel\n }\n },\n {\n headerName: t('Overdue Status'),\n field: 'formSubmission_IsOverdue',\n cellDataType : \"boolean\",\n sortable: true,\n cellRenderer: 'statusRenderer',\n cellRendererParams: {\n statusMappingConfig: getStatus,\n getStatusValue: getOverdueStatusLabel\n }\n },\n {\n headerName: t('Created On'),\n field: 'formSubmission_InitialCreatedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Last Modified On'),\n field: 'formSubmission_LastModifiedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Submitted On'),\n field: 'formSubmission_SubmittedOn',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n headerName: t('Due On'),\n field: 'formSubmission_DueDate',\n valueFormatter: (p) => (p.value ? dateFormatter(p.value) : ''),\n sortable: true,\n cellDataType: 'dateTimeString'\n },\n {\n field: 'actions',\n cellRenderer: 'actionsRenderer',\n cellRendererParams: {\n actionList: [\n {\n id: 0,\n iconName: 'view',\n title: t('Open This Submission'),\n handleOnClick: (e, params) => {\n history.push(\n `${\n formsRendererUrlPath\n ? formsRendererUrlPath\n : '/page/' + UdpPageEnums.Udp_Form_Renderer_Page\n }?udpf_submissionId=${params?.data?.formSubmission_Id}`\n );\n }\n }\n ]\n }\n }\n ],\n [history, t, formsRendererUrlPath]\n );\n\n const gridFunctions = useMemo(\n () => [\n { name: 'agGridSizeColumnsToFit' },\n { name: 'agGridAutoSizeColumns' },\n { name: 'agGridResetColumns' },\n { name: 'agGridHideShowColumns' }\n ],\n []\n );\n\n const handleSidesheetPrimaryClick = useCallback(() => {\n // selectedUdpFormInSideSheet format is \"formId|formVersion\"\n const raw = selectedUdpFormInSideSheet.value || '';\n const [id, versionStr] = raw.split('|');\n const version = Number(versionStr || 0);\n if (!id || !version) {\n console.warn('Invalid selection:', selectedUdpFormInSideSheet);\n setIsSidesheetOpen(false);\n return;\n }\n\n setIsSidesheetOpen(false);\n const urlPath = generateFormRendererUrlPath(id, version);\n history.push(urlPath);\n }, [selectedUdpFormInSideSheet, history, generateFormRendererUrlPath]);\n\n const selectableItems = useMemo(() => {\n const map = new Map();\n\n for (const f of formDataRaw || []) {\n const formType = f.form_Type ?? f.formType ?? f.type;\n if (Number(formType) !== 1) continue;\n\n const formId = f.id ?? f.form_Id ?? f.formId ?? String(f?.Id ?? '');\n const version = Number(f.version ?? f.form_Version ?? f.formVersion ?? 0);\n const name =\n f.name ??\n f.form_Name ??\n f.formName ??\n f.Form_Name ??\n f.displayName ??\n t('Untitled Form');\n const description = f.description ?? f.form_Description ?? '';\n\n const existing = map.get(formId);\n if (!existing || version > existing.version) {\n map.set(formId, { id: formId, name, version, description });\n }\n }\n\n return Array.from(map.values()).sort((a, b) => b.version - a.version);\n }, [formDataRaw, t]);\n\n const selectorOptions = useMemo(() => {\n return (selectableItems || []).map((s) => ({\n value: `${s.id}|${s.version}`,\n label: s.version ? `${s.name} (v${s.version})` : s.name\n }));\n }, [selectableItems]);\n\n const handleSelectedUdpFormInSideSheetChange = (event, newValue) => {\n if (newValue !== null) {\n setSelectedUdpFormInSideSheet(newValue);\n }\n };\n\n const getMainGridContent = ({\n selectedNode,\n menuItemsList,\n idMap,\n classes\n }) => {\n if (!selectedNode) {\n return <PageLoading />;\n }\n const formId = parseIdAndVersion(selectedNode.id);\n const found = innerMenuItemList.find((form) => form.formId == formId);\n const formTitle = `${found?.name}` || 'Unknown Form';\n const newestFormVersion = formDataRaw\n .filter((formObj) => formObj.id == formId)\n .reduce((acc, curr) => {\n return Math.max(acc, curr.version);\n }, 0);\n\n return (\n <>\n <SideSheet\n open={isSidesheetOpen}\n title={t('Submit New Form')}\n position='right'\n width={'30%'}\n buttonLabel={t('New')}\n buttonOneDisabled={!selectedUdpFormInSideSheet.value}\n onSubmit={handleSidesheetPrimaryClick}\n onClose={handleSideSheetClosed}\n >\n <Autocomplete\n options={selectorOptions}\n getOptionLabel={(selectedOption) => selectedOption.label}\n onChange={handleSelectedUdpFormInSideSheetChange}\n value={selectedUdpFormInSideSheet.value}\n size='small'\n renderInput={(params) => (\n <TextField {...params} label='Choose a Form' variant='outlined' />\n )}\n />\n </SideSheet>\n <SearchMethodUdpGrid\n searchMethodConfig={getSearchMethodConfig(formId)}\n columnDefs={columnDefs}\n gridOptions={getGridOptions()}\n gridHeaderConfig={getGridHeaderConfig(\n formId,\n newestFormVersion,\n formTitle\n )}\n gridFunctions={gridFunctions}\n gridApiCallback={handleGridApiCallback} // Pass the setter/ref handler\n />\n </>\n );\n };\n\n useEffect(() => {\n if (!tenant?.activeTenant?.tenantId) return;\n\n const urlSearchObjs = buildFormSubmissionSearchParams(location.search);\n setFormSubmissionUrlSearchObjs(urlSearchObjs); // THIS LINE TRIGGERS initialFilterModel\n\n let cancelled = false;\n (async () => {\n try {\n // replicate fetchSubmissions logic but using local urlSearchObjs (avoids depending on the state)\n let filterElements = [];\n\n filterElements.push({\n searchField: 'Form_TenantId',\n searchOperator: '=',\n searchValue: tenant.activeTenant.tenantId\n });\n\n if (!isManagerMode) {\n filterElements.push({\n searchField: 'FormSubmission_UnityUserId',\n searchOperator: '=',\n searchValue: user.id\n });\n }\n\n if (generic1 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic1',\n searchOperator: '=',\n searchValue: generic1\n });\n }\n\n if (generic2 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic2',\n searchOperator: '=',\n searchValue: generic2\n });\n }\n\n if (generic3 !== undefined) {\n filterElements.push({\n searchField: 'formSubmission_generic3',\n searchOperator: '=',\n searchValue: generic3\n });\n }\n\n const formSubmissionViewSearchResponse = await apiMutate(\n ConfigService.productV1ApiUrl,\n `UdpFormWithSubmissionsView/search`,\n {\n method: 'POST',\n data: {\n eagerLoad: false,\n getAll: true,\n filterElements\n }\n },\n {}\n );\n\n if (cancelled) return;\n\n const submissions = formSubmissionViewSearchResponse?.data.pageList || [];\n const processedSubmissions = submissions.filter((submission) =>\n submission.form_TenantId === tenant.activeTenant.tenantId\n );\n setFormSubmissionViewDataRaw(processedSubmissions);\n await fetchForms();\n } catch (err) {\n console.error('fetching submissions/forms failed', err);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [\n location.search,\n tenant?.activeTenant?.tenantId,\n generic1,\n generic2,\n generic3,\n isManagerMode,\n user?.id,\n fetchForms,\n buildFormSubmissionSearchParams\n ]);\n\n // derive menu items from fetched submissions (separate effect to avoid refetch loop)\n useEffect(() => {\n const innerMenuList = consolidateAndSortFormsByFormId(\n formDataRaw || [],\n formSubmissionViewDataRaw || []\n );\n\n innerMenuList.unshift({\n id: 'all-forms-key',\n name: t(\n isManagerMode ? t('All Form Submissions') : t('All My Form Submissions')\n ),\n submissionCount: formSubmissionViewDataRaw?.length || 0\n });\n setInnerMenuItemList(innerMenuList);\n }, [\n formSubmissionViewDataRaw,\n isManagerMode,\n consolidateAndSortFormsByFormId,\n formDataRaw,\n t\n ]);\n\n return (\n <div>\n <CustomMenuPage\n menuTitle={t('Forms')}\n items={innerMenuItemList}\n idPrefix='form-submission'\n showItemCount={true}\n itemCountAccessor={(item) => item?.submissionCount ?? 0}\n mainContent={({ selectedNode, menuItemsList, idMap, classes }) => {\n return (\n <div>\n {getMainGridContent({\n selectedNode,\n menuItemsList,\n idMap,\n classes\n })}\n </div>\n );\n }}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { a as acquireAccessToken, c as useLogoutAction } from "./apiHelpers-WIR8
|
|
|
2
2
|
import { t as clearStoredTenant } from "./UnitySessionStorage-CUDx9YWR.js";
|
|
3
3
|
import { t as clearStoredPath } from "./LocalRedirectUrlStorage-Bxz8TI-X.js";
|
|
4
4
|
import { t as clearStoredExternalPath } from "./ExternalRedirectUrlStorage-BM-nmI4x.js";
|
|
5
|
-
import { t as AuthProvider } from "./AuthProvider-
|
|
5
|
+
import { t as AuthProvider } from "./AuthProvider-qWjJiYSg.js";
|
|
6
6
|
import React, { useState } from "react";
|
|
7
7
|
|
|
8
8
|
//#region src/utilities/auth/AuthProviderWrapper.jsx
|
|
@@ -35,4 +35,4 @@ const useAccessToken = () => {
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
export { useSingleLogout as n, AuthProviderWrapper as r, useAccessToken as t };
|
|
38
|
-
//# sourceMappingURL=auth-
|
|
38
|
+
//# sourceMappingURL=auth-DX4sNV3x.js.map
|