2021-08-27 00:07:16 +00:00
|
|
|
import React, { useEffect, useState } from "react";
|
2021-04-12 13:32:25 +00:00
|
|
|
import classnames from "classnames";
|
|
|
|
|
|
2022-04-01 06:42:26 +00:00
|
|
|
import { INotification } from "interfaces/notification";
|
2021-08-30 19:52:13 +00:00
|
|
|
// @ts-ignore
|
2021-06-07 01:56:30 +00:00
|
|
|
import FleetIcon from "components/icons/FleetIcon";
|
2021-04-12 13:32:25 +00:00
|
|
|
import Button from "components/buttons/Button";
|
|
|
|
|
|
2021-11-07 06:41:09 +00:00
|
|
|
import CloseIcon from "../../../assets/images/icon-close-white-16x16@2x.png";
|
|
|
|
|
import CloseIconBlack from "../../../assets/images/icon-close-fleet-black-16x16@2x.png";
|
2022-04-04 18:53:14 +00:00
|
|
|
import ErrorIcon from "../../../assets/images/icon-error-white-16x16@2x.png";
|
2021-06-25 15:55:47 +00:00
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
const baseClass = "flash-message";
|
|
|
|
|
|
2021-11-07 06:41:09 +00:00
|
|
|
export interface IFlashMessage {
|
2021-08-30 19:52:13 +00:00
|
|
|
fullWidth: boolean;
|
2022-04-01 06:42:26 +00:00
|
|
|
notification: INotification | null;
|
2021-11-07 06:41:09 +00:00
|
|
|
isPersistent?: boolean;
|
2022-08-31 16:17:27 +00:00
|
|
|
className?: string;
|
2021-08-30 19:52:13 +00:00
|
|
|
onRemoveFlash: () => void;
|
2022-04-01 06:42:26 +00:00
|
|
|
onUndoActionClick?: (
|
2021-08-30 19:52:13 +00:00
|
|
|
value: () => void
|
|
|
|
|
) => (evt: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-12 13:32:25 +00:00
|
|
|
const FlashMessage = ({
|
|
|
|
|
fullWidth,
|
|
|
|
|
notification,
|
2021-11-07 06:41:09 +00:00
|
|
|
isPersistent,
|
2022-08-31 16:17:27 +00:00
|
|
|
className,
|
2021-04-12 13:32:25 +00:00
|
|
|
onRemoveFlash,
|
|
|
|
|
onUndoActionClick,
|
2022-01-17 02:46:20 +00:00
|
|
|
}: IFlashMessage): JSX.Element | null => {
|
2022-04-01 06:42:26 +00:00
|
|
|
const { alertType, isVisible, message, undoAction } = notification || {};
|
2022-08-31 16:17:27 +00:00
|
|
|
const baseClasses = classnames(
|
|
|
|
|
baseClass,
|
|
|
|
|
className,
|
|
|
|
|
`${baseClass}--${alertType}`,
|
|
|
|
|
{
|
|
|
|
|
[`${baseClass}--full-width`]: fullWidth,
|
|
|
|
|
}
|
|
|
|
|
);
|
2016-10-03 17:54:22 +00:00
|
|
|
|
2021-08-27 00:07:16 +00:00
|
|
|
const [hide, setHide] = useState(false);
|
|
|
|
|
|
|
|
|
|
// This useEffect handles hiding successful flash messages after a 4s timeout. By putting the
|
|
|
|
|
// notification in the dependency array, we can properly reset whenever a new flash message comes through.
|
2021-07-27 20:19:52 +00:00
|
|
|
useEffect(() => {
|
2021-08-27 00:07:16 +00:00
|
|
|
// Any time this hook runs, we reset the hide to false (so that subsequent messages that will be
|
|
|
|
|
// using this same component instance will be visible).
|
|
|
|
|
setHide(false);
|
|
|
|
|
|
2021-11-07 06:41:09 +00:00
|
|
|
if (!isPersistent && alertType === "success" && isVisible) {
|
2021-08-27 00:07:16 +00:00
|
|
|
// After 4 seconds, set hide to true.
|
2021-10-22 15:19:34 +00:00
|
|
|
const timer = setTimeout(() => {
|
|
|
|
|
setHide(true);
|
|
|
|
|
onRemoveFlash(); // This function resets notifications which allows CoreLayout reset of selected rows
|
|
|
|
|
}, 4000);
|
2021-08-27 00:07:16 +00:00
|
|
|
// Return a cleanup function that will clear this reset, in case another render happens
|
|
|
|
|
// after this. We want that render to set a new timeout (if needed).
|
|
|
|
|
return () => clearTimeout(timer);
|
2021-07-27 20:19:52 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-27 00:07:16 +00:00
|
|
|
return undefined; // No cleanup when we don't set a timeout.
|
|
|
|
|
}, [notification, alertType, isVisible, setHide]);
|
|
|
|
|
|
|
|
|
|
if (hide || !isVisible) {
|
2022-04-01 06:42:26 +00:00
|
|
|
return null;
|
2016-10-19 20:22:18 +00:00
|
|
|
}
|
2016-10-03 17:54:22 +00:00
|
|
|
|
|
|
|
|
return (
|
2022-08-31 16:17:27 +00:00
|
|
|
<div className={baseClasses} id={baseClasses}>
|
2016-11-03 19:40:54 +00:00
|
|
|
<div className={`${baseClass}__content`}>
|
2022-04-04 18:53:14 +00:00
|
|
|
{alertType === "success" ? (
|
|
|
|
|
<FleetIcon name="success-check" />
|
|
|
|
|
) : (
|
|
|
|
|
<img alt="error icon" src={ErrorIcon} />
|
|
|
|
|
)}
|
|
|
|
|
<span>{message}</span>
|
2022-04-01 06:42:26 +00:00
|
|
|
{onUndoActionClick && undoAction && (
|
2017-01-05 18:08:19 +00:00
|
|
|
<Button
|
|
|
|
|
className={`${baseClass}__undo`}
|
|
|
|
|
variant="unstyled"
|
|
|
|
|
onClick={onUndoActionClick(undoAction)}
|
|
|
|
|
>
|
|
|
|
|
Undo
|
|
|
|
|
</Button>
|
2021-04-12 13:32:25 +00:00
|
|
|
)}
|
2016-10-03 17:54:22 +00:00
|
|
|
</div>
|
2016-11-03 19:40:54 +00:00
|
|
|
<div className={`${baseClass}__action`}>
|
2021-06-07 19:48:52 +00:00
|
|
|
<div className={`${baseClass}__ex`}>
|
2021-06-25 15:55:47 +00:00
|
|
|
<button
|
|
|
|
|
className={`${baseClass}__remove ${baseClass}__remove--${alertType} button--unstyled`}
|
2021-06-07 19:48:52 +00:00
|
|
|
onClick={onRemoveFlash}
|
2021-06-25 15:55:47 +00:00
|
|
|
>
|
2021-08-30 19:52:13 +00:00
|
|
|
<img
|
|
|
|
|
src={alertType === "warning-filled" ? CloseIconBlack : CloseIcon}
|
|
|
|
|
alt="close icon"
|
|
|
|
|
/>
|
2021-06-25 15:55:47 +00:00
|
|
|
</button>
|
2021-06-07 19:48:52 +00:00
|
|
|
</div>
|
2016-10-03 17:54:22 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-03 19:40:54 +00:00
|
|
|
export default FlashMessage;
|