@opengeoweb/taf 4.11.0 → 4.12.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.umd.js CHANGED
@@ -135,6 +135,158 @@
135
135
  return to.concat(ar || Array.prototype.slice.call(from));
136
136
  }
137
137
 
138
+ /* *
139
+ * Licensed under the Apache License, Version 2.0 (the "License");
140
+ * you may not use this file except in compliance with the License.
141
+ * You may obtain a copy of the License at
142
+ *
143
+ * http://www.apache.org/licenses/LICENSE-2.0
144
+ *
145
+ * Unless required by applicable law or agreed to in writing, software
146
+ * distributed under the License is distributed on an "AS IS" BASIS,
147
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148
+ * See the License for the specific language governing permissions and
149
+ * limitations under the License.
150
+ *
151
+ * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
152
+ * Copyright 2021 - Finnish Meteorological Institute (FMI)
153
+ * */
154
+ var tafActionToDraftAction = function tafActionToDraftAction(tafAction) {
155
+ switch (tafAction) {
156
+ case 'AMEND':
157
+ case 'DRAFT_AMEND':
158
+ return 'DRAFT_AMEND';
159
+
160
+ case 'CORRECT':
161
+ case 'DRAFT_CORRECT':
162
+ return 'DRAFT_CORRECT';
163
+
164
+ default:
165
+ return 'DRAFT';
166
+ }
167
+ };
168
+
169
+ var tafActionToPublishAction = function tafActionToPublishAction(tafAction) {
170
+ switch (tafAction) {
171
+ case 'AMEND':
172
+ case 'DRAFT_AMEND':
173
+ return 'AMEND';
174
+
175
+ case 'CORRECT':
176
+ case 'DRAFT_CORRECT':
177
+ return 'CORRECT';
178
+
179
+ default:
180
+ return 'PUBLISH';
181
+ }
182
+ };
183
+
184
+ var buttonsStyle = {
185
+ button: {
186
+ minWidth: {
187
+ xs: '56px',
188
+ sm: '64px'
189
+ },
190
+ width: {
191
+ xs: '56px',
192
+ sm: '64px'
193
+ },
194
+ marginLeft: {
195
+ xs: 0.5,
196
+ sm: 1
197
+ },
198
+ marginTop: 3,
199
+ marginBottom: 3
200
+ }
201
+ };
202
+
203
+ var ViewModeButtons = function ViewModeButtons(_a) {
204
+ var canBe = _a.canBe,
205
+ onTafViewModeButtonPress = _a.onTafViewModeButtonPress;
206
+ return !canBe.includes('CANCELLED') && !canBe.includes('CORRECTED') && !canBe.includes('AMENDED') ? null : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, canBe.includes('CANCELLED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
207
+ "data-testid": "canceltaf",
208
+ variant: "tertiary",
209
+ onClick: function onClick() {
210
+ return onTafViewModeButtonPress('CANCEL');
211
+ }
212
+ }, "Cancel"), canBe.includes('CORRECTED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
213
+ "data-testid": "correcttaf",
214
+ variant: "tertiary",
215
+ onClick: function onClick() {
216
+ return onTafViewModeButtonPress('CORRECT');
217
+ }
218
+ }, "Correct"), canBe.includes('AMENDED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
219
+ "data-testid": "amendtaf",
220
+ variant: "tertiary",
221
+ onClick: function onClick() {
222
+ return onTafViewModeButtonPress('AMEND');
223
+ }
224
+ }, "Amend"));
225
+ };
226
+
227
+ var TafFormButtons = function TafFormButtons(_a) {
228
+ var _b = _a.isFormDisabled,
229
+ isFormDisabled = _b === void 0 ? false : _b,
230
+ tafAction = _a.tafAction,
231
+ _c = _a.canBe,
232
+ canBe = _c === void 0 ? [] : _c,
233
+ onTafEditModeButtonPress = _a.onTafEditModeButtonPress,
234
+ onTafViewModeButtonPress = _a.onTafViewModeButtonPress;
235
+ return /*#__PURE__*/React__default["default"].createElement(material.Grid, {
236
+ container: true,
237
+ justifyContent: "flex-end",
238
+ sx: buttonsStyle,
239
+ columns: 24
240
+ }, /*#__PURE__*/React__default["default"].createElement(material.Grid, {
241
+ item: true,
242
+ container: true,
243
+ justifyContent: "flex-end",
244
+ columns: 24,
245
+ xs: 24,
246
+ sm: 23
247
+ }, isFormDisabled ? /*#__PURE__*/React__default["default"].createElement(ViewModeButtons, {
248
+ canBe: canBe,
249
+ onTafViewModeButtonPress: onTafViewModeButtonPress
250
+ }) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(material.Button, {
251
+ "data-testid": "cleartaf",
252
+ variant: "tertiary",
253
+ onClick: function onClick() {
254
+ // Simply discard the changes and close the dialog.
255
+ onTafEditModeButtonPress('CLEAR');
256
+ }
257
+ }, "Clear"), /*#__PURE__*/React__default["default"].createElement(material.Button, {
258
+ "data-testid": "savedrafttaf",
259
+ variant: "tertiary",
260
+ onClick: function onClick() {
261
+ /* Save the TAF as draft:
262
+ if action NEW or DRAFT - new status will be DRAFT -- default
263
+ if action AMEND - new status will be DRAFT_AMENDED
264
+ if action CORRECT - new status will be DRAFT_CORRECTED
265
+ if action DRAFT_AMEND - new status will be DRAFT_AMENDED
266
+ if action DRAFT_CORRECT - new status will be DRAFT_CORRECTED
267
+ */
268
+ onTafEditModeButtonPress(tafActionToDraftAction(tafAction));
269
+ }
270
+ }, "Save"), /*#__PURE__*/React__default["default"].createElement(material.Button, {
271
+ "data-testid": "publishtaf",
272
+ variant: "tertiary",
273
+ onClick: function onClick() {
274
+ /* Publish the TAF:
275
+ if action NEW or DRAFT - new status will be PUBLISHED -- default
276
+ if action AMEND - new status will be AMENDED
277
+ if action CORRECT - new status will be CORRECTED
278
+ if action DRAFT_AMEND - new status will be AMENDED
279
+ if action DRAFT_CORRECT - new status will be CORRECTED
280
+ */
281
+ onTafEditModeButtonPress(tafActionToPublishAction(tafAction));
282
+ }
283
+ }, "Publish"))), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
284
+ item: true,
285
+ columns: 24,
286
+ sm: 1
287
+ }));
288
+ };
289
+
138
290
  function _typeof(obj) {
139
291
  "@babel/helpers - typeof";
140
292
 
@@ -453,8 +605,8 @@
453
605
  * See the License for the specific language governing permissions and
454
606
  * limitations under the License.
455
607
  *
456
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
457
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
608
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
609
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
458
610
  * */
459
611
 
460
612
  var prependZeroes = function prependZeroes(value, totalDigits) {
@@ -463,6 +615,9 @@
463
615
  return "0" + newVal;
464
616
  }, valueAsString);
465
617
  };
618
+ var getFieldValue = function getFieldValue(fieldValue) {
619
+ return fieldValue === null || fieldValue === void 0 ? void 0 : fieldValue.trim().toUpperCase();
620
+ };
466
621
 
