Files
chart-app/CLAUDE.md
T
Pit Friedrich bcf604b7c5 added gridstack
2026-07-25 21:56:47 +02:00

5.1 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

./mvnw spring-boot:run     # run app (default goal) — http://localhost:8080, ~30s first start
./mvnw compile              # compile only
./mvnw package               # production build → target/*.jar
java -jar target/*.jar       # run production jar

No test sources exist yet (src/test is empty) — spring-boot-starter-test and browserless-test-spring are on the classpath but unused.

Java 25 toolchain required (pom.xml sets java.version=25). If the default JDK on PATH is older (check java -version), point JAVA_HOME at a Java 25 install for the Maven build, e.g.:

JAVA_HOME="/path/to/jdk-25" ./mvnw compile

Port 8080 conflicts: a prior spring-boot:run left running in the background is the usual cause (Vaadin dev mode keeps a second process/thread alive under a different PID than the launching Maven process — killing the Maven process alone may not free the port). Find and stop the actual listener before restarting.

Architecture

Vaadin Flow (server-side Java UI, no hand-written HTML/JS for views) on Spring Boot 4.1, using the Aura theme (not Lumo — no @Theme annotation; Aura is wired via @StyleSheet(Aura.STYLESHEET) in Application.java).

Charts are ApexCharts, not Vaadin Charts. The bridge lives in components/:

  • ApexChart (abstract, @Tag("apex-chart")) — owns the JS module (frontend/components/apex-chart.ts, a Lit element rendering into light DOM), serializes an options Map to JSON via Jackson and calls renderChart client-side, and exposes point-click events back to the server via @ClientCallable.
  • AxisChart (abstract) — builds series/xaxis.categories options for line/bar.
  • LineChart, BarChart extend AxisChart; PieChart extends ApexChart directly (series/labels instead of axis-based).
  • DialectTheme — single source of chart styling (categorical color palette, grid/legend/stroke option fragments). Every chart's setData(...) starts from DialectTheme.baseOptions(chartType) and merges in its data. Add new chart types here, not by duplicating option maps.

Since apex-chart.ts renders into light DOM (createRenderRoot() returns this), global CSS can reach into the chart markup — but series/legend/grid colors are driven entirely by the options JSON, not CSS, because ApexCharts renders its own SVG/canvas.

GridStackLayout/GridStackItem (components/) wrap gridstack.js 13.1.0 for draggable/resizable grids. Unlike ApexChart, the bridge (frontend/components/grid-stack.ts) is a plain HTMLElement, not a Lit component — its children are server-rendered GridStackItems living in light DOM, and a Lit render root would fight gridstack for ownership of them. A MutationObserver calls makeWidget/removeWidget as Flow adds/removes children, so there's no explicit add/remove protocol to the client. Every GridStackItem needs a stable gs-id (auto-generated if not given) — GridStackLayout.setStorageKey(...) persists drag/resize state to browser localStorage keyed on it and restores by matching ids, so items lose their saved position if their id changes between reloads. Item styling (.grid-stack-item-content) extends the --dialect-* alias layer in styles.css, same as .dialect-card.

Views (views/): MainLayout (@Layout, applies to all routes) is the AppLayout shell — navbar + SideNav drawer, with one SideNavItem per route. Routes: DashboardView (@Route("")) wraps each chart in a Card (components/Card.java); FormView (@Route("formular")) demonstrates form controls bound via Binder; TableView (@Route("tabelle")) demonstrates a Grid over dummy data with a live text filter (GridListDataView.addFilter, TextField in ValueChangeMode.EAGER). New views should reuse Card to wrap their content rather than adding components directly, and get a matching SideNavItem in MainLayout.

Styling: src/main/resources/META-INF/resources/styles.css is the one project-level stylesheet (loaded via @StyleSheet("styles.css") in Application.java). It defines --dialect-* design tokens (Dialect design system: primary orange #E86C00, cool-gray background, card radius/shadow) and aliases them onto Aura's own CSS custom properties (--aura-accent-color-*, --aura-background-color-*, --aura-orange, --aura-yellow) rather than fighting the theme. Aura tokens use OKLCH + relative-color syntax and accept plain hex overrides. When restyling, prefer extending this alias layer over hardcoding new colors in components.

UI copy/data (chart labels, notifications) is in German.

AI-Autofix Regeln

  • Nur Issues mit Label ai-ready bearbeiten.
  • Branch-Namensschema: ai/issue-<nr>-<kurz-slug>.
  • Kein Fix ohne grüne Tests. Test-Befehl: <dein Testkommando>.
  • Bei Unklarheit / Scope > ~200 Zeilen Diff: NICHT fixen, stattdessen Issue kommentieren ("needs human") und Label ai-blocked setzen.
  • PR-Beschreibung MUSS Closes #<nr> enthalten.
  • Keine Änderungen an <kritische Pfade, z.B. build config, Migrations> ohne Freigabe.