mirror of https://github.com/buster-so/buster.git
prefetcher for version history panel
This commit is contained in:
parent
441ec1df40
commit
73768eebc9
|
@ -118,6 +118,30 @@ export const useGetMetric = <TData = IBusterMetric>(
|
|||
});
|
||||
};
|
||||
|
||||
export const prefetchGetMetricClient = async (
|
||||
{ id, versionNumber }: { id: string; versionNumber: number | undefined },
|
||||
queryClient: QueryClient
|
||||
) => {
|
||||
const options = metricsQueryKeys.metricsGetMetric(id, versionNumber);
|
||||
const existingData = queryClient.getQueryData(options.queryKey);
|
||||
if (!existingData) {
|
||||
await queryClient.prefetchQuery({
|
||||
...options,
|
||||
queryFn: async () => {
|
||||
const result = await getMetric({ id, version_number: versionNumber });
|
||||
return upgradeMetricToIMetric(result, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const usePrefetchGetMetricClient = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMemoizedFn(({ id, versionNumber }: { id: string; versionNumber: number | undefined }) =>
|
||||
prefetchGetMetricClient({ id, versionNumber }, queryClient)
|
||||
);
|
||||
};
|
||||
|
||||
export const useGetMetricsList = (
|
||||
params: Omit<Parameters<typeof listMetrics>[0], 'page_token' | 'page_size'>
|
||||
) => {
|
||||
|
@ -206,6 +230,13 @@ export const prefetchGetMetricDataClient = async (
|
|||
}
|
||||
};
|
||||
|
||||
export const usePrefetchGetMetricDataClient = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMemoizedFn(({ id, versionNumber }: { id: string; versionNumber: number | undefined }) =>
|
||||
prefetchGetMetricDataClient({ id, version_number: versionNumber }, queryClient)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a mutation that saves a metric to the server.
|
||||
* It will simply use the params passed in and not do any special logic.
|
||||
|
|
|
@ -8,17 +8,24 @@ import { cn } from '@/lib/classMerge';
|
|||
import { timeFromNow, timeout } from '@/lib';
|
||||
import { AppPageLayout } from '@/components/ui/layouts';
|
||||
import { useListVersionHistories } from './useListVersionHistories';
|
||||
import { useMount } from '@/hooks';
|
||||
import { useMemoizedFn, useMount } from '@/hooks';
|
||||
import { AppTooltip } from '@/components/ui/tooltip';
|
||||
import Link from 'next/link';
|
||||
import { useGetFileLink } from '@/context/Assets/useGetFileLink';
|
||||
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const VersionHistoryPanel = React.memo(
|
||||
({ assetId, type }: { assetId: string; type: 'metric' | 'dashboard' }) => {
|
||||
const chatId = useChatLayoutContextSelector((x) => x.chatId);
|
||||
const { listItems, currentVersionNumber, selectedQueryVersion, onClickRestoreVersion } =
|
||||
useListVersionHistories({
|
||||
const {
|
||||
listItems,
|
||||
onPrefetchAsset,
|
||||
currentVersionNumber,
|
||||
selectedQueryVersion,
|
||||
onClickRestoreVersion
|
||||
} = useListVersionHistories({
|
||||
assetId,
|
||||
type
|
||||
});
|
||||
|
@ -51,6 +58,7 @@ export const VersionHistoryPanel = React.memo(
|
|||
<ListItem
|
||||
key={item.version_number}
|
||||
{...item}
|
||||
onPrefetchAsset={onPrefetchAsset}
|
||||
selected={item.version_number === selectedQueryVersion}
|
||||
showRestoreButton={item.version_number !== currentVersionNumber}
|
||||
onClickRestoreVersion={onClickRestoreVersion}
|
||||
|
@ -78,18 +86,37 @@ const ListItem = React.memo(
|
|||
selected,
|
||||
showRestoreButton,
|
||||
link,
|
||||
onClickRestoreVersion
|
||||
onClickRestoreVersion,
|
||||
onPrefetchAsset
|
||||
}: {
|
||||
version_number: number;
|
||||
updated_at: string;
|
||||
selected: boolean;
|
||||
showRestoreButton: boolean;
|
||||
onClickRestoreVersion: (versionNumber: number) => void;
|
||||
onPrefetchAsset: (versionNumber: number, link: string) => Promise<void>;
|
||||
link: string;
|
||||
}) => {
|
||||
const routePrefetchTimeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const onHoverLink = useMemoizedFn(() => {
|
||||
// Prefetch route after 50ms
|
||||
routePrefetchTimeoutRef.current = setTimeout(() => {
|
||||
onPrefetchAsset(version_number, link);
|
||||
}, 125);
|
||||
});
|
||||
|
||||
const onHoverEnd = useCallback(() => {
|
||||
if (routePrefetchTimeoutRef.current) {
|
||||
clearTimeout(routePrefetchTimeoutRef.current);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Link prefetch={false} href={link}>
|
||||
<div
|
||||
onMouseEnter={onHoverLink}
|
||||
onMouseLeave={onHoverEnd}
|
||||
className={cn(
|
||||
'group hover:bg-item-hover flex cursor-pointer items-center justify-between space-x-2 rounded px-2.5 py-1.5',
|
||||
selected && 'bg-item-select hover:bg-item-select selected-version'
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
'use client';
|
||||
|
||||
import { useGetDashboard, useUpdateDashboard } from '@/api/buster_rest/dashboards';
|
||||
import { useGetMetric, useSaveMetric } from '@/api/buster_rest/metrics';
|
||||
import {
|
||||
useGetMetric,
|
||||
usePrefetchGetMetricDataClient,
|
||||
useSaveMetric
|
||||
} from '@/api/buster_rest/metrics';
|
||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||
import { useMemoizedFn } from '@/hooks';
|
||||
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout';
|
||||
|
@ -9,6 +13,8 @@ import { useCloseVersionHistory } from '@/layouts/ChatLayout/FileContainer/FileC
|
|||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||
import last from 'lodash/last';
|
||||
import { useMemo } from 'react';
|
||||
import { usePrefetchGetMetricClient } from '@/api/buster_rest/metrics';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
export const useListVersionHistories = ({
|
||||
assetId,
|
||||
|
@ -17,24 +23,27 @@ export const useListVersionHistories = ({
|
|||
assetId: string;
|
||||
type: 'metric' | 'dashboard';
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const { onCloseVersionHistory } = useCloseVersionHistory();
|
||||
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
||||
const {
|
||||
dashboardVersions,
|
||||
versions: dashboardVersions,
|
||||
selectedQueryVersion: dashboardSelectedQueryVersion,
|
||||
currentVersionNumber: dashboardCurrentVersionNumber,
|
||||
onRestoreVersion: onRestoreDashboardVersion,
|
||||
isSavingDashboard
|
||||
isSaving: isSavingDashboard,
|
||||
onPrefetchAsset: onPrefetchDashboardAsset
|
||||
} = useListDashboardVersions({
|
||||
assetId,
|
||||
type
|
||||
});
|
||||
const {
|
||||
metricVersions,
|
||||
versions: metricVersions,
|
||||
selectedQueryVersion: metricSelectedQueryVersion,
|
||||
currentVersionNumber: metricCurrentVersionNumber,
|
||||
onRestoreVersion: onRestoreMetricVersion,
|
||||
isSavingMetric
|
||||
isSaving: isSavingMetric,
|
||||
onPrefetchAsset: onPrefetchMetricAsset
|
||||
} = useListMetricVersions({
|
||||
assetId,
|
||||
type
|
||||
|
@ -82,13 +91,24 @@ export const useListVersionHistories = ({
|
|||
}
|
||||
);
|
||||
|
||||
const onPrefetchAsset = useMemoizedFn(async (versionNumber: number, link: string) => {
|
||||
router.prefetch(link);
|
||||
|
||||
if (type === 'metric') {
|
||||
await onPrefetchMetricAsset(versionNumber);
|
||||
} else {
|
||||
await onPrefetchDashboardAsset(versionNumber);
|
||||
}
|
||||
});
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
listItems,
|
||||
currentVersionNumber,
|
||||
selectedQueryVersion,
|
||||
onClickRestoreVersion,
|
||||
isRestoringVersion: isSavingDashboard || isSavingMetric
|
||||
isRestoringVersion: isSavingDashboard || isSavingMetric,
|
||||
onPrefetchAsset
|
||||
};
|
||||
}, [
|
||||
listItems,
|
||||
|
@ -96,19 +116,34 @@ export const useListVersionHistories = ({
|
|||
selectedQueryVersion,
|
||||
onClickRestoreVersion,
|
||||
isSavingDashboard,
|
||||
isSavingMetric
|
||||
isSavingMetric,
|
||||
onPrefetchAsset
|
||||
]);
|
||||
};
|
||||
|
||||
type UseListVersionReturn = {
|
||||
versions:
|
||||
| {
|
||||
version_number: number;
|
||||
updated_at: string;
|
||||
}[]
|
||||
| undefined;
|
||||
selectedQueryVersion: number | undefined;
|
||||
onRestoreVersion: (versionNumber: number) => Promise<unknown>;
|
||||
currentVersionNumber: number | undefined;
|
||||
isSaving: boolean;
|
||||
onPrefetchAsset: (versionNumber: number) => Promise<void>;
|
||||
};
|
||||
|
||||
const useListDashboardVersions = ({
|
||||
assetId,
|
||||
type
|
||||
}: {
|
||||
assetId: string;
|
||||
type: 'metric' | 'dashboard';
|
||||
}) => {
|
||||
}): UseListVersionReturn => {
|
||||
const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber);
|
||||
const { mutateAsync: updateDashboard, isPending: isSavingDashboard } = useUpdateDashboard({
|
||||
const { mutateAsync: updateDashboard, isPending: isSaving } = useUpdateDashboard({
|
||||
saveToServer: true,
|
||||
updateVersion: true
|
||||
});
|
||||
|
@ -125,13 +160,13 @@ const useListDashboardVersions = ({
|
|||
}
|
||||
);
|
||||
|
||||
const dashboardVersions = dashboardData?.versions;
|
||||
const versions = dashboardData?.versions;
|
||||
const currentVersionNumber = dashboardData?.version_number;
|
||||
|
||||
const selectedQueryVersion = useMemo(() => {
|
||||
if (dashboardVersionNumber) return dashboardVersionNumber;
|
||||
return last(dashboardVersions)?.version_number;
|
||||
}, [dashboardVersions, dashboardVersionNumber]);
|
||||
return last(versions)?.version_number;
|
||||
}, [versions, dashboardVersionNumber]);
|
||||
|
||||
const onRestoreVersion = useMemoizedFn(async (versionNumber: number) => {
|
||||
await updateDashboard({
|
||||
|
@ -140,20 +175,26 @@ const useListDashboardVersions = ({
|
|||
});
|
||||
});
|
||||
|
||||
const onPrefetchAsset = useMemoizedFn(async (versionNumber: number) => {
|
||||
//
|
||||
});
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
dashboardVersions,
|
||||
versions,
|
||||
selectedQueryVersion,
|
||||
onRestoreVersion,
|
||||
currentVersionNumber,
|
||||
isSavingDashboard
|
||||
isSaving,
|
||||
onPrefetchAsset
|
||||
};
|
||||
}, [
|
||||
dashboardVersions,
|
||||
versions,
|
||||
currentVersionNumber,
|
||||
onRestoreVersion,
|
||||
selectedQueryVersion,
|
||||
isSavingDashboard
|
||||
isSaving,
|
||||
onPrefetchAsset
|
||||
]);
|
||||
};
|
||||
|
||||
|
@ -163,10 +204,12 @@ const useListMetricVersions = ({
|
|||
}: {
|
||||
assetId: string;
|
||||
type: 'metric' | 'dashboard';
|
||||
}) => {
|
||||
const { mutateAsync: updateMetric, isPending: isSavingMetric } = useSaveMetric({
|
||||
}): UseListVersionReturn => {
|
||||
const { mutateAsync: updateMetric, isPending: isSaving } = useSaveMetric({
|
||||
updateOnSave: true
|
||||
});
|
||||
const prefetchGetMetric = usePrefetchGetMetricClient();
|
||||
const prefetchGetMetricData = usePrefetchGetMetricDataClient();
|
||||
|
||||
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||
|
||||
|
@ -181,9 +224,14 @@ const useListMetricVersions = ({
|
|||
})
|
||||
}
|
||||
);
|
||||
const metricVersions = metric?.versions;
|
||||
const versions = metric?.versions;
|
||||
const currentVersionNumber = metricVersionNumber || metric?.version_number;
|
||||
|
||||
const selectedQueryVersion = useMemo(() => {
|
||||
if (metricVersionNumber) return metricVersionNumber;
|
||||
return last(versions)?.version_number;
|
||||
}, [versions, metricVersionNumber]);
|
||||
|
||||
const onRestoreVersion = useMemoizedFn(async (versionNumber: number) => {
|
||||
await updateMetric({
|
||||
id: assetId,
|
||||
|
@ -191,24 +239,28 @@ const useListMetricVersions = ({
|
|||
});
|
||||
});
|
||||
|
||||
const selectedQueryVersion = useMemo(() => {
|
||||
if (metricVersionNumber) return metricVersionNumber;
|
||||
return last(metricVersions)?.version_number;
|
||||
}, [metricVersions, metricVersionNumber]);
|
||||
const onPrefetchAsset = useMemoizedFn(async (versionNumber: number) => {
|
||||
await Promise.all([
|
||||
prefetchGetMetric({ id: assetId, versionNumber }),
|
||||
prefetchGetMetricData({ id: assetId, versionNumber })
|
||||
]);
|
||||
});
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
metricVersions,
|
||||
versions,
|
||||
selectedQueryVersion,
|
||||
onRestoreVersion,
|
||||
currentVersionNumber,
|
||||
isSavingMetric
|
||||
isSaving,
|
||||
onPrefetchAsset
|
||||
};
|
||||
}, [
|
||||
metricVersions,
|
||||
versions,
|
||||
currentVersionNumber,
|
||||
onRestoreVersion,
|
||||
selectedQueryVersion,
|
||||
currentVersionNumber,
|
||||
isSavingMetric
|
||||
isSaving,
|
||||
onPrefetchAsset
|
||||
]);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue