Skip to content

Commit 0bc2627

Browse files
committed
Add a button: Create Issues & PRs in coverage dashboard actions button
1 parent e54062e commit 0bc2627

File tree

3 files changed

+86
-9
lines changed

3 files changed

+86
-9
lines changed

app/api/github/create-coverage-issues/route.ts

+65-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextResponse } from "next/server";
22
import { getGraphQL } from "@/app/api/github";
33
import { CoverageData } from "@/app/dashboard/coverage/types";
4-
import { ABSOLUTE_URLS } from "@/config";
4+
import { ABSOLUTE_URLS, PRODUCT_ID } from "@/config";
55
import { supabase } from "@/lib/supabase";
66

77
type CreateIssueResponse = {
@@ -13,9 +13,17 @@ type CreateIssueResponse = {
1313
};
1414
};
1515

16+
type CreateLabelResponse = {
17+
createLabel: {
18+
label: {
19+
id: string;
20+
};
21+
};
22+
};
23+
1624
export async function POST(request: Request) {
1725
try {
18-
const { selectedCoverages, ownerName, repoName, accessToken, parentNodeId } =
26+
const { selectedCoverages, ownerName, repoName, accessToken, parentNodeId, hasLabel } =
1927
await request.json();
2028

2129
if (!selectedCoverages?.length || !ownerName || !repoName || !accessToken || !parentNodeId) {
@@ -31,19 +39,68 @@ export async function POST(request: Request) {
3139

3240
const graphqlClient = getGraphQL(accessToken);
3341

34-
// Get repository Node ID
35-
const getRepoId = await graphqlClient<{ repository: { id: string } }>(
42+
// Get repository Node ID and label ID if needed
43+
const getRepoAndLabel = await graphqlClient<{
44+
repository: {
45+
id: string;
46+
labels?: {
47+
nodes: Array<{
48+
id: string;
49+
name: string;
50+
}>;
51+
};
52+
};
53+
}>(
3654
`
37-
query getRepoId($owner: String!, $name: String!) {
55+
query getRepoAndLabel($owner: String!, $name: String!, $labelName: String!) {
3856
repository(owner: $owner, name: $name) {
3957
id
58+
labels(first: 1, query: $labelName) {
59+
nodes {
60+
id
61+
name
62+
}
63+
}
4064
}
4165
}
4266
`,
43-
{ owner: ownerName, name: repoName }
67+
{ owner: ownerName, name: repoName, labelName: PRODUCT_ID || "" }
4468
);
4569

46-
const repositoryId = getRepoId.repository.id;
70+
const repositoryId = getRepoAndLabel.repository.id;
71+
const labels = getRepoAndLabel.repository.labels?.nodes;
72+
console.log("labels: ", labels);
73+
let labelId =
74+
hasLabel && PRODUCT_ID ? labels?.find((label) => label.name === PRODUCT_ID)?.id : null;
75+
76+
// If label doesn't exist but is needed, create it
77+
if (hasLabel && PRODUCT_ID && !labelId) {
78+
try {
79+
const createLabelResponse = await graphqlClient<CreateLabelResponse>(
80+
`
81+
mutation createLabel($input: CreateLabelInput!) {
82+
createLabel(input: $input) {
83+
label {
84+
id
85+
}
86+
}
87+
}
88+
`,
89+
{
90+
input: {
91+
repositoryId,
92+
name: PRODUCT_ID,
93+
color: "EC4899", // GitAuto brand color (pink)
94+
description: "Issues to be handled by GitAuto",
95+
},
96+
}
97+
);
98+
labelId = createLabelResponse.createLabel.label.id;
99+
} catch (error) {
100+
console.error("Failed to create label:", error);
101+
// If label creation fails, continue with issue creation
102+
}
103+
}
47104

48105
const createdIssues = await Promise.all(
49106
selectedCoverages.map(async (coverage: CoverageData) => {
@@ -91,6 +148,7 @@ View full coverage details in the [Coverage Dashboard](${ABSOLUTE_URLS.GITAUTO.C
91148
title,
92149
body,
93150
...(parentNodeId && { parentIssueId: parentNodeId }),
151+
...(labelId && { labelIds: [labelId] }),
94152
},
95153
}
96154
);

app/dashboard/coverage/page.tsx

+19-2
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,7 @@ export default function CoveragePage() {
220220
}
221221
};
222222

223-
// handleCreateIssuesを修正
224-
const handleCreateIssues = async () => {
223+
const handleCreateIssues = async ({ hasLabel = false } = {}) => {
225224
if (selectedRows.length === 0) return;
226225

227226
setIsCreatingIssues(true);
@@ -239,6 +238,7 @@ export default function CoveragePage() {
239238
repoName: currentRepoName,
240239
accessToken,
241240
parentNodeId: selectedParentIssue?.id,
241+
hasLabel,
242242
}),
243243
}
244244
);
@@ -540,6 +540,23 @@ export default function CoveragePage() {
540540
`Create Issues (${selectedRows.length})`
541541
)}
542542
</button>
543+
<button
544+
onClick={() => {
545+
handleCreateIssues({ hasLabel: true });
546+
setIsActionsOpen(false);
547+
}}
548+
className="w-full px-4 py-2 text-left hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2 whitespace-nowrap min-w-[200px]"
549+
disabled={isCreatingIssues || selectedRows.length === 0}
550+
>
551+
{isCreatingIssues ? (
552+
<>
553+
<SpinnerIcon />
554+
<span>Creating Issues & PRs...</span>
555+
</>
556+
) : (
557+
`Create Issues & PRs (${selectedRows.length})`
558+
)}
559+
</button>
543560
</div>
544561
</>
545562
)}

config/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const isPrd = process.env.NODE_ENV === "production";
22

33
// GitAuto Constants
44
export const EMAIL = "[email protected]";
5+
export const PRODUCT_ID = process.env.NEXT_PUBLIC_PRODUCT_ID
56
export const PRODUCT_NAME = "GitAuto";
67
export const DESCRIPTION =
78
"GitAuto, an AI Coding Agent, helps engineering teams facing resource constraints and hiring challenges to fix more bugs and ship more features by automatically writing code and creating GitHub pull requests from your GitHub and Jira issues every day.";
@@ -85,6 +86,7 @@ export const ABSOLUTE_URLS = {
8586
GITAUTO: {
8687
INDEX: "https://gitauto.ai",
8788
COVERAGES: `${NEXT_PUBLIC_SITE_URL}${RELATIVE_URLS.COVERAGES}`,
89+
PRICING: `${NEXT_PUBLIC_SITE_URL}${RELATIVE_URLS.PRICING}`,
8890
THUMBNAIL: "https://gitauto.ai/homepage/thumbnail.jpg",
8991
},
9092
GITHUB: {

0 commit comments

Comments
 (0)