mirror of https://github.com/buster-so/buster.git
router change updates
This commit is contained in:
parent
f176ebe2b4
commit
0b7f71ca14
|
@ -21,9 +21,16 @@ export const useAppLayout = () => {
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const targetPath = typeof params === 'string' ? params : createBusterRoute(params);
|
const targetPath = typeof params === 'string' ? params : createBusterRoute(params);
|
||||||
|
|
||||||
|
// Check if the target URL is exactly the same as current URL (including search params)
|
||||||
|
const targetUrl = new URL(targetPath, window.location.origin);
|
||||||
|
const currentUrl = new URL(window.location.href);
|
||||||
|
if (targetUrl.toString() === currentUrl.toString()) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the pathname without query parameters
|
// Extract the pathname without query parameters
|
||||||
const targetPathname = new URL(targetPath, window.location.origin).pathname;
|
const targetPathname = targetUrl.pathname;
|
||||||
const currentPathname = new URL(window.location.href).pathname;
|
const currentPathname = currentUrl.pathname;
|
||||||
|
|
||||||
if (options?.shallow) {
|
if (options?.shallow) {
|
||||||
const isSamePathname = targetPathname === currentPathname;
|
const isSamePathname = targetPathname === currentPathname;
|
||||||
|
@ -48,6 +55,20 @@ export const useAppLayout = () => {
|
||||||
|
|
||||||
// If target and current pathnames are the same but target includes query params
|
// If target and current pathnames are the same but target includes query params
|
||||||
if (currentPathname === targetPathname && targetPath.indexOf('?') !== -1) {
|
if (currentPathname === targetPathname && targetPath.indexOf('?') !== -1) {
|
||||||
|
// Compare current and target query parameters
|
||||||
|
const currentUrl = new URL(window.location.href);
|
||||||
|
const targetUrl = new URL(targetPath, window.location.origin);
|
||||||
|
const currentParams = Object.fromEntries(currentUrl.searchParams.entries());
|
||||||
|
const targetParams = Object.fromEntries(targetUrl.searchParams.entries());
|
||||||
|
|
||||||
|
// Check if the params are actually different
|
||||||
|
const paramsAreDifferent = JSON.stringify(currentParams) !== JSON.stringify(targetParams);
|
||||||
|
|
||||||
|
if (!paramsAreDifferent) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
push(targetPath);
|
push(targetPath);
|
||||||
// Set up an effect to watch for pathname changes
|
// Set up an effect to watch for pathname changes
|
||||||
const checkPathChange = (waitTime: number = 25, iteration: number = 0) => {
|
const checkPathChange = (waitTime: number = 25, iteration: number = 0) => {
|
||||||
|
@ -85,23 +106,21 @@ export const useAppLayout = () => {
|
||||||
const createQueryParams = useMemoizedFn(
|
const createQueryParams = useMemoizedFn(
|
||||||
(params: Record<string, string | null>, preserveExisting: boolean) => {
|
(params: Record<string, string | null>, preserveExisting: boolean) => {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
const searchParams = url.searchParams;
|
|
||||||
|
|
||||||
if (!preserveExisting) {
|
if (!preserveExisting) {
|
||||||
searchParams.forEach((value, key) => {
|
// Clear all existing search parameters
|
||||||
searchParams.delete(key);
|
url.search = '';
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add new parameters
|
||||||
Object.entries(params).forEach(([key, value]) => {
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
searchParams.set(key, value);
|
url.searchParams.set(key, value);
|
||||||
} else {
|
} else {
|
||||||
searchParams.delete(key);
|
url.searchParams.delete(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
url.search = searchParams.toString();
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -109,8 +128,12 @@ export const useAppLayout = () => {
|
||||||
//TODO: make this typesafe...
|
//TODO: make this typesafe...
|
||||||
const onChangeQueryParams = useMemoizedFn(
|
const onChangeQueryParams = useMemoizedFn(
|
||||||
(params: Record<string, string | null>, preserveExisting: boolean) => {
|
(params: Record<string, string | null>, preserveExisting: boolean) => {
|
||||||
|
const isRemovingANonExistentParam = Object.keys(params).every(
|
||||||
|
(key) => !window.location.href.includes(key)
|
||||||
|
);
|
||||||
|
if (isRemovingANonExistentParam) return; //we don't need to do anything if we're removing a non-existent param
|
||||||
const url = createQueryParams(params, preserveExisting);
|
const url = createQueryParams(params, preserveExisting);
|
||||||
window.history.pushState({}, '', url); //we used window.history instead of replace for true shallow routing
|
if (url) window.history.pushState({}, '', url); //we used window.history instead of replace for true shallow routing
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,6 @@ export const useBusterNewChat = () => {
|
||||||
(messageId) => messageId === messageId
|
(messageId) => messageId === messageId
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('messageIndex', messageIndex);
|
|
||||||
|
|
||||||
if (messageIndex && messageIndex !== -1) {
|
if (messageIndex && messageIndex !== -1) {
|
||||||
console.log('oldMessageIds', currentChat?.message_ids);
|
console.log('oldMessageIds', currentChat?.message_ids);
|
||||||
const updatedMessageIds = currentChat?.message_ids.slice(0, messageIndex + 1);
|
const updatedMessageIds = currentChat?.message_ids.slice(0, messageIndex + 1);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { BusterChart } from '@/components/ui/charts';
|
||||||
import { cn } from '@/lib/classMerge';
|
import { cn } from '@/lib/classMerge';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { METRIC_CHART_CONTAINER_ID } from './config';
|
import { METRIC_CHART_CONTAINER_ID } from './config';
|
||||||
|
import { useMount } from '@/hooks';
|
||||||
|
|
||||||
interface MetricViewChartContentProps {
|
interface MetricViewChartContentProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -35,6 +36,10 @@ export const MetricViewChartContent: React.FC<MetricViewChartContentProps> = Rea
|
||||||
return 'p-4';
|
return 'p-4';
|
||||||
}, [isTable, fetchedData]);
|
}, [isTable, fetchedData]);
|
||||||
|
|
||||||
|
useMount(() => {
|
||||||
|
console.log('metricData');
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('flex h-full flex-col overflow-hidden', cardClassName, className)}>
|
<div className={cn('flex h-full flex-col overflow-hidden', cardClassName, className)}>
|
||||||
<BusterChart
|
<BusterChart
|
||||||
|
|
|
@ -145,12 +145,7 @@ export const useLayoutConfig = ({
|
||||||
draft[selectedFileId].fileViewConfig[selectedFileView].secondaryView = null;
|
draft[selectedFileId].fileViewConfig[selectedFileView].secondaryView = null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
onChangeQueryParams(
|
onChangeQueryParams({ secondary_view: null }, true);
|
||||||
{
|
|
||||||
secondary_view: null
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
await timeout(250); //wait for the panel to close
|
await timeout(250); //wait for the panel to close
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -61,10 +61,10 @@ export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> =
|
||||||
MetricContainerHeaderButtons.displayName = 'MetricContainerHeaderButtons';
|
MetricContainerHeaderButtons.displayName = 'MetricContainerHeaderButtons';
|
||||||
|
|
||||||
const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
|
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
||||||
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
const selectedFileViewSecondary = useChatLayoutContextSelector(
|
||||||
(x) => x.selectedFileViewSecondary
|
(x) => x.selectedFileViewSecondary
|
||||||
);
|
);
|
||||||
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
|
||||||
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
||||||
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
const editableSecondaryView: MetricFileViewSecondary = 'chart-edit';
|
const editableSecondaryView: MetricFileViewSecondary = 'chart-edit';
|
||||||
|
@ -125,6 +125,16 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
||||||
|
|
||||||
const href = useMemo(() => {
|
const href = useMemo(() => {
|
||||||
|
if (isSelectedView) {
|
||||||
|
return assetParamsToRoute({
|
||||||
|
chatId,
|
||||||
|
assetId: metricId,
|
||||||
|
type: 'metric',
|
||||||
|
secondaryView: null,
|
||||||
|
versionNumber: metricVersionNumber
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return assetParamsToRoute({
|
return assetParamsToRoute({
|
||||||
chatId,
|
chatId,
|
||||||
assetId: metricId,
|
assetId: metricId,
|
||||||
|
@ -140,7 +150,12 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={href}>
|
<Link
|
||||||
|
href={href}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}}>
|
||||||
<SelectableButton
|
<SelectableButton
|
||||||
tooltipText="SQL editor"
|
tooltipText="SQL editor"
|
||||||
icon={<SquareCode />}
|
icon={<SquareCode />}
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const SelectableButton = React.memo<{
|
||||||
tooltipText: string;
|
tooltipText: string;
|
||||||
tooltipShortcuts?: string[];
|
tooltipShortcuts?: string[];
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
onClick: () => void;
|
onClick?: () => void;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
}>(({ tooltipText, tooltipShortcuts, icon, onClick, selected }) => {
|
}>(({ tooltipText, tooltipShortcuts, icon, onClick, selected }) => {
|
||||||
return (
|
return (
|
||||||
|
|
Loading…
Reference in New Issue