Fully customize menu items AntD

Now the menu items are following the order of resources of <Refine>. I want to have a fully customize menu list, in terms of create menu items that aren't link to any resources,...
8 Replies
kapa.ai
kapa.ai5mo ago
Hi @lukevo. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To fully customize the menu items in Ant Design with Refine, you can use the useMenu hook and the resources property of the <Refine> component. You can create an object array with the resources properties to customize your menu items. Here is an example:
<Refine
...
resources={[
{
name: "CMS",
},
{
name: "posts",
meta: { parent: "CMS" },
list: "/posts",
},
{
name: "category",
meta: { parent: "CMS", canDelete: true },
list: "/categories",
},
]}
/>
<Refine
...
resources={[
{
name: "CMS",
},
{
name: "posts",
meta: { parent: "CMS" },
list: "/posts",
},
{
name: "category",
meta: { parent: "CMS", canDelete: true },
list: "/categories",
},
]}
/>
In this example, the meta.parent you give in the resource objects must be strictly equal to the resource name you want to group under. If you want to create your multi-level menu without any UI framework integration, useMenu hook gives your resources. Here is an example:
import { useMenu } from "@refinedev/core";

export const Sider: React.FC = () => {
const { menuItems, selectedKey, defaultOpenKeys } = useMenu();

// Here create your Sider to your UI choice
};
import { useMenu } from "@refinedev/core";

export const Sider: React.FC = () => {
const { menuItems, selectedKey, defaultOpenKeys } = useMenu();

// Here create your Sider to your UI choice
};
You can also add custom items to the sider using the resources property on the <Refine> component. The <Sider> component shows the resources whose list property is set. So, you can have an extra navigation link by adding a resource with the list attribute. Here is an example:
import { Refine } from "@refinedev/core";

<Refine
...
resources={[
{
name: "dashboard",
list: "/",
meta: {
label: "Dashboard",
icon: "🏠",
},
},
]}
/>;
import { Refine } from "@refinedev/core";

