@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.
Files changed (198) hide show
  1. package/lib/{map-layers.d.ts → cjs/map-layers.d.ts} +0 -0
  2. package/lib/cjs/map-layers.d.ts.map +1 -0
  3. package/lib/{map-layers.js → cjs/map-layers.js} +0 -0
  4. package/lib/cjs/map-layers.js.map +1 -0
  5. package/lib/{mapLayers.d.ts → cjs/mapLayers.d.ts} +0 -0
  6. package/lib/cjs/mapLayers.d.ts.map +1 -0
  7. package/lib/{mapLayers.js → cjs/mapLayers.js} +0 -0
  8. package/lib/cjs/mapLayers.js.map +1 -0
  9. package/lib/{public → cjs/public}/locales/en/mapLayers.json +0 -0
  10. package/lib/{ui → cjs/ui}/Interfaces.d.ts +0 -0
  11. package/lib/cjs/ui/Interfaces.d.ts.map +1 -0
  12. package/lib/{ui → cjs/ui}/Interfaces.js +0 -0
  13. package/lib/cjs/ui/Interfaces.js.map +1 -0
  14. package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.d.ts +0 -0
  15. package/lib/cjs/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
  16. package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.js +0 -0
  17. package/lib/cjs/ui/MapLayersUiItemsProvider.js.map +1 -0
  18. package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.d.ts +0 -0
  19. package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
  20. package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.js +0 -0
  21. package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -0
  22. package/lib/{ui → cjs/ui}/widget/BasemapPanel.d.ts +0 -0
  23. package/lib/cjs/ui/widget/BasemapPanel.d.ts.map +1 -0
  24. package/lib/{ui → cjs/ui}/widget/BasemapPanel.js +0 -0
  25. package/lib/cjs/ui/widget/BasemapPanel.js.map +1 -0
  26. package/lib/{ui → cjs/ui}/widget/BasemapPanel.scss +1 -1
  27. package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.d.ts +0 -0
  28. package/lib/cjs/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
  29. package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.js +0 -0
  30. package/lib/cjs/ui/widget/ConfirmMessageDialog.js.map +1 -0
  31. package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.d.ts +0 -0
  32. package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -0
  33. package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.js +0 -0
  34. package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -0
  35. package/lib/{ui → cjs/ui}/widget/MapLayerManager.d.ts +0 -0
  36. package/lib/cjs/ui/widget/MapLayerManager.d.ts.map +1 -0
  37. package/lib/{ui → cjs/ui}/widget/MapLayerManager.js +0 -0
  38. package/lib/cjs/ui/widget/MapLayerManager.js.map +1 -0
  39. package/lib/{ui → cjs/ui}/widget/MapLayerManager.scss +1 -1
  40. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.d.ts +0 -0
  41. package/lib/cjs/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
  42. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.js +0 -0
  43. package/lib/cjs/ui/widget/MapLayerSettingsMenu.js.map +1 -0
  44. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.d.ts +0 -0
  45. package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
  46. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.js +0 -0
  47. package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
  48. package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.scss +1 -1
  49. package/lib/{ui → cjs/ui}/widget/MapLayersWidget.d.ts +0 -0
  50. package/lib/cjs/ui/widget/MapLayersWidget.d.ts.map +1 -0
  51. package/lib/{ui → cjs/ui}/widget/MapLayersWidget.js +0 -0
  52. package/lib/cjs/ui/widget/MapLayersWidget.js.map +1 -0
  53. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.d.ts +0 -0
  54. package/lib/cjs/ui/widget/MapManagerSettings.d.ts.map +1 -0
  55. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.js +0 -0
  56. package/lib/cjs/ui/widget/MapManagerSettings.js.map +1 -0
  57. package/lib/{ui → cjs/ui}/widget/MapManagerSettings.scss +1 -1
  58. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.d.ts +0 -0
  59. package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -0
  60. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.js +0 -0
  61. package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -0
  62. package/lib/{ui → cjs/ui}/widget/MapUrlDialog.scss +1 -1
  63. package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.d.ts +0 -0
  64. package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
  65. package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.js +0 -0
  66. package/lib/cjs/ui/widget/SubLayersDataProvider.js.map +1 -0
  67. package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.d.ts +0 -0
  68. package/lib/cjs/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
  69. package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.js +0 -0
  70. package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -0
  71. package/lib/{ui → cjs/ui}/widget/SubLayersTree.d.ts +0 -0
  72. package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -0
  73. package/lib/{ui → cjs/ui}/widget/SubLayersTree.js +0 -0
  74. package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -0
  75. package/lib/{ui → cjs/ui}/widget/SubLayersTree.scss +1 -1
  76. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.d.ts +0 -0
  77. package/lib/cjs/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
  78. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.js +0 -0
  79. package/lib/cjs/ui/widget/TransparencyPopupButton.js.map +1 -0
  80. package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.scss +1 -1
  81. package/lib/esm/map-layers.d.ts +5 -0
  82. package/lib/esm/map-layers.d.ts.map +1 -0
  83. package/lib/esm/map-layers.js +9 -0
  84. package/lib/esm/map-layers.js.map +1 -0
  85. package/lib/esm/mapLayers.d.ts +29 -0
  86. package/lib/esm/mapLayers.d.ts.map +1 -0
  87. package/lib/esm/mapLayers.js +50 -0
  88. package/lib/esm/mapLayers.js.map +1 -0
  89. package/lib/esm/public/locales/en/mapLayers.json +113 -0
  90. package/lib/esm/ui/Interfaces.d.ts +32 -0
  91. package/lib/esm/ui/Interfaces.d.ts.map +1 -0
  92. package/lib/esm/ui/Interfaces.js +2 -0
  93. package/lib/esm/ui/Interfaces.js.map +1 -0
  94. package/lib/esm/ui/MapLayersUiItemsProvider.d.ts +23 -0
  95. package/lib/esm/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
  96. package/lib/esm/ui/MapLayersUiItemsProvider.js +50 -0
  97. package/lib/esm/ui/MapLayersUiItemsProvider.js.map +1 -0
  98. package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts +14 -0
  99. package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
  100. package/lib/esm/ui/widget/AttachLayerPopupButton.js +308 -0
  101. package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -0
  102. package/lib/esm/ui/widget/BasemapPanel.d.ts +5 -0
  103. package/lib/esm/ui/widget/BasemapPanel.d.ts.map +1 -0
  104. package/lib/esm/ui/widget/BasemapPanel.js +141 -0
  105. package/lib/esm/ui/widget/BasemapPanel.js.map +1 -0
  106. package/lib/esm/ui/widget/BasemapPanel.scss +98 -0
  107. package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts +22 -0
  108. package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
  109. package/lib/esm/ui/widget/ConfirmMessageDialog.js +22 -0
  110. package/lib/esm/ui/widget/ConfirmMessageDialog.js.map +1 -0
  111. package/lib/esm/ui/widget/MapLayerDroppable.d.ts +19 -0
  112. package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -0
  113. package/lib/esm/ui/widget/MapLayerDroppable.js +80 -0
  114. package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -0
  115. package/lib/esm/ui/widget/MapLayerManager.d.ts +27 -0
  116. package/lib/esm/ui/widget/MapLayerManager.d.ts.map +1 -0
  117. package/lib/esm/ui/widget/MapLayerManager.js +347 -0
  118. package/lib/esm/ui/widget/MapLayerManager.js.map +1 -0
  119. package/lib/esm/ui/widget/MapLayerManager.scss +525 -0
  120. package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts +10 -0
  121. package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
  122. package/lib/esm/ui/widget/MapLayerSettingsMenu.js +79 -0
  123. package/lib/esm/ui/widget/MapLayerSettingsMenu.js.map +1 -0
  124. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts +5 -0
  125. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
  126. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js +31 -0
  127. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
  128. package/lib/esm/ui/widget/MapLayerSettingsPopupButton.scss +31 -0
  129. package/lib/esm/ui/widget/MapLayersWidget.d.ts +12 -0
  130. package/lib/esm/ui/widget/MapLayersWidget.d.ts.map +1 -0
  131. package/lib/esm/ui/widget/MapLayersWidget.js +23 -0
  132. package/lib/esm/ui/widget/MapLayersWidget.js.map +1 -0
  133. package/lib/esm/ui/widget/MapManagerSettings.d.ts +4 -0
  134. package/lib/esm/ui/widget/MapManagerSettings.d.ts.map +1 -0
  135. package/lib/esm/ui/widget/MapManagerSettings.js +168 -0
  136. package/lib/esm/ui/widget/MapManagerSettings.js.map +1 -0
  137. package/lib/esm/ui/widget/MapManagerSettings.scss +23 -0
  138. package/lib/esm/ui/widget/MapUrlDialog.d.ts +23 -0
  139. package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -0
  140. package/lib/esm/ui/widget/MapUrlDialog.js +346 -0
  141. package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -0
  142. package/lib/esm/ui/widget/MapUrlDialog.scss +85 -0
  143. package/lib/esm/ui/widget/SubLayersDataProvider.d.ts +21 -0
  144. package/lib/esm/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
  145. package/lib/esm/ui/widget/SubLayersDataProvider.js +73 -0
  146. package/lib/esm/ui/widget/SubLayersDataProvider.js.map +1 -0
  147. package/lib/esm/ui/widget/SubLayersPopupButton.d.ts +11 -0
  148. package/lib/esm/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
  149. package/lib/esm/ui/widget/SubLayersPopupButton.js +36 -0
  150. package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -0
  151. package/lib/esm/ui/widget/SubLayersTree.d.ts +16 -0
  152. package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -0
  153. package/lib/esm/ui/widget/SubLayersTree.js +374 -0
  154. package/lib/esm/ui/widget/SubLayersTree.js.map +1 -0
  155. package/lib/esm/ui/widget/SubLayersTree.scss +64 -0
  156. package/lib/esm/ui/widget/TransparencyPopupButton.d.ts +14 -0
  157. package/lib/esm/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
  158. package/lib/esm/ui/widget/TransparencyPopupButton.js +44 -0
  159. package/lib/esm/ui/widget/TransparencyPopupButton.js.map +1 -0
  160. package/lib/esm/ui/widget/TransparencyPopupButton.scss +53 -0
  161. package/lib/public/en/mapLayers.json +113 -0
  162. package/package.json +45 -39
  163. package/lib/map-layers.d.ts.map +0 -1
  164. package/lib/map-layers.js.map +0 -1
  165. package/lib/mapLayers.d.ts.map +0 -1
  166. package/lib/mapLayers.js.map +0 -1
  167. package/lib/ui/Interfaces.d.ts.map +0 -1
  168. package/lib/ui/Interfaces.js.map +0 -1
  169. package/lib/ui/MapLayersUiItemsProvider.d.ts.map +0 -1
  170. package/lib/ui/MapLayersUiItemsProvider.js.map +0 -1
  171. package/lib/ui/widget/AttachLayerPopupButton.d.ts.map +0 -1
  172. package/lib/ui/widget/AttachLayerPopupButton.js.map +0 -1
  173. package/lib/ui/widget/BasemapPanel.d.ts.map +0 -1
  174. package/lib/ui/widget/BasemapPanel.js.map +0 -1
  175. package/lib/ui/widget/ConfirmMessageDialog.d.ts.map +0 -1
  176. package/lib/ui/widget/ConfirmMessageDialog.js.map +0 -1
  177. package/lib/ui/widget/MapLayerDroppable.d.ts.map +0 -1
  178. package/lib/ui/widget/MapLayerDroppable.js.map +0 -1
  179. package/lib/ui/widget/MapLayerManager.d.ts.map +0 -1
  180. package/lib/ui/widget/MapLayerManager.js.map +0 -1
  181. package/lib/ui/widget/MapLayerSettingsMenu.d.ts.map +0 -1
  182. package/lib/ui/widget/MapLayerSettingsMenu.js.map +0 -1
  183. package/lib/ui/widget/MapLayerSettingsPopupButton.d.ts.map +0 -1
  184. package/lib/ui/widget/MapLayerSettingsPopupButton.js.map +0 -1
  185. package/lib/ui/widget/MapLayersWidget.d.ts.map +0 -1
  186. package/lib/ui/widget/MapLayersWidget.js.map +0 -1
  187. package/lib/ui/widget/MapManagerSettings.d.ts.map +0 -1
  188. package/lib/ui/widget/MapManagerSettings.js.map +0 -1
  189. package/lib/ui/widget/MapUrlDialog.d.ts.map +0 -1
  190. package/lib/ui/widget/MapUrlDialog.js.map +0 -1
  191. package/lib/ui/widget/SubLayersDataProvider.d.ts.map +0 -1
  192. package/lib/ui/widget/SubLayersDataProvider.js.map +0 -1
  193. package/lib/ui/widget/SubLayersPopupButton.d.ts.map +0 -1
  194. package/lib/ui/widget/SubLayersPopupButton.js.map +0 -1
  195. package/lib/ui/widget/SubLayersTree.d.ts.map +0 -1
  196. package/lib/ui/widget/SubLayersTree.js.map +0 -1
  197. package/lib/ui/widget/TransparencyPopupButton.d.ts.map +0 -1
  198. 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\">&nbsp;</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