| |
| |
| |
| |
| |
|
|
| import { useQuery, useInfiniteQuery } from '@tanstack/react-query'; |
| import { getElectronAPI } from '@/lib/electron'; |
| import { queryKeys } from '@/lib/query-keys'; |
| import { STALE_TIMES } from '@/lib/query-client'; |
| import type { |
| GitHubIssue, |
| GitHubPR, |
| GitHubComment, |
| PRReviewComment, |
| StoredValidation, |
| } from '@/lib/electron'; |
|
|
| interface GitHubIssuesResult { |
| openIssues: GitHubIssue[]; |
| closedIssues: GitHubIssue[]; |
| } |
|
|
| interface GitHubPRsResult { |
| openPRs: GitHubPR[]; |
| mergedPRs: GitHubPR[]; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function useGitHubIssues(projectPath: string | undefined) { |
| return useQuery({ |
| queryKey: queryKeys.github.issues(projectPath ?? ''), |
| queryFn: async (): Promise<GitHubIssuesResult> => { |
| if (!projectPath) throw new Error('No project path'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.listIssues(projectPath); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to fetch issues'); |
| } |
| return { |
| openIssues: result.openIssues ?? [], |
| closedIssues: result.closedIssues ?? [], |
| }; |
| }, |
| enabled: !!projectPath, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function useGitHubPRs(projectPath: string | undefined) { |
| return useQuery({ |
| queryKey: queryKeys.github.prs(projectPath ?? ''), |
| queryFn: async (): Promise<GitHubPRsResult> => { |
| if (!projectPath) throw new Error('No project path'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.listPRs(projectPath); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to fetch PRs'); |
| } |
| return { |
| openPRs: result.openPRs ?? [], |
| mergedPRs: result.mergedPRs ?? [], |
| }; |
| }, |
| enabled: !!projectPath, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function useGitHubValidations(projectPath: string | undefined, issueNumber?: number) { |
| return useQuery({ |
| queryKey: issueNumber |
| ? queryKeys.github.validation(projectPath ?? '', issueNumber) |
| : queryKeys.github.validations(projectPath ?? ''), |
| queryFn: async (): Promise<StoredValidation[]> => { |
| if (!projectPath) throw new Error('No project path'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.getValidations(projectPath, issueNumber); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to fetch validations'); |
| } |
| return result.validations ?? []; |
| }, |
| enabled: !!projectPath, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function useGitHubRemote(projectPath: string | undefined) { |
| return useQuery({ |
| queryKey: queryKeys.github.remote(projectPath ?? ''), |
| queryFn: async () => { |
| if (!projectPath) throw new Error('No project path'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.checkRemote(projectPath); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to check remote'); |
| } |
| return { |
| hasRemote: result.hasGitHubRemote ?? false, |
| owner: result.owner, |
| repo: result.repo, |
| url: result.remoteUrl, |
| }; |
| }, |
| enabled: !!projectPath, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function useGitHubIssueComments( |
| projectPath: string | undefined, |
| issueNumber: number | undefined |
| ) { |
| return useInfiniteQuery({ |
| queryKey: queryKeys.github.issueComments(projectPath ?? '', issueNumber ?? 0), |
| queryFn: async ({ pageParam }: { pageParam: string | undefined }) => { |
| if (!projectPath || !issueNumber) throw new Error('Missing project path or issue number'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.getIssueComments(projectPath, issueNumber, pageParam); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to fetch comments'); |
| } |
| return { |
| comments: (result.comments ?? []) as GitHubComment[], |
| totalCount: result.totalCount ?? 0, |
| hasNextPage: result.hasNextPage ?? false, |
| endCursor: result.endCursor as string | undefined, |
| }; |
| }, |
| initialPageParam: undefined as string | undefined, |
| getNextPageParam: (lastPage) => (lastPage.hasNextPage ? lastPage.endCursor : undefined), |
| enabled: !!projectPath && !!issueNumber, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function useGitHubPRReviewComments( |
| projectPath: string | undefined, |
| prNumber: number | undefined |
| ) { |
| return useQuery({ |
| queryKey: queryKeys.github.prReviewComments(projectPath ?? '', prNumber ?? 0), |
| queryFn: async (): Promise<{ comments: PRReviewComment[]; totalCount: number }> => { |
| if (!projectPath || !prNumber) throw new Error('Missing project path or PR number'); |
| const api = getElectronAPI(); |
| if (!api.github) { |
| throw new Error('GitHub API not available'); |
| } |
| const result = await api.github.getPRReviewComments(projectPath, prNumber); |
| if (!result.success) { |
| throw new Error(result.error || 'Failed to fetch PR review comments'); |
| } |
| return { |
| comments: (result.comments ?? []) as PRReviewComment[], |
| totalCount: result.totalCount ?? 0, |
| }; |
| }, |
| enabled: !!projectPath && !!prNumber, |
| staleTime: STALE_TIMES.GITHUB, |
| }); |
| } |
|
|