diff --git a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/i18n.json b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/i18n.json index 08af8f59c..934b05122 100644 --- a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/i18n.json +++ b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/i18n.json @@ -24,6 +24,7 @@ "wfpExposed90": "Exposed (90km/h)", "wfpExposed120": "Exposed (120km/h)", "wfpFloodArea": "Flood Area", - "wfpFloodCropland": "Flood Cropland" + "wfpFloodCropland": "Flood Cropland", + "wfpChartLabel": "Windspeed over time" } } diff --git a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/index.tsx b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/index.tsx index 6f614f7f2..e7418a31d 100644 --- a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/index.tsx +++ b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/index.tsx @@ -10,9 +10,10 @@ import Link from '#components/Link'; import BlockLoading from '#components/BlockLoading'; import Container from '#components/Container'; import TextOutput from '#components/TextOutput'; +import Tooltip from '#components/Tooltip'; +import useTranslation from '#hooks/useTranslation'; import { getPercentage, maxSafe, roundSafe } from '#utils/common'; import { type RiskApiResponse } from '#utils/restRequest'; -import useTranslation from '#hooks/useTranslation'; import { isValidFeatureCollection, isValidPointFeature } from '#utils/domain/risk'; import { resolveToString } from '#utils/translation'; @@ -167,23 +168,33 @@ function EventDetails(props: Props) { {stormPoints && stormPoints.length > 0 && isDefined(maxWindSpeed) && ( /* TODO: use proper svg charts */
- {stormPoints.map( - (point) => ( -
- ), - )} +
+ {stormPoints.map( + (point) => ( +
+ +
+
+ ), + )} +
+
+ {strings.wfpChartLabel} +
)} {isDefined(eventDetails) diff --git a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/styles.module.css b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/styles.module.css index 07a8064c8..20c79cf7d 100644 --- a/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/styles.module.css +++ b/src/components/domain/RiskImminentEvents/WfpAdam/EventDetails/styles.module.css @@ -6,15 +6,42 @@ .wind-speed-chart { display: flex; - align-items: flex-end; - justify-content: space-around; - height: 10rem; + flex-direction: column; + gap: var(--go-ui-spacing-xs); - .bar { - border-top-left-radius: 2pt; - border-top-right-radius: 2pt; - background-color: var(--go-ui-color-primary-red); - width: 4pt; + .bar-list-container { + display: flex; + align-items: stretch; + height: 10rem; + + .bar-container { + display: flex; + align-items: flex-end; + flex-basis: 0; + flex-grow: 1; + justify-content: center; + transition: var(--go-ui-duration-transition-medium) background-color ease-in-out; + border-top-left-radius: 2pt; + border-top-right-radius: 2pt; + background-color: transparent; + + .bar { + background-color: var(--go-ui-color-primary-red); + width: 4pt; + height: 100%; + } + + &:hover { + background-color: var(--go-ui-color-background-hover); + } + } + } + + .chart-label { + text-align: center; + color: var(--go-ui-color-text-light); + font-size: var(--go-ui-font-size-sm); + font-weight: var(--go-ui-font-weight-medium); } } diff --git a/src/utils/domain/risk.test.ts b/src/utils/domain/risk.test.ts new file mode 100644 index 000000000..92397fad2 --- /dev/null +++ b/src/utils/domain/risk.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from 'vitest'; + +import { CATEGORY_RISK_LOW, CATEGORY_RISK_VERY_LOW } from '#utils/constants'; + +import { riskScoreToCategory } from './risk.ts'; + +test('Risk score to category', () => { + expect( + riskScoreToCategory( + 0, + 'FL', + ), + ).toEqual(CATEGORY_RISK_VERY_LOW); + expect( + riskScoreToCategory( + 3, + 'FL', + ), + ).toEqual(CATEGORY_RISK_LOW); +}); diff --git a/src/utils/domain/risk.ts b/src/utils/domain/risk.ts index 2fef90818..d90f0b6a0 100644 --- a/src/utils/domain/risk.ts +++ b/src/utils/domain/risk.ts @@ -77,7 +77,7 @@ export interface RiskDataItem { annual_average?: number | null, } -export const monthNumberToNameMap: Record = { +const monthToKeyMap: Record = { 0: 'january', 1: 'february', 2: 'march', @@ -90,6 +90,10 @@ export const monthNumberToNameMap: Record = { 9: 'october', 10: 'november', 11: 'december', +}; + +export const monthNumberToNameMap: Record = { + ...monthToKeyMap, // FIXME: we should not have these different // class of data into same list 12: 'annual_average', @@ -100,8 +104,42 @@ export function getValueForSelectedMonths( riskDataItem: RiskDataItem | undefined, aggregationMode: 'sum' | 'max' = 'sum', ) { - if (isNotDefined(selectedMonths)) { - return riskDataItem?.annual_average ?? undefined; + let annualValue; + + if (aggregationMode === 'sum') { + annualValue = sumSafe([ + riskDataItem?.january, + riskDataItem?.february, + riskDataItem?.march, + riskDataItem?.april, + riskDataItem?.may, + riskDataItem?.june, + riskDataItem?.july, + riskDataItem?.august, + riskDataItem?.september, + riskDataItem?.october, + riskDataItem?.november, + riskDataItem?.december, + ]); + } else if (aggregationMode === 'max') { + annualValue = maxSafe([ + riskDataItem?.january, + riskDataItem?.february, + riskDataItem?.march, + riskDataItem?.april, + riskDataItem?.may, + riskDataItem?.june, + riskDataItem?.july, + riskDataItem?.august, + riskDataItem?.september, + riskDataItem?.october, + riskDataItem?.november, + riskDataItem?.december, + ]); + } + + if (isNotDefined(selectedMonths) || selectedMonths[12] === true) { + return riskDataItem?.annual_average ?? annualValue ?? undefined; } const monthKeys = Object.keys( @@ -269,7 +307,7 @@ export function riskScoreToCategory( score: number | undefined | null, hazardType: HazardType, ) { - if (isNotDefined(score) || score <= 0) { + if (isNotDefined(score) || score < 0) { return undefined; } diff --git a/src/views/CountryProfileRiskWatch/PossibleEarlyActionTable/index.tsx b/src/views/CountryProfileRiskWatch/PossibleEarlyActionTable/index.tsx index b4079b8e4..644faa503 100644 --- a/src/views/CountryProfileRiskWatch/PossibleEarlyActionTable/index.tsx +++ b/src/views/CountryProfileRiskWatch/PossibleEarlyActionTable/index.tsx @@ -143,6 +143,10 @@ function PossibleEarlyActionTable(props: Props) { }, }); + if (!filtered && possibleEarlyActionResponse?.count === 0) { + return null; + } + return ( { + if (isNotDefined(imminentEventCountsResponse)) { + return false; + } + + const eventCounts = mapToList( + imminentEventCountsResponse, + (value) => value, + ).filter(isDefined).filter( + (value) => value > 0, + ); + + return eventCounts.length > 0; + }, + [imminentEventCountsResponse], + ); + // NOTE: we always get 1 child in the response const riskResponse = countryRiskResponse?.[0]; const bbox = useMemo( @@ -52,7 +82,10 @@ export function Component() { return (
- {countryResponse && isDefined(countryResponse.iso3) && ( + {pendingImminentEventCounts && ( + + )} + {hasImminentEvents && isDefined(countryResponse) && isDefined(countryResponse.iso3) && (