mirror of https://github.com/buster-so/buster.git
change auto layout ocnif
This commit is contained in:
parent
9f914a34f9
commit
18549b442f
|
@ -2,5 +2,5 @@ export const itemAnimationConfig = {
|
|||
initial: { opacity: 0 },
|
||||
animate: { opacity: 1 },
|
||||
exit: { opacity: 0 },
|
||||
transition: { duration: 0.675 }
|
||||
transition: { duration: 0.725 }
|
||||
};
|
||||
|
|
|
@ -34,7 +34,6 @@ export const ReasoningMessageContainer: React.FC<{
|
|||
isLastMessageItem={index === lastMessageIndex}
|
||||
chatId={chatId}
|
||||
/>
|
||||
<VerticalDivider />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -71,6 +70,12 @@ const useStyles = createStyles(({ token, css }) => ({
|
|||
&:has(+ .file-card) {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
&:has(+ .thought-card) {
|
||||
.vertical-divider {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`,
|
||||
fileCard: css`
|
||||
margin-bottom: 4px;
|
||||
|
|
|
@ -15,7 +15,7 @@ export const ReasoningMessage_Thought: React.FC<ReasoningMessageProps> = React.m
|
|||
|
||||
return (
|
||||
<BarContainer
|
||||
showBar={hasThoughts}
|
||||
showBar={hasThoughts || !isLastMessageItem}
|
||||
status={loadingStatus}
|
||||
isCompletedStream={isCompletedStream}
|
||||
title={thought_title}
|
||||
|
|
|
@ -40,7 +40,10 @@ export const useChatIndividualContext = ({
|
|||
(x) => !x.chatsMessages[currentMessageId]?.isCompletedStream
|
||||
);
|
||||
|
||||
useAutoChangeLayout({ lastMessageId: currentMessageId, onSetSelectedFile });
|
||||
useAutoChangeLayout({
|
||||
lastMessageId: currentMessageId,
|
||||
onSetSelectedFile
|
||||
});
|
||||
|
||||
return {
|
||||
hasChat,
|
||||
|
|
|
@ -5,6 +5,7 @@ import { useEffect } from 'react';
|
|||
|
||||
export const useAutoChangeLayout = ({
|
||||
lastMessageId,
|
||||
|
||||
onSetSelectedFile
|
||||
}: {
|
||||
lastMessageId: string;
|
||||
|
@ -18,6 +19,7 @@ export const useAutoChangeLayout = ({
|
|||
const hasReasoning = !!reasoningMessagesLength;
|
||||
const previousIsEmpty = previousReasoningMessagesLength === 0;
|
||||
|
||||
//change the page to reasoning file if we get a reasoning message
|
||||
useEffect(() => {
|
||||
if (isLoading && previousIsEmpty && hasReasoning) {
|
||||
onSetSelectedFile({ id: lastMessageId, type: 'reasoning' });
|
||||
|
|
|
@ -11,7 +11,7 @@ import type { AppSplitterRef } from '@/components/layout';
|
|||
import { createChatAssetRoute, createFileRoute } from './helpers';
|
||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||
import { DEFAULT_CHAT_OPTION } from './config';
|
||||
import { useAutoSetLayout } from '../hooks';
|
||||
import { useInitialChatLayout } from '../hooks';
|
||||
import { useChatFileLayout } from './useChatFileLayout';
|
||||
|
||||
interface UseChatSplitterProps {
|
||||
|
@ -32,12 +32,13 @@ export const useChatLayout = ({
|
|||
|
||||
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
||||
if (appSplitterRef.current) {
|
||||
const { animateWidth, isSideClosed } = appSplitterRef.current;
|
||||
const { animateWidth } = appSplitterRef.current;
|
||||
if (side === 'left') {
|
||||
animateWidth('100%', 'left');
|
||||
} else if (side === 'right') {
|
||||
animateWidth('100%', 'right');
|
||||
} else if (side === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
|
||||
} else if (side === 'both') {
|
||||
//&& (isSideClosed('right') || isSideClosed('left'))
|
||||
animateWidth(DEFAULT_CHAT_OPTION, 'left');
|
||||
setIsPureChat(false);
|
||||
setIsPureFile(false);
|
||||
|
@ -69,7 +70,9 @@ export const useChatLayout = ({
|
|||
|
||||
setIsCollapseOpen(!isCloseAction);
|
||||
|
||||
if (isFileLayout) {
|
||||
if (defaultSelectedFile && defaultSelectedFile.type === 'reasoning') {
|
||||
animateOpenSplitter(!isCloseAction ? 'both' : 'left');
|
||||
} else if (isFileLayout) {
|
||||
// For file layout, toggle between 'both' and 'right'
|
||||
animateOpenSplitter(!isCloseAction && defaultSelectedFile ? 'both' : 'right');
|
||||
} else {
|
||||
|
@ -86,8 +89,11 @@ export const useChatLayout = ({
|
|||
setIsPureFile,
|
||||
collapseDirection,
|
||||
isCollapseOpen
|
||||
} = useAutoSetLayout({
|
||||
defaultSelectedLayout
|
||||
} = useInitialChatLayout({
|
||||
defaultSelectedLayout,
|
||||
defaultSelectedFile,
|
||||
chatId,
|
||||
onCollapseFileClick
|
||||
});
|
||||
|
||||
const fileLayoutContext = useChatFileLayout({
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export * from './useDefaultFile';
|
||||
export * from './useAutoSetLayout';
|
||||
export * from './useInitialChatLayout';
|
||||
export * from './useDefaultSplitterLayout';
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import { useUpdateLayoutEffect } from 'ahooks';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
export const useAutoSetLayout = ({
|
||||
defaultSelectedLayout
|
||||
}: {
|
||||
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
|
||||
}) => {
|
||||
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
||||
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
|
||||
const [isCollapseOpen, setIsCollapseOpen] = useState(isPureChat ? true : false);
|
||||
|
||||
useUpdateLayoutEffect(() => {
|
||||
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
|
||||
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
|
||||
}, [defaultSelectedLayout]);
|
||||
|
||||
const collapseDirection: 'left' | 'right' = useMemo(() => {
|
||||
return defaultSelectedLayout === 'file' ? 'left' : 'right';
|
||||
}, [defaultSelectedLayout]);
|
||||
|
||||
return {
|
||||
isPureFile,
|
||||
isPureChat,
|
||||
setIsPureChat,
|
||||
setIsPureFile,
|
||||
collapseDirection,
|
||||
setIsCollapseOpen,
|
||||
isCollapseOpen
|
||||
};
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
import { useMemoizedFn, useUpdateEffect, useUpdateLayoutEffect } from 'ahooks';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { ChatSplitterProps } from '../ChatLayout';
|
||||
import { useBusterChatContextSelector } from '@/context/Chats';
|
||||
|
||||
export const useInitialChatLayout = ({
|
||||
defaultSelectedLayout,
|
||||
defaultSelectedFile,
|
||||
chatId,
|
||||
onCollapseFileClick
|
||||
}: {
|
||||
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
|
||||
chatId: string | undefined;
|
||||
defaultSelectedFile: ChatSplitterProps['defaultSelectedFile'];
|
||||
onCollapseFileClick: (close?: boolean) => void;
|
||||
}) => {
|
||||
const getChatMemoized = useBusterChatContextSelector((x) => x.getChatMemoized);
|
||||
const isReasoningFile = defaultSelectedFile?.type === 'reasoning';
|
||||
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
||||
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
|
||||
const [isCollapseOpen, setIsCollapseOpen] = useState(
|
||||
isPureChat || isReasoningFile ? true : false
|
||||
);
|
||||
|
||||
const collapseDirection: 'left' | 'right' = useMemo(() => {
|
||||
if (defaultSelectedFile?.type === 'reasoning') return 'right';
|
||||
|
||||
return defaultSelectedLayout === 'file' ? 'left' : 'right';
|
||||
}, [defaultSelectedLayout, defaultSelectedFile?.type]);
|
||||
|
||||
const resetChatForNewChat = useMemoizedFn(() => {
|
||||
onCollapseFileClick(true);
|
||||
setIsPureChat(true);
|
||||
});
|
||||
|
||||
useUpdateLayoutEffect(() => {
|
||||
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
|
||||
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
|
||||
}, [defaultSelectedLayout]);
|
||||
|
||||
useUpdateEffect(() => {
|
||||
if (chatId && getChatMemoized(chatId)?.isNewChat) {
|
||||
resetChatForNewChat();
|
||||
}
|
||||
}, [chatId]);
|
||||
|
||||
return {
|
||||
isPureFile,
|
||||
isPureChat,
|
||||
setIsPureChat,
|
||||
setIsPureFile,
|
||||
collapseDirection,
|
||||
setIsCollapseOpen,
|
||||
isCollapseOpen
|
||||
};
|
||||
};
|
|
@ -17,7 +17,7 @@ export const useBusterNewChat = () => {
|
|||
startListeningForChatProgress,
|
||||
stopListeningForChatProgress,
|
||||
stopChatCallback,
|
||||
initializeChatCallback,
|
||||
initializeNewChatCallback,
|
||||
replaceMessageCallback
|
||||
} = useChatUpdateMessage();
|
||||
|
||||
|
@ -52,7 +52,7 @@ export const useBusterNewChat = () => {
|
|||
},
|
||||
responseEvent: {
|
||||
route: '/chats/post:initializeChat',
|
||||
callback: initializeChatCallback
|
||||
callback: initializeNewChatCallback
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -68,10 +68,20 @@ export const useBusterNewChat = () => {
|
|||
);
|
||||
|
||||
const onStartChatFromFile = useMemoizedFn(
|
||||
async ({}: { prompt: string; fileId: string; fileType: FileType }) => {
|
||||
console.log('start chat from file');
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
async ({
|
||||
prompt,
|
||||
fileId,
|
||||
fileType
|
||||
}: {
|
||||
prompt: string;
|
||||
fileId: string;
|
||||
fileType: FileType;
|
||||
}) => {
|
||||
onStartNewChat({
|
||||
prompt,
|
||||
metricId: fileType === 'metric' ? fileId : undefined,
|
||||
dashboardId: fileType === 'dashboard' ? fileId : undefined
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import { updateChatToIChat } from '@/utils/chat';
|
|||
import { useAutoAppendThought } from './useAutoAppendThought';
|
||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||
import { BusterRoutes } from '@/routes';
|
||||
import last from 'lodash/last';
|
||||
|
||||
export const useChatUpdateMessage = () => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
|
@ -69,11 +68,14 @@ export const useChatUpdateMessage = () => {
|
|||
const _generatingReasoningMessageCallback = useMemoizedFn(
|
||||
(d: ChatEvent_GeneratingReasoningMessage) => {
|
||||
const { message_id, reasoning, chat_id } = d;
|
||||
const currentReasoning = getChatMessageMemoized(message_id)!.reasoning;
|
||||
const isNewMessage = !currentReasoning?.some(({ id }) => id === message_id);
|
||||
const currentReasoning = getChatMessageMemoized(message_id)?.reasoning ?? [];
|
||||
const reasoningMessageId = reasoning.id;
|
||||
const foundReasoningMessage = currentReasoning.find(({ id }) => id === reasoningMessageId);
|
||||
const isNewMessage = !foundReasoningMessage;
|
||||
|
||||
const updatedReasoning = isNewMessage
|
||||
? [...currentReasoning, reasoning]
|
||||
: currentReasoning.map((rm) => (rm.id === message_id ? reasoning : rm));
|
||||
: currentReasoning.map((rm) => (rm.id === reasoningMessageId ? reasoning : rm));
|
||||
|
||||
onUpdateChatMessage({
|
||||
id: message_id,
|
||||
|
@ -96,7 +98,7 @@ export const useChatUpdateMessage = () => {
|
|||
});
|
||||
});
|
||||
|
||||
const initializeChatCallback = useMemoizedFn((d: BusterChat) => {
|
||||
const initializeNewChatCallback = useMemoizedFn((d: BusterChat) => {
|
||||
const { iChat, iChatMessages } = updateChatToIChat(d, true);
|
||||
onBulkSetChatMessages(iChatMessages);
|
||||
onUpdateChat(iChat);
|
||||
|
@ -179,7 +181,7 @@ export const useChatUpdateMessage = () => {
|
|||
});
|
||||
|
||||
return {
|
||||
initializeChatCallback,
|
||||
initializeNewChatCallback,
|
||||
completeChatCallback,
|
||||
startListeningForChatProgress,
|
||||
stopListeningForChatProgress,
|
||||
|
|
|
@ -2,6 +2,7 @@ import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
|
|||
|
||||
export interface IBusterChat extends Omit<BusterChat, 'messages'> {
|
||||
messages: string[];
|
||||
isNewChat: boolean;
|
||||
}
|
||||
|
||||
export interface IBusterChatMessage extends BusterChatMessage {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import type { BusterChat, BusterChatMessage } from '@/api/asset_interfaces';
|
||||
import type { IBusterChat, IBusterChatMessage } from '@/context/Chats/interfaces';
|
||||
|
||||
const chatUpgrader = (chat: BusterChat): IBusterChat => {
|
||||
const chatUpgrader = (chat: BusterChat, { isNewChat }: { isNewChat: boolean }): IBusterChat => {
|
||||
return {
|
||||
...chat,
|
||||
messages: chat.messages.map((message) => message.id)
|
||||
messages: chat.messages.map((message) => message.id),
|
||||
isNewChat
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -36,7 +37,7 @@ const chatMessageUpgrader = (
|
|||
};
|
||||
|
||||
export const updateChatToIChat = (chat: BusterChat, isNewChat: boolean) => {
|
||||
const iChat = chatUpgrader(chat);
|
||||
const iChat = chatUpgrader(chat, { isNewChat });
|
||||
const iChatMessages = chatMessageUpgrader(chat.messages, {
|
||||
isCompletedStream: !isNewChat,
|
||||
messageId: chat.messages[0].id
|
||||
|
|
Loading…
Reference in New Issue