diff --git a/frontend/src/correspondents/CorrespondentsPanel.tsx b/frontend/src/correspondents/CorrespondentsPanel.tsx index 8863cfa..91bf53b 100644 --- a/frontend/src/correspondents/CorrespondentsPanel.tsx +++ b/frontend/src/correspondents/CorrespondentsPanel.tsx @@ -1,22 +1,11 @@ import { useCallback, useState } from 'react'; import type { FormEvent, KeyboardEvent } from 'react'; - -interface CorrespondentUsage { - total?: number; - [key: string]: unknown; -} - -interface CorrespondentEntry { - id?: string; - name?: string; - usage?: CorrespondentUsage; - [key: string]: unknown; -} +import type { Correspondent } from '../types/documents'; export interface CorrespondentsPanelProps { - correspondents?: CorrespondentEntry[]; + correspondents?: Correspondent[]; onRefresh?: () => void | Promise; - onCreate: (payload: { name: string }) => Promise; + onCreate: (payload: { name: string }) => Promise; onUpdate: (id: string, payload: { name: string }) => Promise; onDelete: (id: string) => Promise; onNotify?: (message: string, variant?: string) => void; @@ -37,7 +26,7 @@ function CorrespondentsPanel({ const [creating, setCreating] = useState(false); const [deletingId, setDeletingId] = useState(null); - const startEdit = useCallback((correspondent: CorrespondentEntry) => { + const startEdit = useCallback((correspondent: Correspondent) => { setEditingId(correspondent.id); setDraftName(correspondent.name); }, []); @@ -68,7 +57,7 @@ function CorrespondentsPanel({ }, [editingId, draftName, onUpdate, cancelEdit, onNotify]); const handleDelete = useCallback( - async (correspondent: CorrespondentEntry) => { + async (correspondent: Correspondent) => { if (!correspondent?.id) return; setDeletingId(correspondent.id); try { @@ -121,12 +110,12 @@ function CorrespondentsPanel({ [handleSave, cancelEdit], ); - const renderUsage = useCallback((usage?: CorrespondentUsage) => { - if (!usage) { + const renderUsage = useCallback((correspondent: Correspondent) => { + const count = correspondent.usage_count; + if (count == null || !Number.isFinite(count)) { return '0'; } - const total = Number.isFinite(usage.total) ? Number(usage.total) : 0; - return total.toString(); + return count.toString(); }, []); return ( @@ -195,7 +184,7 @@ function CorrespondentsPanel({ {correspondent.name} )} - {renderUsage(correspondent.usage)} + {renderUsage(correspondent)} {isEditing ? (
diff --git a/frontend/src/hooks/documents/useCorrespondents.ts b/frontend/src/hooks/documents/useCorrespondents.ts index bbeb998..12435b1 100644 --- a/frontend/src/hooks/documents/useCorrespondents.ts +++ b/frontend/src/hooks/documents/useCorrespondents.ts @@ -1,4 +1,5 @@ import { MutableRefObject, useCallback, useState } from 'react'; +import type { Correspondent } from '../../types/documents'; type ApiClient = { get: (path: string) => Promise<{ data: unknown }>; @@ -7,12 +8,6 @@ type ApiClient = { delete: (path: string) => Promise<{ data: unknown }>; }; -interface CorrespondentEntry { - id?: string; - name?: string; - [key: string]: unknown; -} - interface UseCorrespondentsOptions { apiClient: ApiClient; notifyApiError: (error: unknown, fallback: string) => void; @@ -28,7 +23,7 @@ const useCorrespondents = ({ tenantIdRef, mapDocumentCaches, }: UseCorrespondentsOptions) => { - const [correspondents, setCorrespondents] = useState([]); + const [correspondents, setCorrespondents] = useState([]); const refreshCorrespondents = useCallback(async () => { const requestTenantId = tenantIdRef.current; diff --git a/frontend/src/hooks/documents/useTags.ts b/frontend/src/hooks/documents/useTags.ts index 815cef8..baa4e5b 100644 --- a/frontend/src/hooks/documents/useTags.ts +++ b/frontend/src/hooks/documents/useTags.ts @@ -1,5 +1,6 @@ import { MutableRefObject, useCallback, useState } from 'react'; import type { TagId, TenantId } from '../../types/identifiers'; +import type { Tag } from '../../types/documents'; type ApiClient = { get: (path: string) => Promise<{ data: unknown }> @@ -12,13 +13,6 @@ interface TagManagerInterface { buildPayload: (input: { label?: string; color?: string | null }) => { label: string; color: string | null }; } -interface TagEntry { - id?: TagId; - label?: string; - color?: string | null; - [key: string]: unknown; -} - interface UseTagsOptions { apiClient: ApiClient; notifyApiError: (error: unknown, fallback: string) => void; @@ -38,7 +32,7 @@ const useTags = ({ setActiveTagFilters, mapDocumentCaches, }: UseTagsOptions) => { - const [tags, setTags] = useState([]); + const [tags, setTags] = useState([]); const refreshTags = useCallback(async () => { const requestTenantId = tenantIdRef.current; diff --git a/frontend/src/types/documents.ts b/frontend/src/types/documents.ts index 0905ce3..f5a8f06 100644 --- a/frontend/src/types/documents.ts +++ b/frontend/src/types/documents.ts @@ -14,6 +14,29 @@ export interface DocumentCorrespondent { count?: number; } +/** + * A tag entity as returned by the API (includes usage_count). + * Use DocumentTag for the embedded version on documents. + */ +export interface Tag { + id?: Identifier; + label?: string; + color?: string | null; + usage_count?: number; + [key: string]: unknown; +} + +/** + * A correspondent entity as returned by the API. + * Use DocumentCorrespondent for the embedded version on documents. + */ +export interface Correspondent { + id?: Identifier; + name?: string; + usage_count?: number; + [key: string]: unknown; +} + export interface DocumentVersion { assets?: Record | Asset[] | null; metadata?: Record & { page_count?: number } | null;