diff --git a/web/src/pages/agents/hooks/use-select-filters.ts b/web/src/pages/agents/hooks/use-select-filters.ts index e6bc32682c..7a2a448641 100644 --- a/web/src/pages/agents/hooks/use-select-filters.ts +++ b/web/src/pages/agents/hooks/use-select-filters.ts @@ -26,7 +26,7 @@ export function useSelectFilters() { const filters: FilterCollection[] = [ { field: 'owner', - list: agentFilters.owner, + list: agentFilters?.owner, label: t('common.owner'), }, { @@ -36,7 +36,7 @@ export function useSelectFilters() { id: AgentCategory.DataflowCanvas, label: t('flow.tabList.ingestionPipeline'), count: - agentFilters.canvas_category.find( + agentFilters?.canvas_category.find( (item) => item.id === AgentCategory.DataflowCanvas, )?.count ?? 0, }, @@ -44,7 +44,7 @@ export function useSelectFilters() { id: AgentListItemType.CompilationTemplateGroup, label: t('flow.tabList.compilationOperator'), count: - agentFilters.canvas_category.find( + agentFilters?.canvas_category.find( (item) => item.id === AgentListItemType.CompilationTemplateGroup, )?.count ?? 0, }, @@ -52,7 +52,7 @@ export function useSelectFilters() { id: AgentCategory.AgentCanvas, label: t('flow.tabList.workflow'), count: - agentFilters.canvas_category.find( + agentFilters?.canvas_category.find( (item) => item.id === AgentCategory.AgentCanvas, )?.count ?? 0, }, diff --git a/web/src/pages/dataset/compilation/dataset-structure-view.tsx b/web/src/pages/dataset/compilation/dataset-structure-view.tsx index 1449cccfc4..c2c47a752a 100644 --- a/web/src/pages/dataset/compilation/dataset-structure-view.tsx +++ b/web/src/pages/dataset/compilation/dataset-structure-view.tsx @@ -23,7 +23,7 @@ import { } from '@/hooks/use-knowledge-request'; import { useQueryClient } from '@tanstack/react-query'; import { Trash2 } from 'lucide-react'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { @@ -33,6 +33,7 @@ import { ViewModeLabelKeyMap, } from './constants'; import CompilationEmptyState from './empty-state'; +import { useRunEndEffect } from './hooks/use-run-end-effect'; import { CompilationLoadingCard } from './loading-card'; import { CompilationUpdateButton } from './update-button'; import { UpdateLogSheet } from './update-log-sheet'; @@ -66,13 +67,12 @@ export function DatasetStructureView({ kind }: DatasetStructureViewProps) { const removed = alteration?.removed ?? 0; const hasChanges = newlyUploaded > 0 || removed > 0; - useEffect(() => { - if (structureStatus === GenerateStatus.Completed) { - queryClient.invalidateQueries({ - queryKey: DatasetStructureKeys.kind(knowledgeBaseId, kind), - }); - } - }, [structureStatus, queryClient, knowledgeBaseId, kind]); + const handleRunEnd = useCallback(() => { + queryClient.invalidateQueries({ + queryKey: DatasetStructureKeys.kind(knowledgeBaseId, kind), + }); + }, [queryClient, knowledgeBaseId, kind]); + useRunEndEffect(structureStatus, handleRunEnd); const entityOptions = useMemo( () => diff --git a/web/src/pages/dataset/compilation/hooks/use-run-end-effect.ts b/web/src/pages/dataset/compilation/hooks/use-run-end-effect.ts new file mode 100644 index 0000000000..4daefb94f0 --- /dev/null +++ b/web/src/pages/dataset/compilation/hooks/use-run-end-effect.ts @@ -0,0 +1,24 @@ +import { GenerateStatus } from '@/constants/knowledge'; +import { useEffect, useRef } from 'react'; + +// Fires once when a compilation run leaves the Running state, no matter how it +// ended: finished at 100% (Running -> Completed), paused (the task is unbound, +// so the trace resets and Running -> Start), or failed. Views refresh their +// data through this single path so pausing behaves exactly like completion. +export function useRunEndEffect( + status: GenerateStatus, + onRunEnd: () => void, +) { + const prevStatusRef = useRef(status); + + useEffect(() => { + const prevStatus = prevStatusRef.current; + prevStatusRef.current = status; + if ( + prevStatus === GenerateStatus.Running && + status !== GenerateStatus.Running + ) { + onRunEnd(); + } + }, [status, onRunEnd]); +} diff --git a/web/src/pages/dataset/compilation/llm-wiki-view.tsx b/web/src/pages/dataset/compilation/llm-wiki-view.tsx index ffc2562121..f404b290f1 100644 --- a/web/src/pages/dataset/compilation/llm-wiki-view.tsx +++ b/web/src/pages/dataset/compilation/llm-wiki-view.tsx @@ -4,7 +4,7 @@ import { ResizablePanel, ResizablePanelGroup, } from '@/components/ui/resizable'; -import { GenerateStatus, GenerateType } from '@/constants/knowledge'; +import { GenerateType } from '@/constants/knowledge'; import { useGenerateStatus, useTraceRunData, @@ -16,12 +16,13 @@ import { useFetchKnowledgeBaseConfiguration, } from '@/hooks/use-knowledge-request'; import { useQueryClient } from '@tanstack/react-query'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useState } from 'react'; import { useParams } from 'react-router'; import { LeftPanelTab, ViewMode } from './constants'; import CompilationEmptyState from './empty-state'; import { useCompilationArtifact } from './hooks/use-compilation-artifact'; +import { useRunEndEffect } from './hooks/use-run-end-effect'; import { CompilationLoadingCard } from './loading-card'; import { WikiDetailContent } from './wiki-detail-content'; import { WikiLeftPanel } from './wiki-left-panel'; @@ -44,17 +45,15 @@ export function LlmWikiView() { const { status: artifactStatus } = useGenerateStatus(artifactRunData); const [updateSheetOpen, setUpdateSheetOpen] = useState(false); - useEffect(() => { - if (artifactStatus === GenerateStatus.Completed) { - setUpdateSheetOpen(false); - queryClient.invalidateQueries({ - queryKey: ArtifactKeys.listByDataset(id!), - }); - queryClient.invalidateQueries({ - queryKey: ArtifactTopicKeys.listByDataset(id!), - }); - } - }, [artifactStatus, queryClient, id]); + const handleRunEnd = useCallback(() => { + queryClient.invalidateQueries({ + queryKey: ArtifactKeys.listByDataset(id!), + }); + queryClient.invalidateQueries({ + queryKey: ArtifactTopicKeys.listByDataset(id!), + }); + }, [queryClient, id]); + useRunEndEffect(artifactStatus, handleRunEnd); const handleLeftTabChange = useCallback((value: string) => { setLeftTab(value as LeftPanelTab); diff --git a/web/src/pages/dataset/compilation/skills-view.tsx b/web/src/pages/dataset/compilation/skills-view.tsx index 3bccf478aa..9d529ac172 100644 --- a/web/src/pages/dataset/compilation/skills-view.tsx +++ b/web/src/pages/dataset/compilation/skills-view.tsx @@ -5,7 +5,7 @@ import { ResizablePanel, ResizablePanelGroup, } from '@/components/ui/resizable'; -import { GenerateStatus, GenerateType } from '@/constants/knowledge'; +import { GenerateType } from '@/constants/knowledge'; import { useGenerateStatus, useTraceRunData, @@ -13,12 +13,13 @@ import { import { DatasetSkillKeys } from '@/hooks/use-dataset-skill-request'; import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request'; import { useQueryClient } from '@tanstack/react-query'; -import { useEffect } from 'react'; +import { useCallback } from 'react'; import { useParams } from 'react-router'; import { ViewMode } from './constants'; import CompilationEmptyState from './empty-state'; import { useCompilationSkill } from './hooks/use-compilation-skill'; +import { useRunEndEffect } from './hooks/use-run-end-effect'; import { CompilationLoadingCard } from './loading-card'; import { SkillsLeftPanel } from './skills-left-panel'; @@ -37,13 +38,12 @@ export function SkillsView() { const { data: skillRunData } = useTraceRunData(GenerateType.ToSkills); const { status: skillStatus } = useGenerateStatus(skillRunData); - useEffect(() => { - if (skillStatus === GenerateStatus.Completed) { - queryClient.invalidateQueries({ - queryKey: DatasetSkillKeys.tree(id!), - }); - } - }, [skillStatus, queryClient, id]); + const handleRunEnd = useCallback(() => { + queryClient.invalidateQueries({ + queryKey: DatasetSkillKeys.tree(id!), + }); + }, [queryClient, id]); + useRunEndEffect(skillStatus, handleRunEnd); const canGenerate = (knowledgeBase?.chunk_count ?? 0) > 0; const isLoading = skillTreeLoading && !skillTree?.skill_with_weight?.length; diff --git a/web/src/pages/dataset/compilation/update-log-sheet.tsx b/web/src/pages/dataset/compilation/update-log-sheet.tsx index c93b6b2028..f6c85e1604 100644 --- a/web/src/pages/dataset/compilation/update-log-sheet.tsx +++ b/web/src/pages/dataset/compilation/update-log-sheet.tsx @@ -1,13 +1,10 @@ -import { useEffect } from 'react'; - import { Sheet, SheetContent, SheetHeader, SheetTitle, } from '@/components/ui/sheet'; -import { GenerateStatus } from '@/constants/knowledge'; -import { ITraceInfo, useGenerateStatus } from '@/hooks/use-dataset-generate'; +import { ITraceInfo } from '@/hooks/use-dataset-generate'; import { ProgressLogPanel } from './progress-log-panel'; @@ -28,14 +25,6 @@ export function UpdateLogSheet({ data, title, }: UpdateLogSheetProps) { - const { status } = useGenerateStatus(data); - - useEffect(() => { - if (status === GenerateStatus.Completed) { - onOpenChange(false); - } - }, [status, onOpenChange]); - return (