Skip to content

Commit 46acab3

Browse files
committed
fix(log): clarify commit ref chips
1 parent 8cad84d commit 46acab3

3 files changed

Lines changed: 235 additions & 70 deletions

File tree

‎src/components/centre/CentrePanel.css‎

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -944,16 +944,31 @@
944944
display: inline-flex;
945945
align-items: center;
946946
gap: 3px;
947-
flex: 0 1 auto;
948947
min-width: 0;
949-
max-width: min(42%, 150px);
948+
max-width: 100%;
950949
overflow: hidden;
951950
}
952951

952+
.log-view__refs--inline {
953+
flex: 0 1 auto;
954+
}
955+
956+
.log-view__refs--prominent {
957+
display: flex;
958+
width: 100%;
959+
margin-top: 3px;
960+
}
961+
962+
.log-view__refs--prominent .log-view__ref {
963+
transition: max-width 0.1s ease;
964+
}
965+
953966
.log-view__ref {
954967
display: inline-flex;
955968
align-items: center;
956-
max-width: 58px;
969+
gap: 3px;
970+
max-width: 14ch;
971+
min-width: 0;
957972
padding: 1px 5px;
958973
border-radius: var(--radius-sm);
959974
border: 1px solid var(--border-subtle);
@@ -963,6 +978,16 @@
963978
font-family: var(--font-mono);
964979
white-space: nowrap;
965980
overflow: hidden;
981+
}
982+
983+
.log-view__ref-marker {
984+
flex-shrink: 0;
985+
opacity: 0.75;
986+
}
987+
988+
.log-view__ref-label {
989+
min-width: 0;
990+
overflow: hidden;
966991
text-overflow: ellipsis;
967992
}
968993

@@ -972,13 +997,53 @@
972997
border-color: var(--diff-add-border);
973998
}
974999

1000+
.log-view__ref--head {
1001+
max-width: none;
1002+
color: var(--green);
1003+
background: var(--green-dim);
1004+
border-color: var(--diff-add-border);
1005+
flex-shrink: 0;
1006+
}
1007+
9751008
.log-view__ref--remoteBranch {
1009+
max-width: 24ch;
1010+
color: var(--accent);
1011+
background: var(--accent-dim);
1012+
border-color: var(--selection-border);
1013+
}
1014+
1015+
.log-view__ref--upstream {
1016+
max-width: 24ch;
9761017
color: var(--accent);
9771018
background: var(--accent-dim);
9781019
border-color: var(--selection-border);
9791020
}
9801021

1022+
.log-view__refs--prominent .log-view__ref--remoteBranch,
1023+
.log-view__refs--prominent .log-view__ref--upstream {
1024+
max-width: 34ch;
1025+
}
1026+
1027+
@media (hover: hover) and (pointer: fine) {
1028+
.log-view__refs--prominent:has(.log-view__ref:not(.log-view__ref--head):not(.log-view__ref--more):hover)
1029+
.log-view__ref:not(:hover):not(.log-view__ref--head):not(.log-view__ref--more) {
1030+
max-width: 10ch;
1031+
}
1032+
1033+
.log-view__refs--prominent:has(.log-view__ref:not(.log-view__ref--head):not(.log-view__ref--more):hover)
1034+
.log-view__ref--remoteBranch:not(:hover),
1035+
.log-view__refs--prominent:has(.log-view__ref:not(.log-view__ref--head):not(.log-view__ref--more):hover)
1036+
.log-view__ref--upstream:not(:hover) {
1037+
max-width: 16ch;
1038+
}
1039+
1040+
.log-view__refs--prominent .log-view__ref:hover:not(.log-view__ref--head):not(.log-view__ref--more) {
1041+
max-width: 42ch;
1042+
}
1043+
}
1044+
9811045
.log-view__ref--tag {
1046+
max-width: 14ch;
9821047
color: var(--yellow);
9831048
background: var(--bg-elevated);
9841049
border-color: var(--yellow);
@@ -1002,28 +1067,7 @@
10021067
font-size: var(--font-size-xs);
10031068
color: var(--accent);
10041069
opacity: 0.7;
1005-
}
1006-
1007-
.log-view__marker {
1008-
font-size: var(--font-size-xxs);
1009-
font-family: var(--font-mono);
1010-
font-weight: var(--font-weight-bold);
1011-
letter-spacing: 0.03em;
1012-
padding: 1px 6px;
1013-
border-radius: 999px;
1014-
border: 1px solid transparent;
1015-
}
1016-
1017-
.log-view__marker--head {
1018-
color: var(--green);
1019-
background: var(--green-dim);
1020-
border-color: var(--diff-add-border);
1021-
}
1022-
1023-
.log-view__marker--upstream {
1024-
color: var(--accent);
1025-
background: var(--accent-dim);
1026-
border-color: var(--selection-border);
1070+
flex-shrink: 0;
10271071
}
10281072

