import { createElement } from "react"; import { useCanAccess, useCreatePath, useGetResourceLabel, useHasDashboard, useResourceDefinitions, useTranslate, } from "ra-core"; import { Link, useMatch } from "react-router"; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar"; import { Skeleton } from "@/components/ui/skeleton"; import { House, List, Shell } from "lucide-react"; /** * Navigation sidebar displaying menu items, allowing users to navigate between different sections of the application. * * The sidebar can collapse to an icon-only view and renders as a collapsible drawer on mobile devices. * It automatically includes links to the dashboard (if defined) and all list views defined in Resource components. * * Included in the default Layout component * * @see {@link https://marmelab.com/shadcn-admin-kit/docs/appsidebar AppSidebar documentation} * @see {@link https://ui.shadcn.com/docs/components/sidebar shadcn/ui Sidebar component} * @see layout.tsx */ export function AppSidebar() { const hasDashboard = useHasDashboard(); const resources = useResourceDefinitions(); const { openMobile, setOpenMobile } = useSidebar(); const handleClick = () => { if (openMobile) { setOpenMobile(false); } }; return ( Acme Inc. {hasDashboard ? ( ) : null} {Object.keys(resources) .filter((name) => resources[name].hasList) .map((name) => ( ))} ); } /** * Menu item for the dashboard link in the sidebar. * * This component renders a sidebar menu item that links to the dashboard page. * It displays as active when the user is on the dashboard route. * * @example * */ export const DashboardMenuItem = ({ onClick }: { onClick?: () => void }) => { const translate = useTranslate(); const label = translate("ra.page.dashboard", { _: "Dashboard", }); const match = useMatch({ path: "/", end: true }); return ( {label} ); }; /** * Menu item for a resource link in the sidebar. * * This component renders a sidebar menu item that links to a resource's list view. * It checks permissions using canAccess and displays as active when the user is viewing that resource. * The component icon and label are derived from the resource definition. * * @example * */ export const ResourceMenuItem = ({ name, onClick, }: { name: string; onClick?: () => void; }) => { const { canAccess, isPending } = useCanAccess({ resource: name, action: "list", }); const resources = useResourceDefinitions(); const getResourceLabel = useGetResourceLabel(); const createPath = useCreatePath(); const to = createPath({ resource: name, type: "list", }); const match = useMatch({ path: to, end: false }); if (isPending) { return ; } if (!resources || !resources[name] || !canAccess) return null; return ( {resources[name].icon ? ( createElement(resources[name].icon) ) : ( )} {getResourceLabel(name, 2)} ); };