@opengeoweb/warnings 14.3.0 → 14.4.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/index.esm.js CHANGED
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useDispatch, useSelector } from 'react-redux';
3
3
  import { Polygons, ExitDomain, Share, Edit, Delete, CoastalEvent, TemperatureLow, TemperatureHigh, Rain, Snow, Lightning, Fog, Wind, Thunderstorm, SevereMountainWaves, VulcanicEruption, Haze, FreezingPrecipitation, ModerateAircraftIcing, SevereAircraftIcing, ModerateTurbulence, SevereTurbulence, SandStorm, RadioactiveMaterials, DrawPolygon, Visibility, Add, ArrowUpCompact, ArrowDownCompact, breakpoints, DragHandle, Info, Copy, Update, Cancel, Success, Expire, Remove, Options, ChevronDown, ChevronUp, Close, Clock } from '@opengeoweb/theme';
4
4
  import { uiTypes, uiActions, getSingularDrawtoolDrawLayerId, drawingToolSelectors, layerSelectors, uiSelectors, drawingToolActions, layerActions, mapListener, layersListener, drawingToolListener, syncGroupsListener, openlayersListener, syncGroupsReducer, drawingToolReducer, uiReducer, layerReducer, mapReducer, useSetupDialog, genericSelectors, useUpdateSharedData, genericActions, selectorMemoizationOptions } from '@opengeoweb/store';
5
- import { defaultPolygon, getDrawModeIdFromSelectionType, currentlySupportedDrawModes, emptyGeoJSON, MapControlButton, defaultSmoothLine, defaultOval, defaultBox, defaultLocation, getIcon, defaultCircle, defaultSquare, defaultLineString, defaultPoint, rewindGeometry, getGeoJSONPropertyValue, defaultLayers, viewUtils, OpenLayersMapView, MapControls, OpenLayersZoomControl, OpenLayersLayer, OpenLayersFeatureLayer, genericOpenLayersFeatureStyle, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_SECONDARY_FILL_COLOR } from '@opengeoweb/webmap-react';
5
+ import { WEBMAP_REACT_NAMESPACE, defaultPolygon, getDrawModeIdFromSelectionType, currentlySupportedDrawModes, emptyGeoJSON, MapControlButton, defaultSmoothLine, defaultLineString, defaultFreehandLine, defaultOval, defaultCircle, defaultBox, defaultSquare, defaultLocation, defaultPoint, defaultDelete, getIcon, rewindGeometry, getGeoJSONPropertyValue, defaultLayers, viewUtils, OpenLayersMapView, MapControls, OpenLayersZoomControl, OpenLayersLayer, OpenLayersFeatureLayer, genericOpenLayersFeatureStyle, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_SECONDARY_FILL_COLOR, FEATURE_DRAW_STROKE_COLOR } from '@opengeoweb/webmap-react';
6
6
  import { SHARED_NAMESPACE, useConfirmationDialog, dateUtils, ToggleMenu, calculateStartSize, ToolContainerDraggable, AlertBanner, sessionStorageProvider, ConfirmationDialog, usePrevious, CustomIconButton, usePreventBrowserClose, CustomTooltip, Avatar, getInitials, SwitchButton, FilterChip, TooltipSelect, LastUpdateTime, CustomToggleButton, Filter, StatusTag, FilterOption, getAxiosErrorMessage, CustomDialog, ConfirmationButtons, ErrorBoundary } from '@opengeoweb/shared';
7
7
  import { createEntityAdapter, createSlice, createSelector, createListenerMiddleware, current, combineReducers, configureStore } from '@reduxjs/toolkit';
8
8
  import { defaultBbox } from '@opengeoweb/core';