467
622
  var config$1 = [{
468
623
  key: 'range',
@@ -2433,7 +2588,8 @@
2433
2588
  }; // Check if the amended/corrected TAF has been changed. Only compare the fields users are able to fill in
2434
2589
  // (i.e. exclude baseforecast valid time as that gets updated when doing an amendment automatically outside of the users influence)
2435
2590
 
2436
- var isTafAmendedCorrectedChanged = function isTafAmendedCorrectedChanged(isFormDirty, originalTaf, currentTaf) {
2591
+ var isTafAmendedCorrectedChanged = function isTafAmendedCorrectedChanged(originalTaf, currentTaf) {
2592
+ if (originalTaf === null || currentTaf === null) return false;
2437
2593
  var originalBaseF = originalTaf.baseForecast,
2438
2594
  originalChG = originalTaf.changeGroups;
2439
2595
  var currentBaseF = currentTaf.baseForecast,
@@ -2445,7 +2601,7 @@
2445
2601
  currentBaseF.valid;
2446
2602
  var currentNoValid = __rest(currentBaseF, ["valid"]);
2447
2603
 
2448
- return isFormDirty && (!lodash.isEqual(originalNoValid, currentNoValid) || !lodash.isEqual(originalChG, currentChG));
2604
+ return !lodash.isEqual(originalNoValid, currentNoValid) || !lodash.isEqual(originalChG, currentChG);
2449
2605
  };
2450
2606
  var getConfirmationDialogContent = function getConfirmationDialogContent(action, isFormDirty) {
2451
2607
  switch (action) {
@@ -2497,13 +2653,30 @@
2497
2653
  change: '',
2498
2654
  probability: ''
2499
2655
  };
2500
- var getTafStatusLabel = function getTafStatusLabel(status) {
2656
+ var getTafStatusLabel = function getTafStatusLabel(status, action, isFormDisabled) {
2657
+ // See if we need to base status label on action if form is not disabled and action passed
2658
+ var baseOnAction = isFormDisabled !== undefined && !isFormDisabled && action;
2659
+
2660
+ if (baseOnAction && action === 'AMEND' && (status === 'PUBLISHED' || status === 'AMENDED' || status === 'CORRECTED')) {
2661
+ return 'new amendment';
2662
+ }
2663
+
2664
+ if (baseOnAction && action === 'CORRECT' && (status === 'PUBLISHED' || status === 'AMENDED' || status === 'CORRECTED')) {
2665
+ return 'new correction';
2666
+ }
2667
+
2501
2668
  switch (status) {
2502
2669
  case 'DRAFT_AMENDED':
2503
- return 'draft amended';
2670
+ return 'draft amendment';
2504
2671
 
2505
2672
  case 'DRAFT_CORRECTED':
2506
- return 'draft corrected';
2673
+ return 'draft correction';
2674
+
2675
+ case 'AMENDED':
2676
+ return 'published amendment';
2677
+
2678
+ case 'CORRECTED':
2679
+ return 'published correction';
2507
2680
 
2508
2681
  default:
2509
2682
  return status.toLocaleLowerCase();
@@ -2648,191 +2821,56 @@
2648
2821
  var isFormDirty = function isFormDirty(dirtyFields) {
2649
2822
  return Object.keys(dirtyFields).length > 0;
2650
2823
  };
2824
+ var getFormRowPosition = function getFormRowPosition(formRow) {
2825
+ var _a = formRow.getBoundingClientRect(),
2826
+ top = _a.top,
2827
+ left = _a.left,
2828
+ height = _a.height;
2651
2829
 
2652
- var textFieldStyle = function textFieldStyle(theme) {
2830
+ var newTop = top + height;
2653
2831
  return {
2654
- // input
2655
- marginRight: '2px',
2656
- marginBottom: '4px',
2657
- width: 56,
2658
- height: 46,
2659
- input: {
2660
- textAlign: 'center',
2661
- fontSize: 10,
2662
- fontWeight: 500,
2663
- paddingLeft: 0,
2664
- paddingRight: 0,
2665
- '&.Mui-disabled': {
2666
- color: 'geowebColors.typographyAndIcons.text',
2667
- WebkitTextFillColor: theme.palette.geowebColors.typographyAndIcons.text
2668
- },
2669
- // TODO: https://gitlab.com/opengeoweb/opengeoweb/-/issues/1995 disables the default autofill styling, should be a better fix
2670
- '&:-webkit-autofill': {
2671
- WebkitTransitionDelay: '86400s' // 1 day delay
2832
+ top: newTop,
2833
+ left: left
2834
+ };
2835
+ };
2672
2836
 
2673
- }
2674
- },
2675
- label: {
2676
- transformOrigin: 'center top',
2677
- right: 0,
2678
- textAlign: 'center',
2679
- fontSize: '10px',
2680
- '&.Mui-disabled': {
2681
- color: 'geowebColors.captions.captionStatus.rgba'
2682
- },
2683
- whiteSpace: 'nowrap',
2684
- maxWidth: '100%',
2685
- transform: 'translate(0px, 16px) scale(1)'
2686
- },
2687
- // shrink
2688
- ' .MuiInputLabel-shrink': {
2689
- transform: 'translate(2px, 10px) scale(0.75) !important',
2690
- letterSpacing: '0.33px',
2691
- textAlign: 'left'
2692
- },
2693
- // root
2694
- '&': {
2695
- '.Mui-error.MuiFilledInput-root': {
2696
- backgroundColor: 'geowebColors.captions.captionErrorBackground.rgba'
2837
+ /* *
2838
+ * Licensed under the Apache License, Version 2.0 (the "License");
2839
+ * you may not use this file except in compliance with the License.
2840
+ * You may obtain a copy of the License at
2841
+ *
2842
+ * http://www.apache.org/licenses/LICENSE-2.0
2843
+ *
2844
+ * Unless required by applicable law or agreed to in writing, software
2845
+ * distributed under the License is distributed on an "AS IS" BASIS,
2846
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2847
+ * See the License for the specific language governing permissions and
2848
+ * limitations under the License.
2849
+ *
2850
+ * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2851
+ * Copyright 2021 - Finnish Meteorological Institute (FMI)
2852
+ * */
2853
+
2854
+ var DragHandle = function DragHandle(_a) {
2855
+ var _b = _a.isSorting,
2856
+ isSorting = _b === void 0 ? false : _b,
2857
+ _c = _a.isDisabled,
2858
+ isDisabled = _c === void 0 ? false : _c,
2859
+ index = _a.index;
2860
+ return /*#__PURE__*/React__default["default"].createElement(material.IconButton, {
2861
+ className: "handle",
2862
+ "data-testid": "dragHandle-" + index,
2863
+ disableRipple: true,
2864
+ disabled: isDisabled,
2865
+ size: "large",
2866
+ sx: {
2867
+ backgroundColor: 'transparent',
2868
+ '&:hover': {
2869
+ backgroundColor: 'transparent'
2697
2870
  },
2698
- '.Mui-disabled:before': {
2699
- borderColor: 'transparent'
2700
- }
2871
+ cursor: isSorting ? 'grabbing' : 'grab'
2701
2872
  }
2702
- };
2703
- };
2704
-
2705
- var getTafErrors = function getTafErrors(name, errors) {
2706
- var nameAsArray = name.split('.');
2707
-
2708
- if (nameAsArray[0].includes('changeGroups')) {
2709
- if (errors.changeGroups) {
2710
- var changeGroupNum = nameAsArray[0].slice(13, nameAsArray[0].length - 1);
2711
- var restArray = nameAsArray.slice(1);
2712
- return formFields.getDeepProperty(restArray, errors.changeGroups[changeGroupNum]);
2713
- } // No changegroup errors
2714
-
2715
-
2716
- return null;
2717
- }
2718
-
2719
- return formFields.getDeepProperty(nameAsArray, errors);
2720
- };
2721
-
2722
- var getDisplayValue = function getDisplayValue(value, disabled) {
2723
- return disabled && !value ? '-' : value;
2724
- };
2725
- var BaseTextField = /*#__PURE__*/React__default["default"].memo(function (props) {
2726
- return /*#__PURE__*/React__default["default"].createElement(material.TextField, __assign({
2727
- type: "text",
2728
- variant: "filled",
2729
- sx: textFieldStyle
2730
- }, props));
2731
- }, function (prevProps, nextProps) {
2732
- return prevProps.value === nextProps.value && prevProps.error === nextProps.error && prevProps.name === nextProps.name && prevProps.disabled === nextProps.disabled;
2733
- });
2734
-
2735
- var TafFormTextField = function TafFormTextField(_a) {
2736
- var label = _a.label,
2737
- _b = _a.disabled,
2738
- disabled = _b === void 0 ? false : _b,
2739
- _c = _a.name,
2740
- name = _c === void 0 ? '' : _c,
2741
- _d = _a.onChange,
2742
- onChange = _d === void 0 ? function () {} : _d,
2743
- _e = _a.onBlur,
2744
- onBlur = _e === void 0 ? function () {} : _e,
2745
- _f = _a.defaultValue,
2746
- defaultValue = _f === void 0 ? '' : _f,
2747
- _g = _a.formatter,
2748
- formatter = _g === void 0 ? null : _g,
2749
- rules = _a.rules,
2750
- _h = _a.autoComplete,
2751
- autoComplete = _h === void 0 ? [] : _h,
2752
- _j = _a.autoFocus,
2753
- autoFocus = _j === void 0 ? false : _j;
2754
-
2755
- var _k = reactHookForm.useFormContext(),
2756
- control = _k.control,
2757
- setValue = _k.setValue,
2758
- errors = _k.formState.errors;
2759
-
2760
- var fieldErrors = getTafErrors(name, errors);
2761
-
2762
- var _l = __read(React__default["default"].useState(null), 2),
2763
- maxLength = _l[0],
2764
- setMaxLength = _l[1];
2765
-
2766
- var onKeyDown = React__default["default"].useCallback(function (event) {
2767
- var target = event.target;
2768
- var currentValue = target.value,
2769
- selectionStart = target.selectionStart,
2770
- selectionEnd = target.selectionEnd;
2771
- var textSelection = currentValue.substring(selectionStart, selectionEnd);
2772
-
2773
- if (autoComplete && !currentValue.length || textSelection.length && currentValue.length && textSelection === currentValue) {
2774
- var pressedKey_1 = event.key.toString().toUpperCase();
2775
- var foundValue = autoComplete.find(function (el) {
2776
- return el.key === pressedKey_1;
2777
- }) || null;
2778
-
2779
- if (foundValue) {
2780
- setValue(name, foundValue.value, {
2781
- shouldDirty: true
2782
- });
2783
- setMaxLength(foundValue.value.length);
2784
- event.preventDefault();
2785
- }
2786
- }
2787
- }, [name, autoComplete, setValue]);
2788
- var onChangeField = React__default["default"].useCallback(function (event, callback) {
2789
- var valueUppercase = event.currentTarget.value.toUpperCase();
2790
-
2791
- if (autoComplete) {
2792
- var exist = autoComplete.find(function (e) {
2793
- return e.value === valueUppercase;
2794
- });
2795
- var newMaxLength = exist ? valueUppercase.length : null;
2796
- setMaxLength(newMaxLength);
2797
- }
2798
-
2799
- callback(valueUppercase);
2800
- onChange(valueUppercase);
2801
- }, [onChange, autoComplete]);
2802
- var onBlurField = React__default["default"].useCallback(function (callback) {
2803
- callback();
2804
- onBlur();
2805
- }, [onBlur]);
2806
- var hasError = !!fieldErrors;
2807
- return /*#__PURE__*/React__default["default"].createElement(reactHookForm.Controller, {
2808
- render: function render(_a) {
2809
- var field = _a.field;
2810
- var displayValue = formatter ? formatter(field.value) : getDisplayValue(field.value, disabled);
2811
- return /*#__PURE__*/React__default["default"].createElement(BaseTextField, {
2812
- label: label,
2813
- disabled: disabled,
2814
- name: name,
2815
- value: displayValue,
2816
- inputRef: field.ref,
2817
- onChange: function onChange(e) {
2818
- return onChangeField(e, field.onChange);
2819
- },
2820
- onKeyDown: onKeyDown,
2821
- error: hasError,
2822
- onBlur: function onBlur() {
2823
- return onBlurField(field.onBlur);
2824
- },
2825
- inputProps: {
2826
- maxLength: maxLength
2827
- },
2828
- autoFocus: autoFocus
2829
- });
2830
- },
2831
- name: name,
2832
- control: control,
2833
- defaultValue: defaultValue,
2834
- rules: rules
2835
- });
2873
+ }, /*#__PURE__*/React__default["default"].createElement(theme.DragHandle, null));
2836
2874
  };
2837
2875
 
2838
2876
  /* *
@@ -2848,27 +2886,82 @@
2848
2886
  * See the License for the specific language governing permissions and
2849
2887
  * limitations under the License.
2850
2888
  *
2851
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2852
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
2889
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2890
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
2853
2891
  * */
2854
- // messages
2855
- var invalidChangeMessage = 'Invalid Change input, only BECMG, TEMPO or FM are allowed';
2856
- var invalidChangeProbCombinationMessage = 'A probability is only allowed in combination with TEMPO or an empty Change input'; // validations
2892
+ var getCustomError = function getCustomError(error, isChangeGroup, rowIndex) {
2893
+ return __assign(__assign({}, error), {
2894
+ isChangeGroup: isChangeGroup,
2895
+ rowIndex: rowIndex
2896
+ });
2897
+ };
2898
+ var getIssuesLabel = function getIssuesLabel(sumOfErrors) {
2899
+ switch (sumOfErrors) {
2900
+ case 0:
2901
+ return '0 issues';
2857
2902
 
2858
- var validateChangeField = function validateChangeField(value) {
2859
- var trimmedValue = value.trim();
2860
- var isValid = trimmedValue === '' || trimmedValue === 'FM' || trimmedValue === 'TEMPO' || trimmedValue === 'BECMG';
2861
- return isValid ? true : invalidChangeMessage;
2903
+ case 1:
2904
+ return '1 issue';
2905
+
2906
+ default:
2907
+ return sumOfErrors + " issues";
2908
+ }
2862
2909
  };
2863
- var validateChangeFieldInterField = function validateChangeFieldInterField(value, valueProb) {
2864
- var trimmedProbValue = valueProb.trim();
2865
- var trimmedValue = value.trim();
2910
+ var getErrorValues = function getErrorValues(fieldErrors, isChangeGroup, rowIndex) {
2911
+ if (isChangeGroup === void 0) {
2912
+ isChangeGroup = false;
2913
+ }
2866
2914
 
2867
- if (trimmedProbValue !== '' && trimmedValue !== '' && trimmedValue !== 'TEMPO') {
2868
- return invalidChangeProbCombinationMessage;
2915
+ if (rowIndex === void 0) {
2916
+ rowIndex = -1;
2869
2917
  }
2870
2918
 
2871
- return true;
2919
+ if (!fieldErrors) return [];
2920
+ return Object.keys(fieldErrors).reduce(function (list, key) {
2921
+ var error = __assign({}, fieldErrors[key]);
2922
+
2923
+ if (error.ref) {
2924
+ return list.concat(getCustomError(error, isChangeGroup, rowIndex));
2925
+ }
2926
+
2927
+ return list.concat(getErrorValues(error, isChangeGroup, rowIndex));
2928
+ }, []);
2929
+ };
2930
+ var filterDuplicateErrors = function filterDuplicateErrors(errors) {
2931
+ return errors.reduce(function (list, error) {
2932
+ // check on type validateRequiredSub and validateRequiredMainOptional since these are giving 'duplicates'
2933
+ if (error.type === 'validateRequiredSub') {
2934
+ var exist = list.find(function (e) {
2935
+ return e.type === 'validateRequiredSub' && e.rowIndex === error.rowIndex;
2936
+ });
2937
+ return exist ? list : list.concat(error);
2938
+ }
2939
+
2940
+ if (error.type === 'validateRequiredMainOptional') {
2941
+ var exist = list.find(function (e) {
2942
+ return e.type === 'validateRequiredMainOptional' && e.rowIndex === error.rowIndex;
2943
+ });
2944
+ return exist ? list : list.concat(error);
2945
+ }
2946
+
2947
+ return list.concat(error);
2948
+ }, []);
2949
+ };
2950
+ var getErrors = function getErrors(errors) {
2951
+ var errorList = Object.keys(errors).reduce(function (list, key) {
2952
+ var errorValue = errors[key]; // changeGroups
2953
+
2954
+ if (Array.isArray(errorValue)) {
2955
+ var errorValues = errorValue.reduce(function (changeGroupErrors, changeGroupError, index) {
2956
+ return changeGroupErrors.concat(getErrorValues(changeGroupError, true, index));
2957
+ }, []);
2958
+ return list.concat.apply(list, __spreadArray([], __read(errorValues)));
2959
+ } // baseForecast
2960
+
2961
+
2962
+ return list.concat(getErrorValues(errorValue, false, -1));
2963
+ }, []);
2964
+ return errorList;
2872
2965
  };
2873
2966
 
2874
2967
  /* *
@@ -2887,672 +2980,475 @@
2887
2980
  * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2888
2981
  * Copyright 2021 - Finnish Meteorological Institute (FMI)
2889
2982
  * */
2890
- // messages
2891
- var invalidProbabilityMessage = 'Invalid Probability input, only PROB30 or PROB40 are allowed'; // validations
2892
2983
 
2893
- var validateProbabilityField = function validateProbabilityField(value) {
2894
- var trimmedValue = value.trim();
2895
- var isValid = trimmedValue === '' || trimmedValue === 'PROB30' || trimmedValue === 'PROB40';
2896
- return isValid ? true : invalidProbabilityMessage;
2897
- };
2984
+ var IssuesButton = function IssuesButton(_a) {
2985
+ var _b = _a.errors,
2986
+ errors = _b === void 0 ? {} : _b,
2987
+ _c = _a.isIssuesPaneOpen,
2988
+ isIssuesPaneOpen = _c === void 0 ? false : _c,
2989
+ _d = _a.setIsIssuesPaneOpen,
2990
+ setIsIssuesPaneOpen = _d === void 0 ? function () {
2991
+ return null;
2992
+ } : _d;
2993
+ var errorList = filterDuplicateErrors(getErrors(errors));
2994
+ var totalErrors = errorList.length;
2995
+ var errorStatus = totalErrors > 0 ? 'error' : 'success';
2996
+ var buttonColor = "geowebColors.functional." + errorStatus;
2898
2997
 
2899
- /* *
2900
- * Licensed under the Apache License, Version 2.0 (the "License");
2901
- * you may not use this file except in compliance with the License.
2902
- * You may obtain a copy of the License at
2903
- *
2904
- * http://www.apache.org/licenses/LICENSE-2.0
2905
- *
2906
- * Unless required by applicable law or agreed to in writing, software
2907
- * distributed under the License is distributed on an "AS IS" BASIS,
2908
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2909
- * See the License for the specific language governing permissions and
2910
- * limitations under the License.
2911
- *
2912
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2913
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
2914
- * */
2998
+ var toggleIssuesPane = function toggleIssuesPane(newPosition) {
2999
+ return setIsIssuesPaneOpen(!isIssuesPaneOpen, newPosition);
3000
+ };
2915
3001
 
2916
- var TafFormOptionsButton = function TafFormOptionsButton(_a) {
2917
- var isChangeGroup = _a.isChangeGroup,
2918
- addChangeGroupBelow = _a.addChangeGroupBelow,
2919
- addChangeGroupAbove = _a.addChangeGroupAbove,
2920
- removeChangeGroup = _a.removeChangeGroup,
2921
- clearRow = _a.clearRow,
2922
- index = _a.index;
2923
- var insertAbove = {
2924
- text: 'Insert 1 row above',
2925
- icon: /*#__PURE__*/React__namespace.createElement(theme.Add, null),
2926
- action: addChangeGroupAbove
2927
- };
2928
- var insertBelow = {
2929
- text: 'Insert 1 row below',
2930
- icon: /*#__PURE__*/React__namespace.createElement(theme.Add, null),
2931
- action: addChangeGroupBelow
2932
- };
2933
- var deleteRow = {
2934
- text: 'Delete row',
2935
- icon: /*#__PURE__*/React__namespace.createElement(theme.Delete, null),
2936
- action: removeChangeGroup
2937
- };
2938
- var clear = {
2939
- text: 'Clear row',
2940
- icon: /*#__PURE__*/React__namespace.createElement(theme.Close, null),
2941
- action: clearRow
2942
- };
2943
- var menuItemsBaseForecast = [insertBelow, clear];
2944
- var menuItemsChangeGroup = [insertAbove, insertBelow, deleteRow, clear];
2945
- return /*#__PURE__*/React__namespace.createElement(shared.ToggleMenu, {
2946
- buttonTestId: "tafFormOptions[" + index + "]",
2947
- buttonSx: {
2948
- marginTop: '10px',
2949
- marginLeft: '4px'
2950
- },
2951
- menuItems: isChangeGroup ? menuItemsChangeGroup : menuItemsBaseForecast
2952
- });
2953
- };
3002
+ var onClickButton = function onClickButton(event) {
3003
+ var _a;
2954
3004
 
2955
- var getDefaultValue = function getDefaultValue(fieldName, data) {
2956
- if (!data) {
2957
- return '';
2958
- }
3005
+ var _b = event.currentTarget.getBoundingClientRect(),
3006
+ left = _b.left,
3007
+ top = _b.top;
2959
3008
 
2960
- return formFields.getDeepProperty(fieldName.split('.'), data) || '';
2961
- };
3009
+ var parentOffset = ((_a = document.getElementById('tafmodule')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) || {
3010
+ top: 0,
3011
+ left: 0
3012
+ };
3013
+ var newPosition = {
3014
+ left: left - parentOffset.left + 100,
3015
+ top: top - parentOffset.top
3016
+ };
3017
+ toggleIssuesPane(newPosition);
3018
+ };
2962
3019
 
2963
- var getRequiredCrossFields = function getRequiredCrossFields(fieldNames) {
2964
- return [[fieldNames.valid], [fieldNames.change, fieldNames.probability], [fieldNames.wind, fieldNames.visibility, fieldNames.weather1, fieldNames.cloud1] // sub fields
2965
- ];
3020
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3021
+ title: "View details"
3022
+ }, /*#__PURE__*/React__namespace.createElement(material.Chip, {
3023
+ "data-testid": "issuesButton",
3024
+ className: "status-" + errorStatus,
3025
+ size: "small",
3026
+ label: getIssuesLabel(totalErrors),
3027
+ onClick: onClickButton,
3028
+ sx: {
3029
+ width: '74px',
3030
+ color: '#ffffff',
3031
+ backgroundColor: buttonColor,
3032
+ '&:hover': {
3033
+ backgroundColor: buttonColor
3034
+ },
3035
+ '&:focus': {
3036
+ backgroundColor: buttonColor
3037
+ },
3038
+ fontSize: 12
3039
+ }
3040
+ }));
2966
3041
  };
2967
3042
 
2968
- var TafFormRow = /*#__PURE__*/React__default["default"].forwardRef(function (_a, ref) {
2969
- var isNotRequiredForAction = _a.isNotRequiredForAction,
2970
- _b = _a.isChangeGroup,
2971
- isChangeGroup = _b === void 0 ? false : _b,
2972
- _c = _a.disabled,
2973
- disabled = _c === void 0 ? false : _c,
2974
- _d = _a.index,
2975
- index = _d === void 0 ? -1 : _d,
2976
- onRemoveChangeGroup = _a.onRemoveChangeGroup,
2977
- _e = _a.field,
2978
- field = _e === void 0 ? null : _e,
2979
- _f = _a.dragHandle,
2980
- dragHandle = _f === void 0 ? null : _f,
2981
- onAddChangeGroupBelow = _a.onAddChangeGroupBelow,
2982
- onAddChangeGroupAbove = _a.onAddChangeGroupAbove,
2983
- onClearRow = _a.onClearRow,
2984
- props = __rest(_a, ["isNotRequiredForAction", "isChangeGroup", "disabled", "index", "onRemoveChangeGroup", "field", "dragHandle", "onAddChangeGroupBelow", "onAddChangeGroupAbove", "onClearRow"]);
2985
-
2986
- var namePrefix = !isChangeGroup ? 'baseForecast' : "changeGroups[" + index + "]";
2987
- var fieldNames = getFieldNames(isChangeGroup, index);
2988
-
2989
- var _g = reactHookForm.useFormContext(),
2990
- getValues = _g.getValues,
2991
- trigger = _g.trigger; // cross-field required validation
2992
-
2993
-
2994
- var _h = __read(getRequiredCrossFields(fieldNames), 3),
2995
- mainFields = _h[0],
2996
- mainOptionalFields = _h[1],
2997
- subFields = _h[2];
2998
-
2999
- var hasFieldsValue = function hasFieldsValue(fields) {
3000
- return fields.map(getValues).find(function (field) {
3001
- return !!field;
3002
- });
3003
- }; // Used to validate the required field for change groups: Valid
3004
-
3005
-
3006
- var validateRequiredMain = function validateRequiredMain(value) {
3007
- return isNotRequiredForAction(value) !== true && isChangeGroup && !value.length && (hasFieldsValue(subFields) || hasFieldsValue(mainFields) || hasFieldsValue(mainOptionalFields)) ? 'Valid is required' : true;
3008
- }; // Used to ensure either probability or change is entered, or both
3009
-
3010
-
3011
- var validateRequiredMainOptional = function validateRequiredMainOptional(value) {
3012
- return isNotRequiredForAction(value) !== true && isChangeGroup && (hasFieldsValue(mainFields) || hasFieldsValue(subFields)) && !hasFieldsValue(mainOptionalFields) ? 'Probability or change is required' : true;
3013
- }; // Used to ensure one wind, visibility, weather or cloud is entered when start editing a changegroup and all of these are empty
3014
-
3015
-
3016
- var validateRequiredSub = function validateRequiredSub(value) {
3017
- return isNotRequiredForAction(value) !== true && isChangeGroup && (hasFieldsValue(mainFields) || hasFieldsValue(mainOptionalFields)) && !hasFieldsValue(subFields) ? 'Wind, visibility, weather or cloud is required' : true;
3018
- }; // Used to validate the combination of change group and wind, visibility, weather and/or cloud data entered
3043
+ var getPaneTitle = function getPaneTitle(sumOfErrors) {
3044
+ switch (sumOfErrors) {
3045
+ case 0:
3046
+ return 'Looks good';
3019
3047
 
3048
+ case 1:
3049
+ return 'There is an issue to address';
3020
3050
 
3021
- var _validateRequiredMainFields = function validateRequiredMainFields(value, fieldName) {
3022
- var changeField = getValues(namePrefix + ".change");
3023
- var visibilityField = getValues(namePrefix + ".visibility");
3024
- var isFM = changeField && changeField.trim() === 'FM';
3025
- var isCAVOK = visibilityField && visibilityField.trim() === 'CAVOK';
3051
+ default:
3052
+ return 'There are a few issues to address';
3053
+ }
3054
+ };
3026
3055
 
3027
- if (isNotRequiredForAction(value) !== true && !value.length) {
3028
- if (isChangeGroup && isFM || !isChangeGroup) {
3029
- // exception for CavOK
3030
- if (isCAVOK && (fieldName === 'Clouds' || fieldName === 'Weather')) {
3031
- return true;
3032
- } // exception for visibility > 5000
3056
+ var humanizeErrorMessage = function humanizeErrorMessage(errorTitle, fieldNumberedValue) {
3057
+ if (fieldNumberedValue !== undefined && fieldNumberedValue >= 0) {
3058
+ // when name contains a number we assume it's a formgroup and we add a index +1 for human readability
3059
+ var fieldNumber = fieldNumberedValue + 1;
3060
+ return errorTitle + " " + fieldNumber;
3061
+ }
3033
3062
 
3063
+ return errorTitle;
3064
+ };
3065
+ var getErrorMessage = function getErrorMessage(error, index) {
3066
+ var errorTitleCategory = error.isChangeGroup ? 'Changegroups' : 'Baseforecast';
3067
+ var fieldErrorTitle = humanizeErrorMessage(errorTitleCategory, error.rowIndex);
3068
+ return index + 1 + ". " + fieldErrorTitle + ": " + error.message;
3069
+ };
3070
+ var MODAL_DIALOG_ELEMENT = 'modal-dialog';
3071
+ var useIssuesPane = function useIssuesPane() {
3072
+ var _a = __read(React__namespace.useState(false), 2),
3073
+ isIssuesPaneOpen = _a[0],
3074
+ setIsIssuesPaneOpen = _a[1];
3034
3075
 
3035
- if (visibilityField && parseInt(visibilityField.trim(), 10) >= 5000 && fieldName === 'Weather') {
3036
- return true;
3037
- }
3076
+ var _b = __read(React__namespace.useState(null), 2),
3077
+ startPosition = _b[0],
3078
+ setStartPosition = _b[1];
3038
3079
 
3039
- return fieldName + " is required";
3040
- }
3041
- }
3080
+ var _c = __read(React__namespace.useState(false), 2),
3081
+ hasUserDragged = _c[0],
3082
+ setHasUserDragged = _c[1];
3042
3083
 
3043
- return true;
3084
+ var onUserHasDragged = function onUserHasDragged() {
3085
+ return setHasUserDragged(true);
3044
3086
  };
3045
3087
 
3046
- var validatePreviousRow = React__default["default"].useCallback(function () {
3047
- if (isChangeGroup && index > 0) {
3048
- var _a = getValues(),
3049
- validDateEnd = _a.validDateEnd,
3050
- validDateStart = _a.validDateStart,
3051
- changeGroups = _a.changeGroups;
3052
-
3053
- var currentChangeGroup = changeGroups[index];
3054
- var previousChangeGroup = changeGroups[index - 1];
3055
- return validatePreviousChangeGroup(currentChangeGroup, previousChangeGroup, validDateStart, validDateEnd);
3088
+ var onToggleIssuesPane = function onToggleIssuesPane(isOpen, newPosition) {
3089
+ if (!hasUserDragged) {
3090
+ setStartPosition(newPosition);
3056
3091
  }
3057
3092
 
3058
- return true;
3059
- }, [index, isChangeGroup, getValues]);
3060
-
3061
- var getFieldFromRow = function getFieldFromRow(fieldname, rowIndex) {
3062
- var indexedFieldName = "changeGroups[" + rowIndex + "]." + fieldname;
3063
- var rowValue = getValues(indexedFieldName);
3064
- return rowValue ? [indexedFieldName] : [];
3093
+ setIsIssuesPaneOpen(isOpen);
3065
3094
  };
3066
3095
 
3067
- var getValidFieldFromNextRow = function getValidFieldFromNextRow() {
3068
- return getFieldFromRow('valid', index + 1);
3096
+ var onCloseIssuesPane = function onCloseIssuesPane() {
3097
+ return setIsIssuesPaneOpen(false);
3069
3098
  };
3070
3099
 
3071
- var validateNextRows = React__default["default"].useCallback(function () {
3072
- if (isChangeGroup) {
3073
- var _a = getValues(),
3074
- validDateEnd = _a.validDateEnd,
3075
- validDateStart = _a.validDateStart,
3076
- changeGroups = _a.changeGroups;
3077
-
3078
- var currentChangeGroup = changeGroups[index];
3079
- var nextChangeGroups = changeGroups.slice(index + 1);
3080
- return validateOverlapWithFM(currentChangeGroup, nextChangeGroups, validDateStart, validDateEnd);
3081
- }
3082
-
3083
- return true;
3084
- }, [index, isChangeGroup, getValues]);
3085
-
3086
- var getPreviousValidFields = function getPreviousValidFields(rowIndex) {
3087
- var changeGroups = getValues().changeGroups;
3088
- var previousChangeGroups = changeGroups.slice(0, rowIndex);
3089
- var validFields = previousChangeGroups.map(function (_element, index) {
3090
- return getFieldFromRow('valid', index)[0];
3091
- });
3092
- return validFields;
3100
+ return {
3101
+ isIssuesPaneOpen: isIssuesPaneOpen,
3102
+ startPosition: startPosition,
3103
+ onToggleIssuesPane: onToggleIssuesPane,
3104
+ onCloseIssuesPane: onCloseIssuesPane,
3105
+ onUserHasDragged: onUserHasDragged
3093
3106
  };
3107
+ };
3094
3108
 
3095
- var addChangeGroupBelow = React__default["default"].useCallback(function () {
3096
- onAddChangeGroupBelow(index);
3097
- }, [onAddChangeGroupBelow, index]);
3098
- var addChangeGroupAbove = React__default["default"].useCallback(function () {
3099
- onAddChangeGroupAbove(index);
3100
- }, [onAddChangeGroupAbove, index]);
3101
- var clearRow = React__default["default"].useCallback(function () {
3102
- onClearRow(index);
3103
- }, [onClearRow, index]);
3104
- return /*#__PURE__*/React__default["default"].createElement(material.Grid, __assign({
3105
- sx: {
3106
- marginTop: '8px',
3107
- backgroundColor: 'geowebColors.cards.cardContainer',
3108
- position: 'relative',
3109
- '&.sortable-chosen': {
3110
- boxShadow: 1
3111
- },
3112
- '&.sortable-ghost': {
3113
- opacity: 0.5
3114
- }
3115
- },
3116
- justifyContent: "flex-start",
3117
- "data-testid": "row-" + namePrefix,
3118
- container: true,
3119
- ref: ref
3120
- }, props), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3121
- columns: 24,
3122
- item: true,
3123
- container: true,
3124
- justifyContent: "flex-end",
3125
- xs: 24,
3126
- sm: 23
3127
- }, !isChangeGroup && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3128
- label: "Type",
3129
- name: fieldNames.messageType,
3130
- disabled: true
3131
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3132
- label: "Location",
3133
- name: "location",
3134
- disabled: true
3135
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3136
- formatter: formatIssueTime,
3137
- label: "Issue time",
3138
- name: "issueDate",
3139
- disabled: true
3140
- })), isChangeGroup && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(material.Box, {
3141
- sx: {
3142
- width: 56,
3143
- marginRight: '2px'
3144
- }
3145
- }, !disabled && dragHandle), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3146
- label: "Prob",
3147
- name: fieldNames.probability,
3148
- disabled: disabled,
3149
- defaultValue: getDefaultValue('probability', field),
3150
- rules: {
3151
- validate: {
3152
- validateRequiredMainOptional: validateRequiredMainOptional,
3153
- validateProbabilityField: validateProbabilityField
3154
- }
3109
+ var IssuesPane = function IssuesPane(_a) {
3110
+ var _b = _a.errorList,
3111
+ errorList = _b === void 0 ? [] : _b,
3112
+ isOpen = _a.isOpen,
3113
+ handleClose = _a.handleClose,
3114
+ _c = _a.startPosition,
3115
+ startPosition = _c === void 0 ? {
3116
+ left: 20,
3117
+ top: 50
3118
+ } : _c,
3119
+ _d = _a.onUserHasDragged,
3120
+ onUserHasDragged = _d === void 0 ? function () {} : _d;
3121
+ var rootElement = document.getElementById(MODAL_DIALOG_ELEMENT) || document.body;
3122
+ return /*#__PURE__*/ReactDOM__default["default"].createPortal( /*#__PURE__*/React__namespace.createElement(shared.ToolContainerDraggable, {
3123
+ startSize: {
3124
+ width: '577px',
3125
+ height: '200px'
3155
3126
  },
3156
- autoComplete: [{
3157
- key: '3',
3158
- value: 'PROB30'
3159
- }, {
3160
- key: '4',
3161
- value: 'PROB40'
3162
- }],
3163
- onBlur: function onBlur() {
3164
- if (isChangeGroup) {
3165
- var nextValidFieldName = getValidFieldFromNextRow();
3166
- trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)));
3127
+ startPosition: startPosition,
3128
+ minWidth: 300,
3129
+ onClose: handleClose,
3130
+ title: getPaneTitle(errorList.length),
3131
+ headerSize: "xs",
3132
+ isOpen: isOpen,
3133
+ "data-testid": "moveable-issues-pane",
3134
+ bounds: "parent",
3135
+ onDragEnd: function onDragEnd(event) {
3136
+ if (event.x !== 0 && event.y !== 0) {
3137
+ onUserHasDragged();
3167
3138
  }
3168
3139
  }
3169
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3170
- label: "Change",
3171
- name: fieldNames.change,
3172
- disabled: disabled,
3173
- defaultValue: getDefaultValue('change', field),
3174
- rules: {
3175
- validate: {
3176
- validateRequiredMainOptional: validateRequiredMainOptional,
3177
- validateChangeField: validateChangeField,
3178
- validateChangeFieldInterField: function validateChangeFieldInterField$1(value) {
3179
- return validateChangeFieldInterField(value, getValues(fieldNames.probability));
3180
- }
3181
- }
3140
+ }, /*#__PURE__*/React__namespace.createElement(material.Box, {
3141
+ component: "div",
3142
+ sx: {
3143
+ marginTop: '16px',
3144
+ marginLeft: '24px'
3145
+ }
3146
+ }, errorList.length === 0 && /*#__PURE__*/React__namespace.createElement(material.Box, {
3147
+ component: "div",
3148
+ sx: {
3149
+ fontSize: '4rem'
3182
3150
  },
3183
- autoComplete: [{
3184
- key: 'T',
3185
- value: 'TEMPO'
3186
- }, {
3187
- key: 'B',
3188
- value: 'BECMG'
3189
- }, {
3190
- key: 'F',
3191
- value: 'FM'
3192
- }],
3193
- onBlur: function onBlur() {
3194
- if (isChangeGroup) {
3195
- var nextValidFieldName = getValidFieldFromNextRow();
3196
- var previousValidFieldNames = getPreviousValidFields(index);
3197
- trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)), __read(previousValidFieldNames)));
3198
- }
3151
+ "data-testid": "zeroIssuesImage"
3152
+ }, /*#__PURE__*/React__namespace.createElement(theme.ThumbsUp, {
3153
+ sx: {
3154
+ height: '69px',
3155
+ width: '58px'
3199
3156
  }
3200
- })), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3201
- label: "Valid",
3202
- name: fieldNames.valid,
3203
- // always disabled for baseforecast row
3204
- disabled: !isChangeGroup ? true : disabled,
3205
- defaultValue: getDefaultValue('valid', field),
3206
- rules: {
3207
- validate: {
3208
- validateRequiredMain: validateRequiredMain,
3209
- validateValidField: function validateValidField$1(value) {
3210
- return isChangeGroup ? validateValidField(value, getValues('validDateStart'), getValues('validDateEnd')) : true;
3211
- },
3212
- validateValidChangeGroupInterField: function validateValidChangeGroupInterField$1(value) {
3213
- return isChangeGroup ? validateValidChangeGroupInterField(value, getValues(fieldNames.change), getValues(fieldNames.probability), getValues('validDateStart'), getValues('validDateEnd')) : true;
3214
- },
3215
- validatePreviousRow: validatePreviousRow,
3216
- validateNextRows: validateNextRows
3157
+ })), errorList.length > 0 && errorList.map(function (error, index) {
3158
+ return /*#__PURE__*/React__namespace.createElement(material.Typography // eslint-disable-next-line react/no-array-index-key
3159
+ , {
3160
+ // eslint-disable-next-line react/no-array-index-key
3161
+ key: "message-" + index,
3162
+ variant: "body1",
3163
+ "data-testid": "errorMessage"
3164
+ }, getErrorMessage(error, index));
3165
+ }))), rootElement);
3166
+ };
3167
+
3168
+ /* *
3169
+ * Licensed under the Apache License, Version 2.0 (the "License");
3170
+ * you may not use this file except in compliance with the License.
3171
+ * You may obtain a copy of the License at
3172
+ *
3173
+ * http://www.apache.org/licenses/LICENSE-2.0
3174
+ *
3175
+ * Unless required by applicable law or agreed to in writing, software
3176
+ * distributed under the License is distributed on an "AS IS" BASIS,
3177
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3178
+ * See the License for the specific language governing permissions and
3179
+ * limitations under the License.
3180
+ *
3181
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3182
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3183
+ * */
3184
+ var TafModuleContext = /*#__PURE__*/React__namespace.createContext({
3185
+ onValidateForm: null,
3186
+ registerValidateForm: null,
3187
+ tafAction: null,
3188
+ setTafAction: null,
3189
+ onPreventCloseView: null
3190
+ });
3191
+ var useTafModuleContext = function useTafModuleContext() {
3192
+ return React__namespace.useContext(TafModuleContext);
3193
+ };
3194
+ var useTafModuleState = function useTafModuleState(_a) {
3195
+ var onPreventCloseView = _a.onPreventCloseView;
3196
+
3197
+ var _b = __read(React__namespace.useState(function () {
3198
+ return new Promise(function () {
3199
+ return true;
3200
+ });
3201
+ }), 2),
3202
+ onValidateForm = _b[0],
3203
+ registerValidateForm = _b[1];
3204
+
3205
+ var _c = __read(React__namespace.useState(), 2),
3206
+ tafAction = _c[0],
3207
+ setTafAction = _c[1];
3208
+
3209
+ var onRegisterValidateForm = function onRegisterValidateForm(promiseToRegister) {
3210
+ registerValidateForm(function () {
3211
+ return promiseToRegister;
3212
+ });
3213
+ };
3214
+
3215
+ return {
3216
+ onValidateForm: onValidateForm,
3217
+ registerValidateForm: onRegisterValidateForm,
3218
+ tafAction: tafAction,
3219
+ setTafAction: setTafAction,
3220
+ onPreventCloseView: onPreventCloseView
3221
+ };
3222
+ };
3223
+ var TafModuleProvider = function TafModuleProvider(_a) {
3224
+ var children = _a.children,
3225
+ _b = _a.onPreventCloseView,
3226
+ onPreventCloseView = _b === void 0 ? function () {} : _b;
3227
+ var contextState = useTafModuleState({
3228
+ onPreventCloseView: onPreventCloseView
3229
+ });
3230
+ return /*#__PURE__*/React__namespace.createElement(TafModuleContext.Provider, {
3231
+ value: contextState
3232
+ }, children);
3233
+ };
3234
+
3235
+ var styles = {
3236
+ label: {
3237
+ color: 'geowebColors.buttons.tertiary.default.color',
3238
+ opacity: 1,
3239
+ fontSize: '12px',
3240
+ fontWeight: 500
3241
+ }
3242
+ };
3243
+
3244
+ var SwitchButton = function SwitchButton(props) {
3245
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3246
+ title: "Switch mode"
3247
+ }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(material.FormLabel, {
3248
+ sx: styles.label
3249
+ }, "Viewer"), /*#__PURE__*/React__namespace.createElement(material.Switch, __assign({
3250
+ "data-testid": "switchMode"
3251
+ }, props)), /*#__PURE__*/React__namespace.createElement(material.FormLabel, {
3252
+ sx: styles.label
3253
+ }, "Editor")));
3254
+ };
3255
+
3256
+ var TafAvatar = function TafAvatar(_a) {
3257
+ var editor = _a.editor,
3258
+ _b = _a.tooltipPlacement,
3259
+ tooltipPlacement = _b === void 0 ? 'bottom' : _b;
3260
+ return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3261
+ title: "Editor: " + editor,
3262
+ placement: tooltipPlacement
3263
+ }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(shared.Avatar, {
3264
+ size: "small"
3265
+ }, shared.getInitials(editor))));
3266
+ };
3267
+
3268
+ var textFieldStyle = function textFieldStyle(theme) {
3269
+ return {
3270
+ // input
3271
+ marginRight: '2px',
3272
+ marginBottom: '4px',
3273
+ width: 56,
3274
+ height: 46,
3275
+ input: {
3276
+ textAlign: 'center',
3277
+ fontSize: 10,
3278
+ fontWeight: 500,
3279
+ paddingLeft: 0,
3280
+ paddingRight: 0,
3281
+ '&.Mui-disabled': {
3282
+ color: 'geowebColors.typographyAndIcons.text',
3283
+ WebkitTextFillColor: theme.palette.geowebColors.typographyAndIcons.text
3284
+ },
3285
+ // TODO: https://gitlab.com/opengeoweb/opengeoweb/-/issues/1995 disables the default autofill styling, should be a better fix
3286
+ '&:-webkit-autofill': {
3287
+ WebkitTransitionDelay: '86400s' // 1 day delay
3288
+
3217
3289
  }
3218
3290
  },
3219
- onBlur: function onBlur() {
3220
- if (isChangeGroup) {
3221
- var nextValidFieldName = getValidFieldFromNextRow();
3222
- var previousValidFieldNames = getPreviousValidFields(index);
3223
- trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)), __read(previousValidFieldNames)));
3224
- }
3225
- }
3226
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3227
- label: "Wind",
3228
- name: fieldNames.wind,
3229
- disabled: disabled,
3230
- defaultValue: getDefaultValue('wind', field),
3231
- rules: {
3232
- validate: {
3233
- validateRequiredMainFields: function validateRequiredMainFields(value) {
3234
- return _validateRequiredMainFields(value, 'Wind');
3235
- },
3236
- validateRequiredSub: validateRequiredSub,
3237
- validateWindField: function validateWindField$1(value) {
3238
- return validateWindField(value, getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3239
- }
3240
- }
3241
- },
3242
- onBlur: function onBlur() {
3243
- if (isChangeGroup) {
3244
- trigger(__spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)));
3245
- }
3246
- },
3247
- autoFocus: !isChangeGroup
3248
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3249
- label: "Visibility",
3250
- name: fieldNames.visibility,
3251
- disabled: disabled,
3252
- defaultValue: getDefaultValue('visibility', field),
3253
- rules: {
3254
- validate: {
3255
- validateRequiredMainFields: function validateRequiredMainFields(value) {
3256
- return _validateRequiredMainFields(value, 'Visibility');
3257
- },
3258
- validateRequiredSub: validateRequiredSub,
3259
- validateVisibilityField: validateVisibilityField
3260
- }
3261
- },
3262
- autoComplete: [{
3263
- key: 'C',
3264
- value: 'CAVOK'
3265
- }],
3266
- onBlur: function onBlur() {
3267
- var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : subFields;
3268
- trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather1, fieldNames.weather2, fieldNames.weather3]));
3269
- }
3270
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3271
- label: "Weather",
3272
- name: fieldNames.weather1,
3273
- disabled: disabled,
3274
- defaultValue: getDefaultValue('weather.weather1', field),
3275
- rules: {
3276
- validate: {
3277
- validateRequiredMainFields: function validateRequiredMainFields(value) {
3278
- return _validateRequiredMainFields(value, 'Weather');
3279
- },
3280
- validateRequiredSub: validateRequiredSub,
3281
- validateWeatherField: function validateWeatherField$1(value) {
3282
- return validateWeatherField(value, getValues(fieldNames.visibility), !!isChangeGroup);
3283
- }
3284
- }
3285
- },
3286
- onBlur: function onBlur() {
3287
- var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3288
- return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather2, fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3289
- }
3290
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3291
- label: "Weather",
3292
- name: fieldNames.weather2,
3293
- disabled: disabled,
3294
- defaultValue: getDefaultValue('weather.weather2', field),
3295
- rules: {
3296
- validate: {
3297
- validateSecondWeatherField: function validateSecondWeatherField$1(value) {
3298
- return validateSecondWeatherField(getValues(fieldNames.weather1), value, getValues(fieldNames.visibility));
3299
- }
3300
- }
3301
- },
3302
- onBlur: function onBlur() {
3303
- var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3304
- return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3305
- }
3306
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3307
- label: "Weather",
3308
- name: fieldNames.weather3,
3309
- disabled: disabled,
3310
- defaultValue: getDefaultValue('weather.weather3', field),
3311
- rules: {
3312
- validate: {
3313
- validateThirdWeatherField: function validateThirdWeatherField$1(value) {
3314
- return validateThirdWeatherField(getValues(fieldNames.weather1), getValues(fieldNames.weather2), value, getValues(fieldNames.visibility));
3315
- }
3316
- }
3317
- },
3318
- onBlur: function onBlur() {
3319
- return trigger([fieldNames.wind, fieldNames.cloud1]);
3320
- }
3321
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3322
- label: "Cloud",
3323
- name: fieldNames.cloud1,
3324
- disabled: disabled,
3325
- defaultValue: getDefaultValue('cloud.cloud1', field),
3326
- rules: {
3327
- validate: {
3328
- validateRequiredMainFields: function validateRequiredMainFields(value) {
3329
- return _validateRequiredMainFields(value, 'Clouds');
3330
- },
3331
- validateRequiredSub: validateRequiredSub,
3332
- validateFirstCloud: function validateFirstCloud$1(value) {
3333
- return validateFirstCloud(value, getValues(fieldNames.visibility), getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3334
- }
3335
- }
3336
- },
3337
- onBlur: function onBlur() {
3338
- var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3339
- return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.cloud2, fieldNames.cloud3, fieldNames.cloud4]));
3340
- }
3341
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3342
- label: "Cloud",
3343
- name: fieldNames.cloud2,
3344
- disabled: disabled,
3345
- defaultValue: getDefaultValue('cloud.cloud2', field),
3346
- rules: {
3347
- validate: {
3348
- validateSecondCloud: function validateSecondCloud$1(value) {
3349
- return validateSecondCloud(getValues(fieldNames.cloud1), value, getValues(fieldNames.visibility));
3350
- }
3351
- }
3291
+ label: {
3292
+ transformOrigin: 'center top',
3293
+ right: 0,
3294
+ textAlign: 'center',
3295
+ fontSize: '10px',
3296
+ '&.Mui-disabled': {
3297
+ color: 'geowebColors.captions.captionStatus.rgba'
3298
+ },
3299
+ whiteSpace: 'nowrap',
3300
+ maxWidth: '100%',
3301
+ transform: 'translate(0px, 16px) scale(1)'
3352
3302
  },
3353
- onBlur: function onBlur() {
3354
- return trigger([fieldNames.cloud3, fieldNames.cloud4]);
3355
- }
3356
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3357
- label: "Cloud",
3358
- name: fieldNames.cloud3,
3359
- disabled: disabled,
3360
- defaultValue: getDefaultValue('cloud.cloud3', field),
3361
- rules: {
3362
- validate: {
3363
- validateThirdCloud: function validateThirdCloud$1(value) {
3364
- return validateThirdCloud(getValues(fieldNames.cloud1), getValues(fieldNames.cloud2), value, getValues(fieldNames.visibility));
3365
- }
3366
- }
3303
+ // shrink
3304
+ ' .MuiInputLabel-shrink': {
3305
+ transform: 'translate(2px, 10px) scale(0.75) !important',
3306
+ letterSpacing: '0.33px',
3307
+ textAlign: 'left'
3367
3308
  },
3368
- onBlur: function onBlur() {
3369
- return trigger(fieldNames.cloud4);
3370
- }
3371
- }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3372
- label: "Cloud",
3373
- name: fieldNames.cloud4,
3374
- disabled: disabled,
3375
- defaultValue: getDefaultValue('cloud.cloud4', field),
3376
- rules: {
3377
- validate: {
3378
- validateFourthCloud: function validateFourthCloud$1(value) {
3379
- return validateFourthCloud(getValues(fieldNames.cloud1), getValues(fieldNames.cloud2), getValues(fieldNames.cloud3), value, getValues(fieldNames.visibility));
3380
- }
3309
+ // root
3310
+ '&': {
3311
+ '.Mui-error.MuiFilledInput-root': {
3312
+ backgroundColor: 'geowebColors.captions.captionErrorBackground.rgba'
3313
+ },
3314
+ '.Mui-disabled:before': {
3315
+ borderColor: 'transparent'
3381
3316
  }
3382
3317
  }
3383
- })), !disabled && /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3384
- item: true,
3385
- container: true,
3386
- justifyContent: "flex-end",
3387
- alignItems: "flex-end",
3388
- xs: 24,
3389
- sm: 1,
3390
- sx: {
3391
- marginBottom: '16px'
3392
- },
3393
- columns: 24
3394
- }, /*#__PURE__*/React__default["default"].createElement(TafFormOptionsButton, {
3395
- isChangeGroup: isChangeGroup,
3396
- addChangeGroupBelow: addChangeGroupBelow,
3397
- addChangeGroupAbove: addChangeGroupAbove,
3398
- removeChangeGroup: function removeChangeGroup() {
3399
- return onRemoveChangeGroup(index);
3400
- },
3401
- clearRow: clearRow,
3402
- index: index
3403
- })));
3404
- });
3405
-
3406
- /* *
3407
- * Licensed under the Apache License, Version 2.0 (the "License");
3408
- * you may not use this file except in compliance with the License.
3409
- * You may obtain a copy of the License at
3410
- *
3411
- * http://www.apache.org/licenses/LICENSE-2.0
3412
- *
3413
- * Unless required by applicable law or agreed to in writing, software
3414
- * distributed under the License is distributed on an "AS IS" BASIS,
3415
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3416
- * See the License for the specific language governing permissions and
3417
- * limitations under the License.
3418
- *
3419
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3420
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
3421
- * */
3422
- var tafActionToDraftAction = function tafActionToDraftAction(tafAction) {
3423
- switch (tafAction) {
3424
- case 'AMEND':
3425
- case 'DRAFT_AMEND':
3426
- return 'DRAFT_AMEND';
3427
-
3428
- case 'CORRECT':
3429
- case 'DRAFT_CORRECT':
3430
- return 'DRAFT_CORRECT';
3431
-
3432
- default:
3433
- return 'DRAFT';
3434
- }
3318
+ };
3435
3319
  };
