@esri/solutions-components 0.8.4 → 0.8.6

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 (98) hide show
  1. package/dist/assets/t9n/crowdsource-reporter/resources.json +5 -6
  2. package/dist/assets/t9n/crowdsource-reporter/resources_en.json +5 -6
  3. package/dist/assets/t9n/feature-list/resources.json +1 -1
  4. package/dist/assets/t9n/feature-list/resources_en.json +1 -1
  5. package/dist/assets/t9n/public-notification/resources.json +3 -1
  6. package/dist/assets/t9n/public-notification/resources_en.json +3 -1
  7. package/dist/cjs/buffer-tools_3.cjs.entry.js +2 -2
  8. package/dist/cjs/calcite-alert_4.cjs.entry.js +2 -2
  9. package/dist/cjs/calcite-combobox_5.cjs.entry.js +2 -2
  10. package/dist/cjs/calcite-flow_5.cjs.entry.js +163 -16
  11. package/dist/cjs/card-manager_3.cjs.entry.js +41 -2
  12. package/dist/cjs/crowdsource-manager.cjs.entry.js +2 -1
  13. package/dist/cjs/crowdsource-reporter.cjs.entry.js +120 -38
  14. package/dist/cjs/loader.cjs.js +1 -1
  15. package/dist/cjs/map-select-tools_3.cjs.entry.js +2 -2
  16. package/dist/cjs/public-notification.cjs.entry.js +110 -4
  17. package/dist/cjs/{publicNotificationStore-ef379d11.js → publicNotificationStore-e790601d.js} +2 -2
  18. package/dist/cjs/solutions-components.cjs.js +1 -1
  19. package/dist/collection/collection-manifest.json +1 -1
  20. package/dist/collection/components/create-feature/create-feature.css +9 -0
  21. package/dist/collection/components/create-feature/create-feature.js +134 -6
  22. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +19 -1
  23. package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.css +5 -0
  24. package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.js +120 -38
  25. package/dist/collection/components/feature-list/feature-list.js +93 -5
  26. package/dist/collection/components/info-card/info-card.css +1 -1
  27. package/dist/collection/components/info-card/info-card.js +1 -1
  28. package/dist/collection/components/layer-list/layer-list.js +6 -6
  29. package/dist/collection/components/map-card/map-card.js +27 -2
  30. package/dist/collection/components/map-draw-tools/map-draw-tools.js +1 -1
  31. package/dist/collection/components/map-layer-picker/map-layer-picker.js +1 -1
  32. package/dist/collection/components/map-select-tools/map-select-tools.js +1 -1
  33. package/dist/collection/components/public-notification/public-notification.js +110 -3
  34. package/dist/collection/demos/crowdsource-reporter.html +1 -1
  35. package/dist/collection/utils/interfaces.ts +7 -0
  36. package/dist/collection/utils/publicNotificationStore.js +2 -2
  37. package/dist/collection/utils/publicNotificationStore.ts +3 -2
  38. package/dist/components/create-feature2.js +111 -7
  39. package/dist/components/crowdsource-manager.js +3 -1
  40. package/dist/components/crowdsource-reporter.js +121 -39
  41. package/dist/components/feature-list2.js +54 -6
  42. package/dist/components/info-card2.js +2 -2
  43. package/dist/components/layer-list2.js +6 -6
  44. package/dist/components/map-card2.js +42 -2
  45. package/dist/components/map-draw-tools2.js +1 -1
  46. package/dist/components/map-layer-picker2.js +1 -1
  47. package/dist/components/map-select-tools2.js +1 -1
  48. package/dist/components/public-notification.js +110 -3
  49. package/dist/components/publicNotificationStore.js +2 -2
  50. package/dist/esm/buffer-tools_3.entry.js +2 -2
  51. package/dist/esm/calcite-alert_4.entry.js +3 -3
  52. package/dist/esm/calcite-combobox_5.entry.js +3 -3
  53. package/dist/esm/calcite-flow_5.entry.js +164 -17
  54. package/dist/esm/card-manager_3.entry.js +43 -4
  55. package/dist/esm/crowdsource-manager.entry.js +3 -2
  56. package/dist/esm/crowdsource-reporter.entry.js +121 -39
  57. package/dist/esm/{downloadUtils-0c13073b.js → downloadUtils-0c1e4d7b.js} +2 -2
  58. package/dist/esm/{index.es-ad250bc6.js → index.es-286e3cfa.js} +2 -2
  59. package/dist/esm/loader.js +1 -1
  60. package/dist/esm/map-select-tools_3.entry.js +4 -4
  61. package/dist/esm/{mapViewUtils-20504620.js → mapViewUtils-253178f1.js} +1 -1
  62. package/dist/esm/public-notification.entry.js +112 -6
  63. package/dist/esm/{publicNotificationStore-3bf4de75.js → publicNotificationStore-223faed2.js} +2 -2
  64. package/dist/esm/solutions-components.js +1 -1
  65. package/dist/solutions-components/demos/crowdsource-reporter.html +1 -1
  66. package/dist/solutions-components/p-15f9624a.entry.js +6 -0
  67. package/dist/solutions-components/{p-955647ea.entry.js → p-1ea5e061.entry.js} +2 -2
  68. package/dist/solutions-components/{p-590a2a26.js → p-212b02e7.js} +1 -1
  69. package/dist/solutions-components/p-238d3b5f.entry.js +6 -0
  70. package/dist/solutions-components/p-273d833b.entry.js +6 -0
  71. package/dist/solutions-components/{p-cc280aa1.js → p-322868ec.js} +1 -1
  72. package/dist/solutions-components/{p-1d3a1794.js → p-331b5d1e.js} +2 -2
  73. package/dist/solutions-components/{p-c897e3eb.js → p-3af79063.js} +1 -1
  74. package/dist/solutions-components/p-45ed16d5.entry.js +6 -0
  75. package/dist/solutions-components/p-80b11ec1.entry.js +17 -0
  76. package/dist/solutions-components/{p-5c7e3941.entry.js → p-813fd8a4.entry.js} +2 -2
  77. package/dist/solutions-components/{p-ff302d95.entry.js → p-d136eab0.entry.js} +2 -2
  78. package/dist/solutions-components/p-e0446d5b.entry.js +6 -0
  79. package/dist/solutions-components/solutions-components.esm.js +1 -1
  80. package/dist/solutions-components/utils/interfaces.ts +7 -0
  81. package/dist/solutions-components/utils/publicNotificationStore.ts +3 -2
  82. package/dist/types/components/create-feature/create-feature.d.ts +43 -1
  83. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +4 -0
  84. package/dist/types/components/crowdsource-reporter/crowdsource-reporter.d.ts +31 -10
  85. package/dist/types/components/feature-list/feature-list.d.ts +31 -0
  86. package/dist/types/components/layer-list/layer-list.d.ts +3 -3
  87. package/dist/types/components/map-card/map-card.d.ts +8 -0
  88. package/dist/types/components/public-notification/public-notification.d.ts +48 -0
  89. package/dist/types/components.d.ts +37 -0
  90. package/dist/types/utils/interfaces.d.ts +6 -0
  91. package/dist/types/utils/publicNotificationStore.d.ts +2 -1
  92. package/package.json +2 -1
  93. package/dist/solutions-components/p-6512dc44.entry.js +0 -6
  94. package/dist/solutions-components/p-65ad1625.entry.js +0 -6
  95. package/dist/solutions-components/p-989bf0bf.entry.js +0 -6
  96. package/dist/solutions-components/p-a0611720.entry.js +0 -6
  97. package/dist/solutions-components/p-efe1694a.entry.js +0 -17
  98. package/dist/solutions-components/p-f3467807.entry.js +0 -6
