forked from molecule-ai/molecule-core
fix(canvas,org): collapse org-imported parents on first paint
Importing a 15-workspace org template dropped every child as a freely-positioned card into its parent's coordinate space. Parents with 5-10 kids had the kids spill below the parent's initial min size, producing the "ugly default" layout the user just flagged — a mess of overlapping cards the moment the import completed. Fix: every workspace in an org-template import that HAS children is inserted with `collapsed = true`. Leaf workspaces stay expanded (nothing to hide). The canvas renders a collapsed parent as a compact header-only card with its "N sub" badge — visually identical to the pre-refactor default the user asked for. Double-click on a collapsed parent now EXPANDS it (flipping `collapsed` locally + persisting via PATCH) so the user can drill in to see the subtree. Only once expanded does a second double-click zoom-to-team, matching the prior behaviour. Leaf-first creation order stays the same; the collapsed flag just means "render compact" not "hide from API". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
507696d88a
commit
286dcbfd1e
@ -81,9 +81,23 @@ export function WorkspaceNode({ id, data }: NodeProps<Node<WorkspaceNodeData>>)
|
||||
}}
|
||||
onDoubleClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (hasChildren) {
|
||||
window.dispatchEvent(new CustomEvent("molecule:zoom-to-team", { detail: { nodeId: id } }));
|
||||
if (!hasChildren) return;
|
||||
// A collapsed parent double-click EXPANDS first (flipping the
|
||||
// collapsed flag + persisting it via the API). Once expanded,
|
||||
// subsequent double-clicks zoom-to-team so the user can see
|
||||
// the hierarchy fit in the viewport. Matches the user's ask:
|
||||
// default-collapsed for clean first paint, one gesture reveals
|
||||
// the subtree.
|
||||
if (data.collapsed) {
|
||||
const state = useCanvasStore.getState();
|
||||
state.setCollapsed(id, false);
|
||||
// Fire-and-forget persist so reload retains the expansion.
|
||||
import("@/lib/api").then(({ api }) => {
|
||||
api.patch(`/workspaces/${id}`, { collapsed: false }).catch(() => {});
|
||||
});
|
||||
return;
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent("molecule:zoom-to-team", { detail: { nodeId: id } }));
|
||||
}}
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
@ -88,11 +88,19 @@ func (h *OrgHandler) createWorkspaceTree(ws OrgWorkspace, parentID *string, defa
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Insert workspace
|
||||
// Org-template imports can drop dozens of nested workspaces onto the
|
||||
// canvas at once. Letting them render expanded by default sprays
|
||||
// child cards across the viewport (sibling workspaces spill below
|
||||
// the parent before the user can orient themselves). Default every
|
||||
// parent in the imported tree to collapsed — the parent card shows
|
||||
// only its header + "N sub" badge until the user double-clicks to
|
||||
// expand it. Leaf workspaces stay expanded (nothing to hide).
|
||||
initialCollapsed := len(ws.Children) > 0
|
||||
|
||||
_, err := db.DB.ExecContext(ctx, `
|
||||
INSERT INTO workspaces (id, name, role, tier, runtime, awareness_namespace, status, parent_id, workspace_dir, workspace_access)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
`, id, ws.Name, role, tier, runtime, awarenessNS, "provisioning", parentID, workspaceDir, workspaceAccess)
|
||||
INSERT INTO workspaces (id, name, role, tier, runtime, awareness_namespace, status, parent_id, workspace_dir, workspace_access, collapsed)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
`, id, ws.Name, role, tier, runtime, awarenessNS, "provisioning", parentID, workspaceDir, workspaceAccess, initialCollapsed)
|
||||
if err != nil {
|
||||
log.Printf("Org import: failed to create %s: %v", ws.Name, err)
|
||||
return fmt.Errorf("failed to create %s: %w", ws.Name, err)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user