Files
kandev/apps/web/lib/state/layout-manager/intent.ts
T
José Almeida b4ce4d6eef refactor(web): improve compact desktop layouts (#937)
* refactor(web): improve compact desktop layouts

* fix(web): address compact desktop review feedback

* fix(web): address responsive review followups

* fix(web): preserve compact sidebar restore sizing

* fix(web): harden compact preset sidebar test

* refactor(web): extract dockview layout hooks
2026-05-18 23:08:14 +01:00

92 lines
3.0 KiB
TypeScript

import type { LayoutState, LayoutIntent, LayoutIntentPanel, LayoutPanel } from "./types";
import { CENTER_GROUP, RIGHT_TOP_GROUP, RIGHT_BOTTOM_GROUP } from "./constants";
/** Well-known intent name constants (used as URL ?layout= values). */
export const INTENT_COMPACT = "compact";
export const INTENT_PLAN = "plan";
export const INTENT_PR_REVIEW = "pr-review";
/** Registry of named layout intents, keyed by URL param value. */
const NAMED_INTENTS: Record<string, LayoutIntent> = {
[INTENT_COMPACT]: { preset: "compact" },
[INTENT_PLAN]: { preset: "plan" },
[INTENT_PR_REVIEW]: {
panels: [
{
id: "pr-detail",
component: "pr-detail",
title: "Pull Request",
targetGroup: "center",
},
],
activePanels: {
[CENTER_GROUP]: "pr-detail",
[RIGHT_TOP_GROUP]: "changes",
},
},
};
/** Resolve a named intent string (from URL param) to a LayoutIntent, or null if unknown. */
export function resolveNamedIntent(name: string): LayoutIntent | null {
return NAMED_INTENTS[name] ?? null;
}
/** Map short aliases to well-known group IDs. */
const GROUP_ALIASES: Record<string, string> = {
center: CENTER_GROUP,
"right-top": RIGHT_TOP_GROUP,
"right-bottom": RIGHT_BOTTOM_GROUP,
};
function resolveGroupId(target: string): string {
return GROUP_ALIASES[target] ?? target;
}
/** Inject LayoutIntentPanels into the matching groups of a LayoutState. */
export function injectIntentPanels(state: LayoutState, panels: LayoutIntentPanel[]): LayoutState {
const columns = state.columns.map((col) => {
const groups = col.groups.map((group) => {
const matching = panels.filter((p) => {
const targetId = resolveGroupId(p.targetGroup ?? "center");
if (group.id === targetId) return true;
// Fallback: match center column's first group when no explicit group ID
if (targetId === CENTER_GROUP && col.id === "center" && col.groups[0] === group) {
return true;
}
return false;
});
if (matching.length === 0) return group;
const newPanels: LayoutPanel[] = matching.map((p) => ({
id: p.id,
component: p.component,
title: p.title,
...(p.tabComponent ? { tabComponent: p.tabComponent } : {}),
...(p.params ? { params: p.params } : {}),
}));
return { ...group, panels: [...group.panels, ...newPanels] };
});
return { ...col, groups };
});
return { columns };
}
/** Set activePanel on groups that match the override map. */
export function applyActivePanelOverrides(
state: LayoutState,
overrides: Record<string, string>,
): LayoutState {
const columns = state.columns.map((col) => {
const groups = col.groups.map((group) => {
if (!group.id || !overrides[group.id]) return group;
const targetPanelId = overrides[group.id];
if (!group.panels.some((p) => p.id === targetPanelId)) return group;
return { ...group, activePanel: targetPanelId };
});
return { ...col, groups };
});
return { columns };
}