import { LayoutTemplate } from "lucide-react";
import { toast } from "sonner";
import type { PanelProps, TermixApp } from "@termix/plugin-sdk/frontend";
import { WorkspacesPanel } from "./WorkspacesPanel";
import { createWorkspacesApi } from "./workspaces-api";
import type { Workspace } from "./types";
const LAST_SESSION_DELAY_MS = 2000;
export function activate(app: TermixApp): void {
const api = createWorkspacesApi(app.api);
const applyWorkspace = async (workspace: Workspace) => {
const { skipped } = await app.tabs.applyLayout(workspace.payload, {
name: workspace.name,
});
if (skipped.length > 0) {
toast.warning(
app.t("newUi.sidebar.workspaces.tabsSkipped", {
count: skipped.length,
names: skipped.join(", "),
}),
);
}
api.apply(workspace.id).catch(() => {});
};
function Panel({ active }: PanelProps) {
return (
app.tabs.getLayout()}
onApplyWorkspace={(workspace) => void applyWorkspace(workspace)}
/>
);
}
app.registerRailItem({
id: "workspaces",
icon: LayoutTemplate,
titleKey: "nav.workspaces",
after: "macros",
permission: "use",
});
app.registerPanel("workspaces", Panel);
// Without workspaces.use the restore and the autosave below would only
// collect 403s. The lookup is cached, so asking each time is cheap and a
// revoke takes effect.
const allowed = () => app.hasPermission("use");
// After login, a default workspace applies unless the session already
// brought tabs back, which is the more precise restore.
app.tabs.onReady(() => {
const layout = app.tabs.getLayout() as { tabs?: unknown[] } | null;
if (layout && (layout.tabs?.length ?? 0) > 0) return;
void allowed().then(async (ok) => {
if (!ok) return;
try {
const workspaces = await api.list();
const preferred = workspaces.find(
(workspace) => workspace.kind === "manual" && workspace.isDefault,
);
if (preferred) await applyWorkspace(preferred);
} catch {
// A failed restore leaves the empty session as it is.
}
});
});
// Keeps an implicit "last session" snapshot current, so an arrangement can
// always be recovered even if it was never saved.
let timer: ReturnType | null = null;
app.tabs.onChange(() => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
const layout = app.tabs.getLayout();
if (!layout) return;
void allowed().then((ok) => {
if (ok) api.saveLastSession(layout).catch(() => {});
});
}, LAST_SESSION_DELAY_MS);
});
app.onDispose(() => {
if (timer) clearTimeout(timer);
});
app.registerSlotContribution("onboarding.workflow", {
actionId: "workspaces.tip",
titleKey: "onboarding.workflow_workspaces",
descriptionKey: "onboarding.workflow_workspaces_desc",
icon: LayoutTemplate,
});
}