diff --git a/ordinis-admin-ui/src/components/timetravel/TimeTravelModal.tsx b/ordinis-admin-ui/src/components/timetravel/TimeTravelModal.tsx index 5a14ff7..5587ac7 100644 --- a/ordinis-admin-ui/src/components/timetravel/TimeTravelModal.tsx +++ b/ordinis-admin-ui/src/components/timetravel/TimeTravelModal.tsx @@ -109,13 +109,25 @@ export function TimeTravelModal({ isAtNow0 ? undefined : { at: new Date(picked).toISOString() }, ) - // Range: от min(marks, createdAt) до now+padding. + // Range: от min(marks, createdAt) до max(now+30d, future marks)+padding. + // + // Future support (fix paired с TimeTravelPicker !220): если у dict есть + // scheduled records (validFrom > now) или user navigated к future date, + // slider должен дотягиваться. Раньше max = now + 1day pad — record с + // validFrom=18.05 был недостижим если сейчас 15.05. + // + // Default future window = 30 days, match'ит TimeTravelPicker.tsx logic. const createdMs = Date.parse(detail.createdAt) const range = useMemo(() => { - const minMark = marks.length > 0 ? Math.min(...marks, createdMs) : createdMs - 86_400_000 - const span = now - minMark - const pad = Math.max(span * 0.04, 86_400_000) - return { min: minMark - pad, max: now + pad } + const DAY_MS = 86_400_000 + const FUTURE_WINDOW_MS = 30 * DAY_MS + const minMark = marks.length > 0 ? Math.min(...marks, createdMs) : createdMs - DAY_MS + // Push max forward: at least now + 30 days, и further если есть future marks. + const maxMark = marks.length > 0 ? Math.max(...marks, now) : now + const effectiveMax = Math.max(maxMark, now + FUTURE_WINDOW_MS) + const span = effectiveMax - minMark + const pad = Math.max(span * 0.04, DAY_MS) + return { min: minMark - pad, max: effectiveMax + pad } }, [marks, createdMs, now]) // Sync picked when value prop changes while modal open.