mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
dd0889e3d6
Introduce a SessionManager for relay-based remote sessions in the Tauri MGMT client: new SessionCommand API, start/stop/session input routing, clipboard/recording/quality controls, and notification read/dismiss state. Wire AppState with new mutexes and show main window on startup. CI: add SBOM generation (anchore) and Trivy vulnerability scan steps. Misc: change console Docker DB path, large README/CHANGELOG updates (chat E2E, unattended access/WOL, i18n expansion, CDAP/SDK docs), and many web-nodejs assets/locales/routes/views/services and server-side changes.
338 lines
12 KiB
CSS
338 lines
12 KiB
CSS
/* fleet.css — Fleet Management (resources, tasks, builder, compliance) */
|
|
|
|
.fleet-page { max-width: 1400px; margin: 0 auto; padding: 0 16px; }
|
|
|
|
/* Tab bar */
|
|
.fleet-tabs {
|
|
display: flex; gap: 4px; margin-bottom: 20px;
|
|
border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
padding-bottom: 0;
|
|
}
|
|
.fleet-tab {
|
|
display: flex; align-items: center; gap: 6px;
|
|
padding: 10px 18px; border: none; background: none;
|
|
color: var(--text-secondary, #8b949e); cursor: pointer;
|
|
font-size: 13px; font-weight: 500;
|
|
border-bottom: 2px solid transparent;
|
|
transition: color .15s, border-color .15s;
|
|
}
|
|
.fleet-tab:hover { color: var(--text-primary, #e6edf3); }
|
|
.fleet-tab.active {
|
|
color: var(--accent-blue, #58a6ff);
|
|
border-bottom-color: var(--accent-blue, #58a6ff);
|
|
}
|
|
.fleet-tab .material-icons { font-size: 18px; }
|
|
|
|
/* Toolbar */
|
|
.fleet-toolbar {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
gap: 12px; margin-bottom: 16px; flex-wrap: wrap;
|
|
}
|
|
.fleet-toolbar-left {
|
|
display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
|
|
}
|
|
.fleet-toolbar-right {
|
|
display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
|
|
}
|
|
.fleet-select {
|
|
padding: 6px 10px; border-radius: 6px;
|
|
background: var(--bg-secondary, #161b22); color: var(--text-primary, #e6edf3);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 13px; min-width: 150px;
|
|
}
|
|
.fleet-search {
|
|
padding: 6px 10px; border-radius: 6px;
|
|
background: var(--bg-secondary, #161b22); color: var(--text-primary, #e6edf3);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 13px; width: 200px;
|
|
}
|
|
|
|
/* Tables */
|
|
.fleet-table-wrap { overflow-x: auto; }
|
|
.fleet-table {
|
|
width: 100%; border-collapse: collapse;
|
|
font-size: 13px;
|
|
}
|
|
.fleet-table thead th {
|
|
text-align: left; padding: 10px 12px;
|
|
background: var(--bg-secondary, #161b22);
|
|
color: var(--text-secondary, #8b949e);
|
|
font-weight: 600; font-size: 11px; text-transform: uppercase;
|
|
letter-spacing: .5px;
|
|
border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
}
|
|
.fleet-table tbody td {
|
|
padding: 10px 12px;
|
|
border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
color: var(--text-primary, #e6edf3);
|
|
vertical-align: middle;
|
|
}
|
|
.fleet-table tbody tr:hover { background: rgba(88,166,255,.04); }
|
|
.fleet-empty {
|
|
display: flex; flex-direction: column; align-items: center;
|
|
padding: 48px 16px; color: var(--text-secondary, #8b949e);
|
|
}
|
|
.fleet-empty .material-icons { font-size: 48px; margin-bottom: 12px; opacity: .4; }
|
|
|
|
/* Status badges */
|
|
.status-badge {
|
|
display: inline-flex; align-items: center; gap: 4px;
|
|
padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600;
|
|
}
|
|
.status-badge.pending { background: #3d2e00; color: #f0b429; }
|
|
.status-badge.running { background: #0a2540; color: #58a6ff; }
|
|
.status-badge.success { background: #0d2818; color: #3fb950; }
|
|
.status-badge.failed { background: #2d0000; color: #f85149; }
|
|
.status-badge.active { background: #0d2818; color: #3fb950; }
|
|
.status-badge.inactive { background: #1e1e1e; color: #8b949e; }
|
|
|
|
/* Task output panel */
|
|
.fleet-output-panel {
|
|
margin-top: 16px; border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 8px; overflow: hidden;
|
|
background: var(--bg-tertiary, #0d1117);
|
|
}
|
|
.fleet-output-header {
|
|
display: flex; align-items: center; gap: 8px;
|
|
padding: 8px 12px; background: var(--bg-secondary, #161b22);
|
|
border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 13px; font-weight: 600;
|
|
color: var(--text-primary, #e6edf3);
|
|
}
|
|
.fleet-output-header .btn-icon { margin-left: auto; }
|
|
.fleet-output-pre {
|
|
padding: 12px; margin: 0; max-height: 300px; overflow-y: auto;
|
|
font-family: 'JetBrains Mono', monospace; font-size: 12px; line-height: 1.5;
|
|
color: var(--text-primary, #e6edf3); white-space: pre-wrap;
|
|
}
|
|
|
|
/* ======= BUILDER ======= */
|
|
.builder-layout {
|
|
display: grid;
|
|
grid-template-columns: 200px 1fr 260px;
|
|
gap: 12px; min-height: 500px;
|
|
}
|
|
.builder-palette {
|
|
background: var(--bg-secondary, #161b22);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 8px; padding: 8px; overflow-y: auto;
|
|
}
|
|
.palette-section { margin-bottom: 12px; }
|
|
.palette-section h4 {
|
|
display: flex; align-items: center; gap: 6px;
|
|
font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
|
|
color: var(--text-secondary, #8b949e);
|
|
margin: 0 0 6px; padding: 4px 0;
|
|
}
|
|
.node-dot {
|
|
width: 8px; height: 8px; border-radius: 50%; display: inline-block;
|
|
}
|
|
.node-dot.trigger { background: #58a6ff; }
|
|
.node-dot.condition { background: #f0b429; }
|
|
.node-dot.action { background: #3fb950; }
|
|
.node-dot.result { background: #f85149; }
|
|
.node-dot.transform { background: #bc8cff; }
|
|
|
|
.palette-node {
|
|
display: flex; align-items: center; gap: 6px;
|
|
padding: 6px 8px; margin-bottom: 2px; border-radius: 6px;
|
|
font-size: 12px; color: var(--text-primary, #e6edf3);
|
|
cursor: grab; user-select: none;
|
|
transition: background .12s;
|
|
}
|
|
.palette-node:hover { background: rgba(255,255,255,.06); }
|
|
.palette-node:active { cursor: grabbing; }
|
|
.palette-node .material-icons { font-size: 16px; }
|
|
|
|
/* Canvas */
|
|
.builder-canvas-wrap {
|
|
position: relative;
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 8px; overflow: hidden;
|
|
background: var(--bg-tertiary, #0d1117);
|
|
background-image:
|
|
radial-gradient(circle, var(--border-primary, #2d333b) .6px, transparent .6px);
|
|
background-size: 20px 20px;
|
|
}
|
|
.builder-canvas {
|
|
width: 100%; height: 500px; display: block;
|
|
}
|
|
.builder-zoom {
|
|
position: absolute; bottom: 8px; right: 8px;
|
|
display: flex; align-items: center; gap: 4px;
|
|
background: var(--bg-secondary, #161b22);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 6px; padding: 2px 6px;
|
|
font-size: 11px; color: var(--text-secondary, #8b949e);
|
|
}
|
|
|
|
/* Node styles (SVG) */
|
|
.node-group { cursor: move; }
|
|
.node-group:hover .node-body { stroke: var(--accent-blue, #58a6ff); }
|
|
.node-body {
|
|
fill: var(--bg-secondary, #161b22);
|
|
stroke: var(--border-primary, #2d333b); stroke-width: 1.5;
|
|
rx: 8; ry: 8;
|
|
}
|
|
.node-header {
|
|
rx: 8; ry: 8;
|
|
}
|
|
.node-header.trigger { fill: rgba(88,166,255,.15); }
|
|
.node-header.condition { fill: rgba(240,180,41,.15); }
|
|
.node-header.action { fill: rgba(63,185,80,.15); }
|
|
.node-header.result { fill: rgba(248,81,73,.15); }
|
|
.node-header.transform { fill: rgba(188,140,255,.15); }
|
|
|
|
.node-title {
|
|
font-size: 11px; font-weight: 600; fill: var(--text-primary, #e6edf3);
|
|
dominant-baseline: central;
|
|
}
|
|
.node-port {
|
|
fill: var(--bg-secondary, #161b22);
|
|
stroke: var(--text-secondary, #8b949e); stroke-width: 1.5;
|
|
cursor: crosshair;
|
|
}
|
|
.node-port:hover { stroke: var(--accent-blue, #58a6ff); fill: var(--accent-blue, #58a6ff); }
|
|
.node-selected .node-body {
|
|
stroke: var(--accent-blue, #58a6ff); stroke-width: 2;
|
|
}
|
|
.connection-line {
|
|
fill: none; stroke: var(--text-secondary, #8b949e); stroke-width: 1.5;
|
|
marker-end: url(#arrowhead);
|
|
}
|
|
.connection-line:hover { stroke: var(--accent-blue, #58a6ff); }
|
|
|
|
/* Properties panel */
|
|
.builder-properties {
|
|
background: var(--bg-secondary, #161b22);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 8px; padding: 0; overflow-y: auto;
|
|
}
|
|
.props-header {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: 10px 12px; border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 13px; font-weight: 600;
|
|
color: var(--text-primary, #e6edf3);
|
|
}
|
|
#props-body {
|
|
padding: 12px;
|
|
}
|
|
#props-body .form-group { margin-bottom: 10px; }
|
|
#props-body label {
|
|
display: block; font-size: 11px; font-weight: 600;
|
|
color: var(--text-secondary, #8b949e);
|
|
text-transform: uppercase; letter-spacing: .3px;
|
|
margin-bottom: 4px;
|
|
}
|
|
#props-body .form-control {
|
|
width: 100%; padding: 6px 8px; border-radius: 6px;
|
|
background: var(--bg-tertiary, #0d1117);
|
|
color: var(--text-primary, #e6edf3);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* ======= COMPLIANCE ======= */
|
|
.compliance-stats {
|
|
display: grid; grid-template-columns: repeat(4, 1fr);
|
|
gap: 12px; margin-bottom: 20px;
|
|
}
|
|
.comp-stat-card {
|
|
display: flex; align-items: center; gap: 12px;
|
|
padding: 16px; border-radius: 8px;
|
|
background: var(--bg-secondary, #161b22);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
}
|
|
.comp-stat-card .material-icons { font-size: 32px; }
|
|
.comp-stat-card.compliant .material-icons { color: #3fb950; }
|
|
.comp-stat-card.warning .material-icons { color: #f0b429; }
|
|
.comp-stat-card.critical .material-icons { color: #f85149; }
|
|
.comp-stat-card.score .material-icons { color: #58a6ff; }
|
|
.comp-stat-body { display: flex; flex-direction: column; }
|
|
.comp-stat-value {
|
|
font-size: 24px; font-weight: 700;
|
|
color: var(--text-primary, #e6edf3);
|
|
}
|
|
.comp-stat-label {
|
|
font-size: 11px; color: var(--text-secondary, #8b949e);
|
|
text-transform: uppercase; letter-spacing: .3px;
|
|
}
|
|
.score-bar {
|
|
width: 80px; height: 6px; border-radius: 3px;
|
|
background: var(--bg-tertiary, #0d1117);
|
|
display: inline-block; vertical-align: middle; margin-left: 6px;
|
|
}
|
|
.score-bar-fill {
|
|
height: 100%; border-radius: 3px;
|
|
transition: width .3s;
|
|
}
|
|
.score-bar-fill.good { background: #3fb950; }
|
|
.score-bar-fill.warning { background: #f0b429; }
|
|
.score-bar-fill.bad { background: #f85149; }
|
|
|
|
/* ======= MODALS ======= */
|
|
.modal-overlay {
|
|
position: fixed; inset: 0; z-index: 1000;
|
|
background: rgba(0,0,0,.55); backdrop-filter: blur(4px);
|
|
display: flex; align-items: center; justify-content: center;
|
|
}
|
|
.modal-dialog {
|
|
background: var(--bg-secondary, #161b22);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
border-radius: 12px; width: 480px; max-width: 95vw;
|
|
max-height: 90vh; overflow-y: auto;
|
|
box-shadow: 0 16px 48px rgba(0,0,0,.4);
|
|
}
|
|
.modal-dialog.modal-lg { width: 640px; }
|
|
.modal-header {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: 16px 20px; border-bottom: 1px solid var(--border-primary, #2d333b);
|
|
}
|
|
.modal-header h3 { margin: 0; font-size: 15px; color: var(--text-primary, #e6edf3); }
|
|
.modal-body { padding: 20px; }
|
|
.modal-footer {
|
|
display: flex; justify-content: flex-end; gap: 8px;
|
|
padding: 12px 20px; border-top: 1px solid var(--border-primary, #2d333b);
|
|
}
|
|
.form-group { margin-bottom: 14px; }
|
|
.form-group label {
|
|
display: block; font-size: 12px; font-weight: 600;
|
|
color: var(--text-secondary, #8b949e); margin-bottom: 4px;
|
|
}
|
|
.form-control {
|
|
width: 100%; padding: 8px 10px; border-radius: 6px;
|
|
background: var(--bg-tertiary, #0d1117);
|
|
color: var(--text-primary, #e6edf3);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
font-size: 13px;
|
|
}
|
|
.form-row { display: flex; gap: 12px; }
|
|
.flex-1 { flex: 1; }
|
|
.code-textarea {
|
|
font-family: 'JetBrains Mono', monospace; font-size: 12px;
|
|
resize: vertical;
|
|
}
|
|
|
|
/* Buttons (reuse panel btn pattern) */
|
|
.btn-sm { padding: 6px 12px; font-size: 12px; }
|
|
.btn-outline {
|
|
background: transparent; color: var(--text-secondary, #8b949e);
|
|
border: 1px solid var(--border-primary, #2d333b);
|
|
}
|
|
.btn-outline:hover { color: var(--text-primary, #e6edf3); border-color: var(--text-secondary, #8b949e); }
|
|
|
|
/* Responsive */
|
|
@media (max-width: 1024px) {
|
|
.builder-layout { grid-template-columns: 160px 1fr; }
|
|
.builder-properties { display: none !important; }
|
|
.compliance-stats { grid-template-columns: repeat(2, 1fr); }
|
|
}
|
|
@media (max-width: 768px) {
|
|
.fleet-tabs { overflow-x: auto; }
|
|
.fleet-tab span:not(.material-icons) { display: none; }
|
|
.builder-layout { grid-template-columns: 1fr; }
|
|
.builder-palette { display: none; }
|
|
.compliance-stats { grid-template-columns: 1fr; }
|
|
.form-row { flex-direction: column; }
|
|
}
|