@@ -7,6 +7,7 @@
7
7
  "components/consent-manager/consent-manager.js",
8
8
  "components/create-feature/create-feature.js",
9
9
  "components/crowdsource-manager/crowdsource-manager.js",
10
+ "components/layer-list/layer-list.js",
10
11
  "components/crowdsource-reporter/crowdsource-reporter.js",
11
12
  "components/deduct-calculator/deduct-calculator.js",
12
13
  "components/delete-button/delete-button.js",
@@ -18,7 +19,6 @@
18
19
  "components/floor-filter/floor-filter.js",
19
20
  "components/info-card/info-card.js",
20
21
  "components/json-editor/json-editor.js",
21
- "components/layer-list/layer-list.js",
22
22
  "components/layer-table/layer-table.js",
23
23
  "components/layout-manager/layout-manager.js",
24
24
  "components/list-flow-item/list-flow-item.js",
@@ -47,4 +47,13 @@
47
47
  .esri-editor .esri-item-list__filter-container--sticky {
48
48
  padding-block: 0px !important;
49
49
  padding-inline: 10px !important;
50
+ }
51
+
52
+ .search-widget {
53
+ width: 92% !important;
54
+ margin: 5px 0 20px 14px;
55
+ }
56
+
57
+ .display-none {
58
+ display: none !important;
50
59
  }
@@ -18,14 +18,16 @@
18
18
  * See the License for the specific language governing permissions and
19
19
  * limitations under the License.
20
20
  */
21
- import { Host, h } from "@stencil/core";
21
+ import { Fragment, h } from "@stencil/core";
22
22
  import { loadModules } from "../../utils/loadModules";
