mirror of https://github.com/buster-so/buster.git
Merge pull request #511 from buster-so/big-nate/bus-1374-remove-dashboard-cache-if-a-metric-version-is-updated
Big nate/bus 1374 remove dashboard cache if a metric version is updated
This commit is contained in:
commit
b42242e6e8
|
@ -6,6 +6,12 @@ import { updateMessageShapeToIChatMessage } from './helpers';
|
||||||
import { useMemoizedFn } from '@/hooks';
|
import { useMemoizedFn } from '@/hooks';
|
||||||
import { prefetchGetListChats, useGetChatMemoized } from '@/api/buster_rest/chats';
|
import { prefetchGetListChats, useGetChatMemoized } from '@/api/buster_rest/chats';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
|
import type { ChatMessageResponseMessage_File } from '@buster/server-shared/chats';
|
||||||
|
import type { BusterChatMessage } from '../../asset_interfaces/chat';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { dashboardQueryKeys } from '../../query_keys/dashboard';
|
||||||
|
import last from 'lodash/last';
|
||||||
|
import isEmpty from 'lodash/isEmpty';
|
||||||
|
|
||||||
export const useGetMessage = ({ chatId, messageId }: { chatId: string; messageId: string }) => {
|
export const useGetMessage = ({ chatId, messageId }: { chatId: string; messageId: string }) => {
|
||||||
const shape = useMemo(() => messageShape({ chatId, messageId }), [chatId, messageId]);
|
const shape = useMemo(() => messageShape({ chatId, messageId }), [chatId, messageId]);
|
||||||
|
@ -32,6 +38,7 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
callback?: (message: ReturnType<typeof updateMessageShapeToIChatMessage>) => void
|
callback?: (message: ReturnType<typeof updateMessageShapeToIChatMessage>) => void
|
||||||
) => {
|
) => {
|
||||||
const { onUpdateChatMessage, onUpdateChat } = useChatUpdate();
|
const { onUpdateChatMessage, onUpdateChat } = useChatUpdate();
|
||||||
|
const checkIfWeHaveAFollowupDashboard = useCheckIfWeHaveAFollowupDashboard();
|
||||||
const getChatMemoized = useGetChatMemoized();
|
const getChatMemoized = useGetChatMemoized();
|
||||||
|
|
||||||
const subscribe = !!chatId && !!messageId && messageId !== 'undefined';
|
const subscribe = !!chatId && !!messageId && messageId !== 'undefined';
|
||||||
|
@ -60,6 +67,22 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check if we have a files in the message
|
||||||
|
const hasFiles = iChatMessage.reasoning_message_ids?.some((id) => {
|
||||||
|
const reasoningMessage = iChatMessage.response_messages?.[id];
|
||||||
|
return (
|
||||||
|
reasoningMessage &&
|
||||||
|
(reasoningMessage as ChatMessageResponseMessage_File)?.file_type === 'dashboard'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
if (hasFiles) {
|
||||||
|
prefetchGetListChats();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty(iChatMessage.reasoning_message_ids)) {
|
||||||
|
checkIfWeHaveAFollowupDashboard(iChatMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if (iChatMessage.is_completed) {
|
if (iChatMessage.is_completed) {
|
||||||
prefetchGetListChats();
|
prefetchGetListChats();
|
||||||
}
|
}
|
||||||
|
@ -71,3 +94,27 @@ export const useTrackAndUpdateMessageChanges = (
|
||||||
subscribe
|
subscribe
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useCheckIfWeHaveAFollowupDashboard = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const method = (message: Partial<BusterChatMessage>) => {
|
||||||
|
const lastResponseMessageId = last(message.response_message_ids || []) || '';
|
||||||
|
const lastResponseMessage = message.response_messages?.[lastResponseMessageId] as
|
||||||
|
| ChatMessageResponseMessage_File
|
||||||
|
| undefined;
|
||||||
|
const hasDashboardInMessage =
|
||||||
|
lastResponseMessage && lastResponseMessage?.file_type === 'dashboard';
|
||||||
|
|
||||||
|
if (hasDashboardInMessage) {
|
||||||
|
const fileId = lastResponseMessage?.id;
|
||||||
|
const versionNumber = lastResponseMessage?.version_number;
|
||||||
|
const { queryKey } = dashboardQueryKeys.dashboardGetDashboard(fileId, versionNumber);
|
||||||
|
const isFoundInCache = queryClient.getQueryData(queryKey);
|
||||||
|
if (isFoundInCache) {
|
||||||
|
queryClient.invalidateQueries({ queryKey });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return useMemoizedFn(method);
|
||||||
|
};
|
||||||
|
|
|
@ -87,6 +87,10 @@ export const usePrefetchGetDashboardClient = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const queryFn = useGetDashboardAndInitializeMetrics(false);
|
const queryFn = useGetDashboardAndInitializeMetrics(false);
|
||||||
return useMemoizedFn((id: string, versionNumber: number) => {
|
return useMemoizedFn((id: string, versionNumber: number) => {
|
||||||
|
const getDashboardQueryKey = dashboardQueryKeys.dashboardGetDashboard(id, versionNumber);
|
||||||
|
const isStale = isQueryStale(getDashboardQueryKey, queryClient);
|
||||||
|
if (!isStale) return queryClient;
|
||||||
|
|
||||||
return queryClient.prefetchQuery({
|
return queryClient.prefetchQuery({
|
||||||
...dashboardQueryKeys.dashboardGetDashboard(id, versionNumber),
|
...dashboardQueryKeys.dashboardGetDashboard(id, versionNumber),
|
||||||
queryFn: () => queryFn(id, versionNumber)
|
queryFn: () => queryFn(id, versionNumber)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { DataResult } from '@buster/server-shared/metrics';
|
||||||
import { AppSplitter, type AppSplitterRef } from '@/components/ui/layouts/AppSplitter';
|
import { AppSplitter, type AppSplitterRef } from '@/components/ui/layouts/AppSplitter';
|
||||||
import { DataContainer } from './DataContainer';
|
import { DataContainer } from './DataContainer';
|
||||||
import { SQLContainer } from './SQLContainer';
|
import { SQLContainer } from './SQLContainer';
|
||||||
|
import { useMemoizedFn } from '../../../../hooks';
|
||||||
|
|
||||||
export interface AppVerticalCodeSplitterProps {
|
export interface AppVerticalCodeSplitterProps {
|
||||||
sql: string;
|
sql: string;
|
||||||
|
@ -45,6 +46,12 @@ export const AppVerticalCodeSplitter = forwardRef<AppSplitterRef, AppVerticalCod
|
||||||
const sqlContainerClassName = !topHidden ? `pb-${gapAmount}` : '';
|
const sqlContainerClassName = !topHidden ? `pb-${gapAmount}` : '';
|
||||||
const dataContainerClassName = !topHidden ? `pt-${gapAmount}` : '';
|
const dataContainerClassName = !topHidden ? `pt-${gapAmount}` : '';
|
||||||
|
|
||||||
|
const bustStorageOnInit = useMemoizedFn(
|
||||||
|
(preservedSideValue: number | null, refWidth: number) => {
|
||||||
|
return !preservedSideValue || preservedSideValue < 80 || refWidth < 120;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppSplitter
|
<AppSplitter
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
@ -78,6 +85,7 @@ export const AppVerticalCodeSplitter = forwardRef<AppSplitterRef, AppVerticalCod
|
||||||
leftPanelMinSize={'120px'}
|
leftPanelMinSize={'120px'}
|
||||||
leftHidden={topHidden}
|
leftHidden={topHidden}
|
||||||
className={className}
|
className={className}
|
||||||
|
bustStorageOnInit={bustStorageOnInit}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,6 @@ export const ChatResponseMessage_DashboardFile: React.FC<{
|
||||||
return <TextAndVersionText text={file_name} version={version_number} />;
|
return <TextAndVersionText text={file_name} version={version_number} />;
|
||||||
}, [file_name, version_number, metricId]);
|
}, [file_name, version_number, metricId]);
|
||||||
|
|
||||||
useMount(() => {
|
|
||||||
if (isSelectedFile) prefetchGetDashboard(id, version_number);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence initial={!isCompletedStream}>
|
<AnimatePresence initial={!isCompletedStream}>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import findLast from 'lodash/findLast';
|
|
||||||
import { useEffect, useLayoutEffect, useRef } from 'react';
|
import { useEffect, useLayoutEffect, useRef } from 'react';
|
||||||
import type { BusterChatResponseMessage_file } from '@/api/asset_interfaces/chat';
|
import type { BusterChatResponseMessage_file } from '@/api/asset_interfaces/chat';
|
||||||
import { useGetChat, useGetChatMessage, useGetChatMessageMemoized } from '@/api/buster_rest/chats';
|
import { useGetChat, useGetChatMessage, useGetChatMessageMemoized } from '@/api/buster_rest/chats';
|
||||||
|
|
|
@ -8,6 +8,7 @@ export const isQueryStale = (
|
||||||
queryClient: QueryClient
|
queryClient: QueryClient
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const queryState = queryClient.getQueryState(options.queryKey);
|
const queryState = queryClient.getQueryState(options.queryKey);
|
||||||
|
|
||||||
const updatedAt = queryState?.dataUpdatedAt;
|
const updatedAt = queryState?.dataUpdatedAt;
|
||||||
const staleTime =
|
const staleTime =
|
||||||
(options.staleTime as number) ||
|
(options.staleTime as number) ||
|
||||||
|
@ -15,7 +16,7 @@ export const isQueryStale = (
|
||||||
0;
|
0;
|
||||||
const isStale = updatedAt ? Date.now() - updatedAt > staleTime : true;
|
const isStale = updatedAt ? Date.now() - updatedAt > staleTime : true;
|
||||||
|
|
||||||
return isStale;
|
return isStale && queryState?.fetchStatus !== 'fetching';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hasOrganizationId = (queryClient: QueryClient): boolean => {
|
export const hasOrganizationId = (queryClient: QueryClient): boolean => {
|
||||||
|
|
Loading…
Reference in New Issue