@opengeoweb/time-series 19.2.0 → 19.3.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/dist/index.esm.js CHANGED
@@ -7,7 +7,7 @@ import { mapUtils, selectorMemoizationOptions, genericSelectors, uiSelectors, ui
7
7
  import { useTheme, MenuItem, LinearProgress, Grid, Box, Typography, ClickAwayListener, Input, Collapse, Button, List, ListItem, ListItemText, InputAdornment, ListItemButton, styled, Card, Stack, Tooltip, ListItemIcon, Checkbox } from '@mui/material';
8
8
  import { isString, trim, trimStart, compact, chain, groupBy, countBy, sortBy, uniqBy, isEqual } from 'lodash';
9
9
  import { ReactSortable } from 'react-sortablejs';
10
- import { Info, ArrowDropDownDown, Copy, Delete, Visibility, VisibilityOff, TimeSeriesSelect as TimeSeriesSelect$1, DragHandle, ChevronUp, ChevronDown, Add, DimensionsTime, DrawRegion, Cached, Edit, useThemeContext, EChartsDarkTheme, EChartsLightTheme, Layers, Location, LockLocked, LockUnlocked, Menu } from '@opengeoweb/theme';
10
+ import { Info, ArrowDropDownDown, Copy, Delete, Visibility, VisibilityOff, TimeSeriesSelect as TimeSeriesSelect$1, DragHandle, ChevronUp, ChevronDown, Add, DimensionsTime, DrawRegion, Cached, Edit, Location, useThemeContext, EChartsDarkTheme, EChartsLightTheme, Layers, LockLocked, LockUnlocked, Menu } from '@opengeoweb/theme';
11
11
  import i18n from 'i18next';
12
12
  import { useTranslation } from 'react-i18next';
13
13
  import '@opengeoweb/core';
@@ -2582,7 +2582,8 @@ var createGeoJsonArrays = function createGeoJsonArrays(locations, services, hide
2582
2582
  });
2583
2583
  return acc;
2584
2584
  }, initialAccumulator),
2585
- obj = _locations$reduce.obj;
2585
+ obj = _locations$reduce.obj,
2586
+ collectionMap = _locations$reduce.collectionMap;
2586
2587
  var combinedGeoJson = {
2587
2588
  type: 'FeatureCollection',
2588
2589
  features: Object.keys(obj).map(function (key) {
@@ -2601,7 +2602,8 @@ var createGeoJsonArrays = function createGeoJsonArrays(locations, services, hide
2601
2602
  })
2602
2603
  };
2603
2604
  return {
2604
- combinedGeoJson: combinedGeoJson
2605
+ combinedGeoJson: combinedGeoJson,
2606
+ splitGeoJsonByCollection: Object.values(collectionMap)
2605
2607
  };
2606
2608
  };
2607
2609
  var getNearbyLocation = function getNearbyLocation(parameter, service, selectedLocation, geojsonMap) {
@@ -6873,6 +6875,72 @@ var LocationInfoButtonConnect = function LocationInfoButtonConnect(_ref) {
6873
6875
  });
6874
6876
  };
6875
6877
 
