43 lines1,736 bytesCodeBlame
1import { data } from "react-router";
2
3import type { Route } from "./+types/soon";
4import { page } from "../../lib/meta";
5import { roadmapItem } from "../../lib/roadmap";
6import { projects } from "../../lib/services.server";
7import { getViewer } from "../../lib/session.server";
8import { SoonView } from "../repo/soon";
9
10export function meta({ params, ...args }: Route.MetaArgs) {
11 const item = roadmapItem(params.feature);
12 return page(args, {
13 title: `${item?.title ?? "Soon"} · ${params.owner} · g1t`,
14 description: item ? `Soon on g1t: ${item.summary}` : null,
15 version: item ? [item.title, item.summary] : undefined,
16 });
17}
18
19export async function loader({ params, context }: Route.LoaderArgs) {
20 const item = roadmapItem(params.feature);
21 // Only what spans projects lives under the workspace.
22 if (!item || item.section !== "Workspace") throw data(null, { status: 404 });
23 // What to use until then lives in each project, so list the projects.
24 const listed = item.today ? await projects.list(params.owner, getViewer(context)).catch(() => null) : null;
25 const inProjects = listed?.ok
26 ? listed.value.map((project) => ({ name: project.name || project.slug, to: `/${project.workspace}/${project.slug}` }))
27 : [];
28 return { item, inProjects };
29}
30
31/** What a workspace will have across its projects: boards, the roadmap, packages, the fleet. */
32export default function WorkspaceSoon({ loaderData, params }: Route.ComponentProps) {
33 return (
34 <div className="mx-auto max-w-5xl px-4 py-10 sm:px-8">
35 <SoonView
36 item={loaderData.item}
37 base={`/${params.owner}/-`}
38 inProjects={loaderData.inProjects}
39 newProject={`/new?workspace=${params.owner}`}
40 />
41 </div>
42 );
43}