update support mdals

This commit is contained in:
Nate Kelley 2025-09-03 19:08:38 -06:00
parent ed9a09e051
commit 1404792006
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
8 changed files with 128 additions and 67 deletions

View File

@ -1,6 +1,6 @@
import type { AssetType } from '@buster/server-shared/assets';
import { Link, useNavigate } from '@tanstack/react-router';
import type React from 'react';
import { useMemo } from 'react';
import React, { useMemo } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import {
useIsAnonymousUser,
@ -26,6 +26,7 @@ import {
import {
createSidebarGroup,
createSidebarItem,
createSidebarItems,
createSidebarList,
} from '@/components/ui/sidebar/create-sidebar-item';
import { Sidebar } from '@/components/ui/sidebar/SidebarComponent';
@ -34,12 +35,13 @@ import {
closeContactSupportModal,
toggleContactSupportModal,
useContactSupportModalStore,
} from '@/context/BusterAppLayout/useContactSupportModalStore';
} from '@/context/GlobalStore/useContactSupportModalStore';
import {
closeInviteModal,
toggleInviteModal,
useInviteModalStore,
} from '@/context/BusterAppLayout/useInviteModalStore';
} from '@/context/GlobalStore/useInviteModalStore';
import { useGetSelectedAssetTypeLoose } from '@/context/Routes/useAppRoutes';
import { cn } from '@/lib/classMerge';
import { InvitePeopleModal } from '../../modals/InvitePeopleModal';
import { SupportModal } from '../../modals/SupportModal';
@ -71,41 +73,55 @@ const topItems: ISidebarList = createSidebarList({
],
});
const yourStuff: ISidebarGroup = createSidebarGroup({
label: 'Your stuff',
id: 'your-stuff',
items: [
{
label: 'Metrics',
icon: <ASSET_ICONS.metrics />,
link: { to: '/app/metrics', preload: 'intent', preloadDelay: 500 },
id: '/app/metrics',
},
{
label: 'Dashboards',
icon: <ASSET_ICONS.dashboards />,
link: { to: '/app/dashboards', preload: 'intent', preloadDelay: 500 },
id: '/app/dashboards/',
},
{
label: 'Collections',
icon: <ASSET_ICONS.collections />,
link: { to: '/app/collections', preload: 'intent', preloadDelay: 500 },
id: '/app/collections/',
},
{
label: 'Reports',
icon: <ASSET_ICONS.reports />,
link: { to: '/app/reports', preload: 'intent', preloadDelay: 500 },
id: '/app/reports/',
},
],
});
const yourStuff = (selectedAssetType?: AssetType): ISidebarGroup =>
createSidebarGroup({
label: 'Your stuff',
id: 'your-stuff',
items: createSidebarItems(
[
{
label: 'Metrics',
assetType: 'metric' satisfies AssetType,
icon: <ASSET_ICONS.metrics />,
link: { to: '/app/metrics' },
id: '/app/metrics',
},
{
label: 'Dashboards',
assetType: 'dashboard' satisfies AssetType,
icon: <ASSET_ICONS.dashboards />,
link: { to: '/app/dashboards' },
id: '/app/dashboards/',
},
{
label: 'Collections',
assetType: 'collection' satisfies AssetType,
icon: <ASSET_ICONS.collections />,
link: { to: '/app/collections' },
id: '/app/collections/',
},
{
label: 'Reports',
assetType: 'report' satisfies AssetType,
icon: <ASSET_ICONS.reports />,
link: { to: '/app/reports' },
id: '/app/reports/',
},
].map(({ assetType, ...item }) => ({
...item,
link: {
...item.link,
activeOptions: { exact: true },
},
active: selectedAssetType === assetType,
}))
),
});
const adminTools: ISidebarGroup = createSidebarGroup({
label: 'Admin tools',
id: 'admin-tools',
items: [
items: createSidebarItems([
{
label: 'Logs',
icon: <UnorderedList2 />,
@ -120,7 +136,7 @@ const adminTools: ISidebarGroup = createSidebarGroup({
id: '/app/datasets/',
collapsedTooltip: 'Datasets',
},
],
]),
});
const tryGroup = (showInvitePeople: boolean): ISidebarGroup => ({
@ -146,37 +162,58 @@ const tryGroup = (showInvitePeople: boolean): ISidebarGroup => ({
}, [] as ISidebarItem[]),
});
export const SidebarPrimary = () => {
const makeSidebarItems = ({
isUserRegistered,
isAdmin,
favoritesDropdownItems,
tryGroupMemoized,
selectedAssetType,
}: {
isUserRegistered: boolean;
isAdmin: boolean;
favoritesDropdownItems: ISidebarGroup | null;
tryGroupMemoized: ISidebarGroup;
selectedAssetType?: AssetType;
}) => {
if (!isUserRegistered) return [];
const items = [topItems];
if (isAdmin) {
items.push(adminTools);
}
items.push(yourStuff(selectedAssetType));
if (favoritesDropdownItems) {
items.push(favoritesDropdownItems);
}
items.push(tryGroupMemoized);
return items;
};
export const SidebarPrimary = React.memo(() => {
const isAdmin = useIsUserAdmin();
const restrictNewUserInvitations = useRestrictNewUserInvitations();
const isUserRegistered = useIsUserRegistered();
const favoritesDropdownItems = useFavoriteSidebarPanel();
const selectedAssetType = useGetSelectedAssetTypeLoose();
const tryGroupMemoized = useMemo(
() => tryGroup(!restrictNewUserInvitations),
[restrictNewUserInvitations]
);
const sidebarItems: SidebarProps['content'] = useMemo(() => {
if (!isUserRegistered) return [];
const items = [topItems];
if (isAdmin) {
items.push(adminTools);
}
items.push(yourStuff);
if (favoritesDropdownItems) {
items.push(favoritesDropdownItems);
}
items.push(tryGroupMemoized);
return items;
}, [isUserRegistered, restrictNewUserInvitations, favoritesDropdownItems, isAdmin]);
const sidebarItems: SidebarProps['content'] = makeSidebarItems({
isUserRegistered,
isAdmin,
favoritesDropdownItems,
tryGroupMemoized,
selectedAssetType,
});
return (
<>
@ -193,7 +230,7 @@ export const SidebarPrimary = () => {
<GlobalModals />
</>
);
};
});
SidebarPrimary.displayName = 'SidebarPrimary';

View File

@ -19,7 +19,7 @@ import {
COLLAPSED_WIDTH_FIT,
} from '@/components/ui/sidebar/config';
import { BUSTER_DOCS_URL } from '@/config/externalRoutes';
import { toggleContactSupportModal } from '@/context/BusterAppLayout/useContactSupportModalStore';
import { toggleContactSupportModal } from '@/context/GlobalStore/useContactSupportModalStore';
import { cn } from '@/lib/classMerge';
export const SidebarUserFooter: React.FC = React.memo(() => {

View File

@ -1,4 +1,4 @@
import { Link, type LinkProps, MatchRoute } from '@tanstack/react-router';
import { Link } from '@tanstack/react-router';
import { cva, type VariantProps } from 'class-variance-authority';
import type React from 'react';
import { cn } from '@/lib/classMerge';

View File

@ -1,8 +0,0 @@
import { useMatches } from '@tanstack/react-router';
export const useGetParentRoute = () => {
const afterAppSplash = useMatches({
select: (matches) => matches[2],
});
return afterAppSplash?.routeId;
};

View File

@ -0,0 +1,26 @@
import type { AssetType } from '@buster/server-shared/assets';
import { useMatches } from '@tanstack/react-router';
import { useMemo } from 'react';
import { useMemoizedFn } from '@/hooks/useMemoizedFn';
export const useGetParentRoute = () => {
const afterAppSplash = useMatches({
select: (matches) => {
const secondToLastMatch = matches[matches.length - 2];
return secondToLastMatch.routeId;
},
});
return afterAppSplash;
};
export const useGetSelectedAssetTypeLoose = () => {
const assetType = useMatches({
select: useMemoizedFn((matches) => {
return [...matches].reverse().find(({ staticData }) => staticData?.assetType)?.staticData
?.assetType;
}),
});
return useMemo(() => assetType as unknown as AssetType, [assetType]);
};

View File

@ -14,6 +14,12 @@ export const Route = createFileRoute('/app/_app/_asset')({
assetType,
};
},
loader: async ({ context }) => {
const { assetType } = context;
return {
assetType,
};
},
});
const stableCtxSelector = (ctx: RouteContext) => ctx.assetType;