Merge git-panel-layout-fixes: right-pinned worktree actions, count on the heading
This commit is contained in:
@@ -100,8 +100,16 @@ function renderCommitRow(c: CommitLogEntry): HTMLElement {
|
||||
}
|
||||
|
||||
/** Render a GitLogResult into a container (clears first). Empty → an inert note. */
|
||||
export function renderGitLog(container: HTMLElement, log: GitLogResult): void {
|
||||
export function renderGitLog(
|
||||
container: HTMLElement,
|
||||
log: GitLogResult,
|
||||
labelEl?: HTMLElement,
|
||||
): void {
|
||||
container.textContent = ''
|
||||
// Design: the count sits ON the section heading, not on a line of its own —
|
||||
// it qualifies "Recent commits", it is not a separate statement.
|
||||
const badgeHost = labelEl ?? container
|
||||
badgeHost.querySelector('.proj-commitlog-count')?.remove()
|
||||
if (log.commits.length === 0) {
|
||||
container.append(el('div', 'proj-empty', 'No commits yet.'))
|
||||
return
|
||||
@@ -110,9 +118,9 @@ export function renderGitLog(container: HTMLElement, log: GitLogResult): void {
|
||||
// readable before the eye has walked the rows looking for rails.
|
||||
const unpushedCount = log.commits.filter((c) => c.unpushed === true).length
|
||||
if (unpushedCount > 0 && log.upstream !== undefined) {
|
||||
const badge = el('div', 'proj-commitlog-count', `↑ ${unpushedCount} unpushed`)
|
||||
const badge = el('span', 'proj-commitlog-count', `↑ ${unpushedCount} unpushed`)
|
||||
badge.title = `${unpushedCount} commit(s) not on ${log.upstream}`
|
||||
container.append(badge)
|
||||
badgeHost.append(badge)
|
||||
}
|
||||
|
||||
const list = el('div', 'proj-commitlog-list')
|
||||
@@ -150,7 +158,11 @@ export interface GitLogHandle {
|
||||
* the log, then swap in the rows. A fetch failure degrades to a short inert
|
||||
* message (never throws). destroy() removes the node and cancels the swap.
|
||||
*/
|
||||
export function mountGitLog(container: HTMLElement, repoPath: string): GitLogHandle {
|
||||
export function mountGitLog(
|
||||
container: HTMLElement,
|
||||
repoPath: string,
|
||||
labelEl?: HTMLElement,
|
||||
): GitLogHandle {
|
||||
let destroyed = false
|
||||
|
||||
container.textContent = ''
|
||||
@@ -164,7 +176,7 @@ export function mountGitLog(container: HTMLElement, repoPath: string): GitLogHan
|
||||
container.append(el('div', 'proj-empty', 'Could not read recent commits.'))
|
||||
return
|
||||
}
|
||||
renderGitLog(container, log)
|
||||
renderGitLog(container, log, labelEl)
|
||||
})()
|
||||
|
||||
return {
|
||||
|
||||
Binary file not shown.
@@ -1725,18 +1725,17 @@ body {
|
||||
.proj-commitlog-count {
|
||||
font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
||||
font-size: 11.5px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--accent);
|
||||
margin: -4px 0 6px;
|
||||
text-transform: none;
|
||||
letter-spacing: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* ── w6/G5: worktree rows as two-line cards ──────────────────────────────── */
|
||||
.proj-wt-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 14px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* NOTE: the row's own display/grid lives with the ORIGINAL .proj-wt-row rule
|
||||
further down. Declaring it twice let the later copy silently win and the
|
||||
Open button never reached the right edge. One rule per selector. */
|
||||
.proj-wt-row-current {
|
||||
border-color: rgba(227, 166, 74, 0.36);
|
||||
background: linear-gradient(90deg, var(--accent-soft), transparent 46%);
|
||||
@@ -2349,10 +2348,12 @@ body {
|
||||
gap: 6px;
|
||||
}
|
||||
.proj-wt-row {
|
||||
display: flex;
|
||||
/* w6: two-line card — content column, then the actions rail pinned right. */
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 9px 12px;
|
||||
gap: 14px;
|
||||
padding: 11px 14px;
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
|
||||
@@ -217,14 +217,44 @@ describe('renderGitLog — unpushed count beside the heading (w6 design)', () =>
|
||||
return { hash, at: Date.now(), subject, ...(unpushed === true ? { unpushed: true } : {}) }
|
||||
}
|
||||
|
||||
it('states the count so it is readable before scanning the rows', () => {
|
||||
it('puts the count ON the heading when one is supplied, not on its own line', () => {
|
||||
const host = document.createElement('div')
|
||||
const label = document.createElement('div')
|
||||
label.textContent = 'Recent commits'
|
||||
renderGitLog(
|
||||
host,
|
||||
{
|
||||
commits: [entry('a1', 'x', true), entry('b2', 'y', true), entry('c3', 'z')],
|
||||
truncated: false,
|
||||
upstream: 'origin/develop',
|
||||
},
|
||||
label,
|
||||
)
|
||||
expect(label.querySelector('.proj-commitlog-count')!.textContent).toContain('2')
|
||||
expect(host.querySelector('.proj-commitlog-count')).toBeNull()
|
||||
})
|
||||
|
||||
it('does not stack duplicate counts across re-renders', () => {
|
||||
const host = document.createElement('div')
|
||||
const label = document.createElement('div')
|
||||
const log = {
|
||||
commits: [entry('a1', 'x', true)],
|
||||
truncated: false,
|
||||
upstream: 'origin/develop',
|
||||
}
|
||||
renderGitLog(host, log, label)
|
||||
renderGitLog(host, log, label)
|
||||
expect(label.querySelectorAll('.proj-commitlog-count').length).toBe(1)
|
||||
})
|
||||
|
||||
it('falls back to the list container when no heading is given', () => {
|
||||
const host = document.createElement('div')
|
||||
renderGitLog(host, {
|
||||
commits: [entry('a1', 'x', true), entry('b2', 'y', true), entry('c3', 'z')],
|
||||
commits: [entry('a1', 'x', true)],
|
||||
truncated: false,
|
||||
upstream: 'origin/develop',
|
||||
})
|
||||
expect(host.querySelector('.proj-commitlog-count')!.textContent).toContain('2')
|
||||
expect(host.querySelector('.proj-commitlog-count')).not.toBeNull()
|
||||
})
|
||||
|
||||
it('omits the count when nothing is unpushed', () => {
|
||||
|
||||
Reference in New Issue
Block a user