6878
+ var LocationSelectButtonConnect = function LocationSelectButtonConnect(_ref) {
6879
+ var _timeSeriesLocation$o;
6880
+ var panelId = _ref.panelId;
6881
+ var dispatch = useDispatch();
6882
+ var _useTimeseriesTransla = useTimeseriesTranslation(),
6883
+ t = _useTimeseriesTransla.t;
6884
+ var timeSeriesLocation = useSelector(function (state) {
6885
+ return getCurrentLocation(state, panelId);
6886
+ });
6887
+ var currentSourcePanelId = useSelector(function (store) {
6888
+ return uiSelectors.getSourcePanelId(store, uiTypes.DialogTypes.TimeseriesLocations);
6889
+ });
6890
+ var isLocationsDialogOpen = useSelector(function (store) {
6891
+ return uiSelectors.getisDialogOpen(store, uiTypes.DialogTypes.TimeseriesLocations);
6892
+ });
6893
+ var isMapPinDisabled = useSelector(function (state) {
6894
+ return getIsMapPinDisabled(state, panelId);
6895
+ });
6896
+ var isLocationsDialogOpenRef = React.useRef(isLocationsDialogOpen);
6897
+ var currentSourcePanelIdRef = React.useRef(currentSourcePanelId);
6898
+ React.useEffect(function () {
6899
+ isLocationsDialogOpenRef.current = isLocationsDialogOpen;
6900
+ currentSourcePanelIdRef.current = currentSourcePanelId;
6901
+ }, [isLocationsDialogOpen, currentSourcePanelId]);
6902
+ var selectedLocationName = typeof (timeSeriesLocation == null || (_timeSeriesLocation$o = timeSeriesLocation.occurrences) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o[0]) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o.properties) == null ? void 0 : _timeSeriesLocation$o.name) === 'string' ? timeSeriesLocation.occurrences[0].properties.name : '';
6903
+ var toggleLocationsDialog = function toggleLocationsDialog() {
6904
+ dispatch(uiActions.setToggleOpenDialog({
6905
+ type: uiTypes.DialogTypes.TimeseriesLocations,
6906
+ setOpen: currentSourcePanelId !== panelId ? true : !isLocationsDialogOpen,
6907
+ sourcePanelId: panelId
6908
+ }));
6909
+ };
6910
+ React.useEffect(function () {
6911
+ return function () {
6912
+ if (isLocationsDialogOpenRef.current && currentSourcePanelIdRef.current === panelId) {
6913
+ dispatch(uiActions.setToggleOpenDialog({
6914
+ setOpen: false,
6915
+ type: uiTypes.DialogTypes.TimeseriesLocations,
6916
+ sourcePanelId: panelId
6917
+ }));
6918
+ }
6919
+ };
6920
+ }, [dispatch, panelId]);
6921
+ return jsx(CustomTooltip, {
6922
+ title: selectedLocationName || t('timeseries-select-location'),
6923
+ children: jsx("span", {
6924
+ children: jsx(TimeSeriesTopRowButton, {
6925
+ "aria-label": t('timeseries-location'),
6926
+ "data-testid": "locationSelectButton",
6927
+ disabled: isMapPinDisabled,
6928
+ icon: jsx(Location, {
6929
+ sx: {
6930
+ '@container time-series-container (width < 720px)': {
6931
+ display: 'none'
6932
+ }
6933
+ }
6934
+ }),
6935
+ longText: selectedLocationName || t('timeseries-location'),
6936
+ onClick: toggleLocationsDialog,
6937
+ selected: isLocationsDialogOpen ? currentSourcePanelId === panelId : null,
6938
+ shortText: selectedLocationName || t('timeseries-location')
6939
+ })
6940
+ })
6941
+ });
6942
+ };
6943
+
6876
6944
  var TimeSeriesMarkersSwitch = function TimeSeriesMarkersSwitch(_ref) {
6877
6945
  var shouldHideMarkers = _ref.shouldHideMarkers,
6878
6946
  toggleMarkers = _ref.toggleMarkers;
@@ -7825,6 +7893,109 @@ var TimeSeriesView = /*#__PURE__*/React.memo(function (_ref2) {
7825
7893
  return samePreset && sameLocation && sameGeoJson && sameLegend && sameServices && sameTime;
7826
7894
  });
7827
7895
 
7896
+ /* *
7897
+ * Licensed under the Apache License, Version 2.0 (the "License");
7898
+ * you may not use this file except in compliance with the License.
7899
+ * You may obtain a copy of the License at
7900
+ *
7901
+ * http://www.apache.org/licenses/LICENSE-2.0
7902
+ *
7903
+ * Unless required by applicable law or agreed to in writing, software
7904
+ * distributed under the License is distributed on an "AS IS" BASIS,
7905
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7906
+ * See the License for the specific language governing permissions and
7907
+ * limitations under the License.
7908
+ *
7909
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
7910
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
7911
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
7912
+ * */
7913
+ var getUniqueServicesFromPreset = function getUniqueServicesFromPreset(parameters, services) {
7914
+ if (!parameters.length || !services.length) {
7915
+ return [];
7916
+ }
7917
+ var options = parameters.map(function (_ref) {
7918
+ var serviceId = _ref.serviceId,
7919
+ collectionId = _ref.collectionId;
7920
+ var service = services.find(function (item) {
7921
+ return item.id === serviceId;
7922
+ });
7923
+ return service ? {
7924
+ service: service,
7925
+ collectionId: collectionId
7926
+ } : null;
7927
+ }).filter(function (item) {
7928
+ return item !== null;
7929
+ });
7930
+ return options.filter(function (current, index, array) {
7931
+ return index === array.findIndex(function (item) {
7932
+ return item.service.id === current.service.id && item.collectionId === current.collectionId;
7933
+ });
7934
+ });
7935
+ };
7936
+ var useTimeSeriesLocations = function useTimeSeriesLocations(panelId) {
7937
+ var _linkedMapIds$;
7938
+ var services = useSelector(function (state) {
7939
+ return getServices(state);
7940
+ });
7941
+ var shouldHideLocationMarkers = useSelector(function (state) {
7942
+ return getShouldHideLocationMarkers(state, panelId);
7943
+ });
7944
+ var plotPresetState = useSelector(function (state) {
7945
+ return getPlotState(state, panelId);
7946
+ });
7947
+ var linkedMapIds = useSelector(function (state) {
7948
+ return genericSelectors.getLinkedTargetIds(state, panelId);
7949
+ });
7950
+ var panelMapId = (_linkedMapIds$ = linkedMapIds == null ? void 0 : linkedMapIds[0]) != null ? _linkedMapIds$ : plotPresetState == null ? void 0 : plotPresetState.mapId;
7951
+ var selectedFeatureFromPanel = useSelector(function (state) {
7952
+ return genericSelectors.getSelectedFeature(state, panelId);
7953
+ });
7954
+ var selectedFeatureFromMap = useSelector(function (state) {
7955
+ return panelMapId ? genericSelectors.getSelectedFeature(state, panelMapId) : null;
7956
+ });
7957
+ var selectedFeature = selectedFeatureFromPanel != null ? selectedFeatureFromPanel : selectedFeatureFromMap;
7958
+ var memoizedSelectedFeature = React.useMemo(function () {
7959
+ if (!selectedFeature) {
7960
+ return null;
7961
+ }
7962
+ return {
7963
+ lat: selectedFeature.lat,
7964
+ lon: selectedFeature.lon,
7965
+ id: selectedFeature.id,
7966
+ occurrences: selectedFeature.occurrences
7967
+ };
7968
+ // eslint-disable-next-line react-hooks/exhaustive-deps
7969
+ }, [selectedFeature == null ? void 0 : selectedFeature.lat, selectedFeature == null ? void 0 : selectedFeature.lon]);
7970
+ var parameters = React.useMemo(function () {
7971
+ return (plotPresetState == null ? void 0 : plotPresetState.parameters) || [];
7972
+ }, [plotPresetState == null ? void 0 : plotPresetState.parameters]);
7973
+ var stableServices = React.useMemo(function () {
7974
+ return services || [];
7975
+ }, [services]);
7976
+ var serviceListForLocations = React.useMemo(function () {
7977
+ return getUniqueServicesFromPreset(parameters, stableServices);
7978
+ }, [parameters, stableServices]);
7979
+ var _useGetLocations = useGetLocations(serviceListForLocations),
7980
+ locationsData = _useGetLocations.data,
7981
+ isLocationsFetching = _useGetLocations.isFetching;
7982
+ var locationsGeoJson = React.useMemo(function () {
7983
+ return stableServices.length ? createGeoJsonArrays(locationsData, stableServices, shouldHideLocationMarkers, memoizedSelectedFeature) : {
7984
+ combinedGeoJson: {
7985
+ type: 'FeatureCollection',
7986
+ features: []
7987
+ },
7988
+ splitGeoJsonByCollection: []
7989
+ };
7990
+ }, [locationsData, memoizedSelectedFeature, shouldHideLocationMarkers, stableServices]);
7991
+ return {
7992
+ combinedGeoJson: locationsGeoJson.combinedGeoJson,
7993
+ isLocationsFetching: isLocationsFetching,
7994
+ serviceListForLocations: serviceListForLocations,
7995
+ splitGeoJsonByCollection: locationsGeoJson.splitGeoJsonByCollection
7996
+ };
7997
+ };
7998
+
7828
7999
  var TOOLTIP_TITLE = 'Timeseries Manager';
7829
8000
  var TimeSeriesManagerMapButtonConnect = function TimeSeriesManagerMapButtonConnect(_ref) {
7830
8001
  var viewId = _ref.viewId;
@@ -7860,102 +8031,9 @@ var TimeSeriesManagerMapButtonConnect = function TimeSeriesManagerMapButtonConne
7860
8031
  });