@@ -220,6 +220,8 @@ var en = {
220
220
  "tac-missing-data": "Missing data: no TAC can be generated",
221
221
  "warning-list-button-renew": "Renew",
222
222
  "warning-list-button-amend": "Amend",
223
+ "warning-list-too-many-title": "Too many warnings requested",
224
+ "warning-list-too-many-info": "There are {{count}} warnings in the selected timespan. In order to list the warnings, narrow down the search.",
223
225
  "aviation-save-success": "{{warningType}} has succesfully been saved!",
224
226
  "aviation-publish-success": "{{warningType}} has succesfully been published!",
225
227
  "publish-this-product": "Are you sure you want to publish this {{product}}?",
@@ -284,7 +286,9 @@ var en = {
284
286
  "maritime-config-error": "Something went wrong with loading the configuration file",
285
287
  "maritime-warning-validuntil": "End time: ",
286
288
  "maritime-wind-change-warning": "The entered wind change exceeds 180°. Please check if veering / backing is correct.",
287
- "maritime-wind-change-error": "A wind change less than 45° is not allowed."
289
+ "maritime-wind-change-error": "A wind change less than 45° is not allowed.",
290
+ "maritime-button-extend": "Extend +24h",
291
+ "maritime-button-extending": "Extending"
288
292
  };
289
293
  var nl = {
290
294
  "drawing-tool-form-tools": "Gereedschap",
@@ -398,6 +402,10 @@ var nl = {
398
402
  "warning-list-header-levels": "Niveaus",
399
403
  "warning-list-header-status": "Status",
400
404
  "warning-list-header-draft": "CONCEPT",
405
+ "warning-list-too-many-title": "niet vertaald",
406
+ "warning-list-too-many-info": "niet vertaald",
407
+ "warning-list-show-anyway": "niet vertaald",
408
+ "warning-list-adjust-filter": "niet vertaald",
401
409
  "area-object-loader-title": "Gebieden & Objecten",
402
410
  "add-button": "Toevoegen",
403
411
  "replace-button": "Vervangen",
@@ -498,7 +506,9 @@ var nl = {
498
506
  "maritime-config-error": "Er is iets misgegaan bij het laden van het configuratiebestand",
499
507
  "maritime-warning-validuntil": "Eind tijd: ",
500
508
  "maritime-wind-change-warning": "De ingevulde wind wijziging overschrijdt 180°. Controleer of ruimend / krimpend klopt.",
501
- "maritime-wind-change-error": "Een wind wijziging van minder dan 45° is niet toegestaan."
509
+ "maritime-wind-change-error": "Een wind wijziging van minder dan 45° is niet toegestaan.",
510
+ "maritime-button-extend": "Verlengen +24h",
511
+ "maritime-button-extending": "Verlengen"
502
512
  };
503
513
  var fi = {
504
514
  "drawing-tool-form-tools": "Työkalut",
@@ -612,6 +622,10 @@ var fi = {
612
622
  "warning-list-header-levels": "Tasot",
613
623
  "warning-list-header-status": "Tila",
614
624
  "warning-list-header-draft": "LUONNOS",
625
+ "warning-list-too-many-title": "ei käännetty",
626
+ "warning-list-too-many-info": "ei käännetty",
627
+ "warning-list-show-anyway": "ei käännetty",
628
+ "warning-list-adjust-filter": "ei käännetty",
615
629
  "area-object-loader-title": "ei käännetty",
616
630
  "add-button": "ei käännetty",
617
631
  "replace-button": "ei käännetty",
@@ -762,6 +776,10 @@ var no = {
762
776
  "warning-list-button-expire": "Sett som utgått",
763
777
  "warning-list-button-withdraw": "Ta ut",
764
778
  "warning-list-button-amend": "Amend",
779
+ "warning-list-too-many-title": "For mange varsler",
780
+ "warning-list-too-many-info": "Det er {{count}} varsler i den valgte tidsperioden. Vennligst juster filteret for å redusere antallet varsler som vises.",
781
+ "warning-list-show-anyway": "Vis likevel",
782
+ "warning-list-adjust-filter": "Juster filter",
765
783
  "warning-list-status-draft": "Utkast",
766
784
  "warning-list-status-published": "Publisert",
767
785
  "warning-list-status-todo": "Til sjekk",
@@ -1278,7 +1296,7 @@ var getWarningFormDirty = createSelector(selectDrawByInstanceId, function (drawi
1278
1296
  * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1279
1297
  * */
1280
1298
  var WARN_NAMESPACE = 'warn';
1281
- var ns = [WARN_NAMESPACE, FORM_FIELDS_NAMESPACE, SHARED_NAMESPACE, SA_NAMESPACE];
1299
+ var ns = [WARN_NAMESPACE, FORM_FIELDS_NAMESPACE, SHARED_NAMESPACE, SA_NAMESPACE, WEBMAP_REACT_NAMESPACE];
1282
1300
  var useWarningsTranslation = function useWarningsTranslation() {
1283
1301
  return useTranslation(ns);
1284
1302
  };
@@ -2076,8 +2094,13 @@ var ObjectManager = function ObjectManager(_ref) {
2076
2094
  var config$1 = sessionStorageProvider.getConfig();
2077
2095
  var publicWarningBaseUrl = config$1.GW_DRAWINGS_BASE_URL || '';
2078
2096
  // API
2079
- var getPublicWarningList = function getPublicWarningList(auth) {
2080
- return fetch(publicWarningBaseUrl + "/warnings", {
2097
+ var getPublicWarningList = function getPublicWarningList(auth, apiParams) {
2098
+ if (apiParams === void 0) {
2099
+ apiParams = {};
2100
+ }
2101
+ var params = new URLSearchParams(apiParams);
2102
+ var url = publicWarningBaseUrl + "/warnings" + (params.toString() ? "?" + params : '');
2103
+ return fetch(url, {
2081
2104
  headers: getHeaders(auth)
2082
2105
  }).then(handleResponse).then(function (warnings) {
2083
2106
  return warnings.map(function (warning) {
@@ -2377,6 +2400,12 @@ var slice$1 = createSlice({
2377
2400
  },
2378
2401
  setSelectedWarningId: function setSelectedWarningId(draft, action) {
2379
2402
  draft.selectedWarningId = action.payload;
2403
+ },
2404
+ setWarningLevel: function setWarningLevel(draft, action) {
2405
+ var level = action.payload;
2406
+ if (draft.warning) {
2407
+ draft.warning.warningDetail.level = level;
2408
+ }
2380
2409
  }
2381
2410
  },
2382
2411
  extraReducers: function extraReducers(builder) {
@@ -3150,11 +3179,16 @@ var getSnackbarMessage = function getSnackbarMessage(objectName, wasUpdate) {
3150
3179
  * @param disabled - Disables fetching, but still returns cached values.
3151
3180
  * https://tanstack.com/query/v4/docs/framework/react/guides/disabling-queries
3152
3181
  */
3153
- var usePublicWarnings = function usePublicWarnings(disabled) {
3182
+ var usePublicWarnings = function usePublicWarnings(disabled, timeFilter) {
3154
3183
  if (disabled === void 0) {
3155
3184
  disabled = false;
3156
3185
  }
3157
- return useAuthQuery(['public-warning-list'], getPublicWarningList, disabled, 1000 * 60 * 5);
3186
+ var shouldFilter = timeFilter && timeFilter.mode !== TimeFilterMode.all;
3187
+ var apiParams = shouldFilter ? getApiParams(timeFilter) : {};
3188
+ var queryKey = apiParams ? ['public-warning-list', JSON.stringify(apiParams)] : ['public-warning-list'];
3189
+ return useAuthQuery(queryKey, function (auth) {
3190
+ return getPublicWarningList(auth, apiParams);
3191
+ }, disabled, 1000 * 60);
3158
3192
  };
3159
3193
  var useMutatePublicWarningEditor = function useMutatePublicWarningEditor() {
3160
3194
  var queryClient = useQueryClient();
@@ -3228,7 +3262,8 @@ var useMutateWarning = function useMutateWarning(snackBarMessage) {
3228
3262
  },
3229
3263
  onError: function onError(error) {
3230
3264
  void queryClient.invalidateQueries({
3231
- queryKey: ['public-warning-list']
3265
+ queryKey: ['public-warning-list'],
3266
+ exact: false
3232
3267
  });
3233
3268
  dispatch(publicWarningFormActions.setFormError({
3234
3269
  message: error.message
@@ -3242,7 +3277,8 @@ var useMutateWarning = function useMutateWarning(snackBarMessage) {
3242
3277
  case 0:
3243
3278
  _context2.next = 2;
3244
3279
  return queryClient.invalidateQueries({
3245
- queryKey: ['public-warning-list']
3280
+ queryKey: ['public-warning-list'],
3281
+ exact: false
3246
3282
  });
3247
3283
  case 2:
3248
3284
  location = data == null ? void 0 : data.get('location');
@@ -3308,7 +3344,9 @@ var useMutateDeleteWarning = function useMutateDeleteWarning() {
3308
3344
  void queryClient.cancelQueries({
3309
3345
  queryKey: ['public-warning-list']
3310
3346
  });
3311
- queryClient.setQueryData(['public-warning-list'], function (old) {
3347
+ queryClient.setQueriesData({
3348
+ queryKey: ['public-warning-list']
3349
+ }, function (old) {
3312
3350
  return old == null ? void 0 : old.filter(function (warning) {
3313
3351
  return warning.id !== variables.id;
3314
3352
  });
@@ -3968,36 +4006,38 @@ var useFormDirty = function useFormDirty(_ref) {
3968
4006
  };
3969
4007
 
3970
4008
  var opacityOptions = [100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0];
3971
- var secondaryDrawToolKeys = [defaultSmoothLine.drawModeId, defaultOval.drawModeId, defaultBox.drawModeId, defaultLocation.drawModeId];
3972
- // Utility to determine if the secondary draw mode button should be shown
3973
- var getButtonStyle = function getButtonStyle(mode, activeDrawModeId, geoJSONDrawMode) {
3974
- if (mode.drawModeId === defaultOval.drawModeId && (activeDrawModeId === defaultCircle.drawModeId || activeDrawModeId === defaultOval.drawModeId || geoJSONDrawMode === defaultOval.drawModeId)) {
3975
- return {
3976
- display: 'inline-flex',
3977
- marginLeft: 15
3978
- };
3979
- }
3980
- if (mode.drawModeId === defaultBox.drawModeId && (activeDrawModeId === defaultSquare.drawModeId || activeDrawModeId === defaultBox.drawModeId || geoJSONDrawMode === defaultBox.drawModeId)) {
3981
- return {
3982
- display: 'inline-flex',
3983
- marginLeft: 20
3984
- };
3985
- }
3986
- if (mode.drawModeId === defaultSmoothLine.drawModeId && (activeDrawModeId === defaultLineString.drawModeId || activeDrawModeId === defaultSmoothLine.drawModeId || geoJSONDrawMode === defaultSmoothLine.drawModeId)) {
3987
- return {
3988
- display: 'inline-flex',
3989
- marginLeft: 5
3990
- };
3991
- }
3992
- if (mode.drawModeId === defaultLocation.drawModeId && (activeDrawModeId === defaultPoint.drawModeId || activeDrawModeId === defaultLocation.drawModeId || geoJSONDrawMode === defaultLocation.drawModeId)) {
3993
- return {
3994
- display: 'inline-flex',
3995
- marginLeft: 25
3996
- };
4009
+ var drawToolConfig = [{
4010
+ primaryMode: defaultPolygon
4011
+ }, {
4012
+ primaryMode: defaultLineString,
4013
+ secondaryMode: defaultSmoothLine
4014
+ }, {
4015
+ primaryMode: defaultFreehandLine
4016
+ }, {
4017
+ primaryMode: defaultCircle,
4018
+ secondaryMode: defaultOval
4019
+ }, {
4020
+ primaryMode: defaultSquare,
4021
+ secondaryMode: defaultBox
4022
+ }, {
4023
+ primaryMode: defaultPoint,
4024
+ secondaryMode: defaultLocation
4025
+ }, {
4026
+ primaryMode: defaultDelete
4027
+ }];
4028
+ /**
4029
+ * Utility to determine if the secondary draw mode button should be shown
4030
+ * @param mode DrawMode of the primary button
4031
+ * @param secondaryMode DrawMode of the secondary button
4032
+ * @param activeDrawModeId Currently active DrawMode id
4033
+ * @param geoJSONDrawMode DrawMode id derived from the GeoJSON selection type
4034
+ * @returns
4035
+ */
4036
+ var shouldDisplayButton = function shouldDisplayButton(mode, secondaryMode, activeDrawModeId, geoJSONDrawMode) {
4037
+ if (activeDrawModeId === mode.drawModeId || activeDrawModeId === secondaryMode.drawModeId || geoJSONDrawMode === secondaryMode.drawModeId) {
4038
+ return true;
3997
4039
  }
3998
- return {
3999
- display: 'none'
4000
- };
4040
+ return false;
4001
4041
  };
4002
4042
  var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref) {
4003
4043
  var _geoJSON$features;
@@ -4018,11 +4058,11 @@ var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref)
4018
4058
  var _useWarningsTranslati = useWarningsTranslation(),
4019
4059
  t = _useWarningsTranslati.t;
4020
4060
  var hasErrors = Object.keys(errors).length > 0;
4021
- var drawModesPrimary = drawModes.filter(function (mode) {
4022
- return !secondaryDrawToolKeys.includes(mode.drawModeId);
4023
- });
4024
- var drawModesSecondary = drawModes.filter(function (mode) {
4025
- return secondaryDrawToolKeys.includes(mode.drawModeId);
4061
+ // Only show the draw modes that are available in the current context
4062
+ var filteredDrawModes = drawToolConfig.filter(function (configItem) {
4063
+ return drawModes.find(function (mode) {
4064
+ return mode.drawModeId === configItem.primaryMode.drawModeId;
4065
+ });
4026
4066
  });
4027
4067
  var geoJSONDrawMode = getDrawModeIdFromSelectionType(geoJSON == null || (_geoJSON$features = geoJSON.features) == null || (_geoJSON$features = _geoJSON$features[0]) == null || (_geoJSON$features = _geoJSON$features.properties) == null ? void 0 : _geoJSON$features.selectionType, drawModes);
4028
4068
  return jsxs(Fragment, {
@@ -4050,73 +4090,75 @@ var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref)
4050
4090
  variant: "body2",
4051
4091
  children: t('drawing-tool-form-tools')
4052
4092
  })
4053
- }), jsx(Grid, {
4093
+ }), jsxs(Grid, {
4054
4094
  container: true,
4055
- children: jsxs(Grid, {
4056
- children: [drawModesPrimary.map(function (mode) {
4057
- return jsx(CustomIconButton, {
4095
+ marginBottom: 1,
4096
+ children: [filteredDrawModes.map(function (_ref2) {
4097
+ var primaryMode = _ref2.primaryMode,
4098
+ secondaryMode = _ref2.secondaryMode;
4099
+ var showSecondaryButton = secondaryMode && drawModes.find(function (mode) {
4100
+ return mode.drawModeId === secondaryMode.drawModeId;
4101
+ }) && shouldDisplayButton(primaryMode, secondaryMode, activeDrawModeId, geoJSONDrawMode);
4102
+ return jsxs(Box, {
4103
+ sx: {
4104
+ display: 'inline-flex',
4105
+ flexDirection: 'column'
4106
+ },
4107
+ children: [jsx(CustomIconButton, {
4058
4108
  variant: "tool",
4059
- tooltipTitle: mode.title,
4060
- isSelected: mode.isSelectable && activeDrawModeId === mode.drawModeId,
4109
+ tooltipTitle: t("" + primaryMode.title),
4110
+ isSelected: primaryMode.isSelectable && activeDrawModeId === primaryMode.drawModeId,
4061
4111
  onClick: function onClick() {
4062
- return onChangeDrawMode(mode);
4112
+ return onChangeDrawMode(primaryMode);
4113
+ },
4114
+ "data-testid": primaryMode.drawModeId,
4115
+ disabled: isLoading,
4116
+ size: "medium",
4117
+ shouldShowExtraOptionsIndicator: !!secondaryMode,
4118
+ children: getIcon(primaryMode.selectionType)
4119
+ }), showSecondaryButton ? jsx(CustomIconButton, {
4120
+ variant: "tool",
4121
+ tooltipTitle: t("" + secondaryMode.title),
4122
+ isSelected: secondaryMode.isSelectable && activeDrawModeId === secondaryMode.drawModeId,
4123
+ onClick: function onClick() {
4124
+ return onChangeDrawMode(secondaryMode);
4063
4125
  },
4064
4126
  sx: {
4065
- marginRight: 1,
4066
- marginBottom: 1
4127
+ marginTop: 1
4067
4128
  },
4068
- "data-testid": mode.drawModeId,
4129
+ "data-testid": secondaryMode.drawModeId,
4069
4130
  disabled: isLoading,
4070
4131
  size: "medium",
4071
- children: getIcon(mode.selectionType)
4072
- }, mode.drawModeId);
4073
- }), drawModesSecondary.length > 0 && jsx(Box, {
4074
- children: drawModesSecondary.map(function (mode) {
4075
- return jsx(CustomIconButton, {
4076
- variant: "tool",
4077
- tooltipTitle: mode.title,
4078
- isSelected: mode.isSelectable && activeDrawModeId === mode.drawModeId,
4079
- onClick: function onClick() {
4080
- return onChangeDrawMode(mode);
4081
- },
4082
- sx: Object.assign({
4083
- marginRight: 1,
4084
- marginBottom: 1
4085
- }, getButtonStyle(mode, activeDrawModeId, geoJSONDrawMode)),
4086
- "data-testid": mode.drawModeId,
4087
- disabled: isLoading,
4088
- size: "medium",
4089
- children: getIcon(mode.selectionType)
4090
- }, mode.drawModeId);
4091
- })
4092
- }), isInEditMode && jsx(Typography, {
4093
- component: "span",
4094
- sx: {
4095
- display: 'inline-block',
4096
- marginLeft: 2,
4097
- top: -1,
4098
- position: 'relative',
4099
- fontSize: 14
4100
- },
4101
- children: t('drawing-tool-form-exit-draw-mode')
4102
- }), !!errors.geoJSON && isDirty && jsx(FormHelperText, {
4103
- error: true,
4104
- variant: "filled",
4105
- sx: {
4106
- marginLeft: 0
4107
- },
4108
- children: errors.geoJSON.message
4109
- }), jsx(ReactHookFormHiddenInput, {
4110
- name: "geoJSON",
4111
- rules: {
4112
- validate: {
4113
- coordinatesNotEmpty: function coordinatesNotEmpty(value) {
4114
- return isValidGeoJsonCoordinates(value) || t('drawing-tool-form-drawing-required');
4115
- }
4132
+ children: getIcon(secondaryMode.selectionType)
4133
+ }) : null]
4134
+ }, primaryMode.drawModeId);
4135
+ }), isInEditMode && jsx(Typography, {
4136
+ component: "span",
4137
+ sx: {
4138
+ display: 'inline-block',
4139
+ marginLeft: 2,
4140
+ top: -1,
4141
+ position: 'relative',
4142
+ fontSize: 14
4143
+ },
4144
+ children: t('drawing-tool-form-exit-draw-mode')
4145
+ }), !!errors.geoJSON && isDirty && jsx(FormHelperText, {
4146
+ error: true,
4147
+ variant: "filled",
4148
+ sx: {
4149
+ marginLeft: 0
4150
+ },
4151
+ children: errors.geoJSON.message
4152
+ }), jsx(ReactHookFormHiddenInput, {
4153
+ name: "geoJSON",
4154
+ rules: {
4155
+ validate: {
4156
+ coordinatesNotEmpty: function coordinatesNotEmpty(value) {
4157
+ return isValidGeoJsonCoordinates(value) || t('drawing-tool-form-drawing-required');
4116
4158
  }
4117
4159
  }
4118
- })]
4119
- })
4160
+ }
4161
+ })]
4120
4162
  }), jsx(Grid, {
4121
4163
  container: true,
4122
4164
  size: "grow",
@@ -5077,7 +5119,7 @@ var useAirmetList = function useAirmetList(disabled, timeFilter) {
5077
5119
  var apiParams = timeFilter ? getApiParams(timeFilter) : {};
5078
5120
  return useAuthQuery(['airmet-list', JSON.stringify(apiParams)], function (auth) {
5079
5121
  return getAirmetList(auth, apiParams);
5080
- }, disabled);
5122
+ }, disabled, 1000 * 60);
5081
5123
  };
5082
5124
  var useSigmetList = function useSigmetList(disabled, timeFilter) {
5083
5125
  if (disabled === void 0) {
@@ -5086,7 +5128,7 @@ var useSigmetList = function useSigmetList(disabled, timeFilter) {
5086
5128
  var apiParams = timeFilter ? getApiParams(timeFilter) : {};
5087
5129
  return useAuthQuery(['sigmet-list', JSON.stringify(apiParams)], function (auth) {
5088
5130
  return getSigmetList(auth, apiParams);
5089
- }, disabled);
5131
+ }, disabled, 1000 * 60);
5090
5132
  };
5091
5133
  var useAviationWarnings = function useAviationWarnings() {
5092
5134
  var _useAirmetList = useAirmetList(),
@@ -6615,24 +6657,24 @@ var WarningListSelect = /*#__PURE__*/React__default.memo(function (_ref) {
6615
6657
  label = _ref.label,
6616
6658
  _onChange = _ref.onChange,
6617
6659
  renderOption = _ref.renderOption,
6618
- renderValue = _ref.renderValue,
6660
+ _renderValue = _ref.renderValue,
6619
6661
  gridArea = _ref.gridArea,
6620
6662
  additionalStyling = _ref.additionalStyling,
6621
6663
  _ref$isReadOnly = _ref.isReadOnly,
6622
6664
  isReadOnly = _ref$isReadOnly === void 0 ? false : _ref$isReadOnly,
6623
- _ref$displayEmpty = _ref.displayEmpty,
6624
- displayEmpty = _ref$displayEmpty === void 0 ? false : _ref$displayEmpty,
6665
+ emptyMessage = _ref.emptyMessage,
6625
6666
  _ref$validationResult = _ref.validationResult,
6626
6667
  validationResult = _ref$validationResult === void 0 ? true : _ref$validationResult;
6627
6668
  var currentIndex = options.findIndex(function (option) {
6628
6669
  return option.value === value;
6629
6670
  });
6671
+ var hasEmptyMessage = emptyMessage !== undefined && emptyMessage.length > 0;
6630
6672
  return jsx(FormControl, {
6631
6673
  style: {
6632
6674
  width: '100%',
6633
6675
  gridArea: gridArea
6634
6676
  },
6635
- children: jsxs(TooltipSelect, {
6677
+ children: jsxs(TooltipSelect, Object.assign({
6636
6678
  disableUnderline: true,
6637
6679
  tooltip: "",
6638
6680
  style: {
@@ -6641,7 +6683,7 @@ var WarningListSelect = /*#__PURE__*/React__default.memo(function (_ref) {
6641
6683
  isEnabled: !isReadOnly,
6642
6684
  disabled: isReadOnly,
6643
6685
  value: value != null ? value : '',
6644
- displayEmpty: displayEmpty,
6686
+ displayEmpty: hasEmptyMessage,
6645
6687
  SelectDisplayProps: {
6646
6688
  'aria-label': label
6647
6689
  },
@@ -6660,7 +6702,28 @@ var WarningListSelect = /*#__PURE__*/React__default.memo(function (_ref) {
6660
6702
  backgroundColor: "geowebColors.functional." + validationResult + "Outline.fill"
6661
6703
  }, additionalStyling),
6662
6704
  currentIndex: currentIndex > -1 ? currentIndex : undefined,
6663
- renderValue: renderValue,
6705
+ renderValue: _renderValue
6706
+ }, hasEmptyMessage && {
6707
+ renderValue: function renderValue(value) {
6708
+ if (value === '' && hasEmptyMessage) {
6709
+ return jsx(Typography, {
6710
+ variant: "caption",
6711
+ color: "textSecondary",
6712
+ sx: {
6713
+ alignSelf: 'center'
6714
+ },
6715
+ children: emptyMessage
6716
+ });
6717
+ }
6718
+ if (_renderValue) {
6719
+ return _renderValue(value);
6720
+ }
6721
+ var option = options.find(function (item) {
6722
+ return item.value === value;
6723
+ });
6724
+ return typeof (option == null ? void 0 : option.label) === 'function' ? option.label(t) : option == null ? void 0 : option.label;
6725
+ }
6726
+ }, {
6664
6727
  onChange: function onChange(event) {
6665
6728
  _onChange(event.target.value);
6666
6729
  },
@@ -6686,7 +6749,7 @@ var WarningListSelect = /*#__PURE__*/React__default.memo(function (_ref) {
6686
6749
  children: typeof option.label === 'function' ? option.label(t) : option.label
6687
6750
  }, option.value);
6688
6751
  })]
6689
- })
6752
+ }))
6690
6753
  });
6691
6754
  });
6692
6755
 
@@ -6795,7 +6858,8 @@ var WindForceSelect = function WindForceSelect(_ref) {
6795
6858
  '& .MuiSelect-standard': {
6796
6859
  paddingBlock: 0
6797
6860
  }
6798
- }
6861
+ },
6862
+ emptyMessage: "(" + t('maritime-header-windforce') + ")"
6799
6863
  });
6800
6864
  };
6801
6865
 
@@ -6849,9 +6913,12 @@ var isWarningValid = function isWarningValid(item, config) {
6849
6913
  }
6850
6914
  return true;
6851
6915
  };
6852
- var isWarningsValid = function isWarningsValid(warnings, config) {
6916
+ var isWarningsValid = function isWarningsValid(warnings, config, allowEmpty) {
6917
+ if (allowEmpty === void 0) {
6918
+ allowEmpty = true;
6919
+ }
6853
6920
  // One single empty row is allowed, if not empty it should be valid
6854
- if (warnings.length === 1) {
6921
+ if (allowEmpty && warnings.length === 1) {
6855
6922
  return isWarningEmpty(warnings[0]) || isWarningValid(warnings[0], config);
6856
6923
  }
6857
6924
  return warnings.every(function (warning) {
@@ -6875,8 +6942,12 @@ var getType = function getType(domain) {
6875
6942
  return 'maritimeWarningNorthSea';
6876
6943
  }
6877
6944
  };
6878
- var mapItemsToMaritimeWarnings = function mapItemsToMaritimeWarnings(warnings, domain, maritimeConfig, editor) {
6945
+ var mapItemsToMaritimeWarnings = function mapItemsToMaritimeWarnings(warnings, domain, maritimeConfig, editor, shouldExtend) {
6946
+ if (shouldExtend === void 0) {
6947
+ shouldExtend = false;
6948
+ }
6879
6949
  var type = getType(domain);
6950
+ var now = Date.now();
6880
6951
  if (warnings.length === 1 && warnings[0].assignedAreaIds.length === 0) {
6881
6952
  // 1 warning without any areas means cancel/withdraw all warnings
6882
6953
  return [{
@@ -6896,8 +6967,9 @@ var mapItemsToMaritimeWarnings = function mapItemsToMaritimeWarnings(warnings, d
6896
6967
  status: PublicWarningStatus.PUBLISHED,
6897
6968
  warningDetail: {
6898
6969
  phenomenon: 'wind',
6899
- validFrom: new Date().toISOString(),
6900
- validUntil: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
6970
+ validFrom: shouldExtend && warning.validFrom ? warning.validFrom // keep original validFrom when extending
6971
+ : new Date(now).toISOString(),
6972
+ validUntil: new Date(now + 24 * 60 * 60 * 1000).toISOString(),
6901
6973
  level: getLevelFromWindForce(maritimeConfig, warning.windForce || ''),
6902
6974
  probability: 100,
6903
6975
  areas: warning.assignedAreaIds.map(function (areaId) {
@@ -7072,7 +7144,8 @@ var WarningListItem$1 = /*#__PURE__*/React__default.memo(function (_ref) {
7072
7144
  options: getWindDirectionsFromConfig(maritimeConfig.windDirectionDefinition, t),
7073
7145
  onChange: handleChangeFromDirection,
7074
7146
  value: warning.windDirectionFrom,
7075
- isReadOnly: isReadOnly
7147
+ isReadOnly: isReadOnly,
7148
+ emptyMessage: "(" + t('maritime-header-direction') + ")"
7076
7149
  }), jsx(WindForceSelect, {
7077
7150
  gridArea: "windForce",
7078
7151
  value: warning.windForce,
@@ -7095,32 +7168,18 @@ var WarningListItem$1 = /*#__PURE__*/React__default.memo(function (_ref) {
7095
7168
  onChange: handleChangeWindChangeType,
7096
7169
  value: warning.changeType,
7097
7170
  isReadOnly: isReadOnly,
7098
- renderValue: function renderValue(value) {
7099
- if (value === '') {
7100
- return jsx(Typography, {
7101
- variant: "caption",
7102
- color: "textSecondary",
7103
- sx: {
7104
- alignSelf: 'center'
7105
- },
7106
- children: t('maritime-no-change-selected')
7107
- });
7108
- }
7109
- var option = changeOptions.find(function (item) {
7110
- return item.value === value;
7111
- });
7112
- return typeof (option == null ? void 0 : option.label) === 'function' ? option.label(t) : option == null ? void 0 : option.label;
7113
- },
7114
- displayEmpty: true,
7171
+ emptyMessage: t('maritime-no-change-selected'),
7115
7172
  validationResult: validationResult
7116
- }), jsx(WarningListSelect, {
7173
+ }), jsx(WarningListSelect, Object.assign({
7117
7174
  gridArea: "dirTo",
7118
7175
  label: t('maritime-header-direction-to'),
7119
7176
  options: getWindDirectionsFromConfig(maritimeConfig.windDirectionDefinition, t),
7120
7177
  onChange: handleChangeToDirection,
7121
7178
  value: warning.windDirectionTo,
7122
7179
  isReadOnly: shouldDisableDirTo
7123
- }), showInfoIcon ? jsx(Box, {
7180
+ }, warning.changeType !== 'NO_CHANGE' && {
7181
+ emptyMessage: "(" + t('maritime-header-direction') + ")"
7182
+ })), showInfoIcon ? jsx(Box, {
7124
7183
  sx: {
7125
7184
  gridArea: 'info',
7126
7185
  justifySelf: 'left',
@@ -7574,7 +7633,7 @@ var getWarningsValidity = function getWarningsValidity(t, warnings) {
7574
7633
  return validUntil ? "" + t('maritime-warning-validuntil') + validUntil : '';
7575
7634
  };
7576
7635
  var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7577
- var _sx, _sx2, _sx3, _sx4;
7636
+ var _sx, _sx2, _sx3, _sx4, _sx5;
7578
7637
  var areas = _ref.areas,
7579
7638
  selectedAreaIds = _ref.selectedAreaIds,
7580
7639
  modified = _ref.modified,
@@ -7602,6 +7661,9 @@ var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7602
7661
  var _React$useState = React__default.useState(false),
7603
7662
  isPublishing = _React$useState[0],
7604
7663
  setIsPublishing = _React$useState[1];
7664
+ var _React$useState2 = React__default.useState(false),
7665
+ isExtending = _React$useState2[0],
7666
+ setIsExtending = _React$useState2[1];
7605
7667
  var _useWarningsTranslati = useWarningsTranslation(),
7606
7668
  t = _useWarningsTranslati.t;
7607
7669
  var showConfirmDialog = useConfirmationDialog();
@@ -7634,7 +7696,8 @@ var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7634
7696
  }
7635
7697
  }, _callee);
7636
7698
  })), [onClear, t, showConfirmDialog]);
7637
- var isValid = isWarningsValid(warnings, maritimeConfig);
7699
+ var isValidForPublish = isWarningsValid(warnings, maritimeConfig);
7700
+ var isValidForExtend = isWarningsValid(warnings, maritimeConfig, false);
7638
7701
  var onSwitchMode = /*#__PURE__*/function () {
7639
7702
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(event) {
7640
7703
  var checked, isReadOnly;
@@ -7700,6 +7763,39 @@ var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7700
7763
  return _ref4.apply(this, arguments);
7701
7764
  };
7702
7765
  }();
7766
+ var onPressExtend = /*#__PURE__*/function () {
7767
+ var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
7768
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
7769
+ while (1) switch (_context4.prev = _context4.next) {
7770
+ case 0:
7771
+ if (isExtending) {
7772
+ _context4.next = 12;
7773
+ break;
7774
+ }
7775
+ setIsExtending(true);
7776
+ _context4.prev = 2;
7777
+ _context4.next = 5;
7778
+ return onSubmit(true);
7779
+ case 5:
7780
+ _context4.next = 9;
7781
+ break;
7782
+ case 7:
7783
+ _context4.prev = 7;
7784
+ _context4.t0 = _context4["catch"](2);
7785
+ case 9:
7786
+ _context4.prev = 9;
7787
+ setIsExtending(false);
7788
+ return _context4.finish(9);
7789
+ case 12:
7790
+ case "end":
7791
+ return _context4.stop();
7792
+ }
7793
+ }, _callee4, null, [[2, 7, 9, 12]]);
7794
+ }));
7795
+ return function onPressExtend() {
7796
+ return _ref5.apply(this, arguments);
7797
+ };
7798
+ }();
7703
7799
  return jsxs(Box, {
7704
7800
  sx: (_sx = {
7705
7801
  display: 'flex',
@@ -7806,7 +7902,10 @@ var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7806
7902
  }), !isReadOnly && jsxs(Stack, {
7807
7903
  spacing: 2,
7808
7904
  direction: "row",
7809
- sx: (_sx3 = {}, _sx3["@container maritime (min-width: " + breakpoints.tablet + "px)"] = {
7905
+ useFlexGap: true,
7906
+ sx: (_sx3 = {
7907
+ flexWrap: 'wrap'
7908
+ }, _sx3["@container maritime (min-width: " + breakpoints.tablet + "px)"] = {
7810
7909
  position: 'absolute',
7811
7910
  bottom: 0,
7812
7911
  right: 0,
@@ -7818,22 +7917,42 @@ var MaritimeWarningsForm = function MaritimeWarningsForm(_ref) {
7818
7917
  }
7819
7918
  }, _sx3),
7820
7919
  children: [jsx(Button, {
7821
- onClick: onClearWithConfirmation,
7822
- variant: "tertiary",
7920
+ variant: "primary",
7823
7921
  size: "small",
7824
7922
  sx: {
7825
7923
  width: '134px'
7826
7924
  },
7827
- children: t('warning-button-clear')
7925
+ disabled: modified || !isValidForExtend || isExtending || isPublishing,
7926
+ onClick: onPressExtend,
7927
+ children: jsxs("span", {
7928
+ style: {
7929
+ position: 'relative'
7930
+ },
7931
+ children: [isExtending ? t('maritime-button-extending') : t('maritime-button-extend'), isExtending && jsx(CircularProgress, {
7932
+ "data-testid": "spinner",
7933
+ color: "inherit",
7934
+ sx: spinnerSx$1
7935
+ })]
7936
+ })
7828
7937
  }), jsx(Button, {
7829
- variant: "primary",
7938
+ onClick: onClearWithConfirmation,
7939
+ variant: "tertiary",
7830
7940
  size: "small",
7831
7941
  sx: (_sx4 = {
7832
7942
  width: '134px'
7833
7943
  }, _sx4["@container maritime (min-width: " + breakpoints.tablet + "px)"] = {
7834
- marginLeft: '24px!important'
7944
+ marginLeft: '8px'
7835
7945
  }, _sx4),
7836
- disabled: !modified || !isValid || isPublishing,
7946
+ children: t('warning-button-clear')
7947
+ }), jsx(Button, {
7948
+ variant: "primary",
7949
+ size: "small",
7950
+ sx: (_sx5 = {
7951
+ width: '134px'
7952
+ }, _sx5["@container maritime (min-width: " + breakpoints.tablet + "px)"] = {
7953
+ marginLeft: '8px'
7954
+ }, _sx5),
7955
+ disabled: !modified || !isValidForPublish || isPublishing || isExtending,
7837
7956
  onClick: onPressPublish,
7838
7957
  children: jsxs("span", {
7839
7958
  style: {
@@ -7997,32 +8116,40 @@ var MaritimeWarningsFormConnect = function MaritimeWarningsFormConnect(_ref) {
7997
8116
  newIndex: newIndex
7998
8117
  });
7999
8118
  }, [dispatch]);
8000
- var onSubmit = React__default.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
8001
- var nextState, maritimeWarnings;
8002
- return _regeneratorRuntime().wrap(function _callee$(_context) {
8003
- while (1) switch (_context.prev = _context.next) {
8004
- case 0:
8005
- dispatch({
8006
- type: 'mergeWarnings'
8007
- });
8008
- nextState = reducer(state, {
8009
- type: 'mergeWarnings'
8010
- });
8011
- maritimeWarnings = mapItemsToMaritimeWarnings(nextState.warnings, domain, maritimeConfig, auth == null ? void 0 : auth.username);
8012
- _context.next = 5;
8013
- return postWarnings(maritimeWarnings, {
8014
- onSuccess: function onSuccess() {
8015
- dispatch({
8016
- type: 'submitWarnings'
8017
- });
8119
+ var onSubmit = React__default.useCallback(/*#__PURE__*/function () {
8120
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(shouldExtend) {
8121
+ var nextState, maritimeWarnings;
8122
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
8123
+ while (1) switch (_context.prev = _context.next) {
8124
+ case 0:
8125
+ if (shouldExtend === void 0) {
8126
+ shouldExtend = false;
8018
8127
  }
8019
- });
8020
- case 5:
8021
- case "end":
8022
- return _context.stop();
8023
- }
8024
- }, _callee);
8025
- })), [dispatch, state, domain, maritimeConfig, auth == null ? void 0 : auth.username, postWarnings]);
8128
+ dispatch({
8129
+ type: 'mergeWarnings'
8130
+ });
8131
+ nextState = reducer(state, {
8132
+ type: 'mergeWarnings'
8133
+ });
8134
+ maritimeWarnings = mapItemsToMaritimeWarnings(nextState.warnings, domain, maritimeConfig, auth == null ? void 0 : auth.username, shouldExtend);
8135
+ _context.next = 6;
8136
+ return postWarnings(maritimeWarnings, {
8137
+ onSuccess: function onSuccess() {
8138
+ dispatch({
8139
+ type: 'submitWarnings'
8140
+ });
8141
+ }
8142
+ });
8143
+ case 6:
8144
+ case "end":
8145
+ return _context.stop();
8146
+ }
8147
+ }, _callee);
8148
+ }));
8149
+ return function (_x) {
8150
+ return _ref2.apply(this, arguments);
8151
+ };
8152
+ }(), [dispatch, state, domain, maritimeConfig, auth == null ? void 0 : auth.username, postWarnings]);
8026
8153
  var onToggleReadOnly = React__default.useCallback(function (isReadOnly) {
8027
8154
  var message = isReadOnly ? t('maritime-editor-off', {
8028
8155
  domain: domainLabel
@@ -8331,14 +8458,14 @@ isAviationWarning) {
8331
8458
  // Orange for start, purple for end
8332
8459
  borderColor: isStartGeometry ? FEATURE_DRAW_FILL_COLOR : FEATURE_DRAW_SECONDARY_FILL_COLOR
8333
8460
  };
8334
- } else if (level) {
8461
+ } else if (level && level in LevelColors) {
8335
8462
  // Public warning: use LevelColors if level is defined
8336
8463
  colors = LevelColors[level];
8337
8464
  } else {
8338
- // Default to blue if level is undefined (public warning)
8465
+ // Public warning: default to blue if level is undefined=
8339
8466
  colors = {
8340
- color: '#0000FF',
8341
- borderColor: '#0000A0'
8467
+ color: FEATURE_DRAW_FILL_COLOR,
8468
+ borderColor: FEATURE_DRAW_STROKE_COLOR
8342
8469
  };
8343
8470
  }
8344
8471
  var defaultProperties = {
@@ -8423,7 +8550,9 @@ var Form = function Form(_ref5) {
8423
8550
  _ref5$onSetViewModeRe = _ref5.onSetViewModeResetArea,
8424
8551
  onSetViewModeResetArea = _ref5$onSetViewModeRe === void 0 ? function () {} : _ref5$onSetViewModeRe,
8425
8552
  storedStartGeoJSON = _ref5.storedStartGeoJSON,
8426
- storedEndGeoJSON = _ref5.storedEndGeoJSON;
8553
+ storedEndGeoJSON = _ref5.storedEndGeoJSON,
8554
+ _ref5$setWarningLevel = _ref5.setWarningLevel,
8555
+ setWarningLevel = _ref5$setWarningLevel === void 0 ? function () {} : _ref5$setWarningLevel;
8427
8556
  var _React$useState = React.useState(false),
8428
8557
  isPublishing = _React$useState[0],
8429
8558
  setIsPublishing = _React$useState[1];
@@ -8457,7 +8586,7 @@ var Form = function Form(_ref5) {
8457
8586
  return clearTimeout(timer);
8458
8587
  };
8459
8588
  }, [endOfWarningValidity, formState, onCloseForm]);
8460
- var initialPublicWarningArea = (publicWarningDetails == null || (_publicWarningDetails = publicWarningDetails.areas) == null ? void 0 : _publicWarningDetails.length) && (publicWarningDetails == null || (_publicWarningDetails2 = publicWarningDetails.areas[0]) == null ? void 0 : _publicWarningDetails2.geoJSON);
8589
+ var initialPublicWarningArea = publicWarningDetails != null && (_publicWarningDetails = publicWarningDetails.areas) != null && _publicWarningDetails.length ? publicWarningDetails == null || (_publicWarningDetails2 = publicWarningDetails.areas[0]) == null ? void 0 : _publicWarningDetails2.geoJSON : undefined;
8461
8590
  var _React$useState3 = React.useState(initialPublicWarningArea),
8462
8591
  warningGeoJSONFeature = _React$useState3[0],
8463
8592
  setWarningGeoJSONFeature = _React$useState3[1];
@@ -8713,6 +8842,7 @@ var Form = function Form(_ref5) {
8713
8842
  default:
8714
8843
  reset(getEmptyPublicWarning());
8715
8844
  setWarningGeoJSONFeature(undefined);
8845
+ setWarningLevel('');
8716
8846
  break;
8717
8847
  }
8718
8848
  onClearForm();
@@ -8759,14 +8889,20 @@ var Form = function Form(_ref5) {
8759
8889
  }
8760
8890
  // eslint-disable-next-line react-hooks/exhaustive-deps
8761
8891
  }, [areas, setValue]);
8892
+ var level = watch('level');
8762
8893
  React.useEffect(function () {
8763
8894
  if (selectedAviationProduct) {
8764
8895
  return;
8765
8896
  }
8766
- // sync drawing on map with selected warning
8767
- setWarningGeoJSONFeature(initialPublicWarningArea);
8897
+ // sync drawing on map with selected warning including selected level color
8898
+ var geoJSONFeature = warningLevelFeatureColors(level, initialPublicWarningArea);
8899
+ setWarningGeoJSONFeature(geoJSONFeature);
8768
8900
  // eslint-disable-next-line react-hooks/exhaustive-deps
8769
- }, [initialPublicWarningArea]);
8901
+ }, [initialPublicWarningArea, level]);
8902
+ React.useEffect(function () {
8903
+ // update level in redux so linked map updates feature color accordingly
8904
+ setWarningLevel(level || '');
8905
+ }, [level, setWarningLevel]);
8770
8906
  var aviationId = selectedAviationProduct == null ? void 0 : selectedAviationProduct.uuid;
8771
8907
  var publishedStart = publicWarningDetails == null ? void 0 : publicWarningDetails.validFrom;
8772
8908
  var nowIso = dateUtils.getCurrentTimeAsString();
@@ -8780,8 +8916,6 @@ var Form = function Form(_ref5) {
8780
8916
  // eslint-disable-next-line react-hooks/exhaustive-deps
8781
8917
  }, [aviationId, warningType]);
8782
8918
  var errors = getErrors(error.message);
8783
- var level = publicWarningDetails != null && publicWarningDetails.level ? WarningLevel[publicWarningDetails.level] : undefined;
8784
- var geoJSONFeature = warningLevelFeatureColors(level, warningGeoJSONFeature);
8785
8919
  var ref = useScrollTopOnError(error);
8786
8920
  var _useProductConfig = useProductConfig(warningType),
8787
8921
  aviationConfig = _useProductConfig.data;
@@ -8884,7 +9018,7 @@ var Form = function Form(_ref5) {
8884
9018
  xs: 12
8885
9019
  },
8886
9020
  children: jsx(WarningsMapView, {
8887
- geojsonFeature: geoJSONFeature,
9021
+ geojsonFeature: warningGeoJSONFeature,
8888
9022
  defaultMapPreset: defaultMapPreset,
8889
9023
  isSnapshot: isSnapshot
8890
9024
  })
@@ -9364,6 +9498,9 @@ var PublicWarningsFormConnect = function PublicWarningsFormConnect(_ref) {
9364
9498
  area: area[0]
9365
9499
  }));
9366
9500
  };
9501
+ var setWarningLevel = function setWarningLevel(level) {
9502
+ dispatch(publicWarningFormActions.setWarningLevel(level));
9503
+ };
9367
9504
  var selectedMapIds = useSelector(function (state) {
9368
9505
  return genericSelectors.getLinkedMaps(state, panelId);
9369
9506
  });
@@ -9396,7 +9533,8 @@ var PublicWarningsFormConnect = function PublicWarningsFormConnect(_ref) {
9396
9533
  formState: formState,
9397
9534
  onSetViewModeResetArea: onSetViewModeResetArea,
9398
9535
  storedStartGeoJSON: storedStartGeoJSON,
9399
- storedEndGeoJSON: storedEndGeoJSON
9536
+ storedEndGeoJSON: storedEndGeoJSON,
9537
+ setWarningLevel: setWarningLevel
9400
9538
  }, (warning == null ? void 0 : warning.id) || (selectedAviationProduct == null ? void 0 : selectedAviationProduct.uuid) || 'new');
9401
9539
  };
9402
9540
 
@@ -10096,7 +10234,7 @@ var AreaObjectLoaderConnect = function AreaObjectLoaderConnect(_ref) {
10096
10234
  * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
10097
10235
  * */
10098
10236
  var useWarnings = function useWarnings(disabled, timeFilter) {
10099
- var _usePublicWarnings = usePublicWarnings(disabled),
10237
+ var _usePublicWarnings = usePublicWarnings(disabled, timeFilter),
10100
10238
  publicWarnings = _usePublicWarnings.data,
10101
10239
  refetchPublicWarnings = _usePublicWarnings.refetch,
10102
10240
  isFetchingPublicWarnings = _usePublicWarnings.isFetching,
@@ -10189,6 +10327,7 @@ var PublicWarningsFormDialogConnect = function PublicWarningsFormDialogConnect(_
10189
10327
  t = _useWarningsTranslati.t;
10190
10328
  var dispatch = useDispatch();
10191
10329
  var confirmDialog = useConfirmationDialog();
10330
+ var queryClient = useQueryClient();
10192
10331
  var formAction = useSelector(function (store) {
10193
10332
  return getPublicWarningFormState(store);
10194
10333
  });
@@ -10301,6 +10440,19 @@ var PublicWarningsFormDialogConnect = function PublicWarningsFormDialogConnect(_
10301
10440
  return _regeneratorRuntime().wrap(function _callee$(_context) {
10302
10441
  while (1) switch (_context.prev = _context.next) {
10303
10442
  case 0:
10443
+ queryClient.setQueriesData({
10444
+ queryKey: ['public-warning-list'],
10445
+ exact: false
10446
+ }, function (old) {
10447
+ if (!old) {
10448
+ return old;
10449
+ }
10450
+ return old.map(function (warning) {
10451
+ return warning.id === selectedWarningId ? Object.assign({}, warning, {
10452
+ editor: isReadOnly ? undefined : auth == null ? void 0 : auth.username
10453
+ }) : warning;
10454
+ });
10455
+ });
10304
10456
  dispatch(publicWarningFormActions.setFormValues({
10305
10457
  formState: isReadOnly ? 'readonly' : ''
10306
10458
  }));
@@ -10308,7 +10460,7 @@ var PublicWarningsFormDialogConnect = function PublicWarningsFormDialogConnect(_
10308
10460
  type: uiTypes.DialogTypes.AreaObjectLoader,
10309
10461
  setOpen: false
10310
10462
  }));
10311
- case 2:
10463
+ case 3:
10312
10464
  case "end":
10313
10465
  return _context.stop();
10314
10466
  }
@@ -11814,7 +11966,9 @@ var PublicWarningList = function PublicWarningList(_ref) {
11814
11966
  onActionMaritimeWarning = _ref$onActionMaritime === void 0 ? function () {} : _ref$onActionMaritime,
11815
11967
  hoveredFeatureId = _ref.hoveredFeatureId,
11816
11968
  expandedSections = _ref.expandedSections,
11817
- setExpandedSections = _ref.setExpandedSections;
11969
+ setExpandedSections = _ref.setExpandedSections,
11970
+ limitAlertCount = _ref.limitAlertCount,
11971
+ showLimitAlert = _ref.showLimitAlert;
11818
11972
  var updateFilter = filterHookState.updateFilter,
11819
11973
  allSelected = filterHookState.allSelected,
11820
11974
  filterState = filterHookState.filterState,
@@ -11953,7 +12107,19 @@ var PublicWarningList = function PublicWarningList(_ref) {
11953
12107
  }), error ? jsx(AlertBanner, {
11954
12108
  title: error.message,
11955
12109
  shouldClose: true
11956
- }) : null, !error && jsxs(Grid, {
12110
+ }) : null, showLimitAlert && jsx(Box, {
12111
+ sx: {
12112
+ mb: 2
12113
+ },
12114
+ children: jsx(AlertBanner, {
12115
+ severity: "warning",
12116
+ title: t('warning-list-too-many-title'),
12117
+ dataTestId: "warning-list-over-limit",
12118
+ info: t('warning-list-too-many-info', {
12119
+ count: limitAlertCount
12120
+ })
12121
+ })
12122
+ }), !error && jsxs(Grid, {
11957
12123
  container: true,
11958
12124
  rowSpacing: 0,
11959
12125
  columnSpacing: 0,
@@ -12657,8 +12823,9 @@ var CancelAviationConfirmDialog = function CancelAviationConfirmDialog(_ref) {
12657
12823
  });
12658
12824
  };
12659
12825
 
12826
+ var MAX_WARNINGS_DISPLAY = 200;
12660
12827
  var PublicWarningListConnect = function PublicWarningListConnect(_ref) {
12661
- var _filteredWarnings$fin;
12828
+ var _displayedWarnings$fi;
12662
12829
  var panelId = _ref.panelId,
12663
12830
  presetFilterState = _ref.presetFilterState;
12664
12831
  var updatePublicWarningEditor = useMutatePublicWarningEditor();
@@ -13160,6 +13327,12 @@ var PublicWarningListConnect = function PublicWarningListConnect(_ref) {
13160
13327
  var filteredWarnings = React__default.useMemo(function () {
13161
13328
  return combinedWarnings.filter(filterHookState.byFilterState);
13162
13329
  }, [combinedWarnings, filterHookState.byFilterState]);
13330
+ var isOverLimit = filteredWarnings.length > MAX_WARNINGS_DISPLAY;
13331
+ var hasCustomTimeFilter = savedFilterState.time.mode === TimeFilterMode.custom;
13332
+ var shouldShowAlertBanner = hasCustomTimeFilter && isOverLimit;
13333
+ var displayedWarnings = React__default.useMemo(function () {
13334
+ return shouldShowAlertBanner ? [] : filteredWarnings;
13335
+ }, [shouldShowAlertBanner, filteredWarnings]);
13163
13336
  var _React$useState4 = React__default.useState({
13164
13337
  TODO: false,
13165
13338
  DRAFT: false,
@@ -13169,14 +13342,14 @@ var PublicWarningListConnect = function PublicWarningListConnect(_ref) {
13169
13342
  expandedSections = _React$useState4[0],
13170
13343
  setExpandedSections = _React$useState4[1];
13171
13344
  var filteredWarningsByExpandedSections = React__default.useMemo(function () {
13172
- return filteredWarnings.filter(function (warning) {
13345
+ return displayedWarnings.filter(function (warning) {
13173
13346
  var _ref7;
13174
13347
  return (_ref7 = warning.status && expandedSections[warning.status]) != null ? _ref7 : warning.productStatus && expandedSections[warning.productStatus];
13175
13348
  });
13176
- }, [filteredWarnings, expandedSections]);
13177
- var selectedAviationProductId = (_filteredWarnings$fin = filteredWarnings.find(function (warning) {
13349
+ }, [displayedWarnings, expandedSections]);
13350
+ var selectedAviationProductId = (_displayedWarnings$fi = displayedWarnings.find(function (warning) {
13178
13351
  return (warning.warningDetail.level === 'SIG' || warning.warningDetail.level === 'AIR') && warning.id === selectedWarningId;
13179
- })) == null ? void 0 : _filteredWarnings$fin.id;
13352
+ })) == null ? void 0 : _displayedWarnings$fi.id;
13180
13353
  var allFeatures = React__default.useMemo(function () {
13181
13354
  return filteredWarningsByExpandedSections.flatMap(function (warning) {
13182
13355
  var _warning$warningDetai, _warning$warningDetai2;
@@ -13226,7 +13399,9 @@ var PublicWarningListConnect = function PublicWarningListConnect(_ref) {
13226
13399
  onWithdrawWarning: withdrawWarning,
13227
13400
  selectedWarningId: selectedWarningId,
13228
13401
  setExpandedSections: setExpandedSections,
13229
- warnings: filteredWarnings
13402
+ warnings: displayedWarnings,
13403
+ limitAlertCount: filteredWarnings.length,
13404
+ showLimitAlert: shouldShowAlertBanner
13230
13405
  }), confirmDialogOptions ? jsx(ConfirmDeleteWarningDialog, {
13231
13406
  callback: confirmDialogOptions.callback,
13232
13407
  confirmLabel: confirmDialogOptions.confirmLabel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/warnings",
3
- "version": "14.3.0",
3
+ "version": "14.4.0",
4
4
  "description": "GeoWeb warinings library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,25 +8,25 @@
8
8
  "url": "git@gitlab.com:opengeoweb/opengeoweb.git"
9
9
  },
10
10
  "dependencies": {
11
- "@opengeoweb/api": "14.3.0",
12
- "@opengeoweb/shared": "14.3.0",
13
- "@opengeoweb/store": "14.3.0",
14
- "@opengeoweb/webmap-react": "14.3.0",
11
+ "@opengeoweb/api": "14.4.0",
12
+ "@opengeoweb/shared": "14.4.0",
13
+ "@opengeoweb/store": "14.4.0",
14
+ "@opengeoweb/webmap-react": "14.4.0",
15
15
  "@tanstack/react-query": "^5.85.5",
16
16
  "react-redux": "^9.2.0",
17
- "@opengeoweb/theme": "14.3.0",
18
- "@opengeoweb/form-fields": "14.3.0",
17
+ "@opengeoweb/theme": "14.4.0",
18
+ "@opengeoweb/form-fields": "14.4.0",
19
19
  "react-hook-form": "^7.50.1",
20
20
  "lodash": "^4.17.21",
21
21
  "@reduxjs/toolkit": "^2.6.1",
22
- "@opengeoweb/snackbar": "14.3.0",
22
+ "@opengeoweb/snackbar": "14.4.0",
23
23
  "react-window": "^1.8.10",
24
24
  "react-virtualized-auto-sizer": "^1.0.20",
25
25
  "axios": "^1.7.7",
26
- "@opengeoweb/core": "14.3.0",
27
- "@opengeoweb/webmap": "14.3.0",
28
- "@opengeoweb/authentication": "14.3.0",
29
- "@opengeoweb/sigmet-airmet": "14.3.0",
26
+ "@opengeoweb/core": "14.4.0",
27
+ "@opengeoweb/webmap": "14.4.0",
28
+ "@opengeoweb/authentication": "14.4.0",
29
+ "@opengeoweb/sigmet-airmet": "14.4.0",
30
30
  "react-i18next": "^15.1.1",
31
31
  "i18next": "^25.0.1",
32
32
  "@mui/material": "^7.0.1",
@@ -2,7 +2,7 @@ import { Credentials } from '@opengeoweb/authentication';
2
2
  import { MaritimeWarning, MaritimeWarningsType, PublicWarning } from '../../store/publicWarningForm/types';
3
3
  import { DrawingFromBE, DrawingFromFE, DrawingListItem, FetchDrawingParams } from '../../store/warningsDrawings/types';
4
4
  import { MaritimeWarningsConfig } from '../../components/MaritimeWarningsForm/types';
5
- export declare const getPublicWarningList: (auth: Credentials) => Promise<PublicWarning[]>;
5
+ export declare const getPublicWarningList: (auth: Credentials, apiParams?: Record<string, string>) => Promise<PublicWarning[]>;
6
6
  export declare const updatePublicWarningEditor: (warningId: string, isEditor: boolean, auth: Credentials, force?: boolean) => Promise<Headers | null>;
7
7
  export declare const updatePublicWarning: (warningId: string, auth: Credentials, data: PublicWarning) => Promise<Headers | null>;
8
8
  export declare const postPublicWarning: (auth: Credentials, data: PublicWarning) => Promise<Headers | null>;
@@ -2,11 +2,12 @@ import { UseMutationResult, UseQueryResult } from '@tanstack/react-query';
2
2
  import { MaritimeWarning, MaritimeWarningsType, PublicWarning } from '../../store/publicWarningForm/types';
3
3
  import { DrawingFromBE, DrawingFromFE, DrawingListItem, FetchDrawingParams } from '../../store/warningsDrawings/types';
4
4
  import { MaritimeWarningsConfig } from '../../components/MaritimeWarningsForm/types';
5
+ import { TimeFilter } from '../../components/FilterList/filter-utils';
5
6
  /**
6
7
  * @param disabled - Disables fetching, but still returns cached values.
7
8
  * https://tanstack.com/query/v4/docs/framework/react/guides/disabling-queries
8
9
  */
9
- export declare const usePublicWarnings: (disabled?: boolean) => UseQueryResult<(PublicWarning | MaritimeWarning)[]>;
10
+ export declare const usePublicWarnings: (disabled?: boolean, timeFilter?: TimeFilter) => UseQueryResult<(PublicWarning | MaritimeWarning)[]>;
10
11
  type MutationReturnType<T> = UseMutationResult<Headers | null, Error, T, {
11
12
  oldData: PublicWarning[] | undefined;
12
13
  }>;
@@ -16,7 +16,7 @@ export interface MaritimeWarningsFormProps {
16
16
  onAddWarning: () => void;
17
17
  onChangeWarning: (id: string, newValues: Partial<MaritimeWarningItemAttributes>) => void;
18
18
  onMoveWarning: (oldIndex: number, newIndex: number) => void;
19
- onSubmit: () => Promise<void>;
19
+ onSubmit: (shouldExtend?: boolean) => Promise<void>;
20
20
  onClear: () => void;
21
21
  onToggleReadOnly: (isReadOnly: boolean) => void;
22
22
  isReadOnly: boolean;
@@ -15,7 +15,7 @@ export interface WarningListSelectProps {
15
15
  gridArea: string;
16
16
  additionalStyling?: SxProps;
17
17
  isReadOnly?: boolean;
18
- displayEmpty?: boolean;
18
+ emptyMessage?: string;
19
19
  validationResult?: true | 'error' | 'warning';
20
20
  }
21
- export declare const WarningListSelect: React.MemoExoticComponent<({ options, value, label, onChange, renderOption, renderValue, gridArea, additionalStyling, isReadOnly, displayEmpty, validationResult, }: WarningListSelectProps) => import("react/jsx-runtime").JSX.Element>;
21
+ export declare const WarningListSelect: React.MemoExoticComponent<({ options, value, label, onChange, renderOption, renderValue, gridArea, additionalStyling, isReadOnly, emptyMessage, validationResult, }: WarningListSelectProps) => import("react/jsx-runtime").JSX.Element>;
@@ -1,7 +1,7 @@
1
1
  import { MaritimeWarning, MaritimeWarningsType } from '../../store/publicWarningForm/types';
2
2
  import { MaritimeWarningItem, MaritimeWarningsConfig, MaritimeWarningsDomain } from './types';
3
- export declare const isWarningsValid: (warnings: MaritimeWarningItem[], config: MaritimeWarningsConfig) => boolean;
3
+ export declare const isWarningsValid: (warnings: MaritimeWarningItem[], config: MaritimeWarningsConfig, allowEmpty?: boolean) => boolean;
4
4
  export declare const getType: (domain: MaritimeWarningsDomain) => MaritimeWarningsType;
5
- export declare const mapItemsToMaritimeWarnings: (warnings: MaritimeWarningItem[], domain: MaritimeWarningsDomain, maritimeConfig: MaritimeWarningsConfig, editor?: string) => MaritimeWarning[];
5
+ export declare const mapItemsToMaritimeWarnings: (warnings: MaritimeWarningItem[], domain: MaritimeWarningsDomain, maritimeConfig: MaritimeWarningsConfig, editor?: string, shouldExtend?: boolean) => MaritimeWarning[];
6
6
  export declare const mapMaritimeWarningsToItems: (warnings: MaritimeWarning[]) => MaritimeWarningItem[];
7
7
  export declare const validateWindDirectionChange: (directionFrom: string | undefined, directionTo: string | undefined, changeType: string | undefined, config?: MaritimeWarningsConfig) => true | "warning" | "error";
@@ -16,6 +16,8 @@ export interface PublicWarningListProps extends WarningListItemActions {
16
16
  expandedSections: Record<string, boolean>;
17
17
  setExpandedSections: (expandedSections: Record<string, boolean>) => void;
18
18
  onActionAviationWarning?: () => void;
19
+ limitAlertCount?: number;
20
+ showLimitAlert?: boolean;
19
21
  }
20
22
  export declare const PublicWarningList: React.FC<PublicWarningListProps>;
21
23
  export default PublicWarningList;
@@ -58,3 +58,7 @@ export declare const PublicWarningListMaritime: {
58
58
  (): React.ReactElement;
59
59
  tags: string[];
60
60
  };
61
+ export declare const PublicWarningListTooManyWarnings: {
62
+ (): React.ReactElement;
63
+ tags: string[];
64
+ };
@@ -5,4 +5,3 @@ export interface PublicWarningListConnectProps {
5
5
  presetFilterState?: PickedFilterState;
6
6
  }
7
7
  export declare const PublicWarningListConnect: React.FC<PublicWarningListConnectProps>;
8
- export default PublicWarningListConnect;
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { FilterTranslation } from '../../../store/publicWarnings/types';
3
3
  export interface ColorDefinition {
4
4
  color: string;
5
- textColor: string;
5
+ textColor?: string;
6
6
  borderColor: string;
7
7
  }
8
8
  export interface LevelDetails extends FilterTranslation, ColorDefinition {
@@ -37,6 +37,7 @@ export interface FormProps {
37
37
  onSetViewModeResetArea?: (area: Area[]) => void;
38
38
  storedStartGeoJSON?: FeatureCollection<Geometry, GeoJsonProperties>;
39
39
  storedEndGeoJSON?: FeatureCollection<Geometry, GeoJsonProperties>;
40
+ setWarningLevel?: (level: WarningLevel | '') => void;
40
41
  }
41
42
  export declare function warningLevelFeatureColors(level: WarningLevel | undefined, geoJSON: FeatureCollection<Geometry, GeoJsonProperties> | undefined, // Allow undefined
42
43
  isAviationWarning?: boolean): FeatureCollection<Geometry, GeoJsonProperties>;
@@ -2,6 +2,7 @@ import { AlertColor } from '@mui/material';
2
2
  import { Draft, PayloadAction } from '@reduxjs/toolkit';
3
3
  import { DrawingListItem } from '../warningsDrawings/types';
4
4
  import { Area, Warning, WarningType } from './types';
5
+ import { WarningLevel } from '../../components/PublicWarningsForm/LevelField';
5
6
  export type FormAction = '' | 'saving' | 'publishing' | 'readonly' | 'edit' | 'amending' | 'cancel';
6
7
  export interface FormError {
7
8
  severity?: AlertColor;
@@ -48,4 +49,5 @@ export declare const publicWarningFormReducer: import("redux").Reducer<WarningFo
48
49
  warningId: string;
49
50
  }>) => void;
50
51
  setSelectedWarningId: (draft: Draft<WarningFormState>, action: PayloadAction<string>) => void;
52
+ setWarningLevel: (draft: Draft<WarningFormState>, action: PayloadAction<WarningLevel | "">) => void;
51
53
  }, "publicWarningForm">;