Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TPI Frontend #3862

Merged
merged 29 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
06be346
TPI status work
dgboss Jul 9, 2024
491f327
Mockup changes
dgboss Jul 29, 2024
5be177b
TPI HFI infographic
dgboss Aug 14, 2024
fd5eee0
Remove message
dgboss Aug 14, 2024
46555c0
Minor fixes
dgboss Aug 14, 2024
5bacf07
Fix unit test
dgboss Aug 14, 2024
ab9d851
Whitespace
dgboss Aug 14, 2024
d7a6965
Remove unused imports
dgboss Aug 15, 2024
81844f4
Temp bump nats consumer mem
dgboss Aug 15, 2024
f36cb61
Reduce nats mem to 2GB
dgboss Aug 15, 2024
4e651ee
Fire Center Advisory Report (#3850)
brettedw Aug 15, 2024
7eac11e
Update renovatebot/github-action action to v40.2.6 (#3859)
renovate[bot] Aug 19, 2024
1344dc4
Update .gitignore and env example keys (#3856)
conbrad Aug 19, 2024
cf50337
ASA Radio Buttons (#3861)
brettedw Aug 19, 2024
6a27e6b
TPI HFI infographic
dgboss Aug 14, 2024
5797062
Fire Center Advisory Report (#3850)
brettedw Aug 15, 2024
bb1b3de
TPI HFI infographic
dgboss Aug 14, 2024
bbf19e9
Fire Center Advisory Report (#3850)
brettedw Aug 15, 2024
f306c46
Fix bad merge
conbrad Aug 19, 2024
518bb41
Merge branch 'main' into task/tpi-front-end/2190B
conbrad Aug 19, 2024
82cbb29
Remove duplication
conbrad Aug 19, 2024
af7bc88
Sync up with backend changes
conbrad Aug 19, 2024
5ed6210
Sync up with backend 2
conbrad Aug 19, 2024
d2b2de6
Simplify response type
conbrad Aug 19, 2024
618ca60
Bump nats deploy resources for jobs
conbrad Aug 19, 2024
b920342
Fix db lookup
conbrad Aug 19, 2024
12641d2
Add back fuel type summary, add tests
conbrad Aug 20, 2024
c013a41
More tests
conbrad Aug 20, 2024
d328405
Just use width
conbrad Aug 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ jobs:
shell: bash
run: |
oc login "${{ secrets.OPENSHIFT_CLUSTER }}" --token="${{ secrets.OC4_DEV_TOKEN }}"
PROJ_DEV="e1e498-dev" MEMORY_REQUEST=250Mi MEMORY_LIMIT=500Mi bash openshift/scripts/oc_provision_nats.sh ${SUFFIX} apply
PROJ_DEV="e1e498-dev" MEMORY_REQUEST=3800Mi MEMORY_LIMIT=5000Mi bash openshift/scripts/oc_provision_nats.sh ${SUFFIX} apply

scan-dev:
name: ZAP Baseline Scan Dev
Expand Down
5 changes: 1 addition & 4 deletions api/app/db/crud/auto_spatial_advisory.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,7 @@ async def get_zonal_tpi_stats(session: AsyncSession, fire_zone_id: int, run_type
shape_id = result.scalar()

stmt = select(
AdvisoryTPIStats.advisory_shape_id,
AdvisoryTPIStats.valley_bottom,
AdvisoryTPIStats.mid_slope,
AdvisoryTPIStats.upper_slope,
AdvisoryTPIStats.advisory_shape_id, AdvisoryTPIStats.valley_bottom, AdvisoryTPIStats.mid_slope, AdvisoryTPIStats.upper_slope, AdvisoryTPIStats.pixel_size_metres
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is pixel_size needed here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's expected to compute the area in the TPI endpoint

).where(AdvisoryTPIStats.advisory_shape_id == shape_id, AdvisoryTPIStats.run_parameters == run_parameters_id)

result = await session.execute(stmt)
Expand Down
19 changes: 19 additions & 0 deletions web/src/api/fbaAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export interface FireZoneElevationInfoResponse {
hfi_elevation_info: ElevationInfoByThreshold[]
}

export interface FireZoneTPIStats {
fire_zone_id: number
valley_bottom: number
mid_slope: number
upper_slope: number
}

export interface FireShapeAreaListResponse {
shapes: FireShapeArea[]
}
Expand Down Expand Up @@ -151,6 +158,18 @@ export async function getFireZoneElevationInfo(
return data
}

export async function getFireZoneTPIStats(
fire_zone_id: number,
run_type: RunType,
run_datetime: string,
for_date: string
): Promise<FireZoneTPIStats> {
const url = `fba/fire-zone-tpi-stats/${run_type.toLowerCase()}/${run_datetime}/${for_date}/${fire_zone_id}`
const { data } = await axios.get(url)
return data
}


export async function getValueAtCoordinate(
layer: string,
latitude: number,
Expand Down
3 changes: 3 additions & 0 deletions web/src/app/rootReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import valueAtCoordinateSlice from 'features/fba/slices/valueAtCoordinateSlice'
import runDatesSlice from 'features/fba/slices/runDatesSlice'
import hfiFuelTypesSlice from 'features/fba/slices/hfiFuelTypesSlice'
import fireZoneElevationInfoSlice from 'features/fba/slices/fireZoneElevationInfoSlice'
import fireZoneTPIStatsSlice from 'features/fba/slices/fireZoneTPIStatsSlice'
import stationGroupsSlice from 'commonSlices/stationGroupsSlice'
import selectedStationGroupsMembersSlice from 'commonSlices/selectedStationGroupMembers'
import dataSlice from 'features/moreCast2/slices/dataSlice'
Expand All @@ -38,6 +39,7 @@ const rootReducer = combineReducers({
valueAtCoordinate: valueAtCoordinateSlice,
hfiFuelTypes: hfiFuelTypesSlice,
fireZoneElevationInfo: fireZoneElevationInfoSlice,
fireZoneTPIStats: fireZoneTPIStatsSlice,
stationGroups: stationGroupsSlice,
stationGroupsMembers: selectedStationGroupsMembersSlice,
weatherIndeterminates: dataSlice,
Expand Down Expand Up @@ -67,6 +69,7 @@ export const selectRunDates = (state: RootState) => state.runDates
export const selectValueAtCoordinate = (state: RootState) => state.valueAtCoordinate
export const selectHFIFuelTypes = (state: RootState) => state.hfiFuelTypes
export const selectFireZoneElevationInfo = (state: RootState) => state.fireZoneElevationInfo
export const selectFireZoneTPIStats = (state: RootState) => state.fireZoneTPIStats

export const selectHFIDailiesLoading = (state: RootState): boolean => state.hfiCalculatorDailies.fireCentresLoading
export const selectHFICalculatorState = (state: RootState): HFICalculatorState => state.hfiCalculatorDailies
Expand Down
44 changes: 32 additions & 12 deletions web/src/features/fba/components/infoPanel/FireZoneUnitSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import React from 'react'
import { Grid } from '@mui/material'
import { isUndefined } from 'lodash'
import { ElevationInfoByThreshold, FireShape, FireShapeArea, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import ElevationInfoViz from 'features/fba/components/viz/ElevationInfoViz'
import React, { useEffect, useState } from 'react'
import { Grid, Typography } from '@mui/material'
import { isNull, isUndefined } from 'lodash'
import { FireShape, FireZoneTPIStats, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import InfoAccordion from 'features/fba/components/infoPanel/InfoAccordion'
import ElevationStatus from 'features/fba/components/viz/ElevationStatus'
import { useTheme } from '@mui/material/styles'
import FuelSummary from 'features/fba/components/viz/FuelSummary'

interface FireZoneUnitSummaryProps {
selectedFireZoneUnit: FireShape | undefined
fuelTypeInfo: Record<number, FireZoneThresholdFuelTypeArea[]>
hfiElevationInfo: ElevationInfoByThreshold[]
fireShapeAreas: FireShapeArea[]
fireZoneTPIStats: FireZoneTPIStats | null
}

const FireZoneUnitSummary = ({
fireShapeAreas,
fuelTypeInfo,
hfiElevationInfo,
fireZoneTPIStats,
selectedFireZoneUnit
}: FireZoneUnitSummaryProps) => {
const theme = useTheme()
const [midSlope, setMidSlope] = useState<number>(0)
const [upperSlope, setUpperSlope] = useState<number>(0)
const [valleyBottom, setValleyBottom] = useState<number>(0)

useEffect(() => {
if (!isNull(fireZoneTPIStats)) {
const total = fireZoneTPIStats.mid_slope + fireZoneTPIStats.upper_slope + fireZoneTPIStats.valley_bottom
setMidSlope(Math.round(fireZoneTPIStats.mid_slope/total*100))
setUpperSlope(Math.round(fireZoneTPIStats.upper_slope/total*100))
setValleyBottom(Math.round(fireZoneTPIStats.valley_bottom/total*100))
}
}, [fireZoneTPIStats])

if (isUndefined(selectedFireZoneUnit)) {
return <div data-testid="fire-zone-unit-summary-empty"></div>
Expand All @@ -34,11 +44,21 @@ const FireZoneUnitSummary = ({
direction={'column'}
sx={{ paddingBottom: theme.spacing(2), paddingTop: theme.spacing(2) }}
>
<Grid item sx={{ width: '95%' }}>

<Grid item sx={{ paddingBottom: theme.spacing(2), width: '95%' }}>
<FuelSummary selectedFireZoneUnit={selectedFireZoneUnit} fuelTypeInfo={fuelTypeInfo} />
</Grid>
<Grid item>
<ElevationInfoViz selectedFireZone={selectedFireZoneUnit} hfiElevationInfo={hfiElevationInfo} />
<Grid item sx={{ width: '95%' }}>
{ isNull(fireZoneTPIStats) ? (
<Typography>
No elevation information available.
</Typography>
) : (
<ElevationStatus
upper={upperSlope}
mid={midSlope}
bottom={valleyBottom}
></ElevationStatus>)}
</Grid>
</Grid>
</InfoAccordion>
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/fba/components/infoPanel/InfoPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface InfoPanelProps {
// A component to host information in a side panel in ASA.
const InfoPanel = React.forwardRef(({ children }: InfoPanelProps, ref: React.ForwardedRef<HTMLDivElement>) => {
return (
<Grid data-testid="info-panel" item ref={ref} sx={{ width: '500px', overflowY: 'auto' }}>
<Grid data-testid="info-panel" item ref={ref} sx={{ minWidth: '500px', maxWidth: '500px', overflowY: 'auto' }}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, what's the purpose of setting both min and max width to be equal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, picked it up from the existing commits in the branch but I can try undoing it 😅

{children}
</Grid>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import FireZoneUnitSummary from 'features/fba/components/infoPanel/FireZoneUnitS
import { FireShape } from 'api/fbaAPI'
import { render } from '@testing-library/react'

const fireZoneTPIStats = {
fire_zone_id: 0,
valley_bottom: 0,
mid_slope: 100,
upper_slope: 0
}

describe('FireZoneUnitSummary', () => {
class ResizeObserver {
observe() {
Expand All @@ -19,9 +26,8 @@ describe('FireZoneUnitSummary', () => {
it('should not render empty div if selectedFireZoneUnit is undefined', () => {
const { getByTestId } = render(
<FireZoneUnitSummary
fireShapeAreas={[]}
fuelTypeInfo={[]}
hfiElevationInfo={[]}
fireZoneTPIStats={fireZoneTPIStats}
selectedFireZoneUnit={undefined}
/>
)
Expand All @@ -37,13 +43,46 @@ describe('FireZoneUnitSummary', () => {
}
const { getByTestId } = render(
<FireZoneUnitSummary
fireShapeAreas={[]}
fuelTypeInfo={[]}
hfiElevationInfo={[]}
fireZoneTPIStats={fireZoneTPIStats}
selectedFireZoneUnit={fireShape}
/>
)
const fireZoneUnitInfo = getByTestId('fire-zone-unit-summary')
expect(fireZoneUnitInfo).toBeInTheDocument()
})
it('should not render TPI stats if null', () => {
const fireShape: FireShape = {
fire_shape_id: 1,
mof_fire_zone_name: 'foo',
mof_fire_centre_name: 'fizz',
area_sqm: 10
}
const { queryByTestId } = render(
<FireZoneUnitSummary
fuelTypeInfo={[]}
fireZoneTPIStats={null}
selectedFireZoneUnit={fireShape}
/>
)
const fireZoneUnitInfo = queryByTestId('elevation-status')
expect(fireZoneUnitInfo).not.toBeInTheDocument()
})
it('should render TPI stats if not null', () => {
const fireShape: FireShape = {
fire_shape_id: 1,
mof_fire_zone_name: 'foo',
mof_fire_centre_name: 'fizz',
area_sqm: 10
}
const { getByTestId } = render(
<FireZoneUnitSummary
fuelTypeInfo={[]}
fireZoneTPIStats={fireZoneTPIStats}
selectedFireZoneUnit={fireShape}
/>
)
const fireZoneUnitInfo = getByTestId('elevation-status')
expect(fireZoneUnitInfo).toBeInTheDocument()
})
})
1 change: 0 additions & 1 deletion web/src/features/fba/components/map/FBAMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import Legend from 'features/fba/components/map/Legend'
import ScalebarContainer from 'features/fba/components/map/ScaleBarContainer'
export const MapContext = React.createContext<ol.Map | null>(null)

const zoom = 5.5
const bcExtent = boundingExtent(BC_EXTENT.map(coord => fromLonLat(coord)))

export interface FBAMapProps {
Expand Down
39 changes: 39 additions & 0 deletions web/src/features/fba/components/viz/ElevationFlag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import { Box, Grid, Typography } from '@mui/material'

const FLAG_COLOUR = '#CCCCCC'

interface ElevationFlagProps {
testId?: string
percent: number
}

const ElevationFlag = ({ percent, testId }: ElevationFlagProps) => {
return (
<Grid item sx={{ display: 'flex', alignItems: 'center', flexGrow: 1, justifyContent: 'flex-start' }} xs={12}>
<Box
sx={{
backgroundColor: FLAG_COLOUR,
clipPath: 'polygon(0 50%, 10% 0, 100% 0, 100% 100%, 10% 100%)',
height: '32px',
padding: '1px',
width: '65%'
}}>
<Box
sx={{
alignItems: 'center',
backgroundImage: `linear-gradient(to right, ${FLAG_COLOUR} ${percent}%, #FFFFFFFF ${percent}%)`,
clipPath: 'polygon(0 50%, 10% 0, 100% 0, 100% 100%, 10% 100%)',
display: 'flex',
height: '30px',
justifyContent: 'center',
}}
>
<Typography sx={{ fontSize: '0.75em' }} data-testid={testId}>{percent}%</Typography>
</Box>
</Box>
</Grid>
)
}

export default React.memo(ElevationFlag)
16 changes: 16 additions & 0 deletions web/src/features/fba/components/viz/ElevationLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'
import { Grid, Typography } from '@mui/material'

interface ElevationLabelProps {
label: string
}

const ElevationLabel = ({ label }: ElevationLabelProps) => {
return (
<Grid item sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-end' }} xs={12}>
<Typography sx={{ fontSize: '0.75em' }}>{label}</Typography>
</Grid>
)
}

export default React.memo(ElevationLabel)
71 changes: 71 additions & 0 deletions web/src/features/fba/components/viz/ElevationStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react'
import { useTheme } from '@mui/material/styles'
import Grid from '@mui/material/Unstable_Grid2'
import Typography from '@mui/material/Typography'
import ElevationFlag from 'features/fba/components/viz/ElevationFlag'
import ElevationLabel from 'features/fba/components/viz/ElevationLabel'
import TPIMountain from 'features/fba/components/viz/TPIMountain'
import { Box } from '@mui/material'

enum ElevationOption {
BOTTOM = 'Valley Bottom',
MID = 'Mid Slope',
Upper = 'Upper Slope'
}

interface ElevationStatusProps {
bottom: number
mid: number
upper: number
}

const ElevationStatus = ({ bottom, mid, upper }: ElevationStatusProps) => {
const theme = useTheme()
return (
<Box sx={{ paddingBottom: theme.spacing(2), paddingTop: theme.spacing(2) }} data-testid="elevation-status">
<Grid container sx={{ minHeight: theme.spacing(19) }} xs={12}>
<Grid container sx={{ paddingRight: theme.spacing(2) }} xs={4}>
<Grid sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-end' }} xs={12}>
<Typography
sx={{
fontSize: '0.75em',
textAlign: 'right',
fontWeight: 'bold',
maxWidth: '75%'
}}
>
Topographic Position:
</Typography>
</Grid>
<ElevationLabel label={ElevationOption.Upper} />
<ElevationLabel label={ElevationOption.MID} />
<ElevationLabel label={ElevationOption.BOTTOM} />
</Grid>
<Grid container sx={{ alignItems: 'flex-end', display: 'flex' }} xs={4} data-testid='tpi-mountain'>
<Grid sx={{ display: 'flex', alignItems: 'flex-end', height: '80%', justifyContent: 'center' }} xs={12}>
<TPIMountain />
</Grid>
</Grid>
<Grid container sx={{ paddingLeft: theme.spacing(2) }} xs={4}>
<Grid sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-start' }} xs={12}>
<Typography
sx={{
fontSize: '0.75em',
textAlign: 'left',
fontWeight: 'bold',
maxWidth: '75%'
}}
>
Proportion of Advisory Area:
</Typography>
</Grid>
<ElevationFlag percent={upper} testId='upper-slope' />
<ElevationFlag percent={mid} testId='mid-slope' />
<ElevationFlag percent={bottom} testId='valley-bottom' />
</Grid>
</Grid>
</Box>
)
}

export default ElevationStatus
3 changes: 0 additions & 3 deletions web/src/features/fba/components/viz/FuelSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ const FuelSummary = ({ fuelTypeInfo, selectedFireZoneUnit }: FuelSummaryProps) =

return (
<Box sx={{ paddingBottom: theme.spacing(2), paddingTop: theme.spacing(2) }}>
<Typography sx={{ fontWeight: 'bold', paddingBottom: theme.spacing(1), textAlign: 'center' }}>
HFI Distribution by Fuel Type
</Typography>
{fuelTypeInfoRollup.length === 0 ? (
<Typography>No fuel type information available.</Typography>
) : (
Expand Down
Loading
Loading