expand logic for auto change layout

This commit is contained in:
Nate Kelley 2025-04-14 14:03:51 -06:00
parent 0b6707bed3
commit 35f7a7c49d
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
5 changed files with 134 additions and 20 deletions

View File

@ -4,7 +4,6 @@ import React from 'react';
import { ShareAssetType, ShareRole } from '@/api/asset_interfaces'; import { ShareAssetType, ShareRole } from '@/api/asset_interfaces';
import { Text } from '@/components/ui/typography'; import { Text } from '@/components/ui/typography';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { R } from 'node_modules/@tanstack/react-query-devtools/build/modern/ReactQueryDevtools-Cn7cKi7o';
export const IndividualSharePerson: React.FC<{ export const IndividualSharePerson: React.FC<{
name?: string; name?: string;
@ -20,8 +19,6 @@ export const IndividualSharePerson: React.FC<{
onUpdateShareRole(email, v); onUpdateShareRole(email, v);
}); });
console.log(role, assetType);
return ( return (
<div className="flex h-8 items-center justify-between space-x-2 overflow-hidden"> <div className="flex h-8 items-center justify-between space-x-2 overflow-hidden">
<div className="flex h-full items-center space-x-1.5 overflow-hidden"> <div className="flex h-full items-center space-x-1.5 overflow-hidden">

View File

@ -8,6 +8,7 @@ export const useGetFileLink = () => {
const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber); const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber);
const metricId = useChatLayoutContextSelector((x) => x.metricId); const metricId = useChatLayoutContextSelector((x) => x.metricId);
const dashboardId = useChatLayoutContextSelector((x) => x.dashboardId); const dashboardId = useChatLayoutContextSelector((x) => x.dashboardId);
const messageId = useChatLayoutContextSelector((x) => x.messageId);
const getFileLink = useMemoizedFn( const getFileLink = useMemoizedFn(
({ ({
@ -114,12 +115,18 @@ export const useGetFileLink = () => {
versionNumber?: number; versionNumber?: number;
fileType: FileType; fileType: FileType;
fileId: string; fileId: string;
}) => { }): boolean => {
if (fileType === 'metric') { if (fileType === 'metric') {
return versionNumber === metricVersionNumber && fileId === metricId; return versionNumber === metricVersionNumber && fileId === metricId;
} else if (fileType === 'dashboard') { } else if (fileType === 'dashboard') {
return versionNumber === dashboardVersionNumber && fileId === dashboardId; return versionNumber === dashboardVersionNumber && fileId === dashboardId;
} }
if (fileType === 'reasoning') {
return fileId === messageId;
}
return false;
} }
); );
@ -136,7 +143,11 @@ export const useGetFileLink = () => {
chatId?: string; chatId?: string;
versionNumber?: number; versionNumber?: number;
useVersionHistoryMode?: boolean; useVersionHistoryMode?: boolean;
}) => { }): {
link: string | undefined;
isSelected: boolean;
selectedVersionNumber: number | undefined;
} => {
const link = getFileLink({ fileId, fileType, chatId, versionNumber, useVersionHistoryMode }); const link = getFileLink({ fileId, fileType, chatId, versionNumber, useVersionHistoryMode });
const isSelected = getFileIsSelected({ versionNumber, fileType, fileId }); const isSelected = getFileIsSelected({ versionNumber, fileType, fileId });

View File

@ -50,7 +50,6 @@ const useChatIndividualContext = ({
useAutoChangeLayout({ useAutoChangeLayout({
lastMessageId: currentMessageId, lastMessageId: currentMessageId,
onSetSelectedFile,
selectedFileId, selectedFileId,
chatId chatId
}); });

View File

@ -2,26 +2,33 @@
import { useGetChatMessageMemoized, useGetChatMessage } from '@/api/buster_rest/chats'; import { useGetChatMessageMemoized, useGetChatMessage } from '@/api/buster_rest/chats';
import type { SelectedFile } from '../interfaces'; import type { SelectedFile } from '../interfaces';
import { useEffect, useRef } from 'react'; import { MutableRefObject, useEffect, useRef } from 'react';
import findLast from 'lodash/findLast'; import findLast from 'lodash/findLast';
import { BusterChatResponseMessage_file } from '@/api/asset_interfaces/chat'; import { BusterChatResponseMessage_file } from '@/api/asset_interfaces/chat';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { useGetFileLink } from '@/context/Assets/useGetFileLink'; import { useGetFileLink } from '@/context/Assets/useGetFileLink';
import { useChatLayoutContextSelector } from '../ChatLayoutContext'; import { useChatLayoutContextSelector } from '../ChatLayoutContext';
import { usePrevious } from '@/hooks'; import { useMemoizedFn, usePrevious } from '@/hooks';
import { BusterRoutes, createBusterRoute } from '@/routes';
export const useAutoChangeLayout = ({ export const useAutoChangeLayout = ({
lastMessageId, lastMessageId,
onSetSelectedFile,
selectedFileId, selectedFileId,
chatId chatId
}: { }: {
lastMessageId: string; lastMessageId: string;
onSetSelectedFile: (file: SelectedFile) => void;
selectedFileId: string | undefined; selectedFileId: string | undefined;
chatId: string | undefined; chatId: string | undefined;
}) => { }) => {
const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile);
const messageId = useChatLayoutContextSelector((x) => x.messageId);
const metricId = useChatLayoutContextSelector((x) => x.metricId);
const dashboardId = useChatLayoutContextSelector((x) => x.dashboardId);
const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber);
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
const isVersionHistoryMode = useChatLayoutContextSelector((x) => x.isVersionHistoryMode); const isVersionHistoryMode = useChatLayoutContextSelector((x) => x.isVersionHistoryMode);
const isCompletedStream = useGetChatMessage(lastMessageId, (x) => x?.isCompletedStream);
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage); const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
const previousLastMessageId = useRef<string | null>(null); const previousLastMessageId = useRef<string | null>(null);
const reasoningMessagesLength = useGetChatMessage( const reasoningMessagesLength = useGetChatMessage(
@ -31,26 +38,24 @@ export const useAutoChangeLayout = ({
const getChatMessageMemoized = useGetChatMessageMemoized(); const getChatMessageMemoized = useGetChatMessageMemoized();
const { getFileLinkMeta } = useGetFileLink(); const { getFileLinkMeta } = useGetFileLink();
const isCompletedStream = useGetChatMessage(lastMessageId, (x) => x?.isCompletedStream);
const previousIsCompletedStream = usePrevious(isCompletedStream); const previousIsCompletedStream = usePrevious(isCompletedStream);
const hasReasoning = !!reasoningMessagesLength; const hasReasoning = !!reasoningMessagesLength;
//change the page to reasoning file if we get a reasoning message
//change the page to the file if we get a file
useEffect(() => { useEffect(() => {
//this will trigger when the chat is streaming and is has not completed yet (new chat)
if ( if (
!isCompletedStream && !isCompletedStream &&
hasReasoning && hasReasoning &&
previousLastMessageId.current !== lastMessageId && previousLastMessageId.current !== lastMessageId &&
chatId chatId
) { ) {
onSetSelectedFile({ id: lastMessageId, type: 'reasoning' }); handle_isStreaming({ previousLastMessageId, onSetSelectedFile, lastMessageId });
previousLastMessageId.current = lastMessageId;
} }
//we check for false because on initial load, the isCompletedStream is false //this will when the chat is completed and it WAS streaming
if (isCompletedStream && previousIsCompletedStream === false) { else if (isCompletedStream && previousIsCompletedStream === false) {
//
const chatMessage = getChatMessageMemoized(lastMessageId); const chatMessage = getChatMessageMemoized(lastMessageId);
const lastFileId = findLast(chatMessage?.response_message_ids, (id) => { const lastFileId = findLast(chatMessage?.response_message_ids, (id) => {
const responseMessage = chatMessage?.response_messages[id]; const responseMessage = chatMessage?.response_messages[id];
@ -60,6 +65,7 @@ export const useAutoChangeLayout = ({
| BusterChatResponseMessage_file | BusterChatResponseMessage_file
| undefined; | undefined;
//this will trigger when the chat was streaming (new chat)
if (lastFileId && lastFile) { if (lastFileId && lastFile) {
const { link, isSelected, selectedVersionNumber } = getFileLinkMeta({ const { link, isSelected, selectedVersionNumber } = getFileLinkMeta({
fileId: lastFileId, fileId: lastFileId,
@ -76,14 +82,115 @@ export const useAutoChangeLayout = ({
) { ) {
onSetSelectedFile({ onSetSelectedFile({
id: lastFileId, id: lastFileId,
type: lastFile.file_type type: lastFile.file_type,
versionNumber: selectedVersionNumber
}); });
} }
if (link && !selectedVersionNumber && !isVersionHistoryMode) { if (link) {
onChangePage(link); onChangePage(link);
} }
return;
}
}
//this will trigger on a page refresh and the chat is completed
else if (isCompletedStream && chatId) {
const isChatOnlyMode = !metricId && !dashboardId && !messageId;
if (isChatOnlyMode) {
return;
}
const chatMessage = getChatMessageMemoized(lastMessageId);
//reasoning_message_mode
if (messageId) {
const messageExists = !!chatMessage?.reasoning_message_ids.find((id) => id === messageId);
if (messageExists) {
return;
} else {
onChangePage(
createBusterRoute({
route: BusterRoutes.APP_CHAT_ID,
chatId
})
);
}
}
//dashboard_mode
if (dashboardId) {
if (!dashboardVersionNumber) {
const lastMatchingDashboardInChat = chatMessage?.response_message_ids.reduce<
BusterChatResponseMessage_file | undefined
>((acc, messageId) => {
const message = chatMessage?.response_messages[messageId]!;
const isFile =
message.type === 'file' &&
message.file_type === 'dashboard' &&
message.id === dashboardId;
if (isFile) {
return message;
}
return acc;
}, undefined);
if (lastMatchingDashboardInChat) {
onChangePage(
createBusterRoute({
route: BusterRoutes.APP_CHAT_ID_DASHBOARD_ID_VERSION_NUMBER,
dashboardId: lastMatchingDashboardInChat.id,
versionNumber: lastMatchingDashboardInChat.version_number,
chatId
})
);
}
} else {
return;
}
}
//metric_mode
if (metricId) {
if (!metricVersionNumber) {
const lastMatchingMetricInChat = chatMessage?.response_message_ids.reduce<
BusterChatResponseMessage_file | undefined
>((acc, messageId) => {
const message = chatMessage?.response_messages[messageId]!;
const isFile =
message.type === 'file' && message.file_type === 'metric' && message.id === metricId;
if (isFile) {
return message;
}
return acc;
}, undefined);
if (lastMatchingMetricInChat) {
onChangePage(
createBusterRoute({
route: BusterRoutes.APP_CHAT_ID_METRIC_ID_VERSION_NUMBER,
metricId,
versionNumber: lastMatchingMetricInChat.version_number,
chatId
})
);
}
} else {
return;
}
} }
} }
}, [isCompletedStream, hasReasoning, lastMessageId]); }, [isCompletedStream, hasReasoning, lastMessageId]);
}; };
const handle_isStreaming = ({
previousLastMessageId,
onSetSelectedFile,
lastMessageId
}: {
previousLastMessageId: MutableRefObject<string | null>;
onSetSelectedFile: (file: SelectedFile) => void;
lastMessageId: string;
}) => {
previousLastMessageId.current = lastMessageId;
onSetSelectedFile({ id: lastMessageId, type: 'reasoning', versionNumber: undefined });
};

View File

@ -3,7 +3,7 @@ import type { FileType } from '@/api/asset_interfaces';
export type SelectedFile = { export type SelectedFile = {
id: string; id: string;
type: FileType; type: FileType;
versionNumber?: number; versionNumber: number | undefined; // will be undefined for reasoning files
}; };
export type ChatLayoutView = 'chat' | 'file' | 'both'; export type ChatLayoutView = 'chat' | 'file' | 'both';