@esri/solutions-components 0.5.9 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/assets/t9n/public-notification/resources.json +1 -1
  2. package/dist/assets/t9n/public-notification/resources_ar.json +5 -4
  3. package/dist/assets/t9n/public-notification/resources_bg.json +5 -4
  4. package/dist/assets/t9n/public-notification/resources_bs.json +5 -4
  5. package/dist/assets/t9n/public-notification/resources_ca.json +5 -4
  6. package/dist/assets/t9n/public-notification/resources_cs.json +5 -4
  7. package/dist/assets/t9n/public-notification/resources_da.json +5 -4
  8. package/dist/assets/t9n/public-notification/resources_de.json +5 -4
  9. package/dist/assets/t9n/public-notification/resources_el.json +5 -4
  10. package/dist/assets/t9n/public-notification/resources_en.json +1 -1
  11. package/dist/assets/t9n/public-notification/resources_es.json +5 -4
  12. package/dist/assets/t9n/public-notification/resources_et.json +5 -4
  13. package/dist/assets/t9n/public-notification/resources_fi.json +5 -4
  14. package/dist/assets/t9n/public-notification/resources_fr.json +5 -4
  15. package/dist/assets/t9n/public-notification/resources_he.json +5 -4
  16. package/dist/assets/t9n/public-notification/resources_hr.json +5 -4
  17. package/dist/assets/t9n/public-notification/resources_hu.json +5 -4
  18. package/dist/assets/t9n/public-notification/resources_id.json +5 -4
  19. package/dist/assets/t9n/public-notification/resources_it.json +5 -4
  20. package/dist/assets/t9n/public-notification/resources_ja.json +5 -4
  21. package/dist/assets/t9n/public-notification/resources_ko.json +5 -4
  22. package/dist/assets/t9n/public-notification/resources_lt.json +5 -4
  23. package/dist/assets/t9n/public-notification/resources_lv.json +5 -4
  24. package/dist/assets/t9n/public-notification/resources_nb.json +5 -4
  25. package/dist/assets/t9n/public-notification/resources_nl.json +5 -4
  26. package/dist/assets/t9n/public-notification/resources_pl.json +5 -4
  27. package/dist/assets/t9n/public-notification/resources_pt-BR.json +5 -4
  28. package/dist/assets/t9n/public-notification/resources_pt-PT.json +5 -4
  29. package/dist/assets/t9n/public-notification/resources_ro.json +5 -4
  30. package/dist/assets/t9n/public-notification/resources_ru.json +5 -4
  31. package/dist/assets/t9n/public-notification/resources_sk.json +5 -4
  32. package/dist/assets/t9n/public-notification/resources_sl.json +5 -4
  33. package/dist/assets/t9n/public-notification/resources_sr.json +5 -4
  34. package/dist/assets/t9n/public-notification/resources_sv.json +5 -4
  35. package/dist/assets/t9n/public-notification/resources_th.json +5 -4
  36. package/dist/assets/t9n/public-notification/resources_tr.json +5 -4
  37. package/dist/assets/t9n/public-notification/resources_uk.json +5 -4
  38. package/dist/assets/t9n/public-notification/resources_vi.json +5 -4
  39. package/dist/assets/t9n/public-notification/resources_zh-CN.json +5 -4
  40. package/dist/assets/t9n/public-notification/resources_zh-HK.json +5 -4
  41. package/dist/assets/t9n/public-notification/resources_zh-TW.json +5 -4
  42. package/dist/cjs/buffer-tools_4.cjs.entry.js +3 -3
  43. package/dist/cjs/calcite-input-text_5.cjs.entry.js +6 -11
  44. package/dist/cjs/{downloadUtils-4ef4b28b.js → downloadUtils-7a0fd3c0.js} +77 -20
  45. package/dist/cjs/{index.es-cbe67d5b.js → index.es-9965b78c.js} +1 -1
  46. package/dist/cjs/layer-table_2.cjs.entry.js +8 -3
  47. package/dist/cjs/loader.cjs.js +1 -1
  48. package/dist/cjs/public-notification.cjs.entry.js +56 -21
  49. package/dist/cjs/solutions-components.cjs.js +1 -1
  50. package/dist/collection/components/buffer-tools/buffer-tools.css +4 -0
  51. package/dist/collection/components/buffer-tools/buffer-tools.js +1 -1
  52. package/dist/collection/components/layer-table/layer-table.js +7 -2
  53. package/dist/collection/components/map-draw-tools/map-draw-tools.css +4 -0
  54. package/dist/collection/components/map-select-tools/map-select-tools.js +18 -1
  55. package/dist/collection/components/pdf-download/pdf-download.js +3 -9
  56. package/dist/collection/components/public-notification/public-notification.js +57 -21
  57. package/dist/collection/demos/new-public-notification.html +6 -4
  58. package/dist/collection/utils/downloadUtils.js +74 -19
  59. package/dist/collection/utils/downloadUtils.ts +93 -26
  60. package/dist/collection/utils/interfaces.ts +2 -2
  61. package/dist/components/buffer-tools2.js +2 -2
  62. package/dist/components/downloadUtils.js +75 -20
  63. package/dist/components/layer-table2.js +7 -2
  64. package/dist/components/map-draw-tools2.js +1 -1
  65. package/dist/components/map-select-tools2.js +3 -1
  66. package/dist/components/pdf-download2.js +3 -9
  67. package/dist/components/public-notification.js +57 -21
  68. package/dist/esm/buffer-tools_4.entry.js +3 -3
  69. package/dist/esm/calcite-combobox_3.entry.js +1 -1
  70. package/dist/esm/calcite-input-text_5.entry.js +7 -12
  71. package/dist/esm/{downloadUtils-2ebeb46d.js → downloadUtils-a447bab1.js} +77 -22
  72. package/dist/esm/{index.es-6dd27a48.js → index.es-b9cb902a.js} +2 -2
  73. package/dist/esm/layer-table_2.entry.js +9 -4
  74. package/dist/esm/loader.js +1 -1
  75. package/dist/esm/{mapViewUtils-ebbd4733.js → mapViewUtils-27dfdc29.js} +1 -1
  76. package/dist/esm/public-notification.entry.js +57 -22
  77. package/dist/esm/solutions-components.js +1 -1
  78. package/dist/solutions-components/demos/new-public-notification.html +6 -4
  79. package/dist/solutions-components/p-2f4e1ddf.entry.js +6 -0
  80. package/dist/solutions-components/{p-657caece.js → p-345f517c.js} +5 -5
  81. package/dist/solutions-components/{p-390d7de8.js → p-4b426bab.js} +1 -1
  82. package/dist/solutions-components/{p-b4d4b50a.entry.js → p-52b747fa.entry.js} +3 -3
  83. package/dist/solutions-components/p-62492a2d.entry.js +17 -0
  84. package/dist/solutions-components/{p-ad82c173.js → p-80757ebd.js} +1 -1
  85. package/dist/solutions-components/p-cf00a2ef.entry.js +6 -0
  86. package/dist/solutions-components/{p-83e3db8e.entry.js → p-db099e05.entry.js} +1 -1
  87. package/dist/solutions-components/solutions-components.esm.js +1 -1
  88. package/dist/solutions-components/utils/downloadUtils.ts +93 -26
  89. package/dist/solutions-components/utils/interfaces.ts +2 -2
  90. package/dist/types/components/map-select-tools/map-select-tools.d.ts +5 -0
  91. package/dist/types/components/public-notification/public-notification.d.ts +18 -11
  92. package/dist/types/components.d.ts +8 -0
  93. package/dist/types/utils/downloadUtils.d.ts +22 -8
  94. package/dist/types/utils/interfaces.d.ts +2 -2
  95. package/package.json +1 -1
  96. package/dist/solutions-components/p-6f27bea2.entry.js +0 -17
  97. package/dist/solutions-components/p-db82a9ce.entry.js +0 -6
  98. package/dist/solutions-components/p-deb90ce7.entry.js +0 -6
