@esri/solutions-components 0.8.5 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
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) {