62 lines
3.8 KiB
TypeScript
62 lines
3.8 KiB
TypeScript
import { createFailure, createSuccess, type FacadeResponse } from "./facade-envelope.js";
|
|
import type { WebModuleRouter } from "./module-router.js";
|
|
import { viewEndpoint, type ViewOwner } from "./part-view-facade.js";
|
|
|
|
export type WindowPanel = { objectName: string; title: string; visible: boolean; enabled?: boolean };
|
|
export type WindowLayout = {
|
|
windows: Array<{ documentId: string; label: string }>;
|
|
columns: number; rows: number; activeDocument: string | null;
|
|
};
|
|
export type WindowHostResult = Partial<WindowLayout> & {
|
|
command: string; documentId: string; items?: WindowPanel[]; locked?: boolean;
|
|
};
|
|
type Host = {
|
|
snapshot(): { panels: WindowPanel[]; toolbar: string };
|
|
apply(value: WindowHostResult, owner: ViewOwner): void;
|
|
};
|
|
let host: Host | undefined;
|
|
export function registerWebWindowHost(value: Host) {
|
|
host = value;
|
|
return () => { if (host === value) host = undefined; };
|
|
}
|
|
|
|
export function executeWebWindowHost(router: WebModuleRouter, command: string,
|
|
args: Record<string, unknown>, documentId: string): Promise<FacadeResponse> | undefined {
|
|
if (!["Std_DockViewMenu", "Std_TileWindows", "Std_ToggleToolBarLock"].includes(command)) return;
|
|
const mounted = host;
|
|
if (!mounted) return Promise.resolve(createFailure("desktop-Web", "window_host_unavailable", "The workbench window host is not mounted"));
|
|
const owner = args.runtimeOwner ?? "PartBox";
|
|
if (owner !== "PartBox" && owner !== "DocumentProbe")
|
|
return Promise.resolve(createFailure("desktop-Web", "wrong_document_owner", "Select the document's native runtime"));
|
|
if (!documentId.trim() || (args.documentId !== undefined && args.documentId !== documentId))
|
|
return Promise.resolve(createFailure("desktop-Web", "document_mismatch", "Command document identifiers differ"));
|
|
return router.request("Part", viewEndpoint(owner), {
|
|
schema: "freecad-web/document-view/v1", owner, document: documentId, command,
|
|
parameters: { ...args, documentId, host: mounted.snapshot() },
|
|
}, documentId).then(response => {
|
|
if (response.kind !== "result") return response;
|
|
const value = response.result as WindowHostResult;
|
|
if (!value || value.command !== command || value.documentId !== documentId)
|
|
return createFailure(response.requestId, "native_protocol_error", "Window response identity mismatch");
|
|
if (command === "Std_DockViewMenu" && (!Array.isArray(value.items)
|
|
|| value.items.some(item => !item || typeof item.objectName !== "string" || typeof item.title !== "string"
|
|
|| typeof item.visible !== "boolean" || typeof item.enabled !== "boolean")))
|
|
return createFailure(response.requestId, "native_protocol_error", "Invalid native dock actions");
|
|
if (command === "Std_ToggleToolBarLock" && typeof value.locked !== "boolean")
|
|
return createFailure(response.requestId, "native_protocol_error", "Invalid native toolbar lock state");
|
|
if (command === "Std_TileWindows" && (!Array.isArray(value.windows) || !value.windows.length
|
|
|| value.windows.some(item => !item || typeof item.documentId !== "string" || !item.documentId || typeof item.label !== "string")
|
|
|| !Number.isInteger(value.columns) || (value.columns ?? 0) < 1
|
|
|| !Number.isInteger(value.rows) || (value.rows ?? 0) < 1
|
|
|| !(value.activeDocument === null || typeof value.activeDocument === "string")))
|
|
return createFailure(response.requestId, "native_protocol_error", "Invalid native window layout");
|
|
if (host !== mounted)
|
|
return createFailure(response.requestId, "window_host_unavailable", "The workbench window host changed during the command");
|
|
mounted.apply(value, owner);
|
|
return createSuccess(response.requestId, {
|
|
schema: "freecad-web/document-view-batch/v1", owner, documentId,
|
|
records: [{ apiId: `Web:desktop:${command}`, name: command, status: "success", native: true, result: value }], count: 1,
|
|
});
|
|
});
|
|
}
|