gitdataai/src/hooks/useRepoDetailQuery.ts

259 lines
8.0 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
gitCommitLog,
gitBranchList,
gitTagList,
gitBranchSummary,
pullRequestList,
gitTreeList,
gitCommitGet,
gitDiffTreeToTree,
gitUpdateRepo,
branchProtectionList,
branchProtectionCreate,
branchProtectionUpdate,
branchProtectionDelete,
projectRepos,
} from "@/client/api";
const REPO_DETAIL_QUERY_KEY = "repoDetail";
const REPO_COMMITS_QUERY_KEY = "repoCommits";
const REPO_BRANCHES_QUERY_KEY = "repoBranches";
const REPO_TAGS_QUERY_KEY = "repoTags";
const REPO_BRANCH_SUMMARY_QUERY_KEY = "repoBranchSummary";
const REPO_PULLS_QUERY_KEY = "repoPulls";
const REPO_TREE_QUERY_KEY = "repoTree";
interface RepoParams {
namespace: string;
repo: string;
}
export function useRepoDetailQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [REPO_DETAIL_QUERY_KEY, namespace, repo],
queryFn: async () => {
return { namespace, repo };
},
enabled: !!namespace && !!repo,
});
}
interface RepoCommitsParams extends RepoParams {
page?: number;
perPage?: number;
}
export function useRepoCommitsQuery({
namespace,
repo,
page = 1,
perPage = 20,
}: RepoCommitsParams) {
return useQuery({
queryKey: [REPO_COMMITS_QUERY_KEY, namespace, repo, page, perPage],
queryFn: async () => {
const res = await gitCommitLog(namespace, repo, { page, per_page: perPage });
const body = res.data.data as unknown as { data: unknown[]; total: number; total_pages: number } | undefined;
const commits = body?.data ?? [];
const total = body?.total ?? commits.length;
return {
commits,
totalCount: total,
page,
totalPages: body?.total_pages ?? (Math.ceil(total / perPage) || 1),
};
},
enabled: !!namespace && !!repo,
});
}
export function useRepoBranchesQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [REPO_BRANCHES_QUERY_KEY, namespace, repo],
queryFn: async () => {
const res = await gitBranchList(namespace, repo);
return (res.data.data as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any[]) || [];
},
enabled: !!namespace && !!repo,
});
}
export function useRepoTagsQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [REPO_TAGS_QUERY_KEY, namespace, repo],
queryFn: async () => {
const res = await gitTagList(namespace, repo);
return (res.data.data as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any[]) || [];
},
enabled: !!namespace && !!repo,
});
}
export function useRepoBranchSummaryQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [REPO_BRANCH_SUMMARY_QUERY_KEY, namespace, repo],
queryFn: async () => {
const res = await gitBranchSummary(namespace, repo);
return (res.data.data as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any) || {};
},
enabled: !!namespace && !!repo,
});
}
export function useRepoPullsQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [REPO_PULLS_QUERY_KEY, namespace, repo],
queryFn: async () => {
const res = await pullRequestList(namespace, repo);
return ((res.data.data as unknown as { pull_requests?: unknown[] })?.pull_requests ?? []) as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any[];
},
enabled: !!namespace && !!repo,
});
}
interface RepoTreeParams extends RepoParams {
oid: string;
}
export function useRepoTreeQuery({ namespace, repo, oid }: RepoTreeParams) {
return useQuery({
queryKey: [REPO_TREE_QUERY_KEY, namespace, repo, oid],
queryFn: async () => {
const res = await gitTreeList(namespace, repo, oid);
return (res.data.data as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any[]) || [];
},
enabled: !!namespace && !!repo && !!oid,
});
}
const REPO_COMMIT_DETAIL_QUERY_KEY = "repoCommitDetail";
const REPO_COMMIT_DIFF_QUERY_KEY = "repoCommitDiff";
export function useRepoCommitDetailQuery({ namespace, repo, oid }: RepoTreeParams) {
return useQuery({
queryKey: [REPO_COMMIT_DETAIL_QUERY_KEY, namespace, repo, oid],
queryFn: async () => {
const res = await gitCommitGet(namespace, repo, oid);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return res.data.data as any;
},
enabled: !!namespace && !!repo && !!oid,
});
}
export function useRepoCommitDiffQuery({ namespace, repo, oid, baseOid }: RepoTreeParams & { baseOid?: string }) {
return useQuery({
queryKey: [REPO_COMMIT_DIFF_QUERY_KEY, namespace, repo, oid, baseOid],
queryFn: async () => {
const res = await gitDiffTreeToTree(namespace, repo, {
old_tree: baseOid || "",
new_tree: oid,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return res.data.data as any;
},
enabled: !!namespace && !!repo && !!oid,
});
}
// Repo Settings Hooks
export function useRepoInfoQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: ["repoInfo", namespace, repo],
queryFn: async () => {
const res = await projectRepos(namespace);
const items = res.data.data?.items ?? [];
return items.find((item) => item.repo_name === repo) ?? null;
},
enabled: !!namespace && !!repo,
});
}
export function useUpdateRepoSettingsMutation(namespace: string, repo: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (params: {
name?: string;
default_branch?: string;
ai_code_review_enabled?: boolean;
description?: string;
is_private?: boolean;
}) => {
return gitUpdateRepo(namespace, repo, params);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [REPO_DETAIL_QUERY_KEY, namespace, repo] });
queryClient.invalidateQueries({ queryKey: ["repoInfo", namespace, repo] });
},
});
}
// Branch Protection Hooks
const BRANCH_PROTECTION_QUERY_KEY = "branchProtection";
export function useBranchProtectionQuery({ namespace, repo }: RepoParams) {
return useQuery({
queryKey: [BRANCH_PROTECTION_QUERY_KEY, namespace, repo],
queryFn: async () => {
const res = await branchProtectionList(namespace, repo);
return (res.data.data as unknown as // eslint-disable-next-line @typescript-eslint/no-explicit-any
any[]) || [];
},
enabled: !!namespace && !!repo,
});
}
export function useCreateBranchProtectionMutation(namespace: string, repo: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (params: {
branch: string;
forbid_push?: boolean;
forbid_pull?: boolean;
forbid_merge?: boolean;
forbid_deletion?: boolean;
forbid_force_push?: boolean;
forbid_tag_push?: boolean;
required_approvals?: number;
dismiss_stale_reviews?: boolean;
require_linear_history?: boolean;
allow_fork_syncing?: boolean;
}) => {
return branchProtectionCreate(namespace, repo, params);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [BRANCH_PROTECTION_QUERY_KEY, namespace, repo] });
},
});
}
export function useUpdateBranchProtectionMutation(namespace: string, repo: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ id, ...params }: { id: number; [key: string]: unknown }) => {
return branchProtectionUpdate(namespace, repo, id, params);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [BRANCH_PROTECTION_QUERY_KEY, namespace, repo] });
},
});
}
export function useDeleteBranchProtectionMutation(namespace: string, repo: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (id: number) => {
return branchProtectionDelete(namespace, repo, id);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [BRANCH_PROTECTION_QUERY_KEY, namespace, repo] });
},
});
}