Merge pull request #30897 from drodil/notification_snackbar_customization
feat: improve customization of notification snackbar
This commit is contained in:
+83
-20
@@ -13,7 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import * as React from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useNotificationsApi } from '../../hooks';
|
||||
import { Link, SidebarItem } from '@backstage/core-components';
|
||||
import NotificationsIcon from '@material-ui/icons/Notifications';
|
||||
@@ -27,6 +28,7 @@ import { rootRouteRef } from '../../routes';
|
||||
import { useSignal } from '@backstage/plugin-signals-react';
|
||||
import {
|
||||
Notification,
|
||||
NotificationSeverity,
|
||||
NotificationSignal,
|
||||
} from '@backstage/plugin-notifications-common';
|
||||
import { useWebNotifications } from '../../hooks/useWebNotifications';
|
||||
@@ -79,18 +81,51 @@ declare module 'notistack' {
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const NotificationsSidebarItem = (props?: {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationSnackbarProperties = {
|
||||
enabled?: boolean;
|
||||
autoHideDuration?: number | null;
|
||||
anchorOrigin?: {
|
||||
vertical: 'top' | 'bottom';
|
||||
horizontal: 'left' | 'center' | 'right';
|
||||
};
|
||||
dense?: boolean;
|
||||
maxSnack?: number;
|
||||
snackStyle?: React.CSSProperties;
|
||||
iconVariant?: Partial<Record<NotificationSeverity, React.ReactNode>>;
|
||||
Components?: {
|
||||
[key in NotificationSeverity]: React.JSXElementConstructor<any>;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationsSideBarItemProps = {
|
||||
webNotificationsEnabled?: boolean;
|
||||
titleCounterEnabled?: boolean;
|
||||
/**
|
||||
* @deprecated Use `snackbarProps` instead.
|
||||
*/
|
||||
snackbarEnabled?: boolean;
|
||||
/**
|
||||
* @deprecated Use `snackbarProps` instead.
|
||||
*/
|
||||
snackbarAutoHideDuration?: number | null;
|
||||
snackbarProps?: NotificationSnackbarProperties;
|
||||
className?: string;
|
||||
icon?: IconComponent;
|
||||
text?: string;
|
||||
disableHighlight?: boolean;
|
||||
noTrack?: boolean;
|
||||
}) => {
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const NotificationsSidebarItem = (
|
||||
props?: NotificationsSideBarItemProps,
|
||||
) => {
|
||||
const {
|
||||
webNotificationsEnabled = false,
|
||||
titleCounterEnabled = true,
|
||||
@@ -102,10 +137,21 @@ export const NotificationsSidebarItem = (props?: {
|
||||
} = props ?? {
|
||||
webNotificationsEnabled: false,
|
||||
titleCounterEnabled: true,
|
||||
snackbarEnabled: true,
|
||||
snackbarAutoHideDuration: 10000,
|
||||
snackbarProps: {
|
||||
enabled: true,
|
||||
autoHideDuration: 10000,
|
||||
},
|
||||
};
|
||||
|
||||
const snackbarProps = useMemo(
|
||||
() =>
|
||||
props?.snackbarProps ?? {
|
||||
enabled: snackbarEnabled,
|
||||
autoHideDuration: snackbarAutoHideDuration,
|
||||
},
|
||||
[props?.snackbarProps, snackbarAutoHideDuration, snackbarEnabled],
|
||||
);
|
||||
|
||||
const { loading, error, value, retry } = useNotificationsApi(api =>
|
||||
api.getStatus(),
|
||||
);
|
||||
@@ -185,7 +231,7 @@ export const NotificationsSidebarItem = (props?: {
|
||||
useEffect(() => {
|
||||
const handleNotificationSignal = (signal: NotificationSignal) => {
|
||||
if (
|
||||
(!webNotificationsEnabled && !snackbarEnabled) ||
|
||||
(!webNotificationsEnabled && !snackbarProps.enabled) ||
|
||||
signal.action !== 'new_notification'
|
||||
) {
|
||||
return;
|
||||
@@ -204,7 +250,7 @@ export const NotificationsSidebarItem = (props?: {
|
||||
link: notification.payload.link,
|
||||
});
|
||||
}
|
||||
if (snackbarEnabled) {
|
||||
if (snackbarProps.enabled) {
|
||||
const { action } = getSnackbarProperties(notification);
|
||||
const snackBarText =
|
||||
notification.payload.title.length > 50
|
||||
@@ -212,10 +258,14 @@ export const NotificationsSidebarItem = (props?: {
|
||||
: notification.payload.title;
|
||||
enqueueSnackbar(snackBarText, {
|
||||
key: notification.id,
|
||||
style: snackbarProps.snackStyle,
|
||||
variant: notification.payload.severity,
|
||||
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
||||
anchorOrigin: snackbarProps.anchorOrigin ?? {
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
},
|
||||
action,
|
||||
autoHideDuration: snackbarAutoHideDuration,
|
||||
autoHideDuration: snackbarProps.autoHideDuration,
|
||||
} as OptionsWithExtraProps<VariantType>);
|
||||
}
|
||||
})
|
||||
@@ -235,11 +285,10 @@ export const NotificationsSidebarItem = (props?: {
|
||||
lastSignal,
|
||||
sendWebNotification,
|
||||
webNotificationsEnabled,
|
||||
snackbarEnabled,
|
||||
snackbarAutoHideDuration,
|
||||
notificationsApi,
|
||||
alertApi,
|
||||
getSnackbarProperties,
|
||||
snackbarProps,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -261,16 +310,30 @@ export const NotificationsSidebarItem = (props?: {
|
||||
{snackbarEnabled && (
|
||||
<SnackbarProvider
|
||||
iconVariant={{
|
||||
normal: <SeverityIcon severity="normal" />,
|
||||
critical: <SeverityIcon severity="critical" />,
|
||||
high: <SeverityIcon severity="high" />,
|
||||
low: <SeverityIcon severity="low" />,
|
||||
normal: snackbarProps?.iconVariant?.normal ?? (
|
||||
<SeverityIcon severity="normal" />
|
||||
),
|
||||
critical: snackbarProps?.iconVariant?.critical ?? (
|
||||
<SeverityIcon severity="critical" />
|
||||
),
|
||||
high: snackbarProps?.iconVariant?.high ?? (
|
||||
<SeverityIcon severity="high" />
|
||||
),
|
||||
low: snackbarProps?.iconVariant?.low ?? (
|
||||
<SeverityIcon severity="low" />
|
||||
),
|
||||
}}
|
||||
dense={snackbarProps?.dense}
|
||||
maxSnack={snackbarProps?.maxSnack}
|
||||
Components={{
|
||||
normal: StyledMaterialDesignContent,
|
||||
critical: StyledMaterialDesignContent,
|
||||
high: StyledMaterialDesignContent,
|
||||
low: StyledMaterialDesignContent,
|
||||
normal:
|
||||
snackbarProps?.Components?.normal ?? StyledMaterialDesignContent,
|
||||
critical:
|
||||
snackbarProps?.Components?.critical ??
|
||||
StyledMaterialDesignContent,
|
||||
high:
|
||||
snackbarProps?.Components?.high ?? StyledMaterialDesignContent,
|
||||
low: snackbarProps?.Components?.low ?? StyledMaterialDesignContent,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user