7861
8032
  };
7862
8033
 
7863
- var LocationSelectButtonConnect = function LocationSelectButtonConnect(_ref) {
7864
- var _timeSeriesLocation$o;
8034
+ var useMapPin = function useMapPin(_ref) {
7865
8035
  var panelId = _ref.panelId;
7866
8036
  var dispatch = useDispatch();
7867
- var _useTimeseriesTransla = useTimeseriesTranslation(),
7868
- t = _useTimeseriesTransla.t;
7869
- var timeSeriesLocation = useSelector(function (state) {
7870
- return getCurrentLocation(state, panelId);
7871
- });
7872
- var currentSourcePanelId = useSelector(function (store) {
7873
- return uiSelectors.getSourcePanelId(store, uiTypes.DialogTypes.TimeseriesLocations);
7874
- });
7875
- var isLocationsDialogOpen = useSelector(function (store) {
7876
- return uiSelectors.getisDialogOpen(store, uiTypes.DialogTypes.TimeseriesLocations);
7877
- });
7878
- var isMapPinDisabled = useSelector(function (state) {
7879
- return getIsMapPinDisabled(state, panelId);
7880
- });
7881
- var isLocationsDialogOpenRef = React.useRef(isLocationsDialogOpen);
7882
- var currentSourcePanelIdRef = React.useRef(currentSourcePanelId);
7883
- React.useEffect(function () {
7884
- isLocationsDialogOpenRef.current = isLocationsDialogOpen;
7885
- currentSourcePanelIdRef.current = currentSourcePanelId;
7886
- }, [isLocationsDialogOpen, currentSourcePanelId]);
7887
- var selectedLocationName = typeof (timeSeriesLocation == null || (_timeSeriesLocation$o = timeSeriesLocation.occurrences) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o[0]) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o.properties) == null ? void 0 : _timeSeriesLocation$o.name) === 'string' ? timeSeriesLocation.occurrences[0].properties.name : '';
7888
- var toggleLocationsDialog = function toggleLocationsDialog() {
7889
- dispatch(uiActions.setToggleOpenDialog({
7890
- type: uiTypes.DialogTypes.TimeseriesLocations,
7891
- setOpen: currentSourcePanelId !== panelId ? true : !isLocationsDialogOpen,
7892
- sourcePanelId: panelId
7893
- }));
7894
- };
7895
- React.useEffect(function () {
7896
- return function () {
7897
- if (isLocationsDialogOpenRef.current && currentSourcePanelIdRef.current === panelId) {
7898
- dispatch(uiActions.setToggleOpenDialog({
7899
- setOpen: false,
7900
- type: uiTypes.DialogTypes.TimeseriesLocations,
7901
- sourcePanelId: panelId
7902
- }));
7903
- }
7904
- };
7905
- }, [dispatch, panelId]);
7906
- return jsx(CustomTooltip, {
7907
- title: selectedLocationName || t('timeseries-select-location'),
7908
- children: jsx("span", {
7909
- children: jsx(TimeSeriesTopRowButton, {
7910
- "aria-label": t('timeseries-location'),
7911
- "data-testid": "locationSelectButton",
7912
- disabled: isMapPinDisabled,
7913
- icon: jsx(Location, {
7914
- sx: {
7915
- '@container time-series-container (width < 720px)': {
7916
- display: 'none'
7917
- }
7918
- }
7919
- }),
7920
- longText: selectedLocationName || t('timeseries-location'),
7921
- onClick: toggleLocationsDialog,
7922
- selected: isLocationsDialogOpen ? currentSourcePanelId === panelId : null,
7923
- shortText: selectedLocationName || t('timeseries-location')
7924
- })
7925
- })
7926
- });
7927
- };
7928
-
7929
- var getUniqueServicesFromPreset = function getUniqueServicesFromPreset(parameters, services) {
7930
- if (!parameters.length || !services.length) {
7931
- return [];
7932
- }
7933
- var options = parameters.map(function (_ref) {
7934
- var serviceId = _ref.serviceId,
7935
- collectionId = _ref.collectionId;
7936
- var service = services.find(function (item) {
7937
- return item.id === serviceId;
7938
- });
7939
- return service ? {
7940
- service: service,
7941
- collectionId: collectionId
7942
- } : null;
7943
- })
7944
- // Filter out null values
7945
- .filter(function (item) {
7946
- return item !== null;
7947
- });
7948
- // Remove duplicates
7949
- var uniqueOptions = options.filter(function (current, index, array) {
7950
- return index === array.findIndex(function (item) {
7951
- return item.service.id === current.service.id && item.collectionId === current.collectionId;
7952
- });
7953
- });
7954
- return uniqueOptions;
7955
- };
7956
- var useMapPin = function useMapPin(_ref2) {
7957
- var panelId = _ref2.panelId;
7958
- var dispatch = useDispatch();
7959
8037
  var selectedMapIds = useSelector(function (state) {
7960
8038
  return genericSelectors.getLinkedTargetIds(state, panelId);
7961
8039
  });
@@ -7996,9 +8074,9 @@ var useMapPin = function useMapPin(_ref2) {
7996
8074
  isMapPinDisabled: isMapPinDisabled
7997
8075
  };
7998
8076
  };
