@itwin/map-layers 3.0.0-dev.78 → 3.0.0-dev.82
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/lib/{map-layers.d.ts → cjs/map-layers.d.ts} +0 -0
- package/lib/cjs/map-layers.d.ts.map +1 -0
- package/lib/{map-layers.js → cjs/map-layers.js} +0 -0
- package/lib/cjs/map-layers.js.map +1 -0
- package/lib/{mapLayers.d.ts → cjs/mapLayers.d.ts} +0 -0
- package/lib/cjs/mapLayers.d.ts.map +1 -0
- package/lib/{mapLayers.js → cjs/mapLayers.js} +0 -0
- package/lib/cjs/mapLayers.js.map +1 -0
- package/lib/{public → cjs/public}/locales/en/mapLayers.json +0 -0
- package/lib/{ui → cjs/ui}/Interfaces.d.ts +0 -0
- package/lib/cjs/ui/Interfaces.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/Interfaces.js +0 -0
- package/lib/cjs/ui/Interfaces.js.map +1 -0
- package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.d.ts +0 -0
- package/lib/cjs/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.js +0 -0
- package/lib/cjs/ui/MapLayersUiItemsProvider.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.js +0 -0
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.d.ts +0 -0
- package/lib/cjs/ui/widget/BasemapPanel.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.js +0 -0
- package/lib/cjs/ui/widget/BasemapPanel.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.d.ts +0 -0
- package/lib/cjs/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.js +0 -0
- package/lib/cjs/ui/widget/ConfirmMessageDialog.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.js +0 -0
- package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerManager.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.js +0 -0
- package/lib/cjs/ui/widget/MapLayerManager.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.js +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsMenu.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.js +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapLayersWidget.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayersWidget.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayersWidget.js +0 -0
- package/lib/cjs/ui/widget/MapLayersWidget.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.d.ts +0 -0
- package/lib/cjs/ui/widget/MapManagerSettings.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.js +0 -0
- package/lib/cjs/ui/widget/MapManagerSettings.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.d.ts +0 -0
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.js +0 -0
- package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.js +0 -0
- package/lib/cjs/ui/widget/SubLayersDataProvider.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.js +0 -0
- package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.js +0 -0
- package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.js +0 -0
- package/lib/cjs/ui/widget/TransparencyPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.scss +1 -1
- package/lib/esm/map-layers.d.ts +5 -0
- package/lib/esm/map-layers.d.ts.map +1 -0
- package/lib/esm/map-layers.js +9 -0
- package/lib/esm/map-layers.js.map +1 -0
- package/lib/esm/mapLayers.d.ts +29 -0
- package/lib/esm/mapLayers.d.ts.map +1 -0
- package/lib/esm/mapLayers.js +50 -0
- package/lib/esm/mapLayers.js.map +1 -0
- package/lib/esm/public/locales/en/mapLayers.json +113 -0
- package/lib/esm/ui/Interfaces.d.ts +32 -0
- package/lib/esm/ui/Interfaces.d.ts.map +1 -0
- package/lib/esm/ui/Interfaces.js +2 -0
- package/lib/esm/ui/Interfaces.js.map +1 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.d.ts +23 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.js +50 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.js.map +1 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts +14 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.js +308 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.d.ts +5 -0
- package/lib/esm/ui/widget/BasemapPanel.d.ts.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.js +141 -0
- package/lib/esm/ui/widget/BasemapPanel.js.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.scss +98 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts +22 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.js +22 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts +19 -0
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerDroppable.js +80 -0
- package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.d.ts +27 -0
- package/lib/esm/ui/widget/MapLayerManager.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.js +347 -0
- package/lib/esm/ui/widget/MapLayerManager.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.scss +525 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts +10 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.js +79 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts +5 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js +31 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.scss +31 -0
- package/lib/esm/ui/widget/MapLayersWidget.d.ts +12 -0
- package/lib/esm/ui/widget/MapLayersWidget.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayersWidget.js +23 -0
- package/lib/esm/ui/widget/MapLayersWidget.js.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.d.ts +4 -0
- package/lib/esm/ui/widget/MapManagerSettings.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.js +168 -0
- package/lib/esm/ui/widget/MapManagerSettings.js.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.scss +23 -0
- package/lib/esm/ui/widget/MapUrlDialog.d.ts +23 -0
- package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapUrlDialog.js +346 -0
- package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -0
- package/lib/esm/ui/widget/MapUrlDialog.scss +85 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts +21 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.js +73 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.d.ts +11 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.js +36 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.d.ts +16 -0
- package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.js +374 -0
- package/lib/esm/ui/widget/SubLayersTree.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.scss +64 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.d.ts +14 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.js +44 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.scss +53 -0
- package/lib/public/en/mapLayers.json +113 -0
- package/package.json +45 -39
- package/lib/map-layers.d.ts.map +0 -1
- package/lib/map-layers.js.map +0 -1
- package/lib/mapLayers.d.ts.map +0 -1
- package/lib/mapLayers.js.map +0 -1
- package/lib/ui/Interfaces.d.ts.map +0 -1
- package/lib/ui/Interfaces.js.map +0 -1
- package/lib/ui/MapLayersUiItemsProvider.d.ts.map +0 -1
- package/lib/ui/MapLayersUiItemsProvider.js.map +0 -1
- package/lib/ui/widget/AttachLayerPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/AttachLayerPopupButton.js.map +0 -1
- package/lib/ui/widget/BasemapPanel.d.ts.map +0 -1
- package/lib/ui/widget/BasemapPanel.js.map +0 -1
- package/lib/ui/widget/ConfirmMessageDialog.d.ts.map +0 -1
- package/lib/ui/widget/ConfirmMessageDialog.js.map +0 -1
- package/lib/ui/widget/MapLayerDroppable.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerDroppable.js.map +0 -1
- package/lib/ui/widget/MapLayerManager.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerManager.js.map +0 -1
- package/lib/ui/widget/MapLayerSettingsMenu.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerSettingsMenu.js.map +0 -1
- package/lib/ui/widget/MapLayerSettingsPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerSettingsPopupButton.js.map +0 -1
- package/lib/ui/widget/MapLayersWidget.d.ts.map +0 -1
- package/lib/ui/widget/MapLayersWidget.js.map +0 -1
- package/lib/ui/widget/MapManagerSettings.d.ts.map +0 -1
- package/lib/ui/widget/MapManagerSettings.js.map +0 -1
- package/lib/ui/widget/MapUrlDialog.d.ts.map +0 -1
- package/lib/ui/widget/MapUrlDialog.js.map +0 -1
- package/lib/ui/widget/SubLayersDataProvider.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersDataProvider.js.map +0 -1
- package/lib/ui/widget/SubLayersPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersPopupButton.js.map +0 -1
- package/lib/ui/widget/SubLayersTree.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersTree.js.map +0 -1
- package/lib/ui/widget/TransparencyPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/TransparencyPopupButton.js.map +0 -1
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
// cSpell:ignore Modeless WMTS
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { Input, LabeledInput, ProgressLinear, Radio, Select } from "@itwin/itwinui-react";
|
|
8
|
+
import { Dialog, Icon, InputStatus } from "@itwin/core-react";
|
|
9
|
+
import { ModalDialogManager } from "@itwin/appui-react";
|
|
10
|
+
import { MapLayersUiItemsProvider } from "../MapLayersUiItemsProvider";
|
|
11
|
+
import { IModelApp, MapLayerImageryProviderStatus, MapLayerSettingsService, MapLayerSource, MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority, } from "@itwin/core-frontend";
|
|
12
|
+
import "./MapUrlDialog.scss";
|
|
13
|
+
import { DialogButtonType, SpecialKey } from "@itwin/appui-abstract";
|
|
14
|
+
export const MAP_TYPES = {
|
|
15
|
+
wms: "WMS",
|
|
16
|
+
arcGis: "ArcGIS",
|
|
17
|
+
wmts: "WMTS",
|
|
18
|
+
tileUrl: "TileURL",
|
|
19
|
+
};
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
21
|
+
export function MapUrlDialog(props) {
|
|
22
|
+
var _a, _b, _c, _d, _e, _f;
|
|
23
|
+
const { isOverlay, onOkResult, mapTypesOptions } = props;
|
|
24
|
+
const supportWmsAuthentication = ((mapTypesOptions === null || mapTypesOptions === void 0 ? void 0 : mapTypesOptions.supportWmsAuthentication) ? true : false);
|
|
25
|
+
const getMapUrlFromProps = React.useCallback(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
if (props.mapLayerSourceToEdit) {
|
|
28
|
+
return props.mapLayerSourceToEdit.url;
|
|
29
|
+
}
|
|
30
|
+
else if ((_a = props.layerRequiringCredentials) === null || _a === void 0 ? void 0 : _a.url) {
|
|
31
|
+
return props.layerRequiringCredentials.url;
|
|
32
|
+
}
|
|
33
|
+
return "";
|
|
34
|
+
}, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);
|
|
35
|
+
const getMapNameFromProps = React.useCallback(() => {
|
|
36
|
+
var _a;
|
|
37
|
+
if (props.mapLayerSourceToEdit) {
|
|
38
|
+
return props.mapLayerSourceToEdit.name;
|
|
39
|
+
}
|
|
40
|
+
else if ((_a = props.layerRequiringCredentials) === null || _a === void 0 ? void 0 : _a.name) {
|
|
41
|
+
return props.layerRequiringCredentials.name;
|
|
42
|
+
}
|
|
43
|
+
return "";
|
|
44
|
+
}, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);
|
|
45
|
+
const getFormatFromProps = React.useCallback(() => {
|
|
46
|
+
var _a;
|
|
47
|
+
if (props.mapLayerSourceToEdit) {
|
|
48
|
+
return props.mapLayerSourceToEdit.formatId;
|
|
49
|
+
}
|
|
50
|
+
else if ((_a = props.layerRequiringCredentials) === null || _a === void 0 ? void 0 : _a.formatId) {
|
|
51
|
+
return props.layerRequiringCredentials.formatId;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);
|
|
55
|
+
const [dialogTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(props.layerRequiringCredentials || props.mapLayerSourceToEdit ? "mapLayers:CustomAttach.EditCustomLayer" : "mapLayers:CustomAttach.AttachCustomLayer"));
|
|
56
|
+
const [typeLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.Type"));
|
|
57
|
+
const [nameLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.Name"));
|
|
58
|
+
const [nameInputPlaceHolder] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.NameInputPlaceHolder"));
|
|
59
|
+
const [urlLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.URL"));
|
|
60
|
+
const [urlInputPlaceHolder] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.UrlInputPlaceHolder"));
|
|
61
|
+
const [iTwinSettingsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.StoreOnITwinSettings"));
|
|
62
|
+
const [modelSettingsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.StoreOnModelSettings"));
|
|
63
|
+
const [missingCredentialsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.MissingCredentials"));
|
|
64
|
+
const [invalidCredentialsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.InvalidCredentials"));
|
|
65
|
+
const [serverRequireCredentials, setServerRequireCredentials] = React.useState((_a = props.layerRequiringCredentials) !== null && _a !== void 0 ? _a : false);
|
|
66
|
+
const [invalidCredentialsProvided, setInvalidCredentialsProvided] = React.useState(false);
|
|
67
|
+
const [layerAttachPending, setLayerAttachPending] = React.useState(false);
|
|
68
|
+
const [warningMessage, setWarningMessage] = React.useState(props.layerRequiringCredentials ? missingCredentialsLabel : undefined);
|
|
69
|
+
const [mapUrl, setMapUrl] = React.useState(getMapUrlFromProps());
|
|
70
|
+
const [mapName, setMapName] = React.useState(getMapNameFromProps());
|
|
71
|
+
const [userName, setUserName] = React.useState("");
|
|
72
|
+
const [password, setPassword] = React.useState("");
|
|
73
|
+
const [noSaveSettingsWarning] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.NoSaveSettingsWarning"));
|
|
74
|
+
const [passwordLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AuthenticationInputs.Password"));
|
|
75
|
+
const [passwordRequiredLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AuthenticationInputs.PasswordRequired"));
|
|
76
|
+
const [userNameLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AuthenticationInputs.Username"));
|
|
77
|
+
const [userNameRequiredLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:AuthenticationInputs.UsernameRequired"));
|
|
78
|
+
const [settingsStorage, setSettingsStorageRadio] = React.useState("ITwin");
|
|
79
|
+
const [mapType, setMapType] = React.useState((_b = getFormatFromProps()) !== null && _b !== void 0 ? _b : MAP_TYPES.arcGis);
|
|
80
|
+
// 'isMounted' is used to prevent any async operation once the hook has been
|
|
81
|
+
// unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.
|
|
82
|
+
const isMounted = React.useRef(false);
|
|
83
|
+
React.useEffect(() => {
|
|
84
|
+
isMounted.current = true;
|
|
85
|
+
return () => {
|
|
86
|
+
isMounted.current = false;
|
|
87
|
+
};
|
|
88
|
+
}, []);
|
|
89
|
+
const [mapTypes] = React.useState(() => {
|
|
90
|
+
const types = [
|
|
91
|
+
{ value: MAP_TYPES.arcGis, label: MAP_TYPES.arcGis },
|
|
92
|
+
{ value: MAP_TYPES.wms, label: MAP_TYPES.wms },
|
|
93
|
+
{ value: MAP_TYPES.wmts, label: MAP_TYPES.wmts },
|
|
94
|
+
];
|
|
95
|
+
if (mapTypesOptions === null || mapTypesOptions === void 0 ? void 0 : mapTypesOptions.supportTileUrl)
|
|
96
|
+
types.push({ value: MAP_TYPES.tileUrl, label: MAP_TYPES.tileUrl });
|
|
97
|
+
return types;
|
|
98
|
+
});
|
|
99
|
+
const [isSettingsStorageAvailable] = React.useState(((_d = (_c = props === null || props === void 0 ? void 0 : props.activeViewport) === null || _c === void 0 ? void 0 : _c.iModel) === null || _d === void 0 ? void 0 : _d.iTwinId) && ((_f = (_e = props === null || props === void 0 ? void 0 : props.activeViewport) === null || _e === void 0 ? void 0 : _e.iModel) === null || _f === void 0 ? void 0 : _f.iModelId));
|
|
100
|
+
// Even though the settings storage is available,
|
|
101
|
+
// we don't always want to enable it in the UI.
|
|
102
|
+
const [settingsStorageDisabled] = React.useState(!isSettingsStorageAvailable || props.mapLayerSourceToEdit !== undefined || props.layerRequiringCredentials !== undefined);
|
|
103
|
+
const isAuthSupported = React.useCallback(() => {
|
|
104
|
+
return ((mapType === MAP_TYPES.wms || mapType === MAP_TYPES.wms) && supportWmsAuthentication)
|
|
105
|
+
|| mapType === MAP_TYPES.arcGis;
|
|
106
|
+
}, [mapType, supportWmsAuthentication]);
|
|
107
|
+
// const [layerIdxToEdit] = React.useState((): number | undefined => {
|
|
108
|
+
const [layerRequiringCredentialsIdx] = React.useState(() => {
|
|
109
|
+
var _a;
|
|
110
|
+
if (props.layerRequiringCredentials === undefined || !props.layerRequiringCredentials.name || !props.layerRequiringCredentials.url) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
const indexInDisplayStyle = (_a = props.activeViewport) === null || _a === void 0 ? void 0 : _a.displayStyle.findMapLayerIndexByNameAndUrl(props.layerRequiringCredentials.name, props.layerRequiringCredentials.url, isOverlay);
|
|
114
|
+
if (indexInDisplayStyle === undefined || indexInDisplayStyle < 0) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
return indexInDisplayStyle;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// Update warning message based on the dialog state and server response
|
|
122
|
+
React.useEffect(() => {
|
|
123
|
+
if (invalidCredentialsProvided) {
|
|
124
|
+
setWarningMessage(invalidCredentialsLabel);
|
|
125
|
+
}
|
|
126
|
+
else if (serverRequireCredentials && (!userName || !password)) {
|
|
127
|
+
setWarningMessage(missingCredentialsLabel);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
setWarningMessage(undefined);
|
|
131
|
+
}
|
|
132
|
+
}, [invalidCredentialsProvided, invalidCredentialsLabel, missingCredentialsLabel, serverRequireCredentials, userName, password, setWarningMessage]);
|
|
133
|
+
const handleMapTypeSelection = React.useCallback((newValue) => {
|
|
134
|
+
setMapType(newValue);
|
|
135
|
+
}, [setMapType]);
|
|
136
|
+
const handleCancel = React.useCallback(() => {
|
|
137
|
+
if (props.onCancelResult) {
|
|
138
|
+
props.onCancelResult();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
ModalDialogManager.closeDialog();
|
|
142
|
+
}, [props]);
|
|
143
|
+
const onUsernameChange = React.useCallback((event) => {
|
|
144
|
+
setUserName(event.target.value);
|
|
145
|
+
if (invalidCredentialsProvided)
|
|
146
|
+
setInvalidCredentialsProvided(false);
|
|
147
|
+
}, [setUserName, invalidCredentialsProvided, setInvalidCredentialsProvided]);
|
|
148
|
+
const onPasswordChange = React.useCallback((event) => {
|
|
149
|
+
setPassword(event.target.value);
|
|
150
|
+
if (invalidCredentialsProvided)
|
|
151
|
+
setInvalidCredentialsProvided(false);
|
|
152
|
+
}, [setPassword, invalidCredentialsProvided, setInvalidCredentialsProvided]);
|
|
153
|
+
const doAttach = React.useCallback(async (source) => {
|
|
154
|
+
// Returns a promise, When true, the dialog should closed
|
|
155
|
+
return new Promise((resolve, _reject) => {
|
|
156
|
+
const vp = props === null || props === void 0 ? void 0 : props.activeViewport;
|
|
157
|
+
if (vp === undefined || source === undefined) {
|
|
158
|
+
resolve(true);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const storeOnIModel = "Model" === settingsStorage;
|
|
162
|
+
source.validateSource(true).then(async (validation) => {
|
|
163
|
+
if (validation.status === MapLayerSourceStatus.Valid
|
|
164
|
+
|| validation.status === MapLayerSourceStatus.RequireAuth
|
|
165
|
+
|| validation.status === MapLayerSourceStatus.InvalidCredentials) {
|
|
166
|
+
const sourceRequireAuth = (validation.status === MapLayerSourceStatus.RequireAuth);
|
|
167
|
+
const invalidCredentials = (validation.status === MapLayerSourceStatus.InvalidCredentials);
|
|
168
|
+
const closeDialog = !sourceRequireAuth && !invalidCredentials;
|
|
169
|
+
resolve(closeDialog);
|
|
170
|
+
if (sourceRequireAuth && !serverRequireCredentials) {
|
|
171
|
+
setServerRequireCredentials(true);
|
|
172
|
+
}
|
|
173
|
+
if (invalidCredentials) {
|
|
174
|
+
setInvalidCredentialsProvided(true);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
else if (invalidCredentialsProvided) {
|
|
178
|
+
setInvalidCredentialsProvided(false); // flag reset
|
|
179
|
+
}
|
|
180
|
+
if (validation.status === MapLayerSourceStatus.Valid) {
|
|
181
|
+
// Attach layer and update settings service (only if editing)
|
|
182
|
+
if (layerRequiringCredentialsIdx !== undefined) {
|
|
183
|
+
// Update username / password
|
|
184
|
+
vp.displayStyle.changeMapLayerProps({
|
|
185
|
+
subLayers: validation.subLayers,
|
|
186
|
+
}, layerRequiringCredentialsIdx, isOverlay);
|
|
187
|
+
vp.displayStyle.changeMapLayerCredentials(layerRequiringCredentialsIdx, isOverlay, source.userName, source.password);
|
|
188
|
+
// Reset the provider's status
|
|
189
|
+
const provider = vp.getMapLayerImageryProvider(layerRequiringCredentialsIdx, isOverlay);
|
|
190
|
+
if (provider && provider.status !== MapLayerImageryProviderStatus.Valid) {
|
|
191
|
+
provider.status = MapLayerImageryProviderStatus.Valid;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Update service settings if storage is available and we are not prompting user for credentials
|
|
196
|
+
if (!settingsStorageDisabled && !props.layerRequiringCredentials) {
|
|
197
|
+
if (!(await MapLayerSettingsService.storeSourceInSettingsService(source, storeOnIModel, vp.iModel.iTwinId, vp.iModel.iModelId)))
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const layerSettings = source.toLayerSettings(validation.subLayers);
|
|
201
|
+
if (layerSettings) {
|
|
202
|
+
vp.displayStyle.attachMapLayerSettings(layerSettings, isOverlay, undefined);
|
|
203
|
+
const msg = IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerAttached", { sourceName: source.name, sourceUrl: source.url });
|
|
204
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
const msgError = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:Messages.MapLayerLayerSettingsConversionError");
|
|
208
|
+
const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.MapLayerAttachError", { error: msgError, sourceUrl: source.url });
|
|
209
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
vp.invalidateRenderPlan();
|
|
213
|
+
}
|
|
214
|
+
if (closeDialog) {
|
|
215
|
+
// This handler will close the layer source handler, and therefore the MapUrl dialog.
|
|
216
|
+
// don't call it if the dialog needs to remains open.
|
|
217
|
+
onOkResult();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.ValidationError");
|
|
222
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, `${msg} ${source.url}`));
|
|
223
|
+
resolve(true);
|
|
224
|
+
}
|
|
225
|
+
resolve(false);
|
|
226
|
+
}).catch((error) => {
|
|
227
|
+
const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.MapLayerAttachError", { error, sourceUrl: source.url });
|
|
228
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
|
|
229
|
+
resolve(true);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
}, [props.activeViewport, props.layerRequiringCredentials, settingsStorage, serverRequireCredentials, invalidCredentialsProvided, onOkResult, layerRequiringCredentialsIdx, isOverlay, settingsStorageDisabled]);
|
|
233
|
+
const onNameChange = React.useCallback((event) => {
|
|
234
|
+
setMapName(event.target.value);
|
|
235
|
+
}, [setMapName]);
|
|
236
|
+
const onRadioChange = React.useCallback((event) => {
|
|
237
|
+
setSettingsStorageRadio(event.target.value);
|
|
238
|
+
}, [setSettingsStorageRadio]);
|
|
239
|
+
const onUrlChange = React.useCallback((event) => {
|
|
240
|
+
setMapUrl(event.target.value);
|
|
241
|
+
}, [setMapUrl]);
|
|
242
|
+
const handleOk = React.useCallback(() => {
|
|
243
|
+
let source;
|
|
244
|
+
if (mapUrl && mapName) {
|
|
245
|
+
source = MapLayerSource.fromJSON({
|
|
246
|
+
url: mapUrl,
|
|
247
|
+
name: mapName,
|
|
248
|
+
formatId: mapType,
|
|
249
|
+
userName,
|
|
250
|
+
password,
|
|
251
|
+
});
|
|
252
|
+
if (source === undefined || props.mapLayerSourceToEdit) {
|
|
253
|
+
ModalDialogManager.closeDialog();
|
|
254
|
+
if (source === undefined) {
|
|
255
|
+
// Close the dialog and inform end user something went wrong.
|
|
256
|
+
const msgError = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:Messages.MapLayerLayerSourceCreationFailed");
|
|
257
|
+
const msg = MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:CustomAttach.MapLayerAttachError", { error: msgError, sourceUrl: mapUrl });
|
|
258
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// Simply change the source definition in the setting service
|
|
262
|
+
if (props.mapLayerSourceToEdit !== undefined) {
|
|
263
|
+
const vp = props.activeViewport;
|
|
264
|
+
void (async () => {
|
|
265
|
+
var _a;
|
|
266
|
+
if (isSettingsStorageAvailable && vp) {
|
|
267
|
+
if (!(await MapLayerSettingsService.replaceSourceInSettingsService(props.mapLayerSourceToEdit, source, vp.iModel.iTwinId, vp.iModel.iModelId))) {
|
|
268
|
+
const errorMessage = IModelApp.localization.getLocalizedString("mapLayers:Messages.MapLayerEditError", { layerName: (_a = props.mapLayerSourceToEdit) === null || _a === void 0 ? void 0 : _a.name });
|
|
269
|
+
IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, errorMessage));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
})();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
setLayerAttachPending(true);
|
|
278
|
+
void (async () => {
|
|
279
|
+
// Code below is executed in the an async manner but
|
|
280
|
+
// I don't necessarily want to mark the handler as async
|
|
281
|
+
// so Im wrapping it un in a void wrapper.
|
|
282
|
+
try {
|
|
283
|
+
const closeDialog = await doAttach(source);
|
|
284
|
+
if (isMounted.current) {
|
|
285
|
+
setLayerAttachPending(false);
|
|
286
|
+
}
|
|
287
|
+
// In theory the modal dialog should always get closed by the parent
|
|
288
|
+
// AttachLayerPanel's 'onOkResult' handler. We close it here just in case.
|
|
289
|
+
if (closeDialog) {
|
|
290
|
+
ModalDialogManager.closeDialog();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (_error) {
|
|
294
|
+
ModalDialogManager.closeDialog();
|
|
295
|
+
}
|
|
296
|
+
})();
|
|
297
|
+
}
|
|
298
|
+
}, [mapUrl, mapName, mapType, userName, password, props.mapLayerSourceToEdit, props.activeViewport, isSettingsStorageAvailable, doAttach]);
|
|
299
|
+
const dialogContainer = React.useRef(null);
|
|
300
|
+
const readyToSave = React.useCallback(() => {
|
|
301
|
+
const credentialsSet = !!userName && !!password;
|
|
302
|
+
return (!!mapUrl && !!mapName)
|
|
303
|
+
&& (!serverRequireCredentials || (serverRequireCredentials && credentialsSet) && !layerAttachPending)
|
|
304
|
+
&& !invalidCredentialsProvided;
|
|
305
|
+
}, [mapUrl, mapName, userName, password, layerAttachPending, invalidCredentialsProvided, serverRequireCredentials]);
|
|
306
|
+
const buttonCluster = React.useMemo(() => [
|
|
307
|
+
{ type: DialogButtonType.OK, onClick: handleOk, disabled: !readyToSave() },
|
|
308
|
+
{ type: DialogButtonType.Cancel, onClick: handleCancel },
|
|
309
|
+
], [readyToSave, handleCancel, handleOk]);
|
|
310
|
+
const handleOnKeyDown = React.useCallback((event) => {
|
|
311
|
+
if (event.key === SpecialKey.Enter) {
|
|
312
|
+
if (readyToSave())
|
|
313
|
+
handleOk();
|
|
314
|
+
}
|
|
315
|
+
}, [handleOk, readyToSave]);
|
|
316
|
+
return (React.createElement("div", { ref: dialogContainer },
|
|
317
|
+
React.createElement(Dialog, { className: "map-layer-url-dialog", title: dialogTitle, opened: true, resizable: true, movable: true, modal: true, buttonCluster: buttonCluster, onClose: handleCancel, onEscape: handleCancel, minHeight: 120, maxWidth: 600, trapFocus: false },
|
|
318
|
+
React.createElement("div", null,
|
|
319
|
+
React.createElement("div", { className: "map-layer-source-url" },
|
|
320
|
+
React.createElement("span", { className: "map-layer-source-label" }, typeLabel),
|
|
321
|
+
React.createElement(Select, { className: "map-manager-base-select", options: mapTypes, value: mapType, disabled: props.layerRequiringCredentials !== undefined || props.mapLayerSourceToEdit !== undefined, onChange: handleMapTypeSelection }),
|
|
322
|
+
React.createElement("span", { className: "map-layer-source-label" }, nameLabel),
|
|
323
|
+
React.createElement(Input, { placeholder: nameInputPlaceHolder, onChange: onNameChange, value: mapName, disabled: props.layerRequiringCredentials !== undefined }),
|
|
324
|
+
React.createElement("span", { className: "map-layer-source-label" }, urlLabel),
|
|
325
|
+
React.createElement(Input, { placeholder: urlInputPlaceHolder, onKeyPress: handleOnKeyDown, onChange: onUrlChange, disabled: props.mapLayerSourceToEdit !== undefined, value: mapUrl }),
|
|
326
|
+
isAuthSupported() && props.mapLayerSourceToEdit === undefined &&
|
|
327
|
+
React.createElement(React.Fragment, null,
|
|
328
|
+
React.createElement("span", { className: "map-layer-source-label" }, userNameLabel),
|
|
329
|
+
React.createElement(LabeledInput, { placeholder: serverRequireCredentials ? userNameRequiredLabel : userNameLabel, status: !userName && serverRequireCredentials ? InputStatus.Warning : undefined, onChange: onUsernameChange }),
|
|
330
|
+
React.createElement("span", { className: "map-layer-source-label" }, passwordLabel),
|
|
331
|
+
React.createElement(LabeledInput, { type: "password", placeholder: serverRequireCredentials ? passwordRequiredLabel : passwordLabel, status: !password && serverRequireCredentials ? InputStatus.Warning : undefined, onChange: onPasswordChange, onKeyPress: handleOnKeyDown })),
|
|
332
|
+
isSettingsStorageAvailable && React.createElement("div", { title: settingsStorageDisabled ? noSaveSettingsWarning : "" },
|
|
333
|
+
React.createElement(Radio, { disabled: settingsStorageDisabled, name: "settingsStorage", value: "iTwin", label: iTwinSettingsLabel, checked: settingsStorage === "iTwin", onChange: onRadioChange }),
|
|
334
|
+
React.createElement(Radio, { disabled: settingsStorageDisabled, name: "settingsStorage", value: "Model", label: modelSettingsLabel, checked: settingsStorage === "Model", onChange: onRadioChange })))),
|
|
335
|
+
React.createElement("div", { className: "map-layer-source-warnMessage" }, warningMessage ?
|
|
336
|
+
React.createElement(React.Fragment, null,
|
|
337
|
+
React.createElement(Icon, { className: "map-layer-source-warnMessage-icon", iconSpec: "icon-status-warning" }),
|
|
338
|
+
React.createElement("span", { className: "map-layer-source-warnMessage-label" }, warningMessage))
|
|
339
|
+
:
|
|
340
|
+
// Place holder to avoid dialog resize
|
|
341
|
+
React.createElement("span", { className: "map-layer-source-placeholder" }, "\u00A0")),
|
|
342
|
+
layerAttachPending &&
|
|
343
|
+
React.createElement("div", { className: "map-layer-source-progressBar" },
|
|
344
|
+
React.createElement(ProgressLinear, { indeterminate: true })))));
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=MapUrlDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MapUrlDialog.js","sourceRoot":"","sources":["../../../../src/ui/widget/MapUrlDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n// cSpell:ignore Modeless WMTS\n\nimport * as React from \"react\";\nimport { Input, LabeledInput, ProgressLinear, Radio, Select, SelectOption } from \"@itwin/itwinui-react\";\nimport { Dialog, Icon, InputStatus } from \"@itwin/core-react\";\nimport { ModalDialogManager } from \"@itwin/appui-react\";\nimport { MapLayersUiItemsProvider } from \"../MapLayersUiItemsProvider\";\nimport { MapTypesOptions } from \"../Interfaces\";\nimport {\n IModelApp, MapLayerImageryProviderStatus, MapLayerSettingsService, MapLayerSource,\n MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority, ScreenViewport,\n} from \"@itwin/core-frontend\";\nimport { MapLayerProps } from \"@itwin/core-common\";\nimport \"./MapUrlDialog.scss\";\nimport { DialogButtonType, SpecialKey } from \"@itwin/appui-abstract\";\n\nexport const MAP_TYPES = {\n wms: \"WMS\",\n arcGis: \"ArcGIS\",\n wmts: \"WMTS\",\n tileUrl: \"TileURL\",\n};\n\ninterface MapUrlDialogProps {\n activeViewport?: ScreenViewport;\n isOverlay: boolean;\n onOkResult: () => void;\n onCancelResult?: () => void;\n mapTypesOptions?: MapTypesOptions;\n\n // An optional layer definition can be provide to enable the edit mode\n layerRequiringCredentials?: MapLayerProps;\n\n mapLayerSourceToEdit?: MapLayerSource;\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function MapUrlDialog(props: MapUrlDialogProps) {\n const { isOverlay, onOkResult, mapTypesOptions } = props;\n const supportWmsAuthentication = (mapTypesOptions?.supportWmsAuthentication ? true : false);\n\n const getMapUrlFromProps = React.useCallback(() => {\n if (props.mapLayerSourceToEdit) {\n return props.mapLayerSourceToEdit.url;\n } else if (props.layerRequiringCredentials?.url) {\n return props.layerRequiringCredentials.url;\n }\n return \"\";\n }, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);\n\n const getMapNameFromProps = React.useCallback(() => {\n if (props.mapLayerSourceToEdit) {\n return props.mapLayerSourceToEdit.name;\n } else if (props.layerRequiringCredentials?.name) {\n return props.layerRequiringCredentials.name;\n }\n return \"\";\n }, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);\n\n const getFormatFromProps = React.useCallback(() => {\n if (props.mapLayerSourceToEdit) {\n return props.mapLayerSourceToEdit.formatId;\n } else if (props.layerRequiringCredentials?.formatId) {\n return props.layerRequiringCredentials.formatId;\n }\n return undefined;\n }, [props.layerRequiringCredentials, props.mapLayerSourceToEdit]);\n\n const [dialogTitle] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(props.layerRequiringCredentials || props.mapLayerSourceToEdit ? \"mapLayers:CustomAttach.EditCustomLayer\" : \"mapLayers:CustomAttach.AttachCustomLayer\"));\n const [typeLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.Type\"));\n const [nameLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.Name\"));\n const [nameInputPlaceHolder] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.NameInputPlaceHolder\"));\n const [urlLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.URL\"));\n const [urlInputPlaceHolder] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.UrlInputPlaceHolder\"));\n const [iTwinSettingsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.StoreOnITwinSettings\"));\n const [modelSettingsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.StoreOnModelSettings\"));\n const [missingCredentialsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.MissingCredentials\"));\n const [invalidCredentialsLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.InvalidCredentials\"));\n const [serverRequireCredentials, setServerRequireCredentials] = React.useState(props.layerRequiringCredentials ?? false);\n const [invalidCredentialsProvided, setInvalidCredentialsProvided] = React.useState(false);\n const [layerAttachPending, setLayerAttachPending] = React.useState(false);\n const [warningMessage, setWarningMessage] = React.useState(props.layerRequiringCredentials ? missingCredentialsLabel : undefined);\n const [mapUrl, setMapUrl] = React.useState(getMapUrlFromProps());\n const [mapName, setMapName] = React.useState(getMapNameFromProps());\n const [userName, setUserName] = React.useState(\"\");\n const [password, setPassword] = React.useState(\"\");\n const [noSaveSettingsWarning] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.NoSaveSettingsWarning\"));\n const [passwordLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AuthenticationInputs.Password\"));\n const [passwordRequiredLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AuthenticationInputs.PasswordRequired\"));\n const [userNameLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AuthenticationInputs.Username\"));\n const [userNameRequiredLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:AuthenticationInputs.UsernameRequired\"));\n const [settingsStorage, setSettingsStorageRadio] = React.useState(\"ITwin\");\n\n const [mapType, setMapType] = React.useState(getFormatFromProps() ?? MAP_TYPES.arcGis);\n\n // 'isMounted' is used to prevent any async operation once the hook has been\n // unloaded. Otherwise we get a 'Can't perform a React state update on an unmounted component.' warning in the console.\n const isMounted = React.useRef(false);\n React.useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const [mapTypes] = React.useState((): SelectOption<string>[] => {\n const types = [\n { value: MAP_TYPES.arcGis, label: MAP_TYPES.arcGis },\n { value: MAP_TYPES.wms, label: MAP_TYPES.wms },\n { value: MAP_TYPES.wmts, label: MAP_TYPES.wmts },\n ];\n if (mapTypesOptions?.supportTileUrl)\n types.push({ value: MAP_TYPES.tileUrl, label: MAP_TYPES.tileUrl });\n return types;\n });\n\n const [isSettingsStorageAvailable] = React.useState(props?.activeViewport?.iModel?.iTwinId && props?.activeViewport?.iModel?.iModelId);\n\n // Even though the settings storage is available,\n // we don't always want to enable it in the UI.\n const [settingsStorageDisabled] = React.useState(!isSettingsStorageAvailable || props.mapLayerSourceToEdit !== undefined || props.layerRequiringCredentials !== undefined);\n\n const isAuthSupported = React.useCallback(() => {\n return ((mapType === MAP_TYPES.wms || mapType === MAP_TYPES.wms) && supportWmsAuthentication)\n || mapType === MAP_TYPES.arcGis;\n }, [mapType, supportWmsAuthentication]);\n\n // const [layerIdxToEdit] = React.useState((): number | undefined => {\n const [layerRequiringCredentialsIdx] = React.useState((): number | undefined => {\n if (props.layerRequiringCredentials === undefined || !props.layerRequiringCredentials.name || !props.layerRequiringCredentials.url) {\n return undefined;\n }\n\n const indexInDisplayStyle = props.activeViewport?.displayStyle.findMapLayerIndexByNameAndUrl(props.layerRequiringCredentials.name, props.layerRequiringCredentials.url, isOverlay);\n if (indexInDisplayStyle === undefined || indexInDisplayStyle < 0) {\n return undefined;\n } else {\n return indexInDisplayStyle;\n }\n });\n\n // Update warning message based on the dialog state and server response\n React.useEffect(() => {\n if (invalidCredentialsProvided) {\n setWarningMessage(invalidCredentialsLabel);\n } else if (serverRequireCredentials && (!userName || !password)) {\n setWarningMessage(missingCredentialsLabel);\n } else {\n setWarningMessage(undefined);\n }\n }, [invalidCredentialsProvided, invalidCredentialsLabel, missingCredentialsLabel, serverRequireCredentials, userName, password, setWarningMessage]);\n\n const handleMapTypeSelection = React.useCallback((newValue: string) => {\n setMapType(newValue);\n }, [setMapType]);\n\n const handleCancel = React.useCallback(() => {\n if (props.onCancelResult) {\n props.onCancelResult();\n return;\n }\n ModalDialogManager.closeDialog();\n }, [props]);\n\n const onUsernameChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setUserName(event.target.value);\n if (invalidCredentialsProvided)\n setInvalidCredentialsProvided(false);\n }, [setUserName, invalidCredentialsProvided, setInvalidCredentialsProvided]);\n\n const onPasswordChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setPassword(event.target.value);\n if (invalidCredentialsProvided)\n setInvalidCredentialsProvided(false);\n }, [setPassword, invalidCredentialsProvided, setInvalidCredentialsProvided]);\n\n const doAttach = React.useCallback(async (source: MapLayerSource): Promise<boolean> => {\n // Returns a promise, When true, the dialog should closed\n return new Promise<boolean>((resolve, _reject) => {\n const vp = props?.activeViewport;\n if (vp === undefined || source === undefined) {\n resolve(true);\n return;\n }\n\n const storeOnIModel = \"Model\" === settingsStorage;\n source.validateSource(true).then(async (validation) => {\n if (validation.status === MapLayerSourceStatus.Valid\n || validation.status === MapLayerSourceStatus.RequireAuth\n || validation.status === MapLayerSourceStatus.InvalidCredentials) {\n const sourceRequireAuth = (validation.status === MapLayerSourceStatus.RequireAuth);\n const invalidCredentials = (validation.status === MapLayerSourceStatus.InvalidCredentials);\n const closeDialog = !sourceRequireAuth && !invalidCredentials;\n resolve(closeDialog);\n\n if (sourceRequireAuth && !serverRequireCredentials) {\n setServerRequireCredentials(true);\n }\n if (invalidCredentials) {\n setInvalidCredentialsProvided(true);\n return;\n } else if (invalidCredentialsProvided) {\n setInvalidCredentialsProvided(false); // flag reset\n }\n\n if (validation.status === MapLayerSourceStatus.Valid) {\n // Attach layer and update settings service (only if editing)\n if (layerRequiringCredentialsIdx !== undefined) {\n // Update username / password\n vp.displayStyle.changeMapLayerProps({\n subLayers: validation.subLayers,\n }, layerRequiringCredentialsIdx, isOverlay);\n vp.displayStyle.changeMapLayerCredentials(layerRequiringCredentialsIdx, isOverlay, source.userName, source.password);\n\n // Reset the provider's status\n const provider = vp.getMapLayerImageryProvider(layerRequiringCredentialsIdx, isOverlay);\n if (provider && provider.status !== MapLayerImageryProviderStatus.Valid) {\n provider.status = MapLayerImageryProviderStatus.Valid;\n }\n } else {\n // Update service settings if storage is available and we are not prompting user for credentials\n if (!settingsStorageDisabled && !props.layerRequiringCredentials) {\n if (!(await MapLayerSettingsService.storeSourceInSettingsService(source, storeOnIModel, vp.iModel.iTwinId!, vp.iModel.iModelId!)))\n return;\n }\n const layerSettings = source.toLayerSettings(validation.subLayers);\n if (layerSettings) {\n vp.displayStyle.attachMapLayerSettings(layerSettings, isOverlay, undefined);\n\n const msg = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerAttached\", { sourceName: source.name, sourceUrl: source.url });\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Info, msg));\n } else {\n const msgError = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:Messages.MapLayerLayerSettingsConversionError\");\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.MapLayerAttachError\", { error: msgError, sourceUrl: source.url });\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\n }\n }\n\n vp.invalidateRenderPlan();\n }\n\n if (closeDialog) {\n // This handler will close the layer source handler, and therefore the MapUrl dialog.\n // don't call it if the dialog needs to remains open.\n onOkResult();\n }\n\n } else {\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.ValidationError\");\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, `${msg} ${source.url}`));\n resolve(true);\n }\n resolve(false);\n }).catch((error) => {\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.MapLayerAttachError\", { error, sourceUrl: source.url });\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\n resolve(true);\n });\n });\n }, [props.activeViewport, props.layerRequiringCredentials, settingsStorage, serverRequireCredentials, invalidCredentialsProvided, onOkResult, layerRequiringCredentialsIdx, isOverlay, settingsStorageDisabled]);\n\n const onNameChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setMapName(event.target.value);\n }, [setMapName]);\n\n const onRadioChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setSettingsStorageRadio(event.target.value);\n }, [setSettingsStorageRadio]);\n\n const onUrlChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n setMapUrl(event.target.value);\n }, [setMapUrl]);\n\n const handleOk = React.useCallback(() => {\n let source: MapLayerSource | undefined;\n if (mapUrl && mapName) {\n source = MapLayerSource.fromJSON({\n url: mapUrl,\n name: mapName,\n formatId: mapType,\n userName,\n password,\n });\n\n if (source === undefined || props.mapLayerSourceToEdit) {\n\n ModalDialogManager.closeDialog();\n\n if (source === undefined) {\n // Close the dialog and inform end user something went wrong.\n const msgError = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:Messages.MapLayerLayerSourceCreationFailed\");\n const msg = MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:CustomAttach.MapLayerAttachError\", { error: msgError, sourceUrl: mapUrl });\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, msg));\n return;\n }\n\n // Simply change the source definition in the setting service\n if (props.mapLayerSourceToEdit !== undefined) {\n const vp = props.activeViewport;\n void (async () => {\n if (isSettingsStorageAvailable && vp) {\n if (!(await MapLayerSettingsService.replaceSourceInSettingsService(props.mapLayerSourceToEdit!, source, vp.iModel.iTwinId!, vp.iModel.iModelId!))) {\n const errorMessage = IModelApp.localization.getLocalizedString(\"mapLayers:Messages.MapLayerEditError\", { layerName: props.mapLayerSourceToEdit?.name });\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Error, errorMessage));\n return;\n }\n\n }\n })();\n return;\n }\n }\n\n setLayerAttachPending(true);\n\n void (async () => {\n // Code below is executed in the an async manner but\n // I don't necessarily want to mark the handler as async\n // so Im wrapping it un in a void wrapper.\n try {\n const closeDialog = await doAttach(source);\n if (isMounted.current) {\n setLayerAttachPending(false);\n }\n\n // In theory the modal dialog should always get closed by the parent\n // AttachLayerPanel's 'onOkResult' handler. We close it here just in case.\n if (closeDialog) {\n ModalDialogManager.closeDialog();\n }\n } catch (_error) {\n ModalDialogManager.closeDialog();\n }\n })();\n }\n\n }, [mapUrl, mapName, mapType, userName, password, props.mapLayerSourceToEdit, props.activeViewport, isSettingsStorageAvailable, doAttach]);\n\n const dialogContainer = React.useRef<HTMLDivElement>(null);\n\n const readyToSave = React.useCallback(() => {\n const credentialsSet = !!userName && !!password;\n return (!!mapUrl && !!mapName)\n && (!serverRequireCredentials || (serverRequireCredentials && credentialsSet) && !layerAttachPending)\n && !invalidCredentialsProvided;\n }, [mapUrl, mapName, userName, password, layerAttachPending, invalidCredentialsProvided, serverRequireCredentials]);\n\n const buttonCluster = React.useMemo(() => [\n { type: DialogButtonType.OK, onClick: handleOk, disabled: !readyToSave() },\n { type: DialogButtonType.Cancel, onClick: handleCancel },\n ], [readyToSave, handleCancel, handleOk]);\n\n const handleOnKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === SpecialKey.Enter) {\n if (readyToSave())\n handleOk();\n }\n }, [handleOk, readyToSave]);\n\n return (\n <div ref={dialogContainer}>\n <Dialog\n className=\"map-layer-url-dialog\"\n title={dialogTitle}\n opened={true}\n resizable={true}\n movable={true}\n modal={true}\n buttonCluster={buttonCluster}\n onClose={handleCancel}\n onEscape={handleCancel}\n minHeight={120}\n maxWidth={600}\n trapFocus={false}\n >\n <div>\n <div className=\"map-layer-source-url\">\n <span className=\"map-layer-source-label\">{typeLabel}</span>\n <Select\n className=\"map-manager-base-select\"\n options={mapTypes}\n value={mapType}\n disabled={props.layerRequiringCredentials !== undefined || props.mapLayerSourceToEdit !== undefined}\n onChange={handleMapTypeSelection} />\n <span className=\"map-layer-source-label\">{nameLabel}</span>\n <Input placeholder={nameInputPlaceHolder} onChange={onNameChange} value={mapName} disabled={props.layerRequiringCredentials !== undefined} />\n <span className=\"map-layer-source-label\">{urlLabel}</span>\n <Input placeholder={urlInputPlaceHolder} onKeyPress={handleOnKeyDown} onChange={onUrlChange} disabled={props.mapLayerSourceToEdit !== undefined} value={mapUrl} />\n {isAuthSupported() && props.mapLayerSourceToEdit === undefined &&\n <>\n <span className=\"map-layer-source-label\">{userNameLabel}</span>\n <LabeledInput placeholder={serverRequireCredentials ? userNameRequiredLabel : userNameLabel}\n status={!userName && serverRequireCredentials ? InputStatus.Warning : undefined}\n onChange={onUsernameChange} />\n\n <span className=\"map-layer-source-label\">{passwordLabel}</span>\n <LabeledInput type=\"password\" placeholder={serverRequireCredentials ? passwordRequiredLabel : passwordLabel}\n status={!password && serverRequireCredentials ? InputStatus.Warning : undefined}\n onChange={onPasswordChange}\n onKeyPress={handleOnKeyDown} />\n </>\n }\n\n {/* Store settings options, not shown when editing a layer */}\n {isSettingsStorageAvailable && <div title={settingsStorageDisabled ? noSaveSettingsWarning : \"\"}>\n <Radio disabled={settingsStorageDisabled}\n name=\"settingsStorage\" value=\"iTwin\"\n label={iTwinSettingsLabel} checked={settingsStorage === \"iTwin\"}\n onChange={onRadioChange} />\n <Radio disabled={settingsStorageDisabled}\n name=\"settingsStorage\" value=\"Model\"\n label={modelSettingsLabel} checked={settingsStorage === \"Model\"}\n onChange={onRadioChange} />\n </div>}\n </div>\n </div>\n\n {/* Warning message */}\n <div className=\"map-layer-source-warnMessage\">\n {warningMessage ?\n <>\n <Icon className=\"map-layer-source-warnMessage-icon\" iconSpec=\"icon-status-warning\" />\n <span className=\"map-layer-source-warnMessage-label\">{warningMessage}</span >\n </>\n :\n // Place holder to avoid dialog resize\n <span className=\"map-layer-source-placeholder\"> </span>\n }\n </div>\n\n {/* Progress bar */}\n {layerAttachPending &&\n <div className=\"map-layer-source-progressBar\">\n <ProgressLinear indeterminate />\n </div>\n }\n </Dialog>\n </div >\n );\n}\n"]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
@import "~@itwin/core-react/lib/cjs/core-react/index";
|
|
6
|
+
@import "~@itwin/itwinui-css/scss/style/typography";
|
|
7
|
+
|
|
8
|
+
$divider-color: $buic-background-toolbutton-stroke;
|
|
9
|
+
$hovered-icon-color: $buic-foreground-primary-tone;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
.map-layer-url-dialog {
|
|
13
|
+
z-Index: 21000;
|
|
14
|
+
|
|
15
|
+
.core-dialog-content {
|
|
16
|
+
padding-right: 11px !important;
|
|
17
|
+
padding-left: 11px !important;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.map-layer-source-url {
|
|
22
|
+
|
|
23
|
+
height: 100%;
|
|
24
|
+
width: 100%;
|
|
25
|
+
display: grid;
|
|
26
|
+
grid-template-columns: auto 1fr;
|
|
27
|
+
grid-column-gap: 10px;
|
|
28
|
+
align-items: center;
|
|
29
|
+
|
|
30
|
+
.map-layer-source-label {
|
|
31
|
+
font-size: $iui-font-size;
|
|
32
|
+
color: $buic-foreground-body;
|
|
33
|
+
padding-right: 6px;
|
|
34
|
+
flex: initial;
|
|
35
|
+
width: fit-content;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.map-layer-source-editor {
|
|
40
|
+
width: 100%;
|
|
41
|
+
height: 100%;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
label {
|
|
45
|
+
grid-column-start: 2;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.map-layer-warning-icon {
|
|
49
|
+
margin-left: 3%;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.map-layer-source-progressBar {
|
|
55
|
+
margin-top: 10px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.map-layer-source-placeholder {
|
|
59
|
+
white-space: pre-wrap;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.map-layer-source-warnMessage {
|
|
63
|
+
margin-top: 5px;
|
|
64
|
+
|
|
65
|
+
.map-layer-source-warnMessage-label {
|
|
66
|
+
margin-left: 5px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.map-layer-source-warnMessage-icon {
|
|
70
|
+
background-color: transparent;
|
|
71
|
+
border: none;
|
|
72
|
+
color: $buic-foreground-warning;
|
|
73
|
+
background-color: transparent;
|
|
74
|
+
|
|
75
|
+
&:hover {
|
|
76
|
+
color: $hovered-icon-color;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&:focus {
|
|
80
|
+
outline: none;
|
|
81
|
+
box-shadow: $uicore-button-focus-boxshadow;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BeEvent } from "@itwin/core-bentley";
|
|
2
|
+
import { MapSubLayerProps } from "@itwin/core-common";
|
|
3
|
+
import { ITreeDataProvider, TreeDataChangesListener, TreeNodeItem } from "@itwin/components-react";
|
|
4
|
+
import { StyleMapLayerSettings } from "../Interfaces";
|
|
5
|
+
/**
|
|
6
|
+
* Data provider that returns some fake nodes to show in tree.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SubLayersDataProvider implements ITreeDataProvider {
|
|
9
|
+
private readonly _nodeMap;
|
|
10
|
+
private readonly _mapLayer;
|
|
11
|
+
constructor(mapLayer: StyleMapLayerSettings);
|
|
12
|
+
static isUnnamedGroup(subLayer: MapSubLayerProps | undefined): boolean;
|
|
13
|
+
private createId;
|
|
14
|
+
private createNode;
|
|
15
|
+
private loadChildNodes;
|
|
16
|
+
private loadNodes;
|
|
17
|
+
onTreeNodeChanged: BeEvent<TreeDataChangesListener>;
|
|
18
|
+
getNodesCount(parent?: TreeNodeItem): Promise<number>;
|
|
19
|
+
getNodes(parent?: TreeNodeItem): Promise<TreeNodeItem[]>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=SubLayersDataProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersDataProvider.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersDataProvider.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAA6B,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAc,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAA2B,iBAAiB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5H,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD;;GAEG;AACH,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;gBAEtC,QAAQ,EAAE,qBAAqB;WAK7B,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,GAAG,OAAO;IAO7E,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,SAAS;IAOV,iBAAiB,mCAA0C;IAErD,aAAa,CAAC,MAAM,CAAC,EAAE,YAAY;IAQnC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY;CAO5C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { BeEvent, compareStringsOrUndefined } from "@itwin/core-bentley";
|
|
6
|
+
import { PropertyRecord } from "@itwin/appui-abstract";
|
|
7
|
+
import { CheckBoxState } from "@itwin/core-react";
|
|
8
|
+
/**
|
|
9
|
+
* Data provider that returns some fake nodes to show in tree.
|
|
10
|
+
*/
|
|
11
|
+
export class SubLayersDataProvider {
|
|
12
|
+
constructor(mapLayer) {
|
|
13
|
+
this._nodeMap = new Map();
|
|
14
|
+
this.onTreeNodeChanged = new BeEvent();
|
|
15
|
+
this._mapLayer = mapLayer;
|
|
16
|
+
this.loadNodes(mapLayer.subLayers);
|
|
17
|
+
}
|
|
18
|
+
static isUnnamedGroup(subLayer) {
|
|
19
|
+
if (!subLayer)
|
|
20
|
+
return false;
|
|
21
|
+
return (!subLayer.name || subLayer.name.length === 0) && (subLayer.children !== undefined && subLayer.children.length > 0);
|
|
22
|
+
}
|
|
23
|
+
createId(props) {
|
|
24
|
+
return undefined !== props.id ? `${props.id}` : props.name ? props.name : "no-id";
|
|
25
|
+
}
|
|
26
|
+
createNode(props, expanded, isCheckboxDisabled, icon) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
return {
|
|
29
|
+
id: this.createId(props),
|
|
30
|
+
label: PropertyRecord.fromString((_b = (_a = props.title) !== null && _a !== void 0 ? _a : props.name) !== null && _b !== void 0 ? _b : "unknown"),
|
|
31
|
+
hasChildren: !!props.children,
|
|
32
|
+
isCheckboxVisible: true,
|
|
33
|
+
checkBoxState: props.visible && !isCheckboxDisabled ? CheckBoxState.On : CheckBoxState.Off,
|
|
34
|
+
extendedData: { subLayerId: props.id },
|
|
35
|
+
isCheckboxDisabled,
|
|
36
|
+
autoExpand: expanded,
|
|
37
|
+
icon,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
loadChildNodes(allSubLayers, parentId) {
|
|
41
|
+
const filteredProps = allSubLayers.filter((props) => parentId === props.parent);
|
|
42
|
+
if (filteredProps.length) {
|
|
43
|
+
filteredProps === null || filteredProps === void 0 ? void 0 : filteredProps.sort((a, b) => compareStringsOrUndefined(a.title, b.title));
|
|
44
|
+
const treeNodes = [];
|
|
45
|
+
filteredProps.forEach((props) => {
|
|
46
|
+
treeNodes.push(this.createNode(props, (!parentId && (props === null || props === void 0 ? void 0 : props.children) !== undefined) ? true : undefined, // expand root group only (i.e. not the entire tree),
|
|
47
|
+
undefined, SubLayersDataProvider.isUnnamedGroup(props) ? "icon-folder" : "icon-layers"));
|
|
48
|
+
if (props.children)
|
|
49
|
+
this.loadChildNodes(allSubLayers, props.id);
|
|
50
|
+
});
|
|
51
|
+
this._nodeMap.set(undefined !== parentId ? `${parentId}` : "", treeNodes);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
loadNodes(subLayerNodes) {
|
|
55
|
+
subLayerNodes === null || subLayerNodes === void 0 ? void 0 : subLayerNodes.sort((a, b) => compareStringsOrUndefined(a.title, b.title));
|
|
56
|
+
if (subLayerNodes) {
|
|
57
|
+
this.loadChildNodes(subLayerNodes, undefined);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async getNodesCount(parent) {
|
|
61
|
+
const nodeArray = parent ? this._nodeMap.get(parent.id) : this._nodeMap.get("");
|
|
62
|
+
if (nodeArray)
|
|
63
|
+
return nodeArray.length;
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
async getNodes(parent) {
|
|
67
|
+
const nodeArray = parent ? this._nodeMap.get(parent.id) : this._nodeMap.get("");
|
|
68
|
+
if (nodeArray)
|
|
69
|
+
return nodeArray;
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=SubLayersDataProvider.js.map
|