From b820c7d1cb98602475d30af2bf3b16f9558321f0 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 10 Feb 2026 11:45:35 +0800 Subject: [PATCH] feat: plugin not found show --- .../plugins/tool-block/component.tsx | 111 +++++++++++++----- web/i18n/en-US/workflow.json | 2 + web/i18n/zh-Hans/workflow.json | 2 + web/i18n/zh-Hant/workflow.json | 2 + 4 files changed, 87 insertions(+), 30 deletions(-) diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx index 588cbebde8..012ec30c14 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx @@ -4,15 +4,17 @@ import type { ToolValue } from '@/app/components/workflow/block-selector/types' import type { ToolWithProvider } from '@/app/components/workflow/types' import type { AppAssetTreeView } from '@/types/app-asset' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' +import Link from 'next/link' import * as React from 'react' import { useEffect, useMemo, useState } from 'react' import { createPortal } from 'react-dom' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { useShallow } from 'zustand/react/shallow' 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 Tooltip from '@/app/components/base/tooltip' 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' @@ -207,6 +209,8 @@ const ToolBlockComponent = ({ const resultMetadata = fileMetadata.get(activeTabId) as SkillFileMetadata | undefined return resultMetadata?.tools?.[configId] }, [activeTabId, configId, fileMetadata, isUsingExternalMetadata, metadata]) + const isToolMissing = !currentProvider || !currentTool + const missingFieldCount = toolConfigFromMetadata?.configuration?.fields?.length ?? 0 const isInteractive = editor.isEditable() @@ -350,6 +354,13 @@ const ToolBlockComponent = ({ }, [currentProvider]) const renderIcon = () => { + if (isToolMissing) { + return ( + + + + ) + } if (!resolvedIcon) return null const iconNode = (() => { @@ -408,6 +419,27 @@ const ToolBlockComponent = ({ ) } + const missingTooltipContent = useMemo(() => { + if (!isToolMissing) + return null + return ( +
+
+ {t('skillEditor.toolMissing', { ns: 'workflow' })} +
+
+ , + }} + /> +
+
+ ) + }, [isToolMissing, t]) + const handleToolValueChange = (nextValue: ToolValue) => { setToolValue(nextValue) if (!currentProvider || !currentTool) @@ -562,36 +594,55 @@ const ToolBlockComponent = ({ return ( <> - { - if (!isInteractive) - return - if (!currentProvider || !currentTool) - return - if (configuredToolValue) - setToolValue(configuredToolValue) - setIsSettingOpen(true) - }} - > - {renderIcon()} - - {displayLabel} - - {needAuthorization && ( - - {authBadgeLabel} - + + + { + if (!isInteractive) + return + if (!currentProvider || !currentTool) + return + if (configuredToolValue) + setToolValue(configuredToolValue) + setIsSettingOpen(true) + }} + > + {renderIcon()} + + {displayLabel} + + {isToolMissing && ( + <> + + {missingFieldCount} + + + + + + )} + {!isToolMissing && needAuthorization && ( + + {authBadgeLabel} + + + )} - )} + {useModalValue && ( Plugins to install", "skillEditor.unsupportedPreview": "This file type is not supported for preview", "skillSidebar.addFile": "Upload File", "skillSidebar.addFolder": "New Folder", diff --git a/web/i18n/zh-Hans/workflow.json b/web/i18n/zh-Hans/workflow.json index 5b2d9c1ae2..82a886c7a0 100644 --- a/web/i18n/zh-Hans/workflow.json +++ b/web/i18n/zh-Hans/workflow.json @@ -1209,6 +1209,8 @@ "skillEditor.openInSkillEditor": "在技能编辑器中打开", "skillEditor.previewUnavailable": "无法预览", "skillEditor.referenceFiles": "引用文件", + "skillEditor.toolMissing": "工具缺失", + "skillEditor.toolMissingDesc": "前往 插件 安装", "skillEditor.unsupportedPreview": "该文件类型不支持预览", "skillSidebar.addFile": "上传文件", "skillSidebar.addFolder": "新建文件夹", diff --git a/web/i18n/zh-Hant/workflow.json b/web/i18n/zh-Hant/workflow.json index 2c5c277326..fc76da27be 100644 --- a/web/i18n/zh-Hant/workflow.json +++ b/web/i18n/zh-Hant/workflow.json @@ -1149,6 +1149,8 @@ "singleRun.testRunIteration": "測試運行迭代", "singleRun.testRunLoop": "測試運行循環", "skillEditor.referenceFiles": "參考檔案", + "skillEditor.toolMissing": "工具遺失", + "skillEditor.toolMissingDesc": "前往 外掛 安裝", "subGraphModal.canvasPlaceholder": "點擊配置內部結構", "subGraphModal.defaultValueHint": "返回以下值", "subGraphModal.internalStructure": "內部結構",