[eric] canvas: new app cards anchor on the nearest on-canvas ancestor and docked rects stop being invisible obstacles (ENG-346)

This commit is contained in:
ciregenz
2026-08-18 19:04:56 -07:00
parent 82a9860eaa
commit 201216d166
2 changed files with 14 additions and 2 deletions
@@ -370,13 +370,22 @@ export function useDashboardLifecycle({
if (sess.dashboard_id !== dashboardId) continue;
autoOpenedOutputsRef.current.add(output.id);
if (viewCards[output.id]) continue;
dispatch(addViewCard({ outputId: output.id, expandedSessionIds, parentSessionId: sid }));
// A sub-agent has no canvas card, so anchoring on it dumped the app at a far grid cell; walk up to the nearest ancestor that IS on the canvas (ENG-346).
const layoutCards = store.getState().dashboardLayout.cards;
let anchorSid: string = sid;
for (let hops = 0; hops < 5 && !layoutCards[anchorSid]; hops += 1) {
const up = sessions[anchorSid]?.parent_session_id;
if (!up || !sessions[up]) break;
anchorSid = up;
}
if (!layoutCards[anchorSid]) anchorSid = sid;
dispatch(addViewCard({ outputId: output.id, expandedSessionIds, parentSessionId: anchorSid }));
const outputId = output.id;
setTimeout(() => {
const vc = store.getState().dashboardLayout.viewCards[outputId];
if (!vc) return;
const rects = [{ x: vc.x, y: vc.y, width: vc.width, height: vc.height }];
const ac = store.getState().dashboardLayout.cards[sid];
const ac = store.getState().dashboardLayout.cards[anchorSid];
if (ac) rects.push({ x: ac.x, y: ac.y, width: ac.width, height: ac.height });
canvasActions.revealCards(rects);
handleHighlightCard(outputId);
@@ -418,10 +418,13 @@ function collectOccupiedRects(
}
for (const c of Object.values(state.viewCards)) {
if (exclude?.type === 'view' && exclude.id === c.output_id) continue;
// Docked cards render inside a chat; their stored canvas rect is an invisible obstacle that flings new placements far away (ENG-346).
if (c.docked_to) continue;
rects.push({ x: c.x, y: c.y, w: c.width, h: c.height });
}
for (const c of Object.values(state.browserCards)) {
if (exclude?.type === 'browser' && exclude.id === c.browser_id) continue;
if (c.docked_to) continue;
rects.push({ x: c.x, y: c.y, w: c.width, h: c.height });
}
for (const w of Object.values(state.workflowCards)) {