@opengeoweb/taf 4.4.0 → 4.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/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { TextField, Grid, Box, Button, IconButton, Tooltip, Chip, Typography, FormLabel, Switch, Card, Tabs, Tab, Dialog, MenuList, MenuItem, Backdrop, CircularProgress } from '@mui/material';
3
+ import { TextField, Grid, Box, Button, IconButton, Chip, Typography, FormLabel, Switch, Card, Tabs, Tab, Dialog, MenuList, MenuItem, Backdrop, CircularProgress } from '@mui/material';
4
4
  import { useFormContext, Controller, useFieldArray } from 'react-hook-form';
5
5
  import { useDispatch } from 'react-redux';
6
6
  import { ReactSortable } from 'react-sortablejs';
@@ -8,7 +8,7 @@ import Sortable from 'sortablejs';
8
8
  import { isEqual } from 'lodash';
9
9
  import { useAuthenticationContext } from '@opengeoweb/authentication';
10
10
  import { getDeepProperty, ReactHookFormHiddenInput, ReactHookFormProvider } from '@opengeoweb/form-fields';
11
- import { useIsMounted, ToggleMenu, useDraftFormHelpers, ToolContainerDraggable, Avatar, getInitials, useConfirmationDialog, usePreventBrowserClose, ToolButton, ToolHeader, AlertBanner, getErrorMessage as getErrorMessage$1, getWarningMessage, ConfirmationServiceProvider, usePoller, ErrorBoundary } from '@opengeoweb/shared';
11
+ import { useIsMounted, ToggleMenu, useDraftFormHelpers, CustomTooltip, ToolContainerDraggable, Avatar, getInitials, useConfirmationDialog, usePreventBrowserClose, ToolButton, ToolHeader, AlertBanner, getErrorMessage as getErrorMessage$1, getWarningMessage, ConfirmationServiceProvider, usePoller, ErrorBoundary } from '@opengeoweb/shared';
12
12
  import { snackbarActions } from '@opengeoweb/core';
13
13
  import moment from 'moment';
14
14
  import { Add, Delete, Close, DragHandle as DragHandle$1, ThumbsUp, Clock, Cancel, Edit, Success, Export, ListItem, Cached } from '@opengeoweb/theme';
@@ -52,10 +52,6 @@ function _slicedToArray(arr, i) {
52
52
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
53
53
  }
54
54
 
55
- function _toArray(arr) {
56
- return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest();
57
- }
58
-
59
55
  function _toConsumableArray(arr) {
60
56
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
61
57
  }
@@ -1363,11 +1359,10 @@ var invalidWindDirectionStepMessage = 'Invalid wind direction, the direction mus
1363
1359
  var invalidWindSpeedMessage = 'Invalid wind speed, expected a speed equal to 2 digits or P99';
1364
1360
  var invalidWindGustsMessage = 'Invalid wind gusts, expected gusts equal to 2 digits or P99';
1365
1361
  var invalidWindGustSpeedCombinationMessage = 'Invalid wind gusts, gusts must at least be 10 knots greater than the wind speed';
1366
- var invalidWindGustSpeedBelow15Message = 'Invalid wind gusts, gusts are only allowed for a minimum wind speed of 15 knots';
1367
1362
  var invalidGustForWindP99Message = 'Invalid wind speed and gust combination, if wind is P99, gusts can only be empty or P99';
1368
1363
  var invalidWindSpeedForDirectionZeroMessage = 'Invalid wind speed, if direction is 000, speed can only be 00';
1369
1364
  var invalidWindSpeedForDirectionNonZeroMessage = 'Invalid wind speed, if direction is not 000, speed can not be 00';
1370
- var invalidWindVRBWindDirectionMessage = 'Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 4 or in combination with gusts and showers'; // validations
1365
+ var invalidWindVRBWindDirectionMessage = 'Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 3 or in combination with gusts and showers'; // validations
1371
1366
 
