From 0b460662c2e436f13fc63207753a6cdccbee5d0f Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Fri, 7 Aug 2020 15:44:34 +0200 Subject: [PATCH] initial version of the alert system --- src/App.tsx | 20 ++++++++++-- src/components/alert/AlertPanel.tsx | 40 ++++++++++++++++++++++++ src/components/alert/Alerts.tsx | 48 +++++++++++++++++++++++++++++ stories/5-AlertPanel.stories.js | 24 +++++++++++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 src/components/alert/AlertPanel.tsx create mode 100644 src/components/alert/Alerts.tsx create mode 100644 stories/5-AlertPanel.stories.js diff --git a/src/App.tsx b/src/App.tsx index 142780cc86..3b4e665f0a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,22 @@ import React, { useContext } from 'react'; +import { + Page, + PageSection, + Button, + AlertVariant, +} from '@patternfly/react-core'; import { ClientList } from './clients/ClientList'; import { DataLoader } from './components/data-loader/DataLoader'; import { HttpClientContext } from './http-service/HttpClientContext'; import { Client } from './clients/client-model'; -import { Page, PageSection } from '@patternfly/react-core'; import { Header } from './PageHeader'; import { PageNav } from './PageNav'; +import { AlertPanel } from './components/alert/AlertPanel'; +import { useAlerts, withAlerts } from './components/alert/Alerts'; -export const App = () => { +const AppComponent = () => { + const [alerts, add, hide] = useAlerts(); const httpClient = useContext(HttpClientContext); const loader = async () => { @@ -19,10 +27,18 @@ export const App = () => { return ( } sidebar={}> + {(clients) => } + ); }; + +export const App = withAlerts(AppComponent); diff --git a/src/components/alert/AlertPanel.tsx b/src/components/alert/AlertPanel.tsx new file mode 100644 index 0000000000..d10793506e --- /dev/null +++ b/src/components/alert/AlertPanel.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { + AlertGroup, + Alert, + AlertActionCloseButton, + AlertVariant, +} from '@patternfly/react-core'; + +export type AlertType = { + key: number; + message: string; + variant: AlertVariant; +}; + +type AlertPanelProps = { + alerts: AlertType[]; + onCloseAlert: (key: number) => void; +}; + +export function AlertPanel({ alerts, onCloseAlert }: AlertPanelProps) { + return ( + + {alerts.map(({ key, variant, message }) => ( + onCloseAlert(key)} + /> + } + key={key} + /> + ))} + + ); +} diff --git a/src/components/alert/Alerts.tsx b/src/components/alert/Alerts.tsx new file mode 100644 index 0000000000..771c046d93 --- /dev/null +++ b/src/components/alert/Alerts.tsx @@ -0,0 +1,48 @@ +import React, { + useState, + FunctionComponent, + useContext, + Dispatch, + SetStateAction, +} from 'react'; +import { AlertType } from './AlertPanel'; +import { AlertVariant } from '@patternfly/react-core'; + +const AlertsContext = React.createContext< + [AlertType[], Dispatch>] | undefined +>(undefined); + +export function withAlerts(WrappedComponent: FunctionComponent) { + return function (props: any) { + const state = useState([]); + + return ( + + + + ); + }; +} + +export function useAlerts(): [ + AlertType[], + (message: string, type: AlertVariant) => void, + (key: number) => void +] { + const createId = () => new Date().getTime(); + const [alerts, setAlerts] = useContext(AlertsContext)!; + + const hideAlert = (key: number) => { + setAlerts([...alerts.filter((el) => el.key !== key)]); + }; + + const add = (message: string, type: AlertVariant) => { + const key = createId(); + setAlerts([...alerts, { key, message, variant: type }]); + if (type !== AlertVariant.danger) { + setTimeout(() => hideAlert(key), 8000); + } + }; + + return [alerts, add, hideAlert]; +} diff --git a/stories/5-AlertPanel.stories.js b/stories/5-AlertPanel.stories.js new file mode 100644 index 0000000000..e7e03269f1 --- /dev/null +++ b/stories/5-AlertPanel.stories.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { AlertVariant, Button } from '@patternfly/react-core'; +import { storiesOf } from '@storybook/react'; + +import { AlertPanel } from '../src/components/alert/AlertPanel'; +import { withAlerts, useAlerts } from '../src/components/alert/Alerts'; + +storiesOf('Alert Panel', module) + .add('api', () => { }} />) + .add('add alert', () => { + const Comp = () => { + const [alerts, add, hide] = useAlerts(); + return ( + <> + + + + ); + } + const WrapperComponent = withAlerts(Comp); + return ( + + ); + });