From 6f316fa0bdc6b0bd80289ad8675d4901cbbcca64 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 20 May 2026 12:01:57 +0200 Subject: [PATCH] feat(extension): rework merge-box queue row to match GitHub native styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse Primer utility classes (bgColor-muted, borderColor-muted, border-top, rounded-bottom-2) and the --base-size-16 padding token, so the Mergify row sits flush against GH's own "Merge pull request" section in the merge box instead of inheriting the darker page bg with an ad-hoc border-top. Restructure the row so it reads like a GH action panel: [Add to merge queue] [Refresh] [Rebase] [Update] ☰ queue 🕓 logs [● Mergify] - All action buttons grouped on the left (matches GH's "Squash and merge" + chevron block). - Right cluster holds the navigation: queue/logs links with Octicon prefixes (list-unordered for queue, clock for logs) so they read as first-class nav rather than metadata, and the logo+Mergify text fused into one anchor linking to dashboard.mergify.com. - Primary/dequeue labels expanded ("Add to merge queue" / "Remove from merge queue") so the primary button has the same visual weight as GitHub's merge button and clearly states what it does. - 24px effective left padding so the primary button doesn't crowd the card edge. Co-Authored-By: Claude Opus 4.7 (1M context) Change-Id: I41e4c5e0a527bea4915e4bff37b04402a58f8fe6 --- src/queue.js | 108 ++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/src/queue.js b/src/queue.js index 508ff30..f81d939 100644 --- a/src/queue.js +++ b/src/queue.js @@ -4,6 +4,10 @@ import { getPullRequestData, isGitHubPullRequestPage } from "./dom.js"; import { getLogoSvg, parseSvg } from "./logo.js"; import { resetStackState } from "./stacks.js"; +const QUEUE_ICON_SVG = ``; + +const LOGS_ICON_SVG = ``; + export const BUTTONS = [ { command: "refresh", @@ -365,7 +369,9 @@ export function buildQueueButton(state) { case "dequeuing": btn = buildMergeBoxButton( state === "queuing" ? "queue" : "dequeue", - state === "queuing" ? "Queuing…" : "Dequeuing…", + state === "queuing" + ? "Adding to merge queue…" + : "Removing from merge queue…", "Waiting for Mergify to process…", true, "secondary", @@ -374,7 +380,7 @@ export function buildQueueButton(state) { case "queued": btn = buildMergeBoxButton( "dequeue", - "Dequeue", + "Remove from merge queue", "Remove the pull request from the merge queue", false, "danger", @@ -384,7 +390,7 @@ export function buildQueueButton(state) { default: btn = buildMergeBoxButton( "queue", - "Queue", + "Add to merge queue", "Add the pull request to the merge queue", false, "primary", @@ -411,76 +417,72 @@ export function buildMergifyRow() { const row = document.createElement("div"); row.id = "mergify"; + row.className = + "bgColor-muted borderColor-muted border-top rounded-bottom-2"; row.style.cssText = - "padding:10px 16px;border-top:1px solid var(--borderColor-default, #30363d);display:flex;align-items:center;gap:10px;"; + "display:flex;align-items:center;gap:8px;padding:var(--base-size-16,16px)!important;"; - const logo = document.createElement("div"); - logo.style.cssText = "flex-shrink:0;display:flex;"; - const svgEl = parseSvg(getLogoSvg()); - svgEl.setAttribute("width", "20"); - svgEl.setAttribute("height", "20"); - logo.appendChild(svgEl); - row.appendChild(logo); + if (state !== "merged" && state !== "closed") { + const buttons = document.createElement("div"); + buttons.style.cssText = "display:flex;gap:6px;"; + buttons.appendChild(buildQueueButton(state)); + for (const btn of BUTTONS) { + buttons.appendChild( + buildMergeBoxButton( + btn.command, + btn.label, + btn.tooltip, + false, + "secondary", + ), + ); + } + row.appendChild(buttons); + } const info = document.createElement("div"); info.style.cssText = - "flex:1;display:flex;align-items:center;gap:6px;font-size:13px;"; - - const label = document.createElement("span"); - label.style.fontWeight = "600"; - label.textContent = "Mergify"; - info.appendChild(label); - - function appendDot() { - const dot = document.createElement("span"); - dot.style.color = "var(--fgColor-muted, #7d8590)"; - dot.textContent = "·"; - info.appendChild(dot); - } + "display:flex;align-items:center;gap:12px;font-size:14px;margin-left:auto;"; - function appendLink(href, text) { - appendDot(); + function appendLink(href, text, iconSvg) { const link = document.createElement("a"); link.href = href; link.target = "_blank"; link.rel = "noopener noreferrer"; - link.textContent = text; link.style.cssText = - "color:var(--fgColor-accent, #58a6ff);text-decoration:none;font-size:12px;"; + "color:var(--fgColor-accent, #58a6ff);text-decoration:none;display:inline-flex;align-items:center;gap:4px;"; + link.appendChild(parseSvg(iconSvg)); + link.appendChild(document.createTextNode(text)); info.appendChild(link); } - appendLink(getMergeQueueLink(), "queue"); - appendLink(getEventLogLink(), "logs"); - - row.appendChild(info); + appendLink(getMergeQueueLink(), "queue", QUEUE_ICON_SVG); + appendLink(getEventLogLink(), "logs", LOGS_ICON_SVG); if (state === "merged") { const status = document.createElement("span"); - status.style.cssText = - "color:var(--fgColor-muted, #7d8590);font-size:13px;"; + status.style.color = "var(--fgColor-muted, #7d8590)"; status.textContent = getMergedMessage(); - row.appendChild(status); - } else if (state !== "closed") { - const buttons = document.createElement("div"); - buttons.style.cssText = "display:flex;gap:6px;"; - - buttons.appendChild(buildQueueButton(state)); + info.appendChild(status); + } - for (const btn of BUTTONS) { - buttons.appendChild( - buildMergeBoxButton( - btn.command, - btn.label, - btn.tooltip, - false, - "secondary", - ), - ); - } + const brand = document.createElement("a"); + brand.href = "https://dashboard.mergify.com"; + brand.target = "_blank"; + brand.rel = "noopener noreferrer"; + brand.title = "Open Mergify dashboard"; + brand.style.cssText = + "display:flex;align-items:center;gap:6px;margin-left:8px;color:var(--fgColor-default, #e6edf3);text-decoration:none;font-weight:600;"; + const svgEl = parseSvg(getLogoSvg()); + svgEl.setAttribute("width", "20"); + svgEl.setAttribute("height", "20"); + brand.appendChild(svgEl); + const brandText = document.createElement("span"); + brandText.textContent = "Mergify"; + brand.appendChild(brandText); + info.appendChild(brand); - row.appendChild(buttons); - } + row.appendChild(info); return row; }