@esri/solutions-components 0.8.5 → 0.8.7

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 (94) 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/crowdsource-manager.cjs.entry.js +6 -4
  12. package/dist/cjs/crowdsource-reporter.cjs.entry.js +124 -38
  13. package/dist/cjs/loader.cjs.js +1 -1
  14. package/dist/cjs/map-select-tools_3.cjs.entry.js +2 -2
  15. package/dist/cjs/public-notification.cjs.entry.js +110 -4
  16. package/dist/cjs/{publicNotificationStore-ef379d11.js → publicNotificationStore-e790601d.js} +2 -2
  17. package/dist/cjs/solutions-components.cjs.js +1 -1
  18. package/dist/collection/collection-manifest.json +1 -1
  19. package/dist/collection/components/create-feature/create-feature.css +9 -0
  20. package/dist/collection/components/create-feature/create-feature.js +134 -6
  21. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +102 -66
  22. package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.css +5 -0
  23. package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.js +196 -38
  24. package/dist/collection/components/feature-list/feature-list.js +93 -5
  25. package/dist/collection/components/info-card/info-card.css +1 -1
  26. package/dist/collection/components/info-card/info-card.js +1 -1
  27. package/dist/collection/components/layer-list/layer-list.js +6 -6
  28. package/dist/collection/components/map-draw-tools/map-draw-tools.js +1 -1
  29. package/dist/collection/components/map-layer-picker/map-layer-picker.js +1 -1
  30. package/dist/collection/components/map-select-tools/map-select-tools.js +1 -1
  31. package/dist/collection/components/public-notification/public-notification.js +110 -3
  32. package/dist/collection/demos/crowdsource-reporter.html +1 -1
  33. package/dist/collection/utils/interfaces.ts +23 -0
  34. package/dist/collection/utils/publicNotificationStore.js +2 -2
  35. package/dist/collection/utils/publicNotificationStore.ts +3 -2
  36. package/dist/components/create-feature2.js +111 -7
  37. package/dist/components/crowdsource-manager.js +12 -8
  38. package/dist/components/crowdsource-reporter.js +129 -39
  39. package/dist/components/feature-list2.js +54 -6
  40. package/dist/components/info-card2.js +2 -2
  41. package/dist/components/layer-list2.js +6 -6
  42. package/dist/components/map-draw-tools2.js +1 -1
  43. package/dist/components/map-layer-picker2.js +1 -1
  44. package/dist/components/map-select-tools2.js +1 -1
  45. package/dist/components/public-notification.js +110 -3
  46. package/dist/components/publicNotificationStore.js +2 -2
  47. package/dist/esm/buffer-tools_3.entry.js +2 -2
  48. package/dist/esm/calcite-alert_4.entry.js +3 -3
  49. package/dist/esm/calcite-combobox_5.entry.js +3 -3
  50. package/dist/esm/calcite-flow_5.entry.js +164 -17
  51. package/dist/esm/card-manager_3.entry.js +2 -2
  52. package/dist/esm/crowdsource-manager.entry.js +7 -5
  53. package/dist/esm/crowdsource-reporter.entry.js +125 -39
  54. package/dist/esm/{downloadUtils-0c13073b.js → downloadUtils-0c1e4d7b.js} +2 -2
  55. package/dist/esm/{index.es-ad250bc6.js → index.es-286e3cfa.js} +2 -2
  56. package/dist/esm/loader.js +1 -1
  57. package/dist/esm/map-select-tools_3.entry.js +4 -4
  58. package/dist/esm/{mapViewUtils-20504620.js → mapViewUtils-253178f1.js} +1 -1
  59. package/dist/esm/public-notification.entry.js +112 -6
  60. package/dist/esm/{publicNotificationStore-3bf4de75.js → publicNotificationStore-223faed2.js} +2 -2
  61. package/dist/esm/solutions-components.js +1 -1
  62. package/dist/solutions-components/demos/crowdsource-reporter.html +1 -1
  63. package/dist/solutions-components/p-15f9624a.entry.js +6 -0
  64. package/dist/solutions-components/{p-955647ea.entry.js → p-1ea5e061.entry.js} +2 -2
  65. package/dist/solutions-components/{p-590a2a26.js → p-212b02e7.js} +1 -1
  66. package/dist/solutions-components/p-238d3b5f.entry.js +6 -0
  67. package/dist/solutions-components/{p-cc280aa1.js → p-322868ec.js} +1 -1
  68. package/dist/solutions-components/{p-1d3a1794.js → p-331b5d1e.js} +2 -2
  69. package/dist/solutions-components/{p-c897e3eb.js → p-3af79063.js} +1 -1
  70. package/dist/solutions-components/p-6db185bf.entry.js +6 -0
  71. package/dist/solutions-components/p-80b11ec1.entry.js +17 -0
  72. package/dist/solutions-components/{p-5c7e3941.entry.js → p-813fd8a4.entry.js} +2 -2
  73. package/dist/solutions-components/{p-ff302d95.entry.js → p-d136eab0.entry.js} +2 -2
  74. package/dist/solutions-components/p-e0446d5b.entry.js +6 -0
  75. package/dist/solutions-components/p-e8f13354.entry.js +6 -0
  76. package/dist/solutions-components/solutions-components.esm.js +1 -1
  77. package/dist/solutions-components/utils/interfaces.ts +23 -0
  78. package/dist/solutions-components/utils/publicNotificationStore.ts +3 -2
  79. package/dist/types/components/create-feature/create-feature.d.ts +43 -1
  80. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +22 -14
  81. package/dist/types/components/crowdsource-reporter/crowdsource-reporter.d.ts +48 -11
  82. package/dist/types/components/feature-list/feature-list.d.ts +31 -0
  83. package/dist/types/components/layer-list/layer-list.d.ts +3 -3
  84. package/dist/types/components/public-notification/public-notification.d.ts +48 -0
  85. package/dist/types/components.d.ts +71 -2
  86. package/dist/types/utils/interfaces.d.ts +20 -0
  87. package/dist/types/utils/publicNotificationStore.d.ts +2 -1
  88. package/package.json +1 -1
  89. package/dist/solutions-components/p-6512dc44.entry.js +0 -6
  90. package/dist/solutions-components/p-6f65682c.entry.js +0 -6
  91. package/dist/solutions-components/p-989bf0bf.entry.js +0 -6
  92. package/dist/solutions-components/p-a0611720.entry.js +0 -6
  93. package/dist/solutions-components/p-b8c12736.entry.js +0 -6
  94. package/dist/solutions-components/p-efe1694a.entry.js +0 -17
