diff --git a/apps/web-tss/src/components/features/sidebars/SidebarPrimary/SidebarPrimary.tsx b/apps/web-tss/src/components/features/sidebars/SidebarPrimary/SidebarPrimary.tsx index 71c15b05e..c5114bc77 100644 --- a/apps/web-tss/src/components/features/sidebars/SidebarPrimary/SidebarPrimary.tsx +++ b/apps/web-tss/src/components/features/sidebars/SidebarPrimary/SidebarPrimary.tsx @@ -49,22 +49,21 @@ const topItems: ISidebarList = { { label: 'Home', icon: , - route: { to: '/app/home' }, + route: { to: '/app/home', preload: 'viewport', preloadDelay: 1000 }, id: '/app/home', - preload: 'viewport', - preloadDelay: 1000, }, { label: 'Chat history', icon: , - 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: , - route: { to: '/app/metrics' }, + route: { to: '/app/metrics', preload: 'intent', preloadDelay: 1000 }, id: '/app/metrics', - preload: 'intent', - preloadDelay: 1000, }, { label: 'Dashboards', icon: , - route: { to: '/app/dashboards' }, + route: { to: '/app/dashboards', preload: 'intent', preloadDelay: 1000 }, id: '/app/dashboards/', - preload: 'intent', - preloadDelay: 1000, }, { label: 'Collections', icon: , - route: { to: '/app/collections' }, + route: { to: '/app/collections', preload: 'intent', preloadDelay: 1000 }, id: '/app/collections/', - preload: 'intent', - preloadDelay: 1000, }, { label: 'Reports', icon: , - 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: , - route: { to: '/app/logs' }, + route: { to: '/app/logs', preload: 'viewport', preloadDelay: 1000 }, id: '/app/logs/', collapsedTooltip: 'Logs', - preload: 'viewport', }, { label: 'Datasets', diff --git a/apps/web-tss/src/components/features/sidebars/SidebarPrimary/useFavoritesSidebarPanel.tsx b/apps/web-tss/src/components/features/sidebars/SidebarPrimary/useFavoritesSidebarPanel.tsx index 1dcbb1205..6f9a4100e 100644 --- a/apps/web-tss/src/components/features/sidebars/SidebarPrimary/useFavoritesSidebarPanel.tsx +++ b/apps/web-tss/src/components/features/sidebars/SidebarPrimary/useFavoritesSidebarPanel.tsx @@ -1,4 +1,4 @@ -import { useMatchRoute } from '@tanstack/react-router'; +import { type LinkProps, useMatchRoute } from '@tanstack/react-router'; import { useMemo } from 'react'; import { useDeleteUserFavorite, diff --git a/apps/web-tss/src/components/ui/sidebar/interfaces.ts b/apps/web-tss/src/components/ui/sidebar/interfaces.ts index 5568965c2..4c49426cc 100644 --- a/apps/web-tss/src/components/ui/sidebar/interfaces.ts +++ b/apps/web-tss/src/components/ui/sidebar/interfaces.ts @@ -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; diff --git a/apps/web-tss/src/context/BusterAssets/metric-server/metricIndexServerAssetContext.ts b/apps/web-tss/src/context/BusterAssets/metric-server/metricIndexServerAssetContext.ts index ecfdc3738..ce61a147d 100644 --- a/apps/web-tss/src/context/BusterAssets/metric-server/metricIndexServerAssetContext.ts +++ b/apps/web-tss/src/context/BusterAssets/metric-server/metricIndexServerAssetContext.ts @@ -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({ diff --git a/apps/web-tss/src/lib/assets/assetParamsToRoute.ts b/apps/web-tss/src/lib/assets/assetParamsToRoute.ts index 4207ec760..9699cd652 100644 --- a/apps/web-tss/src/lib/assets/assetParamsToRoute.ts +++ b/apps/web-tss/src/lib/assets/assetParamsToRoute.ts @@ -1,4 +1,3 @@ -import type { AssetType } from '@buster/server-shared/assets'; import type { FileRouteTypes } from '@/routeTree.gen'; import type { OptionsTo } from '@/types/routes'; diff --git a/apps/web-tss/src/lib/tss-routes/createRoute.ts b/apps/web-tss/src/lib/tss-routes/createRoute.ts deleted file mode 100644 index 9b2ee255c..000000000 --- a/apps/web-tss/src/lib/tss-routes/createRoute.ts +++ /dev/null @@ -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 extends { params: infer P } ? P : never, - options?: Omit, 'to' | 'params'> - ): OptionsTo => { - return { - to, - params, - ...options, - } as OptionsTo; - }; -} diff --git a/apps/web-tss/src/lib/tss-routes/createRoute.tsx b/apps/web-tss/src/lib/tss-routes/createRoute.tsx new file mode 100644 index 000000000..e2358bfc3 --- /dev/null +++ b/apps/web-tss/src/lib/tss-routes/createRoute.tsx @@ -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( + options: ValidateLinkOptions +) { + return options; +} + +// function createLinkOptions(options: ValidateLinkOptions) { +// 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 ( +// +//
+//

Test

+//
+// +// ); +// }; diff --git a/apps/web-tss/src/lib/tss-routes/navigationOptionsToHref.ts b/apps/web-tss/src/lib/tss-routes/navigationOptionsToHref.ts index a5ee02190..2e33b1ae6 100644 --- a/apps/web-tss/src/lib/tss-routes/navigationOptionsToHref.ts +++ b/apps/web-tss/src/lib/tss-routes/navigationOptionsToHref.ts @@ -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) diff --git a/apps/web-tss/src/types/routes.ts b/apps/web-tss/src/types/routes.ts index f8aea2c59..8ef21d652 100644 --- a/apps/web-tss/src/types/routes.ts +++ b/apps/web-tss/src/types/routes.ts @@ -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, 'to' | 'params'>; }[FileRouteTypes['to']]; + +export type LinkOptionsTo = OptionsTo & + Pick< + LinkOptions, + | 'preload' + | 'preloadDelay' + | 'activeOptions' + | 'preloadIntentProximity' + | 'unsafeRelative' + | 'ignoreBlocker' + | 'disabled' + | 'reloadDocument' + | 'target' + >;