@opengeoweb/warnings 20.0.1 → 20.1.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,7 +1,7 @@
1
1
  import type { Credentials } from '@opengeoweb/authentication';
2
2
  import type { MaritimeWarningsConfig } from '../../components/MaritimeWarningsForm/types';
3
3
  import type { DrawingFromBE, DrawingFromFE, DrawingListItem, FetchDrawingParams } from '../../store/warningsDrawings/types';
4
- import type { MaritimeWarning, MaritimeWarningsType, PublicWarning, WarningEvent } from '../../store/warningsForm/types';
4
+ import type { MaritimeWarning, MaritimeWarningsType, PublicWarning, WarningEvent, WarningEventsConfig } from '../../store/warningsForm/types';
5
5
  export declare const getPublicWarningList: (auth: Credentials, apiParams?: Record<string, string>) => Promise<PublicWarning[]>;
6
6
  export declare const updatePublicWarningEditor: (warningId: string, isEditor: boolean, auth: Credentials, force?: boolean) => Promise<Headers | null>;
7
7
  export declare const updatePublicWarning: (warningId: string, auth: Credentials, data: PublicWarning) => Promise<Headers | null>;
@@ -17,6 +17,7 @@ export declare const saveDrawingAs: (auth: Credentials, data: DrawingFromFE) =>
17
17
  export declare const updateDrawing: (auth: Credentials, drawingId: string, data: DrawingFromFE) => Promise<void>;
18
18
  export declare const deleteDrawing: (auth: Credentials, drawingId: string) => Promise<void>;
19
19
  export declare const getMaritimeWarningsConfig: (auth: Credentials) => Promise<MaritimeWarningsConfig>;
20
+ export declare const getWarningEventsConfig: (auth: Credentials) => Promise<WarningEventsConfig>;
20
21
  export declare const getWarningEventList: (auth: Credentials, apiParams?: Record<string, string>) => Promise<WarningEvent[]>;
21
22
  export declare const updateWarningEventEditor: (eventId: string, isEditor: boolean, auth: Credentials, force?: boolean) => Promise<Headers | null>;
22
23
  export declare const updateWarningEvent: (eventId: string, auth: Credentials, data: WarningEvent) => Promise<Headers | null>;
@@ -3,7 +3,7 @@ import type { UseMutationReturnType } from '@opengeoweb/api';
3
3
  import type { TimeFilter } from '../../components/FilterList/filter-utils';
4
4
  import type { MaritimeWarningsConfig } from '../../components/MaritimeWarningsForm/types';
5
5
  import type { DrawingFromBE, DrawingFromFE, DrawingListItem, FetchDrawingParams } from '../../store/warningsDrawings/types';