23
- import { getAllLayers } from "../../utils/mapViewUtils";
23
+ import { getAllLayers, getLayerOrTable } from "../../utils/mapViewUtils";
24
24
  export class CreateFeature {
25
25
  constructor() {
26
26
  this.mapView = undefined;
27
27
  this.selectedLayerId = undefined;
28
28
  this.customizeSubmit = false;
29
+ this.searchConfiguration = undefined;
30
+ this.showSearchWidget = undefined;
29
31
  }
30
32
  //--------------------------------------------------------------------------
31
33
  //
@@ -85,7 +87,8 @@ export class CreateFeature {
85
87
  * Renders the component.
86
88
  */
87
89
  render() {
88
- return (h(Host, { id: "feature-form" }));
90
+ const showSearchWidget = this.showSearchWidget ? '' : 'display-none';
91
+ return (h(Fragment, null, h("div", { id: "feature-form" }), h("div", { class: `search-widget ${showSearchWidget}`, id: "search-widget-ref" })));
89
92
  }
90
93
  //--------------------------------------------------------------------------
91
94
  //
@@ -93,11 +96,12 @@ export class CreateFeature {
93
96
  //
94
97
  //--------------------------------------------------------------------------
95
98
  /**
96
- * Init Editor widget and starts the create workflow
99
+ * Init Editor widget and Search widget
97
100
  */
98
101
  async init() {
99
102
  if (this.mapView && this.selectedLayerId) {
100
103
  await this.createEditorWidget();
104
+ await this.createSearchWidget();
101
105
  }
102
106
  }
103
107
  /**
@@ -106,12 +110,14 @@ export class CreateFeature {
106
110
  * @protected
107
111
  */
108
112
  async initModules() {
109
- const [Editor, reactiveUtils] = await loadModules([
113
+ const [Editor, reactiveUtils, Search] = await loadModules([
110
114
  "esri/widgets/Editor",
111
- "esri/core/reactiveUtils"
115
+ "esri/core/reactiveUtils",
116
+ "esri/widgets/Search"
112
117
  ]);
113
118
  this.Editor = Editor;
114
119
  this.reactiveUtils = reactiveUtils;
120
+ this.Search = Search;
115
121
  }
116
122
  /**
117
123
  * Display editor widget to create the new feature
@@ -165,6 +171,13 @@ export class CreateFeature {
165
171
  }
166
172
  });
167
173
  this._editor.viewModel.addHandles(handle);
174
+ //Add handle to watch editor viewmodel state and then show the search widget
175
+ const formHandle = this.reactiveUtils.watch(() => this._editor.viewModel.state, (state) => {
176
+ if (state === 'creating-features') {
177
+ this.showSearchWidget = true;
178
+ }
179
+ });
180
+ this._editor.viewModel.addHandles(formHandle);
168
181
  }
169
182
  /**
170
183
  * Start creating the feature
@@ -183,6 +196,7 @@ export class CreateFeature {
183
196
  //on sketch complete emit the event
184
197
  this._editor.viewModel.sketchViewModel.on("create", (evt) => {
185
198
  if (evt.state === "complete") {
199
+ this.showSearchWidget = false;
186
200
  this.drawComplete.emit();
187
201
  }
188
202
  });
@@ -199,6 +213,94 @@ export class CreateFeature {
199
213
  this.hideEditorsElements();
200
214
  }
201
215
  }
216
+ /**
217
+ * Display search widget to search location
218
+ * @protected
219
+ */
220
+ async createSearchWidget() {
221
+ let searchOptions = {
222
+ view: this.mapView,
223
+ };
224
+ if (this.searchConfiguration) {
225
+ const searchConfiguration = this._getSearchConfig(this.searchConfiguration, this.mapView);
226
+ searchOptions = Object.assign({}, searchConfiguration);
227
+ }
228
+ this._search = new this.Search(searchOptions);
229
+ this._search.container = 'search-widget-ref';
230
+ this._search.popupEnabled = false;
231
+ this._search.resultGraphicEnabled = false;
232
+ const layer = await getLayerOrTable(this.mapView, this.selectedLayerId);
233
+ let pointGeometry = null;
234
+ // on search get the geometry of the searched location and pass it in sketchViewModel and go to featureForm page
235
+ this._search.on('search-complete', (e) => {
236
+ var _a;
237
+ void this.mapView.goTo(e.results[0].results[0].extent);
238
+ if (layer.geometryType === 'point') {
239
+ pointGeometry = (_a = e.results[0].results[0]) === null || _a === void 0 ? void 0 : _a.feature.geometry;
240
+ }
241
+ });
242
+ //Add handle to watch if search viewModel state is ready
243
+ const createFeatureHandle = this.reactiveUtils.watch(() => this._search.viewModel.state, (state) => {
244
+ if (state === 'ready') {
245
+ setTimeout(() => {
246
+ if (this._editor.viewModel.sketchViewModel.createGraphic && pointGeometry) {
247
+ this._editor.viewModel.sketchViewModel.createGraphic.set('geometry', pointGeometry);
248
+ this._editor.viewModel.sketchViewModel.complete();
249
+ this.hideEditorsElements();
250
+ }
251
+ }, 100);
252
+ }
253
+ });
254
+ this._search.viewModel.addHandles(createFeatureHandle);
255
+ }
256
+ /**
257
+ * Initialize the search widget based on user defined configuration
258
+ *
259
+ * @param searchConfiguration search configuration defined by the user
260
+ * @param view the current map view
261
+ *
262
+ * @protected
263
+ */
264
+ _getSearchConfig(searchConfiguration, view) {
265
+ const INCLUDE_DEFAULT_SOURCES = "includeDefaultSources";
266
+ const sources = searchConfiguration.sources;
267
+ if ((sources === null || sources === void 0 ? void 0 : sources.length) > 0) {
268
+ searchConfiguration[INCLUDE_DEFAULT_SOURCES] = false;
269
+ sources.forEach((source) => {
270
+ var _a, _b;
271
+ const isLayerSource = source.hasOwnProperty("layer");
272
+ if (isLayerSource) {
273
+ const layerSource = source;
274
+ const layerId = (_a = layerSource.layer) === null || _a === void 0 ? void 0 : _a.id;
275
+ const layerFromMap = layerId ? view.map.findLayerById(layerId) : null;
276
+ const layerUrl = (_b = layerSource === null || layerSource === void 0 ? void 0 : layerSource.layer) === null || _b === void 0 ? void 0 : _b.url;
277
+ if (layerFromMap) {
278
+ layerSource.layer = layerFromMap;
279
+ }
280
+ else if (layerUrl) {
281
+ layerSource.layer = new this.FeatureLayer(layerUrl);
282
+ }
283
+ }
284
+ });
285
+ sources === null || sources === void 0 ? void 0 : sources.forEach((source) => {
286
+ const isLocatorSource = source.hasOwnProperty("locator");
287
+ if (isLocatorSource) {
288
+ const locatorSource = source;
289
+ if ((locatorSource === null || locatorSource === void 0 ? void 0 : locatorSource.name) === "ArcGIS World Geocoding Service") {
290
+ const outFields = locatorSource.outFields || ["Addr_type", "Match_addr", "StAddr", "City"];
291
+ locatorSource.outFields = outFields;
292
+ locatorSource.singleLineFieldName = "SingleLine";
293
+ }
294
+ locatorSource.url = locatorSource.url;
295
+ delete locatorSource.url;
296
+ }
297
+ });
298
+ }
299
+ else {
300
+ searchConfiguration = Object.assign(Object.assign({}, searchConfiguration), { includeDefaultSources: true });
301
+ }
302
+ return searchConfiguration;
303
+ }
202
304
  /**
203
305
  * Hides the elements of editor widget
204
306
  * @protected
@@ -319,9 +421,35 @@ export class CreateFeature {
319
421
  "attribute": "customize-submit",
320
422
  "reflect": false,
321
423
  "defaultValue": "false"
424
+ },
425
+ "searchConfiguration": {
426
+ "type": "unknown",
427
+ "mutable": false,
428
+ "complexType": {
429
+ "original": "ISearchConfiguration",
430
+ "resolved": "ISearchConfiguration",
431
+ "references": {
432
+ "ISearchConfiguration": {
433
+ "location": "import",
434
+ "path": "../../utils/interfaces",
435
+ "id": "src/utils/interfaces.ts::ISearchConfiguration"
436
+ }
437
+ }
438
+ },
439
+ "required": false,
440
+ "optional": false,
441
+ "docs": {
442
+ "tags": [],
443
+ "text": "ISearchConfiguration: Configuration details for the Search widget"
444
+ }
322
445
  }
323
446
  };
324
447
  }
448
+ static get states() {
449
+ return {
450
+ "showSearchWidget": {}
451
+ };
452
+ }
325
453
  static get events() {
326
454
  return [{
327
455
  "method": "success",
@@ -44,6 +44,7 @@ export class CrowdsourceManager {
44
44
  * MapView.when is not fired when mapView is not currently visible
45
45
  */
46
46
  this._shouldSetMapView = false;
47
+ this.appProxies = undefined;
47
48
  this.defaultCenter = "";
48
49
  this.defaultGlobalId = "";
49
50
  this.defaultLayer = "";
@@ -331,7 +332,7 @@ export class CrowdsourceManager {
331
332
  _getMapNode(panelOpen) {
332
333
  var _a;
333
334
  const mapContainerClass = this._layoutMode === ELayoutMode.HORIZONTAL && (!this._isMobile || panelOpen) ? "" : "adjusted-height-50";
334
- return (h("div", { class: `${mapContainerClass} overflow-hidden` }, h("map-card", { basemapConfig: this.basemapConfig, class: "width-full", defaultWebmapId: this.defaultWebmap, enableBasemap: this.enableBasemap, enableFloorFilter: this.enableFloorFilter, enableFullscreen: this.enableFullscreen, enableHome: this.enableHome, enableLegend: this.enableLegend, enableSearch: this.enableSearch, enableSingleExpand: true, hidden: this._expandPopup && !this._isMobile, homeZoomIndex: 3, homeZoomPosition: "top-left", homeZoomToolsSize: "s", mapInfos: (_a = this.mapInfos) === null || _a === void 0 ? void 0 : _a.filter(mapInfo => mapInfo.visible !== false), mapWidgetsIndex: 0, mapWidgetsPosition: "top-right", mapWidgetsSize: "m", stackTools: true, theme: this.theme, toolOrder: ["legend", "search", "fullscreen", "basemap", "floorfilter"] })));
335
+ return (h("div", { class: `${mapContainerClass} overflow-hidden` }, h("map-card", { appProxies: this.appProxies, basemapConfig: this.basemapConfig, class: "width-full", defaultWebmapId: this.defaultWebmap, enableBasemap: this.enableBasemap, enableFloorFilter: this.enableFloorFilter, enableFullscreen: this.enableFullscreen, enableHome: this.enableHome, enableLegend: this.enableLegend, enableSearch: this.enableSearch, enableSingleExpand: true, hidden: this._expandPopup && !this._isMobile, homeZoomIndex: 3, homeZoomPosition: "top-left", homeZoomToolsSize: "s", mapInfos: (_a = this.mapInfos) === null || _a === void 0 ? void 0 : _a.filter(mapInfo => mapInfo.visible !== false), mapWidgetsIndex: 0, mapWidgetsPosition: "top-right", mapWidgetsSize: "m", stackTools: true, theme: this.theme, toolOrder: ["legend", "search", "fullscreen", "basemap", "floorfilter"] })));
335
336
  }
336
337
  /**
337
338
  * Get the expand node for the popup information
@@ -504,6 +505,23 @@ export class CrowdsourceManager {
504
505
  }
505
506
  static get properties() {
506
507
  return {
508
+ "appProxies": {
509
+ "type": "any",
510
+ "mutable": false,
511
+ "complexType": {
512
+ "original": "any",
513
+ "resolved": "any",
514
+ "references": {}
515
+ },
516
+ "required": false,
517
+ "optional": false,
518
+ "docs": {
519
+ "tags": [],
520
+ "text": "Array of objects containing proxy information for premium platform services."
521
+ },
522
+ "attribute": "app-proxies",
523
+ "reflect": false
524
+ },
507
525
  "defaultCenter": {
508
526
  "type": "string",
509
527
  "mutable": false,
@@ -56,3 +56,8 @@
56
56
  .footer-button {
57
57
  height: 35px;
58
58
  }
59
+
60
+ .report-submitted-msg {
61
+ position: absolute;
62
+ z-index: 1000;
63
+ }
@@ -21,7 +21,7 @@
21
21
  import { Host, h } from "@stencil/core";
22
22
  import { getLocaleComponentStrings } from "../../utils/locale";
23
23
  import { loadModules } from "../../utils/loadModules";
24
- import { getAllLayers, getFeatureLayerView, getLayerOrTable, highlightFeatures } from "../../utils/mapViewUtils";
24
+ import { getAllLayers, getFeatureLayerView, getLayerOrTable, getMapLayerHash, highlightFeatures } from "../../utils/mapViewUtils";
25
25
  import { queryFeaturesByID } from "../../utils/queryUtils";
26
26
  export class CrowdsourceReporter {
27
27
  constructor() {
@@ -53,7 +53,7 @@ export class CrowdsourceReporter {
53
53
  this.theme = "light";
54
54
  this.enableZoom = true;
55
55
  this._mapInfo = undefined;
56
- this._flowItems = ["layer-list"];
56
+ this._flowItems = [];
57
57
  this._sidePanelCollapsed = false;
58
58
  this._translations = undefined;
59
59
  this._hasValidLayers = false;
@@ -92,16 +92,20 @@ export class CrowdsourceReporter {
92
92
  * @returns Promise when complete
93
93
  */
94
94
  async componentWillLoad() {
95
+ var _a;
95
96
  this._urlParamsLoaded = false;
96
97
  await this._initModules();
97
98
  await this._getTranslations();
99
+ await ((_a = this.mapView) === null || _a === void 0 ? void 0 : _a.when(async () => {
100
+ await this.setMapView();
101
+ }));
98
102
  }
99
103
  /**
100
104
  * Renders the component.
101
105
  */
102
106
  render() {
103
107
  const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
104
- return (h(Host, null, this._reportSubmitted && h("calcite-alert", { "auto-close": true, class: themeClass, icon: "check-circle", kind: "success", label: "", onCalciteAlertClose: () => { this._reportSubmitted = false; }, open: true, placement: "top" }, h("div", { slot: "title" }, this._translations.reportSubmit), h("div", { slot: "message" }, this.reportSubmittedMessage ? this.reportSubmittedMessage : this._translations.submitMsg)), this._featureCreationFailedErrorMsg && h("calcite-alert", { "auto-close": true, class: themeClass, icon: "x-octagon", kind: "danger", label: "", onCalciteAlertClose: () => { this._featureCreationFailedErrorMsg = ""; }, open: true, placement: "top" }, h("div", { slot: "title" }, this._translations.error), h("div", { slot: "message" }, this._featureCreationFailedErrorMsg)), h("div", null, h("calcite-shell", { "content-behind": true }, this._getReporter()))));
108
+ return (h(Host, null, this._reportSubmitted && h("calcite-alert", { "auto-close": true, class: themeClass + " report-submitted-msg", icon: "check-circle", kind: "success", label: "", onCalciteAlertClose: () => { this._reportSubmitted = false; }, open: true, placement: "top" }, h("div", { slot: "message" }, this.reportSubmittedMessage ? this.reportSubmittedMessage : this._translations.submitMsg)), this._featureCreationFailedErrorMsg && h("calcite-alert", { "auto-close": true, class: themeClass, icon: "x-octagon", kind: "danger", label: "", onCalciteAlertClose: () => { this._featureCreationFailedErrorMsg = ""; }, open: true, placement: "top" }, h("div", { slot: "title" }, this._translations.error), h("div", { slot: "message" }, this._featureCreationFailedErrorMsg)), h("div", null, h("calcite-shell", { "content-behind": true }, this._getReporter()))));
105
109
  }
106
110
  //--------------------------------------------------------------------------
107
111
  //
@@ -171,8 +175,9 @@ export class CrowdsourceReporter {
171
175
  * @protected
172
176
  */
173
177
  getLayerListFlowItem() {
178
+ var _a;
174
179
  return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this.reportsHeader }, this.isMobile && this.getActionToExpandCollapsePanel(), this._hasValidLayers && this.enableNewReports &&
175
- h("calcite-button", { appearance: "solid", onClick: this.navigateToChooseCategory.bind(this), slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true, "full-width": true }, h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._noLayerToDisplayErrorMsg, onLayerSelect: this.displayFeaturesList.bind(this), onLayersListLoaded: this.layerListLoaded.bind(this), ref: el => this._layerList = el, showFeatureCount: true, showNextIcon: true }))));
180
+ h("calcite-button", { appearance: "solid", onClick: this.navigateToChooseCategory.bind(this), slot: "footer", width: "full" }, this.reportButtonText ? this.reportButtonText : this._translations.createReportButtonText), h("calcite-panel", { "full-height": true, "full-width": true }, h("layer-list", { class: "height-full", layers: ((_a = this._editableLayerIds) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this._editableLayerIds : this.layers, mapView: this.mapView, noLayerErrorMsg: this._noLayerToDisplayErrorMsg, onLayerSelect: this.displayFeaturesList.bind(this), onLayersListLoaded: this.layerListLoaded.bind(this), ref: el => this._layerList = el, showFeatureCount: true, showNextIcon: true }))));
176
181
  }
177
182
  /**
178
183
  * Get the layer list for creating a report
@@ -180,7 +185,7 @@ export class CrowdsourceReporter {
180
185
  * @protected
181
186
  */
182
187
  getChooseCategoryFlowItem() {
183
- return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._translations.createReportHeader, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), h("div", { class: "width-full", slot: "footer" }, h("calcite-button", { appearance: "solid", class: "footer-top-button footer-button", disabled: !this._selectedLayerId, onClick: this.navigateToCreateFeature.bind(this), width: "full" }, this._translations.next), h("calcite-button", { appearance: "outline", class: "footer-button", onClick: this.backFromSelectedPanel.bind(this), width: "full" }, this._translations.cancel)), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.chooseCategoryMsg)), h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._noLayerToDisplayErrorMsg, onLayerSelect: this.highlightSelectedLayer.bind(this), showFeatureCount: false, showNextIcon: false }))));
188
+ return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this.reportButtonText ? this.reportButtonText : this._translations.createReportButtonText, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.chooseCategoryMsg)), h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._noLayerToDisplayErrorMsg, onLayerSelect: this.navigateToCreateFeature.bind(this), showFeatureCount: false, showNextIcon: false }))));
184
189
  }
