Move engine stop, pause, and scheduler tuning controls into the executor footer status bar. - Add a footer EngineControlMenu popover with stop/start, pause/resume, and debounced concurrency/worktree sliders. - Remove the engine controls from the dashboard header and wire the footer running-state text to open the controls. - Update dashboard tests, English labels, and operator documentation for the footer control location. Files changed: docs/dashboard-guide.md | 4 + packages/dashboard/app/App.tsx | 7 - .../app/__tests__/tablet-header-controls.test.tsx | 21 +- .../dashboard/app/components/EngineControlMenu.css | 118 +++++++++ .../dashboard/app/components/EngineControlMenu.tsx | 292 +++++++++++++++++++++ .../dashboard/app/components/ExecutorStatusBar.css | 28 ++ .../dashboard/app/components/ExecutorStatusBar.tsx | 25 +- packages/dashboard/app/components/Header.css | 89 ------- packages/dashboard/app/components/Header.tsx | 81 +----- .../app/components/__tests__/App.test.tsx | 132 ---------- .../__tests__/EngineControlMenu.test.tsx | 145 ++++++++++ .../__tests__/ExecutorStatusBar.test.tsx | 40 +++ .../app/components/__tests__/Header.test.tsx | 57 +--- .../components/__tests__/MultiProjectFlow.test.tsx | 8 - .../app/components/__tests__/ResearchView.test.tsx | 4 - packages/i18n/locales/en/app.json | 5 +- 16 files changed, 666 insertions(+), 390 deletions(-) Fusion-Task-Id: FN-6844 Fusion-Task-Lineage: f0e17e3d-489e-483c-ba7d-a020c111231c
119 lines
2.5 KiB
CSS
119 lines
2.5 KiB
CSS
.engine-control-menu {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.engine-control-menu__trigger {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.engine-control-menu__trigger:hover {
|
|
color: var(--text);
|
|
}
|
|
|
|
.engine-control-menu__popover {
|
|
position: absolute;
|
|
right: 0;
|
|
bottom: calc(100% + var(--space-xs));
|
|
z-index: 70;
|
|
width: min(24rem, calc(100vw - (var(--space-lg) * 2)));
|
|
max-height: min(32rem, calc(100vh - var(--space-2xl)));
|
|
overflow: auto;
|
|
padding: var(--space-md);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-md);
|
|
background: var(--surface-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-lg);
|
|
color: var(--text);
|
|
}
|
|
|
|
.engine-control-menu__section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.engine-control-menu__section--actions {
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.engine-control-menu__action {
|
|
width: 100%;
|
|
justify-content: flex-start;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.engine-control-menu__action:disabled {
|
|
opacity: var(--opacity-disabled);
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.engine-control-menu__section-header,
|
|
.engine-control-menu__slider-label {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: var(--space-md);
|
|
}
|
|
|
|
.engine-control-menu__section-header {
|
|
color: var(--text);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.engine-control-menu__save-state {
|
|
color: var(--text-muted);
|
|
font-size: var(--font-size-xs);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.engine-control-menu__save-state--saving {
|
|
color: var(--color-warning);
|
|
}
|
|
|
|
.engine-control-menu__save-state--saved {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
.engine-control-menu__save-state--error,
|
|
.engine-control-menu__error {
|
|
color: var(--color-error);
|
|
}
|
|
|
|
.engine-control-menu__slider {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.engine-control-menu__slider-label strong {
|
|
color: var(--text);
|
|
font-family: var(--font-mono);
|
|
}
|
|
|
|
.engine-control-menu__range {
|
|
width: 100%;
|
|
accent-color: var(--color-primary);
|
|
}
|
|
|
|
.engine-control-menu__error {
|
|
margin: 0;
|
|
font-size: var(--font-size-xs);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.engine-control-menu__popover {
|
|
position: fixed;
|
|
left: var(--space-sm);
|
|
right: var(--space-sm);
|
|
bottom: calc(var(--mobile-nav-height) + max(env(safe-area-inset-bottom, 0px), var(--space-md)) + var(--space-2xl));
|
|
width: auto;
|
|
max-height: min(28rem, calc(100vh - var(--mobile-nav-height) - var(--space-3xl)));
|
|
}
|
|
}
|