feat(web): open project surfaces in browser targets — #204
This commit is contained in:
97
frontend/src/features/web/webSurfaceNavigation.ts
Normal file
97
frontend/src/features/web/webSurfaceNavigation.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import {
|
||||
isWebOpenablePanel,
|
||||
type WebOpenablePanelId,
|
||||
} from "./webSurfaceCatalog";
|
||||
|
||||
export type WebSurfaceOpenTarget = "tab" | "window";
|
||||
export type WebSurfaceOpenResult = "tab" | "window" | "blocked";
|
||||
|
||||
export interface WebSurfaceWindowParams {
|
||||
panel: WebOpenablePanelId;
|
||||
projectId: string;
|
||||
projectRoot: string;
|
||||
projectName: string;
|
||||
focusSprintId?: string | null;
|
||||
}
|
||||
|
||||
export interface OpenWebSurfaceInput extends WebSurfaceWindowParams {
|
||||
baseHref?: string;
|
||||
}
|
||||
|
||||
export interface OpenWebSurfaceOutcome {
|
||||
result: WebSurfaceOpenResult;
|
||||
url: string;
|
||||
}
|
||||
|
||||
type BrowserOpen = Window["open"];
|
||||
|
||||
const QUERY_PANEL = "webPanel";
|
||||
const QUERY_PROJECT_ID = "projectId";
|
||||
const QUERY_PROJECT_ROOT = "projectRoot";
|
||||
const QUERY_PROJECT_NAME = "projectName";
|
||||
const QUERY_FOCUS_SPRINT = "focusSprintId";
|
||||
|
||||
export function parseWebSurfaceWindowParams(search: string): WebSurfaceWindowParams | null {
|
||||
const params = new URLSearchParams(search);
|
||||
const panel = params.get(QUERY_PANEL);
|
||||
const projectId = params.get(QUERY_PROJECT_ID);
|
||||
const projectRoot = params.get(QUERY_PROJECT_ROOT);
|
||||
const projectName = params.get(QUERY_PROJECT_NAME);
|
||||
|
||||
if (!panel || !isWebOpenablePanel(panel) || !projectId || !projectRoot || !projectName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
panel,
|
||||
projectId,
|
||||
projectRoot,
|
||||
projectName,
|
||||
focusSprintId: params.get(QUERY_FOCUS_SPRINT),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildWebSurfaceWindowUrl(input: OpenWebSurfaceInput): string {
|
||||
const href =
|
||||
input.baseHref ??
|
||||
(typeof window !== "undefined" && window.location
|
||||
? window.location.href
|
||||
: "http://localhost/");
|
||||
const url = new URL(href);
|
||||
url.hash = "";
|
||||
url.search = "";
|
||||
url.searchParams.set(QUERY_PANEL, input.panel);
|
||||
url.searchParams.set(QUERY_PROJECT_ID, input.projectId);
|
||||
url.searchParams.set(QUERY_PROJECT_ROOT, input.projectRoot);
|
||||
url.searchParams.set(QUERY_PROJECT_NAME, input.projectName);
|
||||
if (input.focusSprintId) {
|
||||
url.searchParams.set(QUERY_FOCUS_SPRINT, input.focusSprintId);
|
||||
}
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
export function openWebSurfaceInBrowser(
|
||||
input: OpenWebSurfaceInput,
|
||||
target: WebSurfaceOpenTarget,
|
||||
open: BrowserOpen = window.open.bind(window),
|
||||
): OpenWebSurfaceOutcome {
|
||||
const url = buildWebSurfaceWindowUrl(input);
|
||||
if (target === "tab") {
|
||||
return {
|
||||
url,
|
||||
result: open(url, "_blank", "noopener,noreferrer") ? "tab" : "blocked",
|
||||
};
|
||||
}
|
||||
|
||||
const popup = open(
|
||||
url,
|
||||
`idea-web-${input.panel}`,
|
||||
"popup,width=1280,height=900,noopener,noreferrer",
|
||||
);
|
||||
if (popup) return { url, result: "window" };
|
||||
|
||||
return {
|
||||
url,
|
||||
result: open(url, "_blank", "noopener,noreferrer") ? "tab" : "blocked",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user