@itwin/map-layers 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -1
- package/lib/cjs/public/locales/en/mapLayers.json +7 -2
- package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -1
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js +144 -64
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -1
- package/lib/cjs/ui/widget/BasemapPanel.d.ts.map +1 -1
- package/lib/cjs/ui/widget/BasemapPanel.js +44 -15
- package/lib/cjs/ui/widget/BasemapPanel.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapLayerDroppable.js +26 -3
- package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerManager.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapLayerManager.js +35 -57
- package/lib/cjs/ui/widget/MapLayerManager.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerManager.scss +2 -8
- package/lib/cjs/ui/widget/MapSelectFeaturesDialog.d.ts +11 -0
- package/lib/cjs/ui/widget/MapSelectFeaturesDialog.d.ts.map +1 -0
- package/lib/cjs/ui/widget/MapSelectFeaturesDialog.js +58 -0
- package/lib/cjs/ui/widget/MapSelectFeaturesDialog.js.map +1 -0
- package/lib/cjs/ui/widget/MapSelectFeaturesDialog.scss +17 -0
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts +7 -2
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapUrlDialog.js +38 -134
- package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -1
- package/lib/cjs/ui/widget/MapUrlDialog.scss +10 -10
- package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts +3 -1
- package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts.map +1 -1
- package/lib/cjs/ui/widget/SubLayersDataProvider.js +3 -3
- package/lib/cjs/ui/widget/SubLayersDataProvider.js.map +1 -1
- package/lib/cjs/ui/widget/SubLayersPopupButton.js +1 -1
- package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -1
- package/lib/cjs/ui/widget/SubLayersTree.d.ts +5 -0
- package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -1
- package/lib/cjs/ui/widget/SubLayersTree.js +12 -36
- package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -1
- package/lib/cjs/ui/widget/SubLayersTree.scss +12 -3
- package/lib/esm/public/locales/en/mapLayers.json +7 -2
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -1
- package/lib/esm/ui/widget/AttachLayerPopupButton.js +145 -65
- package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -1
- package/lib/esm/ui/widget/BasemapPanel.d.ts.map +1 -1
- package/lib/esm/ui/widget/BasemapPanel.js +44 -15
- package/lib/esm/ui/widget/BasemapPanel.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapLayerDroppable.js +27 -4
- package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerManager.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapLayerManager.js +36 -58
- package/lib/esm/ui/widget/MapLayerManager.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerManager.scss +2 -8
- package/lib/esm/ui/widget/MapSelectFeaturesDialog.d.ts +11 -0
- package/lib/esm/ui/widget/MapSelectFeaturesDialog.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapSelectFeaturesDialog.js +54 -0
- package/lib/esm/ui/widget/MapSelectFeaturesDialog.js.map +1 -0
- package/lib/esm/ui/widget/MapSelectFeaturesDialog.scss +17 -0
- package/lib/esm/ui/widget/MapUrlDialog.d.ts +7 -2
- package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapUrlDialog.js +38 -134
- package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -1
- package/lib/esm/ui/widget/MapUrlDialog.scss +10 -10
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts +3 -1
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts.map +1 -1
- package/lib/esm/ui/widget/SubLayersDataProvider.js +3 -3
- package/lib/esm/ui/widget/SubLayersDataProvider.js.map +1 -1
- package/lib/esm/ui/widget/SubLayersPopupButton.js +1 -1
- package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -1
- package/lib/esm/ui/widget/SubLayersTree.d.ts +5 -0
- package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -1
- package/lib/esm/ui/widget/SubLayersTree.js +13 -37
- package/lib/esm/ui/widget/SubLayersTree.js.map +1 -1
- package/lib/esm/ui/widget/SubLayersTree.scss +12 -3
- package/lib/public/locales/en/mapLayers.json +7 -2
- package/package.json +16 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# Change Log - @itwin/map-layers
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 26 Jul 2023 21:49:07 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 5.1.0
|
|
6
|
+
Wed, 26 Jul 2023 21:49:07 GMT
|
|
7
|
+
|
|
8
|
+
### Minor changes
|
|
9
|
+
|
|
10
|
+
- New UI that allow creating multiple layers from sources supporting single layer per request.
|
|
11
|
+
|
|
12
|
+
### Patches
|
|
13
|
+
|
|
14
|
+
- Fixvarious display issues with MapLayer widget
|
|
4
15
|
|
|
5
16
|
## 5.0.0
|
|
6
17
|
Tue, 06 Jun 2023 10:57:06 GMT
|
|
@@ -39,15 +39,18 @@
|
|
|
39
39
|
"MissingCredentials": "This layer requires credentials to be provided",
|
|
40
40
|
"Name": "Name",
|
|
41
41
|
"NameInputPlaceHolder": "Enter Map Name",
|
|
42
|
+
"NoLayersSelected": "Please select at least one layer",
|
|
42
43
|
"RemoveLayerDefButtonTitle": "Delete layer definition",
|
|
43
44
|
"RemoveLayerDefDialogMessage": "Are you sure you want to delete {{layerName}} ?",
|
|
44
45
|
"RemoveLayerDefDialogTitle": "Delete layer definition",
|
|
45
46
|
"RemoveLayerDefError": "Could not delete map layer definition: {{layerName}}",
|
|
46
47
|
"RemoveLayerDefSuccess": "Successfully deleted map layer definition: {{layerName}}",
|
|
47
48
|
"SearchPlaceholder": "Search...",
|
|
49
|
+
"SelectLayersToCreate": "Select layers to be created",
|
|
48
50
|
"StoreOnModelSettings": "Store on Model Settings",
|
|
49
51
|
"StoreOnITwinSettings": "Store on iTwin Settings",
|
|
50
52
|
"TechPreviewBadgeTooltip": "Technology preview",
|
|
53
|
+
"TooManyLayersSelected": "There are currently {{layerCount}} layers selected; Adding too many layers may impact performance.",
|
|
51
54
|
"Type": "Type",
|
|
52
55
|
"URL": "URL",
|
|
53
56
|
"UrlInputPlaceHolder": "Enter Map Source URL",
|
|
@@ -64,9 +67,10 @@
|
|
|
64
67
|
"NotSupported": "No active viewport or geo-located iModel available.",
|
|
65
68
|
"NoRangeDefined": "No range is defined for Map Layer",
|
|
66
69
|
"Start": "Map Layers Extension Loaded",
|
|
67
|
-
"MapLayerAttached": "Map layer {{
|
|
70
|
+
"MapLayerAttached": "Map layer {{layerNames}} attached",
|
|
71
|
+
"MapLayersAttached": "Map layers ({{sourceName}}) attached",
|
|
68
72
|
"MapLayerAttachedRequiresAuth": "Map layer {{sourceName}} attached, but requires credentials to be provided",
|
|
69
|
-
"MapLayerAttachError": "Error '{{error}}' occurred attaching MapLayer
|
|
73
|
+
"MapLayerAttachError": "Error '{{error}}' occurred attaching MapLayer '{{sourceName}}'",
|
|
70
74
|
"MapLayerAttachMissingViewOrSource": "Missing view or source",
|
|
71
75
|
"MapLayerEditError": "Failed to edit '{{layerName}}'",
|
|
72
76
|
"MapLayerLayerSettingsConversionError": "Conversion to layer settings failed",
|
|
@@ -119,6 +123,7 @@
|
|
|
119
123
|
"AllOn": "Turn on all Sub-layers",
|
|
120
124
|
"AllOff": "Turn off all Sub-layers",
|
|
121
125
|
"Hide": "Hide Sub-layers",
|
|
126
|
+
"NoResults": "No Results",
|
|
122
127
|
"NoSubLayers": "No Sub-layers Available",
|
|
123
128
|
"SearchPlaceholder": "Search...",
|
|
124
129
|
"Show": "Show Sub-layers"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachLayerPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AttachLayerPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"AAocA,gBAAgB;AAChB,oBAAY,qBAAqB;IAC/B,OAAO,IAAA;IACP,IAAI,IAAA;IACJ,IAAI,IAAA;CACL;AACD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,gBAAgB;AAEhB,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,eAkHxE"}
|
|
@@ -16,11 +16,12 @@ const ConfirmMessageDialog_1 = require("./ConfirmMessageDialog");
|
|
|
16
16
|
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
17
17
|
const MapLayerPreferences_1 = require("../../MapLayerPreferences");
|
|
18
18
|
const mapLayers_1 = require("../../mapLayers");
|
|
19
|
+
const MapSelectFeaturesDialog_1 = require("./MapSelectFeaturesDialog");
|
|
19
20
|
// cSpell:ignore droppable Sublayer
|
|
20
21
|
var LayerAction;
|
|
21
22
|
(function (LayerAction) {
|
|
22
|
-
LayerAction[LayerAction["
|
|
23
|
-
LayerAction[LayerAction["
|
|
23
|
+
LayerAction[LayerAction["New"] = 0] = "New";
|
|
24
|
+
LayerAction[LayerAction["Edit"] = 1] = "Edit";
|
|
24
25
|
})(LayerAction || (LayerAction = {}));
|
|
25
26
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
26
27
|
function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick }) {
|
|
@@ -63,93 +64,172 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
63
64
|
const mapTypesOptions = mapLayerOptions?.mapTypeOptions;
|
|
64
65
|
const iTwinId = activeViewport?.iModel?.iTwinId;
|
|
65
66
|
const iModelId = activeViewport?.iModel?.iModelId;
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
const attachLayer = React.useCallback((source, subLayers, oneMapLayerPerSubLayer) => {
|
|
68
|
+
if (activeViewport) {
|
|
69
|
+
const generateUniqueMapLayerName = (layerName) => {
|
|
70
|
+
let uniqueLayerName = layerName;
|
|
71
|
+
let layerNameIdx = 1;
|
|
72
|
+
while ((backgroundLayers && backgroundLayers.some((layer) => uniqueLayerName === layer.name))
|
|
73
|
+
|| (overlayLayers && overlayLayers.some((layer) => uniqueLayerName === layer.name))) {
|
|
74
|
+
uniqueLayerName = `${layerName} (${layerNameIdx++})`;
|
|
75
|
+
}
|
|
76
|
+
return { layerNameUpdate: layerNameIdx > 1, uniqueLayerName };
|
|
77
|
+
};
|
|
78
|
+
const doAttachLayer = (layerName, subLayer) => {
|
|
79
|
+
const generatedName = generateUniqueMapLayerName(layerName);
|
|
80
|
+
let sourceToAdd = source;
|
|
81
|
+
if (generatedName.layerNameUpdate || sourceToAdd.name !== generatedName.uniqueLayerName) {
|
|
82
|
+
// create a source with a unique name
|
|
83
|
+
const clonedSource = core_frontend_1.MapLayerSource.fromJSON({ ...source.toJSON(), name: generatedName.uniqueLayerName });
|
|
84
|
+
if (clonedSource !== undefined) {
|
|
85
|
+
clonedSource.userName = source.userName;
|
|
86
|
+
clonedSource.password = source.password;
|
|
87
|
+
sourceToAdd = clonedSource;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const settings = sourceToAdd.toLayerSettings(subLayer ? [subLayer] : subLayers);
|
|
91
|
+
if (settings) {
|
|
92
|
+
activeViewport.displayStyle.attachMapLayer({ settings, mapLayerIndex: { index: -1, isOverlay } });
|
|
93
|
+
return generatedName.uniqueLayerName;
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
};
|
|
97
|
+
if (oneMapLayerPerSubLayer && subLayers) {
|
|
98
|
+
const layerNamesAttached = [];
|
|
99
|
+
for (const subLayer of subLayers) {
|
|
100
|
+
const attachedLayerName = doAttachLayer(`${source.name} - ${subLayer.name}`, subLayer);
|
|
101
|
+
if (attachedLayerName !== undefined) {
|
|
102
|
+
layerNamesAttached.push(attachedLayerName);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (layerNamesAttached.length > 0) {
|
|
106
|
+
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayersAttached", { layerNames: layerNamesAttached.join(", ") });
|
|
107
|
+
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, msg));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const attachedLayerName = doAttachLayer(source.name);
|
|
112
|
+
if (attachedLayerName !== undefined) {
|
|
113
|
+
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttached", { sourceName: attachedLayerName });
|
|
114
|
+
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, msg));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (isMounted.current) {
|
|
118
|
+
setLoading(false);
|
|
119
|
+
}
|
|
74
120
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
121
|
+
onLayerAttached();
|
|
122
|
+
resumeOutsideClick();
|
|
123
|
+
}, [activeViewport, backgroundLayers, isOverlay, onLayerAttached, overlayLayers, resumeOutsideClick]);
|
|
124
|
+
const handleSelectFeaturesCancel = React.useCallback(() => {
|
|
125
|
+
if (isMounted.current) {
|
|
126
|
+
setLoading(false);
|
|
81
127
|
}
|
|
82
128
|
resumeOutsideClick();
|
|
83
|
-
|
|
129
|
+
appui_react_1.UiFramework.dialogs.modal.close();
|
|
130
|
+
}, [resumeOutsideClick, setLoading]);
|
|
131
|
+
const handleSelectFeaturesOk = React.useCallback((source, sourceSubLayers, selectedSubLayers) => {
|
|
132
|
+
// keep only visible subLayers
|
|
133
|
+
const visibleSubLayers = selectedSubLayers.filter((value) => value.visible);
|
|
134
|
+
// Re-apply default visibility from the source validation
|
|
135
|
+
visibleSubLayers.forEach((visible) => {
|
|
136
|
+
const found = sourceSubLayers.find((value) => { visible.name === value.name; });
|
|
137
|
+
if (found)
|
|
138
|
+
visible.visible = found?.visible;
|
|
139
|
+
});
|
|
140
|
+
attachLayer(source, visibleSubLayers, true);
|
|
141
|
+
}, [attachLayer]);
|
|
142
|
+
const openFeatureSelectionDialog = React.useCallback((subLayers, source) => {
|
|
143
|
+
// Keep leafs sub-layers and force default visibility to false
|
|
144
|
+
const noGroupLayers = subLayers.filter((value) => value.children === undefined);
|
|
145
|
+
const visibleLayers = noGroupLayers.map((value) => { return { ...value, visible: false }; });
|
|
146
|
+
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapSelectFeaturesDialog_1.MapSelectFeaturesDialog, { handleOk: (selectedLayers) => { handleSelectFeaturesOk(source, subLayers, selectedLayers); }, handleCancel: handleSelectFeaturesCancel, source: source, subLayers: visibleLayers }));
|
|
147
|
+
}, [handleSelectFeaturesCancel, handleSelectFeaturesOk]);
|
|
148
|
+
const needsFeatureSelection = React.useCallback((source, validation) => {
|
|
149
|
+
return (source.formatId === "ArcGISFeature" || source.formatId === "WMTS") // TODO, replace this with a flag in MapLayerSourceStatus
|
|
150
|
+
&& validation.subLayers
|
|
151
|
+
&& validation.subLayers.length > 1;
|
|
152
|
+
}, []);
|
|
153
|
+
const handleModalUrlDialogOk = React.useCallback((action, sourceState) => {
|
|
154
|
+
appui_react_1.UiFramework.dialogs.modal.close();
|
|
155
|
+
if (LayerAction.New === action
|
|
156
|
+
&& sourceState
|
|
157
|
+
&& (sourceState.validation.status === core_frontend_1.MapLayerSourceStatus.Valid)) {
|
|
158
|
+
if (needsFeatureSelection(sourceState.source, sourceState.validation)) {
|
|
159
|
+
openFeatureSelectionDialog(sourceState.validation.subLayers, sourceState.source);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
attachLayer(sourceState.source, sourceState.validation.subLayers, false);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
resumeOutsideClick();
|
|
167
|
+
}
|
|
168
|
+
}, [attachLayer, needsFeatureSelection, openFeatureSelectionDialog, resumeOutsideClick]);
|
|
84
169
|
const handleModalUrlDialogCancel = React.useCallback(() => {
|
|
85
170
|
// close popup and refresh UI
|
|
86
171
|
setLoading(false);
|
|
87
172
|
appui_react_1.UiFramework.dialogs.modal.close();
|
|
88
173
|
resumeOutsideClick();
|
|
89
|
-
}, [resumeOutsideClick]);
|
|
174
|
+
}, [setLoading, resumeOutsideClick]);
|
|
90
175
|
React.useEffect(() => {
|
|
91
|
-
async function attemptToAddLayer(
|
|
92
|
-
if (
|
|
176
|
+
async function attemptToAddLayer() {
|
|
177
|
+
if (layerNameToAdd && activeViewport) {
|
|
93
178
|
// if the layer is not in the style add it now.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
179
|
+
const mapLayerSettings = sources?.find((source) => source.name === layerNameToAdd);
|
|
180
|
+
if (mapLayerSettings === undefined) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
if (isMounted.current) {
|
|
185
|
+
setLoading(true);
|
|
98
186
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (status === core_frontend_1.MapLayerSourceStatus.Valid || status === core_frontend_1.MapLayerSourceStatus.RequireAuth) {
|
|
105
|
-
if (status === core_frontend_1.MapLayerSourceStatus.Valid) {
|
|
106
|
-
const settings = mapLayerSettings.toLayerSettings(subLayers);
|
|
107
|
-
if (settings) {
|
|
108
|
-
activeViewport.displayStyle.attachMapLayer({ settings, mapLayerIndex: { index: -1, isOverlay } });
|
|
109
|
-
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttached", { sourceName: settings.name, sourceUrl: settings.url });
|
|
110
|
-
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, msg));
|
|
111
|
-
}
|
|
112
|
-
if (isMounted.current) {
|
|
113
|
-
setLoading(false);
|
|
114
|
-
}
|
|
115
|
-
if (onLayerAttached) {
|
|
116
|
-
onLayerAttached();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else if (status === core_frontend_1.MapLayerSourceStatus.RequireAuth && isMounted.current) {
|
|
120
|
-
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, layerRequiringCredentials: mapLayerSettings.toJSON(), onOkResult: () => handleModalUrlDialogOk(LayerAction.Attached), onCancelResult: handleModalUrlDialogCancel, mapTypesOptions: mapTypesOptions }));
|
|
187
|
+
const sourceValidation = await mapLayerSettings.validateSource();
|
|
188
|
+
if (sourceValidation.status === core_frontend_1.MapLayerSourceStatus.Valid || sourceValidation.status === core_frontend_1.MapLayerSourceStatus.RequireAuth) {
|
|
189
|
+
if (sourceValidation.status === core_frontend_1.MapLayerSourceStatus.Valid) {
|
|
190
|
+
if (sourceValidation.subLayers && needsFeatureSelection(mapLayerSettings, sourceValidation)) {
|
|
191
|
+
openFeatureSelectionDialog(sourceValidation.subLayers, mapLayerSettings);
|
|
121
192
|
if (onHandleOutsideClick) {
|
|
122
193
|
onHandleOutsideClick(false);
|
|
123
194
|
}
|
|
124
195
|
}
|
|
196
|
+
else {
|
|
197
|
+
attachLayer(mapLayerSettings, sourceValidation.subLayers, false);
|
|
198
|
+
}
|
|
125
199
|
}
|
|
126
|
-
else {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
setLoading(false);
|
|
200
|
+
else if (sourceValidation.status === core_frontend_1.MapLayerSourceStatus.RequireAuth && isMounted.current) {
|
|
201
|
+
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, layerRequiringCredentials: mapLayerSettings.toJSON(), onOkResult: (sourceState) => handleModalUrlDialogOk(LayerAction.New, sourceState), onCancelResult: handleModalUrlDialogCancel, mapTypesOptions: mapTypesOptions }));
|
|
202
|
+
if (onHandleOutsideClick) {
|
|
203
|
+
onHandleOutsideClick(false);
|
|
131
204
|
}
|
|
132
205
|
}
|
|
133
206
|
}
|
|
134
|
-
|
|
207
|
+
else {
|
|
208
|
+
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerValidationFailed", { sourceUrl: mapLayerSettings.url });
|
|
209
|
+
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, msg));
|
|
135
210
|
if (isMounted.current) {
|
|
136
211
|
setLoading(false);
|
|
137
212
|
}
|
|
138
|
-
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttachError", { error: err, sourceUrl: mapLayerSettings.url });
|
|
139
|
-
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, msg));
|
|
140
213
|
}
|
|
141
214
|
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
if (isMounted.current) {
|
|
217
|
+
setLoading(false);
|
|
218
|
+
}
|
|
219
|
+
const msg = core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttachError", { error: err, sourceName: mapLayerSettings.name });
|
|
220
|
+
core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Error, msg));
|
|
221
|
+
}
|
|
142
222
|
}
|
|
143
223
|
return;
|
|
144
224
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
setLayerNameToAdd(undefined);
|
|
149
|
-
}
|
|
225
|
+
attemptToAddLayer(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
|
226
|
+
if (isMounted.current) {
|
|
227
|
+
setLayerNameToAdd(undefined);
|
|
150
228
|
}
|
|
151
|
-
}, [setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers,
|
|
152
|
-
|
|
229
|
+
}, [attachLayer, needsFeatureSelection, setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers,
|
|
230
|
+
onLayerAttached, handleModalUrlDialogOk, handleSelectFeaturesCancel, handleSelectFeaturesOk, mapTypesOptions,
|
|
231
|
+
handleModalUrlDialogCancel, onHandleOutsideClick, openFeatureSelectionDialog]);
|
|
232
|
+
const options = React.useMemo(() => sources, [sources]);
|
|
153
233
|
const filteredOptions = React.useMemo(() => {
|
|
154
234
|
if (undefined === sourceFilterString || 0 === sourceFilterString.length) {
|
|
155
235
|
return options;
|
|
@@ -159,7 +239,7 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
159
239
|
}
|
|
160
240
|
}, [options, sourceFilterString]);
|
|
161
241
|
const handleAddNewMapSource = React.useCallback(() => {
|
|
162
|
-
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, onOkResult: () => handleModalUrlDialogOk(LayerAction.
|
|
242
|
+
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, onOkResult: (result) => handleModalUrlDialogOk(LayerAction.New, result), onCancelResult: handleModalUrlDialogCancel, mapTypesOptions: mapTypesOptions }));
|
|
163
243
|
if (onHandleOutsideClick) {
|
|
164
244
|
onHandleOutsideClick(false);
|
|
165
245
|
}
|
|
@@ -224,7 +304,7 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
224
304
|
if (matchingSource === undefined) {
|
|
225
305
|
return;
|
|
226
306
|
}
|
|
227
|
-
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, mapLayerSourceToEdit: matchingSource, onOkResult: () => handleModalUrlDialogOk(LayerAction.
|
|
307
|
+
appui_react_1.UiFramework.dialogs.modal.open(React.createElement(MapUrlDialog_1.MapUrlDialog, { activeViewport: activeViewport, isOverlay: isOverlay, mapLayerSourceToEdit: matchingSource, onOkResult: (result) => handleModalUrlDialogOk(LayerAction.Edit, result), onCancelResult: handleModalUrlDialogCancel, mapTypesOptions: mapTypesOptions }));
|
|
228
308
|
if (onHandleOutsideClick) {
|
|
229
309
|
onHandleOutsideClick(false);
|
|
230
310
|
}
|
|
@@ -327,7 +407,7 @@ function AttachLayerPopupButton(props) {
|
|
|
327
407
|
}
|
|
328
408
|
return (React.createElement(React.Fragment, null,
|
|
329
409
|
renderButton(),
|
|
330
|
-
React.createElement(UiCore.Popup, { isOpen: popupOpen, position: appui_abstract_1.RelativePosition.BottomRight, onClose: handleClosePopup, onOutsideClick: onHandleOutsideClick, target: buttonRef.current, closeOnEnter: false, closeOnContextMenu: false },
|
|
410
|
+
React.createElement(UiCore.Popup, { isOpen: popupOpen, position: appui_abstract_1.RelativePosition.BottomRight, onClose: handleClosePopup, onOutsideClick: onHandleOutsideClick, closeOnWheel: false, target: buttonRef.current, closeOnEnter: false, closeOnContextMenu: false },
|
|
331
411
|
React.createElement("div", { ref: panelRef, className: "map-sources-popup-panel" },
|
|
332
412
|
React.createElement(AttachLayerPanel, { isOverlay: props.isOverlay, onLayerAttached: handleLayerAttached, onHandleOutsideClick: setHandleOutsideClick })))));
|
|
333
413
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachLayerPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport { IModelApp, MapLayerSource, MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority } from \"@itwin/core-frontend\";\r\nimport { RelativePosition } from \"@itwin/appui-abstract\";\r\nimport * as UiCore from \"@itwin/core-react\";\r\nimport { UiFramework } from \"@itwin/appui-react\";\r\nimport { useSourceMapContext } from \"./MapLayerManager\";\r\nimport { MapUrlDialog } from \"./MapUrlDialog\";\r\nimport { ConfirmMessageDialog } from \"./ConfirmMessageDialog\";\r\nimport { Button, Input } from \"@itwin/itwinui-react\";\r\nimport { MapLayerPreferences } from \"../../MapLayerPreferences\";\r\nimport { MapLayersUI } from \"../../mapLayers\";\r\n\r\n// cSpell:ignore droppable Sublayer\r\n\r\nenum LayerAction {\r\n Attached,\r\n Edited\r\n}\r\n\r\ninterface AttachLayerPanelProps {\r\n isOverlay: boolean;\r\n onLayerAttached: () => void;\r\n onHandleOutsideClick?: (shouldHandle: boolean) => void;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick }: AttachLayerPanelProps) {\r\n const [layerNameToAdd, setLayerNameToAdd] = React.useState<string | undefined>();\r\n const [sourceFilterString, setSourceFilterString] = React.useState<string | undefined>();\r\n\r\n const { placeholderLabel, addCustomLayerLabel, addCustomLayerToolTip, loadingMapSources, removeLayerDefButtonTitle, editLayerDefButtonTitle, removeLayerDefDialogTitle } = React.useMemo(() => {\r\n return {\r\n placeholderLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.SearchPlaceholder\"),\r\n addCustomLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.Custom\"),\r\n addCustomLayerToolTip: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.AttachCustomLayer\"),\r\n loadingMapSources: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.LoadingMapSources\"),\r\n removeLayerDefButtonTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefButtonTitle\"),\r\n editLayerDefButtonTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.EditLayerDefButtonTitle\"),\r\n removeLayerDefDialogTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogTitle\"),\r\n };\r\n }, []);\r\n\r\n const [loading, setLoading] = React.useState(false);\r\n const [layerNameUnderCursor, setLayerNameUnderCursor] = React.useState<string | undefined>();\r\n\r\n const resumeOutsideClick = React.useCallback(() => {\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(true);\r\n }\r\n }, [onHandleOutsideClick]);\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n\r\n // We close any open dialogs that we might have opened\r\n // This was added because the modal dialog remained remained displayed after the session expired.\r\n UiFramework.dialogs.modal.close();\r\n };\r\n }, []);\r\n\r\n const handleFilterTextChanged = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\r\n setSourceFilterString(event.target.value);\r\n }, []);\r\n\r\n const { loadingSources, sources, activeViewport, backgroundLayers, overlayLayers, mapLayerOptions } = useSourceMapContext();\r\n const mapTypesOptions = mapLayerOptions?.mapTypeOptions;\r\n const iTwinId = activeViewport?.iModel?.iTwinId;\r\n const iModelId = activeViewport?.iModel?.iModelId;\r\n\r\n const styleContainsLayer = React.useCallback((name: string) => {\r\n if (backgroundLayers) {\r\n if (-1 !== backgroundLayers.findIndex((layer) => layer.name === name))\r\n return true;\r\n }\r\n if (overlayLayers) {\r\n if (-1 !== overlayLayers.findIndex((layer) => layer.name === name))\r\n return true;\r\n }\r\n return false;\r\n }, [backgroundLayers, overlayLayers]);\r\n\r\n const handleModalUrlDialogOk = React.useCallback((action: LayerAction) => {\r\n if (LayerAction.Attached === action) {\r\n // close popup and refresh UI\r\n onLayerAttached();\r\n }\r\n\r\n resumeOutsideClick();\r\n }, [onLayerAttached, resumeOutsideClick]);\r\n\r\n const handleModalUrlDialogCancel = React.useCallback(() => {\r\n // close popup and refresh UI\r\n setLoading(false);\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [resumeOutsideClick]);\r\n\r\n React.useEffect(() => {\r\n async function attemptToAddLayer(layerName: string) {\r\n if (layerName && activeViewport) {\r\n // if the layer is not in the style add it now.\r\n if (undefined === backgroundLayers?.find((layer) => layerName === layer.name) && undefined === overlayLayers?.find((layer) => layerName === layer.name)) {\r\n const mapLayerSettings = sources?.find((source) => source.name === layerName);\r\n if (mapLayerSettings === undefined) {\r\n return;\r\n }\r\n\r\n try {\r\n if (isMounted.current) {\r\n setLoading(true);\r\n }\r\n\r\n const { status, subLayers } = await mapLayerSettings.validateSource();\r\n if (status === MapLayerSourceStatus.Valid || status === MapLayerSourceStatus.RequireAuth) {\r\n\r\n if (status === MapLayerSourceStatus.Valid) {\r\n const settings = mapLayerSettings.toLayerSettings(subLayers);\r\n\r\n if (settings) {\r\n activeViewport.displayStyle.attachMapLayer({ settings, mapLayerIndex: {index: -1, isOverlay} });\r\n\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttached\", { sourceName: settings.name, sourceUrl: settings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n }\r\n\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n if (onLayerAttached) {\r\n onLayerAttached();\r\n }\r\n\r\n } else if (status === MapLayerSourceStatus.RequireAuth && isMounted.current) {\r\n UiFramework.dialogs.modal.open(\r\n <MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n layerRequiringCredentials={mapLayerSettings.toJSON()}\r\n onOkResult={() => handleModalUrlDialogOk(LayerAction.Attached)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />\r\n );\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }\r\n\r\n } else {\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerValidationFailed\", { sourceUrl: mapLayerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n }\r\n } catch (err) {\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttachError\", { error: err, sourceUrl: mapLayerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n\r\n }\r\n return;\r\n }\r\n\r\n if (layerNameToAdd) {\r\n attemptToAddLayer(layerNameToAdd); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n if (isMounted.current) {\r\n setLayerNameToAdd(undefined);\r\n }\r\n }\r\n }, [setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers, onLayerAttached, handleModalUrlDialogOk, mapTypesOptions, handleModalUrlDialogCancel, onHandleOutsideClick]);\r\n\r\n const options = React.useMemo(() => sources?.filter((source) => !styleContainsLayer(source.name)), [sources, styleContainsLayer]);\r\n const filteredOptions = React.useMemo(() => {\r\n if (undefined === sourceFilterString || 0 === sourceFilterString.length) {\r\n return options;\r\n } else {\r\n return options?.filter((option) => option.name.toLowerCase().includes(sourceFilterString?.toLowerCase()));\r\n }\r\n }, [options, sourceFilterString]);\r\n\r\n const handleAddNewMapSource = React.useCallback(() => {\r\n UiFramework.dialogs.modal.open(<MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n onOkResult={() => handleModalUrlDialogOk(LayerAction.Attached)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />);\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n return;\r\n }, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, isOverlay, mapTypesOptions, onHandleOutsideClick]);\r\n\r\n const handleAttach = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleKeypressOnSourceList = React.useCallback((event: React.KeyboardEvent<HTMLUListElement>) => {\r\n const key = event.key;\r\n if (key === \"Enter\") {\r\n event.preventDefault();\r\n const mapName = event.currentTarget?.dataset?.value;\r\n if (mapName && mapName.length) {\r\n handleAttach(mapName);\r\n }\r\n }\r\n }, [handleAttach]);\r\n\r\n const onListboxValueChange = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleNoConfirmation = React.useCallback((_layerName: string) => {\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [resumeOutsideClick]);\r\n\r\n const handleYesConfirmation = React.useCallback(async (source: MapLayerSource) => {\r\n const layerName = source.name;\r\n if (!!iTwinId) {\r\n try {\r\n await MapLayerPreferences.deleteByName(source, iTwinId, iModelId);\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefSuccess\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n } catch (err: any) {\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefError\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [iTwinId, iModelId, resumeOutsideClick]);\r\n\r\n /*\r\n Handle Remove layer button clicked\r\n */\r\n const onItemRemoveButtonClicked = React.useCallback((source, event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const layerName = source.name;\r\n\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogMessage\", { layerName });\r\n UiFramework.dialogs.modal.open(\r\n <ConfirmMessageDialog\r\n className=\"map-sources-delete-confirmation\"\r\n title={removeLayerDefDialogTitle}\r\n message={msg}\r\n maxWidth={400}\r\n onClose={() => handleNoConfirmation(layerName)}\r\n onEscape={() => handleNoConfirmation(layerName)}\r\n onYesResult={async () => handleYesConfirmation(source)}\r\n onNoResult={() => handleNoConfirmation(layerName)}\r\n />\r\n );\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }, [handleNoConfirmation, handleYesConfirmation, onHandleOutsideClick, removeLayerDefDialogTitle]);\r\n\r\n /*\r\n Handle Edit layer button clicked\r\n */\r\n const onItemEditButtonClicked = React.useCallback((event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const targetLayerName = event?.currentTarget?.parentNode?.dataset?.value;\r\n const matchingSource = sources.find((layerSource) => layerSource.name === targetLayerName);\r\n\r\n // we expect a single layer source matching this name\r\n if (matchingSource === undefined) {\r\n return;\r\n }\r\n UiFramework.dialogs.modal.open(<MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n mapLayerSourceToEdit={matchingSource}\r\n onOkResult={() => handleModalUrlDialogOk(LayerAction.Edited)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />);\r\n\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, isOverlay, mapTypesOptions, onHandleOutsideClick, sources]);\r\n\r\n return (\r\n <div className=\"map-manager-header\">\r\n {(loading || loadingSources) && <UiCore.LoadingSpinner message={loadingMapSources} />}\r\n <div className=\"map-manager-source-listbox-header\">\r\n <Input type=\"text\" className=\"map-manager-source-list-filter\"\r\n placeholder={placeholderLabel}\r\n value={sourceFilterString}\r\n onChange={handleFilterTextChanged}\r\n size=\"small\" />\r\n <Button className=\"map-manager-add-source-button\" title={addCustomLayerToolTip} onClick={handleAddNewMapSource}>\r\n {addCustomLayerLabel}</Button>\r\n </div>\r\n <div className=\"map-manager-sources\">\r\n <UiCore.Listbox\r\n id=\"map-sources\"\r\n selectedValue={layerNameToAdd}\r\n className=\"map-manager-source-list\"\r\n onKeyPress={handleKeypressOnSourceList}\r\n onListboxValueChange={onListboxValueChange} >\r\n {\r\n filteredOptions?.map((source) =>\r\n <UiCore.ListboxItem\r\n key={source.name}\r\n className=\"map-source-list-entry\"\r\n value={source.name}\r\n onMouseEnter={() => setLayerNameUnderCursor(source.name)}\r\n onMouseLeave={() => setLayerNameUnderCursor(undefined)}>\r\n <span className=\"map-source-list-entry-name\" title={source.name}>{source.name}</span>\r\n\r\n { // Display the delete icon only when the mouse over a specific item\r\n // otherwise list feels cluttered.\r\n (!!iTwinId && layerNameUnderCursor && layerNameUnderCursor === source.name) &&\r\n <>\r\n <Button\r\n size=\"small\"\r\n styleType=\"borderless\"\r\n className=\"map-source-list-entry-button\"\r\n title={editLayerDefButtonTitle}\r\n onClick={onItemEditButtonClicked}>\r\n <UiCore.Icon iconSpec=\"icon-edit\" />\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n styleType=\"borderless\"\r\n className=\"map-source-list-entry-button\"\r\n title={removeLayerDefButtonTitle}\r\n onClick={(event: React.MouseEvent) => { onItemRemoveButtonClicked(source, event); }}>\r\n <UiCore.Icon iconSpec=\"icon-delete\" />\r\n </Button>\r\n </>}\r\n\r\n </UiCore.ListboxItem>\r\n )\r\n }\r\n </UiCore.Listbox>\r\n </div>\r\n </div>\r\n\r\n );\r\n}\r\n\r\n/** @internal */\r\nexport enum AttachLayerButtonType {\r\n Primary,\r\n Blue,\r\n Icon\r\n}\r\nexport interface AttachLayerPopupButtonProps {\r\n isOverlay: boolean;\r\n buttonType?: AttachLayerButtonType;\r\n disabled?: boolean;\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function AttachLayerPopupButton(props: AttachLayerPopupButtonProps) {\r\n const { showAttachLayerLabel, hideAttachLayerLabel, addCustomLayerButtonLabel } = React.useMemo(() => {\r\n return {\r\n showAttachLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Attach\"),\r\n hideAttachLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Close\"),\r\n addCustomLayerButtonLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.AddCustomLayerButtonLabel\"),\r\n };\r\n }, []);\r\n\r\n const [handleOutsideClick, setHandleOutsideClick] = React.useState(true);\r\n const [popupOpen, setPopupOpen] = React.useState(false);\r\n const buttonRef = React.useRef<HTMLButtonElement>(null);\r\n const panelRef = React.useRef<HTMLDivElement>(null);\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n };\r\n }, []);\r\n\r\n const togglePopup = React.useCallback(() => {\r\n setPopupOpen(!popupOpen);\r\n }, [popupOpen]);\r\n\r\n const handleClosePopup = React.useCallback(() => {\r\n setPopupOpen(false);\r\n }, []);\r\n\r\n const onHandleOutsideClick = React.useCallback((event: MouseEvent) => {\r\n if (!handleOutsideClick) {\r\n return;\r\n }\r\n\r\n // If clicking on button that open panel - don't trigger outside click processing\r\n if (buttonRef?.current && buttonRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If clicking the panel, this is not an outside clicked\r\n if (panelRef.current && panelRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If we reach this point, we got an outside clicked, no close the popup\r\n setPopupOpen(false);\r\n\r\n }, [handleOutsideClick]);\r\n\r\n const { refreshFromStyle } = useSourceMapContext();\r\n\r\n const handleLayerAttached = React.useCallback(() => {\r\n if (!isMounted.current) {\r\n return;\r\n }\r\n setPopupOpen(false);\r\n refreshFromStyle();\r\n }, [refreshFromStyle]);\r\n\r\n function renderButton(): React.ReactNode {\r\n let button: React.ReactNode;\r\n\r\n if (props.buttonType === undefined || props.buttonType === AttachLayerButtonType.Icon) {\r\n button = (\r\n <Button disabled={props.disabled} size=\"small\" styleType=\"borderless\" ref={buttonRef} className=\"map-manager-attach-layer-button\" title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>\r\n <UiCore.WebFontIcon iconName=\"icon-add\" />\r\n </Button>\r\n );\r\n } else {\r\n const determineStyleType = () => {\r\n switch (props.buttonType) {\r\n case AttachLayerButtonType.Blue:\r\n return \"high-visibility\";\r\n case AttachLayerButtonType.Primary:\r\n default:\r\n return \"cta\";\r\n }\r\n };\r\n const styleType = determineStyleType();\r\n button = (\r\n <Button disabled={props.disabled} ref={buttonRef} styleType={styleType} title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>{addCustomLayerButtonLabel}</Button>\r\n );\r\n }\r\n\r\n return button;\r\n }\r\n\r\n return (\r\n <>\r\n {renderButton()}\r\n <UiCore.Popup\r\n isOpen={popupOpen}\r\n position={RelativePosition.BottomRight}\r\n onClose={handleClosePopup}\r\n onOutsideClick={onHandleOutsideClick}\r\n target={buttonRef.current}\r\n closeOnEnter={false}\r\n closeOnContextMenu={false}\r\n >\r\n <div ref={panelRef} className=\"map-sources-popup-panel\" >\r\n <AttachLayerPanel\r\n isOverlay={props.isOverlay}\r\n onLayerAttached={handleLayerAttached}\r\n onHandleOutsideClick={setHandleOutsideClick} />\r\n </div>\r\n </UiCore.Popup >\r\n </>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"AttachLayerPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport { IModelApp, MapLayerSource, MapLayerSourceStatus, MapLayerSourceValidation, NotifyMessageDetails, OutputMessagePriority } from \"@itwin/core-frontend\";\r\nimport { RelativePosition } from \"@itwin/appui-abstract\";\r\nimport * as UiCore from \"@itwin/core-react\";\r\nimport { UiFramework } from \"@itwin/appui-react\";\r\nimport { useSourceMapContext } from \"./MapLayerManager\";\r\nimport { MapUrlDialog, SourceState } from \"./MapUrlDialog\";\r\nimport { ConfirmMessageDialog } from \"./ConfirmMessageDialog\";\r\nimport { Button, Input } from \"@itwin/itwinui-react\";\r\nimport { MapLayerPreferences } from \"../../MapLayerPreferences\";\r\nimport { MapLayersUI } from \"../../mapLayers\";\r\nimport { MapSelectFeaturesDialog } from \"./MapSelectFeaturesDialog\";\r\nimport { MapSubLayerProps } from \"@itwin/core-common\";\r\n\r\n// cSpell:ignore droppable Sublayer\r\n\r\nenum LayerAction {\r\n New,\r\n Edit\r\n}\r\n\r\ninterface AttachLayerPanelProps {\r\n isOverlay: boolean;\r\n onLayerAttached: () => void;\r\n onHandleOutsideClick?: (shouldHandle: boolean) => void;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick }: AttachLayerPanelProps) {\r\n const [layerNameToAdd, setLayerNameToAdd] = React.useState<string | undefined>();\r\n const [sourceFilterString, setSourceFilterString] = React.useState<string | undefined>();\r\n\r\n const { placeholderLabel, addCustomLayerLabel, addCustomLayerToolTip, loadingMapSources, removeLayerDefButtonTitle, editLayerDefButtonTitle, removeLayerDefDialogTitle } = React.useMemo(() => {\r\n return {\r\n placeholderLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.SearchPlaceholder\"),\r\n addCustomLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.Custom\"),\r\n addCustomLayerToolTip: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.AttachCustomLayer\"),\r\n loadingMapSources: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.LoadingMapSources\"),\r\n removeLayerDefButtonTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefButtonTitle\"),\r\n editLayerDefButtonTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.EditLayerDefButtonTitle\"),\r\n removeLayerDefDialogTitle: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogTitle\"),\r\n };\r\n }, []);\r\n\r\n const [loading, setLoading] = React.useState(false);\r\n const [layerNameUnderCursor, setLayerNameUnderCursor] = React.useState<string | undefined>();\r\n\r\n const resumeOutsideClick = React.useCallback(() => {\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(true);\r\n }\r\n }, [onHandleOutsideClick]);\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n\r\n // We close any open dialogs that we might have opened\r\n // This was added because the modal dialog remained remained displayed after the session expired.\r\n UiFramework.dialogs.modal.close();\r\n };\r\n }, []);\r\n\r\n const handleFilterTextChanged = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\r\n setSourceFilterString(event.target.value);\r\n }, []);\r\n\r\n const { loadingSources, sources, activeViewport, backgroundLayers, overlayLayers, mapLayerOptions } = useSourceMapContext();\r\n const mapTypesOptions = mapLayerOptions?.mapTypeOptions;\r\n const iTwinId = activeViewport?.iModel?.iTwinId;\r\n const iModelId = activeViewport?.iModel?.iModelId;\r\n\r\n const attachLayer = React.useCallback((source: MapLayerSource, subLayers: MapSubLayerProps[]|undefined, oneMapLayerPerSubLayer: boolean) => {\r\n if (activeViewport) {\r\n const generateUniqueMapLayerName = (layerName: string) => {\r\n let uniqueLayerName = layerName;\r\n let layerNameIdx = 1;\r\n while (\r\n (backgroundLayers && backgroundLayers.some((layer) => uniqueLayerName === layer.name))\r\n || (overlayLayers && overlayLayers.some((layer) => uniqueLayerName === layer.name)) ) {\r\n uniqueLayerName = `${layerName} (${layerNameIdx++})`;\r\n }\r\n return {layerNameUpdate: layerNameIdx>1, uniqueLayerName};\r\n };\r\n\r\n const doAttachLayer = (layerName: string, subLayer?: MapSubLayerProps) => {\r\n const generatedName = generateUniqueMapLayerName(layerName);\r\n let sourceToAdd = source;\r\n if (generatedName.layerNameUpdate || sourceToAdd.name !== generatedName.uniqueLayerName) {\r\n // create a source with a unique name\r\n const clonedSource = MapLayerSource.fromJSON({...source.toJSON(), name: generatedName.uniqueLayerName});\r\n if (clonedSource !== undefined) {\r\n clonedSource.userName = source.userName;\r\n clonedSource.password = source.password;\r\n sourceToAdd = clonedSource;\r\n }\r\n\r\n }\r\n\r\n const settings = sourceToAdd.toLayerSettings(subLayer ? [subLayer] : subLayers);\r\n if (settings) {\r\n activeViewport.displayStyle.attachMapLayer({ settings, mapLayerIndex: {index: -1, isOverlay} });\r\n return generatedName.uniqueLayerName;\r\n }\r\n return undefined;\r\n };\r\n\r\n if (oneMapLayerPerSubLayer && subLayers) {\r\n const layerNamesAttached: string[] = [];\r\n for (const subLayer of subLayers) {\r\n\r\n const attachedLayerName = doAttachLayer(`${source.name} - ${subLayer.name}`, subLayer);\r\n if (attachedLayerName !== undefined) {\r\n layerNamesAttached.push(attachedLayerName);\r\n }\r\n }\r\n\r\n if (layerNamesAttached.length > 0) {\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayersAttached\", { layerNames: layerNamesAttached.join(\", \") });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n }\r\n } else {\r\n const attachedLayerName = doAttachLayer(source.name);\r\n if (attachedLayerName !== undefined) {\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttached\", { sourceName: attachedLayerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n }\r\n }\r\n\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n }\r\n onLayerAttached();\r\n resumeOutsideClick();\r\n }, [activeViewport, backgroundLayers, isOverlay, onLayerAttached, overlayLayers, resumeOutsideClick]);\r\n\r\n const handleSelectFeaturesCancel = React.useCallback( () => {\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n resumeOutsideClick();\r\n UiFramework.dialogs.modal.close();\r\n\r\n }, [resumeOutsideClick, setLoading]);\r\n\r\n const handleSelectFeaturesOk = React.useCallback((source: MapLayerSource, sourceSubLayers: MapSubLayerProps[], selectedSubLayers: MapSubLayerProps[] ) => {\r\n // keep only visible subLayers\r\n const visibleSubLayers = selectedSubLayers.filter((value) => value.visible);\r\n\r\n // Re-apply default visibility from the source validation\r\n visibleSubLayers.forEach((visible) => {\r\n const found = sourceSubLayers.find((value) => {visible.name === value.name;});\r\n if (found)\r\n visible.visible = found?.visible;\r\n });\r\n attachLayer(source, visibleSubLayers, true);\r\n\r\n }, [attachLayer]);\r\n\r\n const openFeatureSelectionDialog = React.useCallback((subLayers: MapSubLayerProps[], source: MapLayerSource ) => {\r\n // Keep leafs sub-layers and force default visibility to false\r\n const noGroupLayers = subLayers.filter((value: MapSubLayerProps) => value.children === undefined);\r\n const visibleLayers = noGroupLayers.map((value: MapSubLayerProps) => {return {...value, visible: false};});\r\n UiFramework.dialogs.modal.open(\r\n <MapSelectFeaturesDialog\r\n handleOk={(selectedLayers) => {handleSelectFeaturesOk(source, subLayers, selectedLayers);}}\r\n handleCancel={handleSelectFeaturesCancel}\r\n source={source}\r\n subLayers={visibleLayers}/>);\r\n }, [handleSelectFeaturesCancel, handleSelectFeaturesOk]);\r\n\r\n const needsFeatureSelection = React.useCallback((source: MapLayerSource, validation: MapLayerSourceValidation ) => {\r\n return (source.formatId === \"ArcGISFeature\" || source.formatId === \"WMTS\") // TODO, replace this with a flag in MapLayerSourceStatus\r\n && validation.subLayers\r\n && validation.subLayers.length > 1;\r\n }, []);\r\n\r\n const handleModalUrlDialogOk = React.useCallback((action: LayerAction, sourceState?: SourceState) => {\r\n UiFramework.dialogs.modal.close();\r\n if (LayerAction.New === action\r\n && sourceState\r\n && (sourceState.validation.status === MapLayerSourceStatus.Valid)) {\r\n if (needsFeatureSelection(sourceState.source, sourceState.validation)) {\r\n openFeatureSelectionDialog(sourceState.validation.subLayers!, sourceState.source);\r\n } else {\r\n attachLayer(sourceState.source, sourceState.validation.subLayers, false);\r\n }\r\n } else {\r\n resumeOutsideClick();\r\n }\r\n }, [attachLayer, needsFeatureSelection, openFeatureSelectionDialog, resumeOutsideClick]);\r\n\r\n const handleModalUrlDialogCancel = React.useCallback(() => {\r\n // close popup and refresh UI\r\n setLoading(false);\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [setLoading, resumeOutsideClick]);\r\n\r\n React.useEffect(() => {\r\n async function attemptToAddLayer() {\r\n if (layerNameToAdd && activeViewport) {\r\n // if the layer is not in the style add it now.\r\n const mapLayerSettings = sources?.find((source) => source.name === layerNameToAdd);\r\n if (mapLayerSettings === undefined) {\r\n return;\r\n }\r\n\r\n try {\r\n if (isMounted.current) {\r\n setLoading(true);\r\n }\r\n\r\n const sourceValidation = await mapLayerSettings.validateSource();\r\n if (sourceValidation.status === MapLayerSourceStatus.Valid || sourceValidation.status === MapLayerSourceStatus.RequireAuth) {\r\n if (sourceValidation.status === MapLayerSourceStatus.Valid) {\r\n if (sourceValidation.subLayers && needsFeatureSelection(mapLayerSettings, sourceValidation)) {\r\n openFeatureSelectionDialog(sourceValidation.subLayers, mapLayerSettings);\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n } else {\r\n attachLayer(mapLayerSettings, sourceValidation.subLayers, false);\r\n }\r\n } else if (sourceValidation.status === MapLayerSourceStatus.RequireAuth && isMounted.current) {\r\n UiFramework.dialogs.modal.open(\r\n <MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n layerRequiringCredentials={mapLayerSettings.toJSON()}\r\n onOkResult={(sourceState?: SourceState) => handleModalUrlDialogOk(LayerAction.New, sourceState)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />\r\n );\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }\r\n\r\n } else {\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerValidationFailed\", { sourceUrl: mapLayerSettings.url });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n }\r\n } catch (err) {\r\n if (isMounted.current) {\r\n setLoading(false);\r\n }\r\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttachError\", { error: err, sourceName: mapLayerSettings.name });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n return;\r\n }\r\n\r\n attemptToAddLayer(); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n if (isMounted.current) {\r\n setLayerNameToAdd(undefined);\r\n }\r\n }, [attachLayer, needsFeatureSelection, setLayerNameToAdd, layerNameToAdd, activeViewport, sources, backgroundLayers, isOverlay, overlayLayers,\r\n onLayerAttached, handleModalUrlDialogOk, handleSelectFeaturesCancel, handleSelectFeaturesOk, mapTypesOptions,\r\n handleModalUrlDialogCancel, onHandleOutsideClick, openFeatureSelectionDialog]);\r\n\r\n const options = React.useMemo(() => sources, [sources]);\r\n\r\n const filteredOptions = React.useMemo(() => {\r\n if (undefined === sourceFilterString || 0 === sourceFilterString.length) {\r\n return options;\r\n } else {\r\n return options?.filter((option) => option.name.toLowerCase().includes(sourceFilterString?.toLowerCase()));\r\n }\r\n }, [options, sourceFilterString]);\r\n\r\n const handleAddNewMapSource = React.useCallback(() => {\r\n UiFramework.dialogs.modal.open(<MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n onOkResult={(result?: SourceState) => handleModalUrlDialogOk(LayerAction.New, result)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />);\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n return;\r\n }, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, isOverlay, mapTypesOptions, onHandleOutsideClick]);\r\n\r\n const handleAttach = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleKeypressOnSourceList = React.useCallback((event: React.KeyboardEvent<HTMLUListElement>) => {\r\n const key = event.key;\r\n if (key === \"Enter\") {\r\n event.preventDefault();\r\n const mapName = event.currentTarget?.dataset?.value;\r\n if (mapName && mapName.length) {\r\n handleAttach(mapName);\r\n }\r\n }\r\n }, [handleAttach]);\r\n\r\n const onListboxValueChange = React.useCallback((mapName: string) => {\r\n setLayerNameToAdd(mapName);\r\n }, []);\r\n\r\n const handleNoConfirmation = React.useCallback((_layerName: string) => {\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [resumeOutsideClick]);\r\n\r\n const handleYesConfirmation = React.useCallback(async (source: MapLayerSource) => {\r\n const layerName = source.name;\r\n if (!!iTwinId) {\r\n try {\r\n await MapLayerPreferences.deleteByName(source, iTwinId, iModelId);\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefSuccess\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\r\n } catch (err: any) {\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefError\", { layerName });\r\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\r\n }\r\n }\r\n\r\n UiFramework.dialogs.modal.close();\r\n resumeOutsideClick();\r\n }, [iTwinId, iModelId, resumeOutsideClick]);\r\n\r\n /*\r\n Handle Remove layer button clicked\r\n */\r\n const onItemRemoveButtonClicked = React.useCallback((source, event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const layerName = source.name;\r\n\r\n const msg = MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.RemoveLayerDefDialogMessage\", { layerName });\r\n UiFramework.dialogs.modal.open(\r\n <ConfirmMessageDialog\r\n className=\"map-sources-delete-confirmation\"\r\n title={removeLayerDefDialogTitle}\r\n message={msg}\r\n maxWidth={400}\r\n onClose={() => handleNoConfirmation(layerName)}\r\n onEscape={() => handleNoConfirmation(layerName)}\r\n onYesResult={async () => handleYesConfirmation(source)}\r\n onNoResult={() => handleNoConfirmation(layerName)}\r\n />\r\n );\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }, [handleNoConfirmation, handleYesConfirmation, onHandleOutsideClick, removeLayerDefDialogTitle]);\r\n\r\n /*\r\n Handle Edit layer button clicked\r\n */\r\n const onItemEditButtonClicked = React.useCallback((event) => {\r\n event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.\r\n\r\n const targetLayerName = event?.currentTarget?.parentNode?.dataset?.value;\r\n const matchingSource = sources.find((layerSource) => layerSource.name === targetLayerName);\r\n\r\n // we expect a single layer source matching this name\r\n if (matchingSource === undefined) {\r\n return;\r\n }\r\n UiFramework.dialogs.modal.open(<MapUrlDialog\r\n activeViewport={activeViewport}\r\n isOverlay={isOverlay}\r\n mapLayerSourceToEdit={matchingSource}\r\n onOkResult={(result?: SourceState) => handleModalUrlDialogOk(LayerAction.Edit, result)}\r\n onCancelResult={handleModalUrlDialogCancel}\r\n mapTypesOptions={mapTypesOptions} />);\r\n\r\n if (onHandleOutsideClick) {\r\n onHandleOutsideClick(false);\r\n }\r\n }, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, isOverlay, mapTypesOptions, onHandleOutsideClick, sources]);\r\n\r\n return (\r\n <div className=\"map-manager-header\">\r\n {(loading || loadingSources) && <UiCore.LoadingSpinner message={loadingMapSources} />}\r\n <div className=\"map-manager-source-listbox-header\">\r\n <Input type=\"text\" className=\"map-manager-source-list-filter\"\r\n placeholder={placeholderLabel}\r\n value={sourceFilterString}\r\n onChange={handleFilterTextChanged}\r\n size=\"small\" />\r\n <Button className=\"map-manager-add-source-button\" title={addCustomLayerToolTip} onClick={handleAddNewMapSource}>\r\n {addCustomLayerLabel}</Button>\r\n </div>\r\n <div className=\"map-manager-sources\">\r\n <UiCore.Listbox\r\n id=\"map-sources\"\r\n selectedValue={layerNameToAdd}\r\n className=\"map-manager-source-list\"\r\n onKeyPress={handleKeypressOnSourceList}\r\n onListboxValueChange={onListboxValueChange} >\r\n {\r\n filteredOptions?.map((source) =>\r\n <UiCore.ListboxItem\r\n key={source.name}\r\n className=\"map-source-list-entry\"\r\n value={source.name}\r\n onMouseEnter={() => setLayerNameUnderCursor(source.name)}\r\n onMouseLeave={() => setLayerNameUnderCursor(undefined)}>\r\n <span className=\"map-source-list-entry-name\" title={source.name}>{source.name}</span>\r\n\r\n { // Display the delete icon only when the mouse over a specific item\r\n // otherwise list feels cluttered.\r\n (!!iTwinId && layerNameUnderCursor && layerNameUnderCursor === source.name) &&\r\n <>\r\n <Button\r\n size=\"small\"\r\n styleType=\"borderless\"\r\n className=\"map-source-list-entry-button\"\r\n title={editLayerDefButtonTitle}\r\n onClick={onItemEditButtonClicked}>\r\n <UiCore.Icon iconSpec=\"icon-edit\" />\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n styleType=\"borderless\"\r\n className=\"map-source-list-entry-button\"\r\n title={removeLayerDefButtonTitle}\r\n onClick={(event: React.MouseEvent) => { onItemRemoveButtonClicked(source, event); }}>\r\n <UiCore.Icon iconSpec=\"icon-delete\" />\r\n </Button>\r\n </>}\r\n\r\n </UiCore.ListboxItem>\r\n )\r\n }\r\n </UiCore.Listbox>\r\n </div>\r\n </div>\r\n\r\n );\r\n}\r\n\r\n/** @internal */\r\nexport enum AttachLayerButtonType {\r\n Primary,\r\n Blue,\r\n Icon\r\n}\r\nexport interface AttachLayerPopupButtonProps {\r\n isOverlay: boolean;\r\n buttonType?: AttachLayerButtonType;\r\n disabled?: boolean;\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function AttachLayerPopupButton(props: AttachLayerPopupButtonProps) {\r\n const { showAttachLayerLabel, hideAttachLayerLabel, addCustomLayerButtonLabel } = React.useMemo(() => {\r\n return {\r\n showAttachLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Attach\"),\r\n hideAttachLayerLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:AttachLayerPopup.Close\"),\r\n addCustomLayerButtonLabel: MapLayersUI.localization.getLocalizedString(\"mapLayers:CustomAttach.AddCustomLayerButtonLabel\"),\r\n };\r\n }, []);\r\n\r\n const [handleOutsideClick, setHandleOutsideClick] = React.useState(true);\r\n const [popupOpen, setPopupOpen] = React.useState(false);\r\n const buttonRef = React.useRef<HTMLButtonElement>(null);\r\n const panelRef = React.useRef<HTMLDivElement>(null);\r\n\r\n // 'isMounted' is used to prevent any async operation once the hook has been\r\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\r\n const isMounted = React.useRef(false);\r\n React.useEffect(() => {\r\n isMounted.current = true;\r\n return () => {\r\n isMounted.current = false;\r\n };\r\n }, []);\r\n\r\n const togglePopup = React.useCallback(() => {\r\n setPopupOpen(!popupOpen);\r\n }, [popupOpen]);\r\n\r\n const handleClosePopup = React.useCallback(() => {\r\n setPopupOpen(false);\r\n }, []);\r\n\r\n const onHandleOutsideClick = React.useCallback((event: MouseEvent) => {\r\n if (!handleOutsideClick) {\r\n return;\r\n }\r\n\r\n // If clicking on button that open panel - don't trigger outside click processing\r\n if (buttonRef?.current && buttonRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If clicking the panel, this is not an outside clicked\r\n if (panelRef.current && panelRef?.current.contains(event.target as Node)) {\r\n return;\r\n }\r\n\r\n // If we reach this point, we got an outside clicked, no close the popup\r\n setPopupOpen(false);\r\n\r\n }, [handleOutsideClick]);\r\n\r\n const { refreshFromStyle } = useSourceMapContext();\r\n\r\n const handleLayerAttached = React.useCallback(() => {\r\n if (!isMounted.current) {\r\n return;\r\n }\r\n setPopupOpen(false);\r\n refreshFromStyle();\r\n }, [refreshFromStyle]);\r\n\r\n function renderButton(): React.ReactNode {\r\n let button: React.ReactNode;\r\n\r\n if (props.buttonType === undefined || props.buttonType === AttachLayerButtonType.Icon) {\r\n button = (\r\n <Button disabled={props.disabled} size=\"small\" styleType=\"borderless\" ref={buttonRef} className=\"map-manager-attach-layer-button\" title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>\r\n <UiCore.WebFontIcon iconName=\"icon-add\" />\r\n </Button>\r\n );\r\n } else {\r\n const determineStyleType = () => {\r\n switch (props.buttonType) {\r\n case AttachLayerButtonType.Blue:\r\n return \"high-visibility\";\r\n case AttachLayerButtonType.Primary:\r\n default:\r\n return \"cta\";\r\n }\r\n };\r\n const styleType = determineStyleType();\r\n button = (\r\n <Button disabled={props.disabled} ref={buttonRef} styleType={styleType} title={popupOpen ? hideAttachLayerLabel : showAttachLayerLabel}\r\n onClick={togglePopup}>{addCustomLayerButtonLabel}</Button>\r\n );\r\n }\r\n\r\n return button;\r\n }\r\n\r\n return (\r\n <>\r\n {renderButton()}\r\n <UiCore.Popup\r\n isOpen={popupOpen}\r\n position={RelativePosition.BottomRight}\r\n onClose={handleClosePopup}\r\n onOutsideClick={onHandleOutsideClick}\r\n closeOnWheel={false}\r\n target={buttonRef.current}\r\n closeOnEnter={false}\r\n closeOnContextMenu={false}\r\n >\r\n <div ref={panelRef} className=\"map-sources-popup-panel\" >\r\n <AttachLayerPanel\r\n isOverlay={props.isOverlay}\r\n onLayerAttached={handleLayerAttached}\r\n onHandleOutsideClick={setHandleOutsideClick} />\r\n </div>\r\n </UiCore.Popup >\r\n </>\r\n );\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BasemapPanel.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/BasemapPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BasemapPanel.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/BasemapPanel.tsx"],"names":[],"mappings":"AAgBA,OAAO,qBAAqB,CAAC;AAY7B,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,gBAAgB;AAEhB,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,eAiLpD"}
|