@opengeoweb/taf 2.1.2 → 2.2.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.
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { makeStyles, Grid, TextField, IconButton, Tooltip, Chip, SvgIcon, Typography, Button, Dialog, DialogTitle, DialogContent, Card, Accordion, AccordionSummary, AccordionDetails, Backdrop, CircularProgress } from '@material-ui/core';
4
- import { Skeleton } from '@material-ui/lab';
3
+ import { Grid, TextField, IconButton, Tooltip, Chip, SvgIcon, Typography, Button, Dialog, DialogTitle, DialogContent, Card, Accordion, AccordionSummary, AccordionDetails, Skeleton, Backdrop, CircularProgress } from '@mui/material';
4
+ import makeStyles from '@mui/styles/makeStyles';
5
5
  import moment from 'moment';
6
6
  import { useIsMounted, useDraftFormHelpers, ToolContainerDraggable, useConfirmationDialog, usePreventBrowserClose, StatusTag, AlertBanner, ConfirmationServiceProvider, usePoller, isAxiosError, getAxiosErrorMessage } from '@opengeoweb/shared';
7
- import { Add, Delete, DragIndicator, Close, InfoOutlined, Create, CheckCircle, Schedule, OpenInNew, ExpandMore } from '@material-ui/icons';
7
+ import { Add, Delete, DragIndicator, Close, InfoOutlined, Create, CheckCircle, Schedule, OpenInNew, ExpandMore } from '@mui/icons-material';
8
8
  import { useApiContext, useApi, createApiInstance } from '@opengeoweb/api';
9
9
  import { getDeepProperty, ReactHookFormHiddenInput, ReactHookFormProvider } from '@opengeoweb/form-fields';
10
10
  import { useFormContext, Controller, useFieldArray } from 'react-hook-form';
