typescript

This commit is contained in:
2025-11-13 01:07:55 +01:00
parent b812d748ea
commit ada089c05b
147 changed files with 7427 additions and 2534 deletions
+106
View File
@@ -0,0 +1,106 @@
import { useCallback, useEffect, useRef, useState } from 'react';
export interface DetailDocument {
id?: string | number;
[key: string]: unknown;
}
interface UseDetailPanelOptions {
documentLookup: Map<string | number, DetailDocument>;
orderedSelectedDocuments: DetailDocument[];
}
interface OpenDetailPanelArgs {
documentId?: string | number;
document?: DetailDocument | null;
documentIds?: Array<string | number>;
documents?: DetailDocument[];
}
export const useDetailPanel = ({
documentLookup,
orderedSelectedDocuments,
}: UseDetailPanelOptions) => {
const [detailPanelOpen, setDetailPanelOpen] = useState(false);
const [detailPanelDocId, setDetailPanelDocId] = useState<string | number | null>(null);
const [detailPanelDocument, setDetailPanelDocument] = useState<DetailDocument | null>(null);
const latestOrderedDocsRef = useRef<DetailDocument[]>([]);
useEffect(() => {
latestOrderedDocsRef.current = orderedSelectedDocuments;
if (detailPanelOpen && orderedSelectedDocuments.length) {
const nextDoc = orderedSelectedDocuments[orderedSelectedDocuments.length - 1];
if (nextDoc?.id) {
setDetailPanelDocId(nextDoc.id);
setDetailPanelDocument(nextDoc);
}
}
}, [orderedSelectedDocuments, detailPanelOpen]);
useEffect(() => {
if (!detailPanelDocId) {
if (!detailPanelOpen) {
setDetailPanelDocument(null);
}
return;
}
const resolved = documentLookup.get(detailPanelDocId);
if (resolved && resolved !== detailPanelDocument) {
setDetailPanelDocument(resolved);
}
}, [detailPanelDocId, documentLookup, detailPanelDocument, detailPanelOpen]);
const openDetailPanel = useCallback(
({ documentId, document, documentIds, documents }: OpenDetailPanelArgs = {}) => {
let targetDoc = document || null;
let targetId = documentId ?? document?.id ?? null;
if (!targetDoc && Array.isArray(documents) && documents.length) {
targetDoc = documents[documents.length - 1];
targetId = targetDoc?.id ?? targetId;
}
if (!targetDoc && Array.isArray(documentIds) && documentIds.length) {
targetId = documentIds[documentIds.length - 1];
}
if (!targetDoc && targetId != null) {
targetDoc = documentLookup.get(String(targetId)) || null;
}
if (!targetDoc) {
const fallbackDocs = latestOrderedDocsRef.current;
const fallbackDoc = Array.isArray(fallbackDocs) && fallbackDocs.length
? fallbackDocs[fallbackDocs.length - 1]
: null;
if (fallbackDoc) {
targetDoc = fallbackDoc;
targetId = fallbackDoc.id;
}
}
if (!targetDoc && targetId == null) {
return;
}
setDetailPanelDocId(targetDoc?.id ?? targetId ?? null);
setDetailPanelDocument(targetDoc || null);
setDetailPanelOpen(Boolean(targetDoc || targetId));
},
[documentLookup],
);
const closeDetailPanel = useCallback(() => {
setDetailPanelOpen(false);
}, []);
return {
detailPanelOpen,
detailPanelDocument,
openDetailPanel,
closeDetailPanel,
setDetailPanelOpen,
};
};
export default useDetailPanel;