Skip to content

Commit

Permalink
ASA Advisory Status Bar (#3980)
Browse files Browse the repository at this point in the history
- Adds coloured advisory hash bar to the advisory report dropdown. Bar only visible if there is Warning or Advisory status

- Closes ASA Hashing #3963

- Additional minor change: updates default tab colour to white to match figma design
  • Loading branch information
brettedw authored Oct 2, 2024
1 parent 43f30bf commit 8aefeda
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 23 deletions.
17 changes: 16 additions & 1 deletion web/src/features/fba/components/infoPanel/AdvisoryReport.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { calculateStatusText } from '@/features/fba/calculateZoneStatus'
import { useFireCentreDetails } from '@/features/fba/hooks/useFireCentreDetails'
import { Box, Tabs, Tab, Grid } from '@mui/material'
import { FireCenter, FireShape } from 'api/fbaAPI'
import { INFO_PANEL_CONTENT_BACKGROUND } from 'app/theme'
Expand Down Expand Up @@ -28,19 +30,32 @@ const TabPanel = ({ children, index, value }: TabPanelProps) => {
)
}

const AdvisoryReport = ({ issueDate, forDate, advisoryThreshold, selectedFireCenter, selectedFireZoneUnit }: AdvisoryReportProps) => {
const AdvisoryReport = ({
issueDate,
forDate,
advisoryThreshold,
selectedFireCenter,
selectedFireZoneUnit
}: AdvisoryReportProps) => {
const [tabNumber, setTabNumber] = useState(0)

const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
setTabNumber(newValue)
}

const groupedFireZoneUnits = useFireCentreDetails(selectedFireCenter)
const fireZoneUnitDetails = groupedFireZoneUnits.find(
zone => zone.fire_shape_id === selectedFireZoneUnit?.fire_shape_id
)

return (
<div data-testid="advisory-report">
<InfoAccordion
defaultExpanded={true}
title={'Advisory Report'}
accordionDetailBackgroundColour={INFO_PANEL_CONTENT_BACKGROUND}
showAdvisoryStatusBar={true}
advisoryStatus={calculateStatusText(fireZoneUnitDetails?.fireShapeDetails || [], advisoryThreshold)}
>
<Grid container justifyContent="center">
<Grid item sx={{ width: '90%' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const FireZoneUnitTabs = ({
key={key}
data-testid={`zone-${key}-tab`}
sx={{
backgroundColor: calculateStatusColour(zone.fireShapeDetails, advisoryThreshold, '#DCDCDC'),
backgroundColor: calculateStatusColour(zone.fireShapeDetails, advisoryThreshold, '#FFFFFF'),
minWidth: 'auto',
marginTop: theme.spacing(2),
fontWeight: 'bold',
Expand Down
80 changes: 64 additions & 16 deletions web/src/features/fba/components/infoPanel/InfoAccordion.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,51 @@
import React from 'react'

import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material'
import { Accordion, AccordionDetails, AccordionSummary, Box, Typography } from '@mui/material'
import { styled, useTheme } from '@mui/material/styles'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import { INFO_PANEL_HEADER_BACKGROUND } from 'app/theme'
import { INFO_PANEL_CONTENT_BACKGROUND, INFO_PANEL_HEADER_BACKGROUND } from 'app/theme'
import { AdvisoryStatus } from '@/utils/constants'
import { ADVISORY_ORANGE_FILL, ADVISORY_RED_LINE } from '@/features/fba/components/map/featureStylers'

const getAdvisoryBarColour = (advisoryStatus: AdvisoryStatus | undefined) => {
switch (advisoryStatus) {
case AdvisoryStatus.WARNING:
return ADVISORY_RED_LINE
case AdvisoryStatus.ADVISORY:
return ADVISORY_ORANGE_FILL
default:
return INFO_PANEL_CONTENT_BACKGROUND
}
}
interface AdvisoryStatusBarProps {
advisoryStatus: AdvisoryStatus | undefined
}

const AdvisoryStatusBar = ({ advisoryStatus }: AdvisoryStatusBarProps) => {
const barColour = getAdvisoryBarColour(advisoryStatus)

const advisoryBackground = advisoryStatus
? `repeating-linear-gradient(135deg, ${barColour}, ${barColour} 40px, white 40px, white 70px)`
: barColour

return (
<Box
data-testid="advisory-status-bar"
sx={{
height: '10px',
background: advisoryBackground
}}
/>
)
}

interface InfoAccordionProps {
accordionDetailBackgroundColour?: string
children: React.ReactNode
defaultExpanded: boolean
title: string
showAdvisoryStatusBar?: boolean
advisoryStatus?: AdvisoryStatus
}

const StyledAccordionSummary = styled(AccordionSummary)(() => ({
Expand All @@ -20,24 +56,36 @@ const StyledAccordionSummary = styled(AccordionSummary)(() => ({
}))

// A component for rendering the provided title and content in an accordion format in the info panel.
const InfoAccordion = ({ accordionDetailBackgroundColour, children, defaultExpanded, title }: InfoAccordionProps) => {
const InfoAccordion = ({
accordionDetailBackgroundColour,
children,
defaultExpanded,
title,
showAdvisoryStatusBar = false,
advisoryStatus
}: InfoAccordionProps) => {
const theme = useTheme()

return (
<Accordion data-testid="info-accordion" disableGutters defaultExpanded={defaultExpanded} elevation={0}>
<StyledAccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography
data-testid="info-accordion-title"
sx={{
color: theme.palette.primary.main,
fontWeight: 'bold',
paddingLeft: '1.25rem'
}}
variant="h6"
>
{title}
</Typography>
</StyledAccordionSummary>
<Box>
<StyledAccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography
data-testid="info-accordion-title"
sx={{
color: theme.palette.primary.main,
fontWeight: 'bold',
paddingLeft: '1.25rem'
}}
variant="h6"
>
{title}
</Typography>
</StyledAccordionSummary>
{showAdvisoryStatusBar && (
<AdvisoryStatusBar data-testid="advisory-status-bar" advisoryStatus={advisoryStatus} />
)}
</Box>
<AccordionDetails
data-testid="info-accordion-details"
sx={{
Expand Down
57 changes: 56 additions & 1 deletion web/src/features/fba/components/infoPanel/infoAccordion.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import InfoAccordion from 'features/fba/components/infoPanel/InfoAccordion'
import { render } from '@testing-library/react'
import { AdvisoryStatus } from '@/utils/constants'
import { ADVISORY_ORANGE_FILL, ADVISORY_RED_LINE } from '@/features/fba/components/map/featureStylers'
import { INFO_PANEL_CONTENT_BACKGROUND } from '@/app/theme'

describe('InfoAccordion', () => {
it('should render', () => {
Expand Down Expand Up @@ -58,4 +60,57 @@ describe('InfoAccordion', () => {
const fizzDiv = getByTestId('fizz')
expect(fizzDiv).not.toBeVisible()
})
it('should render a red advisory status bar if provided a Warning status', () => {
const { getByTestId } = render(
<InfoAccordion
defaultExpanded={true}
title="foo"
showAdvisoryStatusBar={true}
advisoryStatus={AdvisoryStatus.WARNING}
>
<div data-testid="fizz">fizz</div>
</InfoAccordion>
)
const statusBar = getByTestId('advisory-status-bar')
expect(statusBar).toBeVisible()
expect(statusBar).toHaveStyle(`
background: repeating-linear-gradient(135deg, ${ADVISORY_RED_LINE} , ${ADVISORY_RED_LINE} 40px, white 40px, white 70px)
`)
})
it('should render an orange advisory status bar if provided an Advisory status', () => {
const { getByTestId } = render(
<InfoAccordion
defaultExpanded={true}
title="foo"
showAdvisoryStatusBar={true}
advisoryStatus={AdvisoryStatus.ADVISORY}
>
<div data-testid="fizz">fizz</div>
</InfoAccordion>
)
const statusBar = getByTestId('advisory-status-bar')
expect(statusBar).toBeVisible()
expect(statusBar).toHaveStyle(`
background: repeating-linear-gradient(135deg, ${ADVISORY_ORANGE_FILL} , ${ADVISORY_ORANGE_FILL} 40px, white 40px, white 70px)
`)
})
it('should render a grey advisory status bar if no status is provided or the status is undefined', () => {
const { queryByTestId } = render(
<InfoAccordion defaultExpanded={true} title="foo" showAdvisoryStatusBar={true} advisoryStatus={undefined}>
<div data-testid="fizz">fizz</div>
</InfoAccordion>
)
const statusBar = queryByTestId('advisory-status-bar')
expect(statusBar).toBeVisible()
expect(statusBar).toHaveStyle(`background: ${INFO_PANEL_CONTENT_BACKGROUND}`)
})
it('should not render an advisory status bar if showAdvisoryStatusBar is not set to true', () => {
const { queryByTestId } = render(
<InfoAccordion defaultExpanded={true} title="foo">
<div data-testid="fizz">fizz</div>
</InfoAccordion>
)
const statusBar = queryByTestId('advisory-status-bar')
expect(statusBar).not.toBeInTheDocument()
})
})
12 changes: 8 additions & 4 deletions web/src/features/fba/components/map/featureStylers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const EMPTY_FILL = 'rgba(0, 0, 0, 0.0)'
export const ADVISORY_ORANGE_FILL = 'rgba(255, 147, 38, 0.4)'
export const ADVISORY_RED_FILL = 'rgba(128, 0, 0, 0.4)'

export const ADVISORY_RED_LINE = 'rgba(238, 0, 0, 1)'
export const ADVISORY_ORANGE_LINE = 'rgba(219, 135, 1, 1)'
const ADVISORY_GREY_LINE = 'rgba(127, 127, 127, 1)'

export const HFI_ADVISORY = 'rgba(255, 128, 0, 0.4)'
export const HFI_WARNING = 'rgba(255, 0, 0, 0.4)'

Expand Down Expand Up @@ -131,11 +135,11 @@ const getFireShapeStatus = (advisoryThreshold: number, fireShapeArea?: FireShape
const getFireShapeStrokeColor = (fireShapeStatus: FireShapeStatus) => {
switch (fireShapeStatus) {
case FireShapeStatus.ADVISORY:
return '#db8701'
return ADVISORY_ORANGE_LINE
case FireShapeStatus.WARNING:
return [227, 0, 1, 0.99]
return ADVISORY_RED_LINE
default:
return '#7f7f7f'
return ADVISORY_GREY_LINE
}
}

Expand Down Expand Up @@ -164,7 +168,7 @@ const getFireZoneUnitLabel = (feature: RenderFeature | ol.Feature<Geometry>) =>
const index = fireZoneUnit.indexOf('(')
const prefix = fireZoneUnit.substring(0, index).trim()
const suffix = fireZoneUnit.substring(index)
fireZoneUnit = `${prefix}\n${suffix}`
fireZoneUnit = `${prefix}\n${suffix}`
}

return `${fireZoneId}-${fireZoneUnit}`
Expand Down

0 comments on commit 8aefeda

Please sign in to comment.