@esri/solutions-components 0.5.3 → 0.5.4

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 (116) hide show
  1. package/dist/cjs/calcite-input-text_5.cjs.entry.js +36 -36
  2. package/dist/cjs/calcite-shell-panel_14.cjs.entry.js +1 -1
  3. package/dist/cjs/solution-configuration.cjs.entry.js +1 -1
  4. package/dist/cjs/solution-contents_3.cjs.entry.js +1 -1
  5. package/dist/cjs/{solution-store-70002b57.js → solution-store-ca4639d5.js} +3 -3
  6. package/dist/collection/components/add-record-modal/test/add-record-modal.e2e.js +24 -0
  7. package/dist/collection/components/add-record-modal/test/add-record-modal.spec.js +32 -0
  8. package/dist/collection/components/buffer-tools/test/buffer-tools.e2e.js +24 -0
  9. package/dist/collection/components/buffer-tools/test/buffer-tools.spec.js +157 -0
  10. package/dist/collection/components/card-manager/test/card-manager.e2e.js +24 -0
  11. package/dist/collection/components/card-manager/test/card-manager.spec.js +32 -0
  12. package/dist/collection/components/comment-card/test/comment-card.e2e.js +24 -0
  13. package/dist/collection/components/comment-card/test/comment-card.spec.js +32 -0
  14. package/dist/collection/components/crowdsource-manager/test/crowdsource-manager.e2e.js +24 -0
  15. package/dist/collection/components/crowdsource-manager/test/crowdsource-manager.spec.js +32 -0
  16. package/dist/collection/components/crowdsource-reporter/test/crowdsource-reporter.e2e.js +24 -0
  17. package/dist/collection/components/crowdsource-reporter/test/crowdsource-reporter.spec.js +32 -0
  18. package/dist/collection/components/deduct-calculator/test/deduct-calculator.e2e.js +24 -0
  19. package/dist/collection/components/deduct-calculator/test/deduct-calculator.spec.js +32 -0
  20. package/dist/collection/components/edit-record-modal/test/edit-record-modal.e2e.js +24 -0
  21. package/dist/collection/components/edit-record-modal/test/edit-record-modal.spec.js +32 -0
  22. package/dist/collection/components/info-card/test/info-card.e2e.js +24 -0
  23. package/dist/collection/components/info-card/test/info-card.spec.js +32 -0
  24. package/dist/collection/components/json-editor/test/json-editor.e2e.js +31 -0
  25. package/dist/collection/components/json-editor/test/json-editor.spec.js +60 -0
  26. package/dist/collection/components/layer-table/test/layer-table.e2e.js +24 -0
  27. package/dist/collection/components/layer-table/test/layer-table.spec.js +32 -0
  28. package/dist/collection/components/list-item/test/list-item.e2e.js +24 -0
  29. package/dist/collection/components/list-item/test/list-item.spec.js +32 -0
  30. package/dist/collection/components/map-card/test/map-card.e2e.js +24 -0
  31. package/dist/collection/components/map-card/test/map-card.spec.js +32 -0
  32. package/dist/collection/components/map-draw-tools/test/map-draw-tools.e2e.js +24 -0
  33. package/dist/collection/components/map-draw-tools/test/map-draw-tools.spec.js +32 -0
  34. package/dist/collection/components/map-layer-picker/test/map-layer-picker.e2e.js +24 -0
  35. package/dist/collection/components/map-layer-picker/test/map-layer-picker.spec.js +109 -0
  36. package/dist/collection/components/map-search/test/map-search.e2e.js +24 -0
  37. package/dist/collection/components/map-search/test/map-search.spec.js +53 -0
  38. package/dist/collection/components/map-select-tools/map-select-tools.js +36 -36
  39. package/dist/collection/components/map-select-tools/test/map-select-tools.e2e.js +24 -0
  40. package/dist/collection/components/map-select-tools/test/map-select-tools.spec.js +349 -0
  41. package/dist/collection/components/media-card/test/media-card.e2e.js +24 -0
  42. package/dist/collection/components/media-card/test/media-card.spec.js +32 -0
  43. package/dist/collection/components/pci-calculator/test/pci-calculator.e2e.js +24 -0
  44. package/dist/collection/components/pci-calculator/test/pci-calculator.spec.js +32 -0
  45. package/dist/collection/components/pdf-download/test/pdf-download.e2e.js +71 -0
  46. package/dist/collection/components/pdf-download/test/pdf-download.spec.js +104 -0
  47. package/dist/collection/components/public-notification/test/public-notification.e2e.js +95 -0
  48. package/dist/collection/components/public-notification/test/public-notification.spec.js +149 -0
  49. package/dist/collection/components/refine-selection/refine-selection.css +85 -85
  50. package/dist/collection/components/solution-configuration/test/solution-configuration.e2e.js +31 -0
  51. package/dist/collection/components/solution-configuration/test/solution-configuration.spec.js +114 -0
  52. package/dist/collection/components/solution-contents/test/solution-contents.e2e.js +89 -0
  53. package/dist/collection/components/solution-contents/test/solution-contents.spec.js +138 -0
  54. package/dist/collection/components/solution-item/test/solution-item.e2e.js +31 -0
  55. package/dist/collection/components/solution-item/test/solution-item.spec.js +72 -0
  56. package/dist/collection/components/solution-item-details/test/solution-item-details.e2e.js +31 -0
  57. package/dist/collection/components/solution-item-details/test/solution-item-details.spec.js +137 -0
  58. package/dist/collection/components/solution-item-icon/test/solution-item-icon.e2e.js +24 -0
  59. package/dist/collection/components/solution-item-icon/test/solution-item-icon.spec.js +34 -0
  60. package/dist/collection/components/solution-item-sharing/test/solution-item-sharing.e2e.js +31 -0
  61. package/dist/collection/components/solution-item-sharing/test/solution-item-sharing.spec.js +49 -0
  62. package/dist/collection/components/solution-organization-variables/test/solution-organization-variables.e2e.js +31 -0
  63. package/dist/collection/components/solution-organization-variables/test/solution-organization-variables.spec.js +60 -0
  64. package/dist/collection/components/solution-resource-item/test/solution-resource-item.e2e.js +31 -0
  65. package/dist/collection/components/solution-resource-item/test/solution-resource-item.spec.js +50 -0
  66. package/dist/collection/components/solution-spatial-ref/test/solution-spatial-ref.e2e.js +31 -0
  67. package/dist/collection/components/solution-spatial-ref/test/solution-spatial-ref.spec.js +170 -0
  68. package/dist/collection/components/solution-template-data/test/solution-template-data.e2e.js +31 -0
  69. package/dist/collection/components/solution-template-data/test/solution-template-data.spec.js +55 -0
  70. package/dist/collection/components/solution-variables/test/solution-variables.e2e.js +31 -0
  71. package/dist/collection/components/solution-variables/test/solution-variables.spec.js +126 -0
  72. package/dist/collection/utils/publicNotificationUtils.js +45 -0
  73. package/dist/collection/utils/templates.e2e.js +25 -0
  74. package/dist/collection/utils/test/csvUtils.spec.js +46 -0
  75. package/dist/collection/utils/test/downloadUtils.spec.js +102 -0
  76. package/dist/collection/utils/test/pciUtils.spec.js +297 -0
  77. package/dist/collection/utils/test/solution-store.spec.js +439 -0
  78. package/dist/components/map-select-tools2.js +36 -36
  79. package/dist/components/solution-store.js +3 -3
  80. package/dist/esm/calcite-input-text_5.entry.js +36 -36
  81. package/dist/esm/calcite-shell-panel_14.entry.js +1 -1
  82. package/dist/esm/solution-configuration.entry.js +1 -1
  83. package/dist/esm/solution-contents_3.entry.js +1 -1
  84. package/dist/esm/{solution-store-5d068b07.js → solution-store-70f874f8.js} +3 -3
  85. package/dist/solutions-components/{p-41802f6b.entry.js → p-16dfb254.entry.js} +1 -1
  86. package/dist/solutions-components/{p-4769a2a5.entry.js → p-5ed755a2.entry.js} +1 -1
  87. package/dist/solutions-components/{p-826a814d.js → p-78719506.js} +2 -2
  88. package/dist/solutions-components/{p-9f620303.entry.js → p-b4b19fd3.entry.js} +1 -1
  89. package/dist/solutions-components/{p-24fe6e1c.entry.js → p-d5d5942d.entry.js} +1 -1
  90. package/dist/solutions-components/solutions-components.esm.js +1 -1
  91. package/dist/solutions-components/utils/common.js +291 -0
  92. package/dist/solutions-components/utils/csvDownload.js +36 -0
  93. package/dist/solutions-components/utils/csvUtils.js +32 -0
  94. package/dist/solutions-components/utils/downloadUtils.js +386 -0
  95. package/dist/solutions-components/utils/interfaces.js +56 -0
  96. package/dist/solutions-components/utils/languageUtil.js +85 -0
  97. package/dist/solutions-components/utils/loadModules.js +20 -0
  98. package/dist/solutions-components/utils/locale.js +56 -0
  99. package/dist/solutions-components/utils/mapViewUtils.js +140 -0
  100. package/dist/solutions-components/utils/pciUtils.js +837 -0
  101. package/dist/solutions-components/utils/pdfUtils.js +62 -0
  102. package/dist/solutions-components/utils/publicNotificationStore.js +38 -0
  103. package/dist/solutions-components/utils/publicNotificationUtils.js +45 -0
  104. package/dist/solutions-components/utils/queryUtils.js +148 -0
  105. package/dist/solutions-components/utils/solution-store.js +579 -0
  106. package/dist/solutions-components/utils/templates.e2e.js +25 -0
  107. package/dist/solutions-components/utils/templates.js +341 -0
  108. package/dist/solutions-components/utils/test/csvUtils.spec.js +46 -0
  109. package/dist/solutions-components/utils/test/downloadUtils.spec.js +102 -0
  110. package/dist/solutions-components/utils/test/mocks/jsApi.js +74 -0
  111. package/dist/solutions-components/utils/test/pciUtils.spec.js +297 -0
  112. package/dist/solutions-components/utils/test/solution-store.spec.js +439 -0
  113. package/dist/solutions-components/utils/test/testUtils.js +135 -0
  114. package/dist/solutions-components/utils/types.js +14 -0
  115. package/dist/solutions-components_commit.txt +7 -0
  116. package/package.json +7 -7
