mirror of
https://github.com/github/awesome-copilot.git
synced 2026-10-15 08:11:44 +00:00
fix(canvases): dismiss previews and enable PR card dragging
Close review board previews after successful item actions and outside clicks without dismissing a different item during in-flight requests. Explicitly enable native dragging on editable PR cards and add regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cd29e26b-0e56-48bf-a046-ac749aef86ce
This commit is contained in:
co-authored by
Copilot App
parent
764b3829bf
commit
a10206b7f6
@@ -26,6 +26,8 @@ Open it by asking Copilot to "open the plugin review board" (canvas id `external
|
||||
Fast-track never overrides an existing review or a bucket you chose; drag a card to *Unreviewed* to opt it
|
||||
out and have it reviewed normally. Cards show *First party* / *Third party* pills from the intake labels.
|
||||
- **Details panel** shows the AI review, the rendered issue body, and all comments.
|
||||
Clicking outside the panel or successfully submitting an item action closes it;
|
||||
failed actions leave it open so you can correct or retry them.
|
||||
- **Quick actions** post `/approve` (with an optional note) or `/reject <reason>` straight to the issue
|
||||
after a confirm click. The reject reason is prefilled from the AI's suggested comment.
|
||||
- **Column actions** approve, reject, or re-review every eligible item in a column, including
|
||||
@@ -60,3 +62,4 @@ Run `node --experimental-vm-modules --test eng/board-state-storage.test.mjs` fro
|
||||
to check both canvases' session-scoped persistence without accessing GitHub.
|
||||
Run `node --test eng/board-bulk-actions.test.mjs` to check column confirmation, staged feedback,
|
||||
queue exclusions, and partial failures using in-process fakes.
|
||||
Run `node --test eng/board-preview.test.mjs` to check preview dismissal and in-flight actions.
|
||||
|
||||
@@ -261,6 +261,7 @@ async function bulkAction(columnId, kind) {
|
||||
}
|
||||
await api("POST", "/api/decision", { ...item, kind });
|
||||
completed++;
|
||||
if (selected === item.number) closeDrawer();
|
||||
} catch (error) {
|
||||
failures.push(`#${item.number}: ${error.message}`);
|
||||
}
|
||||
@@ -343,6 +344,7 @@ async function moveItem(number, column) {
|
||||
const hadReview = column === "unreviewed" && Boolean(findItem(number)?.review);
|
||||
try {
|
||||
await api("POST", "/api/move", { number, column });
|
||||
if (selected === number) closeDrawer();
|
||||
if (hadReview) toast(`Cleared the AI review for #${number}; it will be included in the next review.`);
|
||||
} catch (error) {
|
||||
toast(error.message, { error: true });
|
||||
@@ -616,10 +618,11 @@ async function decide(kind) {
|
||||
: `Posted ${result.body.split("\n")[0]} on #${item.number}`,
|
||||
{ link: result.commentUrl },
|
||||
);
|
||||
if (selected === item.number) closeDrawer();
|
||||
} catch (error) {
|
||||
toast(error.message, { error: true });
|
||||
} finally {
|
||||
resetConfirm();
|
||||
if (selected === item.number) resetConfirm();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,6 +675,9 @@ ui.search.addEventListener("input", () => {
|
||||
});
|
||||
|
||||
ui.drawerClose.addEventListener("click", closeDrawer);
|
||||
document.addEventListener("pointerdown", (event) => {
|
||||
if (selected !== null && !ui.drawer.contains(event.target)) closeDrawer();
|
||||
}, true);
|
||||
ui.drawerMove.addEventListener("change", () => moveItem(selected, ui.drawerMove.value));
|
||||
function hideRereview() {
|
||||
ui.rereviewPanel.hidden = true;
|
||||
@@ -711,7 +717,7 @@ ui.rereviewPanel.addEventListener("submit", async (event) => {
|
||||
try {
|
||||
const result = await api("POST", "/api/rereview", { number, guidance: ui.rereviewGuidance.value });
|
||||
toast(result.message);
|
||||
hideRereview();
|
||||
if (selected === number) closeDrawer();
|
||||
} catch (error) {
|
||||
toast(error.message, { error: true });
|
||||
} finally {
|
||||
|
||||
@@ -32,6 +32,8 @@ authenticated `gh` CLI.
|
||||
- **Detail drawer** — AI review, description, conversation, changed files, and checks.
|
||||
Keyboard focus stays inside the modal drawer and returns to its card on close.
|
||||
Use Left/Right arrows or Home/End to switch detail tabs.
|
||||
Clicking outside the drawer or successfully submitting an item action closes it;
|
||||
failed actions leave it open so you can correct or retry them.
|
||||
- **GitHub actions** — submit feedback, request changes, close a PR, or approve it and
|
||||
enable auto-merge with a merge commit. Each action needs two clicks to confirm and
|
||||
is also recorded in local board history. Approval is pinned to the board's commit
|
||||
@@ -92,5 +94,7 @@ Run `node --test eng/open-pr-board.test.mjs` from the repository root. GitHub wr
|
||||
are tested with injected in-process fakes, never the authenticated CLI.
|
||||
Run `node --test eng/board-bulk-actions.test.mjs` to check column confirmation, staged feedback,
|
||||
queue exclusions, and partial failures using in-process fakes.
|
||||
Run `node --test eng/board-preview.test.mjs` to check preview dismissal and in-flight actions.
|
||||
Run `node --test eng/open-pr-board-drag.test.mjs` to check native card dragging and transfer data.
|
||||
Run `node --experimental-vm-modules --test eng/board-state-storage.test.mjs` to check
|
||||
both canvases' session-scoped persistence without accessing GitHub.
|
||||
|
||||
@@ -241,7 +241,7 @@ function renderCard(item) {
|
||||
"article",
|
||||
{
|
||||
class: item.number === selectedNumber ? "card selected" : "card",
|
||||
draggable: !item.decision,
|
||||
draggable: item.decision ? "false" : "true",
|
||||
dataset: { number: String(item.number) },
|
||||
tabindex: "0",
|
||||
role: "button",
|
||||
@@ -402,6 +402,7 @@ async function bulkAction(columnId, kind) {
|
||||
method: "POST", body: { number: item.number, kind, comment: item.comment },
|
||||
});
|
||||
completed++;
|
||||
if (selectedNumber === item.number) closeDrawer();
|
||||
if (result.warning) failures.push(`#${item.number}: ${result.warning}`);
|
||||
} catch (error) {
|
||||
failures.push(`#${item.number}: ${error.message}`);
|
||||
@@ -436,12 +437,14 @@ function reviewTab(item) {
|
||||
{
|
||||
class: "btn btn-small btn-primary",
|
||||
type: "button",
|
||||
onclick: (event) =>
|
||||
run(
|
||||
onclick: async (event) => {
|
||||
const result = await run(
|
||||
event.currentTarget,
|
||||
() => api("/api/review", { method: "POST", body: { numbers: [item.number] } }),
|
||||
(result) => result.message ?? "Review requested.",
|
||||
),
|
||||
);
|
||||
if (result && selectedNumber === item.number) closeDrawer();
|
||||
},
|
||||
},
|
||||
"Review this PR",
|
||||
),
|
||||
@@ -728,12 +731,12 @@ async function submitDecision(button, kind) {
|
||||
api("/api/decision", { method: "POST", body: { number: item.number, kind, comment } }),
|
||||
);
|
||||
decisionsInFlight.delete(item.number);
|
||||
renderDrawerHeader();
|
||||
if (selectedNumber === item.number) renderDrawerHeader();
|
||||
button.textContent = DECISION_BUTTONS[kind];
|
||||
if (result) {
|
||||
if (result.warning) toast(result.warning, { error: true, url: result.url });
|
||||
else toast(`#${item.number}: ${result.status}.`, { url: result.url });
|
||||
if (currentItem()) loadDetail(item.number, { force: true });
|
||||
if (selectedNumber === item.number) closeDrawer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,6 +781,10 @@ el.review.addEventListener("click", (event) =>
|
||||
|
||||
el.drawerClose.addEventListener("click", closeDrawer);
|
||||
|
||||
document.addEventListener("pointerdown", (event) => {
|
||||
if (selectedNumber !== null && !el.drawer.contains(event.target)) closeDrawer();
|
||||
}, true);
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (!el.drawer.classList.contains("open")) return;
|
||||
if (event.key === "Escape") {
|
||||
@@ -806,6 +813,7 @@ el.drawerColumn.addEventListener("change", async (event) => {
|
||||
if (column === item.column) return;
|
||||
try {
|
||||
await api("/api/move", { method: "POST", body: { number: item.number, column } });
|
||||
if (selectedNumber === item.number) closeDrawer();
|
||||
} catch (error) {
|
||||
toast(error.message, { error: true });
|
||||
event.target.value = item.column;
|
||||
@@ -855,9 +863,10 @@ el.rereviewStart.addEventListener("click", async (event) => {
|
||||
}),
|
||||
(value) => value.message ?? "Re-review requested.",
|
||||
);
|
||||
if (result) {
|
||||
if (result && selectedNumber === item.number) {
|
||||
el.rereviewGuidance.value = "";
|
||||
el.rereviewPanel.hidden = true;
|
||||
closeDrawer();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user