1372
1367
  var validateDirection = function validateDirection(value) {
1373
1368
  // if not a number
@@ -1424,8 +1419,8 @@ var validateWindInterSection = function validateWindInterSection(speed, gust, di
1424
1419
  return invalidWindSpeedForDirectionNonZeroMessage;
1425
1420
  }
1426
1421
 
1427
- if (direction === 'VRB' && (speed === 'P99' || parseInt(speed, 10) > 3)) {
1428
- // Only allow VRB for speeds smaller than 4 or in combination with gusts and showers (SH, TS, SQ)
1422
+ if (direction === 'VRB' && (speed === 'P99' || parseInt(speed, 10) > 2)) {
1423
+ // Only allow VRB for speeds smaller than 3 or in combination with gusts and showers (SH, TS, SQ)
1429
1424
  var allowedWeatherPhenom = ['SH', 'TS', 'SQ'];
1430
1425
  if (gust === '' || !allowedWeatherPhenom.some(function (allowedPhenom) {
1431
1426
  return weather1Value.includes(allowedPhenom);
@@ -1445,10 +1440,6 @@ var validateWindInterSection = function validateWindInterSection(speed, gust, di
1445
1440
  return invalidGustForWindP99Message;
1446
1441
  }
1447
1442
 
1448
- if (parseInt(speed, 10) < 15) {
1449
- return invalidWindGustSpeedBelow15Message;
1450
- }
1451
-
1452
1443
  if (gust !== 'P99' && parseInt(gust, 10) - parseInt(speed, 10) < 10) {
1453
1444
  return invalidWindGustSpeedCombinationMessage;
1454
1445
  }
@@ -3566,14 +3557,10 @@ var DragHandle = function DragHandle(_ref) {
3566
3557
  * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3567
3558
  * Copyright 2022 - Finnish Meteorological Institute (FMI)
3568
3559
  * */
3569
- var getCustomError = function getCustomError(error) {
3570
- var name = error.ref.name;
3571
- var isChangeGroup = name.includes('changeGroups');
3572
- var matchRowNumber = name.match(/\[(.*?)\]/);
3573
- var row = matchRowNumber ? parseInt(matchRowNumber[1], 10) : null;
3560
+ var getCustomError = function getCustomError(error, isChangeGroup, rowIndex) {
3574
3561
  return Object.assign(Object.assign({}, error), {
3575
3562
  isChangeGroup: isChangeGroup,
3576
- row: row
3563
+ rowIndex: rowIndex
3577
3564
  });
3578
3565
  };
3579
3566
  var getIssuesLabel = function getIssuesLabel(sumOfErrors) {
@@ -3588,33 +3575,33 @@ var getIssuesLabel = function getIssuesLabel(sumOfErrors) {
3588
3575
  return "".concat(sumOfErrors, " issues");
3589
3576
  }
3590
3577
  };
3591
-
3592
3578
  var getErrorValues = function getErrorValues(fieldErrors) {
3579
+ var isChangeGroup = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
3580
+ var rowIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1;
3593
3581
  if (!fieldErrors) return [];
3594
3582
  return Object.keys(fieldErrors).reduce(function (list, key) {
3595
3583
  var error = Object.assign({}, fieldErrors[key]);
3596
3584
 
3597
3585
  if (error.ref) {
3598
- return list.concat(getCustomError(error));
3586
+ return list.concat(getCustomError(error, isChangeGroup, rowIndex));
3599
3587
  }
3600
3588
 
3601
- return list.concat(getErrorValues(error));
3589
+ return list.concat(getErrorValues(error, isChangeGroup, rowIndex));
3602
3590
  }, []);
3603
3591
  };
3604
-
3605
3592
  var filterDuplicateErrors = function filterDuplicateErrors(errors) {
3606
3593
  return errors.reduce(function (list, error) {
3607
3594
  // check on type validateRequiredSub and validateRequiredMainOptional since these are giving 'duplicates'
3608
3595
  if (error.type === 'validateRequiredSub') {
3609
3596
  var exist = list.find(function (e) {
3610
- return e.type === 'validateRequiredSub' && e.row === error.row;
3597
+ return e.type === 'validateRequiredSub' && e.rowIndex === error.rowIndex;
3611
3598
  });
3612
3599
  return exist ? list : list.concat(error);
3613
3600
  }
3614
3601
 
3615
3602
  if (error.type === 'validateRequiredMainOptional') {
3616
3603
  var _exist = list.find(function (e) {
3617
- return e.type === 'validateRequiredMainOptional' && e.row === error.row;
3604
+ return e.type === 'validateRequiredMainOptional' && e.rowIndex === error.rowIndex;
3618
3605
  });
3619
3606
 
3620
3607
  return _exist ? list : list.concat(error);
@@ -3625,16 +3612,17 @@ var filterDuplicateErrors = function filterDuplicateErrors(errors) {
3625
3612
  };
3626
3613
  var getErrors = function getErrors(errors) {
3627
3614
  var errorList = Object.keys(errors).reduce(function (list, key) {
3628
- var errorValue = errors[key];
3615
+ var errorValue = errors[key]; // changeGroups
3629
3616
 
3630
3617
  if (Array.isArray(errorValue)) {
3631
- var errorValues = errorValue.reduce(function (l, i) {
3632
- return l.concat(getErrorValues(i));
3618
+ var errorValues = errorValue.reduce(function (changeGroupErrors, changeGroupError, index) {
3619
+ return changeGroupErrors.concat(getErrorValues(changeGroupError, true, index));
3633
3620
  }, []);
3634
3621
  return list.concat.apply(list, _toConsumableArray(errorValues));
3635
- }
3622
+ } // baseForecast
3623
+
3636
3624
 
3637
- return list.concat(getErrorValues(errorValue));
3625
+ return list.concat(getErrorValues(errorValue, false, -1));
3638
3626
  }, []);
3639
3627
  return errorList;
3640
3628
  };
@@ -3692,7 +3680,7 @@ var IssuesButton = function IssuesButton(_ref) {
3692
3680
  toggleIssuesPane(newPosition);
3693
3681
  };
3694
3682
 
3695
- return /*#__PURE__*/React.createElement(Tooltip, {
3683
+ return /*#__PURE__*/React.createElement(CustomTooltip, {
3696
3684
  title: "View details"
3697
3685
  }, /*#__PURE__*/React.createElement(Chip, {
3698
3686
  "data-testid": "issuesButton",
@@ -3728,43 +3716,18 @@ var getPaneTitle = function getPaneTitle(sumOfErrors) {
3728
3716
  }
3729
3717
  };
3730
3718
 
3731
- var capitalizeWord = function capitalizeWord(_ref) {
3732
- var _ref2 = _toArray(_ref),
3733
- firstLetter = _ref2[0],
3734
- restOfWord = _ref2.slice(1);
3735
-
3736
- return firstLetter.toUpperCase() + restOfWord.join('');
3737
- };
3738
- var humanizeErrorMessage = function humanizeErrorMessage(nameAsString) {
3739
- var nameWithoutBrackets = nameAsString.replace(/[[\]']+/g, '');
3740
- var nameLowerCase = nameWithoutBrackets.toLowerCase();
3741
-
3742
- var _nameLowerCase$split$ = nameLowerCase.split(/([0-9]+)/) // split num bers from field and build array
3743
- .filter(function (s) {
3744
- return s.length;
3745
- }),
3746
- _nameLowerCase$split$2 = _slicedToArray(_nameLowerCase$split$, 2),
3747
- fieldName = _nameLowerCase$split$2[0],
3748
- fieldNumberedValue = _nameLowerCase$split$2[1];
3749
-
3750
- var nameCapitalized = capitalizeWord(fieldName);
3751
-
3752
- if (fieldNumberedValue) {
3719
+ var humanizeErrorMessage = function humanizeErrorMessage(errorTitle, fieldNumberedValue) {
3720
+ if (fieldNumberedValue !== undefined && fieldNumberedValue >= 0) {
3753
3721
  // when name contains a number we assume it's a formgroup and we add a index +1 for human readability
3754
- var fieldNumber = parseInt(fieldNumberedValue, 10) + 1;
3755
- return "".concat(nameCapitalized, " ").concat(fieldNumber);
3722
+ var fieldNumber = fieldNumberedValue + 1;
3723
+ return "".concat(errorTitle, " ").concat(fieldNumber);
3756
3724
  }
3757
3725
 
3758
- return nameCapitalized;
3726
+ return errorTitle;
3759
3727
  };
3760
3728
  var getErrorMessage = function getErrorMessage(error, index) {
3761
- var name = error.ref.name;
3762
-
3763
- var _name$split = name.split('.'),
3764
- _name$split2 = _slicedToArray(_name$split, 1),
3765
- firstNamePart = _name$split2[0];
3766
-
3767
- var fieldErrorTitle = humanizeErrorMessage(firstNamePart);
3729
+ var errorTitleCategory = error.isChangeGroup ? 'Changegroups' : 'Baseforecast';
3730
+ var fieldErrorTitle = humanizeErrorMessage(errorTitleCategory, error.rowIndex);
3768
3731
  return "".concat(index + 1, ". ").concat(fieldErrorTitle, ": ").concat(error.message);
3769
3732
  };
3770
3733
  var MODAL_DIALOG_ELEMENT = 'modal-dialog';
@@ -3799,16 +3762,16 @@ var useIssuesPane = function useIssuesPane() {
3799
3762
  };
3800
3763
  };
3801
3764
 
3802
- var IssuesPane = function IssuesPane(_ref3) {
3803
- var _ref3$errorList = _ref3.errorList,
3804
- errorList = _ref3$errorList === void 0 ? [] : _ref3$errorList,
3805
- isOpen = _ref3.isOpen,
3806
- handleClose = _ref3.handleClose,
3807
- _ref3$startPosition = _ref3.startPosition,
3808
- startPosition = _ref3$startPosition === void 0 ? {
3765
+ var IssuesPane = function IssuesPane(_ref) {
3766
+ var _ref$errorList = _ref.errorList,
3767
+ errorList = _ref$errorList === void 0 ? [] : _ref$errorList,
3768
+ isOpen = _ref.isOpen,
3769
+ handleClose = _ref.handleClose,
3770
+ _ref$startPosition = _ref.startPosition,
3771
+ startPosition = _ref$startPosition === void 0 ? {
3809
3772
  left: 20,
3810
3773
  top: 50
3811
- } : _ref3$startPosition;
3774
+ } : _ref$startPosition;
3812
3775
  var rootElement = document.getElementById(MODAL_DIALOG_ELEMENT) || document.body;
3813
3776
  return /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(ToolContainerDraggable, {
3814
3777
  startSize: {
@@ -3956,7 +3919,7 @@ var styles = {
3956
3919
  };
3957
3920
 
3958
3921
  var SwitchButton = function SwitchButton(props) {
3959
- return /*#__PURE__*/React.createElement(Tooltip, {
3922
+ return /*#__PURE__*/React.createElement(CustomTooltip, {
3960
3923
  title: "Switch mode"
3961
3924
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormLabel, {
3962
3925
  sx: styles.label
@@ -3967,28 +3930,11 @@ var SwitchButton = function SwitchButton(props) {
3967
3930
  }, "Editor")));
3968
3931
  };
3969
3932
 
3970
- /* *
3971
- * Licensed under the Apache License, Version 2.0 (the "License");
3972
- * you may not use this file except in compliance with the License.
3973
- * You may obtain a copy of the License at
3974
- *
3975
- * http://www.apache.org/licenses/LICENSE-2.0
3976
- *
3977
- * Unless required by applicable law or agreed to in writing, software
3978
- * distributed under the License is distributed on an "AS IS" BASIS,
3979
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3980
- * See the License for the specific language governing permissions and
3981
- * limitations under the License.
3982
- *
3983
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3984
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
3985
- * */
3986
-
3987
3933
  var TafAvatar = function TafAvatar(_ref) {
3988
3934
  var editor = _ref.editor,
3989
3935
  _ref$tooltipPlacement = _ref.tooltipPlacement,
3990
3936
  tooltipPlacement = _ref$tooltipPlacement === void 0 ? 'bottom' : _ref$tooltipPlacement;
3991
- return /*#__PURE__*/React.createElement(Tooltip, {
3937
+ return /*#__PURE__*/React.createElement(CustomTooltip, {
3992
3938
  title: "Editor: ".concat(editor),
3993
3939
  placement: tooltipPlacement
3994
3940
  }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(Avatar, {
@@ -4022,7 +3968,11 @@ var TafForm = /*#__PURE__*/React__default.memo(function (_ref) {
4022
3968
  _ref$onSwitchEditor = _ref.onSwitchEditor,
4023
3969
  onSwitchEditor = _ref$onSwitchEditor === void 0 ? function () {
4024
3970
  return null;
4025
- } : _ref$onSwitchEditor;
3971
+ } : _ref$onSwitchEditor,
3972
+ _ref$fetchNewTafList = _ref.fetchNewTafList,
3973
+ fetchNewTafList = _ref$fetchNewTafList === void 0 ? function () {
3974
+ return null;
3975
+ } : _ref$fetchNewTafList;
4026
3976
  var originalTaf = tafFromBackend.taf,
4027
3977
  editor = tafFromBackend.editor;
4028
3978
 
@@ -4141,42 +4091,64 @@ var TafForm = /*#__PURE__*/React__default.memo(function (_ref) {
4141
4091
  }));
4142
4092
  }, [dispatch]);
4143
4093
 
4094
+ var isLatestEditor = function isLatestEditor(latestEditor, userName) {
4095
+ return latestEditor !== '' && latestEditor !== null && latestEditor !== userName;
4096
+ };
4097
+
4144
4098
  var setIsEditor = function setIsEditor(checked) {
4145
4099
  return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
4146
- var editor, didSucceed;
4100
+ var username, latestList, _latestList$find, latestEditor, didSucceed;
4101
+
4147
4102
  return regeneratorRuntime.wrap(function _callee$(_context) {
4148
4103
  while (1) {
4149
4104
  switch (_context.prev = _context.next) {
4150
4105
  case 0:
4151
- editor = checked ? auth === null || auth === void 0 ? void 0 : auth.username : '';
4106
+ username = checked ? auth === null || auth === void 0 ? void 0 : auth.username : ''; // make sure to get the latest changes
4107
+
4108
+ _context.next = 3;
4109
+ return fetchNewTafList();
4152
4110
 
4153
- if (!(editor === tafFromBackend.editor)) {
4154
- _context.next = 3;
4111
+ case 3:
4112
+ latestList = _context.sent;
4113
+ _latestList$find = latestList.find(function (taf) {
4114
+ return taf.taf.uuid === originalTaf.uuid;
4115
+ }), latestEditor = _latestList$find.editor;
4116
+
4117
+ if (!(username === latestEditor)) {
4118
+ _context.next = 7;
4155
4119
  break;
4156
4120
  }
4157
4121
 
4158
4122
  return _context.abrupt("return", true);
4159
4123
 
4160
- case 3:
4161
- if (!(tafFromBackend.editor !== '' && tafFromBackend.editor !== null && tafFromBackend.editor !== (auth === null || auth === void 0 ? void 0 : auth.username))) {
4162
- _context.next = 6;
4124
+ case 7:
4125
+ if (!(!checked && isLatestEditor(latestEditor, auth === null || auth === void 0 ? void 0 : auth.username))) {
4126
+ _context.next = 9;
4127
+ break;
4128
+ }
4129
+
4130
+ return _context.abrupt("return", true);
4131
+
4132
+ case 9:
4133
+ if (!(checked && isLatestEditor(latestEditor, auth === null || auth === void 0 ? void 0 : auth.username))) {
4134
+ _context.next = 12;
4163
4135
  break;
4164
4136
  }
4165
4137
 
4166
- _context.next = 6;
4138
+ _context.next = 12;
4167
4139
  return confirmDialog({
4168
4140
  title: 'Switch to editor mode',
4169
4141
  description: 'This TAF is already in edit mode and important information could get lost in the switching process.',
4170
4142
  confirmLabel: 'Edit mode'
4171
4143
  });
4172
4144
 
4173
- case 6:
4174
- _context.next = 8;
4145
+ case 12:
4146
+ _context.next = 14;
4175
4147
  return onSwitchEditor(Object.assign(Object.assign({}, tafFromBackend), {
4176
- editor: editor
4148
+ editor: username
4177
4149
  }));
4178
4150
 
4179
- case 8:
4151
+ case 14:
4180
4152
  didSucceed = _context.sent;
4181
4153
 
4182
4154
  if (didSucceed) {
@@ -4185,7 +4157,7 @@ var TafForm = /*#__PURE__*/React__default.memo(function (_ref) {
4185
4157
 
4186
4158
  return _context.abrupt("return", didSucceed);
4187
4159
 
4188
- case 11:
4160
+ case 17:
4189
4161
  case "end":
4190
4162
  return _context.stop();
4191
4163
  }
@@ -4728,8 +4700,8 @@ var sortTafsOnIssueDate = function sortTafsOnIssueDate() {
4728
4700
  return _toConsumableArray(tafList).sort(function (_ref3, _ref4) {
4729
4701
  var tafA = _ref3.taf;
4730
4702
  var tafB = _ref4.taf;
4731
- if (tafA.issueDate < tafB.issueDate || tafA.issueDate && !tafB.issueDate) return -1;
4732
- return 1;
4703
+ if (tafA.issueDate < tafB.issueDate || tafA.issueDate && !tafB.issueDate) return 1;
4704
+ return -1;
4733
4705
  });
4734
4706
  };
4735
4707
  var getBaseTime = function getBaseTime(baseTime, location) {
@@ -4844,7 +4816,7 @@ var getNewTafLocationIndex = function getNewTafLocationIndex(tafLocations, previ
4844
4816
  var IconWithTooltip = function IconWithTooltip(_ref) {
4845
4817
  var title = _ref.title,
4846
4818
  children = _ref.children;
4847
- return /*#__PURE__*/React.createElement(Tooltip, {
4819
+ return /*#__PURE__*/React.createElement(CustomTooltip, {
4848
4820
  title: title,
4849
4821
  placement: "right"
4850
4822
  }, /*#__PURE__*/React.createElement(Box, {
@@ -4932,7 +4904,7 @@ var TOOLTIP_TITLE = 'Import TAC';
4932
4904
  var ExportButton = function ExportButton(_ref) {
4933
4905
  var onClick = _ref.onClick,
4934
4906
  isHidden = _ref.isHidden;
4935
- return isHidden ? null : /*#__PURE__*/React__default.createElement(Tooltip, {
4907
+ return isHidden ? null : /*#__PURE__*/React__default.createElement(CustomTooltip, {
4936
4908
  title: TOOLTIP_TITLE,
4937
4909
  placement: "left"
4938
4910
  }, /*#__PURE__*/React__default.createElement(ToolButton, {
@@ -5647,7 +5619,11 @@ var TafPanel = function TafPanel(_ref) {
5647
5619
  setIsFormDisabled = _ref$setIsFormDisable === void 0 ? function () {
5648
5620
  return null;
5649
5621
  } : _ref$setIsFormDisable,
5650
- error = _ref.error;
5622
+ error = _ref.error,
5623
+ _ref$fetchNewTafList = _ref.fetchNewTafList,
5624
+ fetchNewTafList = _ref$fetchNewTafList === void 0 ? function () {
5625
+ return null;
5626
+ } : _ref$fetchNewTafList;
5651
5627
  var severity = isWarning(error) ? 'warning' : 'error';
5652
5628
 
5653
5629
  var onTafAction = function onTafAction(action, taf) {
@@ -5729,7 +5705,8 @@ var TafPanel = function TafPanel(_ref) {
5729
5705
  setIsIssuesPaneOpen: setIsIssuesPaneOpen,
5730
5706
  isDisabled: isFormDisabled,
5731
5707
  setIsDisabled: setIsFormDisabled,
5732
- onSwitchEditor: patchTaf
5708
+ onSwitchEditor: patchTaf,
5709
+ fetchNewTafList: fetchNewTafList
5733
5710
  })));
5734
5711
  };
5735
5712
 
@@ -5799,7 +5776,7 @@ var LastUpdateTime = function LastUpdateTime(_ref) {
5799
5776
  letterSpacing: '0.33px'
5800
5777
  },
5801
5778
  "data-testid": "lastupdated-time"
5802
- }, getLastUpdateTitle(lastUpdateTime)), /*#__PURE__*/React__default.createElement(Tooltip, {
5779
+ }, getLastUpdateTitle(lastUpdateTime)), /*#__PURE__*/React__default.createElement(CustomTooltip, {
5803
5780
  title: "Click to refresh"
5804
5781
  }, /*#__PURE__*/React__default.createElement(ToolButton, {
5805
5782
  "data-testid": "updateTafBtn",
@@ -5866,7 +5843,9 @@ var TafLayout = function TafLayout(_ref2) {
5866
5843
  var _ref2$tafList = _ref2.tafList,
5867
5844
  tafList = _ref2$tafList === void 0 ? [] : _ref2$tafList,
5868
5845
  _ref2$onUpdateTaf = _ref2.onUpdateTaf,
5869
- onUpdateTaf = _ref2$onUpdateTaf === void 0 ? function () {} : _ref2$onUpdateTaf,
5846
+ onUpdateTaf = _ref2$onUpdateTaf === void 0 ? function () {
5847
+ return null;
5848
+ } : _ref2$onUpdateTaf,
5870
5849
  lastUpdateTime = _ref2.lastUpdateTime;
5871
5850
 
5872
5851
  var _useApiContext = useApiContext(),
@@ -6203,7 +6182,8 @@ var TafLayout = function TafLayout(_ref2) {
6203
6182
  postTaf: postTaf,
6204
6183
  patchTaf: patchTaf,
6205
6184
  isLoading: isLoading,
6206
- error: error
6185
+ error: error,
6186
+ fetchNewTafList: onUpdateTaf
6207
6187
  });
6208
6188
  }))), /*#__PURE__*/React__default.createElement(Grid, {
6209
6189
  item: true,
@@ -6289,26 +6269,39 @@ var TafModule = function TafModule() {
6289
6269
  setTafList(result.data);
6290
6270
  setIsLoading(false);
6291
6271
  setLastUpdateTime(getCurrentDate());
6292
- _context.next = 15;
6293
- break;
6272
+ return _context.abrupt("return", result.data);
6294
6273
 
6295
- case 11:
6296
- _context.prev = 11;
6274
+ case 12:
6275
+ _context.prev = 12;
6297
6276
  _context.t0 = _context["catch"](2);
6298
6277
  setError(_context.t0);
6299
6278
  setIsLoading(false);
6279
+ return _context.abrupt("return", []);
6300
6280
 
6301
- case 15:
6281
+ case 17:
6302
6282
  case "end":
6303
6283
  return _context.stop();
6304
6284
  }
6305
6285
  }
6306
- }, _callee, null, [[2, 11]]);
6286
+ }, _callee, null, [[2, 12]]);
6307
6287
  }));
6308
6288
  };
6309
6289
 
6310
6290
  var onUpdateTaf = function onUpdateTaf() {
6311
- fetchNewTafList();
6291
+ return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
6292
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
6293
+ while (1) {
6294
+ switch (_context2.prev = _context2.next) {
6295
+ case 0:
6296
+ return _context2.abrupt("return", fetchNewTafList());
6297
+
6298
+ case 1:
6299
+ case "end":
6300
+ return _context2.stop();
6301
+ }
6302
+ }
6303
+ }, _callee2);
6304
+ }));
6312
6305
  };
6313
6306
 
6314
6307
  React.useEffect(function () {
@@ -7016,7 +7009,7 @@ var fakePublishedTaf = {
7016
7009
  direction: 10,
7017
7010
  speed: 10,
7018
7011
  unit: 'KT',
7019
- gust: 35
7012
+ gust: 15
7020
7013
  },
7021
7014
  cloud: {
7022
7015
  cloud1: {
package/index.umd.js CHANGED
@@ -1358,11 +1358,10 @@
1358
1358
  var invalidWindSpeedMessage = 'Invalid wind speed, expected a speed equal to 2 digits or P99';
1359
1359
  var invalidWindGustsMessage = 'Invalid wind gusts, expected gusts equal to 2 digits or P99';
1360
1360
  var invalidWindGustSpeedCombinationMessage = 'Invalid wind gusts, gusts must at least be 10 knots greater than the wind speed';
1361
- var invalidWindGustSpeedBelow15Message = 'Invalid wind gusts, gusts are only allowed for a minimum wind speed of 15 knots';
1362
1361
  var invalidGustForWindP99Message = 'Invalid wind speed and gust combination, if wind is P99, gusts can only be empty or P99';
1363
1362
  var invalidWindSpeedForDirectionZeroMessage = 'Invalid wind speed, if direction is 000, speed can only be 00';
1364
1363
  var invalidWindSpeedForDirectionNonZeroMessage = 'Invalid wind speed, if direction is not 000, speed can not be 00';
1365
- var invalidWindVRBWindDirectionMessage = 'Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 4 or in combination with gusts and showers'; // validations
1364
+ var invalidWindVRBWindDirectionMessage = 'Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 3 or in combination with gusts and showers'; // validations
1366
1365
 
1367
1366
  var validateDirection = function validateDirection(value) {
1368
1367
  // if not a number
@@ -1419,8 +1418,8 @@
1419
1418
  return invalidWindSpeedForDirectionNonZeroMessage;
1420
1419
  }
1421
1420
 
1422
- if (direction === 'VRB' && (speed === 'P99' || parseInt(speed, 10) > 3)) {
1423
- // Only allow VRB for speeds smaller than 4 or in combination with gusts and showers (SH, TS, SQ)
1421
+ if (direction === 'VRB' && (speed === 'P99' || parseInt(speed, 10) > 2)) {
1422
+ // Only allow VRB for speeds smaller than 3 or in combination with gusts and showers (SH, TS, SQ)
1424
1423
  var allowedWeatherPhenom = ['SH', 'TS', 'SQ'];
1425
1424
  if (gust === '' || !allowedWeatherPhenom.some(function (allowedPhenom) {
1426
1425
  return weather1Value.includes(allowedPhenom);
@@ -1440,10 +1439,6 @@
1440
1439
  return invalidGustForWindP99Message;
1441
1440
  }
1442
1441
 
1443
- if (parseInt(speed, 10) < 15) {
1444
- return invalidWindGustSpeedBelow15Message;
1445
- }
1446
-
1447
1442
  if (gust !== 'P99' && parseInt(gust, 10) - parseInt(speed, 10) < 10) {
1448
1443
  return invalidWindGustSpeedCombinationMessage;
1449
1444
  }
@@ -3563,14 +3558,10 @@
3563
3558
  * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3564
3559
  * Copyright 2022 - Finnish Meteorological Institute (FMI)
3565
3560
  * */
3566
- var getCustomError = function getCustomError(error) {
3567
- var name = error.ref.name;
3568
- var isChangeGroup = name.includes('changeGroups');
3569
- var matchRowNumber = name.match(/\[(.*?)\]/);
3570
- var row = matchRowNumber ? parseInt(matchRowNumber[1], 10) : null;
3561
+ var getCustomError = function getCustomError(error, isChangeGroup, rowIndex) {
3571
3562
  return __assign(__assign({}, error), {
3572
3563
  isChangeGroup: isChangeGroup,
3573
- row: row
3564
+ rowIndex: rowIndex
3574
3565
  });
3575
3566
  };
3576
3567
  var getIssuesLabel = function getIssuesLabel(sumOfErrors) {
@@ -3585,33 +3576,39 @@
3585
3576
  return sumOfErrors + " issues";
3586
3577
  }
3587
3578
  };
3579
+ var getErrorValues = function getErrorValues(fieldErrors, isChangeGroup, rowIndex) {
3580
+ if (isChangeGroup === void 0) {
3581
+ isChangeGroup = false;
3582
+ }
3583
+
3584
+ if (rowIndex === void 0) {
3585
+ rowIndex = -1;
3586
+ }
3588
3587
 
3589
- var getErrorValues = function getErrorValues(fieldErrors) {
3590
3588
  if (!fieldErrors) return [];
3591
3589
  return Object.keys(fieldErrors).reduce(function (list, key) {
3592
3590
  var error = __assign({}, fieldErrors[key]);
3593
3591
 
3594
3592
  if (error.ref) {
3595
- return list.concat(getCustomError(error));
3593
+ return list.concat(getCustomError(error, isChangeGroup, rowIndex));
3596
3594
  }
3597
3595
 
3598
- return list.concat(getErrorValues(error));
3596
+ return list.concat(getErrorValues(error, isChangeGroup, rowIndex));
3599
3597
  }, []);
3600
3598
  };
3601
-
3602
3599
  var filterDuplicateErrors = function filterDuplicateErrors(errors) {
3603
3600
  return errors.reduce(function (list, error) {
3604
3601
  // check on type validateRequiredSub and validateRequiredMainOptional since these are giving 'duplicates'
3605
3602
  if (error.type === 'validateRequiredSub') {
3606
3603
  var exist = list.find(function (e) {
3607
- return e.type === 'validateRequiredSub' && e.row === error.row;
3604
+ return e.type === 'validateRequiredSub' && e.rowIndex === error.rowIndex;
3608
3605
  });
3609
3606
  return exist ? list : list.concat(error);
3610
3607
  }
3611
3608
 
3612
3609
  if (error.type === 'validateRequiredMainOptional') {
3613
3610
  var exist = list.find(function (e) {
3614
- return e.type === 'validateRequiredMainOptional' && e.row === error.row;
3611
+ return e.type === 'validateRequiredMainOptional' && e.rowIndex === error.rowIndex;
3615
3612
  });
3616
3613
  return exist ? list : list.concat(error);
3617
3614
  }
@@ -3621,16 +3618,17 @@
3621
3618
  };
3622
3619
  var getErrors = function getErrors(errors) {
3623
3620
  var errorList = Object.keys(errors).reduce(function (list, key) {
3624
- var errorValue = errors[key];
3621
+ var errorValue = errors[key]; // changeGroups
3625
3622
 
3626
3623
  if (Array.isArray(errorValue)) {
3627
- var errorValues = errorValue.reduce(function (l, i) {
3628
- return l.concat(getErrorValues(i));
3624
+ var errorValues = errorValue.reduce(function (changeGroupErrors, changeGroupError, index) {
3625
+ return changeGroupErrors.concat(getErrorValues(changeGroupError, true, index));
3629
3626
  }, []);
3630
3627
  return list.concat.apply(list, __spreadArray([], __read(errorValues)));
3631
- }
3628
+ } // baseForecast
3629
+
3632
3630
 
3633
- return list.concat(getErrorValues(errorValue));
3631
+ return list.concat(getErrorValues(errorValue, false, -1));
3634
3632
  }, []);
3635
3633
  return errorList;
3636
3634
  };
@@ -3688,7 +3686,7 @@
3688
3686
  toggleIssuesPane(newPosition);
3689
3687
  };
3690
3688
 
3691
- return /*#__PURE__*/React__namespace.createElement(material.Tooltip, {
3689
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3692
3690
  title: "View details"
3693
3691
  }, /*#__PURE__*/React__namespace.createElement(material.Chip, {
3694
3692
  "data-testid": "issuesButton",
@@ -3724,41 +3722,18 @@
3724
3722
  }
3725
3723
  };
3726
3724
 
3727
- var capitalizeWord = function capitalizeWord(_a) {
3728
- var _b = __read(_a),
3729
- firstLetter = _b[0],
3730
- restOfWord = _b.slice(1);
3731
-
3732
- return firstLetter.toUpperCase() + restOfWord.join('');
3733
- };
3734
- var humanizeErrorMessage = function humanizeErrorMessage(nameAsString) {
3735
- var nameWithoutBrackets = nameAsString.replace(/[[\]']+/g, '');
3736
- var nameLowerCase = nameWithoutBrackets.toLowerCase();
3737
-
3738
- var _a = __read(nameLowerCase.split(/([0-9]+)/) // split num bers from field and build array
3739
- .filter(function (s) {
3740
- return s.length;
3741
- }), 2),
3742
- fieldName = _a[0],
3743
- fieldNumberedValue = _a[1];
3744
-
3745
- var nameCapitalized = capitalizeWord(fieldName);
3746
-
3747
- if (fieldNumberedValue) {
3725
+ var humanizeErrorMessage = function humanizeErrorMessage(errorTitle, fieldNumberedValue) {
3726
+ if (fieldNumberedValue !== undefined && fieldNumberedValue >= 0) {
3748
3727
  // when name contains a number we assume it's a formgroup and we add a index +1 for human readability
3749
- var fieldNumber = parseInt(fieldNumberedValue, 10) + 1;
3750
- return nameCapitalized + " " + fieldNumber;
3728
+ var fieldNumber = fieldNumberedValue + 1;
3729
+ return errorTitle + " " + fieldNumber;
3751
3730
  }
3752
3731
 
3753
- return nameCapitalized;
3732
+ return errorTitle;
3754
3733
  };
3755
3734
  var getErrorMessage = function getErrorMessage(error, index) {
3756
- var name = error.ref.name;
3757
-
3758
- var _a = __read(name.split('.'), 1),
3759
- firstNamePart = _a[0];
3760
-
3761
- var fieldErrorTitle = humanizeErrorMessage(firstNamePart);
3735
+ var errorTitleCategory = error.isChangeGroup ? 'Changegroups' : 'Baseforecast';
3736
+ var fieldErrorTitle = humanizeErrorMessage(errorTitleCategory, error.rowIndex);
3762
3737
  return index + 1 + ". " + fieldErrorTitle + ": " + error.message;
3763
3738
  };
3764
3739
  var MODAL_DIALOG_ELEMENT = 'modal-dialog';
@@ -3926,7 +3901,7 @@
3926
3901
  };
3927
3902
 
3928
3903
  var SwitchButton = function SwitchButton(props) {
3929
- return /*#__PURE__*/React__namespace.createElement(material.Tooltip, {
3904
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3930
3905
  title: "Switch mode"
3931
3906
  }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(material.FormLabel, {
3932
3907
  sx: styles.label
@@ -3937,28 +3912,11 @@
3937
3912
  }, "Editor")));
3938
3913
  };
3939
3914
 
3940
- /* *
3941
- * Licensed under the Apache License, Version 2.0 (the "License");
3942
- * you may not use this file except in compliance with the License.
3943
- * You may obtain a copy of the License at
3944
- *
3945
- * http://www.apache.org/licenses/LICENSE-2.0
3946
- *
3947
- * Unless required by applicable law or agreed to in writing, software
3948
- * distributed under the License is distributed on an "AS IS" BASIS,
3949
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3950
- * See the License for the specific language governing permissions and
3951
- * limitations under the License.
3952
- *
3953
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3954
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
3955
- * */
3956
-
3957
3915
  var TafAvatar = function TafAvatar(_a) {
3958
3916
  var editor = _a.editor,
3959
3917
  _b = _a.tooltipPlacement,
3960
3918
  tooltipPlacement = _b === void 0 ? 'bottom' : _b;
3961
- return /*#__PURE__*/React__namespace.createElement(material.Tooltip, {
3919
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3962
3920
  title: "Editor: " + editor,
3963
3921
  placement: tooltipPlacement
3964
3922
  }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(shared.Avatar, {
@@ -3992,7 +3950,11 @@
3992
3950
  _g = _a.onSwitchEditor,
3993
3951
  onSwitchEditor = _g === void 0 ? function () {
3994
3952
  return null;
3995
- } : _g;
3953
+ } : _g,
3954
+ _h = _a.fetchNewTafList,
3955
+ fetchNewTafList = _h === void 0 ? function () {
3956
+ return null;
3957
+ } : _h;
3996
3958
  var originalTaf = tafFromBackend.taf,
3997
3959
  editor = tafFromBackend.editor;
3998
3960
  var auth = authentication.useAuthenticationContext().auth;
@@ -4001,38 +3963,38 @@
4001
3963
  var isDefaultDisabled = getIsFormDefaultDisabled(originalTaf.status);
4002
3964
  var confirmDialog = shared.useConfirmationDialog();
4003
3965
 
4004
- var _h = shared.useDraftFormHelpers(true),
4005
- toggleIsDraft = _h.toggleIsDraft,
4006
- DraftFieldHelper = _h.DraftFieldHelper;
3966
+ var _j = shared.useDraftFormHelpers(true),
3967
+ toggleIsDraft = _j.toggleIsDraft,
3968
+ DraftFieldHelper = _j.DraftFieldHelper;
4007
3969
 
4008
- var _j = useTafModuleContext(),
4009
- registerValidateForm = _j.registerValidateForm,
4010
- tafAction = _j.tafAction,
4011
- setIsFormDirty = _j.setIsFormDirty,
4012
- setTafAction = _j.setTafAction,
4013
- TAC = _j.TAC,
4014
- updateTAC = _j.updateTAC,
4015
- setTAC = _j.setTAC;
3970
+ var _k = useTafModuleContext(),
3971
+ registerValidateForm = _k.registerValidateForm,
3972
+ tafAction = _k.tafAction,
3973
+ setIsFormDirty = _k.setIsFormDirty,
3974
+ setTafAction = _k.setTafAction,
3975
+ TAC = _k.TAC,
3976
+ updateTAC = _k.updateTAC,
3977
+ setTAC = _k.setTAC;
4016
3978
 
4017
3979
  var isMounted = shared.useIsMounted().isMounted;
4018
3980
 
4019
- var _k = reactHookForm.useFormContext(),
4020
- control = _k.control,
4021
- handleSubmit = _k.handleSubmit,
4022
- trigger = _k.trigger,
4023
- formState = _k.formState,
4024
- getValues = _k.getValues,
4025
- setValue = _k.setValue,
4026
- reset = _k.reset;
3981
+ var _l = reactHookForm.useFormContext(),
3982
+ control = _l.control,
3983
+ handleSubmit = _l.handleSubmit,
3984
+ trigger = _l.trigger,
3985
+ formState = _l.formState,
3986
+ getValues = _l.getValues,
3987
+ setValue = _l.setValue,
3988
+ reset = _l.reset;
4027
3989
 
4028
3990
  var isFormDirty = formState.isDirty,
4029
3991
  errors = formState.errors;
4030
3992
  shared.usePreventBrowserClose(isFormDirty && !isDisabled);
4031
3993
  var hiddenInputFields = ['baseTime', 'issueDate', 'uuid', 'validDateStart', 'validDateEnd', 'status', 'previousId', 'previousValidDateStart', 'previousValidDateEnd'];
4032
3994
 
4033
- var _l = __read(React__default["default"].useState(getValues()), 2),
4034
- delayedFormValues = _l[0],
4035
- setDelayedFormValues = _l[1];
3995
+ var _m = __read(React__default["default"].useState(getValues()), 2),
3996
+ delayedFormValues = _m[0],
3997
+ setDelayedFormValues = _m[1];
4036
3998
 
4037
3999
  var hasErrors = Object.keys(errors).length;
4038
4000
 
@@ -4110,24 +4072,44 @@
4110
4072
  }));
4111
4073
  }, [dispatch]);
4112
4074
 
4075
+ var isLatestEditor = function isLatestEditor(latestEditor, userName) {
4076
+ return latestEditor !== '' && latestEditor !== null && latestEditor !== userName;
4077
+ };
4078
+
4113
4079
  var setIsEditor = function setIsEditor(checked) {
4114
4080
  return __awaiter(void 0, void 0, void 0, function () {
4115
- var editor, didSucceed;
4081
+ var username, latestList, latestEditor, didSucceed;
4116
4082
  return __generator(this, function (_a) {
4117
4083
  switch (_a.label) {
4118
4084
  case 0:
4119
- editor = checked ? auth === null || auth === void 0 ? void 0 : auth.username : '';
4085
+ username = checked ? auth === null || auth === void 0 ? void 0 : auth.username : '';
4086
+ return [4
4087
+ /*yield*/
4088
+ , fetchNewTafList()];
4089
+
4090
+ case 1:
4091
+ latestList = _a.sent();
4092
+ latestEditor = latestList.find(function (taf) {
4093
+ return taf.taf.uuid === originalTaf.uuid;
4094
+ }).editor;
4120
4095
 
4121
- if (editor === tafFromBackend.editor) {
4096
+ if (username === latestEditor) {
4122
4097
  // do nothing, correct editor is already set
4123
4098
  return [2
4124
4099
  /*return*/
4125
4100
  , true];
4126
4101
  }
4127
4102
 
4128
- if (!(tafFromBackend.editor !== '' && tafFromBackend.editor !== null && tafFromBackend.editor !== (auth === null || auth === void 0 ? void 0 : auth.username))) return [3
4103
+ if (!checked && isLatestEditor(latestEditor, auth === null || auth === void 0 ? void 0 : auth.username)) {
4104
+ // do nothing, someone else is editor so user will already get set to viewer mode
4105
+ return [2
4106
+ /*return*/
4107
+ , true];
4108
+ }
4109
+
4110
+ if (!(checked && isLatestEditor(latestEditor, auth === null || auth === void 0 ? void 0 : auth.username))) return [3
4129
4111
  /*break*/
4130
- , 2];
4112
+ , 3];
4131
4113
  return [4
4132
4114
  /*yield*/
4133
4115
  , confirmDialog({
@@ -4136,19 +4118,19 @@
4136
4118
  confirmLabel: 'Edit mode'
4137
4119
  })];
4138
4120
 
4139
- case 1:
4121
+ case 2:
4140
4122
  _a.sent();
4141
4123
 
4142
- _a.label = 2;
4124
+ _a.label = 3;
4143
4125
 
4144
- case 2:
4126
+ case 3:
4145
4127
  return [4
4146
4128
  /*yield*/
4147
4129
  , onSwitchEditor(__assign(__assign({}, tafFromBackend), {
4148
- editor: editor
4130
+ editor: username
4149
4131
  }))];
4150
4132
 
4151
- case 3:
4133
+ case 4:
4152
4134
  didSucceed = _a.sent();
4153
4135
 
4154
4136
  if (didSucceed) {
@@ -4300,19 +4282,19 @@
4300
4282
  }
4301
4283
  };
4302
4284
 
4303
- var _m = reactHookForm.useFieldArray({
4285
+ var _o = reactHookForm.useFieldArray({
4304
4286
  control: control,
4305
4287
  name: 'changeGroups'
4306
4288
  }),
4307
- fields = _m.fields,
4308
- insert = _m.insert,
4309
- remove = _m.remove,
4310
- move = _m.move;
4289
+ fields = _o.fields,
4290
+ insert = _o.insert,
4291
+ remove = _o.remove,
4292
+ move = _o.move;
4311
4293
 
4312
- var _o = useDragOrder(trigger, move, onFormBlur),
4313
- onChangeOrder = _o.onChangeOrder,
4314
- onStartDrag = _o.onStartDrag,
4315
- activeDraggingIndex = _o.activeDraggingIndex;
4294
+ var _p = useDragOrder(trigger, move, onFormBlur),
4295
+ onChangeOrder = _p.onChangeOrder,
4296
+ onStartDrag = _p.onStartDrag,
4297
+ activeDraggingIndex = _p.activeDraggingIndex;
4316
4298
 
4317
4299
  var onRemoverow = function onRemoverow(index) {
4318
4300
  confirmDialog({
@@ -4393,9 +4375,9 @@
4393
4375
  });
4394
4376
  };
4395
4377
 
4396
- var _p = __read(React__default["default"].useState(false), 2),
4397
- shouldValidate = _p[0],
4398
- setShouldValidate = _p[1];
4378
+ var _q = __read(React__default["default"].useState(false), 2),
4379
+ shouldValidate = _q[0],
4380
+ setShouldValidate = _q[1];
4399
4381
 
4400
4382
  React__default["default"].useEffect(function () {
4401
4383
  setIsDisabled(!isEditor || isDefaultDisabled);
@@ -4706,8 +4688,8 @@
4706
4688
  return __spreadArray([], __read(tafList)).sort(function (_a, _b) {
4707
4689
  var tafA = _a.taf;
4708
4690
  var tafB = _b.taf;
4709
- if (tafA.issueDate < tafB.issueDate || tafA.issueDate && !tafB.issueDate) return -1;
4710
- return 1;
4691
+ if (tafA.issueDate < tafB.issueDate || tafA.issueDate && !tafB.issueDate) return 1;
4692
+ return -1;
4711
4693
  });
4712
4694
  };
4713
4695
  var getBaseTime = function getBaseTime(baseTime, location) {
@@ -4822,7 +4804,7 @@
4822
4804
  var IconWithTooltip = function IconWithTooltip(_a) {
4823
4805
  var title = _a.title,
4824
4806
  children = _a.children;
4825
- return /*#__PURE__*/React__namespace.createElement(material.Tooltip, {
4807
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
4826
4808
  title: title,
4827
4809
  placement: "right"
4828
4810
  }, /*#__PURE__*/React__namespace.createElement(material.Box, {
@@ -4910,7 +4892,7 @@
4910
4892
  var ExportButton = function ExportButton(_a) {
4911
4893
  var onClick = _a.onClick,
4912
4894
  isHidden = _a.isHidden;
4913
- return isHidden ? null : /*#__PURE__*/React__default["default"].createElement(material.Tooltip, {
4895
+ return isHidden ? null : /*#__PURE__*/React__default["default"].createElement(shared.CustomTooltip, {
4914
4896
  title: TOOLTIP_TITLE,
4915
4897
  placement: "left"
4916
4898
  }, /*#__PURE__*/React__default["default"].createElement(shared.ToolButton, {
@@ -5594,7 +5576,11 @@
5594
5576
  setIsFormDisabled = _h === void 0 ? function () {
5595
5577
  return null;
5596
5578
  } : _h,
5597
- error = _a.error;
5579
+ error = _a.error,
5580
+ _j = _a.fetchNewTafList,
5581
+ fetchNewTafList = _j === void 0 ? function () {
5582
+ return null;
5583
+ } : _j;
5598
5584
  var severity = isWarning(error) ? 'warning' : 'error';
5599
5585
 
5600
5586
  var onTafAction = function onTafAction(action, taf) {
@@ -5728,7 +5714,8 @@
5728
5714
  setIsIssuesPaneOpen: setIsIssuesPaneOpen,
5729
5715
  isDisabled: isFormDisabled,
5730
5716
  setIsDisabled: setIsFormDisabled,
5731
- onSwitchEditor: patchTaf
5717
+ onSwitchEditor: patchTaf,
5718
+ fetchNewTafList: fetchNewTafList
5732
5719
  })));
5733
5720
  };
5734
5721
 
@@ -5779,7 +5766,7 @@
5779
5766
  letterSpacing: '0.33px'
5780
5767
  },
5781
5768
  "data-testid": "lastupdated-time"
5782
- }, getLastUpdateTitle(lastUpdateTime)), /*#__PURE__*/React__default["default"].createElement(material.Tooltip, {
5769
+ }, getLastUpdateTitle(lastUpdateTime)), /*#__PURE__*/React__default["default"].createElement(shared.CustomTooltip, {
5783
5770
  title: "Click to refresh"
5784
5771
  }, /*#__PURE__*/React__default["default"].createElement(shared.ToolButton, {
5785
5772
  "data-testid": "updateTafBtn",
@@ -5849,7 +5836,9 @@
5849
5836
  var _b = _a.tafList,
5850
5837
  tafList = _b === void 0 ? [] : _b,
5851
5838
  _c = _a.onUpdateTaf,
5852
- onUpdateTaf = _c === void 0 ? function () {} : _c,
5839
+ onUpdateTaf = _c === void 0 ? function () {
5840
+ return null;
5841
+ } : _c,
5853
5842
  lastUpdateTime = _a.lastUpdateTime;
5854
5843
  var api$1 = api.useApiContext().api;
5855
5844
  var dispatch = reactRedux.useDispatch();
@@ -6199,7 +6188,8 @@
6199
6188
  postTaf: postTaf,
6200
6189
  patchTaf: patchTaf,
6201
6190
  isLoading: isLoading,
6202
- error: error
6191
+ error: error,
6192
+ fetchNewTafList: onUpdateTaf
6203
6193
  });
6204
6194
  }))), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
6205
6195
  item: true,
@@ -6284,17 +6274,17 @@
6284
6274
  setTafList(result.data);
6285
6275
  setIsLoading(false);
6286
6276
  setLastUpdateTime(getCurrentDate());
6287
- return [3
6288
- /*break*/
6289
- , 4];
6277
+ return [2
6278
+ /*return*/
6279
+ , result.data];
6290
6280
 
6291
6281
  case 3:
6292
6282
  error_1 = _a.sent();
6293
6283
  setError(error_1);
6294
6284
  setIsLoading(false);
6295
- return [3
6296
- /*break*/
6297
- , 4];
6285
+ return [2
6286
+ /*return*/
6287
+ , []];
6298
6288
 
6299
6289
  case 4:
6300
6290
  return [2
@@ -6306,7 +6296,13 @@
6306
6296
  };
6307
6297
 
6308
6298
  var onUpdateTaf = function onUpdateTaf() {
6309
- fetchNewTafList();
6299
+ return __awaiter(void 0, void 0, void 0, function () {
6300
+ return __generator(this, function (_a) {
6301
+ return [2
6302
+ /*return*/
6303
+ , fetchNewTafList()];
6304
+ });
6305
+ });
6310
6306
  };
6311
6307
 
6312
6308
  React__namespace.useEffect(function () {
@@ -6994,7 +6990,7 @@
6994
6990
  direction: 10,
6995
6991
  speed: 10,
6996
6992
  unit: 'KT',
6997
- gust: 35
6993
+ gust: 15
6998
6994
  },
6999
6995
  cloud: {
7000
6996
  cloud1: {
@@ -1,9 +1,7 @@
1
1
  import * as React from 'react';
2
- import { FieldError } from 'react-hook-form';
3
- import { IssuesPaneProps, IssuesPanePosition } from './types';
4
- export declare const capitalizeWord: ([firstLetter, ...restOfWord]: string) => string;
5
- export declare const humanizeErrorMessage: (nameAsString: string) => string;
6
- export declare const getErrorMessage: (error: FieldError, index: number) => string;
2
+ import { IssuesPaneProps, IssuesPanePosition, CustomErrorField } from './types';
3
+ export declare const humanizeErrorMessage: (errorTitle: string, fieldNumberedValue: number) => string;
4
+ export declare const getErrorMessage: (error: CustomErrorField, index: number) => string;
7
5
  export declare const MODAL_DIALOG_ELEMENT = "modal-dialog";
8
6
  export declare const useIssuesPane: () => {
9
7
  isIssuesPaneOpen: boolean;
@@ -3,8 +3,12 @@ export declare type IssuesPanePosition = {
3
3
  left: number;
4
4
  top: number;
5
5
  };
6
+ export interface CustomErrorField extends FieldError {
7
+ isChangeGroup: boolean;
8
+ rowIndex: number;
9
+ }
6
10
  export interface IssuesPaneProps {
7
- errorList?: FieldError[];
11
+ errorList?: CustomErrorField[];
8
12
  isOpen: boolean;
9
13
  handleClose: () => void;
10
14
  startPosition?: IssuesPanePosition;
@@ -1,10 +1,7 @@
1
- import { DeepMap, FieldError } from 'react-hook-form';
2
- interface CustomErrorField extends FieldError {
3
- isChangeGroup: boolean;
4
- row: number;
5
- }
6
- export declare const getCustomError: (error: FieldError) => CustomErrorField;
1
+ import { FieldError } from 'react-hook-form';
2
+ import { CustomErrorField } from './types';
3
+ export declare const getCustomError: (error: FieldError, isChangeGroup: boolean, rowIndex: number) => CustomErrorField;
7
4
  export declare const getIssuesLabel: (sumOfErrors: number) => string;
5
+ export declare const getErrorValues: (fieldErrors: FieldError, isChangeGroup?: boolean, rowIndex?: number) => FieldError[];
8
6
  export declare const filterDuplicateErrors: (errors: CustomErrorField[]) => CustomErrorField[];
9
- export declare const getErrors: (errors: DeepMap<Record<string, unknown>, FieldError>) => CustomErrorField[];
10
- export {};
7
+ export declare const getErrors: (errors: Record<string, FieldError>) => CustomErrorField[];
@@ -10,6 +10,7 @@ export interface TafFormProps {
10
10
  isIssuesPaneOpen?: boolean;
11
11
  setIsIssuesPaneOpen?: (isOpen: boolean, position?: IssuesPanePosition) => void;
12
12
  onSwitchEditor?: (formValues: TafFromFrontEnd) => Promise<boolean>;
13
+ fetchNewTafList?: () => Promise<TafFromBackend[]>;
13
14
  }
14
15
  declare const TafForm: React.FC<TafFormProps>;
15
16
  export default TafForm;
@@ -9,9 +9,8 @@ export declare const invalidWindDirectionStepMessage = "Invalid wind direction,
9
9
  export declare const invalidWindSpeedMessage = "Invalid wind speed, expected a speed equal to 2 digits or P99";
10
10
  export declare const invalidWindGustsMessage = "Invalid wind gusts, expected gusts equal to 2 digits or P99";
11
11
  export declare const invalidWindGustSpeedCombinationMessage = "Invalid wind gusts, gusts must at least be 10 knots greater than the wind speed";
12
- export declare const invalidWindGustSpeedBelow15Message = "Invalid wind gusts, gusts are only allowed for a minimum wind speed of 15 knots";
13
12
  export declare const invalidGustForWindP99Message = "Invalid wind speed and gust combination, if wind is P99, gusts can only be empty or P99";
14
13
  export declare const invalidWindSpeedForDirectionZeroMessage = "Invalid wind speed, if direction is 000, speed can only be 00";
15
14
  export declare const invalidWindSpeedForDirectionNonZeroMessage = "Invalid wind speed, if direction is not 000, speed can not be 00";
16
- export declare const invalidWindVRBWindDirectionMessage = "Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 4 or in combination with gusts and showers";
15
+ export declare const invalidWindVRBWindDirectionMessage = "Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 3 or in combination with gusts and showers";
17
16
  export declare const validateWindField: (value: string, weatherfield1: string, weatherfield2: string, weatherfield3: string) => boolean | string;
@@ -9,7 +9,7 @@ export declare const getTafMessagePrefix: ({ location, validDateStart, messageTy
9
9
  export declare const getSnackbarMessage: (tafFromFrontEnd: TafFromFrontEnd, isAutoSaved?: boolean) => string;
10
10
  interface TafLayoutProps {
11
11
  tafList: TafFromBackend[];
12
- onUpdateTaf: () => void;
12
+ onUpdateTaf: () => Promise<TafFromBackend[]>;
13
13
  lastUpdateTime?: string;
14
14
  }
15
15
  declare const TafLayout: React.FC<TafLayoutProps>;
@@ -21,6 +21,7 @@ interface TafPanelProps {
21
21
  isFormDisabled?: boolean;
22
22
  setIsFormDisabled?: (isDisabled: boolean) => void;
23
23
  error?: TafError;
24
+ fetchNewTafList?: () => Promise<TafFromBackend[]>;
24
25
  }
25
26
  export declare const isWarning: (error: TafError) => boolean;
26
27
  export declare const usePostTafRequest: (request: (params?: unknown) => Promise<void>, errorParser?: (error: AxiosError | Error, params: TafFromFrontEnd) => TafError) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/taf",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "GeoWeb TAF library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -12,24 +12,24 @@
12
12
  "typings": "./index.d.ts",
13
13
  "dependencies": {},
14
14
  "peerDependencies": {
15
- "@opengeoweb/core": "4.4.0",
15
+ "@opengeoweb/core": "4.6.0",
16
16
  "react": "^17.0.2",
17
- "@opengeoweb/theme": "4.4.0",
17
+ "@opengeoweb/theme": "4.6.0",
18
18
  "@mui/material": "^5.10.8",
19
19
  "moment": "^2.29.0",
20
20
  "react-redux": "^8.0.4",
21
21
  "react-intl": "^5.17.5",
22
- "lodash": "^4.17.20",
23
- "@opengeoweb/shared": "4.4.0",
22
+ "@opengeoweb/shared": "4.6.0",
24
23
  "react-draggable": "^4.4.5",
25
24
  "re-resizable": "^6.9.0",
26
25
  "@redux-eggs/core": "^2.2.0",
27
- "@opengeoweb/form-fields": "4.4.0",
26
+ "@opengeoweb/form-fields": "4.6.0",
28
27
  "react-hook-form": "^6.12.1",
29
28
  "moment-timezone": "^0.5.31",
30
29
  "@mui/x-date-pickers": "^5.0.4",
30
+ "lodash": "^4.17.20",
31
31
  "axios": "^0.25.0",
32
- "@opengeoweb/webmap": "4.4.0",
32
+ "@opengeoweb/webmap": "4.6.0",
33
33
  "throttle-debounce": "^3.0.1",
34
34
  "proj4": "^2.6.2",
35
35
  "react-sortablejs": "^6.1.4",
@@ -43,9 +43,9 @@
43
43
  "redux-saga": "^1.2.1",
44
44
  "@redux-eggs/redux-toolkit": "^2.2.0",
45
45
  "@redux-eggs/saga-extension": "^2.2.0",
46
- "@opengeoweb/api": "4.4.0",
46
+ "@opengeoweb/api": "4.6.0",
47
47
  "react-dom": "^17.0.2",
48
- "@opengeoweb/authentication": "4.4.0",
48
+ "@opengeoweb/authentication": "4.6.0",
49
49
  "react-router-dom": "^6.4.2",
50
50
  "query-string": "^6.13.7"
51
51
  }