Добавлен audit log (solution-users-6) с retention N дней и hourly purge; таблица пользователей приведена к DNA solution-users-1 (Filters, avatar, sorting). Co-authored-by: Cursor <[email protected]>
108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
import { Link, useRouterState } from '@tanstack/react-router'
|
|
import { useQuery } from '@tanstack/react-query'
|
|
import {
|
|
AppWindowIcon,
|
|
HistoryIcon,
|
|
LayoutGridIcon,
|
|
UsersIcon,
|
|
} from 'lucide-react'
|
|
import { AppSwitcher } from '@/components/app-switcher'
|
|
import { NavUser } from '@/components/nav-user'
|
|
import { meQueryOptions } from '@/queries/auth'
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarFooter,
|
|
SidebarGroup,
|
|
SidebarGroupContent,
|
|
SidebarGroupLabel,
|
|
SidebarHeader,
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
} from '@authportal/ui/components/sidebar'
|
|
|
|
function isActive(pathname: string, to: string, exact: boolean) {
|
|
if (exact) return pathname === to
|
|
return pathname === to || pathname.startsWith(`${to}/`)
|
|
}
|
|
|
|
export function AppSidebar() {
|
|
const pathname = useRouterState({ select: (s) => s.location.pathname })
|
|
const { data: me } = useQuery(meQueryOptions)
|
|
|
|
return (
|
|
<Sidebar collapsible="icon">
|
|
<SidebarHeader>
|
|
<AppSwitcher />
|
|
</SidebarHeader>
|
|
<SidebarContent>
|
|
<SidebarGroup>
|
|
<SidebarGroupLabel>Портал</SidebarGroupLabel>
|
|
<SidebarGroupContent>
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton
|
|
tooltip="Приложения"
|
|
isActive={isActive(pathname, '/apps', true)}
|
|
render={<Link to="/apps" />}
|
|
>
|
|
<LayoutGridIcon className="size-4" />
|
|
<span>Приложения</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</SidebarGroupContent>
|
|
</SidebarGroup>
|
|
|
|
{me?.is_admin ? (
|
|
<SidebarGroup>
|
|
<SidebarGroupLabel>Админ</SidebarGroupLabel>
|
|
<SidebarGroupContent>
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton
|
|
tooltip="Пользователи"
|
|
isActive={
|
|
isActive(pathname, '/admin', false) &&
|
|
!pathname.startsWith('/admin/apps') &&
|
|
!pathname.startsWith('/admin/audit')
|
|
}
|
|
render={<Link to="/admin" />}
|
|
>
|
|
<UsersIcon className="size-4" />
|
|
<span>Пользователи</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton
|
|
tooltip="Журнал"
|
|
isActive={isActive(pathname, '/admin/audit', false)}
|
|
render={<Link to="/admin/audit" />}
|
|
>
|
|
<HistoryIcon className="size-4" />
|
|
<span>Журнал</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton
|
|
tooltip="Приложения"
|
|
isActive={isActive(pathname, '/admin/apps', false)}
|
|
render={<Link to="/admin/apps" />}
|
|
>
|
|
<AppWindowIcon className="size-4" />
|
|
<span>Ссылки приложений</span>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</SidebarGroupContent>
|
|
</SidebarGroup>
|
|
) : null}
|
|
</SidebarContent>
|
|
<SidebarFooter>
|
|
<NavUser />
|
|
</SidebarFooter>
|
|
</Sidebar>
|
|
)
|
|
}
|