mirror of https://github.com/buster-so/buster.git
collapse file click looking good 👼
This commit is contained in:
parent
2fde9f27a1
commit
df1a685dde
|
@ -85,7 +85,7 @@ export const DropdownBase = <T,>({
|
||||||
closeOnSelect = true,
|
closeOnSelect = true,
|
||||||
onSelect,
|
onSelect,
|
||||||
children,
|
children,
|
||||||
align = 'center',
|
align = 'start',
|
||||||
side = 'bottom',
|
side = 'bottom',
|
||||||
open,
|
open,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useMemo } from 'react';
|
||||||
import type { MetricViewProps } from '../config';
|
import type { MetricViewProps } from '../config';
|
||||||
import { useMemoizedFn, useUnmount } from '@/hooks';
|
import { useMemoizedFn, useUnmount } from '@/hooks';
|
||||||
import { IDataResult } from '@/api/asset_interfaces';
|
import { IDataResult } from '@/api/asset_interfaces';
|
||||||
import { useMetricLayout } from '../useMetricLayout';
|
import { useMetricResultsLayout } from './useMetricResultsLayout';
|
||||||
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout/ChatLayoutContext';
|
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout/ChatLayoutContext';
|
||||||
import { AppSplitterRef } from '@/components/ui/layouts';
|
import { AppSplitterRef } from '@/components/ui/layouts';
|
||||||
import { AppVerticalCodeSplitter } from '@/components/features/layouts/AppVerticalCodeSplitter';
|
import { AppVerticalCodeSplitter } from '@/components/features/layouts/AppVerticalCodeSplitter';
|
||||||
|
@ -67,11 +67,10 @@ export const MetricViewResults: React.FC<MetricViewProps> = React.memo(({ metric
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const { defaultLayout, renderSecondary } = useMetricLayout({
|
const { defaultLayout, renderSecondary } = useMetricResultsLayout({
|
||||||
selectedFileViewSecondary,
|
selectedFileViewSecondary,
|
||||||
appSplitterRef,
|
appSplitterRef,
|
||||||
autoSaveId,
|
autoSaveId
|
||||||
type: 'sql'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -4,29 +4,23 @@ import { type AppSplitterRef } from '@/components/ui/layouts';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import { createAutoSaveId } from '@/components/ui/layouts/AppSplitter/helper';
|
import { createAutoSaveId } from '@/components/ui/layouts/AppSplitter/helper';
|
||||||
|
|
||||||
const defaultChartOpenLayout = ['auto', '310px'];
|
|
||||||
const defaultSqlOpenLayout = ['30%', 'auto'];
|
const defaultSqlOpenLayout = ['30%', 'auto'];
|
||||||
|
|
||||||
const defaultChartLayout = ['auto', '0px'];
|
|
||||||
const defaultSqlLayout = ['0px', 'auto'];
|
const defaultSqlLayout = ['0px', 'auto'];
|
||||||
|
|
||||||
export const useMetricLayout = ({
|
export const useMetricResultsLayout = ({
|
||||||
selectedFileViewSecondary,
|
selectedFileViewSecondary,
|
||||||
appSplitterRef,
|
appSplitterRef,
|
||||||
autoSaveId,
|
autoSaveId
|
||||||
type
|
|
||||||
}: {
|
}: {
|
||||||
selectedFileViewSecondary: null | string;
|
selectedFileViewSecondary: null | string;
|
||||||
appSplitterRef: React.RefObject<AppSplitterRef | null>;
|
appSplitterRef: React.RefObject<AppSplitterRef | null>;
|
||||||
autoSaveId: string;
|
autoSaveId: string;
|
||||||
type: 'chart' | 'sql';
|
|
||||||
}) => {
|
}) => {
|
||||||
const [renderSecondary, setRenderSecondary] = useState<boolean>(!!selectedFileViewSecondary);
|
const [renderSecondary, setRenderSecondary] = useState<boolean>(!!selectedFileViewSecondary);
|
||||||
|
|
||||||
const isOpenSecondary = !!selectedFileViewSecondary;
|
const isOpenSecondary = !!selectedFileViewSecondary;
|
||||||
const isChart = type === 'chart';
|
const defaultOpenLayout = defaultSqlOpenLayout;
|
||||||
const defaultOpenLayout = isChart ? defaultChartOpenLayout : defaultSqlOpenLayout;
|
const defaultOriginalLayout = defaultSqlLayout;
|
||||||
const defaultOriginalLayout = isChart ? defaultChartLayout : defaultSqlLayout;
|
|
||||||
|
|
||||||
const secondaryLayoutDimensions: [string, string] = useMemo(() => {
|
const secondaryLayoutDimensions: [string, string] = useMemo(() => {
|
||||||
const cookieKey = createAutoSaveId(autoSaveId);
|
const cookieKey = createAutoSaveId(autoSaveId);
|
||||||
|
@ -54,20 +48,10 @@ export const useMetricLayout = ({
|
||||||
const animateOpenSplitter = useMemoizedFn((side: 'metric' | 'both') => {
|
const animateOpenSplitter = useMemoizedFn((side: 'metric' | 'both') => {
|
||||||
if (!appSplitterRef.current) return;
|
if (!appSplitterRef.current) return;
|
||||||
|
|
||||||
if (type === 'chart') {
|
if (side === 'metric') {
|
||||||
if (side === 'metric') {
|
appSplitterRef.current.animateWidth('0px', 'left');
|
||||||
appSplitterRef.current.animateWidth('100%', 'left');
|
} else if (side === 'both') {
|
||||||
} else if (side === 'both') {
|
appSplitterRef.current.animateWidth('40%', 'left');
|
||||||
appSplitterRef.current.animateWidth('310px', 'right');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'sql') {
|
|
||||||
if (side === 'metric') {
|
|
||||||
appSplitterRef.current.animateWidth('0px', 'left');
|
|
||||||
} else if (side === 'both') {
|
|
||||||
appSplitterRef.current.animateWidth('40%', 'left');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,8 +26,6 @@ export const ChatLayout: React.FC<ChatSplitterProps> = ({ children }) => {
|
||||||
return ['380px', 'auto'];
|
return ['380px', 'auto'];
|
||||||
}, [selectedLayout]);
|
}, [selectedLayout]);
|
||||||
|
|
||||||
console.log(selectedLayout);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatLayoutContextProvider chatLayoutProps={chatLayoutProps}>
|
<ChatLayoutContextProvider chatLayoutProps={chatLayoutProps}>
|
||||||
<ChatContextProvider
|
<ChatContextProvider
|
||||||
|
|
|
@ -37,12 +37,11 @@ export const useChatLayoutContext = ({ appSplitterRef }: UseLayoutConfigProps) =
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { onCollapseFileClick, selectedFile, onSetSelectedFile, isVersionHistoryMode } =
|
const { selectedFile, onSetSelectedFile, isVersionHistoryMode } = useSelectedFile({
|
||||||
useSelectedFile({
|
animateOpenSplitter,
|
||||||
animateOpenSplitter,
|
chatParams,
|
||||||
chatParams,
|
appSplitterRef
|
||||||
appSplitterRef
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
selectedFileView,
|
selectedFileView,
|
||||||
|
@ -50,11 +49,14 @@ export const useChatLayoutContext = ({ appSplitterRef }: UseLayoutConfigProps) =
|
||||||
selectedFileViewSecondary,
|
selectedFileViewSecondary,
|
||||||
onSetFileView,
|
onSetFileView,
|
||||||
closeSecondaryView,
|
closeSecondaryView,
|
||||||
selectedLayout
|
selectedLayout,
|
||||||
|
onCollapseFileClick
|
||||||
} = useLayoutConfig({
|
} = useLayoutConfig({
|
||||||
selectedFile,
|
selectedFile,
|
||||||
isVersionHistoryMode,
|
isVersionHistoryMode,
|
||||||
chatId: chatParams.chatId
|
chatId: chatParams.chatId,
|
||||||
|
animateOpenSplitter,
|
||||||
|
onSetSelectedFile
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -7,15 +7,20 @@ import { useMemoizedFn } from '@/hooks';
|
||||||
import { create } from 'mutative';
|
import { create } from 'mutative';
|
||||||
import { ChatLayoutView } from '../../interfaces';
|
import { ChatLayoutView } from '../../interfaces';
|
||||||
import type { SelectedFile } from '../../interfaces';
|
import type { SelectedFile } from '../../interfaces';
|
||||||
|
import { timeout } from '@/lib';
|
||||||
|
|
||||||
export const useLayoutConfig = ({
|
export const useLayoutConfig = ({
|
||||||
selectedFile,
|
selectedFile,
|
||||||
isVersionHistoryMode,
|
isVersionHistoryMode,
|
||||||
chatId
|
chatId,
|
||||||
|
onSetSelectedFile,
|
||||||
|
animateOpenSplitter
|
||||||
}: {
|
}: {
|
||||||
selectedFile: SelectedFile | null;
|
selectedFile: SelectedFile | null;
|
||||||
isVersionHistoryMode: boolean;
|
isVersionHistoryMode: boolean;
|
||||||
chatId: string | undefined;
|
chatId: string | undefined;
|
||||||
|
animateOpenSplitter: (side: 'left' | 'right' | 'both') => void;
|
||||||
|
onSetSelectedFile: (file: SelectedFile | null) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [fileViews, setFileViews] = useState<Record<string, FileConfig>>({});
|
const [fileViews, setFileViews] = useState<Record<string, FileConfig>>({});
|
||||||
|
|
||||||
|
@ -48,7 +53,7 @@ export const useLayoutConfig = ({
|
||||||
}, [selectedFileViewConfig]);
|
}, [selectedFileViewConfig]);
|
||||||
|
|
||||||
const onSetFileView = useMemoizedFn(
|
const onSetFileView = useMemoizedFn(
|
||||||
({
|
async ({
|
||||||
fileView,
|
fileView,
|
||||||
fileId: fileIdProp,
|
fileId: fileIdProp,
|
||||||
secondaryView,
|
secondaryView,
|
||||||
|
@ -61,6 +66,14 @@ export const useLayoutConfig = ({
|
||||||
}) => {
|
}) => {
|
||||||
const fileId = fileIdProp ?? selectedFileId;
|
const fileId = fileIdProp ?? selectedFileId;
|
||||||
if (!fileId) return;
|
if (!fileId) return;
|
||||||
|
|
||||||
|
if (secondaryView) {
|
||||||
|
animateOpenSplitter('right');
|
||||||
|
await timeout(250); //wait for splitter to close before opening secondary view
|
||||||
|
} else {
|
||||||
|
animateOpenSplitter('both');
|
||||||
|
}
|
||||||
|
|
||||||
setFileViews((prev) => {
|
setFileViews((prev) => {
|
||||||
return create(prev, (draft) => {
|
return create(prev, (draft) => {
|
||||||
if (!draft[fileId]) {
|
if (!draft[fileId]) {
|
||||||
|
@ -105,6 +118,11 @@ export const useLayoutConfig = ({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const onCollapseFileClick = useMemoizedFn(() => {
|
||||||
|
onSetSelectedFile(null);
|
||||||
|
closeSecondaryView();
|
||||||
|
});
|
||||||
|
|
||||||
const selectedLayout: ChatLayoutView = useMemo(() => {
|
const selectedLayout: ChatLayoutView = useMemo(() => {
|
||||||
if (chatId) {
|
if (chatId) {
|
||||||
if (selectedFileId) return 'both';
|
if (selectedFileId) return 'both';
|
||||||
|
@ -128,14 +146,26 @@ export const useLayoutConfig = ({
|
||||||
}
|
}
|
||||||
}, [isVersionHistoryMode, selectedFileId]);
|
}, [isVersionHistoryMode, selectedFileId]);
|
||||||
|
|
||||||
return {
|
return useMemo(
|
||||||
selectedLayout,
|
() => ({
|
||||||
selectedFileView,
|
selectedLayout,
|
||||||
selectedFileViewSecondary,
|
selectedFileView,
|
||||||
selectedFileViewRenderSecondary,
|
selectedFileViewSecondary,
|
||||||
onSetFileView,
|
selectedFileViewRenderSecondary,
|
||||||
closeSecondaryView
|
onSetFileView,
|
||||||
};
|
closeSecondaryView,
|
||||||
|
onCollapseFileClick
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
selectedLayout,
|
||||||
|
selectedFileView,
|
||||||
|
selectedFileViewSecondary,
|
||||||
|
selectedFileViewRenderSecondary,
|
||||||
|
onSetFileView,
|
||||||
|
closeSecondaryView,
|
||||||
|
onCollapseFileClick
|
||||||
|
]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_FILE_VIEW: Record<FileType, FileView> = {
|
const DEFAULT_FILE_VIEW: Record<FileType, FileView> = {
|
||||||
|
|
|
@ -44,16 +44,11 @@ export const useSelectedFile = ({
|
||||||
animateOpenSplitter('both');
|
animateOpenSplitter('both');
|
||||||
});
|
});
|
||||||
|
|
||||||
const onCollapseFileClick = useMemoizedFn((close?: boolean) => {
|
|
||||||
onSetSelectedFile(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
isVersionHistoryMode,
|
isVersionHistoryMode,
|
||||||
onSetSelectedFile,
|
onSetSelectedFile,
|
||||||
selectedFile,
|
selectedFile
|
||||||
onCollapseFileClick
|
|
||||||
}),
|
}),
|
||||||
[onSetSelectedFile, isVersionHistoryMode, selectedFile]
|
[onSetSelectedFile, isVersionHistoryMode, selectedFile]
|
||||||
);
|
);
|
||||||
|
|
|
@ -78,7 +78,7 @@ export const FileContainer: React.FC<FileContainerProps> = ({ children }) => {
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
animateOpenSplitter(isOpenSecondary ? 'open' : 'closed');
|
animateOpenSplitter(isOpenSecondary ? 'open' : 'closed');
|
||||||
}, 25);
|
}, 20);
|
||||||
}, [isOpenSecondary]);
|
}, [isOpenSecondary]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,18 +2,14 @@ import { DoubleChevronRight } from '@/components/ui/icons';
|
||||||
import { Button } from '@/components/ui/buttons';
|
import { Button } from '@/components/ui/buttons';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { useMemoizedFn } from '@/hooks';
|
import { AppTooltip } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
export const CollapseFileButton: React.FC<{
|
export const CollapseFileButton: React.FC<{
|
||||||
showCollapseButton: boolean;
|
showCollapseButton: boolean;
|
||||||
onCollapseFileClick: (value?: boolean) => void;
|
onCollapseFileClick: () => void;
|
||||||
}> = React.memo(({ showCollapseButton, onCollapseFileClick }) => {
|
}> = React.memo(({ showCollapseButton, onCollapseFileClick }) => {
|
||||||
const icon = <DoubleChevronRight />;
|
const icon = <DoubleChevronRight />;
|
||||||
|
|
||||||
const onClick = useMemoizedFn(() => {
|
|
||||||
onCollapseFileClick();
|
|
||||||
});
|
|
||||||
|
|
||||||
const animation = useMemo(() => {
|
const animation = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
initial: { opacity: 0 },
|
initial: { opacity: 0 },
|
||||||
|
@ -26,7 +22,9 @@ export const CollapseFileButton: React.FC<{
|
||||||
<AnimatePresence mode="wait" initial={false}>
|
<AnimatePresence mode="wait" initial={false}>
|
||||||
{showCollapseButton && (
|
{showCollapseButton && (
|
||||||
<motion.div variants={animation}>
|
<motion.div variants={animation}>
|
||||||
<Button onClick={onClick} variant="ghost" prefix={icon}></Button>
|
<AppTooltip title="Collapse file" delayDuration={350}>
|
||||||
|
<Button onClick={onCollapseFileClick} variant="ghost" prefix={icon}></Button>
|
||||||
|
</AppTooltip>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
|
@ -7,10 +7,9 @@ import { useMemoizedFn } from '@/hooks';
|
||||||
import { AppTooltip } from '@/components/ui/tooltip';
|
import { AppTooltip } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
export const CreateChatButton = React.memo(() => {
|
export const CreateChatButton = React.memo(() => {
|
||||||
const onCollapseFileClick = useChatLayoutContextSelector((x) => x.onCollapseFileClick);
|
|
||||||
|
|
||||||
const onCollapseFileClickPreflight = useMemoizedFn(() => {
|
const onCollapseFileClickPreflight = useMemoizedFn(() => {
|
||||||
onCollapseFileClick(false);
|
// onCollapseFileClick(false);
|
||||||
|
alert('TODO');
|
||||||
});
|
});
|
||||||
|
|
||||||
useHotkeys('e', onCollapseFileClickPreflight, { preventDefault: true });
|
useHotkeys('e', onCollapseFileClickPreflight, { preventDefault: true });
|
||||||
|
|
Loading…
Reference in New Issue