<Refine
...
resources={[
{
name: "dashboard",
list: "/",
meta: {
label: "Dashboard",
icon: "🏠",
},
},
]}
/>;
For more examples of customization, you can check out these CodeSandbox examples: - Customization-top-menu-layout example (https://codesandbox.io/embed/github/refinedev/refine/tree/master/examples/customization-top-menu-layout?view=preview&amp;theme=dark&amp;codemirror=1) - Customization-theme-antd example (https://codesandbox.io/embed/github/refinedev/refine/tree/master/examples/customization-theme-antd?view=preview&amp;theme=dark&amp;codemirror=1) Sources: - Multi Level Menu Usage (https://refine.dev/docs/advanced-tutorials/multi-level-menu#usage) - How to hide items from the Sider component (https://refine.dev/docs/guides-concepts/faq#how-to-hide-items-from-the-sider-component) - How can I add an item to the Sider component (https://refine.dev/docs/guides-concepts/faq#how-can-i-add-an-item-to-the-sider-component) - Multi Level Menus Part 1 (https://refine.dev/docs/core/hooks/utilities/use-menu#multi-level-menus) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire
conscious-sapphire5mo ago
@kapa.ai basically I don't want the resources to automatically create menu items, I will manually create menu items how I want, multi level or not, all up to me with AntD and Refine
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To manually create menu items with AntD and Refine, you can use the useMenu hook from Refine. This hook provides you with the menuItems and selectedKey which you can use to create your own custom menu. Here is an example of how you can use the useMenu hook to create a custom menu:
import React from "react";
import { useMenu, LayoutProps, ITreeMenu } from "@refinedev/core";
import { Link } from "react-router-dom";

const Layout: React.FC<LayoutProps> = ({ children }) => {
const { menuItems, selectedKey } = useMenu();

const renderMenuItems = (items: ITreeMenu[]) => {
return (
<>
{items.map(({ key, name, label, icon, route, children, list }) => {
if (!list) {
return (
<li key={label}>
<span>{label ?? name}</span>
{children ? renderMenuItems(children) : null}
</li>
);
}

const isSelected = key === selectedKey;

return (
<li key={label}>
<Link
to={route}
style={{
fontWeight: isSelected ? "bold" : "normal",
}}
>
{icon}
<span>{label ?? name}</span>
</Link>
</li>
);
})}
</>
);
};

return (
<div>
<div>
<Link to="/">
<img src="<https://refine.dev/img/refine_logo.png"> alt="Logo" />
</Link>
<ul>{renderMenuItems(menuItems)}</ul>
</div>
<div>{children}</div>
</div>
);
};
import React from "react";
import { useMenu, LayoutProps, ITreeMenu } from "@refinedev/core";
import { Link } from "react-router-dom";

const Layout: React.FC<LayoutProps> = ({ children }) => {
const { menuItems, selectedKey } = useMenu();

const renderMenuItems = (items: ITreeMenu[]) => {
return (
<>
{items.map(({ key, name, label, icon, route, children, list }) => {
if (!list) {
return (
<li key={label}>
<span>{label ?? name}</span>
{children ? renderMenuItems(children) : null}
</li>
);
}

const isSelected = key === selectedKey;

return (
<li key={label}>
<Link
to={route}
style={{
fontWeight: isSelected ? "bold" : "normal",
}}
>
{icon}
<span>{label ?? name}</span>
</Link>
</li>
);
})}
</>
);
};

return (
<div>
<div>
<Link to="/">
<img src="<https://refine.dev/img/refine_logo.png"> alt="Logo" />
</Link>
<ul>{renderMenuItems(menuItems)}</ul>
</div>
<div>{children}</div>
</div>
);
};
In this example, the renderMenuItems function is used to render each menu item. You can customize this function to create your own menu structure. The menuItems array contains all the menu items, and the selectedKey is the key of the currently selected menu item. You can also customize the resources property of the <Refine> component to define your own resources and their properties. Sources: - Creating a Menu Part 1 (https://refine.dev/docs/core/hooks/utilities/use-menu#creating-a-menu) - Multi Level Menus Part 2 (https://refine.dev/docs/core/hooks/utilities/use-menu#multi-level-menus) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire
conscious-sapphire5mo ago
How to properly and conventionally implement rbac with AntD, Refine and Supabase @kapa.ai
kapa.ai
kapa.ai5mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To implement Role-Based Access Control (RBAC) with Ant Design, Refine, and Supabase, you can follow these steps: 1. Set up your project: Initialize your project with Refine and Supabase. You can use the create refine-app CLI tool to do this. Choose Supabase as your backend service and Ant Design as your UI Framework. Here's an example of how to do this:
npm create refine-app@latest pixels
npm create refine-app@latest pixels
And choose the following options:
Choose a project template · Refine(Vite)
What would you like to name your project?: · pixels
Choose your backend service to connect: · Supabase
Do you want to use a UI Framework?: · Ant Design
Do you want to add example pages?: · no
Do you need i18n (Internationalization) support?: · no
Choose a package manager: · npm
Choose a project template · Refine(Vite)
What would you like to name your project?: · pixels
Choose your backend service to connect: · Supabase
Do you want to use a UI Framework?: · Ant Design
Do you want to add example pages?: · no
Do you need i18n (Internationalization) support?: · no
Choose a package manager: · npm
This will create a Refine app that supports Ant Design in the UI and Supabase in the backend (source (https://refine.dev/blog/refine-pixels-2#project-setup)). 2. Define your roles and permissions: Define the roles and permissions for your application. For example, you might have an editor role that can promote and unpromote a canvas, and an admin role that can promote, unpromote, and delete a canvas (source (https://refine.dev/blog/refine-pixels-6#overview)). 3. Implement RBAC with Casbin: Use Casbin to manage RBAC and authorization. You can use Refine's accessControlProvider and associated hooks to enforce policies for these roles. For example, you might use the can method to check if a user has permission to perform a certain action (source (https://refine.dev/blog/refine-pixels-6#refine-can-method)). 4. Store user roles with Supabase Custom Claims: Use Supabase Custom Claims to set and store user roles in the auth.users table. This allows you to manage user roles and permissions in your Supabase database (source (https://refine.dev/blog/refine-pixels-6#overview)). 5. Use Refine's Ant Design package for UI: Refine's Ant Design package provides components that support authorization. For example, the <DeleteButton /> component is enabled or disabled based on the result of access control enforcement (source (https://refine.dev/blog/refine-pixels-6#refine-can-method)). 6. Get roles from Supabase database: Use the authProvider's getPermissions() method to get the roles from your Supabase database (source (https://refine.dev/blog/refine-pixels-6#refine-can-method)). For more detailed instructions and examples, you can refer to the Refine Pixels blog series (https://refine.dev/blog/refine-pixels-6#overview), which provides a step-by-step guide on how to implement RBAC with Refine, Ant Design, and Supabase. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below