From d8f5e05659fcb66d1f280724a88185470e418214 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Jul 2026 18:02:39 +0000
Subject: [PATCH 1/3] Initial plan
From 03d305fd3c6142f49998665753cbc0d0dbccd12e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Jul 2026 18:05:57 +0000
Subject: [PATCH 2/3] Group Attention Required sections
Co-authored-by: praveenkuttappan <55455725+praveenkuttappan@users.noreply.github.com>
---
.../release-plan-dashboard/public/index.html | 153 ++++++++++--------
tools/release-plan-dashboard/public/style.css | 25 +++
.../tests/pm-view-layout.test.js | 74 +++++++++
3 files changed, 186 insertions(+), 66 deletions(-)
create mode 100644 tools/release-plan-dashboard/tests/pm-view-layout.test.js
diff --git a/tools/release-plan-dashboard/public/index.html b/tools/release-plan-dashboard/public/index.html
index 85e65498b95..23f024bc547 100644
--- a/tools/release-plan-dashboard/public/index.html
+++ b/tools/release-plan-dashboard/public/index.html
@@ -644,76 +644,97 @@
PM View — Release Plan Health
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/release-plan-dashboard/public/style.css b/tools/release-plan-dashboard/public/style.css
index 0f1be01e475..1562b94675b 100644
--- a/tools/release-plan-dashboard/public/style.css
+++ b/tools/release-plan-dashboard/public/style.css
@@ -452,6 +452,31 @@ main {
opacity: 0.8;
}
+.pm-section-group {
+ border: 1px solid #e1dfdd;
+ border-radius: var(--radius);
+ background: #faf9f8;
+ padding: 16px 18px 8px;
+ margin-bottom: 20px;
+}
+
+.pm-section-group-header {
+ margin-bottom: 8px;
+}
+
+.pm-section-group-title {
+ margin: 0;
+ font-size: 1.1rem;
+ font-weight: 700;
+ color: var(--azure-dark);
+}
+
+.pm-section-group-desc {
+ margin: 4px 0 0;
+ color: var(--gray);
+ font-size: 0.9rem;
+}
+
.section-header {
cursor: pointer;
user-select: none;
diff --git a/tools/release-plan-dashboard/tests/pm-view-layout.test.js b/tools/release-plan-dashboard/tests/pm-view-layout.test.js
new file mode 100644
index 00000000000..f444cb1cb91
--- /dev/null
+++ b/tools/release-plan-dashboard/tests/pm-view-layout.test.js
@@ -0,0 +1,74 @@
+import { describe, expect, test } from "vitest";
+import { readFileSync } from "node:fs";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const indexHtml = readFileSync(
+ path.join(__dirname, "../public/index.html"),
+ "utf8",
+);
+
+function expectOrdered(block, labels) {
+ let lastIndex = -1;
+ for (const label of labels) {
+ const index = block.indexOf(label);
+ expect(index, `Expected to find "${label}"`).toBeGreaterThanOrEqual(0);
+ expect(index, `Expected "${label}" after prior sections`).toBeGreaterThan(
+ lastIndex,
+ );
+ lastIndex = index;
+ }
+}
+
+describe("PM View Attention Required layout", () => {
+ test("groups informational and action sections in the expected order", () => {
+ const informationalIndex = indexHtml.indexOf('id="pm-informational"');
+ const needsAttentionIndex = indexHtml.indexOf('id="pm-needs-attention"');
+
+ expect(informationalIndex).toBeGreaterThanOrEqual(0);
+ expect(indexHtml).toMatch(
+ /id="pm-informational"[\s\S]*?>\s*Informational\s*,
+ );
+ expect(needsAttentionIndex).toBeGreaterThanOrEqual(0);
+ expect(indexHtml).toMatch(
+ /id="pm-needs-attention"[\s\S]*?>\s*Needs Attention\s*,
+ );
+ expect(needsAttentionIndex).toBeGreaterThan(informationalIndex);
+
+ expectOrdered(indexHtml.slice(informationalIndex, needsAttentionIndex), [
+ "Recently Finished (Last 2",
+ "Approaching SDK Release",
+ ]);
+
+ expectOrdered(indexHtml.slice(needsAttentionIndex), [
+ "Ready to Complete Private",
+ "Past Due Release Plans",
+ "Stale Release Plans",
+ "Release Plans Without SDK",
+ "Partially Released",
+ "Missing Namespace Approval",
+ "Missing Product Details",
+ ]);
+ });
+
+ test("keeps each PM section present exactly once", () => {
+ const sectionIds = [
+ "section-pm-finished",
+ "section-pm-approaching",
+ "section-pm-pp-ready",
+ "section-pm-pastdue",
+ "section-pm-inactive",
+ "section-pm-tier1",
+ "section-pm-partial",
+ "section-pm-ns-missing",
+ "section-pm-product-missing",
+ ];
+
+ for (const sectionId of sectionIds) {
+ const matches =
+ indexHtml.match(new RegExp(`id="${sectionId}"`, "g")) || [];
+ expect(matches).toHaveLength(1);
+ }
+ });
+});
From c12f29690a021674ff4a10e11f03af8dc15f26ae Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Jul 2026 19:11:24 +0000
Subject: [PATCH 3/3] Update PM attention group order and collapse behavior
Co-authored-by: praveenkuttappan <55455725+praveenkuttappan@users.noreply.github.com>
---
.../release-plan-dashboard/public/index.html | 186 ++++++++++--------
tools/release-plan-dashboard/public/style.css | 16 ++
.../tests/pm-view-layout.test.js | 22 +--
3 files changed, 128 insertions(+), 96 deletions(-)
diff --git a/tools/release-plan-dashboard/public/index.html b/tools/release-plan-dashboard/public/index.html
index 23f024bc547..955ef9316b7 100644
--- a/tools/release-plan-dashboard/public/index.html
+++ b/tools/release-plan-dashboard/public/index.html
@@ -644,97 +644,113 @@ PM View — Release Plan Health
-
-
diff --git a/tools/release-plan-dashboard/public/style.css b/tools/release-plan-dashboard/public/style.css
index 1562b94675b..a40555a1660 100644
--- a/tools/release-plan-dashboard/public/style.css
+++ b/tools/release-plan-dashboard/public/style.css
@@ -464,6 +464,18 @@ main {
margin-bottom: 8px;
}
+.pm-section-group-header.section-header {
+ padding-top: 0;
+}
+
+.pm-section-group-header.section-header > div {
+ min-width: 0;
+}
+
+.pm-section-group-header.section-header:hover .pm-section-group-title {
+ color: var(--azure-blue);
+}
+
.pm-section-group-title {
margin: 0;
font-size: 1.1rem;
@@ -477,6 +489,10 @@ main {
font-size: 0.9rem;
}
+.pm-section-group.collapsed > .pm-section-group-content {
+ display: none !important;
+}
+
.section-header {
cursor: pointer;
user-select: none;
diff --git a/tools/release-plan-dashboard/tests/pm-view-layout.test.js b/tools/release-plan-dashboard/tests/pm-view-layout.test.js
index f444cb1cb91..089100ade08 100644
--- a/tools/release-plan-dashboard/tests/pm-view-layout.test.js
+++ b/tools/release-plan-dashboard/tests/pm-view-layout.test.js
@@ -26,22 +26,17 @@ describe("PM View Attention Required layout", () => {
const informationalIndex = indexHtml.indexOf('id="pm-informational"');
const needsAttentionIndex = indexHtml.indexOf('id="pm-needs-attention"');
- expect(informationalIndex).toBeGreaterThanOrEqual(0);
+ expect(needsAttentionIndex).toBeGreaterThanOrEqual(0);
expect(indexHtml).toMatch(
- /id="pm-informational"[\s\S]*?>\s*Informational\s*,
+ /aria-labelledby="pm-needs-attention"[\s\S]*class="pm-section-group-header section-header"[\s\S]*data-target="list-pm-needs-attention"[\s\S]*id="pm-needs-attention"[\s\S]*>\s*Needs Attention\s*,
);
- expect(needsAttentionIndex).toBeGreaterThanOrEqual(0);
+ expect(informationalIndex).toBeGreaterThanOrEqual(0);
expect(indexHtml).toMatch(
- /id="pm-needs-attention"[\s\S]*?>\s*Needs Attention\s*,
+ /aria-labelledby="pm-informational"[\s\S]*class="pm-section-group-header section-header"[\s\S]*data-target="list-pm-informational"[\s\S]*id="pm-informational"[\s\S]*>\s*Informational\s*,
);
- expect(needsAttentionIndex).toBeGreaterThan(informationalIndex);
-
- expectOrdered(indexHtml.slice(informationalIndex, needsAttentionIndex), [
- "Recently Finished (Last 2",
- "Approaching SDK Release",
- ]);
+ expect(informationalIndex).toBeGreaterThan(needsAttentionIndex);
- expectOrdered(indexHtml.slice(needsAttentionIndex), [
+ expectOrdered(indexHtml.slice(needsAttentionIndex, informationalIndex), [
"Ready to Complete Private",
"Past Due Release Plans",
"Stale Release Plans",
@@ -50,6 +45,11 @@ describe("PM View Attention Required layout", () => {
"Missing Namespace Approval",
"Missing Product Details",
]);
+
+ expectOrdered(indexHtml.slice(informationalIndex), [
+ "Recently Finished (Last 2",
+ "Approaching SDK Release",
+ ]);
});
test("keeps each PM section present exactly once", () => {