fix(admin): adjust admin panel settings style (#11291)

Adjusted the style of some runtime configurations to match the new parameters.
Adjusted the style of dialog and right sidebar.

close AF-2411 AF-2412 AF-2413 AF-2422
This commit is contained in:
JimmFly
2025-03-31 10:26:07 +00:00
parent 51dddc10be
commit eda680ccdc
19 changed files with 202 additions and 88 deletions
@@ -7,6 +7,9 @@ import {
import { useCallback } from 'react';
import { NavLink } from 'react-router-dom';
import { buttonVariants } from '../../components/ui/button';
import { cn } from '../../utils';
export const CollapsibleItem = ({
title,
changeModule,
@@ -14,22 +17,12 @@ export const CollapsibleItem = ({
title: string;
changeModule?: (module: string) => void;
}) => {
const handleClick = useCallback(
(id: string) => {
const targetElement = document.getElementById(id);
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'center',
});
}
changeModule?.(title);
},
[changeModule, title]
);
const handleClick = useCallback(() => {
changeModule?.(title);
}, [changeModule, title]);
return (
<Accordion type="multiple" className="w-full ">
<AccordionItem value="item-1" className="border-b-0 ml-7 ">
<Accordion type="multiple" className="w-full">
<AccordionItem value="item-1" className="border-b-0 ml-7">
<NavLink
to={`/admin/settings/${title}`}
className={({ isActive }) => {
@@ -39,7 +32,7 @@ export const CollapsibleItem = ({
}}
>
<AccordionTrigger
onClick={() => handleClick(title)}
onClick={handleClick}
className="py-2 px-2 rounded [&[data-state=closed]>svg]:rotate-270 [&[data-state=open]>svg]:rotate-360"
>
{title}
@@ -50,6 +43,36 @@ export const CollapsibleItem = ({
);
};
export const NormalSubItem = ({
title,
changeModule,
}: {
title: string;
changeModule?: (module: string) => void;
}) => {
const handleClick = useCallback(() => {
changeModule?.(title);
}, [changeModule, title]);
return (
<div className="w-full flex">
<NavLink
to={`/admin/settings/${title}`}
onClick={handleClick}
className={({ isActive }) => {
return cn(
buttonVariants({
variant: 'ghost',
className: `ml-8 px-2 w-full justify-start ${isActive ? 'bg-zinc-100' : ''}`,
})
);
}}
>
{title}
</NavLink>
</div>
);
};
export const OtherModules = ({
moduleList,
changeModule,
@@ -58,14 +81,14 @@ export const OtherModules = ({
changeModule?: (module: string) => void;
}) => {
return (
<Accordion type="multiple" className="w-full ">
<Accordion type="multiple" className="w-full">
<AccordionItem value="item-1" className="border-b-0">
<AccordionTrigger className="ml-7 py-2 px-2 rounded [&[data-state=closed]>svg]:rotate-270 [&[data-state=open]>svg]:rotate-360">
<AccordionTrigger className="ml-8 py-2 px-2 rounded [&[data-state=closed]>svg]:rotate-270 [&[data-state=open]>svg]:rotate-360">
Other
</AccordionTrigger>
<AccordionContent className="flex flex-col gap-2 py-1">
<AccordionContent className="flex flex-col gap-1 py-1">
{moduleList.map(module => (
<CollapsibleItem
<NormalSubItem
key={module}
title={module}
changeModule={changeModule}
@@ -33,12 +33,15 @@ export const ServerVersion = () => {
}
return (
<div
className="flex items-center justify-between pt-2 border-t px-2 text-xs"
className="inline-flex items-center justify-between pt-2 border-t px-2 text-xs flex-nowrap gap-1"
style={{
color: cssVarV2('text/tertiary'),
}}
>
ServerVersion<span>v{version}</span>
<span>ServerVersion</span>
<span className="overflow-hidden text-ellipsis" title={version}>
v{version}
</span>
</div>
);
};
@@ -13,7 +13,7 @@ import { cssVarV2 } from '@toeverything/theme/v2';
import { NavLink } from 'react-router-dom';
import { ALL_CONFIGURABLE_MODULES } from '../settings/config';
import { CollapsibleItem, OtherModules } from './collapsible-item';
import { NormalSubItem, OtherModules } from './collapsible-item';
import { useNav } from './context';
const authModule = ALL_CONFIGURABLE_MODULES.find(module => module === 'auth');
@@ -53,13 +53,35 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
</NavigationMenuPrimitive.Trigger>
<NavigationMenuPrimitive.Content>
<ul
className="border rounded-lg w-full flex flex-col p-1"
className="border rounded-lg w-full flex flex-col p-1 min-w-[160px] max-h-[200px] overflow-y-auto"
style={{
backgroundColor: cssVarV2('layer/background/overlayPanel'),
borderColor: cssVarV2('layer/insideBorder/blackBorder'),
}}
>
{ALL_CONFIGURABLE_MODULES.map(module => (
{authModule ? (
<li key={authModule} className="flex">
<NavLink
to={`/admin/settings/${authModule}`}
className={cn(
buttonVariants({
variant: 'ghost',
className:
'p-2 rounded-[6px] text-[14px] w-full justify-start font-normal',
})
)}
style={({ isActive }) => ({
backgroundColor: isActive
? cssVarV2('selfhost/button/sidebarButton/bg/select')
: undefined,
})}
onClick={() => setCurrentModule?.(authModule)}
>
{authModule}
</NavLink>
</li>
) : null}
{otherModules.map(module => (
<li key={module} className="flex">
<NavLink
to={`/admin/settings/${module}`}
@@ -67,7 +89,7 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
buttonVariants({
variant: 'ghost',
className:
'p-1.5 rounded-[6px] text-[14px] w-full justify-start',
'p-2 rounded-[6px] text-[14px] w-full justify-start font-normal',
})
)}
style={({ isActive }) => ({
@@ -91,7 +113,7 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
}
return (
<Accordion type="multiple" className="w-full h-full overflow-hidden">
<Accordion type="multiple" className="w-full overflow-hidden">
<AccordionItem
value="item-1"
className="border-b-0 h-full flex flex-col gap-1 w-full"
@@ -130,7 +152,7 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit] [&>div]:!block">
{authModule && (
<CollapsibleItem
<NormalSubItem
title={authModule}
changeModule={setCurrentModule}
/>
@@ -24,6 +24,40 @@ interface UserDropdownProps {
isCollapsed: boolean;
}
const UserInfo = ({
name,
email,
avatarUrl,
}: {
email: string;
avatarUrl: string | null;
name?: string;
}) => {
return (
<>
<Avatar className="w-8 h-8">
<AvatarImage src={avatarUrl ?? undefined} />
<AvatarFallback>
<CircleUser size={32} />
</AvatarFallback>
</Avatar>
<div className="flex flex-col font-medium gap-1">
{name ?? email.split('@')[0]}
<span
className="w-fit rounded px-2 py-0.5 text-xs h-5 border text-center inline-flex items-center font-normal"
style={{
borderRadius: '4px',
backgroundColor: cssVarV2('chip/label/blue'),
borderColor: cssVarV2('layer/insideBorder/border'),
}}
>
Admin
</span>
</div>
</>
);
};
export function UserDropdown({ isCollapsed }: UserDropdownProps) {
const currentUser = useCurrentUser();
const relative = useRevalidateCurrentUser();
@@ -53,7 +87,15 @@ export function UserDropdown({ isCollapsed }: UserDropdownProps) {
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="right">
<DropdownMenuLabel>{currentUser?.name}</DropdownMenuLabel>
<DropdownMenuLabel className="flex items-center gap-2">
{currentUser ? (
<UserInfo
email={currentUser.email}
name={currentUser.name}
avatarUrl={currentUser.avatarUrl}
/>
) : null}
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onSelect={handleLogout}>Logout</DropdownMenuItem>
</DropdownMenuContent>
@@ -104,25 +146,13 @@ export function UserDropdown({ isCollapsed }: UserDropdownProps) {
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="right">
<DropdownMenuLabel className="flex items-center gap-2">
<Avatar className="w-8 h-8">
<AvatarImage src={currentUser?.avatarUrl ?? undefined} />
<AvatarFallback>
<CircleUser size={32} />
</AvatarFallback>
</Avatar>
<div className="flex flex-col font-medium gap-1">
{currentUser?.name ?? currentUser?.email.split('@')[0]}
<span
className="w-fit rounded px-2 py-0.5 text-xs h-5 border text-center inline-flex items-center font-normal"
style={{
borderRadius: '4px',
backgroundColor: cssVarV2('chip/label/blue'),
borderColor: cssVarV2('layer/insideBorder/border'),
}}
>
Admin
</span>
</div>
{currentUser ? (
<UserInfo
email={currentUser.email}
name={currentUser.name}
avatarUrl={currentUser.avatarUrl}
/>
) : null}
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onSelect={handleLogout}>Logout</DropdownMenuItem>