7999
- var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8077
+ var TimeSeriesConnect = function TimeSeriesConnect(_ref2) {
8000
8078
  var _linkedMapIds$;
8001
- var panelId = _ref3.panelId;
8079
+ var panelId = _ref2.panelId;
8002
8080
  var dispatch = useDispatch();
8003
8081
  var _useTimeseriesTransla = useTimeseriesTranslation(),
8004
8082
  t = _useTimeseriesTransla.t;
@@ -8007,7 +8085,7 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8007
8085
  return getIsLegendVisible(state, panelId);
8008
8086
  });
8009
8087
  var services = useSelector(function (state) {
8010
- return getServices(state);
8088
+ return getServices(state) || [];
8011
8089
  });
8012
8090
  var shouldHideLocationMarkers = useSelector(function (state) {
8013
8091
  return getShouldHideLocationMarkers(state, panelId);
@@ -8037,13 +8115,6 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8037
8115
  }),
8038
8116
  toggleDisableMapPin = _useMapPin.toggleDisableMapPin,
8039
8117
  isMapPinDisabled = _useMapPin.isMapPinDisabled;
8040
- var geoJSONWithService = useSelector(function (state) {
8041
- return getGeoJSONWithService(state, panelId);
8042
- });
8043
- var geojson = useSelector(function (state) {
8044
- var _genericSelectors$sel;
8045
- return (_genericSelectors$sel = genericSelectors.selectFeatureSyncLayersForPanel(state, panelId)[0]) == null ? void 0 : _genericSelectors$sel.geojson;
8046
- });
8047
8118
  var isLoading = useCallback(function (startOrFinish) {
8048
8119
  dispatch(loadingIndicatorActions.setEDRIsLoading({
8049
8120
  id: panelId,
@@ -8088,34 +8159,21 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8088
8159
  }
8089
8160
  }, [panelMapId, selectedFeature, setTimeSeriesLocation, memoizedSelectedFeature, allMaps]);
8090
8161
  useRegisterFeatureSyncSource(panelId);
8091
- var parameters = useMemo(function () {
8092
- return (plotPresetState == null ? void 0 : plotPresetState.parameters) || [];
8093
- }, [plotPresetState == null ? void 0 : plotPresetState.parameters]);
8094
- var stableServices = useMemo(function () {
8095
- return services || [];
8096
- }, [services]);
8097
- var serviceListForLocations = useMemo(function () {
8098
- return getUniqueServicesFromPreset(parameters, stableServices);
8099
- }, [parameters, stableServices]);
8100
- var _useGetLocations = useGetLocations(serviceListForLocations),
8101
- locationsData = _useGetLocations.data,
8102
- isLocationsFetching = _useGetLocations.isFetching;
8103
- var combinedGeoJson = useMemo(function () {
8104
- return stableServices.length ? createGeoJsonArrays(locationsData, stableServices, shouldHideLocationMarkers, memoizedSelectedFeature).combinedGeoJson : {
8105
- type: 'FeatureCollection',
8106
- features: []
8107
- };
8108
- }, [locationsData, memoizedSelectedFeature, shouldHideLocationMarkers, stableServices]);
8162
+ var _useTimeSeriesLocatio = useTimeSeriesLocations(panelId),
8163
+ combinedGeoJson = _useTimeSeriesLocatio.combinedGeoJson,
8164
+ isLocationsFetching = _useTimeSeriesLocatio.isLocationsFetching,
8165
+ serviceListForLocations = _useTimeSeriesLocatio.serviceListForLocations,
8166
+ splitGeoJsonByCollection = _useTimeSeriesLocatio.splitGeoJsonByCollection;
8109
8167
  var featureSyncLayersById = useMemo(function () {
8110
- var _ref4;
8111
- return stableServices.length ? (_ref4 = {}, _ref4[geojsonLayerId] = {
8168
+ var _ref3;
8169
+ return serviceListForLocations.length ? (_ref3 = {}, _ref3[geojsonLayerId] = {
8112
8170
  id: geojsonLayerId,
8113
8171
  geojson: consolidateFeatures([{
8114
8172
  id: 'combined-layer',
8115
8173
  geoJSON: combinedGeoJson
8116
8174
  }])
8117
- }, _ref4) : {};
8118
- }, [combinedGeoJson, geojsonLayerId, stableServices]);
8175
+ }, _ref3) : {};
8176
+ }, [combinedGeoJson, geojsonLayerId, serviceListForLocations.length]);
8119
8177
  useUpdateFeatureSyncLayers(featureSyncLayersById, panelId);