6
- import type { MaritimeWarning, MaritimeWarningsType, PublicWarning, WarningEvent } from '../../store/warningsForm/types';
6
+ import type { MaritimeWarning, MaritimeWarningsType, PublicWarning, WarningEvent, WarningEventsConfig } from '../../store/warningsForm/types';
7
7
  /**
8
8
  * @param disabled - Disables fetching, but still returns cached values.
9
9
  * https://tanstack.com/query/v4/docs/framework/react/guides/disabling-queries
@@ -56,6 +56,7 @@ interface MutateMaritimeEditorParams {
56
56
  }
57
57
  export declare const useMutateMaritimeWarningsEditor: () => MutationReturnType<MutateMaritimeEditorParams>;
58
58
  export declare const useMaritimeWarningsConfig: (disabled?: boolean) => UseQueryResult<MaritimeWarningsConfig>;
59
+ export declare const useWarningEventsConfig: (disabled?: boolean) => UseQueryResult<WarningEventsConfig>;
59
60
  export declare const useWarningEventsList: (disabled?: boolean, timeFilter?: TimeFilter) => UseQueryResult<WarningEvent[]>;
60
61
  type EventMutationReturnType<T> = UseMutationReturnType<Headers | null, T, {
61
62
  previousData: [QueryKey, WarningEvent[] | undefined][];
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
+ import type { ListFilter } from '@opengeoweb/shared';
2
3
  import type { uiTypes } from '@opengeoweb/store';
4
+ import type { FetchDrawingParams } from '../../store/warningsDrawings/types';
5
+ export declare const MY_DRAWINGS_FILTER_ID = "my-drawings";
6
+ export declare const getFilterParams: (areas: ListFilter[], searchQuery: string, isMyDrawingsSelected?: boolean) => FetchDrawingParams;
3
7
  export declare const AreaDrawingLoaderConnect: React.FC<{
4
8
  bounds?: string;
5
9
  source?: uiTypes.Source;
@@ -1,6 +1,6 @@
1
1
  import type { Feature, FeatureCollection, MultiPolygon, Polygon } from 'geojson';
2
2
  import type { DrawingListItem, DrawingTransformation } from '../../store/warningsDrawings/types';
3
- type MaskPolygon = Feature<Polygon | MultiPolygon>;
3
+ export type MaskPolygon = Feature<Polygon | MultiPolygon>;
4
4
  export declare const CLIPPED_RESULT_FILL_OPACITY = 0.4;
5
5
  export declare const MASKED_FILL_OPACITY_KEY = "maskedFillOpacity";
6
6
  export declare const getDrawnFeatureIndexes: (geoJSON: FeatureCollection) => number[];
@@ -8,8 +8,30 @@ export declare const getFeatureIndexesToHideFill: (geoJSON: FeatureCollection) =
8
8
  export declare const getFeatureIndexesToRestoreFill: (geoJSON: FeatureCollection) => number[];
9
9
  export declare const restoreMaskedFillProperties: (properties: GeoJSON.GeoJsonProperties) => GeoJSON.GeoJsonProperties;
10
10
  export declare const restoreMaskedFill: (geoJSON: FeatureCollection) => FeatureCollection;
11
+ export declare const isPolygonFeature: (feature: Feature) => feature is MaskPolygon;
11
12
  export declare const getMaskPolygon: (mask: FeatureCollection) => MaskPolygon | null;
12
13
  export declare const clipGeoJSONWithMask: (geoJSON: FeatureCollection, mask: FeatureCollection) => FeatureCollection;
14
+ export type PolygonClipResult = 'inside' | 'clipped' | 'outside' | 'error';
15
+ export type PolygonMaskOverlap = 'overlap' | 'outside' | 'error';
16
+ /**
17
+ * Checks whether the polygon overlaps the mask:
18
+ * - overlap: (part of) the polygon lies within the mask
19
+ * - outside: the polygon has no overlap with the mask
20
+ * - error: the polygon could not be clipped (invalid geometry)
21
+ */
22
+ export declare const getPolygonMaskOverlap: (feature: MaskPolygon, mask: FeatureCollection) => PolygonMaskOverlap;
23
+ /**
24
+ * Clips a polygon with the mask and classifies the result:
25
+ * - inside: the polygon lies within the mask and is returned unchanged
26
+ * - clipped: the polygon lies partly within the mask and is clipped to it
27
+ * - outside: the polygon has no overlap with the mask, returned unchanged
28
+ * - error: the polygon could not be clipped, returned unchanged
29
+ * Since the clipped geometry is rounded and its vertices can be reordered, the
30
+ * areas are compared instead of the geometries to detect whether it was changed.
31
+ */
32
+ export declare const classifyPolygonClip: (feature: MaskPolygon, mask: FeatureCollection) => {
33
+ feature: Feature;
34
+ result: PolygonClipResult;
35
+ };
13
36
  export declare const findMaskForTransformation: (masks: DrawingListItem[], transformation?: DrawingTransformation | null) => DrawingListItem | undefined;
14
37
  export declare const buildClippedHighlightGeoJSON: (clipped: FeatureCollection) => FeatureCollection;
15
- export {};
@@ -24,10 +24,10 @@ export declare enum Phenomenon {
24
24
  }
