diff --git a/bun.lock b/bun.lock index 1aa91d5..192bd4a 100644 --- a/bun.lock +++ b/bun.lock @@ -6,6 +6,10 @@ "name": "pulldash", "dependencies": { "@hono/node-server": "^2.0.2", + "@tanstack/query-async-storage-persister": "^5.101.1", + "@tanstack/react-query": "^5.101.1", + "@tanstack/react-query-devtools": "^5.101.1", + "@tanstack/react-query-persist-client": "^5.101.1", "hono": "^4.10.7", }, "devDependencies": { @@ -259,6 +263,20 @@ "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], + "@tanstack/query-async-storage-persister": ["@tanstack/query-async-storage-persister@5.101.1", "", { "dependencies": { "@tanstack/query-core": "5.101.1", "@tanstack/query-persist-client-core": "5.101.1" } }, "sha512-QuHhCTLyQjiVFUYRW5xtgeuiP1NEmqL5wnuFgPGeO6SjTLKeN9VnAhAKsKzde3AcEZEe4PL7FehfKbVhM/9kLA=="], + + "@tanstack/query-core": ["@tanstack/query-core@5.101.1", "", {}, "sha512-Y6Y92dkXtNqx67m2pMSxUsA3zOCwv862JexZRP8/EPwvKXMPu9m8rv43spiXWzOUIggQ3SQApttALStzhA8B4g=="], + + "@tanstack/query-devtools": ["@tanstack/query-devtools@5.101.1", "", {}, "sha512-37RQ9U2PxlXQiv1era2t+uHgVhmiyvxqTMu30+KoVf0rufiucu6rpGRKFJk61Wh5OAZFKqCQd6lxTzFWfLZiuQ=="], + + "@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.101.1", "", { "dependencies": { "@tanstack/query-core": "5.101.1" } }, "sha512-rR5Er6jmdI3Oo8o6Wc0ceM6glDU4umgePu2IxM3Gy2UvPqcQONduxxxSzU1+F17mpS09XHqHKmj0Irhfb2cGYg=="], + + "@tanstack/react-query": ["@tanstack/react-query@5.101.1", "", { "dependencies": { "@tanstack/query-core": "5.101.1" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-ZnONUuQKJe1bJMStXUL1s5uKN9FcfC28j5cK+iDZcdSHtUv1wtin1cGc/Oewhf2Oc4eKY7lggtpvT/AbMmhHew=="], + + "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.101.1", "", { "dependencies": { "@tanstack/query-devtools": "5.101.1" }, "peerDependencies": { "@tanstack/react-query": "^5.101.1", "react": "^18 || ^19" } }, "sha512-OXFR9XKdEslraq3cpl3kCUeNvTIq/xGWEZiFZdn2bLB/q4WxSALMEDKYZ5yYjMQytsfnQxwQYqV4qtVEf0nuog=="], + + "@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.101.1", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.101.1" }, "peerDependencies": { "@tanstack/react-query": "^5.101.1", "react": "^18 || ^19" } }, "sha512-bBSne+3+28EZ/Ch5a06J0YQi6d5yaT2G+vyHAyhzwzYA1FAEAFe6Ou6TsNVQaT6ef6pFShU73FL/NB4guTWNng=="], + "@tanstack/react-virtual": ["@tanstack/react-virtual@3.14.3", "", { "dependencies": { "@tanstack/virtual-core": "3.17.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-k/cnHPVaOfn46hSbiY6n4Dzf4QjCGWSF40zR5QIIYUqPAjpA6TN7InfYmcMiDVQGP2iUn9xsRbAl8u1v3UmeVQ=="], "@tanstack/virtual-core": ["@tanstack/virtual-core@3.17.1", "", {}, "sha512-VZyW2Uiml5tmBZwPGrSD3Sz73OxzljQMCmzYHsUTPEuTsERf5xwa+uWb01xEzkz3ZSYTjj8NEb/mKHvgKxyZdA=="], diff --git a/package.json b/package.json index 4473963..2132682 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,10 @@ }, "dependencies": { "@hono/node-server": "^2.0.2", + "@tanstack/query-async-storage-persister": "^5.101.1", + "@tanstack/react-query": "^5.101.1", + "@tanstack/react-query-devtools": "^5.101.1", + "@tanstack/react-query-persist-client": "^5.101.1", "hono": "^4.10.7" }, "devDependencies": { diff --git a/scripts/build-browser.ts b/scripts/build-browser.ts index 1d9fe59..37fc969 100644 --- a/scripts/build-browser.ts +++ b/scripts/build-browser.ts @@ -8,6 +8,7 @@ const isWatch = process.argv.includes("--watch"); const REPO_URL = process.env.REPO_URL ?? "https://github.com/jennings/pulldash"; const define = { __REPO_URL__: JSON.stringify(REPO_URL), + __DEV__: JSON.stringify(isWatch), }; async function build() { diff --git a/src/browser/components/home.tsx b/src/browser/components/home.tsx index de1e25d..aa65790 100644 --- a/src/browser/components/home.tsx +++ b/src/browser/components/home.tsx @@ -1,4 +1,6 @@ import { useState, useEffect, useCallback, useMemo } from "react"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { queries } from "../lib/queries"; import { Search, GitPullRequest, @@ -43,8 +45,6 @@ import { import { useGitHubStore, useGitHubReady, - usePRList, - usePRListActions, getCachedTeams, type PRSearchResult, } from "../contexts/github"; @@ -326,9 +326,7 @@ export function Home() { const github = useGitHubStore(); const { isAuthenticated } = useAuth(); - // Data store - const prList = usePRList(); - const { fetchPRList, refreshPRList } = usePRListActions(); + const queryClient = useQueryClient(); // Filter config const [config, setConfig] = useState(getFilterConfig); @@ -361,21 +359,29 @@ export function Home() { saveFilterConfig(config); }, [config]); - useEffect(() => { - if (githubReady) { - fetchPRList(searchQueries, page, perPage); - } - }, [fetchPRList, searchQueries, page, perPage, githubReady]); - // Reset page when config changes useEffect(() => { setPage(1); }, [config.repos, config.state]); + // PR list via React Query + const { + data: prListData, + isFetching: loadingPrs, + isPending: prListPending, + dataUpdatedAt, + } = useQuery({ + ...queries.prList(searchQueries, page, perPage), + enabled: githubReady, + }); + + const refreshPRList = useCallback(() => { + queryClient.invalidateQueries({ queryKey: ["pr-list"] }); + }, [queryClient]); + // Convenience accessors - const prs = prList.items; - const loadingPrs = prList.loading; - const totalCount = prList.totalCount; + const prs = prListData?.items ?? []; + const totalCount = prListData?.totalCount ?? 0; // Client-side filter for UPDATED PRs const filteredPrs = useMemo(() => { @@ -1045,8 +1051,8 @@ export function Home() { )}
- {prList.lastFetchedAt && !loadingPrs && ( - + {dataUpdatedAt > 0 && !loadingPrs && ( + )}