diff --git a/dashboard/src/skills/App.tsx b/dashboard/src/skills/App.tsx index ecb9e3789..ea78765d7 100644 --- a/dashboard/src/skills/App.tsx +++ b/dashboard/src/skills/App.tsx @@ -8,6 +8,7 @@ import { ResponsiveContainer, } from "recharts"; import { apiUrl } from "../shared/apiUrl"; +import { issuesUrl } from "./issuesUrl"; import { buildDaySeries, groupByTest, @@ -279,6 +280,16 @@ export default function App() {

Files: {selectedSkill.fileCount}

+

+ + View open issues for {selectedSkill.name} ↗ + +

{ + it("points at the repo's issue search", () => { + expect(issuesUrl("azure-deploy")).toContain( + "https://github.com/microsoft/GitHub-Copilot-for-Azure/issues?q=", + ); + }); + + it("filters to open issues labelled with the skill name", () => { + const url = issuesUrl("azure-deploy"); + const query = new URL(url).searchParams.get("q"); + expect(query).toBe('is:issue state:open label:"azure-deploy"'); + }); + + it("url-encodes skill names with special characters", () => { + const url = issuesUrl("foundry agent/create"); + // Raw skill name must not appear unencoded in the URL. + expect(url).not.toContain("foundry agent/create"); + const query = new URL(url).searchParams.get("q"); + expect(query).toBe('is:issue state:open label:"foundry agent/create"'); + }); +}); diff --git a/dashboard/src/skills/issuesUrl.ts b/dashboard/src/skills/issuesUrl.ts new file mode 100644 index 000000000..ff3eb9c12 --- /dev/null +++ b/dashboard/src/skills/issuesUrl.ts @@ -0,0 +1,11 @@ +/** Repository whose issues are surfaced from each skill page. */ +const ISSUES_REPO = "microsoft/GitHub-Copilot-for-Azure"; + +/** + * Build a GitHub search URL for the open issues labelled with a skill's name. + * The skill name is used verbatim as the label value. + */ +export function issuesUrl(skillName: string): string { + const query = `is:issue state:open label:"${skillName}"`; + return `https://github.com/${ISSUES_REPO}/issues?q=${encodeURIComponent(query)}`; +} diff --git a/dashboard/src/skills/skills.css b/dashboard/src/skills/skills.css index ea28b15cb..dee404703 100644 --- a/dashboard/src/skills/skills.css +++ b/dashboard/src/skills/skills.css @@ -83,6 +83,27 @@ font-size: 0.9rem; } +.skills-issues-link { + margin: 0.5rem 0 0; + font-size: 0.9rem; +} + +.skills-issues-link a { + color: var(--color-focus, #3b82f6); + text-decoration: none; +} + +.skills-issues-link a:hover { + text-decoration: underline; +} + +.skills-issues-link a:focus-visible { + outline: 2px solid var(--color-focus, #3b82f6); + outline-offset: 2px; + text-decoration: underline; + border-radius: 2px; +} + .skills-file-count { margin: 0; color: var(--color-text-muted);