From 434604586c2651197fdc0d72688fe10f331b104b Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Sun, 29 Mar 2026 21:14:46 +0200 Subject: [PATCH] fix(web): resolve all 607 lint warnings disable react-in-jsx-scope (585 false positives with jsx: react-jsx) fix no-unsafe-enum-comparison (7): - import GitObjectType/GitRefType enums from codegen - compare against enum members instead of string literals fix no-unsafe-type-assertion (8): - replace `as string` casts with typeof guards in validateSearch - add type guard functions for union validation fix no-array-sort (3): - replace `[...arr].sort()` with `arr.toSorted()` (ES2023) - add ES2023 to tsconfig lib fix remaining: - rename shadowed `_` variable (no-shadow) - move handleSignOut to module scope (consistent-function-scoping) - suppress import/no-unassigned-import for CSS import Co-Authored-By: Claude Opus 4.6 (1M context) --- webui2/.oxlintrc.json | 3 +- webui2/src/components/bugs/IssueFilters.tsx | 4 +-- webui2/src/components/code/CommitList.tsx | 2 +- webui2/src/components/code/FileTree.tsx | 8 +++--- webui2/src/components/code/RefSelector.tsx | 8 +++--- webui2/src/components/layout/Header.tsx | 11 ++++---- webui2/src/lib/auth.tsx | 6 ++-- webui2/src/main.tsx | 1 + webui2/src/routes/$repo/index.tsx | 31 ++++++++++++++------- webui2/src/routes/$repo/issues/index.tsx | 14 ++++++---- webui2/src/routes/auth/select-identity.tsx | 1 + webui2/tsconfig.app.json | 1 + 12 files changed, 56 insertions(+), 34 deletions(-) diff --git a/webui2/.oxlintrc.json b/webui2/.oxlintrc.json index addf78786e901b7dd696f2b587a4792ee32c3e55..dfe61b10d843cad9ea958ad566e07091bf4b5e4f 100644 --- a/webui2/.oxlintrc.json +++ b/webui2/.oxlintrc.json @@ -13,7 +13,8 @@ "typescript/no-unsafe-member-access": "warn", "typescript/no-unsafe-return": "warn", "typescript/await-thenable": "error", - "typescript/no-unnecessary-type-assertion": "warn" + "typescript/no-unnecessary-type-assertion": "warn", + "react/react-in-jsx-scope": "off" }, "options": { "typeAware": true, diff --git a/webui2/src/components/bugs/IssueFilters.tsx b/webui2/src/components/bugs/IssueFilters.tsx index 32dac9d2a02bdd768fefe0d2383054b2ccf539c3..26c752fc72c3db25c04bf9f81ab699d3977d0890 100644 --- a/webui2/src/components/bugs/IssueFilters.tsx +++ b/webui2/src/components/bugs/IssueFilters.tsx @@ -81,7 +81,7 @@ export function IssueFilters({ const validLabels = useMemo( () => - [...(labelsData?.repository?.validLabels.nodes ?? [])].sort((a, b) => + (labelsData?.repository?.validLabels.nodes ?? []).toSorted((a, b) => a.name.localeCompare(b.name), ), [labelsData], @@ -89,7 +89,7 @@ export function IssueFilters({ const allIdentities = useMemo( () => - [...(authorsData?.repository?.allIdentities.nodes ?? [])].sort((a, b) => + (authorsData?.repository?.allIdentities.nodes ?? []).toSorted((a, b) => a.displayName.localeCompare(b.displayName), ), [authorsData], diff --git a/webui2/src/components/code/CommitList.tsx b/webui2/src/components/code/CommitList.tsx index ef756e3dc0cc3835a23b178d4a909a72f0bcfac1..9e87fee884b3450d317f8c02456e6cb6da1caff6 100644 --- a/webui2/src/components/code/CommitList.tsx +++ b/webui2/src/components/code/CommitList.tsx @@ -177,7 +177,7 @@ function CommitListSkeleton() {
- {Array.from({ length: 4 }).map((_, i) => ( + {Array.from({ length: 4 }).map((_c, i) => (
diff --git a/webui2/src/components/code/FileTree.tsx b/webui2/src/components/code/FileTree.tsx index 6b847c1bb250d5de61a69d9567d14e0cb86146e2..fa5daa21c53a538c33f8a3a403080f844d3eafcf 100644 --- a/webui2/src/components/code/FileTree.tsx +++ b/webui2/src/components/code/FileTree.tsx @@ -2,7 +2,7 @@ import { Link } from "@tanstack/react-router"; import { formatDistanceToNow } from "date-fns"; import { Folder, File } from "lucide-react"; -import type { GitTreeEntry } from "@/__generated__/graphql"; +import { GitObjectType, type GitTreeEntry } from "@/__generated__/graphql"; import { Skeleton } from "@/components/ui/skeleton"; import { useRepo } from "@/lib/repo"; @@ -27,8 +27,8 @@ interface FileTreeProps { // name, last-commit message (linked to commit detail), and relative date. export function FileTree({ entries, path, loading, onNavigate, onNavigateUp }: FileTreeProps) { // Directories first, then files — each group alphabetical - const sorted = [...entries].sort((a, b) => { - if (a.type !== b.type) return a.type === "TREE" ? -1 : 1; + const sorted = entries.toSorted((a, b) => { + if (a.type !== b.type) return a.type === GitObjectType.Tree ? -1 : 1; return a.name.localeCompare(b.name); }); @@ -64,7 +64,7 @@ function FileTreeRow({ entry: TreeEntryWithCommit; onNavigate: (entry: TreeEntryWithCommit) => void; }) { - const isDir = entry.type === "TREE"; + const isDir = entry.type === GitObjectType.Tree; const repo = useRepo(); return ( diff --git a/webui2/src/components/code/RefSelector.tsx b/webui2/src/components/code/RefSelector.tsx index 2db3bc0e376ca29dfed587cff9376ae443a7b5f3..642ad7d33beb3b266a9d8daca4441394b2aa92e2 100644 --- a/webui2/src/components/code/RefSelector.tsx +++ b/webui2/src/components/code/RefSelector.tsx @@ -1,7 +1,7 @@ import { GitBranch, Tag, Check, ChevronsUpDown } from "lucide-react"; import { useState } from "react"; -import type { GitRef } from "@/__generated__/graphql"; +import { GitRefType, type GitRef } from "@/__generated__/graphql"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; @@ -20,8 +20,8 @@ export function RefSelector({ refs, currentRef, onSelect }: RefSelectorProps) { const [filter, setFilter] = useState(""); const filtered = refs.filter((r) => r.shortName.toLowerCase().includes(filter.toLowerCase())); - const branches = filtered.filter((r) => r.type === "BRANCH"); - const tags = filtered.filter((r) => r.type === "TAG"); + const branches = filtered.filter((r) => r.type === GitRefType.Branch); + const tags = filtered.filter((r) => r.type === GitRefType.Tag); return ( @@ -102,7 +102,7 @@ function RefItem({ active && "font-medium", )} > - {ref_.type === "BRANCH" ? ( + {ref_.type === GitRefType.Branch ? ( ) : ( diff --git a/webui2/src/components/layout/Header.tsx b/webui2/src/components/layout/Header.tsx index 5a3a43345233101c76bbd2f77c09be8afdc4c60e..0ed2677d468dded56886288dee076e0707fb19d3 100644 --- a/webui2/src/components/layout/Header.tsx +++ b/webui2/src/components/layout/Header.tsx @@ -17,12 +17,13 @@ import { useTheme } from "@/lib/theme"; // SignOutButton sends a POST to /auth/logout and reloads the page. // A full reload is the simplest way to reset all Apollo cache + React state. +function handleSignOut() { + void fetch("/auth/logout", { method: "POST", credentials: "include" }).finally(() => + window.location.assign("/"), + ); +} + function SignOutButton() { - function handleSignOut() { - void fetch("/auth/logout", { method: "POST", credentials: "include" }).finally(() => - window.location.assign("/"), - ); - } return (