typescript

This commit is contained in:
2025-11-13 02:37:16 +01:00
parent ada089c05b
commit 6d55e61cee
43 changed files with 923 additions and 406 deletions
@@ -57,6 +57,44 @@ const EntryType = Object.freeze({
const noop = () => {};
type Identifier = string | number;
type DocumentId = Identifier;
type FolderId = Identifier | 'root';
interface DocumentLike {
id?: DocumentId | null;
title?: string | null;
[key: string]: unknown;
}
interface FolderNode {
id: FolderId;
name?: string | null;
parentId?: FolderId | null;
children: FolderId[];
hasChildren?: boolean;
expanded?: boolean;
loaded?: boolean;
[key: string]: unknown;
}
interface FolderContentsEntry {
folder?: { id?: FolderId; name?: string | null } | null;
documents?: DocumentLike[];
subfolders?: Array<{ id?: FolderId; name?: string | null; [key: string]: unknown }>;
__includesDocuments?: boolean;
__sortField?: string | null;
__sortDirection?: string | null;
[key: string]: unknown;
}
interface TenantOption {
id?: Identifier | null;
name?: string | null;
slug?: string | null;
[key: string]: unknown;
}
interface UseDocumentsWorkspaceOptions {
documentsViewMode?: string;
documentsSortField?: string;
@@ -118,9 +156,31 @@ const useDocumentsWorkspace = ({
const routeFolderId = folderMatch?.params?.folderId || null;
const routeDocumentId = docMatch?.params?.documentId || null;
const previewDocumentId = routeDocumentId;
const { status: appStatus, token, tenant, tenants: tenantOptions = [] } = appState;
const tenantName = tenant?.name || tenant?.slug || null;
const currentTenantId = tenant?.id || null;
const {
status: appStatus,
token,
tenant,
tenants: tenantOptionsRaw = [],
} = 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 currentTenantId: Identifier | null = (() => {
const value = tenantRecord?.id;
if (typeof value === 'string' || typeof value === 'number') {
return value as Identifier;
}
return null;
})();
const tenantOptions: TenantOption[] = Array.isArray(tenantOptionsRaw)
? (tenantOptionsRaw as TenantOption[])
: [];
const { status, setStatusMessage } = useDocumentsStore();
const handleApiReport = useCallback(
({ message, variant }) => setStatusMessage(message, variant),
@@ -172,9 +232,9 @@ const useDocumentsWorkspace = ({
documentsRouteMatch || documentsFolderRouteMatch || documentsDetailRouteMatch,
);
const [draggedDocumentIds, setDraggedDocumentIds] = useState([]);
const [draggedFolderId, setDraggedFolderId] = useState(null);
const [activePreviewId, setActivePreviewId] = useState(routeDocumentId || null);
const [draggedDocumentIds, setDraggedDocumentIds] = useState<DocumentId[]>([]);
const [draggedFolderId, setDraggedFolderId] = useState<FolderId | null>(null);
const [activePreviewId, setActivePreviewId] = useState<DocumentId | null>(routeDocumentId || null);
const shellRef = useRef(null);
const assetManagerRef = useRef(null);
if (!assetManagerRef.current) {
@@ -249,7 +309,9 @@ const useDocumentsWorkspace = ({
],
);
const [folderContents, setFolderContents] = useState(() => new Map());
const [folderContents, setFolderContents] = useState<Map<FolderId, FolderContentsEntry>>(
() => new Map(),
);
const folderContentsRef = useRef(folderContents);
useEffect(() => {
folderContentsRef.current = folderContents;
@@ -363,6 +425,17 @@ const useDocumentsWorkspace = ({
setActivePreviewId,
});
const openDocumentPreviewForDetail = useCallback(
({ documentIds }: { documentIds?: Identifier[] } = {}) => {
const targetId = documentIds?.find((value): value is Identifier => value != null);
if (targetId == null) {
return;
}
openDocumentPreview(targetId, { replace: true });
},
[openDocumentPreview],
);
const getDocumentAsset = useCallback((doc, type) => {
if (!doc || !type) return null;
return getAssetFromVersion(doc.current_version || null, type);
@@ -688,12 +761,13 @@ const useDocumentsWorkspace = ({
const removeDocumentsFromCaches = useCallback(
(documentIds) => {
if (!documentIds || documentIds.length === 0) {
(documentIds: DocumentId[] | null | undefined) => {
const safeIds = Array.isArray(documentIds) ? documentIds : [];
if (!safeIds.length) {
return;
}
const idSet = new Set(documentIds);
const idSet = new Set<DocumentId>(safeIds);
setDocuments((prev) => prev.filter((doc) => !idSet.has(doc.id)));
setSearchResults((prev) => {
@@ -704,12 +778,12 @@ const useDocumentsWorkspace = ({
return filtered.length === prev.length ? prev : filtered;
});
setFolderContents((prev) => {
setFolderContents((prev: Map<FolderId, FolderContentsEntry>) => {
if (!prev.size) {
return prev;
}
let changed = false;
const next = new Map();
const next = new Map<FolderId, FolderContentsEntry>();
prev.forEach((contents, key) => {
const docs = Array.isArray(contents?.documents) ? contents.documents : null;
if (!docs || docs.length === 0) {
@@ -1177,7 +1251,6 @@ const useDocumentsWorkspace = ({
documents,
searchResults,
previewDocuments,
focusedDocumentId,
selectionOrder,
selectedDocumentIds,
documentLookup,
@@ -1188,8 +1261,7 @@ const useDocumentsWorkspace = ({
previewEntries,
previewDocumentId,
activePreviewId,
openDocumentPreview,
promoteSelectionOrder,
openDocumentPreview: openDocumentPreviewForDetail,
handleDocumentTitleUpdate,
handleDocumentIssuedUpdate,
handleDocumentTagAdd,
@@ -1206,6 +1278,17 @@ const useDocumentsWorkspace = ({
tagLookupById,
});
const inspectDocumentForDesk = useCallback(
(doc: DocumentLike | null) => {
const docId = doc?.id;
if (docId == null) {
return;
}
inspectDocument(docId);
},
[inspectDocument],
);
const handleEntryPointerCore = useEntryPointerCore({
resolveDocumentRowKey,
resolveFolderRowKey,
@@ -1426,7 +1509,7 @@ const useDocumentsWorkspace = ({
handleDocumentsViewModeChange,
handleDeskExit: handleDeskExitSafe,
refreshCurrentFolder,
inspectDocument,
inspectDocument: inspectDocumentForDesk,
handleEntryPointerCore,
promoteSelectionOrder,
currentTenantId,