gitdataai/src/hooks/useIssueExtraQuery.ts

351 lines
12 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
issueAssigneeList,
issueAssigneeAdd,
issueAssigneeRemove,
issueClose,
issueDelete as apiIssueDelete,
issueReopen,
issueUpdate,
issueLabelList,
issueLabelAdd,
issueLabelAddBulk,
issueLabelRemove,
issuePullRequestList,
issuePullRequestLink,
issuePullRequestUnlink,
issueReactionList,
issueRepoList,
issueRepoLink,
issueRepoUnlink,
issueSubscriberList,
issueSubscribe,
issueUnsubscribe,
projectLabels,
labelCreate,
labelList as apiLabelList,
labelDelete as apiLabelDelete,
} from "@/client/api";
import type {
IssueAssigneeResponse,
IssueLabelResponse,
IssuePullRequestResponse,
IssueRepoResponse,
IssueSubscriberResponse,
ReactionListResponse,
LabelResponse,
CreateLabelRequest,
IssueUpdateRequest,
} from "@/client/model";
const ISSUE_QUERY_KEY = "issue";
interface IssueParams {
projectName: string;
issueNumber: number;
}
// Assignees
export function useIssueAssigneesQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "assignees"],
queryFn: async (): Promise<IssueAssigneeResponse[]> => {
const res = await issueAssigneeList(projectName, issueNumber);
return res.data.data ?? [];
},
enabled: !!projectName && !!issueNumber,
});
}
export function useAddAssigneeMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, userId }: IssueParams & { userId: string }) => {
await issueAssigneeAdd(projectName, issueNumber, { user_id: userId });
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "assignees"] });
},
});
}
export function useRemoveAssigneeMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, userId }: IssueParams & { userId: string }) => {
await issueAssigneeRemove(projectName, issueNumber, userId);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "assignees"] });
},
});
}
// Labels
export function useIssueLabelsQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "labels"],
queryFn: async (): Promise<IssueLabelResponse[]> => {
const res = await issueLabelList(projectName, issueNumber);
return res.data.data ?? [];
},
enabled: !!projectName && !!issueNumber,
});
}
export function useAddIssueLabelMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, labelId }: IssueParams & { labelId: number }) => {
await issueLabelAdd(projectName, issueNumber, { label_id: labelId });
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "labels"] });
},
});
}
export function useRemoveIssueLabelMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, labelId }: IssueParams & { labelId: number }) => {
await issueLabelRemove(projectName, issueNumber, labelId);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "labels"] });
},
});
}
// Project Labels
export function useProjectLabelsQuery(projectName: string) {
return useQuery({
queryKey: ["project", projectName, "labels"],
queryFn: async (): Promise<LabelResponse[]> => {
const res = await projectLabels(projectName);
return res.data.data?.labels ?? [];
},
enabled: !!projectName,
});
}
export function useCreateLabelMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, req }: { projectName: string, req: CreateLabelRequest }) => {
await labelCreate(projectName, req);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ["project", variables.projectName, "labels"] });
},
});
}
// Reactions
export function useIssueReactionsQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "reactions"],
queryFn: async (): Promise<ReactionListResponse | null> => {
const res = await issueReactionList(projectName, issueNumber);
return res.data.data ?? null;
},
enabled: !!projectName && !!issueNumber,
});
}
// Subscribers
export function useIssueSubscribersQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "subscribers"],
queryFn: async (): Promise<IssueSubscriberResponse[]> => {
const res = await issueSubscriberList(projectName, issueNumber);
return res.data.data ?? [];
},
enabled: !!projectName && !!issueNumber,
});
}
export function useIssueSubscribeMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber }: IssueParams) => {
await issueSubscribe(projectName, issueNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "subscribers"] });
},
});
}
// PRs & Repos
export function useIssuePRsQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "prs"],
queryFn: async (): Promise<IssuePullRequestResponse[]> => {
const res = await issuePullRequestList(projectName, issueNumber);
return res.data.data ?? [];
},
enabled: !!projectName && !!issueNumber,
});
}
export function useIssueReposQuery({ projectName, issueNumber }: IssueParams) {
return useQuery({
queryKey: [ISSUE_QUERY_KEY, projectName, issueNumber, "repos"],
queryFn: async (): Promise<IssueRepoResponse[]> => {
const res = await issueRepoList(projectName, issueNumber);
return res.data.data ?? [];
},
enabled: !!projectName && !!issueNumber,
});
}
// Close/Reopen/Update/Delete
export function useCloseIssueMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber }: IssueParams) => {
await issueClose(projectName, issueNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber] });
},
});
}
export function useReopenIssueMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber }: IssueParams) => {
await issueReopen(projectName, issueNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber] });
},
});
}
export function useUpdateIssueMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, req }: IssueParams & { req: IssueUpdateRequest }) => {
await issueUpdate(projectName, issueNumber, req);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber] });
},
});
}
export function useDeleteIssueMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber }: IssueParams) => {
await apiIssueDelete(projectName, issueNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber] });
},
});
}
// Bulk Label Add
export function useAddIssueLabelsBulkMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, labelNames }: IssueParams & { labelNames: string[] }) => {
await issueLabelAddBulk(projectName, issueNumber, { names: labelNames });
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "labels"] });
},
});
}
// PR Link/Unlink
export function useLinkPRMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, repo, prNumber }: IssueParams & { repo: string; prNumber: number }) => {
await issuePullRequestLink(projectName, issueNumber, { repo, number: prNumber });
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "prs"] });
},
});
}
export function useUnlinkPRMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, repo, prNumber }: IssueParams & { repo: string; prNumber: number }) => {
await issuePullRequestUnlink(projectName, issueNumber, repo, prNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "prs"] });
},
});
}
// Repo Link/Unlink
export function useLinkRepoMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, repo }: IssueParams & { repo: string }) => {
await issueRepoLink(projectName, issueNumber, { repo });
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "repos"] });
},
});
}
export function useUnlinkRepoMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber, repoId }: IssueParams & { repoId: string }) => {
await issueRepoUnlink(projectName, issueNumber, repoId);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "repos"] });
},
});
}
// Unsubscribe
export function useIssueUnsubscribeMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, issueNumber }: IssueParams) => {
await issueUnsubscribe(projectName, issueNumber);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: [ISSUE_QUERY_KEY, variables.projectName, variables.issueNumber, "subscribers"] });
},
});
}
// Label List/Delete (project level)
export function useLabelsQuery(projectName: string) {
return useQuery({
queryKey: ["project", projectName, "labels"],
queryFn: async () => {
const res = await apiLabelList(projectName);
return res.data.data ?? [];
},
enabled: !!projectName,
});
}
export function useDeleteLabelMutation() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async ({ projectName, labelId }: { projectName: string; labelId: number }) => {
await apiLabelDelete(projectName, labelId);
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ["project", variables.projectName, "labels"] });
},
});
}