Root location folds away once there is nothing left to do
Everything under it is in order most of the time, and a card that is four paragraphs of "fine" pushes the settings that are not fine off the screen. So it shuts, with a check on the right, and opens on a click. "Finished" is three bits reported upward by the parts that own them: the path is saved, the checkout is a repository, and media/ both exists and is current. None of those is knowable in the parent — each child fetches its own status — and lifting all of it up to answer one question would be a far worse trade than three booleans. It is only collapsible while settled. A block you can shut on unfinished setup is a way to hide the thing you came here to fix. And the children are NOT RENDERED while it is shut rather than hidden, because a collapsed block whose children still poll is a settled panel making requests all afternoon about something nobody is looking at. The `null` in `collapsed` is a sentinel for "nobody has decided", which is what lets a deliberate expand survive. Setting it to false while unsettled spent it on the first render — before any status had arrived — so the block could never fold itself away at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -86,7 +86,7 @@ const took = (from: string, to: string) => {
|
||||
return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
||||
};
|
||||
|
||||
export const MediaSync = () => {
|
||||
export const MediaSync = ({ onSettled }: { onSettled?: (settled: boolean) => void }) => {
|
||||
const client = useClient();
|
||||
const clientRef = useRef(client);
|
||||
clientRef.current = client;
|
||||
@@ -164,6 +164,17 @@ export const MediaSync = () => {
|
||||
const reconciliation = ledger?.reconciliation ?? null;
|
||||
const outstanding = (reconciliation?.missing.length ?? 0) + (reconciliation?.stale.length ?? 0);
|
||||
|
||||
/*
|
||||
One bit, upward: is there anything left to do?
|
||||
|
||||
Reported rather than lifted, because everything else about this — the polling, the run history, the
|
||||
errors — belongs here and would only be harder to read in a parent. What the parent needs is the
|
||||
single fact it cannot compute: whether this part of the setup is finished.
|
||||
*/
|
||||
useEffect(() => {
|
||||
if (reconciliation) onSettled?.(outstanding === 0);
|
||||
}, [reconciliation, outstanding, onSettled]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 pt-1">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
|
||||
Reference in New Issue
Block a user