-
Notifications
You must be signed in to change notification settings - Fork 1
Get and display integrated repositories on a Jira ticket #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,10 +1,12 @@ | ||||||
import React, { useEffect, useState } from "react"; | ||||||
import ForgeReconciler, { Select, Text, useProductContext } from "@forge/react"; | ||||||
import { requestJira } from "@forge/bridge"; | ||||||
import { invoke } from "@forge/bridge"; | ||||||
|
||||||
const App = () => { | ||||||
// Get Jira cloud ID (== workspace ID) | ||||||
const context = useProductContext(); | ||||||
|
||||||
// Get Jira cloud ID | ||||||
const [cloudId, setCloudId] = useState(null); | ||||||
useEffect(() => { | ||||||
if (context) { | ||||||
|
@@ -14,17 +16,47 @@ const App = () => { | |||||
} | ||||||
}, [context]); | ||||||
|
||||||
// Get Jira project ID | ||||||
const [projectId, setProjectId] = useState(null); | ||||||
useEffect(() => { | ||||||
if (context) setProjectId(context.extension.project.id); | ||||||
}, [context]); | ||||||
|
||||||
// Get corresponding GitHub repositories from Supabase | ||||||
const [githubRepos, setGithubRepos] = useState([]); | ||||||
useEffect(() => { | ||||||
const fetchRepositories = async () => { | ||||||
if (cloudId && projectId) { | ||||||
try { | ||||||
const response = await invoke("getGithubRepos", { | ||||||
cloudId, | ||||||
projectId, | ||||||
}); | ||||||
|
||||||
// response will be an array of repositories from Supabase | ||||||
setGithubRepos( | ||||||
response.map((repo) => `${repo.github_owner_name}/${repo.github_repo_name}`) | ||||||
); | ||||||
} catch (error) { | ||||||
console.error("Error fetching repositories:", error); | ||||||
setGithubRepos([]); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Add user-facing error feedback when repository fetching fails Consider showing an error message in the UI to inform users when repositories cannot be loaded. setGithubRepos([]);
setError("Unable to load repositories. Please try again later."); |
||||||
} | ||||||
} | ||||||
}; | ||||||
|
||||||
fetchRepositories(); | ||||||
}, [cloudId, projectId]); | ||||||
|
||||||
// Get repository list where GitAuto is installed | ||||||
const repositories = ["gitautoai/gitauto", "gitautoai/gitauto-jira"]; | ||||||
const [selectedRepo, setSelectedRepo] = useState(repositories[0]); | ||||||
const [selectedRepo, setSelectedRepo] = useState(githubRepos[0]); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider handling the case where githubRepos is empty to avoid setting undefined as the initial value You could set it to null or provide a placeholder value when the array is empty.
Suggested change
|
||||||
|
||||||
return ( | ||||||
<> | ||||||
<Text>Target GitHub Repository:</Text> | ||||||
<Select | ||||||
value={selectedRepo} | ||||||
onChange={setSelectedRepo} | ||||||
options={repositories.map((repo) => ({ label: repo, value: repo }))} | ||||||
options={githubRepos.map((repo) => ({ label: repo, value: repo }))} | ||||||
/> | ||||||
</> | ||||||
); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,35 @@ | ||
import Resolver from '@forge/resolver'; | ||
import Resolver from "@forge/resolver"; | ||
import forge from "@forge/api"; | ||
|
||
const resolver = new Resolver(); | ||
|
||
resolver.define('getText', (req) => { | ||
console.log(req); | ||
return 'Hello, world!'; | ||
// https://developer.atlassian.com/platform/forge/runtime-reference/forge-resolver/ | ||
resolver.define("getGithubRepos", async ({ payload }) => { | ||
const { cloudId, projectId } = payload; | ||
|
||
// https://supabase.com/docs/guides/api/sql-to-rest | ||
const queryParams = new URLSearchParams({ | ||
select: "*", | ||
jira_site_id: `eq.${cloudId}`, | ||
jira_project_id: `eq.${projectId}`, | ||
}).toString(); | ||
const url = `${process.env.SUPABASE_URL}/rest/v1/jira_github_links?${queryParams}`; | ||
console.log(url); | ||
|
||
const response = await forge.fetch(url, { | ||
method: "GET", | ||
headers: { | ||
apikey: process.env.SUPABASE_API_KEY, | ||
Authorization: `Bearer ${process.env.SUPABASE_API_KEY}`, | ||
"Content-Type": "application/json", | ||
}, | ||
}); | ||
|
||
if (!response.ok) throw new Error(`Failed to fetch repositories: ${response.status}`); | ||
|
||
const data = await response.json(); | ||
console.log(data); | ||
return data; | ||
}); | ||
|
||
export const handler = resolver.getDefinitions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider consolidating the multiple state variables and effects into a single custom hook for managing GitHub repository data
The current implementation uses multiple chained useEffect hooks and state variables that could be simplified into a single custom hook. Here's how to reduce complexity while maintaining functionality:
Then simplify the App component:
This approach: