Skip to content
29 linesCodeBlameRaw
1/**
2 * The workspace a page outside `/<workspace>` acts on (New project, Import
3 * from GitHub): always the one you're in, as the sidebar shows it, never a
4 * choice made on the page. A link that names another of your workspaces
5 * (`?workspace=`) switches you to it first, so the page and the shell
6 * agree, and then drops it from the address.
7 */
8import { redirect } from "react-router";
9import type { User } from "@g1t/contracts";
10
11import { readCookie } from "./mission";
12import { WORKSPACE_COOKIE, chosenWorkspace, rememberWorkspace } from "./workspace-choice";
13import { pagePath } from "./workspace-nav";
14
15export function currentWorkspace(user: User, request: Request) {
16 const memberships = user.workspaces ?? [];
17 const url = new URL(request.url);
18 const asked = url.searchParams.get("workspace")?.trim().toLowerCase();
19 const current = chosenWorkspace(memberships, readCookie(request.headers.get("cookie"), WORKSPACE_COOKIE));
20 if (asked) {
21 const named = memberships.find((membership) => membership.slug.toLowerCase() === asked);
22 url.searchParams.delete("workspace");
23 // A click asks for `<path>.data?_routes=…`; the address given is the page's own.
24 url.searchParams.delete("_routes");
25 const headers = named && named.slug !== current?.slug ? { "set-cookie": rememberWorkspace(named.slug, url.protocol === "https:") } : undefined;
26 throw redirect(`${pagePath(url.pathname)}${url.search}`, { headers });
27 }
28 return current;
29}