block selector & data source node

This commit is contained in:
zxhlyh
2025-04-22 16:46:33 +08:00
parent efb27eb443
commit 8d9c252811
20 changed files with 201 additions and 70 deletions

View File

@ -109,7 +109,7 @@ const Blocks = ({
}, [groups, nodesExtraData, onSelect, t])
return (
<div className='p-1'>
<div className='max-h-[480px] overflow-y-auto p-1'>
{
isEmpty && (
<div className='flex h-[22px] items-center px-3 text-xs font-medium text-text-tertiary'>{t('workflow.tabs.noResult')}</div>

View File

@ -3,6 +3,12 @@ import { BlockEnum } from '../types'
import { BlockClassificationEnum } from './types'
export const BLOCKS: Block[] = [
{
classification: BlockClassificationEnum.Default,
type: BlockEnum.DataSource,
title: 'File upload',
description: '',
},
{
classification: BlockClassificationEnum.Default,
type: BlockEnum.Start,

View File

@ -1,3 +1,7 @@
import {
useMemo,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { BLOCKS } from './constants'
import {
@ -16,19 +20,43 @@ export const useBlocks = () => {
})
}
export const useTabs = () => {
export const useTabs = (noBlocks?: boolean) => {
const { t } = useTranslation()
const tabs = useMemo(() => {
return [
...(
noBlocks
? []
: [
{
key: TabsEnum.Blocks,
name: t('workflow.tabs.blocks'),
},
]
),
{
key: TabsEnum.Sources,
name: t('workflow.tabs.sources'),
},
{
key: TabsEnum.Tools,
name: t('workflow.tabs.tools'),
},
]
}, [t, noBlocks])
const initialTab = useMemo(() => {
if (noBlocks)
return TabsEnum.Sources
return [
{
key: TabsEnum.Blocks,
name: t('workflow.tabs.blocks'),
},
{
key: TabsEnum.Tools,
name: t('workflow.tabs.tools'),
},
]
return TabsEnum.Blocks
}, [noBlocks])
const [activeTab, setActiveTab] = useState(initialTab)
return {
tabs,
activeTab,
setActiveTab,
}
}
export const useToolTabs = () => {

View File

@ -16,13 +16,15 @@ import type {
import type { BlockEnum, OnSelectBlock } from '../types'
import Tabs from './tabs'
import { TabsEnum } from './types'
import { useTabs } from './hooks'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import Input from '@/app/components/base/input'
import SearchBox from '@/app/components/plugins/marketplace/search-box'
// import SearchBox from '@/app/components/plugins/marketplace/search-box'
import cn from '@/utils/classnames'
import {
Plus02,
@ -85,10 +87,12 @@ const NodeSelector: FC<NodeSelectorProps> = ({
onSelect(type, toolDefaultValue)
}, [handleOpenChange, onSelect])
const [activeTab, setActiveTab] = useState(noBlocks ? TabsEnum.Tools : TabsEnum.Blocks)
const handleActiveTabChange = useCallback((newActiveTab: TabsEnum) => {
setActiveTab(newActiveTab)
}, [])
const {
activeTab,
setActiveTab,
tabs,
} = useTabs()
const searchPlaceholder = useMemo(() => {
if (activeTab === TabsEnum.Blocks)
return t('workflow.tabs.searchBlock')
@ -128,9 +132,31 @@ const NodeSelector: FC<NodeSelectorProps> = ({
}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'>
<div className={`rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg ${popupClassName}`}>
<div className='px-2 pt-2' onClick={e => e.stopPropagation()}>
{activeTab === TabsEnum.Blocks && (
<div className={cn(
'overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg backdrop-blur-[5px]',
popupClassName,
)}>
<div className='border-b border-divider-subtle bg-background-section-burn'>
<div className='flex h-9 items-center px-1 pt-1'>
{
tabs.map(tab => (
<div
key={tab.key}
className={cn(
'system-sm-medium mr-0.5 cursor-pointer rounded-t-lg px-3 py-2 text-text-tertiary hover:bg-state-base-hover',
activeTab === tab.key && 'bg-components-panel-bg text-text-accent shadow-sm',
)}
onClick={(e) => {
e.stopPropagation()
setActiveTab(tab.key)
}}
>
{tab.name}
</div>
))
}
</div>
<div className='relative z-[1] bg-components-panel-bg p-2'>
<Input
showLeftIcon
showClearIcon
@ -140,6 +166,10 @@ const NodeSelector: FC<NodeSelectorProps> = ({
onChange={e => setSearchText(e.target.value)}
onClear={() => setSearchText('')}
/>
</div>
</div>
{/* <div className='p-2' onClick={e => e.stopPropagation()}>
{activeTab === TabsEnum.Blocks && (
)}
{activeTab === TabsEnum.Tools && (
<SearchBox
@ -151,11 +181,9 @@ const NodeSelector: FC<NodeSelectorProps> = ({
placeholder={t('plugin.searchTools')!}
/>
)}
</div>
</div> */}
<Tabs
activeTab={activeTab}
onActiveTabChange={handleActiveTabChange}
onSelect={handleSelect}
searchText={searchText}
tags={tags}

View File

@ -2,16 +2,13 @@ import type { FC } from 'react'
import { memo } from 'react'
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools'
import type { BlockEnum } from '../types'
import { useTabs } from './hooks'
import type { ToolDefaultValue } from './types'
import { TabsEnum } from './types'
import Blocks from './blocks'
import AllTools from './all-tools'
import cn from '@/utils/classnames'
export type TabsProps = {
activeTab: TabsEnum
onActiveTabChange: (activeTab: TabsEnum) => void
searchText: string
tags: string[]
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
@ -20,42 +17,18 @@ export type TabsProps = {
}
const Tabs: FC<TabsProps> = ({
activeTab,
onActiveTabChange,
tags,
searchText,
onSelect,
availableBlocksTypes,
noBlocks,
}) => {
const tabs = useTabs()
const { data: buildInTools } = useAllBuiltInTools()
const { data: customTools } = useAllCustomTools()
const { data: workflowTools } = useAllWorkflowTools()
return (
<div onClick={e => e.stopPropagation()}>
{
!noBlocks && (
<div className='flex items-center border-b-[0.5px] border-divider-subtle px-3'>
{
tabs.map(tab => (
<div
key={tab.key}
className={cn(
'system-sm-medium relative mr-4 cursor-pointer pb-2 pt-1',
activeTab === tab.key
? 'text-text-primary after:absolute after:bottom-0 after:left-0 after:h-0.5 after:w-full after:bg-util-colors-blue-brand-blue-brand-600'
: 'text-text-tertiary',
)}
onClick={() => onActiveTabChange(tab.key)}
>
{tab.name}
</div>
))
}
</div>
)
}
{
activeTab === TabsEnum.Blocks && !noBlocks && (
<Blocks

View File

@ -1,6 +1,7 @@
export enum TabsEnum {
Blocks = 'blocks',
Tools = 'tools',
Sources = 'sources',
}
export enum ToolTypeEnum {