Skip to content

Commit 6571201

Browse files
committed
Fix for task page search bar re-rendering bug
1 parent afe6dd9 commit 6571201

2 files changed

Lines changed: 24 additions & 23 deletions

File tree

  • apps/webapp/app
    • components/primitives
    • routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index

apps/webapp/app/components/primitives/SearchInput.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,22 @@ export function SearchInput({
4747
const [text, setText] = useState(initialSearch);
4848
const [isFocused, setIsFocused] = useState(false);
4949

50+
// Compare against a ref, not `text`, so the effect stays off the keystroke path.
51+
const lastSyncedRef = useRef(initialSearch);
52+
5053
useEffect(() => {
5154
if (isControlled) {
52-
if (controlledValue !== undefined && controlledValue !== text) {
55+
if (controlledValue !== undefined && controlledValue !== lastSyncedRef.current) {
56+
lastSyncedRef.current = controlledValue;
5357
setText(controlledValue);
5458
}
5559
return;
5660
}
5761
const urlSearch = value(paramName) ?? "";
58-
if (urlSearch !== text && !isFocused) {
59-
setText(urlSearch);
60-
}
61-
}, [isControlled, controlledValue, value, text, isFocused, paramName]);
62+
if (urlSearch === lastSyncedRef.current) return;
63+
lastSyncedRef.current = urlSearch;
64+
if (!isFocused) setText(urlSearch);
65+
}, [isControlled, controlledValue, value, isFocused, paramName]);
6266

6367
const updateText = (next: string) => {
6468
setText(next);

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export default function Page() {
193193
}, [streamedEvents]); // eslint-disable-line react-hooks/exhaustive-deps
194194

195195
const [showUsefulLinks, setShowUsefulLinks] = useState(usefulLinksPreference ?? true);
196-
// Unmount the charts while the side panel animates; 25 SVGs in a reflowing table tanks perf.
196+
// Hide (don't unmount) the charts during the panel animation; 25 reflowing SVGs tank the resize.
197197
const [isPanelAnimating, setIsPanelAnimating] = useState(false);
198198
const animatingTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
199199
const usefulLinksPanelRef = useRef<PanelHandle>(null);
@@ -436,24 +436,21 @@ function TaskRow({
436436
</Suspense>
437437
</TableCell>
438438
<TableCell to={rowPath} actionClassName="py-1.5">
439-
{/* Reserve the cell footprint while the chart unmounts during the panel animation. */}
440439
<div style={{ width: ACTIVITY_CELL_WIDTH, height: ACTIVITY_CHART_HEIGHT }}>
441-
{!isPanelAnimating && (
442-
<div className="duration-100 animate-in fade-in">
443-
<Suspense fallback={<TaskActivityBlankState />}>
444-
<TypedAwait resolve={hourlyActivity} errorElement={<FailedToLoadStats />}>
445-
{(data) => {
446-
const taskData = data[item.slug];
447-
return taskData && taskData.length > 0 ? (
448-
<TaskActivityGraph activity={taskData} />
449-
) : (
450-
<TaskActivityBlankState />
451-
);
452-
}}
453-
</TypedAwait>
454-
</Suspense>
455-
</div>
456-
)}
440+
<div hidden={isPanelAnimating}>
441+
<Suspense fallback={<TaskActivityBlankState />}>
442+
<TypedAwait resolve={hourlyActivity} errorElement={<FailedToLoadStats />}>
443+
{(data) => {
444+
const taskData = data[item.slug];
445+
return taskData && taskData.length > 0 ? (
446+
<TaskActivityGraph activity={taskData} />
447+
) : (
448+
<TaskActivityBlankState />
449+
);
450+
}}
451+
</TypedAwait>
452+
</Suspense>
453+
</div>
457454
</div>
458455
</TableCell>
459456
<TableCellMenu

0 commit comments

Comments
 (0)