g1t/apps/web/app/lib/chrome.ts

101 lines3,192 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put1/**
2 * Which frame a page is drawn in, and what the sidebar offers someone who
3 * is not signed in.
4 *
5 * g1t is a sidebar site: projects, Explore, Search, profiles and
6 * not-found pages are drawn in the app's sidebar for everyone, so a
7 * visitor browsing public projects finds their way the same as a member.
8 * Only the front page and the pages about signing in or paying keep the
9 * marketing header and footer.
10 */
11
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look12import type { Abilities, Capability } from "@g1t/contracts";
13
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put14/** Pages a visitor sees in the marketing frame. */
15const MARKETING = new Set([
16 "/",
17 "/pricing",
18 "/login",
19 "/register",
20 "/logout",
21 "/verify",
22 "/forgot",
23 "/reset",
24 "/device",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look25 // Who makes g1t, and the promises it keeps: the policies, security,
26 // support and status.
27 "/policies",
28 "/security",
29 "/support",
30 "/status",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put31 // These send a visitor to sign in; the frame matters only for a moment.
32 "/new",
33 "/settings",
34 "/workspaces/new",
35]);
36
37/** Whether the page is drawn in the app's sidebar frame. */
38export function usesAppShell(pathname: string, signedIn: boolean): boolean {
39 if (signedIn) return true;
40 const path = pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
41 if (MARKETING.has(path)) return false;
42 if (path === "/oauth" || path.startsWith("/oauth/")) return false;
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look43 // An invite link is the front door: the marketing frame, like /register.
44 if (path.startsWith("/invite/")) return false;
45 if (path.startsWith("/policies/")) return false;
status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas46 // Your settings pages, like /settings: a visitor is sent to sign in.
47 if (path.startsWith("/settings/")) return false;
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put48 return true;
49}
50
51export type SidebarItem = { label: string; to: string };
52
53/** The visitor's sidebar menu: where to browse from. */
54export const VISITOR_LINKS: SidebarItem[] = [
55 { label: "Explore", to: "/explore" },
56 { label: "Search", to: "/search" },
57];
58
59/** The project pages the sidebar lists, by key, for a member or not. */
60export type ProjectPage =
61 | "code"
62 | "issues"
63 | "pulls"
64 | "agents"
65 | "actions"
66 | "deployments"
67 | "observability"
68 | "security"
69 | "insights"
70 | "settings";
71
72/**
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look73 * What a page needs beyond a role on the repository, once what the viewer
74 * may do is known: Security's findings are for people who can push.
75 */
76export const PAGE_NEEDS: Partial<Record<ProjectPage, Capability>> = { security: "push" };
77
78/**
79 * A project's menu, in order. Security and Settings are for people with a
80 * role on its repository, and a page in `PAGE_NEEDS` only for those whose
81 * role has its capability (`can`, once the repository's page has loaded);
82 * everyone who can see the project sees the rest.
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put83 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look84export function projectPages(member: boolean, can?: Partial<Abilities>): ProjectPage[] {
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put85 const pages: (ProjectPage | false)[] = [
86 "code",
87 "issues",
88 "pulls",
89 "agents",
90 "actions",
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look91 // A public repository's deployments and build logs are for anyone, as its code is.
92 "deployments",
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put93 "observability",
94 member && "security",
95 "insights",
96 member && "settings",
97 ];
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look98 return pages.filter(
99 (page): page is ProjectPage => page !== false && (!can || !PAGE_NEEDS[page] || Boolean(can[PAGE_NEEDS[page]!])),
100 );
Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put101}