feat: tool config

This commit is contained in:
Joel 2026-01-22 16:49:04 +08:00
parent 9733621301
commit 43648b1660
6 changed files with 47 additions and 24 deletions

View File

@ -10,11 +10,13 @@ export const ReadmeEntrance = ({
pluginDetail,
showType = ReadmeShowType.drawer,
className,
position = 'left',
showShortTip = false,
}: {
pluginDetail: PluginDetail
showType?: ReadmeShowType
className?: string
position?: 'left' | 'right'
showShortTip?: boolean
}) => {
const { t } = useTranslation()
@ -22,7 +24,7 @@ export const ReadmeEntrance = ({
const handleReadmeClick = () => {
if (pluginDetail)
setCurrentPluginDetail(pluginDetail, showType)
setCurrentPluginDetail(pluginDetail, showType, position)
}
if (!pluginDetail || !pluginDetail?.plugin_unique_identifier || BUILTIN_TOOLS_ARRAY.includes(pluginDetail.id))
return null

View File

@ -14,7 +14,7 @@ import { ReadmeShowType, useReadmePanelStore } from './store'
const ReadmePanel: FC = () => {
const { currentPluginDetail, setCurrentPluginDetail } = useReadmePanelStore()
const { detail, showType } = currentPluginDetail || {}
const { detail, showType, position } = currentPluginDetail || {}
const { t } = useTranslation()
const language = useLanguage()
@ -87,7 +87,7 @@ const ReadmePanel: FC = () => {
const portalContent = showType === ReadmeShowType.drawer
? (
<div className="fixed inset-0 z-[999] flex justify-start" onClick={onClose}>
<div className={cn('fixed inset-0 z-[999] flex', position === 'left' ? 'justify-start' : 'justify-end')} onClick={onClose}>
<div
className={cn(
'pointer-events-auto mb-2 ml-2 mr-2 mt-16 w-[600px] max-w-[600px] justify-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-0 shadow-xl',

View File

@ -10,18 +10,20 @@ type Shape = {
currentPluginDetail?: {
detail: PluginDetail
showType: ReadmeShowType
position?: 'left' | 'right'
}
setCurrentPluginDetail: (detail?: PluginDetail, showType?: ReadmeShowType) => void
setCurrentPluginDetail: (detail?: PluginDetail, showType?: ReadmeShowType, position?: 'left' | 'right') => void
}
export const useReadmePanelStore = create<Shape>(set => ({
currentPluginDetail: undefined,
setCurrentPluginDetail: (detail?: PluginDetail, showType?: ReadmeShowType) => set({
setCurrentPluginDetail: (detail?: PluginDetail, showType?: ReadmeShowType, position?: 'left' | 'right') => set({
currentPluginDetail: !detail
? undefined
: {
detail,
showType: showType ?? ReadmeShowType.drawer,
position,
},
}),
}))

View File

@ -1,15 +1,20 @@
import type { FC } from 'react'
import type { PluginDetail } from '@/app/components/plugins/types'
import type { Emoji } from '@/app/components/tools/types'
import type { ToolValue } from '@/app/components/workflow/block-selector/types'
import type { ToolWithProvider } from '@/app/components/workflow/types'
import * as React from 'react'
import { useEffect, useMemo, useState } from 'react'
import { createPortal } from 'react-dom'
import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import Modal from '@/app/components/base/modal'
import { useSelectOrDelete } from '@/app/components/base/prompt-editor/hooks'
import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import ToolAuthorizationSection from '@/app/components/plugins/plugin-detail-panel/tool-selector/sections/tool-authorization-section'
import { ReadmeEntrance } from '@/app/components/plugins/readme-panel/entrance'
import { ReadmeShowType } from '@/app/components/plugins/readme-panel/store'
import { CollectionType } from '@/app/components/tools/types'
import { generateFormValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
import { VarKindType } from '@/app/components/workflow/nodes/_base/types'
@ -103,6 +108,7 @@ const ToolBlockComponent: FC<ToolBlockComponentProps> = ({
}) => {
const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_TOOL_BLOCK_COMMAND)
const language = useGetLanguage()
const { t } = useTranslation()
const { theme } = useTheme()
const toolBlockContext = useToolBlockContext()
const isUsingExternalMetadata = Boolean(toolBlockContext?.onMetadataChange)
@ -396,11 +402,16 @@ const ToolBlockComponent: FC<ToolBlockComponentProps> = ({
}
const needAuthorization = useMemo(() => {
return !(!currentProvider || currentProvider.type !== CollectionType.builtIn || !currentProvider.allow_delete)
return !currentProvider?.is_team_authorization
}, [currentProvider])
const readmeEntrance = useMemo(() => {
if (!currentProvider)
return null
return <ReadmeEntrance pluginDetail={currentProvider as unknown as PluginDetail} showType={ReadmeShowType.drawer} position="right" className="mt-auto" />
}, [currentProvider])
const toolSettingsContent = currentProvider && currentTool && toolValue && (
<>
<div className="flex min-h-full flex-col">
<ToolHeader
icon={resolvedIcon}
providerLabel={currentProvider.label?.[language] || currentProvider.name || provider}
@ -408,25 +419,31 @@ const ToolBlockComponent: FC<ToolBlockComponentProps> = ({
description={toolDescriptionText}
onClose={() => setIsSettingOpen(false)}
/>
<ToolAuthorizationSection
currentProvider={currentProvider}
credentialId={toolValue.credential_id}
onAuthorizationItemClick={handleAuthorizationItemClick}
/>
{needAuthorization && (
<>
<ToolAuthorizationSection
currentProvider={currentProvider}
credentialId={toolValue.credential_id}
onAuthorizationItemClick={handleAuthorizationItemClick}
/>
</>
<div className="flex min-h-[200px] flex-1 flex-col items-center justify-center px-4 py-6 text-text-tertiary">
<div className="flex h-9 w-9 items-center justify-center rounded-full border border-divider-subtle">
<InfoCircle className="h-4 w-4 text-text-tertiary" />
</div>
<div className="system-xs-regular mt-3 text-text-tertiary">
{t('skillEditor.authorizationRequired', { ns: 'workflow' })}
</div>
</div>
)}
{!needAuthorization && (
<ToolSettingsSection
currentProvider={currentProvider}
currentTool={currentTool}
value={toolValue}
onChange={handleToolValueChange}
nodeId={undefined}
/>
)}
</>
<ToolSettingsSection
currentProvider={currentProvider}
currentTool={currentTool}
value={toolValue}
onChange={handleToolValueChange}
nodeId={undefined}
/>
{readmeEntrance}
</div>
)
return (

View File

@ -1031,6 +1031,7 @@
"singleRun.testRun": "Test Run",
"singleRun.testRunIteration": "Test Run Iteration",
"singleRun.testRunLoop": "Test Run Loop",
"skillEditor.authorizationRequired": "Authorization required before use.",
"skillEditor.previewUnavailable": "Preview unavailable",
"skillEditor.referenceFiles": "Reference files",
"skillEditor.unsupportedPreview": "This file type is not supported for preview",

View File

@ -1023,6 +1023,7 @@
"singleRun.testRun": "测试运行",
"singleRun.testRunIteration": "测试运行迭代",
"singleRun.testRunLoop": "测试运行循环",
"skillEditor.authorizationRequired": "使用前需要授权。",
"skillEditor.previewUnavailable": "无法预览",
"skillEditor.referenceFiles": "引用文件",
"skillEditor.unsupportedPreview": "该文件类型不支持预览",