This commit is contained in:
2025-11-14 02:35:17 +01:00
parent 6f4ff68062
commit a3c5494bf7
53 changed files with 269 additions and 340 deletions
@@ -53,7 +53,7 @@ const useCorrespondents = ({
}
const payload: Record<string, unknown> = {};
if (typeof changes?.name?.trim === 'function') {
if (changes?.name != null) {
const trimmed = changes.name.trim();
if (!trimmed) {
throw new Error('Correspondent name cannot be empty.');
@@ -120,9 +120,7 @@ const useCorrespondents = ({
await apiClient.delete(`/correspondents/${correspondentId}`);
await refreshCorrespondents();
if (typeof mapDocumentCaches === 'function') {
mapDocumentCaches(stripFromDoc);
}
mapDocumentCaches?.(stripFromDoc);
setStatusMessage('Correspondent deleted.', 'success');
return true;
@@ -1,4 +1,5 @@
import { useCallback, useMemo } from 'react';
import { isPlainObject, isStringValue } from '../../utils/typeGuards';
type ApiClient = {
post: (path: string, body?: unknown) => Promise<{ data: unknown }>;
@@ -99,10 +100,10 @@ const useDocumentCorrespondentActions = ({
if (!option) {
return null;
}
if (typeof option === 'object' && 'id' in option) {
if (isPlainObject(option) && 'id' in option) {
return option as CorrespondentOption;
}
if (typeof option === 'string') {
if (isStringValue(option)) {
const trimmed = option.trim();
if (trimmed) {
return { id: null, name: trimmed };
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useRef } from 'react';
import type { DragEvent } from 'react';
import { isPlainObject, isFunctionValue } from '../../utils/typeGuards';
type Identifier = string | number;
type FolderIdentifier = Identifier | 'root';
@@ -144,11 +145,17 @@ const useDocumentDragHandlers = ({
}
} else {
const payload = item.payload;
const folderId = (payload && typeof payload === 'object' && 'id' in payload)
? (payload as { id?: FolderIdentifier }).id
: (typeof (payload as { trim?: () => string })?.trim === 'function'
? (payload as { trim: () => string }).trim()
: null);
const folderId = (() => {
if (isPlainObject(payload) && 'id' in payload) {
return (payload as { id?: FolderIdentifier }).id ?? null;
}
const maybeTrim = (payload as { trim?: () => string })?.trim;
if (isFunctionValue(maybeTrim)) {
const nextValue = maybeTrim.call(payload);
return nextValue || null;
}
return null;
})();
const rowEl = folderId
? (document.getElementById(`folder-row-${folderId}`)
|| document.getElementById(`folder-card-${folderId}`))
@@ -205,10 +212,9 @@ const useDocumentDragHandlers = ({
const handleDocumentDragStart = useCallback(
(event: DragEvent<HTMLElement>, documentOrId: DocumentLike | Identifier | null | undefined) => {
const documentId =
(documentOrId as DocumentLike)?.id ?? (typeof documentOrId === 'string' || typeof documentOrId === 'number'
? documentOrId
: null);
const documentId: Identifier | null = Object(documentOrId) === documentOrId
? (documentOrId as DocumentLike)?.id ?? null
: (documentOrId as Identifier | null);
if (!documentId) {
return;
}
@@ -1,4 +1,5 @@
import { useCallback } from 'react';
import { isPlainObject } from '../../utils/typeGuards';
import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
import { DEFAULT_FOLDER_NAME, getRowId, isDocumentRowKey } from '../../app/appLayoutUtils';
@@ -173,7 +174,7 @@ interface UseDocumentMutationsResult {
const normalizeDocumentId = (value: unknown): DocumentId | null => {
if (!value) return null;
if (typeof value === 'object' && value !== null && 'id' in value && value.id != null) {
if (isPlainObject(value) && 'id' in value && value.id != null) {
return value.id as DocumentId;
}
return value as DocumentId;
@@ -562,8 +563,8 @@ const useDocumentMutations = ({
}
await api.post(`/documents/${document.id}/tags`, { tag_ids: [tag.id] });
setStatusMessage('Tag assigned.', 'success');
if (input && typeof input === 'object') {
input.value = '';
if (input && Object(input) === input && 'value' in (input as Record<string, unknown>)) {
(input as { value?: string }).value = '';
}
await refreshCurrentFolder();
} catch (error) {
@@ -582,12 +583,16 @@ const useDocumentMutations = ({
const resolveTagForCache = (): Tag | null => {
const lookupTag = tagLookupById.get(tagId);
const source = lookupTag ?? tagData;
if (!source || source.id == null || typeof source.label?.trim !== 'function') {
if (!source || source.id == null) {
return null;
}
const labelText = `${source.label ?? ''}`.trim();
if (!labelText) {
return null;
}
return {
id: source.id,
label: source.label,
label: labelText,
color: Object.prototype.hasOwnProperty.call(source, 'color') ? (source as Tag).color ?? null : null,
};
};
@@ -222,7 +222,9 @@ const useDocumentTagging = ({
},
);
const payload = 'data' in response ? response.data : response;
const queued = typeof payload?.queued === 'number' ? payload.queued : targetIds.length;
const queued = Number.isFinite(payload?.queued)
? Number(payload.queued)
: targetIds.length;
setStatusMessage(
`Queued re-analysis for ${queued} document${queued === 1 ? '' : 's'}.`,
'success',
@@ -322,7 +322,7 @@ const useDocumentUploads = ({
items.map(async (item, index) => {
if (item.kind !== 'file') return;
const fileFromItem = typeof item.getAsFile === 'function' ? item.getAsFile() : null;
const fileFromItem = item.getAsFile?.() ?? null;
if (fileFromItem) {
const relativePath = (fileFromItem as File & { webkitRelativePath?: string })?.webkitRelativePath ?? '';
const segments = relativePath
@@ -334,9 +334,9 @@ const useDocumentUploads = ({
pushFile(fileFromItem, segments);
}
if (typeof item.webkitGetAsEntry === 'function') {
if ((item as ExtendedDataTransferItem).webkitGetAsEntry) {
try {
const entry = item.webkitGetAsEntry();
const entry = (item as ExtendedDataTransferItem).webkitGetAsEntry?.();
if (entry) {
await walkEntry(entry, []);
return;
+1 -4
View File
@@ -20,9 +20,6 @@ const useDocuments = ({ setSearchResults, setFolderContents }: UseDocumentsOptio
const mapDocumentCaches = useCallback(
(mapper: (doc: DocumentLike) => DocumentLike | undefined) => {
if (typeof mapper !== 'function') {
return;
}
const applyToList = (list?: DocumentLike[] | null) => {
let changed = false;
@@ -81,7 +78,7 @@ const useDocuments = ({ setSearchResults, setFolderContents }: UseDocumentsOptio
const updateDocumentCaches = useCallback(
(documentId, updater) => {
if (!documentId || typeof updater !== 'function') {
if (!documentId) {
return;
}
@@ -153,19 +153,10 @@ const useDocumentsWorkspace = ({
} = appState;
const tenantRecord = (tenant ?? null) as TenantOption | null;
const tenantName: string | null = typeof tenantRecord?.name === 'string'
? tenantRecord.name
: typeof tenantRecord?.slug === 'string'
? tenantRecord.slug
: null;
const tenantNameCandidate = tenantRecord?.name ?? tenantRecord?.slug ?? null;
const tenantName = tenantNameCandidate ? String(tenantNameCandidate) : null;
const currentTenantId: Identifier | null = (() => {
const value = tenantRecord?.id;
if (typeof value === 'string' || typeof value === 'number') {
return value as Identifier;
}
return null;
})();
const currentTenantId: Identifier | null = (tenantRecord?.id ?? null) as Identifier | null;
const tenantOptions: TenantOption[] = Array.isArray(tenantOptionsRaw)
? (tenantOptionsRaw as TenantOption[])
@@ -306,11 +297,9 @@ const useDocumentsWorkspace = ({
folderContentsRef.current = folderContents;
}, [folderContents]);
const setSearchResultsRef = useRef(() => {});
const setSearchResultsRef = useRef<(value: unknown) => void>(() => {});
const setSearchResultsProxy = useCallback((value) => {
if (typeof setSearchResultsRef.current === 'function') {
setSearchResultsRef.current(value);
}
setSearchResultsRef.current(value);
}, []);
const {
@@ -1290,7 +1279,9 @@ const useDocumentsWorkspace = ({
if (docOrId == null) {
return;
}
const docId = typeof docOrId === 'object' ? docOrId?.id : docOrId;
const docId: Identifier | null = Object(docOrId) === docOrId
? (docOrId as DocumentLike)?.id ?? null
: (docOrId as Identifier | null);
if (docId == null) {
return;
}
+3 -10
View File
@@ -311,16 +311,9 @@ const useFolderTree = ({
if (Array.isArray(child?.subfolders)) {
return child.subfolders.length > 0;
}
if (typeof child?.has_children === 'boolean') {
return child.has_children;
}
if (typeof child?.hasChildren === 'boolean') {
return child.hasChildren;
}
if (typeof childNode?.hasChildren === 'boolean') {
return childNode.hasChildren;
}
return false;
const flag = [child?.has_children, child?.hasChildren, childNode?.hasChildren]
.find((value) => value != null);
return Boolean(flag);
})();
next.set(childId, {
id: childId,
+2 -4
View File
@@ -62,7 +62,7 @@ const useTags = ({
}
const payload: Record<string, unknown> = {};
if (typeof changes?.label?.trim === 'function') {
if (changes?.label != null) {
payload.label = changes.label;
}
if (Object.prototype.hasOwnProperty.call(changes, 'color')) {
@@ -124,9 +124,7 @@ const useTags = ({
return { ...doc, tags: nextTags };
};
if (typeof mapDocumentCaches === 'function') {
mapDocumentCaches(stripTagFromDoc);
}
mapDocumentCaches?.(stripTagFromDoc);
await refreshTags();
setStatusMessage('Tag deleted.', 'success');