8120
8178
  /* Set the loading state based on the locations fetching status */
8121
8179
  useEffect(function () {
@@ -8123,12 +8181,12 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8123
8181
  }, [isLoading, isLocationsFetching]);
8124
8182
  /* Create GeoJSON arrays and draw the geojson layer based on the locationsData */
8125
8183
  useEffect(function () {
8126
- if (stableServices.length) {
8184
+ if (serviceListForLocations.length) {
8127
8185
  if (combinedGeoJson.features.length === 0) {
8128
8186
  setTimeSeriesLocation(undefined);
8129
8187
  }
8130
8188
  }
8131
- }, [combinedGeoJson.features.length, setTimeSeriesLocation, stableServices]);
8189
+ }, [combinedGeoJson.features.length, serviceListForLocations.length, setTimeSeriesLocation]);
8132
8190
  var toggleLocationMarkers = function toggleLocationMarkers(shouldHide) {
8133
8191
  dispatch(timeSeriesActions.toggleLocationMarkers({
8134
8192
  panelId: panelId,
@@ -8168,7 +8226,7 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8168
8226
  },
8169
8227
  children: [jsx(TimeSeriesManagerMapButtonConnect, {
8170
8228
  viewId: panelId
8171
- }), !!geojson && jsx(LocationSelectButtonConnect, {
8229
+ }), !!serviceListForLocations.length && jsx(LocationSelectButtonConnect, {
8172
8230
  panelId: panelId
8173
8231
  }), jsx(LocationInfoButtonConnect, {
8174
8232
  panelId: panelId,
@@ -8204,14 +8262,14 @@ var TimeSeriesConnect = function TimeSeriesConnect(_ref3) {
8204
8262
  sx: {
8205
8263
  overflow: 'auto'
8206
8264
  },
8207
- children: !!services && jsx(TimeSeriesView, {
8265
+ children: !!plotPresetState && jsx(TimeSeriesView, {
8208
8266
  isLoading: isLoading,
8209
8267
  onToggleLegendParam: onToggleLegendParam,
8210
8268
  plotPreset: plotPresetState,
8211
8269
  selectedLocation: timeSeriesLocation,
8212
8270
  services: services,
8213
8271
  shouldShowLegend: shouldShowLegend,
8214
- splitGeoJsonByCollection: geoJSONWithService || [],
8272
+ splitGeoJsonByCollection: splitGeoJsonByCollection,
8215
8273
  syncgroupTimeState: syncgroupTimeState
8216
8274
  })
8217
8275
  })]
@@ -8552,7 +8610,7 @@ var RowComponent = function RowComponent(_ref) {
8552
8610
  handleChange: handleChange,
8553
8611
  isDisabled: isDisabled,
8554
8612
  location: (_feature$properties = feature.properties) == null ? void 0 : _feature$properties.name,
8555
- selectedLocation: selectedLocation
8613
+ selectedLocation: selectedLocation != null ? selectedLocation : ''
8556
8614
  }, feature.id)
8557
8615
  });
8558
8616
  };
@@ -8633,44 +8691,18 @@ var FocusableListWrapper = function FocusableListWrapper(_ref2) {
8633
8691
  children: children
8634
8692
  });
8635
8693
  };