@@ -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() {
@@ -41,8 +41,11 @@ export class CrowdsourceReporter {
41
41
  this.objectId = undefined;
42
42
  this.center = undefined;
43
43
  this.level = undefined;
44
+ this.popupHeaderHoverColor = undefined;
45
+ this.popupHeaderColor = undefined;
44
46
  this.reportButtonText = undefined;
45
47
  this.reportsHeader = undefined;
48
+ this.reportingOptions = undefined;
46
49
  this.reportSubmittedMessage = undefined;
47
50
  this.searchConfiguration = undefined;
48
51
  this.showComments = undefined;
@@ -52,8 +55,9 @@ export class CrowdsourceReporter {
52
55
  this.mapInfos = [];
53
56
  this.theme = "light";
54
57
  this.enableZoom = true;
58
+ this.zoomToScale = undefined;
55
59
  this._mapInfo = undefined;
56
- this._flowItems = ["layer-list"];
60
+ this._flowItems = [];
57
61
  this._sidePanelCollapsed = false;
58
62
  this._translations = undefined;
59
63
  this._hasValidLayers = false;
@@ -92,16 +96,20 @@ export class CrowdsourceReporter {
92
96
  * @returns Promise when complete
93
97
  */
94
98
  async componentWillLoad() {
99
+ var _a;
95
100
  this._urlParamsLoaded = false;
96
101
  await this._initModules();
97
102
  await this._getTranslations();
103
+ await ((_a = this.mapView) === null || _a === void 0 ? void 0 : _a.when(async () => {
104
+ await this.setMapView();
105
+ }));
98
106
  }
99
107
  /**
100
108
  * Renders the component.
101
109
  */
102
110
  render() {
103
111
  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()))));
112
+ 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
113
  }
106
114
  //--------------------------------------------------------------------------
107
115
  //
@@ -171,8 +179,9 @@ export class CrowdsourceReporter {
171
179
  * @protected
172
180
  */
173
181
  getLayerListFlowItem() {
182
+ var _a;
174
183
  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 }))));
184
+ 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
185
  }
177
186
  /**
178
187
  * Get the layer list for creating a report
@@ -180,7 +189,7 @@ export class CrowdsourceReporter {
180
189
  * @protected
181
190
  */
182
191
  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 }))));
192
+ 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
193
  }
