feat(260929-dmx): Widget-Raster horizontal doppelt so fein (48 Spalten, Version 3)

- COLS lg 48 / md 40 / sm 24 / xs 16 / xxs 4, Zeilenhoehe und Abstand unveraendert
- Migration stufenweise: v1->v2 wie bisher, v2->v3 nur x/w/minW/maxW x2
- Rueckfallwerte fuer Widgets ohne Eintrag auf 8 Einheiten

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 09:51:26 +02:00
parent acd3c7a05f
commit 97744b59cd
5 changed files with 123 additions and 57 deletions
@@ -194,7 +194,7 @@ describe('DashboardGrid', () => {
expect(document.querySelector('.widget-drag-handle')).toBeInTheDocument();
});
it('quick-260916-bwo Test 4: Grid-Props — 24/20/12/8/2 Spalten, rowHeight 20, margin 12, Breakpoints unveraendert, containerPadding folgt dem margin', async () => {
it('quick-260916-bwo Test 4: Grid-Props — 48/40/24/16/4 Spalten (quick-260929-dmx), rowHeight 20, margin 12, Breakpoints unveraendert, containerPadding folgt dem margin', async () => {
captured.props = null;
const { DashboardGrid } = await import('./dashboard-grid');
render(
@@ -208,7 +208,7 @@ describe('DashboardGrid', () => {
);
expect(captured.props).not.toBeNull();
expect(captured.props?.cols).toEqual({ lg: 24, md: 20, sm: 12, xs: 8, xxs: 2 });
expect(captured.props?.cols).toEqual({ lg: 48, md: 40, sm: 24, xs: 16, xxs: 4 });
expect(captured.props?.rowHeight).toBe(20);
expect(captured.props?.margin).toEqual([12, 12]);
expect(captured.props?.breakpoints).toEqual({ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 });
@@ -503,9 +503,9 @@ describe('RESIZE_AXIS_FALLBACK (Design „Mosaik“, Runde 3)', () => {
describe('centeringOffset (Design „Mosaik“, Runde 3)', () => {
it('stellt belegte Spalten mittig und laesst eine volle Anordnung stehen', () => {
// 24 Spalten auf 1212 px: Spalte 38 px + 12 px Abstand = 50 px je Spalte.
expect(centeringOffset([{ x: 0, w: 12 }], 24, 1212)).toBe(300);
expect(centeringOffset([{ x: 12, w: 12 }], 24, 1212)).toBe(0);
expect(centeringOffset([], 24, 1212)).toBe(0);
// 48 Spalten auf 1212 px: Spalte 13 px + 12 px Abstand = 25 px je Spalte.
expect(centeringOffset([{ x: 0, w: 24 }], 48, 1212)).toBe(300);
expect(centeringOffset([{ x: 24, w: 24 }], 48, 1212)).toBe(0);
expect(centeringOffset([], 48, 1212)).toBe(0);
});
});
@@ -14,9 +14,16 @@ import { WidgetWrapper } from './widgets/widget-wrapper';
// quick-260916-bwo: Raster doppelt so fein wie zuvor (24 statt 12 Spalten,
// 20 statt 40 px Zeilenhoehe, 8 statt 16 px Abstand). Gespeicherte Anordnungen
// in alten Einheiten werden in `@/lib/grid-layout-migration` einmalig
// umgerechnet und mit `__gridVersion: 2` markiert. BREAKPOINTS unveraendert.
// umgerechnet und mit `__gridVersion` markiert. BREAKPOINTS unveraendert.
//
// quick-260929-dmx (Version 3): Raster in der BREITE noch einmal doppelt so
// fein (48 statt 24 Spalten am lg-Breakpoint, uebrige Breakpoints ebenso
// verdoppelt). Zeilenhoehe (20 px) und Abstand (12 px) bleiben. Alle
// Breitenwerte (x, w, minW, maxW, WIDGET_CONSTRAINTS, Rueckfallwerte) sind
// damit in 48stel-Einheiten; gespeicherte Anordnungen rechnet die Migration
// einmalig um, jedes Widget behaelt seine Bildschirmgroesse und -position.
const BREAKPOINTS = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 };
const COLS = { lg: 24, md: 20, sm: 12, xs: 8, xxs: 2 };
const COLS = { lg: 48, md: 40, sm: 24, xs: 16, xxs: 4 };
// quick-260916-dyv: Ziehen zuverlaessig.
// - Griff ist die GANZE Karte (`widget-drag-handle` in widget-wrapper.tsx).
@@ -379,10 +386,10 @@ export function DashboardGrid({
...(effectiveLayouts.lg?.find((l) => l.i === widget.id) ?? {
x: 0,
y: 0,
w: constraints?.defaultW ?? 4,
w: constraints?.defaultW ?? 8,
h: constraints?.defaultH ?? 4,
}),
minW: constraints?.minW ?? 4,
minW: constraints?.minW ?? 8,
minH: constraints?.minH ?? 4,
}}
>