From ec31bbc24a4d13aed6cb7f70b264665d17285b60 Mon Sep 17 00:00:00 2001 From: jZonG Date: Wed, 7 May 2025 23:13:15 +0800 Subject: [PATCH] mcp card --- web/app/components/tools/mcp/hooks.ts | 12 ++++ web/app/components/tools/mcp/index.tsx | 19 +++-- web/app/components/tools/mcp/mock.ts | 18 ++--- .../components/tools/mcp/provider-card.tsx | 72 +++++++++++++++++++ web/i18n/en-US/tools.ts | 4 ++ web/i18n/zh-Hans/tools.ts | 4 ++ 6 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 web/app/components/tools/mcp/hooks.ts create mode 100644 web/app/components/tools/mcp/provider-card.tsx diff --git a/web/app/components/tools/mcp/hooks.ts b/web/app/components/tools/mcp/hooks.ts new file mode 100644 index 0000000000..b2b521557f --- /dev/null +++ b/web/app/components/tools/mcp/hooks.ts @@ -0,0 +1,12 @@ +import dayjs from 'dayjs' +import { useCallback } from 'react' +import { useI18N } from '@/context/i18n' + +export const useFormatTimeFromNow = () => { + const { locale } = useI18N() + const formatTimeFromNow = useCallback((time: number) => { + return dayjs(time).locale(locale === 'zh-Hans' ? 'zh-cn' : locale).fromNow() + }, [locale]) + + return { formatTimeFromNow } +} diff --git a/web/app/components/tools/mcp/index.tsx b/web/app/components/tools/mcp/index.tsx index fe92c6b288..248d791202 100644 --- a/web/app/components/tools/mcp/index.tsx +++ b/web/app/components/tools/mcp/index.tsx @@ -1,7 +1,9 @@ 'use client' -import { useMemo } from 'react' +import { useMemo, useState } from 'react' import NewMCPCard from './create-card' +import MCPCard from './provider-card' import { useAllMCPTools, useInvalidateAllMCPTools } from '@/service/use-tools' +import type { MCPProvider } from '@/app/components/tools/types' import cn from '@/utils/classnames' type Props = { @@ -22,12 +24,14 @@ const MCPList = ({ }) }, [list, searchText]) + const [currentProvider, setCurrentProvider] = useState() + function renderDefaultCard() { const defaultCards = Array.from({ length: 36 }, (_, index) => (
= 4 && index < 8 && 'opacity-50', index >= 8 && index < 12 && 'opacity-40', @@ -44,13 +48,18 @@ const MCPList = ({ <>
- {filteredList.map((item, index) => ( -
+ {filteredList.map(provider => ( + ))} {!list.length && renderDefaultCard()}
diff --git a/web/app/components/tools/mcp/mock.ts b/web/app/components/tools/mcp/mock.ts index 26633f824f..083e84bddb 100644 --- a/web/app/components/tools/mcp/mock.ts +++ b/web/app/components/tools/mcp/mock.ts @@ -1,35 +1,35 @@ export const listData = [ { - id: 'fdjklajfkljadslf', + id: 'fdjklajfkljadslf111', author: 'KVOJJJin', name: 'GOGOGO', icon: 'https://cloud.dify.dev/console/api/workspaces/694cc430-fa36-4458-86a0-4a98c09c4684/model-providers/langgenius/openai/openai/icon_large/en_US', server_url: 'https://mcp.composio.dev/notion/****/abc', type: 'mcp', - is_team_authorization: false, + is_team_authorization: true, tools: ['aaa', 'bbb'], - update_elapsed_time: 1742892299, + update_elapsed_time: 1744793369, }, { - id: 'fdjklajfkljadslf', + id: 'fdjklajfkljadslf222', author: 'KVOJJJin', name: 'GOGOGO2', icon: 'https://cloud.dify.dev/console/api/workspaces/694cc430-fa36-4458-86a0-4a98c09c4684/model-providers/langgenius/openai/openai/icon_large/en_US', server_url: 'https://mcp.composio.dev/notion/****/abc', type: 'mcp', is_team_authorization: false, - tools: ['aaa', 'bbb'], - update_elapsed_time: 1742892299, + tools: [], + update_elapsed_time: 1744793369, }, { - id: 'fdjklajfkljadslf', + id: 'fdjklajfkljadslf333', author: 'KVOJJJin', name: 'GOGOGO3', icon: 'https://cloud.dify.dev/console/api/workspaces/694cc430-fa36-4458-86a0-4a98c09c4684/model-providers/langgenius/openai/openai/icon_large/en_US', server_url: 'https://mcp.composio.dev/notion/****/abc', type: 'mcp', - is_team_authorization: false, + is_team_authorization: true, tools: ['aaa', 'bbb'], - update_elapsed_time: 1742892299, + update_elapsed_time: 1744793369, }, ] diff --git a/web/app/components/tools/mcp/provider-card.tsx b/web/app/components/tools/mcp/provider-card.tsx new file mode 100644 index 0000000000..9080c45e53 --- /dev/null +++ b/web/app/components/tools/mcp/provider-card.tsx @@ -0,0 +1,72 @@ +'use client' +// import { useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +// import { useContext } from 'use-context-selector' +// import I18n from '@/context/i18n' +// import { getLanguage } from '@/i18n/language' +// import { useAppContext } from '@/context/app-context' +import { RiHammerFill } from '@remixicon/react' +import Indicator from '@/app/components/header/indicator' +import Icon from '@/app/components/plugins/card/base/card-icon' +import { useFormatTimeFromNow } from './hooks' +import type { MCPProvider } from '@/app/components/tools/types' +import cn from '@/utils/classnames' + +type Props = { + currentProvider?: MCPProvider + data: MCPProvider + handleSelect: (provider: MCPProvider) => void +} + +const MCPCard = ({ + currentProvider, + data, + handleSelect, +}: Props) => { + const { t } = useTranslation() + const { formatTimeFromNow } = useFormatTimeFromNow() + // const { locale } = useContext(I18n) + // const language = getLanguage(locale) +// const { isCurrentWorkspaceManager } = useAppContext() + + return ( +
handleSelect(data)} + className={cn( + 'relative flex cursor-pointer flex-col rounded-xl border-[1.5px] border-transparent bg-components-card-bg shadow-xs hover:bg-components-card-bg-alt hover:shadow-md', + currentProvider?.id === data.id && 'border-components-option-card-option-selected-border bg-components-card-bg-alt', + )} + > +
+ +
+
{data.name}
+
+
+ + {data.tools.length > 0 && ( +
{t('tools.mcp.toolsCount', { count: data.tools.length })}
+ )} + {!data.tools.length && ( +
{t('tools.mcp.noTools')}
+ )} +
+
/
+
{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.update_elapsed_time * 1000)}`}
+
+
+
+
+
{data.server_url}
+ {data.is_team_authorization && } + {!data.is_team_authorization && ( +
+ {t('tools.mcp.noConfigured')} + +
+ )} +
+
+ ) +} +export default MCPCard diff --git a/web/i18n/en-US/tools.ts b/web/i18n/en-US/tools.ts index 550989b58a..624819efae 100644 --- a/web/i18n/en-US/tools.ts +++ b/web/i18n/en-US/tools.ts @@ -158,6 +158,10 @@ const translation = { cardTitle: 'Add MCP Server (HTTP)', cardLink: 'Learn more about MCP server integration', }, + noConfigured: 'Unconfigured Server', + updateTime: 'Updated', + toolsCount: '{{count}} tools', + noTools: 'No tools available', }, } diff --git a/web/i18n/zh-Hans/tools.ts b/web/i18n/zh-Hans/tools.ts index b1a9978940..4f8dcc09e2 100644 --- a/web/i18n/zh-Hans/tools.ts +++ b/web/i18n/zh-Hans/tools.ts @@ -158,6 +158,10 @@ const translation = { cardTitle: '添加 MCP 服务 (HTTP)', cardLink: '了解更多关于 MCP 服务集成的信息', }, + noConfigured: '未配置', + updateTime: '更新于', + toolsCount: '{{count}} 个工具', + noTools: '没有可用的工具', }, }