diff --git a/bun.lockb b/bun.lockb index 019adb8..e46f64c 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 933d917..2e52264 100644 --- a/package.json +++ b/package.json @@ -28,21 +28,21 @@ "recharts": "^3.6.0" }, "devDependencies": { - "@eslint/js": "^9.39.2", + "@eslint/js": "^10.0.0", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.6.1", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@vitejs/plugin-react-swc": "^4.2.2", - "eslint": "^9.39.2", - "eslint-plugin-react-hooks": "^7.0.0", + "eslint": "^10.0.0", + "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.0", "globals": "^17.0.0", "happy-dom": "^20.9.0", "jsdom": "^29.1.1", "typescript": "~6.0.0", - "typescript-eslint": "^8.52.0", + "typescript-eslint": "^8.60.0", "vite": "^8.0.0", "vitest": "^3" } diff --git a/src/pages/repository/RepositoryPage.tsx b/src/pages/repository/RepositoryPage.tsx index 0442a90..b7084c0 100644 --- a/src/pages/repository/RepositoryPage.tsx +++ b/src/pages/repository/RepositoryPage.tsx @@ -37,8 +37,7 @@ export const RepositoryPage: React.FC = () => { const {org: orgName, repo: repoName} = useParams(); const [searchParams] = useSearchParams(); - const queryTab = searchParams.get('tab') || RepoPageTabs.RESULTS; - const [currentTab, setCurrentTab] = React.useState(queryTab); + const currentTab = searchParams.get('tab') || RepoPageTabs.RESULTS; const navigate = useNavigate(); const updateUrlTab = (tab: string) => { @@ -47,11 +46,6 @@ export const RepositoryPage: React.FC = () => { }); }; - // Updates currentTab if query param changes - React.useEffect(() => { - setCurrentTab(queryTab); - }, [queryTab]); - const orgQuery = useQuery({ queryKey: ["getOrgByName", orgName], enabled: !!orgName, @@ -171,7 +165,6 @@ export const RepositoryPage: React.FC = () => { activeKey={currentTab} onChange={(key: string) => { if (key === RepoPageTabs.CONFIGS || key === RepoPageTabs.RESULTS || key === RepoPageTabs.TRENDS) { - setCurrentTab(key); updateUrlTab(key); } }} diff --git a/src/pages/run_result/RunResult.tsx b/src/pages/run_result/RunResult.tsx index 669d9ce..72e6226 100644 --- a/src/pages/run_result/RunResult.tsx +++ b/src/pages/run_result/RunResult.tsx @@ -69,10 +69,9 @@ type StatusFilter = 'all' | 'drifted' | 'errored' | 'skipped' | 'ok'; const RunResultPage: React.FC = () => { const [searchText, setSearchText] = React.useState(''); - const [statusFilter, setStatusFilter] = React.useState('all'); + const [userSetFilter, setUserSetFilter] = React.useState(null); const [drawerOpen, setDrawerOpen] = React.useState(false); const [selectedProject, setSelectedProject] = React.useState(null); - const hasInitializedFilter = React.useRef(false); const axios = useAxios(); const {org: orgName, repo: repoName, run: runUuid} = useParams(); @@ -91,24 +90,19 @@ const RunResultPage: React.FC = () => { const run = runQuery.data; - // Set default filter based on priority: drifted > errored > skipped > all (on initial load) - React.useEffect(() => { - if (run && !hasInitializedFilter.current) { - hasInitializedFilter.current = true; - const driftedCount = run.projects?.filter(p => p.drifted && !p.skipped_due_to_pr && p.succeeded).length ?? 0; - const erroredCount = run.projects?.filter(p => !p.succeeded).length ?? 0; - const skippedCount = run.projects?.filter(p => p.skipped_due_to_pr && p.succeeded).length ?? 0; - - if (driftedCount > 0) { - setStatusFilter('drifted'); - } else if (erroredCount > 0) { - setStatusFilter('errored'); - } else if (skippedCount > 0) { - setStatusFilter('skipped'); - } - // If no drifted, errored, or skipped projects, keep the default 'all' filter - } + // Default filter priority: drifted > errored > skipped > all. The user's explicit + // pick (userSetFilter) always wins so the auto-pick can't clobber it on refetch. + const defaultFilter = React.useMemo(() => { + if (!run) return 'all'; + const driftedCount = run.projects?.filter(p => p.drifted && !p.skipped_due_to_pr && p.succeeded).length ?? 0; + if (driftedCount > 0) return 'drifted'; + const erroredCount = run.projects?.filter(p => !p.succeeded).length ?? 0; + if (erroredCount > 0) return 'errored'; + const skippedCount = run.projects?.filter(p => p.skipped_due_to_pr && p.succeeded).length ?? 0; + if (skippedCount > 0) return 'skipped'; + return 'all'; }, [run]); + const statusFilter: StatusFilter = userSetFilter ?? defaultFilter; const allProjects = React.useMemo(() => run?.projects ?? [], [run?.projects]); // Filter projects based on search text and status filter @@ -317,7 +311,7 @@ const RunResultPage: React.FC = () => { /> setStatusFilter(value as StatusFilter)} + onChange={(value) => setUserSetFilter(value as StatusFilter)} options={[ {label: `All (${counts.all})`, value: 'all'}, {label: `Drifted (${counts.drifted})`, value: 'drifted'}, @@ -395,7 +389,7 @@ const RunResultPage: React.FC = () => { } > -