185
194
  /**
186
195
  * Get Feature create form of the selected feature layer
@@ -188,7 +197,7 @@ export class CrowdsourceReporter {
188
197
  * @protected
189
198
  */
190
199
  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 }))));
200
+ 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
201
  }
193
202
  /**
194
203
  * When drawing of incident location completed on map show the submit and cancel button
@@ -238,13 +247,13 @@ export class CrowdsourceReporter {
238
247
  */
239
248
  onReportSubmitted() {
240
249
  this._reportSubmitted = true;
241
- this.navigateToHomePage();
250
+ void this.navigateToHomePage();
242
251
  }
243
252
  /**
244
253
  * Navigates to layer-list
245
254
  * @protected
246
255
  */
247
- navigateToHomePage() {
256
+ async navigateToHomePage() {
248
257
  if (this._createFeature) {
249
258
  this._createFeature.close();
250
259
  }
@@ -252,21 +261,23 @@ export class CrowdsourceReporter {
252
261
  this._layerList.refresh();
253
262
  }
254
263
  this.setSelectedFeatures([]);
255
- this._flowItems = ["layer-list"];
264
+ if (this._editableLayerIds.length === 1) {
265
+ await this._featureList.refresh();
266
+ this._flowItems = ["feature-list"];
267
+ }
268
+ else {
269
+ this._flowItems = ["layer-list"];
270
+ }
256
271
  }
257
272
  /**
258
- * Update the selected layer id and name
273
+ * On layer select open the feature create flow item
259
274
  * @param evt Event which has details of selected layerId and layerName
260
275
  * @protected
261
276
  */
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() {
277
+ async navigateToCreateFeature(evt) {
278
+ if (evt.detail.layerId && evt.detail.layerName) {
279
+ this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
280
+ }
270
281
  this._showSubmitCancelButton = false;
271
282
  this._flowItems = [...this._flowItems, "feature-create"];
272
283
  }
@@ -319,8 +330,8 @@ export class CrowdsourceReporter {
319
330
  updatedFlowItems.pop();
320
331
  this.clearHighlights();
321
332
  //Back to layer list, and return as the flowItems will be reset in navigateToHomePage
322
- if (updatedFlowItems.length === 1) {
323
- this.navigateToHomePage();
333
+ if (updatedFlowItems.length === 1 && updatedFlowItems[0] === 'layer-list') {
334
+ void this.navigateToHomePage();
324
335
  return;
325
336
  }
326
337
  this._flowItems = [...updatedFlowItems];
@@ -350,7 +361,7 @@ export class CrowdsourceReporter {
350
361
  */
351
362
  getFeatureListFlowItem(layerId, layerName) {
352
363
  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 }))));
364
+ 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
365
  }
355
366
  /**
356
367
  * Returns the calcite-flow item for feature details
@@ -378,7 +389,9 @@ export class CrowdsourceReporter {
378
389
  this._currentFeatureId = selectedFeature.attributes[layer.objectIdField];
379
390
  }
380
391
  else {
381
- this.setSelectedLayer('', '');
392
+ if (this._editableLayerIds.length > 1) {
393
+ this.setSelectedLayer('', '');
394
+ }
382
395
  this._currentFeatureId = '';
383
396
  }
384
397
  this._updateShareURL();
@@ -401,6 +414,8 @@ export class CrowdsourceReporter {
401
414
  // highlight the newly selected feature only when it has valid geometry
402
415
  if (selectedFeature && selectedFeature.geometry && selectedFeature.layer) {
403
416
  const selectedLayerView = await getFeatureLayerView(this.mapView, selectedFeature.layer.id);
417
+ // remove previous highlight options (if any) to highlight the feature by default color
418
+ selectedLayerView.highlightOptions = null;
404
419
  this._highlightHandle = await highlightFeatures([selectedFeature.getObjectId()], selectedLayerView, this.mapView, true);
405
420
  }
406
421
  }
@@ -426,6 +441,15 @@ export class CrowdsourceReporter {
426
441
  * @protected
427
442
  */