8636
- var LocationDropdown = function LocationDropdown(_ref3) {
8637
- var _combinedSelectedLoca;
8638
- var geoJson = _ref3.geoJson,
8639
- splitGeoJson = _ref3.splitGeoJson,
8640
- handleChange = _ref3.handleChange,
8641
- selectedLocation = _ref3.selectedLocation,
8642
- _ref3$isDisabled = _ref3.isDisabled,
8643
- isDisabled = _ref3$isDisabled === void 0 ? false : _ref3$isDisabled,
8644
- defaultExpanded = _ref3.defaultExpanded;
8694
+ var FocusableList = function FocusableList(_ref3) {
8695
+ var rowCount = _ref3.rowCount,
8696
+ rowHeight = _ref3.rowHeight,
8697
+ rowProps = _ref3.rowProps,
8698
+ style = _ref3.style;
8645
8699
  var listRef = useListRef(null);
8646
- var _React$useState2 = React.useState(''),
8647
- searchTerm = _React$useState2[0],
8648
- setSearchTerm = _React$useState2[1];
8649
- var combinedSelectedLocation = geoJson == null ? void 0 : geoJson.features.find(function (feature) {
8650
- var _feature$properties2;
8651
- return selectedLocation === ((_feature$properties2 = feature.properties) == null ? void 0 : _feature$properties2.name);
8652
- });
8653
- var selectedLocationNames = combinedSelectedLocation ? Object.keys(combinedSelectedLocation == null || (_combinedSelectedLoca = combinedSelectedLocation.properties) == null ? void 0 : _combinedSelectedLoca.names) : [];
8654
- var filteredResults = useMemo(function () {
8655
- return splitGeoJson == null ? void 0 : splitGeoJson.map(function (dataset) {
8656
- var filteredFeatures = dataset.geoJson.features.filter(function (feature) {
8657
- var _feature$properties3;
8658
- return (_feature$properties3 = feature.properties) == null ? void 0 : _feature$properties3.name.toLowerCase().includes(searchTerm.toLowerCase());
8659
- });
8660
- return Object.assign({}, dataset, {
8661
- geoJson: Object.assign({}, dataset.geoJson, {
8662
- features: filteredFeatures
8663
- })
8664
- });
8665
- });
8666
- }, [searchTerm, splitGeoJson]);
8667
- var listContainerRef = React.useRef(null);
8668
- var heightObserver = useResizeObserver(listContainerRef, filteredResults);
8669
8700
  var handleKeyDown = function handleKeyDown(e) {
8670
- var _listContainerRef$cur, _listContainerRef$cur2;
8701
+ var _listRef$current, _element$scrollTop;
8671
8702
  var lineHeight = 40;
8672
- var page = 8 * lineHeight; // or compute from measured height if you want
8673
- var next = (listContainerRef == null || (_listContainerRef$cur = listContainerRef.current) == null ? void 0 : _listContainerRef$cur.scrollTop) || 0;
8703
+ var page = 8 * lineHeight;
8704
+ var element = (_listRef$current = listRef.current) == null ? void 0 : _listRef$current.element;
8705
+ var next = (_element$scrollTop = element == null ? void 0 : element.scrollTop) != null ? _element$scrollTop : 0;
8674
8706
  switch (e.key) {
8675
8707
  case 'ArrowDown':
8676
8708
  e.preventDefault();
@@ -8695,18 +8727,62 @@ var LocationDropdown = function LocationDropdown(_ref3) {
8695
8727
  default:
8696
8728
  return;
8697
8729
  }
8698
- listContainerRef == null || (_listContainerRef$cur2 = listContainerRef.current) == null || _listContainerRef$cur2.scrollTo({
8730
+ element == null || element.scrollTo({
8699
8731
  top: Math.max(0, next),
8700
8732
  behavior: 'smooth'
8701
8733
  });
8702
8734
  };
8735
+ return jsx(FocusableListWrapper, {
8736
+ "aria-label": "Locations list",
8737
+ onKeyDown: handleKeyDown,
8738
+ children: jsx(List$1, {
8739
+ listRef: listRef,
8740
+ rowComponent: RowComponent,
8741
+ rowCount: rowCount,
8742
+ rowHeight: rowHeight,
8743
+ rowProps: rowProps,
8744
+ style: style
8745
+ })
8746
+ });
8747
+ };
8748
+ var LocationDropdown = function LocationDropdown(_ref4) {
8749
+ var _combinedSelectedLoca;
8750
+ var geoJson = _ref4.geoJson,
8751
+ splitGeoJson = _ref4.splitGeoJson,
8752
+ handleChange = _ref4.handleChange,
8753
+ selectedLocation = _ref4.selectedLocation,
8754
+ _ref4$isDisabled = _ref4.isDisabled,
8755
+ isDisabled = _ref4$isDisabled === void 0 ? false : _ref4$isDisabled,
8756
+ defaultExpanded = _ref4.defaultExpanded;
8757
+ var _React$useState2 = React.useState(''),
8758
+ searchTerm = _React$useState2[0],
8759
+ setSearchTerm = _React$useState2[1];
8760
+ var combinedSelectedLocation = geoJson == null ? void 0 : geoJson.features.find(function (feature) {
8761
+ var _feature$properties2;
8762
+ return selectedLocation === ((_feature$properties2 = feature.properties) == null ? void 0 : _feature$properties2.name);
8763
+ });
8764
+ var selectedLocationNames = combinedSelectedLocation ? Object.keys(combinedSelectedLocation == null || (_combinedSelectedLoca = combinedSelectedLocation.properties) == null ? void 0 : _combinedSelectedLoca.names) : [];
8765
+ var filteredResults = useMemo(function () {
8766
+ return splitGeoJson == null ? void 0 : splitGeoJson.map(function (dataset) {
8767
+ var filteredFeatures = dataset.geoJson.features.filter(function (feature) {
8768
+ var _feature$properties3;
8769
+ return (_feature$properties3 = feature.properties) == null ? void 0 : _feature$properties3.name.toLowerCase().includes(searchTerm.toLowerCase());
8770
+ });
8771
+ return Object.assign({}, dataset, {
8772
+ geoJson: Object.assign({}, dataset.geoJson, {
8773
+ features: filteredFeatures
8774
+ })
8775
+ });
8776
+ });
8777
+ }, [searchTerm, splitGeoJson]);
8778
+ var listContainerRef = React.useRef(null);
8779
+ var heightObserver = useResizeObserver(listContainerRef, filteredResults);
8703
8780
  return jsx(Box, {
8704
8781
  "data-testid": "locationDropdownContainer",
8705
8782
  ref: listContainerRef,
8706
8783
  sx: {
8707
8784
  width: '100%',
8708
8785
  height: '100%',
8709
- overflowY: 'auto',
8710
8786
  backgroundColor: 'geowebColors.background.surface'
8711
8787
  },
8712
8788
  children: jsxs(Grid, {
@@ -8745,31 +8821,28 @@ var LocationDropdown = function LocationDropdown(_ref3) {
8745
8821
  amountOfItems: collectionGeoJson.features.length || 0,
8746
8822
  "data-testid": "locationDropdownCollectionAccordion",
8747
8823
  defaultExpanded: defaultExpanded || false,
8824
+ detailsSx: {
8825
+ padding: 0
8826
+ },
8748
8827
  sx: {
8749
8828
  mx: 1,
8750
8829
  mb: 1
8751
8830
  },
8752
8831
  title: collectionName,
8753
8832
  title2: serviceName,
8754
- children: jsx(FocusableListWrapper, {
8755
- "aria-label": "Locations list",
8756
- onKeyDown: handleKeyDown,
8757
- children: jsx(List$1, {
8758
- listRef: listRef,
8759
- rowComponent: RowComponent,
8760
- rowCount: collectionGeoJson.features.length,
8761
- rowHeight: 40,
8762
- rowProps: {
8763
- handleChange: handleChange,
8764
- selectedLocation: collectionSelectedLocation == null || (_collectionSelectedLo = collectionSelectedLocation.properties) == null ? void 0 : _collectionSelectedLo.name,
8765
- features: collectionGeoJson.features,
8766
- isDisabled: isDisabled
8767
- },
8768
- style: {
8769
- height: heightObserver,
8770
- width: '100%'
8771
- }
8772
- })
8833
+ children: jsx(FocusableList, {
8834
+ rowCount: collectionGeoJson.features.length,
8835
+ rowHeight: 40,
8836
+ rowProps: {
8837
+ handleChange: handleChange,
8838
+ selectedLocation: collectionSelectedLocation == null || (_collectionSelectedLo = collectionSelectedLocation.properties) == null ? void 0 : _collectionSelectedLo.name,
8839
+ features: collectionGeoJson.features,
8840
+ isDisabled: isDisabled
8841
+ },
8842
+ style: {
8843
+ height: heightObserver,
8844
+ width: '100%'
8845
+ }
8773
8846
  })
8774
8847
  })
8775
8848
  }, collectionName + "-" + serviceName);
@@ -8793,12 +8866,6 @@ var LocationSelectDialogConnect = function LocationSelectDialogConnect() {
8793
8866
  onCloseDialog = _useSetupDialog.onCloseDialog,
8794
8867
  dialogOrder = _useSetupDialog.dialogOrder,
8795
8868
  setDialogOrder = _useSetupDialog.setDialogOrder;
8796
- var geoJSONWithService = useSelector(function (state) {
8797
- return panelId ? getGeoJSONWithService(state, panelId) : undefined;
8798
- });
8799
- var sharedFeature = useSelector(function (state) {
8800
- return panelId ? genericSelectors.selectFeatureSyncLayersForPanel(state, panelId)[0] : undefined;
8801
- });
8802
8869
  var featureSyncLayerIds = useSelector(function (state) {
8803
8870
  return panelId ? genericSelectors.selectFeatureSyncLayerIdsForPanel(state, panelId) : emptyMapIdList;
8804
8871
  });
@@ -8811,6 +8878,9 @@ var LocationSelectDialogConnect = function LocationSelectDialogConnect() {
8811
8878
  var timeSeriesLocation = useSelector(function (state) {
8812
8879
  return panelId ? getCurrentLocation(state, panelId) : undefined;
8813
8880
  });
8881
+ var _useTimeSeriesLocatio = useTimeSeriesLocations(panelId || ''),
8882
+ combinedGeoJson = _useTimeSeriesLocatio.combinedGeoJson,
8883
+ splitGeoJsonByCollection = _useTimeSeriesLocatio.splitGeoJsonByCollection;
8814
8884
  var setSelectedFeatureIds = function setSelectedFeatureIds(selectedFeatureIds) {
8815
8885
  featureSyncLayerIds.forEach(function (layerId) {
8816
8886
  dispatch(layerActions.setSelectedFeatures({
@@ -8836,20 +8906,19 @@ var LocationSelectDialogConnect = function LocationSelectDialogConnect() {
8836
8906
  }));
8837
8907
  });
8838
8908
  };
8839
- var geojson = sharedFeature == null ? void 0 : sharedFeature.geojson;
8840
8909
  var selectedLocationName = typeof (timeSeriesLocation == null || (_timeSeriesLocation$o = timeSeriesLocation.occurrences) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o[0]) == null || (_timeSeriesLocation$o = _timeSeriesLocation$o.properties) == null ? void 0 : _timeSeriesLocation$o.name) === 'string' ? timeSeriesLocation.occurrences[0].properties.name : '';
8841
8910
  var onChangeLocation = function onChangeLocation(newSelectedLocation) {
8842
- var _geojson$features, _feature$properties;
8911
+ var _feature$properties;
8843
8912
  if (!panelId) {
8844
8913
  return;
8845
8914
  }
8846
- if (!(geojson != null && (_geojson$features = geojson.features) != null && _geojson$features.length)) {
8915
+ if (!combinedGeoJson.features.length) {
8847
8916
  return;
8848
8917
  }
8849
- var selectedFeatureIndex = geojson.features.findIndex(function (feature) {
8918
+ var selectedFeatureIndex = combinedGeoJson.features.findIndex(function (feature) {
8850
8919
  return Object.keys(feature.properties.names).includes(newSelectedLocation);
8851
8920
  });
8852
- var feature = geojson.features[selectedFeatureIndex];
8921
+ var feature = combinedGeoJson.features[selectedFeatureIndex];
8853
8922
  setSelectedFeatureIds(feature != null && feature.id ? [String(feature.id)] : []);
8854
8923
  var _getFeatureCenterPoin = getFeatureCenterPoint(feature),
8855
8924
  lon = _getFeatureCenterPoin[0],
@@ -8897,11 +8966,11 @@ var LocationSelectDialogConnect = function LocationSelectDialogConnect() {
8897
8966
  },
8898
8967
  title: t('locations'),
8899
8968
  children: jsx(LocationDropdown, {
8900
- geoJson: geojson,
8969
+ geoJson: combinedGeoJson,
8901
8970
  handleChange: onChangeLocation,
8902
8971
  isDisabled: isMapPinDisabled,
8903
8972
  selectedLocation: selectedLocationName,
8904
- splitGeoJson: geoJSONWithService
8973
+ splitGeoJson: splitGeoJsonByCollection
8905
8974
  })
8906
8975
  });
8907
8976
  };
@@ -1,8 +1,4 @@
1
1
  import React from 'react';
2
- import type { TimeSeriesService } from '@opengeoweb/shared';
3
- import type { Parameter } from './types';
4
- import type { GetLocationsOption } from '../../utils/timeseries-api/hooks';
5
- export declare const getUniqueServicesFromPreset: (parameters: Parameter[], services: TimeSeriesService[]) => GetLocationsOption[];
6
2
  export interface TimeSeriesConnectProps {
7
3
  panelId: string;
8
4
  }
@@ -0,0 +1,12 @@
1
+ import type { TimeSeriesService } from '@opengeoweb/shared';
2
+ import type { GeoJsonWithService, Parameter } from './types';
3
+ import type { GetLocationsOption } from '../../utils/timeseries-api/hooks';
4
+ export declare const getUniqueServicesFromPreset: (parameters: Parameter[], services: TimeSeriesService[]) => GetLocationsOption[];
5
+ interface UseTimeSeriesLocationsResult {
6
+ combinedGeoJson: GeoJSON.FeatureCollection;
7
+ isLocationsFetching: boolean;
8
+ serviceListForLocations: GetLocationsOption[];
9
+ splitGeoJsonByCollection: GeoJsonWithService[];
10
+ }
11
+ export declare const useTimeSeriesLocations: (panelId: string) => UseTimeSeriesLocationsResult;
12
+ export {};
@@ -8,6 +8,7 @@ export type PlotErrorsMap = Record<Plot['plotId'], string[]>;
8
8
  export type FailedParametersMap = Record<Plot['plotId'], FailedParameterInfo[]>;
9
9
  export declare const createGeoJsonArrays: (locations: (FeatureCollection<GeometryObject, UseGetLocationReturnTypeProperties> | undefined)[], services: TimeSeriesService[] | undefined, hideFeatures: boolean, memoizedSelectedFeature: TimeSeriesLocation | null) => {
10
10
  combinedGeoJson: FeatureCollection<GeometryObject, syncGroupsTypes.PotentialDataProperties>;
11
+ splitGeoJsonByCollection: GeoJsonWithService[];
11
12
  };
12
13
  export declare const getNearbyLocation: (parameter: Parameter, service: TimeSeriesService, selectedLocation: PointerLocation, geojsonMap: Map<string, GeoJsonWithService>) => TimeSeriesLocation | null;
13
14
  export declare const getPlotsWithParameters: (plots: Plot[], parameters: ParameterWithData[], plotErrors?: PlotErrorsMap, failedParameters?: FailedParametersMap) => PlotWithData[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/time-series",
3
- "version": "19.2.0",
3
+ "version": "19.3.0",
4
4
  "description": "GeoWeb time-series library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {