Skip to content

Commit

Permalink
Add alert icon and popover
Browse files Browse the repository at this point in the history
  • Loading branch information
prasm313 authored and haakonsf committed Aug 20, 2024
1 parent c7a3439 commit 0d45330
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 14 deletions.
24 changes: 24 additions & 0 deletions frontend/src/components/Alerts/AlertsBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ const StyledCard = styled.div`
}
`

const StyledListItem = styled.div`
display: flex;
width: 300px;
height: auto;
padding: 3px 10px 2px 10px;
justify-content: space-between;
align-items: center;
`

const Horizontal = styled.div`
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -69,3 +78,18 @@ export const AlertBanner = ({ children, dismissAlert, alertCategory }: AlertProp
</>
)
}

export const AlertListItem = ({ children, dismissAlert, alertCategory }: AlertProps) => {
return (
<>
<StyledListItem>
<Horizontal>
<Center>{children}</Center>
</Horizontal>
<Button variant="ghost_icon" onClick={dismissAlert}>
<Icon name={Icons.Clear} size={24}></Icon>
</Button>
</StyledListItem>
</>
)
}
49 changes: 49 additions & 0 deletions frontend/src/components/Alerts/AlertsListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button, Icon } from '@equinor/eds-core-react'
import { ReactNode } from 'react'
import styled from 'styled-components'
import { Icons } from 'utils/icons'

const StyledListItem = styled.div`
display: flex;
width: 300px;
height: auto;
padding: 3px 10px 2px 10px;
justify-content: space-between;
align-items: center;
`
const Horizontal = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
`
const Center = styled.div`
align-items: center;
`

export enum AlertCategory {
ERROR,
WARNING,
INFO,
}

interface AlertProps {
children: ReactNode
dismissAlert: () => void
alertCategory: AlertCategory
}

