@opengeoweb/layer-select 9.4.0 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -2,21 +2,21 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default from 'react';
4
4
  import { useSelector, useDispatch } from 'react-redux';
5
- import { uiTypes, serviceActions, selectorMemoizationOptions, serviceSelectors, uiActions, uiSelectors, mapSelectors, layerActions, layerTypes, useSetupDialog } from '@opengeoweb/store';
6
- import { CustomIconButton, ToolContainerDraggable, SearchField, CustomToggleButton, CustomTooltip, SearchHighlight, ToggleMenu, CustomAccordion } from '@opengeoweb/shared';
7
- import { Info, DimensionsOther, DimensionsElevation, DimensionsRefTime, DimensionsTime, LayersAdd, Filter, Add, Cached, Edit, Visibility, Delete, Close, Copy } from '@opengeoweb/theme';
5
+ import { CustomIconButton, ToolContainerDraggable, CustomAccordion, CustomToggleButton, CustomTooltip, SearchHighlight, SearchField, ToggleMenu } from '@opengeoweb/shared';
6
+ import { Filter, Info, DimensionsOther, DimensionsElevation, DimensionsRefTime, DimensionsTime, LayersAdd, Add, Cached, Edit, Visibility, Delete, Close, Copy } from '@opengeoweb/theme';
7
+ import { uiTypes, serviceActions, selectorMemoizationOptions, serviceSelectors, uiActions, uiSelectors, useSetupDialog, mapSelectors, layerActions, layerTypes } from '@opengeoweb/store';
8
8
  import { createEntityAdapter, createSlice, createSelector } from '@reduxjs/toolkit';
9
9
  import { compact, countBy, partition } from 'lodash';
10
10
  import { createStore } from '@redux-eggs/redux-toolkit';
11
11
  import { getSagaExtension } from '@redux-eggs/saga-extension';
12
12
  import { takeEvery, select, put, all } from 'redux-saga/effects';
13
+ import { ListItem, ListItemIcon, Checkbox, Typography, ListItemSecondaryAction, Switch, Grid, List, Box as Box$1, Backdrop, CircularProgress, Button, ListItemText, Dialog, DialogTitle, LinearProgress, DialogContent, InputAdornment, DialogActions } from '@mui/material';
13
14
  import Box from '@mui/material/Box';
14
- import Typography from '@mui/material/Typography';
15
- import Grid from '@mui/material/Grid';
15
+ import Typography$1 from '@mui/material/Typography';
16
+ import Grid$1 from '@mui/material/Grid';
16
17
  import { LegendLayout } from '@opengeoweb/webmap-react';
17
- import { Grid as Grid$1, Box as Box$1, Typography as Typography$1, Backdrop, CircularProgress, Button, List, ListItem, ListItemText, ListItemSecondaryAction, ListItemIcon, Checkbox, Switch, Dialog, DialogTitle, LinearProgress, DialogContent, InputAdornment, DialogActions } from '@mui/material';
18
- import { webmapUtils, LayerType, getCapabilities, WMGetServiceFromStore, clearImageCache } from '@opengeoweb/webmap';
19
18
  import { FixedSizeList } from 'react-window';
19
+ import { webmapUtils, LayerType, getCapabilities, WMGetServiceFromStore, clearImageCache } from '@opengeoweb/webmap';
20
20
  import { snackbarActions } from '@opengeoweb/snackbar';
21
21
  import { ReactHookFormProvider, defaultFormOptions, ReactHookFormTextField } from '@opengeoweb/form-fields';
22
22
  import { useFormContext } from 'react-hook-form';
@@ -1106,68 +1106,6 @@ $$8({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== assign }
1106
1106
  assign: assign
1107
1107
  });
1108
1108
 
1109
- /******************************************************************************
1110
- Copyright (c) Microsoft Corporation.
1111
-
1112
- Permission to use, copy, modify, and/or distribute this software for any
1113
- purpose with or without fee is hereby granted.
1114
-
1115
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1116
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1117
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1118
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1119
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1120
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1121
- PERFORMANCE OF THIS SOFTWARE.
1122
- ***************************************************************************** */
1123
-
1124
- function __rest(s, e) {
1125
- var t = {};
1126
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
1127
- t[p] = s[p];
1128
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
1129
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
1130
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
1131
- t[p[i]] = s[p[i]];
1132
- }
1133
- return t;
1134
- }
1135
-
1136
- function __awaiter(thisArg, _arguments, P, generator) {
1137
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1138
- return new (P || (P = Promise))(function (resolve, reject) {
1139
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1140
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1141
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1142
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1143
- });
1144
- }
1145
-
1146
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1147
- var e = new Error(message);
1148
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1149
- };
1150
-
1151
- const LayerInfoButton = _a => {
1152
- var {
1153
- isOpenInStore,
1154
- isActive,
1155
- onClick
1156
- } = _a,
1157
- props = __rest(_a, ["isOpenInStore", "isActive", "onClick"]);
1158
- return jsx(CustomIconButton, Object.assign({
1159
- variant: "flat",
1160
- isSelected: isActive && isOpenInStore,
1161
- onClick: onClick,
1162
- id: "layerInfoButton",
1163
- "data-testid": "layerInfoButton",
1164
- "aria-label": "layer info",
1165
- className: "layerInfoButton"
1166
- }, props, {
1167
- children: jsx(Info, {})
1168
- }));
1169
- };
1170
-
1171
1109
  var aCallable$4 = aCallable$6;
1172
1110
  var toObject$3 = toObject$6;
1173
1111
  var IndexedObject = indexedObject;
@@ -2916,492 +2854,861 @@ const layerSelectConfig = {
2916
2854
  sagas: [rootSaga]
2917
2855
  };
2918
2856
 
2919
- const LayerInfoButtonConnect = ({
2920
- isLayerMissing,
2921
- layer,
2857
+ const KeywordFilterButtonConnect = ({
2922
2858
  mapId,
2923
- serviceName,
2924
- source: _source = 'app'
2859
+ source: _source = 'app',
2860
+ isMultiMap
2925
2861
  }) => {
2926
2862
  const dispatch = useDispatch();
2927
- const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, uiTypes.DialogTypes.LayerInfo));
2928
- const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, uiTypes.DialogTypes.LayerInfo));
2929
- const currentLayerInfo = useAppSelector(store => getActiveLayerInfo(store));
2930
- const isActive = layer.name === (currentLayerInfo === null || currentLayerInfo === void 0 ? void 0 : currentLayerInfo.name) && serviceName === (currentLayerInfo === null || currentLayerInfo === void 0 ? void 0 : currentLayerInfo.serviceName);
2931
- const toggleInfoDialog = React__default.useCallback(() => {
2863
+ const dialogType = isMultiMap ? `${uiTypes.DialogTypes.KeywordFilter}-${mapId}` : uiTypes.DialogTypes.KeywordFilter;
2864
+ const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, dialogType));
2865
+ const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, dialogType));
2866
+ const openFilterResultsDialog = React.useCallback(() => {
2932
2867
  dispatch(uiActions.setActiveMapIdForDialog({
2933
- type: uiTypes.DialogTypes.LayerInfo,
2868
+ type: dialogType,
2934
2869
  mapId,
2935
2870
  setOpen: currentActiveMapId !== mapId ? true : !isOpenInStore,
2936
2871
  source: _source
2937
2872
  }));
2938
- }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source]);
2939
- const setActiveLayerInfo = React__default.useCallback(() => {
2940
- dispatch(layerSelectActions.setActiveLayerInfo({
2941
- layer: Object.assign(Object.assign({}, layer), {
2942
- serviceName
2943
- })
2944
- }));
2945
- dispatch(uiActions.orderDialog({
2946
- type: uiTypes.DialogTypes.LayerInfo
2947
- }));
2948
- }, [dispatch, layer, serviceName]);
2949
- const onClick = () => {
2950
- if (isActive) {
2951
- toggleInfoDialog();
2952
- }
2953
- if (!isActive && isOpenInStore) {
2954
- setActiveLayerInfo();
2955
- }
2956
- if (!isActive && !isOpenInStore) {
2957
- setActiveLayerInfo();
2958
- toggleInfoDialog();
2959
- }
2960
- };
2961
- return jsx(LayerInfoButton, {
2962
- disabled: isLayerMissing,
2963
- isActive: isActive,
2964
- isOpenInStore: isOpenInStore,
2965
- onClick: onClick
2966
- });
2873
+ }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source, dialogType]);
2874
+ return jsx(CustomIconButton, Object.assign({
2875
+ variant: "tool",
2876
+ onClick: openFilterResultsDialog,
2877
+ isSelected: isOpenInStore,
2878
+ id: "keywordFilterButton",
2879
+ "data-testid": "keywordFilterButton"
2880
+ }, {
2881
+ children: jsx(Filter, {})
2882
+ }));
2967
2883
  };
2968
2884
 
