diff --git a/artifacts/tx-os/src/pages/executive-meetings.tsx b/artifacts/tx-os/src/pages/executive-meetings.tsx index 93456a9d..5304b093 100644 --- a/artifacts/tx-os/src/pages/executive-meetings.tsx +++ b/artifacts/tx-os/src/pages/executive-meetings.tsx @@ -2146,6 +2146,7 @@ function ScheduleSection({ // never in `orderedMeetings`, so they keep their existing tuple. const queryKey = ["/api/executive-meetings", date] as const; const previous = qc.getQueryData(queryKey); + const previousOptimisticOrder = optimisticOrder; const slotById = new Map(); newOrder.forEach((id, i) => { const slotMeeting = orderedMeetings[i]; @@ -2173,6 +2174,12 @@ function ScheduleSection({ } : prev, ); + // #489: also drive the rendered row order so slot[i] visually + // shows newOrder[i]. Without this, the array order in cache + // remains the pre-drag order and times appear rotated against + // the wrong row content (e.g. 11:00, 09:00, 10:00). Cleared on + // refetch by the useEffect on `meetings`. + setOptimisticOrder(newOrder); const expectedUpdatedAt: Record = {}; for (const m of orderedMeetings) { expectedUpdatedAt[String(m.id)] = m.updatedAt; @@ -2193,6 +2200,9 @@ function ScheduleSection({ if (previous !== undefined) { qc.setQueryData(queryKey, previous); } + // #489: restore the prior optimistic order on rollback so a + // failed rotate doesn't leave the UI in the post-drop order. + setOptimisticOrder(previousOptimisticOrder); const msg = err instanceof Error ? err.message : String(err); toast({ title: t("common.error"), @@ -2204,7 +2214,7 @@ function ScheduleSection({ setReordering(false); } }, - [orderedMeetings, date, qc, refreshDay, toast, t], + [orderedMeetings, optimisticOrder, date, qc, refreshDay, toast, t], ); // #486 → #489: Move up / Move down were retired in favour of