@opengeoweb/taf 2.4.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -4,13 +4,13 @@ import { TextField, SvgIcon, Grid, Box, Button, IconButton, Tooltip, Chip, Typog
4
4
  import { useFormContext, Controller, useFieldArray } from 'react-hook-form';
5
5
  import { ReactSortable, Sortable } from 'react-sortablejs';
6
6
  import { getDeepProperty, ReactHookFormHiddenInput, ReactHookFormProvider } from '@opengeoweb/form-fields';
7
- import { useApiContext, useApi, createApiInstance } from '@opengeoweb/api';
8
- import { useIsMounted, ToggleMenu, useDraftFormHelpers, ToolContainerDraggable, useConfirmationDialog, usePreventBrowserClose, ToolButton, ToolHeader, AlertBanner, getAxiosErrorMessage, ConfirmationServiceProvider, usePoller } from '@opengeoweb/shared';
9
- import moment from 'moment';
7
+ import { useIsMounted, ToggleMenu, useDraftFormHelpers, ToolContainerDraggable, useConfirmationDialog, usePreventBrowserClose, ToolButton, ToolHeader, isAxiosError, getAxiosErrorMessage, AlertBanner, ConfirmationServiceProvider, usePoller, ErrorBoundary } from '@opengeoweb/shared';
10
8
  import { isEqual } from 'lodash';
9
+ import moment from 'moment';
11
10
  import makeStyles from '@mui/styles/makeStyles';
12
11
  import { DragIndicator, Schedule, CheckCircle } from '@mui/icons-material';
13
12
  import ReactDOM from 'react-dom';
13
+ import { useApiContext, useApi, createApiInstance, ApiProvider } from '@opengeoweb/api';
14
14
  import LinearProgress from '@mui/material/LinearProgress';
15
15
  import DoDisturbIcon from '@mui/icons-material/DoDisturb';
16
16
  import Box$1 from '@mui/material/Box';
@@ -1994,6 +1994,22 @@ var validateFourthCloud = function validateFourthCloud(firstCloudValue, secondCl
1994
1994
  return true;
1995
1995
  };
1996
1996
 
1997
+ var emptyBaseForecast = {
1998
+ wind: '',
1999
+ visibility: '',
2000
+ weather: {
2001
+ weather1: '',
2002
+ weather2: '',
2003
+ weather3: ''
2004
+ },
2005
+ cloud: {
2006
+ cloud1: '',
2007
+ cloud2: '',
2008
+ cloud3: '',
2009
+ cloud4: ''
2010
+ }
2011
+ }; // formatters
2012
+
1997
2013
  var formatIssueTime = function formatIssueTime(issueDate) {
1998
2014
  return issueDate ? "".concat(moment(issueDate).utc().format('DDHHmm'), "Z") : 'Not issued';
1999
2015
  };
@@ -2294,10 +2310,12 @@ var getFieldNames = function getFieldNames(isChangeGroup, index) {
2294
2310
  var TAC_MISSING_DATA = 'Missing data: no TAC can be generated';
2295
2311
  var TAC_NOT_AVAILABLE = 'No TAC available';
2296
2312
  var TAC_RETRIEVING_DATA = 'Retrieving TAC';
2313
+ var TAC_FAILED = 'Failed to retrieve TAC';
2314
+ var tacHasError = function tacHasError(tac) {
2315
+ return tac === TAC_MISSING_DATA || tac === TAC_NOT_AVAILABLE || tac === TAC_RETRIEVING_DATA || tac === TAC_FAILED;
2316
+ };
2297
2317
  var useTACGenerator = function useTACGenerator(taf, requestTAC) {
2298
- var standardTAC = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
2299
-
2300
- var _React$useState = React__default.useState(taf.status === 'NEW' ? TAC_NOT_AVAILABLE : TAC_RETRIEVING_DATA),
2318
+ var _React$useState = React__default.useState(!taf || taf.status === 'NEW' ? TAC_NOT_AVAILABLE : TAC_RETRIEVING_DATA),
2301
2319
  _React$useState2 = _slicedToArray(_React$useState, 2),
2302
2320
  TAC = _React$useState2[0],
2303
2321
  setTAC = _React$useState2[1];
@@ -2305,34 +2323,44 @@ var useTACGenerator = function useTACGenerator(taf, requestTAC) {
2305
2323
  var _useIsMounted = useIsMounted(),
2306
2324
  isMounted = _useIsMounted.isMounted;
2307
2325
 
2308
- var retrieveTAC = function retrieveTAC(tafToPost) {
2326
+ var controller = React__default.useRef(null);
2327
+
2328
+ var onSetTac = function onSetTac(newTAC) {
2329
+ if (controller.current) {
2330
+ controller.current.abort();
2331
+ }
2332
+
2333
+ setTAC(newTAC);
2334
+ };
2335
+
2336
+ var retrieveTAC = React__default.useCallback(function (tafToPost) {
2309
2337
  if (shouldRetrieveTAC(tafToPost)) {
2310
- requestTAC(tafToPost).then(function (result) {
2338
+ if (controller.current) {
2339
+ controller.current.abort();
2340
+ }
2341
+
2342
+ controller.current = new AbortController();
2343
+ setTAC(TAC_RETRIEVING_DATA);
2344
+ requestTAC(tafToPost, controller.current.signal).then(function (result) {
2311
2345
  if (isMounted.current) {
2312
2346
  setTAC(result.data);
2313
2347
  }
2314
- })["catch"](function () {
2315
- if (isMounted.current) {
2316
- setTAC('Failed to retrieve TAC');
2348
+ })["catch"](function (error) {
2349
+ if (isMounted && error.message !== 'canceled') {
2350
+ setTAC(TAC_FAILED);
2317
2351
  }
2318
2352
  });
2319
2353
  } else {
2320
2354
  setTAC(TAC_MISSING_DATA);
2321
2355
  }
2322
- };
2323
-
2356
+ }, [isMounted, requestTAC]);
2324
2357
  React__default.useEffect(function () {
2325
- if (taf.status !== 'NEW' && !standardTAC) {
2358
+ if (taf && taf.status !== 'NEW') {
2326
2359
  retrieveTAC(taf);
2327
2360
  } // eslint-disable-next-line react-hooks/exhaustive-deps
2328
2361
 
2329
2362
  }, []);
2330
- React__default.useEffect(function () {
2331
- if (standardTAC !== '') {
2332
- setTAC(standardTAC);
2333
- }
2334
- }, [standardTAC]);
2335
- return [TAC, retrieveTAC];
2363
+ return [TAC, retrieveTAC, onSetTac];
2336
2364
  };
2337
2365
  var useDragOrder = function useDragOrder(trigger, move, onFormBlur) {
2338
2366
  var _React$useState3 = React__default.useState(null),
@@ -2483,6 +2511,10 @@ var getMessageType = function getMessageType(taf, tafAction) {
2483
2511
  return 'AMD';
2484
2512
  }
2485
2513
 
2514
+ if (tafAction === 'CANCEL') {
2515
+ return 'CNL';
2516
+ }
2517
+
2486
2518
  return taf.messageType;
2487
2519
  }; // For corrections and amendment we need to add the previousValidStart and End for the TAC converter
2488
2520
 
@@ -2517,15 +2549,50 @@ var prepareTafValues = function prepareTafValues(_taf, tafAction) {
2517
2549
  // If action is AMEND/CORRECT/DRAFT_AMEND/DRAFT_CORRECTION - add previous valid start and end
2518
2550
  // If action is AMEND/DRAFT_AMEND - update validity start time to current time
2519
2551
  var taf = tafAction === 'AMEND' || tafAction === 'DRAFT_AMEND' || tafAction === 'CORRECT' || tafAction === 'DRAFT_CORRECT' ? getAmendedCorrectedTafTimes(_taf, tafAction) : _taf;
2552
+ var formattedBaseForecast = formatFormValues(taf.baseForecast);
2553
+ var baseForecast = Object.assign(Object.assign(Object.assign({}, emptyBaseForecast), formattedBaseForecast), {
2554
+ weather: Object.assign(Object.assign({}, emptyBaseForecast.weather), formattedBaseForecast.weather),
2555
+ cloud: Object.assign(Object.assign({}, emptyBaseForecast.cloud), formattedBaseForecast.cloud)
2556
+ });
2520
2557
  return Object.assign(Object.assign(Object.assign(Object.assign({}, taf), {
2521
2558
  messageType: getMessageType(taf, tafAction),
2522
- baseForecast: formatFormValues(taf.baseForecast)
2559
+ baseForecast: baseForecast
2523
2560
  }), taf.changeGroups && {
2524
2561
  changeGroups: taf.changeGroups.map(formatFormValues)
2525
2562
  }), addEmptyChangeGroup && {
2526
2563
  changeGroups: [emptyChangegroup]
2527
2564
  });
2528
2565
  };
2566
+ var getIsFormDefaultDisabled = function getIsFormDefaultDisabled(status) {
2567
+ return !(status === 'NEW' || status === 'DRAFT' || status === 'DRAFT_AMENDED' || status === 'DRAFT_CORRECTED');
2568
+ };
2569
+ var fromStatusToAction = function fromStatusToAction(tafStatus) {
2570
+ switch (tafStatus) {
2571
+ case 'DRAFT':
2572
+ return 'DRAFT';
2573
+
2574
+ case 'DRAFT_AMENDED':
2575
+ return 'DRAFT_AMEND';
2576
+
2577
+ case 'DRAFT_CORRECTED':
2578
+ return 'DRAFT_CORRECT';
2579
+
2580
+ case 'PUBLISHED':
2581
+ return 'PUBLISH';
2582
+
2583
+ case 'AMENDED':
2584
+ return 'AMEND';
2585
+
2586
+ case 'CORRECTED':
2587
+ return 'CORRECT';
2588
+
2589
+ case 'CANCELLED':
2590
+ return 'CANCEL';
2591
+
2592
+ default:
2593
+ return 'NEW';
2594
+ }
2595
+ };
2529
2596
 
2530
2597
  var textFieldStyle = function textFieldStyle(theme) {
2531
2598
  return {
@@ -2876,7 +2943,7 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2876
2943
  getValues = _useFormContext.getValues,
2877
2944
  trigger = _useFormContext.trigger;
2878
2945
 
2879
- var _useDraftFormHelpers = useDraftFormHelpers(),
2946
+ var _useDraftFormHelpers = useDraftFormHelpers(true),
2880
2947
  isNotRequiredForAction = _useDraftFormHelpers.isRequired; // cross-field required validation
2881
2948
 
2882
2949
 
@@ -3310,6 +3377,36 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3310
3377
  * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3311
3378
  * Copyright 2021 - Finnish Meteorological Institute (FMI)
3312
3379
  * */
3380
+ var tafActionToDraftAction = function tafActionToDraftAction(tafAction) {
3381
+ switch (tafAction) {
3382
+ case 'AMEND':
3383
+ case 'DRAFT_AMEND':
3384
+ return 'DRAFT_AMEND';
3385
+
3386
+ case 'CORRECT':
3387
+ case 'DRAFT_CORRECT':
3388
+ return 'DRAFT_CORRECT';
3389
+
3390
+ default:
3391
+ return 'DRAFT';
3392
+ }
3393
+ };
3394
+
3395
+ var tafActionToPublishAction = function tafActionToPublishAction(tafAction) {
3396
+ switch (tafAction) {
3397
+ case 'AMEND':
3398
+ case 'DRAFT_AMEND':
3399
+ return 'AMEND';
3400
+
3401
+ case 'CORRECT':
3402
+ case 'DRAFT_CORRECT':
3403
+ return 'CORRECT';
3404
+
3405
+ default:
3406
+ return 'PUBLISH';
3407
+ }
3408
+ };
3409
+
3313
3410
  var buttonsStyle = {
3314
3411
  button: {
3315
3412
  minWidth: {
@@ -3339,7 +3436,7 @@ var ViewModeButtons = function ViewModeButtons(_ref) {
3339
3436
  return onTafViewModeButtonPress('CANCEL');
3340
3437
  }
3341
3438
  }, "Cancel"), canBe.includes('CORRECTED') && /*#__PURE__*/React__default.createElement(Button, {
3342
- "data-testid": "correctaf",
3439
+ "data-testid": "correcttaf",
3343
3440
  variant: "tertiary",
3344
3441
  onClick: function onClick() {
3345
3442
  return onTafViewModeButtonPress('CORRECT');
@@ -3393,21 +3490,7 @@ var TafFormButtons = function TafFormButtons(_ref2) {
3393
3490
  if action DRAFT_AMEND - new status will be DRAFT_AMENDED
3394
3491
  if action DRAFT_CORRECT - new status will be DRAFT_CORRECTED
3395
3492
  */
3396
- switch (tafAction) {
3397
- case 'AMEND':
3398
- case 'DRAFT_AMEND':
3399
- onTafEditModeButtonPress('DRAFT_AMEND');
3400
- break;
3401
-
3402
- case 'CORRECT':
3403
- case 'DRAFT_CORRECT':
3404
- onTafEditModeButtonPress('DRAFT_CORRECT');
3405
- break;
3406
-
3407
- default:
3408
- onTafEditModeButtonPress('DRAFT');
3409
- break;
3410
- }
3493
+ onTafEditModeButtonPress(tafActionToDraftAction(tafAction));
3411
3494
  }
3412
3495
  }, "Save"), /*#__PURE__*/React__default.createElement(Button, {
3413
3496
  "data-testid": "publishtaf",
@@ -3420,21 +3503,7 @@ var TafFormButtons = function TafFormButtons(_ref2) {
3420
3503
  if action DRAFT_AMEND - new status will be AMENDED
3421
3504
  if action DRAFT_CORRECT - new status will be CORRECTED
3422
3505
  */
3423
- switch (tafAction) {
3424
- case 'AMEND':
3425
- case 'DRAFT_AMEND':
3426
- onTafEditModeButtonPress('AMEND');
3427
- break;
3428
-
3429
- case 'CORRECT':
3430
- case 'DRAFT_CORRECT':
3431
- onTafEditModeButtonPress('CORRECT');
3432
- break;
3433
-
3434
- default:
3435
- onTafEditModeButtonPress('PUBLISH');
3436
- break;
3437
- }
3506
+ onTafEditModeButtonPress(tafActionToPublishAction(tafAction));
3438
3507
  }
3439
3508
  }, "Publish"))), /*#__PURE__*/React__default.createElement(Grid, {
3440
3509
  item: true,
@@ -3703,20 +3772,6 @@ var getPaneTitle = function getPaneTitle(sumOfErrors) {
3703
3772
  }
3704
3773
  };
3705
3774
 
3706
- var getErrorDefaultMessage = function getErrorDefaultMessage(error) {
3707
- switch (error.type) {
3708
- case 'required':
3709
- {
3710
- return 'this field is required';
3711
- }
3712
-
3713
- default:
3714
- {
3715
- return error.message;
3716
- }
3717
- }
3718
- };
3719
-
3720
3775
  var capitalizeWord = function capitalizeWord(_ref) {
3721
3776
  var _ref2 = _toArray(_ref),
3722
3777
  firstLetter = _ref2[0],
@@ -3754,7 +3809,7 @@ var getErrorMessage = function getErrorMessage(error, index) {
3754
3809
  firstNamePart = _name$split2[0];
3755
3810
 
3756
3811
  var fieldErrorTitle = humanizeErrorMessage(firstNamePart);
3757
- return "".concat(index + 1, ". ").concat(fieldErrorTitle, ": ").concat(getErrorDefaultMessage(error));
3812
+ return "".concat(index + 1, ". ").concat(fieldErrorTitle, ": ").concat(error.message);
3758
3813
  };
3759
3814
  var MODAL_DIALOG_ELEMENT = 'modal-dialog';
3760
3815
  var useIssuesPane = function useIssuesPane() {
@@ -3835,76 +3890,121 @@ var IssuesPane = function IssuesPane(_ref3) {
3835
3890
  }))), rootElement);
3836
3891
  };
3837
3892
 
3838
- var fromStatusToAction = function fromStatusToAction(tafStatus) {
3839
- switch (tafStatus) {
3840
- case 'DRAFT':
3841
- return 'DRAFT';
3893
+ var TafModuleContext = /*#__PURE__*/React.createContext({
3894
+ onValidateForm: null,
3895
+ registerValidateForm: null,
3896
+ tafAction: null,
3897
+ setTafAction: null,
3898
+ isFormDirty: null,
3899
+ setIsFormDirty: null
3900
+ });
3901
+ var useTafModuleContext = function useTafModuleContext() {
3902
+ return React.useContext(TafModuleContext);
3903
+ };
3904
+ var useTafModuleState = function useTafModuleState(_ref) {
3905
+ var onPreventCloseView = _ref.onPreventCloseView;
3842
3906
 
3843
- case 'DRAFT_AMENDED':
3844
- return 'DRAFT_AMEND';
3907
+ var _useApiContext = useApiContext(),
3908
+ api = _useApiContext.api;
3845
3909
 
3846
- case 'DRAFT_CORRECTED':
3847
- return 'DRAFT_CORRECT';
3910
+ var _React$useState = React.useState(function () {
3911
+ return new Promise(function () {
3912
+ return true;
3913
+ });
3914
+ }),
3915
+ _React$useState2 = _slicedToArray(_React$useState, 2),
3916
+ onValidateForm = _React$useState2[0],
3917
+ registerValidateForm = _React$useState2[1];
3848
3918
 
3849
- case 'PUBLISHED':
3850
- return 'PUBLISH';
3919
+ var _React$useState3 = React.useState(),
3920
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
3921
+ tafAction = _React$useState4[0],
3922
+ setTafAction = _React$useState4[1];
3851
3923
 
3852
- case 'AMENDED':
3853
- return 'AMEND';
3924
+ var _React$useState5 = React.useState(false),
3925
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
3926
+ isFormDirty = _React$useState6[0],
3927
+ setIsFormDirty = _React$useState6[1];
3854
3928
 
3855
- case 'CORRECTED':
3856
- return 'CORRECT';
3929
+ var _useTACGenerator = useTACGenerator(undefined, api.getTAC),
3930
+ _useTACGenerator2 = _slicedToArray(_useTACGenerator, 3),
3931
+ TAC = _useTACGenerator2[0],
3932
+ updateTAC = _useTACGenerator2[1],
3933
+ setTAC = _useTACGenerator2[2];
3857
3934
 
3858
- case 'CANCELLED':
3859
- return 'CANCEL';
3935
+ var onRegisterValidateForm = function onRegisterValidateForm(promiseToRegister) {
3936
+ registerValidateForm(function () {
3937
+ return promiseToRegister;
3938
+ });
3939
+ };
3860
3940
 
3861
- default:
3862
- return 'NEW';
3863
- }
3864
- }; // prevents default functionality
3941
+ var onChangeFormDirty = function onChangeFormDirty(isDirty) {
3942
+ if (isDirty !== isFormDirty) {
3943
+ setIsFormDirty(isDirty);
3944
+ onPreventCloseView(isDirty);
3945
+ }
3946
+ };
3865
3947
 
3948
+ return {
3949
+ onValidateForm: onValidateForm,
3950
+ registerValidateForm: onRegisterValidateForm,
3951
+ tafAction: tafAction,
3952
+ setTafAction: setTafAction,
3953
+ TAC: TAC,
3954
+ updateTAC: updateTAC,
3955
+ setTAC: setTAC,
3956
+ isFormDirty: isFormDirty,
3957
+ setIsFormDirty: onChangeFormDirty
3958
+ };
3959
+ };
3960
+ var TafModuleProvider = function TafModuleProvider(_ref2) {
3961
+ var children = _ref2.children,
3962
+ _ref2$onPreventCloseV = _ref2.onPreventCloseView,
3963
+ onPreventCloseView = _ref2$onPreventCloseV === void 0 ? function () {} : _ref2$onPreventCloseV;
3964
+ var contextState = useTafModuleState({
3965
+ onPreventCloseView: onPreventCloseView
3966
+ });
3967
+ return /*#__PURE__*/React.createElement(TafModuleContext.Provider, {
3968
+ value: contextState
3969
+ }, children);
3970
+ };
3866
3971
 
3867
3972
  var noop = function noop() {};
3868
3973
 
3869
3974
  var TafForm = function TafForm(_ref) {
3870
- var _ref$isDisabled = _ref.isDisabled,
3871
- isDefaultDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled,
3872
- tafFromBackend = _ref.tafFromBackend,
3975
+ var tafFromBackend = _ref.tafFromBackend,
3873
3976
  _ref$onFormAction = _ref.onFormAction,
3874
3977
  onFormAction = _ref$onFormAction === void 0 ? function () {
3875
3978
  return null;
3876
3979
  } : _ref$onFormAction,
3877
- _ref$onFormDirty = _ref.onFormDirty,
3878
- onFormDirty = _ref$onFormDirty === void 0 ? function () {
3879
- return null;
3880
- } : _ref$onFormDirty,
3881
3980
  _ref$isIssuesPaneOpen = _ref.isIssuesPaneOpen,
3882
3981
  isIssuesPaneOpen = _ref$isIssuesPaneOpen === void 0 ? false : _ref$isIssuesPaneOpen,
3883
3982
  _ref$setIsIssuesPaneO = _ref.setIsIssuesPaneOpen,
3884
3983
  setIsIssuesPaneOpen = _ref$setIsIssuesPaneO === void 0 ? function () {
3885
3984
  return null;
3886
- } : _ref$setIsIssuesPaneO;
3985
+ } : _ref$setIsIssuesPaneO,
3986
+ _ref$isDisabled = _ref.isDisabled,
3987
+ isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled,
3988
+ _ref$setIsDisabled = _ref.setIsDisabled,
3989
+ setIsDisabled = _ref$setIsDisabled === void 0 ? function () {
3990
+ return null;
3991
+ } : _ref$setIsDisabled;
3887
3992
  var originalTaf = tafFromBackend.taf;
3888
- var defaultTafAction = fromStatusToAction(originalTaf.status);
3889
-
3890
- var _React$useState = React__default.useState(defaultTafAction),
3891
- _React$useState2 = _slicedToArray(_React$useState, 2),
3892
- tafAction = _React$useState2[0],
3893
- setTafAction = _React$useState2[1];
3894
-
3895
- var _React$useState3 = React__default.useState(isDefaultDisabled),
3896
- _React$useState4 = _slicedToArray(_React$useState3, 2),
3897
- isDisabled = _React$useState4[0],
3898
- setIsDisabled = _React$useState4[1];
3899
-
3993
+ var isDefaultDisabled = getIsFormDefaultDisabled(tafFromBackend.taf.status);
3900
3994
  var confirmDialog = useConfirmationDialog();
3901
3995
 
3902
- var _useDraftFormHelpers = useDraftFormHelpers(),
3996
+ var _useDraftFormHelpers = useDraftFormHelpers(true),
3903
3997
  toggleIsDraft = _useDraftFormHelpers.toggleIsDraft,
3904
3998
  DraftFieldHelper = _useDraftFormHelpers.DraftFieldHelper;
3905
3999
 
3906
- var _useApiContext = useApiContext(),
3907
- api = _useApiContext.api;
4000
+ var _useTafModuleContext = useTafModuleContext(),
4001
+ registerValidateForm = _useTafModuleContext.registerValidateForm,
4002
+ tafAction = _useTafModuleContext.tafAction,
4003
+ setIsFormDirty = _useTafModuleContext.setIsFormDirty,
4004
+ setTafAction = _useTafModuleContext.setTafAction,
4005
+ TAC = _useTafModuleContext.TAC,
4006
+ updateTAC = _useTafModuleContext.updateTAC,
4007
+ setTAC = _useTafModuleContext.setTAC;
3908
4008
 
3909
4009
  var _useIsMounted = useIsMounted(),
3910
4010
  isMounted = _useIsMounted.isMounted;
@@ -3923,20 +4023,25 @@ var TafForm = function TafForm(_ref) {
3923
4023
  usePreventBrowserClose(isFormDirty && !isDisabled);
3924
4024
  var hiddenInputFields = ['baseTime', 'issueDate', 'type', 'uuid', 'validDateStart', 'validDateEnd', 'status', 'previousId', 'previousValidDateStart', 'previousValidDateEnd'];
3925
4025
 
3926
- var _React$useState5 = React__default.useState(getValues()),
3927
- _React$useState6 = _slicedToArray(_React$useState5, 2),
3928
- delayedFormValues = _React$useState6[0],
3929
- setDelayedFormValues = _React$useState6[1];
3930
-
3931
- var _useTACGenerator = useTACGenerator(tafFromBackend.taf, api.getTAC),
3932
- _useTACGenerator2 = _slicedToArray(_useTACGenerator, 2),
3933
- TAC = _useTACGenerator2[0],
3934
- updateTAC = _useTACGenerator2[1];
4026
+ var _React$useState = React__default.useState(getValues()),
4027
+ _React$useState2 = _slicedToArray(_React$useState, 2),
4028
+ delayedFormValues = _React$useState2[0],
4029
+ setDelayedFormValues = _React$useState2[1];
3935
4030
 
3936
4031
  var hasErrors = Object.keys(errors).length;
3937
4032
 
3938
4033
  var onFormBlur = function onFormBlur() {
3939
- setDelayedFormValues(getValues());
4034
+ if (!isEqual(getValues(), delayedFormValues)) {
4035
+ setDelayedFormValues(getValues());
4036
+ }
4037
+ };
4038
+
4039
+ var resetTAC = function resetTAC() {
4040
+ if (originalTaf.status !== 'NEW') {
4041
+ updateTAC(originalTaf);
4042
+ } else {
4043
+ setTAC(TAC_NOT_AVAILABLE);
4044
+ }
3940
4045
  };
3941
4046
 
3942
4047
  React__default.useEffect(function () {
@@ -3955,8 +4060,8 @@ var TafForm = function TafForm(_ref) {
3955
4060
  }, [hasErrors]); // Needed to be able to show a confirmation dialog on switching tabs when form is edited and not saved
3956
4061
 
3957
4062
  React__default.useEffect(function () {
3958
- onFormDirty(isFormDirty);
3959
- }, [isFormDirty, onFormDirty]);
4063
+ setIsFormDirty(isFormDirty);
4064
+ }, [isFormDirty, setIsFormDirty]);
3960
4065
 
3961
4066
  var onSubmit = function onSubmit(data) {
3962
4067
  // eslint-disable-next-line no-console
@@ -3997,6 +4102,7 @@ var TafForm = function TafForm(_ref) {
3997
4102
  toggleIsDraft(true);
3998
4103
  handleSubmit(function (data) {
3999
4104
  onFormAction(action, convertTafValuesToObject(data));
4105
+ reset(getValues());
4000
4106
  })();
4001
4107
  break;
4002
4108
 
@@ -4004,6 +4110,7 @@ var TafForm = function TafForm(_ref) {
4004
4110
  if (isFormDirty) {
4005
4111
  showConfirmDialog(action).then(function () {
4006
4112
  resetForm(undefined, isDefaultDisabled);
4113
+ resetTAC();
4007
4114
  });
4008
4115
  } else {
4009
4116
  resetForm(undefined, isDefaultDisabled);
@@ -4058,7 +4165,7 @@ var TafForm = function TafForm(_ref) {
4058
4165
  switch (action) {
4059
4166
  case 'CANCEL':
4060
4167
  showConfirmDialog(action).then(function () {
4061
- onFormAction(action, tafFromBackend.taf);
4168
+ onFormAction(action, convertTafValuesToObject(prepareTafValues(tafFromBackend.taf, action)));
4062
4169
  });
4063
4170
  break;
4064
4171
 
@@ -4149,21 +4256,47 @@ var TafForm = function TafForm(_ref) {
4149
4256
  });
4150
4257
  };
4151
4258
 
4152
- var _React$useState7 = React__default.useState(false),
4153
- _React$useState8 = _slicedToArray(_React$useState7, 2),
4154
- shouldValidate = _React$useState8[0],
4155
- setShouldValidate = _React$useState8[1];
4259
+ var _React$useState3 = React__default.useState(false),
4260
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
4261
+ shouldValidate = _React$useState4[0],
4262
+ setShouldValidate = _React$useState4[1];
4156
4263
 
4157
4264
  React__default.useEffect(function () {
4158
- var defaultValues = prepareTafValues(tafFromBackend.taf, undefined, !isDisabled && !tafFromBackend.taf.changeGroups); // set initial form values
4265
+ setIsDisabled(isDefaultDisabled);
4266
+ var defaultValues = prepareTafValues(tafFromBackend.taf, undefined, !isDefaultDisabled && !tafFromBackend.taf.changeGroups); // set initial form values
4159
4267
 
4160
4268
  reset(defaultValues); // set validate flag to validate after the values have been set
4161
4269
 
4162
- setShouldValidate(true);
4270
+ setShouldValidate(true); // register validate method to use in parent components
4271
+
4272
+ var onValidateFormPromise = function onValidateFormPromise() {
4273
+ return new Promise(function (resolve, reject) {
4274
+ toggleIsDraft(true);
4275
+ handleSubmit(function (formData) {
4276
+ resolve(convertTafValuesToObject(formData));
4277
+ })().then(function (formData) {
4278
+ if (formData === undefined) {
4279
+ reject();
4280
+ }
4281
+
4282
+ resolve(formData);
4283
+ });
4284
+ });
4285
+ };
4286
+
4287
+ registerValidateForm(onValidateFormPromise); // set default taf action
4288
+
4289
+ setTafAction(fromStatusToAction(originalTaf.status));
4290
+ resetTAC();
4163
4291
  return function () {
4164
- reset();
4292
+ reset({});
4165
4293
  }; // eslint-disable-next-line react-hooks/exhaustive-deps
4166
4294
  }, []);
4295
+ React__default.useEffect(function () {
4296
+ var newValues = prepareTafValues(tafFromBackend.taf, undefined, !isDefaultDisabled && !tafFromBackend.taf.changeGroups); // set new form values when tafFromBackend changed
4297
+
4298
+ reset(newValues); // eslint-disable-next-line react-hooks/exhaustive-deps
4299
+ }, [tafFromBackend]);
4167
4300
  React__default.useEffect(function () {
4168
4301
  if (shouldValidate && !isDisabled) {
4169
4302
  // trigger validation on all changegroup validity times after initial load since they could be outside the new validity period
@@ -4449,6 +4582,20 @@ var muiTabA11yProps = function muiTabA11yProps(index) {
4449
4582
  'aria-controls': "simple-tabpanel-".concat(index)
4450
4583
  };
4451
4584
  };
4585
+ var prepareTafExportValues = function prepareTafExportValues(tafToCopy, currentTaf) {
4586
+ var _a;
4587
+
4588
+ var convertedCopy = prepareTafValues(tafToCopy, undefined, false);
4589
+ var baseForecast = convertedCopy.baseForecast,
4590
+ _convertedCopy$change = convertedCopy.changeGroups,
4591
+ changeGroups = _convertedCopy$change === void 0 ? [] : _convertedCopy$change;
4592
+ return Object.assign(Object.assign({}, currentTaf), {
4593
+ baseForecast: Object.assign(Object.assign({}, baseForecast), {
4594
+ valid: (_a = currentTaf === null || currentTaf === void 0 ? void 0 : currentTaf.baseForecast) === null || _a === void 0 ? void 0 : _a.valid
4595
+ }),
4596
+ changeGroups: changeGroups
4597
+ });
4598
+ };
4452
4599
 
4453
4600
  /* *
4454
4601
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -4539,10 +4686,44 @@ var StatusIcon = function StatusIcon(_ref) {
4539
4686
  }));
4540
4687
  };
4541
4688
 
4689
+ /* *
4690
+ * Licensed under the Apache License, Version 2.0 (the "License");
4691
+ * you may not use this file except in compliance with the License.
4692
+ * You may obtain a copy of the License at
4693
+ *
4694
+ * http://www.apache.org/licenses/LICENSE-2.0
4695
+ *
4696
+ * Unless required by applicable law or agreed to in writing, software
4697
+ * distributed under the License is distributed on an "AS IS" BASIS,
4698
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4699
+ * See the License for the specific language governing permissions and
4700
+ * limitations under the License.
4701
+ *
4702
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
4703
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
4704
+ * */
4705
+ var ExportIcon = /*#__PURE__*/React__default.createElement(SvgIcon, null, /*#__PURE__*/React__default.createElement("path", {
4706
+ d: "M14.744 5.476a1.252 1.252 0 1 0 0 2.504h2.752v9.516H6.48v-1.753a1.251 1.251 0 1 0-2.504 0v3.004c0 .693.561 1.253 1.252 1.253h13.52C19.44 20 20 19.44 20 18.747V6.727c0-.69-.56-1.251-1.252-1.251zM9.133 2.385a1.252 1.252 0 0 0-1.77 0L1.773 7.974l5.54 5.54c.49.49 1.281.49 1.77 0l.022-.026a1.25 1.25 0 0 0-.021-1.745L6.568 9.225h1.371c.914 0 2.756.618 4.045 2.763 1.29 2.145.352 2.526.653 2.526.301 0 1.943-1.798.721-4.295-1.71-3.498-4.6-3.498-5.346-3.498H6.568l2.565-2.565a1.253 1.253 0 0 0 0-1.771z"
4707
+ }));
4708
+
4709
+ var ExportButton = function ExportButton(_ref) {
4710
+ var onClick = _ref.onClick,
4711
+ isHidden = _ref.isHidden;
4712
+ return isHidden ? null : /*#__PURE__*/React__default.createElement(Tooltip, {
4713
+ title: "Import TAC",
4714
+ placement: "left"
4715
+ }, /*#__PURE__*/React__default.createElement("span", null, /*#__PURE__*/React__default.createElement(ToolButton, {
4716
+ onClick: onClick,
4717
+ "data-testid": "export-tac-button"
4718
+ }, ExportIcon)));
4719
+ };
4720
+
4542
4721
  var TacContainer = function TacContainer(_ref) {
4543
4722
  var taf = _ref.taf,
4544
4723
  _ref$isActive = _ref.isActive,
4545
- isActive = _ref$isActive === void 0 ? false : _ref$isActive;
4724
+ isActive = _ref$isActive === void 0 ? false : _ref$isActive,
4725
+ _ref$isFormDisabled = _ref.isFormDisabled,
4726
+ isFormDisabled = _ref$isFormDisabled === void 0 ? false : _ref$isFormDisabled;
4546
4727
 
4547
4728
  var _useApiContext = useApiContext(),
4548
4729
  api = _useApiContext.api;
@@ -4557,6 +4738,30 @@ var TacContainer = function TacContainer(_ref) {
4557
4738
  baseTime = taf.baseTime;
4558
4739
  var locationLabel = getLocationSetting(location).label;
4559
4740
  var timeSlot = getTafTimeSlot(baseTime, location, status);
4741
+
4742
+ var _useFormContext = useFormContext(),
4743
+ getValues = _useFormContext.getValues,
4744
+ trigger = _useFormContext.trigger,
4745
+ setValue = _useFormContext.setValue;
4746
+
4747
+ var _useTafModuleContext = useTafModuleContext(),
4748
+ updateTAC = _useTafModuleContext.updateTAC;
4749
+
4750
+ var handleExport = function handleExport() {
4751
+ var currentTaf = getValues();
4752
+ var newTaf = prepareTafExportValues(taf, currentTaf);
4753
+ setValue('baseForecast', newTaf.baseForecast, {
4754
+ shouldDirty: true
4755
+ });
4756
+ setValue('changeGroups', newTaf.changeGroups, {
4757
+ shouldDirty: true
4758
+ });
4759
+ setTimeout(function () {
4760
+ trigger(); // trigger all fields validation
4761
+ }, 0);
4762
+ updateTAC(convertTafValuesToObject(newTaf));
4763
+ };
4764
+
4560
4765
  React__default.useEffect(function () {
4561
4766
  if (isActive) {
4562
4767
  retrieveTAC(taf);
@@ -4572,14 +4777,22 @@ var TacContainer = function TacContainer(_ref) {
4572
4777
  sx: {
4573
4778
  display: 'flex',
4574
4779
  alignItems: 'center',
4575
- marginBottom: '2px'
4780
+ justifyContent: 'space-between',
4781
+ height: 24
4576
4782
  }
4577
4783
  }, /*#__PURE__*/React__default.createElement(Box, {
4578
4784
  sx: {
4579
- width: 20,
4580
- height: 20,
4581
4785
  display: 'flex',
4582
- marginRight: '6px'
4786
+ alignItems: 'center'
4787
+ }
4788
+ }, /*#__PURE__*/React__default.createElement(Box, {
4789
+ sx: {
4790
+ width: 24,
4791
+ height: 24,
4792
+ display: 'flex',
4793
+ marginRight: '2px',
4794
+ alignItems: 'center',
4795
+ justifyContent: 'center'
4583
4796
  }
4584
4797
  }, /*#__PURE__*/React__default.createElement(StatusIcon, {
4585
4798
  timeSlot: timeSlot,
@@ -4606,7 +4819,10 @@ var TacContainer = function TacContainer(_ref) {
4606
4819
  },
4607
4820
  "data-testid": "tafLocationLabel",
4608
4821
  component: "span"
4609
- }, locationLabel))), /*#__PURE__*/React__default.createElement(Box, {
4822
+ }, locationLabel))), /*#__PURE__*/React__default.createElement(ExportButton, {
4823
+ onClick: handleExport,
4824
+ isHidden: isFormDisabled || tacHasError(TAC)
4825
+ })), /*#__PURE__*/React__default.createElement(Box, {
4610
4826
  sx: {
4611
4827
  fontSize: '12px',
4612
4828
  letterSpacing: '0.4px',
@@ -4642,7 +4858,9 @@ var TacOverview = function TacOverview(_ref) {
4642
4858
  _ref$hideTitle = _ref.hideTitle,
4643
4859
  hideTitle = _ref$hideTitle === void 0 ? false : _ref$hideTitle,
4644
4860
  _ref$activeTaf = _ref.activeTaf,
4645
- activeTaf = _ref$activeTaf === void 0 ? null : _ref$activeTaf;
4861
+ activeTaf = _ref$activeTaf === void 0 ? null : _ref$activeTaf,
4862
+ _ref$isFormDisabled = _ref.isFormDisabled,
4863
+ isFormDisabled = _ref$isFormDisabled === void 0 ? false : _ref$isFormDisabled;
4646
4864
 
4647
4865
  var _React$useState = React__default.useState(0),
4648
4866
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -4739,7 +4957,8 @@ var TacOverview = function TacOverview(_ref) {
4739
4957
  return /*#__PURE__*/React__default.createElement(TacContainer, {
4740
4958
  key: taf.uuid,
4741
4959
  taf: taf,
4742
- isActive: isActiveLocation(taf.location)
4960
+ isActive: isActiveLocation(taf.location),
4961
+ isFormDisabled: isFormDisabled
4743
4962
  });
4744
4963
  }));
4745
4964
  })));
@@ -5008,25 +5227,22 @@ var fromActionToStatus = function fromActionToStatus(tafAction) {
5008
5227
  }
5009
5228
  };
5010
5229
 
5011
- var TafPanel = function TafPanel(_ref) {
5012
- var tafFromBackend = _ref.tafFromBackend,
5013
- activeTafIndex = _ref.activeTafIndex,
5014
- index = _ref.index,
5015
- _ref$onPostTaf = _ref.onPostTaf,
5016
- onPostTaf = _ref$onPostTaf === void 0 ? function () {} : _ref$onPostTaf,
5017
- _ref$onFormDirty = _ref.onFormDirty,
5018
- onFormDirty = _ref$onFormDirty === void 0 ? function () {
5019
- return null;
5020
- } : _ref$onFormDirty,
5021
- _ref$isIssuesPaneOpen = _ref.isIssuesPaneOpen,
5022
- isIssuesPaneOpen = _ref$isIssuesPaneOpen === void 0 ? false : _ref$isIssuesPaneOpen,
5023
- _ref$setIsIssuesPaneO = _ref.setIsIssuesPaneOpen,
5024
- setIsIssuesPaneOpen = _ref$setIsIssuesPaneO === void 0 ? function () {
5025
- return null;
5026
- } : _ref$setIsIssuesPaneO;
5230
+ var parseErrorMessage = function parseErrorMessage(error, params) {
5231
+ return params.changeStatusTo === 'CANCELLED' ? {
5232
+ type: 'CANCELLED',
5233
+ title: 'Cancelling this TAF failed, please try again'
5234
+ } : {
5235
+ type: 'SERVER',
5236
+ title: 'An error has occurred while saving, please try again',
5237
+ message: isAxiosError(error) ? getAxiosErrorMessage(error) : error.message
5238
+ };
5239
+ };
5027
5240
 
5028
- var _useApiContext = useApiContext(),
5029
- api = _useApiContext.api;
5241
+ var usePostTafRequest = function usePostTafRequest(request) {
5242
+ var errorParser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : parseErrorMessage;
5243
+
5244
+ var _useIsMounted = useIsMounted(),
5245
+ isMounted = _useIsMounted.isMounted;
5030
5246
 
5031
5247
  var _React$useState = React__default.useState(false),
5032
5248
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -5036,68 +5252,92 @@ var TafPanel = function TafPanel(_ref) {
5036
5252
  var _React$useState3 = React__default.useState(null),
5037
5253
  _React$useState4 = _slicedToArray(_React$useState3, 2),
5038
5254
  error = _React$useState4[0],
5039
- setError = _React$useState4[1]; // removes cancelled error message
5040
-
5255
+ setError = _React$useState4[1];
5041
5256
 
5042
- React__default.useEffect(function () {
5043
- var cancelErrorTimeout = error && error.type === 'CANCELLED' ? setTimeout(function () {
5044
- setError(null);
5045
- }, 10000) : null;
5046
- return function () {
5047
- if (cancelErrorTimeout !== null) {
5048
- clearTimeout(cancelErrorTimeout);
5049
- }
5050
- };
5051
- }, [error]);
5052
-
5053
- var postTaf = function postTaf(data) {
5257
+ var doRequest = function doRequest(params) {
5054
5258
  return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
5055
- var newError;
5259
+ var newErrorr;
5056
5260
  return regeneratorRuntime.wrap(function _callee$(_context) {
5057
5261
  while (1) {
5058
5262
  switch (_context.prev = _context.next) {
5059
5263
  case 0:
5060
- _context.prev = 0;
5061
5264
  setLoading(true);
5062
- _context.next = 4;
5063
- return api.postTaf(data);
5265
+ setError(null);
5266
+ _context.prev = 2;
5267
+ _context.next = 5;
5268
+ return request(params);
5269
+
5270
+ case 5:
5271
+ if (isMounted.current) {
5272
+ _context.next = 7;
5273
+ break;
5274
+ }
5064
5275
 
5065
- case 4:
5276
+ return _context.abrupt("return");
5277
+
5278
+ case 7:
5066
5279
  setLoading(false);
5067
5280
  setError(null);
5068
- onFormDirty(false); // callback
5069
-
5070
- onPostTaf();
5071
- _context.next = 16;
5281
+ _context.next = 19;
5072
5282
  break;
5073
5283
 
5074
- case 10:
5075
- _context.prev = 10;
5076
- _context.t0 = _context["catch"](0);
5077
- newError = data.changeStatusTo === 'CANCELLED' ? {
5078
- type: 'CANCELLED',
5079
- title: 'Cancelling this TAF failed, please try again'
5080
- } : {
5081
- type: 'SERVER',
5082
- title: 'An error has occurred while saving, please try again',
5083
- message: getAxiosErrorMessage(_context.t0)
5084
- };
5085
- setError(newError);
5284
+ case 11:
5285
+ _context.prev = 11;
5286
+ _context.t0 = _context["catch"](2);
5287
+
5288
+ if (isMounted.current) {
5289
+ _context.next = 15;
5290
+ break;
5291
+ }
5292
+
5293
+ return _context.abrupt("return");
5294
+
5295
+ case 15:
5296
+ newErrorr = errorParser ? errorParser(_context.t0, params) : _context.t0;
5086
5297
  setLoading(false);
5087
- throw _context.t0;
5298
+ setError(newErrorr);
5299
+ throw newErrorr;
5088
5300
 
5089
- case 16:
5301
+ case 19:
5090
5302
  case "end":
5091
5303
  return _context.stop();
5092
5304
  }
5093
5305
  }
5094
- }, _callee, null, [[0, 10]]);
5306
+ }, _callee, null, [[2, 11]]);
5095
5307
  }));
5096
5308
  };
5097
5309
 
5098
- var getViewMode = function getViewMode(status) {
5099
- return status === 'NEW' || status === 'DRAFT' || status === 'DRAFT_AMENDED' || status === 'DRAFT_CORRECTED' ? 'edit' : 'view';
5310
+ return {
5311
+ isLoading: isLoading,
5312
+ error: error,
5313
+ setError: setError,
5314
+ doRequest: doRequest
5100
5315
  };
5316
+ };
5317
+
5318
+ var TafPanel = function TafPanel(_ref) {
5319
+ var tafFromBackend = _ref.tafFromBackend,
5320
+ activeTafIndex = _ref.activeTafIndex,
5321
+ index = _ref.index,
5322
+ _ref$isLoading = _ref.isLoading,
5323
+ isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading,
5324
+ _ref$postTaf = _ref.postTaf,
5325
+ postTaf = _ref$postTaf === void 0 ? function () {
5326
+ return null;
5327
+ } : _ref$postTaf,
5328
+ _ref$isIssuesPaneOpen = _ref.isIssuesPaneOpen,
5329
+ isIssuesPaneOpen = _ref$isIssuesPaneOpen === void 0 ? false : _ref$isIssuesPaneOpen,
5330
+ _ref$setIsIssuesPaneO = _ref.setIsIssuesPaneOpen,
5331
+ setIsIssuesPaneOpen = _ref$setIsIssuesPaneO === void 0 ? function () {
5332
+ return null;
5333
+ } : _ref$setIsIssuesPaneO,
5334
+ _ref$isFormDisabled = _ref.isFormDisabled,
5335
+ isFormDisabled = _ref$isFormDisabled === void 0 ? false : _ref$isFormDisabled,
5336
+ _ref$setIsFormDisable = _ref.setIsFormDisabled,
5337
+ setIsFormDisabled = _ref$setIsFormDisable === void 0 ? function () {
5338
+ return null;
5339
+ } : _ref$setIsFormDisable,
5340
+ error = _ref.error;
5101
5341
 
5102
5342
  var onTafAction = function onTafAction(action, taf) {
5103
5343
  return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
@@ -5158,15 +5398,21 @@ var TafPanel = function TafPanel(_ref) {
5158
5398
  severity: "error",
5159
5399
  title: error.title,
5160
5400
  info: error.message,
5161
- dataTestId: "taf-error"
5162
- }), /*#__PURE__*/React__default.createElement(TafForm, {
5163
- isDisabled: getViewMode(tafFromBackend.taf.status) === 'view',
5401
+ dataTestId: "taf-error",
5402
+ shouldClose: true
5403
+ }), /*#__PURE__*/React__default.createElement(Box, {
5404
+ sx: {
5405
+ marginTop: '10px',
5406
+ padding: 1
5407
+ }
5408
+ }, /*#__PURE__*/React__default.createElement(TafForm, {
5164
5409
  tafFromBackend: tafFromBackend,
5165
5410
  onFormAction: onTafAction,
5166
- onFormDirty: onFormDirty,
5167
5411
  isIssuesPaneOpen: isIssuesPaneOpen,
5168
- setIsIssuesPaneOpen: setIsIssuesPaneOpen
5169
- }));
5412
+ setIsIssuesPaneOpen: setIsIssuesPaneOpen,
5413
+ isDisabled: isFormDisabled,
5414
+ setIsDisabled: setIsFormDisabled
5415
+ })));
5170
5416
  };
5171
5417
 
5172
5418
  /* *
@@ -5196,11 +5442,21 @@ var IssuesPaneWrapper = function IssuesPaneWrapper(props) {
5196
5442
  }, props));
5197
5443
  };
5198
5444
 
5445
+ var CONFIRM_DIALOG_OPTIONS = {
5446
+ title: 'Whoops',
5447
+ description: "It's not possible to autosave this TAF due to the presence of issue(s). Are you sure you want to close this TAF? Any changes made will be lost.",
5448
+ confirmLabel: 'Exit without saving'
5449
+ };
5450
+
5199
5451
  var TafLayout = function TafLayout(_ref) {
5200
5452
  var _ref$tafList = _ref.tafList,
5201
5453
  tafList = _ref$tafList === void 0 ? [] : _ref$tafList,
5202
5454
  _ref$onPostTaf = _ref.onPostTaf,
5203
5455
  onPostTaf = _ref$onPostTaf === void 0 ? function () {} : _ref$onPostTaf;
5456
+
5457
+ var _useApiContext = useApiContext(),
5458
+ api = _useApiContext.api;
5459
+
5204
5460
  var confirmDialog = useConfirmationDialog();
5205
5461
 
5206
5462
  var _useIssuesPane = useIssuesPane(),
@@ -5209,6 +5465,17 @@ var TafLayout = function TafLayout(_ref) {
5209
5465
  onCloseIssuesPane = _useIssuesPane.onCloseIssuesPane,
5210
5466
  startPosition = _useIssuesPane.startPosition;
5211
5467
 
5468
+ var _usePostTafRequest = usePostTafRequest(api.postTaf),
5469
+ isLoading = _usePostTafRequest.isLoading,
5470
+ postTafRequest = _usePostTafRequest.doRequest,
5471
+ error = _usePostTafRequest.error,
5472
+ setError = _usePostTafRequest.setError;
5473
+
5474
+ var _useTafModuleContext = useTafModuleContext(),
5475
+ onValidateForm = _useTafModuleContext.onValidateForm,
5476
+ tafAction = _useTafModuleContext.tafAction,
5477
+ isFormDirty = _useTafModuleContext.isFormDirty;
5478
+
5212
5479
  var _React$useState = React__default.useState(sortTafTimeSlots(tafList)),
5213
5480
  _React$useState2 = _slicedToArray(_React$useState, 2),
5214
5481
  _React$useState2$ = _React$useState2[0],
@@ -5238,21 +5505,83 @@ var TafLayout = function TafLayout(_ref) {
5238
5505
 
5239
5506
  var _React$useState9 = React__default.useState(false),
5240
5507
  _React$useState10 = _slicedToArray(_React$useState9, 2),
5241
- isFormDirty = _React$useState10[0],
5242
- setIsFormDirty = _React$useState10[1];
5508
+ isFormDisabled = _React$useState10[0],
5509
+ setIsFormDisabled = _React$useState10[1];
5510
+
5511
+ var postTaf = function postTaf(data) {
5512
+ return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
5513
+ return regeneratorRuntime.wrap(function _callee$(_context) {
5514
+ while (1) {
5515
+ switch (_context.prev = _context.next) {
5516
+ case 0:
5517
+ _context.next = 2;
5518
+ return postTafRequest(data);
5519
+
5520
+ case 2:
5521
+ // callback
5522
+ onPostTaf();
5523
+
5524
+ case 3:
5525
+ case "end":
5526
+ return _context.stop();
5527
+ }
5528
+ }
5529
+ }, _callee);
5530
+ }));
5531
+ };
5243
5532
 
5244
5533
  function onChangeTab(action, value) {
5245
- if (isFormDirty) {
5246
- confirmDialog({
5247
- title: 'Whoops',
5248
- description: 'Do you want to leave this open TAF without saving it? All changes will be lost.',
5249
- confirmLabel: 'Exit without saving'
5250
- }).then(function () {
5251
- action(value);
5252
- });
5253
- } else {
5254
- action(value);
5255
- }
5534
+ return __awaiter(this, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
5535
+ var taf;
5536
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
5537
+ while (1) {
5538
+ switch (_context2.prev = _context2.next) {
5539
+ case 0:
5540
+ if (!isFormDirty) {
5541
+ _context2.next = 15;
5542
+ break;
5543
+ }
5544
+
5545
+ _context2.prev = 1;
5546
+ _context2.next = 4;
5547
+ return onValidateForm();
5548
+
5549
+ case 4:
5550
+ taf = _context2.sent;
5551
+ _context2.next = 7;
5552
+ return postTaf({
5553
+ taf: taf,
5554
+ changeStatusTo: fromActionToStatus(tafActionToDraftAction(tafAction))
5555
+ });
5556
+
5557
+ case 7:
5558
+ action(value);
5559
+ _context2.next = 13;
5560
+ break;
5561
+
5562
+ case 10:
5563
+ _context2.prev = 10;
5564
+ _context2.t0 = _context2["catch"](1);
5565
+ confirmDialog(CONFIRM_DIALOG_OPTIONS).then(function () {
5566
+ action(value);
5567
+ setError(null);
5568
+ });
5569
+
5570
+ case 13:
5571
+ _context2.next = 17;
5572
+ break;
5573
+
5574
+ case 15:
5575
+ action(value);
5576
+ setError(null);
5577
+
5578
+ case 17:
5579
+ case "end":
5580
+ return _context2.stop();
5581
+ }
5582
+ }
5583
+ }, _callee2, null, [[1, 10]]);
5584
+ }));
5256
5585
  }
5257
5586
 
5258
5587
  var onChangeLocationTab = function onChangeLocationTab(index) {
@@ -5276,11 +5605,23 @@ var TafLayout = function TafLayout(_ref) {
5276
5605
  setLocations(updatedLocations); // update active index
5277
5606
 
5278
5607
  var newActiveIndex = updatedLocations.findIndex(function (location) {
5279
- return location.taf.previousId === locations[activeTafIndex].taf.uuid;
5608
+ var _a, _b, _c;
5609
+
5610
+ return ((_a = location === null || location === void 0 ? void 0 : location.taf) === null || _a === void 0 ? void 0 : _a.previousId) === ((_c = (_b = locations[activeTafIndex]) === null || _b === void 0 ? void 0 : _b.taf) === null || _c === void 0 ? void 0 : _c.uuid);
5280
5611
  });
5281
5612
  var newIndex = newActiveIndex !== -1 ? newActiveIndex : activeTafIndex;
5282
5613
  setActiveTafIndex(newIndex); // eslint-disable-next-line react-hooks/exhaustive-deps
5283
5614
  }, [tafList, setLocations]);
5615
+ React__default.useEffect(function () {
5616
+ var cancelErrorTimeout = error && error.type === 'CANCELLED' ? setTimeout(function () {
5617
+ setError(null);
5618
+ }, 10000) : null;
5619
+ return function () {
5620
+ if (cancelErrorTimeout !== null) {
5621
+ clearTimeout(cancelErrorTimeout);
5622
+ }
5623
+ };
5624
+ }, [error, setError]);
5284
5625
 
5285
5626
  if (!tafList) {
5286
5627
  return null;
@@ -5355,10 +5696,9 @@ var TafLayout = function TafLayout(_ref) {
5355
5696
  }, /*#__PURE__*/React__default.createElement(Card, {
5356
5697
  variant: "outlined",
5357
5698
  sx: {
5358
- padding: 1,
5359
- paddingTop: 0,
5360
5699
  marginBottom: '12px',
5361
- position: 'relative'
5700
+ position: 'relative',
5701
+ minHeight: locations.length * 62 + 32
5362
5702
  }
5363
5703
  }, /*#__PURE__*/React__default.createElement(TacOverviewMobile, {
5364
5704
  upcomingTafs: upcoming,
@@ -5371,26 +5711,32 @@ var TafLayout = function TafLayout(_ref) {
5371
5711
  activeTafIndex: activeTafIndex,
5372
5712
  index: index,
5373
5713
  tafFromBackend: tafFromBackend,
5374
- onPostTaf: onPostTaf,
5375
- onFormDirty: setIsFormDirty,
5376
5714
  isIssuesPaneOpen: isIssuesPaneOpen,
5377
- setIsIssuesPaneOpen: onToggleIssuesPane
5715
+ setIsIssuesPaneOpen: onToggleIssuesPane,
5716
+ isFormDisabled: isFormDisabled,
5717
+ setIsFormDisabled: setIsFormDisabled,
5718
+ postTaf: postTaf,
5719
+ isLoading: isLoading,
5720
+ error: error
5378
5721
  });
5379
5722
  }))), /*#__PURE__*/React__default.createElement(Grid, {
5380
5723
  item: true,
5381
- xs: 3,
5382
- sx: {
5383
- height: '100%'
5724
+ xs: 0,
5725
+ sm: 3,
5726
+ height: {
5727
+ xs: 0,
5728
+ sm: '100%'
5384
5729
  },
5385
- display: {
5386
- xs: 'none',
5387
- sm: 'block'
5730
+ width: {
5731
+ xs: 0,
5732
+ sm: '100%'
5388
5733
  }
5389
5734
  }, /*#__PURE__*/React__default.createElement(TacOverview, {
5390
5735
  upcomingTafs: upcoming,
5391
5736
  currentTafs: current,
5392
5737
  expiredTafs: expired,
5393
- activeTaf: activeTaf
5738
+ activeTaf: activeTaf,
5739
+ isFormDisabled: isFormDisabled
5394
5740
  })))))), /*#__PURE__*/React__default.createElement(IssuesPaneWrapper, {
5395
5741
  handleClose: onCloseIssuesPane,
5396
5742
  isOpen: isIssuesPaneOpen,
@@ -5398,6 +5744,19 @@ var TafLayout = function TafLayout(_ref) {
5398
5744
  }));
5399
5745
  };
5400
5746
 
5747
+ var TafWrapper = function TafWrapper(_a) {
5748
+ var children = _a.children,
5749
+ props = __rest(_a, ["children"]);
5750
+
5751
+ return /*#__PURE__*/React.createElement(TafModuleProvider, Object.assign({}, props), /*#__PURE__*/React.createElement(ConfirmationServiceProvider, null, /*#__PURE__*/React.createElement(ReactHookFormProvider, {
5752
+ options: {
5753
+ mode: 'onTouched',
5754
+ reValidateMode: 'onChange',
5755
+ criteriaMode: 'all'
5756
+ }
5757
+ }, children)));
5758
+ };
5759
+
5401
5760
  /* *
5402
5761
  * Licensed under the Apache License, Version 2.0 (the "License");
5403
5762
  * you may not use this file except in compliance with the License.
@@ -5415,29 +5774,13 @@ var TafLayout = function TafLayout(_ref) {
5415
5774
  * Copyright 2022 - Finnish Meteorological Institute (FMI)
5416
5775
  * */
5417
5776
 
5418
- var TafWrapper = function TafWrapper(_ref) {
5419
- var children = _ref.children;
5420
- return /*#__PURE__*/React.createElement(ConfirmationServiceProvider, null, /*#__PURE__*/React.createElement(ReactHookFormProvider, {
5421
- options: {
5422
- mode: 'onTouched',
5423
- reValidateMode: 'onChange',
5424
- criteriaMode: 'all'
5425
- }
5426
- }, children));
5427
- };
5428
-
5429
5777
  var TafModule = function TafModule() {
5430
5778
  var _useApiContext = useApiContext(),
5431
5779
  api = _useApiContext.api;
5432
5780
 
5433
- var _React$useState = React.useState(false),
5434
- _React$useState2 = _slicedToArray(_React$useState, 2),
5435
- isLoading = _React$useState2[0],
5436
- setLoading = _React$useState2[1];
5437
-
5438
5781
  var _useApi = useApi(api.getTafList),
5439
5782
  getTafListError = _useApi.error,
5440
- isFetchingInitial = _useApi.isLoading,
5783
+ isLoading = _useApi.isLoading,
5441
5784
  tafList = _useApi.result,
5442
5785
  fetchNewTafList = _useApi.fetchApiData;
5443
5786
 
@@ -5445,45 +5788,11 @@ var TafModule = function TafModule() {
5445
5788
  return fetchNewTafList({});
5446
5789
  });
5447
5790
 
5448
- var reFetchNewTafList = function reFetchNewTafList() {
5449
- return __awaiter(void 0, void 0, void 0, /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
5450
- return regeneratorRuntime.wrap(function _callee$(_context) {
5451
- while (1) {
5452
- switch (_context.prev = _context.next) {
5453
- case 0:
5454
- _context.prev = 0;
5455
- setLoading(true);
5456
- _context.next = 4;
5457
- return fetchNewTafList({});
5458
-
5459
- case 4:
5460
- setLoading(false);
5461
- _context.next = 10;
5462
- break;
5463
-
5464
- case 7:
5465
- _context.prev = 7;
5466
- _context.t0 = _context["catch"](0);
5467
- setLoading(false);
5468
-
5469
- case 10:
5470
- case "end":
5471
- return _context.stop();
5472
- }
5473
- }
5474
- }, _callee, null, [[0, 7]]);
5475
- }));
5791
+ var onPostTaf = function onPostTaf() {
5792
+ fetchNewTafList({});
5476
5793
  };
5477
5794
 
5478
5795
  var hasTafListError = getTafListError !== null;
5479
-
5480
- if (isFetchingInitial) {
5481
- return /*#__PURE__*/React.createElement(LinearProgress, {
5482
- color: "secondary",
5483
- "data-testid": "loading-bar"
5484
- });
5485
- }
5486
-
5487
5796
  return /*#__PURE__*/React.createElement(Box, {
5488
5797
  component: "div",
5489
5798
  id: "tafmodule",
@@ -5499,33 +5808,22 @@ var TafModule = function TafModule() {
5499
5808
  }), hasTafListError && /*#__PURE__*/React.createElement(AlertBanner, {
5500
5809
  severity: "error",
5501
5810
  title: "An error has occurred while retrieving the list",
5502
- info: getTafListError.message
5811
+ info: getTafListError.message,
5812
+ dataTestId: "taf-list-error",
5813
+ actionButtonProps: {
5814
+ title: 'Try again',
5815
+ onClick: fetchNewTafList
5816
+ }
5503
5817
  }), /*#__PURE__*/React.createElement(TafLayout, {
5504
5818
  tafList: tafList,
5505
- onPostTaf: reFetchNewTafList
5819
+ onPostTaf: onPostTaf
5506
5820
  }));
5507
5821
  };
