From 48724f8d90ec9927ed07382061bce78171ccb1b2 Mon Sep 17 00:00:00 2001 From: Bat-Zion Rotman Date: Tue, 30 Jan 2024 15:25:14 +0200 Subject: [PATCH] fix(orchestrator): resolve bug in workflow instance page assessed by link (#1142) fix(orchestrator): resolve FLPATH-945 - clicking on ASSESSED BY link in Workflow instance page doesn't refresh the page --- .../src/components/WorkflowInstancePage.tsx | 14 ++++++++------ .../src/components/WorkflowRunsTabContent.tsx | 7 ++++--- plugins/orchestrator/src/hooks/usePolling.test.ts | 15 +++++++++++++++ plugins/orchestrator/src/hooks/usePolling.ts | 15 ++++++++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/plugins/orchestrator/src/components/WorkflowInstancePage.tsx b/plugins/orchestrator/src/components/WorkflowInstancePage.tsx index 3d4632b8e7..2874ec96f5 100644 --- a/plugins/orchestrator/src/components/WorkflowInstancePage.tsx +++ b/plugins/orchestrator/src/components/WorkflowInstancePage.tsx @@ -29,15 +29,17 @@ export const WorkflowInstancePage = ({ workflowInstanceRouteRef, ); + const fetchInstance = React.useCallback(async () => { + if (!instanceId && !queryInstanceId) { + return undefined; + } + return await orchestratorApi.getInstance(instanceId || queryInstanceId); + }, [instanceId, orchestratorApi, queryInstanceId]); + const { loading, error, value, restart } = usePolling< ProcessInstance | undefined >( - async () => { - if (!instanceId && !queryInstanceId) { - return undefined; - } - return await orchestratorApi.getInstance(instanceId || queryInstanceId); - }, + fetchInstance, SHORT_REFRESH_INTERVAL, (curValue: ProcessInstance | undefined) => !!curValue && curValue.state === 'ACTIVE', diff --git a/plugins/orchestrator/src/components/WorkflowRunsTabContent.tsx b/plugins/orchestrator/src/components/WorkflowRunsTabContent.tsx index aefe964445..99e523ce2a 100644 --- a/plugins/orchestrator/src/components/WorkflowRunsTabContent.tsx +++ b/plugins/orchestrator/src/components/WorkflowRunsTabContent.tsx @@ -48,14 +48,15 @@ export const WorkflowRunsTabContent = () => { Selector.AllItems, ); - const { loading, error, value } = usePolling(async () => { + const fetchInstances = React.useCallback(async () => { const instances = await orchestratorApi.getInstances(); const clonedData: WorkflowRunDetail[] = instances.map( mapProcessInstanceToDetails, ); - return clonedData; - }); + }, [orchestratorApi]); + + const { loading, error, value } = usePolling(fetchInstances); const columns = React.useMemo( (): TableColumn[] => [ diff --git a/plugins/orchestrator/src/hooks/usePolling.test.ts b/plugins/orchestrator/src/hooks/usePolling.test.ts index 7503d6c237..69ee2b6198 100644 --- a/plugins/orchestrator/src/hooks/usePolling.test.ts +++ b/plugins/orchestrator/src/hooks/usePolling.test.ts @@ -162,4 +162,19 @@ describe('usePolling', () => { await act(async () => result.current.restart()); expect(result.current.value).toEqual(ABORTED); }); + + test('should refetch after fn property changed', async () => { + const mockAsyncFn = jest.fn().mockResolvedValue(ACTIVE); + const { result, waitForNextUpdate, rerender } = renderHook( + ({ fn }: { fn: () => Promise }) => + usePolling(fn, SHORT_REFRESH_INTERVAL), + { initialProps: { fn: mockAsyncFn } }, + ); + await waitForNextUpdate(); + const mockAsyncFn2 = jest.fn().mockResolvedValue(COMPLETED); + expect(result.current.value).toEqual(ACTIVE); + rerender({ fn: mockAsyncFn2 }); + await waitForNextUpdate(); + expect(result.current.value).toEqual(COMPLETED); + }); }); diff --git a/plugins/orchestrator/src/hooks/usePolling.ts b/plugins/orchestrator/src/hooks/usePolling.ts index e2f1daf5b7..04c5c4bfd7 100644 --- a/plugins/orchestrator/src/hooks/usePolling.ts +++ b/plugins/orchestrator/src/hooks/usePolling.ts @@ -13,6 +13,7 @@ const usePolling = ( ) => { const config = useSWRConfig(); + const prevFn = React.useRef(fn); const uniqueKey = React.useMemo(() => { return uuid.v4(); }, []); @@ -38,6 +39,18 @@ const usePolling = ( }, }); + const restart = React.useCallback( + () => config.mutate(uniqueKey), + [config, uniqueKey], + ); + + React.useEffect(() => { + if (prevFn.current !== fn) { + restart(); + prevFn.current = fn; + } + }, [fn, restart]); + React.useEffect(() => { // clean cache after unmount, no need to store the data globally return () => config.cache.delete(uniqueKey); @@ -48,7 +61,7 @@ const usePolling = ( value: data, error, loading: isLoading, - restart: () => config.mutate(uniqueKey), + restart, }; };