From b6e140f5479035722f51695ee2e6cf5378805528 Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Fri, 26 Dec 2025 23:46:52 +0800 Subject: [PATCH] type safe --- web/app/components/plugins/constants.ts | 8 ++++++-- web/app/components/plugins/hooks.ts | 11 ++++++----- .../subscription-list/create/index.tsx | 2 +- .../hooks/use-available-nodes-meta-data.ts | 4 ++-- .../rag-pipeline/hooks/use-pipeline-template.ts | 2 +- .../tools/edit-custom-collection-modal/examples.ts | 2 +- .../tools/edit-custom-collection-modal/get-schema.tsx | 2 +- .../tools/edit-custom-collection-modal/index.tsx | 2 +- .../tools/edit-custom-collection-modal/test-api.tsx | 2 +- web/app/components/tools/provider/empty.tsx | 10 +++++----- web/i18n/en-US/tools.json | 6 ++++++ web/i18n/en-US/workflow.json | 6 ++++++ 12 files changed, 37 insertions(+), 20 deletions(-) diff --git a/web/app/components/plugins/constants.ts b/web/app/components/plugins/constants.ts index d9203fd4ea..f618e68764 100644 --- a/web/app/components/plugins/constants.ts +++ b/web/app/components/plugins/constants.ts @@ -19,7 +19,9 @@ export const tagKeys = [ 'entertainment', 'utilities', 'other', -] +] as const + +export type TagKey = typeof tagKeys[number] export const categoryKeys = [ PluginCategoryEnum.model, @@ -29,4 +31,6 @@ export const categoryKeys = [ PluginCategoryEnum.extension, 'bundle', PluginCategoryEnum.trigger, -] +] as const + +export type CategoryKey = typeof categoryKeys[number] diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts index ecab8338ca..262935205b 100644 --- a/web/app/components/plugins/hooks.ts +++ b/web/app/components/plugins/hooks.ts @@ -1,4 +1,5 @@ import type { TFunction } from 'i18next' +import type { CategoryKey, TagKey } from './constants' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { @@ -8,7 +9,7 @@ import { import { PluginCategoryEnum } from './types' export type Tag = { - name: string + name: TagKey label: string } @@ -20,7 +21,7 @@ export const useTags = (translateFromOut?: TFunction) => { return tagKeys.map((tag) => { return { name: tag, - label: t(`tags.${tag}` as any, { ns: 'pluginTags' }) as string, + label: t(`tags.${tag}`, { ns: 'pluginTags' }), } }) }, [t]) @@ -48,7 +49,7 @@ export const useTags = (translateFromOut?: TFunction) => { } type Category = { - name: string + name: CategoryKey label: string } @@ -66,14 +67,14 @@ export const useCategories = (translateFromOut?: TFunction, isSingle?: boolean) } return { name: category, - label: isSingle ? t(`categorySingle.${category}` as any, { ns: 'plugin' }) as string : t(`category.${category}s` as any, { ns: 'plugin' }) as string, + label: isSingle ? t(`categorySingle.${category}`, { ns: 'plugin' }) : t(`category.${category}s`, { ns: 'plugin' }), } }) }, [t, isSingle]) const categoriesMap = useMemo(() => { return categories.reduce((acc, category) => { - acc[category.name] = category as any + acc[category.name] = category return acc }, {} as Record) }, [categories]) diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx index 54d9bdc237..d119f42a13 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx @@ -208,7 +208,7 @@ export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BU ) : ( = MAX_COUNT ? t('subscription.maxCount', { ns: 'pluginTrigger', num: MAX_COUNT }) : t(`subscription.addType.options.${methodType.toLowerCase()}.description` as any, { ns: 'pluginTrigger' })} + popupContent={subscriptionCount >= MAX_COUNT ? t('subscription.maxCount', { ns: 'pluginTrigger', num: MAX_COUNT }) : t(`subscription.addType.options.${methodType.toLowerCase() as Lowercase}.description`, { ns: 'pluginTrigger' })} disabled={!(supportedMethods?.length === 1 || subscriptionCount >= MAX_COUNT)} > { const availableNodesMetaData = useMemo(() => mergedNodesMetaData.map((node) => { const { metaData } = node - const title = t(`blocks.${metaData.type}` as any, { ns: 'workflow' }) as string - const description = t(`blocksAbout.${metaData.type}` as any, { ns: 'workflow' }) as string + const title = t(`blocks.${metaData.type}`, { ns: 'workflow' }) + const description = t(`blocksAbout.${metaData.type}`, { ns: 'workflow' }) return { ...node, metaData: { diff --git a/web/app/components/rag-pipeline/hooks/use-pipeline-template.ts b/web/app/components/rag-pipeline/hooks/use-pipeline-template.ts index 19e2fe9fa5..be3490c47c 100644 --- a/web/app/components/rag-pipeline/hooks/use-pipeline-template.ts +++ b/web/app/components/rag-pipeline/hooks/use-pipeline-template.ts @@ -14,7 +14,7 @@ export const usePipelineTemplate = () => { data: { ...knowledgeBaseDefault.defaultValue as KnowledgeBaseNodeType, type: knowledgeBaseDefault.metaData.type, - title: t(`blocks.${knowledgeBaseDefault.metaData.type}` as any, { ns: 'workflow' }) as string, + title: t(`blocks.${knowledgeBaseDefault.metaData.type}`, { ns: 'workflow' }), selected: true, }, position: { diff --git a/web/app/components/tools/edit-custom-collection-modal/examples.ts b/web/app/components/tools/edit-custom-collection-modal/examples.ts index 0d8369c14e..089de2ea1d 100644 --- a/web/app/components/tools/edit-custom-collection-modal/examples.ts +++ b/web/app/components/tools/edit-custom-collection-modal/examples.ts @@ -176,6 +176,6 @@ const examples = [ } }`, }, -] +] as const export default examples diff --git a/web/app/components/tools/edit-custom-collection-modal/get-schema.tsx b/web/app/components/tools/edit-custom-collection-modal/get-schema.tsx index e53bbaff37..7ad8050a2d 100644 --- a/web/app/components/tools/edit-custom-collection-modal/get-schema.tsx +++ b/web/app/components/tools/edit-custom-collection-modal/get-schema.tsx @@ -111,7 +111,7 @@ const GetSchema: FC = ({ }} className="system-sm-regular cursor-pointer whitespace-nowrap rounded-lg px-3 py-1.5 leading-5 text-text-secondary hover:bg-components-panel-on-panel-item-bg-hover" > - {t(`createTool.exampleOptions.${item.key}` as any, { ns: 'tools' }) as string} + {t(`createTool.exampleOptions.${item.key}`, { ns: 'tools' })} ))} diff --git a/web/app/components/tools/edit-custom-collection-modal/index.tsx b/web/app/components/tools/edit-custom-collection-modal/index.tsx index c74579b829..5fad827a69 100644 --- a/web/app/components/tools/edit-custom-collection-modal/index.tsx +++ b/web/app/components/tools/edit-custom-collection-modal/index.tsx @@ -292,7 +292,7 @@ const EditCustomCollectionModal: FC = ({
{t('createTool.authMethod.title', { ns: 'tools' })}
setCredentialsModalShow(true)}> -
{t(`createTool.authMethod.types.${credential.auth_type}` as any, { ns: 'tools' }) as string}
+
{t(`createTool.authMethod.types.${credential.auth_type}`, { ns: 'tools' })}
diff --git a/web/app/components/tools/edit-custom-collection-modal/test-api.tsx b/web/app/components/tools/edit-custom-collection-modal/test-api.tsx index 7e9eb43b27..978870baa1 100644 --- a/web/app/components/tools/edit-custom-collection-modal/test-api.tsx +++ b/web/app/components/tools/edit-custom-collection-modal/test-api.tsx @@ -78,7 +78,7 @@ const TestApi: FC = ({
{t('createTool.authMethod.title', { ns: 'tools' })}
setCredentialsModalShow(true)}> -
{t(`createTool.authMethod.types.${tempCredential.auth_type}` as any, { ns: 'tools' }) as string}
+
{t(`createTool.authMethod.types.${tempCredential.auth_type}`, { ns: 'tools' })}
diff --git a/web/app/components/tools/provider/empty.tsx b/web/app/components/tools/provider/empty.tsx index 262f173b3a..4940dd6fc5 100644 --- a/web/app/components/tools/provider/empty.tsx +++ b/web/app/components/tools/provider/empty.tsx @@ -32,18 +32,18 @@ const Empty = ({ const hasLink = type && [ToolTypeEnum.Custom, ToolTypeEnum.MCP].includes(type) const Comp = (hasLink ? Link : 'div') as any const linkProps = hasLink ? { href: getLink(type), target: '_blank' } : {} - const renderType = isAgent ? 'agent' : type - const hasTitle = t(`addToolModal.${renderType}.title` as any, { ns: 'tools' }) as string !== `tools.addToolModal.${renderType}.title` + const renderType = isAgent ? 'agent' as const : type + const hasTitle = renderType && t(`addToolModal.${renderType}.title`, { ns: 'tools' }) !== `addToolModal.${renderType}.title` return (
- {hasTitle ? t(`addToolModal.${renderType}.title` as any, { ns: 'tools' }) as string : 'No tools available'} + {(hasTitle && renderType) ? t(`addToolModal.${renderType}.title`, { ns: 'tools' }) : 'No tools available'}
- {(!isAgent && hasTitle) && ( + {(!isAgent && hasTitle && renderType) && ( - {t(`addToolModal.${renderType}.tip` as any, { ns: 'tools' }) as string} + {t(`addToolModal.${renderType}.tip`, { ns: 'tools' })} {' '} {hasLink && } diff --git a/web/i18n/en-US/tools.json b/web/i18n/en-US/tools.json index 53eff967e4..30ee4f58df 100644 --- a/web/i18n/en-US/tools.json +++ b/web/i18n/en-US/tools.json @@ -1,6 +1,11 @@ { "addToolModal.added": "added", + "addToolModal.agent.tip": "", "addToolModal.agent.title": "No agent strategy available", + "addToolModal.all.tip": "", + "addToolModal.all.title": "No tools available", + "addToolModal.built-in.tip": "", + "addToolModal.built-in.title": "No built-in tool available", "addToolModal.category": "category", "addToolModal.custom.tip": "Create a custom tool", "addToolModal.custom.title": "No custom tool available", @@ -34,6 +39,7 @@ "createTool.authMethod.type": "Authorization type", "createTool.authMethod.types.apiKeyPlaceholder": "HTTP header name for API Key", "createTool.authMethod.types.apiValuePlaceholder": "Enter API Key", + "createTool.authMethod.types.api_key": "API Key", "createTool.authMethod.types.api_key_header": "Header", "createTool.authMethod.types.api_key_query": "Query Param", "createTool.authMethod.types.none": "None", diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 224be01d1b..454b4a4253 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -4,6 +4,7 @@ "blocks.assigner": "Variable Assigner", "blocks.code": "Code", "blocks.datasource": "Data Source", + "blocks.datasource-empty": "Empty Data Source", "blocks.document-extractor": "Doc Extractor", "blocks.end": "Output", "blocks.http-request": "HTTP Request", @@ -22,6 +23,7 @@ "blocks.question-classifier": "Question Classifier", "blocks.start": "User Input", "blocks.template-transform": "Template", + "blocks.tool": "Tool", "blocks.trigger-plugin": "Plugin Trigger", "blocks.trigger-schedule": "Schedule Trigger", "blocks.trigger-webhook": "Webhook Trigger", @@ -32,21 +34,25 @@ "blocksAbout.assigner": "The variable assignment node is used for assigning values to writable variables(like conversation variables).", "blocksAbout.code": "Execute a piece of Python or NodeJS code to implement custom logic", "blocksAbout.datasource": "Data Source About", + "blocksAbout.datasource-empty": "Empty Data Source placeholder", "blocksAbout.document-extractor": "Used to parse uploaded documents into text content that is easily understandable by LLM.", "blocksAbout.end": "Define the output and result type of a workflow", "blocksAbout.http-request": "Allow server requests to be sent over the HTTP protocol", "blocksAbout.if-else": "Allows you to split the workflow into two branches based on if/else conditions", "blocksAbout.iteration": "Perform multiple steps on a list object until all results are outputted.", + "blocksAbout.iteration-start": "Iteration Start node", "blocksAbout.knowledge-index": "Knowledge Base About", "blocksAbout.knowledge-retrieval": "Allows you to query text content related to user questions from the Knowledge", "blocksAbout.list-operator": "Used to filter or sort array content.", "blocksAbout.llm": "Invoking large language models to answer questions or process natural language", "blocksAbout.loop": "Execute a loop of logic until the termination condition is met or the maximum loop count is reached.", "blocksAbout.loop-end": "Equivalent to \"break\". This node has no configuration items. When the loop body reaches this node, the loop terminates.", + "blocksAbout.loop-start": "Loop Start node", "blocksAbout.parameter-extractor": "Use LLM to extract structured parameters from natural language for tool invocations or HTTP requests.", "blocksAbout.question-classifier": "Define the classification conditions of user questions, LLM can define how the conversation progresses based on the classification description", "blocksAbout.start": "Define the initial parameters for launching a workflow", "blocksAbout.template-transform": "Convert data to string using Jinja template syntax", + "blocksAbout.tool": "Use external tools to extend workflow capabilities", "blocksAbout.trigger-plugin": "Third-party integration trigger that starts workflows from external platform events", "blocksAbout.trigger-schedule": "Time-based workflow trigger that starts workflows on a schedule", "blocksAbout.trigger-webhook": "Webhook Trigger receives HTTP pushes from third-party systems to automatically trigger workflows.",