@opengeoweb/cap 9.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/index.esm.d.ts +1 -0
- package/index.esm.js +990 -0
- package/package.json +37 -0
- package/src/index.d.ts +1 -0
- package/src/lib/CapDemo.stories.d.ts +7 -0
- package/src/lib/components/CapMapAndList.integration.spec.d.ts +1 -0
- package/src/lib/components/ComponentsLookUp/componentsLookUp.d.ts +34 -0
- package/src/lib/components/ComponentsLookUp/componentsLookUp.spec.d.ts +1 -0
- package/src/lib/components/ComponentsLookUp/index.d.ts +1 -0
- package/src/lib/components/GanttChart/Gantt.d.ts +40 -0
- package/src/lib/components/GanttChart/GanttModule.d.ts +7 -0
- package/src/lib/components/GanttChart/GanttModule.spec.d.ts +1 -0
- package/src/lib/components/GanttChart/GanttModule.stories.d.ts +6 -0
- package/src/lib/components/GanttChart/GanttReactWrapper.d.ts +37 -0
- package/src/lib/components/GanttChart/GanttWrapper.d.ts +9 -0
- package/src/lib/components/GanttChart/GanttWrapper.spec.d.ts +1 -0
- package/src/lib/components/GanttChart/GanttWrapper.stories.d.ts +8 -0
- package/src/lib/components/GanttChart/Task.d.ts +29 -0
- package/src/lib/components/GanttChart/ViewMode.d.ts +9 -0
- package/src/lib/components/GanttChart/mockTasks.d.ts +2 -0
- package/src/lib/components/GanttChart/utils.d.ts +5 -0
- package/src/lib/components/GanttChart/utils.spec.d.ts +1 -0
- package/src/lib/components/MapViewCap/MapViewCapConnect.d.ts +18 -0
- package/src/lib/components/MapViewCap/MapViewCapConnect.spec.d.ts +1 -0
- package/src/lib/components/MapViewCap/MapViewCapConnect.stories.d.ts +6 -0
- package/src/lib/components/MapViewCap/MapViewCapConnectWrapper.d.ts +17 -0
- package/src/lib/components/MapViewCap/MapViewCapConnectWrapper.spec.d.ts +1 -0
- package/src/lib/components/MapViewCap/index.d.ts +1 -0
- package/src/lib/components/Providers/Providers.d.ts +30 -0
- package/src/lib/components/Providers/index.d.ts +1 -0
- package/src/lib/components/WarningListCap/WarningListCap.d.ts +8 -0
- package/src/lib/components/WarningListCap/WarningListCap.spec.d.ts +1 -0
- package/src/lib/components/WarningListCap/WarningListCap.stories.d.ts +6 -0
- package/src/lib/components/WarningListCap/WarningListCapConnect.d.ts +7 -0
- package/src/lib/components/WarningListCap/WarningListCapConnectWrapper.d.ts +6 -0
- package/src/lib/components/WarningListCap/WarningListCapConnectWrapper.spec.d.ts +1 -0
- package/src/lib/components/WarningListCap/WarningListRowCap/WarningListRowCap.d.ts +7 -0
- package/src/lib/components/WarningListCap/WarningListRowCap/WarningListRowCap.spec.d.ts +1 -0
- package/src/lib/components/WarningListCap/WarningListRowCap/WarningListRowCap.stories.d.ts +6 -0
- package/src/lib/components/WarningListCap/WarningListRowCap/WarningListRowCapConnect.d.ts +8 -0
- package/src/lib/components/WarningListCap/WarningListRowCap/WarningListRowCapConnect.spec.d.ts +1 -0
- package/src/lib/components/WarningListCap/index.d.ts +1 -0
- package/src/lib/components/WarningListCap/types.d.ts +47 -0
- package/src/lib/components/types.d.ts +73 -0
- package/src/lib/index.d.ts +4 -0
- package/src/lib/store/config.d.ts +6 -0
- package/src/lib/store/index.d.ts +3 -0
- package/src/lib/store/mockStore.d.ts +21 -0
- package/src/lib/store/reducer.d.ts +13 -0
- package/src/lib/store/reducer.spec.d.ts +1 -0
- package/src/lib/store/selector.spec.d.ts +1 -0
- package/src/lib/store/selectors.d.ts +15 -0
- package/src/lib/store/types.d.ts +42 -0
- package/src/lib/store.d.ts +4 -0
- package/src/lib/utils/addColors.d.ts +2 -0
- package/src/lib/utils/addColors.spec.d.ts +1 -0
- package/src/lib/utils/addFeedAddressToCustomGeoJsonFeature.d.ts +2 -0
- package/src/lib/utils/addFeedAddressToCustomGeoJsonFeature.spec.d.ts +1 -0
- package/src/lib/utils/api.d.ts +20 -0
- package/src/lib/utils/api.spec.d.ts +1 -0
- package/src/lib/utils/fakeApi.d.ts +2 -0
- package/src/lib/utils/fakeApi.spec.d.ts +1 -0
- package/src/lib/utils/feedLanguageUtils.d.ts +1 -0
- package/src/lib/utils/feedLanguageUtils.spec.d.ts +1 -0
- package/src/lib/utils/findEventIndexInLanguage.d.ts +10 -0
- package/src/lib/utils/findEventIndexInLanguage.spec.d.ts +1 -0
- package/src/lib/utils/highlightGeoJson.d.ts +3 -0
- package/src/lib/utils/highlightGeoJson.spec.d.ts +1 -0
- package/src/lib/utils/i18n.d.ts +2 -0
- package/src/lib/utils/mockAlert.d.ts +19 -0
- package/src/lib/utils/mockCapData.d.ts +6 -0
- package/src/lib/utils/mockGeoJson.d.ts +4 -0
- package/src/lib/utils/mockGeoJsonMultipleFeatures.d.ts +3 -0
- package/src/lib/utils/store.d.ts +2 -0
package/index.esm.js
ADDED
|
@@ -0,0 +1,990 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useApiContext, useApi, createNonAuthApiInstance, ApiProvider } from '@opengeoweb/api';
|
|
3
|
+
import { Grid, Typography, Box, Card, CircularProgress } from '@mui/material';
|
|
4
|
+
import { Box as Box$1 } from '@mui/system';
|
|
5
|
+
import { dateUtils, AlertBanner, withEggs } from '@opengeoweb/shared';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import { useSelector, useDispatch } from 'react-redux';
|
|
8
|
+
import { createEntityAdapter, createSlice, createSelector } from '@reduxjs/toolkit';
|
|
9
|
+
import 'i18next';
|
|
10
|
+
import { ConfigurableMapConnect } from '@opengeoweb/core';
|
|
11
|
+
import { mapSelectors, coreModuleConfig } from '@opengeoweb/store';
|
|
12
|
+
import { webmapUtils } from '@opengeoweb/webmap';
|
|
13
|
+
import { MapViewLayer, MapWarningProperties } from '@opengeoweb/webmap-react';
|
|
14
|
+
import { fromUnixTime } from 'date-fns';
|
|
15
|
+
import { ThemeWrapper } from '@opengeoweb/theme';
|
|
16
|
+
|
|
17
|
+
/* *
|
|
18
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
19
|
+
* you may not use this file except in compliance with the License.
|
|
20
|
+
* You may obtain a copy of the License at
|
|
21
|
+
*
|
|
22
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
23
|
+
*
|
|
24
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
25
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
26
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
27
|
+
* See the License for the specific language governing permissions and
|
|
28
|
+
* limitations under the License.
|
|
29
|
+
*
|
|
30
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
31
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
32
|
+
* */
|
|
33
|
+
const feedAdapter = createEntityAdapter();
|
|
34
|
+
const feedInitialState = feedAdapter.getInitialState();
|
|
35
|
+
const alertAdapter = createEntityAdapter({
|
|
36
|
+
// we use identifier as id
|
|
37
|
+
selectId: capAlert => capAlert.identifier
|
|
38
|
+
});
|
|
39
|
+
const alertInitialState = alertAdapter.getInitialState();
|
|
40
|
+
const initialState = {
|
|
41
|
+
feeds: feedInitialState,
|
|
42
|
+
alerts: alertInitialState
|
|
43
|
+
};
|
|
44
|
+
const slice = createSlice({
|
|
45
|
+
initialState,
|
|
46
|
+
name: 'capReducer',
|
|
47
|
+
reducers: {
|
|
48
|
+
addManyAlerts: (draft, action) => {
|
|
49
|
+
alertAdapter.upsertMany(draft.alerts, action.payload);
|
|
50
|
+
},
|
|
51
|
+
addManyAlertsToFeed: (draft, action) => {
|
|
52
|
+
feedAdapter.upsertOne(draft.feeds, {
|
|
53
|
+
id: action.payload.feedId,
|
|
54
|
+
lastUpdated: Date.now(),
|
|
55
|
+
alertIds: action.payload.alertIds
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
setFeedLastUpdatedTimes: (draft, action) => {
|
|
59
|
+
feedAdapter.updateMany(draft.feeds, action.payload);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const {
|
|
64
|
+
reducer
|
|
65
|
+
} = slice;
|
|
66
|
+
const capActions = slice.actions;
|
|
67
|
+
|
|
68
|
+
/* *
|
|
69
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
70
|
+
* you may not use this file except in compliance with the License.
|
|
71
|
+
* You may obtain a copy of the License at
|
|
72
|
+
*
|
|
73
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
74
|
+
*
|
|
75
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
76
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
77
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
78
|
+
* See the License for the specific language governing permissions and
|
|
79
|
+
* limitations under the License.
|
|
80
|
+
*
|
|
81
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
82
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
83
|
+
* */
|
|
84
|
+
const {
|
|
85
|
+
selectById: getCapFeedById,
|
|
86
|
+
selectAll: getCapFeeds
|
|
87
|
+
} = feedAdapter.getSelectors(state => state.capStore.feeds);
|
|
88
|
+
const {
|
|
89
|
+
selectById: getAlertById,
|
|
90
|
+
selectAll: getAlerts,
|
|
91
|
+
selectIds: getAlertIds
|
|
92
|
+
} = alertAdapter.getSelectors(state => state.capStore.alerts);
|
|
93
|
+
const getAlertsInEffect = createSelector(getAlerts, (_state, selectedTime) => selectedTime, (alerts, selectedTime) => {
|
|
94
|
+
return alerts.filter(alert => dateUtils.isBetween(dateUtils.createDate(selectedTime), dateUtils.createDate(alert.onset), dateUtils.createDate(alert.expires), '[)'));
|
|
95
|
+
});
|
|
96
|
+
const getLastUpdatedTimes = createSelector(getCapFeeds, feeds => {
|
|
97
|
+
return feeds.map(feed => feed.lastUpdated);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/* *
|
|
101
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
102
|
+
* you may not use this file except in compliance with the License.
|
|
103
|
+
* You may obtain a copy of the License at
|
|
104
|
+
*
|
|
105
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
106
|
+
*
|
|
107
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
108
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
109
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
110
|
+
* See the License for the specific language governing permissions and
|
|
111
|
+
* limitations under the License.
|
|
112
|
+
*
|
|
113
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
114
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
115
|
+
* */
|
|
116
|
+
const findEventIndexInLanguage = (languages, capWarningPresets, feedAddressFromProps) => {
|
|
117
|
+
const correctFeedIndex = capWarningPresets.feeds.findIndex(({
|
|
118
|
+
feedAddress
|
|
119
|
+
}) => feedAddress === feedAddressFromProps);
|
|
120
|
+
if (correctFeedIndex === -1) {
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
const languageIndex = languages.findIndex(object => object.language === (capWarningPresets === null || capWarningPresets === void 0 ? void 0 : capWarningPresets.feeds[correctFeedIndex].languagePriority));
|
|
124
|
+
if (languageIndex === -1) {
|
|
125
|
+
const fallbackLanguage = languages.findIndex(object => object.language.startsWith('en'));
|
|
126
|
+
if (fallbackLanguage === -1) {
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
return fallbackLanguage;
|
|
130
|
+
}
|
|
131
|
+
return languageIndex;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
var en = {
|
|
135
|
+
"map-view-cap-error-title": "Something went wrong with loading the configuration file",
|
|
136
|
+
"warning-list-cap-alert-banner-title": "Note: Only map is affected by timeslider based filtering",
|
|
137
|
+
"warning-list-cap-error-title": "Something went wrong with loading the configuration file",
|
|
138
|
+
"warning-list-row-event": "Event",
|
|
139
|
+
"warning-list-row-severity": "Severity",
|
|
140
|
+
"warning-list-row-expires": "Expires",
|
|
141
|
+
"warning-list-row-not-expired": "(not expired)"
|
|
142
|
+
};
|
|
143
|
+
var fi = {
|
|
144
|
+
"map-view-cap-error-title": "🚧 ei käännetty",
|
|
145
|
+
"warning-list-cap-alert-banner-title": "🚧 ei käännetty",
|
|
146
|
+
"warning-list-cap-error-title": "🚧 ei käännetty",
|
|
147
|
+
"warning-list-row-event": "🚧 ei käännetty",
|
|
148
|
+
"warning-list-row-severity": "🚧 ei käännetty",
|
|
149
|
+
"warning-list-row-expires": "🚧 ei käännetty",
|
|
150
|
+
"warning-list-row-not-expired": "🚧 ei käännetty"
|
|
151
|
+
};
|
|
152
|
+
var capTrans = {
|
|
153
|
+
en: en,
|
|
154
|
+
fi: fi
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/* *
|
|
158
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
159
|
+
* you may not use this file except in compliance with the License.
|
|
160
|
+
* You may obtain a copy of the License at
|
|
161
|
+
*
|
|
162
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
163
|
+
*
|
|
164
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
165
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
166
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
167
|
+
* See the License for the specific language governing permissions and
|
|
168
|
+
* limitations under the License.
|
|
169
|
+
*
|
|
170
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
171
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
172
|
+
* */
|
|
173
|
+
const CAP_NAMESPACE = 'cap';
|
|
174
|
+
|
|
175
|
+
/* *
|
|
176
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
177
|
+
* you may not use this file except in compliance with the License.
|
|
178
|
+
* You may obtain a copy of the License at
|
|
179
|
+
*
|
|
180
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
181
|
+
*
|
|
182
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
183
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
184
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
185
|
+
* See the License for the specific language governing permissions and
|
|
186
|
+
* limitations under the License.
|
|
187
|
+
*
|
|
188
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
189
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
190
|
+
* */
|
|
191
|
+
const severityStyles = {
|
|
192
|
+
Extreme: {
|
|
193
|
+
border: 'solid 5px rgb(255, 9, 9)',
|
|
194
|
+
background: 'rgba(255, 9, 9, 0.15)'
|
|
195
|
+
},
|
|
196
|
+
Severe: {
|
|
197
|
+
border: 'solid 5px rgb(255, 165, 0)',
|
|
198
|
+
background: 'rgba(255, 165, 0, 0.15)'
|
|
199
|
+
},
|
|
200
|
+
Moderate: {
|
|
201
|
+
border: 'solid 5px rgb(248, 248, 0)',
|
|
202
|
+
background: 'rgba(248, 248, 0, 0.15)'
|
|
203
|
+
},
|
|
204
|
+
Minor: {
|
|
205
|
+
border: 'solid 5px rgb(106, 248, 108)',
|
|
206
|
+
background: 'rgba(106, 248, 108, 0.15)'
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
const WarningListRowCap = ({
|
|
210
|
+
event,
|
|
211
|
+
severity,
|
|
212
|
+
expires
|
|
213
|
+
}) => {
|
|
214
|
+
const {
|
|
215
|
+
t
|
|
216
|
+
} = useTranslation(CAP_NAMESPACE);
|
|
217
|
+
return React.createElement(Grid, {
|
|
218
|
+
container: true,
|
|
219
|
+
sx: {
|
|
220
|
+
border: severityStyles[severity].border,
|
|
221
|
+
background: severityStyles[severity].background,
|
|
222
|
+
padding: '5px',
|
|
223
|
+
marginTop: '20px',
|
|
224
|
+
marginBottom: '20px',
|
|
225
|
+
width: '100%'
|
|
226
|
+
}
|
|
227
|
+
}, React.createElement(Grid, {
|
|
228
|
+
item: true,
|
|
229
|
+
xs: 4
|
|
230
|
+
}, React.createElement(Typography, {
|
|
231
|
+
variant: "overline"
|
|
232
|
+
}, t('warning-list-row-event')), React.createElement(Typography, {
|
|
233
|
+
variant: "subtitle2",
|
|
234
|
+
sx: {
|
|
235
|
+
fontWeight: 'normal'
|
|
236
|
+
},
|
|
237
|
+
"data-testid": "event"
|
|
238
|
+
}, event ? `${event}` : '')), React.createElement(Grid, {
|
|
239
|
+
item: true,
|
|
240
|
+
xs: 4
|
|
241
|
+
}, React.createElement(Typography, {
|
|
242
|
+
variant: "overline"
|
|
243
|
+
}, t('warning-list-row-severity')), React.createElement(Typography, {
|
|
244
|
+
variant: "subtitle2",
|
|
245
|
+
sx: {
|
|
246
|
+
fontWeight: 'normal'
|
|
247
|
+
},
|
|
248
|
+
"data-testid": "severity"
|
|
249
|
+
}, severity ? `${severity}` : '')), React.createElement(Grid, {
|
|
250
|
+
item: true,
|
|
251
|
+
xs: 4
|
|
252
|
+
}, React.createElement(Typography, {
|
|
253
|
+
variant: "overline"
|
|
254
|
+
}, t('warning-list-row-expires')), React.createElement(Typography, {
|
|
255
|
+
variant: "subtitle2",
|
|
256
|
+
sx: {
|
|
257
|
+
fontWeight: 'normal'
|
|
258
|
+
},
|
|
259
|
+
"data-testid": "expires"
|
|
260
|
+
}, expires ? dateUtils.dateToString(dateUtils.createDate(expires), "dd MMM yyyy, HH:mm 'UTC'") : t('warning-list-row-not-expired'))));
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/* *
|
|
264
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
265
|
+
* you may not use this file except in compliance with the License.
|
|
266
|
+
* You may obtain a copy of the License at
|
|
267
|
+
*
|
|
268
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
269
|
+
*
|
|
270
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
271
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
272
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
273
|
+
* See the License for the specific language governing permissions and
|
|
274
|
+
* limitations under the License.
|
|
275
|
+
*
|
|
276
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
277
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
278
|
+
* */
|
|
279
|
+
const WarningListRowCapConnect = ({
|
|
280
|
+
alertId,
|
|
281
|
+
capWarningPresets
|
|
282
|
+
}) => {
|
|
283
|
+
const [languageIndex, setLanguageIndex] = React.useState(0);
|
|
284
|
+
const alert = useSelector(store => getAlertById(store, alertId));
|
|
285
|
+
React.useEffect(() => {
|
|
286
|
+
if (alert) {
|
|
287
|
+
const foundLanguageIndex = findEventIndexInLanguage(alert.languages, capWarningPresets, alert.feedAddress);
|
|
288
|
+
setLanguageIndex(foundLanguageIndex);
|
|
289
|
+
}
|
|
290
|
+
}, [alert, capWarningPresets]);
|
|
291
|
+
return React.createElement("div", null, alert && React.createElement(WarningListRowCap, {
|
|
292
|
+
event: alert.languages[languageIndex].event,
|
|
293
|
+
severity: alert.severity,
|
|
294
|
+
expires: alert.expires
|
|
295
|
+
}));
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/* *
|
|
299
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
300
|
+
* you may not use this file except in compliance with the License.
|
|
301
|
+
* You may obtain a copy of the License at
|
|
302
|
+
*
|
|
303
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
304
|
+
*
|
|
305
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
306
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
307
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
308
|
+
* See the License for the specific language governing permissions and
|
|
309
|
+
* limitations under the License.
|
|
310
|
+
*
|
|
311
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
312
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
313
|
+
* */
|
|
314
|
+
const WarningListCap = ({
|
|
315
|
+
capWarningPresets,
|
|
316
|
+
alertIds
|
|
317
|
+
}) => {
|
|
318
|
+
const {
|
|
319
|
+
t
|
|
320
|
+
} = useTranslation(CAP_NAMESPACE);
|
|
321
|
+
return React.createElement(Box, {
|
|
322
|
+
sx: {
|
|
323
|
+
width: '100%',
|
|
324
|
+
height: '100%',
|
|
325
|
+
display: 'flex'
|
|
326
|
+
}
|
|
327
|
+
}, React.createElement(Card, {
|
|
328
|
+
sx: {
|
|
329
|
+
justifyContent: 'center',
|
|
330
|
+
alignItems: 'center',
|
|
331
|
+
overflow: 'auto',
|
|
332
|
+
height: '95%',
|
|
333
|
+
width: '100%',
|
|
334
|
+
padding: '10px',
|
|
335
|
+
margin: '20px',
|
|
336
|
+
marginBottom: '10px',
|
|
337
|
+
position: 'relative'
|
|
338
|
+
},
|
|
339
|
+
"data-testid": "warningList"
|
|
340
|
+
}, alertIds.length > 0 && React.createElement(Box, {
|
|
341
|
+
sx: {
|
|
342
|
+
position: 'sticky',
|
|
343
|
+
top: 0,
|
|
344
|
+
width: '100%',
|
|
345
|
+
display: 'flex',
|
|
346
|
+
justifyContent: 'center'
|
|
347
|
+
}
|
|
348
|
+
}, React.createElement(AlertBanner, {
|
|
349
|
+
title: t('warning-list-cap-alert-banner-title')
|
|
350
|
+
})), alertIds.length === 0 ? React.createElement(Box, {
|
|
351
|
+
sx: {
|
|
352
|
+
position: 'absolute',
|
|
353
|
+
left: '50%',
|
|
354
|
+
top: '20%',
|
|
355
|
+
zIndex: '100'
|
|
356
|
+
}
|
|
357
|
+
}, React.createElement(CircularProgress, null)) : null, alertIds.map(id => React.createElement(WarningListRowCapConnect, {
|
|
358
|
+
key: id,
|
|
359
|
+
alertId: id,
|
|
360
|
+
capWarningPresets: capWarningPresets
|
|
361
|
+
}))));
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
/* *
|
|
365
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
366
|
+
* you may not use this file except in compliance with the License.
|
|
367
|
+
* You may obtain a copy of the License at
|
|
368
|
+
*
|
|
369
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
370
|
+
*
|
|
371
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
372
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
373
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
374
|
+
* See the License for the specific language governing permissions and
|
|
375
|
+
* limitations under the License.
|
|
376
|
+
*
|
|
377
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
378
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
379
|
+
* */
|
|
380
|
+
const WarningListCapConnect = ({
|
|
381
|
+
capWarningPresets
|
|
382
|
+
}) => {
|
|
383
|
+
const alertIDs = useSelector(store => getAlertIds(store));
|
|
384
|
+
return React.createElement(WarningListCap, {
|
|
385
|
+
capWarningPresets: capWarningPresets,
|
|
386
|
+
alertIds: alertIDs
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/* *
|
|
391
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
392
|
+
* you may not use this file except in compliance with the License.
|
|
393
|
+
* You may obtain a copy of the License at
|
|
394
|
+
*
|
|
395
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
396
|
+
*
|
|
397
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
398
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
399
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
400
|
+
* See the License for the specific language governing permissions and
|
|
401
|
+
* limitations under the License.
|
|
402
|
+
*
|
|
403
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
404
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
405
|
+
* */
|
|
406
|
+
const WarningListCapConnectWrapper = ({
|
|
407
|
+
productConfigKey
|
|
408
|
+
}) => {
|
|
409
|
+
const {
|
|
410
|
+
api
|
|
411
|
+
} = useApiContext();
|
|
412
|
+
const {
|
|
413
|
+
t
|
|
414
|
+
} = useTranslation(CAP_NAMESPACE);
|
|
415
|
+
const {
|
|
416
|
+
result: productConfig,
|
|
417
|
+
isLoading: isConfigLoading,
|
|
418
|
+
error
|
|
419
|
+
} = useApi(api.getCapConfiguration, productConfigKey);
|
|
420
|
+
if (isConfigLoading) {
|
|
421
|
+
return React.createElement(Box$1, {
|
|
422
|
+
sx: {
|
|
423
|
+
display: 'flex',
|
|
424
|
+
justifyContent: 'center',
|
|
425
|
+
alignItems: 'center'
|
|
426
|
+
}
|
|
427
|
+
}, React.createElement(CircularProgress, {
|
|
428
|
+
"data-testid": "loadingSpinner"
|
|
429
|
+
}));
|
|
430
|
+
}
|
|
431
|
+
if (error) {
|
|
432
|
+
return React.createElement(AlertBanner, {
|
|
433
|
+
title: t('warning-list-cap-error-title'),
|
|
434
|
+
info: error.message
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
return React.createElement(WarningListCapConnect, {
|
|
438
|
+
capWarningPresets: productConfig
|
|
439
|
+
});
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/* *
|
|
443
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
444
|
+
* you may not use this file except in compliance with the License.
|
|
445
|
+
* You may obtain a copy of the License at
|
|
446
|
+
*
|
|
447
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
448
|
+
*
|
|
449
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
450
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
451
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
452
|
+
* See the License for the specific language governing permissions and
|
|
453
|
+
* limitations under the License.
|
|
454
|
+
*
|
|
455
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
456
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
457
|
+
* */
|
|
458
|
+
const getApiRoutes = (axiosInstance, nonAuthAxiosInstance) => ({
|
|
459
|
+
getCapConfiguration: productConfigKey => {
|
|
460
|
+
return nonAuthAxiosInstance.get(`/assets/${productConfigKey}`);
|
|
461
|
+
},
|
|
462
|
+
getAllAlerts: thirdPartyApiUrl => {
|
|
463
|
+
return axiosInstance.get(`/allalerts?url=${thirdPartyApiUrl}`);
|
|
464
|
+
},
|
|
465
|
+
getFeedLinks: thirdPartyApiUrl => {
|
|
466
|
+
return axiosInstance.get(`/feedlinks?url=${thirdPartyApiUrl}`);
|
|
467
|
+
},
|
|
468
|
+
getSingleAlert: alertUrl => {
|
|
469
|
+
return axiosInstance.get(`/singlealert?url=${alertUrl}`);
|
|
470
|
+
},
|
|
471
|
+
getLastUpdated: thirdPartyApiUrl => {
|
|
472
|
+
return axiosInstance.get(`/poll_feed?url=${thirdPartyApiUrl}`);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
const createApi = props => {
|
|
476
|
+
const axiosInstance = createNonAuthApiInstance(props);
|
|
477
|
+
const nonAuthAxiosInstance = createNonAuthApiInstance({});
|
|
478
|
+
return getApiRoutes(axiosInstance, nonAuthAxiosInstance);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
/******************************************************************************
|
|
482
|
+
Copyright (c) Microsoft Corporation.
|
|
483
|
+
|
|
484
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
485
|
+
purpose with or without fee is hereby granted.
|
|
486
|
+
|
|
487
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
488
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
489
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
490
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
491
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
492
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
493
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
494
|
+
***************************************************************************** */
|
|
495
|
+
|
|
496
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
497
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
498
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
499
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
500
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
501
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
502
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
507
|
+
var e = new Error(message);
|
|
508
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
/* *
|
|
512
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
513
|
+
* you may not use this file except in compliance with the License.
|
|
514
|
+
* You may obtain a copy of the License at
|
|
515
|
+
*
|
|
516
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
517
|
+
*
|
|
518
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
519
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
520
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
521
|
+
* See the License for the specific language governing permissions and
|
|
522
|
+
* limitations under the License.
|
|
523
|
+
*
|
|
524
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
525
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
526
|
+
* */
|
|
527
|
+
const highlightGeoJson = (currentFeatures, featureResults) => Object.entries(currentFeatures).reduce((byId, [alertId, features]) => {
|
|
528
|
+
const isSelected = alertId === (featureResults === null || featureResults === void 0 ? void 0 : featureResults.feature.properties.details.identifier);
|
|
529
|
+
return Object.assign(Object.assign({}, byId), {
|
|
530
|
+
[alertId]: features.map(feature => {
|
|
531
|
+
const recoloredFeature = Object.assign({}, feature);
|
|
532
|
+
recoloredFeature.properties.fill = isSelected ? feature.properties.fill.replace('0.10', '0.25') : recoloredFeature.properties.fill = feature.properties.fill.replace('0.25', '0.10');
|
|
533
|
+
recoloredFeature.properties['stroke-width'] = isSelected ? 3 : 2;
|
|
534
|
+
return recoloredFeature;
|
|
535
|
+
})
|
|
536
|
+
});
|
|
537
|
+
}, {});
|
|
538
|
+
|
|
539
|
+
/* *
|
|
540
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
541
|
+
* you may not use this file except in compliance with the License.
|
|
542
|
+
* You may obtain a copy of the License at
|
|
543
|
+
*
|
|
544
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
545
|
+
*
|
|
546
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
547
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
548
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
549
|
+
* See the License for the specific language governing permissions and
|
|
550
|
+
* limitations under the License.
|
|
551
|
+
*
|
|
552
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
553
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
554
|
+
* */
|
|
555
|
+
const addColors = features => {
|
|
556
|
+
const severityStyles = {
|
|
557
|
+
Extreme: {
|
|
558
|
+
stroke: 'rgb(255, 9, 9)',
|
|
559
|
+
fill: 'rgba(255, 9, 9, 0.10)'
|
|
560
|
+
},
|
|
561
|
+
Severe: {
|
|
562
|
+
stroke: 'rgb(255, 165, 0)',
|
|
563
|
+
fill: 'rgba(255, 165, 0, 0.10)'
|
|
564
|
+
},
|
|
565
|
+
Moderate: {
|
|
566
|
+
stroke: 'rgb(248, 248, 0)',
|
|
567
|
+
fill: 'rgba(248, 248, 0, 0.10)'
|
|
568
|
+
},
|
|
569
|
+
Minor: {
|
|
570
|
+
stroke: 'rgb(106, 248, 108)',
|
|
571
|
+
fill: 'rgba(106, 248, 108, 0.10)'
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
for (const feature of features) {
|
|
575
|
+
const {
|
|
576
|
+
severity
|
|
577
|
+
} = feature.properties.details;
|
|
578
|
+
feature.properties.stroke = severityStyles[severity].stroke;
|
|
579
|
+
feature.properties.fill = severityStyles[severity].fill;
|
|
580
|
+
feature.properties['stroke-opacity'] = 1;
|
|
581
|
+
feature.properties['stroke-width'] = 2;
|
|
582
|
+
}
|
|
583
|
+
return features;
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
/* *
|
|
587
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
588
|
+
* you may not use this file except in compliance with the License.
|
|
589
|
+
* You may obtain a copy of the License at
|
|
590
|
+
*
|
|
591
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
592
|
+
*
|
|
593
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
594
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
595
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
596
|
+
* See the License for the specific language governing permissions and
|
|
597
|
+
* limitations under the License.
|
|
598
|
+
*
|
|
599
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
600
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
601
|
+
* */
|
|
602
|
+
const addFeedAdressToCustomGeoJSonFeature = (feedAddress, features) => {
|
|
603
|
+
return features.reduce((list, feature) => {
|
|
604
|
+
return list.concat(Object.assign(Object.assign({}, feature), {
|
|
605
|
+
properties: Object.assign(Object.assign({}, feature.properties), {
|
|
606
|
+
details: Object.assign(Object.assign({}, feature.properties.details), {
|
|
607
|
+
feedAddress
|
|
608
|
+
})
|
|
609
|
+
})
|
|
610
|
+
}));
|
|
611
|
+
}, []);
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
/* *
|
|
615
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
616
|
+
* you may not use this file except in compliance with the License.
|
|
617
|
+
* You may obtain a copy of the License at
|
|
618
|
+
*
|
|
619
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
620
|
+
*
|
|
621
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
622
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
623
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
624
|
+
* See the License for the specific language governing permissions and
|
|
625
|
+
* limitations under the License.
|
|
626
|
+
*
|
|
627
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
628
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
629
|
+
* */
|
|
630
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
|
|
631
|
+
const isPromiseFulfilled = result => result.status === 'fulfilled';
|
|
632
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
|
|
633
|
+
const promiseSuccesses = results => results.reduce((acc, result) => isPromiseFulfilled(result) ? [...acc, result.value] : acc, []);
|
|
634
|
+
const MapViewCapConnect = ({
|
|
635
|
+
id,
|
|
636
|
+
title,
|
|
637
|
+
bbox,
|
|
638
|
+
srs,
|
|
639
|
+
capWarningPresets,
|
|
640
|
+
layers
|
|
641
|
+
}) => {
|
|
642
|
+
const {
|
|
643
|
+
api
|
|
644
|
+
} = useApiContext();
|
|
645
|
+
const dispatch = useDispatch();
|
|
646
|
+
const previousFeatures = React.useRef(null);
|
|
647
|
+
const [featuresByAlert, setFeaturesByAlert] = React.useState({});
|
|
648
|
+
const [selectedFeatureEvent, setSelectedFeatureEvent] = React.useState(null);
|
|
649
|
+
const mapIdRef = React.useRef(id || webmapUtils.generateMapId());
|
|
650
|
+
const layerIdRef = React.useRef(webmapUtils.generateLayerId());
|
|
651
|
+
const currentLastUpdatedTimes = useSelector(store => getLastUpdatedTimes(store));
|
|
652
|
+
const fetchData = (links, feedAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
653
|
+
const alertsAndFeaturesPromises = links.map(alertUrl => __awaiter(void 0, void 0, void 0, function* () {
|
|
654
|
+
const {
|
|
655
|
+
data
|
|
656
|
+
} = yield api.getSingleAlert(alertUrl);
|
|
657
|
+
const alert = Object.assign(Object.assign({}, data.alert), {
|
|
658
|
+
feedAddress
|
|
659
|
+
});
|
|
660
|
+
const features = addFeedAdressToCustomGeoJSonFeature(feedAddress, data.features.features);
|
|
661
|
+
return {
|
|
662
|
+
alert,
|
|
663
|
+
features
|
|
664
|
+
};
|
|
665
|
+
}));
|
|
666
|
+
const alertsAndFeatures = yield Promise.allSettled(alertsAndFeaturesPromises);
|
|
667
|
+
const realAlertsAndFeatures = alertsAndFeatures.reduce((alerts, result) =>
|
|
668
|
+
// endpoints may throttle requests and return empty alerts
|
|
669
|
+
isPromiseFulfilled(result) && result.value.alert ? [...alerts, result.value] : alerts, []);
|
|
670
|
+
const alerts = realAlertsAndFeatures.map(({
|
|
671
|
+
alert
|
|
672
|
+
}) => Object.assign({}, alert));
|
|
673
|
+
dispatch(capActions.addManyAlerts(alerts));
|
|
674
|
+
dispatch(capActions.addManyAlertsToFeed({
|
|
675
|
+
feedId: feedAddress,
|
|
676
|
+
alertIds: alerts.map(alert => alert.identifier)
|
|
677
|
+
}));
|
|
678
|
+
const featuresByAlert = realAlertsAndFeatures.reduce((byId, {
|
|
679
|
+
alert,
|
|
680
|
+
features
|
|
681
|
+
}) => Object.assign(Object.assign({}, byId), {
|
|
682
|
+
[alert.identifier]: addColors(features)
|
|
683
|
+
}), {});
|
|
684
|
+
const combinedFeatures = Object.assign(Object.assign({}, previousFeatures.current), featuresByAlert);
|
|
685
|
+
setFeaturesByAlert(combinedFeatures);
|
|
686
|
+
previousFeatures.current = combinedFeatures;
|
|
687
|
+
});
|
|
688
|
+
const fetchDataFromAllFeeds = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
689
|
+
const feedPromises = capWarningPresets === null || capWarningPresets === void 0 ? void 0 : capWarningPresets.feeds.map(({
|
|
690
|
+
feedAddress
|
|
691
|
+
}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
692
|
+
const {
|
|
693
|
+
data: links
|
|
694
|
+
} = yield api.getFeedLinks(feedAddress);
|
|
695
|
+
return {
|
|
696
|
+
links,
|
|
697
|
+
feedAddress
|
|
698
|
+
};
|
|
699
|
+
}));
|
|
700
|
+
const feedLinks = promiseSuccesses(yield Promise.allSettled(feedPromises));
|
|
701
|
+
feedLinks.forEach(({
|
|
702
|
+
links,
|
|
703
|
+
feedAddress
|
|
704
|
+
}) => {
|
|
705
|
+
fetchData(links, feedAddress);
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
const pollAndUpdate = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
709
|
+
const lastUpdatedPromises = capWarningPresets === null || capWarningPresets === void 0 ? void 0 : capWarningPresets.feeds.map(feed => __awaiter(void 0, void 0, void 0, function* () {
|
|
710
|
+
const {
|
|
711
|
+
data: updated
|
|
712
|
+
} = yield api.getLastUpdated(feed.feedAddress);
|
|
713
|
+
return {
|
|
714
|
+
id: feed.feedAddress,
|
|
715
|
+
changes: {
|
|
716
|
+
lastUpdated: updated.lastUpdated
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
}));
|
|
720
|
+
if (lastUpdatedPromises) {
|
|
721
|
+
const lastUpdateTimes = promiseSuccesses(yield Promise.allSettled(lastUpdatedPromises));
|
|
722
|
+
lastUpdateTimes.forEach((feed, i) => __awaiter(void 0, void 0, void 0, function* () {
|
|
723
|
+
if (dateUtils.isAfter(feed.changes.lastUpdated, currentLastUpdatedTimes[i])) {
|
|
724
|
+
const {
|
|
725
|
+
data: links
|
|
726
|
+
} = yield api.getFeedLinks(feed.id);
|
|
727
|
+
fetchData(links, feed.id);
|
|
728
|
+
}
|
|
729
|
+
}));
|
|
730
|
+
dispatch(capActions.setFeedLastUpdatedTimes(lastUpdateTimes));
|
|
731
|
+
}
|
|
732
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
733
|
+
}), [currentLastUpdatedTimes]);
|
|
734
|
+
React.useEffect(() => {
|
|
735
|
+
fetchDataFromAllFeeds();
|
|
736
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
737
|
+
}, []);
|
|
738
|
+
React.useEffect(() => {
|
|
739
|
+
var _a;
|
|
740
|
+
const pollInterval = (_a = capWarningPresets === null || capWarningPresets === void 0 ? void 0 : capWarningPresets.pollInterval) !== null && _a !== void 0 ? _a : 300000;
|
|
741
|
+
const timer = setInterval(() => {
|
|
742
|
+
pollAndUpdate();
|
|
743
|
+
}, pollInterval);
|
|
744
|
+
return () => {
|
|
745
|
+
clearInterval(timer);
|
|
746
|
+
};
|
|
747
|
+
}, [capWarningPresets === null || capWarningPresets === void 0 ? void 0 : capWarningPresets.pollInterval, currentLastUpdatedTimes, pollAndUpdate]);
|
|
748
|
+
const parentSizeRef = React.useRef(null);
|
|
749
|
+
const [parentSize, setParentSize] = React.useState(window.innerWidth / 2);
|
|
750
|
+
React.useEffect(() => {
|
|
751
|
+
const handleWindowResize = () => {
|
|
752
|
+
setParentSize(parentSizeRef.current.parentElement.offsetWidth);
|
|
753
|
+
};
|
|
754
|
+
window.addEventListener('resize', handleWindowResize);
|
|
755
|
+
return () => {
|
|
756
|
+
window.removeEventListener('resize', handleWindowResize);
|
|
757
|
+
};
|
|
758
|
+
}, []);
|
|
759
|
+
const highLightGeoJsonOnClick = featureResults => {
|
|
760
|
+
const nextState = highlightGeoJson(featuresByAlert, featureResults);
|
|
761
|
+
setSelectedFeatureEvent(featureResults);
|
|
762
|
+
setFeaturesByAlert(nextState);
|
|
763
|
+
};
|
|
764
|
+
const selectedTime = useSelector(store => mapSelectors.getSelectedTime(store, mapIdRef.current));
|
|
765
|
+
const alertIdsInEffect = useSelector(store => getAlertsInEffect(store, fromUnixTime(selectedTime).toISOString())).map(({
|
|
766
|
+
identifier
|
|
767
|
+
}) => identifier);
|
|
768
|
+
const featuresInEffect = Object.keys(featuresByAlert).filter(id => alertIdsInEffect.includes(id)).flatMap(id => featuresByAlert[id]);
|
|
769
|
+
const geoJsonObject = {
|
|
770
|
+
type: 'FeatureCollection',
|
|
771
|
+
features: featuresInEffect
|
|
772
|
+
};
|
|
773
|
+
return React.createElement("div", {
|
|
774
|
+
"data-testid": "mapViewCap",
|
|
775
|
+
style: {
|
|
776
|
+
height: '100%',
|
|
777
|
+
width: '100%'
|
|
778
|
+
},
|
|
779
|
+
ref: parentSizeRef
|
|
780
|
+
}, React.createElement(ConfigurableMapConnect, {
|
|
781
|
+
id: mapIdRef.current,
|
|
782
|
+
title: title,
|
|
783
|
+
layers: layers || [],
|
|
784
|
+
"data-testid": "capWarningMap",
|
|
785
|
+
bbox: bbox,
|
|
786
|
+
srs: srs
|
|
787
|
+
}, React.createElement(MapViewLayer, {
|
|
788
|
+
id: layerIdRef.current,
|
|
789
|
+
geojson: geoJsonObject,
|
|
790
|
+
onClickFeature: highLightGeoJsonOnClick,
|
|
791
|
+
"data-testid": "polygonLayer"
|
|
792
|
+
}), selectedFeatureEvent && React.createElement(MapWarningProperties, {
|
|
793
|
+
"data-testid": "mapWarnings",
|
|
794
|
+
selectedFeatureProperties: selectedFeatureEvent.feature.properties.details,
|
|
795
|
+
languageIndex: findEventIndexInLanguage(selectedFeatureEvent.feature.properties.details.languages, capWarningPresets, selectedFeatureEvent.feature.properties.details.feedAddress),
|
|
796
|
+
parentSize: parentSize
|
|
797
|
+
})));
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
/* *
|
|
801
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
802
|
+
* you may not use this file except in compliance with the License.
|
|
803
|
+
* You may obtain a copy of the License at
|
|
804
|
+
*
|
|
805
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
806
|
+
*
|
|
807
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
808
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
809
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
810
|
+
* See the License for the specific language governing permissions and
|
|
811
|
+
* limitations under the License.
|
|
812
|
+
*
|
|
813
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
814
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
815
|
+
* */
|
|
816
|
+
const MapViewCapConnectWrapper = ({
|
|
817
|
+
id,
|
|
818
|
+
title,
|
|
819
|
+
bbox,
|
|
820
|
+
srs,
|
|
821
|
+
productConfigKey,
|
|
822
|
+
layers
|
|
823
|
+
}) => {
|
|
824
|
+
const {
|
|
825
|
+
api
|
|
826
|
+
} = useApiContext();
|
|
827
|
+
const {
|
|
828
|
+
t
|
|
829
|
+
} = useTranslation(CAP_NAMESPACE);
|
|
830
|
+
const {
|
|
831
|
+
result: capWarningPresets,
|
|
832
|
+
isLoading: isConfigLoading,
|
|
833
|
+
error
|
|
834
|
+
} = useApi(api.getCapConfiguration, productConfigKey);
|
|
835
|
+
if (isConfigLoading) {
|
|
836
|
+
return React.createElement(Box$1, {
|
|
837
|
+
sx: {
|
|
838
|
+
display: 'flex',
|
|
839
|
+
justifyContent: 'center',
|
|
840
|
+
alignItems: 'center'
|
|
841
|
+
}
|
|
842
|
+
}, React.createElement(CircularProgress, {
|
|
843
|
+
"data-testid": "loadingSpinner"
|
|
844
|
+
}));
|
|
845
|
+
}
|
|
846
|
+
if (error) {
|
|
847
|
+
return React.createElement(AlertBanner, {
|
|
848
|
+
title: t('map-view-cap-error-title'),
|
|
849
|
+
info: error.message
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
return React.createElement(MapViewCapConnect, {
|
|
853
|
+
capWarningPresets: capWarningPresets,
|
|
854
|
+
id: id,
|
|
855
|
+
title: title,
|
|
856
|
+
bbox: bbox,
|
|
857
|
+
srs: srs,
|
|
858
|
+
layers: layers
|
|
859
|
+
});
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
/* *
|
|
863
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
864
|
+
* you may not use this file except in compliance with the License.
|
|
865
|
+
* You may obtain a copy of the License at
|
|
866
|
+
*
|
|
867
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
868
|
+
*
|
|
869
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
870
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
871
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
872
|
+
* See the License for the specific language governing permissions and
|
|
873
|
+
* limitations under the License.
|
|
874
|
+
*
|
|
875
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
876
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
877
|
+
* */
|
|
878
|
+
const capModuleConfig = {
|
|
879
|
+
id: 'capStore-module',
|
|
880
|
+
reducersMap: {
|
|
881
|
+
capStore: reducer
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
/* *
|
|
886
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
887
|
+
* you may not use this file except in compliance with the License.
|
|
888
|
+
* You may obtain a copy of the License at
|
|
889
|
+
*
|
|
890
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
891
|
+
*
|
|
892
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
893
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
894
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
895
|
+
* See the License for the specific language governing permissions and
|
|
896
|
+
* limitations under the License.
|
|
897
|
+
*
|
|
898
|
+
* Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
899
|
+
* Copyright 2022 - Finnish Meteorological Institute (FMI)
|
|
900
|
+
* */
|
|
901
|
+
const CapThemeWrapper = ({
|
|
902
|
+
theme,
|
|
903
|
+
children
|
|
904
|
+
}) => React.createElement(ThemeWrapper, {
|
|
905
|
+
theme: theme
|
|
906
|
+
}, children);
|
|
907
|
+
withEggs([capModuleConfig, ...coreModuleConfig])(({
|
|
908
|
+
theme,
|
|
909
|
+
children
|
|
910
|
+
}) => React.createElement(CapThemeWrapper, {
|
|
911
|
+
theme: theme
|
|
912
|
+
}, children));
|
|
913
|
+
const CapTranslationsWrapper = ({
|
|
914
|
+
children
|
|
915
|
+
}) => {
|
|
916
|
+
const {
|
|
917
|
+
i18n
|
|
918
|
+
} = useTranslation();
|
|
919
|
+
React.useEffect(() => {
|
|
920
|
+
i18n.addResourceBundle('en', CAP_NAMESPACE, capTrans.en);
|
|
921
|
+
i18n.addResourceBundle('fi', CAP_NAMESPACE, capTrans.fi);
|
|
922
|
+
}, [i18n]);
|
|
923
|
+
return children;
|
|
924
|
+
};
|
|
925
|
+
|
|
926
|
+
/* *
|
|
927
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
928
|
+
* you may not use this file except in compliance with the License.
|
|
929
|
+
* You may obtain a copy of the License at
|
|
930
|
+
*
|
|
931
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
932
|
+
*
|
|
933
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
934
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
935
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
936
|
+
* See the License for the specific language governing permissions and
|
|
937
|
+
* limitations under the License.
|
|
938
|
+
*
|
|
939
|
+
* Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
940
|
+
* Copyright 2023 - Finnish Meteorological Institute (FMI)
|
|
941
|
+
* */
|
|
942
|
+
/**
|
|
943
|
+
* The lookup table is for registering your own components with the workspace.
|
|
944
|
+
* @param payload
|
|
945
|
+
* @returns
|
|
946
|
+
*/
|
|
947
|
+
const ComponentsLookUp = ({
|
|
948
|
+
componentType,
|
|
949
|
+
initialProps,
|
|
950
|
+
productConfigKey,
|
|
951
|
+
config,
|
|
952
|
+
id
|
|
953
|
+
}) => {
|
|
954
|
+
// TODO: implement polling when backend is ready
|
|
955
|
+
// TODO: fetch new data using feedLanguage if previous response indicates there are new warnings
|
|
956
|
+
var _a, _b;
|
|
957
|
+
// NOTE: Fetching data inside this component might not work, as using React Hooks causes Invalid Hook Call -errors in tests.
|
|
958
|
+
switch (componentType) {
|
|
959
|
+
case 'CapWarningMap':
|
|
960
|
+
{
|
|
961
|
+
return React.createElement(CapTranslationsWrapper, null, React.createElement(ApiProvider, {
|
|
962
|
+
config: {
|
|
963
|
+
baseURL: config.baseURL
|
|
964
|
+
},
|
|
965
|
+
createApi: createApi
|
|
966
|
+
}, React.createElement(MapViewCapConnectWrapper, {
|
|
967
|
+
id: id,
|
|
968
|
+
bbox: (_a = initialProps.mapPreset.proj) === null || _a === void 0 ? void 0 : _a.bbox,
|
|
969
|
+
srs: (_b = initialProps.mapPreset.proj) === null || _b === void 0 ? void 0 : _b.srs,
|
|
970
|
+
layers: initialProps.mapPreset.layers,
|
|
971
|
+
productConfigKey: productConfigKey
|
|
972
|
+
})));
|
|
973
|
+
}
|
|
974
|
+
case 'CapWarningList':
|
|
975
|
+
{
|
|
976
|
+
return React.createElement(CapTranslationsWrapper, null, React.createElement(ApiProvider, {
|
|
977
|
+
config: {
|
|
978
|
+
baseURL: config.baseURL
|
|
979
|
+
},
|
|
980
|
+
createApi: createApi
|
|
981
|
+
}, React.createElement(WarningListCapConnectWrapper, {
|
|
982
|
+
productConfigKey: productConfigKey
|
|
983
|
+
})));
|
|
984
|
+
}
|
|
985
|
+
default:
|
|
986
|
+
return null;
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
export { ComponentsLookUp, capModuleConfig, reducer as capReducer };
|