3436
3320
 
3437
- var tafActionToPublishAction = function tafActionToPublishAction(tafAction) {
3438
- switch (tafAction) {
3439
- case 'AMEND':
3440
- case 'DRAFT_AMEND':
3441
- return 'AMEND';
3321
+ var getTafErrors = function getTafErrors(name, errors) {
3322
+ var nameAsArray = name.split('.');
3442
3323
 
3443
- case 'CORRECT':
3444
- case 'DRAFT_CORRECT':
3445
- return 'CORRECT';
3324
+ if (nameAsArray[0].includes('changeGroups')) {
3325
+ if (errors.changeGroups) {
3326
+ var changeGroupNum = nameAsArray[0].slice(13, nameAsArray[0].length - 1);
3327
+ var restArray = nameAsArray.slice(1);
3328
+ return formFields.getDeepProperty(restArray, errors.changeGroups[changeGroupNum]);
3329
+ } // No changegroup errors
3446
3330
 
3447
- default:
3448
- return 'PUBLISH';
3331
+
3332
+ return null;
3449
3333
  }
3450
- };
3451
3334
 
3452
- var buttonsStyle = {
3453
- button: {
3454
- minWidth: {
3455
- xs: '56px',
3456
- sm: '64px'
3457
- },
3458
- width: {
3459
- xs: '56px',
3460
- sm: '64px'
3461
- },
3462
- marginLeft: {
3463
- xs: 0.5,
3464
- sm: 1
3465
- },
3466
- marginTop: 3,
3467
- marginBottom: 3
3468
- }
3335
+ return formFields.getDeepProperty(nameAsArray, errors);
3469
3336
  };
3470
3337
 
3471
- var ViewModeButtons = function ViewModeButtons(_a) {
3472
- var canBe = _a.canBe,
3473
- onTafViewModeButtonPress = _a.onTafViewModeButtonPress;
3474
- return !canBe.includes('CANCELLED') && !canBe.includes('CORRECTED') && !canBe.includes('AMENDED') ? null : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, canBe.includes('CANCELLED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
3475
- "data-testid": "canceltaf",
3476
- variant: "tertiary",
3477
- onClick: function onClick() {
3478
- return onTafViewModeButtonPress('CANCEL');
3479
- }
3480
- }, "Cancel"), canBe.includes('CORRECTED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
3481
- "data-testid": "correcttaf",
3482
- variant: "tertiary",
3483
- onClick: function onClick() {
3484
- return onTafViewModeButtonPress('CORRECT');
3485
- }
3486
- }, "Correct"), canBe.includes('AMENDED') && /*#__PURE__*/React__default["default"].createElement(material.Button, {
3487
- "data-testid": "amendtaf",
3488
- variant: "tertiary",
3489
- onClick: function onClick() {
3490
- return onTafViewModeButtonPress('AMEND');
3491
- }
3492
- }, "Amend"));
3338
+ var getDisplayValue = function getDisplayValue(value, disabled) {
3339
+ return disabled && !value ? '-' : value;
3493
3340
  };
