Files
mesalogo e89db96b85 feat(workspace): unify projects and conversations in one menu
Replace separate project and activity navigation with a fixed-height two-line button and a shared workspace menu. Browse local, remote and channel projects, preview sessions on hover, restore the last opened conversation, and show ten recent conversations alongside active work.

Preserve project settings, recovery actions, draft leave guards and completion reminders. Reuse conversation summaries and windowed lists without hover fetches or polling.

Validation: focused component and App tests, real Electron layout and interaction checks, typecheck and lint passed. The earlier full suite timed out and reported Supervisor settings/layout failures.

Release note: 左上角统一项目与活动入口,支持分类查找、悬停预览和最近 10 个会话;双行按钮整体点击,保留项目设置与跨项目会话切换。
2026-10-04 09:53:11 +08:00

70 lines
15 KiB
CSS

:root {
color-scheme: light;
--surface-canvas: #e8f0f5; --surface-raised: #fff; --surface-subtle: #f4f8fb;
--text-primary: #17263a; --text-secondary: #4f6278; --border-default: #cedce7;
--accent: #086fc7; --accent-subtle: #e8f4ff; --accent-selected: #a7cfea;
--success: #147566; --success-subtle: #e5f4ee; --warning: #865200;
--radius-control: 10px; --radius-card: 14px;
--shadow: 0 24px 80px #17263a26;
font-family: "Inter Variable", "PingFang SC", "Microsoft YaHei UI", system-ui, sans-serif;
}
[data-theme="dark"] { color-scheme: dark; --surface-canvas: #07131f; --surface-raised: #102335; --surface-subtle: #162c40; --text-primary: #edf7ff; --text-secondary: #b5c6d5; --border-default: #29445a; --accent: #72c5ff; --accent-subtle: #123b5b; --accent-selected: #28668f; --success: #72d8be; --success-subtle: #123d37; --warning: #f2bd66; }
* { box-sizing: border-box; }
body { margin: 0; padding: 24px 32px; background: var(--surface-subtle); color: var(--text-primary); font-size: 13px; line-height: 1.6; }
button, textarea, input { font: inherit; color: inherit; }
button { border: 1px solid transparent; border-radius: var(--radius-control); background: transparent; padding: 8px 12px; cursor: pointer; }
button:hover { background: var(--accent-subtle); }
button:focus-visible, textarea:focus-visible, input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
button:disabled { opacity: .5; cursor: default; }
h1, h2, h3, p { margin: 0; } .muted, .eyebrow, .section-label { color: var(--text-secondary); }
.eyebrow, .section-label { font-size: 11px; letter-spacing: 1px; }
.lab, .lab-foot { max-width: 1440px; margin: auto; display: flex; justify-content: space-between; gap: 16px; align-items: center; }
.lab { margin-bottom: 24px; }.lab strong { font-size: 15px; }.lab span { margin-left: 24px; color: var(--text-secondary); }.tools { display: flex; gap: 4px; }.tools button { border-color: var(--border-default); }
.shell { max-width: 1440px; margin: auto; height: calc(100dvh - 160px); min-height: 580px; display: grid; grid-template-columns: 256px minmax(0, 1fr); border: 1px solid var(--border-default); border-radius: var(--radius-card); overflow: hidden; background: var(--surface-raised); }
.sidebar { background: var(--surface-canvas); padding: 24px 12px 12px; display: flex; flex-direction: column; border-right: 1px solid var(--border-default); }.brand { display: flex; align-items: center; gap: 8px; margin: 0 8px 32px; }.brand .muted { font-size: 11px; margin-left: auto; }.logo { background: var(--text-primary); color: var(--surface-raised); border-radius: var(--radius-control); padding: 4px 10px; }
.workspace-control { background: var(--surface-raised); border: 1px solid var(--border-default); border-radius: var(--radius-card); overflow: hidden; }#workspace-trigger { position: relative; display: grid; text-align: left; width: 100%; padding: 12px; }#project-name { font-size: 16px; }.expand { position: absolute; right: 12px; top: 20px; font-size: 22px; color: var(--accent); }#activity-trigger { border-top: 1px solid var(--border-default); border-radius: 0; width: 100%; font-size: 10px; padding: 8px; display: flex; gap: 4px; justify-content: space-between; }
.new { margin: 16px 0 24px; text-align: left; border-color: var(--border-default); }.section-label { margin: 0 12px 8px; }#sessions { overflow: auto; }#sessions button { width: 100%; text-align: left; display: flex; gap: 8px; align-items: center; }#sessions button span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }[aria-current="true"], button[aria-pressed="true"] { background: var(--accent-subtle); border-color: var(--accent-selected); color: var(--accent); }.sidebar-bottom { margin-top: auto; padding-top: 24px; }.sidebar-bottom > span { display: block; margin: 8px 12px; font-size: 11px; }.sidebar-bottom button { width: 100%; text-align: left; }kbd { font: 10px/1.5 inherit; border: 1px solid var(--border-default); border-radius: 4px; padding: 2px 4px; color: var(--text-secondary); margin-left: 8px; }
.workspace { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }.titlebar { padding: 16px 24px; border-bottom: 1px solid var(--border-default); background: var(--surface-subtle); display: flex; justify-content: space-between; gap: 12px; }#conversation { flex: 1; overflow: auto; padding: 48px max(32px, calc((100% - 740px) / 2)); }#conversation h1 { font-size: 28px; font-weight: 550; letter-spacing: -1px; margin: 12px 0 32px; }.user-message { margin: 0 0 32px 48px; padding: 16px 24px; background: var(--surface-subtle); border-radius: var(--radius-card); }.assistant-label { color: var(--accent); font-size: 12px; margin-bottom: 12px; }.answer { font-size: 15px; line-height: 1.9; white-space: pre-wrap; }.execution { margin-top: 24px; padding: 16px; border: 1px solid var(--border-default); border-radius: var(--radius-control); }.execution p { margin: 8px 0 16px; color: var(--text-secondary); }.primary { background: var(--accent); color: var(--surface-raised); }.primary:hover { background: var(--text-primary); color: var(--surface-raised); }#composer { margin: 16px 32px 24px; border: 1px solid var(--border-default); border-radius: var(--radius-card); padding: 12px 16px; }textarea { display: block; width: 100%; resize: vertical; border: 0; background: transparent; padding: 8px 0; }#composer > div { display: flex; align-items: center; justify-content: space-between; }.lab-foot { margin-top: 16px; color: var(--text-secondary); font-size: 11px; }
.waiting { color: var(--warning); }.running { color: var(--accent); }.done { color: var(--success); }.idle { color: var(--text-secondary); }.empty { text-align: center; padding: 48px 16px; color: var(--text-secondary); }#toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); padding: 12px 24px; border: 1px solid var(--accent-selected); background: var(--surface-raised); color: var(--text-primary); border-radius: var(--radius-card); box-shadow: var(--shadow); z-index: 5; }
@media (max-width: 800px) { body { padding: 12px; }.lab { flex-wrap: wrap; margin-bottom: 12px; }.lab span { display: none; }.shell { grid-template-columns: 208px minmax(0, 1fr); }.brand .muted { display: none; }#conversation { padding: 24px; }.lab-foot span:last-child { display: none; } }
@media (max-width: 560px) { .shell { display: flex; flex-direction: column; height: auto; min-height: calc(100dvh - 150px); }.sidebar { border-right: 0; border-bottom: 1px solid var(--border-default); padding: 12px; }.brand, .new, .section-label, #sessions, .sidebar-bottom { display: none; }.workspace-control { display: flex; }#workspace-trigger { width: 48%; }#activity-trigger { width: 52%; flex-wrap: wrap; align-content: center; border-top: 0; border-left: 1px solid var(--border-default); }.workspace { min-height: 540px; }.titlebar { padding: 12px; }.titlebar > .muted { display: none; }#conversation { padding: 24px 16px; }#composer { margin: 12px; }.user-message { margin-left: 16px; } }
#overview { position: fixed; inset: auto; margin: 0; padding: 0; width: min(920px, calc(100vw - 16px)); height: 640px; border: 1px solid var(--border-default); border-radius: var(--radius-card); box-shadow: var(--shadow); background: var(--surface-raised); color: var(--text-primary); overflow: hidden; }
#overview:popover-open { display: flex; flex-direction: column; }
#activity-trigger[hidden] { display: none; }
.menu-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 16px; border-bottom: 1px solid var(--border-default); flex-shrink: 0; }.menu-header button { font-size: 11px; }
.menu-layout { display: grid; grid-template-columns: 360px minmax(0, 1fr); flex: 1; min-height: 0; }
.project-pane { display: flex; flex-direction: column; min-height: 0; min-width: 0; background: var(--surface-subtle); border-right: 1px solid var(--border-default); }
#project-search { margin: 12px 8px 8px; width: calc(100% - 16px); min-width: 0; border: 1px solid var(--border-default); background: var(--surface-raised); border-radius: 6px; padding: 8px; font-size: 12px; }
#all-projects { text-align: left; margin: 0 8px 8px; padding: 8px; }
#project-tabs { display: flex; gap: 4px; padding: 0 8px 8px; border-bottom: 1px solid var(--border-default); flex-shrink: 0; }#project-tabs[hidden] { display: none; }#project-tabs button { flex: 1; white-space: nowrap; font-size: 11px; padding: 6px 4px; }#project-tabs [aria-selected="true"] { color: var(--accent); background: var(--accent-subtle); border-color: var(--accent-selected); }
#desktops { display: block; padding: 8px; overflow-y: auto; flex: 1; min-height: 0; overscroll-behavior: contain; }
.search-result > small { display: block; padding: 0 8px 8px 32px; font-size: 10px; color: var(--text-secondary); }.search-result .desktop { margin-bottom: 0; }
.host-heading { cursor: pointer; }.host-heading > span:first-child::before { content: '▸'; margin-right: 4px; }details[open] > .host-heading > span:first-child::before { content: '▾'; }
.project-row { position: relative; margin-bottom: 4px; }
.project-row .desktop { display: grid; grid-template-columns: 16px minmax(0, 1fr) 14px; min-height: 52px; padding: 8px 44px 8px 8px; gap: 8px; margin: 0; }
.project-copy { min-width: 0; display: grid; gap: 2px; }.project-heading { display: flex; align-items: center; gap: 8px; min-width: 0; }.project-heading strong { font-size: 13px; font-weight: 650; }.project-path { display: block; font-size: 11px; line-height: 16px; color: var(--text-secondary); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }.project-row .project-counts { width: auto; padding: 0; flex-wrap: nowrap; }.current-project { color: var(--accent); font-size: 13px; }
.project-settings-button { position: absolute; top: 50%; right: 4px; transform: translateY(-50%); width: 32px; height: 32px; padding: 8px; opacity: 0; pointer-events: none; color: var(--text-secondary); }.project-row:hover .project-settings-button, .project-row:focus-within .project-settings-button { opacity: 1; pointer-events: auto; }
.project-copy > .project-counts { font-size: 11px; line-height: 16px; flex-wrap: wrap; gap: 2px 8px; }.project-copy > .project-counts > span { white-space: nowrap; }
@media (hover: none) { .project-settings-button { opacity: 1; pointer-events: auto; } }
#project-settings { width: min(480px, calc(100vw - 24px)); max-height: calc(100dvh - 32px); overflow-y: auto; border: 1px solid var(--border-default); border-radius: var(--radius-card); background: var(--surface-raised); color: var(--text-primary); padding: 24px; box-shadow: var(--shadow); }#project-settings::backdrop { background: color-mix(in srgb, var(--text-primary) 25%, transparent); }
#settings-form { display: grid; gap: 16px; }#settings-form header, #settings-form footer { display: flex; align-items: center; gap: 8px; }#settings-form header strong, #settings-form footer small { flex: 1; }#settings-form label { display: grid; gap: 4px; font-size: 12px; }#settings-form input, #settings-form select, #settings-form textarea { width: 100%; min-width: 0; border: 1px solid var(--border-default); border-radius: 6px; background: var(--surface-subtle); color: var(--text-primary); padding: 8px; font: inherit; }
.desktop { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px; margin-bottom: 4px; text-align: left; border-color: transparent; background: transparent; }.desktop strong { display: block; margin: 0; min-width: 0; flex: 1; font-size: 12px; font-weight: 500; }.project-counts { display: flex; gap: 8px; font-size: 10px; color: var(--text-secondary); flex-shrink: 0; }
#desktops svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.project-section { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border-default); }.project-section h2 { display: flex; align-items: center; gap: 8px; margin: 0 8px 8px; font-size: 11px; font-weight: 500; color: var(--text-secondary); }.host-group + .host-group { margin-top: 12px; }.host-heading { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 4px 8px; font-size: 11px; }.host-status { border: 1px solid var(--border-default); border-radius: 4px; padding: 0 4px; font-size: 10px; }.host-group .desktop { padding-left: 16px; }
@media (min-width: 561px) and (max-width: 800px) { .menu-layout { grid-template-columns: 300px minmax(0, 1fr); } }
.activity-pane { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
#menu-new-chat { color: var(--accent); font-size: 11px; padding: 4px 8px; white-space: nowrap; flex-shrink: 0; }
#project-form:not([hidden]) { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 12px; border-top: 1px solid var(--border-default); flex-shrink: 0; }#project-form input { min-width: 80px; width: 120px; flex: 1; background: var(--surface-raised); border: 1px solid var(--border-default); border-radius: 6px; padding: 8px; }.desktop strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.overview-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; border-top: 0; border-bottom: 1px solid var(--border-default); }
#filters { display: flex; gap: 4px; overflow-x: auto; min-width: 0; }#filters button { font-size: 11px; padding: 4px 8px; white-space: nowrap; flex-shrink: 0; }
#windows { overflow-y: auto; padding: 8px; flex: 1; min-height: 0; overscroll-behavior: contain; }
.window-group { margin: 0 0 16px; }.group-title { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 500; margin: 8px; }
.session-row { display: flex; align-items: center; gap: 12px; text-align: left; width: 100%; padding: 12px 8px; border-radius: 6px; }.session-copy { flex: 1; min-width: 0; }.session-copy strong { display: block; font-weight: 500; }.session-copy small { display: block; font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }.row-action { font-size: 10px; flex-shrink: 0; }
.overview-footer { padding: 8px 16px; background: var(--surface-subtle); border-top: 1px solid var(--border-default); min-height: 48px; flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--text-secondary); font-size: 11px; }
@media (max-width: 560px) {
.project-row .desktop { grid-template-columns: minmax(0, 1fr) 12px; padding: 8px 36px 8px 4px; gap: 4px; }.project-row .desktop > svg { display: none; }.project-heading { flex-wrap: wrap; gap: 0; }.project-heading strong { flex-basis: 100%; }.project-settings-button { right: 0; }.project-row .project-counts { font-size: 9px; }.project-row .project-path { font-size: 10px; }
#project-tabs { overflow-x: auto; gap: 0; padding-inline: 4px; }#project-tabs button { flex: 0 0 auto; }#project-search { font-size: 11px; padding: 6px; }.search-result > small { padding-left: 8px; }
.desktop { flex-wrap: wrap; gap: 4px; }.desktop strong { flex-basis: calc(100% - 24px); }.project-counts { width: 100%; padding-left: 19px; }.host-heading { flex-wrap: wrap; gap: 4px; }.host-group .desktop { padding-left: 8px; }
.menu-layout { grid-template-columns: 176px minmax(0, 1fr); }#desktops { padding: 4px; }.desktop { padding: 8px; }.desktop strong { font-size: 12px; }.project-counts { gap: 4px; flex-wrap: wrap; }.overview-toolbar { padding: 8px; }#filters { gap: 0; }#filters button { padding: 4px; }.session-row { align-items: flex-start; gap: 4px; flex-direction: column; }.session-copy { width: 100%; }.overview-footer { padding: 8px; gap: 4px; }.overview-footer span { max-width: 55%; }
}