feat: standardize correspondent and tag types with usage count
This commit is contained in:
@@ -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<void>;
|
||||
onCreate: (payload: { name: string }) => Promise<CorrespondentEntry | void>;
|
||||
onCreate: (payload: { name: string }) => Promise<Correspondent | void>;
|
||||
onUpdate: (id: string, payload: { name: string }) => Promise<void>;
|
||||
onDelete: (id: string) => Promise<void>;
|
||||
onNotify?: (message: string, variant?: string) => void;
|
||||
@@ -37,7 +26,7 @@ function CorrespondentsPanel({
|
||||
const [creating, setCreating] = useState(false);
|
||||
const [deletingId, setDeletingId] = useState<string | null>(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({
|
||||
<span>{correspondent.name}</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="numeric">{renderUsage(correspondent.usage)}</td>
|
||||
<td className="numeric">{renderUsage(correspondent)}</td>
|
||||
<td className="actions">
|
||||
{isEditing ? (
|
||||
<div className="tags-table__edit-controls">
|
||||
|
||||
@@ -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<CorrespondentEntry[]>([]);
|
||||
const [correspondents, setCorrespondents] = useState<Correspondent[]>([]);
|
||||
|
||||
const refreshCorrespondents = useCallback(async () => {
|
||||
const requestTenantId = tenantIdRef.current;
|
||||
|
||||
@@ -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<TagEntry[]>([]);
|
||||
const [tags, setTags] = useState<Tag[]>([]);
|
||||
|
||||
const refreshTags = useCallback(async () => {
|
||||
const requestTenantId = tenantIdRef.current;
|
||||
|
||||
@@ -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<string, Asset> | Asset[] | null;
|
||||
metadata?: Record<string, unknown> & { page_count?: number } | null;
|
||||
|
||||
Reference in New Issue
Block a user