cleanup
This commit is contained in:
@@ -2,6 +2,8 @@ import type { AxiosInstance } from 'axios';
|
||||
|
||||
export type Identifier = string | number;
|
||||
|
||||
type Nullable<T> = T | null;
|
||||
|
||||
export interface AssetObject {
|
||||
ordinal?: number;
|
||||
url?: string | null;
|
||||
@@ -40,12 +42,12 @@ export type EnsureAssetUrl = (
|
||||
options?: { start?: number | null; limit?: number | null; force?: boolean; [key: string]: unknown },
|
||||
) => Promise<unknown>;
|
||||
|
||||
export type GetAsset = (document: DocumentLike, assetType: string) => AssetLike | null | undefined;
|
||||
export type GetAsset = (document: DocumentLike, assetType: string) => Nullable<AssetLike>;
|
||||
|
||||
export const getAssetFromGroup = (
|
||||
assets: AssetLike[] | Record<string, AssetLike> | null | undefined,
|
||||
assetType: string,
|
||||
): AssetLike | null => {
|
||||
assets?: AssetLike[] | Record<string, AssetLike> | null,
|
||||
assetType: string = '',
|
||||
): Nullable<AssetLike> => {
|
||||
if (!assetType || !assets) {
|
||||
return null;
|
||||
}
|
||||
@@ -57,11 +59,11 @@ export const getAssetFromGroup = (
|
||||
return assets?.[assetType] || null;
|
||||
};
|
||||
|
||||
export const getAssetFromVersion = (currentVersion, assetType) => {
|
||||
export const getAssetFromVersion = (currentVersion: Nullable<DocumentVersionLike>, assetType: string) => {
|
||||
if (!currentVersion) {
|
||||
return null;
|
||||
}
|
||||
return getAssetFromGroup(currentVersion.assets, assetType);
|
||||
return getAssetFromGroup(currentVersion.assets ?? null, assetType);
|
||||
};
|
||||
|
||||
const normalizeAssetObjects = (objects?: AssetObject[] | null): AssetObject[] => {
|
||||
@@ -182,7 +184,7 @@ export class AssetView {
|
||||
export const createAssetView = (asset?: AssetLike | null): AssetView => new AssetView(asset);
|
||||
|
||||
export const resolveDocumentAssetUrl = (
|
||||
doc: DocumentLike | null | undefined,
|
||||
doc: Nullable<DocumentLike>,
|
||||
type: string,
|
||||
{
|
||||
ensureAssetUrl,
|
||||
@@ -195,7 +197,7 @@ export const resolveDocumentAssetUrl = (
|
||||
ensureOptions?: { start?: number; limit?: number; [key: string]: unknown };
|
||||
objectOrdinal?: number;
|
||||
} = {},
|
||||
): string | null => {
|
||||
): Nullable<string> => {
|
||||
if (!doc || !type) {
|
||||
return null;
|
||||
}
|
||||
@@ -251,13 +253,13 @@ class AssetManager {
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
rememberAsset(entry: AssetLike | null | undefined) {
|
||||
rememberAsset(entry?: Nullable<AssetLike>) {
|
||||
if (entry?.id) {
|
||||
this.assetCache.set(entry.id, entry);
|
||||
}
|
||||
}
|
||||
|
||||
hydrateAsset(asset: AssetLike | null | undefined): AssetLike | null | undefined {
|
||||
hydrateAsset(asset?: Nullable<AssetLike>): Nullable<AssetLike> {
|
||||
if (!asset || !asset.id) {
|
||||
return asset;
|
||||
}
|
||||
@@ -287,7 +289,7 @@ class AssetManager {
|
||||
return merged;
|
||||
}
|
||||
|
||||
hydrateDocument(document: DocumentLike | null | undefined): DocumentLike | null | undefined {
|
||||
hydrateDocument(document?: Nullable<DocumentLike>): Nullable<DocumentLike> {
|
||||
if (!document) {
|
||||
return document;
|
||||
}
|
||||
@@ -330,14 +332,14 @@ class AssetManager {
|
||||
return { ...document, current_version: nextCurrentVersion };
|
||||
}
|
||||
|
||||
hydrateDocuments(documents: DocumentLike[] | null | undefined) {
|
||||
hydrateDocuments(documents?: DocumentLike[] | null) {
|
||||
if (!Array.isArray(documents)) {
|
||||
return documents;
|
||||
return documents ?? [];
|
||||
}
|
||||
return documents.map((doc) => this.hydrateDocument(doc));
|
||||
}
|
||||
|
||||
hydrateDetail(detail: { document?: DocumentLike; assets?: AssetLike[] } | null | undefined) {
|
||||
hydrateDetail(detail?: { document?: DocumentLike; assets?: AssetLike[] } | null) {
|
||||
if (!detail) {
|
||||
return detail;
|
||||
}
|
||||
@@ -366,10 +368,7 @@ class AssetManager {
|
||||
return changed ? next : detail;
|
||||
}
|
||||
|
||||
hydrateFolderContents(contents: {
|
||||
documents?: DocumentLike[];
|
||||
document?: DocumentLike;
|
||||
} | null | undefined) {
|
||||
hydrateFolderContents(contents?: { documents?: DocumentLike[]; document?: DocumentLike } | null) {
|
||||
if (!contents) {
|
||||
return contents;
|
||||
}
|
||||
@@ -384,12 +383,12 @@ class AssetManager {
|
||||
}
|
||||
|
||||
ensureAsset(
|
||||
documentId: Identifier | null | undefined,
|
||||
asset: AssetLike | null | undefined,
|
||||
documentId?: Identifier | null,
|
||||
asset?: Nullable<AssetLike>,
|
||||
{ force = false, start = null, limit = null }: { force?: boolean; start?: number | null; limit?: number | null } = {},
|
||||
): Promise<AssetLike | null> {
|
||||
): Promise<Nullable<AssetLike>> {
|
||||
if (!documentId || !asset?.id) {
|
||||
return Promise.resolve(asset || null);
|
||||
return Promise.resolve(asset ?? null);
|
||||
}
|
||||
|
||||
const requestedStart = Number.isInteger(start) && start > 0 ? start : 1;
|
||||
|
||||
@@ -476,7 +476,7 @@ const DocumentSummarySection: React.FC<DocumentSummarySectionProps> = ({
|
||||
}, [correspondents, document?.correspondents]);
|
||||
|
||||
const metaRows = useMemo(() => {
|
||||
const rows: { key: string; label: string; value: string | null | undefined }[] = [];
|
||||
const rows: { key: string; label: string; value: string | null }[] = [];
|
||||
const currentVersionNumber = document?.current_version?.version_number;
|
||||
if (Number.isFinite(currentVersionNumber)) {
|
||||
rows.push({
|
||||
|
||||
@@ -17,7 +17,7 @@ const DEFAULT_THUMBNAIL_SIZE = 48;
|
||||
// Detect when an element becomes visible within a scroll container so we can delay loading.
|
||||
const useLazyVisibility = (
|
||||
rootRef: MutableRefObject<Element | null> | null,
|
||||
resetKey: string | number | null | undefined,
|
||||
resetKey?: string | number | null,
|
||||
) => {
|
||||
const targetRef = useRef<HTMLDivElement | null>(null);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
@@ -66,10 +66,10 @@ const useLazyVisibility = (
|
||||
return { ref: targetRef, isVisible };
|
||||
};
|
||||
|
||||
const getPageCount = (doc: DocumentLike | null | undefined) =>
|
||||
Number.isFinite(doc?.current_version?.metadata?.page_count)
|
||||
? (doc?.current_version?.metadata?.page_count as number)
|
||||
: null;
|
||||
const getPageCount = (doc?: DocumentLike | null) => {
|
||||
const count = doc?.current_version?.metadata?.page_count;
|
||||
return Number.isFinite(count) ? Number(count) : null;
|
||||
};
|
||||
|
||||
type DocumentLike = AssetManagerDocumentLike;
|
||||
type AssetLike = AssetManagerAssetLike;
|
||||
|
||||
@@ -80,7 +80,7 @@ interface DocumentsGridProps {
|
||||
onTagClick?: (tagId?: Identifier | null) => void;
|
||||
scrollRef?: RefObject<HTMLElement | null>;
|
||||
onCorrespondentClick?: (correspondentId?: Identifier | null) => void;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null | undefined> | null;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null> | null;
|
||||
onDocumentRename?: (docId: Identifier, title: string) => Promise<boolean> | boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export interface DocumentsListProps {
|
||||
tagLookupById?: Map<Identifier, DocumentTag> | null;
|
||||
onTagClick?: (tagId?: Identifier | null) => void;
|
||||
onCorrespondentClick?: (correspondentId?: Identifier | null) => void;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null | undefined> | null;
|
||||
activeCorrespondentIdSet?: Set<Identifier | null> | null;
|
||||
scrollRef?: RefObject<HTMLElement | null>;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ import { useWorkspaceSelectionContext } from '../app/WorkspaceSelectionContext';
|
||||
const ROOT_FOLDER_LABEL = 'Documents';
|
||||
|
||||
type DocumentId = string | number;
|
||||
type NullableDocumentId = DocumentId | null | undefined;
|
||||
type NullableDocumentId = DocumentId | null;
|
||||
|
||||
type SelectedIdList = Array<NullableDocumentId> | null | undefined;
|
||||
type SelectedIdList = NullableDocumentId[] | null;
|
||||
|
||||
type FolderTreeNode = {
|
||||
id?: DocumentId;
|
||||
@@ -137,8 +137,8 @@ const buildFolderTreeOptions = (tree?: FolderTreeNode[] | null): SelectionAssign
|
||||
|
||||
const buildTagAssignments = (
|
||||
selectedDocuments: DocumentLike[],
|
||||
tagLookupById: Map<DocumentId, TagOption> | null | undefined,
|
||||
tags: TagOption[] | null | undefined,
|
||||
tagLookupById: Map<DocumentId, TagOption> | null,
|
||||
tags: TagOption[] | null,
|
||||
total: number,
|
||||
): SelectionAssignmentMenuItem[] => {
|
||||
if (!total) {
|
||||
@@ -202,7 +202,7 @@ const buildTagAssignments = (
|
||||
|
||||
const buildCorrespondentAssignments = (
|
||||
selectedDocuments: DocumentLike[],
|
||||
correspondents: CorrespondentOption[] | null | undefined,
|
||||
correspondents: CorrespondentOption[] | null,
|
||||
total: number,
|
||||
): SelectionAssignmentMenuItem[] => {
|
||||
if (!total) {
|
||||
@@ -493,7 +493,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
|
||||
if (!documentIdList.length || !onMoveDocumentsToFolder) {
|
||||
return;
|
||||
}
|
||||
const candidate = option as { id?: DocumentId; value?: DocumentId } | DocumentId | null | undefined;
|
||||
const candidate = option as { id?: DocumentId; value?: DocumentId } | DocumentId | null;
|
||||
const value = isRecord(candidate)
|
||||
? (candidate?.id ?? candidate?.value ?? null)
|
||||
: candidate;
|
||||
|
||||
@@ -20,7 +20,7 @@ export interface DocumentLike {
|
||||
|
||||
export interface DocumentMetadataItem {
|
||||
label: string;
|
||||
value: string | null | undefined;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export const buildDocumentMetadataItems = (document?: DocumentLike | null): DocumentMetadataItem[] => {
|
||||
@@ -35,19 +35,19 @@ export const buildDocumentMetadataItems = (document?: DocumentLike | null): Docu
|
||||
{ label: 'Updated at', value: formatDateTime(document.updated_at) },
|
||||
{
|
||||
label: 'Filename',
|
||||
value: document.filename,
|
||||
value: document.filename ?? null,
|
||||
},
|
||||
{
|
||||
label: 'Original filename',
|
||||
value: document.original_name || '—',
|
||||
value: document.original_name ?? null,
|
||||
},
|
||||
{
|
||||
label: 'SHA-256 checksum',
|
||||
value: metadata.checksum || '—',
|
||||
value: metadata.checksum ?? null,
|
||||
},
|
||||
{
|
||||
label: 'Content type',
|
||||
value: document.content_type || '—',
|
||||
value: document.content_type ?? null,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
@@ -38,12 +38,12 @@ interface DescribeSummaryOptions {
|
||||
export interface DocumentSummaryRow {
|
||||
key: string;
|
||||
label: string;
|
||||
value: string | null | undefined;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export interface DocumentSummary {
|
||||
title: string | undefined;
|
||||
originalName: string | null | undefined;
|
||||
originalName: string | null;
|
||||
mimeTypeLabel: string;
|
||||
sizeLabel: string;
|
||||
createdAtLabel: string;
|
||||
@@ -51,7 +51,7 @@ export interface DocumentSummary {
|
||||
updatedAtLabel: string;
|
||||
pageCount: number | null;
|
||||
pageCountLabel: string;
|
||||
folderLabel: string | null | undefined;
|
||||
folderLabel: string | null;
|
||||
tags: TagEntry[];
|
||||
correspondents: CorrespondentEntry[];
|
||||
tagsSummary: string;
|
||||
@@ -59,7 +59,7 @@ export interface DocumentSummary {
|
||||
summaryRows: DocumentSummaryRow[];
|
||||
}
|
||||
|
||||
const coercePageCount = (metadata: DocumentMetadata | null | undefined): number | null => {
|
||||
const coercePageCount = (metadata?: DocumentMetadata | null): number | null => {
|
||||
const raw = metadata?.page_count;
|
||||
if (raw == null || raw === '') {
|
||||
return null;
|
||||
@@ -68,7 +68,7 @@ const coercePageCount = (metadata: DocumentMetadata | null | undefined): number
|
||||
return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
|
||||
};
|
||||
|
||||
const sanitizeArray = <T>(entries: (T | null | undefined)[] | null | undefined): T[] =>
|
||||
const sanitizeArray = <T>(entries?: Array<T | null> | null): T[] =>
|
||||
Array.isArray(entries) ? entries.filter(Boolean) as T[] : [];
|
||||
|
||||
export const describeDocumentSummary = (document?: SummaryDocument | null, options: DescribeSummaryOptions = {}): DocumentSummary => {
|
||||
@@ -79,7 +79,7 @@ export const describeDocumentSummary = (document?: SummaryDocument | null, optio
|
||||
if (!document) {
|
||||
return {
|
||||
title: '',
|
||||
originalName: '',
|
||||
originalName: null,
|
||||
mimeTypeLabel: '—',
|
||||
sizeLabel: '—',
|
||||
createdAtLabel: '—',
|
||||
@@ -110,7 +110,8 @@ export const describeDocumentSummary = (document?: SummaryDocument | null, optio
|
||||
const issuedLabel = formatDateTime(document.issued_at);
|
||||
const updatedAtLabel = formatDateTime(document.updated_at);
|
||||
|
||||
const folderLabel = document.folder_path;
|
||||
const folderLabel = document.folder_path ?? null;
|
||||
const displayFolderLabel = folderLabel ?? 'Documents';
|
||||
|
||||
const tags = sanitizeArray<TagEntry>(document.tags);
|
||||
const correspondents = sanitizeArray<CorrespondentEntry>(document.correspondents);
|
||||
@@ -130,7 +131,7 @@ export const describeDocumentSummary = (document?: SummaryDocument | null, optio
|
||||
{ key: 'issued', label: 'Issued', value: issuedLabel },
|
||||
{ key: 'pages', label: 'Pages', value: pageCountLabel },
|
||||
{ key: 'updated', label: 'Updated', value: updatedAtLabel },
|
||||
{ key: 'folder', label: 'Folder', value: folderLabel },
|
||||
{ key: 'folder', label: 'Folder', value: displayFolderLabel },
|
||||
{ key: 'tags', label: 'Tags', value: tagsSummary },
|
||||
{ key: 'correspondents', label: 'Correspondents', value: correspondentsSummary },
|
||||
];
|
||||
|
||||
@@ -21,7 +21,7 @@ const serializePayload = (payload: TagPayload): string | null => {
|
||||
}
|
||||
};
|
||||
|
||||
export const createTagTransferPayload = (tag: TagLike | null | undefined, sourceDocId: string | number | null = null): TagPayload | null => {
|
||||
export const createTagTransferPayload = (tag?: TagLike | null, sourceDocId: string | number | null = null): TagPayload | null => {
|
||||
if (!tag || tag.id == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -58,7 +58,7 @@ export const writeTagTransferData = (dataTransfer: DataTransfer | null, tag: Tag
|
||||
}
|
||||
};
|
||||
|
||||
export const readTagTransferData = (dataTransfer: DataTransfer | null | undefined): string | null => {
|
||||
export const readTagTransferData = (dataTransfer?: DataTransfer | null): string | null => {
|
||||
if (!dataTransfer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ export interface WorkspaceEntry {
|
||||
}
|
||||
|
||||
interface UseEntryPointerOptions {
|
||||
resolveDocumentRowKey?: (id: string | number) => string | null | undefined;
|
||||
resolveFolderRowKey?: (id: string | number) => string | null | undefined;
|
||||
resolveDocumentRowKey?: (id: string | number) => string | null;
|
||||
resolveFolderRowKey?: (id: string | number) => string | null;
|
||||
onSelectEntry?: (entry: WorkspaceEntry, event?: PointerEventLike | null, metadata?: EntryPointerMetadata) => void;
|
||||
onInspectDocument?: (id: string | number, metadata?: EntryPointerMetadata) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user