feat(workflow): persist RAG recommendation panel collapse state

This commit is contained in:
lyzno1 2025-10-29 15:10:45 +08:00
parent c94dc52310
commit 0db082f6d0
No known key found for this signature in database
1 changed files with 77 additions and 44 deletions

View File

@ -1,5 +1,6 @@
'use client'
import type { Dispatch, SetStateAction } from 'react'
import React, { useCallback, useMemo } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import type { OnSelectBlock } from '@/app/components/workflow/types'
import type { ViewType } from '@/app/components/workflow/block-selector/view-type-select'
@ -10,6 +11,7 @@ import { getMarketplaceUrl } from '@/utils/var'
import { useRAGRecommendedPlugins } from '@/service/use-tools'
import List from './list'
import { getFormattedPlugin } from '@/app/components/plugins/marketplace/utils'
import { ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/arrows'
type RAGToolRecommendationsProps = {
viewType: ViewType
@ -17,12 +19,34 @@ type RAGToolRecommendationsProps = {
onTagsChange: Dispatch<SetStateAction<string[]>>
}
const STORAGE_KEY = 'workflow_rag_recommendations_collapsed'
const RAGToolRecommendations = ({
viewType,
onSelect,
onTagsChange,
}: RAGToolRecommendationsProps) => {
const { t } = useTranslation()
const [isCollapsed, setIsCollapsed] = useState<boolean>(() => {
if (typeof window === 'undefined')
return false
const stored = window.localStorage.getItem(STORAGE_KEY)
return stored === 'true'
})
useEffect(() => {
if (typeof window === 'undefined')
return
const stored = window.localStorage.getItem(STORAGE_KEY)
if (stored !== null)
setIsCollapsed(stored === 'true')
}, [])
useEffect(() => {
if (typeof window === 'undefined')
return
window.localStorage.setItem(STORAGE_KEY, String(isCollapsed))
}, [isCollapsed])
const {
data: ragRecommendedPlugins,
@ -52,51 +76,60 @@ const RAGToolRecommendations = ({
return (
<div className='flex flex-col p-1'>
<div className='system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary'>
{t('pipeline.ragToolSuggestions.title')}
</div>
{/* For first time loading, show loading */}
{isLoadingRAGRecommendedPlugins && (
<div className='py-2'>
<Loading type='app' />
</div>
)}
{!isFetchingRAGRecommendedPlugins && recommendedPlugins.length === 0 && unInstalledPlugins.length === 0 && (
<p className='system-xs-regular px-3 py-1 text-text-tertiary'>
<Trans
i18nKey='pipeline.ragToolSuggestions.noRecommendationPlugins'
components={{
CustomLink: (
<Link
className='text-text-accent'
target='_blank'
rel='noopener noreferrer'
href={getMarketplaceUrl('', { tags: 'rag' })}
/>
),
}}
/>
</p>
)}
{(recommendedPlugins.length > 0 || unInstalledPlugins.length > 0) && (
<button
type='button'
className='flex w-full items-center rounded-md px-3 pb-0.5 pt-1 text-left text-text-tertiary'
onClick={() => setIsCollapsed(prev => !prev)}
>
<span className='system-xs-medium text-text-tertiary'>{t('pipeline.ragToolSuggestions.title')}</span>
<ArrowDownRoundFill className={`ml-1 h-4 w-4 text-text-tertiary transition-transform ${isCollapsed ? '-rotate-90' : 'rotate-0'}`} />
</button>
{!isCollapsed && (
<>
<List
tools={recommendedPlugins}
unInstalledPlugins={unInstalledPlugins}
onSelect={onSelect}
viewType={viewType}
/>
<div
className='flex cursor-pointer items-center gap-x-2 py-1 pl-3 pr-2'
onClick={loadMore}
>
<div className='px-1'>
<RiMoreLine className='size-4 text-text-tertiary' />
{/* For first time loading, show loading */}
{isLoadingRAGRecommendedPlugins && (
<div className='py-2'>
<Loading type='app' />
</div>
<div className='system-xs-regular text-text-tertiary'>
{t('common.operation.more')}
</div>
</div>
)}
{!isFetchingRAGRecommendedPlugins && recommendedPlugins.length === 0 && unInstalledPlugins.length === 0 && (
<p className='system-xs-regular px-3 py-1 text-text-tertiary'>
<Trans
i18nKey='pipeline.ragToolSuggestions.noRecommendationPlugins'
components={{
CustomLink: (
<Link
className='text-text-accent'
target='_blank'
rel='noopener noreferrer'
href={getMarketplaceUrl('', { tags: 'rag' })}
/>
),
}}
/>
</p>
)}
{(recommendedPlugins.length > 0 || unInstalledPlugins.length > 0) && (
<>
<List
tools={recommendedPlugins}
unInstalledPlugins={unInstalledPlugins}
onSelect={onSelect}
viewType={viewType}
/>
<div
className='flex cursor-pointer items-center gap-x-2 py-1 pl-3 pr-2'
onClick={loadMore}
>
<div className='px-1'>
<RiMoreLine className='size-4 text-text-tertiary' />
</div>
<div className='system-xs-regular text-text-tertiary'>
{t('common.operation.more')}
</div>
</div>
</>
)}
</>
)}
</div>