buster/web/src/layouts/ChatLayout/ChatLayoutContext/useLayoutConfig/useLayoutConfig.ts

150 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-03-22 12:01:14 +08:00
'use client';
2025-02-01 02:04:49 +08:00
import { FileType } from '@/api/asset_interfaces';
2025-03-26 13:14:36 +08:00
import { useLayoutEffect, useMemo, useState } from 'react';
2025-01-31 06:33:06 +08:00
import { FileConfig, FileView, FileViewConfig, FileViewSecondary } from './interfaces';
2025-03-08 07:02:56 +08:00
import { useMemoizedFn } from '@/hooks';
2025-02-08 05:11:05 +08:00
import { create } from 'mutative';
2025-03-28 05:05:06 +08:00
import { ChatLayoutView } from '../../interfaces';
import type { SelectedFile } from '../../interfaces';
2025-01-31 06:33:06 +08:00
2025-03-26 11:56:21 +08:00
export const useLayoutConfig = ({
2025-03-28 05:05:06 +08:00
selectedFile,
isVersionHistoryMode,
chatId
2025-01-31 06:33:06 +08:00
}: {
2025-03-28 05:05:06 +08:00
selectedFile: SelectedFile | null;
2025-03-26 13:14:36 +08:00
isVersionHistoryMode: boolean;
2025-03-28 05:05:06 +08:00
chatId: string | undefined;
2025-01-31 06:33:06 +08:00
}) => {
const [fileViews, setFileViews] = useState<Record<string, FileConfig>>({});
2025-03-28 05:05:06 +08:00
const selectedFileId = selectedFile?.id;
const selectedFileType = selectedFile?.type;
2025-03-20 04:47:15 +08:00
const selectedFileView: FileView | undefined = useMemo(() => {
if (!selectedFileId) return undefined;
return (
2025-03-28 05:05:06 +08:00
fileViews[selectedFileId]?.selectedFileView || DEFAULT_FILE_VIEW[selectedFileType as FileType]
2025-03-20 04:47:15 +08:00
);
}, [fileViews, selectedFileId, selectedFileType]);
const selectedFileViewConfig: FileViewConfig | undefined = useMemo(() => {
if (!selectedFileId) return undefined;
return fileViews[selectedFileId]?.fileViewConfig;
}, [fileViews, selectedFileId]);
const selectedFileViewSecondary: FileViewSecondary | null = useMemo(() => {
if (!selectedFileId || !selectedFileViewConfig || !selectedFileView) return null;
return selectedFileViewConfig?.[selectedFileView]?.secondaryView ?? null;
}, [selectedFileViewConfig, selectedFileId, selectedFileView]);
2025-03-26 13:14:36 +08:00
const selectedFileViewRenderSecondary: boolean = useMemo(() => {
if (!selectedFileId || !selectedFileViewConfig || !selectedFileView) return false;
if (selectedFileViewConfig?.[selectedFileView]?.secondaryView) {
return selectedFileViewConfig?.[selectedFileView]?.renderView !== false;
}
return false;
}, [selectedFileViewConfig]);
2025-01-31 06:33:06 +08:00
const onSetFileView = useMemoizedFn(
({
fileView,
2025-03-28 05:05:06 +08:00
fileId: fileIdProp,
2025-03-26 13:14:36 +08:00
secondaryView,
renderView
2025-01-31 06:33:06 +08:00
}: {
fileView?: FileView;
2025-03-28 05:05:06 +08:00
fileId?: string | undefined;
2025-01-31 06:33:06 +08:00
secondaryView?: FileViewSecondary;
2025-03-26 13:14:36 +08:00
renderView?: boolean;
2025-01-31 06:33:06 +08:00
}) => {
2025-03-28 05:05:06 +08:00
const fileId = fileIdProp ?? selectedFileId;
if (!fileId) return;
2025-01-31 06:33:06 +08:00
setFileViews((prev) => {
2025-03-28 05:05:06 +08:00
return create(prev, (draft) => {
if (!draft[fileId]) {
draft[fileId] = {
selectedFileView: DEFAULT_FILE_VIEW[selectedFileType as FileType] || 'file',
fileViewConfig: {}
};
}
const usedFileView =
fileView ??
draft[fileId].selectedFileView ??
DEFAULT_FILE_VIEW[selectedFileType as FileType];
if (fileView !== undefined) {
draft[fileId].selectedFileView = fileView;
}
if (secondaryView !== undefined) {
if (!draft[fileId].fileViewConfig) {
draft[fileId].fileViewConfig = {};
2025-01-31 06:33:06 +08:00
}
2025-03-28 05:05:06 +08:00
draft[fileId].fileViewConfig[usedFileView] = {
...(draft[fileId].fileViewConfig[usedFileView] || {}),
secondaryView,
renderView
};
}
});
2025-01-31 06:33:06 +08:00
});
}
);
2025-02-04 02:24:32 +08:00
const closeSecondaryView = useMemoizedFn(() => {
if (!selectedFileId || !selectedFileViewConfig || !selectedFileView) return;
2025-03-08 07:02:56 +08:00
setFileViews((prev) => {
return create(prev, (draft) => {
2025-02-04 02:24:32 +08:00
if (!draft[selectedFileId]?.fileViewConfig?.[selectedFileView]) return;
draft[selectedFileId].fileViewConfig[selectedFileView].secondaryView = null;
2025-03-08 07:02:56 +08:00
});
});
2025-02-04 02:24:32 +08:00
});
2025-03-28 05:05:06 +08:00
const selectedLayout: ChatLayoutView = useMemo(() => {
if (chatId) {
if (selectedFileId) return 'both';
return 'chat';
}
return 'file';
}, [selectedFileId]);
2025-03-26 13:14:36 +08:00
useLayoutEffect(() => {
if (
isVersionHistoryMode &&
selectedFileId &&
(selectedFileType === 'metric' || selectedFileType === 'dashboard')
) {
const fileView = selectedFileType === 'metric' ? 'chart' : 'dashboard';
onSetFileView({
fileId: selectedFileId,
fileView,
secondaryView: 'version-history'
});
}
}, [isVersionHistoryMode, selectedFileId]);
2025-01-31 06:33:06 +08:00
return {
2025-03-28 05:05:06 +08:00
selectedLayout,
2025-01-31 06:33:06 +08:00
selectedFileView,
selectedFileViewSecondary,
2025-03-26 13:14:36 +08:00
selectedFileViewRenderSecondary,
2025-02-04 02:24:32 +08:00
onSetFileView,
closeSecondaryView
2025-01-31 06:33:06 +08:00
};
};
2025-03-28 05:05:06 +08:00
const DEFAULT_FILE_VIEW: Record<FileType, FileView> = {
2025-01-31 06:33:06 +08:00
metric: 'chart',
2025-02-08 13:24:18 +08:00
dashboard: 'dashboard',
reasoning: 'reasoning'
// collection: 'results',
// value: 'results',
// term: 'results',
// dataset: 'results',
2025-01-31 06:33:06 +08:00
};