refactor: lazy load document content only when its tab is active and separate content state reset logic

This commit is contained in:
2025-11-28 21:55:47 +01:00
parent b9019d48fc
commit 79aa359c1f
+86 -43
View File
@@ -101,50 +101,7 @@ const DocumentInfoPanel: React.FC<DocumentInfoPanelProps> = ({
return { status: 'idle', data: null, error: null };
});
useEffect(() => {
if (!contentConfig || !showContentTab) {
setContentState(null);
return undefined;
}
if (!contentEnabled || !loadContent) {
setContentState({ status: contentEnabled ? 'idle' : 'unavailable', data: null, error: null });
return undefined;
}
let cancelled = false;
const controller = new AbortController();
setContentState({ status: 'loading', data: null, error: null });
Promise.resolve(loadContent({ signal: controller.signal }))
.then((result) => {
if (cancelled) {
return;
}
if (result && result.length) {
setContentState({ status: 'loaded', data: result, error: null });
} else {
setContentState({ status: 'empty', data: '', error: null });
}
})
.catch((error) => {
if (cancelled || error?.name === 'AbortError') {
return;
}
setContentState({
status: 'error',
data: null,
error,
});
});
return () => {
cancelled = true;
controller.abort();
contentConfig.onCancel?.();
};
}, [contentConfig, contentEnabled, showContentTab, document?.id, resetKey, loadContent]);
const renderSummarySection = useCallback(() => (
<DocumentSummarySection
@@ -373,6 +330,92 @@ const DocumentInfoPanel: React.FC<DocumentInfoPanelProps> = ({
const activeTabId = isControlled ? controlledActiveTab : uncontrolledTab;
// Track previous ID/key to avoid unnecessary resets on prop reference changes
const prevDocIdRef = React.useRef(document?.id);
const prevResetKeyRef = React.useRef(resetKey);
// Reset content state when document changes
useEffect(() => {
const docIdChanged = prevDocIdRef.current !== document?.id;
const resetKeyChanged = prevResetKeyRef.current !== resetKey;
if (docIdChanged || resetKeyChanged) {
prevDocIdRef.current = document?.id;
prevResetKeyRef.current = resetKey;
if (!contentConfig || !showContentTab) {
setContentState(null);
return;
}
if (!contentEnabled || !loadContent) {
setContentState({ status: contentEnabled ? 'idle' : 'unavailable', data: null, error: null });
return;
}
// Reset to idle so the loading effect can trigger if needed
setContentState({ status: 'idle', data: null, error: null });
}
}, [
contentConfig,
showContentTab,
contentEnabled,
loadContent,
document?.id,
resetKey,
]);
// Lazy load content when tab is active
useEffect(() => {
const contentTabId = contentConfig?.id || 'content';
const isActive = activeTabId === contentTabId;
if (!isActive || !contentConfig || !loadContent || !contentEnabled) {
return undefined;
}
if (contentState?.status !== 'idle') {
return undefined;
}
let cancelled = false;
const controller = new AbortController();
setContentState({ status: 'loading', data: null, error: null });
Promise.resolve(loadContent({ signal: controller.signal }))
.then((result) => {
if (cancelled) {
return;
}
if (result && result.length) {
setContentState({ status: 'loaded', data: result, error: null });
} else {
setContentState({ status: 'empty', data: '', error: null });
}
})
.catch((error) => {
if (cancelled || error?.name === 'AbortError') {
return;
}
setContentState({
status: 'error',
data: null,
error,
});
});
return () => {
cancelled = true;
controller.abort();
contentConfig.onCancel?.();
};
}, [
activeTabId,
contentConfig,
loadContent,
contentEnabled,
contentState?.status,
]);
const handleTabSelect = (tabId) => {
if (!visibleTabs.some((tab) => tab.id === tabId)) {
return;