@@ -0,0 +1,341 @@
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
+ //
18
+ // Public Functions
19
+ //
20
+ //--------------------------------------------------------------------------
21
+ /**
22
+ * Sort the solution items
23
+ *
24
+ * @param templates a list of item templates from the solution
25
+ *
26
+ * @returns a sorted list of solution items
27
+ */
28
+ export function getInventoryItems(templates) {
29
+ const hierarchy = getItemHierarchy(templates);
30
+ const ids = hierarchy.reduce((prev, cur) => {
31
+ prev.push(cur.id);
32
+ return prev;
33
+ }, []);
34
+ return templates.reduce((prev, cur) => {
35
+ if (ids.indexOf(cur.itemId) > -1) {
36
+ const hierarchyItems = hierarchy.filter(hi => hi.id === cur.itemId);
37
+ prev.push(_getItemFromTemplate(cur, templates, hierarchyItems[0].dependencies));
38
+ }
39
+ return prev;
40
+ }, []);
41
+ }
42
+ /**
43
+ * Create item hierarchy that will avoid issues from cylical dependencies
44
+ *
45
+ * @param templates a list of item templates from the solution
46
+ *
47
+ * @returns a hierarchy for item and item dependency display
48
+ */
49
+ export function getItemHierarchy(templates) {
50
+ const hierarchy = [];
51
+ // Get the template specified by id out of a list of templates
52
+ function getTemplateInSolution(templates, id) {
53
+ const iTemplate = templates.findIndex((template) => id === template.itemId);
54
+ return iTemplate >= 0 ? templates[iTemplate] : null;
55
+ }
56
+ // Hierarchically list the dependencies of specified node
57
+ function traceItemId(id, accumulatedHierarchy, alreadyVisitedIds = []) {
58
+ // Get the dependencies of the node
59
+ const template = getTemplateInSolution(templates, id);
60
+ /* istanbul ignore else */
61
+ if (template) {
62
+ const templateEntry = {
63
+ id,
64
+ dependencies: []
65
+ };
66
+ // Visit each dependency, but only if this template is not in the alreadyVisitedIds list to avoid infinite loops
67
+ /* istanbul ignore else */
68
+ if (alreadyVisitedIds.indexOf(id) < 0) {
69
+ // Add dependency to alreadyVisitedIds list
70
+ alreadyVisitedIds.push(id);
71
+ template.dependencies.forEach((dependencyId) => {
72
+ // Remove dependency from list of templates to visit in the top-level loop
73
+ const iDependencyTemplate = templateItemIds.indexOf(dependencyId);
74
+ /* istanbul ignore else */
75
+ if (iDependencyTemplate >= 0) {
76
+ templateItemIds.splice(iDependencyTemplate, 1);
77
+ }
78
+ traceItemId(dependencyId, templateEntry.dependencies, alreadyVisitedIds);
79
+ });
80
+ }
81
+ accumulatedHierarchy.push(templateEntry);
82
+ }
83
+ }
84
+ // Start with top-level nodes and add in the rest of the nodes to catch cycles without top-level nodes
85
+ let templateItemIds = _getTopLevelItemIds(templates);
86
+ const otherItems = templates
87
+ .filter((template) => templateItemIds.indexOf(template.itemId) < 0) // only keep non-top-level nodes
88
+ .sort((a, b) => b.dependencies.length - a.dependencies.length); // sort so that nodes with more dependencies come first--reduces stubs
89
+ templateItemIds = templateItemIds.concat(otherItems.map((template) => template.itemId));
90
+ // Step through the list of nodes; we'll also remove nodes as we visit them
91
+ let itemId = templateItemIds.shift();
92
+ while (typeof itemId !== "undefined") {
93
+ traceItemId(itemId, hierarchy);
94
+ itemId = templateItemIds.shift();
95
+ }
96
+ return hierarchy;
97
+ }
98
+ /**
99
+ * Explore the solution item templates for variables we will allow users to insert at runtime
100
+ *
101
+ * @param templates a list of item templates from the solution
102
+ * @param translations nls translation object
103
+ *
104
+ * @returns a list of variables from the solution item templates
105
+ */
106
+ export function getSolutionVariables(templates, translations) {
107
+ const vars = [];
108
+ templates.forEach(t => {
109
+ const item = {
110
+ id: t.itemId,
111
+ title: t.item.title || t.item.name,
112
+ type: t.type,
113
+ value: undefined,
114
+ dependencies: [{
115
+ id: t.itemId,
116
+ title: translations.itemId,
117
+ value: `{{${t.itemId}.itemId}}`,
118
+ }]
119
+ };
120
+ if (t.item.url) {
121
+ item.dependencies.push({
122
+ id: t.itemId,
123
+ title: translations.url,
124
+ value: `{{${t.itemId}.url}}`,
125
+ });
126
+ }
127
+ if (t.type === "Feature Service") {
128
+ // TODO need to set source service name var...
129
+ // TODO need to set soure service shape field name "{{d05b3cf1ffcb4a4fa677627dfb18609e.name}}.Shape"
130
+ item.dependencies.push({
131
+ id: t.itemId,
132
+ title: translations.solutionExtent,
133
+ value: `{{${t.itemId}.solutionExtent}}`,
134
+ });
135
+ _addLayersOrTables(t.properties.layers || [], item, t, translations);
136
+ _addLayersOrTables(t.properties.tables || [], item, t, translations);
137
+ }
138
+ vars.push(item);
139
+ });
140
+ return vars;
141
+ }
142
+ /**
143
+ * Set key organization variables we will allow users to insert at runtime
144
+ *
145
+ * @param translations nls translation object
146
+ *
147
+ * @returns a list of variables for the organization
148
+ */
149
+ export function getOrganizationVariables(translations) {
150
+ const orgVars = [{
151
+ id: "",
152
+ title: translations.geocodeUrl,
153
+ value: "{{organization.helperServices.geocode:getDefaultLocatorURL}}"
154
+ }, {
155
+ id: "",
156
+ title: translations.geometryUrl,
157
+ value: "{{organization.helperServices.geometry.url}}"
158
+ }, {
159
+ id: "",
160
+ title: translations.portalBaseUrl,
161
+ value: "{{portalBaseUrl}}"
162
+ }, {
163
+ id: "",
164
+ title: translations.routeUrl,
165
+ value: "{{organization.helperServices.route.url}}"
166
+ }, {
167
+ id: "",
168
+ title: translations.solutionItemExtent,
169
+ value: "{{solutionItemExtent}}"
170
+ }];
171
+ return orgVars;
172
+ }
173
+ //--------------------------------------------------------------------------
174
+ //
175
+ // Private Functions
176
+ //
177
+ //--------------------------------------------------------------------------
178
+ /**
179
+ * Explore a solution item template for variables we will allow users to insert at runtime.
180
+ * This function will update the item argument that is passed in with the var details.
181
+ *
182
+ * @param children a list of layers or tables from a template
183
+ * @param item an object that store key details for a given variable
184
+ * @param template one of the templates from the current solution
185
+ * @param translations nls translations object
186
+ *
187
+ */
188
+ function _addLayersOrTables(children, item, template, translations) {
189
+ children.forEach(l => {
190
+ const name = l.name && l.name.indexOf("||") > -1 ? l.name.split("||")[1].replace("}}", "").trim() : l.name;
191
+ item.dependencies.push({
192
+ id: template.itemId,
193
+ title: `${name} (${translations.id})`,
194
+ value: `{{${template.itemId}.layer${l.id}.id}}`,
195
+ });
196
+ item.dependencies.push({
197
+ id: template.itemId,
198
+ title: `${name} (${translations.name})`,
199
+ value: `{{${template.itemId}.layer${l.id}.name||${name}}}`,
200
+ });
201
+ });
202
+ }
203
+ /**
204
+ * Capture key details from the solution item template
205
+ *
206
+ * @param template one of the templates from the current solution
207
+ * @param templates full list of templates
208
+ * @param dependencies list of hierarchical dependencies
209
+ *
210
+ * @returns an IInventoryItem that is used by other components to work with this template
211
+ */
212
+ function _getItemFromTemplate(template, templates, dependencies) {
213
+ return {
214
+ id: template.itemId || "",
215
+ title: template.item.title || "",
216
+ dependencies: _getDependencies(dependencies, templates),
217
+ type: template.item.type || "",
218
+ typeKeywords: template.item.typeKeywords || [] /*,
219
+ solutionItem: {
220
+ itemId: template.itemId,
221
+ itemDetails: _getItemDetails(template.item, template.type === "Group"),
222
+ isResource: _getIsResource(template),
223
+ data: template.data,
224
+ properties: template.properties,
225
+ type: template.type,
226
+ groupDetails: _getGroupDetails(template, templates)
227
+ }*/
228
+ };
229
+ }
230
+ /**
231
+ * Capture key details from the solution item template
232
+ *
233
+ * @param dependencies list of dependencies from a template
234
+ * @param templates full list of templates
235
+ *
236
+ * @returns a list of IInventoryItem that are used by other components to work with the templates
237
+ */
238
+ function _getDependencies(dependencies, templates) {
239
+ const dependencyItems = [];
240
+ const depIds = dependencies.reduce((prev, cur) => {
241
+ prev.push(cur.id);
242
+ dependencyItems.push(cur);
243
+ return prev;
244
+ }, []);
245
+ return templates.reduce((prev, curr) => {
246
+ const i = depIds.indexOf(curr.itemId);
247
+ if (i > -1) {
248
+ prev.push(_getItemFromTemplate(curr, templates, dependencyItems[i].dependencies));
249
+ }
250
+ return prev;
251
+ }, []);
252
+ }
253
+ /**
254
+ * Capture the key item details for a given template
255
+ *
256
+ * @param item the templates item
257
+ * @param isGroup boolean to indicate if the item is a group
258
+ * @param itemId the item id of the template
259
+ *
260
+ * @returns a IItemDetails object for the current item
261
+ */
262
+ /*
263
+ function _getItemDetails(
264
+ item: any,
265
+ isGroup: boolean
266
+ ): IItemDetails {
267
+ return {
268
+ title: item.title || "",
269
+ snippet: item.snippet || "",
270
+ description: item.description || "",
271
+ tags: item.tags || [],
272
+ accessInformation: !isGroup ? item.accessInformation || "" : "",
273
+ licenseInfo: !isGroup ? item.licenseInfo || "" : ""
274
+ };
275
+ }
276
+ */
277
+ /**
278
+ * Capture the key item details for a given group template
279
+ *
280
+ * @param template one of the templates from the current solution
281
+ * @param templates full list of templates
282
+ *
283
+ * @returns a list of IItemShare objects
284
+ */
285
+ /*
286
+ function _getGroupDetails(
287
+ template: any,
288
+ templates: any[]
289
+ ): IItemShare[] {
290
+ return template.type === "Group" ? templates.reduce((prev, cur) => {
291
+ if (cur.itemId !== template.itemId && cur.type !== "Group") {
292
+ prev.push({
293
+ id: cur.itemId,
294
+ title: cur.item.name || cur.item.title,
295
+ isShared: (cur.groups || []).indexOf(template.itemId) > -1,
296
+ shareItem: (cur.groups || []).indexOf(template.itemId) > -1,
297
+ type: cur.type,
298
+ typeKeywords: cur.item.typeKeywords
299
+ });
300
+ }
301
+ return prev;
302
+ }, []) : [];
303
+ }
304
+ */
305
+ /**
306
+ * Used to understand if we are dealing with a binary object that will support upload/download
307
+ *
308
+ * @param template one of the templates from the current solution
309
+ *
310
+ * @returns true if this item supports upload/download
311
+ */
312
+ /*
313
+ function _getIsResource(
314
+ template: any
315
+ ): boolean {
316
+ return template.type !== "Group" && template.resources.some(r => r.indexOf("_info_thumbnail") < 0) &&
317
+ (template.data === null || JSON.stringify(template.data) === "{}");
318
+ }
319
+ */
320
+ /**
321
+ * Sort the template ids based on their dependencies
322
+ *
323
+ * @param templates full list of templates
324
+ *
325
+ * @returns a list of Itop level item ids
326
+ */
327
+ function _getTopLevelItemIds(templates) {
328
+ // Find the top-level nodes. Start with all nodes, then remove those that other nodes depend on
329
+ const topLevelItemCandidateIds = templates.map((template) => template.itemId);
330
+ templates.forEach((template) => {
331
+ (template.dependencies || []).forEach((dependencyId) => {
332
+ const iNode = topLevelItemCandidateIds.indexOf(dependencyId);
333
+ if (iNode >= 0) {
334
+ // Node is somebody's dependency, so remove the node from the list of top-level nodes
335
+ // If iNode == -1, then it's a shared dependency and it has already been removed
336
+ topLevelItemCandidateIds.splice(iNode, 1);
337
+ }
338
+ });
339
+ });
340
+ return topLevelItemCandidateIds;
341
+ }
@@ -0,0 +1,46 @@
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
+ import * as csvDownload from "../csvDownload";
17
+ import * as csvUtils from "../csvUtils";
18
+ import { expect, jest } from "@jest/globals";
19
+ afterEach(() => {
20
+ jest.restoreAllMocks();
21
+ });
22
+ describe("csvUtils", () => {
23
+ describe("exportCSV", () => {
24
+ it("prepares output lines 1", () => {
25
+ const title = "title";
26
+ const labels = [
27
+ ["Cyd Charise", "1922 Main St", "Amarillo, TX 79118"],
28
+ ["Fred Astaire", "1899 Main St", "Omaha, NE 68022"],
29
+ ["Gene Kelly", "1912 Main St", "Pittsburgh, PA 15215"],
30
+ ["Ginger Rogers", "1911 Main St", "Independence, MO 64050"]
31
+ ];
32
+ const expectedOutputLines = [
33
+ "\"Cyd Charise\",\"1922 Main St\",\"Amarillo, TX 79118\"\r\n",
34
+ "\"Fred Astaire\",\"1899 Main St\",\"Omaha, NE 68022\"\r\n",
35
+ "\"Gene Kelly\",\"1912 Main St\",\"Pittsburgh, PA 15215\"\r\n",
36
+ "\"Ginger Rogers\",\"1911 Main St\",\"Independence, MO 64050\"\r\n"
37
+ ];
38
+ const downloadCSVFileMock = jest.spyOn(csvDownload, "downloadCSVFile")
39
+ .mockImplementation((fileTitle, outputLines) => { });
40
+ csvUtils.exportCSV(title, labels);
41
+ expect(downloadCSVFileMock).toBeCalledTimes(1);
42
+ expect(downloadCSVFileMock.mock.calls[0][0]).toEqual(title);
43
+ expect(downloadCSVFileMock.mock.calls[0][1]).toEqual(expectedOutputLines);
44
+ });
45
+ });
46
+ });
@@ -0,0 +1,102 @@
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
+ import * as downloadUtils from "../downloadUtils";
17
+ describe("downloadUtils", () => {
18
+ describe("_convertPopupFieldsToLabelSpec", () => {
19
+ it("handles fieldname visibility", () => {
20
+ const fieldInfos = [
21
+ { fieldName: "A", visible: true },
22
+ { fieldName: "B", visible: true },
23
+ { fieldName: "C", visible: false },
24
+ { fieldName: "D", visible: true }
25
+ ];
26
+ const bypassFieldVisiblity = false;
27
+ const expectedLabelSpec = "{A}|{B}|{D}";
28
+ const labelSpec = downloadUtils._convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity);
29
+ expect(labelSpec).toEqual(expectedLabelSpec);
30
+ });
31
+ it("handles fieldname ignoring visibility", () => {
32
+ const fieldInfos = [
33
+ { fieldName: "A", visible: true },
34
+ { fieldName: "B", visible: true },
35
+ { fieldName: "C", visible: false },
36
+ { fieldName: "D", visible: true }
37
+ ];
38
+ const bypassFieldVisiblity = true;
39
+ const expectedLabelSpec = "{A}|{B}|{C}|{D}";
40
+ const labelSpec = downloadUtils._convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity);
41
+ expect(labelSpec).toEqual(expectedLabelSpec);
42
+ });
43
+ });
44
+ describe("_convertPopupTextToLabelSpec", () => {
45
+ it("handles <br> variants", () => {
46
+ const popupInfo = "<div style='text-align: left;'>{NAME}<br />{STREET}<br/>{CITY}, {STATE} {ZIP} <br></div>";
47
+ const expectedLabelSpec = "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}";
48
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
49
+ expect(labelSpec).toEqual(expectedLabelSpec);
50
+ });
51
+ it("handles <p>", () => {
52
+ const popupInfo = "<p>{NAME}</p><p>{STREET}</p><p>{CITY}, {STATE} {ZIP}</p>";
53
+ const expectedLabelSpec = "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}";
54
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
55
+ expect(labelSpec).toEqual(expectedLabelSpec);
56
+ });
57
+ it("handles popup's use of \xA0", () => {
58
+ const popupInfo = "<div style='text-align: left;'>{NAME}<br />{STREET}<br />{CITY},\xA0{STATE}\xA0{ZIP}\xA0<br /></div>";
59
+ const expectedLabelSpec = "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}";
60
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
61
+ expect(labelSpec).toEqual(expectedLabelSpec);
62
+ });
63
+ it("removes newlines and blank lines, and trims each line", () => {
64
+ const popupInfo = " \n\n {NAME} \n \n\n {STREET}\n{CITY}, {STATE} {ZIP}\n\n \n ";
65
+ const expectedLabelSpec = "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}";
66
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
67
+ expect(labelSpec).toEqual(expectedLabelSpec);
68
+ });
69
+ it("removes extra HTML", () => {
70
+ const popupInfo = "\n<div style='text-align: left;'><span style='font-weight:bold'>{NAME}</span><br />{STREET}<br />{CITY},\xA0{STATE}\xA0{ZIP}\xA0<br /></div>\n";
71
+ const expectedLabelSpec = "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}";
72
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
73
+ expect(labelSpec).toEqual(expectedLabelSpec);
74
+ });
75
+ it("handles some special characters", () => {
76
+ const popupInfo = "<div style='text-align: left;'>&lt;{NAME}&gt;<br />{STREET}<br/>{CITY},&nbsp;{STATE}&nbsp;{ZIP}<br></div>";
77
+ const expectedLabelSpec = "<{NAME}>|{STREET}|{CITY}, {STATE} {ZIP}";
78
+ const labelSpec = downloadUtils._convertPopupTextToLabelSpec(popupInfo);
79
+ expect(labelSpec).toEqual(expectedLabelSpec);
80
+ });
81
+ });
82
+ describe("_createTitle", () => {
83
+ it("handles no selection set names", () => {
84
+ const selectionSetNames = [];
85
+ const expectedTitle = "download";
86
+ const title = downloadUtils._createTitle(selectionSetNames);
87
+ expect(title).toEqual(expectedTitle);
88
+ });
89
+ it("handles one selection set name", () => {
90
+ const selectionSetNames = ["fred"];
91
+ const expectedTitle = "fred";
92
+ const title = downloadUtils._createTitle(selectionSetNames);
93
+ expect(title).toEqual(expectedTitle);
94
+ });
95
+ it("handles two selection set names", () => {
96
+ const selectionSetNames = ["fred", "ginger"];
97
+ const expectedTitle = "fred,ginger";
98
+ const title = downloadUtils._createTitle(selectionSetNames);
99
+ expect(title).toEqual(expectedTitle);
100
+ });
101
+ });
102
+ });
@@ -0,0 +1,74 @@
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
+ export class GraphicsLayer {
17
+ constructor(options) {
18
+ this.title = options.title;
19
+ this.graphics = [];
20
+ this.removeAll = () => {
21
+ this.graphics = [];
22
+ };
23
+ this.addMany = (graphics) => {
24
+ this.graphics.concat(graphics);
25
+ };
26
+ }
27
+ }
28
+ export class Graphic {
29
+ constructor(options) {
30
+ Object.assign(this, options);
31
+ }
32
+ }
33
+ export class Sketch {
34
+ constructor(options) {
35
+ Object.assign(this, options);
36
+ this.viewModel = {
37
+ pointSymbol: {},
38
+ polylineSymbol: {},
39
+ polygonSymbol: {},
40
+ };
41
+ this.on = () => { };
42
+ }
43
+ }
44
+ export class Search {
45
+ constructor(options) {
46
+ Object.assign(this, options);
47
+ this.clear = () => { };
48
+ this.on = () => { };
49
+ }
50
+ }
51
+ export class Geometry {
52
+ constructor(options) {
53
+ Object.assign(this, options);
54
+ }
55
+ }
56
+ export class geometryEngine {
57
+ constructor(options) {
58
+ Object.assign(this, options);
59
+ }
60
+ }
61
+ export class highlightHandle {
62
+ }
63
+ export class LayerView {
64
+ constructor(options) {
65
+ Object.assign(this, options);
66
+ this.layer = {
67
+ createQuery: () => {
68
+ return {};
69
+ },
70
+ queryFeatures: async () => {
71
+ }
72
+ };
73
+ }
74
+ }