diff --git a/web/app/components/header/account-setting/model-provider-page/hooks.ts b/web/app/components/header/account-setting/model-provider-page/hooks.ts index 66b3015a6b..c9836ae7e6 100644 --- a/web/app/components/header/account-setting/model-provider-page/hooks.ts +++ b/web/app/components/header/account-setting/model-provider-page/hooks.ts @@ -80,13 +80,13 @@ export const useProviderCredentialsAndLoadBalancing = ( currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields, credentialId?: string, ) => { - const { data: predefinedFormSchemasValue, mutate: mutatePredefined } = useSWR( + const { data: predefinedFormSchemasValue, mutate: mutatePredefined, isLoading: isPredefinedLoading } = useSWR( (configurationMethod === ConfigurationMethodEnum.predefinedModel && configured && credentialId) ? `/workspaces/current/model-providers/${provider}/credentials${credentialId ? `?credential_id=${credentialId}` : ''}` : null, fetchModelProviderCredentials, ) - const { data: customFormSchemasValue, mutate: mutateCustomized } = useSWR( + const { data: customFormSchemasValue, mutate: mutateCustomized, isLoading: isCustomizedLoading } = useSWR( (configurationMethod === ConfigurationMethodEnum.customizableModel && currentCustomConfigurationModelFixedFields && credentialId) ? `/workspaces/current/model-providers/${provider}/models/credentials?model=${currentCustomConfigurationModelFixedFields?.__model_name}&model_type=${currentCustomConfigurationModelFixedFields?.__model_type}${credentialId ? `&credential_id=${credentialId}` : ''}` : null, @@ -122,6 +122,7 @@ export const useProviderCredentialsAndLoadBalancing = ( : customFormSchemasValue )?.load_balancing, mutate, + isLoading: isPredefinedLoading || isCustomizedLoading, } // as ([Record | undefined, ModelLoadBalancingConfig | undefined]) } diff --git a/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx index c56e03e8ff..e20fd58216 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/index.tsx @@ -22,7 +22,10 @@ import Confirm from '@/app/components/base/confirm' import Item from './item' import { useToastContext } from '@/app/components/base/toast' import type { Credential } from '../../declarations' -import { useDeleteModelCredential } from '@/service/use-models' +import { + useDeleteModelCredential, + useSetModelCredentialDefault, +} from '@/service/use-models' type AuthorizedProps = { provider: string @@ -87,6 +90,23 @@ const Authorized = ({ setDoingAction(doing) }, []) const { mutateAsync: deleteModelCredential } = useDeleteModelCredential(provider) + const { mutateAsync: setModelCredentialDefault } = useSetModelCredentialDefault(provider) + const handleSetDefault = useCallback(async (id: string) => { + if (doingActionRef.current) + return + try { + handleSetDoingAction(true) + await setModelCredentialDefault(id) + notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + onUpdate?.() + } + finally { + handleSetDoingAction(false) + } + }, [setModelCredentialDefault, onUpdate, notify, t, handleSetDoingAction]) const handleConfirm = useCallback(async () => { if (doingActionRef.current) return @@ -109,9 +129,10 @@ const Authorized = ({ handleSetDoingAction(false) } }, [onUpdate, notify, t, handleSetDoingAction]) - const handleEdit = useCallback((credential: Credential) => { + const handleOpenSetup = useCallback((credential?: Credential) => { onSetup(credential) - }, [onSetup]) + setMergedIsOpen(false) + }, [onSetup, setMergedIsOpen]) return ( <> @@ -142,10 +163,10 @@ const Authorized = ({
-
+
{ !!credentials.length && (
@@ -162,7 +183,8 @@ const Authorized = ({ credential={credential} disabled={disabled} onDelete={openConfirm} - onEdit={handleEdit} + onEdit={handleOpenSetup} + onSetDefault={handleSetDefault} onItemClick={onItemClick} showSelectedIcon={showItemSelectedIcon} selectedCredentialId={selectedCredentialId} @@ -176,7 +198,7 @@ const Authorized = ({
+ ) + } { !disableEdit && ( diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx index 31f9cf0a6d..4c9652da8f 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx @@ -47,6 +47,7 @@ import type { } from '@/app/components/base/form/types' import { useModelFormSchemas } from '../model-auth/hooks' import type { Credential } from '../declarations' +import Loading from '@/app/components/base/loading' type ModelModalProps = { provider: ModelProvider @@ -70,6 +71,7 @@ const ModelModal: FC = ({ credentials: formSchemasValue, loadBalancing: originalConfig, mutate, + isLoading, } = useProviderCredentialsAndLoadBalancing( provider.provider, configurateMethod, @@ -185,7 +187,7 @@ const ModelModal: FC = ({ ) if (res.result === 'success') { notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) - mutate() + // mutate() onSave() onCancel() } @@ -211,21 +213,32 @@ const ModelModal: FC = ({
- { - return { - ...formSchema, - name: formSchema.variable, - showRadioUI: formSchema.type === FormTypeEnum.radio, - } - }) as FormSchema[]} - defaultValues={{ - ...formSchemasValue, - __authorization_name__: credential?.credential_name, - }} - inputClassName='justify-start' - ref={formRef} - /> + { + isLoading && ( +
+ +
+ ) + } + { + !isLoading && ( + { + return { + ...formSchema, + name: formSchema.variable, + showRadioUI: formSchema.type === FormTypeEnum.radio, + } + }) as FormSchema[]} + defaultValues={{ + ...formSchemasValue, + __authorization_name__: credential?.credential_name, + }} + inputClassName='justify-start' + ref={formRef} + /> + ) + } { !!draftConfig && ( <> diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx index 059c2ec73b..85d013ba45 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx @@ -23,6 +23,7 @@ import { changeModelProviderPriority } from '@/service/common' import { useToastContext } from '@/app/components/base/toast' import { useEventEmitterContextContext } from '@/context/event-emitter' import Authorized from '../model-auth/authorized' +import cn from '@/utils/classnames' type CredentialPanelProps = { provider: ModelProvider @@ -49,8 +50,9 @@ const CredentialPanel = ({ current_credential_name, available_credentials, } = provider.custom_configuration - const authorized = current_credential_id && current_credential_name && available_credentials?.every(item => !!item.credential_id) - const authRemoved = !!available_credentials?.length && available_credentials?.every(item => !item.credential_id) + const hasCredential = !!available_credentials?.length + const authorized = current_credential_id && current_credential_name + const authRemoved = hasCredential && !current_credential_id && !current_credential_name const handleChangePriority = async (key: PreferredProviderTypeEnum) => { const res = await changeModelProviderPriority({ @@ -75,21 +77,30 @@ const CredentialPanel = ({ } } const credentialLabel = useMemo(() => { + if (!hasCredential) + return t('common.model.unAuthorized') if (authorized) return current_credential_name if (authRemoved) - return 'Auth removed' - return 'Unauthorized' - }, [authorized, authRemoved, current_credential_name]) + return t('common.model.authRemoved') + + return '' + }, [authorized, authRemoved, current_credential_name, hasCredential]) return ( <> { provider.provider_credential_schema && ( -
+
{credentialLabel} @@ -98,7 +109,7 @@ const CredentialPanel = ({
{ - (!authorized || authRemoved) && ( + !hasCredential && ( ) } { - authorized && ( + (hasCredential || authRemoved) && ( { }), }) } + +export const useSetModelCredentialDefault = (providerName: string) => { + return useMutation({ + mutationFn: (credentialId: string) => post<{ result: string }>(`/workspaces/current/model-providers/${providerName}/credentials/switch`, { + body: { + credential_id: credentialId, + }, + }), + }) +}