185
190
  /**
186
191
  * Get Feature create form of the selected feature layer
@@ -188,7 +193,7 @@ export class CrowdsourceReporter {
188
193
  * @protected
189
194
  */
190
195
  getFeatureCreateFlowItem() {
191
- return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.backFromCreateFeaturePanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), this._showSubmitCancelButton && h("div", { class: "width-full", slot: "footer" }, h("calcite-button", { appearance: "solid", class: "footer-top-button footer-button", onClick: this.onSubmitButtonClick.bind(this), width: "full" }, this._translations.submit), h("calcite-button", { appearance: "outline", class: "footer-button", onClick: this.backFromCreateFeaturePanel.bind(this), width: "full" }, this._translations.cancel)), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.featureEditFormInfoMsg)), h("create-feature", { customizeSubmit: true, mapView: this.mapView, onDrawComplete: this.onDrawComplete.bind(this), onEditingAttachment: this.showSubmitCancelButton.bind(this), onFail: this.createFeatureFailed.bind(this), onSuccess: this.onReportSubmitted.bind(this), ref: el => this._createFeature = el, selectedLayerId: this._selectedLayerId }))));
196
+ return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.backFromCreateFeaturePanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), this._showSubmitCancelButton && h("div", { class: "width-full", slot: "footer" }, h("calcite-button", { appearance: "solid", class: "footer-top-button footer-button", onClick: this.onSubmitButtonClick.bind(this), width: "full" }, this._translations.submit), h("calcite-button", { appearance: "outline", class: "footer-button", onClick: this.backFromCreateFeaturePanel.bind(this), width: "full" }, this._translations.cancel)), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.featureEditFormInfoMsg)), h("create-feature", { customizeSubmit: true, mapView: this.mapView, onDrawComplete: this.onDrawComplete.bind(this), onEditingAttachment: this.showSubmitCancelButton.bind(this), onFail: this.createFeatureFailed.bind(this), onSuccess: this.onReportSubmitted.bind(this), ref: el => this._createFeature = el, searchConfiguration: this.searchConfiguration, selectedLayerId: this._selectedLayerId }))));
192
197
  }
