From 31ae0ddbeab1ab8ce147419436274f542d8369f3 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Fri, 22 Sep 2023 12:35:02 +0200 Subject: [PATCH 1/2] Add Real Time Notifications section in Realtime introduction --- docs/Realtime.md | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/docs/Realtime.md b/docs/Realtime.md index b15c663ce45..920904a1b06 100644 --- a/docs/Realtime.md +++ b/docs/Realtime.md @@ -97,6 +97,96 @@ And the following components: - [``](./EditLive.md) - [``](./ShowLive.md) +## Real Time Notifications + +Thanks to the Ra-realtime hooks, you can implement custom notifications based on events. For instance, consider a long server action called `recompute` for which you'd like to show the progression. + + + +First, leverage the ability to [add custom dataProvider methods](https://marmelab.com/react-admin/Actions.html#calling-custom-methods) to allow calling this custom end point from the UI: + +```ts +export const dataProvider = { + // ...standard dataProvider methods such as getList, etc. + recompute: async (params) => { + httpClient(`${apiUrl}/recompute`, { + method: 'POST', + body: JSON.stringify(params.data), // contains the project's id + }).then(({ json }) => ({ data: json })); + } +} +``` + +Then, make sure your API sends events with a topic named `recompute_PROJECT_ID` where `PROJECT_ID` is the project identifier: + +```json +{ + "type": "recompute_PROJECT_ID", + "payload": { + "progress": 10 + }, +} +``` + +Finally, create a component to actually call this function and show a notification, leveraging the [useSubscribeCallback](./useSubscribeCallback.md) hook: + +{% raw %} +```jsx +import { useState, useCallback } from 'react'; +import { useDataProvider, useRecordContext } from 'react-admin'; +import { Button, Card, Alert, AlertTitle, LinearProgress } from '@mui/material'; +import { useSubscribeCallback } from '@react-admin/ra-realtime'; + +export const RecomputeProjectStatsButton = () => { + const dataProvider = useDataProvider(); + const record = useRecordContext(); + const [progress, setProgress] = useState(0); + + const callback = useCallback( + (event, unsubscribe) => { + setProgress(event.payload?.progress || 0); + if (event.payload?.progress === 100) { + unsubscribe(); + } + }, + [setProgress] + ); + const subscribe = useSubscribeCallback( + `recompute_${record.id}`, + callback + ); + + return ( +
+ + {progress > 0 && ( + + + + Recomputing stats{' '} + {progress === 100 ? 'complete' : 'in progress'} + + + + + )} +
+ ); +}; +``` +{% endraw %} + ## Menu Badges Ra-realtime also provides **badge notifications in the Menu**, so that users can see that something new happened to a resource list while working on another one. From 0a2265ef82b43da7fdcd874c36490cd5aa29094b Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:49:00 +0200 Subject: [PATCH 2/2] Update code example [skip-ci] --- docs/Realtime.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/Realtime.md b/docs/Realtime.md index 920904a1b06..238b46f7528 100644 --- a/docs/Realtime.md +++ b/docs/Realtime.md @@ -138,7 +138,7 @@ Finally, create a component to actually call this function and show a notificati ```jsx import { useState, useCallback } from 'react'; import { useDataProvider, useRecordContext } from 'react-admin'; -import { Button, Card, Alert, AlertTitle, LinearProgress } from '@mui/material'; +import { Box, Button, Card, Alert, AlertTitle, LinearProgress, Typography } from '@mui/material'; import { useSubscribeCallback } from '@react-admin/ra-realtime'; export const RecomputeProjectStatsButton = () => { @@ -184,6 +184,22 @@ export const RecomputeProjectStatsButton = () => { ); }; + +const LinearProgressWithLabel = props => { + return ( + + + + + + {`${Math.round(props.value)}%`} + + + ); +}; ``` {% endraw %}