3341
+ var BaseTextField = /*#__PURE__*/React__default["default"].memo(function (props) {
3342
+ return /*#__PURE__*/React__default["default"].createElement(material.TextField, __assign({
3343
+ type: "text",
3344
+ variant: "filled",
3345
+ sx: textFieldStyle
3346
+ }, props));
3347
+ }, function (prevProps, nextProps) {
3348
+ return prevProps.value === nextProps.value && prevProps.error === nextProps.error && prevProps.name === nextProps.name && prevProps.disabled === nextProps.disabled;
3349
+ });
3494
3350
 
3495
- var TafFormButtons = function TafFormButtons(_a) {
3496
- var _b = _a.isFormDisabled,
3497
- isFormDisabled = _b === void 0 ? false : _b,
3498
- tafAction = _a.tafAction,
3499
- _c = _a.canBe,
3500
- canBe = _c === void 0 ? [] : _c,
3501
- onTafEditModeButtonPress = _a.onTafEditModeButtonPress,
3502
- onTafViewModeButtonPress = _a.onTafViewModeButtonPress;
3503
- return /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3504
- container: true,
3505
- justifyContent: "flex-end",
3506
- sx: buttonsStyle,
3507
- columns: 24
3508
- }, /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3509
- item: true,
3510
- container: true,
3511
- justifyContent: "flex-end",
3512
- columns: 24,
3513
- xs: 24,
3514
- sm: 23
3515
- }, isFormDisabled ? /*#__PURE__*/React__default["default"].createElement(ViewModeButtons, {
3516
- canBe: canBe,
3517
- onTafViewModeButtonPress: onTafViewModeButtonPress
3518
- }) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(material.Button, {
3519
- "data-testid": "cleartaf",
3520
- variant: "tertiary",
3521
- onClick: function onClick() {
3522
- // Simply discard the changes and close the dialog.
3523
- onTafEditModeButtonPress('CLEAR');
3524
- }
3525
- }, "Clear"), /*#__PURE__*/React__default["default"].createElement(material.Button, {
3526
- "data-testid": "savedrafttaf",
3527
- variant: "tertiary",
3528
- onClick: function onClick() {
3529
- /* Save the TAF as draft:
3530
- if action NEW or DRAFT - new status will be DRAFT -- default
3531
- if action AMEND - new status will be DRAFT_AMENDED
3532
- if action CORRECT - new status will be DRAFT_CORRECTED
3533
- if action DRAFT_AMEND - new status will be DRAFT_AMENDED
3534
- if action DRAFT_CORRECT - new status will be DRAFT_CORRECTED
3535
- */
3536
- onTafEditModeButtonPress(tafActionToDraftAction(tafAction));
3351
+ var TafFormTextField = function TafFormTextField(_a) {
3352
+ var label = _a.label,
3353
+ _b = _a.disabled,
3354
+ disabled = _b === void 0 ? false : _b,
3355
+ _c = _a.name,
3356
+ name = _c === void 0 ? '' : _c,
3357
+ _d = _a.onChange,
3358
+ onChange = _d === void 0 ? function () {} : _d,
3359
+ _e = _a.onBlur,
3360
+ onBlur = _e === void 0 ? function () {} : _e,
3361
+ _f = _a.defaultValue,
3362
+ defaultValue = _f === void 0 ? '' : _f,
3363
+ _g = _a.formatter,
3364
+ formatter = _g === void 0 ? null : _g,
3365
+ rules = _a.rules,
3366
+ _h = _a.autoComplete,
3367
+ autoComplete = _h === void 0 ? [] : _h,
3368
+ _j = _a.autoFocus,
3369
+ autoFocus = _j === void 0 ? false : _j;
3370
+
3371
+ var _k = reactHookForm.useFormContext(),
3372
+ control = _k.control,
3373
+ setValue = _k.setValue,
3374
+ errors = _k.formState.errors;
3375
+
3376
+ var fieldErrors = getTafErrors(name, errors);
3377
+
3378
+ var _l = __read(React__default["default"].useState(null), 2),
3379
+ maxLength = _l[0],
3380
+ setMaxLength = _l[1];
3381
+
3382
+ var onKeyDown = React__default["default"].useCallback(function (event) {
3383
+ var target = event.target;
3384
+ var currentValue = target.value,
3385
+ selectionStart = target.selectionStart,
3386
+ selectionEnd = target.selectionEnd;
3387
+ var textSelection = currentValue.substring(selectionStart, selectionEnd);
3388
+
3389
+ if (autoComplete && !currentValue.length || textSelection.length && currentValue.length && textSelection === currentValue) {
3390
+ var pressedKey_1 = event.key.toString().toUpperCase();
3391
+ var foundValue = autoComplete.find(function (el) {
3392
+ return el.key === pressedKey_1;
3393
+ }) || null;
3394
+
3395
+ if (foundValue) {
3396
+ setValue(name, foundValue.value, {
3397
+ shouldDirty: true
3398
+ });
3399
+ setMaxLength(foundValue.value.length);
3400
+ event.preventDefault();
3401
+ }
3537
3402
  }
3538
- }, "Save"), /*#__PURE__*/React__default["default"].createElement(material.Button, {
3539
- "data-testid": "publishtaf",
3540
- variant: "tertiary",
3541
- onClick: function onClick() {
3542
- /* Publish the TAF:
3543
- if action NEW or DRAFT - new status will be PUBLISHED -- default
3544
- if action AMEND - new status will be AMENDED
3545
- if action CORRECT - new status will be CORRECTED
3546
- if action DRAFT_AMEND - new status will be AMENDED
3547
- if action DRAFT_CORRECT - new status will be CORRECTED
3548
- */
3549
- onTafEditModeButtonPress(tafActionToPublishAction(tafAction));
3403
+ }, [name, autoComplete, setValue]);
3404
+ var onChangeField = React__default["default"].useCallback(function (event, callback) {
3405
+ var valueUppercase = event.currentTarget.value.toUpperCase();
3406
+
3407
+ if (autoComplete) {
3408
+ var exist = autoComplete.find(function (e) {
3409
+ return e.value === valueUppercase;
3410
+ });
3411
+ var newMaxLength = exist ? valueUppercase.length : null;
3412
+ setMaxLength(newMaxLength);
3550
3413
  }
3551
- }, "Publish"))), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3552
- item: true,
3553
- columns: 24,
3554
- sm: 1
3555
- }));
3414
+
3415
+ callback(valueUppercase);
3416
+ onChange(valueUppercase);
3417
+ }, [onChange, autoComplete]);
3418
+ var onBlurField = React__default["default"].useCallback(function (callback) {
3419
+ callback();
3420
+ onBlur();
3421
+ }, [onBlur]);
3422
+ var hasError = !!fieldErrors;
3423
+ return /*#__PURE__*/React__default["default"].createElement(reactHookForm.Controller, {
3424
+ render: function render(_a) {
3425
+ var field = _a.field;
3426
+ var displayValue = formatter ? formatter(field.value) : getDisplayValue(field.value, disabled);
3427
+ return /*#__PURE__*/React__default["default"].createElement(BaseTextField, {
3428
+ label: label,
3429
+ disabled: disabled,
3430
+ name: name,
3431
+ value: displayValue,
3432
+ inputRef: field.ref,
3433
+ onChange: function onChange(e) {
3434
+ return onChangeField(e, field.onChange);
3435
+ },
3436
+ onKeyDown: onKeyDown,
3437
+ error: hasError,
3438
+ onBlur: function onBlur() {
3439
+ return onBlurField(field.onBlur);
3440
+ },
3441
+ inputProps: {
3442
+ maxLength: maxLength
3443
+ },
3444
+ autoFocus: autoFocus
3445
+ });
3446
+ },
3447
+ name: name,
3448
+ control: control,
3449
+ defaultValue: defaultValue,
3450
+ rules: rules
3451
+ });
3556
3452
  };
