mirror of
https://github.com/langgenius/dify.git
synced 2026-01-08 07:14:14 +00:00
feat: list flat view
This commit is contained in:
@@ -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] = []
|
||||
|
||||
@@ -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<Props> = () => {
|
||||
const ToolViewFlatView: FC<Props> = ({
|
||||
payload,
|
||||
onSelect,
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
list...
|
||||
{payload.map(tool => (
|
||||
<Tool
|
||||
key={tool.id}
|
||||
payload={tool}
|
||||
viewType={ViewType.flat}
|
||||
isShowLetterIndex={false}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(ToolViewFlatView)
|
||||
|
||||
@@ -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<string, ToolWithProvider[]>
|
||||
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
|
||||
}
|
||||
|
||||
const OrgTools: FC<Props> = ({
|
||||
const ToolListTreeView: FC<Props> = ({
|
||||
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<Props> = ({
|
||||
{Object.keys(payload).map(groupName => (
|
||||
<Item
|
||||
key={groupName}
|
||||
groupName={groupName}
|
||||
groupName={getI18nGroupName(groupName)}
|
||||
toolList={payload[groupName]}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
@@ -30,4 +43,5 @@ const OrgTools: FC<Props> = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(OrgTools)
|
||||
|
||||
export default React.memo(ToolListTreeView)
|
||||
|
||||
@@ -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<Props> = ({
|
||||
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<Props> = ({
|
||||
}] = 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 (
|
||||
<div
|
||||
key={payload.id}
|
||||
@@ -69,9 +84,15 @@ const Tool: FC<Props> = ({
|
||||
/>
|
||||
<div className='ml-2 text-sm text-gray-900 flex-1 w-0 grow truncate'>{payload.label[language]}</div>
|
||||
</div>
|
||||
{hasAction && (
|
||||
<FoldIcon className={cn('w-4 h-4 text-text-quaternary shrink-0', isFold && 'text-text-tertiary')} />
|
||||
)}
|
||||
|
||||
<div className='flex items-center'>
|
||||
{isFlatView && (
|
||||
<div className='text-text-tertiary system-xs-regular'>{groupName}</div>
|
||||
)}
|
||||
{hasAction && (
|
||||
<FoldIcon className={cn('w-4 h-4 text-text-quaternary shrink-0', isFold && 'text-text-tertiary')} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{hasAction && isFold && (
|
||||
|
||||
@@ -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 ? (
|
||||
<ToolListFlatView
|
||||
payload={listViewToolData}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
) : (
|
||||
<ToolListTreeView
|
||||
|
||||
Reference in New Issue
Block a user