@esri/solutions-components 0.5.9 → 0.5.11
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/assets/data/images/onboarding.png +0 -0
- package/dist/assets/t9n/public-notification/resources.json +1 -1
- package/dist/assets/t9n/public-notification/resources_ar.json +5 -4
- package/dist/assets/t9n/public-notification/resources_bg.json +5 -4
- package/dist/assets/t9n/public-notification/resources_bs.json +5 -4
- package/dist/assets/t9n/public-notification/resources_ca.json +5 -4
- package/dist/assets/t9n/public-notification/resources_cs.json +5 -4
- package/dist/assets/t9n/public-notification/resources_da.json +5 -4
- package/dist/assets/t9n/public-notification/resources_de.json +5 -4
- package/dist/assets/t9n/public-notification/resources_el.json +5 -4
- package/dist/assets/t9n/public-notification/resources_en.json +1 -1
- package/dist/assets/t9n/public-notification/resources_es.json +5 -4
- package/dist/assets/t9n/public-notification/resources_et.json +5 -4
- package/dist/assets/t9n/public-notification/resources_fi.json +5 -4
- package/dist/assets/t9n/public-notification/resources_fr.json +5 -4
- package/dist/assets/t9n/public-notification/resources_he.json +5 -4
- package/dist/assets/t9n/public-notification/resources_hr.json +5 -4
- package/dist/assets/t9n/public-notification/resources_hu.json +5 -4
- package/dist/assets/t9n/public-notification/resources_id.json +5 -4
- package/dist/assets/t9n/public-notification/resources_it.json +5 -4
- package/dist/assets/t9n/public-notification/resources_ja.json +5 -4
- package/dist/assets/t9n/public-notification/resources_ko.json +5 -4
- package/dist/assets/t9n/public-notification/resources_lt.json +5 -4
- package/dist/assets/t9n/public-notification/resources_lv.json +5 -4
- package/dist/assets/t9n/public-notification/resources_nb.json +5 -4
- package/dist/assets/t9n/public-notification/resources_nl.json +5 -4
- package/dist/assets/t9n/public-notification/resources_pl.json +5 -4
- package/dist/assets/t9n/public-notification/resources_pt-BR.json +5 -4
- package/dist/assets/t9n/public-notification/resources_pt-PT.json +5 -4
- package/dist/assets/t9n/public-notification/resources_ro.json +5 -4
- package/dist/assets/t9n/public-notification/resources_ru.json +5 -4
- package/dist/assets/t9n/public-notification/resources_sk.json +5 -4
- package/dist/assets/t9n/public-notification/resources_sl.json +5 -4
- package/dist/assets/t9n/public-notification/resources_sr.json +5 -4
- package/dist/assets/t9n/public-notification/resources_sv.json +5 -4
- package/dist/assets/t9n/public-notification/resources_th.json +5 -4
- package/dist/assets/t9n/public-notification/resources_tr.json +5 -4
- package/dist/assets/t9n/public-notification/resources_uk.json +5 -4
- package/dist/assets/t9n/public-notification/resources_vi.json +5 -4
- package/dist/assets/t9n/public-notification/resources_zh-CN.json +5 -4
- package/dist/assets/t9n/public-notification/resources_zh-HK.json +5 -4
- package/dist/assets/t9n/public-notification/resources_zh-TW.json +5 -4
- package/dist/cjs/buffer-tools_4.cjs.entry.js +18 -4
- package/dist/cjs/calcite-input-text_5.cjs.entry.js +6 -11
- package/dist/cjs/{downloadUtils-4ef4b28b.js → downloadUtils-7a0fd3c0.js} +77 -20
- package/dist/cjs/{index.es-cbe67d5b.js → index.es-9965b78c.js} +1 -1
- package/dist/cjs/layer-table_2.cjs.entry.js +8 -3
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/public-notification.cjs.entry.js +72 -23
- package/dist/cjs/solutions-components.cjs.js +1 -1
- package/dist/collection/components/buffer-tools/buffer-tools.css +4 -0
- package/dist/collection/components/buffer-tools/buffer-tools.js +1 -1
- package/dist/collection/components/layer-table/layer-table.js +7 -2
- package/dist/collection/components/map-draw-tools/map-draw-tools.css +4 -0
- package/dist/collection/components/map-draw-tools/map-draw-tools.js +15 -1
- package/dist/collection/components/map-select-tools/map-select-tools.js +18 -1
- package/dist/collection/components/pdf-download/pdf-download.js +3 -9
- package/dist/collection/components/public-notification/public-notification.css +210 -203
- package/dist/collection/components/public-notification/public-notification.js +73 -22
- package/dist/collection/demos/new-public-notification.html +6 -4
- package/dist/collection/utils/downloadUtils.js +74 -19
- package/dist/collection/utils/downloadUtils.ts +93 -26
- package/dist/collection/utils/interfaces.ts +2 -2
- package/dist/components/buffer-tools2.js +2 -2
- package/dist/components/downloadUtils.js +75 -20
- package/dist/components/layer-table2.js +7 -2
- package/dist/components/map-draw-tools2.js +16 -2
- package/dist/components/map-select-tools2.js +3 -1
- package/dist/components/pdf-download2.js +3 -9
- package/dist/components/public-notification.js +74 -24
- package/dist/esm/buffer-tools_4.entry.js +18 -4
- package/dist/esm/calcite-combobox_3.entry.js +1 -1
- package/dist/esm/calcite-input-text_5.entry.js +7 -12
- package/dist/esm/{downloadUtils-2ebeb46d.js → downloadUtils-a447bab1.js} +77 -22
- package/dist/esm/{index.es-6dd27a48.js → index.es-b9cb902a.js} +2 -2
- package/dist/esm/layer-table_2.entry.js +9 -4
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{mapViewUtils-ebbd4733.js → mapViewUtils-27dfdc29.js} +1 -1
- package/dist/esm/public-notification.entry.js +74 -25
- package/dist/esm/solutions-components.js +1 -1
- package/dist/solutions-components/demos/new-public-notification.html +6 -4
- package/dist/solutions-components/p-2f4e1ddf.entry.js +6 -0
- package/dist/solutions-components/{p-657caece.js → p-345f517c.js} +5 -5
- package/dist/solutions-components/{p-390d7de8.js → p-4b426bab.js} +1 -1
- package/dist/solutions-components/p-62492a2d.entry.js +17 -0
- package/dist/solutions-components/{p-ad82c173.js → p-80757ebd.js} +1 -1
- package/dist/solutions-components/{p-83e3db8e.entry.js → p-db099e05.entry.js} +1 -1
- package/dist/solutions-components/p-f3fbc327.entry.js +6 -0
- package/dist/solutions-components/{p-b4d4b50a.entry.js → p-f516f183.entry.js} +3 -3
- package/dist/solutions-components/solutions-components.esm.js +1 -1
- package/dist/solutions-components/utils/downloadUtils.ts +93 -26
- package/dist/solutions-components/utils/interfaces.ts +2 -2
- package/dist/types/components/map-draw-tools/map-draw-tools.d.ts +6 -0
- package/dist/types/components/map-select-tools/map-select-tools.d.ts +5 -0
- package/dist/types/components/public-notification/public-notification.d.ts +29 -11
- package/dist/types/components.d.ts +8 -0
- package/dist/types/utils/downloadUtils.d.ts +22 -8
- package/dist/types/utils/interfaces.d.ts +2 -2
- package/package.json +2 -2
- package/dist/solutions-components/p-6f27bea2.entry.js +0 -17
- package/dist/solutions-components/p-db82a9ce.entry.js +0 -6
- package/dist/solutions-components/p-deb90ce7.entry.js +0 -6
@@ -24,8 +24,14 @@ 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";
|
28
|
+
import { getAssetPath } from "@stencil/core";
|
27
29
|
export class PublicNotification {
|
28
30
|
constructor() {
|
31
|
+
/**
|
32
|
+
* string: The url to the onboarding image
|
33
|
+
*/
|
34
|
+
this._onboardingImageUrl = "";
|
29
35
|
/**
|
30
36
|
* number: The number of selected features
|
31
37
|
*/
|
@@ -51,6 +57,7 @@ export class PublicNotification {
|
|
51
57
|
this._addTitle = false;
|
52
58
|
this._downloadActive = true;
|
53
59
|
this._exportType = EExportType.PDF;
|
60
|
+
this._numDuplicates = 0;
|
54
61
|
this._pageType = EPageType.LIST;
|
55
62
|
this._saveEnabled = false;
|
56
63
|
this._selectionSets = [];
|
@@ -117,6 +124,9 @@ export class PublicNotification {
|
|
117
124
|
if ((_a = this.mapView) === null || _a === void 0 ? void 0 : _a.popup) {
|
118
125
|
this.mapView.popup.autoOpenEnabled = pageType !== EPageType.LIST ? false : this._popupsEnabled;
|
119
126
|
}
|
127
|
+
if (pageType === EPageType.EXPORT) {
|
128
|
+
this._numDuplicates = await this._getNumDuplicates();
|
129
|
+
}
|
120
130
|
this._clearHighlight();
|
121
131
|
if (oldPageType === EPageType.SELECT || oldPageType === EPageType.REFINE) {
|
122
132
|
// clear any draw shapes or buffers
|
@@ -144,6 +154,7 @@ export class PublicNotification {
|
|
144
154
|
await this._getTranslations();
|
145
155
|
await this._initModules();
|
146
156
|
this._initSymbols();
|
157
|
+
this._onboardingImageUrl = getAssetPath(`../assets/data/images/onboarding.png`);
|
147
158
|
}
|
148
159
|
/**
|
149
160
|
* Renders the component.
|
@@ -302,7 +313,16 @@ export class PublicNotification {
|
|
302
313
|
*/
|
303
314
|
_getListPage() {
|
304
315
|
const hasSets = this._hasSelections();
|
305
|
-
return (h("calcite-panel", null, this._getLabel(this._translations.myLists), this._getNotice(hasSets ? this._translations.listHasSetsTip : this._translations.selectLayerAndAdd, "padding-sides-1 padding-bottom-1"), hasSets ? this._getSelectionSetList() : (
|
316
|
+
return (h("calcite-panel", null, this._getLabel(this._translations.myLists), this._getNotice(hasSets ? this._translations.listHasSetsTip : this._translations.selectLayerAndAdd, "padding-sides-1 padding-bottom-1"), hasSets ? this._getSelectionSetList() : (this._getOnboardingImage()), h("div", { class: "display-flex padding-1" }, h("calcite-button", { onClick: () => { this._setPageType(EPageType.SELECT); }, width: "full" }, this._translations.add))));
|
317
|
+
}
|
318
|
+
/**
|
319
|
+
* Display an image to help illustrate the basic workflow of the widget
|
320
|
+
*
|
321
|
+
* @returns the image node to display
|
322
|
+
* @protected
|
323
|
+
*/
|
324
|
+
_getOnboardingImage() {
|
325
|
+
return (h("div", { class: "display-flex padding-sides-1" }, h("img", { class: "img-container", src: this._onboardingImageUrl })));
|
306
326
|
}
|
307
327
|
/**
|
308
328
|
* Create the selection sets list node for the List page
|
@@ -324,7 +344,7 @@ export class PublicNotification {
|
|
324
344
|
validSet = numIds > 0;
|
325
345
|
}
|
326
346
|
if (validSet) {
|
327
|
-
prev.push((h("calcite-list-item", {
|
347
|
+
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
348
|
}
|
329
349
|
return prev;
|
330
350
|
}, []))));
|
@@ -360,39 +380,67 @@ export class PublicNotification {
|
|
360
380
|
return validateRefineSet && hasRefineSet ? ids.length > 0 || this._selectionSets.length > 1 : this._selectionSets.length > 0;
|
361
381
|
}
|
362
382
|
/**
|
363
|
-
* Check if any
|
383
|
+
* Check if any duplicate labels exist
|
364
384
|
*
|
365
385
|
* @returns true if duplicates are found
|
366
386
|
*
|
367
387
|
* @protected
|
368
388
|
*/
|
369
|
-
|
370
|
-
const
|
371
|
-
|
389
|
+
async _getNumDuplicates() {
|
390
|
+
const exportInfos = this._getExportInfos();
|
391
|
+
const labels = await consolidateLabels(exportInfos);
|
392
|
+
const duplicatesRemoved = removeDuplicateLabels(labels);
|
393
|
+
return labels.length - duplicatesRemoved.length;
|
372
394
|
}
|
373
395
|
/**
|
374
|
-
*
|
375
|
-
*
|
376
|
-
* @param ids the list of currently selected ids
|
396
|
+
* Get key details about what to export
|
377
397
|
*
|
378
|
-
* @returns
|
398
|
+
* @returns IExportInfos that contain ids and layer
|
379
399
|
*
|
380
400
|
* @protected
|
381
401
|
*/
|
382
|
-
|
383
|
-
return
|
402
|
+
_getExportInfos() {
|
403
|
+
return this._selectionSets.reduce((prev, cur) => {
|
404
|
+
if (cur.download) {
|
405
|
+
if (cur.workflowType !== EWorkflowType.REFINE) {
|
406
|
+
const id = cur.layerView.layer.id;
|
407
|
+
this._updateIds(id, cur.layerView, cur.selectedIds, prev);
|
408
|
+
}
|
409
|
+
else {
|
410
|
+
// REFINE stores ids differently as it can contain ids from multiple layers
|
411
|
+
// REFINE will only ever be 1 ISelectionSet
|
412
|
+
Object.keys(cur.refineInfos).forEach(k => {
|
413
|
+
const refineIds = cur.refineInfos[k];
|
414
|
+
this._updateIds(k, refineIds.layerView, refineIds.addIds, prev);
|
415
|
+
});
|
416
|
+
}
|
417
|
+
}
|
418
|
+
return prev;
|
419
|
+
}, {});
|
384
420
|
}
|
385
421
|
/**
|
386
|
-
*
|
422
|
+
* Consolidate ids for each layer
|
423
|
+
*
|
424
|
+
* @param id the layer id from the selectionSet
|
425
|
+
* @param layerView the layerView from the selectionSet
|
426
|
+
* @param ids the selectedIds from the selectionSet
|
427
|
+
* @param obj the object that will store the consolidated ids and layer info
|
387
428
|
*
|
388
|
-
* @returns
|
429
|
+
* @returns IExportInfo key details that will be used for export
|
389
430
|
*
|
390
431
|
* @protected
|
391
432
|
*/
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
}
|
433
|
+
_updateIds(id, layerView, ids, obj) {
|
434
|
+
if (obj[id]) {
|
435
|
+
obj[id].ids = obj[id].ids.concat(ids);
|
436
|
+
}
|
437
|
+
else {
|
438
|
+
obj[id] = {
|
439
|
+
layerView,
|
440
|
+
ids
|
441
|
+
};
|
442
|
+
}
|
443
|
+
return obj;
|
396
444
|
}
|
397
445
|
/**
|
398
446
|
* Create the Select page that shows the selection workflows
|
@@ -402,7 +450,7 @@ export class PublicNotification {
|
|
402
450
|
*/
|
403
451
|
_getSelectPage() {
|
404
452
|
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.
|
453
|
+
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
454
|
}
|
407
455
|
/**
|
408
456
|
* Create the main download page that has the shared aspects of both PDF and CSV
|
@@ -413,8 +461,8 @@ export class PublicNotification {
|
|
413
461
|
*/
|
414
462
|
_getExportPage() {
|
415
463
|
const hasSelections = this._hasSelections(this.showRefineSelection);
|
416
|
-
const
|
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}}",
|
464
|
+
const displayDuplicatesClass = this._numDuplicates > 0 ? "display-block" : "display-none";
|
465
|
+
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
466
|
}
|
419
467
|
/**
|
420
468
|
* Store the user selected export type CSV || PDF
|
@@ -494,13 +542,14 @@ export class PublicNotification {
|
|
494
542
|
*/
|
495
543
|
_getExportSelectionLists() {
|
496
544
|
return this._selectionSets.reduce((prev, cur) => {
|
545
|
+
var _a;
|
497
546
|
const ids = this._getSelectionSetIds(cur);
|
498
547
|
const validSet = cur.workflowType !== EWorkflowType.REFINE || ids.length > 0;
|
499
548
|
if (!this._downloadActive && cur.download && validSet) {
|
500
549
|
this._downloadActive = true;
|
501
550
|
}
|
502
551
|
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", {
|
552
|
+
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
553
|
}
|
505
554
|
return prev;
|
506
555
|
}, []) || (h("div", null));
|
@@ -520,6 +569,7 @@ export class PublicNotification {
|
|
520
569
|
return ss;
|
521
570
|
});
|
522
571
|
this._downloadActive = isActive;
|
572
|
+
this._numDuplicates = await this._getNumDuplicates();
|
523
573
|
await this._highlightFeatures();
|
524
574
|
}
|
525
575
|
/**
|
@@ -1087,6 +1137,7 @@ export class PublicNotification {
|
|
1087
1137
|
"_addTitle": {},
|
1088
1138
|
"_downloadActive": {},
|
1089
1139
|
"_exportType": {},
|
1140
|
+
"_numDuplicates": {},
|
1090
1141
|
"_pageType": {},
|
1091
1142
|
"_saveEnabled": {},
|
1092
1143
|
"_selectionSets": {},
|
@@ -55,12 +55,12 @@
|
|
55
55
|
|
56
56
|
<link
|
57
57
|
rel="stylesheet"
|
58
|
-
href="https://js.arcgis.com/4.
|
58
|
+
href="https://js.arcgis.com/4.27/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.
|
63
|
+
<script src="https://js.arcgis.com/4.27/"></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
|
-
//
|
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
|
-
//
|
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
|
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(
|
43
|
-
|
44
|
-
|
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
|
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(
|
60
|
-
let labels = await
|
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,
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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]:
|
440
|
+
[key: string]: IExportInfo;
|
441
441
|
}
|
442
442
|
|
443
|
-
export interface
|
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
|