3557
3453
 
3558
3454
  /* *
@@ -3568,30 +3464,27 @@
3568
3464
  * See the License for the specific language governing permissions and
3569
3465
  * limitations under the License.
3570
3466
  *
3571
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3572
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
3467
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3468
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
3573
3469
  * */
3574
3470
 
3575
- var DragHandle = function DragHandle(_a) {
3576
- var _b = _a.isSorting,
3577
- isSorting = _b === void 0 ? false : _b,
3578
- _c = _a.isDisabled,
3579
- isDisabled = _c === void 0 ? false : _c,
3580
- index = _a.index;
3581
- return /*#__PURE__*/React__default["default"].createElement(material.IconButton, {
3582
- className: "handle",
3583
- "data-testid": "dragHandle-" + index,
3584
- disableRipple: true,
3585
- disabled: isDisabled,
3586
- size: "large",
3587
- sx: {
3588
- backgroundColor: 'transparent',
3589
- '&:hover': {
3590
- backgroundColor: 'transparent'
3591
- },
3592
- cursor: isSorting ? 'grabbing' : 'grab'
3593
- }
3594
- }, /*#__PURE__*/React__default["default"].createElement(theme.DragHandle, null));
3471
+ var invalidChangeMessage = 'Invalid Change input, only BECMG, TEMPO or FM are allowed';
3472
+ var invalidChangeProbCombinationMessage = 'A probability is only allowed in combination with TEMPO or an empty Change input'; // validations
3473
+
3474
+ var validateChangeField = function validateChangeField(value) {
3475
+ var trimmedValue = getFieldValue(value);
3476
+ var isValid = trimmedValue === '' || trimmedValue === 'FM' || trimmedValue === 'TEMPO' || trimmedValue === 'BECMG';
3477
+ return isValid ? true : invalidChangeMessage;
3478
+ };
3479
+ var validateChangeFieldInterField = function validateChangeFieldInterField(value, valueProb) {
3480
+ var trimmedProbValue = getFieldValue(valueProb);
3481
+ var trimmedValue = getFieldValue(value);
3482
+
3483
+ if (trimmedProbValue !== '' && trimmedValue !== '' && trimmedValue !== 'TEMPO') {
3484
+ return invalidChangeProbCombinationMessage;
3485
+ }
3486
+
3487
+ return true;
3595
3488
  };
3596
3489
 
3597
3490
  /* *
@@ -3607,82 +3500,16 @@
3607
3500
  * See the License for the specific language governing permissions and
3608
3501
  * limitations under the License.
3609
3502
  *
3610
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3611
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
3503
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3504
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
3612
3505
  * */
3613
- var getCustomError = function getCustomError(error, isChangeGroup, rowIndex) {
3614
- return __assign(__assign({}, error), {
3615
- isChangeGroup: isChangeGroup,
3616
- rowIndex: rowIndex
3617
- });
3618
- };
3619
- var getIssuesLabel = function getIssuesLabel(sumOfErrors) {
3620
- switch (sumOfErrors) {
3621
- case 0:
3622
- return '0 issues';
3623
-
3624
- case 1:
3625
- return '1 issue';
3626
-
3627
- default:
3628
- return sumOfErrors + " issues";
3629
- }
3630
- };
3631
- var getErrorValues = function getErrorValues(fieldErrors, isChangeGroup, rowIndex) {
3632
- if (isChangeGroup === void 0) {
3633
- isChangeGroup = false;
3634
- }
3635
-
3636
- if (rowIndex === void 0) {
3637
- rowIndex = -1;
3638
- }
3639
-
3640
- if (!fieldErrors) return [];
3641
- return Object.keys(fieldErrors).reduce(function (list, key) {
3642
- var error = __assign({}, fieldErrors[key]);
3643
-
3644
- if (error.ref) {
3645
- return list.concat(getCustomError(error, isChangeGroup, rowIndex));
3646
- }
3647
-
3648
- return list.concat(getErrorValues(error, isChangeGroup, rowIndex));
3649
- }, []);
3650
- };
3651
- var filterDuplicateErrors = function filterDuplicateErrors(errors) {
3652
- return errors.reduce(function (list, error) {
3653
- // check on type validateRequiredSub and validateRequiredMainOptional since these are giving 'duplicates'
3654
- if (error.type === 'validateRequiredSub') {
3655
- var exist = list.find(function (e) {
3656
- return e.type === 'validateRequiredSub' && e.rowIndex === error.rowIndex;
3657
- });
3658
- return exist ? list : list.concat(error);
3659
- }
3660
-
3661
- if (error.type === 'validateRequiredMainOptional') {
3662
- var exist = list.find(function (e) {
3663
- return e.type === 'validateRequiredMainOptional' && e.rowIndex === error.rowIndex;
3664
- });
3665
- return exist ? list : list.concat(error);
3666
- }
3667
-
3668
- return list.concat(error);
3669
- }, []);
3670
- };
3671
- var getErrors = function getErrors(errors) {
3672
- var errorList = Object.keys(errors).reduce(function (list, key) {
3673
- var errorValue = errors[key]; // changeGroups
3674
-
3675
- if (Array.isArray(errorValue)) {
3676
- var errorValues = errorValue.reduce(function (changeGroupErrors, changeGroupError, index) {
3677
- return changeGroupErrors.concat(getErrorValues(changeGroupError, true, index));
3678
- }, []);
3679
- return list.concat.apply(list, __spreadArray([], __read(errorValues)));
3680
- } // baseForecast
3681
3506
 
3507
+ var invalidProbabilityMessage = 'Invalid Probability input, only PROB30 or PROB40 are allowed'; // validations
3682
3508
 
3683
- return list.concat(getErrorValues(errorValue, false, -1));
3684
- }, []);
3685
- return errorList;
3509
+ var validateProbabilityField = function validateProbabilityField(value) {
3510
+ var trimmedValue = getFieldValue(value);
3511
+ var isValid = trimmedValue === '' || trimmedValue === 'PROB30' || trimmedValue === 'PROB40';
3512
+ return isValid ? true : invalidProbabilityMessage;
3686
3513
  };
3687
3514
 
3688
3515
  /* *
@@ -3698,277 +3525,501 @@
3698
3525
  * See the License for the specific language governing permissions and
3699
3526
  * limitations under the License.
3700
3527
  *
3701
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3702
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
3528
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3529
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3703
3530
  * */
3704
3531
 
3705
- var IssuesButton = function IssuesButton(_a) {
3706
- var _b = _a.errors,
3707
- errors = _b === void 0 ? {} : _b,
3708
- _c = _a.isIssuesPaneOpen,
3709
- isIssuesPaneOpen = _c === void 0 ? false : _c,
3710
- _d = _a.setIsIssuesPaneOpen,
3711
- setIsIssuesPaneOpen = _d === void 0 ? function () {
3712
- return null;
3713
- } : _d;
3714
- var errorList = filterDuplicateErrors(getErrors(errors));
3715
- var totalErrors = errorList.length;
3716
- var errorStatus = totalErrors > 0 ? 'error' : 'success';
3717
- var buttonColor = "geowebColors.functional." + errorStatus;
3718
-
3719
- var toggleIssuesPane = function toggleIssuesPane(newPosition) {
3720
- return setIsIssuesPaneOpen(!isIssuesPaneOpen, newPosition);
3532
+ var TafFormOptionsButton = function TafFormOptionsButton(_a) {
3533
+ var isChangeGroup = _a.isChangeGroup,
3534
+ addChangeGroupBelow = _a.addChangeGroupBelow,
3535
+ addChangeGroupAbove = _a.addChangeGroupAbove,
3536
+ removeChangeGroup = _a.removeChangeGroup,
3537
+ clearRow = _a.clearRow,
3538
+ index = _a.index;
3539
+ var insertAbove = {
3540
+ text: 'Insert 1 row above',
3541
+ icon: /*#__PURE__*/React__namespace.createElement(theme.Add, null),
3542
+ action: addChangeGroupAbove
3721
3543
  };
3544
+ var insertBelow = {
3545
+ text: 'Insert 1 row below',
3546
+ icon: /*#__PURE__*/React__namespace.createElement(theme.Add, null),
3547
+ action: addChangeGroupBelow
3548
+ };
3549
+ var deleteRow = {
3550
+ text: 'Delete row',
3551
+ icon: /*#__PURE__*/React__namespace.createElement(theme.Delete, null),
3552
+ action: removeChangeGroup
3553
+ };
3554
+ var clear = {
3555
+ text: 'Clear row',
3556
+ icon: /*#__PURE__*/React__namespace.createElement(theme.Close, null),
3557
+ action: clearRow
3558
+ };
3559
+ var menuItemsBaseForecast = [insertBelow, clear];
3560
+ var menuItemsChangeGroup = [insertAbove, insertBelow, deleteRow, clear];
3561
+ return /*#__PURE__*/React__namespace.createElement(shared.ToggleMenu, {
3562
+ buttonTestId: "tafFormOptions[" + index + "]",
3563
+ buttonSx: {
3564
+ marginTop: '10px',
3565
+ marginLeft: '4px'
3566
+ },
3567
+ menuItems: isChangeGroup ? menuItemsChangeGroup : menuItemsBaseForecast
3568
+ });
3569
+ };
3722
3570
 
3723
- var onClickButton = function onClickButton(event) {
3724
- var _a;
3725
-
3726
- var _b = event.currentTarget.getBoundingClientRect(),
3727
- left = _b.left,
3728
- top = _b.top;
3571
+ var getDefaultValue = function getDefaultValue(fieldName, data) {
3572
+ if (!data) {
3573
+ return '';
3574
+ }
3729
3575
 
3730
- var parentOffset = ((_a = document.getElementById('tafmodule')) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) || {
3731
- top: 0,
3732
- left: 0
3733
- };
3734
- var newPosition = {
3735
- left: left - parentOffset.left + 100,
3736
- top: top - parentOffset.top
3737
- };
3738
- toggleIssuesPane(newPosition);
3739
- };
3576
+ return formFields.getDeepProperty(fieldName.split('.'), data) || '';
3577
+ };
3740
3578
 
3741
- return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3742
- title: "View details"
3743
- }, /*#__PURE__*/React__namespace.createElement(material.Chip, {
3744
- "data-testid": "issuesButton",
3745
- className: "status-" + errorStatus,
3746
- size: "small",
3747
- label: getIssuesLabel(totalErrors),
3748
- onClick: onClickButton,
3749
- sx: {
3750
- width: '74px',
3751
- color: '#ffffff',
3752
- backgroundColor: buttonColor,
3753
- '&:hover': {
3754
- backgroundColor: buttonColor
3755
- },
3756
- '&:focus': {
3757
- backgroundColor: buttonColor
3758
- },
3759
- fontSize: 12
3760
- }
3761
- }));
3579
+ var getRequiredCrossFields = function getRequiredCrossFields(fieldNames) {
3580
+ return [[fieldNames.valid], [fieldNames.change, fieldNames.probability], [fieldNames.wind, fieldNames.visibility, fieldNames.weather1, fieldNames.cloud1] // sub fields
3581
+ ];
3762
3582
  };
3763
3583
 
3764
- var getPaneTitle = function getPaneTitle(sumOfErrors) {
3765
- switch (sumOfErrors) {
3766
- case 0:
3767
- return 'Looks good';
3584
+ var TafFormRow = /*#__PURE__*/React__default["default"].forwardRef(function (_a, ref) {
3585
+ var isNotRequiredForAction = _a.isNotRequiredForAction,
3586
+ _b = _a.isChangeGroup,
3587
+ isChangeGroup = _b === void 0 ? false : _b,
3588
+ _c = _a.disabled,
3589
+ disabled = _c === void 0 ? false : _c,
3590
+ _d = _a.index,
3591
+ index = _d === void 0 ? -1 : _d,
3592
+ onRemoveChangeGroup = _a.onRemoveChangeGroup,
3593
+ _e = _a.field,
3594
+ field = _e === void 0 ? null : _e,
3595
+ _f = _a.dragHandle,
3596
+ dragHandle = _f === void 0 ? null : _f,
3597
+ onAddChangeGroupBelow = _a.onAddChangeGroupBelow,
3598
+ onAddChangeGroupAbove = _a.onAddChangeGroupAbove,
3599
+ onClearRow = _a.onClearRow,
3600
+ props = __rest(_a, ["isNotRequiredForAction", "isChangeGroup", "disabled", "index", "onRemoveChangeGroup", "field", "dragHandle", "onAddChangeGroupBelow", "onAddChangeGroupAbove", "onClearRow"]);
3768
3601
 
3769
- case 1:
3770
- return 'There is an issue to address';
3602
+ var namePrefix = !isChangeGroup ? 'baseForecast' : "changeGroups[" + index + "]";
3603
+ var fieldNames = getFieldNames(isChangeGroup, index);
3771
3604
 
3772
- default:
3773
- return 'There are a few issues to address';
3774
- }
3775
- };
3605
+ var _g = reactHookForm.useFormContext(),
3606
+ getValues = _g.getValues,
3607
+ trigger = _g.trigger; // cross-field required validation
3776
3608
 
3777
- var humanizeErrorMessage = function humanizeErrorMessage(errorTitle, fieldNumberedValue) {
3778
- if (fieldNumberedValue !== undefined && fieldNumberedValue >= 0) {
3779
- // when name contains a number we assume it's a formgroup and we add a index +1 for human readability
3780
- var fieldNumber = fieldNumberedValue + 1;
3781
- return errorTitle + " " + fieldNumber;
3782
- }
3783
3609
 
3784
- return errorTitle;
3785
- };
3786
- var getErrorMessage = function getErrorMessage(error, index) {
3787
- var errorTitleCategory = error.isChangeGroup ? 'Changegroups' : 'Baseforecast';
3788
- var fieldErrorTitle = humanizeErrorMessage(errorTitleCategory, error.rowIndex);
3789
- return index + 1 + ". " + fieldErrorTitle + ": " + error.message;
3790
- };
3791
- var MODAL_DIALOG_ELEMENT = 'modal-dialog';
3792
- var useIssuesPane = function useIssuesPane() {
3793
- var _a = __read(React__namespace.useState(false), 2),
3794
- isIssuesPaneOpen = _a[0],
3795
- setIsIssuesPaneOpen = _a[1];
3610
+ var _h = __read(getRequiredCrossFields(fieldNames), 3),
3611
+ mainFields = _h[0],
3612
+ mainOptionalFields = _h[1],
3613
+ subFields = _h[2];
3796
3614
 
3797
- var _b = __read(React__namespace.useState(null), 2),
3798
- startPosition = _b[0],
3799
- setStartPosition = _b[1];
3615
+ var hasFieldsValue = function hasFieldsValue(fields) {
3616
+ return fields.map(getValues).find(function (field) {
3617
+ return !!field;
3618
+ });
3619
+ }; // Used to validate the required field for change groups: Valid
3800
3620
 
3801
- var onToggleIssuesPane = function onToggleIssuesPane(isOpen, newPosition) {
3802
- if (!startPosition) {
3803
- setStartPosition(newPosition);
3621
+
3622
+ var validateRequiredMain = function validateRequiredMain(value) {
3623
+ return isNotRequiredForAction(value) !== true && isChangeGroup && !value.length && (hasFieldsValue(subFields) || hasFieldsValue(mainFields) || hasFieldsValue(mainOptionalFields)) ? 'Valid is required' : true;
3624
+ }; // Used to ensure either probability or change is entered, or both
3625
+
3626
+
3627
+ var validateRequiredMainOptional = function validateRequiredMainOptional(value) {
3628
+ return isNotRequiredForAction(value) !== true && isChangeGroup && (hasFieldsValue(mainFields) || hasFieldsValue(subFields)) && !hasFieldsValue(mainOptionalFields) ? 'Probability or change is required' : true;
3629
+ }; // Used to ensure one wind, visibility, weather or cloud is entered when start editing a changegroup and all of these are empty
3630
+
3631
+
3632
+ var validateRequiredSub = function validateRequiredSub(value) {
3633
+ return isNotRequiredForAction(value) !== true && isChangeGroup && (hasFieldsValue(mainFields) || hasFieldsValue(mainOptionalFields)) && !hasFieldsValue(subFields) ? 'Wind, visibility, weather or cloud is required' : true;
3634
+ }; // Used to validate the combination of change group and wind, visibility, weather and/or cloud data entered
3635
+
3636
+
3637
+ var _validateRequiredMainFields = function validateRequiredMainFields(value, fieldName) {
3638
+ var changeField = getValues(namePrefix + ".change");
3639
+ var visibilityField = getValues(namePrefix + ".visibility");
3640
+ var isFM = changeField && changeField.trim() === 'FM';
3641
+ var isCAVOK = visibilityField && visibilityField.trim() === 'CAVOK';
3642
+
3643
+ if (isNotRequiredForAction(value) !== true && !value.length) {
3644
+ if (isChangeGroup && isFM || !isChangeGroup) {
3645
+ // exception for CavOK
3646
+ if (isCAVOK && (fieldName === 'Clouds' || fieldName === 'Weather')) {
3647
+ return true;
3648
+ } // exception for visibility > 5000
3649
+
3650
+
3651
+ if (visibilityField && parseInt(visibilityField.trim(), 10) >= 5000 && fieldName === 'Weather') {
3652
+ return true;
3653
+ }
3654
+
3655
+ return fieldName + " is required";
3656
+ }
3657
+ }
3658
+
3659
+ return true;
3660
+ };
3661
+
3662
+ var validatePreviousRow = React__default["default"].useCallback(function () {
3663
+ if (isChangeGroup && index > 0) {
3664
+ var _a = getValues(),
3665
+ validDateEnd = _a.validDateEnd,
3666
+ validDateStart = _a.validDateStart,
3667
+ changeGroups = _a.changeGroups;
3668
+
3669
+ var currentChangeGroup = changeGroups[index];
3670
+ var previousChangeGroup = changeGroups[index - 1];
3671
+ return validatePreviousChangeGroup(currentChangeGroup, previousChangeGroup, validDateStart, validDateEnd);
3672
+ }
3673
+
3674
+ return true;
3675
+ }, [index, isChangeGroup, getValues]);
3676
+
3677
+ var getFieldFromRow = function getFieldFromRow(fieldname, rowIndex) {
3678
+ var indexedFieldName = "changeGroups[" + rowIndex + "]." + fieldname;
3679
+ var rowValue = getValues(indexedFieldName);
3680
+ return rowValue ? [indexedFieldName] : [];
3681
+ };
3682
+
3683
+ var getValidFieldFromNextRow = function getValidFieldFromNextRow() {
3684
+ return getFieldFromRow('valid', index + 1);
3685
+ };
3686
+
3687
+ var validateNextRows = React__default["default"].useCallback(function () {
3688
+ if (isChangeGroup) {
3689
+ var _a = getValues(),
3690
+ validDateEnd = _a.validDateEnd,
3691
+ validDateStart = _a.validDateStart,
3692
+ changeGroups = _a.changeGroups;
3693
+
3694
+ var currentChangeGroup = changeGroups[index];
3695
+ var nextChangeGroups = changeGroups.slice(index + 1);
3696
+ return validateOverlapWithFM(currentChangeGroup, nextChangeGroups, validDateStart, validDateEnd);
3697
+ }
3698
+
3699
+ return true;
3700
+ }, [index, isChangeGroup, getValues]);
3701
+
3702
+ var getPreviousValidFields = function getPreviousValidFields(rowIndex) {
3703
+ var changeGroups = getValues().changeGroups;
3704
+ var previousChangeGroups = changeGroups.slice(0, rowIndex);
3705
+ var validFields = previousChangeGroups.map(function (_element, index) {
3706
+ return getFieldFromRow('valid', index)[0];
3707
+ });
3708
+ return validFields;
3709
+ };
3710
+
3711
+ var addChangeGroupBelow = React__default["default"].useCallback(function () {
3712
+ onAddChangeGroupBelow(index);
3713
+ }, [onAddChangeGroupBelow, index]);
3714
+ var addChangeGroupAbove = React__default["default"].useCallback(function () {
3715
+ onAddChangeGroupAbove(index);
3716
+ }, [onAddChangeGroupAbove, index]);
3717
+ var clearRow = React__default["default"].useCallback(function () {
3718
+ onClearRow(index);
3719
+ }, [onClearRow, index]);
3720
+ return /*#__PURE__*/React__default["default"].createElement(material.Grid, __assign({
3721
+ sx: {
3722
+ marginTop: '8px',
3723
+ backgroundColor: 'geowebColors.cards.cardContainer',
3724
+ position: 'relative',
3725
+ '&.sortable-chosen': {
3726
+ boxShadow: 1
3727
+ },
3728
+ '&.sortable-ghost': {
3729
+ opacity: 0.5
3730
+ }
3731
+ },
3732
+ justifyContent: "flex-start",
3733
+ "data-testid": "row-" + namePrefix,
3734
+ container: true,
3735
+ ref: ref
3736
+ }, props, {
3737
+ className: "formRow"
3738
+ }), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
3739
+ columns: 24,
3740
+ item: true,
3741
+ container: true,
3742
+ justifyContent: "flex-end",
3743
+ xs: 24,
3744
+ sm: 23
3745
+ }, !isChangeGroup && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3746
+ label: "Type",
3747
+ name: fieldNames.messageType,
3748
+ disabled: true
3749
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3750
+ label: "Location",
3751
+ name: "location",
3752
+ disabled: true
3753
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3754
+ formatter: formatIssueTime,
3755
+ label: "Issue time",
3756
+ name: "issueDate",
3757
+ disabled: true
3758
+ })), isChangeGroup && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(material.Box, {
3759
+ sx: {
3760
+ width: 56,
3761
+ marginRight: '2px'
3762
+ }
3763
+ }, !disabled && dragHandle), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3764
+ label: "Prob",
3765
+ name: fieldNames.probability,
3766
+ disabled: disabled,
3767
+ defaultValue: getDefaultValue('probability', field),
3768
+ rules: {
3769
+ validate: {
3770
+ validateRequiredMainOptional: validateRequiredMainOptional,
3771
+ validateProbabilityField: validateProbabilityField
3772
+ }
3773
+ },
3774
+ autoComplete: [{
3775
+ key: '3',
3776
+ value: 'PROB30'
3777
+ }, {
3778
+ key: '4',
3779
+ value: 'PROB40'
3780
+ }],
3781
+ onBlur: function onBlur() {
3782
+ if (isChangeGroup) {
3783
+ var nextValidFieldName = getValidFieldFromNextRow();
3784
+ trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)));
3785
+ }
3786
+ }
3787
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3788
+ label: "Change",
3789
+ name: fieldNames.change,
3790
+ disabled: disabled,
3791
+ defaultValue: getDefaultValue('change', field),
3792
+ rules: {
3793
+ validate: {
3794
+ validateRequiredMainOptional: validateRequiredMainOptional,
3795
+ validateChangeField: validateChangeField,
3796
+ validateChangeFieldInterField: function validateChangeFieldInterField$1(value) {
3797
+ return validateChangeFieldInterField(value, getValues(fieldNames.probability));
3798
+ }
3799
+ }
3800
+ },
3801
+ autoComplete: [{
3802
+ key: 'T',
3803
+ value: 'TEMPO'
3804
+ }, {
3805
+ key: 'B',
3806
+ value: 'BECMG'
3807
+ }, {
3808
+ key: 'F',
3809
+ value: 'FM'
3810
+ }],
3811
+ onBlur: function onBlur() {
3812
+ if (isChangeGroup) {
3813
+ var nextValidFieldName = getValidFieldFromNextRow();
3814
+ var previousValidFieldNames = getPreviousValidFields(index);
3815
+ trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)), __read(previousValidFieldNames)));
3816
+ }
3817
+ }
3818
+ })), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3819
+ label: "Valid",
3820
+ name: fieldNames.valid,
3821
+ // always disabled for baseforecast row
3822
+ disabled: !isChangeGroup ? true : disabled,
3823
+ defaultValue: getDefaultValue('valid', field),
3824
+ rules: {
3825
+ validate: {
3826
+ validateRequiredMain: validateRequiredMain,
3827
+ validateValidField: function validateValidField$1(value) {
3828
+ return isChangeGroup ? validateValidField(value, getValues('validDateStart'), getValues('validDateEnd')) : true;
3829
+ },
3830
+ validateValidChangeGroupInterField: function validateValidChangeGroupInterField$1(value) {
3831
+ return isChangeGroup ? validateValidChangeGroupInterField(value, getValues(fieldNames.change), getValues(fieldNames.probability), getValues('validDateStart'), getValues('validDateEnd')) : true;
3832
+ },
3833
+ validatePreviousRow: validatePreviousRow,
3834
+ validateNextRows: validateNextRows
3835
+ }
3836
+ },
3837
+ onBlur: function onBlur() {
3838
+ if (isChangeGroup) {
3839
+ var nextValidFieldName = getValidFieldFromNextRow();
3840
+ var previousValidFieldNames = getPreviousValidFields(index);
3841
+ trigger(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(subFields)), __read(mainOptionalFields)), __read(mainFields)), __read(nextValidFieldName)), __read(previousValidFieldNames)));
3842
+ }
3843
+ }
3844
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3845
+ label: "Wind",
3846
+ name: fieldNames.wind,
3847
+ disabled: disabled,
3848
+ defaultValue: getDefaultValue('wind', field),
3849
+ rules: {
3850
+ validate: {
3851
+ validateRequiredMainFields: function validateRequiredMainFields(value) {
3852
+ return _validateRequiredMainFields(value, 'Wind');
3853
+ },
3854
+ validateRequiredSub: validateRequiredSub,
3855
+ validateWindField: function validateWindField$1(value) {
3856
+ return validateWindField(value, getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3857
+ }
3858
+ }
3859
+ },
3860
+ onBlur: function onBlur() {
3861
+ if (isChangeGroup) {
3862
+ trigger(__spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)));
3863
+ }
3864
+ },
3865
+ autoFocus: !isChangeGroup
3866
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3867
+ label: "Visibility",
3868
+ name: fieldNames.visibility,
3869
+ disabled: disabled,
3870
+ defaultValue: getDefaultValue('visibility', field),
3871
+ rules: {
3872
+ validate: {
3873
+ validateRequiredMainFields: function validateRequiredMainFields(value) {
3874
+ return _validateRequiredMainFields(value, 'Visibility');
3875
+ },
3876
+ validateRequiredSub: validateRequiredSub,
3877
+ validateVisibilityField: validateVisibilityField
3878
+ }
3879
+ },
3880
+ autoComplete: [{
3881
+ key: 'C',
3882
+ value: 'CAVOK'
3883
+ }],
3884
+ onBlur: function onBlur() {
3885
+ var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : subFields;
3886
+ trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather1, fieldNames.weather2, fieldNames.weather3]));
3887
+ }
3888
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3889
+ label: "Weather",
3890
+ name: fieldNames.weather1,
3891
+ disabled: disabled,
3892
+ defaultValue: getDefaultValue('weather.weather1', field),
3893
+ rules: {
3894
+ validate: {
3895
+ validateRequiredMainFields: function validateRequiredMainFields(value) {
3896
+ return _validateRequiredMainFields(value, 'Weather');
3897
+ },
3898
+ validateRequiredSub: validateRequiredSub,
3899
+ validateWeatherField: function validateWeatherField$1(value) {
3900
+ return validateWeatherField(value, getValues(fieldNames.visibility), !!isChangeGroup);
3901
+ }
3902
+ }
3903
+ },
3904
+ onBlur: function onBlur() {
3905
+ var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3906
+ return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather2, fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3907
+ }
3908
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3909
+ label: "Weather",
3910
+ name: fieldNames.weather2,
3911
+ disabled: disabled,
3912
+ defaultValue: getDefaultValue('weather.weather2', field),
3913
+ rules: {
3914
+ validate: {
3915
+ validateSecondWeatherField: function validateSecondWeatherField$1(value) {
3916
+ return validateSecondWeatherField(getValues(fieldNames.weather1), value, getValues(fieldNames.visibility));
3917
+ }
3918
+ }
3919
+ },
3920
+ onBlur: function onBlur() {
3921
+ var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3922
+ return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3923
+ }
3924
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3925
+ label: "Weather",
3926
+ name: fieldNames.weather3,
3927
+ disabled: disabled,
3928
+ defaultValue: getDefaultValue('weather.weather3', field),
3929
+ rules: {
3930
+ validate: {
3931
+ validateThirdWeatherField: function validateThirdWeatherField$1(value) {
3932
+ return validateThirdWeatherField(getValues(fieldNames.weather1), getValues(fieldNames.weather2), value, getValues(fieldNames.visibility));
3933
+ }
3934
+ }
3935
+ },
3936
+ onBlur: function onBlur() {
3937
+ return trigger([fieldNames.wind, fieldNames.cloud1]);
3938
+ }
3939
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3940
+ label: "Cloud",
3941
+ name: fieldNames.cloud1,
3942
+ disabled: disabled,
3943
+ defaultValue: getDefaultValue('cloud.cloud1', field),
3944
+ rules: {
3945
+ validate: {
3946
+ validateRequiredMainFields: function validateRequiredMainFields(value) {
3947
+ return _validateRequiredMainFields(value, 'Clouds');
3948
+ },
3949
+ validateRequiredSub: validateRequiredSub,
3950
+ validateFirstCloud: function validateFirstCloud$1(value) {
3951
+ return validateFirstCloud(value, getValues(fieldNames.visibility), getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3952
+ }
3953
+ }
3954
+ },
3955
+ onBlur: function onBlur() {
3956
+ var fields = isChangeGroup ? __spreadArray(__spreadArray([], __read(subFields)), __read(mainFields)) : [];
3957
+ return trigger(__spreadArray(__spreadArray([], __read(fields)), [fieldNames.cloud2, fieldNames.cloud3, fieldNames.cloud4]));
3804
3958
  }
3805
-
3806
- setIsIssuesPaneOpen(isOpen);
3807
- };
3808
-
3809
- var onCloseIssuesPane = function onCloseIssuesPane() {
3810
- return setIsIssuesPaneOpen(false);
3811
- };
3812
-
3813
- return {
3814
- isIssuesPaneOpen: isIssuesPaneOpen,
3815
- startPosition: startPosition,
3816
- onToggleIssuesPane: onToggleIssuesPane,
3817
- onCloseIssuesPane: onCloseIssuesPane
3818
- };
3819
- };
3820
-
3821
- var IssuesPane = function IssuesPane(_a) {
3822
- var _b = _a.errorList,
3823
- errorList = _b === void 0 ? [] : _b,
3824
- isOpen = _a.isOpen,
3825
- handleClose = _a.handleClose,
3826
- _c = _a.startPosition,
3827
- startPosition = _c === void 0 ? {
3828
- left: 20,
3829
- top: 50
3830
- } : _c;
3831
- var rootElement = document.getElementById(MODAL_DIALOG_ELEMENT) || document.body;
3832
- return /*#__PURE__*/ReactDOM__default["default"].createPortal( /*#__PURE__*/React__namespace.createElement(shared.ToolContainerDraggable, {
3833
- startSize: {
3834
- width: '577px',
3835
- height: '200px'
3959
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3960
+ label: "Cloud",
3961
+ name: fieldNames.cloud2,
3962
+ disabled: disabled,
3963
+ defaultValue: getDefaultValue('cloud.cloud2', field),
3964
+ rules: {
3965
+ validate: {
3966
+ validateSecondCloud: function validateSecondCloud$1(value) {
3967
+ return validateSecondCloud(getValues(fieldNames.cloud1), value, getValues(fieldNames.visibility));
3968
+ }
3969
+ }
3836
3970
  },
3837
- startPosition: startPosition,
3838
- minWidth: 300,
3839
- onClose: handleClose,
3840
- title: getPaneTitle(errorList.length),
3841
- headerSize: "xs",
3842
- isOpen: isOpen,
3843
- "data-testid": "moveable-issues-pane",
3844
- bounds: "parent"
3845
- }, /*#__PURE__*/React__namespace.createElement(material.Box, {
3846
- component: "div",
3847
- sx: {
3848
- marginTop: '16px',
3849
- marginLeft: '24px'
3971
+ onBlur: function onBlur() {
3972
+ return trigger([fieldNames.cloud3, fieldNames.cloud4]);
3850
3973
  }
3851
- }, errorList.length === 0 && /*#__PURE__*/React__namespace.createElement(material.Box, {
3852
- component: "div",
3853
- sx: {
3854
- fontSize: '4rem'
3974
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3975
+ label: "Cloud",
3976
+ name: fieldNames.cloud3,
3977
+ disabled: disabled,
3978
+ defaultValue: getDefaultValue('cloud.cloud3', field),
3979
+ rules: {
3980
+ validate: {
3981
+ validateThirdCloud: function validateThirdCloud$1(value) {
3982
+ return validateThirdCloud(getValues(fieldNames.cloud1), getValues(fieldNames.cloud2), value, getValues(fieldNames.visibility));
3983
+ }
3984
+ }
3855
3985
  },
3856
- "data-testid": "zeroIssuesImage"
3857
- }, /*#__PURE__*/React__namespace.createElement(theme.ThumbsUp, {
3858
- sx: {
3859
- height: '69px',
3860
- width: '58px'
3986
+ onBlur: function onBlur() {
3987
+ return trigger(fieldNames.cloud4);
3861
3988
  }
3862
- })), errorList.length > 0 && errorList.map(function (error, index) {
3863
- return /*#__PURE__*/React__namespace.createElement(material.Typography // eslint-disable-next-line react/no-array-index-key
3864
- , {
3865
- // eslint-disable-next-line react/no-array-index-key
3866
- key: "message-" + index,
3867
- variant: "body1",
3868
- "data-testid": "errorMessage"
3869
- }, getErrorMessage(error, index));
3870
- }))), rootElement);
3871
- };
3872
-
3873
- /* *
3874
- * Licensed under the Apache License, Version 2.0 (the "License");
3875
- * you may not use this file except in compliance with the License.
3876
- * You may obtain a copy of the License at
3877
- *
3878
- * http://www.apache.org/licenses/LICENSE-2.0
3879
- *
3880
- * Unless required by applicable law or agreed to in writing, software
3881
- * distributed under the License is distributed on an "AS IS" BASIS,
3882
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3883
- * See the License for the specific language governing permissions and
3884
- * limitations under the License.
3885
- *
3886
- * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3887
- * Copyright 2022 - Finnish Meteorological Institute (FMI)
3888
- * */
3889
- var TafModuleContext = /*#__PURE__*/React__namespace.createContext({
3890
- onValidateForm: null,
3891
- registerValidateForm: null,
3892
- tafAction: null,
3893
- setTafAction: null,
3894
- onPreventCloseView: null
3989
+ }), /*#__PURE__*/React__default["default"].createElement(TafFormTextField, {
3990
+ label: "Cloud",
3991
+ name: fieldNames.cloud4,
3992
+ disabled: disabled,
3993
+ defaultValue: getDefaultValue('cloud.cloud4', field),
3994
+ rules: {
3995
+ validate: {
3996
+ validateFourthCloud: function validateFourthCloud$1(value) {
3997
+ return validateFourthCloud(getValues(fieldNames.cloud1), getValues(fieldNames.cloud2), getValues(fieldNames.cloud3), value, getValues(fieldNames.visibility));
3998
+ }
3999
+ }
4000
+ }
4001
+ })), !disabled && /*#__PURE__*/React__default["default"].createElement(material.Grid, {
4002
+ item: true,
4003
+ container: true,
4004
+ justifyContent: "flex-end",
4005
+ alignItems: "flex-end",
4006
+ xs: 24,
4007
+ sm: 1,
4008
+ sx: {
4009
+ marginBottom: '16px'
4010
+ },
4011
+ columns: 24
4012
+ }, /*#__PURE__*/React__default["default"].createElement(TafFormOptionsButton, {
4013
+ isChangeGroup: isChangeGroup,
4014
+ addChangeGroupBelow: addChangeGroupBelow,
4015
+ addChangeGroupAbove: addChangeGroupAbove,
4016
+ removeChangeGroup: function removeChangeGroup() {
4017
+ return onRemoveChangeGroup(index);
4018
+ },
4019
+ clearRow: clearRow,
4020
+ index: index
4021
+ })));
3895
4022
  });
