CI / changes (push) Successful in 8s
CI / commitlint (push) Skipped
CI / openapi (push) Successful in 40s
CI / web (push) Successful in 55s
CI / go (push) Successful in 1m9s
CI / bird2 (push) Successful in 16s
CI / release (push) Successful in 4m6s
Refactored the settings components to unify navigation between UI and BIRD settings. Updated tab structures to streamline access and improve user experience. Adjusted routing and search parameters to reflect the new tab organization, ensuring a cohesive interface. Removed legacy tenant settings references and enhanced the settings page layout for clarity and usability.
105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
import { Link } from '@tanstack/react-router'
|
|
import { LayoutGridIcon } from 'lucide-react'
|
|
import { Button } from '@evobgp/ui/components/button'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@evobgp/ui/components/dropdown-menu'
|
|
import {
|
|
APP_SWITCHER_ICONS,
|
|
CURRENT_APP_ID,
|
|
} from '@/lib/app-switcher-config'
|
|
import { useAppSwitcherConfig } from '@/hooks/use-app-switcher'
|
|
import { authPortalUrl, isAuthEnabled } from '@/lib/auth'
|
|
|
|
/** Header apps grid — app-shell-12 AppsMenu. @see https://reui.io/preview/base/app-shell-12 */
|
|
export function AppsMenu() {
|
|
const { config, isLoading } = useAppSwitcherConfig()
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger
|
|
render={
|
|
<Button variant="ghost" size="icon" aria-label="Приложения" />
|
|
}
|
|
>
|
|
<LayoutGridIcon
|
|
className="size-4.5 transition-colors"
|
|
aria-hidden="true"
|
|
/>
|
|
</DropdownMenuTrigger>
|
|
|
|
<DropdownMenuContent
|
|
side="bottom"
|
|
align="end"
|
|
sideOffset={8}
|
|
className="w-72"
|
|
>
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuLabel>
|
|
{isLoading ? 'Загрузка…' : config.menuLabel}
|
|
</DropdownMenuLabel>
|
|
<div className="grid grid-cols-3 gap-1 p-1">
|
|
{config.apps.map((app) => {
|
|
const Icon = APP_SWITCHER_ICONS[app.icon]
|
|
const isCurrent = app.id === CURRENT_APP_ID
|
|
|
|
if (isCurrent) {
|
|
return (
|
|
<DropdownMenuItem
|
|
key={app.id}
|
|
disabled
|
|
className="h-auto flex-col gap-1.5 py-3 text-center [&_svg]:size-5"
|
|
>
|
|
<span className="text-muted-foreground">
|
|
<Icon aria-hidden="true" />
|
|
</span>
|
|
<span className="text-xs font-medium">{app.name}</span>
|
|
</DropdownMenuItem>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<DropdownMenuItem
|
|
key={app.id}
|
|
nativeButton={false}
|
|
render={<a href={app.url} />}
|
|
className="h-auto flex-col gap-1.5 py-3 text-center [&_svg]:size-5"
|
|
>
|
|
<span className="text-muted-foreground">
|
|
<Icon aria-hidden="true" />
|
|
</span>
|
|
<span className="text-xs font-medium">{app.name}</span>
|
|
</DropdownMenuItem>
|
|
)
|
|
})}
|
|
</div>
|
|
<DropdownMenuSeparator />
|
|
{isAuthEnabled() ? (
|
|
<DropdownMenuItem
|
|
nativeButton={false}
|
|
render={<a href={authPortalUrl()} />}
|
|
className="justify-center text-sm font-medium"
|
|
>
|
|
Настроить на портале
|
|
</DropdownMenuItem>
|
|
) : (
|
|
<DropdownMenuItem
|
|
nativeButton={false}
|
|
render={<Link to="/settings" search={{ tab: 'ui' }} />}
|
|
className="justify-center text-sm font-medium"
|
|
>
|
|
Настройки
|
|
</DropdownMenuItem>
|
|
)}
|
|
</DropdownMenuGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|