Skip to content

Conversation

djhi
Copy link
Collaborator

@djhi djhi commented Sep 29, 2025

Problem

We now have headless support for some React Admin Enterprise features. It's time to mention them in the ra-core documentation.

How To Test

  • make doc-headless

Additional Checks

  • The PR targets master for a bugfix or a documentation fix, or next for a feature

Screenshots

image image

@djhi djhi added the RFR Ready For Review label Sep 29, 2025
@djhi djhi changed the title Add documentation for headless enterprise features in ra-core documentation [Doc] Add documentation for headless enterprise features in ra-core documentation Sep 29, 2025
@slax57 slax57 self-requested a review October 1, 2025 14:51
*/
function enterpriseEntry(name) {
return {
link: name.toLowerCase().replace(/</g, '').replace(/>/g, ''),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
link: name.toLowerCase().replace(/</g, '').replace(/>/g, ''),
link: name.toLowerCase().replace(/</g, '').replace(/>/g, '') + '/',

Links need to end up with a trailing slash, otherwise the (local) assets path are messed up

};
```

In addition to the [`useLockCallbacks`](#uselockcallbacks) parameters, `<LockStatusBase>` accepts a `render` prop. The function passed to the `render` prop will be called with the result of the `useLockCallbacks` hook. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dead link

| `resource` | Required | `string` | The resource for which to check users has the execution right
| `record` | Required | `string` | The record for which to check users has the execution right

`canAccessWithPermissions` expects the `permissions` to be a flat array of permissions. It is your responsibility to fetch these permissions (usually during login). If the permissions are spread into several role definitions, you can merge them into a single array using the [`getPermissionsFromRoles`](#getpermissionsfromroles) function. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dead link

probably many others like this in this whole PR, I won't point them all...

Comment on lines +277 to +280
badge: {
text: 'React Admin Enterprise',
variant: 'default',
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the badge used somewhere? I don't see it... 🤔

UPDATE: or is it for a11y?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a11y indeed


The hook will subscribe to live updates on the list of records (topic: `resource/[resource]`) and will refetch the list when a new record is created, or an existing record is updated or deleted.

See the [useGetList](https://marmelab.com/react-admin/useGetList.html) documentation for the full list of parameters and return type. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should link to ra-core docs


The hook will subscribe to live updates on the record (topic: `resource/[resource]/[id]`) and will refetch the record when it is updated or deleted.

See the [useGetOne](https://marmelab.com/react-admin/useGetOne.html) documentation for the full list of parameters and return type. No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@slax57 slax57 requested a review from Copilot October 1, 2025 15:15
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds documentation for headless React Admin Enterprise features to the ra-core documentation. It introduces comprehensive documentation for enterprise features like real-time subscriptions, record locking, and role-based permissions in a headless context.

  • Adds documentation for 20+ enterprise hooks and utilities including real-time subscriptions, record locking, and permission management
  • Updates the documentation site configuration to include a new "Realtime" section with enterprise-specific styling
  • Adds CSS styling for enterprise features with premium badges and theme-aware icons

Reviewed Changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 5 comments.

File Description
docs_headless/src/styles/global.css Adds CSS styling for enterprise links with premium badges and theme-aware icons
docs_headless/astro.config.mjs Adds new "Realtime" section and enterprise entry helper function for documentation navigation
Multiple .md files Comprehensive documentation for enterprise hooks covering real-time subscriptions, record locking, permissions, and live data fetching

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 26 to 44
const notity = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notity('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} deleted`);
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in variable name: 'notity' should be 'notify'.

Suggested change
const notity = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notity('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} deleted`);
const notify = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notify('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notify(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notify(`Movie #${event.payload.ids[0]} deleted`);

Copilot uses AI. Check for mistakes.

Comment on lines 26 to 44
const notity = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notity('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} deleted`);
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in variable name: 'notity' should be 'notify'.

Suggested change
const notity = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notity('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notity(`Movie #${event.payload.ids[0]} deleted`);
const notify = useNotify();
const { refetch, data } = useListContext();
useSubscribeToRecordList(event => {
switch (event.type) {
case 'created': {
notify('New movie created');
refetch();
break;
}
case 'updated': {
if (data.find(record => record.id === event.payload.ids[0])) {
notify(`Movie #${event.payload.ids[0]} updated`);
refetch();
}
break;
}
case 'deleted': {
if (data.find(record => record.id === event.payload.ids[0])) {
notify(`Movie #${event.payload.ids[0]} deleted`);

Copilot uses AI. Check for mistakes.

<button type="submit" disabled={isLockedByOtherUser}>Save</button>
{isLockedByOtherUser && (
<span>
{`This record is locked by another user: ${lock?.dentity}.`}
Copy link
Preview

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in property access: 'dentity' should be 'identity'.

Suggested change
{`This record is locked by another user: ${lock?.dentity}.`}
{`This record is locked by another user: ${lock?.identity}.`}

Copilot uses AI. Check for mistakes.

Comment on lines +11 to +17
## Installation

```bash
npm install --save @react-admin/ra-core-ee
# or
yarn add @react-admin/ra-core-ee
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we say we kept that only for the EE docs? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my mind! In its previous form, the doc was not easily comprehensible. We need to make usage more obvious, including installation.

| `resource` | Required | `string` | The resource for which to check users has the execution right
| `record` | Required | `string` | The record for which to check users has the execution right

`canAccessWithPermissions` expects the `permissions` to be a flat array of permissions. It is your responsibility to fetch these permissions (usually during login). If the permissions are spread into several role definitions, you can merge them into a single array using the [`getPermissionsFromRoles`](#getpermissionsfromroles) function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Link should target ./getPermissionsFromRoles.md (can't make a Github diff for some reason 🤷 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Development

Successfully merging this pull request may close these issues.

3 participants