feat: Improve body chart days configuration in DashboardLabPage
- Introduced a draft state for body chart days input to allow for temporary edits without immediate clamping. - Updated input handling to support numeric input mode and improved accessibility with aria-label. - Enhanced save and reset functionalities to manage the new draft state effectively. - Refactored layout normalization to accommodate changes in body chart days configuration.
This commit is contained in:
parent
87c4cbc4b4
commit
4493b140bd
|
|
@ -28,15 +28,28 @@ export default function DashboardLabPage() {
|
|||
const [err, setErr] = useState(null)
|
||||
const [busy, setBusy] = useState(false)
|
||||
const [msg, setMsg] = useState(null)
|
||||
/** Während der Fokus im Körper-Chart-Feld: Rohstring, damit Tippen (z. B. „14“) nicht sofort geclamped wird */
|
||||
const [bodyChartDaysDraft, setBodyChartDaysDraft] = useState(null)
|
||||
|
||||
const metaById = catalogMetaById(catalog)
|
||||
|
||||
const commitBodyChartDraftToLayout = useCallback((draftStr, baseLayout) => {
|
||||
const clamped = normalizeBodyChartDays(draftStr === '' || draftStr == null ? BODY_CHART_DAYS_DEFAULT : draftStr)
|
||||
return {
|
||||
...baseLayout,
|
||||
widgets: baseLayout.widgets.map((x) =>
|
||||
x.id !== 'body_overview' ? x : { ...x, config: { ...x.config, chart_days: clamped } }
|
||||
),
|
||||
}
|
||||
}, [])
|
||||
|
||||
const load = useCallback(async () => {
|
||||
setErr(null)
|
||||
try {
|
||||
const [cat, b] = await Promise.all([api.getAppWidgetsCatalog(), api.getAppDashboardLayout()])
|
||||
setCatalog(cat)
|
||||
setBundle(b)
|
||||
setBodyChartDaysDraft(null)
|
||||
setLayout(normalizeLayoutForEditor(b.layout))
|
||||
} catch (e) {
|
||||
setErr(formatFastApiDetail(null, e.message))
|
||||
|
|
@ -49,11 +62,17 @@ export default function DashboardLabPage() {
|
|||
|
||||
const save = async () => {
|
||||
if (!layout) return
|
||||
let toSave = layout
|
||||
if (bodyChartDaysDraft !== null) {
|
||||
toSave = normalizeLayoutForEditor(commitBodyChartDraftToLayout(bodyChartDaysDraft, layout))
|
||||
setLayout(toSave)
|
||||
setBodyChartDaysDraft(null)
|
||||
}
|
||||
setBusy(true)
|
||||
setMsg(null)
|
||||
setErr(null)
|
||||
try {
|
||||
await api.putAppDashboardLayout(layout)
|
||||
await api.putAppDashboardLayout(toSave)
|
||||
setMsg('Layout gespeichert.')
|
||||
await load()
|
||||
} catch (e) {
|
||||
|
|
@ -70,6 +89,7 @@ export default function DashboardLabPage() {
|
|||
setErr(null)
|
||||
try {
|
||||
const r = await api.resetAppDashboardLayout()
|
||||
setBodyChartDaysDraft(null)
|
||||
setLayout(normalizeLayoutForEditor(r.layout))
|
||||
setMsg('Auf Standard zurückgesetzt.')
|
||||
await load()
|
||||
|
|
@ -82,6 +102,7 @@ export default function DashboardLabPage() {
|
|||
|
||||
const applyDefaultLocal = () => {
|
||||
if (bundle?.default_layout) {
|
||||
setBodyChartDaysDraft(null)
|
||||
setLayout(normalizeLayoutForEditor(structuredClone(bundle.default_layout)))
|
||||
setMsg('Standard geladen (noch nicht gespeichert).')
|
||||
}
|
||||
|
|
@ -206,37 +227,29 @@ export default function DashboardLabPage() {
|
|||
Körper-Chart Zeitraum (Tage): {BODY_CHART_DAYS_MIN}–{BODY_CHART_DAYS_MAX}
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
type="text"
|
||||
inputMode="numeric"
|
||||
autoComplete="off"
|
||||
className="form-input"
|
||||
style={{ maxWidth: 120 }}
|
||||
min={BODY_CHART_DAYS_MIN}
|
||||
max={BODY_CHART_DAYS_MAX}
|
||||
value={chartDaysVal}
|
||||
onChange={(e) => {
|
||||
const v = parseInt(e.target.value, 10)
|
||||
setLayout((L) => ({
|
||||
...L,
|
||||
widgets: L.widgets.map((x, j) =>
|
||||
j !== i
|
||||
? x
|
||||
: {
|
||||
...x,
|
||||
config: {
|
||||
...x.config,
|
||||
chart_days: Number.isFinite(v) ? v : BODY_CHART_DAYS_DEFAULT,
|
||||
},
|
||||
aria-label="Körper-Chart Zeitraum in Tagen"
|
||||
value={
|
||||
bodyChartDaysDraft !== null
|
||||
? bodyChartDaysDraft
|
||||
: String(chartDaysVal)
|
||||
}
|
||||
),
|
||||
}))
|
||||
onFocus={() => setBodyChartDaysDraft(String(chartDaysVal))}
|
||||
onChange={(e) => setBodyChartDaysDraft(e.target.value)}
|
||||
onBlur={() => {
|
||||
setLayout((L) =>
|
||||
normalizeLayoutForEditor(
|
||||
commitBodyChartDraftToLayout(bodyChartDaysDraft ?? String(chartDaysVal), L)
|
||||
)
|
||||
)
|
||||
setBodyChartDaysDraft(null)
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const clamped = normalizeBodyChartDays(e.target.value)
|
||||
setLayout((L) => ({
|
||||
...L,
|
||||
widgets: L.widgets.map((x, j) =>
|
||||
j !== i ? x : { ...x, config: { ...x.config, chart_days: clamped } }
|
||||
),
|
||||
}))
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') e.currentTarget.blur()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user