diff --git a/docs/AuthRBAC.md b/docs/AuthRBAC.md index 877773b46a..c6578472bd 100644 --- a/docs/AuthRBAC.md +++ b/docs/AuthRBAC.md @@ -104,15 +104,15 @@ React-admin already does page-level access control with actions like "list", "sh | Action | Description | Used In | | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------- | -| `list` | Allow to access the List page | [``](#list), [``](./Buttons.md#listbutton), [``](#menu) | -| `show` | Allow to access the Show page | [``](./Show.md), [``](./Buttons.md#showbutton), [``](#datagrid), [``](./Edit.md) | -| `create` | Allow to access the Create page | [``](./Create.md), [``](./Buttons.md#createbutton), [``](#list) | -| `edit` | Allow to access the Edit page | [``](./Edit.md), [``](./Buttons.md#editbutton), [``](#datagrid), [``](./Show.md) | -| `delete` | Allow to delete data | [``](./Buttons.md#deletebutton), [``](./Buttons.md#bulkdeletebutton), [``](#datagrid), [``](#simpleform), [``](#tabform) | -| `export` | Allow to export data | [``](#exportbutton), [``](#list) | +| `list` | Allow to access the List page | [``](./List.md#access-control), [``](./Buttons.md#listbutton), [``](./Menu.md#access-control) | +| `show` | Allow to access the Show page | [``](./Show.md), [``](./Buttons.md#showbutton), [``](./Datagrid.md#access-control), [``](./Edit.md) | +| `create` | Allow to access the Create page | [``](./Create.md), [``](./Buttons.md#createbutton), [``](./List.md#access-control) | +| `edit` | Allow to access the Edit page | [``](./Edit.md), [``](./Buttons.md#editbutton), [``](./Datagrid.md#access-control), [``](./Show.md) | +| `delete` | Allow to delete data | [``](./Buttons.md#deletebutton), [``](./Buttons.md#bulkdeletebutton), [``](./Datagrid.md#access-control), [``](./SimpleForm.md#access-control), [``](#tabform) | +| `export` | Allow to export data | [``](#exportbutton), [``](./List.md#access-control) | | `clone` | Allow to clone a record | [``](#clonebutton), [``](./Edit.md) | -| `read` | Allow to view a field (or a tab) | [``](#datagrid), [``](#simpleshowlayout), [``](#tabbedshowlayout) | -| `write` | Allow to edit a field (or a tab) | [``](#simpleform), [``](#tabbedform), [``](./WizardForm.md#enableaccesscontrol), [``](./LongForm.md#enableaccesscontrol), [``](./AccordionForm.md#enableaccesscontrol) | +| `read` | Allow to view a field (or a tab) | [``](./Datagrid.md#access-control), [``](./SimpleShowLayout.md#access-control), [``](./TabbedShowLayout.md#access-control) | +| `write` | Allow to edit a field (or a tab) | [``](./SimpleForm.md#access-control), [``](./TabbedForm.md#access-control), [``](./WizardForm.md#enableaccesscontrol), [``](./LongForm.md#enableaccesscontrol), [``](./AccordionForm.md#enableaccesscontrol) | **Tip:** Be sure not to confuse "show" and "read", or "edit" and "write", as they are not the same. The first operate at the page level, the second at the field level. A good mnemonic is to realize "show" and "edit" are named the same as the react-admin page they allow to control: the Show and Edit pages. @@ -192,10 +192,10 @@ const perm4 = { action: 'write', resource: 'users.username', record: { id: '123' Only record-level components can perform record-level permissions checks. Below is the list of components that support them: -- [``](#simpleshowlayout) -- [``](#tabbedshowlayout) -- [``](#simpleform) -- [``](#tabbedform) +- [``](./SimpleShowLayout.md#access-control) +- [``](./TabbedShowLayout.md#access-control) +- [``](./SimpleForm.md#access-control) +- [``](./TabbedForm.md#access-control) When you restrict permissions to a specific set of records, components that do not support record-level permissions (such as List Components) will ignore the record criteria and perform their checks at the resource-level only. @@ -370,8 +370,7 @@ Ra-rbac provides alternative components to react-admin base components. These al - [``](./TabbedShowLayout.md#access-control) - Form - [``](./SimpleForm.md#access-control) - - [``](#tabbedform) - - [``](#formtab) + - [``](./TabbedForm.md#access-control) ## `` @@ -411,121 +410,6 @@ It accepts the following props in addition to the default [`` prop { action: "read", resource: `${resource}.*` }. ``` - -## `` - -Replacement for react-admin's `` that adds RBAC control to the delete button (conditioned by the `'delete'` action) and only renders a tab if the user has the right permissions. - -Use in conjunction with [``](#tabbedformtab) and add a `name` prop to the `Tab` to define the resource on which the user needs to have the 'write' permissions for. - -**Tip:** [``](#tabbedformtab) also allows to only render the child inputs for which the user has the 'write' permissions. - -```jsx -import { Edit, TextInput } from 'react-admin'; -import { TabbedForm } from '@react-admin/ra-rbac'; - -const authProvider = { - // ... - canAccess: async ({ action, record, resource }) => - canAccessWithPermissions({ - permissions: [ - // action 'delete' is missing - { action: ['list', 'edit'], resource: 'products' }, - { action: 'write', resource: 'products.reference' }, - { action: 'write', resource: 'products.width' }, - { action: 'write', resource: 'products.height' }, - { action: 'write', resource: 'products.thumbnail' }, - { action: 'write', resource: 'products.tab.description' }, - // tab 'stock' is missing - { action: 'write', resource: 'products.tab.images' }, - ], - action, - record, - resource, - }), -}; - -const ProductEdit = () => ( - - - - - - - - - {/* the "Stock" tab is not displayed */} - - - - - - - - {/* the "Delete" button is not displayed */} - - -); -``` - -## `` - -Replacement for react-admin's `` that only renders a tab and its content if the user has the right permissions. - -Add a `name` prop to the `Tab` to define the resource on which the user needs to have the 'write' permissions for. - -`` also only renders the child inputs for which the user has the 'write' permissions. - -```tsx -import { Edit, TextInput } from 'react-admin'; -import { TabbedForm } from '@react-admin/ra-rbac'; - -const authProvider = { - // ... - canAccess: async ({ action, record, resource }) => - canAccessWithPermissions({ - permissions: [ - { action: ['list', 'edit'], resource: 'products' }, - { action: 'write', resource: 'products.reference' }, - { action: 'write', resource: 'products.width' }, - { action: 'write', resource: 'products.height' }, - // 'products.description' is missing - { action: 'write', resource: 'products.thumbnail' }, - // 'products.image' is missing - { action: 'write', resource: 'products.tab.description' }, - // 'products.tab.stock' is missing - { action: 'write', resource: 'products.tab.images' }, - ], - action, - record, - resource, - }) -}; - -const ProductEdit = () => ( - - - - - - - {/* Input Description is not displayed */} - - - {/* Input Stock is not displayed */} - - - - - {/* Input Image is not displayed */} - - - - - -); -``` - ## `` Replacement for react-admin's [``](./Buttons.md#clonebutton) that checks users have the `'clone'` permission before rendering. Use it if you want to provide your own `actions` to the ``: diff --git a/docs/TabbedForm.md b/docs/TabbedForm.md index 7923187c52..eb9c9bbc45 100644 --- a/docs/TabbedForm.md +++ b/docs/TabbedForm.md @@ -794,114 +794,116 @@ If you're using it in an `` page, you must also use a `pessimistic` or `op Check [the `` component](./AutoSave.md) documentation for more details. -## Displaying a Tab Based On Permissions +## Access Control -You can leverage [the `useCanAccess` hook](./useCanAccess.md) to display tabs if the user has the required access rights. +If you need to hide some tabs based on a set of permissions, use the `` component from the `@react-admin/ra-rbac` package. -{% raw %} -```jsx -import { Edit, FormTab, Loading, TabbedForm, TextInput, useCanAccess } from 'react-admin'; -import { Alert } from '@mui/material'; - -export const UserCreate = () => { - const { canAccess, isPending, error } = useCanAccess({ - resource: 'users.tabs.security', - action: 'write', - }); - if (isPending) return ; - if (error) { - return ( - - An error occurred while checking your permissions - - ); - } - - return ( - - - - ... - - {canAccess && - - ... - - } - - - ); -} +```diff +-import { TabbedForm } from 'react-admin'; ++import { TabbedForm } from '@react-admin/ra-rbac'; ``` -{% endraw %} -If you need to check access rights for multiple tabs, leverage [the `useCanAccessResources` hook](./useCanAccess.md#multiple-resources). +Use in conjunction with [``](#tabbedformtab) and add a `name` prop to the `Tab` to define the resource on which the user needs to have the 'write' permissions for. -{% raw %} ```jsx -import { Edit, Loading, TabbedForm, TextInput, useCanAccessResources } from 'react-admin'; -import { Alert } from '@mui/material'; - -export const UserEdit = () => { - const { canAccess, isPending, error } = useCanAccessResources({ - resources: ['users.tabs.summary', 'users.tabs.security'], - action: 'write', - }); - if (isPending) return ; - if (error) { - return ( - - An error occurred while checking your permissions - - ); - } +import { Edit, TextInput } from 'react-admin'; +import { TabbedForm } from '@react-admin/ra-rbac'; + +const authProvider = { + // ... + canAccess: async ({ action, record, resource }) => + canAccessWithPermissions({ + permissions: [ + // action 'delete' is missing + { action: ['list', 'edit'], resource: 'products' }, + { action: 'write', resource: 'products.reference' }, + { action: 'write', resource: 'products.width' }, + { action: 'write', resource: 'products.height' }, + { action: 'write', resource: 'products.thumbnail' }, + { action: 'write', resource: 'products.tab.description' }, + // tab 'stock' is missing + { action: 'write', resource: 'products.tab.images' }, + ], + action, + record, + resource, + }), +}; - return ( - - - {canAccess['users.tabs.summary'] && - - ... - } - {canAccess['users.tabs.security'] && - - ... - - } - - - ); -} +const ProductEdit = () => ( + + + + + + + + + {/* the "Stock" tab is not displayed */} + + + + + + + + {/* the "Delete" button is not displayed */} + + +); ``` -{% endraw %} - -## Displaying Inputs Based On Permissions -You can leverage [the `` component](./CanAccess.md) to display inputs if the user has the required access rights. +[``](#tabbedformtab) also renders only the child inputs for which the user has the 'write' permissions. -{% raw %} -```jsx -import { CanAccess, Edit, TabbedForm, TextInput } from 'react-admin'; +```tsx +import { Edit, TextInput } from 'react-admin'; +import { TabbedForm } from '@react-admin/ra-rbac'; + +const authProvider = { + // ... + canAccess: async ({ action, record, resource }) => + canAccessWithPermissions({ + permissions: [ + { action: ['list', 'edit'], resource: 'products' }, + { action: 'write', resource: 'products.reference' }, + { action: 'write', resource: 'products.width' }, + { action: 'write', resource: 'products.height' }, + // 'products.description' is missing + { action: 'write', resource: 'products.thumbnail' }, + // 'products.image' is missing + { action: 'write', resource: 'products.tab.description' }, + // 'products.tab.stock' is missing + { action: 'write', resource: 'products.tab.images' }, + ], + action, + record, + resource, + }) +}; -export const UserEdit = () => { - return ( - - - - - - - - } - - ... - - - - ); -} +const ProductEdit = () => ( + + + + + + + {/* Input Description is not displayed */} + + + {/* Input Stock is not displayed */} + + + + + {/* Input Image is not displayed */} + + + + + +); ``` -{% endraw %} ## Versioning