Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Notification component multiLine prop #6670

Merged
merged 8 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/Actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,12 +641,13 @@ const NotifyButton = () => {
};
```

The callback takes 5 arguments:
- the message to display
- the level of the notification (`info`, `success` or `warning` - the default is `info`)
- an `options` object to pass to the `translate` function (because notification messages are translated if your admin has an `i18nProvider`). It is useful for inserting variables into the translation.
- an `undoable` boolean. Set it to `true` if the notification should contain an "undo" button
- a `duration` number. Set it to `0` if the notification should not be dismissible.
The callback takes 6 arguments:
- The message to display
- The level of the notification (`info`, `success` or `warning` - the default is `info`)
- An `options` object to pass to the `translate` function (because notification messages are translated if your admin has an `i18nProvider`). It is useful for inserting variables into the translation.
- An `undoable` boolean. Set it to `true` if the notification should contain an "undo" button
- A `duration` number. Set it to `0` if the notification should not be dismissible.
- A `multiLine` boolean. Set it to `true` if the notification message should be shown in more than one line.

Here are more examples of `useNotify` calls:

Expand Down
4 changes: 3 additions & 1 deletion packages/ra-core/src/actions/notificationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ export const SHOW_NOTIFICATION = 'RA/SHOW_NOTIFICATION';

export type NotificationType = 'success' | 'info' | 'warning' | 'error';

interface NotificationOptions {
export interface NotificationOptions {
// The duration in milliseconds the notification is shown
autoHideDuration?: number;
// Arguments used to translate the message
messageArgs?: any;
// If true, the notification shows the message in multiple lines
multiLine?: boolean;
// If true, the notification shows an Undo button
undoable?: boolean;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/ra-core/src/reducer/admin/notifications.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ describe('notifications reducer', () => {
})
);
});
it('should set multiLine when passed in payload', () => {
expect([{ message: 'test', type: 'info', multiLine: true }]).toEqual(
reducer(undefined, {
type: SHOW_NOTIFICATION,
payload: {
message: 'test',
type: 'info',
multiLine: true,
},
})
);
});
it('should set text and type upon SHOW_NOTIFICATION', () => {
expect([{ message: 'foo', type: 'warning' }]).toEqual(
reducer(undefined, {
Expand Down
51 changes: 51 additions & 0 deletions packages/ra-core/src/sideEffect/useNotify.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react';
import { useEffect } from 'react';
import { renderWithRedux } from 'ra-test';
import { useNotify } from './index';

const Notification = ({
type,
message,
undoable = false,
autoHideDuration = 4000,
multiLine = true,
shortSignature = false,
}) => {
const notify = useNotify();
useEffect(() => {
if (shortSignature) {
// @ts-ignore
notify(message, {
type,
undoable,
autoHideDuration,
multiLine,
});
} else {
notify(message, type, {}, undoable, autoHideDuration, multiLine);
}
}, [
message,
undoable,
autoHideDuration,
multiLine,
shortSignature,
type,
notify,
]);
return null;
};

describe('useNotify', () => {
it('should show a multiline notification message', () => {
const { dispatch } = renderWithRedux(
<Notification
type="info"
message={`One Line\nTwo Lines\nThree Lines`}
multiLine
/>
);

expect(dispatch).toHaveBeenCalledTimes(1);
});
});
4 changes: 3 additions & 1 deletion packages/ra-core/src/sideEffect/useNotify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ const useNotify = () => {
type: NotificationType = 'info',
messageArgs: any = {},
undoable: boolean = false,
autoHideDuration?: number
autoHideDuration?: number,
multiLine?: boolean
) => {
dispatch(
showNotification(message, type, {
messageArgs,
undoable,
autoHideDuration,
multiLine,
})
);
},
Expand Down
18 changes: 14 additions & 4 deletions packages/ra-ui-materialui/src/layout/Notification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import {
useTranslate,
} from 'ra-core';

interface Props {
export interface NotificationProps extends Omit<SnackbarProps, 'open'> {
type?: string;
autoHideDuration?: number;
multiLine?: boolean;
WiXSL marked this conversation as resolved.
Show resolved Hide resolved
}

const useStyles = makeStyles(
Expand All @@ -34,22 +36,26 @@ const useStyles = makeStyles(
backgroundColor: theme.palette.error.light,
color: theme.palette.error.contrastText,
},
undo: (props: Props & Omit<SnackbarProps, 'open'>) => ({
undo: (props: NotificationProps) => ({
color:
props.type === 'success'
? theme.palette.success.contrastText
: theme.palette.primary.light,
}),
multiLine: {
whiteSpace: 'pre-wrap',
},
}),
{ name: 'RaNotification' }
);

const Notification = (props: Props & Omit<SnackbarProps, 'open'>) => {
const Notification = (props: NotificationProps) => {
const {
classes: classesOverride,
type,
className,
autoHideDuration,
multiLine,
...rest
} = props;
const [open, setOpen] = useState(false);
Expand Down Expand Up @@ -97,7 +103,8 @@ const Notification = (props: Props & Omit<SnackbarProps, 'open'>) => {
ContentProps={{
className: classnames(
styles[(notification && notification.type) || type],
className
className,
{ [styles['multiLine']]: multiLine }
),
}}
action={
Expand All @@ -119,11 +126,14 @@ const Notification = (props: Props & Omit<SnackbarProps, 'open'>) => {

Notification.propTypes = {
type: PropTypes.string,
autoHideDuration: PropTypes.number,
multiLine: PropTypes.bool,
};

Notification.defaultProps = {
type: 'info',
autoHideDuration: 4000,
multiLine: false,
};

export default Notification;
3 changes: 2 additions & 1 deletion packages/ra-ui-materialui/src/layout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import LoadingIndicator from './LoadingIndicator';
import Menu, { MenuProps } from './Menu';
import MenuItemLink, { MenuItemLinkProps } from './MenuItemLink';
import NotFound from './NotFound';
import Notification from './Notification';
import Notification, { NotificationProps } from './Notification';
import Responsive, { ResponsiveProps } from './Responsive';
import Sidebar, { SidebarProps } from './Sidebar';
import Title, { TitleProps, TitlePropType } from './Title';
Expand All @@ -41,6 +41,7 @@ export {
MenuItemLink,
NotFound,
Notification,
NotificationProps,
Responsive,
Sidebar,
Title,
Expand Down