diff --git a/ui/src/features/project/pipelines/graph/graph.tsx b/ui/src/features/project/pipelines/graph/graph.tsx index 3a75574964..40eae25212 100644 --- a/ui/src/features/project/pipelines/graph/graph.tsx +++ b/ui/src/features/project/pipelines/graph/graph.tsx @@ -83,56 +83,60 @@ export const Graph = (props: GraphProps) => { setNodes(graph.nodes); }, [graph.nodes]); - useEventsWatcher(props.project, { - onStage(stage) { - const index = stageIndexer.index(stage); - setNodes((nodes) => - nodes.map((node) => { - if (node.id === index && node.type === reactFlowNodeConstants.CUSTOM_NODE) { - return { - ...node, - data: { - ...node.data, - value: stage - } - }; - } - - return node; - }) - ); - - if (!nodes.find((n) => n.id === index)) { - setRedraw((prev) => !prev); - } + useEventsWatcher( + props.project, + { + onStage(stage) { + const index = stageIndexer.index(stage); + setNodes((nodes) => + nodes.map((node) => { + if (node.id === index && node.type === reactFlowNodeConstants.CUSTOM_NODE) { + return { + ...node, + data: { + ...node.data, + value: stage + } + }; + } - queryCache.imageStageMatrix.update(stage); - }, - onWarehouse(warehouse) { - const index = warehouseIndexer.index(warehouse); - setNodes((nodes) => - nodes.map((node) => { - if (node.id === index && node.type === reactFlowNodeConstants.CUSTOM_NODE) { - return { - ...node, - data: { - ...node.data, - value: warehouse - } - }; - } - - return node; - }) - ); - - if (!nodes.find((n) => n.id === index)) { - setRedraw((prev) => !prev); - } + return node; + }) + ); + + if (!nodes.find((n) => n.id === index)) { + setRedraw((prev) => !prev); + } + + queryCache.imageStageMatrix.update(stage); + }, + onWarehouse(warehouse) { + const index = warehouseIndexer.index(warehouse); + setNodes((nodes) => + nodes.map((node) => { + if (node.id === index && node.type === reactFlowNodeConstants.CUSTOM_NODE) { + return { + ...node, + data: { + ...node.data, + value: warehouse + } + }; + } - queryCache.freight.refetch(); - } - }); + return node; + }) + ); + + if (!nodes.find((n) => n.id === index)) { + setRedraw((prev) => !prev); + } + + queryCache.freight.refetch(); + } + }, + filterContext?.preferredFilter?.warehouses || [] + ); const warehouseByName = useMemo(() => { const warehouseByName: Record = {}; diff --git a/ui/src/features/project/pipelines/graph/use-events-watcher.ts b/ui/src/features/project/pipelines/graph/use-events-watcher.ts index 3c50ed75b6..6d6afeb40c 100644 --- a/ui/src/features/project/pipelines/graph/use-events-watcher.ts +++ b/ui/src/features/project/pipelines/graph/use-events-watcher.ts @@ -12,7 +12,8 @@ export const useEventsWatcher = ( act?: { onStage: (stage: Stage) => void; onWarehouse: (warehouse: WarehouseExpanded) => void; - } + }, + warehouses?: string[] ) => { const client = useQueryClient(); const isWindowVisible = useDocumentEvent( @@ -27,7 +28,7 @@ export const useEventsWatcher = ( const watcher = new Watcher(project, client); - watcher.watchStages(act?.onStage); + watcher.watchStages(act?.onStage, warehouses); watcher.watchWarehouses({ onWarehouseEvent: act?.onWarehouse, refreshHook: queryCache.freight.refetchQueryFreight @@ -36,5 +37,5 @@ export const useEventsWatcher = ( return () => { watcher.cancelWatch(); }; - }, [isWindowVisible, project]); + }, [isWindowVisible, project, (warehouses || []).join(',')]); }; diff --git a/ui/src/features/project/pipelines/list/list-view.tsx b/ui/src/features/project/pipelines/list/list-view.tsx index 4f361f1a23..5716496662 100644 --- a/ui/src/features/project/pipelines/list/list-view.tsx +++ b/ui/src/features/project/pipelines/list/list-view.tsx @@ -30,7 +30,11 @@ export const PipelineListView = (props: PipelineListViewProps) => { const actionContext = useActionContext(); const freightTimelineControllerContext = useFreightTimelineControllerContext(); - useEventsWatcher(props.project); + useEventsWatcher( + props.project, + undefined, + freightTimelineControllerContext?.preferredFilter?.warehouses || [] + ); const [filters, setFilters] = useState({ stage: '' diff --git a/ui/src/features/project/pipelines/pipelines.tsx b/ui/src/features/project/pipelines/pipelines.tsx index 0ef9640f2d..4f78b07738 100644 --- a/ui/src/features/project/pipelines/pipelines.tsx +++ b/ui/src/features/project/pipelines/pipelines.tsx @@ -70,8 +70,6 @@ export const Pipelines = (props: { creatingStage?: boolean; creatingWarehouse?: const listImagesQuery = useQuery(listImages, { project: name }); - const getFreightQuery = useQuery(queryFreight, { project: projectName }); - const listWarehousesQuery = useQuery( listWarehouses, { @@ -91,7 +89,19 @@ export const Pipelines = (props: { creatingStage?: boolean; creatingWarehouse?: } ); - const listStagesQuery = useQuery(listStages, { project: projectName }); + const [preferredFilter, setPreferredFilter] = useFreightTimelineControllerStore( + projectName || '' + ); + + const getFreightQuery = useQuery(queryFreight, { + project: projectName, + origins: preferredFilter.warehouses + }); + + const listStagesQuery = useQuery(listStages, { + project: projectName, + freightOrigins: preferredFilter.warehouses + }); const loading = projectQuery.isLoading || @@ -123,10 +133,6 @@ export const Pipelines = (props: { creatingStage?: boolean; creatingWarehouse?: [project, listStagesQuery.data?.stages] ); - const [preferredFilter, setPreferredFilter] = useFreightTimelineControllerStore( - projectName || '' - ); - const pipelineView = preferredFilter.view; const setPipelineView = (nextView: 'graph' | 'list') => { diff --git a/ui/src/features/project/pipelines/use-watch-freight.ts b/ui/src/features/project/pipelines/use-watch-freight.ts index 3b566004b0..803ac02ea8 100644 --- a/ui/src/features/project/pipelines/use-watch-freight.ts +++ b/ui/src/features/project/pipelines/use-watch-freight.ts @@ -79,21 +79,31 @@ export const useWatchFreight = (project: string) => { } } - const updatedFreight = - e.type === 'DELETED' - ? deleteFreight(currentFreight, freight) - : upsertFreight(currentFreight, freight); - - const queryFreightKey = createConnectQueryKey({ - cardinality: 'finite', - schema: queryFreight, - input: { - project - }, - transport: transportWithAuth - }); - - client.setQueryData(queryFreightKey, updatedFreight); + if (e.type === 'DELETED') { + // Remove from all queryFreight caches for this project, including + // warehouse-filtered variants, which use a different cache key. + client.setQueriesData( + { + queryKey: createConnectQueryKey({ + cardinality: 'finite', + schema: queryFreight, + input: { project }, + transport: transportWithAuth + }), + exact: false + }, + (current) => deleteFreight(current, freight) + ); + } else { + const updatedFreight = upsertFreight(currentFreight, freight); + const queryFreightKey = createConnectQueryKey({ + cardinality: 'finite', + schema: queryFreight, + input: { project }, + transport: transportWithAuth + }); + client.setQueryData(queryFreightKey, updatedFreight); + } } }; diff --git a/ui/src/features/project/pipelines/watcher.ts b/ui/src/features/project/pipelines/watcher.ts index 083a088a3c..a1ae4d10dc 100644 --- a/ui/src/features/project/pipelines/watcher.ts +++ b/ui/src/features/project/pipelines/watcher.ts @@ -71,20 +71,26 @@ export class Watcher { async watchStages( // utilise the fact that something changed in this stage // avoid as much as re-construction of data as possible by using this parameter - onStageEvent?: (stage: Stage) => void + onStageEvent?: (stage: Stage) => void, + warehouses?: string[] ) { const stream = this.promiseClient.watchStages( - { project: this.project }, + { project: this.project, freightOrigins: warehouses || [] }, { signal: this.cancel.signal } ); + const stagesInput = create(ListStagesRequestSchema, { + project: this.project, + freightOrigins: warehouses || [] + }); + ProcessEvents( stream, () => { const data = this.client.getQueryData( createConnectQueryKey({ schema: listStages, - input: create(ListStagesRequestSchema, { project: this.project }), + input: stagesInput, cardinality: 'finite', transport: transportWithAuth }) @@ -97,7 +103,7 @@ export class Watcher { // update Stages list const listStagesQueryKey = createConnectQueryKey({ schema: listStages, - input: create(ListStagesRequestSchema, { project: this.project }), + input: stagesInput, cardinality: 'finite', transport: transportWithAuth });