From 64805ae1a2b16ecbe5fd04961ab93e8f9971dfa2 Mon Sep 17 00:00:00 2001 From: Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com> Date: Thu, 30 Jan 2025 17:04:08 +0100 Subject: [PATCH] fix(ui): properly debounce/abort logs search (#3412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes Fixes https://linear.app/nango/issue/NAN-2629/date-filter-issue-when-selecting-past-dates ![Screenshot 2025-01-30 at 14 41 03](https://github.com/user-attachments/assets/4d23fea7-712b-4d25-a14d-fb5dbfe27e10) - Properly debounce/abort logs search When you start selecting a day in the date picker it triggers an initial search that would be done by the time you finished picking the end day of your date range. Which then triggered a second query but with the previous invalid data not being removed. I had bad cancellation/concurrency strategies: - with the `isLoading` debounce which was not triggering some search = not aborting and not fetching - the signal was passed as reference which could be replaced by another signal controller before being checked ## 🧪 Tests - Go to UI - Pick a first day, try to wait 100-200ms before clicking another day (it's not that simple though) - At the end you should have proper data e.g: have the last 2 days picked, start clicking Jan 22, wait, then click Jan 23 as the end day. You should not see Jan 30 as the last operation --- packages/webapp/src/hooks/useLogs.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/webapp/src/hooks/useLogs.tsx b/packages/webapp/src/hooks/useLogs.tsx index 793c6fff08c..7aa52fa24bf 100644 --- a/packages/webapp/src/hooks/useLogs.tsx +++ b/packages/webapp/src/hooks/useLogs.tsx @@ -17,7 +17,9 @@ export function useSearchOperations(env: string, body: SearchOperations['Body'], } setLoading(true); - signal.current = new AbortController(); + const mySignal = new AbortController(); + mySignal.signal.throwIfAborted(); + signal.current = mySignal; try { let period = body.period; // Slide the window automatically when live @@ -30,7 +32,7 @@ export function useSearchOperations(env: string, body: SearchOperations['Body'], const res = await apiFetch(`/api/v1/logs/operations?env=${env}`, { method: 'POST', body: JSON.stringify({ ...body, period, cursor }), - signal: signal.current.signal + signal: mySignal.signal }); if (res.status !== 200) { return { error: (await res.json()) as SearchOperations['Errors'] }; @@ -70,9 +72,7 @@ export function useSearchOperations(env: string, body: SearchOperations['Body'], // }, [enabled, env, body.limit, body.states, body.integrations, body.period, body.types, body.connections, body.syncs]); function trigger(cursor?: SearchOperations['Body']['cursor']) { - if (!loading) { - void fetchData(cursor); - } + void fetchData(cursor); } return { data, error, loading, trigger, manualFetch };