Skip to content

Commit 310d459

Browse files
committed
fix(webapp): stabilize time-sensitive UI renders
1 parent d1fc356 commit 310d459

3 files changed

Lines changed: 27 additions & 18 deletions

File tree

apps/webapp/app/components/dashboard-agent/DashboardAgentHeader.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function DashboardAgentHeader({
4949
onClose: () => void;
5050
}) {
5151
const [isHistoryOpen, setHistoryOpen] = useState(false);
52+
const [historyOpenedAt, setHistoryOpenedAt] = useState<number | null>(null);
5253
const [pendingDelete, setPendingDelete] = useState<DashboardAgentChat | null>(null);
5354

5455
return (
@@ -57,7 +58,10 @@ export function DashboardAgentHeader({
5758
open={isHistoryOpen}
5859
onOpenChange={(open) => {
5960
setHistoryOpen(open);
60-
if (open) onOpenHistory();
61+
if (open) {
62+
setHistoryOpenedAt(Date.now());
63+
onOpenHistory();
64+
}
6165
}}
6266
>
6367
<PopoverArrowTrigger
@@ -74,19 +78,22 @@ export function DashboardAgentHeader({
7478
className="w-72 max-w-(--radix-popover-content-available-width) p-0"
7579
align="start"
7680
>
77-
<DashboardAgentHistoryMenu
78-
chats={chats}
79-
currentChatId={currentChatId}
80-
thinkingChatId={thinkingChatId}
81-
onSelect={(chatId) => {
82-
setHistoryOpen(false);
83-
onSelectChat(chatId);
84-
}}
85-
onRequestDelete={(chat) => {
86-
setHistoryOpen(false);
87-
setPendingDelete(chat);
88-
}}
89-
/>
81+
{historyOpenedAt === null ? null : (
82+
<DashboardAgentHistoryMenu
83+
chats={chats}
84+
currentChatId={currentChatId}
85+
thinkingChatId={thinkingChatId}
86+
now={historyOpenedAt}
87+
onSelect={(chatId) => {
88+
setHistoryOpen(false);
89+
onSelectChat(chatId);
90+
}}
91+
onRequestDelete={(chat) => {
92+
setHistoryOpen(false);
93+
setPendingDelete(chat);
94+
}}
95+
/>
96+
)}
9097
</PopoverContent>
9198
</Popover>
9299

apps/webapp/app/components/dashboard-agent/DashboardAgentHistory.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,17 @@ export function DashboardAgentHistoryMenu({
8080
chats,
8181
currentChatId,
8282
thinkingChatId,
83+
now,
8384
onSelect,
8485
onRequestDelete,
8586
}: {
8687
chats: DashboardAgentChat[];
8788
currentChatId: string;
8889
thinkingChatId?: string | null;
90+
now: number;
8991
onSelect: (chatId: string) => void;
9092
onRequestDelete: (chat: DashboardAgentChat) => void;
9193
}) {
92-
const now = Date.now();
93-
9494
return (
9595
<div className="max-h-80 overflow-y-auto p-1.5 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
9696
{chats.length === 0 ? (

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,9 @@ function CompleteDateTimeWaitpointForm({
252252
const project = useProject();
253253
const environment = useEnvironment();
254254

255-
const timeToComplete = waitpoint.completedAfter.getTime() - Date.now();
255+
// oxlint-disable-next-line react/react-compiler -- This form intentionally snapshots wall-clock time for its deadline UI.
256+
const now = Date.now();
257+
const timeToComplete = waitpoint.completedAfter.getTime() - now;
256258
if (timeToComplete < 0) {
257259
return (
258260
<div className="flex items-center justify-center">
@@ -286,7 +288,7 @@ function CompleteDateTimeWaitpointForm({
286288
<div className="flex items-center gap-1">
287289
<AnimatedHourglassIcon
288290
className="text-dimmed-dimmed size-4"
289-
delay={(waitpoint.completedAfter.getMilliseconds() - Date.now()) / 1000}
291+
delay={(waitpoint.completedAfter.getMilliseconds() - now) / 1000}
290292
/>
291293
<span className="mt-0.5 ">
292294
<LiveCountdown endTime={waitpoint.completedAfter} />

0 commit comments

Comments
 (0)