fix(records): scheduled marks on time-travel + non-empty banner + editor validFrom prefill

Три связанных UX бага после v2.31.0 release:

1. **TimeTravel marks**: после !220 slider extended до now+30d, но отметок в
   future window не было → blind drag. Backend теперь возвращает
   upcomingValidFroms (top 50) в /scheduled-summary; frontend merges как marks.

2. **Non-empty banner**: empty-state hint работает только когда список пуст.
   Если currently active записи есть AND ещё запланированы — пользователь
   не видит. Добавлен info banner над таблицей с тем же текстом + CTA.

3. **Editor "Действует с"**: edit mode оставлял поле пустым (bitemporal
   policy «новая версия с now»). User feedback: «показывает ничего, а даты
   заданы» — выглядит как баг. Prefill nowIsoLocal() — теперь юзер видит
   конкретную дату как точку отсчёта.
This commit is contained in:
Zimin A.N.
2026-05-15 21:28:29 +03:00
parent 1713951f76
commit 9199f380e1
5 changed files with 94 additions and 15 deletions
@@ -203,4 +203,29 @@ public interface DictionaryRecordRepository extends JpaRepository<DictionaryReco
@Param("dictionaryId") UUID dictionaryId,
@Param("allowedScopes") Collection<DataScope> allowedScopes,
@Param("now") OffsetDateTime now);
/**
* Список validFrom timestamps для всех scheduled records (validFrom > now,
* validTo > now) — sorted asc, capped в service слое.
*
* <p>Используется TimeTravel slider marks: показывает «вот тут запись появится»
* pinpoints вместо blind drag вправо после !220 +30day window fix.
* User feedback: «отметки нужны где записи есть или меняются».
*
* <p>{@link org.springframework.data.domain.Pageable Pageable} caller'а
* ограничивает (top 50 typical) — DB sort + limit на index дешевле полной выборки.
*/
@Query("""
SELECT r.validFrom FROM DictionaryRecord r
WHERE r.dictionaryId = :dictionaryId
AND r.dataScope IN :allowedScopes
AND r.validFrom > :now
AND r.validTo > :now
ORDER BY r.validFrom ASC
""")
List<OffsetDateTime> findUpcomingValidFroms(
@Param("dictionaryId") UUID dictionaryId,
@Param("allowedScopes") Collection<DataScope> allowedScopes,
@Param("now") OffsetDateTime now,
org.springframework.data.domain.Pageable pageable);
}