Reserve space for window controls and split the titlebar clusters so brand and chrome no longer collide. Replace the full-screen status spinner with lightweight activity jobs in the event tray.
This commit is contained in:
+84
-12
@@ -66,17 +66,96 @@ body {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
backdrop-filter: blur(16px) saturate(1.4);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(1.4);
|
||||
padding: 0 14px 0 10px;
|
||||
gap: 12px;
|
||||
padding: 0 12px 0 8px;
|
||||
gap: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
-webkit-app-region: drag;
|
||||
overflow: visible;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
#titlebar > * {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
/* Left cluster: window controls + brand (never overlap) */
|
||||
#titlebar .titlebar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex: 0 1 auto;
|
||||
min-width: 0;
|
||||
max-width: 55%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Pear window controls — reserve space so brand never sits under traffic lights */
|
||||
#titlebar pear-ctrl {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
line-height: 0;
|
||||
min-width: 54px;
|
||||
min-height: 28px;
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
overflow: visible;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#titlebar pear-ctrl[data-platform='darwin'] {
|
||||
min-width: 78px;
|
||||
margin: 0 8px 0 8px;
|
||||
margin-top: 0 !important;
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
|
||||
#titlebar pear-ctrl[data-platform='linux'],
|
||||
#titlebar pear-ctrl[data-platform='win32'] {
|
||||
min-width: 110px;
|
||||
}
|
||||
|
||||
#titlebar .app-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
pointer-events: none;
|
||||
-webkit-app-region: no-drag;
|
||||
margin-left: 8px;
|
||||
margin-left: 4px;
|
||||
min-width: 0;
|
||||
flex-shrink: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#titlebar .titlebar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
max-width: 50%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#titlebar .notification-tray {
|
||||
margin-left: 0;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#titlebar .connection-health-badge,
|
||||
#titlebar #active-peer-chip {
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#titlebar .app-brand-mark {
|
||||
@@ -685,14 +764,7 @@ textarea::placeholder {
|
||||
background: var(--bg-elevated);
|
||||
}
|
||||
|
||||
#status-indicator {
|
||||
background: rgba(10, 12, 16, 0.78);
|
||||
}
|
||||
|
||||
#status-indicator .spinner-border {
|
||||
border-color: var(--accent-primary);
|
||||
border-right-color: transparent;
|
||||
}
|
||||
/* Legacy full-screen status spinner removed — activity uses #job-drawer */
|
||||
|
||||
/* Alerts */
|
||||
#alert-container {
|
||||
|
||||
+35
-1
@@ -4,7 +4,16 @@
|
||||
*/
|
||||
import { manager, Methods } from '../client/manager.js'
|
||||
import { presentError, explainError } from '../client/errors.js'
|
||||
import { runJob, renderJobPanel, subscribeJobs, listJobs } from '../client/jobs.js'
|
||||
import {
|
||||
runJob,
|
||||
renderJobPanel,
|
||||
subscribeJobs,
|
||||
listJobs,
|
||||
showActivity as jobsShowActivity,
|
||||
updateActivity as jobsUpdateActivity,
|
||||
completeActivity as jobsCompleteActivity,
|
||||
getJob,
|
||||
} from '../client/jobs.js'
|
||||
import {
|
||||
warmSnapshot,
|
||||
clearSnapshotCache,
|
||||
@@ -144,6 +153,28 @@ export function dismissJobDrawer(drawer) {
|
||||
}, JOB_EXIT_ANIM_MS)
|
||||
}
|
||||
|
||||
/** Activity helpers for uiUtils (replace full-screen spinners) */
|
||||
export function showActivity(message) {
|
||||
const job = jobsShowActivity(message)
|
||||
showJob(job)
|
||||
return job
|
||||
}
|
||||
|
||||
export function updateActivity(message) {
|
||||
const job = jobsUpdateActivity(message)
|
||||
if (job) showJob(job)
|
||||
return job
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} [ok=true]
|
||||
*/
|
||||
export function completeActivity(ok = true) {
|
||||
const job = jobsCompleteActivity(ok)
|
||||
if (job) showJob(job)
|
||||
return job
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy container with step visibility (uses deployContainer RPC).
|
||||
*/
|
||||
@@ -575,6 +606,9 @@ export function initOpsApp({ navigateToView, sendCommand }) {
|
||||
appendLiveEvent,
|
||||
dismissJobDrawer,
|
||||
showJob,
|
||||
showActivity,
|
||||
updateActivity,
|
||||
completeActivity,
|
||||
explainError,
|
||||
presentError: (err, method) => presentError(err, method, { showAlert, notificationManager }),
|
||||
statusBadge,
|
||||
|
||||
+71
-34
@@ -76,25 +76,89 @@
|
||||
right: 0;
|
||||
background: linear-gradient(180deg, var(--bg-elevated) 0%, var(--bg-tertiary) 100%);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
z-index: 1000;
|
||||
z-index: 1100;
|
||||
backdrop-filter: blur(10px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 var(--spacing-md);
|
||||
padding: 0 12px 0 8px;
|
||||
gap: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#titlebar > * {
|
||||
#titlebar > *,
|
||||
#titlebar .titlebar-left,
|
||||
#titlebar .titlebar-right,
|
||||
#titlebar pear-ctrl,
|
||||
#titlebar .app-brand,
|
||||
#titlebar .notification-tray,
|
||||
#titlebar .connection-health-badge,
|
||||
#titlebar #active-peer-chip {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#titlebar .notification-tray {
|
||||
#titlebar .titlebar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#titlebar .titlebar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#titlebar .notification-tray {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* Window controls: keep brand clear of pear-ctrl hit targets */
|
||||
#titlebar pear-ctrl {
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
min-width: 54px;
|
||||
min-height: 28px;
|
||||
padding: 0 4px;
|
||||
overflow: visible;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#titlebar pear-ctrl[data-platform="darwin"] {
|
||||
min-width: 78px;
|
||||
margin: 0 8px 0 8px !important;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
#titlebar pear-ctrl[data-platform="linux"],
|
||||
#titlebar pear-ctrl[data-platform="win32"] {
|
||||
min-width: 110px;
|
||||
}
|
||||
|
||||
pear-ctrl[data-platform="darwin"] {
|
||||
margin-top: 6px;
|
||||
margin-left: 12px;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#titlebar .app-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-left: 4px;
|
||||
min-width: 0;
|
||||
flex-shrink: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
@@ -272,34 +336,7 @@
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
#status-indicator {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(15, 17, 23, 0.85);
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: 1050;
|
||||
}
|
||||
|
||||
#status-indicator .spinner-border {
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
border-width: 0.3rem;
|
||||
border-color: var(--accent-primary);
|
||||
border-right-color: transparent;
|
||||
}
|
||||
|
||||
#status-indicator p {
|
||||
margin-top: var(--spacing-lg);
|
||||
color: var(--text-primary);
|
||||
font-size: 1.125rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
/* Legacy full-screen status spinner removed — activity uses #job-drawer */
|
||||
|
||||
/* Sidebar Content Styling */
|
||||
#sidebar .content {
|
||||
|
||||
Reference in New Issue
Block a user