193
198
  /**
194
199
  * When drawing of incident location completed on map show the submit and cancel button
@@ -238,13 +243,13 @@ export class CrowdsourceReporter {
238
243
  */
239
244
  onReportSubmitted() {
240
245
  this._reportSubmitted = true;
241
- this.navigateToHomePage();
246
+ void this.navigateToHomePage();
242
247
  }
243
248
  /**
244
249
  * Navigates to layer-list
245
250
  * @protected
246
251
  */
247
- navigateToHomePage() {
252
+ async navigateToHomePage() {
248
253
  if (this._createFeature) {
249
254
  this._createFeature.close();
250
255
  }
@@ -252,21 +257,23 @@ export class CrowdsourceReporter {
252
257
  this._layerList.refresh();
253
258
  }
254
259
  this.setSelectedFeatures([]);
255
- this._flowItems = ["layer-list"];
260
+ if (this._editableLayerIds.length === 1) {
261
+ await this._featureList.refresh();
262
+ this._flowItems = ["feature-list"];
263
+ }
264
+ else {
265
+ this._flowItems = ["layer-list"];
266
+ }
256
267
  }
257
268
  /**
258
- * Update the selected layer id and name
269
+ * On layer select open the feature create flow item
259
270
  * @param evt Event which has details of selected layerId and layerName
260
271
  * @protected
261
272
  */
262
- highlightSelectedLayer(evt) {
263
- this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
264
- }
265
- /**
266
- * On next button click open the feature create flow item
267
- * @protected
268
- */
269
- async navigateToCreateFeature() {
273
+ async navigateToCreateFeature(evt) {
274
+ if (evt.detail.layerId && evt.detail.layerName) {
275
+ this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
276
+ }
270
277
  this._showSubmitCancelButton = false;
271
278
  this._flowItems = [...this._flowItems, "feature-create"];
272
279
  }
@@ -319,8 +326,8 @@ export class CrowdsourceReporter {
319
326
  updatedFlowItems.pop();
320
327
  this.clearHighlights();
321
328
  //Back to layer list, and return as the flowItems will be reset in navigateToHomePage
322
- if (updatedFlowItems.length === 1) {
323
- this.navigateToHomePage();
329
+ if (updatedFlowItems.length === 1 && updatedFlowItems[0] === 'layer-list') {
330
+ void this.navigateToHomePage();
324
331
  return;
325
332
  }
326
333
  this._flowItems = [...updatedFlowItems];
@@ -350,7 +357,7 @@ export class CrowdsourceReporter {
350
357
  */
351
358
  getFeatureListFlowItem(layerId, layerName) {
352
359
  return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: layerName, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), this.enableNewReports &&
353
- h("calcite-button", { appearance: "solid", onClick: this.navigateToCreateFeature.bind(this), slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true }, h("feature-list", { class: "height-full", mapView: this.mapView, noFeaturesFoundMsg: this._translations.featureErrorMsg, onFeatureSelect: this.onFeatureSelectFromList.bind(this), pageSize: 30, selectedLayerId: layerId }))));
360
+ h("calcite-button", { appearance: "solid", onClick: this.navigateToCreateFeature.bind(this), slot: "footer", width: "full" }, this.reportButtonText ? this.reportButtonText : this._translations.createReportButtonText), h("calcite-panel", { "full-height": true }, h("feature-list", { class: "height-full", highlightOnHover: true, mapView: this.mapView, noFeaturesFoundMsg: this._translations.featureErrorMsg, onFeatureSelect: this.onFeatureSelectFromList.bind(this), pageSize: 30, ref: el => this._featureList = el, selectedLayerId: layerId }))));
354
361
  }