428
443
  async setMapView() {
444
+ var _a;
445
+ await this.getLayersToShowInList();
446
+ // if only one valid layer is present then directly render features list
447
+ if (((_a = this._editableLayerIds) === null || _a === void 0 ? void 0 : _a.length) === 1) {
448
+ await this.renderFeaturesList();
449
+ }
450
+ else {
451
+ this._flowItems = ['layer-list'];
452
+ }
429
453
  this.mapView.popupEnabled = false;
430
454
  if (this._defaultCenter && this._defaultLevel) {
431
455
  await this.mapView.goTo({
@@ -449,7 +473,7 @@ export class CrowdsourceReporter {
449
473
  this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", this.onMapClick.bind(this));
450
474
  }
451
475
  /**
452
- * On map click do hitTest and get the clicked graphics of valid layers and show feature details
476
+ * On map click do hitTest and get the clicked graphics from both reporting and non-reporting layers, and show feature details
453
477
  * @param event IMapClick map click event details
454
478
  *
455
479
  * @protected
@@ -457,12 +481,8 @@ export class CrowdsourceReporter {
457
481
  async onMapClick(event) {
458
482
  //disable map popup
459
483
  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
484
  // Perform a hitTest on the View
465
- const hitTest = await this.mapView.hitTest(event, opts);
485
+ const hitTest = await this.mapView.hitTest(event);
466
486
  if (hitTest.results.length > 0) {
467
487
  const clickedGraphics = [];
468
488
  hitTest.results.forEach(function (result) {
@@ -471,16 +491,35 @@ export class CrowdsourceReporter {
471
491
  clickedGraphics.push(result.graphic);
472
492
  }
473
493
  });
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"];
494
+ const reportingLayerGraphics = clickedGraphics.filter((graphic) => {
495
+ return this._validLayers.includes(graphic.layer);
496
+ });
497
+ const nonReportingLayerGraphics = clickedGraphics.filter((graphic) => {
498
+ var _a;
499
+ return !this._validLayers.includes(graphic.layer) && ((_a = graphic === null || graphic === void 0 ? void 0 : graphic.layer) === null || _a === void 0 ? void 0 : _a.id);
500
+ });
501
+ // if clicked graphic's layer is one of the reporting layers then show details in layer panel
502
+ if (reportingLayerGraphics.length > 0) {
503
+ //update the selectedFeature
504
+ this.setSelectedFeatures(reportingLayerGraphics);
505
+ //if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
506
+ // eslint-disable-next-line unicorn/prefer-ternary
507
+ if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
508
+ this._flowItems = [...this._flowItems, "feature-details"];
509
+ }
510
+ else {
511
+ this._flowItems = [...this._flowItems];
512
+ void this.highlightOnMap(clickedGraphics[0]);
513
+ }
480
514
  }
481
- else {
482
- this._flowItems = [...this._flowItems];
483
- void this.highlightOnMap(clickedGraphics[0]);
515
+ // if clicked graphic's layer is from non reporting layers then show popup on map
516
+ if (nonReportingLayerGraphics.length > 0) {
517
+ this.mapView.popupEnabled = true;
518
+ const options = {
519
+ features: nonReportingLayerGraphics,
520
+ updateLocationEnabled: true
521
+ };
522
+ await this.mapView.openPopup(options);
484
523
  }
485
524
  }
486
525
  }
@@ -493,10 +532,57 @@ export class CrowdsourceReporter {
493
532
  const messages = await getLocaleComponentStrings(this.el);
494
533
  this._translations = messages[0];
495
534
  }
535
+ /**
536
+ * Returns the ids of all OR configured layers that support edits with the update capability
537
+ * @param hash each layer item details
538
+ * @param layers list of layers id
539
+ * @returns array of editable layer ids
540
+ */
541
+ reduceToConfiguredLayers(hash) {
542
+ var _a;
543
+ const configuredLayers = ((_a = this.layers) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.layers : [];
544
+ return Object.keys(hash).reduce((prev, cur) => {
545
+ let showLayer = hash[cur].supportsAdd;
546
+ if ((configuredLayers === null || configuredLayers === void 0 ? void 0 : configuredLayers.length) > 0) {
547
+ showLayer = configuredLayers.indexOf(cur) > -1 ? hash[cur].supportsAdd : false;
548
+ }
549
+ if (showLayer) {
550
+ prev.push(cur);
551
+ }
552
+ return prev;
553
+ }, []);
554
+ }
555
+ /**
556
+ * Creates the list of layers to be listed in layer list
557
+ * @protected
558
+ */
559
+ async getLayersToShowInList() {
560
+ const layerItemsHash = await getMapLayerHash(this.mapView, true);
561
+ const allMapLayers = await getAllLayers(this.mapView);
562
+ allMapLayers.forEach((eachLayer) => {
563
+ var _a, _b;
564
+ 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)) {
565
+ layerItemsHash[eachLayer.id].supportsAdd = true;
566
+ }
567
+ });
568
+ this._editableLayerIds = this.reduceToConfiguredLayers(layerItemsHash);
569
+ }
570
+ /**
571
+ * renders feature list
572
+ * @protected
573
+ */
574
+ async renderFeaturesList() {
575
+ const evt = {
576
+ detail: this._editableLayerIds
577
+ };
578
+ await this.layerListLoaded(evt);
579
+ this.setSelectedLayer(this._validLayers[0].id, this._validLayers[0].title);
580
+ this._flowItems = ['feature-list'];
581
+ }
496
582
  /**
497
583
  * Updates the share url for current selected feature
498
584
  * @protected
499
- */
585
+ */
500
586
  _updateShareURL() {
501
587
  var _a, _b;
502
588
  const url = (_a = this._shareNode) === null || _a === void 0 ? void 0 : _a.shareUrl;
@@ -805,6 +891,40 @@ export class CrowdsourceReporter {
805
891
  "attribute": "level",
806
892
  "reflect": false
807
893
  },
894
+ "popupHeaderHoverColor": {
895
+ "type": "string",
896
+ "mutable": false,
897
+ "complexType": {
898
+ "original": "string",
899
+ "resolved": "string",
900
+ "references": {}
901
+ },
902
+ "required": false,
903
+ "optional": false,
904
+ "docs": {
905
+ "tags": [],
906
+ "text": "string: The color that will be displayed on hover when expanding the popup header"
907
+ },
908
+ "attribute": "popup-header-hover-color",
909
+ "reflect": false
910
+ },
911
+ "popupHeaderColor": {
912
+ "type": "string",
913
+ "mutable": false,
914
+ "complexType": {
915
+ "original": "string",
916
+ "resolved": "string",
917
+ "references": {}
918
+ },
919
+ "required": false,
920
+ "optional": false,
921
+ "docs": {
922
+ "tags": [],
923
+ "text": "string: The background color to apply to the popup header"
924
+ },
925
+ "attribute": "popup-header-color",
926
+ "reflect": false
927
+ },
808
928
  "reportButtonText": {
809
929
  "type": "string",
810
930
  "mutable": false,
@@ -839,6 +959,27 @@ export class CrowdsourceReporter {
839
959
  "attribute": "reports-header",
840
960
  "reflect": false
841
961
  },
962
+ "reportingOptions": {
963
+ "type": "unknown",
964
+ "mutable": false,
965
+ "complexType": {
966
+ "original": "IReportingOptions",
967
+ "resolved": "IReportingOptions",
968
+ "references": {
969
+ "IReportingOptions": {
970
+ "location": "import",
971
+ "path": "../../utils/interfaces",
972
+ "id": "src/utils/interfaces.ts::IReportingOptions"
973
+ }
974
+ }
975
+ },
976
+ "required": false,
977
+ "optional": false,
978
+ "docs": {
979
+ "tags": [],
980
+ "text": "IReportingOptions: Key options for reporting"
981
+ }
982
+ },
842
983
  "reportSubmittedMessage": {
843
984
  "type": "string",
844
985
  "mutable": false,
@@ -1011,6 +1152,23 @@ export class CrowdsourceReporter {
1011
1152
  "attribute": "enable-zoom",
1012
1153
  "reflect": false,
1013
1154
  "defaultValue": "true"
1155
+ },
1156
+ "zoomToScale": {
1157
+ "type": "number",
1158
+ "mutable": false,
1159
+ "complexType": {
1160
+ "original": "number",
1161
+ "resolved": "number",
1162
+ "references": {}
1163
+ },
1164
+ "required": false,
1165
+ "optional": false,
1166
+ "docs": {
1167
+ "tags": [],
1168
+ "text": "number: default scale to zoom to when zooming to a single point feature"
1169
+ },
1170
+ "attribute": "zoom-to-scale",
1171
+ "reflect": false
1014
1172
  }
1015
1173
  };
1016
1174
  }
@@ -19,6 +19,7 @@
19
19
  * limitations under the License.
20
20
  */
21
21
  import { h } from "@stencil/core";
22
+ import { loadModules } from "../../utils/loadModules";
22
23
  import { PopupUtils } from "../../utils/popupUtils";
23
24
  import { getFeatureLayerView, getLayerOrTable, highlightFeatures } from "../../utils/mapViewUtils";
24
25
  import { getLocaleComponentStrings } from "../../utils/locale";
@@ -29,6 +30,7 @@ export class FeatureList {
29
30
  this.noFeaturesFoundMsg = undefined;
30
31
  this.pageSize = 100;
31
32
  this.highlightOnMap = false;
33
+ this.highlightOnHover = false;
32
34
  this._featureItems = [];
33
35
  this._featuresCount = 0;
34
36
  this._isLoading = false;
@@ -48,6 +50,16 @@ export class FeatureList {
48
50
  }
49
51
  //--------------------------------------------------------------------------
50
52
  //
53
+ // Methods (public)
54
+ /**
55
+ * Refresh the feature list which will fetch the latest features and update the features list
56
+ * @returns Promise that resolves when the operation is complete
57
+ */
58
+ async refresh() {
59
+ await this.initializeFeatureItems();
60
+ }
61
+ //--------------------------------------------------------------------------
62
+ //
51
63
  // Functions (lifecycle)
52
64
  //
53
65
  //--------------------------------------------------------------------------
@@ -56,6 +68,7 @@ export class FeatureList {
56
68
  * @returns Promise when complete
57
69
  */
58
70
  async componentWillLoad() {
71
+ await this.initModules();
59
72
  await this._getTranslations();
60
73
  this._isLoading = true;
61
74
  this._popupUtils = new PopupUtils();
@@ -82,6 +95,17 @@ export class FeatureList {
82
95
  // Functions (protected)
83
96
  //
84
97
  //--------------------------------------------------------------------------
98
+ /**
99
+ * Load esri javascript api modules
100
+ * @returns Promise resolving when function is done
101
+ * @protected
102
+ */
103
+ async initModules() {
104
+ const [Color] = await loadModules([
105
+ "esri/Color"
106
+ ]);
107
+ this.Color = Color;
108
+ }
85
109
  /**
86
110
  * Initialize the features list using the selected layer
87
111
  * @protected
@@ -117,10 +141,7 @@ export class FeatureList {
117
141
  */
118
142
  async featureClicked(event, selectedFeature) {
119
143
  //clear previous highlight and remove the highlightHandle
120
- if (this.highlightOnMap && this._highlightHandle) {
121
- this._highlightHandle.remove();
122
- this._highlightHandle = null;
123
- }
144
+ this.clearHighlights();
124
145
  //highlight on map only if it is selected item
125
146
  if (this.highlightOnMap) {
126
147
  const selectedFeatureObjectId = Number(event.target.value);
@@ -129,6 +150,31 @@ export class FeatureList {
129
150
  }
130
151
  this.featureSelect.emit(selectedFeature);
131
152
  }
153
+ /**
154
+ * On feature hover in feature list highlight the feature on the map
155
+ * @param selectedFeature mouseovered feature graphic
156
+ * @protected
157
+ */
158
+ async onFeatureHover(selectedFeature) {
159
+ //clear previous highlight and remove the highlightHandle
160
+ this.clearHighlights();
161
+ if (this.highlightOnHover) {
162
+ const oId = selectedFeature.getObjectId();
163
+ const selectedLayerView = await getFeatureLayerView(this.mapView, this.selectedLayerId);
164
+ selectedLayerView.highlightOptions = { color: new this.Color("#FFFF00") };
165
+ this._highlightHandle = selectedLayerView.highlight([oId]);
166
+ }
167
+ }
168
+ /**
169
+ * Clears the highlight
170
+ * @protected
171
+ */
172
+ clearHighlights() {
173
+ //if a feature is already highlighted, then remove the highlight
174
+ if (this._highlightHandle) {
175
+ this._highlightHandle.remove();
176
+ }
177
+ }
132
178
  /**
133
179
  * Query the selected feature layer, in descending order of object id's
134
180
  * @param page 0th page number in the pagination item
@@ -179,7 +225,7 @@ export class FeatureList {
179
225
  const oId = selectedFeature.attributes[this._selectedLayer.objectIdField].toString();
180
226
  //use object id if popupTitle is null or undefined
181
227
  popupTitle = popupTitle !== null && popupTitle !== void 0 ? popupTitle : oId;
182
- return (h("calcite-list-item", { onCalciteListItemSelect: (e) => { void this.featureClicked(e, selectedFeature); }, value: oId }, h("div", { class: "popup-title", slot: "content-start" }, popupTitle), h("calcite-icon", { icon: "chevron-right", scale: "s", slot: "content-end" })));
228
+ return (h("calcite-list-item", { onCalciteListItemSelect: (e) => { void this.featureClicked(e, selectedFeature); }, onMouseLeave: () => { void this.clearHighlights(); }, onMouseOver: () => { void this.onFeatureHover(selectedFeature); }, value: oId }, h("div", { class: "popup-title", slot: "content-start" }, popupTitle), h("calcite-icon", { icon: "chevron-right", scale: "s", slot: "content-end" })));
183
229
  }
184
230
  /**
185
231
  * Fetches the component's translations
@@ -292,6 +338,24 @@ export class FeatureList {
292
338
  "attribute": "highlight-on-map",
293
339
  "reflect": false,
294
340
  "defaultValue": "false"
341
+ },
342
+ "highlightOnHover": {
343
+ "type": "boolean",
344
+ "mutable": false,
345
+ "complexType": {
346
+ "original": "boolean",
347
+ "resolved": "boolean",
348
+ "references": {}
349
+ },
350
+ "required": false,
351
+ "optional": true,
352
+ "docs": {
353
+ "tags": [],
354
+ "text": "boolean: Highlight feature on map optional (default false) boolean to indicate if we should highlight when hover on Feature in list"
355
+ },
356
+ "attribute": "highlight-on-hover",
357
+ "reflect": false,
358
+ "defaultValue": "false"
295
359
  }
296
360
  };
297
361
  }
@@ -326,6 +390,30 @@ export class FeatureList {
326
390
  }
327
391
  }];
328
392
  }
393
+ static get methods() {
394
+ return {
395
+ "refresh": {
396
+ "complexType": {
397
+ "signature": "() => Promise<void>",
398
+ "parameters": [],
399
+ "references": {
400
+ "Promise": {
401
+ "location": "global",
402
+ "id": "global::Promise"
403
+ }
404
+ },
405
+ "return": "Promise<void>"
406
+ },
407
+ "docs": {
408
+ "text": "Refresh the feature list which will fetch the latest features and update the features list",
409
+ "tags": [{
410
+ "name": "returns",
411
+ "text": "Promise that resolves when the operation is complete"
412
+ }]
413
+ }
414
+ }
415
+ };
416
+ }
329
417
  static get elementRef() { return "el"; }
330
418
  static get watchers() {
331
419
  return [{
@@ -40,7 +40,7 @@
40
40
  overflow: auto;
41
41
  }
42
42
 
43
- .esri-features__footer {
43
+ .feature-node .esri-features__footer {
44
44
  display: none !important;
45
45
  }
46
46
 
@@ -140,7 +140,7 @@ export class InfoCard {
140
140
  const id = (_d = (_c = this._features) === null || _c === void 0 ? void 0 : _c.selectedFeature) === null || _d === void 0 ? void 0 : _d.getObjectId();
141
141
  const ids = parseInt(id === null || id === void 0 ? void 0 : id.toString(), 10) > -1 ? [id] : [];
142
142
  const deleteEnabled = ((_e = this._layer) === null || _e === void 0 ? void 0 : _e.editingEnabled) && ((_h = (_g = (_f = this._layer) === null || _f === void 0 ? void 0 : _f.capabilities) === null || _g === void 0 ? void 0 : _g.operations) === null || _h === void 0 ? void 0 : _h.supportsDelete);
143
- return (h(Host, null, h("calcite-shell", null, this._getHeader(), h("calcite-loader", { class: loadingClass, label: this._translations.fetchingData }), h("div", { class: "esri-widget " + featureNodeClass, id: "features-node" }), h("div", { class: `${editButtonClass} width-100`, slot: "footer" }, this.allowEditing &&
143
+ return (h(Host, null, h("calcite-shell", null, this._getHeader(), h("calcite-loader", { class: loadingClass, label: this._translations.fetchingData }), h("div", { class: "esri-widget feature-node " + featureNodeClass, id: "features-node" }), h("div", { class: `${editButtonClass} width-100`, slot: "footer" }, this.allowEditing &&
144
144
  h("div", { class: "display-flex top-border padding-1-2" }, h("calcite-button", { appearance: "solid", id: "solutions-edit", onClick: () => this._openEditRecord(), width: "full" }, this._translations.edit), this.isMobile && deleteEnabled ? (h("delete-button", { class: "padding-inline-start-1 width-100", id: "solutions-delete", ids: ids, layer: this._layer, onEditsComplete: () => this._closePopup() })) : undefined, h("calcite-tooltip", { label: "", placement: "bottom", "reference-element": "solutions-edit" }, h("span", null, this._translations.edit)), this.isMobile ? (h("calcite-tooltip", { label: "", placement: "bottom", "reference-element": "solutions-delete" }, h("span", null, this._translations.delete))) : undefined), !nextBackDisabled && h("div", { class: `display-flex padding-1-2 button-container top-border ${nextBackClass}` }, h("div", { class: "min-width-100" }, h("calcite-button", { appearance: "outline", disabled: nextBackDisabled, id: "solutions-back", onClick: () => this._back(), width: "full" }, this._translations.back), h("calcite-tooltip", { label: "", placement: "top", "reference-element": "solutions-back" }, h("span", null, this._translations.back))), h("div", null, h("calcite-action", { icon: "list", onClick: () => this._toggleListView(), scale: "s", text: this._count, textEnabled: true })), h("div", { class: "min-width-100" }, h("calcite-button", { appearance: "outline", disabled: nextBackDisabled, id: "solutions-next", onClick: () => this._next(), width: "full" }, this._translations.next), h("calcite-tooltip", { label: "", placement: "top", "reference-element": "solutions-next" }, h("span", null, this._translations.next))))), h("edit-card", { class: editClass, graphicIndex: (_j = this._features) === null || _j === void 0 ? void 0 : _j.selectedFeatureIndex, graphics: this.graphics, mapView: this.mapView, open: this._editRecordOpen }), h("calcite-alert", { icon: "layer-broken", kind: "warning", label: "", onCalciteAlertClose: () => this._alertClosed(), open: this._alertOpen, placement: "top" }, h("div", { slot: "title" }, this._translations.editDisabled), h("div", { slot: "message" }, this._translations.enableEditing)))));
145
145
  }
146
146
  //--------------------------------------------------------------------------
@@ -79,7 +79,7 @@ export class LayerList {
79
79
  render() {
80
80
  return (h(Fragment, null, this._isLoading && h("calcite-loader", { label: "", scale: "m" }), !this._isLoading && this.mapView && this._noLayersToDisplay &&
81
81
  h("calcite-notice", { class: "error-msg", icon: "layers-reference", kind: "danger", open: true }, h("div", { slot: "title" }, this._translations.error), h("div", { slot: "message" }, this.noLayerErrorMsg ? this.noLayerErrorMsg : this._noLayerToDisplayErrorMsg)), !this._isLoading && this.mapView &&
82
- h("calcite-list", { "selection-appearance": "border", "selection-mode": this.showNextIcon ? "none" : "single-persist" }, this.renderLayerList())));
82
+ h("calcite-list", { "selection-appearance": "border", "selection-mode": "none" }, this.renderLayerList())));
83
83
  }
84
84
  //--------------------------------------------------------------------------
85
85
  //
@@ -127,7 +127,7 @@ export class LayerList {
127
127
  }
128
128
  });
129
129
  await Promise.all(def).then(() => {
130
- const editableLayerIds = this.getEditableIds(this._layerItemsHash);
130
+ const editableLayerIds = this.getLayersToBeShownInList(this._layerItemsHash);
131
131
  this._mapLayerIds = editableLayerIds.reverse();
132
132
  this.handleNoLayersToDisplay();
133
133
  }, () => {
@@ -143,17 +143,17 @@ export class LayerList {
143
143
  this.layersListLoaded.emit(this._mapLayerIds);
144
144
  }
145
145
  /**
146
- * Returns the ids of all OR configured layers that support edits with the update capability
146
+ * Returns the ids of all OR configured layers that needs to be shown in the list
147
147
  * @param hash each layer item details
148
148
  * @returns array of layer ids
149
149
  */
150
- getEditableIds(hash) {
150
+ getLayersToBeShownInList(hash) {
151
151
  var _a;
152
152
  const configuredLayers = ((_a = this.layers) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.layers : [];
153
153
  return Object.keys(hash).reduce((prev, cur) => {
154
- let showLayer = hash[cur].supportsAdd;
154
+ let showLayer = true;
155
155
  if ((configuredLayers === null || configuredLayers === void 0 ? void 0 : configuredLayers.length) > 0) {
156
- showLayer = configuredLayers.indexOf(cur) > -1 ? hash[cur].supportsAdd : false;
156
+ showLayer = configuredLayers.indexOf(cur) > -1;
157
157
  }
158
158
  if (showLayer) {
159
159
  prev.push(cur);
@@ -170,7 +170,7 @@ export class MapDrawTools {
170
170
  }
171
171
  else {
172
172
  this._sketchGraphicsLayer = new this.GraphicsLayer({ title, listMode: "hide" });
173
- state.managedLayers.push(title);
173
+ state.managedLayers[title] = "sketch";
174
174
  this.mapView.map.layers.add(this._sketchGraphicsLayer);
175
175
  }
176
176
  if (this.graphics && this.graphics.length > 0) {