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)}
);
};