Skip to content

Commit 8ae6ac9

Browse files
committed
feat(country-risk-watch): build out JBA and ARC event details for Malawi Risk Watch
- render JBA forecast COGs as a map raster overlay with layer panel, opacity and HDX choropleth controls - present band_5 ensemble stats as population exposed (not flood depth) with a people-scale impact threshold - add forecast trajectory and 30-day rainfall history charts, plus district RP100 flood-exposure context - prefill field reports with population exposed and external source/id; surface activation status (trigger, MRCS review, report created) with a review deep link
1 parent bc570b9 commit 8ae6ac9

66 files changed

Lines changed: 4488 additions & 502 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,14 @@ jobs:
244244
- name: Install dependencies
245245
run: pnpm install
246246

247+
- name: Generate types
248+
run: pnpm generate:type
249+
247250
- uses: actions/download-artifact@v4
248251
with:
249252
name: ui-build
250253
path: packages/ui/dist
251254

252-
- name: Generate types
253-
run: pnpm generate:type
254-
255255
- name: Typecheck
256256
run: pnpm typecheck
257257

app/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default defineConfig({
2424
APP_TINY_API_KEY: Schema.string(),
2525
APP_RISK_API_ENDPOINT: Schema.string({ format: 'url', protocol: true }),
2626
APP_MALAWI_RISK_WATCH_GRAPHQL_ENDPOINT: Schema.string({ format: 'url', protocol: true, tld: false }),
27+
APP_MALAWI_RISK_WATCH_ADMIN_URL: Schema.string.optional({ format: 'url', protocol: true, tld: false }),
2728
APP_SDT_URL: Schema.string.optional({ format: 'url', protocol: true, tld: false }),
2829
APP_POWER_BI_REPORT_ID_1: Schema.string.optional(),
2930
APP_SENTRY_DSN: Schema.string.optional(),

app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"surge:teardown": "branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD); branch=$(echo $branch | tr ./ -); surge teardown https://ifrc-go-$branch.surge.sh"
4444
},
4545
"dependencies": {
46+
"@graphql-typed-document-node/core": "^3.2.0",
4647
"@ifrc-go/icons": "^2.0.1",
4748
"@ifrc-go/ui": "workspace:^",
4849
"@sentry/react": "^10.0.0",
@@ -57,6 +58,7 @@
5758
"diff-match-patch": "^1.0.5",
5859
"exceljs": "^4.4.0",
5960
"file-saver": "^2.0.5",
61+
"geotiff": "^3.0.5",
6062
"graphql": "^16.14.0",
6163
"html-to-image": "^1.11.13",
6264
"mapbox-gl": "^1.13.3",

app/src/components/Link/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ function Link(props: Props) {
133133
</ButtonLayout>
134134
);
135135

136-
if (nonLink) {
136+
if (nonLink || disabled) {
137137
return (
138138
<div className={styles.link}>
139139
{content}
@@ -148,6 +148,7 @@ function Link(props: Props) {
148148
target="_blank"
149149
rel="noopener noreferrer"
150150
href={toLink}
151+
aria-disabled={disabled}
151152
// eslint-disable-next-line react/jsx-props-no-spreading
152153
{...linkProps}
153154
>
@@ -164,6 +165,7 @@ function Link(props: Props) {
164165
search: urlSearch,
165166
hash: urlHash,
166167
}}
168+
aria-disabled={disabled}
167169
// eslint-disable-next-line react/jsx-props-no-spreading
168170
{...linkProps}
169171
>

app/src/components/Navbar/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
sdtUrl,
2424
} from '#config';
2525
import useAuth from '#hooks/domain/useAuth';
26+
import { FIELD_REPORT_STATUS_EARLY_WARNING } from '#utils/constants';
2627

2728
import AuthenticatedUserDropdown from './AuthenticatedUserDropdown';
2829
import CountryDropdown from './CountryDropdown';
@@ -313,7 +314,11 @@ function Navbar(props: Props) {
313314
to="fieldReportFormNew"
314315
colorVariant="primary"
315316
styleVariant="action"
316-
state={{ earlyWarning: true }}
317+
state={{
318+
initialValue: {
319+
status: FIELD_REPORT_STATUS_EARLY_WARNING,
320+
},
321+
}}
317322
withoutFullWidth
318323
>
319324
{strings.userMenuCreateEarlyActionFieldReport}

app/src/components/StepGradientBar/styles.module.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
.step-gradient-bar {
2-
width: min(30cqi, 10rem);
2+
width: min(36cqi, 16rem);
33

44
.step {
55
flex-grow: 1;
6+
text-align: center;
67

78
.swatch {
89
height: 0.5rem;

app/src/components/domain/ActiveCountryBaseMapLayer/index.tsx

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { useMemo } from 'react';
22
import { MapLayer } from '@togglecorp/re-map';
33
import {
4+
type BackgroundLayer,
45
type FillLayer,
56
type LineLayer,
67
type SymbolLayer,
78
} from 'mapbox-gl';
89

910
import {
1011
COLOR_ACTIVE_REGION,
11-
COLOR_LIGHT_GREY,
1212
COLOR_WHITE,
1313
} from '#utils/constants';
1414

@@ -19,6 +19,18 @@ const hiddenFillLayerOptions: Omit<FillLayer, 'id'> = {
1919
},
2020
};
2121

22+
const hiddenLineLayerOptions: Omit<LineLayer, 'id'> = {
23+
type: 'line',
24+
layout: {
25+
visibility: 'none',
26+
},
27+
};
28+
29+
const backgroundLayerOptions: Omit<BackgroundLayer, 'id'> = {
30+
type: 'background',
31+
paint: { 'background-color': COLOR_WHITE },
32+
};
33+
2234
interface Props {
2335
activeCountryIso3: string | undefined | null;
2436
}
@@ -32,20 +44,13 @@ function ActiveCountryBaseMapLayer(props: Props) {
3244
layout: { visibility: 'visible' },
3345
paint: {
3446
'fill-color': [
35-
'interpolate',
36-
['linear'],
37-
['zoom'],
38-
2,
39-
[
40-
'match',
41-
['get', 'iso3'],
42-
activeCountryIso3,
43-
COLOR_ACTIVE_REGION,
44-
COLOR_LIGHT_GREY,
45-
],
46-
10,
47-
COLOR_LIGHT_GREY,
47+
'match',
48+
['get', 'iso3'],
49+
activeCountryIso3,
50+
COLOR_ACTIVE_REGION,
51+
COLOR_WHITE,
4852
],
53+
'fill-opacity': 0.2,
4954
},
5055
}),
5156
[activeCountryIso3],
@@ -56,17 +61,11 @@ function ActiveCountryBaseMapLayer(props: Props) {
5661
type: 'line',
5762
layout: { visibility: 'visible' },
5863
paint: {
59-
'line-color': [
60-
'match',
61-
['get', 'country_iso3'],
62-
activeCountryIso3,
63-
COLOR_WHITE,
64-
COLOR_LIGHT_GREY,
65-
],
64+
'line-color': COLOR_WHITE,
6665
'line-opacity': 1,
6766
},
6867
}),
69-
[activeCountryIso3],
68+
[],
7069
);
7170

7271
const adminOneLabelLayerOptions = useMemo<Omit<SymbolLayer, 'id'>>(
@@ -89,16 +88,58 @@ function ActiveCountryBaseMapLayer(props: Props) {
8988
[activeCountryIso3],
9089
);
9190

91+
const adminZeroLabelLayerOptions = useMemo<Omit<SymbolLayer, 'id'>>(
92+
() => ({
93+
type: 'symbol',
94+
layout: {
95+
visibility: 'none',
96+
},
97+
}),
98+
[],
99+
);
100+
92101
return (
93102
<>
94103
<MapLayer
95-
layerKey="admin-0"
96-
layerOptions={adminZeroHighlightLayerOptions}
104+
layerKey="background"
105+
layerOptions={backgroundLayerOptions}
106+
/>
107+
<MapLayer
108+
layerKey="hillshade"
109+
layerOptions={hiddenFillLayerOptions}
110+
/>
111+
<MapLayer
112+
layerKey="admin-0-boundary-mask"
113+
layerOptions={hiddenLineLayerOptions}
114+
/>
115+
<MapLayer
116+
layerKey="admin-0-boundary"
117+
layerOptions={hiddenLineLayerOptions}
118+
/>
119+
<MapLayer
120+
layerKey="admin-0-boundary-disputed"
121+
layerOptions={hiddenLineLayerOptions}
97122
/>
98123
<MapLayer
99124
layerKey="admin-0-highlight"
100125
layerOptions={hiddenFillLayerOptions}
101126
/>
127+
<MapLayer
128+
layerKey="admin-0-label"
129+
layerOptions={adminZeroLabelLayerOptions}
130+
/>
131+
<MapLayer
132+
layerKey="admin-0-label-priority"
133+
layerOptions={adminZeroLabelLayerOptions}
134+
/>
135+
<MapLayer
136+
layerKey="admin-0-label-non-independent"
137+
layerOptions={adminZeroLabelLayerOptions}
138+
/>
139+
<MapLayer
140+
layerKey="admin-0"
141+
layerOptions={adminZeroHighlightLayerOptions}
142+
/>
102143
<MapLayer
103144
layerKey="admin-1-boundary"
104145
layerOptions={adminOneBoundaryLayerOptions}

app/src/components/domain/ImminentEventListItem/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ function ImminentEventListItem(props: Props) {
7575
withDarkBackground
7676
withPadding
7777
withoutSpacingOpticalCorrection
78-
withContentWell
7978
>
8079
{children}
8180
</Container>

0 commit comments

Comments
 (0)