From cc38cb121f2c061abfae9ff18b64efb5bfb0776b Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 01:34:56 +0000 Subject: [PATCH 01/13] fetcher updates --- .../workflow-history-v2.tsx | 2 +- .../workflow-history-page-size.config.ts | 5 +- .../workflow-history-fetcher.test.tsx | 49 +++++++++++++++++-- .../helpers/workflow-history-fetcher.ts | 9 +++- .../use-workflow-history-fetcher.test.tsx | 6 ++- .../hooks/use-workflow-history-fetcher.ts | 15 ++++-- .../workflow-history/workflow-history.tsx | 2 +- 7 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/views/workflow-history-v2/workflow-history-v2.tsx b/src/views/workflow-history-v2/workflow-history-v2.tsx index 6f33a88db..fcdd0358b 100644 --- a/src/views/workflow-history-v2/workflow-history-v2.tsx +++ b/src/views/workflow-history-v2/workflow-history-v2.tsx @@ -4,7 +4,7 @@ import usePageFilters from '@/components/page-filters/hooks/use-page-filters'; import decodeUrlParams from '@/utils/decode-url-params'; import workflowHistoryFiltersConfig from '../workflow-history/config/workflow-history-filters.config'; -import WORKFLOW_HISTORY_PAGE_SIZE_CONFIG from '../workflow-history/config/workflow-history-page-size.config'; +import { WORKFLOW_HISTORY_PAGE_SIZE_CONFIG } from '../workflow-history/config/workflow-history-page-size.config'; import { WorkflowHistoryContext } from '../workflow-history/workflow-history-context-provider/workflow-history-context-provider'; import workflowPageQueryParamsConfig from '../workflow-page/config/workflow-page-query-params.config'; import { type WorkflowPageTabContentParams } from '../workflow-page/workflow-page-tab-content/workflow-page-tab-content.types'; diff --git a/src/views/workflow-history/config/workflow-history-page-size.config.ts b/src/views/workflow-history/config/workflow-history-page-size.config.ts index 933cf92dd..453efac10 100644 --- a/src/views/workflow-history/config/workflow-history-page-size.config.ts +++ b/src/views/workflow-history/config/workflow-history-page-size.config.ts @@ -1,3 +1,2 @@ -const WORKFLOW_HISTORY_PAGE_SIZE_CONFIG = 200; - -export default WORKFLOW_HISTORY_PAGE_SIZE_CONFIG; +export const WORKFLOW_HISTORY_PAGE_SIZE_CONFIG = 1000; +export const WORKFLOW_HISTORY_FIRST_PAGE_SIZE_CONFIG = 200; diff --git a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx index f2d59e315..23ab86ed2 100644 --- a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx @@ -262,6 +262,37 @@ describe(WorkflowHistoryFetcher.name, () => { const state = fetcher.getCurrentState(); expect(state.data?.pages.length).toBe(pageCountBefore); }); + + it('should use WORKFLOW_HISTORY_FIRST_PAGE_SIZE_CONFIG for the first page', async () => { + const { fetcher, getCapturedPageSizes } = setup(queryClient); + + fetcher.start((state) => !state?.data?.pages?.length); + + await waitFor(() => { + const state = fetcher.getCurrentState(); + expect(state.data?.pages).toHaveLength(1); + }); + + const pageSizes = getCapturedPageSizes(); + expect(pageSizes).toHaveLength(1); + expect(pageSizes[0]).toBe('200'); + }); + + it('should use WORKFLOW_HISTORY_PAGE_SIZE_CONFIG for subsequent pages', async () => { + const { fetcher, getCapturedPageSizes } = setup(queryClient); + + fetcher.start((state) => (state.data?.pages.length || 0) < 2); + + await waitFor(() => { + const state = fetcher.getCurrentState(); + expect(state.data?.pages).toHaveLength(2); + }); + + const pageSizes = getCapturedPageSizes(); + expect(pageSizes.length).toBeGreaterThanOrEqual(2); + expect(pageSizes[0]).toBe('200'); + expect(pageSizes[1]).toBe('1000'); + }); }); function setup(client: QueryClient, options: { failOnPages?: number[] } = {}) { @@ -273,7 +304,10 @@ function setup(client: QueryClient, options: { failOnPages?: number[] } = {}) { pageSize: 10, }; - mockHistoryEndpoint(workflowHistoryMultiPageFixture, options.failOnPages); + const { getCapturedPageSizes } = mockHistoryEndpoint( + workflowHistoryMultiPageFixture, + options.failOnPages + ); const fetcher = new WorkflowHistoryFetcher(client, params); hoistedFetcher = fetcher; @@ -292,6 +326,7 @@ function setup(client: QueryClient, options: { failOnPages?: number[] } = {}) { fetcher, params, waitForData, + getCapturedPageSizes, }; } @@ -299,6 +334,8 @@ function mockHistoryEndpoint( responses: GetWorkflowHistoryResponse[], failOnPages: number[] = [] ) { + const capturedPageSizes: string[] = []; + mswMockEndpoints([ { path: '/api/domains/:domain/:cluster/workflows/:workflowId/:runId/history', @@ -307,6 +344,9 @@ function mockHistoryEndpoint( httpResolver: async ({ request }) => { const url = new URL(request.url); const nextPage = url.searchParams.get('nextPage'); + const pageSize = url.searchParams.get('pageSize'); + + capturedPageSizes.push(pageSize ?? ''); // Determine current page number based on nextPage param let pageNumber = 1; @@ -328,10 +368,13 @@ function mockHistoryEndpoint( // Map page number to response index (0-indexed) const responseIndex = pageNumber - 1; - const response = - responses[responseIndex] || responses[responses.length - 1]; + const response = responses[responseIndex]; return HttpResponse.json(response); }, }, ]); + + return { + getCapturedPageSizes: () => capturedPageSizes, + }; } diff --git a/src/views/workflow-history/helpers/workflow-history-fetcher.ts b/src/views/workflow-history/helpers/workflow-history-fetcher.ts index a43dfaa31..718b21093 100644 --- a/src/views/workflow-history/helpers/workflow-history-fetcher.ts +++ b/src/views/workflow-history/helpers/workflow-history-fetcher.ts @@ -7,6 +7,11 @@ import { } from '@/route-handlers/get-workflow-history/get-workflow-history.types'; import request from '@/utils/request'; +import { + WORKFLOW_HISTORY_FIRST_PAGE_SIZE_CONFIG, + WORKFLOW_HISTORY_PAGE_SIZE_CONFIG, +} from '../config/workflow-history-page-size.config'; + import { type WorkflowHistoryQueryResult, type QueryResultOnChangeCallback, @@ -126,7 +131,9 @@ export default class WorkflowHistoryFetcher { url: `/api/domains/${params.domain}/${params.cluster}/workflows/${params.workflowId}/${params.runId}/history`, query: { nextPage: pageParam, - pageSize: params.pageSize, + pageSize: pageParam + ? WORKFLOW_HISTORY_PAGE_SIZE_CONFIG + : WORKFLOW_HISTORY_FIRST_PAGE_SIZE_CONFIG, waitForNewEvent: params.waitForNewEvent ?? false, } satisfies WorkflowHistoryQueryParams, }) diff --git a/src/views/workflow-history/hooks/__tests__/use-workflow-history-fetcher.test.tsx b/src/views/workflow-history/hooks/__tests__/use-workflow-history-fetcher.test.tsx index 8f67dcbb7..0cb9e7332 100644 --- a/src/views/workflow-history/hooks/__tests__/use-workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/hooks/__tests__/use-workflow-history-fetcher.test.tsx @@ -19,13 +19,17 @@ let mockOnChangeCallback: jest.Mock; let mockUnsubscribe: jest.Mock; function setup() { - const hookResult = renderHook(() => useWorkflowHistoryFetcher(mockParams)); + const mockOnEventsChange = jest.fn(); + const hookResult = renderHook(() => + useWorkflowHistoryFetcher(mockParams, mockOnEventsChange) + ); return { ...hookResult, mockFetcherInstance, mockOnChangeCallback, mockUnsubscribe, + mockOnEventsChange, }; } diff --git a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts index c287edfd3..3609e3bbf 100644 --- a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts +++ b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts @@ -6,6 +6,7 @@ import { useQueryClient, } from '@tanstack/react-query'; +import { type HistoryEvent } from '@/__generated__/proto-ts/uber/cadence/api/v1/HistoryEvent'; import useThrottledState from '@/hooks/use-throttled-state'; import { type WorkflowHistoryQueryParams, @@ -19,6 +20,7 @@ import { type ShouldContinueCallback } from '../helpers/workflow-history-fetcher export default function useWorkflowHistoryFetcher( params: WorkflowHistoryQueryParams & RouteParams, + onEventsChange: (events: HistoryEvent[]) => void, throttleMs: number = 2000 ) { const queryClient = useQueryClient(); @@ -26,6 +28,9 @@ export default function useWorkflowHistoryFetcher( if (!fetcherRef.current) { fetcherRef.current = new WorkflowHistoryFetcher(queryClient, params); + + // Fetch first page + fetcherRef.current.start((state) => !state?.data?.pages?.length); } const [historyQuery, setHistoryQuery] = useThrottledState< @@ -43,20 +48,22 @@ export default function useWorkflowHistoryFetcher( const unsubscribe = fetcherRef.current.onChange((state) => { const pagesCount = state.data?.pages?.length || 0; + onEventsChange( + state.data?.pages?.flatMap((page) => page.history?.events || []) || [] + ); // immediately set if there is the first page without throttling other wise throttle const executeImmediately = pagesCount <= 1; setHistoryQuery(() => state, executeImmediately); }); - // Fetch first page - fetcherRef.current.start((state) => !state?.data?.pages?.length); - return () => { unsubscribe(); }; - }, [setHistoryQuery]); + }, [setHistoryQuery, onEventsChange]); useEffect(() => { + if (!fetcherRef.current) return; + return () => { fetcherRef.current?.destroy(); }; diff --git a/src/views/workflow-history/workflow-history.tsx b/src/views/workflow-history/workflow-history.tsx index ef69c835b..7b8b5a81a 100644 --- a/src/views/workflow-history/workflow-history.tsx +++ b/src/views/workflow-history/workflow-history.tsx @@ -25,7 +25,7 @@ import workflowPageQueryParamsConfig from '../workflow-page/config/workflow-page import { useSuspenseDescribeWorkflow } from '../workflow-page/hooks/use-describe-workflow'; import workflowHistoryFiltersConfig from './config/workflow-history-filters.config'; -import WORKFLOW_HISTORY_PAGE_SIZE_CONFIG from './config/workflow-history-page-size.config'; +import { WORKFLOW_HISTORY_PAGE_SIZE_CONFIG } from './config/workflow-history-page-size.config'; import compareUngroupedEvents from './helpers/compare-ungrouped-events'; import getSortableEventId from './helpers/get-sortable-event-id'; import getVisibleGroupsHasMissingEvents from './helpers/get-visible-groups-has-missing-events'; From 2a41fc674e3599cd78dd4dec9eccdc2a764a76f6 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 10:03:17 +0000 Subject: [PATCH 02/13] add placeholder for fetcher --- src/views/workflow-history/workflow-history.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/views/workflow-history/workflow-history.tsx b/src/views/workflow-history/workflow-history.tsx index 7b8b5a81a..867711826 100644 --- a/src/views/workflow-history/workflow-history.tsx +++ b/src/views/workflow-history/workflow-history.tsx @@ -73,6 +73,8 @@ export default function WorkflowHistory({ params }: Props) { pageSize: wfHistoryRequestArgs.pageSize, waitForNewEvent: wfHistoryRequestArgs.waitForNewEvent, }, + //TODO replace this with grouper callback + () => {}, 2000 ); From 1f54d952d70deb519d8364c6cce7b6ba900fd858 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 10:04:43 +0000 Subject: [PATCH 03/13] update fetcher mock --- .../workflow-history/__tests__/workflow-history.test.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/views/workflow-history/__tests__/workflow-history.test.tsx b/src/views/workflow-history/__tests__/workflow-history.test.tsx index 797b1fde6..3a7a63400 100644 --- a/src/views/workflow-history/__tests__/workflow-history.test.tsx +++ b/src/views/workflow-history/__tests__/workflow-history.test.tsx @@ -29,11 +29,14 @@ jest.mock('@/hooks/use-page-query-params/use-page-query-params', () => ); // Mock the hook to use minimal throttle delay for faster tests +// Mock the hooks to use minimal throttle delay for faster tests jest.mock('../hooks/use-workflow-history-fetcher', () => { const actual = jest.requireActual('../hooks/use-workflow-history-fetcher'); return { __esModule: true, - default: jest.fn((params) => actual.default(params, 0)), // 0ms throttle for tests + default: jest.fn((params, onEventsChange) => + actual.default(params, onEventsChange, 0) + ), // 0ms throttle for tests }; }); From 3398d8ae83520ae861f707f5f23ab12e14c9e6bc Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 10:47:07 +0000 Subject: [PATCH 04/13] fetcher start update --- .../helpers/workflow-history-fetcher.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/views/workflow-history/helpers/workflow-history-fetcher.ts b/src/views/workflow-history/helpers/workflow-history-fetcher.ts index 718b21093..9141698b9 100644 --- a/src/views/workflow-history/helpers/workflow-history-fetcher.ts +++ b/src/views/workflow-history/helpers/workflow-history-fetcher.ts @@ -49,13 +49,17 @@ export default class WorkflowHistoryFetcher { if (shouldContinue) { this.shouldContinue = shouldContinue; } - // If already started, return - if (this.isStarted) return; + + // remove current listener (if exists) to have fresh emits only + this.unsubscribe?.(); + this.unsubscribe = null; + this.isStarted = true; let emitCount = 0; const currentState = this.observer.getCurrentResult(); const fetchedFirstPage = currentState.status !== 'pending'; - const shouldEnableQuery = !fetchedFirstPage && shouldContinue(currentState); + const shouldEnableQuery = + !fetchedFirstPage && this.shouldContinue(currentState); if (shouldEnableQuery) { this.observer.setOptions({ @@ -86,8 +90,6 @@ export default class WorkflowHistoryFetcher { emit(currentState); } - // remove current listener (if exists) and add new one - this.unsubscribe?.(); this.unsubscribe = this.observer.subscribe((res) => emit(res)); } From fb1f87ca1e5f08a1197d3a042c5fb4ea2b17592a Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 10:47:43 +0000 Subject: [PATCH 05/13] update todo --- src/views/workflow-history/workflow-history.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/workflow-history/workflow-history.tsx b/src/views/workflow-history/workflow-history.tsx index 867711826..571ed112c 100644 --- a/src/views/workflow-history/workflow-history.tsx +++ b/src/views/workflow-history/workflow-history.tsx @@ -73,7 +73,7 @@ export default function WorkflowHistory({ params }: Props) { pageSize: wfHistoryRequestArgs.pageSize, waitForNewEvent: wfHistoryRequestArgs.waitForNewEvent, }, - //TODO replace this with grouper callback + //TODO: @assem.hafez replace this with grouper callback () => {}, 2000 ); From 650a918bb252317f8ae963fc3f27e88a166621d2 Mon Sep 17 00:00:00 2001 From: Assem Hafez <137278762+Assem-Uber@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:45:48 +0100 Subject: [PATCH 06/13] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../helpers/__tests__/workflow-history-fetcher.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx index 23ab86ed2..0858d0caf 100644 --- a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx @@ -368,7 +368,7 @@ function mockHistoryEndpoint( // Map page number to response index (0-indexed) const responseIndex = pageNumber - 1; - const response = responses[responseIndex]; + const response = responses[responseIndex] || responses[responses.length - 1]; return HttpResponse.json(response); }, }, From a9e94696aa2a7d7ad47ad906b1d11cd376e6648b Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 14:25:43 +0100 Subject: [PATCH 07/13] fix copilot comments --- .../hooks/use-workflow-history-fetcher.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts index 3609e3bbf..ae36a866c 100644 --- a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts +++ b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts @@ -45,12 +45,16 @@ export default function useWorkflowHistoryFetcher( useEffect(() => { if (!fetcherRef.current) return; - + let lastFlattenedPagesCount: number = 0; const unsubscribe = fetcherRef.current.onChange((state) => { const pagesCount = state.data?.pages?.length || 0; - onEventsChange( - state.data?.pages?.flatMap((page) => page.history?.events || []) || [] - ); + // if the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback + if (pagesCount > lastFlattenedPagesCount) { + lastFlattenedPagesCount = pagesCount; + onEventsChange( + state.data?.pages?.flatMap((page) => page.history?.events || []) || [] + ); + } // immediately set if there is the first page without throttling other wise throttle const executeImmediately = pagesCount <= 1; setHistoryQuery(() => state, executeImmediately); @@ -62,8 +66,6 @@ export default function useWorkflowHistoryFetcher( }, [setHistoryQuery, onEventsChange]); useEffect(() => { - if (!fetcherRef.current) return; - return () => { fetcherRef.current?.destroy(); }; From 8dcf01c6b145d717775b5144e183bc31b1c9adb6 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 14:27:18 +0100 Subject: [PATCH 08/13] remove extra comment --- src/views/workflow-history/__tests__/workflow-history.test.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/views/workflow-history/__tests__/workflow-history.test.tsx b/src/views/workflow-history/__tests__/workflow-history.test.tsx index 3a7a63400..8109f4aad 100644 --- a/src/views/workflow-history/__tests__/workflow-history.test.tsx +++ b/src/views/workflow-history/__tests__/workflow-history.test.tsx @@ -29,7 +29,6 @@ jest.mock('@/hooks/use-page-query-params/use-page-query-params', () => ); // Mock the hook to use minimal throttle delay for faster tests -// Mock the hooks to use minimal throttle delay for faster tests jest.mock('../hooks/use-workflow-history-fetcher', () => { const actual = jest.requireActual('../hooks/use-workflow-history-fetcher'); return { From 573c1951ed218691e642b7bb04c34c2d8791df05 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 13:30:22 +0000 Subject: [PATCH 09/13] lint fix --- .../helpers/__tests__/workflow-history-fetcher.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx index 0858d0caf..7c0f89c91 100644 --- a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx @@ -368,7 +368,8 @@ function mockHistoryEndpoint( // Map page number to response index (0-indexed) const responseIndex = pageNumber - 1; - const response = responses[responseIndex] || responses[responses.length - 1]; + const response = + responses[responseIndex] || responses[responses.length - 1]; return HttpResponse.json(response); }, }, From 730666333bf93d31583f8897d674e738e3602199 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 13:33:41 +0000 Subject: [PATCH 10/13] change lastFlattented initial value to -1 --- .../workflow-history/hooks/use-workflow-history-fetcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts index ae36a866c..6ced9b164 100644 --- a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts +++ b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts @@ -45,7 +45,7 @@ export default function useWorkflowHistoryFetcher( useEffect(() => { if (!fetcherRef.current) return; - let lastFlattenedPagesCount: number = 0; + let lastFlattenedPagesCount: number = -1; const unsubscribe = fetcherRef.current.onChange((state) => { const pagesCount = state.data?.pages?.length || 0; // if the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback From 73e9bd8661634745e66a552733af05849a5677ef Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Thu, 20 Nov 2025 22:22:38 +0000 Subject: [PATCH 11/13] move lastFlattenedPagesCount to a ref and remove shouldContinue condition --- .../workflow-history/helpers/workflow-history-fetcher.ts | 4 +--- .../hooks/use-workflow-history-fetcher.ts | 9 +++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/views/workflow-history/helpers/workflow-history-fetcher.ts b/src/views/workflow-history/helpers/workflow-history-fetcher.ts index 9141698b9..d05f4d63f 100644 --- a/src/views/workflow-history/helpers/workflow-history-fetcher.ts +++ b/src/views/workflow-history/helpers/workflow-history-fetcher.ts @@ -46,9 +46,7 @@ export default class WorkflowHistoryFetcher { } start(shouldContinue: ShouldContinueCallback = () => true): void { - if (shouldContinue) { - this.shouldContinue = shouldContinue; - } + this.shouldContinue = shouldContinue; // remove current listener (if exists) to have fresh emits only this.unsubscribe?.(); diff --git a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts index 6ced9b164..5e1cfed80 100644 --- a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts +++ b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts @@ -25,6 +25,7 @@ export default function useWorkflowHistoryFetcher( ) { const queryClient = useQueryClient(); const fetcherRef = useRef(null); + const lastFlattenedPagesCountRef = useRef(-1); if (!fetcherRef.current) { fetcherRef.current = new WorkflowHistoryFetcher(queryClient, params); @@ -45,12 +46,12 @@ export default function useWorkflowHistoryFetcher( useEffect(() => { if (!fetcherRef.current) return; - let lastFlattenedPagesCount: number = -1; const unsubscribe = fetcherRef.current.onChange((state) => { const pagesCount = state.data?.pages?.length || 0; - // if the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback - if (pagesCount > lastFlattenedPagesCount) { - lastFlattenedPagesCount = pagesCount; + // If the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback + // Depending on ref variable instead of historyQueue is because historyQueue is throttled. + if (pagesCount > lastFlattenedPagesCountRef.current) { + lastFlattenedPagesCountRef.current = pagesCount; onEventsChange( state.data?.pages?.flatMap((page) => page.history?.events || []) || [] ); From f8e080db8dfde686ed21dcf9a3fe7df44fc76006 Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Fri, 21 Nov 2025 12:28:25 +0000 Subject: [PATCH 12/13] fix typo and add mock for configs --- .../helpers/__tests__/workflow-history-fetcher.test.tsx | 9 +++++++++ .../hooks/use-workflow-history-fetcher.ts | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx index 7c0f89c91..311b99574 100644 --- a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx @@ -15,6 +15,15 @@ const RETRY_COUNT = 3; let queryClient: QueryClient; let hoistedFetcher: WorkflowHistoryFetcher; +jest.mock( + '@/views/workflow-history/config/workflow-history-page-size.config', + () => ({ + __esModule: true, + WORKFLOW_HISTORY_FIRST_PAGE_SIZE_CONFIG: 200, + WORKFLOW_HISTORY_PAGE_SIZE_CONFIG: 1000, + }) +); + describe(WorkflowHistoryFetcher.name, () => { beforeEach(() => { queryClient = new QueryClient({ diff --git a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts index 5e1cfed80..94921e7f4 100644 --- a/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts +++ b/src/views/workflow-history/hooks/use-workflow-history-fetcher.ts @@ -49,7 +49,7 @@ export default function useWorkflowHistoryFetcher( const unsubscribe = fetcherRef.current.onChange((state) => { const pagesCount = state.data?.pages?.length || 0; // If the pages count is greater than the last flattened pages count, then we need to flatten the pages and call the onEventsChange callback - // Depending on ref variable instead of historyQueue is because historyQueue is throttled. + // Depending on ref variable instead of historyQuery is because historyQuery is throttled. if (pagesCount > lastFlattenedPagesCountRef.current) { lastFlattenedPagesCountRef.current = pagesCount; onEventsChange( From d9da99f53712f1ef6b255c903c69043d4819232d Mon Sep 17 00:00:00 2001 From: Assem Hafez Date: Fri, 21 Nov 2025 12:32:42 +0000 Subject: [PATCH 13/13] update page size test case --- .../helpers/__tests__/workflow-history-fetcher.test.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx index 311b99574..f997bcc31 100644 --- a/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx +++ b/src/views/workflow-history/helpers/__tests__/workflow-history-fetcher.test.tsx @@ -283,24 +283,22 @@ describe(WorkflowHistoryFetcher.name, () => { }); const pageSizes = getCapturedPageSizes(); - expect(pageSizes).toHaveLength(1); expect(pageSizes[0]).toBe('200'); }); it('should use WORKFLOW_HISTORY_PAGE_SIZE_CONFIG for subsequent pages', async () => { const { fetcher, getCapturedPageSizes } = setup(queryClient); - fetcher.start((state) => (state.data?.pages.length || 0) < 2); + fetcher.start((state) => (state.data?.pages.length || 0) < 3); await waitFor(() => { const state = fetcher.getCurrentState(); - expect(state.data?.pages).toHaveLength(2); + expect(state.data?.pages).toHaveLength(3); }); const pageSizes = getCapturedPageSizes(); - expect(pageSizes.length).toBeGreaterThanOrEqual(2); - expect(pageSizes[0]).toBe('200'); expect(pageSizes[1]).toBe('1000'); + expect(pageSizes[2]).toBe('1000'); }); });