Skip to content
43 linesCodeBlameRaw

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.

Docs: a workspace knowledge base people and agents write together1import { data, useNavigate } from "react-router";
2
3import type { Route } from "./+types/new-space";
4import { useDocsAction } from "../../../components/docs/actions";
5import { SpaceForm, initialSpace, spaceInput } from "../../../components/docs/space-form";
6import { page } from "../../../lib/meta";
7import { identity } from "../../../lib/services.server";
8import { requireUser, roleIn } from "../../../lib/session.server";
9
10export function meta({ params, ...args }: Route.MetaArgs) {
11 return page(args, { title: `New space · Docs · ${params.owner} · g1t` });
12}
13
14export async function loader({ params, context, request }: Route.LoaderArgs) {
15 const viewer = requireUser(context, request);
16 if (!roleIn(viewer, params.owner)) throw data(null, { status: 404 });
17 const teams = await identity.listTeams(viewer, params.owner.toLowerCase()).catch(() => null);
18 return { teams: teams?.ok ? teams.value.map((t) => ({ slug: t.slug, name: t.name })) : [] };
19}
20
21/** A new space: for everyone, a team, or only its members. Whoever makes it has full access. */
22export default function NewSpace({ loaderData, params }: Route.ComponentProps) {
23 const slug = params.owner.toLowerCase();
24 const navigate = useNavigate();
25 const { send, busy, error } = useDocsAction(slug);
26 return (
27 <div className="mx-auto max-w-2xl">
28 <h1 className="text-xl font-semibold tracking-tight">New space</h1>
29 <p className="mt-1 mb-8 text-sm text-muted">A space holds a tree of pages: one per team, project or topic.</p>
30 <SpaceForm
31 initial={initialSpace()}
32 teams={loaderData.teams}
33 submitLabel="Create space"
34 busy={busy}
35 error={error}
36 onSubmit={async (value) => {
37 const made = await send<{ slug: string }>("create_space", { space: spaceInput(value) });
38 if (made.ok) navigate(`/${slug}/-/docs/${made.value.slug}`);
39 }}
40 />
41 </div>
42 );
43}