Merge pull request #515 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:
Nate Kelley 2025-07-14 16:04:49 -06:00 committed by GitHub
commit f257d77d9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 52 additions and 29 deletions

View File

@ -1,4 +1,4 @@
import { useMemo } from 'react';
import { useMemo, useRef } from 'react';
import { messageShape, messagesShape } from './shapes';
import { useShape, useShapeStream } from '../instances';
import { useChatUpdate } from '@/context/Chats/useChatUpdate';
@ -12,6 +12,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { dashboardQueryKeys } from '../../query_keys/dashboard';
import last from 'lodash/last';
import isEmpty from 'lodash/isEmpty';
import { metricsQueryKeys } from '../../query_keys/metric';
export const useGetMessage = ({ chatId, messageId }: { chatId: string; messageId: string }) => {
const shape = useMemo(() => messageShape({ chatId, messageId }), [chatId, messageId]);
@ -38,7 +39,7 @@ export const useTrackAndUpdateMessageChanges = (
callback?: (message: ReturnType<typeof updateMessageShapeToIChatMessage>) => void
) => {
const { onUpdateChatMessage, onUpdateChat } = useChatUpdate();
const checkIfWeHaveAFollowupDashboard = useCheckIfWeHaveAFollowupDashboard();
const checkIfWeHaveAFollowupDashboard = useCheckIfWeHaveAFollowupDashboard(messageId);
const getChatMemoized = useGetChatMemoized();
const subscribe = !!chatId && !!messageId && messageId !== 'undefined';
@ -79,7 +80,7 @@ export const useTrackAndUpdateMessageChanges = (
prefetchGetListChats();
}
if (!isEmpty(iChatMessage.reasoning_message_ids)) {
if (!isEmpty(iChatMessage.response_message_ids)) {
checkIfWeHaveAFollowupDashboard(iChatMessage);
}
@ -95,23 +96,33 @@ export const useTrackAndUpdateMessageChanges = (
);
};
const useCheckIfWeHaveAFollowupDashboard = () => {
const useCheckIfWeHaveAFollowupDashboard = (messageId: string) => {
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';
const hasSeenFileByMessageId = useRef<Record<string, boolean>>({});
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 });
const method = (message: Partial<BusterChatMessage>) => {
if (!hasSeenFileByMessageId.current[messageId]) {
const allFiles = Object.values(message.response_messages || {}).filter(
(x) => (x as ChatMessageResponseMessage_File).file_type === 'dashboard'
) as ChatMessageResponseMessage_File[];
if (allFiles.length > 0) {
hasSeenFileByMessageId.current[messageId] = true;
for (const file of allFiles) {
const fileType = (file as ChatMessageResponseMessage_File).file_type;
if (fileType === 'dashboard') {
const { queryKey } = dashboardQueryKeys.dashboardGetDashboard(
file.id,
file.version_number
);
queryClient.invalidateQueries({ queryKey });
} else if (fileType === 'metric') {
const { queryKey } = metricsQueryKeys.metricsGetMetric(file.id, file.version_number);
queryClient.invalidateQueries({ queryKey });
} else {
const _exhaustiveCheck: 'reasoning' = fileType;
}
}
}
}
};

View File

@ -1,7 +1,6 @@
import { useQueryClient } from '@tanstack/react-query';
import last from 'lodash/last';
import type { BusterDashboardResponse } from '@/api/asset_interfaces/dashboard';
import { queryKeys } from '@/api/query_keys';
import { dashboardQueryKeys } from '@/api/query_keys/dashboard';
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
import { useBusterNotifications } from '@/context/BusterNotifications';
@ -14,6 +13,7 @@ import {
useGetLatestDashboardVersionMemoized
} from './dashboardQueryStore';
import { dashboardsGetDashboard } from './requests';
import { metricsQueryKeys } from '@/api/query_keys/metric';
export const useEnsureDashboardConfig = (prefetchData = true) => {
const queryClient = useQueryClient();
@ -55,11 +55,16 @@ export const useGetDashboardAndInitializeMetrics = (prefetchData = true) => {
const initializeMetrics = useMemoizedFn((metrics: BusterDashboardResponse['metrics']) => {
for (const metric of Object.values(metrics)) {
const prevMetric = queryClient.getQueryData(
queryKeys.metricsGetMetric(metric.id, metric.version_number).queryKey
metricsQueryKeys.metricsGetMetric(metric.id, metric.version_number).queryKey
);
const upgradedMetric = upgradeMetricToIMetric(metric, prevMetric);
console.log(
'upgradedMetric',
upgradedMetric,
metricsQueryKeys.metricsGetMetric(metric.id, metric.version_number).queryKey
);
queryClient.setQueryData(
queryKeys.metricsGetMetric(metric.id, metric.version_number).queryKey,
metricsQueryKeys.metricsGetMetric(metric.id, metric.version_number).queryKey,
upgradedMetric
);
if (prefetchData) {
@ -80,7 +85,9 @@ export const useGetDashboardAndInitializeMetrics = (prefetchData = true) => {
version_number: version_number || undefined
}).then((data) => {
initializeMetrics(data.metrics);
const isLatestVersion = data.dashboard.version_number === last(data.versions)?.version_number;
const latestVersion = last(data.versions)?.version_number || 1;
const isLatestVersion = data.dashboard.version_number === latestVersion;
if (isLatestVersion) {
setOriginalDashboard(data.dashboard);
}
@ -91,7 +98,7 @@ export const useGetDashboardAndInitializeMetrics = (prefetchData = true) => {
.queryKey,
data
);
onSetLatestDashboardVersion(data.dashboard.id, last(data.versions)?.version_number || 1);
onSetLatestDashboardVersion(data.dashboard.id, latestVersion);
}
return data;

View File

@ -63,6 +63,7 @@ export const useGetDashboard = <TData = BusterDashboardResponse>(
const { isFetched: isFetchedInitial, isError: isErrorInitial } = useQuery({
...dashboardQueryKeys.dashboardGetDashboard(id, null),
staleTime: Infinity,
queryFn: () => queryFn(id, paramVersionNumber),
enabled: false, //we made this false because we want to be explicit about the fact that we fetch the dashboard server side
retry(failureCount, error) {

View File

@ -69,6 +69,7 @@ export const useGetMetric = <TData = BusterMetric>(
const { isFetched: isFetchedInitial, isError: isErrorInitial } = useQuery({
...initialOptions,
queryFn: () => initialQueryFn(paramVersionNumber),
staleTime: Infinity,
enabled: false, //In the year of our lord 2025, April 10, I, Nate Kelley, decided to disable this query in favor of explicityly fetching the data. May god have mercy on our souls.
retry(_failureCount, error) {
if (error?.message !== undefined && id) {

View File

@ -18,7 +18,7 @@ const dashboardGetList = (
const dashboardGetDashboard = (dashboardId: string, version_number: number | null) =>
queryOptions<BusterDashboardResponse>({
queryKey: ['dashboard', 'get', dashboardId, version_number || 'INITIAL'] as const,
staleTime: 10 * 1000
staleTime: 60 * 1000
});
export const dashboardQueryKeys = {

View File

@ -50,8 +50,8 @@ export const AppVerticalCodeSplitter = forwardRef<AppSplitterRef, AppVerticalCod
(preservedSideValue: number | null, refSize: number) => {
return (
!preservedSideValue ||
preservedSideValue < 80 ||
refSize < 120 ||
preservedSideValue < 120 ||
refSize < 120 + 80 ||
preservedSideValue > refSize - 80
);
}

View File

@ -20,7 +20,6 @@ export const useIsDashboardReadOnly = ({
} = useGetDashboard(
{ id: dashboardId },
{
enabled: false,
select: (x) => ({
permission: x.permission,
versions: x.versions

View File

@ -92,7 +92,11 @@ export const useGetAsset = (
id: isMetric ? props.assetId : undefined,
versionNumber
},
{ enabled: isMetric && props.assetId !== undefined, select: (x) => x?.name }
{
enabled: isMetric && props.assetId !== undefined,
select: (x) => x?.name,
staleTime: Infinity
}
);
const { isFetched: metricDataIsFetched } = useGetMetricData({
@ -110,7 +114,7 @@ export const useGetAsset = (
id: isDashboard ? props.assetId : undefined,
versionNumber
},
{ enabled: isDashboard, select: (x) => x?.dashboard?.name }
{ enabled: isDashboard, select: (x) => x?.dashboard?.name, staleTime: Infinity }
);
const {