fix sidebar settings for interfaces

This commit is contained in:
Nate Kelley 2025-03-13 14:57:00 -06:00
parent 4fa7e92a38
commit 3ecdf641d3
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
13 changed files with 66 additions and 36 deletions

View File

@ -1,8 +1,8 @@
export enum VerificationStatus {
NOT_REQUESTED = 'NOT REQUESTED',
REQUESTED = 'REQUESTED',
IN_REVIEW = 'IN REVIEW',
VERIFIED = 'VERIFIED',
BACKLOGGED = 'BACKLOGGED',
NOT_VERIFIED = 'NOT VERIFIED'
NOT_REQUESTED = 'notRequested',
REQUESTED = 'requested',
IN_REVIEW = 'inReview',
VERIFIED = 'verified',
BACKLOGGED = 'backlogged',
NOT_VERIFIED = 'notVerified'
}

View File

@ -5,6 +5,7 @@ import { useMemoizedFn } from '@/hooks';
import { Button } from '@/components/ui/buttons';
import { cn } from '@/lib/classMerge';
import { Star } from '@/components/ui/icons';
import { Star as StarFilled } from '@/components/ui/icons/NucleoIconFilled';
import { cva } from 'class-variance-authority';
import {
useAddUserFavorite,
@ -62,7 +63,7 @@ export const FavoriteStar: React.FC<{
return (
<AppTooltip title={tooltipText} key={tooltipText}>
<Button
className={cn(className, 'flex')}
className={cn('flex transition-none', isFavorited && 'opacity-100!', className)}
onClick={onFavoriteClick}
variant="ghost"
prefix={
@ -73,7 +74,7 @@ export const FavoriteStar: React.FC<{
isFavorited
})
)}>
<Star />
{isFavorited ? <StarFilled /> : <Star />}
</div>
}
/>

View File