2969
- const textStyle = {
2970
- lineHeight: '20px',
2971
- letterSpacing: '0.25px'
2972
- };
2973
- const textStyleWithMargin = Object.assign(Object.assign({}, textStyle), {
2974
- marginBottom: 1
2975
- });
2976
- const LayerInfoText = ({
2977
- label,
2978
- value
2885
+ const FilterListItem = ({
2886
+ filter,
2887
+ toggleFilter,
2888
+ enableOnlyOneFilter
2979
2889
  }) => {
2980
- return jsxs(Fragment, {
2981
- children: [jsx(Typography, Object.assign({
2982
- variant: "subtitle2",
2983
- sx: textStyle
2984
- }, {
2985
- children: label
2986
- })), jsx(Typography, Object.assign({
2987
- variant: "body2",
2988
- sx: textStyleWithMargin
2989
- }, {
2990
- children: value
2991
- }))]
2890
+ const [isHovering, setIsHovering] = React.useState(false);
2891
+ const handleMouseEnter = React.useCallback(() => {
2892
+ setIsHovering(true);
2893
+ }, []);
2894
+ const handleMouseLeave = React.useCallback(() => {
2895
+ setIsHovering(false);
2896
+ }, []);
2897
+ const selectOnlyOne = filterId => {
2898
+ enableOnlyOneFilter(filterId);
2899
+ };
2900
+ const toggleCheckbox = filterId => {
2901
+ toggleFilter([filterId]);
2902
+ };
2903
+ const mouseMoveRef = React.useRef(null);
2904
+ React.useEffect(() => {
2905
+ window.addEventListener('mousemove', checkHover, true);
2906
+ return () => {
2907
+ window.removeEventListener('mousemove', checkHover, true);
2908
+ };
2992
2909
  });
2993
- };
2994
-
2995
- const valueStyle = Object.assign(Object.assign({}, textStyle), {
2996
- overflowWrap: 'break-word'
2997
- });
2998
- const LayerInfoList = ({
2999
- label,
3000
- list
3001
- }) => {
3002
- return jsxs(Fragment, {
3003
- children: [jsx(Typography, Object.assign({
3004
- variant: "subtitle2",
3005
- sx: textStyle
3006
- }, {
3007
- children: label
3008
- })), list.length === 0 ? jsx(Typography, Object.assign({
3009
- variant: "body2",
3010
- sx: textStyleWithMargin
3011
- }, {
3012
- children: "-"
3013
- })) : jsx(Grid, Object.assign({
3014
- container: true,
3015
- direction: "column"
2910
+ const checkHover = e => {
2911
+ if (mouseMoveRef.current) {
2912
+ const mouseOver = mouseMoveRef.current.contains(e.target);
2913
+ if (!isHovering && mouseOver) {
2914
+ handleMouseEnter();
2915
+ }
2916
+ if (isHovering && !mouseOver) {
2917
+ handleMouseLeave();
2918
+ }
2919
+ }
2920
+ };
2921
+ if (filter.amountVisible !== 0) {
2922
+ return jsx("div", Object.assign({
2923
+ ref: mouseMoveRef,
2924
+ onMouseEnter: handleMouseEnter,
2925
+ onMouseLeave: handleMouseLeave,
2926
+ onFocus: handleMouseEnter,
2927
+ onBlur: handleMouseLeave
3016
2928
  }, {
3017
- children: list.map(item => jsxs("div", {
3018
- children: [jsxs(Grid, Object.assign({
3019
- item: true,
3020
- container: true,
3021
- direction: "row"
2929
+ children: jsxs(ListItem, Object.assign({
2930
+ sx: {
2931
+ width: '100%',
2932
+ minWidth: '300px',
2933
+ padding: '0px',
2934
+ paddingLeft: '0px',
2935
+ paddingRight: '50px',
2936
+ fontSize: '12px'
2937
+ }
2938
+ }, {
2939
+ children: [jsx(ListItemIcon, Object.assign({
2940
+ sx: {
2941
+ minWidth: '42px'
2942
+ }
3022
2943
  }, {
3023
- children: [item.icon, jsx(Grid, Object.assign({
3024
- item: true,
2944
+ children: jsx(Checkbox, {
2945
+ inputProps: {
2946
+ 'aria-label': filter.name
2947
+ },
2948
+ color: "secondary",
2949
+ checked: filter.checked,
2950
+ onChange: () => {
2951
+ toggleCheckbox(filter.id);
2952
+ },
3025
2953
  sx: {
3026
- marginLeft: '10px'
2954
+ paddingTop: '6px',
2955
+ paddingBottom: '7px',
2956
+ '&&:hover': {
2957
+ backgroundColor: 'transparent'
2958
+ }
3027
2959
  }
3028
- }, {
3029
- children: jsxs(Typography, Object.assign({
3030
- variant: "body2",
3031
- sx: textStyle
3032
- }, {
3033
- children: [item.label, ":"]
3034
- }))
3035
- }))]
3036
- })), jsx(Grid, Object.assign({
3037
- item: true,
3038
- container: true,
3039
- direction: "row",
2960
+ })
2961
+ })), jsxs(Typography, Object.assign({
2962
+ variant: "body2",
3040
2963
  sx: {
3041
- marginBottom: 1,
3042
- paddingLeft: '34px'
2964
+ fontSize: '16px',
2965
+ textOverflow: 'ellipsis',
2966
+ whiteSpace: 'nowrap',
2967
+ overflow: 'hidden'
3043
2968
  }
3044
2969
  }, {
3045
- children: jsx(Typography, Object.assign({
3046
- variant: "body2",
3047
- sx: valueStyle
2970
+ children: [filter.name, " (", filter.amountVisible, ")"]
2971
+ })), isHovering ? jsx(ListItemSecondaryAction, {
2972
+ children: jsx(CustomIconButton, Object.assign({
2973
+ "aria-label": `Only ${filter.name}`,
2974
+ style: {
2975
+ backgroundColor: 'transparent',
2976
+ width: 'auto'
2977
+ },
2978
+ edge: "end",
2979
+ onClick: () => selectOnlyOne(filter.id)
3048
2980
  }, {
3049
- children: item.value
2981
+ children: jsx(Typography, Object.assign({
2982
+ sx: {
2983
+ color: 'geowebColors.buttons.primary.default.fill',
2984
+ fontSize: '14px',
2985
+ fontWeight: 500
2986
+ }
2987
+ }, {
2988
+ children: "ONLY"
2989
+ }))
3050
2990
  }))
3051
- }))]
3052
- }, item.label))
3053
- }))]
3054
- });
2991
+ }) : null]
2992
+ }))
2993
+ }));
2994
+ }
2995
+ return null;
3055
2996
  };
3056
2997
 
3057
- const LayerInfoLegend = ({
3058
- title,
3059
- name,
3060
- dimensions,
3061
- legendURL
2998
+ const KeywordFilterResultsListItemConnect = ({
2999
+ filter
3062
3000
  }) => {
3063
- return jsxs(Fragment, {
3064
- children: [jsx(Typography, Object.assign({
3065
- variant: "subtitle2",
3066
- sx: textStyleWithMargin
3067
- }, {
3068
- children: "Legend"
3069
- })), jsx(LegendLayout, Object.assign({
3070
- title: title,
3071
- name: name,
3072
- dimensions: dimensions
3073
- }, {
3074
- children: legendURL ? jsx("img", {
3075
- alt: title,
3076
- src: legendURL
3077
- }) : '-'
3078
- }))]
3001
+ const dispatch = useDispatch();
3002
+ const toggleFilter = React.useCallback(filterIds => {
3003
+ dispatch(layerSelectActions.toggleFilter({
3004
+ filterIds
3005
+ }));
3006
+ }, [dispatch]);
3007
+ const enableOnlyOneFilter = React.useCallback(filterId => {
3008
+ dispatch(layerSelectActions.enableOnlyOneFilter({
3009
+ filterId
3010
+ }));
3011
+ }, [dispatch]);
3012
+ return jsx(FilterListItem, {
3013
+ filter: filter,
3014
+ toggleFilter: toggleFilter,
3015
+ enableOnlyOneFilter: enableOnlyOneFilter
3079
3016
  });
3080
3017
  };
3081
3018
 
3082
- var anObject$3 = anObject$9;
3083
-
3084
- // `RegExp.prototype.flags` getter implementation
3085
- // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
3086
- var regexpFlags$1 = function () {
3087
- var that = anObject$3(this);
3088
- var result = '';
3089
- if (that.hasIndices) result += 'd';
3090
- if (that.global) result += 'g';
3091
- if (that.ignoreCase) result += 'i';
3092
- if (that.multiline) result += 'm';
3093
- if (that.dotAll) result += 's';
3094
- if (that.unicode) result += 'u';
3095
- if (that.unicodeSets) result += 'v';
3096
- if (that.sticky) result += 'y';
3097
- return result;
3019
+ const KeywordFilterSelectAllSwitchConnect = () => {
3020
+ const dispatch = useDispatch();
3021
+ const allFiltersActive = useAppSelector(store => isAllFiltersChecked(store));
3022
+ const allFilterIds = useAppSelector(store => getAllFilterIds(store));
3023
+ const checkedFilterIds = useAppSelector(store => getCheckedFilterIds(store));
3024
+ const toggleFilters = React.useCallback(() => {
3025
+ const filterIds = allFiltersActive ? checkedFilterIds : allFilterIds.filter(id => !checkedFilterIds.includes(id));
3026
+ dispatch(layerSelectActions.toggleFilter({
3027
+ filterIds
3028
+ }));
3029
+ }, [allFilterIds, allFiltersActive, checkedFilterIds, dispatch]);
3030
+ return jsx(Switch, {
3031
+ inputProps: {
3032
+ 'aria-label': 'All'
3033
+ },
3034
+ checked: allFiltersActive,
3035
+ onChange: toggleFilters,
3036
+ "data-testid": "customSwitch"
3037
+ });
3098
3038
  };
3099
3039
 
3100
- var fails$4 = fails$k;
3101
- var global$3 = global$g;
3102
-
3103
- // babel-minify and Closure Compiler transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
3104
- var $RegExp$2 = global$3.RegExp;
3105
-
3106
- var UNSUPPORTED_Y$2 = fails$4(function () {
3107
- var re = $RegExp$2('a', 'y');
3108
- re.lastIndex = 2;
3109
- return re.exec('abcd') !== null;
3110
- });
3111
-
3112
- // UC Browser bug
3113
- // https://github.com/zloirock/core-js/issues/1008
3114
- var MISSED_STICKY = UNSUPPORTED_Y$2 || fails$4(function () {
3115
- return !$RegExp$2('a', 'y').sticky;
3116
- });
3117
-
3118
- var BROKEN_CARET = UNSUPPORTED_Y$2 || fails$4(function () {
3119
- // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
3120
- var re = $RegExp$2('^r', 'gy');
3121
- re.lastIndex = 2;
3122
- return re.exec('str') !== null;
3123
- });
3124
-
3125
- var regexpStickyHelpers = {
3126
- BROKEN_CARET: BROKEN_CARET,
3127
- MISSED_STICKY: MISSED_STICKY,
3128
- UNSUPPORTED_Y: UNSUPPORTED_Y$2
3040
+ const DIALOG_TITLE = 'Groups & Keywords';
3041
+ const listStyle = {
3042
+ padding: '0px'
3043
+ };
3044
+ const accordionDetailsStyle = {
3045
+ padding: '0px',
3046
+ margin: '0px'
3047
+ };
3048
+ const KeywordFilterResults = ({
3049
+ filters,
3050
+ bounds,
3051
+ onClose: _onClose = () => {},
3052
+ isOpen,
3053
+ onMouseDown: _onMouseDown = () => {},
3054
+ order: _order = 0,
3055
+ source: _source = 'module'
3056
+ }) => {
3057
+ return jsxs(ToolContainerDraggable, Object.assign({
3058
+ title: DIALOG_TITLE,
3059
+ "data-testid": "keywordFilterResults",
3060
+ startSize: {
3061
+ width: 349,
3062
+ height: 600
3063
+ },
3064
+ minWidth: 312,
3065
+ minHeight: 192,
3066
+ isOpen: isOpen,
3067
+ onClose: _onClose,
3068
+ bounds: bounds,
3069
+ onMouseDown: _onMouseDown,
3070
+ order: _order,
3071
+ source: _source
3072
+ }, {
3073
+ children: [jsxs(Grid, Object.assign({
3074
+ container: true,
3075
+ item: true,
3076
+ xs: 12,
3077
+ justifyContent: "space-between",
3078
+ alignItems: "center",
3079
+ sx: {
3080
+ backgroundColor: 'background.paper',
3081
+ position: 'sticky',
3082
+ top: 0,
3083
+ zIndex: 100
3084
+ }
3085
+ }, {
3086
+ children: [jsx(Grid, Object.assign({
3087
+ container: true,
3088
+ item: true,
3089
+ xs: 6,
3090
+ justifyContent: "flex-start",
3091
+ alignItems: "center",
3092
+ sx: {
3093
+ padding: '15px 15px 0 24px'
3094
+ }
3095
+ }, {
3096
+ children: "Select all"
3097
+ })), jsx(Grid, Object.assign({
3098
+ container: true,
3099
+ item: true,
3100
+ xs: 6,
3101
+ justifyContent: "flex-end",
3102
+ alignContent: "center",
3103
+ sx: {
3104
+ padding: '15px 15px 0 15px'
3105
+ }
3106
+ }, {
3107
+ children: jsx(KeywordFilterSelectAllSwitchConnect, {})
3108
+ }))]
3109
+ })), jsx(CustomAccordion, Object.assign({
3110
+ title: "Groups",
3111
+ detailsSx: accordionDetailsStyle
3112
+ }, {
3113
+ children: jsx(List, Object.assign({
3114
+ dense: true,
3115
+ style: listStyle
3116
+ }, {
3117
+ children: filters.groups.map(group => jsx(KeywordFilterResultsListItemConnect, {
3118
+ filter: group
3119
+ }, group.id))
3120
+ }))
3121
+ })), jsx(CustomAccordion, Object.assign({
3122
+ title: "Keywords",
3123
+ detailsSx: accordionDetailsStyle
3124
+ }, {
3125
+ children: jsx(List, Object.assign({
3126
+ dense: true,
3127
+ style: listStyle
3128
+ }, {
3129
+ children: filters.keywords.map(keyword => {
3130
+ return jsx(KeywordFilterResultsListItemConnect, {
3131
+ filter: keyword
3132
+ }, keyword.id);
3133
+ })
3134
+ }))
3135
+ }))]
3136
+ }));
3129
3137
  };
3130
3138
 
3131
- var fails$3 = fails$k;
3132
- var global$2 = global$g;
3133
-
3134
- // babel-minify and Closure Compiler transpiles RegExp('.', 's') -> /./s and it causes SyntaxError
3135
- var $RegExp$1 = global$2.RegExp;
3139
+ const KeywordFilterResultsConnect = ({
3140
+ bounds,
3141
+ mapId,
3142
+ isMultiMap
3143
+ }) => {
3144
+ const dialogType = isMultiMap ? `${uiTypes.DialogTypes.KeywordFilter}-${mapId}` : uiTypes.DialogTypes.KeywordFilter;
3145
+ const {
3146
+ dialogOrder,
3147
+ onCloseDialog,
3148
+ setDialogOrder,
3149
+ isDialogOpen,
3150
+ uiSource
3151
+ } = useSetupDialog(dialogType);
3152
+ const filters = useAppSelector(getFilters);
3153
+ return jsx(KeywordFilterResults, {
3154
+ bounds: bounds,
3155
+ isOpen: isDialogOpen,
3156
+ onClose: onCloseDialog,
3157
+ onMouseDown: setDialogOrder,
3158
+ order: dialogOrder,
3159
+ source: uiSource,
3160
+ filters: filters
3161
+ });
3162
+ };
3136
3163
 
3137
- var regexpUnsupportedDotAll = fails$3(function () {
3138
- var re = $RegExp$1('.', 's');
3139
- return !(re.dotAll && re.test('\n') && re.flags === 's');
3140
- });
3141
-
3142
- var fails$2 = fails$k;
3143
- var global$1 = global$g;
3144
-
3145
- // babel-minify and Closure Compiler transpiles RegExp('(?<a>b)', 'g') -> /(?<a>b)/g and it causes SyntaxError
3146
- var $RegExp = global$1.RegExp;
3147
-
3148
- var regexpUnsupportedNcg = fails$2(function () {
3149
- var re = $RegExp('(?<a>b)', 'g');
3150
- return re.exec('b').groups.a !== 'b' ||
3151
- 'b'.replace(re, '$<a>c') !== 'bc';
3152
- });
3153
-
3154
- /* eslint-disable regexp/no-empty-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */
3155
- /* eslint-disable regexp/no-useless-quantifier -- testing */
3156
- var call$3 = functionCall;
3157
- var uncurryThis$4 = functionUncurryThis;
3158
- var toString$2 = toString$5;
3159
- var regexpFlags = regexpFlags$1;
3160
- var stickyHelpers$1 = regexpStickyHelpers;
3161
- var shared = shared$4.exports;
3162
- var create = objectCreate;
3163
- var getInternalState = internalState.get;
3164
- var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll;
3165
- var UNSUPPORTED_NCG = regexpUnsupportedNcg;
3166
-
3167
- var nativeReplace = shared('native-string-replace', String.prototype.replace);
3168
- var nativeExec = RegExp.prototype.exec;
3169
- var patchedExec = nativeExec;
3170
- var charAt$2 = uncurryThis$4(''.charAt);
3171
- var indexOf = uncurryThis$4(''.indexOf);
3172
- var replace = uncurryThis$4(''.replace);
3173
- var stringSlice$2 = uncurryThis$4(''.slice);
3174
-
3175
- var UPDATES_LAST_INDEX_WRONG = (function () {
3176
- var re1 = /a/;
3177
- var re2 = /b*/g;
3178
- call$3(nativeExec, re1, 'a');
3179
- call$3(nativeExec, re2, 'a');
3180
- return re1.lastIndex !== 0 || re2.lastIndex !== 0;
3181
- })();
3182
-
3183
- var UNSUPPORTED_Y$1 = stickyHelpers$1.BROKEN_CARET;
3184
-
3185
- // nonparticipating capturing group, copied from es5-shim's String#split patch.
3186
- var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
3187
-
3188
- var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$1 || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG;
3189
-
3190
- if (PATCH) {
3191
- patchedExec = function exec(string) {
3192
- var re = this;
3193
- var state = getInternalState(re);
3194
- var str = toString$2(string);
3195
- var raw = state.raw;
3196
- var result, reCopy, lastIndex, match, i, object, group;
3197
-
3198
- if (raw) {
3199
- raw.lastIndex = re.lastIndex;
3200
- result = call$3(patchedExec, raw, str);
3201
- re.lastIndex = raw.lastIndex;
3202
- return result;
3203
- }
3204
-
3205
- var groups = state.groups;
3206
- var sticky = UNSUPPORTED_Y$1 && re.sticky;
3207
- var flags = call$3(regexpFlags, re);
3208
- var source = re.source;
3209
- var charsAdded = 0;
3210
- var strCopy = str;
3211
-
3212
- if (sticky) {
3213
- flags = replace(flags, 'y', '');
3214
- if (indexOf(flags, 'g') === -1) {
3215
- flags += 'g';
3216
- }
3217
-
3218
- strCopy = stringSlice$2(str, re.lastIndex);
3219
- // Support anchored sticky behavior.
3220
- if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt$2(str, re.lastIndex - 1) !== '\n')) {
3221
- source = '(?: ' + source + ')';
3222
- strCopy = ' ' + strCopy;
3223
- charsAdded++;
3224
- }
3225
- // ^(? + rx + ) is needed, in combination with some str slicing, to
3226
- // simulate the 'y' flag.
3227
- reCopy = new RegExp('^(?:' + source + ')', flags);
3228
- }
3229
-
3230
- if (NPCG_INCLUDED) {
3231
- reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
3232
- }
3233
- if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
3164
+ /******************************************************************************
3165
+ Copyright (c) Microsoft Corporation.
3166
+
3167
+ Permission to use, copy, modify, and/or distribute this software for any
3168
+ purpose with or without fee is hereby granted.
3169
+
3170
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
3171
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
3172
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
3173
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
3174
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
3175
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3176
+ PERFORMANCE OF THIS SOFTWARE.
3177
+ ***************************************************************************** */
3178
+
3179
+ function __rest(s, e) {
3180
+ var t = {};
3181
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
3182
+ t[p] = s[p];
3183
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
3184
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
3185
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
3186
+ t[p[i]] = s[p[i]];
3187
+ }
3188
+ return t;
3189
+ }
3190
+
3191
+ function __awaiter(thisArg, _arguments, P, generator) {
3192
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3193
+ return new (P || (P = Promise))(function (resolve, reject) {
3194
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
3195
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
3196
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
3197
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
3198
+ });
3199
+ }
3200
+
3201
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
3202
+ var e = new Error(message);
3203
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
3204
+ };
3234
3205
 
3235
- match = call$3(nativeExec, sticky ? reCopy : re, strCopy);
3206
+ const LayerInfoButton = _a => {
3207
+ var {
3208
+ isOpenInStore,
3209
+ isActive,
3210
+ onClick
3211
+ } = _a,
3212
+ props = __rest(_a, ["isOpenInStore", "isActive", "onClick"]);
3213
+ return jsx(CustomIconButton, Object.assign({
3214
+ variant: "flat",
3215
+ isSelected: isActive && isOpenInStore,
3216
+ onClick: onClick,
3217
+ id: "layerInfoButton",
3218
+ "data-testid": "layerInfoButton",
3219
+ "aria-label": "layer info",
3220
+ className: "layerInfoButton"
3221
+ }, props, {
3222
+ children: jsx(Info, {})
3223
+ }));
3224
+ };
3236
3225
 
3237
- if (sticky) {
3238
- if (match) {
3239
- match.input = stringSlice$2(match.input, charsAdded);
3240
- match[0] = stringSlice$2(match[0], charsAdded);
3241
- match.index = re.lastIndex;
3242
- re.lastIndex += match[0].length;
3243
- } else re.lastIndex = 0;
3244
- } else if (UPDATES_LAST_INDEX_WRONG && match) {
3245
- re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
3226
+ const LayerInfoButtonConnect = ({
3227
+ isLayerMissing,
3228
+ layer,
3229
+ mapId,
3230
+ serviceName,
3231
+ source: _source = 'app'
3232
+ }) => {
3233
+ const dispatch = useDispatch();
3234
+ const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, uiTypes.DialogTypes.LayerInfo));
3235
+ const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, uiTypes.DialogTypes.LayerInfo));
3236
+ const currentLayerInfo = useAppSelector(store => getActiveLayerInfo(store));
3237
+ const isActive = layer.name === (currentLayerInfo === null || currentLayerInfo === void 0 ? void 0 : currentLayerInfo.name) && serviceName === (currentLayerInfo === null || currentLayerInfo === void 0 ? void 0 : currentLayerInfo.serviceName);
3238
+ const toggleInfoDialog = React__default.useCallback(() => {
3239
+ dispatch(uiActions.setActiveMapIdForDialog({
3240
+ type: uiTypes.DialogTypes.LayerInfo,
3241
+ mapId,
3242
+ setOpen: currentActiveMapId !== mapId ? true : !isOpenInStore,
3243
+ source: _source
3244
+ }));
3245
+ }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source]);
3246
+ const setActiveLayerInfo = React__default.useCallback(() => {
3247
+ dispatch(layerSelectActions.setActiveLayerInfo({
3248
+ layer: Object.assign(Object.assign({}, layer), {
3249
+ serviceName
3250
+ })
3251
+ }));
3252
+ dispatch(uiActions.orderDialog({
3253
+ type: uiTypes.DialogTypes.LayerInfo
3254
+ }));
3255
+ }, [dispatch, layer, serviceName]);
3256
+ const onClick = () => {
3257
+ if (isActive) {
3258
+ toggleInfoDialog();
3246
3259
  }
3247
- if (NPCG_INCLUDED && match && match.length > 1) {
3248
- // Fix browsers whose `exec` methods don't consistently return `undefined`
3249
- // for NPCG, like IE8. NOTE: This doesn't work for /(.?)?/
3250
- call$3(nativeReplace, match[0], reCopy, function () {
3251
- for (i = 1; i < arguments.length - 2; i++) {
3252
- if (arguments[i] === undefined) match[i] = undefined;
3253
- }
3254
- });
3260
+ if (!isActive && isOpenInStore) {
3261
+ setActiveLayerInfo();
3255
3262
  }
3256
-
3257
- if (match && groups) {
3258
- match.groups = object = create(null);
3259
- for (i = 0; i < groups.length; i++) {
3260
- group = groups[i];
3261
- object[group[0]] = match[group[1]];
3262
- }
3263
+ if (!isActive && !isOpenInStore) {
3264
+ setActiveLayerInfo();
3265
+ toggleInfoDialog();
3263
3266
  }
3264
-
3265
- return match;
3266
3267
  };
3267
- }
3268
-
3269
- var regexpExec$3 = patchedExec;
3270
-
3271
- var $$1 = _export;
3272
- var exec$1 = regexpExec$3;
3273
-
3274
- // `RegExp.prototype.exec` method
3275
- // https://tc39.es/ecma262/#sec-regexp.prototype.exec
3276
- $$1({ target: 'RegExp', proto: true, forced: /./.exec !== exec$1 }, {
3277
- exec: exec$1
3278
- });
3279
-
3280
- var NATIVE_BIND = functionBindNative;
3281
-
3282
- var FunctionPrototype = Function.prototype;
3283
- var apply$1 = FunctionPrototype.apply;
3284
- var call$2 = FunctionPrototype.call;
3268
+ return jsx(LayerInfoButton, {
3269
+ disabled: isLayerMissing,
3270
+ isActive: isActive,
3271
+ isOpenInStore: isOpenInStore,
3272
+ onClick: onClick
3273
+ });
3274
+ };
3285
3275
 
3286
- // eslint-disable-next-line es/no-reflect -- safe
3287
- var functionApply = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call$2.bind(apply$1) : function () {
3288
- return call$2.apply(apply$1, arguments);
3276
+ const textStyle = {
3277
+ lineHeight: '20px',
3278
+ letterSpacing: '0.25px'
3279
+ };
3280
+ const textStyleWithMargin = Object.assign(Object.assign({}, textStyle), {
3281
+ marginBottom: 1
3289
3282
  });
3283
+ const LayerInfoText = ({
3284
+ label,
3285
+ value
3286
+ }) => {
3287
+ return jsxs(Fragment, {
3288
+ children: [jsx(Typography$1, Object.assign({
3289
+ variant: "subtitle2",
3290
+ sx: textStyle
3291
+ }, {
3292
+ children: label
3293
+ })), jsx(Typography$1, Object.assign({
3294
+ variant: "body2",
3295
+ sx: textStyleWithMargin
3296
+ }, {
3297
+ children: value
3298
+ }))]
3299
+ });
3300
+ };
3290
3301
 
3291
- // TODO: Remove from `core-js@4` since it's moved to entry points
3292
-
3293
- var uncurryThis$3 = functionUncurryThisClause;
3294
- var defineBuiltIn = defineBuiltIn$4;
3295
- var regexpExec$2 = regexpExec$3;
3296
- var fails$1 = fails$k;
3297
- var wellKnownSymbol$1 = wellKnownSymbol$d;
3298
- var createNonEnumerableProperty = createNonEnumerableProperty$5;
3299
-
3300
- var SPECIES$1 = wellKnownSymbol$1('species');
3301
- var RegExpPrototype = RegExp.prototype;
3302
-
3303
- var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) {
3304
- var SYMBOL = wellKnownSymbol$1(KEY);
3302
+ const valueStyle = Object.assign(Object.assign({}, textStyle), {
3303
+ overflowWrap: 'break-word'
3304
+ });
3305
+ const LayerInfoList = ({
3306
+ label,
3307
+ list
3308
+ }) => {
3309
+ return jsxs(Fragment, {
3310
+ children: [jsx(Typography$1, Object.assign({
3311
+ variant: "subtitle2",
3312
+ sx: textStyle
3313
+ }, {
3314
+ children: label
3315
+ })), list.length === 0 ? jsx(Typography$1, Object.assign({
3316
+ variant: "body2",
3317
+ sx: textStyleWithMargin
3318
+ }, {
3319
+ children: "-"
3320
+ })) : jsx(Grid$1, Object.assign({
3321
+ container: true,
3322
+ direction: "column"
3323
+ }, {
3324
+ children: list.map(item => jsxs("div", {
3325
+ children: [jsxs(Grid$1, Object.assign({
3326
+ item: true,
3327
+ container: true,
3328
+ direction: "row"
3329
+ }, {
3330
+ children: [item.icon, jsx(Grid$1, Object.assign({
3331
+ item: true,
3332
+ sx: {
3333
+ marginLeft: '10px'
3334
+ }
3335
+ }, {
3336
+ children: jsxs(Typography$1, Object.assign({
3337
+ variant: "body2",
3338
+ sx: textStyle
3339
+ }, {
3340
+ children: [item.label, ":"]
3341
+ }))
3342
+ }))]
3343
+ })), jsx(Grid$1, Object.assign({
3344
+ item: true,
3345
+ container: true,
3346
+ direction: "row",
3347
+ sx: {
3348
+ marginBottom: 1,
3349
+ paddingLeft: '34px'
3350
+ }
3351
+ }, {
3352
+ children: jsx(Typography$1, Object.assign({
3353
+ variant: "body2",
3354
+ sx: valueStyle
3355
+ }, {
3356
+ children: item.value
3357
+ }))
3358
+ }))]
3359
+ }, item.label))
3360
+ }))]
3361
+ });
3362
+ };
3305
3363
 
3306
- var DELEGATES_TO_SYMBOL = !fails$1(function () {
3307
- // String methods call symbol-named RegEp methods
3308
- var O = {};
3309
- O[SYMBOL] = function () { return 7; };
3310
- return ''[KEY](O) !== 7;
3364
+ const LayerInfoLegend = ({
3365
+ title,
3366
+ name,
3367
+ dimensions,
3368
+ legendURL
3369
+ }) => {
3370
+ return jsxs(Fragment, {
3371
+ children: [jsx(Typography$1, Object.assign({
3372
+ variant: "subtitle2",
3373
+ sx: textStyleWithMargin
3374
+ }, {
3375
+ children: "Legend"
3376
+ })), jsx(LegendLayout, Object.assign({
3377
+ title: title,
3378
+ name: name,
3379
+ dimensions: dimensions
3380
+ }, {
3381
+ children: legendURL ? jsx("img", {
3382
+ alt: title,
3383
+ src: legendURL
3384
+ }) : '-'
3385
+ }))]
3311
3386
  });
3387
+ };
3312
3388
 
3313
- var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$1(function () {
3314
- // Symbol-named RegExp methods call .exec
3315
- var execCalled = false;
3316
- var re = /a/;
3389
+ var anObject$3 = anObject$9;
3317
3390
 
3318
- if (KEY === 'split') {
3319
- // We can't use real regex here since it causes deoptimization
3320
- // and serious performance degradation in V8
3321
- // https://github.com/zloirock/core-js/issues/306
3322
- re = {};
3323
- // RegExp[@@split] doesn't call the regex's exec method, but first creates
3324
- // a new one. We need to return the patched regex when creating the new one.
3325
- re.constructor = {};
3326
- re.constructor[SPECIES$1] = function () { return re; };
3327
- re.flags = '';
3328
- re[SYMBOL] = /./[SYMBOL];
3329
- }
3391
+ // `RegExp.prototype.flags` getter implementation
3392
+ // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
3393
+ var regexpFlags$1 = function () {
3394
+ var that = anObject$3(this);
3395
+ var result = '';
3396
+ if (that.hasIndices) result += 'd';
3397
+ if (that.global) result += 'g';
3398
+ if (that.ignoreCase) result += 'i';
3399
+ if (that.multiline) result += 'm';
3400
+ if (that.dotAll) result += 's';
3401
+ if (that.unicode) result += 'u';
3402
+ if (that.unicodeSets) result += 'v';
3403
+ if (that.sticky) result += 'y';
3404
+ return result;
3405
+ };
3330
3406
 
3331
- re.exec = function () {
3332
- execCalled = true;
3333
- return null;
3334
- };
3407
+ var fails$4 = fails$k;
3408
+ var global$3 = global$g;
3335
3409
 
3336
- re[SYMBOL]('');
3337
- return !execCalled;
3338
- });
3410
+ // babel-minify and Closure Compiler transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
3411
+ var $RegExp$2 = global$3.RegExp;
3339
3412
 
3340
- if (
3341
- !DELEGATES_TO_SYMBOL ||
3342
- !DELEGATES_TO_EXEC ||
3343
- FORCED
3344
- ) {
3345
- var uncurriedNativeRegExpMethod = uncurryThis$3(/./[SYMBOL]);
3346
- var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
3347
- var uncurriedNativeMethod = uncurryThis$3(nativeMethod);
3348
- var $exec = regexp.exec;
3349
- if ($exec === regexpExec$2 || $exec === RegExpPrototype.exec) {
3350
- if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
3351
- // The native String method already delegates to @@method (this
3352
- // polyfilled function), leasing to infinite recursion.
3353
- // We avoid it by directly calling the native @@method method.
3354
- return { done: true, value: uncurriedNativeRegExpMethod(regexp, str, arg2) };
3355
- }
3356
- return { done: true, value: uncurriedNativeMethod(str, regexp, arg2) };
3357
- }
3358
- return { done: false };
3359
- });
3413
+ var UNSUPPORTED_Y$2 = fails$4(function () {
3414
+ var re = $RegExp$2('a', 'y');
3415
+ re.lastIndex = 2;
3416
+ return re.exec('abcd') !== null;
3417
+ });
3360
3418
 
3361
- defineBuiltIn(String.prototype, KEY, methods[0]);
3362
- defineBuiltIn(RegExpPrototype, SYMBOL, methods[1]);
3363
- }
3419
+ // UC Browser bug
3420
+ // https://github.com/zloirock/core-js/issues/1008
3421
+ var MISSED_STICKY = UNSUPPORTED_Y$2 || fails$4(function () {
3422
+ return !$RegExp$2('a', 'y').sticky;
3423
+ });
3364
3424
 
3365
- if (SHAM) createNonEnumerableProperty(RegExpPrototype[SYMBOL], 'sham', true);
3366
- };
3425
+ var BROKEN_CARET = UNSUPPORTED_Y$2 || fails$4(function () {
3426
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
3427
+ var re = $RegExp$2('^r', 'gy');
3428
+ re.lastIndex = 2;
3429
+ return re.exec('str') !== null;
3430
+ });
3367
3431
 
3368
- var isConstructor = isConstructor$2;
3369
- var tryToString = tryToString$3;
3432
+ var regexpStickyHelpers = {
3433
+ BROKEN_CARET: BROKEN_CARET,
3434
+ MISSED_STICKY: MISSED_STICKY,
3435
+ UNSUPPORTED_Y: UNSUPPORTED_Y$2
3436
+ };
3370
3437
 
3371
- var $TypeError$1 = TypeError;
3438
+ var fails$3 = fails$k;
3439
+ var global$2 = global$g;
3372
3440
 
3373
- // `Assert: IsConstructor(argument) is true`
3374
- var aConstructor$1 = function (argument) {
3375
- if (isConstructor(argument)) return argument;
3376
- throw new $TypeError$1(tryToString(argument) + ' is not a constructor');
3377
- };
3441
+ // babel-minify and Closure Compiler transpiles RegExp('.', 's') -> /./s and it causes SyntaxError
3442
+ var $RegExp$1 = global$2.RegExp;
3378
3443
 
3379
- var anObject$2 = anObject$9;
3380
- var aConstructor = aConstructor$1;
3381
- var isNullOrUndefined$1 = isNullOrUndefined$4;
3382
- var wellKnownSymbol = wellKnownSymbol$d;
3444
+ var regexpUnsupportedDotAll = fails$3(function () {
3445
+ var re = $RegExp$1('.', 's');
3446
+ return !(re.dotAll && re.test('\n') && re.flags === 's');
3447
+ });
3383
3448
 
3384
- var SPECIES = wellKnownSymbol('species');
3449
+ var fails$2 = fails$k;
3450
+ var global$1 = global$g;
3385
3451
 
3386
- // `SpeciesConstructor` abstract operation
3387
- // https://tc39.es/ecma262/#sec-speciesconstructor
3388
- var speciesConstructor$1 = function (O, defaultConstructor) {
3389
- var C = anObject$2(O).constructor;
3390
- var S;
3391
- return C === undefined || isNullOrUndefined$1(S = anObject$2(C)[SPECIES]) ? defaultConstructor : aConstructor(S);
3392
- };
3452
+ // babel-minify and Closure Compiler transpiles RegExp('(?<a>b)', 'g') -> /(?<a>b)/g and it causes SyntaxError
3453
+ var $RegExp = global$1.RegExp;
3393
3454
 
3394
- var uncurryThis$2 = functionUncurryThis;
3395
- var toIntegerOrInfinity = toIntegerOrInfinity$3;
3396
- var toString$1 = toString$5;
3397
- var requireObjectCoercible$1 = requireObjectCoercible$5;
3455
+ var regexpUnsupportedNcg = fails$2(function () {
3456
+ var re = $RegExp('(?<a>b)', 'g');
3457
+ return re.exec('b').groups.a !== 'b' ||
3458
+ 'b'.replace(re, '$<a>c') !== 'bc';
3459
+ });
3398
3460
 
3399
- var charAt$1 = uncurryThis$2(''.charAt);
3400
- var charCodeAt = uncurryThis$2(''.charCodeAt);
3401
- var stringSlice$1 = uncurryThis$2(''.slice);
3461
+ /* eslint-disable regexp/no-empty-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */
3462
+ /* eslint-disable regexp/no-useless-quantifier -- testing */
3463
+ var call$3 = functionCall;
3464
+ var uncurryThis$4 = functionUncurryThis;
3465
+ var toString$2 = toString$5;
3466
+ var regexpFlags = regexpFlags$1;
3467
+ var stickyHelpers$1 = regexpStickyHelpers;
3468
+ var shared = shared$4.exports;
3469
+ var create = objectCreate;
3470
+ var getInternalState = internalState.get;
3471
+ var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll;
3472
+ var UNSUPPORTED_NCG = regexpUnsupportedNcg;
3402
3473
 
3403
- var createMethod = function (CONVERT_TO_STRING) {
3404
- return function ($this, pos) {
3474
+ var nativeReplace = shared('native-string-replace', String.prototype.replace);
3475
+ var nativeExec = RegExp.prototype.exec;
3476
+ var patchedExec = nativeExec;
3477
+ var charAt$2 = uncurryThis$4(''.charAt);
3478
+ var indexOf = uncurryThis$4(''.indexOf);
3479
+ var replace = uncurryThis$4(''.replace);
3480
+ var stringSlice$2 = uncurryThis$4(''.slice);
3481
+
3482
+ var UPDATES_LAST_INDEX_WRONG = (function () {
3483
+ var re1 = /a/;
3484
+ var re2 = /b*/g;
3485
+ call$3(nativeExec, re1, 'a');
3486
+ call$3(nativeExec, re2, 'a');
3487
+ return re1.lastIndex !== 0 || re2.lastIndex !== 0;
3488
+ })();
3489
+
3490
+ var UNSUPPORTED_Y$1 = stickyHelpers$1.BROKEN_CARET;
3491
+
3492
+ // nonparticipating capturing group, copied from es5-shim's String#split patch.
3493
+ var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
3494
+
3495
+ var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$1 || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG;
3496
+
3497
+ if (PATCH) {
3498
+ patchedExec = function exec(string) {
3499
+ var re = this;
3500
+ var state = getInternalState(re);
3501
+ var str = toString$2(string);
3502
+ var raw = state.raw;
3503
+ var result, reCopy, lastIndex, match, i, object, group;
3504
+
3505
+ if (raw) {
3506
+ raw.lastIndex = re.lastIndex;
3507
+ result = call$3(patchedExec, raw, str);
3508
+ re.lastIndex = raw.lastIndex;
3509
+ return result;
3510
+ }
3511
+
3512
+ var groups = state.groups;
3513
+ var sticky = UNSUPPORTED_Y$1 && re.sticky;
3514
+ var flags = call$3(regexpFlags, re);
3515
+ var source = re.source;
3516
+ var charsAdded = 0;
3517
+ var strCopy = str;
3518
+
3519
+ if (sticky) {
3520
+ flags = replace(flags, 'y', '');
3521
+ if (indexOf(flags, 'g') === -1) {
3522
+ flags += 'g';
3523
+ }
3524
+
3525
+ strCopy = stringSlice$2(str, re.lastIndex);
3526
+ // Support anchored sticky behavior.
3527
+ if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt$2(str, re.lastIndex - 1) !== '\n')) {
3528
+ source = '(?: ' + source + ')';
3529
+ strCopy = ' ' + strCopy;
3530
+ charsAdded++;
3531
+ }
3532
+ // ^(? + rx + ) is needed, in combination with some str slicing, to
3533
+ // simulate the 'y' flag.
3534
+ reCopy = new RegExp('^(?:' + source + ')', flags);
3535
+ }
3536
+
3537
+ if (NPCG_INCLUDED) {
3538
+ reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
3539
+ }
3540
+ if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
3541
+
3542
+ match = call$3(nativeExec, sticky ? reCopy : re, strCopy);
3543
+
3544
+ if (sticky) {
3545
+ if (match) {
3546
+ match.input = stringSlice$2(match.input, charsAdded);
3547
+ match[0] = stringSlice$2(match[0], charsAdded);
3548
+ match.index = re.lastIndex;
3549
+ re.lastIndex += match[0].length;
3550
+ } else re.lastIndex = 0;
3551
+ } else if (UPDATES_LAST_INDEX_WRONG && match) {
3552
+ re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
3553
+ }
3554
+ if (NPCG_INCLUDED && match && match.length > 1) {
3555
+ // Fix browsers whose `exec` methods don't consistently return `undefined`
3556
+ // for NPCG, like IE8. NOTE: This doesn't work for /(.?)?/
3557
+ call$3(nativeReplace, match[0], reCopy, function () {
3558
+ for (i = 1; i < arguments.length - 2; i++) {
3559
+ if (arguments[i] === undefined) match[i] = undefined;
3560
+ }
3561
+ });
3562
+ }
3563
+
3564
+ if (match && groups) {
3565
+ match.groups = object = create(null);
3566
+ for (i = 0; i < groups.length; i++) {
3567
+ group = groups[i];
3568
+ object[group[0]] = match[group[1]];
3569
+ }
3570
+ }
3571
+
3572
+ return match;
3573
+ };
3574
+ }
3575
+
3576
+ var regexpExec$3 = patchedExec;
3577
+
3578
+ var $$1 = _export;
3579
+ var exec$1 = regexpExec$3;
3580
+
3581
+ // `RegExp.prototype.exec` method
3582
+ // https://tc39.es/ecma262/#sec-regexp.prototype.exec
3583
+ $$1({ target: 'RegExp', proto: true, forced: /./.exec !== exec$1 }, {
3584
+ exec: exec$1
3585
+ });
3586
+
3587
+ var NATIVE_BIND = functionBindNative;
3588
+
3589
+ var FunctionPrototype = Function.prototype;
3590
+ var apply$1 = FunctionPrototype.apply;
3591
+ var call$2 = FunctionPrototype.call;
3592
+
3593
+ // eslint-disable-next-line es/no-reflect -- safe
3594
+ var functionApply = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call$2.bind(apply$1) : function () {
3595
+ return call$2.apply(apply$1, arguments);
3596
+ });
3597
+
3598
+ // TODO: Remove from `core-js@4` since it's moved to entry points
3599
+
3600
+ var uncurryThis$3 = functionUncurryThisClause;
3601
+ var defineBuiltIn = defineBuiltIn$4;
3602
+ var regexpExec$2 = regexpExec$3;
3603
+ var fails$1 = fails$k;
3604
+ var wellKnownSymbol$1 = wellKnownSymbol$d;
3605
+ var createNonEnumerableProperty = createNonEnumerableProperty$5;
3606
+
3607
+ var SPECIES$1 = wellKnownSymbol$1('species');
3608
+ var RegExpPrototype = RegExp.prototype;
3609
+
3610
+ var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) {
3611
+ var SYMBOL = wellKnownSymbol$1(KEY);
3612
+
3613
+ var DELEGATES_TO_SYMBOL = !fails$1(function () {
3614
+ // String methods call symbol-named RegEp methods
3615
+ var O = {};
3616
+ O[SYMBOL] = function () { return 7; };
3617
+ return ''[KEY](O) !== 7;
3618
+ });
3619
+
3620
+ var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$1(function () {
3621
+ // Symbol-named RegExp methods call .exec
3622
+ var execCalled = false;
3623
+ var re = /a/;
3624
+
3625
+ if (KEY === 'split') {
3626
+ // We can't use real regex here since it causes deoptimization
3627
+ // and serious performance degradation in V8
3628
+ // https://github.com/zloirock/core-js/issues/306
3629
+ re = {};
3630
+ // RegExp[@@split] doesn't call the regex's exec method, but first creates
3631
+ // a new one. We need to return the patched regex when creating the new one.
3632
+ re.constructor = {};
3633
+ re.constructor[SPECIES$1] = function () { return re; };
3634
+ re.flags = '';
3635
+ re[SYMBOL] = /./[SYMBOL];
3636
+ }
3637
+
3638
+ re.exec = function () {
3639
+ execCalled = true;
3640
+ return null;
3641
+ };
3642
+
3643
+ re[SYMBOL]('');
3644
+ return !execCalled;
3645
+ });
3646
+
3647
+ if (
3648
+ !DELEGATES_TO_SYMBOL ||
3649
+ !DELEGATES_TO_EXEC ||
3650
+ FORCED
3651
+ ) {
3652
+ var uncurriedNativeRegExpMethod = uncurryThis$3(/./[SYMBOL]);
3653
+ var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
3654
+ var uncurriedNativeMethod = uncurryThis$3(nativeMethod);
3655
+ var $exec = regexp.exec;
3656
+ if ($exec === regexpExec$2 || $exec === RegExpPrototype.exec) {
3657
+ if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
3658
+ // The native String method already delegates to @@method (this
3659
+ // polyfilled function), leasing to infinite recursion.
3660
+ // We avoid it by directly calling the native @@method method.
3661
+ return { done: true, value: uncurriedNativeRegExpMethod(regexp, str, arg2) };
3662
+ }
3663
+ return { done: true, value: uncurriedNativeMethod(str, regexp, arg2) };
3664
+ }
3665
+ return { done: false };
3666
+ });
3667
+
3668
+ defineBuiltIn(String.prototype, KEY, methods[0]);
3669
+ defineBuiltIn(RegExpPrototype, SYMBOL, methods[1]);
3670
+ }
3671
+
3672
+ if (SHAM) createNonEnumerableProperty(RegExpPrototype[SYMBOL], 'sham', true);
3673
+ };
3674
+
3675
+ var isConstructor = isConstructor$2;
3676
+ var tryToString = tryToString$3;
3677
+
3678
+ var $TypeError$1 = TypeError;
3679
+
3680
+ // `Assert: IsConstructor(argument) is true`
3681
+ var aConstructor$1 = function (argument) {
3682
+ if (isConstructor(argument)) return argument;
3683
+ throw new $TypeError$1(tryToString(argument) + ' is not a constructor');
3684
+ };
3685
+
3686
+ var anObject$2 = anObject$9;
3687
+ var aConstructor = aConstructor$1;
3688
+ var isNullOrUndefined$1 = isNullOrUndefined$4;
3689
+ var wellKnownSymbol = wellKnownSymbol$d;
3690
+
3691
+ var SPECIES = wellKnownSymbol('species');
3692
+
3693
+ // `SpeciesConstructor` abstract operation
3694
+ // https://tc39.es/ecma262/#sec-speciesconstructor
3695
+ var speciesConstructor$1 = function (O, defaultConstructor) {
3696
+ var C = anObject$2(O).constructor;
3697
+ var S;
3698
+ return C === undefined || isNullOrUndefined$1(S = anObject$2(C)[SPECIES]) ? defaultConstructor : aConstructor(S);
3699
+ };
3700
+
3701
+ var uncurryThis$2 = functionUncurryThis;
3702
+ var toIntegerOrInfinity = toIntegerOrInfinity$3;
3703
+ var toString$1 = toString$5;
3704
+ var requireObjectCoercible$1 = requireObjectCoercible$5;
3705
+
3706
+ var charAt$1 = uncurryThis$2(''.charAt);
3707
+ var charCodeAt = uncurryThis$2(''.charCodeAt);
3708
+ var stringSlice$1 = uncurryThis$2(''.slice);
3709
+
3710
+ var createMethod = function (CONVERT_TO_STRING) {
3711
+ return function ($this, pos) {
3405
3712
  var S = toString$1(requireObjectCoercible$1($this));
3406
3713
  var position = toIntegerOrInfinity(pos);
3407
3714
  var size = S.length;
@@ -3778,93 +4085,6 @@ const LayerInfoDialog = ({
3778
4085
  }));
3779
4086
  };
3780
4087
 
3781
- const style$2 = {
3782
- width: 'auto !important',
3783
- height: 'auto !important',
3784
- padding: 0
3785
- };
3786
- const LayerSelectButtonConnect = ({
3787
- mapId,
3788
- source: _source = 'app',
3789
- tooltipTitle: _tooltipTitle = 'Open the layer selector',
3790
- icon: _icon = jsx(LayersAdd, {
3791
- "data-testid": "layerSelectButtonConnectIcon"
3792
- }),
3793
- isMultiMap: _isMultiMap = false
3794
- }) => {
3795
- const dispatch = useDispatch();
3796
- const dialogType = _isMultiMap ? `${uiTypes.DialogTypes.LayerSelect}-${mapId}` : uiTypes.DialogTypes.LayerSelect;
3797
- const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, dialogType));
3798
- const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, dialogType));
3799
- const openLayerSelectDialog = React.useCallback(() => {
3800
- dispatch(uiActions.setActiveMapIdForDialog({
3801
- type: dialogType,
3802
- mapId,
3803
- setOpen: currentActiveMapId !== mapId ? true : !isOpenInStore,
3804
- source: _source
3805
- }));
3806
- }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source, dialogType]);
3807
- return jsx(CustomIconButton, Object.assign({
3808
- onClick: openLayerSelectDialog,
3809
- sx: style$2,
3810
- id: "layerSelectButton",
3811
- "data-testid": "layerSelectButton",
3812
- tooltipTitle: _tooltipTitle
3813
- }, {
3814
- children: _icon
3815
- }));
3816
- };
3817
-
3818
- const KeywordFilterButtonConnect = ({
3819
- mapId,
3820
- source: _source = 'app',
3821
- isMultiMap
3822
- }) => {
3823
- const dispatch = useDispatch();
3824
- const dialogType = isMultiMap ? `${uiTypes.DialogTypes.KeywordFilter}-${mapId}` : uiTypes.DialogTypes.KeywordFilter;
3825
- const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, dialogType));
3826
- const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, dialogType));
3827
- const openFilterResultsDialog = React.useCallback(() => {
3828
- dispatch(uiActions.setActiveMapIdForDialog({
3829
- type: dialogType,
3830
- mapId,
3831
- setOpen: currentActiveMapId !== mapId ? true : !isOpenInStore,
3832
- source: _source
3833
- }));
3834
- }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source, dialogType]);
3835
- return jsx(CustomIconButton, Object.assign({
3836
- variant: "tool",
3837
- onClick: openFilterResultsDialog,
3838
- isSelected: isOpenInStore,
3839
- id: "keywordFilterButton",
3840
- "data-testid": "keywordFilterButton"
3841
- }, {
3842
- children: jsx(Filter, {})
3843
- }));
3844
- };
3845
-
3846
- const SearchFieldConnect = () => {
3847
- const dispatch = useDispatch();
3848
- const searchFilter = useAppSelector(store => getSearchFilter(store));
3849
- const toggleServicePopup = url => {
3850
- dispatch(layerSelectActions.toggleServicePopup({
3851
- isOpen: true,
3852
- url,
3853
- variant: 'save'
3854
- }));
3855
- };
3856
- const setSearchFilter = filterText => {
3857
- dispatch(layerSelectActions.setSearchFilter({
3858
- filterText
3859
- }));
3860
- };
3861
- return jsx(SearchField, {
3862
- setSearchFilter: setSearchFilter,
3863
- searchFilter: searchFilter,
3864
- onOpenServicePopup: toggleServicePopup
3865
- });
3866
- };
3867
-
3868
4088
  const LayerAddRemoveButton = ({
3869
4089
  layer,
3870
4090
  layerIndex,
@@ -4049,7 +4269,7 @@ const LayerListRow = ({
4049
4269
  const rowHeight = widthToRowHeight(layerSelectWidth);
4050
4270
  const columns = widthToColumns(layerSelectWidth);
4051
4271
  const dimensions = getDimensionsList(layer.dimensions);
4052
- return jsxs(Grid$1, Object.assign({
4272
+ return jsxs(Grid, Object.assign({
4053
4273
  "data-testid": "layerListLayerRow",
4054
4274
  container: true,
4055
4275
  justifyContent: "center",
@@ -4063,12 +4283,12 @@ const LayerListRow = ({
4063
4283
  borderColor: 'geowebColors.cards.cardContainerBorder'
4064
4284
  }
4065
4285
  }, {
4066
- children: [jsxs(Grid$1, Object.assign({
4286
+ children: [jsxs(Grid, Object.assign({
4067
4287
  container: true,
4068
4288
  item: true,
4069
4289
  sx: columns.column8
4070
4290
  }, {
4071
- children: [jsx(Grid$1, Object.assign({
4291
+ children: [jsx(Grid, Object.assign({
4072
4292
  item: true,
4073
4293
  xs: 12
4074
4294
  }, {
@@ -4087,7 +4307,7 @@ const LayerListRow = ({
4087
4307
  search: searchFilter
4088
4308
  })
4089
4309
  }))
4090
- })), jsxs(Grid$1, Object.assign({
4310
+ })), jsxs(Grid, Object.assign({
4091
4311
  item: true,
4092
4312
  container: true,
4093
4313
  direction: "column",
@@ -4111,15 +4331,15 @@ const LayerListRow = ({
4111
4331
  mapId: mapId,
4112
4332
  serviceName: service.name
4113
4333
  })]
4114
- })), jsxs(Grid$1, Object.assign({
4334
+ })), jsxs(Grid, Object.assign({
4115
4335
  item: true,
4116
4336
  sx: columns.column2
4117
4337
  }, {
4118
- children: [jsx(Grid$1, Object.assign({
4338
+ children: [jsx(Grid, Object.assign({
4119
4339
  item: true,
4120
4340
  sx: columns.column3
4121
4341
  }, {
4122
- children: layer.abstract && jsx(Typography$1, Object.assign({
4342
+ children: layer.abstract && jsx(Typography, Object.assign({
4123
4343
  "data-testid": "layerAbstract",
4124
4344
  sx: layerInfoStyle
4125
4345
  }, {
@@ -4128,30 +4348,30 @@ const LayerListRow = ({
4128
4348
  search: searchFilter
4129
4349
  })
4130
4350
  }))
4131
- })), jsxs(Grid$1, Object.assign({
4351
+ })), jsxs(Grid, Object.assign({
4132
4352
  item: true,
4133
4353
  container: true,
4134
4354
  sx: columns.column4
4135
4355
  }, {
4136
- children: [jsx(Grid$1, Object.assign({
4356
+ children: [jsx(Grid, Object.assign({
4137
4357
  item: true,
4138
4358
  sx: columns.column5
4139
4359
  }, {
4140
4360
  children: jsx(LayerListDimensions, {
4141
4361
  dimensions: dimensions
4142
4362
  })
4143
- })), jsxs(Grid$1, Object.assign({
4363
+ })), jsxs(Grid, Object.assign({
4144
4364
  item: true,
4145
4365
  sx: columns.column6
4146
4366
  }, {
4147
- children: [layer.path.length > 0 && jsxs(Typography$1, Object.assign({
4367
+ children: [layer.path.length > 0 && jsxs(Typography, Object.assign({
4148
4368
  sx: layerInfoStyle
4149
4369
  }, {
4150
4370
  children: ["Groups:", ' ', jsx(SearchHighlight, {
4151
4371
  text: layer.path.join(' / '),
4152
4372
  search: searchFilter
4153
4373
  })]
4154
- })), ((_a = layer.keywords) === null || _a === void 0 ? void 0 : _a.length) > 0 && jsxs(Typography$1, Object.assign({
4374
+ })), ((_a = layer.keywords) === null || _a === void 0 ? void 0 : _a.length) > 0 && jsxs(Typography, Object.assign({
4155
4375
  sx: layerInfoStyle
4156
4376
  }, {
4157
4377
  children: ["Keywords:", ' ', jsx(SearchHighlight, {
@@ -4164,7 +4384,7 @@ const LayerListRow = ({
4164
4384
  }))]
4165
4385
  }))]
4166
4386
  }))]
4167
- })), jsx(Grid$1, Object.assign({
4387
+ })), jsx(Grid, Object.assign({
4168
4388
  container: true,
4169
4389
  item: true,
4170
4390
  sx: columns.column9,
@@ -4305,6 +4525,65 @@ const LayerListConnect = ({
4305
4525
  });
4306
4526
  };
4307
4527
 
4528
+ const style$2 = {
4529
+ width: 'auto !important',
4530
+ height: 'auto !important',
4531
+ padding: 0
4532
+ };
4533
+ const LayerSelectButtonConnect = ({
4534
+ mapId,
4535
+ source: _source = 'app',
4536
+ tooltipTitle: _tooltipTitle = 'Open the layer selector',
4537
+ icon: _icon = jsx(LayersAdd, {
4538
+ "data-testid": "layerSelectButtonConnectIcon"
4539
+ }),
4540
+ isMultiMap: _isMultiMap = false
4541
+ }) => {
4542
+ const dispatch = useDispatch();
4543
+ const dialogType = _isMultiMap ? `${uiTypes.DialogTypes.LayerSelect}-${mapId}` : uiTypes.DialogTypes.LayerSelect;
4544
+ const currentActiveMapId = useAppSelector(store => uiSelectors.getDialogMapId(store, dialogType));
4545
+ const isOpenInStore = useAppSelector(store => uiSelectors.getisDialogOpen(store, dialogType));
4546
+ const openLayerSelectDialog = React.useCallback(() => {
4547
+ dispatch(uiActions.setActiveMapIdForDialog({
4548
+ type: dialogType,
4549
+ mapId,
4550
+ setOpen: currentActiveMapId !== mapId ? true : !isOpenInStore,
4551
+ source: _source
4552
+ }));
4553
+ }, [currentActiveMapId, dispatch, isOpenInStore, mapId, _source, dialogType]);
4554
+ return jsx(CustomIconButton, Object.assign({
4555
+ onClick: openLayerSelectDialog,
4556
+ sx: style$2,
4557
+ id: "layerSelectButton",
4558
+ "data-testid": "layerSelectButton",
4559
+ tooltipTitle: _tooltipTitle
4560
+ }, {
4561
+ children: _icon
4562
+ }));
4563
+ };
4564
+
4565
+ const SearchFieldConnect = () => {
4566
+ const dispatch = useDispatch();
4567
+ const searchFilter = useAppSelector(store => getSearchFilter(store));
4568
+ const toggleServicePopup = url => {
4569
+ dispatch(layerSelectActions.toggleServicePopup({
4570
+ isOpen: true,
4571
+ url,
4572
+ variant: 'save'
4573
+ }));
4574
+ };
4575
+ const setSearchFilter = filterText => {
4576
+ dispatch(layerSelectActions.setSearchFilter({
4577
+ filterText
4578
+ }));
4579
+ };
4580
+ return jsx(SearchField, {
4581
+ setSearchFilter: setSearchFilter,
4582
+ searchFilter: searchFilter,
4583
+ onOpenServicePopup: toggleServicePopup
4584
+ });
4585
+ };
4586
+
4308
4587
  const style$1 = {
4309
4588
  borderRadius: '20px!important',
4310
4589
  marginRight: '4px',
@@ -4331,924 +4610,645 @@ const ServiceChip = ({
4331
4610
  variant: "boxed",
4332
4611
  selected: Boolean(isSelected),
4333
4612
  tabIndex: 0,
4334
- "data-testid": _all ? 'serviceChipAll' : 'serviceChip',
4335
- onClick: () => toggleChip(chip),
4336
- onKeyPress: () => toggleChip(chip),
4337
- disabled: isDisabled,
4338
- sx: style$1
4339
- }, {
4340
- children: service ? service.serviceName : 'All'
4341
- }))
4342
- })
4343
- }));
4344
- };
4345
-
4346
- const ServiceChipConnect = ({
4347
- service,
4348
- isAllSelected
4349
- }) => {
4350
- const dispatch = useDispatch();
4351
- const serviceId = service.serviceId;
4352
- const toggleChip = () => {
4353
- if (service.enabled) {
4354
- if (isAllSelected) {
4355
- dispatch(layerSelectActions.onlyThisServiceEnabled({
4356
- serviceId
4357
- }));
4358
- return;
4359
- }
4360
- dispatch(layerSelectActions.disableActiveService({
4361
- serviceId
4362
- }));
4363
- return;
4364
- }
4365
- dispatch(layerSelectActions.enableActiveService({
4366
- serviceId
4367
- }));
4368
- };
4369
- return jsx(ServiceChip, {
4370
- service: service,
4371
- toggleChip: toggleChip,
4372
- isSelected: isAllSelected ? false : service.enabled,
4373
- isDisabled: service.isLoading
4374
- });
4375
- };
4376
- const AllChipConnect = ({
4377
- isAllSelected
4378
- }) => {
4379
- const dispatch = useDispatch();
4380
- return jsx(ServiceChip, {
4381
- toggleChip: () => {
4382
- if (!isAllSelected) {
4383
- dispatch(layerSelectActions.enableAllActiveServices());
4384
- }
4385
- },
4386
- isSelected: isAllSelected
4387
- });
4388
- };
4389
-
4390
- const ServiceList = ({
4391
- activeServicesById,
4392
- setHeight
4393
- }) => {
4394
- const ref = React.useRef(null);
4395
- const [serviceListHeight, setServiceListHeight] = React.useState(0);
4396
- const clientHeight = ref && ref.current && ref.current.clientHeight && ref.current.clientHeight;
4397
- React.useEffect(() => {
4398
- if (ref && ref.current && ref.current.clientHeight) {
4399
- setServiceListHeight(ref.current.clientHeight);
4400
- }
4401
- }, [activeServicesById, clientHeight]);
4402
- React.useEffect(() => {
4403
- setHeight(serviceListHeight);
4404
- }, [serviceListHeight, setHeight]);
4405
- const activeServicesIds = Object.keys(activeServicesById);
4406
- const activeServices = Object.values(activeServicesById);
4407
- const isAllSelected = activeServices.every(activeService => activeService.enabled);
4408
- return jsx(Box$1, Object.assign({
4409
- sx: {
4410
- marginTop: '8px',
4411
- width: '100%',
4412
- overflow: 'hidden'
4413
- },
4414
- "data-testid": "serviceList"
4415
- }, {
4416
- children: jsxs(Box$1, Object.assign({
4417
- sx: {
4418
- width: '100%',
4419
- display: 'block',
4420
- alignItems: 'center',
4421
- float: 'left',
4422
- paddingLeft: '48px',
4423
- paddingRight: '40px',
4424
- marginBottom: '8px',
4425
- fontSize: '0.875rem'
4426
- },
4427
- ref: ref
4428
- }, {
4429
- children: [(activeServicesIds === null || activeServicesIds === void 0 ? void 0 : activeServicesIds.length) && jsx(AllChipConnect, {
4430
- isAllSelected: isAllSelected
4431
- }), activeServices.map(service => {
4432
- return jsx(ServiceChipConnect, {
4433
- service: service,
4434
- isAllSelected: isAllSelected
4435
- }, service.serviceUrl);
4436
- })]
4437
- }))
4438
- }));
4439
- };
4440
-
4441
- const ServiceListConnect = ({
4442
- setHeight
4443
- }) => {
4444
- const activeServices = useAppSelector(store => getActiveServices(store));
4445
- return jsx(ServiceList, {
4446
- setHeight: setHeight,
4447
- activeServicesById: sortByService(activeServices)
4448
- });
4449
- };
4450
-
4451
- const styles = {
4452
- servicesContainer: {
4453
- width: '360px',
4454
- maxHeight: '412px',
4455
- top: '140px',
4456
- backgroundColor: 'geowebColors.background.surface',
4457
- boxShadow: 6,
4458
- overflow: 'auto'
4459
- },
4460
- header: {
4461
- position: 'sticky',
4462
- top: 0,
4463
- fontSize: 'default',
4464
- padding: '12px',
4465
- backgroundColor: 'geowebColors.background.surface',
4466
- zIndex: 100
4467
- },
4468
- loading: {
4469
- position: 'absolute',
4470
- zIndex: 101
4471
- },
4472
- footer: {
4473
- display: 'flex',
4474
- justifyContent: 'center',
4475
- alignItems: 'center',
4476
- position: 'sticky',
4477
- bottom: 0,
4478
- backgroundColor: 'geowebColors.background.surface',
4479
- zIndex: 100
4480
- },
4481
- button: {
4482
- margin: '16px',
4483
- width: '80%',
4484
- fontSize: '12px',
4485
- textTransform: 'none'
4486
- }
4487
- };
4488
- const stopTabPropagation = event => {
4489
- if (event.key === 'Tab') {
4490
- event.stopPropagation();
4491
- }
4492
- };
4493
- const ServiceOptionsDialog = ({
4494
- services,
4495
- layerSelectRemoveService,
4496
- layerSelectReloadService,
4497
- selectedLayers,
4498
- setServicePopupInfo,
4499
- isLoading: _isLoading = false
4500
- }) => {
4501
- const openAddService = () => {
4502
- setServicePopupInfo({
4503
- isOpen: true,
4504
- variant: 'add'
4505
- });
4506
- };
4507
- const dialogRef = React.useRef(null);
4508
- React.useEffect(() => {
4509
- var _a;
4510
- (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.focus();
4511
- }, []);
4512
- return jsxs(Box$1, Object.assign({
4513
- sx: styles.servicesContainer,
4514
- "data-testid": "ServiceDialog",
4515
- onKeyDown: event => {
4516
- if (event.key !== 'Escape') {
4517
- event.stopPropagation();
4518
- }
4519
- },
4520
- tabIndex: -1,
4521
- ref: dialogRef
4522
- }, {
4523
- children: [jsx(Box$1, Object.assign({
4524
- sx: styles.header
4525
- }, {
4526
- children: "Services"
4527
- })), jsx(Backdrop, Object.assign({
4528
- sx: styles.loading,
4529
- open: _isLoading
4530
- }, {
4531
- children: jsx(CircularProgress, {})
4532
- })), jsx(Rows, {
4533
- services: services,
4534
- layerSelectRemoveService: layerSelectRemoveService,
4535
- layerSelectReloadService: layerSelectReloadService,
4536
- setServicePopupInfo: setServicePopupInfo,
4537
- selectedLayers: selectedLayers
4538
- }), jsx(Box$1, Object.assign({
4539
- sx: styles.footer
4540
- }, {
4541
- children: jsx(Button, Object.assign({
4542
- onClick: openAddService,
4543
- onKeyDown: stopTabPropagation,
4544
- "data-testid": "openAddServiceButton",
4545
- sx: styles.button,
4546
- variant: "tertiary",
4547
- startIcon: jsx(Add, {})
4548
- }, {
4549
- children: "Add a new service"
4550
- }))
4551
- }))]
4552
- }));
4553
- };
4554
- const updateServiceTitle = 'Update layers from WMS service';
4555
- const editServiceTitle = 'Edit Service';
4556
- const showServiceTitle = 'Show Service';
4557
- const deleteServiceTitle = hasActiveLayers => {
4558
- return hasActiveLayers ? 'Service has active layers. Cannot remove this service' : 'Delete Service';
4559
- };
4560
- const tooltipPlacement = () => {
4561
- return 'left';
4562
- };
4563
- const tooltipPopperProps = {
4564
- disablePortal: true,
4565
- sx: {
4566
- '& .MuiTooltip-tooltip': {
4567
- width: '200px',
4568
- display: 'flex',
4569
- justifyContent: 'center',
4570
- alignItems: 'center'
4571
- }
4572
- }
4573
- };
4574
- const Rows = ({
4575
- services,
4576
- layerSelectReloadService,
4577
- layerSelectRemoveService,
4578
- setServicePopupInfo,
4579
- selectedLayers
4580
- }) => {
4581
- const checkIfServiceHasActiveLayers = serviceUrl => {
4582
- const foundService = selectedLayers.find(object => object.service === serviceUrl);
4583
- if (foundService) {
4584
- return true;
4585
- }
4586
- return false;
4587
- };
4588
- const sortedServices = sortByService(services);
4589
- return jsx(List, Object.assign({
4590
- disablePadding: true
4591
- }, {
4592
- children: Object.keys(sortedServices).map(serviceId => {
4593
- const {
4594
- serviceUrl,
4595
- serviceName,
4596
- scope
4597
- } = services[serviceId];
4598
- const serviceHasActiveLayers = checkIfServiceHasActiveLayers(serviceUrl);
4599
- const userAddedService = isUserAddedService(scope);
4600
- return jsxs(ListItem, {
4601
- children: [jsx(ListItemText, Object.assign({
4602
- style: {
4603
- fontSize: '16px'
4604
- }
4605
- }, {
4606
- children: jsx(Typography$1, Object.assign({
4607
- noWrap: true,
4608
- style: {
4609
- textOverflow: 'ellipsis',
4610
- paddingRight: '70px'
4611
- }
4612
- }, {
4613
- children: serviceName
4614
- }))
4615
- })), jsx(ListItemSecondaryAction, Object.assign({
4616
- sx: {
4617
- marginRight: '0px',
4618
- width: 96,
4619
- button: {
4620
- marginLeft: 1
4621
- }
4622
- }
4623
- }, {
4624
- children: jsxs(Grid$1, Object.assign({
4625
- container: true,
4626
- justifyContent: "left"
4627
- }, {
4628
- children: [jsx(CustomTooltip, Object.assign({
4629
- "data-testid": "updateServiceTooltip",
4630
- title: updateServiceTitle,
4631
- placement: tooltipPlacement(),
4632
- PopperProps: tooltipPopperProps
4633
- }, {
4634
- children: jsx(CustomIconButton, Object.assign({
4635
- "data-testid": "updateServiceButton",
4636
- "aria-label": "Update layers from WMS service",
4637
- onKeyDown: stopTabPropagation,
4638
- onClick: () => {
4639
- layerSelectReloadService(serviceUrl);
4640
- }
4641
- }, {
4642
- children: jsx(Cached, {})
4643
- }))
4644
- })), userAddedService ? jsx(CustomTooltip, Object.assign({
4645
- title: editServiceTitle,
4646
- placement: tooltipPlacement(),
4647
- PopperProps: tooltipPopperProps
4648
- }, {
4649
- children: jsx("span", {
4650
- children: jsx(CustomIconButton, Object.assign({
4651
- "aria-label": "edit service",
4652
- "data-testid": "openEditServiceButton",
4653
- onKeyDown: stopTabPropagation,
4654
- onClick: () => {
4655
- setServicePopupInfo({
4656
- isOpen: true,
4657
- serviceId,
4658
- serviceUrl,
4659
- variant: 'edit'
4660
- });
4661
- }
4662
- }, {
4663
- children: jsx(Edit, {})
4664
- }))
4665
- })
4666
- })) : jsx(CustomTooltip, Object.assign({
4667
- title: showServiceTitle,
4668
- placement: tooltipPlacement(),
4669
- PopperProps: tooltipPopperProps
4670
- }, {
4671
- children: jsx("span", {
4672
- children: jsx(CustomIconButton, Object.assign({
4673
- "aria-label": "show service",
4674
- "data-testid": "openShowServiceButton",
4675
- onKeyDown: stopTabPropagation,
4676
- onClick: () => {
4677
- setServicePopupInfo({
4678
- isOpen: true,
4679
- serviceId,
4680
- serviceUrl,
4681
- variant: 'show'
4682
- });
4683
- }
4684
- }, {
4685
- children: jsx(Visibility, {})
4686
- }))
4687
- })
4688
- })), userAddedService && jsx(Box$1, {
4689
- children: jsx(CustomTooltip, Object.assign({
4690
- title: deleteServiceTitle(serviceHasActiveLayers),
4691
- PopperProps: tooltipPopperProps,
4692
- placement: tooltipPlacement(),
4693
- "data-testid": "removeServiceTooltip"
4694
- }, {
4695
- children: jsx("span", {
4696
- children: jsx(CustomIconButton, Object.assign({
4697
- "data-testid": "removeServiceButton",
4698
- "aria-label": "delete service",
4699
- disabled: serviceHasActiveLayers,
4700
- onKeyDown: stopTabPropagation,
4701
- onClick: () => layerSelectRemoveService(serviceId, serviceUrl, serviceName)
4702
- }, {
4703
- children: jsx(Delete, {})
4704
- }))
4705
- })
4706
- }))
4707
- })]
4708
- }))
4709
- }))]
4710
- }, serviceUrl);
4613
+ "data-testid": _all ? 'serviceChipAll' : 'serviceChip',
4614
+ onClick: () => toggleChip(chip),
4615
+ onKeyPress: () => toggleChip(chip),
4616
+ disabled: isDisabled,
4617
+ sx: style$1
4618
+ }, {
4619
+ children: service ? service.serviceName : 'All'
4620
+ }))
4711
4621
  })
4712
4622
  }));
4713
4623
  };
4714
4624
 
4715
- const VALIDATIONS_NAME_EXISTING = 'This name already exists. Choose another name.';
4716
- const VALIDATIONS_SERVICE_EXISTING = 'URL already exists.';
4717
- const VALIDATIONS_SERVICE_VALID_URL = 'Not a valid URL.';
4718
- const VALIDATIONS_REQUEST_FAILED = 'Download failed. Check the URL.';
4719
- const validateServiceName = (value, services, ownServiceName = '') => {
4720
- const serviceName = value === null || value === void 0 ? void 0 : value.toLowerCase();
4721
- const foundName = Object.keys(services).find(serviceId => {
4722
- var _a;
4723
- return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceName.toLowerCase()) === serviceName && serviceName !== ownServiceName.toLocaleLowerCase();
4625
+ const ServiceChipConnect = ({
4626
+ service,
4627
+ isAllSelected
4628
+ }) => {
4629
+ const dispatch = useDispatch();
4630
+ const serviceId = service.serviceId;
4631
+ const toggleChip = () => {
4632
+ if (service.enabled) {
4633
+ if (isAllSelected) {
4634
+ dispatch(layerSelectActions.onlyThisServiceEnabled({
4635
+ serviceId
4636
+ }));
4637
+ return;
4638
+ }
4639
+ dispatch(layerSelectActions.disableActiveService({
4640
+ serviceId
4641
+ }));
4642
+ return;
4643
+ }
4644
+ dispatch(layerSelectActions.enableActiveService({
4645
+ serviceId
4646
+ }));
4647
+ };
4648
+ return jsx(ServiceChip, {
4649
+ service: service,
4650
+ toggleChip: toggleChip,
4651
+ isSelected: isAllSelected ? false : service.enabled,
4652
+ isDisabled: service.isLoading
4724
4653
  });
4725
- return foundName === undefined ? true : VALIDATIONS_NAME_EXISTING;
4726
- };
4727
- const isValidUrl = url => {
4728
- if (url === '' || url === null || typeof url === 'undefined') {
4729
- return false;
4730
- }
4731
- const matcher = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|[0-9a-zA-Z]+[:?\d]*)\S*$/;
4732
- if (!matcher.test(url)) {
4733
- return false;
4734
- }
4735
- return true;
4736
4654
  };
4737
- const validateServiceUrl = (value, services) => {
4738
- const serviceUrl = value;
4739
- // validate valid url
4740
- const isServiceUrlValid = isValidUrl(serviceUrl);
4741
- if (!isServiceUrlValid) {
4742
- return VALIDATIONS_SERVICE_VALID_URL;
4743
- }
4744
- // check url existing
4745
- const foundUrl = Object.keys(services).find(serviceId => {
4746
- var _a;
4747
- return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceUrl) === serviceUrl;
4655
+ const AllChipConnect = ({
4656
+ isAllSelected
4657
+ }) => {
4658
+ const dispatch = useDispatch();
4659
+ return jsx(ServiceChip, {
4660
+ toggleChip: () => {
4661
+ if (!isAllSelected) {
4662
+ dispatch(layerSelectActions.enableAllActiveServices());
4663
+ }
4664
+ },
4665
+ isSelected: isAllSelected
4748
4666
  });
4749
- if (foundUrl) {
4750
- return VALIDATIONS_SERVICE_EXISTING;
4751
- }
4752
- return true;
4753
4667
  };
4754
- const loadWMSService = (serviceUrl, forceReload = false) => __awaiter(void 0, void 0, void 0, function* () {
4755
- const layers = yield getCapabilities.getLayersFlattenedFromService(serviceUrl, forceReload);
4756
- const service = WMGetServiceFromStore(serviceUrl);
4757
- return {
4758
- id: service.id,
4759
- name: service.title,
4760
- serviceUrl,
4761
- abstract: service.abstract,
4762
- layers,
4763
- scope: 'user'
4764
- };
4765
- });
4766
4668
 
4767
- const getService = (services, serviceUrl) => {
4768
- const serviceIds = Object.keys(services);
4769
- const serviceIndex = serviceIds.findIndex(serviceId => {
4770
- var _a;
4771
- return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceUrl) === serviceUrl;
4772
- });
4773
- if (serviceIndex < 0) {
4774
- return null;
4775
- }
4776
- return services[serviceIds[serviceIndex]];
4777
- };
4778
- const getServiceSuccesUpdateMessage = serviceName => `Service "${serviceName}" has been succesfully updated`;
4779
- const getServiceFailedUpdateMessage = error => `Unable to update service, reason: "${error.message}"`;
4780
- const ServiceOptionsDialogConnect = ({
4781
- mapId
4669
+ const ServiceList = ({
4670
+ activeServicesById,
4671
+ setHeight
4782
4672
  }) => {
4783
- const [isLoading, setIsLoading] = React.useState(false);
4784
- const dispatch = useDispatch();
4785
- const serviceSetLayers = React.useCallback(payload => {
4786
- dispatch(serviceActions.serviceSetLayers(Object.assign(Object.assign({}, payload), {
4787
- isUpdating: true
4788
- })));
4789
- }, [dispatch]);
4790
- const setServicePopupInfo = React.useCallback(payload => {
4791
- dispatch(layerSelectActions.toggleServicePopup(Object.assign({}, payload)));
4792
- }, [dispatch]);
4793
- const showSnackbar = React.useCallback(message => {
4794
- dispatch(snackbarActions.openSnackbar({
4795
- message
4796
- }));
4797
- }, [dispatch]);
4798
- const services = useAppSelector(store => getActiveServices(store));
4799
- const selectedLayers = useAppSelector(store => mapSelectors.getMapLayers(store, mapId));
4800
- const layerSelectRemoveService = React.useCallback((serviceId, serviceUrl, serviceName) => {
4801
- const message = `Service "${serviceName}" has been deleted`;
4802
- showSnackbar(message);
4803
- dispatch(layerSelectActions.layerSelectRemoveService({
4804
- serviceId,
4805
- serviceUrl
4806
- }));
4807
- }, [dispatch, showSnackbar]);
4808
- const layerSelectReloadService = React.useCallback(serviceUrl => __awaiter(void 0, void 0, void 0, function* () {
4809
- setIsLoading(true);
4810
- try {
4811
- const layersForService = yield loadWMSService(serviceUrl, true);
4812
- const service = getService(services, serviceUrl);
4813
- serviceSetLayers({
4814
- id: layersForService.id,
4815
- name: service && service.serviceName || layersForService.name,
4816
- serviceUrl,
4817
- abstract: service && service.abstract || layersForService.abstract,
4818
- layers: layersForService.layers,
4819
- scope: service && service.scope || 'user',
4820
- isUpdating: true
4821
- });
4822
- clearImageCache();
4823
- const serviceTitle = service && service.serviceName || layersForService.name;
4824
- showSnackbar(getServiceSuccesUpdateMessage(serviceTitle));
4825
- } catch (error) {
4826
- // TODO: Maarten Plieger 2022-11-02: Snackbars should not be used to inform the user that something went wrong.
4827
- // https://gitlab.com/opengeoweb/opengeoweb/-/issues/2819
4828
- showSnackbar(getServiceFailedUpdateMessage(error));
4829
- } finally {
4830
- setIsLoading(false);
4673
+ const ref = React.useRef(null);
4674
+ const [serviceListHeight, setServiceListHeight] = React.useState(0);
4675
+ const clientHeight = ref && ref.current && ref.current.clientHeight && ref.current.clientHeight;
4676
+ React.useEffect(() => {
4677
+ if (ref && ref.current && ref.current.clientHeight) {
4678
+ setServiceListHeight(ref.current.clientHeight);
4831
4679
  }
4832
- }), [serviceSetLayers, services, showSnackbar]);
4833
- return jsx(ServiceOptionsDialog, {
4834
- selectedLayers: selectedLayers,
4835
- services: services,
4836
- layerSelectRemoveService: layerSelectRemoveService,
4837
- layerSelectReloadService: layerSelectReloadService,
4838
- setServicePopupInfo: setServicePopupInfo,
4839
- isLoading: isLoading
4680
+ }, [activeServicesById, clientHeight]);
4681
+ React.useEffect(() => {
4682
+ setHeight(serviceListHeight);
4683
+ }, [serviceListHeight, setHeight]);
4684
+ const activeServicesIds = Object.keys(activeServicesById);
4685
+ const activeServices = Object.values(activeServicesById);
4686
+ const isAllSelected = activeServices.every(activeService => activeService.enabled);
4687
+ return jsx(Box$1, Object.assign({
4688
+ sx: {
4689
+ marginTop: '8px',
4690
+ width: '100%',
4691
+ overflow: 'hidden'
4692
+ },
4693
+ "data-testid": "serviceList"
4694
+ }, {
4695
+ children: jsxs(Box$1, Object.assign({
4696
+ sx: {
4697
+ width: '100%',
4698
+ display: 'block',
4699
+ alignItems: 'center',
4700
+ float: 'left',
4701
+ paddingLeft: '48px',
4702
+ paddingRight: '40px',
4703
+ marginBottom: '8px',
4704
+ fontSize: '0.875rem'
4705
+ },
4706
+ ref: ref
4707
+ }, {
4708
+ children: [(activeServicesIds === null || activeServicesIds === void 0 ? void 0 : activeServicesIds.length) && jsx(AllChipConnect, {
4709
+ isAllSelected: isAllSelected
4710
+ }), activeServices.map(service => {
4711
+ return jsx(ServiceChipConnect, {
4712
+ service: service,
4713
+ isAllSelected: isAllSelected
4714
+ }, service.serviceUrl);
4715
+ })]
4716
+ }))
4717
+ }));
4718
+ };
4719
+
4720
+ const ServiceListConnect = ({
4721
+ setHeight
4722
+ }) => {
4723
+ const activeServices = useAppSelector(store => getActiveServices(store));
4724
+ return jsx(ServiceList, {
4725
+ setHeight: setHeight,
4726
+ activeServicesById: sortByService(activeServices)
4840
4727
  });
4841
4728
  };
4842
-
4843
- const ServiceOptionsButton = ({
4844
- mapId
4845
- }) => {
4846
- return jsx(ToggleMenu, Object.assign({
4847
- buttonTestId: "serviceOptionsButton",
4848
- menuPosition: "bottom"
4849
- }, {
4850
- children: jsx(ServiceOptionsDialogConnect, {
4851
- mapId: mapId
4852
- })
4853
- }));
4729
+
4730
+ const styles = {
4731
+ servicesContainer: {
4732
+ width: '360px',
4733
+ maxHeight: '412px',
4734
+ top: '140px',
4735
+ backgroundColor: 'geowebColors.background.surface',
4736
+ boxShadow: 6,
4737
+ overflow: 'auto'
4738
+ },
4739
+ header: {
4740
+ position: 'sticky',
4741
+ top: 0,
4742
+ fontSize: 'default',
4743
+ padding: '12px',
4744
+ backgroundColor: 'geowebColors.background.surface',
4745
+ zIndex: 100
4746
+ },
4747
+ loading: {
4748
+ position: 'absolute',
4749
+ zIndex: 101
4750
+ },
4751
+ footer: {
4752
+ display: 'flex',
4753
+ justifyContent: 'center',
4754
+ alignItems: 'center',
4755
+ position: 'sticky',
4756
+ bottom: 0,
4757
+ backgroundColor: 'geowebColors.background.surface',
4758
+ zIndex: 100
4759
+ },
4760
+ button: {
4761
+ margin: '16px',
4762
+ width: '80%',
4763
+ fontSize: '12px',
4764
+ textTransform: 'none'
4765
+ }
4766
+ };
4767
+ const stopTabPropagation = event => {
4768
+ if (event.key === 'Tab') {
4769
+ event.stopPropagation();
4770
+ }
4854
4771
  };
4855
-
4856
- const LayerSelect = ({
4857
- mapId,
4858
- bounds,
4859
- onClose: _onClose = () => {},
4860
- showTitle,
4861
- isOpen,
4862
- onMouseDown: _onMouseDown = () => {},
4863
- order: _order = 0,
4864
- source: _source = 'module',
4865
- startSize: _startSize = {
4866
- width: 750,
4867
- height: 500
4868
- },
4869
- isMultiMap: _isMultiMap = false
4772
+ const ServiceOptionsDialog = ({
4773
+ services,
4774
+ layerSelectRemoveService,
4775
+ layerSelectReloadService,
4776
+ selectedLayers,
4777
+ setServicePopupInfo,
4778
+ isLoading: _isLoading = false
4870
4779
  }) => {
4871
- const initialServiceListHeight = 37;
4872
- const [height, setHeight] = React.useState(_startSize.height);
4873
- const [width, setWidth] = React.useState(_startSize.width);
4874
- const [serviceListHeight, setServiceListHeight] = React.useState(initialServiceListHeight);
4875
- const onChangeSize = ({
4876
- height,
4877
- width
4878
- }) => {
4879
- setHeight(height);
4880
- setWidth(width);
4881
- };
4882
- const handleHeightChange = height => {
4883
- if (height > initialServiceListHeight) {
4884
- setServiceListHeight(height);
4885
- }
4780
+ const openAddService = () => {
4781
+ setServicePopupInfo({
4782
+ isOpen: true,
4783
+ variant: 'add'
4784
+ });
4886
4785
  };
4887
- return jsxs(ToolContainerDraggable, Object.assign({
4888
- title: showTitle ? `Layer Select ${mapId}` : 'Layer Select',
4889
- startSize: {
4890
- width,
4891
- height
4892
- },
4893
- minWidth: 320,
4894
- minHeight: 126,
4895
- startPosition: {
4896
- top: 150,
4897
- left: 100
4898
- },
4899
- isOpen: isOpen,
4900
- onResizeStop: (_event, _direction, node) => {
4901
- const {
4902
- offsetWidth: width,
4903
- offsetHeight: height
4904
- } = node;
4905
- onChangeSize({
4906
- width,
4907
- height
4908
- });
4909
- },
4910
- onClose: _onClose,
4911
- bounds: bounds,
4912
- "data-testid": "layerSelectWindow",
4913
- onMouseDown: event => {
4914
- const target = event.target;
4915
- const isButtonInScrollableList = target.closest('.layerInfoButton') || target.closest('.layerAddRemoveButton');
4916
- // don't propagate when clicking on layerInfoButton or addRemoveButton
4917
- if (isButtonInScrollableList) {
4786
+ const dialogRef = React.useRef(null);
4787
+ React.useEffect(() => {
4788
+ var _a;
4789
+ (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.focus();
4790
+ }, []);
4791
+ return jsxs(Box$1, Object.assign({
4792
+ sx: styles.servicesContainer,
4793
+ "data-testid": "ServiceDialog",
4794
+ onKeyDown: event => {
4795
+ if (event.key !== 'Escape') {
4918
4796
  event.stopPropagation();
4919
- return;
4920
4797
  }
4921
- _onMouseDown(event);
4922
4798
  },
4923
- order: _order,
4924
- source: _source
4799
+ tabIndex: -1,
4800
+ ref: dialogRef
4925
4801
  }, {
4926
4802
  children: [jsx(Box$1, Object.assign({
4927
- sx: {
4928
- padding: '4px 16px 0 16px'
4929
- }
4930
- }, {
4931
- children: jsx(SearchFieldConnect, {})
4932
- })), jsx(Box$1, Object.assign({
4933
- sx: {
4934
- float: 'left',
4935
- position: 'absolute',
4936
- margin: '8px 8px 0 16px',
4937
- zIndex: 2
4938
- }
4803
+ sx: styles.header
4939
4804
  }, {
4940
- children: jsx(KeywordFilterButtonConnect, {
4941
- mapId: mapId,
4942
- isMultiMap: _isMultiMap
4943
- })
4944
- })), jsx(Box$1, Object.assign({
4945
- sx: {
4946
- position: 'absolute',
4947
- margin: '8px 0 0 calc(100% - 40px)',
4948
- zIndex: 2
4949
- }
4805
+ children: "Services"
4806
+ })), jsx(Backdrop, Object.assign({
4807
+ sx: styles.loading,
4808
+ open: _isLoading
4950
4809
  }, {
4951
- children: jsx(ServiceOptionsButton, {
4952
- mapId: mapId
4953
- })
4954
- })), jsx(Box$1, {
4955
- children: jsx(ServiceListConnect, {
4956
- setHeight: handleHeightChange
4957
- })
4810
+ children: jsx(CircularProgress, {})
4811
+ })), jsx(Rows, {
4812
+ services: services,
4813
+ layerSelectRemoveService: layerSelectRemoveService,
4814
+ layerSelectReloadService: layerSelectReloadService,
4815
+ setServicePopupInfo: setServicePopupInfo,
4816
+ selectedLayers: selectedLayers
4958
4817
  }), jsx(Box$1, Object.assign({
4959
- sx: {
4960
- padding: '0 16px'
4961
- }
4818
+ sx: styles.footer
4962
4819
  }, {
4963
- children: jsx(LayerListConnect, {
4964
- mapId: mapId,
4965
- layerSelectHeight: height,
4966
- serviceListHeight: serviceListHeight,
4967
- layerSelectWidth: width
4968
- })
4820
+ children: jsx(Button, Object.assign({
4821
+ onClick: openAddService,
4822
+ onKeyDown: stopTabPropagation,
4823
+ "data-testid": "openAddServiceButton",
4824
+ sx: styles.button,
4825
+ variant: "tertiary",
4826
+ startIcon: jsx(Add, {})
4827
+ }, {
4828
+ children: "Add a new service"
4829
+ }))
4969
4830
  }))]
4970
4831
  }));
4971
4832
  };
4972
-
4973
- const FilterListItem = ({
4974
- filter,
4975
- toggleFilter,
4976
- enableOnlyOneFilter
4833
+ const updateServiceTitle = 'Update layers from WMS service';
4834
+ const editServiceTitle = 'Edit Service';
4835
+ const showServiceTitle = 'Show Service';
4836
+ const deleteServiceTitle = hasActiveLayers => {
4837
+ return hasActiveLayers ? 'Service has active layers. Cannot remove this service' : 'Delete Service';
4838
+ };
4839
+ const tooltipPlacement = () => {
4840
+ return 'left';
4841
+ };
4842
+ const tooltipPopperProps = {
4843
+ disablePortal: true,
4844
+ sx: {
4845
+ '& .MuiTooltip-tooltip': {
4846
+ width: '200px',
4847
+ display: 'flex',
4848
+ justifyContent: 'center',
4849
+ alignItems: 'center'
4850
+ }
4851
+ }
4852
+ };
4853
+ const Rows = ({
4854
+ services,
4855
+ layerSelectReloadService,
4856
+ layerSelectRemoveService,
4857
+ setServicePopupInfo,
4858
+ selectedLayers
4977
4859
  }) => {
4978
- const [isHovering, setIsHovering] = React.useState(false);
4979
- const handleMouseEnter = React.useCallback(() => {
4980
- setIsHovering(true);
4981
- }, []);
4982
- const handleMouseLeave = React.useCallback(() => {
4983
- setIsHovering(false);
4984
- }, []);
4985
- const selectOnlyOne = filterId => {
4986
- enableOnlyOneFilter(filterId);
4987
- };
4988
- const toggleCheckbox = filterId => {
4989
- toggleFilter([filterId]);
4990
- };
4991
- const mouseMoveRef = React.useRef(null);
4992
- React.useEffect(() => {
4993
- window.addEventListener('mousemove', checkHover, true);
4994
- return () => {
4995
- window.removeEventListener('mousemove', checkHover, true);
4996
- };
4997
- });
4998
- const checkHover = e => {
4999
- if (mouseMoveRef.current) {
5000
- const mouseOver = mouseMoveRef.current.contains(e.target);
5001
- if (!isHovering && mouseOver) {
5002
- handleMouseEnter();
5003
- }
5004
- if (isHovering && !mouseOver) {
5005
- handleMouseLeave();
5006
- }
4860
+ const checkIfServiceHasActiveLayers = serviceUrl => {
4861
+ const foundService = selectedLayers.find(object => object.service === serviceUrl);
4862
+ if (foundService) {
4863
+ return true;
5007
4864
  }
4865
+ return false;
5008
4866
  };
5009
- if (filter.amountVisible !== 0) {
5010
- return jsx("div", Object.assign({
5011
- ref: mouseMoveRef,
5012
- onMouseEnter: handleMouseEnter,
5013
- onMouseLeave: handleMouseLeave,
5014
- onFocus: handleMouseEnter,
5015
- onBlur: handleMouseLeave
5016
- }, {
5017
- children: jsxs(ListItem, Object.assign({
5018
- sx: {
5019
- width: '100%',
5020
- minWidth: '300px',
5021
- padding: '0px',
5022
- paddingLeft: '0px',
5023
- paddingRight: '50px',
5024
- fontSize: '12px'
5025
- }
5026
- }, {
5027
- children: [jsx(ListItemIcon, Object.assign({
5028
- sx: {
5029
- minWidth: '42px'
4867
+ const sortedServices = sortByService(services);
4868
+ return jsx(List, Object.assign({
4869
+ disablePadding: true
4870
+ }, {
4871
+ children: Object.keys(sortedServices).map(serviceId => {
4872
+ const {
4873
+ serviceUrl,
4874
+ serviceName,
4875
+ scope
4876
+ } = services[serviceId];
4877
+ const serviceHasActiveLayers = checkIfServiceHasActiveLayers(serviceUrl);
4878
+ const userAddedService = isUserAddedService(scope);
4879
+ return jsxs(ListItem, {
4880
+ children: [jsx(ListItemText, Object.assign({
4881
+ style: {
4882
+ fontSize: '16px'
5030
4883
  }
5031
4884
  }, {
5032
- children: jsx(Checkbox, {
5033
- inputProps: {
5034
- 'aria-label': filter.name
5035
- },
5036
- color: "secondary",
5037
- checked: filter.checked,
5038
- onChange: () => {
5039
- toggleCheckbox(filter.id);
5040
- },
5041
- sx: {
5042
- paddingTop: '6px',
5043
- paddingBottom: '7px',
5044
- '&&:hover': {
5045
- backgroundColor: 'transparent'
5046
- }
4885
+ children: jsx(Typography, Object.assign({
4886
+ noWrap: true,
4887
+ style: {
4888
+ textOverflow: 'ellipsis',
4889
+ paddingRight: '70px'
5047
4890
  }
5048
- })
5049
- })), jsxs(Typography$1, Object.assign({
5050
- variant: "body2",
4891
+ }, {
4892
+ children: serviceName
4893
+ }))
4894
+ })), jsx(ListItemSecondaryAction, Object.assign({
5051
4895
  sx: {
5052
- fontSize: '16px',
5053
- textOverflow: 'ellipsis',
5054
- whiteSpace: 'nowrap',
5055
- overflow: 'hidden'
4896
+ marginRight: '0px',
4897
+ width: 96,
4898
+ button: {
4899
+ marginLeft: 1
4900
+ }
5056
4901
  }
5057
4902
  }, {
5058
- children: [filter.name, " (", filter.amountVisible, ")"]
5059
- })), isHovering ? jsx(ListItemSecondaryAction, {
5060
- children: jsx(CustomIconButton, Object.assign({
5061
- "aria-label": `Only ${filter.name}`,
5062
- style: {
5063
- backgroundColor: 'transparent',
5064
- width: 'auto'
5065
- },
5066
- edge: "end",
5067
- onClick: () => selectOnlyOne(filter.id)
4903
+ children: jsxs(Grid, Object.assign({
4904
+ container: true,
4905
+ justifyContent: "left"
5068
4906
  }, {
5069
- children: jsx(Typography$1, Object.assign({
5070
- sx: {
5071
- color: 'geowebColors.buttons.primary.default.fill',
5072
- fontSize: '14px',
5073
- fontWeight: 500
5074
- }
4907
+ children: [jsx(CustomTooltip, Object.assign({
4908
+ "data-testid": "updateServiceTooltip",
4909
+ title: updateServiceTitle,
4910
+ placement: tooltipPlacement(),
4911
+ PopperProps: tooltipPopperProps
5075
4912
  }, {
5076
- children: "ONLY"
5077
- }))
4913
+ children: jsx(CustomIconButton, Object.assign({
4914
+ "data-testid": "updateServiceButton",
4915
+ "aria-label": "Update layers from WMS service",
4916
+ onKeyDown: stopTabPropagation,
4917
+ onClick: () => {
4918
+ layerSelectReloadService(serviceUrl);
4919
+ }
4920
+ }, {
4921
+ children: jsx(Cached, {})
4922
+ }))
4923
+ })), userAddedService ? jsx(CustomTooltip, Object.assign({
4924
+ title: editServiceTitle,
4925
+ placement: tooltipPlacement(),
4926
+ PopperProps: tooltipPopperProps
4927
+ }, {
4928
+ children: jsx("span", {
4929
+ children: jsx(CustomIconButton, Object.assign({
4930
+ "aria-label": "edit service",
4931
+ "data-testid": "openEditServiceButton",
4932
+ onKeyDown: stopTabPropagation,
4933
+ onClick: () => {
4934
+ setServicePopupInfo({
4935
+ isOpen: true,
4936
+ serviceId,
4937
+ serviceUrl,
4938
+ variant: 'edit'
4939
+ });
4940
+ }
4941
+ }, {
4942
+ children: jsx(Edit, {})
4943
+ }))
4944
+ })
4945
+ })) : jsx(CustomTooltip, Object.assign({
4946
+ title: showServiceTitle,
4947
+ placement: tooltipPlacement(),
4948
+ PopperProps: tooltipPopperProps
4949
+ }, {
4950
+ children: jsx("span", {
4951
+ children: jsx(CustomIconButton, Object.assign({
4952
+ "aria-label": "show service",
4953
+ "data-testid": "openShowServiceButton",
4954
+ onKeyDown: stopTabPropagation,
4955
+ onClick: () => {
4956
+ setServicePopupInfo({
4957
+ isOpen: true,
4958
+ serviceId,
4959
+ serviceUrl,
4960
+ variant: 'show'
4961
+ });
4962
+ }
4963
+ }, {
4964
+ children: jsx(Visibility, {})
4965
+ }))
4966
+ })
4967
+ })), userAddedService && jsx(Box$1, {
4968
+ children: jsx(CustomTooltip, Object.assign({
4969
+ title: deleteServiceTitle(serviceHasActiveLayers),
4970
+ PopperProps: tooltipPopperProps,
4971
+ placement: tooltipPlacement(),
4972
+ "data-testid": "removeServiceTooltip"
4973
+ }, {
4974
+ children: jsx("span", {
4975
+ children: jsx(CustomIconButton, Object.assign({
4976
+ "data-testid": "removeServiceButton",
4977
+ "aria-label": "delete service",
4978
+ disabled: serviceHasActiveLayers,
4979
+ onKeyDown: stopTabPropagation,
4980
+ onClick: () => layerSelectRemoveService(serviceId, serviceUrl, serviceName)
4981
+ }, {
4982
+ children: jsx(Delete, {})
4983
+ }))
4984
+ })
4985
+ }))
4986
+ })]
5078
4987
  }))
5079
- }) : null]
5080
- }))
5081
- }));
5082
- }
5083
- return null;
4988
+ }))]
4989
+ }, serviceUrl);
4990
+ })
4991
+ }));
5084
4992
  };
5085
4993
 
5086
- const KeywordFilterResultsListItemConnect = ({
5087
- filter
5088
- }) => {
5089
- const dispatch = useDispatch();
5090
- const toggleFilter = React.useCallback(filterIds => {
5091
- dispatch(layerSelectActions.toggleFilter({
5092
- filterIds
5093
- }));
5094
- }, [dispatch]);
5095
- const enableOnlyOneFilter = React.useCallback(filterId => {
5096
- dispatch(layerSelectActions.enableOnlyOneFilter({
5097
- filterId
5098
- }));
5099
- }, [dispatch]);
5100
- return jsx(FilterListItem, {
5101
- filter: filter,
5102
- toggleFilter: toggleFilter,
5103
- enableOnlyOneFilter: enableOnlyOneFilter
4994
+ const VALIDATIONS_NAME_EXISTING = 'This name already exists. Choose another name.';
4995
+ const VALIDATIONS_SERVICE_EXISTING = 'URL already exists.';
4996
+ const VALIDATIONS_SERVICE_VALID_URL = 'Not a valid URL.';
4997
+ const VALIDATIONS_REQUEST_FAILED = 'Download failed. Check the URL.';
4998
+ const validateServiceName = (value, services, ownServiceName = '') => {
4999
+ const serviceName = value === null || value === void 0 ? void 0 : value.toLowerCase();
5000
+ const foundName = Object.keys(services).find(serviceId => {
5001
+ var _a;
5002
+ return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceName.toLowerCase()) === serviceName && serviceName !== ownServiceName.toLocaleLowerCase();
5003
+ });
5004
+ return foundName === undefined ? true : VALIDATIONS_NAME_EXISTING;
5005
+ };
5006
+ const isValidUrl = url => {
5007
+ if (url === '' || url === null || typeof url === 'undefined') {
5008
+ return false;
5009
+ }
5010
+ const matcher = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|[0-9a-zA-Z]+[:?\d]*)\S*$/;
5011
+ if (!matcher.test(url)) {
5012
+ return false;
5013
+ }
5014
+ return true;
5015
+ };
5016
+ const validateServiceUrl = (value, services) => {
5017
+ const serviceUrl = value;
5018
+ // validate valid url
5019
+ const isServiceUrlValid = isValidUrl(serviceUrl);
5020
+ if (!isServiceUrlValid) {
5021
+ return VALIDATIONS_SERVICE_VALID_URL;
5022
+ }
5023
+ // check url existing
5024
+ const foundUrl = Object.keys(services).find(serviceId => {
5025
+ var _a;
5026
+ return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceUrl) === serviceUrl;
5104
5027
  });
5028
+ if (foundUrl) {
5029
+ return VALIDATIONS_SERVICE_EXISTING;
5030
+ }
5031
+ return true;
5105
5032
  };
5033
+ const loadWMSService = (serviceUrl, forceReload = false) => __awaiter(void 0, void 0, void 0, function* () {
5034
+ const layers = yield getCapabilities.getLayersFlattenedFromService(serviceUrl, forceReload);
5035
+ const service = WMGetServiceFromStore(serviceUrl);
5036
+ return {
5037
+ id: service.id,
5038
+ name: service.title,
5039
+ serviceUrl,
5040
+ abstract: service.abstract,
5041
+ layers,
5042
+ scope: 'user'
5043
+ };
5044
+ });
5106
5045
 
5107
- const KeywordFilterSelectAllSwitchConnect = () => {
5046
+ const getService = (services, serviceUrl) => {
5047
+ const serviceIds = Object.keys(services);
5048
+ const serviceIndex = serviceIds.findIndex(serviceId => {
5049
+ var _a;
5050
+ return ((_a = services[serviceId]) === null || _a === void 0 ? void 0 : _a.serviceUrl) === serviceUrl;
5051
+ });
5052
+ if (serviceIndex < 0) {
5053
+ return null;
5054
+ }
5055
+ return services[serviceIds[serviceIndex]];
5056
+ };
5057
+ const getServiceSuccesUpdateMessage = serviceName => `Service "${serviceName}" has been succesfully updated`;
5058
+ const getServiceFailedUpdateMessage = error => `Unable to update service, reason: "${error.message}"`;
5059
+ const ServiceOptionsDialogConnect = ({
5060
+ mapId
5061
+ }) => {
5062
+ const [isLoading, setIsLoading] = React.useState(false);
5108
5063
  const dispatch = useDispatch();
5109
- const allFiltersActive = useAppSelector(store => isAllFiltersChecked(store));
5110
- const allFilterIds = useAppSelector(store => getAllFilterIds(store));
5111
- const checkedFilterIds = useAppSelector(store => getCheckedFilterIds(store));
5112
- const toggleFilters = React.useCallback(() => {
5113
- const filterIds = allFiltersActive ? checkedFilterIds : allFilterIds.filter(id => !checkedFilterIds.includes(id));
5114
- dispatch(layerSelectActions.toggleFilter({
5115
- filterIds
5064
+ const serviceSetLayers = React.useCallback(payload => {
5065
+ dispatch(serviceActions.serviceSetLayers(Object.assign(Object.assign({}, payload), {
5066
+ isUpdating: true
5067
+ })));
5068
+ }, [dispatch]);
5069
+ const setServicePopupInfo = React.useCallback(payload => {
5070
+ dispatch(layerSelectActions.toggleServicePopup(Object.assign({}, payload)));
5071
+ }, [dispatch]);
5072
+ const showSnackbar = React.useCallback(message => {
5073
+ dispatch(snackbarActions.openSnackbar({
5074
+ message
5116
5075
  }));
5117
- }, [allFilterIds, allFiltersActive, checkedFilterIds, dispatch]);
5118
- return jsx(Switch, {
5119
- inputProps: {
5120
- 'aria-label': 'All'
5121
- },
5122
- checked: allFiltersActive,
5123
- onChange: toggleFilters,
5124
- "data-testid": "customSwitch"
5076
+ }, [dispatch]);
5077
+ const services = useAppSelector(store => getActiveServices(store));
5078
+ const selectedLayers = useAppSelector(store => mapSelectors.getMapLayers(store, mapId));
5079
+ const layerSelectRemoveService = React.useCallback((serviceId, serviceUrl, serviceName) => {
5080
+ const message = `Service "${serviceName}" has been deleted`;
5081
+ showSnackbar(message);
5082
+ dispatch(layerSelectActions.layerSelectRemoveService({
5083
+ serviceId,
5084
+ serviceUrl
5085
+ }));
5086
+ }, [dispatch, showSnackbar]);
5087
+ const layerSelectReloadService = React.useCallback(serviceUrl => __awaiter(void 0, void 0, void 0, function* () {
5088
+ setIsLoading(true);
5089
+ try {
5090
+ const layersForService = yield loadWMSService(serviceUrl, true);
5091
+ const service = getService(services, serviceUrl);
5092
+ serviceSetLayers({
5093
+ id: layersForService.id,
5094
+ name: service && service.serviceName || layersForService.name,
5095
+ serviceUrl,
5096
+ abstract: service && service.abstract || layersForService.abstract,
5097
+ layers: layersForService.layers,
5098
+ scope: service && service.scope || 'user',
5099
+ isUpdating: true
5100
+ });
5101
+ clearImageCache();
5102
+ const serviceTitle = service && service.serviceName || layersForService.name;
5103
+ showSnackbar(getServiceSuccesUpdateMessage(serviceTitle));
5104
+ } catch (error) {
5105
+ // TODO: Maarten Plieger 2022-11-02: Snackbars should not be used to inform the user that something went wrong.
5106
+ // https://gitlab.com/opengeoweb/opengeoweb/-/issues/2819
5107
+ showSnackbar(getServiceFailedUpdateMessage(error));
5108
+ } finally {
5109
+ setIsLoading(false);
5110
+ }
5111
+ }), [serviceSetLayers, services, showSnackbar]);
5112
+ return jsx(ServiceOptionsDialog, {
5113
+ selectedLayers: selectedLayers,
5114
+ services: services,
5115
+ layerSelectRemoveService: layerSelectRemoveService,
5116
+ layerSelectReloadService: layerSelectReloadService,
5117
+ setServicePopupInfo: setServicePopupInfo,
5118
+ isLoading: isLoading
5125
5119
  });
5126
5120
  };
5127
5121
 
5128
- const DIALOG_TITLE = 'Groups & Keywords';
5129
- const listStyle = {
5130
- padding: '0px'
5131
- };
5132
- const accordionDetailsStyle = {
5133
- padding: '0px',
5134
- margin: '0px'
5122
+ const ServiceOptionsButton = ({
5123
+ mapId
5124
+ }) => {
5125
+ return jsx(ToggleMenu, Object.assign({
5126
+ buttonTestId: "serviceOptionsButton",
5127
+ menuPosition: "bottom"
5128
+ }, {
5129
+ children: jsx(ServiceOptionsDialogConnect, {
5130
+ mapId: mapId
5131
+ })
5132
+ }));
5135
5133
  };
5136
- const KeywordFilterResults = ({
5137
- filters,
5134
+
5135
+ const LayerSelect = ({
5136
+ mapId,
5138
5137
  bounds,
5139
5138
  onClose: _onClose = () => {},
5139
+ showTitle,
5140
5140
  isOpen,
5141
5141
  onMouseDown: _onMouseDown = () => {},
5142
5142
  order: _order = 0,
5143
- source: _source = 'module'
5143
+ source: _source = 'module',
5144
+ startSize: _startSize = {
5145
+ width: 750,
5146
+ height: 500
5147
+ },
5148
+ isMultiMap: _isMultiMap = false
5144
5149
  }) => {
5150
+ const initialServiceListHeight = 37;
5151
+ const [height, setHeight] = React.useState(_startSize.height);
5152
+ const [width, setWidth] = React.useState(_startSize.width);
5153
+ const [serviceListHeight, setServiceListHeight] = React.useState(initialServiceListHeight);
5154
+ const onChangeSize = ({
5155
+ height,
5156
+ width
5157
+ }) => {
5158
+ setHeight(height);
5159
+ setWidth(width);
5160
+ };
5161
+ const handleHeightChange = height => {
5162
+ if (height > initialServiceListHeight) {
5163
+ setServiceListHeight(height);
5164
+ }
5165
+ };
5145
5166
  return jsxs(ToolContainerDraggable, Object.assign({
5146
- title: DIALOG_TITLE,
5147
- "data-testid": "keywordFilterResults",
5167
+ title: showTitle ? `Layer Select ${mapId}` : 'Layer Select',
5148
5168
  startSize: {
5149
- width: 349,
5150
- height: 600
5169
+ width,
5170
+ height
5171
+ },
5172
+ minWidth: 320,
5173
+ minHeight: 126,
5174
+ startPosition: {
5175
+ top: 150,
5176
+ left: 100
5151
5177
  },
5152
- minWidth: 312,
5153
- minHeight: 192,
5154
5178
  isOpen: isOpen,
5179
+ onResizeStop: (_event, _direction, node) => {
5180
+ const {
5181
+ offsetWidth: width,
5182
+ offsetHeight: height
5183
+ } = node;
5184
+ onChangeSize({
5185
+ width,
5186
+ height
5187
+ });
5188
+ },
5155
5189
  onClose: _onClose,
5156
5190
  bounds: bounds,
5157
- onMouseDown: _onMouseDown,
5191
+ "data-testid": "layerSelectWindow",
5192
+ onMouseDown: event => {
5193
+ const target = event.target;
5194
+ const isButtonInScrollableList = target.closest('.layerInfoButton') || target.closest('.layerAddRemoveButton');
5195
+ // don't propagate when clicking on layerInfoButton or addRemoveButton
5196
+ if (isButtonInScrollableList) {
5197
+ event.stopPropagation();
5198
+ return;
5199
+ }
5200
+ _onMouseDown(event);
5201
+ },
5158
5202
  order: _order,
5159
5203
  source: _source
5160
5204
  }, {
5161
- children: [jsxs(Grid$1, Object.assign({
5162
- container: true,
5163
- item: true,
5164
- xs: 12,
5165
- justifyContent: "space-between",
5166
- alignItems: "center",
5205
+ children: [jsx(Box$1, Object.assign({
5167
5206
  sx: {
5168
- backgroundColor: 'background.paper',
5169
- position: 'sticky',
5170
- top: 0,
5171
- zIndex: 100
5207
+ padding: '4px 16px 0 16px'
5172
5208
  }
5173
5209
  }, {
5174
- children: [jsx(Grid$1, Object.assign({
5175
- container: true,
5176
- item: true,
5177
- xs: 6,
5178
- justifyContent: "flex-start",
5179
- alignItems: "center",
5180
- sx: {
5181
- padding: '15px 15px 0 24px'
5182
- }
5183
- }, {
5184
- children: "Select all"
5185
- })), jsx(Grid$1, Object.assign({
5186
- container: true,
5187
- item: true,
5188
- xs: 6,
5189
- justifyContent: "flex-end",
5190
- alignContent: "center",
5191
- sx: {
5192
- padding: '15px 15px 0 15px'
5193
- }
5194
- }, {
5195
- children: jsx(KeywordFilterSelectAllSwitchConnect, {})
5196
- }))]
5197
- })), jsx(CustomAccordion, Object.assign({
5198
- title: "Groups",
5199
- detailsSx: accordionDetailsStyle
5210
+ children: jsx(SearchFieldConnect, {})
5211
+ })), jsx(Box$1, Object.assign({
5212
+ sx: {
5213
+ float: 'left',
5214
+ position: 'absolute',
5215
+ margin: '8px 8px 0 16px',
5216
+ zIndex: 2
5217
+ }
5200
5218
  }, {
5201
- children: jsx(List, Object.assign({
5202
- dense: true,
5203
- style: listStyle
5204
- }, {
5205
- children: filters.groups.map(group => jsx(KeywordFilterResultsListItemConnect, {
5206
- filter: group
5207
- }, group.id))
5208
- }))
5209
- })), jsx(CustomAccordion, Object.assign({
5210
- title: "Keywords",
5211
- detailsSx: accordionDetailsStyle
5219
+ children: jsx(KeywordFilterButtonConnect, {
5220
+ mapId: mapId,
5221
+ isMultiMap: _isMultiMap
5222
+ })
5223
+ })), jsx(Box$1, Object.assign({
5224
+ sx: {
5225
+ position: 'absolute',
5226
+ margin: '8px 0 0 calc(100% - 40px)',
5227
+ zIndex: 2
5228
+ }
5212
5229
  }, {
5213
- children: jsx(List, Object.assign({
5214
- dense: true,
5215
- style: listStyle
5216
- }, {
5217
- children: filters.keywords.map(keyword => {
5218
- return jsx(KeywordFilterResultsListItemConnect, {
5219
- filter: keyword
5220
- }, keyword.id);
5221
- })
5222
- }))
5230
+ children: jsx(ServiceOptionsButton, {
5231
+ mapId: mapId
5232
+ })
5233
+ })), jsx(Box$1, {
5234
+ children: jsx(ServiceListConnect, {
5235
+ setHeight: handleHeightChange
5236
+ })
5237
+ }), jsx(Box$1, Object.assign({
5238
+ sx: {
5239
+ padding: '0 16px'
5240
+ }
5241
+ }, {
5242
+ children: jsx(LayerListConnect, {
5243
+ mapId: mapId,
5244
+ layerSelectHeight: height,
5245
+ serviceListHeight: serviceListHeight,
5246
+ layerSelectWidth: width
5247
+ })
5223
5248
  }))]
5224
5249
  }));
5225
5250
  };
5226
5251
 
5227
- const KeywordFilterResultsConnect = ({
5228
- bounds,
5229
- mapId,
5230
- isMultiMap
5231
- }) => {
5232
- const dialogType = isMultiMap ? `${uiTypes.DialogTypes.KeywordFilter}-${mapId}` : uiTypes.DialogTypes.KeywordFilter;
5233
- const {
5234
- dialogOrder,
5235
- onCloseDialog,
5236
- setDialogOrder,
5237
- isDialogOpen,
5238
- uiSource
5239
- } = useSetupDialog(dialogType);
5240
- const filters = useAppSelector(getFilters);
5241
- return jsx(KeywordFilterResults, {
5242
- bounds: bounds,
5243
- isOpen: isDialogOpen,
5244
- onClose: onCloseDialog,
5245
- onMouseDown: setDialogOrder,
5246
- order: dialogOrder,
5247
- source: uiSource,
5248
- filters: filters
5249
- });
5250
- };
5251
-
5252
5252
  const LayerInfoDialogConnect = () => {
5253
5253
  const layer = useAppSelector(store => getActiveLayerInfo(store));
5254
5254
  const {
@@ -5460,7 +5460,7 @@ const ServicePopupUnwrapped = ({
5460
5460
  }
5461
5461
  }
5462
5462
  }, {
5463
- children: [jsx(Typography$1, Object.assign({
5463
+ children: [jsx(Typography, Object.assign({
5464
5464
  variant: "h5",
5465
5465
  component: "span"
5466
5466
  }, {
@@ -5722,4 +5722,4 @@ const LayerSelectConnect = ({
5722
5722
  });
5723
5723
  };
5724
5724
 
5725
- export { LayerInfoButton, LayerInfoButtonConnect, LayerInfoDialog, LayerSelectButtonConnect, LayerSelectConnect, getUserAddedServices, isUserAddedService, layerSelectActions, layerSelectConfig, initialState as layerSelectInitialState, reducer as layerSelectReducer, selectors as layerSelectSelectors, types as layerSelectTypes, setUserAddedServices, useAppSelector };
5725
+ export { ADD_HEADING, AllChipConnect, COPY_URL_MESSAGE, DIALOG_TITLE, EDIT_HEADING, FilterListItem, KeywordFilterButtonConnect, KeywordFilterResults, KeywordFilterResultsConnect, KeywordFilterResultsListItemConnect, KeywordFilterSelectAllSwitchConnect, LayerAddRemoveButton, LayerInfoButton, LayerInfoButtonConnect, LayerInfoDialog, LayerList, LayerListConnect, LayerListDimensions, LayerListRow, LayerSelectButtonConnect, LayerSelectConnect, SAVE_HEADING, SearchFieldConnect, ServiceChip, ServiceChipConnect, ServiceList, ServiceListConnect, ServiceOptionsButton, ServiceOptionsDialog, ServiceOptionsDialogConnect, ServicePopup, ServicePopupConnect, ServicePopupDialogConnect, getServiceFailedUpdateMessage, getServiceSuccesUpdateMessage, getSuccesMessage, getUserAddedServices, isUserAddedService, layerSelectActions, layerSelectConfig, initialState as layerSelectInitialState, reducer as layerSelectReducer, selectors as layerSelectSelectors, types as layerSelectTypes, setUserAddedServices, useAppSelector };