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

View File

@ -1,5 +1,6 @@
'use client'
import type { Dispatch, SetStateAction } from 'react' 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 { Trans, useTranslation } from 'react-i18next'
import type { OnSelectBlock } from '@/app/components/workflow/types' import type { OnSelectBlock } from '@/app/components/workflow/types'
import type { ViewType } from '@/app/components/workflow/block-selector/view-type-select' 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 { useRAGRecommendedPlugins } from '@/service/use-tools'
import List from './list' import List from './list'
import { getFormattedPlugin } from '@/app/components/plugins/marketplace/utils' import { getFormattedPlugin } from '@/app/components/plugins/marketplace/utils'
import { ArrowDownRoundFill } from '@/app/components/base/icons/src/vender/solid/arrows'
type RAGToolRecommendationsProps = { type RAGToolRecommendationsProps = {
viewType: ViewType viewType: ViewType
@ -17,12 +19,34 @@ type RAGToolRecommendationsProps = {
onTagsChange: Dispatch<SetStateAction<string[]>> onTagsChange: Dispatch<SetStateAction<string[]>>
} }
const STORAGE_KEY = 'workflow_rag_recommendations_collapsed'
const RAGToolRecommendations = ({ const RAGToolRecommendations = ({
viewType, viewType,
onSelect, onSelect,
onTagsChange, onTagsChange,
}: RAGToolRecommendationsProps) => { }: RAGToolRecommendationsProps) => {
const { t } = useTranslation() 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 { const {
data: ragRecommendedPlugins, data: ragRecommendedPlugins,
@ -52,51 +76,60 @@ const RAGToolRecommendations = ({
return ( return (
<div className='flex flex-col p-1'> <div className='flex flex-col p-1'>
<div className='system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary'> <button
{t('pipeline.ragToolSuggestions.title')} type='button'
</div> className='flex w-full items-center rounded-md px-3 pb-0.5 pt-1 text-left text-text-tertiary'
{/* For first time loading, show loading */} onClick={() => setIsCollapsed(prev => !prev)}
{isLoadingRAGRecommendedPlugins && ( >
<div className='py-2'> <span className='system-xs-medium text-text-tertiary'>{t('pipeline.ragToolSuggestions.title')}</span>
<Loading type='app' /> <ArrowDownRoundFill className={`ml-1 h-4 w-4 text-text-tertiary transition-transform ${isCollapsed ? '-rotate-90' : 'rotate-0'}`} />
</div> </button>
)} {!isCollapsed && (
{!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 {/* For first time loading, show loading */}
tools={recommendedPlugins} {isLoadingRAGRecommendedPlugins && (
unInstalledPlugins={unInstalledPlugins} <div className='py-2'>
onSelect={onSelect} <Loading type='app' />
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>
<div className='system-xs-regular text-text-tertiary'> )}
{t('common.operation.more')} {!isFetchingRAGRecommendedPlugins && recommendedPlugins.length === 0 && unInstalledPlugins.length === 0 && (
</div> <p className='system-xs-regular px-3 py-1 text-text-tertiary'>
</div> <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> </div>