import message from '@/components/ui/message'; import { Modal } from '@/components/ui/modal/modal'; import { ResponseGetType } from '@/interfaces/database/base'; import { IToken } from '@/interfaces/database/chat'; import { ITenantInfo } from '@/interfaces/database/knowledge'; import { ILangfuseConfig } from '@/interfaces/database/system'; import { ITenant, ITenantUser, IUserInfo, } from '@/interfaces/database/user-setting'; import { ISetLangfuseConfigRequestBody } from '@/interfaces/request/system'; import { DEFAULT_LANGUAGE_CODE, supportedLanguages } from '@/locales/config'; import { Routes } from '@/routes'; import userService, { addTenantUser, agreeTenant, deleteTenantUser, listTenant, listTenantUser, } from '@/services/user-service'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import DOMPurify from 'dompurify'; import { isEmpty } from 'lodash'; import { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router'; export const enum UserSettingApiAction { UserInfo = 'userInfo', TenantInfo = 'tenantInfo', SaveSetting = 'saveSetting', FetchManualSystemTokenList = 'fetchManualSystemTokenList', FetchSystemTokenList = 'fetchSystemTokenList', RemoveSystemToken = 'removeSystemToken', CreateSystemToken = 'createSystemToken', ListTenantUser = 'listTenantUser', AddTenantUser = 'addTenantUser', DeleteTenantUser = 'deleteTenantUser', ListTenant = 'listTenant', AgreeTenant = 'agreeTenant', SetLangfuseConfig = 'setLangfuseConfig', DeleteLangfuseConfig = 'deleteLangfuseConfig', FetchLangfuseConfig = 'fetchLangfuseConfig', } export const useFetchUserInfo = (): ResponseGetType => { const { data, isFetching: loading } = useQuery({ queryKey: [UserSettingApiAction.UserInfo], initialData: {}, gcTime: 0, queryFn: async () => { const { data } = await userService.userInfo(); if (data.code === 0) { const targetLng = supportedLanguages.find((lang) => lang.code === data.data.language) ?.code ?? DEFAULT_LANGUAGE_CODE; return Object.assign({}, data.data, { language: targetLng, }); } return data.data ?? {}; }, }); return { data, loading }; }; export const useFetchTenantInfo = ( showEmptyModelWarn = false, ): ResponseGetType => { const { t } = useTranslation(); const navigate = useNavigate(); const { data, isFetching: loading } = useQuery({ queryKey: [UserSettingApiAction.TenantInfo, showEmptyModelWarn], initialData: {}, gcTime: 0, queryFn: async () => { const { data: res } = await userService.getTenantInfo(); if (res.code === 0) { // llm_id is chat_id // asr_id is speech2txt const { data } = res; if ( showEmptyModelWarn && (isEmpty(data.embd_id) || isEmpty(data.llm_id)) ) { Modal.warning({ title: t('common.warn'), content: (
), closable: false, showCancel: false, onOk() { // window.open('/user-setting/model', '_self'); navigate(`${Routes.UserSetting}${Routes.Model}`); }, }); } data.chat_id = data.llm_id; data.speech2text_id = data.asr_id; return data; } return res; }, }); return { data, loading }; }; export const useSelectParserList = (): Array<{ value: string; label: string; }> => { const { data: tenantInfo } = useFetchTenantInfo(true); const { t } = useTranslation(); const defaultParsers = useMemo( () => [ { value: 'naive', label: t('knowledgeConfiguration.parserLabel.naive') }, { value: 'qa', label: t('knowledgeConfiguration.parserLabel.qa') }, { value: 'resume', label: t('knowledgeConfiguration.parserLabel.resume'), }, { value: 'manual', label: t('knowledgeConfiguration.parserLabel.manual'), }, { value: 'table', label: t('knowledgeConfiguration.parserLabel.table') }, { value: 'paper', label: t('knowledgeConfiguration.parserLabel.paper') }, { value: 'book', label: t('knowledgeConfiguration.parserLabel.book') }, { value: 'laws', label: t('knowledgeConfiguration.parserLabel.laws') }, { value: 'presentation', label: t('knowledgeConfiguration.parserLabel.presentation'), }, { value: 'picture', label: t('knowledgeConfiguration.parserLabel.picture'), }, { value: 'one', label: t('knowledgeConfiguration.parserLabel.one') }, { value: 'audio', label: t('knowledgeConfiguration.parserLabel.audio') }, { value: 'email', label: t('knowledgeConfiguration.parserLabel.email') }, { value: 'tag', label: t('knowledgeConfiguration.parserLabel.tag') }, ], [t], ); const parserList = useMemo(() => { const parserArray: Array = tenantInfo?.parser_ids?.split(',') ?? []; const filteredArray = parserArray.filter((x) => x.trim() !== ''); if (filteredArray.length === 0) { return defaultParsers; } return filteredArray.map((x) => { const arr = x.split(':'); return { value: arr[0], label: arr[1] }; }); }, [tenantInfo, defaultParsers]); return parserList; }; export const useSaveSetting = (silent = false) => { const queryClient = useQueryClient(); const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.SaveSetting], mutationFn: async ( userInfo: { new_password: string } | Partial, ) => { const { data } = await userService.setting(userInfo); if (data.code === 0) { if (!silent) { message.success(t('message.modified')); } queryClient.invalidateQueries({ queryKey: ['userInfo'] }); } return data?.code; }, }); return { data, loading, saveSetting: mutateAsync }; }; export const useFetchSystemVersion = () => { const [version, setVersion] = useState(''); const [loading, setLoading] = useState(false); const fetchSystemVersion = useCallback(async () => { try { setLoading(true); const { data } = await userService.getSystemVersion(); if (data.code === 0) { setVersion(data.data); setLoading(false); } } catch (error) { setLoading(false); } }, []); return { fetchSystemVersion, version, loading }; }; export const useFetchManualSystemTokenList = () => { const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.FetchManualSystemTokenList], mutationFn: async () => { const { data } = await userService.listToken(); return data?.data ?? []; }, }); return { data, loading, fetchSystemTokenList: mutateAsync }; }; export const useFetchSystemTokenList = () => { const { data, isFetching: loading, refetch, } = useQuery({ queryKey: [UserSettingApiAction.FetchSystemTokenList], initialData: [], gcTime: 0, queryFn: async () => { const { data } = await userService.listToken(); return data?.data ?? []; }, }); return { data, loading, refetch }; }; export const useRemoveSystemToken = () => { const queryClient = useQueryClient(); const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.RemoveSystemToken], mutationFn: async (token: string) => { const { data } = await userService.removeToken({}, token); if (data.code === 0) { message.success(t('message.deleted')); queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.FetchSystemTokenList], }); } return data?.data ?? []; }, }); return { data, loading, removeToken: mutateAsync }; }; export const useCreateSystemToken = () => { const queryClient = useQueryClient(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.CreateSystemToken], mutationFn: async (params: Record) => { const { data } = await userService.createToken(params); if (data.code === 0) { queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.FetchSystemTokenList], }); } return data?.data ?? []; }, }); return { data, loading, createToken: mutateAsync }; }; export const useListTenantUser = () => { const { data: tenantInfo } = useFetchTenantInfo(); const tenantId = tenantInfo.tenant_id; const { data, isFetching: loading, refetch, } = useQuery({ queryKey: [UserSettingApiAction.ListTenantUser, tenantId], initialData: [], gcTime: 0, enabled: !!tenantId, queryFn: async () => { const { data } = await listTenantUser(tenantId); return data?.data ?? []; }, }); return { data, loading, refetch }; }; export const useAddTenantUser = () => { const { data: tenantInfo } = useFetchTenantInfo(); const queryClient = useQueryClient(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.AddTenantUser], mutationFn: async (email: string) => { const { data } = await addTenantUser(tenantInfo.tenant_id, email); if (data.code === 0) { queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.ListTenantUser], }); } return data?.code; }, }); return { data, loading, addTenantUser: mutateAsync }; }; export const useDeleteTenantUser = () => { const { data: tenantInfo } = useFetchTenantInfo(); const queryClient = useQueryClient(); const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.DeleteTenantUser], mutationFn: async ({ userId, tenantId, }: { userId: string; tenantId?: string; }) => { const { data } = await deleteTenantUser({ tenantId: tenantId ?? tenantInfo.tenant_id, userId, }); if (data.code === 0) { message.success(t('message.deleted')); queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.ListTenantUser], }); queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.ListTenant], }); } return data?.data ?? []; }, }); return { data, loading, deleteTenantUser: mutateAsync }; }; export const useListTenant = () => { const { data: tenantInfo } = useFetchTenantInfo(); const tenantId = tenantInfo.tenant_id; const { data, isFetching: loading, refetch, } = useQuery({ queryKey: [UserSettingApiAction.ListTenant, tenantId], initialData: [], gcTime: 0, enabled: !!tenantId, queryFn: async () => { const { data } = await listTenant(); return data?.data ?? []; }, }); return { data, loading, refetch }; }; export const useAgreeTenant = () => { const queryClient = useQueryClient(); const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.AgreeTenant], mutationFn: async (tenantId: string) => { const { data } = await agreeTenant(tenantId); if (data.code === 0) { message.success(t('message.operated')); queryClient.invalidateQueries({ queryKey: [UserSettingApiAction.ListTenant], }); } return data?.data ?? []; }, }); return { data, loading, agreeTenant: mutateAsync }; }; export const useSetLangfuseConfig = () => { const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.SetLangfuseConfig], mutationFn: async (params: ISetLangfuseConfigRequestBody) => { const { data } = await userService.setLangfuseConfig(params); if (data.code === 0) { message.success(t('message.operated')); } return data?.code; }, }); return { data, loading, setLangfuseConfig: mutateAsync }; }; export const useDeleteLangfuseConfig = () => { const { t } = useTranslation(); const { data, isPending: loading, mutateAsync, } = useMutation({ mutationKey: [UserSettingApiAction.DeleteLangfuseConfig], mutationFn: async () => { const { data } = await userService.deleteLangfuseConfig(); if (data.code === 0) { message.success(t('message.deleted')); } return data?.code; }, }); return { data, loading, deleteLangfuseConfig: mutateAsync }; }; export const useFetchLangfuseConfig = () => { const { data, isFetching: loading } = useQuery({ queryKey: [UserSettingApiAction.FetchLangfuseConfig], gcTime: 0, queryFn: async () => { const { data } = await userService.getLangfuseConfig(); return data?.data; }, }); return { data, loading }; };