mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-07-31 21:51:59 +08:00
refactor & perf: improve type safety of component PluginList
(#17498)
This commit is contained in:
parent
cf8d15e8d5
commit
7ca497f0d6
@ -15,7 +15,8 @@ import { useToolTabs } from './hooks'
|
|||||||
import ViewTypeSelect, { ViewType } from './view-type-select'
|
import ViewTypeSelect, { ViewType } from './view-type-select'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import { useGetLanguage } from '@/context/i18n'
|
import { useGetLanguage } from '@/context/i18n'
|
||||||
import PluginList from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
import type { ListRef } from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
||||||
|
import PluginList, { type ListProps } from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
||||||
import ActionButton from '../../base/action-button'
|
import ActionButton from '../../base/action-button'
|
||||||
import { RiAddLine } from '@remixicon/react'
|
import { RiAddLine } from '@remixicon/react'
|
||||||
import { PluginType } from '../../plugins/types'
|
import { PluginType } from '../../plugins/types'
|
||||||
@ -26,7 +27,7 @@ type AllToolsProps = {
|
|||||||
className?: string
|
className?: string
|
||||||
toolContentClassName?: string
|
toolContentClassName?: string
|
||||||
searchText: string
|
searchText: string
|
||||||
tags: string[]
|
tags: ListProps['tags']
|
||||||
buildInTools: ToolWithProvider[]
|
buildInTools: ToolWithProvider[]
|
||||||
customTools: ToolWithProvider[]
|
customTools: ToolWithProvider[]
|
||||||
workflowTools: ToolWithProvider[]
|
workflowTools: ToolWithProvider[]
|
||||||
@ -36,11 +37,14 @@ type AllToolsProps = {
|
|||||||
onShowAddCustomCollectionModal?: () => void
|
onShowAddCustomCollectionModal?: () => void
|
||||||
selectedTools?: ToolValue[]
|
selectedTools?: ToolValue[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_TAGS: AllToolsProps['tags'] = []
|
||||||
|
|
||||||
const AllTools = ({
|
const AllTools = ({
|
||||||
className,
|
className,
|
||||||
toolContentClassName,
|
toolContentClassName,
|
||||||
searchText,
|
searchText,
|
||||||
tags = [],
|
tags = DEFAULT_TAGS,
|
||||||
onSelect,
|
onSelect,
|
||||||
buildInTools,
|
buildInTools,
|
||||||
workflowTools,
|
workflowTools,
|
||||||
@ -97,7 +101,7 @@ const AllTools = ({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [searchText, tags, enable_marketplace])
|
}, [searchText, tags, enable_marketplace])
|
||||||
|
|
||||||
const pluginRef = useRef(null)
|
const pluginRef = useRef<ListRef>(null)
|
||||||
const wrapElemRef = useRef<HTMLDivElement>(null)
|
const wrapElemRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -136,7 +140,7 @@ const AllTools = ({
|
|||||||
<div
|
<div
|
||||||
ref={wrapElemRef}
|
ref={wrapElemRef}
|
||||||
className='max-h-[464px] overflow-y-auto'
|
className='max-h-[464px] overflow-y-auto'
|
||||||
onScroll={(pluginRef.current as any)?.handleScroll}
|
onScroll={pluginRef.current?.handleScroll}
|
||||||
>
|
>
|
||||||
<Tools
|
<Tools
|
||||||
className={toolContentClassName}
|
className={toolContentClassName}
|
||||||
@ -149,8 +153,9 @@ const AllTools = ({
|
|||||||
/>
|
/>
|
||||||
{/* Plugins from marketplace */}
|
{/* Plugins from marketplace */}
|
||||||
{enable_marketplace && <PluginList
|
{enable_marketplace && <PluginList
|
||||||
|
ref={pluginRef}
|
||||||
wrapElemRef={wrapElemRef}
|
wrapElemRef={wrapElemRef}
|
||||||
list={notInstalledPlugins as any} ref={pluginRef}
|
list={notInstalledPlugins}
|
||||||
searchText={searchText}
|
searchText={searchText}
|
||||||
toolContentClassName={toolContentClassName}
|
toolContentClassName={toolContentClassName}
|
||||||
tags={tags}
|
tags={tags}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react'
|
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll'
|
import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll'
|
||||||
import Item from './item'
|
import Item from './item'
|
||||||
@ -8,10 +8,9 @@ import cn from '@/utils/classnames'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { marketplaceUrlPrefix } from '@/config'
|
import { marketplaceUrlPrefix } from '@/config'
|
||||||
import { RiArrowRightUpLine, RiSearchLine } from '@remixicon/react'
|
import { RiArrowRightUpLine, RiSearchLine } from '@remixicon/react'
|
||||||
// import { RiArrowRightUpLine } from '@remixicon/react'
|
|
||||||
import { noop } from 'lodash-es'
|
import { noop } from 'lodash-es'
|
||||||
|
|
||||||
type Props = {
|
export type ListProps = {
|
||||||
wrapElemRef: React.RefObject<HTMLElement>
|
wrapElemRef: React.RefObject<HTMLElement>
|
||||||
list: Plugin[]
|
list: Plugin[]
|
||||||
searchText: string
|
searchText: string
|
||||||
@ -20,17 +19,16 @@ type Props = {
|
|||||||
disableMaxWidth?: boolean
|
disableMaxWidth?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const List = (
|
export type ListRef = { handleScroll: () => void }
|
||||||
{
|
|
||||||
ref,
|
const List = forwardRef<ListRef, ListProps>(({
|
||||||
wrapElemRef,
|
wrapElemRef,
|
||||||
searchText,
|
searchText,
|
||||||
tags,
|
tags,
|
||||||
list,
|
list,
|
||||||
toolContentClassName,
|
toolContentClassName,
|
||||||
disableMaxWidth = false,
|
disableMaxWidth = false,
|
||||||
},
|
}, ref) => {
|
||||||
) => {
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const hasFilter = !searchText
|
const hasFilter = !searchText
|
||||||
const hasRes = list.length > 0
|
const hasRes = list.length > 0
|
||||||
@ -126,7 +124,7 @@ const List = (
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
List.displayName = 'List'
|
List.displayName = 'List'
|
||||||
|
|
||||||
|
@ -18,10 +18,13 @@ import { CollectionType } from '@/app/components/tools/types'
|
|||||||
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
|
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
|
||||||
import { useStrategyInfo } from '../../agent/use-config'
|
import { useStrategyInfo } from '../../agent/use-config'
|
||||||
import { SwitchPluginVersion } from './switch-plugin-version'
|
import { SwitchPluginVersion } from './switch-plugin-version'
|
||||||
import PluginList from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
import type { ListRef } from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
||||||
|
import PluginList, { type ListProps } from '@/app/components/workflow/block-selector/market-place-plugin/list'
|
||||||
import { useMarketplacePlugins } from '@/app/components/plugins/marketplace/hooks'
|
import { useMarketplacePlugins } from '@/app/components/plugins/marketplace/hooks'
|
||||||
import { ToolTipContent } from '@/app/components/base/tooltip/content'
|
import { ToolTipContent } from '@/app/components/base/tooltip/content'
|
||||||
|
|
||||||
|
const DEFAULT_TAGS: ListProps['tags'] = []
|
||||||
|
|
||||||
const NotFoundWarn = (props: {
|
const NotFoundWarn = (props: {
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
description: ReactNode
|
description: ReactNode
|
||||||
@ -138,7 +141,7 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [query])
|
}, [query])
|
||||||
|
|
||||||
const pluginRef = useRef(null)
|
const pluginRef = useRef<ListRef>(null)
|
||||||
|
|
||||||
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
|
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
|
||||||
<PortalToFollowElemTrigger className='w-full'>
|
<PortalToFollowElemTrigger className='w-full'>
|
||||||
@ -213,10 +216,11 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||||||
className='h-full max-h-full max-w-none overflow-y-auto'
|
className='h-full max-h-full max-w-none overflow-y-auto'
|
||||||
indexBarClassName='top-0 xl:top-36' showWorkflowEmpty={false} hasSearchText={false} />
|
indexBarClassName='top-0 xl:top-36' showWorkflowEmpty={false} hasSearchText={false} />
|
||||||
<PluginList
|
<PluginList
|
||||||
|
ref={pluginRef}
|
||||||
wrapElemRef={wrapElemRef}
|
wrapElemRef={wrapElemRef}
|
||||||
list={notInstalledPlugins as any} ref={pluginRef}
|
list={notInstalledPlugins}
|
||||||
searchText={query}
|
searchText={query}
|
||||||
tags={[]}
|
tags={DEFAULT_TAGS}
|
||||||
disableMaxWidth
|
disableMaxWidth
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user