@esri/solutions-components 0.10.12 → 0.10.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. package/dist/cjs/calcite-alert_4.cjs.entry.js +1 -1
  2. package/dist/cjs/calcite-flow_6.cjs.entry.js +103 -7
  3. package/dist/cjs/card-manager_3.cjs.entry.js +2 -1
  4. package/dist/cjs/crowdsource-manager.cjs.entry.js +3 -2
  5. package/dist/cjs/crowdsource-reporter.cjs.entry.js +173 -43
  6. package/dist/cjs/feature-list.cjs.entry.js +110 -17
  7. package/dist/cjs/loader.cjs.js +1 -1
  8. package/dist/cjs/{popupUtils-92e52dbf.js → popupUtils-47bd97e7.js} +1 -1
  9. package/dist/cjs/solutions-components.cjs.js +1 -1
  10. package/dist/collection/assets/t9n/crowdsource-reporter/resources.json +3 -1
  11. package/dist/collection/assets/t9n/crowdsource-reporter/resources_en.json +3 -1
  12. package/dist/collection/assets/t9n/feature-list/resources.json +3 -1
  13. package/dist/collection/assets/t9n/feature-list/resources_en.json +3 -1
  14. package/dist/collection/components/card-manager/card-manager.js +19 -1
  15. package/dist/collection/components/create-feature/create-feature.js +145 -2
  16. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +20 -2
  17. package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.js +227 -43
  18. package/dist/collection/components/feature-list/feature-list.css +16 -1
  19. package/dist/collection/components/feature-list/feature-list.js +165 -15
  20. package/dist/collection/components/layer-list/layer-list.js +35 -6
  21. package/dist/collection/demos/crowdsource-reporter.html +2 -0
  22. package/dist/collection/utils/popupUtils.js +1 -1
  23. package/dist/collection/utils/popupUtils.ts +1 -1
  24. package/dist/components/card-manager2.js +3 -1
  25. package/dist/components/create-feature2.js +91 -3
  26. package/dist/components/crowdsource-manager.js +4 -2
  27. package/dist/components/crowdsource-reporter.js +178 -45
  28. package/dist/components/feature-list2.js +152 -50
  29. package/dist/components/layer-list2.js +18 -6
  30. package/dist/components/popupUtils.js +1 -1
  31. package/dist/esm/calcite-alert_4.entry.js +1 -1
  32. package/dist/esm/calcite-flow_6.entry.js +104 -8
  33. package/dist/esm/card-manager_3.entry.js +2 -1
  34. package/dist/esm/crowdsource-manager.entry.js +3 -2
  35. package/dist/esm/crowdsource-reporter.entry.js +173 -43
  36. package/dist/esm/feature-list.entry.js +110 -17
  37. package/dist/esm/loader.js +1 -1
  38. package/dist/esm/{popupUtils-00c655fb.js → popupUtils-349a26e6.js} +1 -1
  39. package/dist/esm/solutions-components.js +1 -1
  40. package/dist/solutions-components/assets/t9n/crowdsource-reporter/resources.json +3 -1
  41. package/dist/solutions-components/assets/t9n/crowdsource-reporter/resources_en.json +3 -1
  42. package/dist/solutions-components/assets/t9n/feature-list/resources.json +3 -1
  43. package/dist/solutions-components/assets/t9n/feature-list/resources_en.json +3 -1
  44. package/dist/solutions-components/demos/crowdsource-reporter.html +2 -0
  45. package/dist/solutions-components/p-40e305b4.entry.js +17 -0
  46. package/dist/solutions-components/p-4d44410b.entry.js +6 -0
  47. package/dist/solutions-components/{p-900fee65.js → p-5a473f0d.js} +1 -1
  48. package/dist/solutions-components/p-8efa9edf.entry.js +6 -0
  49. package/dist/solutions-components/p-977f2314.entry.js +6 -0
  50. package/dist/solutions-components/p-9b83e593.entry.js +6 -0
  51. package/dist/solutions-components/{p-cde8d6e5.entry.js → p-f6bc95b3.entry.js} +1 -1
  52. package/dist/solutions-components/solutions-components.esm.js +1 -1
  53. package/dist/solutions-components/utils/popupUtils.ts +1 -1
  54. package/dist/types/components/card-manager/card-manager.d.ts +4 -0
  55. package/dist/types/components/create-feature/create-feature.d.ts +34 -0
  56. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +4 -0
  57. package/dist/types/components/crowdsource-reporter/crowdsource-reporter.d.ts +80 -21
  58. package/dist/types/components/feature-list/feature-list.d.ts +49 -7
  59. package/dist/types/components/layer-list/layer-list.d.ts +4 -0
  60. package/dist/types/components.d.ts +93 -0
  61. package/package.json +1 -1
  62. package/dist/solutions-components/p-064e43e0.entry.js +0 -6
  63. package/dist/solutions-components/p-2d1afda0.entry.js +0 -17
  64. package/dist/solutions-components/p-4a0d9efe.entry.js +0 -6
  65. package/dist/solutions-components/p-c9260b4c.entry.js +0 -6
  66. package/dist/solutions-components/p-f7d3ef3e.entry.js +0 -6