10291073
.log-view__sig-badge {

‎src/components/centre/LogView.test.tsx‎

Lines changed: 121 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,16 @@ function rowFor(subject: string): HTMLElement {
228228
return row as HTMLElement;
229229
}
230230

231+
function prominentRefLabelsFor(subject: string): string[] {
232+
return Array.from(rowFor(subject).querySelectorAll(".log-view__refs--prominent .log-view__ref-label"))
233+
.map(label => label.textContent ?? "");
234+
}
235+
236+
function inlineRefLabelsFor(subject: string): string[] {
237+
return Array.from(rowFor(subject).querySelectorAll(".log-view__meta .log-view__refs--inline .log-view__ref-label"))
238+
.map(label => label.textContent ?? "");
239+
}
240+
231241
function renderLog(overrides: Partial<React.ComponentProps<typeof LogView>> = {}) {
232242
const commits = overrides.commits ?? [commit(1), commit(2), commit(3)];
233243
const commitMarkers: CommitMarkers = {
@@ -426,7 +436,7 @@ describe("LogView commit selection", () => {
426436
expect(rowFor("Subject 1")).toHaveTextContent("main");
427437
});
428438

429-
it("keeps commit ref decorations compact", () => {
439+
it("shows up to four commit ref decorations before overflow", () => {
430440
renderLog({
431441
commits: [
432442
commit(1, {
@@ -439,17 +449,16 @@ describe("LogView commit selection", () => {
439449
],
440450
});
441451

442-
expect(rowFor("Subject 1")).toHaveTextContent("main");
443-
expect(rowFor("Subject 1")).toHaveTextContent("v1.0.0");
444-
expect(rowFor("Subject 1")).toHaveTextContent("+1");
445-
expect(rowFor("Subject 1")).not.toHaveTextContent("origin/main");
452+
expect(prominentRefLabelsFor("Subject 1")).toEqual(["main", "origin/main", "v1.0.0"]);
453+
expect(rowFor("Subject 1")).not.toHaveTextContent("+1");
446454
});
447455

448-
it("counts head and upstream markers in the compact ref limit", () => {
456+
it("renders selected checkout refs on a prominent ref line", () => {
449457
const targetCommit = commit(1, {
450458
refDecorations: [
451459
{ name: "main", kind: "localBranch" },
452460
{ name: "origin/main", kind: "remoteBranch" },
461+
{ name: "v1.0.0", kind: "tag" },
453462
],
454463
});
455464
renderLog({
@@ -461,28 +470,124 @@ describe("LogView commit selection", () => {
461470
},
462471
});
463472

464-
const labels = Array.from(rowFor("Subject 1").querySelectorAll(".log-view__refs > span"))
465-
.map(label => label.textContent);
473+
const row = rowFor("Subject 1");
474+
const refs = Array.from(row.querySelectorAll(".log-view__refs--prominent > span"));
466475

467-
expect(labels).toEqual(["HEAD", "origi...", "+1"]);
468-
expect(screen.getByTitle("origin/main")).toBeInTheDocument();
469-
expect(screen.getByTitle("1 more refs: main")).toBeInTheDocument();
476+
expect(prominentRefLabelsFor("Subject 1")).toEqual(["HEAD", "main", "origin/main", "v1.0.0"]);
477+
expect(inlineRefLabelsFor("Subject 1")).toEqual([]);
478+
expect(refs.map(ref => Array.from(ref.classList))).toEqual([
479+
expect.arrayContaining(["log-view__ref--head"]),
480+
expect.arrayContaining(["log-view__ref--localBranch"]),
481+
expect.arrayContaining(["log-view__ref--upstream"]),
482+
expect.arrayContaining(["log-view__ref--tag"]),
483+
]);
484+
expect(screen.getByTitle("Current checkout")).toBeInTheDocument();
485+
expect(screen.getByTitle("Remote branch origin/main")).toBeInTheDocument();
486+
expect(row).not.toHaveTextContent("+1");
470487
});
471488

472-
it("abbreviates long commit ref labels", () => {
489+
it("keeps unselected non-checkout refs inline in the meta row", () => {
490+
const targetCommit = commit(1, {
491+
refDecorations: [
492+
{ name: "main", kind: "localBranch" },
493+
{ name: "origin/main", kind: "remoteBranch" },
494+
],
495+
});
496+
const selectedCommit = commit(2);
497+
498+
renderLog({
499+
commits: [targetCommit, selectedCommit],
500+
selectedCommitHash: selectedCommit.hash,
501+
});
502+
503+
expect(inlineRefLabelsFor("Subject 1")).toEqual(["main", "origin/main"]);
504+
expect(prominentRefLabelsFor("Subject 1")).toEqual([]);
505+
});
506+
507+
it("keeps long remote ref labels visible and exposes the full label in the title", () => {
508+
const remoteName = "origin/feature/long-branch-label";
509+
473510
renderLog({
474511
commits: [
475512
commit(1, {
476513
refDecorations: [
477-
{ name: "0.8.0-develop", kind: "localBranch" },
514+
{ name: remoteName, kind: "remoteBranch" },
478515
],
479516
}),
480517
],
481518
});
482519

483-
expect(rowFor("Subject 1")).toHaveTextContent("0.8.0...");
484-
expect(rowFor("Subject 1")).not.toHaveTextContent("0.8.0-develop");
485-
expect(screen.getByTitle("Local branch 0.8.0-develop")).toBeInTheDocument();
520+
expect(prominentRefLabelsFor("Subject 1")).toEqual([remoteName]);
521+
expect(screen.getByTitle(`Remote branch ${remoteName}`)).toBeInTheDocument();
522+
});
523+
524+
it("lists overflow refs in priority order", () => {
525+
const targetCommit = commit(1, {
526+
refDecorations: [
527+
{ name: "main", kind: "localBranch" },
528+
{ name: "release", kind: "localBranch" },
529+
{ name: "origin/main", kind: "remoteBranch" },
530+
{ name: "origin/feature-a", kind: "remoteBranch" },
531+
{ name: "v1.0.0", kind: "tag" },
532+
{ name: "v2.0.0", kind: "tag" },
533+
],
534+
});
535+
536+
renderLog({
537+
commits: [targetCommit],
538+
commitMarkers: {
539+
localHead: targetCommit.hash,
540+
upstreamHead: null,
541+
upstreamRef: null,
542+
},
543+
});
544+
545+
expect(prominentRefLabelsFor("Subject 1")).toEqual(["HEAD", "main", "release", "origin/feature-a"]);
546+
expect(screen.getByTitle("3 more refs: origin/main, v1.0.0, v2.0.0")).toBeInTheDocument();
547+
});
548+
549+
it("suppresses the duplicate upstream remote decoration on prominent ref rows", () => {
550+
const targetCommit = commit(1, {
551+
refDecorations: [
552+
{ name: "main", kind: "localBranch" },
553+
{ name: "origin/main", kind: "remoteBranch" },
554+
],
555+
});
556+
557+
renderLog({
558+
commits: [targetCommit],
559+
commitMarkers: {
560+
localHead: targetCommit.hash,
561+
upstreamHead: targetCommit.hash,
562+
upstreamRef: "origin/main",
563+
},
564+
});
565+
566+
expect(prominentRefLabelsFor("Subject 1")).toEqual(["HEAD", "main", "origin/main"]);
567+
expect(rowFor("Subject 1")).not.toHaveTextContent("+1");
568+
});
569+
570+
it("suppresses the duplicate upstream remote decoration on inline ref rows", () => {
571+
const targetCommit = commit(1, {
572+
refDecorations: [
573+
{ name: "main", kind: "localBranch" },
574+
{ name: "origin/main", kind: "remoteBranch" },
575+
],
576+
});
577+
const selectedCommit = commit(2);
578+
579+
renderLog({
580+
commits: [targetCommit, selectedCommit],
581+
selectedCommitHash: selectedCommit.hash,
582+
commitMarkers: {
583+
localHead: null,
584+
upstreamHead: targetCommit.hash,
585+
upstreamRef: "origin/main",
586+
},
587+
});
588+
589+
expect(inlineRefLabelsFor("Subject 1")).toEqual(["main", "origin/main"]);
590+
expect(prominentRefLabelsFor("Subject 1")).toEqual([]);
486591
});
487592

488593
it("renders an explicit load more footer instead of wiring automatic end reached loading", () => {

0 commit comments

Comments
 (0)