mirror of https://github.com/buster-so/buster.git
better prevent navigation logic
This commit is contained in:
parent
f915e4caea
commit
d9bc8d4741
|
@ -24,7 +24,6 @@ const SplitterContent: React.FC<{
|
||||||
isSaving: boolean;
|
isSaving: boolean;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
}> = React.memo(({ onReset, onSave, isSaving, open }) => {
|
}> = React.memo(({ onReset, onSave, isSaving, open }) => {
|
||||||
console.log(open);
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="flex w-full items-center space-x-2.5">
|
<div className="flex w-full items-center space-x-2.5">
|
||||||
|
|
|
@ -122,7 +122,7 @@ export const SidebarPrimary = React.memo(() => {
|
||||||
const isAdmin = useUserConfigContextSelector((x) => x.isAdmin);
|
const isAdmin = useUserConfigContextSelector((x) => x.isAdmin);
|
||||||
const isUserRegistered = useUserConfigContextSelector((x) => x.isUserRegistered);
|
const isUserRegistered = useUserConfigContextSelector((x) => x.isUserRegistered);
|
||||||
const { data: favorites } = useGetUserFavorites();
|
const { data: favorites } = useGetUserFavorites();
|
||||||
const currentRoute = useAppLayoutContextSelector((x) => x.currentRoute);
|
const currentParentRoute = useAppLayoutContextSelector((x) => x.currentParentRoute);
|
||||||
const onToggleInviteModal = useInviteModalStore((s) => s.onToggleInviteModal);
|
const onToggleInviteModal = useInviteModalStore((s) => s.onToggleInviteModal);
|
||||||
const [openSupportModal, setOpenSupportModal] = useState(false);
|
const [openSupportModal, setOpenSupportModal] = useState(false);
|
||||||
const { mutateAsync: updateUserFavorites } = useUpdateUserFavorites();
|
const { mutateAsync: updateUserFavorites } = useUpdateUserFavorites();
|
||||||
|
@ -150,7 +150,7 @@ export const SidebarPrimary = React.memo(() => {
|
||||||
items.push(tryGroup(onToggleInviteModal, () => setOpenSupportModal(true)));
|
items.push(tryGroup(onToggleInviteModal, () => setOpenSupportModal(true)));
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}, [isAdmin, isUserRegistered, favorites, currentRoute, onFavoritesReorder]);
|
}, [isAdmin, isUserRegistered, favorites, currentParentRoute, onFavoritesReorder]);
|
||||||
|
|
||||||
const onCloseSupportModal = useMemoizedFn(() => setOpenSupportModal(false));
|
const onCloseSupportModal = useMemoizedFn(() => setOpenSupportModal(false));
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ export const SidebarPrimary = React.memo(() => {
|
||||||
<Sidebar
|
<Sidebar
|
||||||
content={sidebarItems}
|
content={sidebarItems}
|
||||||
header={HeaderMemoized}
|
header={HeaderMemoized}
|
||||||
activeItem={currentRoute}
|
activeItem={currentParentRoute}
|
||||||
footer={FooterMemoized}
|
footer={FooterMemoized}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,10 @@ export const PreventNavigation: React.FC<PreventNavigationProps> = React.memo(
|
||||||
* @param e The triggered event.
|
* @param e The triggered event.
|
||||||
*/
|
*/
|
||||||
const handleClick = useMemoizedFn((event: MouseEvent) => {
|
const handleClick = useMemoizedFn((event: MouseEvent) => {
|
||||||
|
let originalTarget = event.target as HTMLElement;
|
||||||
let target = event.target as HTMLElement;
|
let target = event.target as HTMLElement;
|
||||||
let href: string | null = null;
|
let href: string | null = null;
|
||||||
|
let originalEvent = event;
|
||||||
|
|
||||||
// Traverse up the DOM tree looking for an anchor tag with href
|
// Traverse up the DOM tree looking for an anchor tag with href
|
||||||
while (target && !href) {
|
while (target && !href) {
|
||||||
|
@ -60,11 +62,53 @@ export const PreventNavigation: React.FC<PreventNavigationProps> = React.memo(
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
console.log(target);
|
// Store both the target and the original event details
|
||||||
|
|
||||||
confirmationFn.current = () => {
|
confirmationFn.current = () => {
|
||||||
target.click();
|
// Remove all click listeners temporarily
|
||||||
// if (href) router.push(href);
|
document.querySelectorAll('a').forEach((link) => {
|
||||||
|
link.removeEventListener('click', handleClick);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get all click event handlers on the original target
|
||||||
|
const clickHandlers = originalTarget.onclick;
|
||||||
|
|
||||||
|
// Temporarily remove our prevention
|
||||||
|
if (clickHandlers) {
|
||||||
|
originalTarget.onclick = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new click event
|
||||||
|
const newEvent = new MouseEvent('click', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
view: window,
|
||||||
|
detail: originalEvent.detail,
|
||||||
|
screenX: originalEvent.screenX,
|
||||||
|
screenY: originalEvent.screenY,
|
||||||
|
clientX: originalEvent.clientX,
|
||||||
|
clientY: originalEvent.clientY,
|
||||||
|
ctrlKey: originalEvent.ctrlKey,
|
||||||
|
altKey: originalEvent.altKey,
|
||||||
|
shiftKey: originalEvent.shiftKey,
|
||||||
|
metaKey: originalEvent.metaKey,
|
||||||
|
button: originalEvent.button,
|
||||||
|
buttons: originalEvent.buttons
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dispatch the event directly on the original target
|
||||||
|
originalTarget.dispatchEvent(newEvent);
|
||||||
|
|
||||||
|
// Restore click handlers
|
||||||
|
if (clickHandlers) {
|
||||||
|
originalTarget.onclick = clickHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-attach our listeners after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelectorAll('a').forEach((link) => {
|
||||||
|
link.addEventListener('click', handleClick);
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
setLeavingPage(true);
|
setLeavingPage(true);
|
||||||
|
@ -79,7 +123,6 @@ export const PreventNavigation: React.FC<PreventNavigationProps> = React.memo(
|
||||||
window.history.pushState(null, document.title, window.location.href);
|
window.history.pushState(null, document.title, window.location.href);
|
||||||
|
|
||||||
confirmationFn.current = () => {
|
confirmationFn.current = () => {
|
||||||
console.warn('TODO - make sure we can navigate back to the correct page');
|
|
||||||
router.back();
|
router.back();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,6 @@ export const AppSegmented: AppSegmentedComponent = React.memo(
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
||||||
const handleTabClick = useMemoizedFn((value: string) => {
|
const handleTabClick = useMemoizedFn((value: string) => {
|
||||||
console.log('handleTabClick called with:', value);
|
|
||||||
const item = options.find((item) => item.value === value);
|
const item = options.find((item) => item.value === value);
|
||||||
if (item && !item.disabled && value !== selectedValue) {
|
if (item && !item.disabled && value !== selectedValue) {
|
||||||
setSelectedValue(item.value);
|
setSelectedValue(item.value);
|
||||||
|
@ -174,6 +173,7 @@ export const AppSegmented: AppSegmentedComponent = React.memo(
|
||||||
<Tabs.Root
|
<Tabs.Root
|
||||||
ref={rootRef}
|
ref={rootRef}
|
||||||
value={selectedValue as string}
|
value={selectedValue as string}
|
||||||
|
// onValueChange={handleTabClick}
|
||||||
className={cn(segmentedVariants({ block, type }), heightVariants({ size }), className)}>
|
className={cn(segmentedVariants({ block, type }), heightVariants({ size }), className)}>
|
||||||
{isMeasured && (
|
{isMeasured && (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
@ -231,6 +231,18 @@ function SegmentedTriggerComponent<T extends string = string>(props: SegmentedTr
|
||||||
|
|
||||||
const LinkDiv = link ? Link : 'div';
|
const LinkDiv = link ? Link : 'div';
|
||||||
|
|
||||||
|
const handleClick = async (e: React.MouseEvent) => {
|
||||||
|
if (link) {
|
||||||
|
e.preventDefault();
|
||||||
|
handleTabClick(value);
|
||||||
|
// Wait for a short duration to allow the animation to complete
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||||
|
router.push(link);
|
||||||
|
} else {
|
||||||
|
handleTabClick(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useMount(() => {
|
useMount(() => {
|
||||||
if (link) {
|
if (link) {
|
||||||
router.prefetch(link);
|
router.prefetch(link);
|
||||||
|
@ -239,13 +251,12 @@ function SegmentedTriggerComponent<T extends string = string>(props: SegmentedTr
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={tooltip || ''} sideOffset={10} delayDuration={150}>
|
<Tooltip title={tooltip || ''} sideOffset={10} delayDuration={150}>
|
||||||
<LinkDiv href={link || ''}>
|
<LinkDiv href={link || ''} onClick={handleClick}>
|
||||||
<Tabs.Trigger
|
<Tabs.Trigger
|
||||||
key={value}
|
key={value}
|
||||||
value={value}
|
value={value}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
asChild
|
asChild
|
||||||
onClick={() => handleTabClick(value)}
|
|
||||||
ref={(el) => {
|
ref={(el) => {
|
||||||
if (el) tabRefs.current.set(value, el);
|
if (el) tabRefs.current.set(value, el);
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -13,7 +13,6 @@ export const MetricContainerHeaderSegment: React.FC<FileContainerSegmentProps> =
|
||||||
const metricId = useChatLayoutContextSelector((x) => x.metricId) || '';
|
const metricId = useChatLayoutContextSelector((x) => x.metricId) || '';
|
||||||
|
|
||||||
const onChange = useMemoizedFn((fileView: SegmentedItem<FileView>) => {
|
const onChange = useMemoizedFn((fileView: SegmentedItem<FileView>) => {
|
||||||
console.log(fileView);
|
|
||||||
onSetFileView({ fileView: fileView.value });
|
onSetFileView({ fileView: fileView.value });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,7 @@ export const pathNameToRoute = (pathName: string, params: any): BusterRoutes =>
|
||||||
[BusterRoutes.APP_DATASETS_ID_PERMISSIONS_OVERVIEW]: BusterRoutes.APP_DATASETS,
|
[BusterRoutes.APP_DATASETS_ID_PERMISSIONS_OVERVIEW]: BusterRoutes.APP_DATASETS,
|
||||||
[BusterRoutes.APP_DATASETS_ID_OVERVIEW]: BusterRoutes.APP_DATASETS,
|
[BusterRoutes.APP_DATASETS_ID_OVERVIEW]: BusterRoutes.APP_DATASETS,
|
||||||
[BusterRoutes.APP_DATASETS_ID_EDITOR]: BusterRoutes.APP_DATASETS,
|
[BusterRoutes.APP_DATASETS_ID_EDITOR]: BusterRoutes.APP_DATASETS,
|
||||||
[BusterRoutes.APP_TERMS_ID]: BusterRoutes.APP_TERMS,
|
[BusterRoutes.APP_TERMS_ID]: BusterRoutes.APP_TERMS
|
||||||
[BusterRoutes.APP_CHAT_ID_METRIC_ID_CHART]: BusterRoutes.APP_CHAT,
|
|
||||||
[BusterRoutes.APP_CHAT_ID_METRIC_ID_FILE]: BusterRoutes.APP_CHAT,
|
|
||||||
[BusterRoutes.APP_CHAT_ID_METRIC_ID_RESULTS]: BusterRoutes.APP_CHAT,
|
|
||||||
[BusterRoutes.APP_CHAT_ID_DASHBOARD_ID_FILE]: BusterRoutes.APP_CHAT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (route && paramRoutesToParent[route as string]) {
|
if (route && paramRoutesToParent[route as string]) {
|
||||||
|
@ -67,7 +63,11 @@ export const pathNameToParentRoute = (pathName: string, params: any): BusterRout
|
||||||
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_USERS]: BusterRoutes.SETTINGS_PERMISSION_GROUPS,
|
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_USERS]: BusterRoutes.SETTINGS_PERMISSION_GROUPS,
|
||||||
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_DATASET_GROUPS]:
|
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_DATASET_GROUPS]:
|
||||||
BusterRoutes.SETTINGS_PERMISSION_GROUPS,
|
BusterRoutes.SETTINGS_PERMISSION_GROUPS,
|
||||||
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_DATASETS]: BusterRoutes.SETTINGS_PERMISSION_GROUPS
|
[BusterRoutes.SETTINGS_PERMISSION_GROUPS_ID_DATASETS]: BusterRoutes.SETTINGS_PERMISSION_GROUPS,
|
||||||
|
[BusterRoutes.APP_CHAT_ID_METRIC_ID_CHART]: BusterRoutes.APP_CHAT,
|
||||||
|
[BusterRoutes.APP_CHAT_ID_METRIC_ID_FILE]: BusterRoutes.APP_CHAT,
|
||||||
|
[BusterRoutes.APP_CHAT_ID_METRIC_ID_RESULTS]: BusterRoutes.APP_CHAT,
|
||||||
|
[BusterRoutes.APP_CHAT_ID_DASHBOARD_ID_FILE]: BusterRoutes.APP_CHAT
|
||||||
};
|
};
|
||||||
|
|
||||||
if (route && paramRoutesToParent[route as string]) {
|
if (route && paramRoutesToParent[route as string]) {
|
||||||
|
|
Loading…
Reference in New Issue