@@ -37,6 +37,9 @@ export class FeatureList {
37
37
  this.showInitialLoading = true;
38
38
  this.showErrorWhenNoFeatures = true;
39
39
  this.showUserImageInList = false;
40
+ this.showFeatureSymbol = false;
41
+ this.applyLayerViewFilter = false;
42
+ this.reportingOptions = undefined;
40
43
  this._featureItems = [];
41
44
  this._featuresCount = 0;
42
45
  this._isLoading = false;
@@ -63,6 +66,11 @@ export class FeatureList {
63
66
  * Esri config
64
67
  */
65
68
  esriConfig;
69
+ /**
70
+ * "esri/symbols/support/symbolUtils": https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-support-symbolUtils.html
71
+ * Symbol utils
72
+ */
73
+ symbolUtils;
66
74
  /**
67
75
  * IPopupUtils: To fetch the list label using popup titles
68
76
  */
@@ -79,6 +87,18 @@ export class FeatureList {
79
87
  * HTMLCalcitePaginationElement: Calcite pagination element instance
80
88
  */
81
89
  _pagination;
90
+ /**
91
+ * string[]: Valid field types for like
92
+ */
93
+ _validFieldTypes = ["small-integer", "integer", "big-integer", "single", "long"];
94
+ /**
95
+ * string: Abbrivated like count of the feature
96
+ */
97
+ _abbreviatedLikeCount;
98
+ /**
99
+ * boolean: When true configured like field is available in selected layer
100
+ */
101
+ _likeFieldAvailable = false;
82
102
  //--------------------------------------------------------------------------
83
103
  //
84
104
  // Watch handlers
@@ -152,9 +172,9 @@ export class FeatureList {
152
172
  * Renders the component.
153
173
  */
154
174
  render() {
155
- return (h("calcite-panel", { key: 'ace7bcabf497e9a61d261fd7ea29dc664ee0a526', "full-height": true, "full-width": true }, this._isLoading && h("calcite-loader", { key: '675c7f5be7f8456954acdf353f357bac6145c390', label: "", scale: "m" }), this.showErrorWhenNoFeatures && this._featureItems.length === 0 && !this._isLoading &&
156
- h("calcite-notice", { key: 'b2e6537acdec801ef066a74c78a2c4a13dbbc44b', class: "error-msg", icon: "feature-details", kind: "info", open: true }, h("div", { key: '7697470234b396a904906b80e4fc8df3a0cc732b', slot: "message" }, this.noFeaturesFoundMsg ? this.noFeaturesFoundMsg : this._translations.featureErrorMsg)), h("calcite-list", { key: 'd2b40c9a5e1bf009cb78d640351a16b24711ff59', "selection-appearance": "border", "selection-mode": "none" }, !this._isLoading && this._featureItems.length > 0 && this._featureItems), this._featuresCount > this.pageSize &&
157
- h("div", { key: '15b0dae0fb914faf053a4b0cbea6e35ef7abc038', class: "width-full", slot: "footer" }, h("calcite-pagination", { key: '04f8eb02535f8cff8de0c111ac2d4bfa883ac128', class: "pagination", "full-width": true, onCalcitePaginationChange: this.pageChanged.bind(this), "page-size": this.pageSize, ref: el => this._pagination = el, "start-item": "1", "total-items": this._featuresCount }))));
175
+ return (h("calcite-panel", { key: 'b84cbd9d8c0f4d9d84fe7a49d149b67e88e46c53', "full-height": true, "full-width": true }, this._isLoading && h("calcite-loader", { key: '91ee86a3223b55141206be0d3f20bca1b777e4db', label: "", scale: "m" }), this.showErrorWhenNoFeatures && this._featureItems.length === 0 && !this._isLoading &&
176
+ h("calcite-notice", { key: '3c3b4a35c45715a86bd17630e8f3f9b566592c27', class: "error-msg", icon: "feature-details", kind: "info", open: true }, h("div", { key: '63a35389ac64f66c706fa05e92fb8f1af8dd0b69', slot: "message" }, this.noFeaturesFoundMsg ? this.noFeaturesFoundMsg : this._translations.featureErrorMsg)), h("calcite-list", { key: 'a237f97a0d286af17cce837bfbdd3c0d868ea023', "selection-appearance": "border", "selection-mode": "none" }, !this._isLoading && this._featureItems.length > 0 && this._featureItems), this._featuresCount > this.pageSize &&
177
+ h("div", { key: '9cb166b5095167a2004e93217240bea6789e9039', class: "width-full", slot: "footer" }, h("calcite-pagination", { key: 'a413b26dd30fdc89be1d65ef06995604f1430a18', class: "pagination", "full-width": true, onCalcitePaginationChange: this.pageChanged.bind(this), "page-size": this.pageSize, ref: el => this._pagination = el, "start-item": "1", "total-items": this._featuresCount }))));
158
178
  }
159
179
  //--------------------------------------------------------------------------
160
180
  //
@@ -162,23 +182,25 @@ export class FeatureList {
162
182
  //
163
183
  //--------------------------------------------------------------------------
164
184
  /**
165
- * Load esri javascript api modules
166
- * @returns Promise resolving when function is done
167
- * @protected
168
- */
185
+ * Load esri javascript api modules
186
+ * @returns Promise resolving when function is done
187
+ * @protected
188
+ */
169
189
  async initModules() {
170
- const [Color, esriConfig] = await loadModules([
190
+ const [Color, esriConfig, symbolUtils] = await loadModules([
171
191
  "esri/Color",
172
192
  "esri/config",
193
+ "esri/symbols/support/symbolUtils"
173
194
  ]);
174
195
  this.Color = Color;
175
196
  this.esriConfig = esriConfig;
197
+ this.symbolUtils = symbolUtils;
176
198
  }
177
199
  /**
178
200
  * Return the where condition string considering the defined where clause and layer's definition expression
179
201
  * @protected
180
202
  */
181
- getWhereCondition() {
203
+ async getWhereCondition() {
182
204
  //By Default load all the features
183
205
  let whereClause = '1=1';
184
206
  //if where clause is defined use it
@@ -189,6 +211,13 @@ export class FeatureList {
189
211
  if (this._selectedLayer?.definitionExpression) {
190
212
  whereClause = whereClause + ' AND ' + this._selectedLayer.definitionExpression;
191
213
  }
214
+ // if layerview has any applied filter, use it
215
+ if (this.applyLayerViewFilter) {
216
+ const selectedLayerView = await getFeatureLayerView(this.mapView, this.selectedLayerId);
217
+ if (selectedLayerView?.filter?.where) {
218
+ whereClause = whereClause + ' AND ' + selectedLayerView.filter.where;
219
+ }
220
+ }
192
221
  return whereClause;
193
222
  }
194
223
  /**
@@ -200,8 +229,9 @@ export class FeatureList {
200
229
  void this._pagination?.goTo("start");
201
230
  this._isLoading = this.showInitialLoading;
202
231
  this._featureItems = await this.queryPage(0);
232
+ const whereCondition = await this.getWhereCondition();
203
233
  const query = {
204
- where: this.getWhereCondition()
234
+ where: whereCondition
205
235
  };
206
236
  this._featuresCount = await this._selectedLayer.queryFeatureCount(query);
207
237
  this._isLoading = false;
@@ -287,12 +317,13 @@ export class FeatureList {
287
317
  const featureLayer = this._selectedLayer;
288
318
  const sortField = this.sortingInfo?.field ? this.sortingInfo.field : featureLayer.objectIdField;
289
319
  const sortOrder = this.sortingInfo?.order ? this.sortingInfo.order : 'desc';
320
+ const whereCondition = await this.getWhereCondition();
290
321
  const query = {
291
322
  start: page,
292
323
  num: this.pageSize,
293
324
  outFields: ["*"],
294
325
  returnGeometry: true,
295
- where: this.getWhereCondition(),
326
+ where: whereCondition,
296
327
  outSpatialReference: this.mapView.spatialReference.toJSON()
297
328
  };
298
329
  //sort only when sort field and order is valid
@@ -310,10 +341,12 @@ export class FeatureList {
310
341
  */
311
342
  async createFeatureItem(featureSet) {
312
343
  const currentFeatures = featureSet?.features;
344
+ const showLikeCount = this.reportingOptions && this.reportingOptions[this.selectedLayerId].like;
313
345
  const items = currentFeatures.map(async (feature) => {
314
346
  const popupTitle = await this._popupUtils.getPopupTitle(feature, this.mapView.map);
315
347
  //fetch the feature creator user info to show the creator user image
316
348
  let userInfo;
349
+ let featureSymbol;
317
350
  if (this.showUserImageInList) {
318
351
  const creatorField = this._selectedLayer.editFieldsInfo?.creatorField.toLowerCase();
319
352
  // if feature's creator field is present then only we can fetch the information of user
@@ -321,10 +354,37 @@ export class FeatureList {
321
354
  userInfo = await this.getUserInformation(feature, creatorField);
322
355
  }
323
356
  }
324
- return this.getFeatureItem(feature, popupTitle, userInfo);
357
+ if (this.showFeatureSymbol) {
358
+ featureSymbol = await this.getFeatureSymbol(feature);
359
+ }
360
+ if (showLikeCount) {
361
+ void this.getAbbreviatedLikeCount(feature);
362
+ }
363
+ return this.getFeatureItem(feature, popupTitle, featureSymbol, userInfo);
325
364
  });
326
365
  return Promise.all(items);
327
366
  }
367
+ /**
368
+ * Displays the abbrivated like count on the feature list
369
+ * @param feature feature of the layer
370
+ * @protected
371
+ */
372
+ getAbbreviatedLikeCount(feature) {
373
+ const selectedLayer = this._selectedLayer;
374
+ const likeField = this.reportingOptions[selectedLayer.id].likeField;
375
+ selectedLayer.fields.forEach((eachField) => {
376
+ if (this._validFieldTypes.indexOf(eachField.type) > -1) {
377
+ if (eachField.name === likeField && this.reportingOptions[selectedLayer.id].like) {
378
+ this._likeFieldAvailable = true;
379
+ let likes = feature.attributes[likeField] || 0;
380
+ if (likes > 999) {
381
+ likes = likes > 999999 ? this._translations.millionsAbbreviation.replace("{{abbreviated_value}}", Math.floor(likes / 1000000).toString()) : this._translations.thousandsAbbreviation.replace("{{abbreviated_value}}", Math.floor(likes / 1000).toString());
382
+ }
383
+ this._abbreviatedLikeCount = likes;
384
+ }
385
+ }
386
+ });
387
+ }
328
388
  /**
329
389
  * Get each feature item
330
390
  * @param selectedFeature Each individual feature instance to be listed
@@ -332,15 +392,19 @@ export class FeatureList {
332
392
  * @returns individual feature item to be rendered
333
393
  * @protected
334
394
  */
335
- getFeatureItem(selectedFeature, popupTitle, userInfo) {
395
+ getFeatureItem(selectedFeature, popupTitle, featureSymbol, userInfo) {
336
396
  //get the object id value of the feature
337
397
  const oId = selectedFeature.attributes[this._selectedLayer.objectIdField].toString();
338
398
  //use object id if popupTitle is null or undefined
339
399
  popupTitle = popupTitle ?? oId;
400
+ // get the formatted like count
401
+ const formattedLikeCount = Number(selectedFeature.attributes[this.reportingOptions?.[this._selectedLayer.id].likeField]).toLocaleString();
340
402
  const popupTitleClass = this.textSize === 'small' ? 'feature-list-popup-title-small' : 'feature-list-popup-title';
341
- const popupTitlePaddingClass = this.showUserImageInList ? 'feature-list-popup-title-padding-reduced' : 'feature-list-popup-title-padding';
403
+ const popupTitlePaddingClass = this.showUserImageInList || this.showFeatureSymbol ? 'feature-list-popup-title-padding-reduced' : 'feature-list-popup-title-padding';
342
404
  return (h("calcite-list-item", { onCalciteListItemSelect: (e) => { void this.featureClicked(e, selectedFeature); }, onMouseLeave: () => { void this.clearHighlights(); }, onMouseOver: () => { void this.onFeatureHover(selectedFeature); }, value: oId }, this.showUserImageInList &&
343
- h("calcite-avatar", { class: 'profile-img', "full-name": userInfo?.fullName, id: userInfo?.id, scale: "m", slot: "content-start", thumbnail: userInfo?.userProfileUrl, username: userInfo?.username }), h("div", { class: `${popupTitleClass} ${popupTitlePaddingClass}`, slot: "content-start" }, popupTitle), h("calcite-icon", { flipRtl: true, icon: "chevron-right", scale: "s", slot: "content-end" })));
405
+ h("calcite-avatar", { class: 'profile-img', "full-name": userInfo?.fullName, id: userInfo?.id, scale: "m", slot: "content-start", thumbnail: userInfo?.userProfileUrl, username: userInfo?.username }), this.showFeatureSymbol &&
406
+ h("div", { class: 'feature-symbol', ref: (el) => el && el.appendChild(featureSymbol), slot: "content-start" }), h("div", { class: `${popupTitleClass} ${popupTitlePaddingClass}`, slot: "content-start" }, popupTitle), this._likeFieldAvailable &&
407
+ h("div", { class: "like-container", id: oId.concat("like"), slot: "content-end" }, h("span", null, this._abbreviatedLikeCount), h("calcite-icon", { icon: "thumbs-up", scale: 's' }), h("calcite-tooltip", { "reference-element": oId.concat("like") }, formattedLikeCount)), h("calcite-icon", { flipRtl: true, icon: "chevron-right", scale: "s", slot: "content-end" })));
344
408
  }
345
409
  /**
346
410
  *
@@ -367,6 +431,35 @@ export class FeatureList {
367
431
  userInfo.userProfileUrl = userProfileUrl;
368
432
  return userInfo;
369
433
  }
434
+ /**
435
+ * Creates a feature symbology
436
+ * @param feature Each individual feature
437
+ * @returns Feature symbology
438
+ * @protected
439
+ */
440
+ async getFeatureSymbol(feature) {
441
+ const nodeHtml = document.createElement('div');
442
+ await this.symbolUtils.getDisplayedSymbol(feature).then(async (symbol) => {
443
+ symbol && await this.symbolUtils?.renderPreviewHTML(symbol, {
444
+ node: nodeHtml
445
+ });
446
+ if (nodeHtml.children?.length) {
447
+ const imgOrSvgElm = nodeHtml.children[0];
448
+ if (imgOrSvgElm) {
449
+ const height = Number(imgOrSvgElm.getAttribute('height'));
450
+ const width = Number(imgOrSvgElm.getAttribute('width'));
451
+ if (width > 30) {
452
+ imgOrSvgElm.setAttribute('width', '30');
453
+ }
454
+ else if (width < 19) {
455
+ imgOrSvgElm.setAttribute('width', '20');
456
+ }
457
+ imgOrSvgElm.setAttribute('viewBox', `0 0 ${width} ${height}`);
458
+ }
459
+ }
460
+ });
461
+ return nodeHtml;
462
+ }
370
463
  /**
371
464
  * Fetches the component's translations
372
465
  * @returns Promise when complete
@@ -606,6 +699,63 @@ export class FeatureList {
606
699
  "attribute": "show-user-image-in-list",
607
700
  "reflect": false,
608
701
  "defaultValue": "false"
702
+ },
703
+ "showFeatureSymbol": {
704
+ "type": "boolean",
705
+ "mutable": false,
706
+ "complexType": {
707
+ "original": "boolean",
708
+ "resolved": "boolean",
709
+ "references": {}
710
+ },
711
+ "required": false,
712
+ "optional": true,
713
+ "docs": {
714
+ "tags": [],
715
+ "text": "boolean: If true display's feature symbol on each feature item"
716
+ },
717
+ "attribute": "show-feature-symbol",
718
+ "reflect": false,
719
+ "defaultValue": "false"
720
+ },
721
+ "applyLayerViewFilter": {
722
+ "type": "boolean",
723
+ "mutable": false,
724
+ "complexType": {
725
+ "original": "boolean",
726
+ "resolved": "boolean",
727
+ "references": {}
728
+ },
729
+ "required": false,
730
+ "optional": true,
731
+ "docs": {
732
+ "tags": [],
733
+ "text": "boolean: If true will consider the FeatureFilter applied on the layerview"
734
+ },
735
+ "attribute": "apply-layer-view-filter",
736
+ "reflect": false,
737
+ "defaultValue": "false"
738
+ },
739
+ "reportingOptions": {
740
+ "type": "unknown",
741
+ "mutable": false,
742
+ "complexType": {
743
+ "original": "IReportingOptions",
744
+ "resolved": "IReportingOptions",
745
+ "references": {
746
+ "IReportingOptions": {
747
+ "location": "import",
748
+ "path": "../../utils/interfaces",
749
+ "id": "src/utils/interfaces.ts::IReportingOptions"
750
+ }
751
+ }
752
+ },
753
+ "required": false,
754
+ "optional": false,
755
+ "docs": {
756
+ "tags": [],
757
+ "text": "IReportingOptions: Key options for reporting"
758
+ }
609
759
  }
610
760
  };
611
761
  }
@@ -19,7 +19,7 @@
19
19
  * limitations under the License.
20
20
  */
21
21
  import { h, Fragment } from "@stencil/core";
22
- import { getAllLayers, getMapLayerHash } from "../../utils/mapViewUtils";
22
+ import { getAllLayers, getFeatureLayerView, getMapLayerHash } from "../../utils/mapViewUtils";
23
23
  import { getLocaleComponentStrings } from "../../utils/locale";
24
24
  import { formatNumber } from "../../utils/languageUtil";
25
25
  export class LayerList {
@@ -28,6 +28,7 @@ export class LayerList {
28
28
  this.layers = undefined;
29
29
  this.showFeatureCount = true;
30
30
  this.showNextIcon = false;
31
+ this.applyLayerViewFilter = false;
31
32
  this._noLayersToDisplay = false;
32
33
  this._mapLayerIds = [];
33
34
  this._isLoading = false;
@@ -103,9 +104,9 @@ export class LayerList {
103
104
  * Renders the component.
104
105
  */
105
106
  render() {
106
- return (h(Fragment, { key: '9366302a704c1dbdd7a65aef5c43d0ad84a44b23' }, this._isLoading && h("calcite-loader", { key: '69974a23fd42bc37ef13816efbe6d06e28cb2749', label: "", scale: "m" }), !this._isLoading && this.mapView && this._noLayersToDisplay &&
107
- h("calcite-notice", { key: 'a93abb55b4db09727b3634cb1935e482c377d662', class: "error-msg", icon: "layers-reference", kind: "danger", open: true }, h("div", { key: 'b9046685353b8894e6c6094cff47fab7a8e07ffa', slot: "title" }, this._translations.error), h("div", { key: '90a052e1d80779a09a32fdd35563a1ce21d582e0', slot: "message" }, this._translations.noLayerToDisplayErrorMsg)), !this._isLoading && this.mapView &&
108
- h("calcite-list", { key: '709c1b8edd5710a2476ecef638199c2f929b4165', "selection-appearance": "border", "selection-mode": "none" }, this.renderLayerList())));
107
+ return (h(Fragment, { key: '19f68b9a5d0b6c85832544e4281e1c4a1707ba86' }, this._isLoading && h("calcite-loader", { key: 'c908f311165f8f520f267a0dcde0bd954863ba6b', label: "", scale: "m" }), !this._isLoading && this.mapView && this._noLayersToDisplay &&
108
+ h("calcite-notice", { key: '56dfb252f998333ed6a671cccddd5683f08ad63d', class: "error-msg", icon: "layers-reference", kind: "danger", open: true }, h("div", { key: 'a27ad45ac2b1984152af5a80da36583f7c375be6', slot: "title" }, this._translations.error), h("div", { key: 'a9466cb560b6ee2c72ebd18130ce21371f9e7cdf', slot: "message" }, this._translations.noLayerToDisplayErrorMsg)), !this._isLoading && this.mapView &&
109
+ h("calcite-list", { key: '40e54ba92d2f48a97dd0987808f4b7fdefd266bb', "selection-appearance": "border", "selection-mode": "none" }, this.renderLayerList())));
109
110
  }
110
111
  //--------------------------------------------------------------------------
111
112
  //
@@ -132,10 +133,20 @@ export class LayerList {
132
133
  this._layerItemsHash = await getMapLayerHash(this.mapView, true);
133
134
  const allMapLayers = await getAllLayers(this.mapView);
134
135
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
135
- allMapLayers.forEach(async (eachLayer) => {
136
+ for (const eachLayer of allMapLayers) {
136
137
  if (eachLayer?.type === "feature") {
137
138
  if (this.showFeatureCount) {
138
139
  const q = eachLayer.createQuery();
140
+ //if layer has definitionExpression append it to the where clause
141
+ if (eachLayer?.definitionExpression) {
142
+ q.where = q.where + ' AND ' + eachLayer.definitionExpression;
143
+ }
144
+ if (this.applyLayerViewFilter) {
145
+ const featureLayerView = await getFeatureLayerView(this.mapView, eachLayer.id);
146
+ if (featureLayerView?.filter?.where) {
147
+ q.where = q.where ? q.where + ' AND ' + featureLayerView.filter.where : featureLayerView.filter.where;
148
+ }
149
+ }
139
150
  const result = eachLayer.queryFeatureCount(q);
140
151
  def.push(result);
141
152
  void result.then(async (resCount) => {
@@ -148,7 +159,7 @@ export class LayerList {
148
159
  });
149
160
  }
150
161
  }
151
- });
162
+ }
152
163
  await Promise.all(def).then(() => {
153
164
  const editableLayerIds = this.getLayersToBeShownInList(this._layerItemsHash);
154
165
  this._mapLayerIds = editableLayerIds.reverse();
@@ -302,6 +313,24 @@ export class LayerList {
302
313
  "attribute": "show-next-icon",
303
314
  "reflect": false,
304
315
  "defaultValue": "false"
316
+ },
317
+ "applyLayerViewFilter": {
318
+ "type": "boolean",
319
+ "mutable": false,
320
+ "complexType": {
321
+ "original": "boolean",
322
+ "resolved": "boolean",
323
+ "references": {}
324
+ },
325
+ "required": false,
326
+ "optional": true,
327
+ "docs": {
328
+ "tags": [],
329
+ "text": "boolean: If true will consider the FeatureFilter applied on the layerview"
330
+ },
331
+ "attribute": "apply-layer-view-filter",
332
+ "reflect": false,
333
+ "defaultValue": "false"
305
334
  }
306
335
  };
307
336
  }
@@ -315,6 +315,8 @@
315
315
  //listen to togglePanel event
316
316
  demo.addEventListener('togglePanel', togglePanel);
317
317
  demo.showUserImageInCommentsList = true;
318
+ demo.showFeatureSymbol = true;
319
+ demo.showMyReportsOnly = false;
318
320
  });
319
321
 
320
322
  function togglePanel(evt) {
@@ -71,7 +71,7 @@ export class PopupUtils {
71
71
  }
72
72
  }
73
73
  //Format field values
74
- if (layer.popupTemplate.fieldInfos) {
74
+ if (layer.popupTemplate?.fieldInfos) {
75
75
  layer.fields.forEach((field) => {
76
76
  const attributeValue = graphic.attributes[field.name];
77
77
  //get the field info from popupTemplate
@@ -73,7 +73,7 @@ export class PopupUtils {
73
73
  }
74
74
  }
75
75
  //Format field values
76
- if (layer.popupTemplate.fieldInfos) {
76
+ if (layer.popupTemplate?.fieldInfos) {
77
77
  layer.fields.forEach((field) => {
78
78
  const attributeValue = graphic.attributes[field.name];
79
79
  //get the field info from popupTemplate
@@ -32,6 +32,7 @@ const CardManager = /*@__PURE__*/ proxyCustomElement(class CardManager extends H
32
32
  constructor() {
33
33
  super();
34
34
  this.__registerHost();
35
+ this.customInfoText = undefined;
35
36
  this.enableEditGeometry = false;
36
37
  this.isMobile = undefined;
37
38
  this.layer = undefined;
@@ -94,7 +95,7 @@ const CardManager = /*@__PURE__*/ proxyCustomElement(class CardManager extends H
94
95
  render() {
95
96
  const featuresClass = this._graphics?.length > 0 ? "" : "display-none";
96
97
  const messageClass = this._graphics?.length > 0 ? "display-none" : "";
97
- return (h(Host, { key: '0309205d485d9c7a5c558b3619a6c5ac03fcb528' }, h("div", { key: 'a5d291f6073b0e0a918573549c6eb29fe1d892dd', class: "overflow-auto height-full" }, h("calcite-shell", { key: '572b9cdf002e0c8c46e6c4bc5e2f1f8494228e93', class: "position-relative " + featuresClass }, h("div", { key: 'f8ba07deb9786d64f3d25011ff66ead43d809bf1' }, h("info-card", { key: '6eda3ab2cfa2e5fb948f5a7ddaeb6b9022aa5543', enableEditGeometry: this.enableEditGeometry, graphics: this._graphics, isLoading: this._cardLoading, isMobile: this.isMobile, mapView: this.mapView }))), h("calcite-shell", { key: 'f32d9cfe3a41bbd7d58cdc732c8abe99b232beb7', class: "position-relative " + messageClass }, h("div", { key: 'b97eb023c5d57a4a8dda09467d8599166da40f3c', class: "padding-1" }, h("calcite-notice", { key: '23a204782bd254909e3ab803a944d10004e4954a', icon: "table", open: true }, h("div", { key: 'ea25078647612b8fa40e26b4474a91c853dae126', slot: "message" }, this._translations.selectFeaturesToStart)))))));
98
+ return (h(Host, { key: 'dafff11793b5ae60164964c346cbb152caceaeb9' }, h("div", { key: '02507fe9e1f4205fe8a9342b466f1ada849c8ed8', class: "overflow-auto height-full" }, h("calcite-shell", { key: '712c42c4044c1386e8bc4ff42e44f250ac4023a2', class: "position-relative " + featuresClass }, h("div", { key: 'f2bc47f58463506f7ea8011495b22cafb63e4f27' }, h("info-card", { key: '1ad1fb78dcc99a43d92ad08d4c7bbeda7c2f276d', enableEditGeometry: this.enableEditGeometry, graphics: this._graphics, isLoading: this._cardLoading, isMobile: this.isMobile, mapView: this.mapView }))), h("calcite-shell", { key: 'fa9fcada67198c182f918b939826f1f7f19f8e5b', class: "position-relative " + messageClass }, h("div", { key: '0da349d1442b6375cde177780c5f868d2e32072a', class: "padding-1" }, h("calcite-notice", { key: 'c0e04ca03c546f90c942c2eef622fbe9c8e61227', icon: "table", open: true }, h("div", { key: '85e3925e725798189b16270df31c266c55391ec7', slot: "message" }, this.customInfoText || this._translations.selectFeaturesToStart)))))));
98
99
  }
99
100
  //--------------------------------------------------------------------------
100
101
  //
@@ -125,6 +126,7 @@ const CardManager = /*@__PURE__*/ proxyCustomElement(class CardManager extends H
125
126
  }
126
127
  static get style() { return CardManagerStyle0; }
127
128
  }, [0, "card-manager", {
129
+ "customInfoText": [1, "custom-info-text"],
128
130
  "enableEditGeometry": [4, "enable-edit-geometry"],
129
131
  "isMobile": [4, "is-mobile"],
130
132
  "layer": [1040],
@@ -26,6 +26,8 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
26
26
  this.customizeSubmit = false;
27
27
  this.searchConfiguration = undefined;
28
28
  this.isMobile = undefined;
29
+ this.floorLevel = undefined;
30
+ this.formElements = undefined;
29
31
  this._editorLoading = false;
30
32
  this._showSearchWidget = undefined;
31
33
  }
@@ -40,6 +42,20 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
40
42
  * The Editor constructor
41
43
  */
42
44
  Editor;
45
+ /**
46
+ * esri/form/ExpressionInfo: https://developers.arcgis.com/javascript/latest/api-reference/esri-form-ExpressionInfo.html
47
+ * The ExpressionInfo constructor
48
+ */
49
+ ExpressionInfo;
50
+ /**
51
+ * esri/form/elements/FieldElement: https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html
52
+ * The FieldElement constructor
53
+ */
54
+ FieldElement;
55
+ /**
56
+ * esri/form/FormTemplate: https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html
57
+ */
58
+ FormTemplate;
43
59
  /**
44
60
  * esri/widgets/Editor: https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Editor.html
45
61
  * The Editor instance
@@ -145,6 +161,15 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
145
161
  this._editor.viewModel.featureFormViewModel.submit();
146
162
  }
147
163
  }
164
+ /**
165
+ * refresh the feature form
166
+ * @returns Promise that resolves when the operation is complete
167
+ */
168
+ async refresh(floorLevel) {
169
+ if (this._editor) {
170
+ void this._setFloorLevel(floorLevel);
171
+ }
172
+ }
148
173
  //--------------------------------------------------------------------------
149
174
  //
150
175
  // Events (public)
@@ -200,7 +225,7 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
200
225
  const loaderClass = this._editorLoading ? "" : "display-none";
201
226
  const featureFormClass = this._editorLoading ? "display-none" : "";
202
227
  const mobileMapClass = this.isMobile ? "show-map" : "display-none";
203
- return (h(Fragment, { key: '8adaa70257dfef9632f82be75dbdff572e2c39b3' }, h("calcite-loader", { key: 'e1a1aba8613d9cea1033513748dd21b7f27f9806', class: loaderClass, label: "", scale: "s" }), h("div", { key: 'e1089ffe60d079f345d358aac7ae1a6bd59a55df', class: featureFormClass, id: "feature-form" }), h("div", { key: '52274b6cd4c9f6886293f858caac9e572697da25', class: `search-widget ${showSearchWidget} ${featureFormClass}`, id: "search-widget-ref" }), h("div", { key: '64108cfa3bb57f9739bfb4951352c5523c194761', class: `${mobileMapClass}`, ref: (el) => { this._mapViewContainer = el; } })));
228
+ return (h(Fragment, { key: '47d29e529402482acf3811c37c0cd5a426ed40ed' }, h("calcite-loader", { key: '283b2c6a0f1722c9a8d955e11390e65e6041b247', class: loaderClass, label: "", scale: "s" }), h("div", { key: 'bb596467d5da22882932259db6a9e8029717850b', class: featureFormClass, id: "feature-form" }), h("div", { key: 'c3887f5c5aa92efdcf588da4918933dadb87937f', class: `search-widget ${showSearchWidget} ${featureFormClass}`, id: "search-widget-ref" }), h("div", { key: '566069a6202053468a3cf7a221feb071491eabb4', class: `${mobileMapClass}`, ref: (el) => { this._mapViewContainer = el; } })));
204
229
  }
205
230
  //--------------------------------------------------------------------------
206
231
  //
@@ -223,15 +248,21 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
223
248
  * @protected
224
249
  */
225
250
  async initModules() {
226
- const [Editor, reactiveUtils, Search, MapView] = await loadModules([
251
+ const [Editor, reactiveUtils, Search, ExpressionInfo, FieldElement, FormTemplate, MapView] = await loadModules([
227
252
  "esri/widgets/Editor",
228
253
  "esri/core/reactiveUtils",
229
254
  "esri/widgets/Search",
255
+ "esri/form/ExpressionInfo",
256
+ "esri/form/elements/FieldElement",
257
+ "esri/form/FormTemplate",
230
258
  "esri/views/MapView"
231
259
  ]);
232
260
  this.Editor = Editor;
233
261
  this.reactiveUtils = reactiveUtils;
234
262
  this.Search = Search;
263
+ this.ExpressionInfo = ExpressionInfo;
264
+ this.FieldElement = FieldElement;
265
+ this.FormTemplate = FormTemplate;
235
266
  this.MapView = MapView;
236
267
  }
237
268
  /**
@@ -322,6 +353,7 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
322
353
  const formHandle = this.reactiveUtils.watch(() => this._editor.viewModel.featureFormViewModel?.state, (state) => {
323
354
  if (state === 'ready') {
324
355
  this._mapViewContainer?.classList?.replace("show-map", "hide-map");
356
+ void this._setFloorLevel(this.floorLevel);
325
357
  this._showSearchWidget = false;
326
358
  this.progressStatus.emit(1);
327
359
  this.drawComplete.emit();
@@ -466,6 +498,59 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
466
498
  }
467
499
  return searchConfiguration;
468
500
  }
501
+ /**
502
+ * Add the floor level value to form
503
+ * @param level selected floor level
504
+ *
505
+ * @protected
506
+ */
507
+ async _setFloorLevel(level) {
508
+ if (!level) {
509
+ return;
510
+ }
511
+ const layer = await getLayerOrTable(this._updatedMapView, this.selectedLayerId);
512
+ if (layer?.floorInfo?.floorField) {
513
+ const layerField = layer.fields.find((field) => field.name === layer.floorInfo.floorField);
514
+ // if layer field is present and form template is not present only then we can set value of floorfield into feature form otherwise create a mannual formtemplate to add the floorfeild element
515
+ if (layerField && !layer?.formTemplate) {
516
+ this._editor.viewModel.featureFormViewModel.setValue(layerField.name, level);
517
+ layerField.editable = false;
518
+ }
519
+ else if (layer.formTemplate && this.formElements) {
520
+ const floorInfoExpression = new this.ExpressionInfo({
521
+ expression: `"${level}"`,
522
+ name: "floor-info-test",
523
+ title: "Floor Info",
524
+ returnType: "string"
525
+ });
526
+ const levelIdFieldElement = new this.FieldElement({
527
+ label: layer.floorInfo.floorField,
528
+ editableExpression: 'false',
529
+ fieldName: layer.floorInfo.floorField,
530
+ input: {
531
+ type: "text-box",
532
+ maxLength: 50,
533
+ minLength: 0
534
+ },
535
+ valueExpression: floorInfoExpression.name
536
+ });
537
+ this._updatedMapView.map.editableLayers.forEach((layer) => {
538
+ const orgElements = this.formElements.orgElements;
539
+ const orgExpressionInfos = this.formElements.orgExpressionInfos;
540
+ const elements = [...orgElements];
541
+ elements.push(levelIdFieldElement);
542
+ // Creating formtemplate
543
+ const floorInfoTemplate = new this.FormTemplate({
544
+ title: layer.formTemplate.title,
545
+ description: layer.formTemplate.description,
546
+ elements,
547
+ expressionInfos: [floorInfoExpression].concat(orgExpressionInfos)
548
+ });
549
+ layer.formTemplate = floorInfoTemplate;
550
+ });
551
+ }
552
+ }
553
+ }
469
554
  /**
470
555
  * Hides the elements of editor widget
471
556
  * @protected
@@ -537,10 +622,13 @@ const CreateFeature = /*@__PURE__*/ proxyCustomElement(class CreateFeature exten
537
622
  "customizeSubmit": [4, "customize-submit"],
538
623
  "searchConfiguration": [16],
539
624
  "isMobile": [4, "is-mobile"],
625
+ "floorLevel": [1, "floor-level"],
626
+ "formElements": [8, "form-elements"],
540
627
  "_editorLoading": [32],
541
628
  "_showSearchWidget": [32],
542
629
  "close": [64],
543
- "submit": [64]
630
+ "submit": [64],
631
+ "refresh": [64]
544
632
  }, undefined, {
545
633
  "mapView": ["mapViewWatchHandler"],
546
634
  "isMobile": ["isMobileHandler"],
@@ -78,6 +78,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
78
78
  this.appProxies = undefined;
79
79
  this.basemapConfig = undefined;
80
80
  this.coverPageEnabled = undefined;
81
+ this.customInfoText = undefined;
81
82
  this.defaultCenter = "";
82
83
  this.defaultGlobalId = "";
83
84
  this.defaultLayer = "";
@@ -273,7 +274,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
273
274
  render() {
274
275
  // only avoid border when we have a header color that is not white
275
276
  const borderClass = this.popupHeaderColor && this.popupHeaderColor !== "#FFFFFF" ? "border-width-0" : "";
276
- return (h(Host, { key: '805eb5daf8d5d7879e3404cd3c5145abf36469de' }, h("calcite-shell", { key: 'cb8a9037084e0ce4d32986a19a9aac9e6f407e1a', class: "position-relative" }, h("calcite-panel", { key: '176b6ef3c05414ec4a0582aac2d56deb21bd329f', class: `width-full height-full ${borderClass}` }, this._getBody(this._layoutMode, this._panelOpen, this._hideTable)), this._getFooter()), this._filterModal()));
277
+ return (h(Host, { key: 'fa5d4e79b6f5a3eb176af497a4444bb9aca59f15' }, h("calcite-shell", { key: '3e7466a6db42b61db1f9b6efb5cd84b97d3f9d3b', class: "position-relative" }, h("calcite-panel", { key: '15b850a0e9c3b62ebe3bd94b39b61eff1734ad4b', class: `width-full height-full ${borderClass}` }, this._getBody(this._layoutMode, this._panelOpen, this._hideTable)), this._getFooter()), this._filterModal()));
277
278
  }
278
279
  /**
279
280
  * Called after each render
@@ -496,7 +497,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
496
497
  const isTableLayout = this.appLayout === 'tableView';
497
498
  const cardManagerHeight = (isMapLayout || isTableLayout) ? "height-full" : !this._isMobile ? "height-50" : "height-full";
498
499
  const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
499
- return (h("div", { class: `width-50 height-full ${themeClass}` }, h("card-manager", { class: `${cardManagerHeight} width-full`, enableEditGeometry: this?._mapInfo?.enableEditGeometry, isMobile: this._isMobile, layer: this._layer, mapView: this?._mapView, selectedFeaturesIds: this._layerTable?.selectedIds, zoomAndScrollToSelected: this.zoomAndScrollToSelected })));
500
+ return (h("div", { class: `width-50 height-full ${themeClass}` }, h("card-manager", { class: `${cardManagerHeight} width-full`, customInfoText: this.customInfoText, enableEditGeometry: this?._mapInfo?.enableEditGeometry, isMobile: this._isMobile, layer: this._layer, mapView: this?._mapView, selectedFeaturesIds: this._layerTable?.selectedIds, zoomAndScrollToSelected: this.zoomAndScrollToSelected })));
500
501
  }
501
502
  /**
502
503
  * Get the table node based for the current layout
@@ -740,6 +741,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
740
741
  "appProxies": [8, "app-proxies"],
741
742
  "basemapConfig": [16],
742
743
  "coverPageEnabled": [4, "cover-page-enabled"],
744
+ "customInfoText": [1, "custom-info-text"],
743
745
  "defaultCenter": [1, "default-center"],
744
746
  "defaultGlobalId": [1, "default-global-id"],
745
747
  "defaultLayer": [1, "default-layer"],