mirror of https://github.com/buster-so/buster.git
link options update
This commit is contained in:
parent
9c09a22c74
commit
26108e8029
|
@ -49,22 +49,21 @@ const topItems: ISidebarList = {
|
|||
{
|
||||
label: 'Home',
|
||||
icon: <House4 />,
|
||||
route: { to: '/app/home' },
|
||||
route: { to: '/app/home', preload: 'viewport', preloadDelay: 1000 },
|
||||
id: '/app/home',
|
||||
preload: 'viewport',
|
||||
preloadDelay: 1000,
|
||||
},
|
||||
{
|
||||
label: 'Chat history',
|
||||
icon: <ASSET_ICONS.chats />,
|
||||
route: { to: '/app/chats' },
|
||||
id: '/app/chats/',
|
||||
preload: 'viewport',
|
||||
preloadDelay: 2000,
|
||||
activeOptions: {
|
||||
exact: true,
|
||||
route: {
|
||||
to: '/app/chats',
|
||||
preload: 'viewport',
|
||||
preloadDelay: 2000,
|
||||
activeOptions: {
|
||||
exact: true,
|
||||
},
|
||||
},
|
||||
activeProps: {},
|
||||
id: '/app/chats/',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -76,33 +75,26 @@ const yourStuff: ISidebarGroup = {
|
|||
{
|
||||
label: 'Metrics',
|
||||
icon: <ASSET_ICONS.metrics />,
|
||||
route: { to: '/app/metrics' },
|
||||
route: { to: '/app/metrics', preload: 'intent', preloadDelay: 1000 },
|
||||
id: '/app/metrics',
|
||||
preload: 'intent',
|
||||
preloadDelay: 1000,
|
||||
},
|
||||
{
|
||||
label: 'Dashboards',
|
||||
icon: <ASSET_ICONS.dashboards />,
|
||||
route: { to: '/app/dashboards' },
|
||||
route: { to: '/app/dashboards', preload: 'intent', preloadDelay: 1000 },
|
||||
id: '/app/dashboards/',
|
||||
preload: 'intent',
|
||||
preloadDelay: 1000,
|
||||
},
|
||||
{
|
||||
label: 'Collections',
|
||||
icon: <ASSET_ICONS.collections />,
|
||||
route: { to: '/app/collections' },
|
||||
route: { to: '/app/collections', preload: 'intent', preloadDelay: 1000 },
|
||||
id: '/app/collections/',
|
||||
preload: 'intent',
|
||||
preloadDelay: 1000,
|
||||
},
|
||||
{
|
||||
label: 'Reports',
|
||||
icon: <ASSET_ICONS.reports />,
|
||||
route: { to: '/app/reports' },
|
||||
route: { to: '/app/reports', preload: 'intent', preloadDelay: 1000 },
|
||||
id: '/app/reports/',
|
||||
preload: 'intent',
|
||||
},
|
||||
] satisfies (ISidebarItem & { show?: boolean })[],
|
||||
};
|
||||
|
@ -114,10 +106,9 @@ const adminTools: ISidebarGroup = {
|
|||
{
|
||||
label: 'Logs',
|
||||
icon: <UnorderedList2 />,
|
||||
route: { to: '/app/logs' },
|
||||
route: { to: '/app/logs', preload: 'viewport', preloadDelay: 1000 },
|
||||
id: '/app/logs/',
|
||||
collapsedTooltip: 'Logs',
|
||||
preload: 'viewport',
|
||||
},
|
||||
{
|
||||
label: 'Datasets',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useMatchRoute } from '@tanstack/react-router';
|
||||
import { type LinkProps, useMatchRoute } from '@tanstack/react-router';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
useDeleteUserFavorite,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import type { ActiveOptions, LinkProps } from '@tanstack/react-router';
|
||||
import type {
|
||||
ActiveOptions,
|
||||
LinkProps,
|
||||
RegisteredRouter,
|
||||
ValidateLinkOptions,
|
||||
} from '@tanstack/react-router';
|
||||
import type React from 'react';
|
||||
import type { OptionsTo } from '@/types/routes';
|
||||
import type { LinkOptionsTo, OptionsTo } from '@/types/routes';
|
||||
|
||||
// Base properties shared by all sidebar items
|
||||
type ISidebarItemBase = {
|
||||
|
@ -15,15 +20,13 @@ type ISidebarItemBase = {
|
|||
};
|
||||
|
||||
// Discriminated union: either has a route (with optional activeOptions) or no route at all
|
||||
export type ISidebarItem = ISidebarItemBase &
|
||||
export type ISidebarItem<
|
||||
TRouter extends RegisteredRouter = RegisteredRouter,
|
||||
TOptions = unknown,
|
||||
> = ISidebarItemBase &
|
||||
(
|
||||
| {
|
||||
route: OptionsTo;
|
||||
preload?: LinkProps['preload'];
|
||||
preloadDelay?: LinkProps['preloadDelay'];
|
||||
activeProps?: LinkProps['activeProps'];
|
||||
preloadIntentProximity?: LinkProps['preloadIntentProximity'];
|
||||
activeOptions?: ActiveOptions; // Only allowed when route is provided
|
||||
route: LinkOptionsTo;
|
||||
}
|
||||
| {
|
||||
route?: never;
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import type { AssetType } from '@buster/server-shared/assets';
|
||||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import {
|
||||
BeforeLoadContextOptions,
|
||||
type AnyRoute,
|
||||
type BeforeLoadContextOptions,
|
||||
type BeforeLoadContextParameter,
|
||||
type BeforeLoadFn,
|
||||
redirect,
|
||||
} from '@tanstack/react-router';
|
||||
import { z } from 'zod';
|
||||
import { prefetchGetMetric } from '@/api/buster_rest/metrics';
|
||||
import type { AppRouterContext } from '@/router';
|
||||
import type { FileRouteTypes } from '@/routeTree.gen';
|
||||
|
||||
export const validateSearch = z.object({
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import type { AssetType } from '@buster/server-shared/assets';
|
||||
import type { FileRouteTypes } from '@/routeTree.gen';
|
||||
import type { OptionsTo } from '@/types/routes';
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import type { FileRouteTypes } from '@/routeTree.gen';
|
||||
import type { OptionsTo, OptionsToBase } from '@/types/routes';
|
||||
|
||||
/**
|
||||
* Creates a type-safe route object that can be passed to testNavigate
|
||||
* This function helps ensure that route creation is type-safe
|
||||
*
|
||||
* @example
|
||||
* const route = createRoute({
|
||||
* to: '/app/chats/$chatId',
|
||||
* params: {
|
||||
* chatId: '123'
|
||||
* }
|
||||
* });
|
||||
* testNavigate(route);
|
||||
*
|
||||
* @example
|
||||
* // Use it in a function to return type-safe navigation options
|
||||
* const createMyRoute = () => {
|
||||
* return createRoute({
|
||||
* to: '/app/chats/$chatId',
|
||||
* params: {
|
||||
* chatId: '123'
|
||||
* }
|
||||
* });
|
||||
* };
|
||||
*/
|
||||
export function createRoute(options: OptionsTo): OptionsTo {
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function to create route builders for specific routes
|
||||
* This provides even more type safety by locking in the route path
|
||||
*
|
||||
* @example
|
||||
* const createChatRoute = createRouteFactory('/app/chats/$chatId');
|
||||
* const route = createChatRoute({ chatId: '123' });
|
||||
*/
|
||||
export function createRouteFactory<
|
||||
TTo extends FileRouteTypes['to'],
|
||||
TFrom extends FileRouteTypes['to'] = '/',
|
||||
>(to: TTo) {
|
||||
return (
|
||||
params: OptionsToBase<TFrom, TTo> extends { params: infer P } ? P : never,
|
||||
options?: Omit<OptionsToBase<TFrom, TTo>, 'to' | 'params'>
|
||||
): OptionsTo<TFrom, TTo> => {
|
||||
return {
|
||||
to,
|
||||
params,
|
||||
...options,
|
||||
} as OptionsTo<TFrom, TTo>;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
import {
|
||||
Link,
|
||||
type LinkProps,
|
||||
type RegisteredRouter,
|
||||
type ValidateLinkOptions,
|
||||
} from '@tanstack/react-router';
|
||||
import type { OptionsTo } from '@/types/routes';
|
||||
|
||||
/**
|
||||
* Creates a type-safe route object that can be passed to testNavigate
|
||||
* This function helps ensure that route creation is type-safe
|
||||
*
|
||||
* @example
|
||||
* const route = createRoute({
|
||||
* to: '/app/chats/$chatId',
|
||||
* params: {
|
||||
* chatId: '123'
|
||||
* }
|
||||
* });
|
||||
* testNavigate(route);
|
||||
*
|
||||
* @example
|
||||
* // Use it in a function to return type-safe navigation options
|
||||
* const createMyRoute = () => {
|
||||
* return createRoute({
|
||||
* to: '/app/chats/$chatId',
|
||||
* params: {
|
||||
* chatId: '123'
|
||||
* }
|
||||
* });
|
||||
* };
|
||||
*/
|
||||
export function createRoute(options: OptionsTo): OptionsTo {
|
||||
return options;
|
||||
}
|
||||
|
||||
//I am not super in love with this one. Tanstack has it in their docs..,
|
||||
export function createLinkOptions<TOptions>(
|
||||
options: ValidateLinkOptions<RegisteredRouter, TOptions>
|
||||
) {
|
||||
return options;
|
||||
}
|
||||
|
||||
// function createLinkOptions<TOptions>(options: ValidateLinkOptions<RegisteredRouter, TOptions>) {
|
||||
// return options;
|
||||
// }
|
||||
|
||||
// function createLinkProps(options: LinkProps) {
|
||||
// return options;
|
||||
// }
|
||||
|
||||
// createRoute({
|
||||
// to: '/app/chats/$chatId',
|
||||
// params: { chatId: '123', reportId: '456' },
|
||||
// });
|
||||
|
||||
// createLinkOptions({
|
||||
// to: '/app/chats/$chatId',
|
||||
// params: { chatId: '123', reportId: '456' },
|
||||
// });
|
||||
|
||||
// createLinkProps({
|
||||
// to: '/app/chats/$chatId',
|
||||
// params: { reporhtId: '456' },
|
||||
// });
|
||||
|
||||
// const TestComponent = () => {
|
||||
// return (
|
||||
// <Link to="/app/chats/$chatId" params={{ chatId: '123', reportId: '456' }}>
|
||||
// <div>
|
||||
// <h1>Test</h1>
|
||||
// </div>
|
||||
// </Link>
|
||||
// );
|
||||
// };
|
|
@ -1,5 +1,5 @@
|
|||
import type { FileRouteTypes } from '@/routeTree.gen';
|
||||
import type { OptionsTo, OptionsToBase } from '@/types/routes';
|
||||
import type { OptionsToBase } from '@/types/routes';
|
||||
|
||||
/**
|
||||
* Converts navigation options to a URL string (href)
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import type { NavigateOptions, RegisteredRouter } from '@tanstack/react-router';
|
||||
import type {
|
||||
LinkOptions,
|
||||
LinkProps,
|
||||
NavigateOptions,
|
||||
RegisteredRouter,
|
||||
} from '@tanstack/react-router';
|
||||
import type { FileRouteTypes } from '@/routeTree.gen';
|
||||
|
||||
/**
|
||||
|
@ -41,3 +46,17 @@ export type OptionsTo<
|
|||
: { params?: never }) &
|
||||
Omit<OptionsToBase<TFrom, K, TMaskFrom, TMaskTo>, 'to' | 'params'>;
|
||||
}[FileRouteTypes['to']];
|
||||
|
||||
export type LinkOptionsTo = OptionsTo &
|
||||
Pick<
|
||||
LinkOptions,
|
||||
| 'preload'
|
||||
| 'preloadDelay'
|
||||
| 'activeOptions'
|
||||
| 'preloadIntentProximity'
|
||||
| 'unsafeRelative'
|
||||
| 'ignoreBlocker'
|
||||
| 'disabled'
|
||||
| 'reloadDocument'
|
||||
| 'target'
|
||||
>;
|
||||
|
|
Loading…
Reference in New Issue