Detailed changes
@@ -27,7 +27,8 @@ export const Route = createFileRoute("/$repo/_issues/issues/$id")({
// Issue detail page (/:repo/issues/:id). Shows title, status, timeline of
// comments and events, and a sidebar with labels and participants.
function RouteComponent() {
- const { ref: repo } = Route.useRouteContext();
+ const { ref } = Route.useRouteContext();
+ const { repo } = Route.useParams();
const { bugDetailRef } = Route.useLoaderData();
const { labelsRef } = Route.useRouteContext();
const { data } = useReadQuery(bugDetailRef);
@@ -43,7 +44,7 @@ function RouteComponent() {
<div>
<Link
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: "status:open", after: "" }}
className="text-muted-foreground hover:text-foreground mb-4 flex items-center gap-1.5 text-sm"
>
@@ -53,7 +54,7 @@ function RouteComponent() {
{/* Title row — hover reveals edit button when logged in */}
<div className="mb-3">
- <TitleEditor bugPrefix={bug.humanId} title={bug.title} humanId={bug.humanId} ref_={repo} />
+ <TitleEditor bugPrefix={bug.humanId} title={bug.title} humanId={bug.humanId} ref_={ref} />
</div>
<div className="text-muted-foreground mb-6 flex flex-wrap items-center gap-3 text-sm">
@@ -61,7 +62,7 @@ function RouteComponent() {
<span>
<Link
to="/$repo/user/$id"
- params={{ repo: repo!, id: bug.author.humanId }}
+ params={{ repo: repo, id: bug.author.humanId }}
className="text-foreground font-medium hover:underline"
>
{bug.author.displayName}
@@ -76,7 +77,7 @@ function RouteComponent() {
{/* Timeline + comment box */}
<div className="min-w-0 flex-1 space-y-4">
<Timeline repo={repo} bugPrefix={bug.humanId} items={bug.timeline.nodes} />
- <CommentBox bugPrefix={bug.humanId} bugStatus={bug.status} ref_={repo} />
+ <CommentBox bugPrefix={bug.humanId} bugStatus={bug.status} ref_={ref} />
</div>
{/* Sidebar */}
@@ -84,7 +85,7 @@ function RouteComponent() {
<LabelEditor
bugPrefix={bug.humanId}
currentLabels={bug.labels}
- ref_={repo}
+ ref_={ref}
validLabels={validLabels}
/>
@@ -100,7 +101,7 @@ function RouteComponent() {
<Link
key={p.id}
to="/$repo/user/$id"
- params={{ repo: repo!, id: p.humanId }}
+ params={{ repo: repo, id: p.humanId }}
title={p.displayName}
>
<Avatar className="size-6">
@@ -46,7 +46,7 @@ const PAGE_SIZE = 25;
type StatusFilter = "open" | "closed";
function RouteComponent() {
- const { ref: repo } = Route.useRouteContext();
+ const { repo } = Route.useParams();
const navigate = useNavigate({ from: "/$repo/issues/" });
const { q, after } = Route.useSearch();
@@ -130,7 +130,7 @@ function RouteComponent() {
<div className="flex shrink-0 items-center gap-1">
<Link
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: queryWithStatus("open"), after: "" }}
className={cn(
"flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
@@ -153,7 +153,7 @@ function RouteComponent() {
<Link
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: queryWithStatus("closed"), after: "" }}
className={cn(
"flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors",
@@ -232,7 +232,7 @@ function RouteComponent() {
<div className="border-border flex items-center justify-center gap-2 border-t px-4 py-2">
<ButtonLink
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q, after: "" }}
variant="ghost"
size="sm"
@@ -247,7 +247,7 @@ function RouteComponent() {
</span>
<ButtonLink
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q, after: bugs?.pageInfo.endCursor ?? "" }}
variant="ghost"
size="sm"
@@ -16,7 +16,7 @@ export const Route = createFileRoute("/$repo/_issues/issues/new")({
// New issue form (/:repo/issues/new). Title + body with write/preview tabs.
function RouteComponent() {
const navigate = useNavigate();
- const { ref: repo } = Route.useRouteContext();
+ const { repo } = Route.useParams();
const [title, setTitle] = useState("");
const [message, setMessage] = useState("");
const [preview, setPreview] = useState(false);
@@ -31,7 +31,7 @@ function RouteComponent() {
if (humanId) {
void navigate({
to: "/$repo/issues/$id",
- params: { repo: repo!, id: humanId },
+ params: { repo: repo, id: humanId },
});
}
}
@@ -40,7 +40,7 @@ function RouteComponent() {
<div className="mx-auto max-w-3xl">
<Link
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: "status:open", after: "" }}
className="text-muted-foreground hover:text-foreground mb-6 flex items-center gap-1.5 text-sm"
>
@@ -111,7 +111,7 @@ function RouteComponent() {
<div className="flex justify-end gap-2">
<ButtonLink
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: "status:open", after: "" }}
variant="ghost"
>
@@ -6,7 +6,7 @@
// The :id param is treated as a humanId prefix and passed directly to the
// identity(prefix) and allBugs(query:"author:...") GraphQL arguments.
-import { createFileRoute, useParams, Link } from "@tanstack/react-router";
+import { createFileRoute, Link } from "@tanstack/react-router";
import { formatDistanceToNow } from "date-fns";
import {
ArrowLeft,
@@ -33,8 +33,8 @@ export const Route = createFileRoute("/$repo/_issues/user/$id")({
const PAGE_SIZE = 25;
function RouteComponent() {
- const { id } = useParams({ strict: false });
- const { ref: repo } = Route.useRouteContext();
+ const { id, repo } = Route.useParams();
+ const { ref } = Route.useRouteContext();
const [statusFilter, setStatusFilter] = useState<"open" | "closed">("open");
// Cursor-stack pagination: cursors[i] is the `after` value to fetch page i.
@@ -47,8 +47,8 @@ function RouteComponent() {
// bugs — paginated list for the selected tab
const { data, loading, error } = useUserProfileQuery({
variables: {
- ref: repo,
- prefix: id!,
+ ref,
+ prefix: id,
openQuery: `author:${id} status:open`,
closedQuery: `author:${id} status:closed`,
listQuery: `author:${id} status:${statusFilter}`,
@@ -98,7 +98,7 @@ function RouteComponent() {
<div>
<Link
to="/$repo/issues"
- params={{ repo: repo! }}
+ params={{ repo: repo }}
search={{ q: "status:open", after: "" }}
className="text-muted-foreground hover:text-foreground mb-6 flex items-center gap-1.5 text-sm"
>
@@ -218,7 +218,7 @@ function RouteComponent() {
<div className="flex flex-wrap items-baseline gap-2">
<Link
to="/$repo/issues/$id"
- params={{ repo: repo!, id: bug.humanId }}
+ params={{ repo: repo, id: bug.humanId }}
className="text-foreground hover:text-primary font-medium hover:underline"
>
{bug.title}
@@ -64,7 +64,8 @@ export const Route = createFileRoute("/$repo/commit/$hash")({
});
function RouteComponent() {
- const { ref: repo } = Route.useRouteContext();
+ const { ref } = Route.useRouteContext();
+ const { repo } = Route.useParams();
const { commitRef } = Route.useLoaderData();
const { data } = useReadQuery(commitRef);
@@ -115,7 +116,7 @@ function RouteComponent() {
parent{" "}
<Link
to="/$repo/commit/$hash"
- params={{ repo: repo!, hash: p }}
+ params={{ repo, hash: p }}
className="text-foreground font-mono hover:underline"
>
{p.slice(0, 7)}
@@ -136,7 +137,7 @@ function RouteComponent() {
{files.map((file: { path: string; oldPath?: string | null; status: string }) => (
<FileDiffView
key={file.path}
- repo={repo}
+ repo={ref}
hash={commit.hash}
path={file.path}
oldPath={file.oldPath ?? undefined}
@@ -133,7 +133,8 @@ export const Route = createFileRoute("/$repo/")({
});
function RouteComponent() {
- const { ref: repo } = Route.useRouteContext();
+ const { ref: repoRef } = Route.useRouteContext();
+ const { repo } = Route.useParams();
const navigate = useNavigate({ from: "/$repo/" });
const { ref: currentRef, path: currentPath, type: viewMode } = useSearch({ from: "/$repo/" });
@@ -157,14 +158,14 @@ function RouteComponent() {
const inBlobMode = viewMode === "blob" && !!currentRef && !!currentPath;
const { data: treeData, loading: treeLoading } = useQuery<TreeQueryData>(TREE_QUERY, {
- variables: { repo, ref: currentRef, path: currentPath || null },
+ variables: { repo: repoRef, ref: currentRef, path: currentPath || null },
skip: !inTreeMode,
});
const entries: GitTreeEntry[] = treeData?.repository?.tree ?? [];
const entryNames = entries.map((e: GitTreeEntry) => e.name);
const { data: lastCommitsData } = useQuery<LastCommitsQueryData>(LAST_COMMITS_QUERY, {
- variables: { repo, ref: currentRef, path: currentPath || null, names: entryNames },
+ variables: { repo: repoRef, ref: currentRef, path: currentPath || null, names: entryNames },
skip: !inTreeMode || entryNames.length === 0,
});
const lastCommitsByName = new Map<string, GitLastCommit>(
@@ -176,7 +177,7 @@ function RouteComponent() {
}));
const { data: blobData, loading: blobLoading } = useQuery<BlobQueryData>(BLOB_QUERY, {
- variables: { repo, ref: currentRef, path: currentPath },
+ variables: { repo: repoRef, ref: currentRef, path: currentPath },
skip: !inBlobMode,
});
const blob: GitBlob | null = blobData?.repository?.blob ?? null;
@@ -191,12 +192,12 @@ function RouteComponent() {
: readmeEntry.name
: null;
const { data: readmeBlobData } = useQuery<BlobQueryData>(BLOB_QUERY, {
- variables: { repo, ref: currentRef, path: readmePath },
+ variables: { repo: repoRef, ref: currentRef, path: readmePath },
skip: !inTreeMode || !readmePath,
});
const readme: string | null = readmeBlobData?.repository?.blob?.text ?? null;
- const repoName = refsData?.repository?.name ?? repo ?? "default-repo";
+ const repoName = refsData?.repository?.name ?? repoRef ?? "default-repo";
function navigateTo(path: string, type: ViewMode = "tree") {
void navigate({ search: (prev) => ({ ...prev, path, type }) });
@@ -239,7 +240,7 @@ function RouteComponent() {
<div className="flex items-center gap-2">
<ButtonLink
to="/$repo"
- params={{ repo: repo! }}
+ params={{ repo }}
search={{
ref: currentRef,
path: currentPath,
@@ -256,7 +257,7 @@ function RouteComponent() {
</div>
{viewMode === "commits" ? (
- <CommitList repo={repo} ref_={currentRef} path={currentPath || undefined} />
+ <CommitList repo={repoRef} ref_={currentRef} path={currentPath || undefined} />
) : viewMode === "tree" || !blob ? (
<>
<FileTree