From 8af8a0f46de15ad73db130c38e87fa562f008f46 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Thu, 31 Oct 2024 15:41:02 +0800 Subject: [PATCH 1/3] fix: tool list --- .../plugins/marketplace/empty/line.tsx | 2 +- web/app/components/tools/marketplace/hooks.ts | 52 ++++++++++++++++--- .../components/tools/marketplace/index.tsx | 8 ++- web/app/components/tools/provider-list.tsx | 10 ++-- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/web/app/components/plugins/marketplace/empty/line.tsx b/web/app/components/plugins/marketplace/empty/line.tsx index b505b7846a..19837aa862 100644 --- a/web/app/components/plugins/marketplace/empty/line.tsx +++ b/web/app/components/plugins/marketplace/empty/line.tsx @@ -9,7 +9,7 @@ const Line = ({ - + diff --git a/web/app/components/tools/marketplace/hooks.ts b/web/app/components/tools/marketplace/hooks.ts index 0486db71d2..d84e548653 100644 --- a/web/app/components/tools/marketplace/hooks.ts +++ b/web/app/components/tools/marketplace/hooks.ts @@ -3,28 +3,68 @@ import { useEffect, useState, } from 'react' +import { useDebounceFn } from 'ahooks' import type { Plugin } from '@/app/components/plugins/types' -import type { MarketplaceCollection } from '@/app/components/plugins/marketplace/types' -import { getMarketplaceCollectionsAndPlugins } from '@/app/components/plugins/marketplace/utils' +import type { + MarketplaceCollection, + PluginsSearchParams, +} from '@/app/components/plugins/marketplace/types' +import { + getMarketplaceCollectionsAndPlugins, + getMarketplacePlugins, +} from '@/app/components/plugins/marketplace/utils' -export const useMarketplace = () => { +export const useMarketplace = (searchPluginText: string, filterPluginTags: string[]) => { const [marketplaceCollections, setMarketplaceCollections] = useState([]) const [marketplaceCollectionPluginsMap, setMarketplaceCollectionPluginsMap] = useState>({}) const [isLoading, setIsLoading] = useState(true) - const getMarketplaceCollections = useCallback(async () => { + const [plugins, setPlugins] = useState() + + const handleUpldateMarketplaceCollections = useCallback(async () => { setIsLoading(true) const { marketplaceCollections, marketplaceCollectionPluginsMap } = await getMarketplaceCollectionsAndPlugins() setIsLoading(false) + setMarketplaceCollections(marketplaceCollections) setMarketplaceCollectionPluginsMap(marketplaceCollectionPluginsMap) + setPlugins(undefined) }, []) + + const handleUpdatePlugins = async (query: PluginsSearchParams) => { + setIsLoading(true) + const { marketplacePlugins } = await getMarketplacePlugins(query) + setIsLoading(false) + + setPlugins(marketplacePlugins) + } + + const { run: handleUpdatePluginsWithDebounced } = useDebounceFn(handleUpdatePlugins, { + wait: 500, + }) + useEffect(() => { - getMarketplaceCollections() - }, [getMarketplaceCollections]) + if (searchPluginText || filterPluginTags.length) { + if (searchPluginText) { + handleUpdatePluginsWithDebounced({ + query: searchPluginText, + tags: filterPluginTags, + }) + return + } + handleUpdatePlugins({ + query: searchPluginText, + tags: filterPluginTags, + }) + } + else { + handleUpldateMarketplaceCollections() + } + }, [searchPluginText, filterPluginTags, handleUpdatePluginsWithDebounced, handleUpldateMarketplaceCollections]) return { isLoading, marketplaceCollections, marketplaceCollectionPluginsMap, + plugins, } } diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx index 64ec83f460..2bb935db14 100644 --- a/web/app/components/tools/marketplace/index.tsx +++ b/web/app/components/tools/marketplace/index.tsx @@ -4,16 +4,21 @@ import List from '@/app/components/plugins/marketplace/list' import Loading from '@/app/components/base/loading' type MarketplaceProps = { + searchPluginText: string + filterPluginTags: string[] onMarketplaceScroll: () => void } const Marketplace = ({ + searchPluginText, + filterPluginTags, onMarketplaceScroll, }: MarketplaceProps) => { const { isLoading, marketplaceCollections, marketplaceCollectionPluginsMap, - } = useMarketplace() + plugins, + } = useMarketplace(searchPluginText, filterPluginTags) return (
@@ -55,6 +60,7 @@ const Marketplace = ({ ) diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 24baf9f0e1..acec3dad7e 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -126,9 +126,13 @@ const ProviderList = () => {
{ enable_marketplace && ( - { - containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) - }} /> + { + containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) + }} + searchPluginText={keywords} + filterPluginTags={tagFilterValue} + /> ) } From ae21d48132be8c26e1a6d97063471f310864e771 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 31 Oct 2024 15:59:30 +0800 Subject: [PATCH 2/3] feat: list flat view --- .../workflow/block-selector/index-bar.tsx | 6 ++-- .../tool/tool-list-flat-view/list.tsx | 24 ++++++++++++-- .../tool/tool-list-tree-view/list.tsx | 22 ++++++++++--- .../workflow/block-selector/tool/tool.tsx | 31 ++++++++++++++++--- .../workflow/block-selector/tools.tsx | 13 +++++++- 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/web/app/components/workflow/block-selector/index-bar.tsx b/web/app/components/workflow/block-selector/index-bar.tsx index e21bcedeb9..076d7e7ec9 100644 --- a/web/app/components/workflow/block-selector/index-bar.tsx +++ b/web/app/components/workflow/block-selector/index-bar.tsx @@ -3,6 +3,8 @@ import type { FC, RefObject } from 'react' import type { ToolWithProvider } from '../types' import { CollectionType } from '../../tools/types' +export const CUSTOM_GROUP_NAME = '@@@custom@@@' +export const WORKFLOW_GROUP_NAME = '@@@workflow@@@' /* { A: { @@ -42,9 +44,9 @@ export const groupItems = (items: ToolWithProvider[], getFirstChar: (item: ToolW if (item.type === CollectionType.builtIn) groupName = item.author else if (item.type === CollectionType.custom) - groupName = 'custom' + groupName = CUSTOM_GROUP_NAME else - groupName = 'workflow' + groupName = WORKFLOW_GROUP_NAME if (!acc[letter][groupName]) acc[letter][groupName] = [] diff --git a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx index 3639da5f2b..c59f67e66c 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx @@ -1,16 +1,34 @@ 'use client' import type { FC } from 'react' import React from 'react' +import type { ToolWithProvider } from '../../../types' +import type { BlockEnum } from '../../../types' +import type { ToolDefaultValue } from '../../types' +import Tool from '../tool' +import { ViewType } from '../../view-type-select' type Props = { - + payload: ToolWithProvider[] + onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } -const ToolViewFlatView: FC = () => { +const ToolViewFlatView: FC = ({ + payload, + onSelect, +}) => { return (
- list... + {payload.map(tool => ( + + ))}
) } + export default React.memo(ToolViewFlatView) diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx index a621f08747..1b0dbddca6 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx @@ -1,20 +1,33 @@ 'use client' import type { FC } from 'react' -import React from 'react' +import React, { useCallback } from 'react' import type { ToolWithProvider } from '../../../types' import type { BlockEnum } from '../../../types' import type { ToolDefaultValue } from '../../types' import Item from './item' +import { useTranslation } from 'react-i18next' +import { CUSTOM_GROUP_NAME, WORKFLOW_GROUP_NAME } from '../../index-bar' type Props = { payload: Record onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } -const OrgTools: FC = ({ +const ToolListTreeView: FC = ({ payload, onSelect, }) => { + const { t } = useTranslation() + const getI18nGroupName = useCallback((name: string) => { + if (name === CUSTOM_GROUP_NAME) + return t('workflow.tabs.customTool') + + if (name === WORKFLOW_GROUP_NAME) + return t('workflow.tabs.workflowTool') + + return name + }, [t]) + if (!payload) return null return ( @@ -22,7 +35,7 @@ const OrgTools: FC = ({ {Object.keys(payload).map(groupName => ( @@ -30,4 +43,5 @@ const OrgTools: FC = ({ ) } -export default React.memo(OrgTools) + +export default React.memo(ToolListTreeView) diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index 3e9db61586..958be74143 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React from 'react' +import React, { useMemo } from 'react' import cn from '@/utils/classnames' import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react' import { useGetLanguage } from '@/context/i18n' @@ -13,6 +13,7 @@ import ActonItem from './action-item' import BlockIcon from '../../block-icon' import { useBoolean } from 'ahooks' +import { useTranslation } from 'react-i18next' type Props = { className?: string @@ -29,8 +30,9 @@ const Tool: FC = ({ isShowLetterIndex, onSelect, }) => { + const { t } = useTranslation() const language = useGetLanguage() - const isTreeView = viewType === ViewType.tree + const isFlatView = viewType === ViewType.flat const actions = payload.tools const hasAction = payload.type === CollectionType.builtIn const [isFold, { @@ -38,6 +40,19 @@ const Tool: FC = ({ }] = useBoolean(false) const FoldIcon = isFold ? RiArrowDownSLine : RiArrowRightSLine + const groupName = useMemo(() => { + if (payload.type === CollectionType.builtIn) + return payload.author + + if (payload.type === CollectionType.custom) + return t('workflow.tabs.customTool') + + if (payload.type === CollectionType.workflow) + return t('workflow.tabs.workflowTool') + + return '' + }, [payload.author, payload.type, t]) + return (
= ({ />
{payload.label[language]}
- {hasAction && ( - - )} + +
+ {isFlatView && ( +
{groupName}
+ )} + {hasAction && ( + + )} +
{hasAction && isFold && ( diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index 409a0c87f9..5bc3af3a77 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -28,7 +28,6 @@ const Blocks = ({ const { t } = useTranslation() const language = useGetLanguage() const isFlatView = viewType === ViewType.flat - const isTreeView = viewType === ViewType.tree const isShowLetterIndex = isFlatView && tools.length > 10 /* @@ -61,6 +60,16 @@ const Blocks = ({ return result }, [withLetterAndGroupViewToolsData]) + const listViewToolData = useMemo(() => { + const result: ToolWithProvider[] = [] + Object.keys(withLetterAndGroupViewToolsData).forEach((letter) => { + Object.keys(withLetterAndGroupViewToolsData[letter]).forEach((groupName) => { + result.push(...withLetterAndGroupViewToolsData[letter][groupName]) + }) + }) + return result + }, [withLetterAndGroupViewToolsData]) + const toolRefs = useRef({}) return ( @@ -78,6 +87,8 @@ const Blocks = ({ {!!tools.length && ( isFlatView ? ( ) : ( Date: Thu, 31 Oct 2024 16:10:48 +0800 Subject: [PATCH 3/3] chore: fix index show --- web/app/components/workflow/block-selector/index-bar.tsx | 2 +- .../workflow/block-selector/tool/tool-list-flat-view/list.tsx | 4 +++- web/app/components/workflow/block-selector/tool/tool.tsx | 3 +-- web/app/components/workflow/block-selector/tools.tsx | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/app/components/workflow/block-selector/index-bar.tsx b/web/app/components/workflow/block-selector/index-bar.tsx index 076d7e7ec9..d932239bcb 100644 --- a/web/app/components/workflow/block-selector/index-bar.tsx +++ b/web/app/components/workflow/block-selector/index-bar.tsx @@ -78,7 +78,7 @@ const IndexBar: FC = ({ letters, itemRefs }) => { element.scrollIntoView({ behavior: 'smooth' }) } return ( -
+
{letters.map(letter => (
handleIndexClick(letter)}> diff --git a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx index c59f67e66c..7f04a90bb3 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx @@ -9,11 +9,13 @@ import { ViewType } from '../../view-type-select' type Props = { payload: ToolWithProvider[] + isShowLetterIndex: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void } const ToolViewFlatView: FC = ({ payload, + isShowLetterIndex, onSelect, }) => { return ( @@ -23,7 +25,7 @@ const ToolViewFlatView: FC = ({ key={tool.id} payload={tool} viewType={ViewType.flat} - isShowLetterIndex={false} + isShowLetterIndex={isShowLetterIndex} onSelect={onSelect} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index 958be74143..679f0b0e2e 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -56,7 +56,7 @@ const Tool: FC = ({ return (
= ({ actions.map(action => ( ) : (