@@ -284,20 +284,20 @@ function __awaiter(thisArg, _arguments, P, generator) {
284
284
  * Copyright 2021 - Finnish Meteorological Institute (FMI)
285
285
  * */
286
286
  var FORMAT_DAYS_HOURS = 'DDHH';
287
- var FORMAT_DAYS_HOURS_MINUTS = 'DDHHmm'; // formatters
287
+ var FORMAT_DAYS_HOURS_MINUTES = 'DDHHmm'; // formatters
288
288
 
289
289
  var formatValidToString = function formatValidToString(valid) {
290
290
  // Ensure end of valid period if midnight is shown as 24 and not 00
291
291
  var endHours = moment.utc(valid.end).format('kk');
292
292
  var endDate = endHours === '24' ? moment.utc(valid.end).add(-1, 'day').format('DD') : moment.utc(valid.end).format('DD');
293
- return valid.end ? "".concat(moment.utc(valid.start).format(FORMAT_DAYS_HOURS), "/").concat(endDate).concat(endHours) : moment.utc(valid.start).format(FORMAT_DAYS_HOURS_MINUTS);
293
+ return valid.end ? "".concat(moment.utc(valid.start).format(FORMAT_DAYS_HOURS), "/").concat(endDate).concat(endHours) : moment.utc(valid.start).format(FORMAT_DAYS_HOURS_MINUTES);
294
294
  };
295
295
 
296
296
  var getSections = function getSections(value, format) {
297
297
  return {
298
298
  day: parseInt(value.substring(0, 2), 10),
299
299
  hour: parseInt(value.substring(2, 4), 10),
300
- min: format === FORMAT_DAYS_HOURS_MINUTS ? parseInt(value.substring(4), 10) : 0
300
+ min: format === FORMAT_DAYS_HOURS_MINUTES ? parseInt(value.substring(4), 10) : 0
301
301
  };
302
302
  };
303
303
 
@@ -327,7 +327,7 @@ var parseValidToObject = function parseValidToObject(value, tafStart, tafEnd) {
327
327
  var tafStartMoment = moment.utc(tafStart);
328
328
  var tafEndMoment = moment.utc(tafEnd);
329
329
  var startEnd = trimmedValue.split('/');
330
- var format = trimmedValue.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTS : FORMAT_DAYS_HOURS;
330
+ var format = trimmedValue.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTES : FORMAT_DAYS_HOURS;
331
331
  var startSections = getSections(startEnd[0], format);
332
332
  var start = getValidityTimeStamp('start', startSections, tafStartMoment, tafEndMoment).format('YYYY-MM-DDTHH:mm:ss[Z]'); // If we only have start value - return that otherwise, also get end time
333
333
 
@@ -352,7 +352,8 @@ var invalidValidityStartTimeMessage = 'Invalid validity start time, change group
352
352
  var invalidValidityPeriodMessage = 'Invalid validity period, validity end time has to be after validity start time';
353
353
  var invalidValidityEndTimeMessage = 'Invalid validity end time, change group validity must lie within the TAF validity period';
354
354
  var invalidChangeValidInterFieldMessage = 'Invalid validity period, expected DDHH/DDHH for BECMG and TEMPO or DDHHmm for FM';
355
- var invalidBECMGDurationValidInterFieldMessage = 'Invalid validity period, for BECMG only validity periods with a duration of 1, 2, 3 or 4 hours are allowed'; // Validations
355
+ var invalidBECMGDurationValidInterFieldMessage = 'Invalid validity period, for BECMG only validity periods with a duration of 1, 2, 3 or 4 hours are allowed';
356
+ var invalidChangeGroupOverlapsWithFM = 'The valid time of a change group cannot overlap with the valid time of a following FM group. This change group should end before or at the hour of the start of the FM group'; // Validations
356
357
  // Ensure all individual sections are correct (DD HH mm etc)
357
358
 
358
359
  var validateValidSections = function validateValidSections(sections, isStartEnd) {
@@ -376,7 +377,7 @@ var validateIsValidDates = function validateIsValidDates(value, tafStart, tafEnd
376
377
  var tafStartMoment = moment.utc(tafStart);
377
378
  var tafEndMoment = moment.utc(tafEnd);
378
379
  var startEnd = value.split('/');
379
- var format = value.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTS : FORMAT_DAYS_HOURS;
380
+ var format = value.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTES : FORMAT_DAYS_HOURS;
380
381
  var validateMsg = []; // Validate start time
381
382
 
382
383
  var startSections = getSections(startEnd[0], format); // Validate individual sections for start
@@ -454,7 +455,7 @@ var validateValidChangeGroupInterField = function validateValidChangeGroupInterF
454
455
  var tafStartMoment = moment.utc(tafStart);
455
456
  var tafEndMoment = moment.utc(tafEnd);
456
457
  var startEnd = trimmedValue.split('/');
457
- var format = trimmedValue.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTS : FORMAT_DAYS_HOURS; // Validate start time
458
+ var format = trimmedValue.indexOf('/') === -1 ? FORMAT_DAYS_HOURS_MINUTES : FORMAT_DAYS_HOURS; // Validate start time
458
459
 
459
460
  var startSections = getSections(startEnd[0], format);
460
461
  var startTimestamp = getValidityTimeStamp('start', startSections, tafStartMoment, tafEndMoment);
@@ -474,18 +475,18 @@ var validProbChangeOrder = ['FM', 'BECMG', 'TEMPO', 'PROB40', 'PROB30', 'PROB40
474
475
  var invalidPreviousChangeGroupIsBeforeMessage = 'Valid time should be after previous valid time';
475
476
  var invalidPreviousChangeGroupOrderMessage = "When valid times are equal, the change/probability order should be: ".concat(validProbChangeOrder.join(', '));
476
477
  var invalidPreviousChangeGroupHasSameValue = "When valid times are equal, probability/change can't have the same value as previous row value";
477
- var validatePreviousChangeGroup = function validatePreviousChangeGroup(currentChangeGroup, nextChangeGroup, tafStart, tafEnd) {
478
+ var validatePreviousChangeGroup = function validatePreviousChangeGroup(currentChangeGroup, previousChangeGroup, tafStart, tafEnd) {
478
479
  // extract the needed values from changeGroups
479
480
  var valid = currentChangeGroup.valid,
480
481
  _currentChangeGroup$c = currentChangeGroup.change,
481
482
  change = _currentChangeGroup$c === void 0 ? '' : _currentChangeGroup$c,
482
483
  _currentChangeGroup$p = currentChangeGroup.probability,
483
484
  probability = _currentChangeGroup$p === void 0 ? '' : _currentChangeGroup$p;
484
- var previousValid = nextChangeGroup.valid,
485
- _nextChangeGroup$chan = nextChangeGroup.change,
486
- previousChange = _nextChangeGroup$chan === void 0 ? '' : _nextChangeGroup$chan,
487
- _nextChangeGroup$prob = nextChangeGroup.probability,
488
- previousProbability = _nextChangeGroup$prob === void 0 ? '' : _nextChangeGroup$prob; // get the parsed values
485
+ var previousValid = previousChangeGroup.valid,
486
+ _previousChangeGroup$ = previousChangeGroup.change,
487
+ previousChange = _previousChangeGroup$ === void 0 ? '' : _previousChangeGroup$,
488
+ _previousChangeGroup$2 = previousChangeGroup.probability,
489
+ previousProbability = _previousChangeGroup$2 === void 0 ? '' : _previousChangeGroup$2; // get the parsed values
489
490
 
490
491
  var validValue = parseValidToObject(valid, tafStart, tafEnd);
491
492
  var previousValidValue = parseValidToObject(previousValid, tafStart, tafEnd);
@@ -518,6 +519,27 @@ var validatePreviousChangeGroup = function validatePreviousChangeGroup(currentCh
518
519
  }
519
520
  }
520
521
 
522
+ return true;
523
+ }; // validate overlapping validity when one of the following changegroups is FM
524
+
525
+ var validateOverlapWithFM = function validateOverlapWithFM(currentChangeGroup, nextChangeGroups, tafStart, tafEnd) {
526
+ var valid = currentChangeGroup.valid;
527
+ if (!valid || !nextChangeGroups.length) return true;
528
+ var validValue = parseValidToObject(valid, tafStart, tafEnd);
529
+ var currentRowEndTime = moment(validValue.end);
530
+ var firstFMChangeGroup = nextChangeGroups.find(function (nextChangeGroup) {
531
+ return nextChangeGroup.change.trim() === 'FM';
532
+ });
533
+
534
+ if (firstFMChangeGroup && firstFMChangeGroup.valid) {
535
+ var FMValidValue = parseValidToObject(firstFMChangeGroup.valid, tafStart, tafEnd);
536
+ var FMStartTime = moment(FMValidValue.start);
537
+
538
+ if (currentRowEndTime.isAfter(FMStartTime)) {
539
+ return invalidChangeGroupOverlapsWithFM;
540
+ }
541
+ }
542
+
521
543
  return true;
522
544
  };
523
545
 
@@ -1450,7 +1472,8 @@ var invalidWindGustSpeedCombinationMessage = 'Invalid wind gusts, gusts must at
1450
1472
  var invalidWindGustSpeedBelow15Message = 'Invalid wind gusts, gusts are only allowed for a minimum wind speed of 15 knots';
1451
1473
  var invalidGustForWindP99Message = 'Invalid wind speed and gust combination, if wind is P99, gusts can only be empty or P99';
1452
1474
  var invalidWindSpeedForDirectionZeroMessage = 'Invalid wind speed, if direction is 000, speed can only be 00';
1453
- var invalidWindSpeedForDirectionNonZeroMessage = 'Invalid wind speed, if direction is not 000, speed can not be 00'; // validations
1475
+ var invalidWindSpeedForDirectionNonZeroMessage = 'Invalid wind speed, if direction is not 000, speed can not be 00';
1476
+ var invalidWindVRBWindDirectionMessage = 'Invalid wind direction, VRB can only be used in combination with windspeeds smaller than 4 or in combination with gusts and showers'; // validations
1454
1477
 
1455
1478
  var validateDirection = function validateDirection(value) {
1456
1479
  // if not a number
@@ -1498,7 +1521,7 @@ var validateUnit = function validateUnit(value) {
1498
1521
  return value === 'KT' || value === '' || invalidWindMessage;
1499
1522
  };
1500
1523
 
1501
- var validateWindInterSection = function validateWindInterSection(speed, gust, direction) {
1524
+ var validateWindInterSection = function validateWindInterSection(speed, gust, direction, weather1Value, weather2Value, weather3Value) {
1502
1525
  if (direction === '000' && speed !== '00') {
1503
1526
  return invalidWindSpeedForDirectionZeroMessage;
1504
1527
  }
@@ -1507,6 +1530,19 @@ var validateWindInterSection = function validateWindInterSection(speed, gust, di
1507
1530
  return invalidWindSpeedForDirectionNonZeroMessage;
1508
1531
  }
1509
1532
 
1533
+ if (direction === 'VRB' && (speed === 'P99' || parseInt(speed, 10) > 3)) {
1534
+ // Only allow VRB for speeds smaller than 4 or in combination with gusts and showers (SH, TS, SQ)
1535
+ var allowedWeatherPhenom = ['SH', 'TS', 'SQ'];
1536
+ if (gust === '' || !allowedWeatherPhenom.some(function (allowedPhenom) {
1537
+ return weather1Value.includes(allowedPhenom);
1538
+ }) && !allowedWeatherPhenom.some(function (allowedPhenom) {
1539
+ return weather2Value.includes(allowedPhenom);
1540
+ }) && !allowedWeatherPhenom.some(function (allowedPhenom) {
1541
+ return weather3Value.includes(allowedPhenom);
1542
+ })) return invalidWindVRBWindDirectionMessage;
1543
+ } // Validate gust
1544
+
1545
+
1510
1546
  if (gust === '') {
1511
1547
  return true;
1512
1548
  }
@@ -1527,20 +1563,23 @@ var validateWindInterSection = function validateWindInterSection(speed, gust, di
1527
1563
  }; // Main validation function
1528
1564
 
1529
1565
 
1530
- var validateWindField = function validateWindField(value) {
1531
- var trimmedValue = value.trim();
1566
+ var validateWindField = function validateWindField(value, weatherfield1, weatherfield2, weatherfield3) {
1567
+ var trimmedWindValue = value.trim();
1568
+ var trimmedWeather1Value = weatherfield1.trim();
1569
+ var trimmedWeather2Value = weatherfield2.trim();
1570
+ var trimmedWeather3Value = weatherfield3.trim();
1532
1571
 
1533
- if (!trimmedValue.length) {
1572
+ if (!trimmedWindValue.length) {
1534
1573
  return true;
1535
1574
  } // Validate length and ensure it doesn't contain any other characters than numbers and VRB P KT and G
1536
1575
 
1537
1576
 
1538
- if (trimmedValue.length < 5 || trimmedValue.length > 12 || !trimmedValue.match(/^[0-9VRBPGKT]+$/)) {
1577
+ if (trimmedWindValue.length < 5 || trimmedWindValue.length > 12 || !trimmedWindValue.match(/^[0-9VRBPGKT]+$/)) {
1539
1578
  return invalidWindMessage;
1540
1579
  } // First validate individual sections
1541
1580
 
1542
1581
 
1543
- var windValidationIndv = extractValidateWindSections(trimmedValue, true);
1582
+ var windValidationIndv = extractValidateWindSections(trimmedWindValue, true);
1544
1583
 
1545
1584
  if (windValidationIndv.validations.length !== 0) {
1546
1585
  return windValidationIndv.validations.find(function (error) {
@@ -1549,7 +1588,7 @@ var validateWindField = function validateWindField(value) {
1549
1588
  } // Then do any intersection validation
1550
1589
 
1551
1590
 
1552
- return validateWindInterSection(windValidationIndv.speed, windValidationIndv.gust, windValidationIndv.direction);
1591
+ return validateWindInterSection(windValidationIndv.speed, windValidationIndv.gust, windValidationIndv.direction, trimmedWeather1Value, trimmedWeather2Value, trimmedWeather3Value);
1553
1592
  };
1554
1593
 
1555
1594
  var formatSingleCloud = function formatSingleCloud(value) {
@@ -1596,10 +1635,10 @@ var formatCloudsToString = function formatCloudsToString(clouds) {
1596
1635
  var parseSingleCloud = function parseSingleCloud(value) {
1597
1636
  if (!value) return null;
1598
1637
  var trimmedCloud = value.trim();
1599
- var cloudType = trimmedCloud.substr(6, 3);
1638
+ var cloudType = trimmedCloud.substring(6, 9);
1600
1639
  return Object.assign({
1601
- coverage: trimmedCloud.substr(0, 3),
1602
- height: parseInt(trimmedCloud.substr(3, 3), 10)
1640
+ coverage: trimmedCloud.substring(0, 3),
1641
+ height: parseInt(trimmedCloud.substring(3, 6), 10)
1603
1642
  }, cloudType && {
1604
1643
  type: cloudType
1605
1644
  });
@@ -1615,20 +1654,22 @@ var parseCloudsToObject = function parseCloudsToObject(clouds) {
1615
1654
  switch (key) {
1616
1655
  case 'cloud1':
1617
1656
  {
1618
- if (isVerticalVisibility(clouds[key])) {
1657
+ var trimmedValue = clouds[key].trim();
1658
+
1659
+ if (isVerticalVisibility(trimmedValue)) {
1619
1660
  // Parse Vertical Visibility
1620
1661
  return Object.assign(Object.assign({}, list), _defineProperty({}, key, {
1621
- verticalVisibility: parseInt(clouds[key].substr(2, 3), 10)
1662
+ verticalVisibility: parseInt(trimmedValue.substring(2, 5), 10)
1622
1663
  }));
1623
1664
  }
1624
1665
 
1625
- if (clouds[key] === 'NSC') {
1666
+ if (trimmedValue === 'NSC') {
1626
1667
  // Parse No Significant Clouds
1627
- return Object.assign(Object.assign({}, list), _defineProperty({}, key, clouds[key]));
1668
+ return Object.assign(Object.assign({}, list), _defineProperty({}, key, trimmedValue));
1628
1669
  } // Parse Cloud
1629
1670
 
1630
1671
 
1631
- return Object.assign(Object.assign({}, list), _defineProperty({}, key, parseSingleCloud(clouds[key])));
1672
+ return Object.assign(Object.assign({}, list), _defineProperty({}, key, parseSingleCloud(trimmedValue)));
1632
1673
  }
1633
1674
 
1634
1675
  default:
@@ -1656,16 +1697,19 @@ var invalidCloudHeightMessage = 'Invalid cloud height, expected a height consist
1656
1697
  var invalidCloudHeightStepsMessage = 'Invalid cloud height, a height above 050 must be rounded to the nearest 1000ft';
1657
1698
  var invalidCLoudTypeMessage = 'Invalid cloud type, expected CB or TCU';
1658
1699
  var invalidHeightTypeCombinationMessage = 'Invalid cloud input, when cloud height is 050 or higher, CB or TCU is required';
1659
- var invalidVerticalVisibilityMessage = 'Invalid vertical visibility, expected VV<value> with value consisting of 3 digits between 000 and 010';
1700
+ var invalidVerticalVisibilityMessage = 'Invalid vertical visibility, expected VV<value> with value consisting of 3 digits';
1701
+ var invalidVerticalVisibilityHeightMessage = 'Invalid vertical visibility, visibility should lie between 001 and 010';
1702
+ var invalidVerticalVisibilityHeightFGMessage = 'Invalid vertical visibility, in case of fog visibility should lie between 001 and 005';
1660
1703
  var invalidCloudHeightComparedToPreviousMessage = 'Invalid cloud height, height must be greater than previous cloud group height';
1661
- var invalidCloud2CoverageTypeCombinationMessage = 'Invalid cloud input, cloud type is required when coverage is FEW';
1704
+ var invalidCloud2CoverageTypeCombinationMessage = 'Invalid cloud input, for the second cloud group (excluding any significant convective cloud groups with CB/TCU) a coverage of FEW is not allowed';
1662
1705
  var invalidCloud2WithVerticalVisibilityMessage = 'Invalid cloud input, cloud type is required when Vertical Visibility is given';
1663
- var invalidCloud3CoverageTypeCombinationMessage = 'Invalid cloud input, cloud type is required when coverage is FEW or SCT';
1706
+ var invalidCloud3CoverageTypeCombinationMessage = 'Invalid cloud input, for the third cloud group (excluding any significant convective cloud groups with CB/TCU) a coverage of FEW or SCT is not allowed';
1664
1707
  var invalidCloudWithVerticalVisibilityMessage = 'Invalid cloud input, third or fourth cloud group is not allowed when Vertical Visibility is given';
1665
1708
  var invalidCloudWithPreviousEmptyCloud = 'Invalid cloud input, value is not allowed when previous cloud group is empty';
1666
1709
  var invalidCloudWithNSCMessage = 'Invalid cloud input, other cloud groups are not allowed when No Significant Clouds is given';
1667
- var invalidCloud4WithPreviousType = 'Invalid cloud input, value is not allowed when previous cloud group has a type';
1668
- var invalidCloudCAVOKMessage = 'Invalid cloud input, when CAVOK is used, cloud groups must be empty'; // validations
1710
+ var invalidCloudWithPreviousType = 'Invalid cloud input, only one significant convective cloud group with CB/TCU is allowed';
1711
+ var invalidCloudCAVOKMessage = 'Invalid cloud input, when CAVOK is used, cloud groups must be empty';
1712
+ var invalidCloud4TypeMissingMessage = 'Invalid cloud input for fourth group, CB or TCU required if no other significant convective cloud group present'; // validations
1669
1713
 
1670
1714
  var isLengthValid = function isLengthValid(value) {
1671
1715
  var onlyDigitsOrSpecificLetters = RegExp(/^[0-9FEWSCTBKNOVU]+$/);
@@ -1712,25 +1756,32 @@ var isHeightAllowedWithType = function isHeightAllowedWithType(height, type) {
1712
1756
  };
1713
1757
 
1714
1758
  var isVerticalVisibility = function isVerticalVisibility(value) {
1715
- return value.substr(0, 2) === 'VV';
1759
+ return value.substring(0, 2) === 'VV';
1716
1760
  };
1717
1761
 
1718
- var isVerticalVisibilityValid = function isVerticalVisibilityValid(value) {
1762
+ var isVerticalVisibilityValid = function isVerticalVisibilityValid(value, weather1, weather2, weather3) {
1719
1763
  // validate if its a number
1720
1764
  if (!value.match(/^[0-9]+$/)) {
1721
- return false;
1765
+ return invalidVerticalVisibilityMessage;
1722
1766
  } // check if its 3 digits
1723
1767
 
1724
1768
 
1725
1769
  if (value.length !== 3) {
1726
- return false;
1727
- } // value should not be above 10
1728
-
1770
+ return invalidVerticalVisibilityMessage;
1771
+ }
1729
1772
 
1730
1773
  var intValue = parseInt(value, 10);
1731
1774
 
1732
- if (intValue > 10) {
1733
- return false;
1775
+ if (weather1 !== 'FG' && weather2 !== 'FG' && weather3 !== 'FG') {
1776
+ // value should not be above 10
1777
+ if (intValue < 1 || intValue > 10) {
1778
+ return invalidVerticalVisibilityHeightMessage;
1779
+ }
1780
+ } else if (intValue < 1 || intValue > 5) {
1781
+ // Apply Dutch rule as national exception
1782
+ // In case of fog (FG) the vertical visibility can only be between VV001 up to and including VV005
1783
+ // HEIGHT_VV is: (001-(1)-005). Deze maxima zijn officiële Nederlandse afwijkingen van de WMO/ICAO regelgeving
1784
+ return invalidVerticalVisibilityHeightFGMessage;
1734
1785
  }
1735
1786
 
1736
1787
  return true;
@@ -1747,14 +1798,14 @@ var sharedCloudValidations = function sharedCloudValidations(_ref) {
1747
1798
  } // Validate coverage
1748
1799
 
1749
1800
 
1750
- var coverage = value.substr(0, 3);
1801
+ var coverage = value.substring(0, 3);
1751
1802
 
1752
1803
  if (!isCoverageValid(coverage)) {
1753
1804
  errorMessages.push(invalidCloudCoverageMessage);
1754
1805
  } // Validate height
1755
1806
 
1756
1807
 
1757
- var height = value.substr(3, 3);
1808
+ var height = value.substring(3, 6);
1758
1809
  var isValidHeight = isHeightValid(height);
1759
1810
 
1760
1811
  if (isValidHeight !== true) {
@@ -1763,7 +1814,7 @@ var sharedCloudValidations = function sharedCloudValidations(_ref) {
1763
1814
  } // Validate type
1764
1815
 
1765
1816
 
1766
- var type = value.substr(6, 3);
1817
+ var type = value.substring(6, 9);
1767
1818
 
1768
1819
  if (!isTypeValid(type)) {
1769
1820
  errorMessages.push(invalidCLoudTypeMessage);
@@ -1782,41 +1833,40 @@ var sharedCloudValidations = function sharedCloudValidations(_ref) {
1782
1833
  };
1783
1834
  };
1784
1835
 
1785
- var validateFirstCloud = function validateFirstCloud(value, visibilityValue) {
1786
- var trimmedValue = value.trim(); // Field can be left empty
1836
+ var validateFirstCloud = function validateFirstCloud(value, visibilityValue, weatherfield1, weatherfield2, weatherfield3) {
1837
+ var trimmedValueFirstCloud = value.trim();
1838
+ var trimmedValueVisibility = visibilityValue.trim();
1839
+ var trimmedWeather1Value = weatherfield1.trim();
1840
+ var trimmedWeather2Value = weatherfield2.trim();
1841
+ var trimmedWeather3Value = weatherfield3.trim(); // Field can be left empty
1787
1842
 
1788
- if (!trimmedValue.length) {
1843
+ if (!trimmedValueFirstCloud.length) {
1789
1844
  return true;
1790
1845
  }
1791
1846
 
1792
- if (trimmedValue && visibilityValue === 'CAVOK') {
1847
+ if (trimmedValueFirstCloud && trimmedValueVisibility === 'CAVOK') {
1793
1848
  return invalidCloudCAVOKMessage;
1794
1849
  } // Check for No Signicant Clouds
1795
1850
 
1796
1851
 
1797
- if (trimmedValue === 'NSC') {
1852
+ if (trimmedValueFirstCloud === 'NSC') {
1798
1853
  return true;
1799
1854
  } // Validate Vertical Visibility
1800
1855
 
1801
1856
 
1802
- if (isVerticalVisibility(trimmedValue)) {
1857
+ if (isVerticalVisibility(trimmedValueFirstCloud)) {
1803
1858
  if ( // Validate length of 5
1804
- trimmedValue.length !== 5 || // Ensure it only contains digits or VV
1805
- !trimmedValue.match(/^[0-9V]+$/)) {
1806
- return invalidVerticalVisibilityMessage;
1807
- }
1808
-
1809
- var verticalVisibilityValue = trimmedValue.substr(2, 3);
1810
-
1811
- if (!isVerticalVisibilityValid(verticalVisibilityValue)) {
1859
+ trimmedValueFirstCloud.length !== 5 || // Ensure it only contains digits or VV
1860
+ !trimmedValueFirstCloud.match(/^[0-9V]+$/)) {
1812
1861
  return invalidVerticalVisibilityMessage;
1813
1862
  }
1814
1863
 
1815
- return true;
1864
+ var verticalVisibilityValue = trimmedValueFirstCloud.substring(2, 5);
1865
+ return isVerticalVisibilityValid(verticalVisibilityValue, trimmedWeather1Value, trimmedWeather2Value, trimmedWeather3Value);
1816
1866
  }
1817
1867
 
1818
1868
  var _sharedCloudValidatio = sharedCloudValidations({
1819
- value: trimmedValue,
1869
+ value: trimmedValueFirstCloud,
1820
1870
  canBeNSC: true
1821
1871
  }),
1822
1872
  errorMessages = _sharedCloudValidatio.errorMessages; // Return first error if any
@@ -1825,15 +1875,26 @@ var validateFirstCloud = function validateFirstCloud(value, visibilityValue) {
1825
1875
  return errorMessages.length ? errorMessages[0] : true;
1826
1876
  };
1827
1877
  var validateSecondCloud = function validateSecondCloud(firstCloudValue, secondCloudValue, visibilityValue) {
1828
- var trimmedValue = secondCloudValue.trim(); // Field can be left empty
1878
+ var trimmedValueFirstCloud = firstCloudValue.trim();
1879
+ var trimmedValueSecondCloud = secondCloudValue.trim(); // Field can be left empty
1829
1880
 
1830
- if (!trimmedValue.length) {
1881
+ if (!trimmedValueSecondCloud.length) {
1831
1882
  return true;
1883
+ } // If Cloud1 is NSC, Cloud2 has to be empty
1884
+
1885
+
1886
+ if (trimmedValueFirstCloud === 'NSC' && trimmedValueSecondCloud !== '') {
1887
+ return invalidCloudWithNSCMessage;
1888
+ } // If Cloud1 is empty Cloud2 should be empty
1889
+
1890
+
1891
+ if (trimmedValueFirstCloud === '') {
1892
+ return invalidCloudWithPreviousEmptyCloud;
1832
1893
  } // Generic validations
1833
1894
 
1834
1895
 
1835
1896
  var _sharedCloudValidatio2 = sharedCloudValidations({
1836
- value: trimmedValue
1897
+ value: trimmedValueSecondCloud
1837
1898
  }),
1838
1899
  coverage = _sharedCloudValidatio2.coverage,
1839
1900
  height = _sharedCloudValidatio2.height,
@@ -1843,32 +1904,32 @@ var validateSecondCloud = function validateSecondCloud(firstCloudValue, secondCl
1843
1904
 
1844
1905
  if (errorMessages.length) {
1845
1906
  return errorMessages[0];
1846
- } // Cloud2 specific validations
1847
- // Without type, coverage can not be FEW
1907
+ } // Cloud2 specific validations - only to be applied when cloud1 does not contain type CB/TCU
1848
1908
 
1849
1909
 
1850
- if (type === '' && coverage === 'FEW') {
1851
- return invalidCloud2CoverageTypeCombinationMessage;
1910
+ var typeCloud1 = trimmedValueFirstCloud.substring(6, 9);
1911
+
1912
+ if (typeCloud1 !== 'CB' && typeCloud1 !== 'TCU') {
1913
+ // Without a type specified in cloud group 1, this group counts as #2 and coverage can not be FEW
1914
+ if (type === '' && coverage === 'FEW') {
1915
+ return invalidCloud2CoverageTypeCombinationMessage;
1916
+ }
1852
1917
  } // If Cloud1 is not valid, skip further validation of Cloud2
1918
+ // No need to pass the weatherfields as their content does not influence what happens below
1853
1919
 
1854
1920
 
1855
- if (validateFirstCloud(firstCloudValue, visibilityValue) !== true) {
1921
+ if (validateFirstCloud(trimmedValueFirstCloud, visibilityValue, '', '', '') !== true) {
1856
1922
  return true;
1857
- } // If Cloud1 is NSC, Cloud2 has to be empty
1858
-
1859
-
1860
- if (firstCloudValue === 'NSC' && trimmedValue !== '') {
1861
- return invalidCloudWithNSCMessage;
1862
- } // If Cloud1 is empty Cloud2 should be empty
1923
+ } // If Cloud1 contains a type, Cloud2 cannot contain a type
1863
1924
 
1864
1925
 
1865
- if (firstCloudValue === '') {
1866
- return invalidCloudWithPreviousEmptyCloud;
1926
+ if (type !== '' && typeCloud1 !== '') {
1927
+ return invalidCloudWithPreviousType;
1867
1928
  } // Cloud2 height has to be greater than Cloud1 height
1868
1929
 
1869
1930
 
1870
- if (!isVerticalVisibility(firstCloudValue)) {
1871
- var cloud1Height = firstCloudValue.substr(3, 3);
1931
+ if (!isVerticalVisibility(trimmedValueFirstCloud)) {
1932
+ var cloud1Height = trimmedValueFirstCloud.substring(3, 6);
1872
1933
 
1873
1934
  if (height <= cloud1Height) {
1874
1935
  return invalidCloudHeightComparedToPreviousMessage;
@@ -1876,22 +1937,34 @@ var validateSecondCloud = function validateSecondCloud(firstCloudValue, secondCl
1876
1937
  } // If Cloud1 contains Vertical Visibility then Cloud2 type is required
1877
1938
 
1878
1939
 
1879
- if (isVerticalVisibility(firstCloudValue) && type === '') {
1940
+ if (isVerticalVisibility(trimmedValueFirstCloud) && type === '') {
1880
1941
  return invalidCloud2WithVerticalVisibilityMessage;
1881
1942
  }
1882
1943
 
1883
1944
  return true;
1884
1945
  };
1885
1946
  var validateThirdCloud = function validateThirdCloud(firstCloudValue, secondCloudValue, thirdCloudValue, visibilityValue) {
1886
- var trimmedValue = thirdCloudValue.trim(); // Field can be left empty
1947
+ var trimmedValueFirstCloud = firstCloudValue.trim();
1948
+ var trimmedValueSecondCloud = secondCloudValue.trim();
1949
+ var trimmedValueThirdCloud = thirdCloudValue.trim(); // Field can be left empty
1887
1950
 
1888
- if (!trimmedValue.length) {
1951
+ if (!trimmedValueThirdCloud.length) {
1889
1952
  return true;
1953
+ } // If Cloud1 is NSC, Cloud3 has to be empty
1954
+
1955
+
1956
+ if (trimmedValueFirstCloud === 'NSC' && trimmedValueThirdCloud !== '') {
1957
+ return invalidCloudWithNSCMessage;
1958
+ } // If Cloud1 or Cloud2 is empty Cloud3 should be empty
1959
+
1960
+
1961
+ if (trimmedValueFirstCloud === '' || trimmedValueSecondCloud === '') {
1962
+ return invalidCloudWithPreviousEmptyCloud;
1890
1963
  } // Generic validations
1891
1964
 
1892
1965
 
1893
1966
  var _sharedCloudValidatio3 = sharedCloudValidations({
1894
- value: trimmedValue
1967
+ value: trimmedValueThirdCloud
1895
1968
  }),
1896
1969
  coverage = _sharedCloudValidatio3.coverage,
1897
1970
  height = _sharedCloudValidatio3.height,
@@ -1902,45 +1975,45 @@ var validateThirdCloud = function validateThirdCloud(firstCloudValue, secondClou
1902
1975
  if (errorMessages.length) {
1903
1976
  return errorMessages[0];
1904
1977
  } // Cloud3 specific validations
1905
- // Without type, coverage can not be FEW or SCT
1978
+ // Without a type specified in cloud group 1 or 2, this group counts as #3 and coverage can not be FEW or SCT
1906
1979
 
1907
1980
 
1908
- if (type === '' && (coverage === 'FEW' || coverage === 'SCT')) {
1909
- return invalidCloud3CoverageTypeCombinationMessage;
1981
+ var typeCloud1 = trimmedValueFirstCloud.substring(6, 9);
1982
+ var typeCloud2 = trimmedValueSecondCloud.substring(6, 9);
1983
+
1984
+ if (typeCloud1 !== 'CB' && typeCloud1 !== 'TCU' && typeCloud2 !== 'CB' && typeCloud2 !== 'TCU') {
1985
+ if (type === '' && (coverage === 'FEW' || coverage === 'SCT')) {
1986
+ return invalidCloud3CoverageTypeCombinationMessage;
1987
+ }
1988
+ } else if (type === '' && coverage === 'FEW') {
1989
+ // In case we do have a CB/TCU group in one of the previous clouf groups. This cloudgroup should be evaluated as if it was the second group
1990
+ return invalidCloud2CoverageTypeCombinationMessage;
1910
1991
  } // If Cloud1 is not valid, skip further validation of Cloud3
1992
+ // No need to pass the weatherfields as their content does not influence what happens below
1993
+ // Since in case of VV the third field should be empty anyways
1911
1994
 
1912
1995
 
1913
- if (validateFirstCloud(firstCloudValue, visibilityValue) !== true) {
1996
+ if (validateFirstCloud(trimmedValueFirstCloud, visibilityValue, '', '', '') !== true) {
1914
1997
  return true;
1915
- } // If Cloud1 is empty Cloud3 should be empty
1916
-
1917
-
1918
- if (firstCloudValue === '') {
1919
- return invalidCloudWithPreviousEmptyCloud;
1920
1998
  } // If Cloud1 contains Vertical Visibility then Cloud3 should be empty
1921
1999
 
1922
2000
 
1923
- if (isVerticalVisibility(firstCloudValue)) {
2001
+ if (isVerticalVisibility(trimmedValueFirstCloud)) {
1924
2002
  return invalidCloudWithVerticalVisibilityMessage;
1925
- } // If Cloud1 is NSC, Cloud3 has to be empty
1926
-
1927
-
1928
- if (firstCloudValue === 'NSC' && trimmedValue !== '') {
1929
- return invalidCloudWithNSCMessage;
1930
2003
  } // If Cloud2 is not valid, skip further validation of Cloud3
1931
2004
 
1932
2005
 
1933
- if (validateSecondCloud(firstCloudValue, secondCloudValue, visibilityValue) !== true) {
2006
+ if (validateSecondCloud(trimmedValueFirstCloud, trimmedValueSecondCloud, visibilityValue) !== true) {
1934
2007
  return true;
1935
- } // If Cloud2 is empty Cloud3 should be empty
2008
+ } // If one of the previous groups contains a type, Cloud3 cannot contain a type
1936
2009
 
1937
2010
 
1938
- if (secondCloudValue === '') {
1939
- return invalidCloudWithPreviousEmptyCloud;
2011
+ if (type !== '' && (typeCloud1 !== '' || typeCloud2 !== '')) {
2012
+ return invalidCloudWithPreviousType;
1940
2013
  } // Cloud3 height has to be greater than Cloud2 height
1941
2014
 
1942
2015
 
1943
- var cloud2Height = secondCloudValue.substr(3, 3);
2016
+ var cloud2Height = trimmedValueSecondCloud.substring(3, 6);
1944
2017
 
1945
2018
  if (height <= cloud2Height) {
1946
2019
  return invalidCloudHeightComparedToPreviousMessage;
@@ -1949,17 +2022,31 @@ var validateThirdCloud = function validateThirdCloud(firstCloudValue, secondClou
1949
2022
  return true;
1950
2023
  };
1951
2024
  var validateFourthCloud = function validateFourthCloud(firstCloudValue, secondCloudValue, thirdCloudValue, fourthCloudValue, visibilityValue) {
1952
- var trimmedValue = fourthCloudValue.trim(); // Field can be left empty
2025
+ var trimmedValueFirstCloud = firstCloudValue.trim();
2026
+ var trimmedValueSecondCloud = secondCloudValue.trim();
2027
+ var trimmedValueThirdCloud = thirdCloudValue.trim();
2028
+ var trimmedValueFourthCloud = fourthCloudValue.trim(); // Field can be left empty
1953
2029
 
1954
- if (!trimmedValue.length) {
2030
+ if (!trimmedValueFourthCloud.length) {
1955
2031
  return true;
2032
+ } // If Cloud1 is NSC, Cloud4 has to be empty
2033
+
2034
+
2035
+ if (trimmedValueFirstCloud === 'NSC' && trimmedValueFourthCloud !== '') {
2036
+ return invalidCloudWithNSCMessage;
2037
+ } // If Cloud 1, 2 or 3 is empty Cloud4 should be empty
2038
+
2039
+
2040
+ if (trimmedValueFirstCloud === '' || trimmedValueSecondCloud === '' || trimmedValueThirdCloud === '') {
2041
+ return invalidCloudWithPreviousEmptyCloud;
1956
2042
  } // Generic validations
1957
2043
 
1958
2044
 
1959
2045
  var _sharedCloudValidatio4 = sharedCloudValidations({
1960
- value: trimmedValue
2046
+ value: trimmedValueFourthCloud
1961
2047
  }),
1962
2048
  height = _sharedCloudValidatio4.height,
2049
+ coverage = _sharedCloudValidatio4.coverage,
1963
2050
  type = _sharedCloudValidatio4.type,
1964
2051
  errorMessages = _sharedCloudValidatio4.errorMessages; // Return generic errors if any
1965
2052
 
@@ -1967,50 +2054,48 @@ var validateFourthCloud = function validateFourthCloud(firstCloudValue, secondCl
1967
2054
  if (errorMessages.length) {
1968
2055
  return errorMessages[0];
1969
2056
  } // Cloud4 specific validations
1970
- // Type is required
2057
+ // If none of the previous cloud groups contains a type, the fourth group must contain a type if not empty
2058
+
1971
2059
 
2060
+ var typeCloud1 = trimmedValueFirstCloud.substring(6, 9);
2061
+ var typeCloud2 = trimmedValueSecondCloud.substring(6, 9);
2062
+ var typeCloud3 = trimmedValueThirdCloud.substring(6, 9);
1972
2063
 
1973
- if (type === '') {
1974
- return invalidCLoudTypeMessage;
2064
+ if (typeCloud1 !== 'CB' && typeCloud1 !== 'TCU' && typeCloud2 !== 'CB' && typeCloud2 !== 'TCU' && typeCloud3 !== 'CB' && typeCloud3 !== 'TCU') {
2065
+ if (type === '') {
2066
+ return invalidCloud4TypeMissingMessage;
2067
+ }
2068
+ } else if (coverage === 'FEW' || coverage === 'SCT') {
2069
+ // We have a CB/TCU group in one of the previous cloud groups. This group should be evaluated as if it was the third group
2070
+ return invalidCloud3CoverageTypeCombinationMessage;
1975
2071
  } // If Cloud1 is not valid, skip further validation of Cloud4
2072
+ // No need to pass the weatherfields as their content does not influence what happens below
2073
+ // Since in case of VV the fourth field should be empty anyways
1976
2074
 
1977
2075
 
1978
- if (validateFirstCloud(firstCloudValue, visibilityValue) !== true) {
2076
+ if (validateFirstCloud(trimmedValueFirstCloud, visibilityValue, '', '', '') !== true) {
1979
2077
  return true;
1980
2078
  } // If Cloud1 contains Vertical Visibility then Cloud4 should be empty
1981
2079
 
1982
2080
 
1983
- if (isVerticalVisibility(firstCloudValue)) {
2081
+ if (isVerticalVisibility(trimmedValueFirstCloud)) {
1984
2082
  return invalidCloudWithVerticalVisibilityMessage;
1985
- } // If Cloud1 is NSC, Cloud4 has to be empty
1986
-
1987
-
1988
- if (firstCloudValue === 'NSC' && trimmedValue !== '') {
1989
- return invalidCloudWithNSCMessage;
1990
- } // If Cloud 1, 2 or 3 is empty Cloud4 should be empty
1991
-
1992
-
1993
- if (firstCloudValue === '' || secondCloudValue === '' || thirdCloudValue === '') {
1994
- return invalidCloudWithPreviousEmptyCloud;
1995
2083
  } // If Cloud3 is not valid, skip further validation of Cloud4
1996
2084
 
1997
2085
 
1998
- if (validateThirdCloud(firstCloudValue, secondCloudValue, thirdCloudValue, visibilityValue) !== true) {
2086
+ if (validateThirdCloud(trimmedValueFirstCloud, trimmedValueSecondCloud, trimmedValueThirdCloud, visibilityValue) !== true) {
1999
2087
  return true;
2000
- } // If Cloud3 contains a type, Cloud4 should be empty
2088
+ } // If one of the previous groups contains a type, Cloud4 cannot contain a type
2001
2089
 
2002
2090
 
2003
- var cloud3Type = thirdCloudValue.substr(6, 3);
2004
-
2005
- if (cloud3Type !== '') {
2006
- return invalidCloud4WithPreviousType;
2091
+ if (type !== '' && (typeCloud1 !== '' || typeCloud2 !== '' || typeCloud3 !== '')) {
2092
+ return invalidCloudWithPreviousType;
2007
2093
  } // Cloud4 height has to be greater than Cloud3 height
2008
2094
 
2009
2095
 
2010
- var cloud3Height = thirdCloudValue.substr(3, 3);
2096
+ var cloud3Height = trimmedValueThirdCloud.substring(3, 6);
2011
2097
 
2012
2098
  if (height <= cloud3Height) {
2013
- // Because of the type validations this is automatically enforced for Cloud4, so impossible to end up here but leaving the check in just in case
2014
2099
  return invalidCloudHeightComparedToPreviousMessage;
2015
2100
  }
2016
2101
 
@@ -2449,34 +2534,28 @@ var getConfirmationDialogButtonLabel = function getConfirmationDialogButtonLabel
2449
2534
  }
2450
2535
  };
2451
2536
 
2452
- /* *
2453
- * Licensed under the Apache License, Version 2.0 (the "License");
2454
- * you may not use this file except in compliance with the License.
2455
- * You may obtain a copy of the License at
2456
- *
2457
- * http://www.apache.org/licenses/LICENSE-2.0
2458
- *
2459
- * Unless required by applicable law or agreed to in writing, software
2460
- * distributed under the License is distributed on an "AS IS" BASIS,
2461
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2462
- * See the License for the specific language governing permissions and
2463
- * limitations under the License.
2464
- *
2465
- * Copyright 2021 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2466
- * Copyright 2021 - Finnish Meteorological Institute (FMI)
2467
- * */
2468
2537
  var useStyles$9 = makeStyles(function (theme) {
2469
2538
  return {
2470
2539
  textFieldGridItem: {
2471
2540
  marginRight: 4
2472
2541
  },
2542
+ textFieldRoot: {
2543
+ '&.Mui-disabled::before': {
2544
+ borderBottom: 'none'
2545
+ },
2546
+ '&:after': {
2547
+ borderBottomColor: '#3f51b5'
2548
+ }
2549
+ },
2473
2550
  textFieldInput: {
2474
2551
  fontSize: '14px',
2475
2552
  paddingLeft: 1,
2476
2553
  paddingRight: 1,
2477
2554
  color: '#051039',
2478
- WebkitTextFillColor: '#051039' // safari text color fix
2479
-
2555
+ WebkitTextFillColor: '#051039',
2556
+ '&.Mui-disabled': {
2557
+ backgroundColor: 'white'
2558
+ }
2480
2559
  },
2481
2560
  textFieldLabel: {
2482
2561
  fontSize: '14px'
@@ -2559,7 +2638,8 @@ var BaseTextField = /*#__PURE__*/React__default.memo(function (props) {
2559
2638
  variant: "filled",
2560
2639
  InputProps: {
2561
2640
  classes: {
2562
- input: classes.textFieldInput
2641
+ input: classes.textFieldInput,
2642
+ root: classes.textFieldRoot
2563
2643
  }
2564
2644
  },
2565
2645
  InputLabelProps: {
@@ -2855,11 +2935,40 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2855
2935
  return true;
2856
2936
  }, [index, isChangeGroup, getValues]);
2857
2937
 
2858
- var getFieldFromNextRow = function getFieldFromNextRow() {
2859
- var fieldname = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'valid';
2860
- var nextValidFieldName = "changeGroups[".concat(index + 1, "].").concat(fieldname);
2861
- var nextRowValidValue = getValues(nextValidFieldName);
2862
- return nextRowValidValue ? [nextValidFieldName] : [];
2938
+ var getFieldFromRow = function getFieldFromRow(fieldname, rowIndex) {
2939
+ var indexedFieldName = "changeGroups[".concat(rowIndex, "].").concat(fieldname);
2940
+ var rowValue = getValues(indexedFieldName);
2941
+ return rowValue ? [indexedFieldName] : [];
2942
+ };
2943
+
2944
+ var getValidFieldFromNextRow = function getValidFieldFromNextRow() {
2945
+ return getFieldFromRow('valid', index + 1);
2946
+ };
2947
+
2948
+ var validateNextRows = React__default.useCallback(function () {
2949
+ if (isChangeGroup) {
2950
+ var _getValues2 = getValues(),
2951
+ validDateEnd = _getValues2.validDateEnd,
2952
+ validDateStart = _getValues2.validDateStart,
2953
+ changeGroups = _getValues2.changeGroups;
2954
+
2955
+ var currentChangeGroup = changeGroups[index];
2956
+ var nextChangeGroups = changeGroups.slice(index + 1);
2957
+ return validateOverlapWithFM(currentChangeGroup, nextChangeGroups, validDateStart, validDateEnd);
2958
+ }
2959
+
2960
+ return true;
2961
+ }, [index, isChangeGroup, getValues]);
2962
+
2963
+ var getPreviousValidFields = function getPreviousValidFields(rowIndex) {
2964
+ var _getValues3 = getValues(),
2965
+ changeGroups = _getValues3.changeGroups;
2966
+
2967
+ var previousChangeGroups = changeGroups.slice(0, rowIndex);
2968
+ var validFields = previousChangeGroups.map(function (_element, index) {
2969
+ return getFieldFromRow('valid', index)[0];
2970
+ });
2971
+ return validFields;
2863
2972
  };
2864
2973
 
2865
2974
  var addChangeGroup = React__default.useCallback(function () {
@@ -2908,7 +3017,7 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2908
3017
  }],
2909
3018
  onBlur: function onBlur() {
2910
3019
  if (isChangeGroup) {
2911
- var nextValidFieldName = getFieldFromNextRow();
3020
+ var nextValidFieldName = getValidFieldFromNextRow();
2912
3021
  trigger([].concat(_toConsumableArray(subFields), _toConsumableArray(mainOptionalFields), _toConsumableArray(mainFields), _toConsumableArray(nextValidFieldName)));
2913
3022
  }
2914
3023
  }
@@ -2938,8 +3047,9 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2938
3047
  }],
2939
3048
  onBlur: function onBlur() {
2940
3049
  if (isChangeGroup) {
2941
- var nextValidFieldName = getFieldFromNextRow();
2942
- trigger([].concat(_toConsumableArray(subFields), _toConsumableArray(mainOptionalFields), _toConsumableArray(mainFields), _toConsumableArray(nextValidFieldName)));
3050
+ var nextValidFieldName = getValidFieldFromNextRow();
3051
+ var previousValidFieldNames = getPreviousValidFields(index);
3052
+ trigger([].concat(_toConsumableArray(subFields), _toConsumableArray(mainOptionalFields), _toConsumableArray(mainFields), _toConsumableArray(nextValidFieldName), _toConsumableArray(previousValidFieldNames)));
2943
3053
  }
2944
3054
  }
2945
3055
  })), /*#__PURE__*/React__default.createElement(TafFormTextField, {
@@ -2957,13 +3067,15 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2957
3067
  validateValidChangeGroupInterField: function validateValidChangeGroupInterField$1(value) {
2958
3068
  return isChangeGroup ? validateValidChangeGroupInterField(value, getValues(fieldNames.change), getValues('validDateStart'), getValues('validDateEnd')) : true;
2959
3069
  },
2960
- validatePreviousRow: validatePreviousRow
3070
+ validatePreviousRow: validatePreviousRow,
3071
+ validateNextRows: validateNextRows
2961
3072
  }
2962
3073
  },
2963
3074
  onBlur: function onBlur() {
2964
3075
  if (isChangeGroup) {
2965
- var nextValidFieldName = getFieldFromNextRow();
2966
- trigger([].concat(_toConsumableArray(subFields), _toConsumableArray(mainOptionalFields), _toConsumableArray(mainFields), _toConsumableArray(nextValidFieldName)));
3076
+ var nextValidFieldName = getValidFieldFromNextRow();
3077
+ var previousValidFieldNames = getPreviousValidFields(index);
3078
+ trigger([].concat(_toConsumableArray(subFields), _toConsumableArray(mainOptionalFields), _toConsumableArray(mainFields), _toConsumableArray(nextValidFieldName), _toConsumableArray(previousValidFieldNames)));
2967
3079
  }
2968
3080
  }
2969
3081
  }), /*#__PURE__*/React__default.createElement(TafFormTextField, {
@@ -2977,7 +3089,9 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
2977
3089
  return _validateRequiredMainFields(value, 'Wind');
2978
3090
  },
2979
3091
  validateRequiredSub: validateRequiredSub,
2980
- validateWindField: validateWindField
3092
+ validateWindField: function validateWindField$1(value) {
3093
+ return validateWindField(value, getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3094
+ }
2981
3095
  }
2982
3096
  },
2983
3097
  onBlur: function onBlur() {
@@ -3026,7 +3140,7 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3026
3140
  },
3027
3141
  onBlur: function onBlur() {
3028
3142
  var fields = isChangeGroup ? [].concat(_toConsumableArray(subFields), _toConsumableArray(mainFields)) : [];
3029
- return trigger([].concat(_toConsumableArray(fields), [fieldNames.weather2, fieldNames.weather3]));
3143
+ return trigger([].concat(_toConsumableArray(fields), [fieldNames.weather2, fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3030
3144
  }
3031
3145
  }), /*#__PURE__*/React__default.createElement(TafFormTextField, {
3032
3146
  label: "Weather",
@@ -3042,7 +3156,7 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3042
3156
  },
3043
3157
  onBlur: function onBlur() {
3044
3158
  var fields = isChangeGroup ? [].concat(_toConsumableArray(subFields), _toConsumableArray(mainFields)) : [];
3045
- return trigger([].concat(_toConsumableArray(fields), [fieldNames.weather3]));
3159
+ return trigger([].concat(_toConsumableArray(fields), [fieldNames.weather3, fieldNames.wind, fieldNames.cloud1]));
3046
3160
  }
3047
3161
  }), /*#__PURE__*/React__default.createElement(TafFormTextField, {
3048
3162
  label: "Weather",
@@ -3055,6 +3169,9 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3055
3169
  return validateThirdWeatherField(getValues(fieldNames.weather1), getValues(fieldNames.weather2), value, getValues(fieldNames.visibility));
3056
3170
  }
3057
3171
  }
3172
+ },
3173
+ onBlur: function onBlur() {
3174
+ return trigger([fieldNames.wind, fieldNames.cloud1]);
3058
3175
  }
3059
3176
  }), /*#__PURE__*/React__default.createElement(TafFormTextField, {
3060
3177
  label: "Cloud",
@@ -3068,7 +3185,7 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3068
3185
  },
3069
3186
  validateRequiredSub: validateRequiredSub,
3070
3187
  validateFirstCloud: function validateFirstCloud$1(value) {
3071
- return validateFirstCloud(value, getValues(fieldNames.visibility));
3188
+ return validateFirstCloud(value, getValues(fieldNames.visibility), getValues(fieldNames.weather1), getValues(fieldNames.weather2), getValues(fieldNames.weather3));
3072
3189
  }
3073
3190
  }
3074
3191
  },
@@ -3125,13 +3242,15 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3125
3242
  }, !disabled && /*#__PURE__*/React__default.createElement(IconButton, {
3126
3243
  "aria-label": "add",
3127
3244
  "data-testid": "add-changeGroup",
3128
- onClick: addChangeGroup
3245
+ onClick: addChangeGroup,
3246
+ size: "large"
3129
3247
  }, /*#__PURE__*/React__default.createElement(Add, null))), isChangeGroup && !disabled && /*#__PURE__*/React__default.createElement(Grid, {
3130
3248
  item: true
3131
3249
  }, /*#__PURE__*/React__default.createElement(IconButton, {
3132
3250
  "aria-label": "add",
3133
3251
  "data-testid": "add-changeGroup",
3134
- onClick: addChangeGroup
3252
+ onClick: addChangeGroup,
3253
+ size: "large"
3135
3254
  }, /*#__PURE__*/React__default.createElement(Add, null)), /*#__PURE__*/React__default.createElement(IconButton, Object.assign({
3136
3255
  "aria-label": "delete",
3137
3256
  "data-testid": "remove-changeGroup",
@@ -3139,8 +3258,10 @@ var TafFormRow = /*#__PURE__*/React__default.forwardRef(function (_a, ref) {
3139
3258
  return onRemoveChangeGroup(index);
3140
3259
  }
3141
3260
  }, lastRow ? {
3142
- tabIndex: '-1'
3143
- } : {}), /*#__PURE__*/React__default.createElement(Delete, null))));
3261
+ tabIndex: -1
3262
+ } : {}, {
3263
+ size: "large"
3264
+ }), /*#__PURE__*/React__default.createElement(Delete, null))));
3144
3265
  });
3145
3266
 
3146
3267
  /* *
@@ -3459,7 +3580,7 @@ var TafFormButtons = function TafFormButtons(_ref) {
3459
3580
 
3460
3581
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Grid, {
3461
3582
  container: true,
3462
- justify: "space-between",
3583
+ justifyContent: "space-between",
3463
3584
  alignItems: "center",
3464
3585
  className: classes.lifecycleButtons
3465
3586
  }, /*#__PURE__*/React__default.createElement(Grid, {
@@ -3587,7 +3708,8 @@ var DragHandle = function DragHandle(_ref) {
3587
3708
  className: "".concat(classes.dragHandle, " handle"),
3588
3709
  "data-testid": "dragHandle-".concat(index),
3589
3710
  disableRipple: true,
3590
- disabled: isDisabled
3711
+ disabled: isDisabled,
3712
+ size: "large"
3591
3713
  }, /*#__PURE__*/React__default.createElement(DragIndicator, null));
3592
3714
  };
3593
3715
 
@@ -3984,14 +4106,12 @@ var ContentDialog = function ContentDialog(_a) {
3984
4106
  return onFormAction('CLOSE');
3985
4107
  },
3986
4108
  maxWidth: other.maxWidth ? other.maxWidth : 'lg',
3987
- disableBackdropClick: true,
3988
4109
  PaperProps: {
3989
4110
  style: {
3990
4111
  position: 'inherit'
3991
4112
  }
3992
4113
  }
3993
4114
  }, other), /*#__PURE__*/React.createElement(DialogTitle, {
3994
- disableTypography: true,
3995
4115
  className: classes.dialogHeader
3996
4116
  }, /*#__PURE__*/React.createElement(Grid, {
3997
4117
  container: true
@@ -4177,13 +4297,13 @@ var TafListRow = function TafListRow(_ref) {
4177
4297
  md: 3
4178
4298
  }, /*#__PURE__*/React__default.createElement(Grid, {
4179
4299
  container: true,
4180
- justify: "flex-start",
4300
+ justifyContent: "flex-start",
4181
4301
  spacing: 2
4182
4302
  }, /*#__PURE__*/React__default.createElement(Grid, {
4183
4303
  item: true,
4184
4304
  xs: 8,
4185
4305
  container: true,
4186
- justify: "flex-end"
4306
+ justifyContent: "flex-end"
4187
4307
  }, taf.status === 'DRAFT' || taf.status === 'DRAFT_CORRECTED' || taf.status === 'DRAFT_AMENDED' ? /*#__PURE__*/React__default.createElement(Button, {
4188
4308
  color: "secondary",
4189
4309
  size: "small",
@@ -4306,7 +4426,7 @@ var TafListButtons = function TafListButtons(_ref) {
4306
4426
  return !canBe.includes('CANCELLED') && !canBe.includes('CORRECTED') && !canBe.includes('AMENDED') ? null : /*#__PURE__*/React__default.createElement(Grid, {
4307
4427
  container: true,
4308
4428
  alignItems: "center",
4309
- justify: "flex-end",
4429
+ justifyContent: "flex-end",
4310
4430
  "data-testid": "taflist-canbebuttons",
4311
4431
  spacing: 1,
4312
4432
  className: classes.actionButtons
@@ -4346,6 +4466,9 @@ var useStyles$3 = makeStyles({
4346
4466
  },
4347
4467
  formPadding: {
4348
4468
  padding: '8px'
4469
+ },
4470
+ expandIcon: {
4471
+ color: '#0075a9'
4349
4472
  }
4350
4473
  });
4351
4474
 
@@ -4407,11 +4530,13 @@ var TafListAccordion = function TafListAccordion(_ref) {
4407
4530
  }), /*#__PURE__*/React__default.createElement(AccordionSummary, {
4408
4531
  "data-testid": "tafListSectionAccordionSummary",
4409
4532
  expandIcon: popOut ? /*#__PURE__*/React__default.createElement(Tooltip, {
4410
- title: "Popout to edit"
4533
+ title: "Popout to edit",
4534
+ className: classes.expandIcon
4411
4535
  }, /*#__PURE__*/React__default.createElement(OpenInNew, {
4412
4536
  "data-testid": "popOutIcon",
4413
4537
  fontSize: "small"
4414
4538
  })) : /*#__PURE__*/React__default.createElement(ExpandMore, {
4539
+ className: classes.expandIcon,
4415
4540
  "data-testid": "expandIcon"
4416
4541
  })
4417
4542
  }, /*#__PURE__*/React__default.createElement(TafListRow, {
@@ -4585,7 +4710,7 @@ var TafList = function TafList(_ref) {
4585
4710
  onClickTafActionButton: onClickTafActionButton
4586
4711
  })), isLoading && /*#__PURE__*/React__default.createElement(Skeleton, {
4587
4712
  "data-testid": "tafList-skeleton",
4588
- variant: "rect",
4713
+ variant: "rectangular",
4589
4714
  height: "660px"
4590
4715
  })));
4591
4716
  };