import type { DecisionView, ResearchOpener } from "@chopin/editor"; export type WorkspaceMode = "compact" | "split"; export type WorkspaceSurface = "document" | "child"; export type WorkspacePresentation = | { type: "document" } | { childLabel: string; onChildClose: () => void; type: "parent-with-child" } | { label: string; onClose: () => void; parent?: ChildParent; type: "child" }; /** The document a child opened from, and a way back to the place that produced it. */ export type ChildParent = { id: string; label: string; onReturn: (opener?: ResearchOpener) => void; }; export type WorkspaceProfile = { implementation: boolean; persistChat: boolean; persistPaneSize: boolean; persistView: boolean; research: boolean; surface: WorkspaceSurface; }; export type WorkspaceDestination = "plan" | "decisions" | "chat"; export type WorkspaceState = { chatOpen: boolean; /** Undefined until a person makes an explicit choice. */ desktopChatOpen: boolean | undefined; }; export type WorkspaceEvent = | { type: "set-chat"; open: boolean } | { type: "set-desktop-chat"; open: boolean }; export const CHAT_CHOICE_STORAGE_KEY = "chopin:pane:chat:choice"; export function storedDesktopChat(value: string | null): boolean | undefined { if (value === "true") return true; if (value === "false") return false; } export function initialWorkspaceState( desktopChatOpen: boolean | undefined, ): WorkspaceState { return { chatOpen: false, desktopChatOpen, }; } export function initialDocumentView( profile: WorkspaceProfile, stored: string | null, ): DecisionView { return profile.persistView ? storedDocumentView(stored) : "plan"; } export function workspaceProfile( presentation: WorkspacePresentation, ): WorkspaceProfile { let child = presentation.type === "child"; return { implementation: !child, persistChat: !child, persistPaneSize: !child, persistView: !child, research: !child, surface: child ? "child" : "document", }; } export function workspaceDestinations(): WorkspaceDestination[] { return ["chat", "plan", "decisions"]; } export function workspaceHeadingId(destination: WorkspaceDestination, scope?: string): string { return `${scope ? `${scope}-` : ""}workspace-${destination}-heading`; } export function storedDocumentView(value: string | null): DecisionView { if (value === "decisions") return value; return "plan"; } export function transitionWorkspace(state: WorkspaceState, event: WorkspaceEvent): WorkspaceState { if (event.type === "set-chat") return { ...state, chatOpen: event.open }; return { ...state, desktopChatOpen: event.open }; } export function presentWorkspace( state: WorkspaceState, mode: WorkspaceMode, documentView: DecisionView, ) { let chatVisible = mode === "split" ? (state.desktopChatOpen ?? true) || state.chatOpen : state.chatOpen; let documentVisible = mode === "compact" ? !chatVisible : true; return { documentView, documentVisible, chatVisible, separatorVisible: mode === "split" && chatVisible, }; }