/** * Sichtbarkeit / Umfang für body_history_viz (sync mit backend dashboard_widget_config). * `null` / fehlend → Verlauf: alles sichtbar (vollständige Parität zur History-Seite). */ /** Verlauf-Tab Körper: volle Parität (kein Layout-Config). */ export const BODY_HISTORY_VIZ_HISTORY_FULL = { chart_days: 90, show_goals_strip: true, show_intro_blurb: true, show_layer_meta: true, show_kpis: true, kpi_detail: 'full', show_weight_chart: true, show_body_fat_chart: true, show_proportion_chart: true, show_circumference_index_chart: true, show_circumference_lines_chart: true, } /** Default für Dashboard-Widget (schlank). */ export const BODY_HISTORY_VIZ_WIDGET_DEFAULTS = { chart_days: 30, show_goals_strip: false, show_intro_blurb: false, show_layer_meta: false, show_kpis: true, kpi_detail: 'compact', show_weight_chart: true, show_body_fat_chart: false, show_proportion_chart: false, show_circumference_index_chart: false, show_circumference_lines_chart: false, } const BOOL_KEYS = [ 'show_goals_strip', 'show_intro_blurb', 'show_layer_meta', 'show_kpis', 'show_weight_chart', 'show_body_fat_chart', 'show_proportion_chart', 'show_circumference_index_chart', 'show_circumference_lines_chart', ] /** * @param {Record|null|undefined} raw — aus Layout-Config (Backend liefert nach Save ggf. alle Keys) * @returns {typeof BODY_HISTORY_VIZ_WIDGET_DEFAULTS} */ export function normalizeBodyHistoryVizConfig(raw) { const base = { ...BODY_HISTORY_VIZ_WIDGET_DEFAULTS } if (!raw || typeof raw !== 'object') return base for (const k of BOOL_KEYS) { if (Object.prototype.hasOwnProperty.call(raw, k)) { base[k] = raw[k] === true } } if (raw.kpi_detail === 'full' || raw.kpi_detail === 'compact') { base.kpi_detail = raw.kpi_detail } if (raw.chart_days != null) { const n = Number(raw.chart_days) if (Number.isFinite(n)) { base.chart_days = Math.min(90, Math.max(7, Math.round(n))) } } return base } const COMPACT_KPI_KEYS = new Set(['weight', 'bf', 'lean_ffmi']) /** * @param {Array<{ key: string }>} tiles * @param {'compact'|'full'} detail */ export function filterBodyHistoryKpiTiles(tiles, detail) { if (detail === 'full' || !Array.isArray(tiles)) return tiles return tiles.filter((t) => COMPACT_KPI_KEYS.has(t.key)) }