feat(site-finder): horizon-селектор 6/12/18 на экране анализа (#996) #1072

Merged
bot-backend merged 1 commit from feat/horizon-selector-996 into main 2026-06-05 10:43:42 +00:00
Collaborator

Что

Сегмент-контрол «Горизонт прогноза» 6/12/18 на экране анализа (/site-finder/analysis/[cad]). Меняет ?horizon= в analyze-запросе и мгновенно подсвечивает целевой горизонт в Секции 6.

Closes #996 (958-B1). Часть EPIC #958. Зависимость 958-B2 (#995, backend ?horizon=) — в main.

Содержимое

  • HorizonSelector.tsx — controlled segmented control (radiogroup + role=radio/aria-checked, реальные кнопки, focus-ring, tabular-nums, токены). Отключается, пока идёт пере-анализ (анти-спам).
  • useParcelAnalyzeQuery(cad, horizon=12)horizon в queryKey + ?horizon=; placeholderData: keepPreviousData → переключение горизонта не бланкует страницу в loading (паттерн уже есть в analytics-api.ts).
  • AnalysisPageContent — состояние горизонта, рендер селектора под breadcrumb, инвалидация ["parcel-forecast", cad] при смене (Секция 6 перепулливает).
  • Section6Forecast/ForecastHorizonsBlockselectedHorizontargetHorizon, целевая строка горизонта подсвечивается тегом «Целевой».

Поведение (осознанный трейд-офф)

Смена горизонта = свежий /analyze (~10-30s) + пере-расчёт §22-форсайта (~30-180s). keepPreviousData держит прошлый анализ на экране, селектор заблокирован на время рефетча, а selectedHorizon даёт мгновенную клиентскую подсветку целевого горизонта.

Качество

  • code-reviewer: ⚠️ MINOR (no blockers) — wiring/контракт/семантика верны. Учтены: keepPreviousData+disable-while-fetching (анти-спам/анти-бланк), void invalidate. Оставлено follow-up: ScenariosBlock-подпись при отсутствии точного горизонта (на практике отчёт всегда содержит 6/12/18/24 → не триггерится).
  • npm run build — зелёный (tsc + lint чисто). Без новых зависимостей, без codegen.

Тест-план (post-deploy)

Открыть /site-finder/analysis/66:41:0702048:27 → селектор 6/12/18 над секциями; клик 18 → строка 18 мес помечена «Целевой», сценарии/дефицит на 18 мес; страница не мигает в loading.

## Что Сегмент-контрол **«Горизонт прогноза» 6/12/18** на экране анализа (`/site-finder/analysis/[cad]`). Меняет `?horizon=` в analyze-запросе и мгновенно подсвечивает целевой горизонт в Секции 6. Closes #996 (958-B1). Часть EPIC #958. Зависимость 958-B2 (#995, backend `?horizon=`) — в main. ## Содержимое - `HorizonSelector.tsx` — controlled segmented control (radiogroup + role=radio/aria-checked, реальные кнопки, focus-ring, tabular-nums, токены). Отключается, пока идёт пере-анализ (анти-спам). - `useParcelAnalyzeQuery(cad, horizon=12)` — `horizon` в queryKey + `?horizon=`; `placeholderData: keepPreviousData` → переключение горизонта **не бланкует** страницу в loading (паттерн уже есть в `analytics-api.ts`). - `AnalysisPageContent` — состояние горизонта, рендер селектора под breadcrumb, инвалидация `["parcel-forecast", cad]` при смене (Секция 6 перепулливает). - `Section6Forecast`/`ForecastHorizonsBlock` — `selectedHorizon` → `targetHorizon`, целевая строка горизонта подсвечивается тегом «Целевой». ## Поведение (осознанный трейд-офф) Смена горизонта = свежий `/analyze` (~10-30s) + пере-расчёт §22-форсайта (~30-180s). `keepPreviousData` держит прошлый анализ на экране, селектор заблокирован на время рефетча, а `selectedHorizon` даёт мгновенную клиентскую подсветку целевого горизонта. ## Качество - `code-reviewer`: ⚠️ MINOR (no blockers) — wiring/контракт/семантика верны. Учтены: `keepPreviousData`+disable-while-fetching (анти-спам/анти-бланк), `void` invalidate. Оставлено follow-up: ScenariosBlock-подпись при отсутствии точного горизонта (на практике отчёт всегда содержит 6/12/18/24 → не триггерится). - `npm run build` — зелёный (tsc + lint чисто). Без новых зависимостей, без codegen. ## Тест-план (post-deploy) Открыть `/site-finder/analysis/66:41:0702048:27` → селектор 6/12/18 над секциями; клик 18 → строка 18 мес помечена «Целевой», сценарии/дефицит на 18 мес; страница не мигает в loading.
bot-backend added the
scope/frontend
GG-форсайт
site-finder
labels 2026-06-05 10:43:28 +00:00
bot-backend added 1 commit 2026-06-05 10:43:29 +00:00
feat(site-finder): horizon selector (6/12/18) on analysis screen (#996)
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m49s
Deploy / deploy (push) Successful in 1m0s
740210d9ea
Segmented control «Горизонт прогноза» driving the analyze query (?horizon=)
and Section 6's target highlight. Default 12.

- HorizonSelector: radiogroup + a11y radios, tokens-only, tabular-nums,
  disabled while a re-analyze is in flight
- useParcelAnalyzeQuery(cad, horizon=12): horizon in queryKey + ?horizon=;
  keepPreviousData so switching horizon doesn't blank the page to loading
- AnalysisPageContent: horizon state + forecast-poll invalidation on change
- Section6Forecast/ForecastHorizonsBlock: selectedHorizon → target row («Целевой»)

Part of EPIC #958.
bot-backend merged commit 740210d9ea into main 2026-06-05 10:43:42 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1072
No description provided.