diff --git a/changelog.d/811-repo-header.changed.md b/changelog.d/811-repo-header.changed.md new file mode 100644 index 00000000..e6bd2708 --- /dev/null +++ b/changelog.d/811-repo-header.changed.md @@ -0,0 +1 @@ +The repository header now separates the title and target branch, a compact status strip (automatic work, discovery interval, next run, schedule console, FlyBot and GitHub credential) and a facts line, instead of one long paragraph carrying every fact. diff --git a/docs/architecture.md b/docs/architecture.md index 0047c91d..4860f78f 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -306,9 +306,13 @@ recorded". `scripts/restore-drill.mjs --status-file` is the writer. opens the section that holds it — so a reader without the script still gets the whole page. The bar sticks at `var(--header-h)` and scrolls horizontally in the phone band; the tab is a 44px `--touch` target and the current tab - paints with `--accent-strong`, the one interactive accent. The Danger section - also carries the recent-auth preflight: a stale `recent_auth_at` renders a - **Confirm with GitHub** link whose return target is `/repos/:id#danger`; the + paints with `--accent-strong`, the one interactive accent. Above the tabs, the + header separates the title and target branch, a status strip (automatic work, + discovery interval, next run, schedule console, FlyBot, GitHub credential) and + a facts line (upstream/fork, permission, role, reviewer); the run/plan/review + actions stay in the header and every existing anchor is unchanged. The Danger + section also carries the recent-auth preflight: a stale `recent_auth_at` renders + a **Confirm with GitHub** link whose return target is `/repos/:id#danger`; the stale POST refusal uses the same anchor, so the form is on screen after re-authentication instead of the page top. - **Dashboard job filters** (`src/lib/jobFilters.ts`): `/dashboard` accepts diff --git a/public/app.css b/public/app.css index 0e7385e2..bb09d720 100644 --- a/public/app.css +++ b/public/app.css @@ -523,6 +523,17 @@ p { margin: 0 0 12px; } .work-actions summary { cursor: pointer; color: var(--accent); font-size: var(--text-sm); font-weight: 650; } .work-actions .row { margin-top: 8px; } @media (max-width: 680px) { .work-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } } +.repo-head { align-items: flex-start; } +.repo-head-main { display: grid; gap: 8px; min-width: 0; } +.repo-status-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; } +.repo-status { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--field); color: var(--text); font-size: var(--text-sm); text-decoration: none; } +.repo-status .fine { color: var(--muted); } +.repo-status b { font-weight: 650; } +a.repo-status:hover { border-color: var(--accent); } +@media (max-width: 680px) { + .repo-status-strip { gap: 6px; } + .repo-status { flex: 1 1 calc(50% - 6px); } +} .repo-subnav { position: sticky; top: var(--header-h); z-index: 15; display: flex; gap: var(--space-2); margin: 0 0 var(--space-4); min-height: var(--subnav-h); diff --git a/src/views/pages.ts b/src/views/pages.ts index 71a289fa..88375dbc 100644 --- a/src/views/pages.ts +++ b/src/views/pages.ts @@ -1495,11 +1495,20 @@ export function repoPage(input: { config: Config; locale: Locale; viewer: Viewer const teamGrid = teamRoles.length === 0 ? '' : `
${escapeHtml(role.label)}: ${escapeHtml(role.id)}`).join('')}${escapeHtml(t('目标分支', 'Target branch'))} ${escapeHtml(targetBranch)}${targetBranch === defaultBranch ? '' : ` · ${escapeHtml(t('默认分支', 'Default branch'))} ${escapeHtml(defaultBranch)}`} · ${escapeHtml(repo.auto_iterate === 1 ? t('自动迭代已开启', 'Auto-iteration on') : t('仅手动运行', 'Manual runs only'))} · ${escapeHtml(t('自动间隔', 'Auto every'))} ${escapeHtml(intervalLabel(repo.interval_minutes, t))} · ${escapeHtml(t('下次约', 'Next'))} ${escapeHtml(nextRunText)} · ${escapeHtml(t('排期控制台', 'Schedule console'))} · ${badge(t, repo.last_status ?? 'idle')}
${escapeHtml(t('目标分支', 'Target branch'))} ${escapeHtml(targetBranch)}${targetBranch === defaultBranch ? '' : ` · ${escapeHtml(t('默认分支', 'Default branch'))} ${escapeHtml(defaultBranch)}`}
${escapeHtml(t('上游', 'Upstream'))} ${escapeHtml(upstreamOwner)}/${escapeHtml(upstreamName)} · ${repo.is_fork === 1 ? `${escapeHtml(t('Fork', 'Fork'))} ${escapeHtml(forkOwner)}/${escapeHtml(forkName)}` : escapeHtml(t('自有仓库,无需 fork', 'Own repository, no fork'))} · ${escapeHtml(t('GitHub 权限', 'GitHub permission'))} ${escapeHtml(permission)} · ${escapeHtml(t('你的角色', 'Your role'))} ${escapeHtml(repoRoleLabel(t, repoRole))} · ${escapeHtml(reviewerLabel)}