diff --git a/webui2/src/lib/query-utils.ts b/webui2/src/lib/query-utils.ts index bd824d8128d093636636d84a58bc589335e49160..8b2244adfc9a942c118f9de7523c7fe7f3b5f862 100644 --- a/webui2/src/lib/query-utils.ts +++ b/webui2/src/lib/query-utils.ts @@ -41,13 +41,13 @@ export function tokenizeQuery(input: string): string[] { // Parse a query string back into structured filter state. export function parseQueryString(input: string): { - status: StatusFilter; + status: StatusFilter | null; labels: string[]; author: string | null; freeText: string; sort: SortValue; } { - let status: StatusFilter = "open"; + let status: StatusFilter | null = null; const labels: string[] = []; let author: string | null = null; let sort: SortValue = "creation-desc"; @@ -83,13 +83,14 @@ export function buildBaseQuery(labels: string[], author: string | null, freeText // Build the structured query string sent to the GraphQL allBugs(query:) argument. export function buildQueryString( - status: StatusFilter, + status: StatusFilter | null, labels: string[], author: string | null, freeText: string, sort: SortValue = "creation-desc", ): string { - const parts = [`status:${status}`]; + const parts: string[] = []; + if (status) parts.push(`status:${status}`); const base = buildBaseQuery(labels, author, freeText); if (base) parts.push(base); if (sort !== "creation-desc") parts.push(`sort:${sort}`); diff --git a/webui2/src/routes/$repo/_issues/issues/index.tsx b/webui2/src/routes/$repo/_issues/issues/index.tsx index ae729fe9673d3190ce41464de0df6ef24c6027b3..375ca41aa4c3abd725cf67a345ffe1a3c4d8ab98 100644 --- a/webui2/src/routes/$repo/_issues/issues/index.tsx +++ b/webui2/src/routes/$repo/_issues/issues/index.tsx @@ -2,7 +2,7 @@ import { useReadQuery } from "@apollo/client/react"; import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; import { formatDistanceToNow } from "date-fns"; import { Search } from "lucide-react"; -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import * as v from "valibot"; import { type BugListQuery, BugListDocument } from "@/__generated__/graphql"; @@ -61,12 +61,14 @@ function RouteComponent() { author: selectedAuthorQuery, sort, } = parsed; - // We don't have the humanId from URL — the dropdown will match by query value - const selectedAuthorId: string | null = null; - // Draft is the text input value — starts from URL, only committed on submit const [draft, setDraft] = useState(q); + // Sync draft when URL query changes (e.g. tab clicks, filter changes) + useEffect(() => { + setDraft(q); + }, [q]); + const { bugListRef } = Route.useLoaderData(); const { labelsRef, identitiesRef } = Route.useRouteContext(); const { data } = useReadQuery(bugListRef); @@ -79,6 +81,18 @@ function RouteComponent() { const validLabels = labelsData?.repository?.validLabels.nodes; const allIdentities = identitiesData?.repository?.allIdentities.nodes; + // Resolve the author query value (login/name) back to a humanId for the filter UI + const selectedAuthorId = useMemo(() => { + if (!selectedAuthorQuery || !allIdentities) return null; + const match = allIdentities.find( + (i) => + i.login === selectedAuthorQuery || + i.name === selectedAuthorQuery || + i.humanId === selectedAuthorQuery, + ); + return match?.humanId ?? null; + }, [selectedAuthorQuery, allIdentities]); + const completionProviders: CompletionProvider[] = useMemo( () => [ { @@ -228,7 +242,7 @@ function RouteComponent() { {/* Bug rows */} {bugs?.nodes.length === 0 && ( - No {statusFilter} issues found. + No {statusFilter ?? ""} issues found. )} {bugs?.nodes.map((bug) => (