@esri/solutions-components 0.5.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. package/dist/assets/arcgis-pdf-creator/PDFCreator.js +6 -3
  2. package/dist/assets/arcgis-pdf-creator/PDFCreator_jsPDF.js +1 -1
  3. package/dist/assets/arcgis-pdf-creator/PDFCreator_pdf_lib.js +1 -1
  4. package/dist/assets/arcgis-pdf-creator/PDFLabels.js +54 -3
  5. package/dist/assets/arcgis-pdf-creator/grid.js +1 -1
  6. package/dist/assets/data/images/grid.png +0 -0
  7. package/dist/assets/data/images/horizontal.png +0 -0
  8. package/dist/assets/data/images/vertical.png +0 -0
  9. package/dist/assets/t9n/crowdsource-manager/resources.json +7 -1
  10. package/dist/assets/t9n/crowdsource-manager/resources_en.json +7 -1
  11. package/dist/cjs/buffer-tools_6.cjs.entry.js +88 -92
  12. package/dist/cjs/{calcite-block_2.cjs.entry.js → calcite-action-bar_4.cjs.entry.js} +307 -18
  13. package/dist/cjs/{calcite-action.cjs.entry.js → calcite-action_2.cjs.entry.js} +84 -1
  14. package/dist/cjs/{calcite-combobox_3.cjs.entry.js → calcite-chip_4.cjs.entry.js} +131 -5
  15. package/dist/cjs/{calcite-dropdown-group_4.cjs.entry.js → calcite-dropdown_5.cjs.entry.js} +467 -1
  16. package/dist/cjs/calcite-input-message_5.cjs.entry.js +19 -17
  17. package/dist/cjs/calcite-shell-panel_14.cjs.entry.js +2 -2
  18. package/dist/cjs/{calcite-action-bar_2.cjs.entry.js → calcite-tooltip.cjs.entry.js} +2 -208
  19. package/dist/cjs/crowdsource-manager.cjs.entry.js +88 -14
  20. package/dist/cjs/{downloadUtils-415ab342.js → downloadUtils-9359e9ff.js} +135 -44
  21. package/dist/cjs/{index.es-98008aa0.js → index.es-9c0d0ed6.js} +3 -3
  22. package/dist/cjs/{interfaces-17c631bf.js → interfaces-cac36920.js} +6 -0
  23. package/dist/cjs/layer-table_2.cjs.entry.js +512 -0
  24. package/dist/cjs/loader.cjs.js +1 -1
  25. package/dist/cjs/{mapViewUtils-f617ae9a.js → mapViewUtils-090f4d4d.js} +3 -3
  26. package/dist/cjs/public-notification.cjs.entry.js +173 -48
  27. package/dist/cjs/solution-configuration.cjs.entry.js +2 -2
  28. package/dist/cjs/solution-contents_3.cjs.entry.js +2 -2
  29. package/dist/cjs/{solution-store-b86759b2.js → solution-store-d28c332e.js} +1 -1
  30. package/dist/cjs/solutions-components.cjs.js +1 -1
  31. package/dist/collection/assets/arcgis-pdf-creator/PDFCreator.js +6 -3
  32. package/dist/collection/assets/arcgis-pdf-creator/PDFCreator_jsPDF.js +1 -1
  33. package/dist/collection/assets/arcgis-pdf-creator/PDFCreator_pdf_lib.js +1 -1
  34. package/dist/collection/assets/arcgis-pdf-creator/PDFLabels.js +54 -3
  35. package/dist/collection/assets/arcgis-pdf-creator/grid.js +1 -1
  36. package/dist/collection/components/crowdsource-manager/crowdsource-manager.css +122 -0
  37. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +130 -14
  38. package/dist/collection/components/layer-table/layer-table.css +2 -70
  39. package/dist/collection/components/layer-table/layer-table.js +66 -106
  40. package/dist/collection/components/map-card/map-card.css +4 -7
  41. package/dist/collection/components/map-card/map-card.js +44 -10
  42. package/dist/collection/components/map-draw-tools/map-draw-tools.js +4 -8
  43. package/dist/collection/components/map-select-tools/map-select-tools.js +75 -15
  44. package/dist/collection/components/public-notification/public-notification.js +217 -25
  45. package/dist/collection/components/refine-selection-tools/refine-selection-tools.js +1 -1
  46. package/dist/collection/demos/crowdsource-manager.html +14 -41
  47. package/dist/collection/utils/csvDownload.js +41 -0
  48. package/dist/collection/utils/csvDownload.ts +42 -0
  49. package/dist/collection/utils/csvUtils.js +6 -23
  50. package/dist/collection/utils/csvUtils.ts +8 -27
  51. package/dist/collection/utils/downloadUtils.js +30 -14
  52. package/dist/collection/utils/downloadUtils.ts +36 -14
  53. package/dist/collection/utils/interfaces.js +6 -0
  54. package/dist/collection/utils/interfaces.ts +6 -0
  55. package/dist/collection/utils/pdfUtils.js +9 -6
  56. package/dist/collection/utils/pdfUtils.ts +13 -8
  57. package/dist/collection/utils/queryUtils.js +2 -2
  58. package/dist/collection/utils/queryUtils.ts +2 -2
  59. package/dist/collection/utils/test/csvUtils.spec.tsx +56 -0
  60. package/dist/collection/utils/test/downloadUtils.spec.tsx +133 -0
  61. package/dist/components/crowdsource-manager.js +293 -17
  62. package/dist/components/downloadUtils.js +133 -42
  63. package/dist/components/interfaces3.js +7 -1
  64. package/dist/components/layer-table.js +1 -443
  65. package/dist/components/layer-table2.js +429 -0
  66. package/dist/components/map-card.js +1 -339
  67. package/dist/{esm/map-card.entry.js → components/map-card2.js} +118 -22
  68. package/dist/components/map-draw-tools2.js +19 -23
  69. package/dist/components/map-layer-picker2.js +1 -1
  70. package/dist/components/map-select-tools2.js +21 -16
  71. package/dist/components/public-notification.js +209 -81
  72. package/dist/components/queryUtils.js +2 -2
  73. package/dist/components/refine-selection-tools2.js +3 -3
  74. package/dist/components/refine-selection2.js +1 -1
  75. package/dist/components/solution-resource-item2.js +1 -1
  76. package/dist/components/solution-store.js +1 -1
  77. package/dist/esm/buffer-tools_6.entry.js +79 -83
  78. package/dist/esm/{calcite-block_2.entry.js → calcite-action-bar_4.entry.js} +307 -20
  79. package/dist/esm/{calcite-action.entry.js → calcite-action_2.entry.js} +84 -2
  80. package/dist/esm/{calcite-combobox_3.entry.js → calcite-chip_4.entry.js} +134 -9
  81. package/dist/esm/{calcite-dropdown-group_4.entry.js → calcite-dropdown_5.entry.js} +468 -3
  82. package/dist/esm/calcite-input-message_5.entry.js +19 -17
  83. package/dist/esm/calcite-shell-panel_14.entry.js +2 -2
  84. package/dist/esm/{calcite-action-bar_2.entry.js → calcite-tooltip.entry.js} +4 -209
  85. package/dist/esm/crowdsource-manager.entry.js +88 -14
  86. package/dist/esm/{downloadUtils-606b0f0e.js → downloadUtils-a8f139c5.js} +135 -44
  87. package/dist/esm/{index.es-c736c805.js → index.es-a75412ff.js} +3 -3
  88. package/dist/esm/{interfaces-d0d83efa.js → interfaces-cd4054e5.js} +7 -1
  89. package/dist/esm/layer-table_2.entry.js +507 -0
  90. package/dist/esm/loader.js +1 -1
  91. package/dist/esm/{mapViewUtils-4e945e07.js → mapViewUtils-8ffcd36d.js} +4 -4
  92. package/dist/esm/public-notification.entry.js +169 -44
  93. package/dist/esm/solution-configuration.entry.js +2 -2
  94. package/dist/esm/solution-contents_3.entry.js +2 -2
  95. package/dist/esm/{solution-store-477288ac.js → solution-store-1b67f2c8.js} +1 -1
  96. package/dist/esm/solutions-components.js +1 -1
  97. package/dist/solutions-components/demos/crowdsource-manager.html +14 -41
  98. package/dist/solutions-components/{p-dd11eeb2.js → p-1395b0ef.js} +1 -1
  99. package/dist/solutions-components/{p-4f5641b4.entry.js → p-1affd711.entry.js} +18 -18
  100. package/dist/solutions-components/p-30de8da1.entry.js +17 -0
  101. package/dist/solutions-components/{p-91cad71e.entry.js → p-439c878d.entry.js} +3 -9
  102. package/dist/solutions-components/{p-72117a18.js → p-765a27f3.js} +1 -1
  103. package/dist/solutions-components/p-813a04c3.entry.js +6 -0
  104. package/dist/solutions-components/{p-9e8a371f.entry.js → p-874b39a7.entry.js} +3 -3
  105. package/dist/solutions-components/p-8cece97f.js +21 -0
  106. package/dist/solutions-components/{p-dd0241fb.entry.js → p-97aa7211.entry.js} +1 -1
  107. package/dist/solutions-components/{p-0e459cc7.entry.js → p-a955a3e6.entry.js} +10 -4
  108. package/dist/solutions-components/{p-6a657ff6.js → p-bb64bd47.js} +25 -9
  109. package/dist/solutions-components/p-c392dd95.entry.js +17 -0
  110. package/dist/solutions-components/p-ca386a72.entry.js +6 -0
  111. package/dist/solutions-components/p-d47d74a6.entry.js +23 -0
  112. package/dist/solutions-components/p-db846ee2.entry.js +11 -0
  113. package/dist/solutions-components/p-dc53c9c1.js +36 -0
  114. package/dist/solutions-components/p-e1c93241.entry.js +6 -0
  115. package/dist/solutions-components/{p-4cbaf0f1.entry.js → p-e6d235d6.entry.js} +1 -1
  116. package/dist/solutions-components/solutions-components.esm.js +6 -6
  117. package/dist/solutions-components/utils/csvDownload.ts +42 -0
  118. package/dist/solutions-components/utils/csvUtils.ts +8 -27
  119. package/dist/solutions-components/utils/downloadUtils.ts +36 -14
  120. package/dist/solutions-components/utils/interfaces.ts +6 -0
  121. package/dist/solutions-components/utils/pdfUtils.ts +13 -8
  122. package/dist/solutions-components/utils/queryUtils.ts +2 -2
  123. package/dist/solutions-components/utils/test/csvUtils.spec.tsx +56 -0
  124. package/dist/solutions-components/utils/test/downloadUtils.spec.tsx +133 -0
  125. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +39 -0
  126. package/dist/types/components/layer-table/layer-table.d.ts +35 -48
  127. package/dist/types/components/map-card/map-card.d.ts +10 -6
  128. package/dist/types/components/map-select-tools/map-select-tools.d.ts +16 -1
  129. package/dist/types/components/public-notification/public-notification.d.ts +86 -4
  130. package/dist/types/components.d.ts +68 -0
  131. package/dist/types/preact.d.ts +2 -1
  132. package/dist/types/utils/csvDownload.d.ts +24 -0
  133. package/dist/types/utils/csvUtils.d.ts +2 -1
  134. package/dist/types/utils/downloadUtils.d.ts +25 -0
  135. package/dist/types/utils/interfaces.d.ts +5 -0
  136. package/dist/types/utils/pdfUtils.d.ts +2 -1
  137. package/package.json +4 -4
  138. package/dist/cjs/calcite-chip.cjs.entry.js +0 -142
  139. package/dist/cjs/calcite-dropdown.cjs.entry.js +0 -481
  140. package/dist/cjs/calcite-handle.cjs.entry.js +0 -99
  141. package/dist/cjs/calcite-loader.cjs.entry.js +0 -95
  142. package/dist/cjs/layer-table.cjs.entry.js +0 -317
  143. package/dist/cjs/map-card.cjs.entry.js +0 -252
  144. package/dist/esm/calcite-chip.entry.js +0 -138
  145. package/dist/esm/calcite-dropdown.entry.js +0 -477
  146. package/dist/esm/calcite-handle.entry.js +0 -95
  147. package/dist/esm/calcite-loader.entry.js +0 -91
  148. package/dist/esm/layer-table.entry.js +0 -313
  149. package/dist/solutions-components/p-11132485.entry.js +0 -11
  150. package/dist/solutions-components/p-15b43c29.entry.js +0 -11
  151. package/dist/solutions-components/p-5034aabc.entry.js +0 -11
  152. package/dist/solutions-components/p-5ee7b022.entry.js +0 -12
  153. package/dist/solutions-components/p-6f012424.entry.js +0 -6
  154. package/dist/solutions-components/p-7fd10eb3.entry.js +0 -11
  155. package/dist/solutions-components/p-84bbaebf.entry.js +0 -6
  156. package/dist/solutions-components/p-88e28de2.js +0 -36
  157. package/dist/solutions-components/p-a57ef371.entry.js +0 -6
  158. package/dist/solutions-components/p-ac76d270.entry.js +0 -17
  159. package/dist/solutions-components/p-dbc9a5a8.js +0 -21
  160. package/dist/solutions-components/p-e162304e.entry.js +0 -6
  161. package/dist/solutions-components/p-f5c70be2.entry.js +0 -6
  162. package/dist/solutions-components/p-f6b17cc6.entry.js +0 -11
