import { useState } from "react"; import { createFineGrainedToken } from "~/fns/tokens"; import { useAction } from "~/hooks/use-action"; import { Button } from "~/ui/Button"; import { CheckboxField, SelectField, TextAreaField, TextField } from "~/ui/Field"; import { ErrorBanner } from "~/ui/Callout"; const AREAS = [ { id: "contents", label: "Contents", hint: "Clone, fetch, push, raw files and archives" }, { id: "issues", label: "Issues", hint: "Read and write issues and comments" }, { id: "pulls", label: "Pull requests", hint: "Read, open and review pull requests (needs Contents)" }, { id: "actions", label: "Actions", hint: "Workflow runs, logs and artifacts" }, { id: "admin", label: "Administration", hint: "Repository settings (write grants admin)" }, ] as const; const ACCESS = [ { value: "", label: "No access" }, { value: "read", label: "Read-only" }, { value: "write", label: "Read and write" }, ] as const; const EXPIRY = [ { value: "30", label: "30 days" }, { value: "90", label: "90 days" }, { value: "365", label: "1 year" }, { value: "0", label: "No expiration" }, ] as const; function accessValue(value: FormDataEntryValue | null): "read" | "write" | undefined { return value === "read" || value === "write" ? value : undefined; } const ALL_WRITE = Object.fromEntries(AREAS.map((area) => [area.id, "write" as const])); export function FineGrainedTokenForm({ onCreated }: { onCreated: (token: string) => void }) { const create = useAction(createFineGrainedToken); const [allAccess, setAllAccess] = useState(false); const [chosenAllRepos, setAllRepos] = useState(false); const allRepos = allAccess || chosenAllRepos; return (
{ event.preventDefault(); const formElement = event.currentTarget; const form = new FormData(formElement); const repos = String(form.get("repos") ?? "") .split(/[\s,]+/) .map((entry) => entry.trim()) .filter(Boolean); const result = await create.run({ data: { name: String(form.get("name") ?? ""), expiresInDays: Number(form.get("expires") ?? "90"), allRepos, repos: allRepos ? [] : repos, permissions: allAccess ? ALL_WRITE : Object.fromEntries(AREAS.map((area) => [area.id, accessValue(form.get(area.id))])), password: String(form.get("password") ?? ""), }, }); if (result) { formElement.reset(); setAllAccess(false); onCreated(result.token); } }} > setAllAccess(event.currentTarget.checked)} hint="Every repository you can access, with read and write on every area, including Administration: settings, deploy keys and bypassing branch protection where you are an admin. Use only where a narrower token won't do." /> {!allAccess && ( setAllRepos(event.currentTarget.checked)} /> )} {!allRepos && ( )} {!allAccess && (
Permissions {AREAS.map((area) => ( ))}
)} ); }