Skip to content
36 linesCodeBlameRaw
1import type { Route } from "./+types/runners";
2import { page } from "../../lib/meta";
3import { RunnersPage } from "../../components/runners-page";
4import { actOnRunners, loadRunnersPage } from "../../lib/runners.server";
5import { repos } from "../../lib/services.server";
6import { assertSameOrigin, getViewer, requireUser, roleIn } from "../../lib/session.server";
7
8export function meta({ params, ...args }: Route.MetaArgs) {
9 return page(args, { title: `Runners · ${params.owner} · g1t` });
10}
11
12/**
13 * Runners, in Workspace mode: the machines the workspace's agents and
14 * workflow jobs run on, g1t's cloud and its own side by side, with what
15 * each is running, this month's time and how to add one. The workspace's
16 * machines and their tokens are its owners'.
17 */
18export async function loader({ params, context, request }: Route.LoaderArgs) {
19 if (roleIn(getViewer(context), params.owner) !== "owner") throw new Response(null, { status: 404 });
20 const user = requireUser(context, request);
21 const workspace = params.owner.toLowerCase();
22 // One round: the repositories (for choosing a group's) beside everything else.
23 const [list, data] = await Promise.all([repos.list(user, { namespace: workspace }), loadRunnersPage(workspace, user)]);
24 return { slug: workspace, ...data, repositories: list.map((repo) => repo.name) };
25}
26
27export async function action({ request, params, context }: Route.ActionArgs) {
28 assertSameOrigin(request);
29 if (roleIn(getViewer(context), params.owner) !== "owner") throw new Response(null, { status: 404 });
30 const user = requireUser(context, request);
31 return actOnRunners({ workspace: params.owner.toLowerCase() }, user, await request.formData());
32}
33
34export default function WorkspaceRunners({ loaderData, actionData }: Route.ComponentProps) {
35 return <RunnersPage data={loaderData} action={actionData} slug={loaderData.slug} />;
36}