Merge branch 'fix/sidebar-reviews-badge-count' into 'main'
fix(sidebar): подключить reviews badge к real count See merge request 2-6/2-6-4/terravault/ordinis!156
This commit is contained in:
@@ -622,6 +622,40 @@ export const reviewQueueQuery = (page = 0, size = 50) =>
|
|||||||
export const useReviewQueue = (page = 0, size = 50) =>
|
export const useReviewQueue = (page = 0, size = 50) =>
|
||||||
useQuery(reviewQueueQuery(page, size))
|
useQuery(reviewQueueQuery(page, size))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightweight count для sidebar badge — fetch only metadata (size=1).
|
||||||
|
*
|
||||||
|
* <p>Combines record-reviews + schema-reviews queues. Возвращает сумму pending
|
||||||
|
* drafts обоих видов. Поллится каждые 30s в синк с queue queries — reviewer
|
||||||
|
* увидит свежий counter при возврате на app даже если /reviews не открыт.
|
||||||
|
*
|
||||||
|
* <p>Gated на authenticated — anonymous не должен дёргать admin endpoint'ы
|
||||||
|
* (вернут 401, шум в логах). Когда Phase 1d Keycloak roles подключатся,
|
||||||
|
* этот gate можно сузить до approver-role (useCanReviewSchema).
|
||||||
|
*/
|
||||||
|
export const useReviewsBadgeCount = (enabled = true) => {
|
||||||
|
const recordQ = useQuery({
|
||||||
|
...reviewQueueQuery(0, 1),
|
||||||
|
enabled,
|
||||||
|
// Override interval: badge ОК с 60s — это не deep view, lower frequency
|
||||||
|
// снижает background load когда tab idle.
|
||||||
|
refetchInterval: 60_000,
|
||||||
|
})
|
||||||
|
const schemaQ = useQuery({
|
||||||
|
...schemaReviewQueueQuery(0, 1),
|
||||||
|
enabled,
|
||||||
|
refetchInterval: 60_000,
|
||||||
|
})
|
||||||
|
const recordCount = recordQ.data?.totalElements ?? 0
|
||||||
|
const schemaCount = schemaQ.data?.total ?? 0
|
||||||
|
return {
|
||||||
|
total: recordCount + schemaCount,
|
||||||
|
recordCount,
|
||||||
|
schemaCount,
|
||||||
|
isLoading: recordQ.isLoading || schemaQ.isLoading,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pending drafts на конкретный dict — для бейджа "На review" в records list.
|
* Pending drafts на конкретный dict — для бейджа "На review" в records list.
|
||||||
* Лёгкий poll каждые 30s. Backend возвращает только PENDING (фильтрация в SQL).
|
* Лёгкий poll каждые 30s. Backend возвращает только PENDING (фильтрация в SQL).
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { useAuth } from 'react-oidc-context'
|
import { useAuth } from 'react-oidc-context'
|
||||||
import { useCanMutate } from '@/auth/useCanMutate'
|
import { useCanMutate } from '@/auth/useCanMutate'
|
||||||
import { useDictionaries, useMyDrafts } from '@/api/queries'
|
import { useDictionaries, useMyDrafts, useReviewsBadgeCount } from '@/api/queries'
|
||||||
import { Sheet, SheetContent } from '@/ui'
|
import { Sheet, SheetContent } from '@/ui'
|
||||||
import { ThemeSwitch } from '@/components/layout/ThemeSwitch'
|
import { ThemeSwitch } from '@/components/layout/ThemeSwitch'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
@@ -55,13 +55,14 @@ export function Sidebar() {
|
|||||||
const dictsQuery = useDictionaries()
|
const dictsQuery = useDictionaries()
|
||||||
// Loaded just for сидбар counter — light request, кэшируется.
|
// Loaded just for сидбар counter — light request, кэшируется.
|
||||||
const myDrafts = useMyDrafts(0, 1)
|
const myDrafts = useMyDrafts(0, 1)
|
||||||
|
// Reviews badge — суммирует record-reviews + schema-reviews pending queues
|
||||||
|
// через size=1 paged запросы (cheap: одна запись + metadata). Gated на
|
||||||
|
// authenticated, чтобы anonymous не пытался admin endpoint'ы.
|
||||||
|
const reviews = useReviewsBadgeCount(auth.isAuthenticated)
|
||||||
|
|
||||||
const dictsCount = dictsQuery.data?.length ?? 0
|
const dictsCount = dictsQuery.data?.length ?? 0
|
||||||
const myDraftsCount = myDrafts.data?.totalElements ?? 0
|
const myDraftsCount = myDrafts.data?.totalElements ?? 0
|
||||||
// Reviews count бэйдж — TODO когда будет cheap endpoint /drafts/pending/count.
|
const reviewsCount = reviews.total
|
||||||
// Сейчас GET /drafts/pending возвращает page, paged запрос на каждый mount
|
|
||||||
// sidebar'а — overkill. Skip badge.
|
|
||||||
const reviewsCount = 0
|
|
||||||
|
|
||||||
// Flat list per redesign/compact.html — no section labels, /graph removed
|
// Flat list per redesign/compact.html — no section labels, /graph removed
|
||||||
// (now reachable via catalog toolbar "Граф ⇄" button). Order: Главная →
|
// (now reachable via catalog toolbar "Граф ⇄" button). Order: Главная →
|
||||||
@@ -392,10 +393,11 @@ export function MobileSidebar({ open, onClose }: { open: boolean; onClose: () =>
|
|||||||
const canMutate = useCanMutate()
|
const canMutate = useCanMutate()
|
||||||
const dictsQuery = useDictionaries()
|
const dictsQuery = useDictionaries()
|
||||||
const myDrafts = useMyDrafts(0, 1)
|
const myDrafts = useMyDrafts(0, 1)
|
||||||
|
const reviews = useReviewsBadgeCount(auth.isAuthenticated)
|
||||||
|
|
||||||
const dictsCount = dictsQuery.data?.length ?? 0
|
const dictsCount = dictsQuery.data?.length ?? 0
|
||||||
const myDraftsCount = myDrafts.data?.totalElements ?? 0
|
const myDraftsCount = myDrafts.data?.totalElements ?? 0
|
||||||
const reviewsCount = 0
|
const reviewsCount = reviews.total
|
||||||
|
|
||||||
// Flat list per redesign — same as desktop Sidebar above.
|
// Flat list per redesign — same as desktop Sidebar above.
|
||||||
const sections: NavSection[] = [
|
const sections: NavSection[] = [
|
||||||
|
|||||||
Reference in New Issue
Block a user