| @@ -15,7 +15,8 @@ import { useToolTabs } from './hooks' | |||
| import ViewTypeSelect, { ViewType } from './view-type-select' | |||
| import cn from '@/utils/classnames' | |||
| 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 { RiAddLine } from '@remixicon/react' | |||
| import { PluginType } from '../../plugins/types' | |||
| @@ -26,7 +27,7 @@ type AllToolsProps = { | |||
| className?: string | |||
| toolContentClassName?: string | |||
| searchText: string | |||
| tags: string[] | |||
| tags: ListProps['tags'] | |||
| buildInTools: ToolWithProvider[] | |||
| customTools: ToolWithProvider[] | |||
| workflowTools: ToolWithProvider[] | |||
| @@ -36,11 +37,14 @@ type AllToolsProps = { | |||
| onShowAddCustomCollectionModal?: () => void | |||
| selectedTools?: ToolValue[] | |||
| } | |||
| const DEFAULT_TAGS: AllToolsProps['tags'] = [] | |||
| const AllTools = ({ | |||
| className, | |||
| toolContentClassName, | |||
| searchText, | |||
| tags = [], | |||
| tags = DEFAULT_TAGS, | |||
| onSelect, | |||
| buildInTools, | |||
| workflowTools, | |||
| @@ -97,7 +101,7 @@ const AllTools = ({ | |||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||
| }, [searchText, tags, enable_marketplace]) | |||
| const pluginRef = useRef(null) | |||
| const pluginRef = useRef<ListRef>(null) | |||
| const wrapElemRef = useRef<HTMLDivElement>(null) | |||
| return ( | |||
| @@ -136,7 +140,7 @@ const AllTools = ({ | |||
| <div | |||
| ref={wrapElemRef} | |||
| className='max-h-[464px] overflow-y-auto' | |||
| onScroll={(pluginRef.current as any)?.handleScroll} | |||
| onScroll={pluginRef.current?.handleScroll} | |||
| > | |||
| <Tools | |||
| className={toolContentClassName} | |||
| @@ -149,8 +153,9 @@ const AllTools = ({ | |||
| /> | |||
| {/* Plugins from marketplace */} | |||
| {enable_marketplace && <PluginList | |||
| ref={pluginRef} | |||
| wrapElemRef={wrapElemRef} | |||
| list={notInstalledPlugins as any} ref={pluginRef} | |||
| list={notInstalledPlugins} | |||
| searchText={searchText} | |||
| toolContentClassName={toolContentClassName} | |||
| tags={tags} | |||
| @@ -1,5 +1,5 @@ | |||
| '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 useStickyScroll, { ScrollPosition } from '../use-sticky-scroll' | |||
| import Item from './item' | |||
| @@ -8,10 +8,9 @@ import cn from '@/utils/classnames' | |||
| import Link from 'next/link' | |||
| import { marketplaceUrlPrefix } from '@/config' | |||
| import { RiArrowRightUpLine, RiSearchLine } from '@remixicon/react' | |||
| // import { RiArrowRightUpLine } from '@remixicon/react' | |||
| import { noop } from 'lodash-es' | |||
| type Props = { | |||
| export type ListProps = { | |||
| wrapElemRef: React.RefObject<HTMLElement> | |||
| list: Plugin[] | |||
| searchText: string | |||
| @@ -20,17 +19,16 @@ type Props = { | |||
| disableMaxWidth?: boolean | |||
| } | |||
| const List = ( | |||
| { | |||
| ref, | |||
| wrapElemRef, | |||
| searchText, | |||
| tags, | |||
| list, | |||
| toolContentClassName, | |||
| disableMaxWidth = false, | |||
| }, | |||
| ) => { | |||
| export type ListRef = { handleScroll: () => void } | |||
| const List = forwardRef<ListRef, ListProps>(({ | |||
| wrapElemRef, | |||
| searchText, | |||
| tags, | |||
| list, | |||
| toolContentClassName, | |||
| disableMaxWidth = false, | |||
| }, ref) => { | |||
| const { t } = useTranslation() | |||
| const hasFilter = !searchText | |||
| const hasRes = list.length > 0 | |||
| @@ -126,7 +124,7 @@ const List = ( | |||
| </div> | |||
| </> | |||
| ) | |||
| } | |||
| }) | |||
| 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 { useStrategyInfo } from '../../agent/use-config' | |||
| 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 { ToolTipContent } from '@/app/components/base/tooltip/content' | |||
| const DEFAULT_TAGS: ListProps['tags'] = [] | |||
| const NotFoundWarn = (props: { | |||
| title: ReactNode, | |||
| description: ReactNode | |||
| @@ -138,7 +141,7 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => | |||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||
| }, [query]) | |||
| const pluginRef = useRef(null) | |||
| const pluginRef = useRef<ListRef>(null) | |||
| return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'> | |||
| <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' | |||
| indexBarClassName='top-0 xl:top-36' showWorkflowEmpty={false} hasSearchText={false} /> | |||
| <PluginList | |||
| ref={pluginRef} | |||
| wrapElemRef={wrapElemRef} | |||
| list={notInstalledPlugins as any} ref={pluginRef} | |||
| list={notInstalledPlugins} | |||
| searchText={query} | |||
| tags={[]} | |||
| tags={DEFAULT_TAGS} | |||
| disableMaxWidth | |||
| /> | |||
| </main> | |||