mirror of
https://github.com/langgenius/dify.git
synced 2025-12-19 17:27:16 -05:00
212 lines
7.0 KiB
TypeScript
212 lines
7.0 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useEffect, useMemo } from 'react'
|
|
import { createContext, useContext, useContextSelector } from 'use-context-selector'
|
|
import type { FC, ReactNode } from 'react'
|
|
import { useQueryClient } from '@tanstack/react-query'
|
|
import {
|
|
useCurrentWorkspace,
|
|
useLangGeniusVersion,
|
|
useUserProfile,
|
|
} from '@/service/use-common'
|
|
import type { ICurrentWorkspace, LangGeniusVersionResponse, UserProfileResponse } from '@/models/common'
|
|
import MaintenanceNotice from '@/app/components/header/maintenance-notice'
|
|
import { noop } from 'lodash-es'
|
|
import { setZendeskConversationFields } from '@/app/components/base/zendesk/utils'
|
|
import { ZENDESK_FIELD_IDS } from '@/config'
|
|
import { useGlobalPublicStore } from './global-public-context'
|
|
import { setUserId, setUserProperties } from '@/app/components/base/amplitude'
|
|
|
|
export type AppContextValue = {
|
|
userProfile: UserProfileResponse
|
|
mutateUserProfile: VoidFunction
|
|
currentWorkspace: ICurrentWorkspace
|
|
isCurrentWorkspaceManager: boolean
|
|
isCurrentWorkspaceOwner: boolean
|
|
isCurrentWorkspaceEditor: boolean
|
|
isCurrentWorkspaceDatasetOperator: boolean
|
|
mutateCurrentWorkspace: VoidFunction
|
|
langGeniusVersionInfo: LangGeniusVersionResponse
|
|
useSelector: typeof useSelector
|
|
isLoadingCurrentWorkspace: boolean
|
|
}
|
|
|
|
const userProfilePlaceholder = {
|
|
id: '',
|
|
name: '',
|
|
email: '',
|
|
avatar: '',
|
|
avatar_url: '',
|
|
is_password_set: false,
|
|
}
|
|
|
|
const initialLangGeniusVersionInfo = {
|
|
current_env: '',
|
|
current_version: '',
|
|
latest_version: '',
|
|
release_date: '',
|
|
release_notes: '',
|
|
version: '',
|
|
can_auto_update: false,
|
|
}
|
|
|
|
const initialWorkspaceInfo: ICurrentWorkspace = {
|
|
id: '',
|
|
name: '',
|
|
plan: '',
|
|
status: '',
|
|
created_at: 0,
|
|
role: 'normal',
|
|
providers: [],
|
|
}
|
|
|
|
const AppContext = createContext<AppContextValue>({
|
|
userProfile: userProfilePlaceholder,
|
|
currentWorkspace: initialWorkspaceInfo,
|
|
isCurrentWorkspaceManager: false,
|
|
isCurrentWorkspaceOwner: false,
|
|
isCurrentWorkspaceEditor: false,
|
|
isCurrentWorkspaceDatasetOperator: false,
|
|
mutateUserProfile: noop,
|
|
mutateCurrentWorkspace: noop,
|
|
langGeniusVersionInfo: initialLangGeniusVersionInfo,
|
|
useSelector,
|
|
isLoadingCurrentWorkspace: false,
|
|
})
|
|
|
|
export function useSelector<T>(selector: (value: AppContextValue) => T): T {
|
|
return useContextSelector(AppContext, selector)
|
|
}
|
|
|
|
export type AppContextProviderProps = {
|
|
children: ReactNode
|
|
}
|
|
|
|
export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) => {
|
|
const queryClient = useQueryClient()
|
|
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
|
const { data: userProfileResp } = useUserProfile()
|
|
const { data: currentWorkspaceResp, isPending: isLoadingCurrentWorkspace } = useCurrentWorkspace()
|
|
const langGeniusVersionQuery = useLangGeniusVersion(
|
|
userProfileResp?.meta.currentVersion,
|
|
!systemFeatures.branding.enabled,
|
|
)
|
|
|
|
const userProfile = useMemo<UserProfileResponse>(() => userProfileResp?.profile || userProfilePlaceholder, [userProfileResp?.profile])
|
|
const currentWorkspace = useMemo<ICurrentWorkspace>(() => currentWorkspaceResp || initialWorkspaceInfo, [currentWorkspaceResp])
|
|
const langGeniusVersionInfo = useMemo<LangGeniusVersionResponse>(() => {
|
|
if (!userProfileResp?.meta?.currentVersion || !langGeniusVersionQuery.data)
|
|
return initialLangGeniusVersionInfo
|
|
|
|
const current_version = userProfileResp.meta.currentVersion
|
|
const current_env = userProfileResp.meta.currentEnv || ''
|
|
const versionData = langGeniusVersionQuery.data
|
|
return {
|
|
...versionData,
|
|
current_version,
|
|
latest_version: versionData.version,
|
|
current_env,
|
|
}
|
|
}, [langGeniusVersionQuery.data, userProfileResp?.meta])
|
|
|
|
const isCurrentWorkspaceManager = useMemo(() => ['owner', 'admin'].includes(currentWorkspace.role), [currentWorkspace.role])
|
|
const isCurrentWorkspaceOwner = useMemo(() => currentWorkspace.role === 'owner', [currentWorkspace.role])
|
|
const isCurrentWorkspaceEditor = useMemo(() => ['owner', 'admin', 'editor'].includes(currentWorkspace.role), [currentWorkspace.role])
|
|
const isCurrentWorkspaceDatasetOperator = useMemo(() => currentWorkspace.role === 'dataset_operator', [currentWorkspace.role])
|
|
|
|
const mutateUserProfile = useCallback(() => {
|
|
queryClient.invalidateQueries({ queryKey: ['common', 'user-profile'] })
|
|
}, [queryClient])
|
|
|
|
const mutateCurrentWorkspace = useCallback(() => {
|
|
queryClient.invalidateQueries({ queryKey: ['common', 'current-workspace'] })
|
|
}, [queryClient])
|
|
|
|
// #region Zendesk conversation fields
|
|
useEffect(() => {
|
|
if (ZENDESK_FIELD_IDS.ENVIRONMENT && langGeniusVersionInfo?.current_env) {
|
|
setZendeskConversationFields([{
|
|
id: ZENDESK_FIELD_IDS.ENVIRONMENT,
|
|
value: langGeniusVersionInfo.current_env.toLowerCase(),
|
|
}])
|
|
}
|
|
}, [langGeniusVersionInfo?.current_env])
|
|
|
|
useEffect(() => {
|
|
if (ZENDESK_FIELD_IDS.VERSION && langGeniusVersionInfo?.version) {
|
|
setZendeskConversationFields([{
|
|
id: ZENDESK_FIELD_IDS.VERSION,
|
|
value: langGeniusVersionInfo.version,
|
|
}])
|
|
}
|
|
}, [langGeniusVersionInfo?.version])
|
|
|
|
useEffect(() => {
|
|
if (ZENDESK_FIELD_IDS.EMAIL && userProfile?.email) {
|
|
setZendeskConversationFields([{
|
|
id: ZENDESK_FIELD_IDS.EMAIL,
|
|
value: userProfile.email,
|
|
}])
|
|
}
|
|
}, [userProfile?.email])
|
|
|
|
useEffect(() => {
|
|
if (ZENDESK_FIELD_IDS.WORKSPACE_ID && currentWorkspace?.id) {
|
|
setZendeskConversationFields([{
|
|
id: ZENDESK_FIELD_IDS.WORKSPACE_ID,
|
|
value: currentWorkspace.id,
|
|
}])
|
|
}
|
|
}, [currentWorkspace?.id])
|
|
// #endregion Zendesk conversation fields
|
|
|
|
useEffect(() => {
|
|
// Report user and workspace info to Amplitude when loaded
|
|
if (userProfile?.id) {
|
|
setUserId(userProfile.email)
|
|
const properties: Record<string, any> = {
|
|
email: userProfile.email,
|
|
name: userProfile.name,
|
|
has_password: userProfile.is_password_set,
|
|
}
|
|
|
|
if (currentWorkspace?.id) {
|
|
properties.workspace_id = currentWorkspace.id
|
|
properties.workspace_name = currentWorkspace.name
|
|
properties.workspace_plan = currentWorkspace.plan
|
|
properties.workspace_status = currentWorkspace.status
|
|
properties.workspace_role = currentWorkspace.role
|
|
}
|
|
|
|
setUserProperties(properties)
|
|
}
|
|
}, [userProfile, currentWorkspace])
|
|
|
|
return (
|
|
<AppContext.Provider value={{
|
|
userProfile,
|
|
mutateUserProfile,
|
|
langGeniusVersionInfo,
|
|
useSelector,
|
|
currentWorkspace,
|
|
isCurrentWorkspaceManager,
|
|
isCurrentWorkspaceOwner,
|
|
isCurrentWorkspaceEditor,
|
|
isCurrentWorkspaceDatasetOperator,
|
|
mutateCurrentWorkspace,
|
|
isLoadingCurrentWorkspace,
|
|
}}>
|
|
<div className='flex h-full flex-col overflow-y-auto'>
|
|
{globalThis.document?.body?.getAttribute('data-public-maintenance-notice') && <MaintenanceNotice />}
|
|
<div className='relative flex grow flex-col overflow-y-auto overflow-x-hidden bg-background-body'>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</AppContext.Provider>
|
|
)
|
|
}
|
|
|
|
export const useAppContext = () => useContext(AppContext)
|
|
|
|
export default AppContext
|