Compact circuit editor header, pin grid headers, scope sidebar to project
The circuit editor page now fills the viewport so only the grid scrolls and its sticky column headers stay visible. The large page title is replaced by a compact title bar with back link, board number/name, the feeding reference, the toolbar and a condensed power summary. Inside a project the sidebar shows only the active project with its sections, an expandable board list ordered by logical feed (current board highlighted), Revit and the print view. The feed ordering is shared with the print view through orderDistributionBoardsByFeed. Refs #26 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
898be43ebc
commit
07bc52a134
7 changed files with 444 additions and 156 deletions
|
|
@ -753,6 +753,7 @@ a.kpi:hover {
|
|||
.editor-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
|
@ -762,6 +763,41 @@ a.kpi:hover {
|
|||
box-shadow: 0 1px 0 var(--panel-border-strong);
|
||||
}
|
||||
|
||||
/* Back link and board title at the start of the editor toolbar. */
|
||||
.editor-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.editor-heading-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.editor-heading-kicker {
|
||||
color: var(--text-subtle);
|
||||
font-size: 0.68rem;
|
||||
line-height: 1.15;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.editor-heading-title {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
margin: 0;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.editor-heading-title span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.editor-toolbar button {
|
||||
border: 1px solid var(--panel-border-strong);
|
||||
background: var(--panel-bg);
|
||||
|
|
@ -868,11 +904,14 @@ a.kpi:hover {
|
|||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Compact board power figures at the right end of the editor toolbar. */
|
||||
.distribution-power-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(12rem, 1fr));
|
||||
gap: 0.5rem;
|
||||
padding: 0.55rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.25rem 0.9rem;
|
||||
margin-left: auto;
|
||||
padding: 0.2rem 0.6rem;
|
||||
border: 1px solid var(--panel-border);
|
||||
border-radius: 5px;
|
||||
background: var(--panel-bg-subtle);
|
||||
|
|
@ -881,24 +920,20 @@ a.kpi:hover {
|
|||
.distribution-power-summary > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15rem;
|
||||
gap: 0.05rem;
|
||||
}
|
||||
|
||||
.distribution-power-summary span {
|
||||
color: var(--text-subtle);
|
||||
font-size: 0.74rem;
|
||||
line-height: 1.2;
|
||||
font-size: 0.68rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.distribution-power-summary strong {
|
||||
color: var(--text-strong);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.distribution-power-summary {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.15;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.column-settings-menu {
|
||||
|
|
@ -1072,6 +1107,48 @@ a.kpi:hover {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
/* The editor page fills the viewport; only the grid scrolls, so its sticky
|
||||
column headers stay visible. Small screens fall back to page scrolling. */
|
||||
.circuit-editor-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.circuit-editor-page > .tree-editor-shell {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.circuit-editor-page .tree-editor-layout {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.circuit-editor-page .tree-grid-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
@media (max-width: 720px), (max-height: 540px) {
|
||||
.circuit-editor-page {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.circuit-editor-page .tree-grid-wrap {
|
||||
max-height: max(28rem, calc(100vh - 8rem));
|
||||
}
|
||||
}
|
||||
|
||||
.project-device-sidebar {
|
||||
border: 1px solid var(--panel-border);
|
||||
background: var(--panel-bg);
|
||||
|
|
|
|||
|
|
@ -1,38 +1,17 @@
|
|||
"use client";
|
||||
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
import { CircuitTreeEditor } from "../../../../../../frontend/components/circuit-tree-editor";
|
||||
|
||||
// The editor renders its own compact title bar (back link, board name and
|
||||
// toolbar) and fills the viewport so only the grid scrolls and its column
|
||||
// headers stay visible.
|
||||
export default function CircuitTreeEditPage() {
|
||||
const params = useParams<{ projectId: string; circuitListId: string }>();
|
||||
|
||||
return (
|
||||
<main className="container-fluid px-3 px-xxl-4 py-4">
|
||||
<div className="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-3">
|
||||
<div className="d-flex align-items-center gap-2">
|
||||
<Link
|
||||
aria-label="Zurück zur Verteilerübersicht"
|
||||
className="btn btn-outline-secondary btn-sm"
|
||||
href={`/projects/${params.projectId}`}
|
||||
title="Zurück zur Verteilerübersicht"
|
||||
>
|
||||
<ArrowLeft aria-hidden="true" size={18} />
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="h4 mb-1">Stromkreisliste</h1>
|
||||
<p className="text-secondary mb-0">Stromkreise und zugeordnete Geräte bearbeiten.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex gap-2">
|
||||
<Link href={`/projects/${params.projectId}`} className="btn btn-outline-secondary btn-sm">
|
||||
Zum Projekt
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<main className="circuit-editor-page container-fluid px-3 px-xxl-4">
|
||||
<CircuitTreeEditor projectId={params.projectId} circuitListId={params.circuitListId} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,9 @@ const projectDeviceFilterCollapsedStorageKey =
|
|||
"leistungsbilanz:overview-filter-collapsed:project-devices";
|
||||
const createFeederCircuitSelectValue = "__create_feeder_circuit__";
|
||||
|
||||
// Lets the sidebar refresh its board list after boards change here.
|
||||
const DISTRIBUTION_BOARDS_CHANGED_EVENT = "leistungsbilanz:distribution-boards-changed";
|
||||
|
||||
export default function ProjectDetailPage() {
|
||||
const params = useParams<{ projectId: string }>();
|
||||
const [projectId, setProjectId] = useState("");
|
||||
|
|
@ -217,6 +220,10 @@ export default function ProjectDetailPage() {
|
|||
setProjectId(params.projectId);
|
||||
}, [params.projectId]);
|
||||
|
||||
useEffect(() => {
|
||||
window.dispatchEvent(new Event(DISTRIBUTION_BOARDS_CHANGED_EVENT));
|
||||
}, [boards]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!projectId) {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue