tag filter

This commit is contained in:
zxhlyh 2025-05-15 14:52:00 +08:00
parent b730d153ea
commit bf8324f7f7
6 changed files with 87 additions and 39 deletions

View File

@ -1,6 +1,7 @@
'use client'
import { useState } from 'react'
import type { ReactElement } from 'react'
import {
RiArrowDownSLine,
RiCloseCircleFill,
@ -22,12 +23,18 @@ type TagsFilterProps = {
onTagsChange: (tags: string[]) => void
size: 'small' | 'large'
locale?: string
emptyTrigger?: ReactElement
className?: string
triggerClassName?: string
}
const TagsFilter = ({
tags,
onTagsChange,
size,
locale,
emptyTrigger,
className,
triggerClassName,
}: TagsFilterProps) => {
const { t } = useMixedTranslation(locale)
const [open, setOpen] = useState(false)
@ -62,17 +69,23 @@ const TagsFilter = ({
size === 'small' && 'h-7 py-0.5 pl-1 pr-1.5 ',
selectedTagsLength && 'text-text-secondary',
open && 'bg-state-base-hover',
className,
)}>
<div className='p-0.5'>
<RiFilter3Line className='h-4 w-4' />
</div>
{
!emptyTrigger && (
<div className='p-0.5'>
<RiFilter3Line className='h-4 w-4' />
</div>
)
}
<div className={cn(
'system-sm-medium flex items-center p-1',
size === 'large' && 'p-1',
size === 'small' && 'px-0.5 py-1',
triggerClassName,
)}>
{
!selectedTagsLength && t('pluginTags.allTags')
!selectedTagsLength && (emptyTrigger || t('pluginTags.allTags'))
}
{
!!selectedTagsLength && tags.map(tag => tagsMap[tag].label).slice(0, 2).join(',')
@ -94,7 +107,7 @@ const TagsFilter = ({
)
}
{
!selectedTagsLength && (
!selectedTagsLength && !emptyTrigger && (
<RiArrowDownSLine className='h-4 w-4' />
)
}

View File

@ -28,12 +28,11 @@ import {
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 cn from '@/utils/classnames'
import {
Plus02,
} from '@/app/components/base/icons/src/vender/line/general'
import ToolSearchInputTag from './tool-search-input-tag'
export type NodeSelectorProps = {
open?: boolean
@ -164,31 +163,31 @@ const NodeSelector: FC<NodeSelectorProps> = ({
}
</div>
<div className='relative z-[1] bg-components-panel-bg p-2'>
<Input
showLeftIcon
showClearIcon
autoFocus
value={searchText}
placeholder={searchPlaceholder}
onChange={e => setSearchText(e.target.value)}
onClear={() => setSearchText('')}
/>
<div className='flex items-center rounded-lg' onClick={e => e.stopPropagation()}>
<Input
wrapperClassName='flex items-center'
showLeftIcon
showClearIcon
autoFocus
value={searchText}
placeholder={searchPlaceholder}
onChange={e => setSearchText(e.target.value)}
onClear={() => setSearchText('')}
/>
{
activeTab === TabsEnum.Tools && (
<>
<div className='mr-0.5 h-3.5 w-[1px] bg-divider-regular'></div>
<ToolSearchInputTag
tags={tags}
onTagsChange={setTags}
/>
</>
)
}
</div>
</div>
</div>
{/* <div className='p-2' onClick={e => e.stopPropagation()}>
{activeTab === TabsEnum.Blocks && (
)}
{activeTab === TabsEnum.Tools && (
<SearchBox
search={searchText}
onSearchChange={setSearchText}
tags={tags}
onTagsChange={setTags}
size='small'
placeholder={t('plugin.searchTools')!}
/>
)}
</div> */}
<Tabs
activeTab={activeTab}
onSelect={handleSelect}

View File

@ -0,0 +1,36 @@
import { memo } from 'react'
import { RiPriceTag3Line } from '@remixicon/react'
import TagsFilter from '@/app/components/plugins/marketplace/search-box/tags-filter'
import cn from '@/utils/classnames'
type ToolSearchInputTagProps = {
tags: string[]
onTagsChange: (tags: string[]) => void
}
const ToolSearchInputTag = ({
tags,
onTagsChange,
}: ToolSearchInputTagProps) => {
return (
<TagsFilter
tags={tags}
onTagsChange={onTagsChange}
size='large'
className={cn(
'p-0',
tags.length && 'px-0.5',
)}
triggerClassName={cn(
'p-0',
tags.length && 'px-0.5',
)}
emptyTrigger={
<div className='flex h-7 w-[34px] items-center justify-center'>
<RiPriceTag3Line className='h-4 w-4 text-text-tertiary' />
</div>
}
/>
)
}
export default memo(ToolSearchInputTag)

View File

@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next'
import { useClickAway } from 'ahooks'
import type { NodeProps } from 'reactflow'
import NodeResizer from '../nodes/_base/components/node-resizer'
import { useWorkflowHistoryStore } from '../workflow-history-store'
import {
useNodeDataUpdate,
useNodesInteractions,
@ -58,6 +59,8 @@ const NoteNode = ({
handleNodeDataUpdateWithSyncDraft({ id, data: { selected: false } })
}, ref)
const { setShortcutsEnabled } = useWorkflowHistoryStore()
return (
<div
className={cn(
@ -111,6 +114,7 @@ const NoteNode = ({
containerElement={ref.current}
placeholder={t('workflow.nodes.note.editor.placeholder') || ''}
onChange={handleEditorChange}
setShortcutsEnabled={setShortcutsEnabled}
/>
</div>
</div>

View File

@ -13,7 +13,6 @@ import { ListPlugin } from '@lexical/react/LexicalListPlugin'
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'
import { useWorkflowHistoryStore } from '../../workflow-history-store'
import LinkEditorPlugin from './plugins/link-editor-plugin'
import FormatDetectorPlugin from './plugins/format-detector-plugin'
// import TreeView from '@/app/components/base/prompt-editor/plugins/tree-view'
@ -23,26 +22,26 @@ type EditorProps = {
placeholder?: string
onChange?: (editorState: EditorState) => void
containerElement: HTMLDivElement | null
setShortcutsEnabled?: (v: boolean) => void
}
const Editor = ({
placeholder = 'write you note...',
onChange,
containerElement,
setShortcutsEnabled,
}: EditorProps) => {
const handleEditorChange = useCallback((editorState: EditorState) => {
onChange?.(editorState)
}, [onChange])
const { setShortcutsEnabled } = useWorkflowHistoryStore()
return (
<div className='relative'>
<RichTextPlugin
contentEditable={
<div>
<ContentEditable
onFocus={() => setShortcutsEnabled(false)}
onBlur={() => setShortcutsEnabled(true)}
onFocus={() => setShortcutsEnabled?.(false)}
onBlur={() => setShortcutsEnabled?.(true)}
spellCheck={false}
className='h-full w-full text-text-secondary caret-primary-600 outline-none'
/>

View File

@ -38,7 +38,6 @@ import type {
Node,
} from '@/app/components/workflow/types'
import { CUSTOM_NOTE_NODE } from '@/app/components/workflow/note-node/constants'
import { WorkflowHistoryProvider } from '@/app/components/workflow/workflow-history-store'
import CustomNode from './components/nodes'
import CustomEdge from './components/custom-edge'
import ZoomInOut from './components/zoom-in-out'
@ -137,9 +136,7 @@ const WorkflowPreview = ({
const WorkflowPreviewWrapper = (props: WorkflowPreviewProps) => {
return (
<ReactFlowProvider>
<WorkflowHistoryProvider nodes={[]} edges={[]}>
<WorkflowPreview {...props} />
</WorkflowHistoryProvider>
<WorkflowPreview {...props} />
</ReactFlowProvider>
)
}