fleet/frontend/components/FlashMessage/FlashMessage.tsx
Martavis Parker bcfac603f0
Added components to Storybook library (#2768)
* added storybook

* added avatar component

* added button story

* added dropdown button story

* removed unused ellipsis component

* cleaned up modal path

* reorganized enroll secrets table file

* added flash story; removed unused persistent flash

* added fleet ace story

* added checkbox story

* added dropdown story

* added input story

* fixed storybook build

* fixed avatar

* added input with icon story

* added radio button story

* added select targets dropdown story

* added slider story

* added tooltip story

* added info banner story

* removed unused loaders; added spinner story

* added modal story

* removed unused NumberPill

* added pagination story

* lint fixes

* added documentation to run

* modified documentation

* fixed corelayout test

* fixed format for date-fns

* fixed date format that breaks tests

* wait for page
2021-11-06 23:41:09 -07:00

98 lines
3.1 KiB
TypeScript

import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
import { INotifications } from "interfaces/notification";
// @ts-ignore
import FleetIcon from "components/icons/FleetIcon";
import Button from "components/buttons/Button";
import CloseIcon from "../../../assets/images/icon-close-white-16x16@2x.png";
import CloseIconBlack from "../../../assets/images/icon-close-fleet-black-16x16@2x.png";
const baseClass = "flash-message";
export interface IFlashMessage {
fullWidth: boolean;
notification: INotifications;
isPersistent?: boolean;
onRemoveFlash: () => void;
onUndoActionClick: (
value: () => void
) => (evt: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
}
const FlashMessage = ({
fullWidth,
notification,
isPersistent,
onRemoveFlash,
onUndoActionClick,
}: IFlashMessage) => {
const { alertType, isVisible, message, undoAction } = notification;
const klass = classnames(baseClass, `${baseClass}--${alertType}`, {
[`${baseClass}--full-width`]: fullWidth,
});
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.
useEffect(() => {
// 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);
if (!isPersistent && alertType === "success" && isVisible) {
// After 4 seconds, set hide to true.
const timer = setTimeout(() => {
setHide(true);
onRemoveFlash(); // This function resets notifications which allows CoreLayout reset of selected rows
}, 4000);
// 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);
}
return undefined; // No cleanup when we don't set a timeout.
}, [notification, alertType, isVisible, setHide]);
if (hide || !isVisible) {
return null;
}
const alertIcon =
alertType === "success" ? "success-check" : "warning-filled";
return (
<div className={klass} id={klass}>
<div className={`${baseClass}__content`}>
<FleetIcon name={alertIcon} /> <span>{message}</span>
{undoAction && (
<Button
className={`${baseClass}__undo`}
variant="unstyled"
onClick={onUndoActionClick(undoAction)}
>
Undo
</Button>
)}
</div>
<div className={`${baseClass}__action`}>
<div className={`${baseClass}__ex`}>
<button
className={`${baseClass}__remove ${baseClass}__remove--${alertType} button--unstyled`}
onClick={onRemoveFlash}
>
<img
src={alertType === "warning-filled" ? CloseIconBlack : CloseIcon}
alt="close icon"
/>
</button>
</div>
</div>
</div>
);
};
export default FlashMessage;