mirror of
https://github.com/langgenius/dify.git
synced 2026-04-29 04:26:30 +08:00
feat: init agent strategy install from marketplace
This commit is contained in:
parent
e207894d7e
commit
f03631ff9e
@ -15,6 +15,7 @@ type Props = {
|
|||||||
list: Plugin[]
|
list: Plugin[]
|
||||||
searchText: string
|
searchText: string
|
||||||
tags: string[]
|
tags: string[]
|
||||||
|
disableMaxWidth?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const List = ({
|
const List = ({
|
||||||
@ -22,6 +23,7 @@ const List = ({
|
|||||||
searchText,
|
searchText,
|
||||||
tags,
|
tags,
|
||||||
list,
|
list,
|
||||||
|
disableMaxWidth = false,
|
||||||
}: Props, ref: any) => {
|
}: Props, ref: any) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const hasFilter = !searchText
|
const hasFilter = !searchText
|
||||||
@ -95,7 +97,7 @@ const List = ({
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={cn('p-1', maxWidthClassName)} ref={nextToStickyELemRef}>
|
<div className={cn('p-1', !disableMaxWidth && maxWidthClassName)} ref={nextToStickyELemRef}>
|
||||||
{list.map((item, index) => (
|
{list.map((item, index) => (
|
||||||
<Item
|
<Item
|
||||||
key={index}
|
key={index}
|
||||||
@ -103,7 +105,7 @@ const List = ({
|
|||||||
onAction={() => { }}
|
onAction={() => { }}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<div className='mt-2 mb-3 flex items-center space-x-2'>
|
<div className='mt-2 mb-3 flex items-center justify-center space-x-2'>
|
||||||
<div className="w-[90px] h-[2px] bg-gradient-to-l from-[rgba(16,24,40,0.08)] to-[rgba(255,255,255,0.01)]"></div>
|
<div className="w-[90px] h-[2px] bg-gradient-to-l from-[rgba(16,24,40,0.08)] to-[rgba(255,255,255,0.01)]"></div>
|
||||||
<Link
|
<Link
|
||||||
href={urlWithSearchText}
|
href={urlWithSearchText}
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
|
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import { memo, useMemo, useState } from 'react'
|
import { memo, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import type { Strategy } from './agent-strategy'
|
import type { Strategy } from './agent-strategy'
|
||||||
import classNames from '@/utils/classnames'
|
import classNames from '@/utils/classnames'
|
||||||
import { RiArrowDownSLine, RiArrowRightUpLine, RiErrorWarningFill } from '@remixicon/react'
|
import { RiArrowDownSLine, RiErrorWarningFill } from '@remixicon/react'
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { InstallPluginButton } from './install-plugin-button'
|
import { InstallPluginButton } from './install-plugin-button'
|
||||||
import ViewTypeSelect, { ViewType } from '../../../block-selector/view-type-select'
|
import ViewTypeSelect, { ViewType } from '../../../block-selector/view-type-select'
|
||||||
import SearchInput from '@/app/components/base/search-input'
|
import SearchInput from '@/app/components/base/search-input'
|
||||||
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
|
||||||
import Tools from '../../../block-selector/tools'
|
import Tools from '../../../block-selector/tools'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useStrategyProviders } from '@/service/use-strategy'
|
import { useStrategyProviders } from '@/service/use-strategy'
|
||||||
import type { StrategyPluginDetail } from '@/app/components/plugins/types'
|
import { PluginType, type StrategyPluginDetail } from '@/app/components/plugins/types'
|
||||||
import type { ToolWithProvider } from '../../../types'
|
import type { ToolWithProvider } from '../../../types'
|
||||||
import { CollectionType } from '@/app/components/tools/types'
|
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 { useMarketplacePlugins } from '@/app/components/plugins/marketplace/hooks'
|
||||||
|
|
||||||
const NotFoundWarn = (props: {
|
const NotFoundWarn = (props: {
|
||||||
title: ReactNode,
|
title: ReactNode,
|
||||||
@ -119,6 +120,25 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||||||
)?.icon as string | undefined
|
)?.icon as string | undefined
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const wrapElemRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
const {
|
||||||
|
queryPluginsWithDebounced: fetchPlugins,
|
||||||
|
plugins: notInstalledPlugins = [],
|
||||||
|
} = useMarketplacePlugins()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (query) {
|
||||||
|
fetchPlugins({
|
||||||
|
query,
|
||||||
|
category: PluginType.agent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [query])
|
||||||
|
|
||||||
|
const pluginRef = useRef(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'>
|
||||||
<div
|
<div
|
||||||
@ -172,7 +192,7 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||||||
<SearchInput placeholder={t('workflow.nodes.agent.strategy.searchPlaceholder')} value={query} onChange={setQuery} className={'w-full'} />
|
<SearchInput placeholder={t('workflow.nodes.agent.strategy.searchPlaceholder')} value={query} onChange={setQuery} className={'w-full'} />
|
||||||
<ViewTypeSelect viewType={viewType} onChange={setViewType} />
|
<ViewTypeSelect viewType={viewType} onChange={setViewType} />
|
||||||
</header>
|
</header>
|
||||||
<main className="md:max-h-[300px] xl:max-h-[400px] 2xl:max-h-[564px] relative overflow-hidden flex flex-col">
|
<main className="md:max-h-[300px] xl:max-h-[400px] 2xl:max-h-[564px] relative overflow-hidden flex flex-col w-full" ref={wrapElemRef}>
|
||||||
<Tools
|
<Tools
|
||||||
tools={filteredTools}
|
tools={filteredTools}
|
||||||
viewType={viewType}
|
viewType={viewType}
|
||||||
@ -185,17 +205,16 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
|
|||||||
plugin_unique_identifier: tool!.provider_id,
|
plugin_unique_identifier: tool!.provider_id,
|
||||||
})
|
})
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}}
|
} }
|
||||||
hasSearchText={false}
|
|
||||||
showWorkflowEmpty={false}
|
|
||||||
className='max-w-none max-h-full h-full overflow-y-auto'
|
className='max-w-none max-h-full h-full overflow-y-auto'
|
||||||
indexBarClassName='top-0 xl:top-36'
|
indexBarClassName='top-0 xl:top-36' showWorkflowEmpty={false} hasSearchText={false} />
|
||||||
|
<PluginList
|
||||||
|
wrapElemRef={wrapElemRef}
|
||||||
|
list={notInstalledPlugins as any} ref={pluginRef}
|
||||||
|
searchText={query}
|
||||||
|
tags={[]}
|
||||||
|
disableMaxWidth
|
||||||
/>
|
/>
|
||||||
<div className='px-4 py-2 flex items-center border-t border-divider-subtle text-text-accent-light-mode-only bg-components-panel-bg text-xs'>
|
|
||||||
<Link href={MARKETPLACE_URL_PREFIX} className='flex ml-1'>
|
|
||||||
{t('plugin.findMoreInMarketplace')} <RiArrowRightUpLine className='size-3' />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</PortalToFollowElemContent>
|
</PortalToFollowElemContent>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user