mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 01:26:33 +08:00
Fix start tab marketplace trigger search and plugin list scroll (#28645)
This commit is contained in:
parent
57b405c4c2
commit
e073e755f9
@ -3,8 +3,12 @@ import {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
import type {
|
||||||
|
RefObject,
|
||||||
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import type { BlockEnum, OnSelectBlock } from '../types'
|
import type { BlockEnum, OnSelectBlock } from '../types'
|
||||||
import type { TriggerDefaultValue, TriggerWithProvider } from './types'
|
import type { TriggerDefaultValue, TriggerWithProvider } from './types'
|
||||||
@ -23,6 +27,9 @@ import Divider from '@/app/components/base/divider'
|
|||||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||||
import { useAllTriggerPlugins, useInvalidateAllTriggerPlugins } from '@/service/use-triggers'
|
import { useAllTriggerPlugins, useInvalidateAllTriggerPlugins } from '@/service/use-triggers'
|
||||||
import { useFeaturedTriggersRecommendations } from '@/service/use-plugins'
|
import { useFeaturedTriggersRecommendations } from '@/service/use-plugins'
|
||||||
|
import { PluginCategoryEnum } from '../../plugins/types'
|
||||||
|
import { useMarketplacePlugins } from '../../plugins/marketplace/hooks'
|
||||||
|
import PluginList, { type ListRef } from './market-place-plugin/list'
|
||||||
|
|
||||||
const marketplaceFooterClassName = 'system-sm-medium z-10 flex h-8 flex-none cursor-pointer items-center rounded-b-lg border-[0.5px] border-t border-components-panel-border bg-components-panel-bg-blur px-4 py-1 text-text-accent-light-mode-only shadow-lg'
|
const marketplaceFooterClassName = 'system-sm-medium z-10 flex h-8 flex-none cursor-pointer items-center rounded-b-lg border-[0.5px] border-t border-components-panel-border bg-components-panel-bg-blur px-4 py-1 text-text-accent-light-mode-only shadow-lg'
|
||||||
|
|
||||||
@ -47,6 +54,8 @@ const AllStartBlocks = ({
|
|||||||
const [hasStartBlocksContent, setHasStartBlocksContent] = useState(false)
|
const [hasStartBlocksContent, setHasStartBlocksContent] = useState(false)
|
||||||
const [hasPluginContent, setHasPluginContent] = useState(false)
|
const [hasPluginContent, setHasPluginContent] = useState(false)
|
||||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||||
|
const pluginRef = useRef<ListRef>(null)
|
||||||
|
const wrapElemRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const entryNodeTypes = availableBlocksTypes?.length
|
const entryNodeTypes = availableBlocksTypes?.length
|
||||||
? availableBlocksTypes
|
? availableBlocksTypes
|
||||||
@ -71,14 +80,21 @@ const AllStartBlocks = ({
|
|||||||
const invalidateTriggers = useInvalidateAllTriggerPlugins()
|
const invalidateTriggers = useInvalidateAllTriggerPlugins()
|
||||||
const trimmedSearchText = searchText.trim()
|
const trimmedSearchText = searchText.trim()
|
||||||
const hasSearchText = trimmedSearchText.length > 0
|
const hasSearchText = trimmedSearchText.length > 0
|
||||||
|
const hasFilter = hasSearchText || tags.length > 0
|
||||||
const {
|
const {
|
||||||
plugins: featuredPlugins = [],
|
plugins: featuredPlugins = [],
|
||||||
isLoading: featuredLoading,
|
isLoading: featuredLoading,
|
||||||
} = useFeaturedTriggersRecommendations(enableTriggerPlugin && enable_marketplace && !hasSearchText)
|
} = useFeaturedTriggersRecommendations(enableTriggerPlugin && enable_marketplace && !hasFilter)
|
||||||
|
const {
|
||||||
|
queryPluginsWithDebounced: fetchPlugins,
|
||||||
|
plugins: marketplacePlugins = [],
|
||||||
|
} = useMarketplacePlugins()
|
||||||
|
|
||||||
const shouldShowFeatured = enableTriggerPlugin
|
const shouldShowFeatured = enableTriggerPlugin
|
||||||
&& enable_marketplace
|
&& enable_marketplace
|
||||||
&& !hasSearchText
|
&& !hasFilter
|
||||||
|
const shouldShowTriggerListTitle = hasStartBlocksContent || hasPluginContent
|
||||||
|
const shouldShowMarketplaceFooter = enable_marketplace && !hasFilter
|
||||||
|
|
||||||
const handleStartBlocksContentChange = useCallback((hasContent: boolean) => {
|
const handleStartBlocksContentChange = useCallback((hasContent: boolean) => {
|
||||||
setHasStartBlocksContent(hasContent)
|
setHasStartBlocksContent(hasContent)
|
||||||
@ -88,18 +104,34 @@ const AllStartBlocks = ({
|
|||||||
setHasPluginContent(hasContent)
|
setHasPluginContent(hasContent)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const hasAnyContent = hasStartBlocksContent || hasPluginContent || shouldShowFeatured
|
const hasMarketplaceContent = enableTriggerPlugin && enable_marketplace && marketplacePlugins.length > 0
|
||||||
const shouldShowEmptyState = hasSearchText && !hasAnyContent
|
const hasAnyContent = hasStartBlocksContent || hasPluginContent || shouldShowFeatured || hasMarketplaceContent
|
||||||
|
const shouldShowEmptyState = hasFilter && !hasAnyContent
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!enableTriggerPlugin && hasPluginContent)
|
if (!enableTriggerPlugin && hasPluginContent)
|
||||||
setHasPluginContent(false)
|
setHasPluginContent(false)
|
||||||
}, [enableTriggerPlugin, hasPluginContent])
|
}, [enableTriggerPlugin, hasPluginContent])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!enableTriggerPlugin || !enable_marketplace) return
|
||||||
|
if (hasFilter) {
|
||||||
|
fetchPlugins({
|
||||||
|
query: searchText,
|
||||||
|
tags,
|
||||||
|
category: PluginCategoryEnum.trigger,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [enableTriggerPlugin, enable_marketplace, hasFilter, fetchPlugins, searchText, tags])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('min-w-[400px] max-w-[500px]', className)}>
|
<div className={cn('min-w-[400px] max-w-[500px]', className)}>
|
||||||
<div className='flex max-h-[640px] flex-col'>
|
<div className='flex max-h-[640px] flex-col'>
|
||||||
<div className='flex-1 overflow-y-auto'>
|
<div
|
||||||
|
ref={wrapElemRef}
|
||||||
|
className='flex-1 overflow-y-auto'
|
||||||
|
onScroll={() => pluginRef.current?.handleScroll()}
|
||||||
|
>
|
||||||
<div className={cn(shouldShowEmptyState && 'hidden')}>
|
<div className={cn(shouldShowEmptyState && 'hidden')}>
|
||||||
{shouldShowFeatured && (
|
{shouldShowFeatured && (
|
||||||
<>
|
<>
|
||||||
@ -117,9 +149,11 @@ const AllStartBlocks = ({
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className='px-3 pb-1 pt-2'>
|
{shouldShowTriggerListTitle && (
|
||||||
<span className='system-xs-medium text-text-primary'>{t('workflow.tabs.allTriggers')}</span>
|
<div className='px-3 pb-1 pt-2'>
|
||||||
</div>
|
<span className='system-xs-medium text-text-primary'>{t('workflow.tabs.allTriggers')}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<StartBlocks
|
<StartBlocks
|
||||||
searchText={trimmedSearchText}
|
searchText={trimmedSearchText}
|
||||||
onSelect={onSelect as OnSelectBlock}
|
onSelect={onSelect as OnSelectBlock}
|
||||||
@ -136,6 +170,16 @@ const AllStartBlocks = ({
|
|||||||
tags={tags}
|
tags={tags}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{enableTriggerPlugin && enable_marketplace && (
|
||||||
|
<PluginList
|
||||||
|
ref={pluginRef}
|
||||||
|
wrapElemRef={wrapElemRef as RefObject<HTMLElement>}
|
||||||
|
list={marketplacePlugins}
|
||||||
|
searchText={trimmedSearchText}
|
||||||
|
tags={tags}
|
||||||
|
hideFindMoreFooter
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{shouldShowEmptyState && (
|
{shouldShowEmptyState && (
|
||||||
@ -160,7 +204,7 @@ const AllStartBlocks = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!shouldShowEmptyState && (
|
{shouldShowMarketplaceFooter && !shouldShowEmptyState && (
|
||||||
// Footer - Same as Tools tab marketplace footer
|
// Footer - Same as Tools tab marketplace footer
|
||||||
<Link
|
<Link
|
||||||
className={marketplaceFooterClassName}
|
className={marketplaceFooterClassName}
|
||||||
|
|||||||
@ -231,7 +231,7 @@ const AllTools = ({
|
|||||||
<div
|
<div
|
||||||
ref={wrapElemRef}
|
ref={wrapElemRef}
|
||||||
className='flex-1 overflow-y-auto'
|
className='flex-1 overflow-y-auto'
|
||||||
onScroll={pluginRef.current?.handleScroll}
|
onScroll={() => pluginRef.current?.handleScroll()}
|
||||||
>
|
>
|
||||||
<div className={cn(shouldShowEmptyState && 'hidden')}>
|
<div className={cn(shouldShowEmptyState && 'hidden')}>
|
||||||
{isShowRAGRecommendations && onTagsChange && (
|
{isShowRAGRecommendations && onTagsChange && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user