| 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' | ||||
| 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[] | ||||
| 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, | ||||
| // 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 ( | ||||
| <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} | ||||
| /> | /> | ||||
| {/* 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} |
| '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' | ||||
| 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 | ||||
| disableMaxWidth?: boolean | 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 { t } = useTranslation() | ||||
| const hasFilter = !searchText | const hasFilter = !searchText | ||||
| const hasRes = list.length > 0 | const hasRes = list.length > 0 | ||||
| </div> | </div> | ||||
| </> | </> | ||||
| ) | ) | ||||
| } | |||||
| }) | |||||
| List.displayName = 'List' | List.displayName = 'List' | ||||
| 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 | ||||
| // 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'> | ||||
| 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> |