export const AlertListItem = ({ children, dismissAlert, alertCategory }: AlertProps) => {
return (
<>
<StyledListItem>
<Horizontal>
<Center>{children}</Center>
</Horizontal>
<Button variant="ghost_icon" onClick={dismissAlert}>
<Icon name={Icons.Clear} size={24}></Icon>
</Button>
</StyledListItem>
</>
)
}
3 changes: 1 addition & 2 deletions frontend/src/components/Alerts/FailedAlertContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const Indent = styled.div`
export const FailedAlertContent = ({ title, message }: { title: string; message: string }) => {
const { TranslateText } = useLanguageContext()
const iconColor = tokens.colors.interactive.danger__resting.rgba
const bannerColor = tokens.colors.ui.background__danger.hex

return (
<StyledDiv>
Expand All @@ -31,7 +30,7 @@ export const FailedAlertContent = ({ title, message }: { title: string; message:
<Typography>{TranslateText(title)}</Typography>
</StyledAlertTitle>
<Indent>
<TextAlignedButton variant="ghost" color="secondary" style={{ backgroundColor: bannerColor }}>
<TextAlignedButton variant="ghost" color="secondary">
{TranslateText(message)}
</TextAlignedButton>
</Indent>
Expand Down
109 changes: 97 additions & 12 deletions frontend/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { config } from 'config'
import { Button, Icon, TopBar, Typography } from '@equinor/eds-core-react'
import { Button, Icon, TopBar, Typography, Popover } from '@equinor/eds-core-react'
import { useInstallationContext } from 'components/Contexts/InstallationContext'
import styled from 'styled-components'
import { SelectLanguage } from './LanguageSelector'
import { Icons } from 'utils/icons'
import { useAlertContext } from 'components/Contexts/AlertContext'
import { AlertBanner } from 'components/Alerts/AlertsBanner'
import { FrontPageSectionId } from 'models/FrontPageSectionId'
import { AlertListItem } from 'components/Alerts/AlertsListItem'
import { useState, useRef } from 'react'
import { tokens } from '@equinor/eds-tokens'

const StyledTopBar = styled(TopBar)`
align-items: center;
Expand All @@ -17,11 +19,19 @@ const StyledWrapper = styled.div`
flex-direction: row;
align-items: center;
`
const IconStyle = styled.div`
display: flex;
align-items: center;
flex-direction: row-reverse;
> * {
margin-left: 1rem;
}
`
const HandPointer = styled.div`
cursor: pointer;
`
const SelectLanguageWrapper = styled.div`
margin-left: 1rem;
margin-left: 1.5rem;
`
const StyledAlertList = styled.div`
display: grid;
Expand All @@ -35,13 +45,41 @@ const StyledTopBarHeader = styled.div`
gap: 4px;
`

const StyledAlertPopoverHeader = styled(Popover.Header)`
width: 350px;
`
const StyledAlertPopoverTitle = styled(Popover.Title)`
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-right: 0.25em !important;
`
const Circle = styled.div`
position: absolute;
margin: 14px 23px 0px;
width: 9px;
height: 9px;
border-radius: 50%;
`
export const Header = ({ page }: { page: string }) => {
const { alerts } = useAlertContext()
const { installationName } = useInstallationContext()

const [isAlertDialogOpen, setIsAlertDialogOpen] = useState<boolean>(false)
const referenceElementNotifications = useRef<HTMLButtonElement>(null)

const onAlertOpen = () => {
setIsAlertDialogOpen(true)
}

const onAlertClose = () => {
setIsAlertDialogOpen(false)
}

return (
<>
<StyledTopBar id={FrontPageSectionId.TopBar}>
<StyledTopBar>
<StyledWrapper>
<TopBar.Header
onClick={() => {
Expand All @@ -65,17 +103,64 @@ export const Header = ({ page }: { page: string }) => {
</TopBar.Header>
</StyledWrapper>
<TopBar.Actions>
<Button
variant="ghost_icon"
onClick={() => {
window.location.href = `${config.FRONTEND_BASE_ROUTE}/`
}}
>
<Icon name={Icons.Platform} size={24} title="Change Asset" />
</Button>
<IconStyle>
<Button
variant="ghost_icon"
onClick={!isAlertDialogOpen ? onAlertOpen : onAlertClose}
ref={referenceElementNotifications}
>
<Icon name={Icons.Notifications} size={24} />
{Object.entries(alerts).length !== 0 &&
installationName &&
page !== 'root' && ( //Alert banners
<Circle style={{ background: tokens.colors.interactive.danger__resting.hex }} />
)}
</Button>
<Button
variant="ghost_icon"
onClick={() => {
window.location.href = `${config.FRONTEND_BASE_ROUTE}/`
}}
>
<Icon name={Icons.Platform} size={24} title="Change Asset" />
</Button>
</IconStyle>
<SelectLanguageWrapper>{SelectLanguage()}</SelectLanguageWrapper>
</TopBar.Actions>
</StyledTopBar>
<Popover
onClose={onAlertClose}
open={isAlertDialogOpen}
placement={'bottom'}
anchorEl={referenceElementNotifications.current}
>
<StyledAlertPopoverHeader>
<StyledAlertPopoverTitle>
<span>System alerts</span>
<Button variant={'ghost_icon'} onClick={onAlertClose}>
<Icon name="close" size={24} />
</Button>
</StyledAlertPopoverTitle>
</StyledAlertPopoverHeader>
<Popover.Content>
{Object.entries(alerts).length === 0 && installationName && page !== 'root' && (
<Typography variant="h6">No alerts</Typography>
)}
{Object.entries(alerts).length > 0 && installationName && page !== 'root' && (
<StyledAlertList>
{Object.entries(alerts).map(([key, value]) => (
<AlertListItem
key={key}
dismissAlert={value.dismissFunction}
alertCategory={value.alertCategory}
>
{value.content}
</AlertListItem>
))}
</StyledAlertList>
)}
</Popover.Content>
</Popover>
{Object.entries(alerts).length > 0 && installationName && page !== 'root' && (
<StyledAlertList>
{Object.entries(alerts).map(([key, value]) => (
Expand Down

0 comments on commit 0d45330

Please sign in to comment.