@ -26,17 +26,15 @@ export const StatusBadgeIndicator: React.FC<{
const isNotVerified =
status === VerificationStatus.NOT_VERIFIED || VerificationStatus.NOT_REQUESTED;
const sharedClass = cn(`flex items-center justify-center rounded-full`, colorClasses);
const _size = isNotVerified ? size : 16;
return (
<AppTooltip title={showTooltip ? tooltipText : ''}>
<div
className={`rounded-full ${className} ${sharedClass} ${isNotVerified ? '' : ''}`}
style={{
width: _size,
height: _size
width: size,
height: size
}}>
<Icon size={_size} />
<Icon size={size} />
</div>
</AppTooltip>
);
@ -54,6 +52,7 @@ const statusRecordIcon: Record<VerificationStatus, React.FC<any>> = {
};
const getIcon = (status: BusterMetricListItem['status']) => {
console.log(status, statusRecordIcon);
return statusRecordIcon[status] || (() => <React.Fragment />);
};

View File

@ -1,8 +1,8 @@
import type { Meta, StoryObj } from '@storybook/react';
import { SidebarPrimary } from './SidebarPrimary';
import { BusterRoutes, createBusterRoute } from '@/routes';
import { ShareAssetType } from '@/api/asset_interfaces/share/shareInterfaces';
import { BusterRoutes, createBusterRoute } from '../../../routes';
import { ShareAssetType } from '../../../api/asset_interfaces/share';
import React from 'react';
const meta: Meta<typeof SidebarPrimary> = {
title: 'Features/Sidebars/SidebarPrimary',
component: SidebarPrimary,

View File

@ -18,9 +18,14 @@ import { SupportModal } from '../modal/SupportModal';
import { InvitePeopleModal } from '../modal/InvitePeopleModal';
import { useMemoizedFn } from '@/hooks';
import { SidebarUserFooter } from './SidebarUserFooter/SidebarUserFooter';
import { useGetUserFavorites, useUpdateUserFavorites } from '@/api/buster_rest';
import {
useDeleteUserFavorite,
useGetUserFavorites,
useUpdateUserFavorites
} from '@/api/buster_rest';
const topItems: ISidebarList = {
id: 'top-items',
items: [
{
label: 'Home',
@ -39,6 +44,7 @@ const topItems: ISidebarList = {
const yourStuff: ISidebarGroup = {
label: 'Your stuff',
id: 'your-stuff',
items: [
{
label: 'Metrics',
@ -63,6 +69,7 @@ const yourStuff: ISidebarGroup = {
const adminTools: ISidebarGroup = {
label: 'Admin tools',
id: 'admin-tools',
items: [
{
label: 'Logs',
@ -90,6 +97,7 @@ const tryGroup = (
onClickLeaveFeedback: () => void
): ISidebarGroup => ({
label: 'Try',
id: 'try',
items: [
{
label: 'Invite people',
@ -115,6 +123,7 @@ export const SidebarPrimary = React.memo(() => {
const onToggleInviteModal = useAppLayoutContextSelector((s) => s.onToggleInviteModal);
const [openSupportModal, setOpenSupportModal] = useState(false);
const { mutateAsync: updateUserFavorites } = useUpdateUserFavorites();
const { mutateAsync: deleteUserFavorite } = useDeleteUserFavorite();
const onFavoritesReorder = useMemoizedFn((itemIds: string[]) => {
updateUserFavorites(itemIds);
@ -130,7 +139,7 @@ export const SidebarPrimary = React.memo(() => {
items.push(yourStuff);
if (favorites && favorites.length > 0) {
items.push(favoritesDropdown(favorites, onFavoritesReorder));
items.push(favoritesDropdown(favorites, { deleteUserFavorite, onFavoritesReorder }));
}
items.push(tryGroup(onToggleInviteModal, () => setOpenSupportModal(true)));
@ -213,12 +222,19 @@ GlobalModals.displayName = 'GlobalModals';
const favoritesDropdown = (
favorites: BusterUserFavorite[],
onItemsReorder: (itemIds: string[]) => void
{
onFavoritesReorder,
deleteUserFavorite
}: {
onFavoritesReorder: (itemIds: string[]) => void;
deleteUserFavorite: (itemId: string) => void;
}
): ISidebarGroup => {
return {
label: 'Favorites',
id: 'favorites',
isSortable: true,
onItemsReorder,
onItemsReorder: onFavoritesReorder,
items: favorites.map((favorite) => {
const Icon = assetTypeToIcon(favorite.asset_type);
const route = assetTypeToRoute(favorite.asset_type, favorite.id);
@ -226,7 +242,8 @@ const favoritesDropdown = (
label: favorite.name,
icon: <Icon />,
route,
id: route
id: route,
onRemove: () => deleteUserFavorite(favorite.id)
};
})
};

View File

@ -1,5 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';
import { SidebarSettings } from './SidebarSettings';
import React from 'react';
const meta: Meta<typeof SidebarSettings> = {
title: 'Features/Sidebars/SidebarSettings',

View File

@ -12,6 +12,7 @@ import { SidebarUserFooter } from './SidebarUserFooter/SidebarUserFooter';
const accountItems: ISidebarGroup = {
label: 'Account',
variant: 'icon',
id: 'account',
icon: <CircleUser />,
items: [
{
@ -25,6 +26,7 @@ const accountItems: ISidebarGroup = {
const workspaceItems: ISidebarGroup = {
label: 'Workspace',
variant: 'icon',
id: 'workspace',
icon: <ApartmentBuilding />,
items: [
{
@ -38,6 +40,7 @@ const workspaceItems: ISidebarGroup = {
const permissionAndSecurityItems: ISidebarGroup = {
label: 'Permission & Security',
variant: 'icon',
id: 'permission-and-security',
icon: <LockCircle />,
items: [
{

View File

@ -2,21 +2,16 @@ import React from 'react';
import { ISidebarGroup, ISidebarList, SidebarProps } from './interfaces';
import { SidebarCollapsible } from './SidebarCollapsible';
import { SidebarItem } from './SidebarItem';
import { useMemoizedFn } from '@/hooks';
export const Sidebar: React.FC<SidebarProps> = React.memo(
({ header, content, footer, activeItem }) => {
const onItemsReorder = useMemoizedFn((ids: string[], contentIndex: number) => {
console.log('onItemsReorder', ids);
});
return (
<div className="flex h-full flex-col overflow-hidden px-3.5 pt-4.5">
<div className="flex flex-col space-y-4.5 overflow-hidden">
<div className="mb-5"> {header}</div>
<div className="flex flex-grow flex-col space-y-4.5 overflow-y-auto pb-3">
{content.map((item, index) => (
<ContentSelector key={index} content={item} activeItem={activeItem} />
{content.map((item) => (
<ContentSelector key={item.id} content={item} activeItem={activeItem} />
))}
</div>
</div>

View File

@ -1,6 +1,6 @@
'use client';
import React from 'react';
import React, { useEffect } from 'react';
import {
Collapsible,
CollapsibleContent,
@ -118,7 +118,11 @@ export const SidebarCollapsible: React.FC<
const [draggingId, setDraggingId] = React.useState<string | null>(null);
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(PointerSensor, {
activationConstraint: {
distance: 2
}
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates
})
@ -145,6 +149,10 @@ export const SidebarCollapsible: React.FC<
const draggingItem = draggingId ? sortedItems.find((item) => item.id === draggingId) : null;
useEffect(() => {
setSortedItems(items);
}, [items]);
return (
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="space-y-0.5">
{variant === 'collapsible' && (

View File

@ -1,8 +1,8 @@
import type { Meta, StoryObj } from '@storybook/react';
import { SidebarItem } from './SidebarItem';
import { HouseModern } from '@/components/ui/icons';
import { BusterRoutes } from '@/routes';
import { HouseModern } from '../icons/NucleoIconOutlined';
import { BusterRoutes } from '../../../routes';
import React from 'react';
const meta: Meta<typeof SidebarItem> = {
title: 'UI/Sidebar/SidebarItem',
component: SidebarItem,

View File

@ -83,7 +83,7 @@ export const SidebarItem: React.FC<
href={route || ''}
className={cn(itemVariants({ active, disabled, variant }), className)}
onClick={onClick}>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 overflow-hidden">
<span
className={cn('text-icon-size! text-icon-color', {
'text-text-disabled': disabled,
@ -99,7 +99,11 @@ export const SidebarItem: React.FC<
variant="ghost"
size={'small'}
prefix={<Xmark />}
onClick={onRemove}></Button>
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
onRemove();
}}></Button>
)}
</ItemNode>
);

View File

@ -14,6 +14,7 @@ export interface ISidebarItem {
export interface ISidebarGroup {
label: string;
icon?: React.ReactNode;
id: string;
items: ISidebarItem[];
variant?: 'collapsible' | 'icon'; //default is collapsible
defaultOpen?: boolean; //will default to true
@ -23,6 +24,7 @@ export interface ISidebarGroup {
export interface ISidebarList {
items: ISidebarItem[];
id: string;
}
type SidebarContent = ISidebarGroup | ISidebarList;

View File

@ -13,7 +13,7 @@ const TooltipTrigger = TooltipPrimitive.Trigger;
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 6, ...props }, ref) => (
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}