/** * Sichtbarkeit für recovery_history_viz (sync mit backend dashboard_widget_config). * `visibility === undefined` → Verlauf: volle Erholungs-Übersicht (wie bisher). */ export const RECOVERY_HISTORY_VIZ_HISTORY_FULL = { chart_days: 30, show_layer_meta: true, show_kpis: true, kpi_detail: 'full', show_progress_insights: true, show_sleep_section_heading: true, show_chart_recovery_score: true, show_chart_sleep_quality: true, show_chart_sleep_debt: true, show_heart_section_heading: true, show_heart_context_card: true, show_chart_hrv_rhr: true, show_vitals_extra_heading: true, show_vitals_extra_trends: true, } export const RECOVERY_HISTORY_VIZ_WIDGET_DEFAULTS = { chart_days: 30, show_layer_meta: false, show_kpis: true, kpi_detail: 'compact', show_progress_insights: false, show_sleep_section_heading: true, show_chart_recovery_score: true, show_chart_sleep_quality: true, show_chart_sleep_debt: false, show_heart_section_heading: true, show_heart_context_card: false, show_chart_hrv_rhr: true, show_vitals_extra_heading: false, show_vitals_extra_trends: false, } const BOOL_KEYS = [ 'show_layer_meta', 'show_kpis', 'show_progress_insights', 'show_sleep_section_heading', 'show_chart_recovery_score', 'show_chart_sleep_quality', 'show_chart_sleep_debt', 'show_heart_section_heading', 'show_heart_context_card', 'show_chart_hrv_rhr', 'show_vitals_extra_heading', 'show_vitals_extra_trends', ] /** * @param {Record|null|undefined} raw */ export function normalizeRecoveryHistoryVizConfig(raw) { const base = { ...RECOVERY_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 } /** * @param {Array} kpiTiles * @param {'compact'|'full'} detail */ export function filterRecoveryHistoryKpiTiles(kpiTiles, detail) { if (detail === 'full' || !Array.isArray(kpiTiles)) return kpiTiles return kpiTiles.slice(0, 4) }