3896
- var useTafModuleContext = function useTafModuleContext() {
3897
- return React__namespace.useContext(TafModuleContext);
3898
- };
3899
- var useTafModuleState = function useTafModuleState(_a) {
3900
- var onPreventCloseView = _a.onPreventCloseView;
3901
-
3902
- var _b = __read(React__namespace.useState(function () {
3903
- return new Promise(function () {
3904
- return true;
3905
- });
3906
- }), 2),
3907
- onValidateForm = _b[0],
3908
- registerValidateForm = _b[1];
3909
-
3910
- var _c = __read(React__namespace.useState(), 2),
3911
- tafAction = _c[0],
3912
- setTafAction = _c[1];
3913
-
3914
- var onRegisterValidateForm = function onRegisterValidateForm(promiseToRegister) {
3915
- registerValidateForm(function () {
3916
- return promiseToRegister;
3917
- });
3918
- };
3919
-
3920
- return {
3921
- onValidateForm: onValidateForm,
3922
- registerValidateForm: onRegisterValidateForm,
3923
- tafAction: tafAction,
3924
- setTafAction: setTafAction,
3925
- onPreventCloseView: onPreventCloseView
3926
- };
3927
- };
3928
- var TafModuleProvider = function TafModuleProvider(_a) {
3929
- var children = _a.children,
3930
- _b = _a.onPreventCloseView,
3931
- onPreventCloseView = _b === void 0 ? function () {} : _b;
3932
- var contextState = useTafModuleState({
3933
- onPreventCloseView: onPreventCloseView
3934
- });
3935
- return /*#__PURE__*/React__namespace.createElement(TafModuleContext.Provider, {
3936
- value: contextState
3937
- }, children);
3938
- };
3939
-
3940
- var styles = {
3941
- label: {
3942
- color: 'geowebColors.buttons.tertiary.default.color',
3943
- opacity: 1,
3944
- fontSize: '12px',
3945
- fontWeight: 500
3946
- }
3947
- };
3948
-
3949
- var SwitchButton = function SwitchButton(props) {
3950
- return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3951
- title: "Switch mode"
3952
- }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(material.FormLabel, {
3953
- sx: styles.label
3954
- }, "Viewer"), /*#__PURE__*/React__namespace.createElement(material.Switch, __assign({
3955
- "data-testid": "switchMode"
3956
- }, props)), /*#__PURE__*/React__namespace.createElement(material.FormLabel, {
3957
- sx: styles.label
3958
- }, "Editor")));
3959
- };
3960
-
3961
- var TafAvatar = function TafAvatar(_a) {
3962
- var editor = _a.editor,
3963
- _b = _a.tooltipPlacement,
3964
- tooltipPlacement = _b === void 0 ? 'bottom' : _b;
3965
- return /*#__PURE__*/React__namespace.createElement(shared.CustomTooltip, {
3966
- title: "Editor: " + editor,
3967
- placement: tooltipPlacement
3968
- }, /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement(shared.Avatar, {
3969
- size: "small"
3970
- }, shared.getInitials(editor))));
3971
- };
3972
4023
 
