feat(admin): adapt new config system (#11360)

feat(server): add test mail api

feat(admin): adapt new config system
This commit is contained in:
forehalo
2025-04-01 15:00:10 +00:00
parent 8427293d36
commit dad858014f
29 changed files with 718 additions and 400 deletions

View File

@@ -1,62 +1,25 @@
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from '@affine/admin/components/ui/accordion';
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,
}: {
title: string;
changeModule?: (module: string) => void;
}) => {
const handleClick = useCallback(() => {
changeModule?.(title);
}, [changeModule, title]);
return (
<Accordion type="multiple" className="w-full">
<AccordionItem value="item-1" className="border-b-0 ml-7">
<NavLink
to={`/admin/settings/${title}`}
className={({ isActive }) => {
return isActive
? 'w-full bg-zinc-100 inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
: '';
}}
>
<AccordionTrigger
onClick={handleClick}
className="py-2 px-2 rounded [&[data-state=closed]>svg]:rotate-270 [&[data-state=open]>svg]:rotate-360"
>
{title}
</AccordionTrigger>
</NavLink>
</AccordionItem>
</Accordion>
);
};
export const NormalSubItem = ({
module,
title,
changeModule,
}: {
module: string;
title: string;
changeModule?: (module: string) => void;
}) => {
const handleClick = useCallback(() => {
changeModule?.(title);
}, [changeModule, title]);
changeModule?.(module);
}, [changeModule, module]);
return (
<div className="w-full flex">
<NavLink
to={`/admin/settings/${title}`}
to={`/admin/settings/${module}`}
onClick={handleClick}
className={({ isActive }) => {
return cn(
@@ -72,30 +35,3 @@ export const NormalSubItem = ({
</div>
);
};
export const OtherModules = ({
moduleList,
changeModule,
}: {
moduleList: string[];
changeModule?: (module: string) => void;
}) => {
return (
<Accordion type="multiple" className="w-full">
<AccordionItem value="item-1" className="border-b-0">
<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-1 py-1">
{moduleList.map(module => (
<NormalSubItem
key={module}
title={module}
changeModule={changeModule}
/>
))}
</AccordionContent>
</AccordionItem>
</Accordion>
);
};

View File

@@ -98,9 +98,9 @@ export function Nav({ isCollapsed = false }: NavProps) {
/>
<SettingsItem isCollapsed={isCollapsed} />
<NavItem
to="/admin/config"
to="/admin/about"
icon={<SelfhostIcon fontSize={20} />}
label="Server"
label="About"
isCollapsed={isCollapsed}
/>
</nav>

View File

@@ -12,15 +12,10 @@ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
import { cssVarV2 } from '@toeverything/theme/v2';
import { NavLink } from 'react-router-dom';
import { ALL_CONFIGURABLE_MODULES } from '../settings/config';
import { NormalSubItem, OtherModules } from './collapsible-item';
import { KNOWN_CONFIG_GROUPS, UNKNOWN_CONFIG_GROUPS } from '../settings/config';
import { NormalSubItem } from './collapsible-item';
import { useNav } from './context';
const authModule = ALL_CONFIGURABLE_MODULES.find(module => module === 'auth');
const otherModules = ALL_CONFIGURABLE_MODULES.filter(
module => module !== 'auth'
);
export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
const { setCurrentModule } = useNav();
@@ -59,10 +54,10 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
borderColor: cssVarV2('layer/insideBorder/blackBorder'),
}}
>
{authModule ? (
<li key={authModule} className="flex">
{KNOWN_CONFIG_GROUPS.map(group => (
<li key={group.module} className="flex">
<NavLink
to={`/admin/settings/${authModule}`}
to={`/admin/settings/${group.module}`}
className={cn(
buttonVariants({
variant: 'ghost',
@@ -75,16 +70,16 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
? cssVarV2('selfhost/button/sidebarButton/bg/select')
: undefined,
})}
onClick={() => setCurrentModule?.(authModule)}
onClick={() => setCurrentModule?.(group.module)}
>
{authModule}
{group.name}
</NavLink>
</li>
) : null}
{otherModules.map(module => (
<li key={module} className="flex">
))}
{UNKNOWN_CONFIG_GROUPS.map(group => (
<li key={group.module} className="flex">
<NavLink
to={`/admin/settings/${module}`}
to={`/admin/settings/${group.module}`}
className={cn(
buttonVariants({
variant: 'ghost',
@@ -97,9 +92,9 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
? cssVarV2('selfhost/button/sidebarButton/bg/select')
: undefined,
})}
onClick={() => setCurrentModule?.(module)}
onClick={() => setCurrentModule?.(group.module)}
>
{module}
{group.name}
</NavLink>
</li>
))}
@@ -151,18 +146,31 @@ export const SettingsItem = ({ isCollapsed }: { isCollapsed: boolean }) => {
className={cn('relative overflow-hidden w-full h-full')}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit] [&>div]:!block">
{authModule && (
{KNOWN_CONFIG_GROUPS.map(group => (
<NormalSubItem
title={authModule}
key={group.module}
module={group.module}
title={group.name}
changeModule={setCurrentModule}
/>
)}
{otherModules.length > 0 && (
<OtherModules
moduleList={otherModules}
changeModule={setCurrentModule}
/>
)}
))}
<Accordion type="multiple" className="w-full">
<AccordionItem value="item-1" className="border-b-0">
<AccordionTrigger className="ml-8 py-2 px-2 rounded [&[data-state=closed]>svg]:rotate-270 [&[data-state=open]>svg]:rotate-360">
Experimental
</AccordionTrigger>
<AccordionContent className="flex flex-col gap-1 py-1">
{UNKNOWN_CONFIG_GROUPS.map(group => (
<NormalSubItem
key={group.module}
module={group.module}
title={group.name}
changeModule={setCurrentModule}
/>
))}
</AccordionContent>
</AccordionItem>
</Accordion>
</ScrollAreaPrimitive.Viewport>
<ScrollAreaPrimitive.ScrollAreaScrollbar
className={cn(