@@ -0,0 +1,42 @@
1
+ /** @license
2
+ * Copyright 2022 Esri
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ //#region Public functions
18
+
19
+ /**
20
+ * Download the CSV file
21
+ *
22
+ * @param title Title (without file extension) to use for file; defaults to "export"
23
+ * @param outputLines Lines of output to write to file
24
+ *
25
+ * @see {@link https://medium.com/@danny.pule/export-json-to-csv-file-using-javascript-a0b7bc5b00d2}
26
+ */
27
+ export function downloadCSVFile(
28
+ title: string,
29
+ outputLines: string[]
30
+ ): void {
31
+ const link = document.createElement("a");
32
+ if (link.download !== undefined) {
33
+ link.href = URL.createObjectURL(new Blob(outputLines, { type: "text/csv;charset=utf-8;" }));
34
+ link.download = `${title}.csv` || "export.csv";
35
+ link.style.visibility = "hidden";
36
+ document.body.appendChild(link);
37
+ link.click();
38
+ document.body.removeChild(link);
39
+ }
40
+ }
41
+
42
+ //#endregion
@@ -18,37 +18,20 @@
18
18
  * See the License for the specific language governing permissions and
19
19
  * limitations under the License.
20
20
  */
21
+ //#region Declarations
22
+ import * as csvDownload from "./csvDownload";
23
+ //#endregion
21
24
  //#region Public functions