@@ -24,6 +24,7 @@ import { loadModules } from "../../utils/loadModules";
24
24
  import { goToSelection, highlightFeatures } from "../../utils/mapViewUtils";
25
25
  import state from "../../utils/publicNotificationStore";
26
26
  import { getLocaleComponentStrings } from "../../utils/locale";
27
+ import { consolidateLabels, removeDuplicateLabels } from "../../utils/downloadUtils";
27
28
  export class PublicNotification {
28
29
  constructor() {
29
30
  /**
@@ -51,6 +52,7 @@ export class PublicNotification {
51
52
  this._addTitle = false;
52
53
  this._downloadActive = true;
53
54
  this._exportType = EExportType.PDF;
55
+ this._numDuplicates = 0;
54
56
  this._pageType = EPageType.LIST;
55
57
  this._saveEnabled = false;
56
58
  this._selectionSets = [];
@@ -117,6 +119,9 @@ export class PublicNotification {
117
119
  if ((_a = this.mapView) === null || _a === void 0 ? void 0 : _a.popup) {
118
120
  this.mapView.popup.autoOpenEnabled = pageType !== EPageType.LIST ? false : this._popupsEnabled;
119
121
  }
122
+ if (pageType === EPageType.EXPORT) {
123
+ this._numDuplicates = await this._getNumDuplicates();
124
+ }
120
125
  this._clearHighlight();
121
126
  if (oldPageType === EPageType.SELECT || oldPageType === EPageType.REFINE) {
122
127
  // clear any draw shapes or buffers
@@ -324,7 +329,7 @@ export class PublicNotification {
324
329
  validSet = numIds > 0;
325
330
  }
326
331
  if (validSet) {
327
- prev.push((h("calcite-list-item", { description: this._translations.selectedFeatures.replace("{{n}}", ids.length.toString()), label: cur.label, onClick: () => this._gotoSelection(cur, this.mapView) }, h("div", { slot: "content" }, h("div", { class: "list-label" }, cur.label), h("div", { class: "list-description" }, (_a = cur === null || cur === void 0 ? void 0 : cur.layerView) === null || _a === void 0 ? void 0 : _a.layer.title), h("div", { class: "list-description" }, this._translations.selectedFeatures.replace("{{n}}", ids.length.toString()))), this._getAction(true, "pencil", "", (evt) => this._openSelection(cur, evt), false, "actions-end"), this._getAction(true, "x", "", (evt) => this._deleteSelection(i, evt), false, "actions-end"))));
332
+ prev.push((h("calcite-list-item", { label: cur.label, onClick: () => this._gotoSelection(cur, this.mapView) }, h("div", { slot: "content" }, h("div", { class: "list-label" }, cur.label), h("div", { class: "list-description" }, (_a = cur === null || cur === void 0 ? void 0 : cur.layerView) === null || _a === void 0 ? void 0 : _a.layer.title), h("div", { class: "list-description" }, this._translations.selectedFeatures.replace("{{n}}", ids.length.toString()))), this._getAction(true, "pencil", "", (evt) => this._openSelection(cur, evt), false, "actions-end"), this._getAction(true, "x", "", (evt) => this._deleteSelection(i, evt), false, "actions-end"))));
328
333
  }
329
334
  return prev;
330
335
  }, []))));
@@ -360,39 +365,67 @@ export class PublicNotification {
360
365
  return validateRefineSet && hasRefineSet ? ids.length > 0 || this._selectionSets.length > 1 : this._selectionSets.length > 0;
361
366
  }
362
367
  /**
363
- * Check if any duplicates exist
368
+ * Check if any duplicate labels exist
364
369
  *
365
370
  * @returns true if duplicates are found
366
371
  *
367
372
  * @protected
368
373
  */
369
- _hasDuplicates() {
370
- const selectedIds = this._getSelectedIds();
371
- return this._getNumDuplicates(selectedIds) > 0;
374
+ async _getNumDuplicates() {
375
+ const exportInfos = this._getExportInfos();
376
+ const labels = await consolidateLabels(exportInfos);
377
+ const duplicatesRemoved = removeDuplicateLabels(labels);
378
+ return labels.length - duplicatesRemoved.length;
372
379
  }
373
380
  /**
374
- * Return the number of duplicates
375
- *
376
- * @param ids the list of currently selected ids
381
+ * Get key details about what to export
377
382
  *
378
- * @returns the number of duplicates
383
+ * @returns IExportInfos that contain ids and layer
379
384
  *
380
385
  * @protected
381
386
  */
382
- _getNumDuplicates(ids) {
383
- return ids.length - new Set(ids).size;
387
+ _getExportInfos() {
388
+ return this._selectionSets.reduce((prev, cur) => {
389
+ if (cur.download) {
390
+ if (cur.workflowType !== EWorkflowType.REFINE) {
391
+ const id = cur.layerView.layer.id;
392
+ this._updateIds(id, cur.layerView, cur.selectedIds, prev);
393
+ }
394
+ else {
395
+ // REFINE stores ids differently as it can contain ids from multiple layers
396
+ // REFINE will only ever be 1 ISelectionSet
397
+ Object.keys(cur.refineInfos).forEach(k => {
398
+ const refineIds = cur.refineInfos[k];
399
+ this._updateIds(k, refineIds.layerView, refineIds.addIds, prev);
400
+ });
401
+ }
402
+ }
403
+ return prev;
404
+ }, {});
384
405
  }
385
406
  /**
386
- * Get the complete list of selected ids
407
+ * Consolidate ids for each layer
408
+ *
409
+ * @param id the layer id from the selectionSet
410
+ * @param layerView the layerView from the selectionSet
411
+ * @param ids the selectedIds from the selectionSet
412
+ * @param obj the object that will store the consolidated ids and layer info
387
413
  *
388
- * @returns all currently selected IDs
414
+ * @returns IExportInfo key details that will be used for export
389
415
  *
390
416
  * @protected
391
417
  */
392
- _getSelectedIds() {
393
- return this._selectionSets.reduce((prev, cur) => {
394
- return prev.concat(cur.download ? cur.selectedIds : []);
395
- }, []);
418
+ _updateIds(id, layerView, ids, obj) {
419
+ if (obj[id]) {
420
+ obj[id].ids = obj[id].ids.concat(ids);
421
+ }
422
+ else {
423
+ obj[id] = {
424
+ layerView,
425
+ ids
426
+ };
427
+ }
428
+ return obj;
396
429
  }
397
430
  /**
398
431
  * Create the Select page that shows the selection workflows
@@ -402,7 +435,7 @@ export class PublicNotification {
402
435
  */
403
436
  _getSelectPage() {
404
437
  const noticeText = this._translations.selectSearchTip;
405
- return (h("calcite-panel", null, this._getLabel(this._translations.stepTwoFull, true), this._getNotice(noticeText), h("div", null, h("map-select-tools", { bufferColor: this.bufferColor, bufferOutlineColor: this.bufferOutlineColor, class: "font-bold", customLabelEnabled: this.customLabelEnabled, defaultBufferDistance: this.defaultBufferDistance, defaultBufferUnit: this.defaultBufferUnit, enabledLayerIds: this.selectionLayerIds, isUpdate: !!this._activeSelection, mapView: this.mapView, noResultText: this.noResultText, onSelectionSetChange: (evt) => this._updateForSelection(evt), ref: (el) => { this._selectTools = el; }, searchConfiguration: this._searchConfiguration, selectionSet: this._activeSelection, sketchLineSymbol: this.sketchLineSymbol, sketchPointSymbol: this.sketchPointSymbol, sketchPolygonSymbol: this.sketchPolygonSymbol })), this._getPageNavButtons(this._translations.done, this._numSelected === 0, () => { void this._saveSelection(); }, this._translations.cancel, false, () => { void this._home(); })));
438
+ return (h("calcite-panel", null, this._getLabel(this._translations.stepTwoFull, true), this._getNotice(noticeText), h("div", null, h("map-select-tools", { bufferColor: this.bufferColor, bufferOutlineColor: this.bufferOutlineColor, class: "font-bold", customLabelEnabled: this.customLabelEnabled, defaultBufferDistance: this.defaultBufferDistance, defaultBufferUnit: this.defaultBufferUnit, enabledLayerIds: this.addresseeLayerIds, isUpdate: !!this._activeSelection, mapView: this.mapView, noResultText: this.noResultText, onSelectionSetChange: (evt) => this._updateForSelection(evt), ref: (el) => { this._selectTools = el; }, searchConfiguration: this._searchConfiguration, selectionLayerIds: this.selectionLayerIds, selectionSet: this._activeSelection, sketchLineSymbol: this.sketchLineSymbol, sketchPointSymbol: this.sketchPointSymbol, sketchPolygonSymbol: this.sketchPolygonSymbol })), this._getPageNavButtons(this._translations.done, this._numSelected === 0, () => { void this._saveSelection(); }, this._translations.cancel, false, () => { void this._home(); })));
406
439
  }
407
440
  /**
408
441
  * Create the main download page that has the shared aspects of both PDF and CSV
@@ -413,8 +446,8 @@ export class PublicNotification {
413
446
  */
414
447
  _getExportPage() {
415
448
  const hasSelections = this._hasSelections(this.showRefineSelection);
416
- const numDuplicates = this._getNumDuplicates(this._getSelectedIds());
417
- return (h("calcite-panel", null, h("div", null, this._getLabel(this._translations.export, false), hasSelections ? (h("div", null, this._getNotice(this._translations.exportTip, "padding-sides-1"), this._getLabel(this._translations.exportListsLabel), this._getExportSelectionLists(), h("div", { class: "padding-sides-1" }, h("div", { class: "display-flex" }, h("calcite-label", { layout: "inline" }, h("calcite-checkbox", { ref: (el) => { this._removeDuplicates = el; } }), h("div", { class: "display-flex" }, this._translations.removeDuplicate, h("div", { class: "info-message padding-start-1-2" }, h("calcite-input-message", { class: "info-blue margin-top-0", scale: "m" }, ` ${this._translations.numDuplicates.replace("{{n}}", numDuplicates.toString())}`)))), h("calcite-icon", { class: "padding-start-1-2 icon", icon: "question", id: "remove-duplicates-icon", scale: "s" })), h("calcite-popover", { closable: true, label: "", referenceElement: "remove-duplicates-icon" }, h("span", { class: "tooltip-message" }, this._translations.duplicatesTip))), h("div", { class: "border-bottom" }), h("div", { class: "padding-top-sides-1" }, h("calcite-segmented-control", { class: "w-100", onCalciteSegmentedControlChange: (evt) => this._exportTypeChange(evt) }, h("calcite-segmented-control-item", { checked: this._exportType === EExportType.PDF, class: "w-50 end-border", value: EExportType.PDF }, this._translations.pdf), h("calcite-segmented-control-item", { checked: this._exportType === EExportType.CSV, class: "w-50", value: EExportType.CSV }, this._translations.csv))), h("div", { class: "padding-bottom-1" }, this._getExportOptions()), h("div", { class: "padding-1 display-flex" }, h("calcite-button", { disabled: !this._downloadActive, onClick: () => void this._export(), width: "full" }, this._translations.export)))) : (this._getNotice(this._translations.downloadNoLists, "padding-sides-1 padding-bottom-1")))));
449
+ const displayDuplicatesClass = this._numDuplicates > 0 ? "display-block" : "display-none";
450
+ return (h("calcite-panel", null, h("div", null, this._getLabel(this._translations.export, false), hasSelections ? (h("div", null, this._getNotice(this._translations.exportTip, "padding-sides-1"), this._getLabel(this._translations.exportListsLabel), this._getExportSelectionLists(), h("div", { class: "padding-sides-1 " + displayDuplicatesClass }, h("div", { class: "display-flex" }, h("calcite-label", { layout: "inline" }, h("calcite-checkbox", { ref: (el) => { this._removeDuplicates = el; } }), h("div", { class: "display-flex" }, this._translations.removeDuplicate, h("div", { class: "info-message padding-start-1-2" }, h("calcite-input-message", { class: "info-blue margin-top-0", scale: "m" }, ` ${this._translations.numDuplicates.replace("{{n}}", this._numDuplicates.toString())}`)))), h("calcite-icon", { class: "padding-start-1-2 icon", icon: "question", id: "remove-duplicates-icon", scale: "s" })), h("calcite-popover", { closable: true, label: "", referenceElement: "remove-duplicates-icon" }, h("span", { class: "tooltip-message" }, this._translations.duplicatesTip))), h("div", { class: "border-bottom" }), h("div", { class: "padding-top-sides-1" }, h("calcite-segmented-control", { class: "w-100", onCalciteSegmentedControlChange: (evt) => this._exportTypeChange(evt) }, h("calcite-segmented-control-item", { checked: this._exportType === EExportType.PDF, class: "w-50 end-border", value: EExportType.PDF }, this._translations.pdf), h("calcite-segmented-control-item", { checked: this._exportType === EExportType.CSV, class: "w-50", value: EExportType.CSV }, this._translations.csv))), h("div", { class: "padding-bottom-1" }, this._getExportOptions()), h("div", { class: "padding-1 display-flex" }, h("calcite-button", { disabled: !this._downloadActive, onClick: () => void this._export(), width: "full" }, this._translations.export)))) : (this._getNotice(this._translations.downloadNoLists, "padding-sides-1 padding-bottom-1")))));
418
451
  }
419
452
  /**
420
453
  * Store the user selected export type CSV || PDF
@@ -494,13 +527,14 @@ export class PublicNotification {
494
527
  */
495
528
  _getExportSelectionLists() {
496
529
  return this._selectionSets.reduce((prev, cur) => {
530
+ var _a;
497
531
  const ids = this._getSelectionSetIds(cur);
498
532
  const validSet = cur.workflowType !== EWorkflowType.REFINE || ids.length > 0;
499
533
  if (!this._downloadActive && cur.download && validSet) {
500
534
  this._downloadActive = true;
501
535
  }
502
536
  if (validSet) {
503
- prev.push((h("div", { class: "display-flex padding-sides-1 padding-bottom-1" }, h("calcite-checkbox", { checked: cur.download, class: "align-center", onClick: () => { void this._toggleDownload(cur.id); } }), h("calcite-list", { class: "list-border margin-start-1-2 width-full", id: "download-list" }, h("calcite-list-item", { description: this._translations.selectedFeatures.replace("{{n}}", ids.length.toString()), disabled: !cur.download, label: cur.label, onClick: () => { void this._toggleDownload(cur.id); } })))));
537
+ prev.push((h("div", { class: "display-flex padding-sides-1 padding-bottom-1" }, h("calcite-checkbox", { checked: cur.download, class: "align-center", onClick: () => { void this._toggleDownload(cur.id); } }), h("calcite-list", { class: "list-border margin-start-1-2 width-full", id: "download-list" }, h("calcite-list-item", { disabled: !cur.download, label: cur.label, onClick: () => { void this._toggleDownload(cur.id); } }, h("div", { slot: "content" }, h("div", { class: "list-label" }, cur.label), h("div", { class: "list-description" }, (_a = cur === null || cur === void 0 ? void 0 : cur.layerView) === null || _a === void 0 ? void 0 : _a.layer.title), h("div", { class: "list-description" }, this._translations.selectedFeatures.replace("{{n}}", ids.length.toString()))))))));
504
538
  }
505
539
  return prev;
506
540
  }, []) || (h("div", null));
@@ -520,6 +554,7 @@ export class PublicNotification {
520
554
  return ss;
521
555
  });
522
556
  this._downloadActive = isActive;
557
+ this._numDuplicates = await this._getNumDuplicates();
523
558
  await this._highlightFeatures();
524
559
  }
525
560
  /**
@@ -1087,6 +1122,7 @@ export class PublicNotification {
1087
1122
  "_addTitle": {},
1088
1123
  "_downloadActive": {},
1089
1124
  "_exportType": {},
1125
+ "_numDuplicates": {},
1090
1126
  "_pageType": {},
1091
1127
  "_saveEnabled": {},
1092
1128
  "_selectionSets": {},
@@ -55,12 +55,12 @@
55
55
 
56
56
  <link
57
57
  rel="stylesheet"
58
- href="https://js.arcgis.com/4.25/esri/themes/light/main.css"
58
+ href="https://js.arcgis.com/4.26/esri/themes/light/main.css"
59
59
  />
60
60
  <link rel="stylesheet" href="https://webapps-cdn.esri.com/CDN/fonts/v1.4.1/fonts.css" />
61
61
  <link rel="stylesheet" href="../solutions-components.css" type="text/css">
62
62
 
63
- <script src="https://js.arcgis.com/4.25/"></script>
63
+ <script src="https://js.arcgis.com/4.26/"></script>
64
64
  <script type="module" src="../solutions-components.esm.js"></script>
65
65
 
66
66
  <script>
@@ -90,7 +90,8 @@
90
90
  });
91
91
  demo.mapView.ui.add(legend, "top-left");
92
92
  });
93
- //demo.addresseeLayerIds = ["18434515eb8-layer-12"];
93
+ // solutions layer id
94
+ //demo.addresseeLayerIds = ["TaxParcels_3419"];
94
95
  //demo.defaultBufferDistance = 100;
95
96
  //demo.defaultBufferUnit = "kilometers";
96
97
  demo.featureEffect = {
@@ -99,7 +100,8 @@
99
100
  };
100
101
  demo.featureHighlightEnabled = true;
101
102
  demo.noResultText = "No results found";
102
- //demo.selectionLayerIds = ["1843422bf6b-layer-7"];
103
+ // solutions layer id
104
+ //demo.selectionLayerIds = ["SiteAddresses_8878"];
103
105
  demo.showSearchSettings = true;
104
106
  demo.customLabelEnabled = true;
105
107
  // demo.bufferColor = [227, 0, 0, 0.8];
@@ -30,39 +30,52 @@ const lineSeparatorChar = "|";
30
30
  /**
31
31
  * Downloads csv of mailing labels for the provided list of ids
32
32
  *
33
- * @param selectionSetNames Names of the selection sets used to provide ids
34
- * @param layer Layer providing features and attributes for download
35
- * @param ids List of ids to download
33
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
36
34
  * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
37
35
  * all attributes are exported
38
36
  * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
39
37
  * @param addColumnTitle Indicates if column headings should be included in output
40
38
  * @returns Promise resolving when function is done
41
39
  */
42
- export async function downloadCSV(selectionSetNames, layer, ids, formatUsingLayerPopup, removeDuplicates = false, addColumnTitle = false) {
43
- const labels = await _prepareLabels(layer, ids, removeDuplicates, formatUsingLayerPopup, addColumnTitle);
44
- exportCSV(_createFilename(selectionSetNames), labels);
40
+ export async function downloadCSV(exportInfos, formatUsingLayerPopup, removeDuplicates = false, addColumnTitle = false) {
41
+ let labels = await consolidateLabels(exportInfos, formatUsingLayerPopup, addColumnTitle, true);
42
+ labels = removeDuplicates ? removeDuplicateLabels(labels) : labels;
43
+ const layerIds = Object.keys(exportInfos);
44
+ let layerLabels = [];
45
+ labels.forEach(label => {
46
+ const id = label[0];
47
+ // layerIds are stored as value separator at the end of the values for a given layer
48
+ if (layerIds.indexOf(id) < 0) {
49
+ layerLabels.push(label);
50
+ }
51
+ else {
52
+ const selectionSetNames = _getSelectionSetNames(exportInfos, new RegExp(`\\b${id}\\b`));
53
+ // once we see the layerId we have reached the end of it's values and should export
54
+ exportCSV(_createFilename(selectionSetNames), layerLabels);
55
+ layerLabels = [];
56
+ }
57
+ });
45
58
  return Promise.resolve();
46
59
  }
47
60
  /**
48
61
  * Downloads csv of mailing labels for the provided list of ids
49
62
  *
50
- * @param selectionSetNames Names of the selection sets used to provide ids
51
- * @param layer Layer providing features and attributes for download
52
- * @param ids List of ids to download
63
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
53
64
  * @param labelPageDescription Provides PDF page layout info
54
65
  * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
55
66
  * @param title Title for each page
56
67
  * @param initialImageDataUrl Data URL of image for first page
57
68
  * @returns Promise resolving when function is done
58
69
  */
59
- export async function downloadPDF(selectionSetNames, layer, ids, labelPageDescription, removeDuplicates = false, title = "", initialImageDataUrl = "") {
60
- let labels = await _prepareLabels(layer, ids, removeDuplicates);
70
+ export async function downloadPDF(exportInfos, labelPageDescription, removeDuplicates = false, title = "", initialImageDataUrl = "") {
71
+ let labels = await consolidateLabels(exportInfos);
72
+ const selectionSetNames = _getSelectionSetNames(exportInfos);
61
73
  labels =
62
74
  // Remove empty lines in labels
63
75
  labels.map(labelLines => labelLines.filter(line => line.length > 0))
64
76
  // Remove empty labels
65
77
  .filter(label => label.length > 0);
78
+ labels = removeDuplicates ? removeDuplicateLabels(labels) : labels;
66
79
  exportPDF(_createFilename(selectionSetNames), labels, labelPageDescription, title, initialImageDataUrl);
67
80
  return Promise.resolve();
68
81
  }
@@ -281,13 +294,12 @@ function _prepareAttributeValue(attributeValue, attributeType, attributeDomain,
281
294
  *
282
295
  * @param layer Layer from which to fetch features
283
296
  * @param ids List of ids to download
284
- * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
285
297
  * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
286
298
  * all attributes are exported
287
299
  * @param includeHeaderNames Add the label format at the front of the list of generated labels
288
300
  * @returns Promise resolving when function is done
289
301
  */
290
- async function _prepareLabels(layer, ids, removeDuplicates = true, formatUsingLayerPopup = true, includeHeaderNames = false) {
302
+ async function _prepareLabels(layer, ids, formatUsingLayerPopup = true, includeHeaderNames = false) {
291
303
  var _a, _b, _c, _d, _e, _f;
292
304
  const [intl] = await loadModules(["esri/intl"]);
293
305
  // Get the features to export
@@ -412,12 +424,6 @@ async function _prepareLabels(layer, ids, removeDuplicates = true, formatUsingLa
412
424
  });
413
425
  });
414
426
  }
415
- // Remove duplicates
416
- if (removeDuplicates) {
417
- const labelsAsStrings = labels.map(label => JSON.stringify(label));
418
- const uniqueLabels = new Set(labelsAsStrings);
419
- labels = Array.from(uniqueLabels, labelString => JSON.parse(labelString));
420
- }
421
427
  // Add header names
422
428
  if (includeHeaderNames) {
423
429
  let headerNames = [];
@@ -434,4 +440,53 @@ async function _prepareLabels(layer, ids, removeDuplicates = true, formatUsingLa
434
440
  }
435
441
  return Promise.resolve(labels);
436
442
  }
443
+ /**
444
+ * Remove any duplicate labels
445
+ *
446
+ * @param labels Labels to evaluate for duplicates
447
+ * @returns labels with duplicates removed
448
+ */
449
+ export function removeDuplicateLabels(labels) {
450
+ const labelsAsStrings = labels.map(label => JSON.stringify(label));
451
+ const uniqueLabels = new Set(labelsAsStrings);
452
+ return Array.from(uniqueLabels, labelString => JSON.parse(labelString));
453
+ }
454
+ /**
455
+ * Extract selectionSetNames from the provided exportInfos
456
+ *
457
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
458
+ * @returns selectionSetNames that will be used for export filenames
459
+ */
460
+ function _getSelectionSetNames(exportInfos, id = /.+/) {
461
+ let selectionSetNames = [];
462
+ Object.keys(exportInfos).forEach(k => {
463
+ const exportInfo = exportInfos[k];
464
+ if (id.test(k)) {
465
+ selectionSetNames = selectionSetNames.concat(exportInfo.selectionSetNames);
466
+ }
467
+ });
468
+ return selectionSetNames;
469
+ }
470
+ /**
471
+ * Create and consolidate labels from all layers
472
+ *
473
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
474
+ * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
475
+ * all attributes are exported
476
+ * @param includeHeaderNames Add the label format at the front of the list of generated labels
477
+ * @returns selectionSetNames that will be used for export filenames
478
+ */
479
+ export async function consolidateLabels(exportInfos, formatUsingLayerPopup = true, includeHeaderNames = false, isCSVExport = false) {
480
+ const labelRequests = [];
481
+ Object.keys(exportInfos).forEach(k => {
482
+ const labelInfo = exportInfos[k];
483
+ labelRequests.push(_prepareLabels(labelInfo.layerView.layer, labelInfo.ids, formatUsingLayerPopup, includeHeaderNames));
484
+ if (isCSVExport) {
485
+ // add the layer id as a temp value separator that we can use to split values for CSV export
486
+ labelRequests.push(Promise.resolve([[k]]));
487
+ }
488
+ });
489
+ const labels = await Promise.all(labelRequests);
490
+ return labels.reduce((prev, cur) => prev.concat(cur), []);
491
+ }
437
492
  //#endregion
@@ -20,6 +20,7 @@ import { exportCSV } from "./csvUtils";
20
20
  import { ILabel, exportPDF } from "./pdfUtils";
21
21
  import { loadModules } from "./loadModules";
22
22
  import { queryFeaturesByID } from "./queryUtils";
23
+ import { IExportInfo, IExportInfos } from "../utils/interfaces";
23
24
 
24
25
  export { ILabel } from "./pdfUtils";
25
26
 
@@ -70,9 +71,7 @@ const lineSeparatorChar = "|";
70
71
  /**
71
72
  * Downloads csv of mailing labels for the provided list of ids
72
73
  *
73
- * @param selectionSetNames Names of the selection sets used to provide ids
74
- * @param layer Layer providing features and attributes for download
75
- * @param ids List of ids to download
74
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
76
75
  * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
77
76
  * all attributes are exported
78
77
  * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
@@ -80,16 +79,30 @@ const lineSeparatorChar = "|";
80
79
  * @returns Promise resolving when function is done
81
80
  */
82
81
  export async function downloadCSV(
83
- selectionSetNames: string[],
84
- layer: __esri.FeatureLayer,
85
- ids: number[],
82
+ exportInfos: IExportInfos,
86
83
  formatUsingLayerPopup: boolean,
87
84
  removeDuplicates = false,
88
85
  addColumnTitle = false
89
86
  ): Promise<void> {
90
- const labels = await _prepareLabels(layer, ids, removeDuplicates, formatUsingLayerPopup, addColumnTitle);
87
+ let labels = await consolidateLabels(exportInfos, formatUsingLayerPopup, addColumnTitle, true);
88
+ labels = removeDuplicates ? removeDuplicateLabels(labels) : labels;
89
+
90
+ const layerIds = Object.keys(exportInfos);
91
+
92
+ let layerLabels = [];
93
+ labels.forEach(label => {
94
+ const id = label[0];
95
+ // layerIds are stored as value separator at the end of the values for a given layer
96
+ if (layerIds.indexOf(id) < 0) {
97
+ layerLabels.push(label);
98
+ } else {
99
+ const selectionSetNames = _getSelectionSetNames(exportInfos, new RegExp(`\\b${id}\\b`));
91
100
 
92
- exportCSV(_createFilename(selectionSetNames), labels);
101
+ // once we see the layerId we have reached the end of it's values and should export
102
+ exportCSV(_createFilename(selectionSetNames), layerLabels);
103
+ layerLabels = [];
104
+ }
105
+ });
93
106
 
94
107
  return Promise.resolve();
95
108
  }
@@ -97,9 +110,7 @@ export async function downloadCSV(
97
110
  /**
98
111
  * Downloads csv of mailing labels for the provided list of ids
99
112
  *
100
- * @param selectionSetNames Names of the selection sets used to provide ids
101
- * @param layer Layer providing features and attributes for download
102
- * @param ids List of ids to download
113
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
103
114
  * @param labelPageDescription Provides PDF page layout info
104
115
  * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
105
116
  * @param title Title for each page
@@ -107,15 +118,14 @@ export async function downloadCSV(
107
118
  * @returns Promise resolving when function is done
108
119
  */
109
120
  export async function downloadPDF(
110
- selectionSetNames: string[],
111
- layer: __esri.FeatureLayer,
112
- ids: number[],
121
+ exportInfos: IExportInfos,
113
122
  labelPageDescription: ILabel,
114
123
  removeDuplicates = false,
115
124
  title = "",
116
125
  initialImageDataUrl = ""
117
126
  ): Promise<void> {
118
- let labels = await _prepareLabels(layer, ids, removeDuplicates);
127
+ let labels = await consolidateLabels(exportInfos);
128
+ const selectionSetNames = _getSelectionSetNames(exportInfos);
119
129
 
120
130
  labels =
121
131
  // Remove empty lines in labels
@@ -123,6 +133,8 @@ export async function downloadPDF(
123
133
  // Remove empty labels
124
134
  .filter(label => label.length > 0);
125
135
 
136
+ labels = removeDuplicates ? removeDuplicateLabels(labels) : labels;
137
+
126
138
  exportPDF(_createFilename(selectionSetNames), labels, labelPageDescription, title, initialImageDataUrl);
127
139
 
128
140
  return Promise.resolve();
@@ -395,7 +407,6 @@ function _prepareAttributeValue(
395
407
  *
396
408
  * @param layer Layer from which to fetch features
397
409
  * @param ids List of ids to download
398
- * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
399
410
  * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
400
411
  * all attributes are exported
401
412
  * @param includeHeaderNames Add the label format at the front of the list of generated labels
@@ -404,7 +415,6 @@ function _prepareAttributeValue(
404
415
  async function _prepareLabels(
405
416
  layer: __esri.FeatureLayer,
406
417
  ids: number[],
407
- removeDuplicates = true,
408
418
  formatUsingLayerPopup = true,
409
419
  includeHeaderNames = false
410
420
  ): Promise<string[][]> {
@@ -584,15 +594,6 @@ async function _prepareLabels(
584
594
  );
585
595
  }
586
596
 
587
- // Remove duplicates
588
- if (removeDuplicates) {
589
- const labelsAsStrings: string[] = labels.map(label => JSON.stringify(label));
590
- const uniqueLabels = new Set(labelsAsStrings);
591
- labels = Array.from(uniqueLabels,
592
- labelString => JSON.parse(labelString)
593
- );
594
- }
595
-
596
597
  // Add header names
597
598
  if (includeHeaderNames) {
598
599
  let headerNames = [];
@@ -613,4 +614,70 @@ async function _prepareLabels(
613
614
  return Promise.resolve(labels);
614
615
  }
615
616
 
617
+ /**
618
+ * Remove any duplicate labels
619
+ *
620
+ * @param labels Labels to evaluate for duplicates
621
+ * @returns labels with duplicates removed
622
+ */
623
+ export function removeDuplicateLabels(
624
+ labels: string[][]
625
+ ): string[][] {
626
+ const labelsAsStrings: string[] = labels.map(label => JSON.stringify(label));
627
+ const uniqueLabels = new Set(labelsAsStrings);
628
+ return Array.from(uniqueLabels,
629
+ labelString => JSON.parse(labelString)
630
+ );
631
+ }
632
+
633
+ /**
634
+ * Extract selectionSetNames from the provided exportInfos
635
+ *
636
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
637
+ * @returns selectionSetNames that will be used for export filenames
638
+ */
639
+ function _getSelectionSetNames(
640
+ exportInfos: IExportInfos,
641
+ id = /.+/
642
+ ): string[] {
643
+ let selectionSetNames: string[] = [];
644
+ Object.keys(exportInfos).forEach(k => {
645
+ const exportInfo: IExportInfo = exportInfos[k];
646
+ if (id.test(k)) {
647
+ selectionSetNames = selectionSetNames.concat(exportInfo.selectionSetNames);
648
+ }
649
+ });
650
+ return selectionSetNames;
651
+ }
652
+
653
+ /**
654
+ * Create and consolidate labels from all layers
655
+ *
656
+ * @param exportInfos Key details about what to export (ids, layer, and selectionSetNames)
657
+ * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
658
+ * all attributes are exported
659
+ * @param includeHeaderNames Add the label format at the front of the list of generated labels
660
+ * @returns selectionSetNames that will be used for export filenames
661
+ */
662
+ export async function consolidateLabels(
663
+ exportInfos: IExportInfos,
664
+ formatUsingLayerPopup = true,
665
+ includeHeaderNames = false,
666
+ isCSVExport = false
667
+ ): Promise<string[][]> {
668
+ const labelRequests = [];
669
+
670
+ Object.keys(exportInfos).forEach(k => {
671
+ const labelInfo: IExportInfo = exportInfos[k];
672
+ labelRequests.push(_prepareLabels(labelInfo.layerView.layer, labelInfo.ids, formatUsingLayerPopup, includeHeaderNames));
673
+ if (isCSVExport) {
674
+ // add the layer id as a temp value separator that we can use to split values for CSV export
675
+ labelRequests.push(Promise.resolve([[k]]));
676
+ }
677
+ });
678
+
679
+ const labels = await Promise.all(labelRequests);
680
+ return labels.reduce((prev, cur) => prev.concat(cur), []);
681
+ }
682
+
616
683
  //#endregion
@@ -437,10 +437,10 @@ export interface IMapInfo {
437
437
  }
438
438
 
439
439
  export interface IExportInfos {
440
- [key: string]: IExportLayerInfo;
440
+ [key: string]: IExportInfo;
441
441
  }
442
442
 
443
- export interface IExportLayerInfo {
443
+ export interface IExportInfo {
444
444
  ids: number[],
445
445
  layerView: __esri.FeatureLayerView
446
446
  selectionSetNames: string[]
@@ -14,7 +14,7 @@ import { d as defineCustomElement$3 } from './progress.js';
14
14
  import { d as defineCustomElement$2 } from './select.js';
15
15
  import { d as defineCustomElement$1 } from './slider.js';
16
16
 
17
- const bufferToolsCss = ":host{display:block}.c-container{display:inline-flex}.flex-1{flex:\"1\"}.padding-end-1{-webkit-padding-end:1rem;padding-inline-end:1rem}";
17
+ const bufferToolsCss = ":host{display:block}.c-container{display:inline-flex}.flex-1{flex:\"1\"}.padding-end-1{-webkit-padding-end:1rem;padding-inline-end:1rem}.w-50{width:50%}";
18
18
 
19
19
  const BufferTools = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
20
20
  constructor() {
@@ -175,7 +175,7 @@ const BufferTools = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
175
175
  * @protected
176
176
  */
177
177
  _getTextBoxDisplay() {
178
- return (h("div", { class: "c-container" }, h("calcite-input", { class: "padding-end-1", max: this.max && this.max > 0 ? this.max : undefined, min: this.min, "number-button-type": "vertical", onCalciteInputInput: (evt) => this._setDistance(evt), placeholder: "0", type: "number", value: this.distance ? this.distance.toString() : undefined }), h("calcite-select", { class: "flex-1", label: "label", onCalciteSelectChange: () => this._setUnit(this._unitElement.value), ref: (el) => { this._unitElement = el; } }, this._getUnits())));
178
+ return (h("div", { class: "c-container" }, h("calcite-input", { class: "padding-end-1 w-50", max: this.max && this.max > 0 ? this.max : undefined, min: this.min, "number-button-type": "vertical", onCalciteInputInput: (evt) => this._setDistance(evt), placeholder: "0", type: "number", value: this.distance ? this.distance.toString() : undefined }), h("calcite-select", { class: "flex-1 w-50", label: "label", onCalciteSelectChange: () => this._setUnit(this._unitElement.value), ref: (el) => { this._unitElement = el; } }, this._getUnits())));
179
179
  }
180
180
  /**
181
181
  * Render distance control as a slider