From 18699f86714aa9701916b552929d7fb832b0c789 Mon Sep 17 00:00:00 2001 From: zxhlyh Date: Thu, 10 Jul 2025 17:12:48 +0800 Subject: [PATCH] tool oauth --- .../base/form/components/base/base-field.tsx | 53 +++ web/app/components/base/form/types.ts | 10 + web/app/components/base/select/pure.tsx | 10 +- .../plugin-auth/authorize/api-key-modal.tsx | 61 ++-- .../plugins/plugin-auth/authorize/index.tsx | 14 +- .../plugin-auth/authorized-in-node.tsx | 13 +- .../plugins/plugin-auth/authorized/index.tsx | 83 +++-- .../plugins/plugin-auth/authorized/item.tsx | 123 +++++-- .../components/plugins/plugin-auth/index.tsx | 1 + .../plugin-auth/plugin-auth-in-agent.tsx | 119 +++++++ .../tool-selector/index.tsx | 336 ++++++++---------- .../tool-selector/tool-item.tsx | 12 +- web/app/components/workflow/types.ts | 3 +- web/i18n/en-US/plugin.ts | 20 ++ web/i18n/zh-Hans/plugin.ts | 20 ++ web/service/use-plugins-auth.ts | 3 +- 16 files changed, 599 insertions(+), 282 deletions(-) create mode 100644 web/app/components/plugins/plugin-auth/plugin-auth-in-agent.tsx diff --git a/web/app/components/base/form/components/base/base-field.tsx b/web/app/components/base/form/components/base/base-field.tsx index f997297691..47a8cca419 100644 --- a/web/app/components/base/form/components/base/base-field.tsx +++ b/web/app/components/base/form/components/base/base-field.tsx @@ -7,6 +7,7 @@ import type { AnyFieldApi } from '@tanstack/react-form' import { useStore } from '@tanstack/react-form' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' +import PureSelect from '@/app/components/base/select/pure' import type { FormSchema } from '@/app/components/base/form/types' import { FormTypeEnum } from '@/app/components/base/form/types' import { useRenderI18nObject } from '@/hooks/use-i18n' @@ -32,6 +33,9 @@ const BaseField = ({ const renderI18nObject = useRenderI18nObject() const { label, + required, + placeholder, + options, } = formSchema const memorizedLabel = useMemo(() => { @@ -44,12 +48,32 @@ const BaseField = ({ if (typeof label === 'object' && label !== null) return renderI18nObject(label as Record) }, [label, renderI18nObject]) + const memorizedPlaceholder = useMemo(() => { + if (typeof placeholder === 'string') + return placeholder + + if (typeof placeholder === 'object' && placeholder !== null) + return renderI18nObject(placeholder as Record) + }, [placeholder, renderI18nObject]) + const memorizedOptions = useMemo(() => { + return options?.map((option) => { + return { + label: typeof option.label === 'string' ? option.label : renderI18nObject(option.label), + value: option.value, + } + }) || [] + }, [options, renderI18nObject]) const value = useStore(field.form.store, s => s.values[field.name]) return (
{memorizedLabel} + { + required && ( + * + ) + }
{ @@ -62,6 +86,7 @@ const BaseField = ({ onChange={e => field.handleChange(e.target.value)} onBlur={field.handleBlur} disabled={disabled} + placeholder={memorizedPlaceholder} /> ) } @@ -76,6 +101,34 @@ const BaseField = ({ onChange={e => field.handleChange(e.target.value)} onBlur={field.handleBlur} disabled={disabled} + placeholder={memorizedPlaceholder} + /> + ) + } + { + formSchema.type === FormTypeEnum.textNumber && ( + field.handleChange(e.target.value)} + onBlur={field.handleBlur} + disabled={disabled} + placeholder={memorizedPlaceholder} + /> + ) + } + { + formSchema.type === FormTypeEnum.select && ( + field.handleChange(v)} + disabled={disabled} + placeholder={memorizedPlaceholder} + options={memorizedOptions} + triggerPopupSameWidth /> ) } diff --git a/web/app/components/base/form/types.ts b/web/app/components/base/form/types.ts index 5156477a38..3e1001b54e 100644 --- a/web/app/components/base/form/types.ts +++ b/web/app/components/base/form/types.ts @@ -31,6 +31,13 @@ export enum FormTypeEnum { dynamicSelect = 'dynamic-select', } +export type FormOption = { + label: TypeWithI18N | string + value: string + show_on: FormShowOnObject[] + icon?: string +} + export type FormSchema = { type: FormTypeEnum name: string @@ -41,6 +48,9 @@ export type FormSchema = { show_on?: FormShowOnObject[] url?: string scope?: string + help?: string | TypeWithI18N + placeholder?: string | TypeWithI18N + options?: FormOption[] } export type FormValues = Record diff --git a/web/app/components/base/select/pure.tsx b/web/app/components/base/select/pure.tsx index 81cc2fbadf..be88c936fd 100644 --- a/web/app/components/base/select/pure.tsx +++ b/web/app/components/base/select/pure.tsx @@ -39,6 +39,9 @@ type PureSelectProps = { itemClassName?: string title?: string }, + placeholder?: string + disabled?: boolean + triggerPopupSameWidth?: boolean } const PureSelect = ({ options, @@ -47,6 +50,9 @@ const PureSelect = ({ containerProps, triggerProps, popupProps, + placeholder, + disabled, + triggerPopupSameWidth, }: PureSelectProps) => { const { t } = useTranslation() const { @@ -74,7 +80,7 @@ const PureSelect = ({ }, [onOpenChange]) const selectedOption = options.find(option => option.value === value) - const triggerText = selectedOption?.label || t('common.placeholder.select') + const triggerText = selectedOption?.label || placeholder || t('common.placeholder.select') return ( handleOpenChange(!mergedOpen)} @@ -135,6 +142,7 @@ const PureSelect = ({ )} title={option.label} onClick={() => { + if (disabled) return onChange?.(option.value) handleOpenChange(false) }} diff --git a/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx b/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx index d7d4253089..572dfe125e 100644 --- a/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/api-key-modal.tsx @@ -14,6 +14,7 @@ import AuthForm from '@/app/components/base/form/form-scenarios/auth' import type { FromRefObject } from '@/app/components/base/form/types' import { FormTypeEnum } from '@/app/components/base/form/types' import { useToastContext } from '@/app/components/base/toast' +import Loading from '@/app/components/base/loading' import type { PluginPayload } from '../types' import { useAddPluginCredentialHook, @@ -21,6 +22,7 @@ import { useInvalidPluginCredentialInfoHook, useUpdatePluginCredentialHook, } from '../hooks/use-credential' +import { useRenderI18nObject } from '@/hooks/use-i18n' export type ApiKeyModalProps = { pluginPayload: PluginPayload @@ -38,18 +40,25 @@ const ApiKeyModal = ({ }: ApiKeyModalProps) => { const { t } = useTranslation() const { notify } = useToastContext() - const { data = [] } = useGetPluginCredentialSchemaHook(pluginPayload, CredentialTypeEnum.API_KEY) + const { data = [], isLoading } = useGetPluginCredentialSchemaHook(pluginPayload, CredentialTypeEnum.API_KEY) const formSchemas = useMemo(() => { return [ { type: FormTypeEnum.textInput, name: '__name__', - label: 'Authorization name', + label: t('plugin.auth.authorizationName'), required: false, }, ...data, ] - }, [data]) + }, [data, t]) + const defaultValues = formSchemas.reduce((acc, schema) => { + if (schema.default) + acc[schema.name] = schema.default + return acc + }, {} as Record) + const secretInput = formSchemas.find(schema => schema.type === FormTypeEnum.secretInput) + const renderI18nObject = useRenderI18nObject() const { mutateAsync: addPluginCredential } = useAddPluginCredentialHook(pluginPayload) const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload) const invalidatePluginCredentialInfo = useInvalidPluginCredentialInfoHook(pluginPayload) @@ -77,7 +86,6 @@ const ApiKeyModal = ({ await updatePluginCredential({ credentials: transformedValues, credential_id: __credential_id__, - type: CredentialTypeEnum.API_KEY, name: __name__ || '', }) } @@ -100,19 +108,21 @@ const ApiKeyModal = ({ return ( - Get your API Key from OpenAI - - + secretInput && ( + + {renderI18nObject(secretInput?.help as any)} + + + ) } bottomSlot={
@@ -133,12 +143,23 @@ const ApiKeyModal = ({ onExtraButtonClick={onRemove} disabled={disabled} > - + { + isLoading && ( +
+ +
+ ) + } + { + !isLoading && !!data.length && ( + + ) + } ) } diff --git a/web/app/components/plugins/plugin-auth/authorize/index.tsx b/web/app/components/plugins/plugin-auth/authorize/index.tsx index bb87578671..80f1656fb8 100644 --- a/web/app/components/plugins/plugin-auth/authorize/index.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/index.tsx @@ -2,6 +2,7 @@ import { memo, useMemo, } from 'react' +import { useTranslation } from 'react-i18next' import AddOAuthButton from './add-oauth-button' import type { AddOAuthButtonProps } from './add-oauth-button' import AddApiKeyButton from './add-api-key-button' @@ -24,10 +25,11 @@ const Authorize = ({ canApiKey, disabled, }: AuthorizeProps) => { + const { t } = useTranslation() const oAuthButtonProps: AddOAuthButtonProps = useMemo(() => { if (theme === 'secondary') { return { - buttonText: !canApiKey ? 'Add OAuth Authorization' : 'Add OAuth', + buttonText: !canApiKey ? t('plugin.auth.useOAuthAuth') : t('plugin.auth.addOAuth'), buttonVariant: 'secondary', className: 'hover:bg-components-button-secondary-bg', buttonLeftClassName: 'hover:bg-components-button-secondary-bg-hover', @@ -38,25 +40,25 @@ const Authorize = ({ } return { - buttonText: !canApiKey ? 'Use OAuth Authorization' : 'Use OAuth', + buttonText: !canApiKey ? t('plugin.auth.useOAuthAuth') : t('plugin.auth.addOAuth'), pluginPayload, } - }, [canApiKey, theme, pluginPayload]) + }, [canApiKey, theme, pluginPayload, t]) const apiKeyButtonProps: AddApiKeyButtonProps = useMemo(() => { if (theme === 'secondary') { return { pluginPayload, buttonVariant: 'secondary', - buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Add API Key', + buttonText: !canOAuth ? t('plugin.auth.useApiAuth') : t('plugin.auth.addApi'), } } return { pluginPayload, - buttonText: !canOAuth ? 'API Key Authorization Configuration' : 'Use API Key', + buttonText: !canOAuth ? t('plugin.auth.useApiAuth') : t('plugin.auth.addApi'), buttonVariant: !canOAuth ? 'primary' : 'secondary-accent', } - }, [canOAuth, theme, pluginPayload]) + }, [canOAuth, theme, pluginPayload, t]) return ( <> diff --git a/web/app/components/plugins/plugin-auth/authorized-in-node.tsx b/web/app/components/plugins/plugin-auth/authorized-in-node.tsx index 96eb409829..55516e7fca 100644 --- a/web/app/components/plugins/plugin-auth/authorized-in-node.tsx +++ b/web/app/components/plugins/plugin-auth/authorized-in-node.tsx @@ -3,6 +3,7 @@ import { useCallback, useState, } from 'react' +import { useTranslation } from 'react-i18next' import { RiArrowDownSLine } from '@remixicon/react' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' @@ -26,6 +27,7 @@ const AuthorizedInNode = ({ onAuthorizationItemClick, credentialId, }: AuthorizedInNodeProps) => { + const { t } = useTranslation() const [isOpen, setIsOpen] = useState(false) const { canApiKey, @@ -37,11 +39,11 @@ const AuthorizedInNode = ({ let label = '' let removed = false if (!credentialId) { - label = 'Workspace default' + label = t('plugin.auth.workspaceDefault') } else { const credential = credentials.find(c => c.id === credentialId) - label = credential ? credential.name : 'Auth removed' + label = credential ? credential.name : t('plugin.auth.authRemoved') removed = !credential } return ( @@ -65,13 +67,13 @@ const AuthorizedInNode = ({ /> ) - }, [credentialId, credentials]) + }, [credentialId, credentials, t]) const extraAuthorizationItems: Credential[] = [ { id: '__workspace_default__', - name: 'Workspace default', + name: t('plugin.auth.workspaceDefault'), provider: '', - is_default: false, + is_default: !credentialId, isWorkspaceDefault: true, }, ] @@ -100,6 +102,7 @@ const AuthorizedInNode = ({ disableSetDefault onItemClick={handleAuthorizationItemClick} extraAuthorizationItems={extraAuthorizationItems} + showItemSelectedIcon /> ) } diff --git a/web/app/components/plugins/plugin-auth/authorized/index.tsx b/web/app/components/plugins/plugin-auth/authorized/index.tsx index 13fec807f0..ddd05787b6 100644 --- a/web/app/components/plugins/plugin-auth/authorized/index.tsx +++ b/web/app/components/plugins/plugin-auth/authorized/index.tsx @@ -31,6 +31,7 @@ import { useDeletePluginCredentialHook, useInvalidPluginCredentialInfoHook, useSetPluginDefaultCredentialHook, + useUpdatePluginCredentialHook, } from '../hooks/use-credential' type AuthorizedProps = { @@ -49,6 +50,7 @@ type AuthorizedProps = { disableSetDefault?: boolean onItemClick?: (id: string) => void extraAuthorizationItems?: Credential[] + showItemSelectedIcon?: boolean } const Authorized = ({ pluginPayload, @@ -66,6 +68,7 @@ const Authorized = ({ disableSetDefault, onItemClick, extraAuthorizationItems, + showItemSelectedIcon, }: AuthorizedProps) => { const { t } = useTranslation() const { notify } = useToastContext() @@ -125,6 +128,17 @@ const Authorized = ({ }) invalidatePluginCredentialInfo() }, [setPluginDefaultCredential, invalidatePluginCredentialInfo, notify, t]) + const { mutateAsync: updatePluginCredential } = useUpdatePluginCredentialHook(pluginPayload) + const handleRename = useCallback(async (payload: { + credential_id: string + name: string + }) => { + await updatePluginCredential(payload) + notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + }, [updatePluginCredential, notify, t]) return ( <> @@ -149,7 +163,12 @@ const Authorized = ({ isOpen && 'bg-components-button-secondary-bg-hover', )}> - {credentials.length} Authorizations + {credentials.length}  + { + credentials.length > 1 + ? t('plugin.auth.authorizations') + : t('plugin.auth.authorization') + } ) @@ -160,31 +179,35 @@ const Authorized = ({ 'max-h-[360px] overflow-y-auto rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg', popupClassName, )}> - { - !!extraAuthorizationItems?.length && ( -
- { - extraAuthorizationItems.map(credential => ( - - )) - } -
- ) - }
+ { + !!extraAuthorizationItems?.length && ( +
+ { + extraAuthorizationItems.map(credential => ( + + )) + } +
+ ) + } { !!oAuthCredentials.length && (
-
+
OAuth
{ @@ -192,6 +215,14 @@ const Authorized = ({ )) } @@ -201,7 +232,10 @@ const Authorized = ({ { !!apiKeyCredentials.length && (
-
+
API Keys
{ @@ -214,7 +248,10 @@ const Authorized = ({ onEdit={handleEdit} onSetDefault={handleSetDefault} disableSetDefault={disableSetDefault} + disableRename onItemClick={onItemClick} + onRename={handleRename} + showSelectedIcon={showItemSelectedIcon} /> )) } diff --git a/web/app/components/plugins/plugin-auth/authorized/item.tsx b/web/app/components/plugins/plugin-auth/authorized/item.tsx index f54ef5ac9b..42bce232ff 100644 --- a/web/app/components/plugins/plugin-auth/authorized/item.tsx +++ b/web/app/components/plugins/plugin-auth/authorized/item.tsx @@ -1,8 +1,11 @@ import { memo, useMemo, + useState, } from 'react' +import { useTranslation } from 'react-i18next' import { + RiCheckLine, RiDeleteBinLine, RiEditLine, RiEqualizer2Line, @@ -12,6 +15,8 @@ import Badge from '@/app/components/base/badge' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import Button from '@/app/components/base/button' +import Input from '@/app/components/base/input' +import cn from '@/utils/classnames' import type { Credential } from '../types' import { CredentialTypeEnum } from '../types' @@ -21,11 +26,16 @@ type ItemProps = { onDelete?: (id: string) => void onEdit?: (id: string, values: Record) => void onSetDefault?: (id: string) => void + onRename?: (payload: { + credential_id: string + name: string + }) => void disableRename?: boolean disableEdit?: boolean disableDelete?: boolean disableSetDefault?: boolean onItemClick?: (id: string) => void + showSelectedIcon?: boolean } const Item = ({ credential, @@ -33,12 +43,17 @@ const Item = ({ onDelete, onEdit, onSetDefault, + onRename, disableRename, disableEdit, disableDelete, disableSetDefault, onItemClick, + showSelectedIcon, }: ItemProps) => { + const { t } = useTranslation() + const [renaming, setRenaming] = useState(false) + const [renameValue, setRenameValue] = useState(credential.name) const isOAuth = credential.credential_type === CredentialTypeEnum.OAUTH2 const showAction = useMemo(() => { return !(disableRename && disableEdit && disableDelete && disableSetDefault) @@ -47,27 +62,77 @@ const Item = ({ return (
onItemClick?.(credential.id)} > -
- -
- {credential.name} -
- { - credential.is_default && ( - - Default - - ) - } -
{ - showAction && ( + renaming && ( +
+ setRenameValue(e.target.value)} + placeholder={t('common.placeholder.input')} + /> + + +
+ ) + } + { + !renaming && ( +
+ { + showSelectedIcon && ( +
+ { + credential.is_default && ( + + ) + } +
+ ) + } + +
+ {credential.name} +
+ { + credential.is_default && ( + + {t('plugin.auth.default')} + + ) + } +
+ ) + } + { + showAction && !renaming && (
{ !credential.is_default && !disableSetDefault && ( @@ -79,14 +144,21 @@ const Item = ({ onSetDefault?.(credential.id) }} > - Set as default + {t('plugin.auth.setDefault')} ) } { - isOAuth && !disableRename && ( - - + !disableRename && ( + + { + e.stopPropagation() + setRenaming(true) + setRenameValue(credential.name) + }} + > @@ -94,7 +166,7 @@ const Item = ({ } { !isOAuth && !disableEdit && ( - + { @@ -116,15 +188,16 @@ const Item = ({ } { !disableDelete && ( - + { e.stopPropagation() onDelete?.(credential.id) }} > - + ) diff --git a/web/app/components/plugins/plugin-auth/index.tsx b/web/app/components/plugins/plugin-auth/index.tsx index f5b2f0c457..e4f6ae8b2f 100644 --- a/web/app/components/plugins/plugin-auth/index.tsx +++ b/web/app/components/plugins/plugin-auth/index.tsx @@ -1,5 +1,6 @@ export { default as PluginAuth } from './plugin-auth' export { default as Authorized } from './authorized' export { default as AuthorizedInNode } from './authorized-in-node' +export { default as PluginAuthInAgent } from './plugin-auth-in-agent' export { usePluginAuth } from './hooks/use-plugin-auth' export * from './types' diff --git a/web/app/components/plugins/plugin-auth/plugin-auth-in-agent.tsx b/web/app/components/plugins/plugin-auth/plugin-auth-in-agent.tsx new file mode 100644 index 0000000000..bb5d8e1f3c --- /dev/null +++ b/web/app/components/plugins/plugin-auth/plugin-auth-in-agent.tsx @@ -0,0 +1,119 @@ +import { + memo, + useCallback, + useState, +} from 'react' +import { RiArrowDownSLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import Authorize from './authorize' +import Authorized from './authorized' +import type { + Credential, + PluginPayload, +} from './types' +import { usePluginAuth } from './hooks/use-plugin-auth' +import Button from '@/app/components/base/button' +import Indicator from '@/app/components/header/indicator' +import cn from '@/utils/classnames' + +type PluginAuthInAgentProps = { + pluginPayload: PluginPayload + credentialId?: string + onAuthorizationItemClick?: (id: string) => void +} +const PluginAuthInAgent = ({ + pluginPayload, + credentialId, + onAuthorizationItemClick, +}: PluginAuthInAgentProps) => { + const { t } = useTranslation() + const [isOpen, setIsOpen] = useState(false) + const { + isAuthorized, + canOAuth, + canApiKey, + credentials, + disabled, + } = usePluginAuth(pluginPayload, true) + + const extraAuthorizationItems: Credential[] = [ + { + id: '__workspace_default__', + name: t('plugin.auth.workspaceDefault'), + provider: '', + is_default: !credentialId, + isWorkspaceDefault: true, + }, + ] + + const handleAuthorizationItemClick = useCallback((id: string) => { + onAuthorizationItemClick?.(id) + setIsOpen(false) + }, [ + onAuthorizationItemClick, + setIsOpen, + ]) + + const renderTrigger = useCallback((isOpen?: boolean) => { + let label = '' + let removed = false + if (!credentialId) { + label = t('plugin.auth.workspaceDefault') + } + else { + const credential = credentials.find(c => c.id === credentialId) + label = credential ? credential.name : t('plugin.auth.authRemoved') + removed = !credential + } + return ( + + ) + }, [credentialId, credentials, t]) + + return ( + <> + { + !isAuthorized && ( + + ) + } + { + isAuthorized && ( + + ) + } + + ) +} + +export default memo(PluginAuthInAgent) diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx index 350fe50933..da4323713b 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx @@ -4,7 +4,6 @@ import React, { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { - RiArrowLeftLine, RiArrowRightUpLine, } from '@remixicon/react' import { @@ -15,24 +14,17 @@ import { import ToolTrigger from '@/app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger' import ToolItem from '@/app/components/plugins/plugin-detail-panel/tool-selector/tool-item' import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' -import Button from '@/app/components/base/button' -import Indicator from '@/app/components/header/indicator' -import ToolCredentialForm from '@/app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form' -import Toast from '@/app/components/base/toast' import Textarea from '@/app/components/base/textarea' import Divider from '@/app/components/base/divider' import TabSlider from '@/app/components/base/tab-slider-plain' import ReasoningConfigForm from '@/app/components/plugins/plugin-detail-panel/tool-selector/reasoning-config-form' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' import { generateFormValue, getPlainValue, getStructureValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema' - -import { useAppContext } from '@/context/app-context' import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools, useInvalidateAllBuiltInTools, - useUpdateProviderCredentials, } from '@/service/use-tools' import { useInvalidateInstalledPluginList } from '@/service/use-plugins' import { usePluginInstalledCheck } from '@/app/components/plugins/plugin-detail-panel/tool-selector/hooks' @@ -46,6 +38,10 @@ import { MARKETPLACE_API_PREFIX } from '@/config' import type { Node } from 'reactflow' import type { NodeOutPutVar } from '@/app/components/workflow/types' import cn from '@/utils/classnames' +import { + AuthCategory, + PluginAuthInAgent, +} from '@/app/components/plugins/plugin-auth' type Props = { disabled?: boolean @@ -191,23 +187,6 @@ const ToolSelector: FC = ({ } as any) } - // authorization - const { isCurrentWorkspaceManager } = useAppContext() - const [isShowSettingAuth, setShowSettingAuth] = useState(false) - const handleCredentialSettingUpdate = () => { - invalidateAllBuiltinTools() - Toast.notify({ - type: 'success', - message: t('common.api.actionSuccess'), - }) - setShowSettingAuth(false) - onShowChange(false) - } - - const { mutate: updatePermission } = useUpdateProviderCredentials({ - onSuccess: handleCredentialSettingUpdate, - }) - // install from marketplace const currentTool = useMemo(() => { return currentProvider?.tools.find(tool => tool.name === value?.tool_name) @@ -221,6 +200,12 @@ const ToolSelector: FC = ({ invalidateAllBuiltinTools() invalidateInstalledPluginList() } + const handleAuthorizationItemClick = (id: string) => { + onSelect({ + ...value, + credential_id: id, + } as any) + } return ( <> @@ -257,7 +242,6 @@ const ToolSelector: FC = ({ onSwitchChange={handleEnabledChange} onDelete={onDelete} noAuth={currentProvider && currentTool && !currentProvider.is_team_authorization} - onAuth={() => setShowSettingAuth(true)} uninstalled={!currentProvider && inMarketPlace} versionMismatch={currentProvider && inMarketPlace && !currentTool} installInfo={manifest?.latest_package_identifier} @@ -276,181 +260,141 @@ const ToolSelector: FC = ({ )} -
- {!isShowSettingAuth && ( - <> -
{t(`plugin.detailPanel.toolSelector.${isEdit ? 'toolSetting' : 'title'}`)}
- {/* base form */} -
-
-
{t('plugin.detailPanel.toolSelector.toolLabel')}
- - } - isShow={panelShowState || isShowChooseTool} - onShowChange={trigger ? onPanelShowStateChange as any : setIsShowChooseTool} - disabled={false} - supportAddCustomTool - onSelect={handleSelectTool} - scope={scope} - selectedTools={selectedTools} - /> -
-
-
{t('plugin.detailPanel.toolSelector.descriptionLabel')}
-