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
|
|
|
};
|