22
25
  /**
23
26
  * Export a csv of the attributes from the features that match the provided ids
24
27
  *
28
+ * @param title Title to use for file
25
29
  * @param labels Labels to write
26
30
  */
27
- export function exportCSV(labels) {
31
+ export function exportCSV(title, labels) {
28
32
  // Format values to string so it doesn't get tripped up when a value has a comma
29
33
  // another option could be to export with a different delimiter
30
34
  const outputLines = labels.map(label => Object.values(label).map(v => `"${v}"`).join(",") + "\r\n");
31
- _downloadCSVFile(outputLines, `notify-${Date.now().toString()}`);
32
- }
33
- //#endregion
34
- //#region Private functions
35
- /**
36
- * Download the CSV file
37
- *
38
- * @param outputLines Lines of output to write to file
39
- * @param fileTitle Title (without file extension) to use for file; defaults to "export"
40
- *
41
- * @see {@link https://medium.com/@danny.pule/export-json-to-csv-file-using-javascript-a0b7bc5b00d2}
42
- */
43
- function _downloadCSVFile(outputLines, fileTitle) {
44
- const link = document.createElement("a");
45
- if (link.download !== undefined) {
46
- link.href = URL.createObjectURL(new Blob(outputLines, { type: "text/csv;charset=utf-8;" }));
47
- link.download = `${fileTitle}.csv` || "export.csv";
48
- link.style.visibility = "hidden";
49
- document.body.appendChild(link);
50
- link.click();
51
- document.body.removeChild(link);
52
- }
35
+ csvDownload.downloadCSVFile(title, outputLines);
53
36
  }
54
37
  //#endregion
@@ -14,47 +14,28 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ //#region Declarations
18
+
19
+ import * as csvDownload from "./csvDownload";
20
+
21
+ //#endregion
17
22
  //#region Public functions
18
23
 
19
24
  /**
20
25
  * Export a csv of the attributes from the features that match the provided ids
21
26
  *
27
+ * @param title Title to use for file
22
28
  * @param labels Labels to write
23
29
  */
24
30
  export function exportCSV(
31
+ title: string,
25
32
  labels: string[][],
26
33
  ): void {
27
34
  // Format values to string so it doesn't get tripped up when a value has a comma
28
35
  // another option could be to export with a different delimiter
29
36
  const outputLines = labels.map(label => Object.values(label).map(v => `"${v}"`).join(",") + "\r\n");
30
37
 
31
- _downloadCSVFile(outputLines, `notify-${Date.now().toString()}`);
32
- }
33
-
34
- //#endregion
35
- //#region Private functions
36
-
37
- /**
38
- * Download the CSV file
39
- *
40
- * @param outputLines Lines of output to write to file
41
- * @param fileTitle Title (without file extension) to use for file; defaults to "export"
42
- *
43
- * @see {@link https://medium.com/@danny.pule/export-json-to-csv-file-using-javascript-a0b7bc5b00d2}
44
- */
45
- function _downloadCSVFile(
46
- outputLines: string[],
47
- fileTitle: string
48
- ): void {
49
- const link = document.createElement("a");
50
- if (link.download !== undefined) {
51
- link.href = URL.createObjectURL(new Blob(outputLines, { type: "text/csv;charset=utf-8;" }));
52
- link.download = `${fileTitle}.csv` || "export.csv";
53
- link.style.visibility = "hidden";
54
- document.body.appendChild(link);
55
- link.click();
56
- document.body.removeChild(link);
57
- }
38
+ csvDownload.downloadCSVFile(title, outputLines);
58
39
  }
59
40
 
60
41
  //#endregion
@@ -40,10 +40,8 @@ const lineSeparatorChar = "|";
40
40
  * @returns Promise resolving when function is done
41
41
  */
42
42
  export async function downloadCSV(selectionSetNames, layer, ids, formatUsingLayerPopup, removeDuplicates = false, addColumnTitle = false) {
43
- console.log("downloadCSV using selectionSetNames " + JSON.stringify(selectionSetNames)); //???
44
- console.log("downloadCSV removeDuplicates", removeDuplicates); //???
45
43
  const labels = await _prepareLabels(layer, ids, removeDuplicates, formatUsingLayerPopup, addColumnTitle);
46
- exportCSV(labels);
44
+ exportCSV(_createTitle(selectionSetNames), labels);
47
45
  return Promise.resolve();
48
46
  }
49
47
  /**
@@ -57,15 +55,13 @@ export async function downloadCSV(selectionSetNames, layer, ids, formatUsingLaye
57
55
  * @returns Promise resolving when function is done
58
56
  */
59
57
  export async function downloadPDF(selectionSetNames, layer, ids, removeDuplicates, labelPageDescription) {
60
- console.log("downloadPDF using selectionSetNames " + JSON.stringify(selectionSetNames)); //???
61
- console.log("downloadPDF removeDuplicates", removeDuplicates); //???
62
58
  let labels = await _prepareLabels(layer, ids, removeDuplicates);
63
59
  labels =
64
60
  // Remove empty lines in labels
65
61
  labels.map(labelLines => labelLines.filter(line => line.length > 0))
66
62
  // Remove empty labels
67
63
  .filter(label => label.length > 0);
68
- exportPDF(labels, labelPageDescription);
64
+ exportPDF(_createTitle(selectionSetNames), labels, labelPageDescription);
69
65
  return Promise.resolve();
70
66
  }
71
67
  //#endregion
@@ -77,7 +73,7 @@ export async function downloadPDF(selectionSetNames, layer, ids, removeDuplicate
77
73
  * @param bypassFieldVisiblity Indicates if the configured fieldInfo visibility property should be ignored
78
74
  * @return Label spec with lines separated by `lineSeparatorChar`
79
75
  */
80
- function _convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity = false) {
76
+ export function _convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity = false) {
81
77
  const labelSpec = [];
82
78
  // Every visible attribute is used
83
79
  fieldInfos.forEach(fieldInfo => {
@@ -96,24 +92,32 @@ function _convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity = false
96
92
  * "<div style='text-align: left;'>{NAME}<br />{STREET}<br />{CITY}, {STATE} {ZIP} <br /></div>"
97
93
  * @return Label spec with lines separated by `lineSeparatorChar`
98
94
  */
99
- function _convertPopupTextToLabelSpec(popupInfo) {
95
+ export function _convertPopupTextToLabelSpec(popupInfo) {
100
96
  // Replace <br> variants with the line separator character
101
97
  popupInfo = popupInfo.replace(/<br\s*\/?>/gi, lineSeparatorChar);
102
98
  // Replace <p> variants with the line separator character, except in the first position
103
99
  popupInfo = popupInfo.replace(/<p[^>]*>/gi, lineSeparatorChar).trim().replace(/^\|/, "");
104
100
  // Remove </p>
105
101
  popupInfo = popupInfo.replace(/<\/p>/gi, "");
106
- // Remove \n
107
- popupInfo = popupInfo.replace(/\n/gi, "");
108
- // Remove remaining HTML tags, replace 0xA0 that popup uses for spaces, and replace some char representations,
109
- // and split the label back into individual lines
110
- const labelSpec = popupInfo
102
+ // Replace \n with the line separator character
103
+ popupInfo = popupInfo.replace(/\n/gi, "|");
104
+ // Remove remaining HTML tags, replace 0xA0 that popup uses for spaces, and replace some char representations
105
+ let labelSpec = popupInfo
111
106
  .replace(/<[\s.]*[^<>]*\/?>/gi, "")
112
107
  .replace(/\xA0/gi, " ")
113
108
  .replace(/&lt;/gi, "<")
114
109
  .replace(/&gt;/gi, ">")
115
110
  .replace(/&nbsp;/gi, " ");
116
- return labelSpec;
111
+ // Trim each line
112
+ labelSpec = labelSpec.replace(/\s*\|\s*/g, "|");
113
+ // Remove empty lines
114
+ while (labelSpec.match(/\|\|/)) {
115
+ labelSpec = labelSpec.replace(/\|\|/, "|");
116
+ }
117
+ // Remove leading and trailing line feeds
118
+ labelSpec = labelSpec.replace(/^\|/, "");
119
+ labelSpec = labelSpec.replace(/\|$/, "");
120
+ return labelSpec.trim();
117
121
  }
118
122
  ;
119
123
  /**
@@ -178,6 +182,18 @@ async function _createArcadeExecutors(labelFormat, layer) {
178
182
  return arcadeExecutors;
179
183
  });
180
184
  }
185
+ /**
186
+ * Creates a title from a list of selection set names.
187
+ *
188
+ * @param selectionSetNames Names to use in title
189
+ * @return Title composed of the selectionSetNames separated by commas; if there are no
190
+ * selection set names supplied, "download" is returned
191
+ */
192
+ export function _createTitle(selectionSetNames) {
193
+ // Windows doesn't permit the characters \/:*?"<>|
194
+ const title = selectionSetNames.length > 0 ? selectionSetNames.join(", ") : "download";
195
+ return title;
196
+ }
181
197
  /**
182
198
  * Prepares an attribute's value by applying domain and type information.
183
199
  *
@@ -68,11 +68,9 @@ export async function downloadCSV(
68
68
  removeDuplicates = false,
69
69
  addColumnTitle = false
70
70
  ): Promise<void> {
71
- console.log("downloadCSV using selectionSetNames " + JSON.stringify(selectionSetNames));//???
72
- console.log("downloadCSV removeDuplicates", removeDuplicates);//???
73
71
  const labels = await _prepareLabels(layer, ids, removeDuplicates, formatUsingLayerPopup, addColumnTitle);
74
72
 
75
- exportCSV(labels);
73
+ exportCSV(_createTitle(selectionSetNames), labels);
76
74
 
77
75
  return Promise.resolve();
78
76
  }
@@ -94,8 +92,6 @@ export async function downloadPDF(
94
92
  removeDuplicates: boolean,
95
93
  labelPageDescription: ILabel
96
94
  ): Promise<void> {
97
- console.log("downloadPDF using selectionSetNames " + JSON.stringify(selectionSetNames));//???
98
- console.log("downloadPDF removeDuplicates", removeDuplicates);//???
99
95
  let labels = await _prepareLabels(layer, ids, removeDuplicates);
100
96
 
101
97
  labels =
@@ -104,7 +100,7 @@ export async function downloadPDF(
104
100
  // Remove empty labels
105
101
  .filter(label => label.length > 0);
106
102
 
107
- exportPDF(labels, labelPageDescription);
103
+ exportPDF(_createTitle(selectionSetNames), labels, labelPageDescription);
108
104
 
109
105
  return Promise.resolve();
110
106
  }
@@ -119,7 +115,7 @@ export async function downloadPDF(
119
115
  * @param bypassFieldVisiblity Indicates if the configured fieldInfo visibility property should be ignored
120
116
  * @return Label spec with lines separated by `lineSeparatorChar`
121
117
  */
122
- function _convertPopupFieldsToLabelSpec(
118
+ export function _convertPopupFieldsToLabelSpec(
123
119
  fieldInfos: __esri.FieldInfo[],
124
120
  bypassFieldVisiblity = false
125
121
  ): string {
@@ -145,7 +141,7 @@ function _convertPopupFieldsToLabelSpec(
145
141
  * "<div style='text-align: left;'>{NAME}<br />{STREET}<br />{CITY}, {STATE} {ZIP} <br /></div>"
146
142
  * @return Label spec with lines separated by `lineSeparatorChar`
147
143
  */
148
- function _convertPopupTextToLabelSpec(
144
+ export function _convertPopupTextToLabelSpec(
149
145
  popupInfo: string,
150
146
  ): string {
151
147
  // Replace <br> variants with the line separator character
@@ -157,19 +153,30 @@ function _convertPopupTextToLabelSpec(
157
153
  // Remove </p>
158
154
  popupInfo = popupInfo.replace(/<\/p>/gi, "");
159
155
 
160
- // Remove \n
161
- popupInfo = popupInfo.replace(/\n/gi, "");
156
+ // Replace \n with the line separator character
157
+ popupInfo = popupInfo.replace(/\n/gi, "|");
162
158
 
163
- // Remove remaining HTML tags, replace 0xA0 that popup uses for spaces, and replace some char representations,
164
- // and split the label back into individual lines
165
- const labelSpec = popupInfo
159
+ // Remove remaining HTML tags, replace 0xA0 that popup uses for spaces, and replace some char representations
160
+ let labelSpec = popupInfo
166
161
  .replace(/<[\s.]*[^<>]*\/?>/gi, "")
167
162
  .replace(/\xA0/gi, " ")
168
163
  .replace(/&lt;/gi, "<")
169
164
  .replace(/&gt;/gi, ">")
170
165
  .replace(/&nbsp;/gi, " ");
171
166
 
172
- return labelSpec;
167
+ // Trim each line
168
+ labelSpec = labelSpec.replace(/\s*\|\s*/g, "|");
169
+
170
+ // Remove empty lines
171
+ while (labelSpec.match(/\|\|/)) {
172
+ labelSpec = labelSpec.replace(/\|\|/, "|");
173
+ }
174
+
175
+ // Remove leading and trailing line feeds
176
+ labelSpec = labelSpec.replace(/^\|/, "");
177
+ labelSpec = labelSpec.replace(/\|$/, "");
178
+
179
+ return labelSpec.trim();
173
180
  };
174
181
 
175
182
  /**
@@ -252,6 +259,21 @@ async function _createArcadeExecutors(
252
259
  );
253
260
  }
254
261
 
262
+ /**
263
+ * Creates a title from a list of selection set names.
264
+ *
265
+ * @param selectionSetNames Names to use in title
266
+ * @return Title composed of the selectionSetNames separated by commas; if there are no
267
+ * selection set names supplied, "download" is returned
268
+ */
269
+ export function _createTitle(
270
+ selectionSetNames: string[]
271
+ ): string {
272
+ // Windows doesn't permit the characters \/:*?"<>|
273
+ const title = selectionSetNames.length > 0 ? selectionSetNames.join(", ") : "download";
274
+ return title;
275
+ }
276
+
255
277
  /**
256
278
  * Prepares an attribute's value by applying domain and type information.
257
279
  *
@@ -18,6 +18,12 @@
18
18
  * See the License for the specific language governing permissions and
19
19
  * limitations under the License.
20
20
  */
21
+ export var ELayoutMode;
22
+ (function (ELayoutMode) {
23
+ ELayoutMode["GRID"] = "GRID";
24
+ ELayoutMode["HORIZONTAL"] = "HORIZONTAL";
25
+ ELayoutMode["VERTICAL"] = "VERTICAL";
26
+ })(ELayoutMode || (ELayoutMode = {}));
21
27
  /**
22
28
  * Resource update types
23
29
  */
@@ -19,6 +19,12 @@ import {
19
19
  IItemTemplate
20
20
  } from '@esri/solution-common';
21
21
 
22
+ export enum ELayoutMode {
23
+ GRID = "GRID",
24
+ HORIZONTAL = "HORIZONTAL",
25
+ VERTICAL = "VERTICAL"
26
+ }
27
+
22
28
  /**
23
29
  * Resource update types
24
30
  */
@@ -28,31 +28,34 @@ export { ILabel } from "../assets/arcgis-pdf-creator/PDFLabels";
28
28
  /**
29
29
  * Exports a PDF of labels.
30
30
  *
31
+ * @param title Title to use for file
31
32
  * @param labels Labels to write
32
33
  * @param labelPageDescription Page format to use for labels
33
34
  */
34
- export function exportPDF(labels, labelPageDescription) {
35
- _downloadPDFFile(labels, labelPageDescription, `notify-${Date.now().toString()}`);
35
+ export function exportPDF(title, labels, labelPageDescription) {
36
+ downloadPDFFile(title, labels, labelPageDescription);
36
37
  }
37
38
  //#endregion
38
39
  //#region Private functions
39
40
  /**
40
41
  * Downloads the PDF file.
41
42
  *
43
+ * @param title Title (without file extension) to use for file; defaults to "export"
42
44
  * @param labels Labels to write
43
45
  * @param labelPageDescription Page format to use for labels
44
- * @param fileTitle Title (without file extension) to use for file; defaults to "export"
45
46
  */
46
- function _downloadPDFFile(labels, labelPageDescription, fileTitle) {
47
+ function downloadPDFFile(title, labels, labelPageDescription) {
47
48
  const pdfLib = new PDFCreator_jsPDF.PDFCreator_jsPDF();
48
49
  pdfLib.initialize({
49
50
  pageType: "ANSI_A"
50
- }, getAssetPath(`../assets/arcgis-pdf-creator/`), "en", fileTitle, false)
51
+ }, getAssetPath(`../assets/arcgis-pdf-creator/`), "en", title)
51
52
  .then(() => {
52
53
  const labeller = new PDFLabels.PDFLabels();
53
54
  labeller.initialize(pdfLib)
54
55
  .then(async () => {
55
- await labeller.addLabelsToDoc(labels, labelPageDescription.labelSpec, 1);
56
+ await labeller.addLabelsToDoc(labels, labelPageDescription.labelSpec, 1, // startingPageNum
57
+ title // heading
58
+ );
56
59
  pdfLib.save();
57
60
  });
58
61
  });
@@ -27,14 +27,16 @@ export { ILabel } from "../assets/arcgis-pdf-creator/PDFLabels";
27
27
  /**
28
28
  * Exports a PDF of labels.
29
29
  *
30
+ * @param title Title to use for file
30
31
  * @param labels Labels to write
31
32
  * @param labelPageDescription Page format to use for labels
32
33
  */
33
34
  export function exportPDF(
35
+ title: string,
34
36
  labels: string[][],
35
37
  labelPageDescription: PDFLabels.ILabel
36
38
  ): void {
37
- _downloadPDFFile(labels, labelPageDescription, `notify-${Date.now().toString()}`);
39
+ downloadPDFFile(title, labels, labelPageDescription);
38
40
  }
39
41
 
40
42
  //#endregion
@@ -43,21 +45,23 @@ export function exportPDF(
43
45
  /**
44
46
  * Downloads the PDF file.
45
47
  *
48
+ * @param title Title (without file extension) to use for file; defaults to "export"
46
49
  * @param labels Labels to write
47
50
  * @param labelPageDescription Page format to use for labels
48
- * @param fileTitle Title (without file extension) to use for file; defaults to "export"
49
51
  */
50
- function _downloadPDFFile(
52
+ function downloadPDFFile(
53
+ title: string,
51
54
  labels: string[][],
52
- labelPageDescription: PDFLabels.ILabel,
53
- fileTitle: string
55
+ labelPageDescription: PDFLabels.ILabel
54
56
  ): void {
55
57
  const pdfLib = new PDFCreator_jsPDF.PDFCreator_jsPDF();
56
58
  pdfLib.initialize(
57
59
  {
58
60
  pageType: "ANSI_A"
59
- }, getAssetPath(`../assets/arcgis-pdf-creator/`), "en",
60
- fileTitle, false
61
+ },
62
+ getAssetPath(`../assets/arcgis-pdf-creator/`),
63
+ "en",
64
+ title
61
65
  )
62
66
  .then(
63
67
  () => {
@@ -68,7 +72,8 @@ function _downloadPDFFile(
68
72
  await labeller.addLabelsToDoc(
69
73
  labels,
70
74
  labelPageDescription.labelSpec,
71
- 1
75
+ 1, // startingPageNum
76
+ title // heading
72
77
  );
73
78
 
74
79
  pdfLib.save();
@@ -51,7 +51,7 @@ export async function queryAllFeatures(start, layer, graphics) {
51
51
  */
52
52
  export async function queryObjectIds(geometries, layer) {
53
53
  let ids = [];
54
- const queryDefs = geometries.map(g => _intersectQuery(g, layer));
54
+ const queryDefs = geometries ? geometries.map(g => _intersectQuery(g, layer)) : [Promise.resolve()];
55
55
  const results = await Promise.all(queryDefs);
56
56
  results.forEach(resultIds => {
57
57
  ids = [
@@ -157,7 +157,7 @@ export function getSelectionSetQuery(selectionSet, geometryEngine) {
157
157
  * @returns Array of single unioned geometry for the provided geometry type
158
158
  */
159
159
  function _unionGeoms(geometries, type, geometryEngine) {
160
- const geoms = geometries.filter(g => g.type === type);
160
+ const geoms = (geometries === null || geometries === void 0 ? void 0 : geometries.filter(g => g.type === type)) || [];
161
161
  return geoms.length <= 1 ? geoms : [geometryEngine.union(geoms)];
162
162
  }
163
163
  /**
@@ -61,7 +61,7 @@ export async function queryObjectIds(
61
61
  layer: __esri.FeatureLayer
62
62
  ): Promise<number[]> {
63
63
  let ids = [];
64
- const queryDefs = geometries.map(g => _intersectQuery(g, layer))
64
+ const queryDefs = geometries ? geometries.map(g => _intersectQuery(g, layer)) : [Promise.resolve()];
65
65
  const results = await Promise.all(queryDefs);
66
66
  results.forEach(resultIds => {
67
67
  ids = [
@@ -206,7 +206,7 @@ export function getSelectionSetQuery(
206
206
  type: string,
207
207
  geometryEngine: __esri.geometryEngine
208
208
  ): __esri.Geometry[] {
209
- const geoms = geometries.filter(g => g.type === type);
209
+ const geoms = geometries?.filter(g => g.type === type) || [];
210
210
  return geoms.length <= 1 ? geoms : [geometryEngine.union(geoms)];
211
211
  }
212
212
 
@@ -0,0 +1,56 @@
1
+ /** @license
2
+ * Copyright 2023 Esri
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import * as csvDownload from "../csvDownload";
18
+ import * as csvUtils from "../csvUtils";
19
+ import {expect, jest, test} from "@jest/globals";
20
+
21
+ afterEach(() => {
22
+ jest.restoreAllMocks();
23
+ });
24
+
25
+ describe("csvUtils", () => {
26
+
27
+ describe("exportCSV", () => {
28
+
29
+ it("prepares output lines 1", () => {
30
+ const title = "title";
31
+ const labels = [
32
+ ["Cyd Charise", "1922 Main St", "Amarillo, TX 79118"],
33
+ ["Fred Astaire", "1899 Main St", "Omaha, NE 68022"],
34
+ ["Gene Kelly", "1912 Main St", "Pittsburgh, PA 15215"],
35
+ ["Ginger Rogers", "1911 Main St", "Independence, MO 64050"]
36
+ ];
37
+ const expectedOutputLines = [
38
+ "\"Cyd Charise\",\"1922 Main St\",\"Amarillo, TX 79118\"\r\n",
39
+ "\"Fred Astaire\",\"1899 Main St\",\"Omaha, NE 68022\"\r\n",
40
+ "\"Gene Kelly\",\"1912 Main St\",\"Pittsburgh, PA 15215\"\r\n",
41
+ "\"Ginger Rogers\",\"1911 Main St\",\"Independence, MO 64050\"\r\n"
42
+ ];
43
+
44
+ const downloadCSVFileMock = jest.spyOn(csvDownload, "downloadCSVFile")
45
+ .mockImplementation(
46
+ (fileTitle: string, outputLines: string[]) => {}
47
+ );
48
+ csvUtils.exportCSV(title, labels);
49
+ expect(downloadCSVFileMock).toBeCalledTimes(1);
50
+ expect(downloadCSVFileMock.mock.calls[0][0]).toEqual(title);
51
+ expect(downloadCSVFileMock.mock.calls[0][1]).toEqual(expectedOutputLines);
52
+ });
53
+
54
+ });
55
+
56
+ });