3973
4024
  var noop = function noop() {};
3974
4025
 
@@ -4000,7 +4051,10 @@
4000
4051
  _h = _a.fetchNewTafList,
4001
4052
  fetchNewTafList = _h === void 0 ? function () {
4002
4053
  return null;
4003
- } : _h;
4054
+ } : _h,
4055
+ _j = _a.previousTaf,
4056
+ previousTaf = _j === void 0 ? null : _j;
4057
+ var formRef = React__default["default"].useRef();
4004
4058
  var originalTaf = tafFromBackend.taf,
4005
4059
  editor = tafFromBackend.editor;
4006
4060
  var auth = authentication.useAuthenticationContext().auth;
@@ -4009,41 +4063,41 @@
4009
4063
  var isDefaultDisabled = getIsFormDefaultDisabled(originalTaf.status);
4010
4064
  var confirmDialog = shared.useConfirmationDialog();
4011
4065
 
4012
- var _j = shared.useDraftFormHelpers(),
4013
- toggleIsDraft = _j.toggleIsDraft,
4014
- isNotRequiredForAction = _j.isRequired;
4015
-
4016
- var _k = useTafModuleContext(),
4017
- registerValidateForm = _k.registerValidateForm,
4018
- tafAction = _k.tafAction,
4019
- setTafAction = _k.setTafAction,
4020
- onPreventCloseView = _k.onPreventCloseView;
4021
-
4022
- var _l = reactHookForm.useFormContext(),
4023
- control = _l.control,
4024
- handleSubmit = _l.handleSubmit,
4025
- trigger = _l.trigger,
4026
- formState = _l.formState,
4027
- getValues = _l.getValues,
4028
- setValue = _l.setValue,
4029
- resetField = _l.resetField; // added this ignore as the build is failing otherwise on: Type instantiation is excessively deep and possibly infinite.
4066
+ var _k = shared.useDraftFormHelpers(),
4067
+ toggleIsDraft = _k.toggleIsDraft,
4068
+ isNotRequiredForAction = _k.isRequired;
4069
+
4070
+ var _l = useTafModuleContext(),
4071
+ registerValidateForm = _l.registerValidateForm,
4072
+ tafAction = _l.tafAction,
4073
+ setTafAction = _l.setTafAction,
4074
+ onPreventCloseView = _l.onPreventCloseView;
4075
+
4076
+ var _m = reactHookForm.useFormContext(),
4077
+ control = _m.control,
4078
+ handleSubmit = _m.handleSubmit,
4079
+ trigger = _m.trigger,
4080
+ formState = _m.formState,
4081
+ getValues = _m.getValues,
4082
+ setValue = _m.setValue,
4083
+ resetField = _m.resetField; // added this ignore as the build is failing otherwise on: Type instantiation is excessively deep and possibly infinite.
4030
4084
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4031
4085
  // @ts-ignore
