router change updates

This commit is contained in:
Nate Kelley 2025-04-17 22:11:25 -06:00
parent f176ebe2b4
commit 0b7f71ca14
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
6 changed files with 57 additions and 21 deletions

View File

@ -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
} }
); );

View File

@ -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);

View File

@ -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

View File

@ -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
}); });

View File

@ -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 />}

View File

@ -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 (