355
362
  /**
356
363
  * Returns the calcite-flow item for feature details
@@ -378,7 +385,9 @@ export class CrowdsourceReporter {
378
385
  this._currentFeatureId = selectedFeature.attributes[layer.objectIdField];
379
386
  }
380
387
  else {
381
- this.setSelectedLayer('', '');
388
+ if (this._editableLayerIds.length > 1) {
389
+ this.setSelectedLayer('', '');
390
+ }
382
391
  this._currentFeatureId = '';
383
392
  }
384
393
  this._updateShareURL();
@@ -401,6 +410,8 @@ export class CrowdsourceReporter {
401
410
  // highlight the newly selected feature only when it has valid geometry
402
411
  if (selectedFeature && selectedFeature.geometry && selectedFeature.layer) {
403
412
  const selectedLayerView = await getFeatureLayerView(this.mapView, selectedFeature.layer.id);
413
+ // remove previous highlight options (if any) to highlight the feature by default color
414
+ selectedLayerView.highlightOptions = null;
404
415
  this._highlightHandle = await highlightFeatures([selectedFeature.getObjectId()], selectedLayerView, this.mapView, true);
405
416
  }
406
417
  }
@@ -426,6 +437,15 @@ export class CrowdsourceReporter {
426
437
  * @protected
427
438
  */