4032
4086
 
4033
4087
 
4034
- var _m = reactHookForm.useFieldArray({
4088
+ var _o = reactHookForm.useFieldArray({
4035
4089
  control: control,
4036
4090
  name: 'changeGroups'
4037
4091
  }),
4038
- fields = _m.fields,
4039
- insert = _m.insert,
4040
- remove = _m.remove,
4041
- move = _m.move;
4092
+ fields = _o.fields,
4093
+ insert = _o.insert,
4094
+ remove = _o.remove,
4095
+ move = _o.move;
4042
4096
 
4043
- var _o = useDragOrder(trigger, move),
4044
- onChangeOrder = _o.onChangeOrder,
4045
- onStartDrag = _o.onStartDrag,
4046
- activeDraggingIndex = _o.activeDraggingIndex;
4097
+ var _p = useDragOrder(trigger, move),
4098
+ onChangeOrder = _p.onChangeOrder,
4099
+ onStartDrag = _p.onStartDrag,
4100
+ activeDraggingIndex = _p.activeDraggingIndex;
4047
4101
 
4048
4102
  var dirtyFields = formState.dirtyFields,
4049
4103
  errors = formState.errors;
@@ -4064,7 +4118,8 @@
4064
4118
  return confirmDialog({
4065
4119
  title: getConfirmationDialogTitle(action),
4066
4120
  description: getConfirmationDialogContent(action, function () {
4067
- return isTafAmendedCorrectedChanged(isFormDirty$1, originalTaf, convertTafValuesToObject(getValues()));
4121
+ return isTafAmendedCorrectedChanged( // If already saved as draft amd/cor then send over the previous taf
4122
+ originalTaf.status === 'DRAFT_AMENDED' || originalTaf.status === 'DRAFT_CORRECTED' ? previousTaf : originalTaf, convertTafValuesToObject(getValues()));
4068
4123
  }),
4069
4124
  confirmLabel: getConfirmationDialogButtonLabel(action)
4070
4125
  });
@@ -4271,11 +4326,32 @@
4271
4326
 
4272
4327
  return [2
4273
4328
  /*return*/
4274
- ];
4329
+ , true];
4275
4330
  }
4276
4331
  });
4277
4332
  });
4278
- })();
4333
+ })().then(function () {
4334
+ var hasFormErrors = Object.keys(errors).length;
4335
+ var formNodeRef = formRef.current;
4336
+
4337
+ if (hasFormErrors && formNodeRef) {
4338
+ var inputsWithError = formNodeRef.querySelectorAll('.Mui-error');
4339
+ var firstFormGroupWithError = inputsWithError.length ? inputsWithError[inputsWithError.length - 1].closest('.formRow') : null;
4340
+
4341
+ if (firstFormGroupWithError) {
4342
+ var _a = getFormRowPosition(firstFormGroupWithError),
4343
+ top_1 = _a.top,
4344
+ left = _a.left;
4345
+
4346
+ var tafModuleNode = formNodeRef.closest('#tafmodule');
4347
+ var newTop = top_1 - (tafModuleNode === null || tafModuleNode === void 0 ? void 0 : tafModuleNode.getBoundingClientRect().top) || 0;
4348
+ setIsIssuesPaneOpen(true, {
4349
+ top: newTop,
4350
+ left: left
4351
+ });
4352
+ }
4353
+ }
4354
+ });
4279
4355
  break;
4280
4356
 
4281
4357
  default:
@@ -4395,9 +4471,9 @@
4395
4471
  });
4396
4472
  };
4397
4473
 
4398
- var _p = __read(React__default["default"].useState(false), 2),
4399
- shouldValidate = _p[0],
4400
- setShouldValidate = _p[1];
4474
+ var _q = __read(React__default["default"].useState(false), 2),
4475
+ shouldValidate = _q[0],
4476
+ setShouldValidate = _q[1];
4401
4477
 
4402
4478
  React__default["default"].useEffect(function () {
4403
4479
  setIsDisabled(!isEditor || isDefaultDisabled); // set validate flag to validate after the values have been set
@@ -4474,7 +4550,8 @@
4474
4550
  editor: editor
4475
4551
  }))), /*#__PURE__*/React__default["default"].createElement("form", {
4476
4552
  "data-testid": "taf-form",
4477
- onSubmit: handleSubmit(onSubmit)
4553
+ onSubmit: handleSubmit(onSubmit),
4554
+ ref: formRef
4478
4555
  }, /*#__PURE__*/React__default["default"].createElement(TafFormRow, {
4479
4556
  disabled: isDisabled,
4480
4557
  onAddChangeGroupBelow: onAddRow,
@@ -4771,6 +4848,14 @@
4771
4848
 
4772
4849
  return 0;
4773
4850
  };
4851
+ var getPreviousTaf = function getPreviousTaf(tafList, currentTaf) {
4852
+ var previousId = currentTaf.taf.previousId;
4853
+ if (!previousId) return null;
4854
+ var previousTaf = tafList.find(function (taf) {
4855
+ return taf.taf.uuid === previousId;
4856
+ });
4857
+ return previousTaf ? previousTaf.taf : null;
4858
+ };
4774
4859
 
4775
4860
  /* *
4776
4861
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -5574,7 +5659,10 @@
5574
5659
  _j = _a.fetchNewTafList,
5575
5660
  fetchNewTafList = _j === void 0 ? function () {
5576
5661
  return null;
5577
- } : _j;
5662
+ } : _j,
5663
+ _k = _a.previousTaf,
5664
+ previousTaf = _k === void 0 ? null : _k,
5665
+ tafAction = _a.tafAction;
5578
5666
  var severity = isWarning(error) ? 'warning' : 'error';
5579
5667
 
5580
5668
  var onTafAction = function onTafAction(action, taf) {
@@ -5676,7 +5764,7 @@
5676
5764
  index: index,
5677
5765
  "data-testid": "taf-panel" + (activeTafIndex === index ? '-active' : '')
5678
5766
  }, /*#__PURE__*/React__default["default"].createElement(TafHeader, {
5679
- title: getTafStatusLabel(tafFromBackend.taf.status),
5767
+ title: getTafStatusLabel(tafFromBackend.taf.status, tafAction, isFormDisabled),
5680
5768
  sx: {
5681
5769
  marginBottom: '4px'
5682
5770
  }
@@ -5709,7 +5797,8 @@
5709
5797
  isDisabled: isFormDisabled,
5710
5798
  setIsDisabled: setIsFormDisabled,
5711
5799
  onSwitchEditor: patchTaf,
5712
- fetchNewTafList: fetchNewTafList
5800
+ fetchNewTafList: fetchNewTafList,
5801
+ previousTaf: previousTaf
5713
5802
  })));
5714
5803
  };
5715
5804
 
@@ -5804,7 +5893,7 @@
5804
5893
  return 'Saved as draft';
5805
5894
 
5806
5895
  case 'DRAFT_AMENDED':
5807
- return 'Saved as draft amended';
5896
+ return 'Saved as draft amendment';
5808
5897
 
5809
5898
  case 'DRAFT_CORRECTED':
5810
5899
  return 'Saved as draft correction';
@@ -5842,7 +5931,8 @@
5842
5931
  isIssuesPaneOpen = _d.isIssuesPaneOpen,
5843
5932
  onToggleIssuesPane = _d.onToggleIssuesPane,
5844
5933
  onCloseIssuesPane = _d.onCloseIssuesPane,
5845
- startPosition = _d.startPosition;
5934
+ startPosition = _d.startPosition,
5935
+ onUserHasDragged = _d.onUserHasDragged;
5846
5936
 
5847
5937
  var _e = usePostTafRequest(api$1.postTaf),
5848
5938
  isLoading = _e.isLoading,
@@ -6182,7 +6272,9 @@
6182
6272
  patchTaf: patchTaf,
6183
6273
  isLoading: isLoading,
6184
6274
  error: error,
6185
- fetchNewTafList: onUpdateTaf
6275
+ fetchNewTafList: onUpdateTaf,
6276
+ previousTaf: getPreviousTaf(tafList, tafFromBackend),
6277
+ tafAction: tafAction
6186
6278
  });
6187
6279
  }))), /*#__PURE__*/React__default["default"].createElement(material.Grid, {
6188
6280
  item: true,
@@ -6205,7 +6297,8 @@
6205
6297
  })))))), /*#__PURE__*/React__default["default"].createElement(IssuesPaneWrapper, {
6206
6298
  handleClose: onCloseIssuesPane,
6207
6299
  isOpen: isIssuesPaneOpen,
6208
- startPosition: startPosition
6300
+ startPosition: startPosition,
6301
+ onUserHasDragged: onUserHasDragged
6209
6302
  }));
6210
6303
  };
6211
6304
 
@@ -7197,15 +7290,21 @@
7197
7290
  }
7198
7291
  };
7199
7292
 
7293
+ var _d = fakeDraftAmendmentTaf.taf;
7294
+ _d.changeGroups;
7295
+ var fakeDraftAmendmentWithoutChangeGroups = __rest(_d, ["changeGroups"]); // Only use for display purposes in the list!
7296
+
7297
+
7200
7298
  ({
7201
7299
  creationDate: "2022-01-06T14:00:00Z",
7202
7300
  canbe: ['DRAFTED', 'DISCARDED', 'PUBLISHED'],
7203
7301
  editor: null,
7204
- taf: __assign(__assign({}, fakeDraftAmendmentTaf.taf), {
7302
+ taf: __assign(__assign({}, fakeDraftAmendmentWithoutChangeGroups), {
7205
7303
  location: 'EHRD',
7206
7304
  baseTime: "2022-01-06T12:00:00Z",
7207
7305
  validDateStart: "2022-01-06T14:00:00Z",
7208
7306
  validDateEnd: "2022-01-07T18:00:00Z",
7307
+ previousId: "previousIdOfPreviousTAF",
7209
7308
  previousValidDateStart: "2022-01-06T12:00:00Z",
7210
7309
  previousValidDateEnd: "2022-01-07T18:00:00Z",
7211
7310
  baseForecast: __assign(__assign({}, fakeDraftAmendmentTaf.taf.baseForecast), {
@@ -7213,8 +7312,32 @@
7213
7312
  start: "2022-01-06T14:00:00Z",
7214
7313
  end: "2022-01-07T18:00:00Z"
7215
7314
  }
7216
- }),
7217
- changeGroups: []
7315
+ })
7316
+ })
7317
+ }); // Use as the original previous TAF for TAF above
7318
+
7319
+ ({
7320
+ creationDate: "2022-01-06T14:00:00Z",
7321
+ canbe: ['DRAFTED', 'DISCARDED', 'PUBLISHED'],
7322
+ editor: null,
7323
+ taf: __assign(__assign({}, fakeDraftAmendmentWithoutChangeGroups), {
7324
+ status: 'AMENDED',
7325
+ uuid: 'previousIdOfPreviousTAF',
7326
+ location: 'EHRD',
7327
+ baseTime: "2022-01-06T12:00:00Z",
7328
+ validDateStart: "2022-01-06T14:00:00Z",
7329
+ validDateEnd: "2022-01-07T18:00:00Z",
7330
+ baseForecast: __assign(__assign({}, fakeDraftAmendmentTaf.taf.baseForecast), {
7331
+ valid: {
7332
+ start: "2022-01-06T14:00:00Z",
7333
+ end: "2022-01-07T18:00:00Z"
7334
+ },
7335
+ wind: {
7336
+ direction: 344,
7337
+ speed: 90,
7338
+ unit: 'KT'
7339
+ }
7340
+ })
7218
7341
  })
7219
7342
  });
7220
7343
  var fakeAmendmentTaf = {