feat(records): scheduled records empty-state hint
Fixes UX bug: пользователь создаёт запись с validFrom на будущую дату
(e.g. 18.05), открывает catalog 15.05 — пустая таблица, никаких хинтов
о том что запись существует.
Backend (read-api):
- New endpoint GET /api/v1/{dict}/records/scheduled-summary
- Returns {count, nearestValidFrom} для записей с validFrom > now AND
validTo > now в текущем scope view
- Single-aggregate JPA query (COUNT + MIN), respect scope filter same way
as listActive — INTERNAL scheduled не учитывается для PUBLIC consumer'а
Frontend:
- New useScheduledSummary hook + ScheduledRecordsSummary type
- Empty-state в dictionaries.$name now shows: "Запланировано N, ближайшая
на DD.MM [Перейти к этой дате]" с CTA который set'ает time-travel на
nearestValidFrom
- i18n keys для ru/en plural forms
Связан с MR !219 (TimeTravelPicker 30-day future window) — теперь slider
позволяет дойти до даты записи, и empty-state hint позволяет узнать что
запись существует.
This commit is contained in:
+25
@@ -178,4 +178,29 @@ public interface DictionaryRecordRepository extends JpaRepository<DictionaryReco
|
||||
@Param("from") OffsetDateTime from,
|
||||
@Param("to") OffsetDateTime to,
|
||||
@Param("granularity") String granularity);
|
||||
|
||||
/**
|
||||
* Scheduled records summary: записи которые ещё не активны (validFrom > now),
|
||||
* но запланированы на будущее (validTo > now — т.е. не сразу закрытые).
|
||||
* Используется empty-state hint в admin-UI: «У словаря есть N запланированных
|
||||
* на DD.MM» — fixes UX bug когда пользователь создаёт запись с validFrom
|
||||
* на будущую дату и не видит её в списке.
|
||||
*
|
||||
* <p>Single query → returns {@code [count Long, nearestValidFrom OffsetDateTime]}.
|
||||
* Если scheduled нет — count=0, nearest=null.
|
||||
*
|
||||
* <p>Filter по scope тот же что в read-side listActive: respects user's
|
||||
* view permissions. Anonymous (только PUBLIC) → INTERNAL scheduled не учитывается.
|
||||
*/
|
||||
@Query("""
|
||||
SELECT COUNT(r), MIN(r.validFrom) FROM DictionaryRecord r
|
||||
WHERE r.dictionaryId = :dictionaryId
|
||||
AND r.dataScope IN :allowedScopes
|
||||
AND r.validFrom > :now
|
||||
AND r.validTo > :now
|
||||
""")
|
||||
List<Object[]> findScheduledSummary(
|
||||
@Param("dictionaryId") UUID dictionaryId,
|
||||
@Param("allowedScopes") Collection<DataScope> allowedScopes,
|
||||
@Param("now") OffsetDateTime now);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user