25
25
  export declare enum WarningEventPhenomenon {
26
26
  fog = "fog",
27
- freezingRain = "freezingRain",
28
27
  highTemp = "highTemp",
29
28
  lowTemp = "lowTemp",
30
29
  rain = "rain",
30
+ roadIce = "roadIce",
31
31
  snow = "snow",
32
32
  thunderstorm = "thunderstorm",
33
33
  waterspouts = "waterspouts",
@@ -43,10 +43,10 @@ export declare const defaultAreaFilter: Record<string, boolean>;
43
43
  export declare const makeFilterFromList: <T extends string>(options: T[], value?: boolean) => Record<T | "unspecified", boolean>;
44
44
  declare const AllPhenomena: {
45
45
  readonly fog: WarningEventPhenomenon.fog;
46
- readonly freezingRain: WarningEventPhenomenon.freezingRain;
47
46
  readonly highTemp: WarningEventPhenomenon.highTemp;
48
47
  readonly lowTemp: WarningEventPhenomenon.lowTemp;
49
48
  readonly rain: WarningEventPhenomenon.rain;
49
+ readonly roadIce: WarningEventPhenomenon.roadIce;
50
50
  readonly snow: WarningEventPhenomenon.snow;
51
51
  readonly thunderstorm: WarningEventPhenomenon.thunderstorm;
52
52
  readonly waterspouts: WarningEventPhenomenon.waterspouts;
@@ -22,6 +22,8 @@ export interface WarningEventFormDialogProps {
22
22
  startPosition?: Position;
23
23
  selectedDrawing?: DrawingListItem;
24
24
  hoveredDrawing?: DrawingListItem;
25
+ approvedArea?: GeoJSON.FeatureCollection;
26
+ isApprovedAreaLoading?: boolean;
25
27
  onAddDrawing?: () => void;
26
28
  onClose: () => void;
27
29
  onChangeFormMode?: (isReadOnly: boolean) => void;
@@ -17,6 +17,8 @@ export interface WarningEventFormContentProps {
17
17
  isSummaryDialogOpen?: boolean;
18
18
  selectedDrawing?: DrawingListItem;
19
19
  hoveredDrawing?: DrawingListItem;
20
+ approvedArea?: GeoJSON.FeatureCollection;
21
+ isApprovedAreaLoading?: boolean;
20
22
  selectedEvent?: WarningEvent;
21
23
  shouldHideFormToggleMode?: boolean;
22
24
  isReadOnly?: boolean;
@@ -1,7 +1,10 @@
1
+ import type { Feature, FeatureCollection } from 'geojson';
1
2
  import React from 'react';
2
3
  import type { MapPreset } from '@opengeoweb/store';
3
4
  import type { DrawingListItem } from '../../../store/warningsDrawings/types';
5
+ import type { Area } from '../../../store/warningsForm/types';
4
6
  import { PublicWarningStatus } from '../../../store/warningsForm/types';
7
+ import { WarningLevel } from '../../PublicWarningsForm/LevelField';
5
8
  export declare enum Probability {
6
9
  TEN_TO_THIRTY = 10,
7
10
  THIRTY_TO_SIXTY = 30,
@@ -12,6 +15,9 @@ export declare const probablityOptions: {
12
15
  name: string;
13
16
  value: Probability;
14
17
  }[];
18
+ type Validator = (...args: never[]) => boolean | string;
19
+ export declare const skipValidationWhen: <TValidators extends Record<string, Validator>>(isSkipped: () => boolean, validators: TValidators) => TValidators;
20
+ export declare const buildAreaFromFeature: (feature: Feature, level?: WarningLevel, approvedArea?: FeatureCollection) => Area;
15
21
  export declare const WarningEventItem: React.FC<{
16
22
  defaultMapPreset?: MapPreset;
17
23
  index: number;
@@ -21,9 +27,12 @@ export declare const WarningEventItem: React.FC<{
21
27
  isDeleteButtonDisabled: boolean;
22
28
  selectedDrawing?: DrawingListItem;
23
29
  hoveredDrawing?: DrawingListItem;
30
+ approvedArea?: FeatureCollection;
31
+ isApprovedAreaLoading?: boolean;
24
32
  onExpireWithdraw: (status: PublicWarningStatus, index: number) => void;
25
33
  onToggleCompact: () => void;
26
34
  onAddDrawing: () => void;
27
35
  onDeleteWarning: (index: number) => void;
36
+ onDuplicateWarning: (index: number) => void;
28
37
  }>;
29
38
  export default WarningEventItem;
@@ -17,4 +17,10 @@ export declare const getDefaultWarningTimes: (type: WarningEventType, now?: Date
17
17
  export declare const defaultValues: WarningEvent;
18
18
  export declare const warningEventItemDefaultValues: WarningEventBody;
19
19
  export declare const buildDefaultWarningItem: (event: Pick<WarningEvent, "warningEventType" | "incident" | "phenomenon">) => WarningEventBody;
20
+ /**
21
+ * Copy of an existing warning, stripped of all identity/status fields so it is
22
+ * treated as a brand new, unsaved warning. All content (times, level,
23
+ * probability, areas) is copied over as is.
24
+ */
25
+ export declare const buildDuplicateWarningItem: (source: WarningEventBody) => WarningEventBody;
20
26
  export declare const getDefaultValues: (initialValues?: Partial<WarningEvent>) => WarningEvent;
@@ -1,7 +1,7 @@
1
- import type { Feature, MultiPolygon, Polygon } from 'geojson';
2
- import type { FieldValues, FormState } from 'react-hook-form';
1
+ import type { FeatureCollection } from 'geojson';
3
2
  import type { Area, WarningEventBody, WarningEvent } from '../../../store/warningsForm/types';
4
3
  import { PublicWarningStatus } from '../../../store/warningsForm/types';
4
+ import type { PolygonClipResult } from '../../DrawingToolForm/maskUtils';
5
5
  interface FormData extends WarningEvent {
6
6
  IS_DRAFT?: boolean | string;
7
7
  }
@@ -9,7 +9,6 @@ export declare const buildSubmitValues: (values: FormData) => WarningEvent;
9
9
  export declare const sortWarningsByActivity: (warnings: WarningEventBody[]) => WarningEventBody[];
10
10
  export declare const getFormData: (warningsEvent: WarningEvent | undefined) => FormData;
11
11
  export declare const constructWarningWithNewStatus: (warningsEvent: WarningEvent, status: PublicWarningStatus) => WarningEventBody[];
12
- export declare const isWarningActive: (formState: FormState<FieldValues>, linkedWarningId: string) => boolean;
13
12
  export declare const hasWarningStarted: (warning: Pick<WarningEventBody, "validFrom">) => boolean;
14
13
  export declare const isWarningFinalised: (warning: Pick<WarningEventBody, "status">) => boolean;
15
14
  export declare const getEventStatusActions: (warnings: WarningEventBody[]) => {
@@ -18,10 +17,33 @@ export declare const getEventStatusActions: (warnings: WarningEventBody[]) => {
18
17
  hasPendingWarnings: boolean;
19
18
  };
20
19
  export declare const getWarningStatusesForEventAction: (warnings: WarningEventBody[], action: PublicWarningStatus.EXPIRED | PublicWarningStatus.WITHDRAWN) => (PublicWarningStatus | undefined)[];
21
- export declare const isPolygonalFeature: (featureToCheck: GeoJSON.Feature) => featureToCheck is Feature<Polygon | MultiPolygon>;
22
20
  export declare const hasAreaData: (areas?: Area[]) => boolean;
23
21
  export declare const doAreasOverlap: (areasA?: Area[], areasB?: Area[]) => boolean;
24
22
  export declare const doTimeRangesOverlap: (aFrom: string, aUntil: string, bFrom: string, bUntil: string) => boolean;
25
23
  export declare const doWarningsOverlap: (warningA: WarningEventBody, warningB: WarningEventBody) => boolean;
26
24
  export declare const getOverlappingWarnings: (warnings: WarningEventBody[], index: number) => number[];
25
+ export declare const hasApprovedArea: (approvedArea?: FeatureCollection) => approvedArea is FeatureCollection;
26
+ /**
27
+ * Checks the polygons of the geoJSON against the approved area.
28
+ * - inside: the geoJSON is returned unchanged
29
+ * - clipped: polygons partly outside the approved area are clipped to it
30
+ * - outside: at least one polygon lies completely outside the approved area,
31
+ * the geoJSON is returned unchanged
32
+ * - error: at least one polygon could not be clipped, the geoJSON is returned unchanged
33
+ * Without an approved area, the check is skipped and the result is inside.
34
+ * Non polygon features are not checked.
35
+ */
36
+ export declare const clipToApprovedArea: (geoJSON: FeatureCollection, approvedArea?: FeatureCollection) => {
37
+ geoJSON: FeatureCollection;
38
+ result: PolygonClipResult;
39
+ };
40
+ export type ApprovedAreaError = 'outside' | 'error';
41
+ /**
42
+ * Checks the polygons of the areas against the approved area:
43
+ * - error: at least one polygon could not be checked against the approved area
44
+ * - outside: at least one polygon lies completely outside the approved area
45
+ * - undefined: all polygons (partly) lie within the approved area, or there is
46
+ * no approved area to check against
47
+ */
48
+ export declare const getApprovedAreaError: (areas?: Area[], approvedArea?: FeatureCollection) => ApprovedAreaError | undefined;
27
49
  export {};
@@ -39,6 +39,7 @@ export type DrawingFromFE = Omit<DrawingDetails, 'username'>;
39
39
  export interface FetchDrawingParams {
40
40
  keywords?: string;
41
41
  search?: string;
42
+ scope?: DrawingScope;
42
43
  }
43
44
  export type SetDrawValuesPayload = DrawItem;
44
45
  export type SubmitDrawValuesPayload = DrawingFromFE;
@@ -118,5 +118,8 @@ export interface WarningEvent {
118
118
  mode: WarningEventMode;
119
119
  selectedDrawing?: DrawingListItem;
120
120
  }
121
+ export interface WarningEventsConfig {
122
+ area_validation_domain?: GeoJSON.FeatureCollection | null;
123
+ }
121
124
  export type Warning = PublicWarning | AirmetWarning | SigmetWarning | MaritimeWarning | EventWarningForWarningList;
122
125
  export {};
@@ -1,7 +1,7 @@
1
1
  import type { RequestHandler } from 'msw';
2
2
  import type { SigmetFromBackend } from '@opengeoweb/api';
3
3
  import type { DrawingFromBE, DrawingListItem } from '../../store/warningsDrawings/types';
4
- import type { AirmetWarning, MaritimeWarning, PublicWarning, SigmetWarning, Warning, WarningEvent } from '../../store/warningsForm/types';
4
+ import type { AirmetWarning, MaritimeWarning, PublicWarning, SigmetWarning, Warning, WarningEvent, WarningEventsConfig } from '../../store/warningsForm/types';
5
5
  export declare const newSigmet: SigmetFromBackend;
6
6
  declare const drawingList: DrawingListItem[];
7
7
  declare const drawingsListFullContent: DrawingFromBE[];
@@ -18,6 +18,7 @@ declare const areaKeywordList: string[];
18
18
  export declare const publicWarningEndpoints: import("msw").HttpHandler[];
19
19
  export declare const maritimeWarningEndpoints: import("msw").HttpHandler[];
20
20
  export declare const drawingEndpoints: import("msw").HttpHandler[];
21
+ export declare const warningEventsConfig: WarningEventsConfig;
21
22
  export declare const warningEventsEndpoints: import("msw").HttpHandler[];
22
23
  export declare const makeWarningsHandler: (result: Warning[]) => RequestHandler;
23
24
  declare const requestHandlers: import("msw").HttpHandler[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/warnings",
3
- "version": "20.0.1",
3
+ "version": "20.1.0",
4
4
  "description": "GeoWeb warinings library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,24 +20,24 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@opengeoweb/api": "20.0.1",
24
- "@opengeoweb/shared": "20.0.1",
25
- "@opengeoweb/store": "20.0.1",
26
- "@opengeoweb/webmap-react": "20.0.1",
23
+ "@opengeoweb/api": "20.1.0",
24
+ "@opengeoweb/shared": "20.1.0",
25
+ "@opengeoweb/store": "20.1.0",
26
+ "@opengeoweb/webmap-react": "20.1.0",
27
27
  "@tanstack/react-query": "^5.85.5",
28
28
  "react-redux": "^9.2.0",
29
- "@opengeoweb/theme": "20.0.1",
30
- "@opengeoweb/form-fields": "20.0.1",
29
+ "@opengeoweb/theme": "20.1.0",
30
+ "@opengeoweb/form-fields": "20.1.0",
31
31
  "react-hook-form": "^7.50.1",
32
32
  "lodash": "^4.18.1",
33
33
  "@reduxjs/toolkit": "^2.6.1",
34
- "@opengeoweb/snackbar": "20.0.1",
34
+ "@opengeoweb/snackbar": "20.1.0",
35
35
  "react-window": "^2.2.6",
36
- "axios": "^1.18.0",
37
- "@opengeoweb/core": "20.0.1",
38
- "@opengeoweb/webmap": "20.0.1",
39
- "@opengeoweb/authentication": "20.0.1",
40
- "@opengeoweb/sigmet-airmet": "20.0.1",
36
+ "axios": "^1.20.0",
37
+ "@opengeoweb/core": "20.1.0",
38
+ "@opengeoweb/webmap": "20.1.0",
39
+ "@opengeoweb/authentication": "20.1.0",
40
+ "@opengeoweb/sigmet-airmet": "20.1.0",
41
41
  "react-i18next": "^15.1.1",
42
42
  "i18next": "^25.0.1",
43
43
  "@mui/material": "^9.0.1",