From 4d37d618514a9e7f25e73733ddcfb31cbc99dcda Mon Sep 17 00:00:00 2001 From: lyzno1 Date: Thu, 30 Oct 2025 15:33:32 +0800 Subject: [PATCH] feat: dim node --- .../hooks/use-node-plugin-installation.ts | 10 ++++++++++ .../workflow/nodes/data-source/node.tsx | 17 ++++++++++++++++- web/app/components/workflow/nodes/tool/node.tsx | 17 ++++++++++++++++- .../workflow/nodes/trigger-plugin/node.tsx | 16 +++++++++++++++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/web/app/components/workflow/hooks/use-node-plugin-installation.ts b/web/app/components/workflow/hooks/use-node-plugin-installation.ts index d82ed0ac61..96e3919e67 100644 --- a/web/app/components/workflow/hooks/use-node-plugin-installation.ts +++ b/web/app/components/workflow/hooks/use-node-plugin-installation.ts @@ -99,12 +99,15 @@ const useToolInstallation = (data: ToolNodeType): InstallationState => { invalidateTools() }, [invalidateTools]) + const shouldDim = (!!collectionInfo && !isResolved) || (isResolved && !matchedCollection) + return { isChecking: !!collectionInfo && !isResolved, isMissing: isResolved && !matchedCollection, uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } } @@ -138,12 +141,15 @@ const useTriggerInstallation = (data: PluginTriggerNodeType): InstallationState invalidateTriggers() }, [invalidateTriggers]) + const shouldDim = isLoading || (!isLoading && !!triggerProviders && !matchedProvider) + return { isChecking: isLoading, isMissing: !isLoading && !!triggerProviders && !matchedProvider, uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } } @@ -175,12 +181,15 @@ const useDataSourceInstallation = (data: DataSourceNodeType): InstallationState const hasLoadedList = dataSourceList !== undefined + const shouldDim = !hasLoadedList || (hasLoadedList && !matchedPlugin) + return { isChecking: !hasLoadedList, isMissing: hasLoadedList && !matchedPlugin, uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } } @@ -203,6 +212,7 @@ export const useNodePluginInstallation = (data: CommonNodeType): InstallationSta uniqueIdentifier: undefined, canInstall: false, onInstallSuccess: () => undefined, + shouldDim: false, } } } diff --git a/web/app/components/workflow/nodes/data-source/node.tsx b/web/app/components/workflow/nodes/data-source/node.tsx index ada649270e..354758074b 100644 --- a/web/app/components/workflow/nodes/data-source/node.tsx +++ b/web/app/components/workflow/nodes/data-source/node.tsx @@ -1,11 +1,13 @@ import type { FC } from 'react' -import { memo } from 'react' +import { memo, useEffect } from 'react' import type { NodeProps } from '@/app/components/workflow/types' import { InstallPluginButton } from '@/app/components/workflow/nodes/_base/components/install-plugin-button' import { useNodePluginInstallation } from '@/app/components/workflow/hooks/use-node-plugin-installation' +import { useNodeDataUpdate } from '@/app/components/workflow/hooks/use-node-data-update' import type { DataSourceNodeType } from './types' const Node: FC> = ({ + id, data, }) => { const { @@ -14,7 +16,20 @@ const Node: FC> = ({ uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } = useNodePluginInstallation(data) + const { handleNodeDataUpdate } = useNodeDataUpdate() + + useEffect(() => { + if (data._dimmed === shouldDim) + return + handleNodeDataUpdate({ + id, + data: { + _dimmed: shouldDim, + }, + }) + }, [data._dimmed, handleNodeDataUpdate, id, shouldDim]) const showInstallButton = !isChecking && isMissing && canInstall && uniqueIdentifier diff --git a/web/app/components/workflow/nodes/tool/node.tsx b/web/app/components/workflow/nodes/tool/node.tsx index 0ebee2966c..584d6ff3de 100644 --- a/web/app/components/workflow/nodes/tool/node.tsx +++ b/web/app/components/workflow/nodes/tool/node.tsx @@ -1,12 +1,14 @@ import type { FC } from 'react' -import React from 'react' +import React, { useEffect } from 'react' import type { NodeProps } from '@/app/components/workflow/types' import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { InstallPluginButton } from '@/app/components/workflow/nodes/_base/components/install-plugin-button' import { useNodePluginInstallation } from '@/app/components/workflow/hooks/use-node-plugin-installation' +import { useNodeDataUpdate } from '@/app/components/workflow/hooks/use-node-data-update' import type { ToolNodeType } from './types' const Node: FC> = ({ + id, data, }) => { const { tool_configurations, paramSchemas } = data @@ -17,8 +19,21 @@ const Node: FC> = ({ uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } = useNodePluginInstallation(data) const showInstallButton = !isChecking && isMissing && canInstall && uniqueIdentifier + const { handleNodeDataUpdate } = useNodeDataUpdate() + + useEffect(() => { + if (data._dimmed === shouldDim) + return + handleNodeDataUpdate({ + id, + data: { + _dimmed: shouldDim, + }, + }) + }, [data._dimmed, handleNodeDataUpdate, id, shouldDim]) const hasConfigs = toolConfigs.length > 0 diff --git a/web/app/components/workflow/nodes/trigger-plugin/node.tsx b/web/app/components/workflow/nodes/trigger-plugin/node.tsx index 53694c8759..0aa7f656e2 100644 --- a/web/app/components/workflow/nodes/trigger-plugin/node.tsx +++ b/web/app/components/workflow/nodes/trigger-plugin/node.tsx @@ -1,10 +1,11 @@ import NodeStatus, { NodeStatusEnum } from '@/app/components/base/node-status' import type { NodeProps } from '@/app/components/workflow/types' import type { FC } from 'react' -import React, { useMemo } from 'react' +import React, { useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { InstallPluginButton } from '@/app/components/workflow/nodes/_base/components/install-plugin-button' import { useNodePluginInstallation } from '@/app/components/workflow/hooks/use-node-plugin-installation' +import { useNodeDataUpdate } from '@/app/components/workflow/hooks/use-node-data-update' import type { PluginTriggerNodeType } from './types' import useConfig from './use-config' @@ -50,9 +51,22 @@ const Node: FC> = ({ uniqueIdentifier, canInstall, onInstallSuccess, + shouldDim, } = useNodePluginInstallation(data) + const { handleNodeDataUpdate } = useNodeDataUpdate() const showInstallButton = !isChecking && isMissing && canInstall && uniqueIdentifier + useEffect(() => { + if (data._dimmed === shouldDim) + return + handleNodeDataUpdate({ + id, + data: { + _dimmed: shouldDim, + }, + }) + }, [data._dimmed, handleNodeDataUpdate, id, shouldDim]) + const { t } = useTranslation() const isValidSubscription = useMemo(() => {