5508
5822
 
5509
- var Wrapper = function Wrapper() {
5510
- return /*#__PURE__*/React.createElement(TafWrapper, null, /*#__PURE__*/React.createElement(TafModule, null));
5823
+ var Wrapper = function Wrapper(props) {
5824
+ return /*#__PURE__*/React.createElement(TafWrapper, Object.assign({}, props), /*#__PURE__*/React.createElement(TafModule, null));
5511
5825
  };
5512
5826
 
5513
- /* *
5514
- * Licensed under the Apache License, Version 2.0 (the "License");
5515
- * you may not use this file except in compliance with the License.
5516
- * You may obtain a copy of the License at
5517
- *
5518
- * http://www.apache.org/licenses/LICENSE-2.0
5519
- *
5520
- * Unless required by applicable law or agreed to in writing, software
5521
- * distributed under the License is distributed on an "AS IS" BASIS,
5522
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5523
- * See the License for the specific language governing permissions and
5524
- * limitations under the License.
5525
- *
5526
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
5527
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
5528
- * */
5529
5827
  var createApi$1 = function createApi(url, appUrl, auth, setAuth, authTokenUrl, authClientId) {
5530
5828
  var axiosInstance = createApiInstance(url, appUrl, auth, setAuth, authTokenUrl, authClientId);
5531
5829
  return {
@@ -5536,8 +5834,10 @@ var createApi$1 = function createApi(url, appUrl, auth, setAuth, authTokenUrl, a
5536
5834
  postTaf: function postTaf(formData) {
5537
5835
  return axiosInstance.post('/taf', Object.assign({}, formData));
5538
5836
  },
5539
- getTAC: function getTAC(tafData) {
5540
- return axiosInstance.post('/taf2tac', Object.assign({}, tafData));
5837
+ getTAC: function getTAC(tafData, signal) {
5838
+ return axiosInstance.post.apply(axiosInstance, ['/taf2tac'].concat([Object.assign({}, tafData)].concat(_toConsumableArray(signal ? [{
5839
+ signal: signal
5840
+ }] : []))));
5541
5841
  }
5542
5842
  };
5543
5843
  };
@@ -6180,7 +6480,7 @@ var fakePublishedTaf = {
6180
6480
  change: 'BECMG',
6181
6481
  valid: {
6182
6482
  start: "".concat(currentDate, "T23:00:00Z"),
6183
- end: "".concat(tomorrowDate, "T00:00:00Z")
6483
+ end: "".concat(tomorrowDate, "T01:00:00Z")
6184
6484
  },
6185
6485
  wind: {
6186
6486
  direction: 150,
@@ -6436,7 +6736,7 @@ var fakeAmendmentTaf = {
6436
6736
  }
6437
6737
  }
6438
6738
  }
6439
- }; // Only use for display purposes in the list!
6739
+ };
6440
6740
 
6441
6741
  ({
6442
6742
  creationDate: "2022-01-06T14:00:00Z",
@@ -6461,12 +6761,17 @@ var fakeAmendmentTaf = {
6461
6761
  var fakeTafTac = 'TAF EHAM 0812/0918 20020G35KT 0500 SN BKN040\nBECMG 0814/0816 0700 BKN001=';
6462
6762
 
6463
6763
  var fakePromise = function fakePromise(withRandomError) {
6764
+ var signal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
6464
6765
  return new Promise(function (resolve, reject) {
6465
- setTimeout(function () {
6766
+ var timer = setTimeout(function () {
6466
6767
  if (!withRandomError) return resolve();
6467
6768
  var randomError = Math.floor(Math.random() * 4) + 1;
6468
6769
  return randomError === 4 ? reject(new Error('something went wrong')) : resolve();
6469
6770
  }, 300);
6771
+ signal === null || signal === void 0 ? void 0 : signal.signal.addEventListener('abort', function () {
6772
+ clearTimeout(timer);
6773
+ reject(new Error('canceled'));
6774
+ });
6470
6775
  });
6471
6776
  };
6472
6777
 
@@ -6476,8 +6781,8 @@ var fakeAxiosInstance = {
6476
6781
  return fakePromise(false);
6477
6782
  },
6478
6783
  // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars, @typescript-eslint/explicit-module-boundary-types
6479
- post: function post(_url, _params) {
6480
- return fakePromise(false);
6784
+ post: function post(_url, _params, _signal) {
6785
+ return fakePromise(false, _signal);
6481
6786
  }
6482
6787
  };
6483
6788
  var createApi = function createApi() {
@@ -6491,22 +6796,104 @@ var createApi = function createApi() {
6491
6796
  };
6492
6797
  });
6493
6798
  },
6494
- getTAC: function getTAC() {
6495
- // eslint-disable-next-line no-console
6496
- return fakeAxiosInstance.post('/taf2tac').then(function () {
6497
- return {
6498
- data: fakeTafTac
6499
- };
6500
- });
6501
- },
6502
6799
  postTaf: function postTaf(_postTaf) {
6503
6800
  // eslint-disable-next-line no-console
6504
6801
  console.log("The new status of the taf will be ".concat(_postTaf.changeStatusTo)); // eslint-disable-next-line no-console
6505
6802
 
6506
6803
  console.log('form has been posted with following values:', _postTaf.taf);
6507
6804
  return fakeAxiosInstance.post('/taf', _postTaf);
6805
+ },
6806
+ getTAC: function getTAC(tafData, signal) {
6807
+ return fakeAxiosInstance.post.apply(fakeAxiosInstance, ['/taf2tac'].concat([Object.assign({}, tafData)].concat(_toConsumableArray(signal ? [{
6808
+ signal: signal
6809
+ }] : [])))).then(function () {
6810
+ return {
6811
+ data: fakeTafTac
6812
+ };
6813
+ });
6508
6814
  }
6509
6815
  };
6510
6816
  };
6511
6817
 
6512
- export { TafForm, Wrapper as TafModule, createApi$1 as createApi, createApi as createFakeApi };
6818
+ /* *
6819
+ * Licensed under the Apache License, Version 2.0 (the "License");
6820
+ * you may not use this file except in compliance with the License.
6821
+ * You may obtain a copy of the License at
6822
+ *
6823
+ * http://www.apache.org/licenses/LICENSE-2.0
6824
+ *
6825
+ * Unless required by applicable law or agreed to in writing, software
6826
+ * distributed under the License is distributed on an "AS IS" BASIS,
6827
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6828
+ * See the License for the specific language governing permissions and
6829
+ * limitations under the License.
6830
+ *
6831
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
6832
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
6833
+ * */
6834
+ var tafScreenPreset = {
6835
+ id: 'screenConfigTaf',
6836
+ title: 'TAF',
6837
+ views: {
6838
+ byId: {
6839
+ taf: {
6840
+ title: 'TAF',
6841
+ componentType: 'TafModule',
6842
+ initialProps: {}
6843
+ }
6844
+ },
6845
+ allIds: ['taf']
6846
+ },
6847
+ syncGroups: [],
6848
+ mosaicNode: 'taf'
6849
+ };
6850
+ var TafApiWrapper = function TafApiWrapper(_ref) {
6851
+ var config = _ref.config,
6852
+ auth = _ref.auth,
6853
+ onSetAuth = _ref.onSetAuth,
6854
+ onPreventCloseView = _ref.onPreventCloseView;
6855
+ return config ? /*#__PURE__*/React.createElement(ApiProvider, {
6856
+ baseURL: config.baseUrl,
6857
+ appURL: config.appUrl,
6858
+ auth: auth,
6859
+ onSetAuth: onSetAuth,
6860
+ createApi: createApi$1,
6861
+ authTokenUrl: config.authTokenUrl,
6862
+ authClientId: config.authClientId
6863
+ }, /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(Wrapper, {
6864
+ onPreventCloseView: onPreventCloseView
6865
+ }))) : null;
6866
+ };
6867
+ var componentsLookUp = function componentsLookUp(payload, _ref2) {
6868
+ var config = _ref2.config,
6869
+ auth = _ref2.auth,
6870
+ onSetAuth = _ref2.onSetAuth;
6871
+ var ConnectedModuleWrapper = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
6872
+ var componentType = payload.componentType;
6873
+
6874
+ switch (componentType) {
6875
+ case 'TafModule':
6876
+ if (ConnectedModuleWrapper) {
6877
+ return /*#__PURE__*/React.createElement(ConnectedModuleWrapper, {
6878
+ component: TafApiWrapper,
6879
+ payload: payload,
6880
+ "data-testid": "tafmodule",
6881
+ config: config,
6882
+ auth: auth,
6883
+ onSetAuth: onSetAuth
6884
+ });
6885
+ }
6886
+
6887
+ return /*#__PURE__*/React.createElement(TafApiWrapper, {
6888
+ "data-testid": "tafmodule",
6889
+ config: config,
6890
+ auth: auth,
6891
+ onSetAuth: onSetAuth
6892
+ });
6893
+
6894
+ default:
6895
+ return null;
6896
+ }
6897
+ };
6898
+
6899
+ export { TafApiWrapper, TafForm, Wrapper as TafModule, componentsLookUp, createApi$1 as createApi, createApi as createFakeApi, tafScreenPreset };