Menue nicht mehr abschneiden, Zeile teilt sich nach dem Ausblenden neu auf
Zwei Fehler aus dem Sparring, beide an der Diagrammkarte. **Das Optionsmenue war abgeschnitten.** Die Karte trug `overflow-hidden`, das Menue klappt aus dem Kopf heraus, und der zweite Eintrag war nur zur Haelfte zu sehen. Das Beschneiden ist entfallen; die runden Ecken brauchen es nicht, weil Kopf und Koerper 16 px Innenabstand haben und nichts an der Kante anliegt. **Nach dem Ausblenden blieb eine Luecke.** Die Zeilen waren ein Raster mit festen Spalten. Blendet man eine Karte aus, gibt ChartCard `null` zurueck, die Spalte bleibt aber stehen und die Nachbarkarte behaelt ihre zwei Drittel. Neu ist `ChartReihe` in PageContainer.tsx: eine Flexzeile statt eines Rasters. Die verbliebenen Karten verteilen den Platz unter sich neu, ohne dass jemand mitzaehlen muesste, wie viele gerade sichtbar sind. Nachgemessen auf /analytics: Der Zahlungsverlauf geht von 574 px auf 1164 px, sobald die Nachbarkachel verschwindet. Zehn Zeilen auf allen fuenf Analyse-Seiten umgestellt. `gleichHoch` haelt die Unterscheidung aus dem letzten Sparring fest: gestreckt nur, wo die Karten dieselbe Bauart haben. Beim Umbau eine Regression gebaut und durch Nachmessen gefunden: Aus 885/443 wurde 664/664. `[&>*]:flex-1` erzeugt den Selektor `.zeile > *`, und der ist spezifischer als eine Klasse am Kind, also verlor `xl:flex-[2]`. Jetzt `xl:flex-[2]!`, mit dem Grund als Kommentar an der Komponente. Nachgemessen nach der Aenderung, alle Zeilen: 885/443 wo zwei zu eins gewollt ist, 389/389 und 409/409 und 595/595 wo gleiche Hoehe gewollt ist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
This commit is contained in:
1 parent
f5a3ccd634
commit
bada5db344
7 files changed
+84
-31
No files matched your search
@@ -68,8 +68,14 @@ export function ChartCard({
|
||||
if (!istSichtbar(id)) return null;
|
||||
|
||||
return (
|
||||
/* Kein `overflow-hidden`: Das Optionsmenü klappt aus dem Kartenkopf heraus
|
||||
und wurde an der Kartenkante abgeschnitten. Ein Menü, von dem man den
|
||||
zweiten Eintrag nur zur Hälfte sieht, ist unbenutzbar.
|
||||
|
||||
Die Kante braucht das Beschneiden auch nicht: Kopf und Körper haben
|
||||
16 px Innenabstand, es liegt nichts an den runden Ecken an. */
|
||||
<section
|
||||
className={`flex flex-col overflow-hidden rounded-lg border border-solid border-border-default bg-white shadow-sm ${className}`}
|
||||
className={`flex flex-col rounded-lg border border-solid border-border-default bg-white shadow-sm ${className}`}
|
||||
>
|
||||
<header className="flex flex-none items-start justify-between gap-3 px-4 pb-3 pt-4">
|
||||
<div className="flex min-w-0 flex-col">
|
||||
|
||||
@@ -56,3 +56,50 @@ export function Raster({
|
||||
<div className={`${klassen[spalten]} ${obenBuendig ? "items-start" : ""}`}>{children}</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eine Zeile aus Diagrammkarten.
|
||||
*
|
||||
* Bewusst Flexbox und kein Raster. Karten lassen sich ueber das Menü
|
||||
* ausblenden; `ChartCard` gibt dann `null` zurueck. In einem Raster mit festen
|
||||
* Spalten bleibt an dieser Stelle eine Luecke stehen, und die Nachbarkarte
|
||||
* behaelt ihre zwei Drittel. Im Flexbereich verteilen die verbliebenen Karten
|
||||
* den Platz unter sich neu, ohne dass jemand mitzaehlen muesste, wie viele
|
||||
* gerade sichtbar sind.
|
||||
*
|
||||
* `[&>*]:flex-1` gibt jeder Karte denselben Anteil und ist zugleich das
|
||||
* Sicherheitsnetz: Ohne eigene Breitenangabe schrumpfte ein Flexkind auf seine
|
||||
* Inhaltsbreite, und ein Diagramm mit `ResponsiveContainer` faellt dann in sich
|
||||
* zusammen.
|
||||
*
|
||||
* Eine breitere Karte bekommt `xl:flex-[2]!` mit. Das Ausrufezeichen ist noetig
|
||||
* und kein Reflex: `[&>*]:flex-1` erzeugt den Selektor `.zeile > *`, und der
|
||||
* ist spezifischer als eine Klasse am Kind. Ohne `!` gewinnt die Zeilenregel,
|
||||
* und aus zwei Dritteln zu einem Drittel wird die Haelfte zur Haelfte. Genau
|
||||
* das ist beim Umbau hier passiert und wurde durch Nachmessen gefunden.
|
||||
*
|
||||
* `min-w-0` ist Pflicht: Ohne das nimmt ein Flexkind seine Inhaltsbreite als
|
||||
* Untergrenze, und ein Diagramm mit langer Achsenbeschriftung drueckt die
|
||||
* Zeile ueber den Rand.
|
||||
*/
|
||||
export function ChartReihe({
|
||||
/** Ab welcher Breite die Karten nebeneinander stehen. */
|
||||
umbruch = "xl",
|
||||
/**
|
||||
* Gleiche Hoehe fuer alle Karten der Zeile. Nur richtig, wenn sie dieselbe
|
||||
* Bauart haben (zwei Listen, zwei Diagramme). Sonst oben buendig,
|
||||
* siehe docs/DESIGN-SYSTEM.md, Abschnitt "Kartenhoehen in einer Zeile".
|
||||
*/
|
||||
gleichHoch = false,
|
||||
children,
|
||||
}: {
|
||||
umbruch?: "lg" | "xl";
|
||||
gleichHoch?: boolean;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const klassen =
|
||||
umbruch === "lg"
|
||||
? `flex flex-col gap-4 lg:flex-row ${gleichHoch ? "lg:items-stretch" : "lg:items-start"} [&>*]:min-w-0 lg:[&>*]:flex-1`
|
||||
: `flex flex-col gap-4 xl:flex-row ${gleichHoch ? "xl:items-stretch" : "xl:items-start"} [&>*]:min-w-0 xl:[&>*]:flex-1`;
|
||||
return <div className={klassen}>{children}</div>;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { ChartReihe, PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { KPICard } from "../components/cards/KPICard";
|
||||
import { ChartCard } from "../components/cards/ChartCard";
|
||||
import { StatZeile } from "../components/cards/StatZeile";
|
||||
@@ -142,12 +142,12 @@ export function AuftraegeSeite({ vm }: { vm: VMState<AuftraegeDaten> }) {
|
||||
/>
|
||||
</Raster>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 xl:grid-cols-3">
|
||||
<ChartReihe umbruch="xl">
|
||||
<ChartCard
|
||||
id="auftraege-eingang"
|
||||
titel="Auftragseingang"
|
||||
untertitel="Neu angelegte Vorgänge im Zeitverlauf"
|
||||
className="xl:col-span-2"
|
||||
className="xl:flex-[2]!"
|
||||
>
|
||||
<BalkenVertikal daten={d.eingang} formatWert={(w) => formatZahl(w)} hoehe={250} nurGanzzahlen />
|
||||
<StatZeile
|
||||
@@ -170,9 +170,9 @@ export function AuftraegeSeite({ vm }: { vm: VMState<AuftraegeDaten> }) {
|
||||
>
|
||||
<Trichter stufen={d.trichter} formatWert={(w) => formatZahl(w)} />
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-3">
|
||||
<ChartReihe umbruch="lg">
|
||||
<ChartCard
|
||||
id="auftraege-status"
|
||||
titel="Vorgänge nach Status"
|
||||
@@ -224,7 +224,7 @@ export function AuftraegeSeite({ vm }: { vm: VMState<AuftraegeDaten> }) {
|
||||
]}
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<ChartCard
|
||||
id="auftraege-liste"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { ChartReihe, PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { KPICard } from "../components/cards/KPICard";
|
||||
import { ChartCard } from "../components/cards/ChartCard";
|
||||
import { StatZeile } from "../components/cards/StatZeile";
|
||||
@@ -140,13 +140,13 @@ export function FinanzenSeite({ vm }: { vm: VMState<FinanzenDaten> }) {
|
||||
/>
|
||||
</Raster>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 xl:grid-cols-3">
|
||||
<ChartReihe umbruch="xl" gleichHoch>
|
||||
<ChartCard
|
||||
id="finanzen-verlauf"
|
||||
titel="Zahlungseingang im Zeitverlauf"
|
||||
untertitel="Aktueller Zeitraum gegen Vorjahr"
|
||||
hinweis="Grundlage sind bezahlte Ausgangsrechnungen zum Zahlungsdatum."
|
||||
className="xl:col-span-2"
|
||||
className="xl:flex-[2]!"
|
||||
legende={
|
||||
<ChartLegende
|
||||
eintraege={[
|
||||
@@ -189,11 +189,11 @@ export function FinanzenSeite({ vm }: { vm: VMState<FinanzenDaten> }) {
|
||||
formatMitte={formatEuro}
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-3">
|
||||
<ChartReihe umbruch="lg">
|
||||
<ChartCard
|
||||
className="lg:col-span-2"
|
||||
className="lg:flex-[2]!"
|
||||
id="finanzen-alter"
|
||||
titel="Offene Forderungen nach Alter"
|
||||
untertitel={`Gesamt ${formatEuro(d.posten.gesamt)}`}
|
||||
@@ -234,7 +234,7 @@ export function FinanzenSeite({ vm }: { vm: VMState<FinanzenDaten> }) {
|
||||
/>
|
||||
</ChartCard>
|
||||
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<ChartCard
|
||||
id="finanzen-offene-liste"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { ChartReihe, PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { KPICard } from "../components/cards/KPICard";
|
||||
import { ChartCard } from "../components/cards/ChartCard";
|
||||
import { BalkenVertikal } from "../components/charts/BalkenVertikal";
|
||||
@@ -133,12 +133,12 @@ export function KundenSeite({ vm }: { vm: VMState<KundenDaten> }) {
|
||||
/>
|
||||
</Raster>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 xl:grid-cols-3">
|
||||
<ChartReihe umbruch="xl">
|
||||
<ChartCard
|
||||
id="kunden-entwicklung"
|
||||
titel="Neukunden im Zeitverlauf"
|
||||
untertitel="Anlagedatum des Kundendatensatzes"
|
||||
className="xl:col-span-2"
|
||||
className="xl:flex-[2]!"
|
||||
>
|
||||
<BalkenVertikal daten={d.entwicklung} formatWert={(w) => formatZahl(w)} hoehe={250} nurGanzzahlen />
|
||||
</ChartCard>
|
||||
@@ -156,9 +156,9 @@ export function KundenSeite({ vm }: { vm: VMState<KundenDaten> }) {
|
||||
mitteLabel="Kunden"
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-2">
|
||||
<ChartReihe umbruch="lg">
|
||||
<ChartCard id="kunden-typ" titel="Kundenstruktur" untertitel="Privat, Gewerbe, Verwaltung">
|
||||
<Donut
|
||||
daten={d.nachTyp}
|
||||
@@ -176,9 +176,9 @@ export function KundenSeite({ vm }: { vm: VMState<KundenDaten> }) {
|
||||
>
|
||||
<BalkenHorizontal daten={d.topKunden} formatWert={formatEuroKompakt} />
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 xl:grid-cols-2">
|
||||
<ChartReihe umbruch="xl">
|
||||
<ChartCard
|
||||
id="kunden-inaktiv"
|
||||
titel={`Reaktivierungspotenzial (${d.inaktive.length})`}
|
||||
@@ -206,7 +206,7 @@ export function KundenSeite({ vm }: { vm: VMState<KundenDaten> }) {
|
||||
leerText="Keine Auffälligkeiten"
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
</PageContainer>
|
||||
</>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { ChartReihe, PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { KPICard } from "../components/cards/KPICard";
|
||||
import { ChartCard } from "../components/cards/ChartCard";
|
||||
import { AuslastungsBalken } from "../components/charts/AuslastungsBalken";
|
||||
@@ -159,7 +159,7 @@ export function TeamSeite({ vm }: { vm: VMState<TeamDaten> }) {
|
||||
/>
|
||||
</ChartCard>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-2">
|
||||
<ChartReihe umbruch="lg">
|
||||
<ChartCard
|
||||
id="team-abschluesse"
|
||||
titel="Abschlüsse je Mitarbeiter"
|
||||
@@ -190,7 +190,7 @@ export function TeamSeite({ vm }: { vm: VMState<TeamDaten> }) {
|
||||
mitteLabel="Stunden"
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<ChartCard
|
||||
id="team-tabelle"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { ChartReihe, PageContainer, Raster } from "../components/layout/PageContainer";
|
||||
import { KPICard } from "../components/cards/KPICard";
|
||||
import { ChartCard } from "../components/cards/ChartCard";
|
||||
import { AlertList } from "../components/cards/AlertList";
|
||||
@@ -131,13 +131,13 @@ export function UebersichtSeite({ vm }: { vm: VMState<UebersichtDaten> }) {
|
||||
<AlertList eintraege={d.alerts} spalten={2} />
|
||||
</ChartCard>
|
||||
|
||||
<div className="grid grid-cols-1 items-start gap-4 xl:grid-cols-3">
|
||||
<ChartReihe umbruch="xl">
|
||||
<ChartCard
|
||||
id="uebersicht-umsatzverlauf"
|
||||
titel="Zahlungseingang im Zeitverlauf"
|
||||
untertitel="Aktueller Zeitraum gegen den Vorjahreszeitraum"
|
||||
hinweis="Gezählt wird der Tag des Zahlungseingangs, nicht das Rechnungsdatum. Dadurch entspricht die Kurve dem tatsächlichen Geldfluss."
|
||||
className="xl:col-span-2"
|
||||
className="xl:flex-[2]!"
|
||||
legende={
|
||||
<ChartLegende
|
||||
eintraege={[
|
||||
@@ -179,9 +179,9 @@ export function UebersichtSeite({ vm }: { vm: VMState<UebersichtDaten> }) {
|
||||
einfarbig={false}
|
||||
/>
|
||||
</ChartCard>
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
||||
<ChartReihe umbruch="lg" gleichHoch>
|
||||
<ChartCard
|
||||
id="uebersicht-trichter"
|
||||
titel="Vertriebstrichter"
|
||||
@@ -206,7 +206,7 @@ export function UebersichtSeite({ vm }: { vm: VMState<UebersichtDaten> }) {
|
||||
/>
|
||||
</ChartCard>
|
||||
|
||||
</div>
|
||||
</ChartReihe>
|
||||
|
||||
<ChartCard
|
||||
id="uebersicht-ueberfaellig"
|
||||
|
||||
Reference in new issue
Block a user