428
439
  async setMapView() {
440
+ var _a;
441
+ await this.getLayersToShowInList();
442
+ // if only one valid layer is present then directly render features list
443
+ if (((_a = this._editableLayerIds) === null || _a === void 0 ? void 0 : _a.length) === 1) {
444
+ await this.renderFeaturesList();
445
+ }
446
+ else {
447
+ this._flowItems = ['layer-list'];
448
+ }
429
449
  this.mapView.popupEnabled = false;
430
450
  if (this._defaultCenter && this._defaultLevel) {
431
451
  await this.mapView.goTo({
@@ -449,7 +469,7 @@ export class CrowdsourceReporter {
449
469
  this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", this.onMapClick.bind(this));
450
470
  }
451
471
  /**
452
- * On map click do hitTest and get the clicked graphics of valid layers and show feature details
472
+ * On map click do hitTest and get the clicked graphics from both reporting and non-reporting layers, and show feature details
453
473
  * @param event IMapClick map click event details
454
474
  *
455
475
  * @protected
@@ -457,12 +477,8 @@ export class CrowdsourceReporter {
457
477
  async onMapClick(event) {
458
478
  //disable map popup
459
479
  this.mapView.popupEnabled = false;
460
- // only include graphics from valid layers listed in the layer list widget
461
- const opts = {
462
- include: this._validLayers
463
- };
464
480
  // Perform a hitTest on the View
465
- const hitTest = await this.mapView.hitTest(event, opts);
481
+ const hitTest = await this.mapView.hitTest(event);
466
482
  if (hitTest.results.length > 0) {
467
483
  const clickedGraphics = [];
468
484
  hitTest.results.forEach(function (result) {
@@ -471,16 +487,35 @@ export class CrowdsourceReporter {
471
487
  clickedGraphics.push(result.graphic);
472
488
  }
473
489
  });
474
- //update the selectedFeature
475
- this.setSelectedFeatures(clickedGraphics);
476
- //if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
477
- // eslint-disable-next-line unicorn/prefer-ternary
478
- if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
479
- this._flowItems = [...this._flowItems, "feature-details"];
490
+ const reportingLayerGraphics = clickedGraphics.filter((graphic) => {
491
+ return this._validLayers.includes(graphic.layer);
492
+ });
493
+ const nonReportingLayerGraphics = clickedGraphics.filter((graphic) => {
494
+ var _a;
495
+ return !this._validLayers.includes(graphic.layer) && ((_a = graphic === null || graphic === void 0 ? void 0 : graphic.layer) === null || _a === void 0 ? void 0 : _a.id);
496
+ });
497
+ // if clicked graphic's layer is one of the reporting layers then show details in layer panel
498
+ if (reportingLayerGraphics.length > 0) {
499
+ //update the selectedFeature
500
+ this.setSelectedFeatures(reportingLayerGraphics);
501
+ //if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
502
+ // eslint-disable-next-line unicorn/prefer-ternary
503
+ if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
504
+ this._flowItems = [...this._flowItems, "feature-details"];
505
+ }
506
+ else {
507
+ this._flowItems = [...this._flowItems];
508
+ void this.highlightOnMap(clickedGraphics[0]);
509
+ }
480
510
  }
481
- else {
482
- this._flowItems = [...this._flowItems];
483
- void this.highlightOnMap(clickedGraphics[0]);
511
+ // if clicked graphic's layer is from non reporting layers then show popup on map
512
+ if (nonReportingLayerGraphics.length > 0) {
513
+ this.mapView.popupEnabled = true;
514
+ const options = {
515
+ features: nonReportingLayerGraphics,
516
+ updateLocationEnabled: true
517
+ };
518
+ await this.mapView.openPopup(options);
484
519
  }
485
520
  }
486
521
  }
@@ -493,10 +528,57 @@ export class CrowdsourceReporter {
493
528
  const messages = await getLocaleComponentStrings(this.el);
494
529
  this._translations = messages[0];
495
530
  }
531
+ /**
532
+ * Returns the ids of all OR configured layers that support edits with the update capability
533
+ * @param hash each layer item details
534
+ * @param layers list of layers id
535
+ * @returns array of editable layer ids
536
+ */
537
+ reduceToConfiguredLayers(hash) {
538
+ var _a;
539
+ const configuredLayers = ((_a = this.layers) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.layers : [];
540
+ return Object.keys(hash).reduce((prev, cur) => {
541
+ let showLayer = hash[cur].supportsAdd;
542
+ if ((configuredLayers === null || configuredLayers === void 0 ? void 0 : configuredLayers.length) > 0) {
543
+ showLayer = configuredLayers.indexOf(cur) > -1 ? hash[cur].supportsAdd : false;
544
+ }
545
+ if (showLayer) {
546
+ prev.push(cur);
547
+ }
548
+ return prev;
549
+ }, []);
550
+ }
551
+ /**
552
+ * Creates the list of layers to be listed in layer list
553
+ * @protected
554
+ */
555
+ async getLayersToShowInList() {
556
+ const layerItemsHash = await getMapLayerHash(this.mapView, true);
557
+ const allMapLayers = await getAllLayers(this.mapView);
558
+ allMapLayers.forEach((eachLayer) => {
559
+ var _a, _b;
560
+ if ((eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.type) === "feature" && (eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.editingEnabled) && ((_b = (_a = eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.capabilities) === null || _a === void 0 ? void 0 : _a.operations) === null || _b === void 0 ? void 0 : _b.supportsAdd)) {
561
+ layerItemsHash[eachLayer.id].supportsAdd = true;
562
+ }
563
+ });
564
+ this._editableLayerIds = this.reduceToConfiguredLayers(layerItemsHash);
565
+ }
566
+ /**
567
+ * renders feature list
568
+ * @protected
569
+ */
570
+ async renderFeaturesList() {
571
+ const evt = {
572
+ detail: this._editableLayerIds
573
+ };
574
+ await this.layerListLoaded(evt);
575
+ this.setSelectedLayer(this._validLayers[0].id, this._validLayers[0].title);
576
+ this._flowItems = ['feature-list'];
577
+ }
496
578
  /**
497
579
  * Updates the share url for current selected feature
498
580
  * @protected
499
- */
581
+ */
500
582
  _updateShareURL() {
501
583
  var _a, _b;
502
584
  const url = (_a = this._shareNode) === null || _a === void 0 ? void 0 : _a.shareUrl;