From 1713951f76f02df46a3b470e525d2ec9d79f9545 Mon Sep 17 00:00:00 2001 From: "Zimin A.N." Date: Fri, 15 May 2026 21:08:02 +0300 Subject: [PATCH] =?UTF-8?q?fix(timetravel):=20extend=20modal=20slider=20ma?= =?UTF-8?q?x=20=D0=B4=D0=BE=20now=20+=2030=20days=20(paired=20=D1=81=20!22?= =?UTF-8?q?0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MR !220 расширил range у TimeTravelPicker.tsx, но юзер видит другой компонент — TimeTravelModal.tsx (fullscreen modal с компарисоном now vs picked moment). У него своя range logic с max = now + pad (1 day), и фикс !220 туда не дотянулся. User feedback: создал запись с validFrom=18.05, открыл time-travel modal — слайдер 14.05 → 16.05, не дотянуть до 18-го. Apply same 30-day future window logic к TimeTravelModal так чтобы оба компонента вели себя одинаково. --- .../components/timetravel/TimeTravelModal.tsx | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) 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.