@esri/solutions-components 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
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,386 @@
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
+ //#region Declarations
17
+ import { exportCSV } from "./csvUtils";
18
+ import { exportPDF } from "./pdfUtils";
19
+ import { loadModules } from "./loadModules";
20
+ import { queryFeaturesByID } from "./queryUtils";
21
+ export { ILabel } from "./pdfUtils";
22
+ const lineSeparatorChar = "|";
23
+ //#endregion
24
+ //#region Public functions
25
+ /**
26
+ * Downloads csv of mailing labels for the provided list of ids
27
+ *
28
+ * @param selectionSetNames Names of the selection sets used to provide ids
29
+ * @param layer Layer providing features and attributes for download
30
+ * @param ids List of ids to download
31
+ * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
32
+ * all attributes are exported
33
+ * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
34
+ * @param addColumnTitle Indicates if column headings should be included in output
35
+ * @returns Promise resolving when function is done
36
+ */
37
+ export async function downloadCSV(selectionSetNames, layer, ids, formatUsingLayerPopup, removeDuplicates = false, addColumnTitle = false) {
38
+ const labels = await _prepareLabels(layer, ids, removeDuplicates, formatUsingLayerPopup, addColumnTitle);
39
+ exportCSV(_createFilename(selectionSetNames), labels);
40
+ return Promise.resolve();
41
+ }
42
+ /**
43
+ * Downloads csv of mailing labels for the provided list of ids
44
+ *
45
+ * @param selectionSetNames Names of the selection sets used to provide ids
46
+ * @param layer Layer providing features and attributes for download
47
+ * @param ids List of ids to download
48
+ * @param labelPageDescription Provides PDF page layout info
49
+ * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
50
+ * @param includeMap When true, the first page of the output is a map showing the selection area
51
+ * @param includeTitle When true, a title is included on every page
52
+ * @param title Title for each page when `includeTitle` is true
53
+ * @returns Promise resolving when function is done
54
+ */
55
+ export async function downloadPDF(selectionSetNames, layer, ids, labelPageDescription, removeDuplicates = false, includeMap = false, includeTitle = false, title = "") {
56
+ let labels = await _prepareLabels(layer, ids, removeDuplicates);
57
+ labels =
58
+ // Remove empty lines in labels
59
+ labels.map(labelLines => labelLines.filter(line => line.length > 0))
60
+ // Remove empty labels
61
+ .filter(label => label.length > 0);
62
+ exportPDF(_createFilename(selectionSetNames), labels, labelPageDescription, includeMap, includeTitle, title);
63
+ return Promise.resolve();
64
+ }
65
+ //#endregion
66
+ //#region Private functions
67
+ /**
68
+ * Converts a set of fieldInfos into template lines.
69
+ *
70
+ * @param fieldInfos Layer's fieldInfos structure
71
+ * @param bypassFieldVisiblity Indicates if the configured fieldInfo visibility property should be ignored
72
+ * @return Label spec with lines separated by `lineSeparatorChar`
73
+ */
74
+ export function _convertPopupFieldsToLabelSpec(fieldInfos, bypassFieldVisiblity = false) {
75
+ const labelSpec = [];
76
+ // Every visible attribute is used
77
+ fieldInfos.forEach(fieldInfo => {
78
+ if (fieldInfo.visible || bypassFieldVisiblity) {
79
+ labelSpec.push(`{${fieldInfo.fieldName}}`);
80
+ }
81
+ });
82
+ return labelSpec.join(lineSeparatorChar);
83
+ }
84
+ ;
85
+ /**
86
+ * Converts the text of a custom popup into a multiline label specification; conversion splits text into
87
+ * lines on <br>s, and removes HTML tags. It does not handle Arcade and related records.
88
+ *
89
+ * @param popupInfo Layer's popupInfo structure containing description, fieldInfos, and expressionInfos, e.g.,
90
+ * "<div style='text-align: left;'>{NAME}<br />{STREET}<br />{CITY}, {STATE} {ZIP} <br /></div>"
91
+ * @return Label spec with lines separated by `lineSeparatorChar`
92
+ */
93
+ export function _convertPopupTextToLabelSpec(popupInfo) {
94
+ // Replace <br> variants with the line separator character
95
+ popupInfo = popupInfo.replace(/<br\s*\/?>/gi, lineSeparatorChar);
96
+ // Replace <p> variants with the line separator character, except in the first position
97
+ popupInfo = popupInfo.replace(/<p[^>]*>/gi, lineSeparatorChar).trim().replace(/^\|/, "");
98
+ // Remove </p>
99
+ popupInfo = popupInfo.replace(/<\/p>/gi, "");
100
+ // Replace \n with the line separator character
101
+ popupInfo = popupInfo.replace(/\n/gi, "|");
102
+ // Remove remaining HTML tags, replace 0xA0 that popup uses for spaces, and replace some char representations
103
+ let labelSpec = popupInfo
104
+ .replace(/<[\s.]*[^<>]*\/?>/gi, "")
105
+ .replace(/\xA0/gi, " ")
106
+ .replace(/&lt;/gi, "<")
107
+ .replace(/&gt;/gi, ">")
108
+ .replace(/&nbsp;/gi, " ");
109
+ // Trim each line
110
+ labelSpec = labelSpec.replace(/\s*\|\s*/g, "|");
111
+ // Remove empty lines
112
+ while (labelSpec.match(/\|\|/)) {
113
+ labelSpec = labelSpec.replace(/\|\|/, "|");
114
+ }
115
+ // Remove leading and trailing line feeds
116
+ labelSpec = labelSpec.replace(/^\|/, "");
117
+ labelSpec = labelSpec.replace(/\|$/, "");
118
+ return labelSpec.trim();
119
+ }
120
+ ;
121
+ /**
122
+ * Extracts Arcade expressions from the lines of a label format and creates an Arcade executor for each
123
+ * referenced expression name.
124
+ *
125
+ * @param labelFormat Label to examine
126
+ * @param layer Layer from which to fetch features
127
+ * @return Promise resolving to a set of executors keyed using the expression name
128
+ */
129
+ async function _createArcadeExecutors(labelFormat, layer) {
130
+ const arcadeExecutors = {};
131
+ // Are any Arcade expressions in the layer?
132
+ if (!Array.isArray(layer.popupTemplate.expressionInfos) || layer.popupTemplate.expressionInfos.length === 0) {
133
+ return Promise.resolve(arcadeExecutors);
134
+ }
135
+ // Are there any Arcade expressions in the label format?
136
+ const arcadeExpressionRegExp = /\{expression\/\w+\}/g;
137
+ const arcadeExpressionsMatches = labelFormat.match(arcadeExpressionRegExp);
138
+ if (!arcadeExpressionsMatches) {
139
+ return Promise.resolve(arcadeExecutors);
140
+ }
141
+ // Generate an Arcade executor for each match
142
+ const [arcade] = await loadModules(["esri/arcade"]);
143
+ const labelingProfile = {
144
+ variables: [
145
+ {
146
+ name: "$feature",
147
+ type: "feature"
148
+ },
149
+ {
150
+ name: "$layer",
151
+ type: "featureSet"
152
+ },
153
+ {
154
+ name: "$datastore",
155
+ type: "featureSetCollection"
156
+ },
157
+ {
158
+ name: "$map",
159
+ type: "featureSetCollection"
160
+ }
161
+ ]
162
+ };
163
+ const createArcadeExecutorPromises = {};
164
+ arcadeExpressionsMatches.forEach((match) => {
165
+ const expressionName = match.substring(match.indexOf("/") + 1, match.length - 1);
166
+ (layer.popupTemplate.expressionInfos || []).forEach(expressionInfo => {
167
+ if (expressionInfo.name === expressionName) {
168
+ createArcadeExecutorPromises[expressionName] =
169
+ arcade.createArcadeExecutor(expressionInfo.expression, labelingProfile);
170
+ }
171
+ });
172
+ });
173
+ const promises = Object.values(createArcadeExecutorPromises);
174
+ return Promise.all(promises)
175
+ .then(executors => {
176
+ const expressionNames = Object.keys(createArcadeExecutorPromises);
177
+ for (let i = 0; i < expressionNames.length; ++i) {
178
+ arcadeExecutors[expressionNames[i]] = executors[i].valueOf();
179
+ }
180
+ return arcadeExecutors;
181
+ });
182
+ }
183
+ /**
184
+ * Creates a title from a list of selection set names.
185
+ *
186
+ * @param selectionSetNames Names to use in title
187
+ * @return Title composed of the selectionSetNames separated by commas; if there are no
188
+ * selection set names supplied, "download" is returned
189
+ */
190
+ export function _createFilename(selectionSetNames) {
191
+ // Windows doesn't permit the characters \/:*?"<>|
192
+ const title = selectionSetNames.length > 0 ? selectionSetNames.join(", ") : "download";
193
+ return title;
194
+ }
195
+ /**
196
+ * Prepares an attribute's value by applying domain and type information.
197
+ *
198
+ * @param attributeValue Value of attribute
199
+ * @param attributeType Type of attribute
200
+ * @param attributeDomain Domain info for attribute, if any
201
+ * @param attributeFormat Format info for attribute, if any
202
+ * @param intl esri/intl
203
+ * @return Attribute value modified appropriate to domain and type
204
+ */
205
+ function _prepareAttributeValue(attributeValue, attributeType, attributeDomain, attributeFormat, intl) {
206
+ if (attributeDomain && attributeDomain.type === "coded-value") {
207
+ // "coded-value" domain field
208
+ const value = attributeDomain.getName(attributeValue);
209
+ return value;
210
+ }
211
+ else {
212
+ // Non-domain field or unsupported domain type
213
+ let value = attributeValue;
214
+ switch (attributeType) {
215
+ case "date":
216
+ if (attributeFormat === null || attributeFormat === void 0 ? void 0 : attributeFormat.dateFormat) {
217
+ const dateFormatIntlOptions = intl.convertDateFormatToIntlOptions(attributeFormat.dateFormat);
218
+ value = intl.formatDate(value, dateFormatIntlOptions);
219
+ }
220
+ else {
221
+ value = intl.formatDate(value);
222
+ }
223
+ // Format date produces odd characters for the space between the time and the AM/PM text,
224
+ // e.g., "12/31/1969, 4:00 PM"
225
+ value = value.replace(/\xe2\x80\xaf/g, "");
226
+ break;
227
+ case "double":
228
+ case "integer":
229
+ case "long":
230
+ case "small-integer":
231
+ if (attributeFormat) {
232
+ const numberFormatIntlOptions = intl.convertNumberFormatToIntlOptions(attributeFormat);
233
+ value = intl.formatNumber(value, numberFormatIntlOptions);
234
+ }
235
+ else {
236
+ value = intl.formatNumber(value);
237
+ }
238
+ break;
239
+ }
240
+ return value;
241
+ }
242
+ }
243
+ /**
244
+ * Creates labels from items.
245
+ *
246
+ * @param layer Layer from which to fetch features
247
+ * @param ids List of ids to download
248
+ * @param removeDuplicates When true a single label is generated when multiple featues have a shared address value
249
+ * @param formatUsingLayerPopup When true, the layer's popup is used to choose attributes for each column; when false,
250
+ * all attributes are exported
251
+ * @param includeHeaderNames Add the label format at the front of the list of generated labels
252
+ * @returns Promise resolving when function is done
253
+ */
254
+ async function _prepareLabels(layer, ids, removeDuplicates = true, formatUsingLayerPopup = true, includeHeaderNames = false) {
255
+ var _a, _b, _c, _d;
256
+ const [intl] = await loadModules(["esri/intl"]);
257
+ // Get the features to export
258
+ const featureSet = await queryFeaturesByID(ids, layer);
259
+ let features = featureSet.features;
260
+ if (!removeDuplicates && ids.length > features.length) {
261
+ const oidField = layer.objectIdField;
262
+ features = featureSet.features.reduce((prev, cur) => {
263
+ const id = cur.attributes[oidField];
264
+ // remove the first instance of the id
265
+ const i = ids.indexOf(id);
266
+ if (i > -1) {
267
+ ids = ids.splice(i, 1);
268
+ }
269
+ // add the first instance of the feature to the new array
270
+ prev.push(cur);
271
+ // test for any duplicates
272
+ if (ids.indexOf(id) > -1) {
273
+ // could be more than once..
274
+ const _ids = ids.filter(_id => _id !== id);
275
+ const num = ids.length - _ids.length;
276
+ for (let _i = 0; _i < num; _i++) {
277
+ prev.push(cur);
278
+ }
279
+ ids = _ids;
280
+ }
281
+ return prev;
282
+ }, []);
283
+ }
284
+ // Get field data types. Do we have any domain-based fields?
285
+ const attributeTypes = {};
286
+ const attributeDomains = {};
287
+ layer.fields.forEach(field => {
288
+ attributeTypes[field.name] = field.type;
289
+ attributeDomains[field.name] = field.domain;
290
+ });
291
+ const attributeFormats = {};
292
+ // Get the label formatting, if any
293
+ let labelFormat;
294
+ let arcadeExecutors = {};
295
+ if (layer.popupEnabled) {
296
+ layer.popupTemplate.fieldInfos.forEach(
297
+ // Extract any format info that we have
298
+ fieldInfo => {
299
+ if (fieldInfo.format) {
300
+ attributeFormats[fieldInfo.fieldName] = fieldInfo.format;
301
+ }
302
+ });
303
+ // What data fields are used in the labels?
304
+ // Example labelFormat: ['{NAME}', '{STREET}', '{CITY}, {STATE} {ZIP}']
305
+ if (formatUsingLayerPopup && ((_b = (_a = layer.popupTemplate) === null || _a === void 0 ? void 0 : _a.content[0]) === null || _b === void 0 ? void 0 : _b.type) === "fields") {
306
+ labelFormat = _convertPopupFieldsToLabelSpec(layer.popupTemplate.fieldInfos);
307
+ // If popup is configured with "no attribute information", then no fields will visible
308
+ if (labelFormat.length === 0) {
309
+ // Can we use the popup title?
310
+ // eslint-disable-next-line unicorn/prefer-ternary
311
+ if (typeof layer.popupTemplate.title === "string") {
312
+ labelFormat = layer.popupTemplate.title;
313
+ // Otherwise revert to using attributes
314
+ }
315
+ else {
316
+ labelFormat = _convertPopupFieldsToLabelSpec(layer.popupTemplate.fieldInfos, true);
317
+ }
318
+ }
319
+ }
320
+ else if (formatUsingLayerPopup && ((_d = (_c = layer.popupTemplate) === null || _c === void 0 ? void 0 : _c.content[0]) === null || _d === void 0 ? void 0 : _d.type) === "text") {
321
+ labelFormat = _convertPopupTextToLabelSpec(layer.popupTemplate.content[0].text);
322
+ // Do we need any Arcade executors?
323
+ arcadeExecutors = await _createArcadeExecutors(labelFormat, layer);
324
+ }
325
+ }
326
+ // Apply the label format
327
+ let labels;
328
+ // eslint-disable-next-line unicorn/prefer-ternary
329
+ if (labelFormat) {
330
+ const arcadeExpressionRegExp = /\{expression\/\w+\}/g;
331
+ const attributeRegExp = /\{\w+\}/g;
332
+ // Find the label fields that we need to replace with values
333
+ const arcadeExpressionMatches = labelFormat.match(arcadeExpressionRegExp);
334
+ const attributeMatches = labelFormat.match(attributeRegExp);
335
+ // Convert feature attributes into an array of labels
336
+ labels = features.map(feature => {
337
+ let labelPrep = labelFormat;
338
+ // Replace Arcade expressions
339
+ if (arcadeExpressionMatches) {
340
+ arcadeExpressionMatches.forEach((match) => {
341
+ const expressionName = match.substring(match.indexOf("/") + 1, match.length - 1);
342
+ const value = arcadeExecutors[expressionName].execute({ "$feature": feature });
343
+ labelPrep = labelPrep.replace(match, value);
344
+ });
345
+ }
346
+ // Replace non-Arcade fields
347
+ if (attributeMatches) {
348
+ attributeMatches.forEach((match) => {
349
+ const attributeName = match.substring(1, match.length - 1);
350
+ const value = _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], attributeFormats[attributeName], intl);
351
+ labelPrep = labelPrep.replace(match, value);
352
+ });
353
+ }
354
+ // Split label into lines
355
+ let label = labelPrep.split(lineSeparatorChar);
356
+ // Trim lines
357
+ label = label.map(line => line.trim());
358
+ return label;
359
+ });
360
+ }
361
+ else {
362
+ // Export all attributes
363
+ labels = features.map(feature => {
364
+ return Object.keys(feature.attributes).map((attributeName) => {
365
+ const value = _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], null, intl);
366
+ return `${value}`;
367
+ });
368
+ });
369
+ }
370
+ // Add header names
371
+ if (includeHeaderNames) {
372
+ let headerNames = [];
373
+ if (labelFormat) {
374
+ headerNames = labelFormat.replace(/\{/g, "").replace(/\}/g, "").split(lineSeparatorChar);
375
+ }
376
+ else {
377
+ const featuresAttrs = features[0].attributes;
378
+ Object.keys(featuresAttrs).forEach(k => {
379
+ headerNames.push(k);
380
+ });
381
+ }
382
+ labels.unshift(headerNames);
383
+ }
384
+ return Promise.resolve(labels);
385
+ }
386
+ //#endregion
@@ -0,0 +1,56 @@
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 var ELayoutMode;
17
+ (function (ELayoutMode) {
18
+ ELayoutMode["GRID"] = "GRID";
19
+ ELayoutMode["HORIZONTAL"] = "HORIZONTAL";
20
+ ELayoutMode["VERTICAL"] = "VERTICAL";
21
+ })(ELayoutMode || (ELayoutMode = {}));
22
+ /**
23
+ * Resource update types
24
+ */
25
+ export var EUpdateType;
26
+ (function (EUpdateType) {
27
+ EUpdateType[EUpdateType["Add"] = 0] = "Add";
28
+ EUpdateType[EUpdateType["Update"] = 1] = "Update";
29
+ EUpdateType[EUpdateType["Remove"] = 2] = "Remove";
30
+ EUpdateType[EUpdateType["None"] = 3] = "None";
31
+ EUpdateType[EUpdateType["Obsolete"] = 4] = "Obsolete";
32
+ })(EUpdateType || (EUpdateType = {}));
33
+ export var EPageType;
34
+ (function (EPageType) {
35
+ EPageType[EPageType["LIST"] = 0] = "LIST";
36
+ EPageType[EPageType["SELECT"] = 1] = "SELECT";
37
+ EPageType[EPageType["EXPORT"] = 2] = "EXPORT";
38
+ })(EPageType || (EPageType = {}));
39
+ export var ESelectionType;
40
+ (function (ESelectionType) {
41
+ ESelectionType["POINT"] = "POINT";
42
+ ESelectionType["LINE"] = "LINE";
43
+ ESelectionType["POLY"] = "POLY";
44
+ ESelectionType["RECT"] = "RECT";
45
+ })(ESelectionType || (ESelectionType = {}));
46
+ export var EExpandType;
47
+ (function (EExpandType) {
48
+ EExpandType["EXPAND"] = "EXPAND";
49
+ EExpandType["COLLAPSE"] = "COLLAPSE";
50
+ })(EExpandType || (EExpandType = {}));
51
+ export var EWorkflowType;
52
+ (function (EWorkflowType) {
53
+ EWorkflowType["SEARCH"] = "SEARCH";
54
+ EWorkflowType["SELECT"] = "SELECT";
55
+ EWorkflowType["SKETCH"] = "SKETCH";
56
+ })(EWorkflowType || (EWorkflowType = {}));
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Copyright (c) 2022 Esri
3
+ * All rights reserved.
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
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+ import { loadModules } from "./loadModules";
15
+ export const languageMap = new Map([
16
+ ["ar", "ar"],
17
+ ["bg", "bg"],
18
+ ["bs", "bs"],
19
+ ["ca", "ca"],
20
+ ["cs", "cs"],
21
+ ["da", "da"],
22
+ ["de", "de"],
23
+ ["el", "el"],
24
+ ["en", "en"],
25
+ ["es", "es"],
26
+ ["et", "et"],
27
+ ["fi", "fi"],
28
+ ["fr", "fr"],
29
+ ["he", "he"],
30
+ ["hr", "hr"],
31
+ ["hu", "hu"],
32
+ ["id", "id"],
33
+ ["it", "it"],
34
+ ["ja", "ja"],
35
+ ["ko", "ko"],
36
+ ["lt", "lt"],
37
+ ["lv", "lv"],
38
+ ["nb", "nb"],
39
+ ["nl", "nl"],
40
+ ["pl", "pl"],
41
+ ["pt-br", "pt-BR"],
42
+ ["pt-pt", "pt-PT"],
43
+ ["ro", "ro"],
44
+ ["ru", "ru"],
45
+ ["sk", "sk"],
46
+ ["sl", "sl"],
47
+ ["sr", "sr"],
48
+ ["sv", "sv"],
49
+ ["th", "th"],
50
+ ["tr", "tr"],
51
+ ["uk", "uk"],
52
+ ["vi", "vi"],
53
+ ["zh-cn", "zh-CN"],
54
+ ["zh-hk", "zh-HK"],
55
+ ["zh-tw", "zh-TW"],
56
+ ]);
57
+ // rtl
58
+ export function getElementDir(el) {
59
+ return getElementProp(el, "dir", "ltr");
60
+ }
61
+ function getElementProp(el, prop, value) {
62
+ const closestWithProp = el.closest(`[${prop}]`);
63
+ return closestWithProp ? closestWithProp.getAttribute(prop) : value;
64
+ }
65
+ // css
66
+ export const CSS_UTILITY = {
67
+ rtl: "arcgis--rtl",
68
+ };
69
+ export async function formatNumber(number, options) {
70
+ const { api = 4, type = "decimal", places = 2 } = options || {};
71
+ if (api === 4) {
72
+ const [intl] = await loadModules(["esri/intl"]);
73
+ const numberFormatIntlOptions = intl.convertNumberFormatToIntlOptions({
74
+ places,
75
+ type,
76
+ digitSeparator: true,
77
+ });
78
+ return intl.formatNumber(number, numberFormatIntlOptions);
79
+ }
80
+ const [dojoNumber] = await loadModules(["dojo/number"]);
81
+ return dojoNumber.format(number, {
82
+ type,
83
+ places,
84
+ });
85
+ }
@@ -0,0 +1,20 @@
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
+ import { loadModules as _loadModules } from "esri-loader";
17
+ export const loadModules = async (moduleNames, options) => {
18
+ const mods = await _loadModules(moduleNames, options);
19
+ return mods.map((mod) => (mod.__esModule && mod.default ? mod.default : mod));
20
+ };
@@ -0,0 +1,56 @@
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
+ // https://medium.com/stencil-tricks/implementing-internationalisation-i18n-with-stencil-5e6559554117
17
+ import { languageMap } from "./languageUtil";
18
+ import { getAssetPath } from "@stencil/core";
19
+ export function getComponentClosestLanguage(element) {
20
+ var _a, _b, _c;
21
+ const closestElement = (_a = (element.closest("[lang]"))) !== null && _a !== void 0 ? _a : (_c = (_b = element.shadowRoot) === null || _b === void 0 ? void 0 : _b.ownerDocument) === null || _c === void 0 ? void 0 : _c.documentElement;
22
+ // language set by the calling application or browser. defaults to english.
23
+ const lang = ((closestElement === null || closestElement === void 0 ? void 0 : closestElement.lang) || (navigator === null || navigator === void 0 ? void 0 : navigator.language) || "en").toLowerCase();
24
+ if (languageMap.has(lang)) {
25
+ return languageMap.get(lang);
26
+ }
27
+ else {
28
+ // "ru-RU" maps to "ru" use case
29
+ return languageMap.has(lang.slice(0, 2)) ? languageMap.get(lang.slice(0, 2)) : "en";
30
+ }
31
+ }
32
+ function fetchLocaleStringsForComponent(componentName, locale) {
33
+ return new Promise((resolve, reject) => {
34
+ fetch(getAssetPath(`../assets/t9n/${componentName}/resources_${locale}.json`)).then(result => {
35
+ if (result.ok) {
36
+ resolve(result.json());
37
+ }
38
+ else {
39
+ reject();
40
+ }
41
+ }, () => reject());
42
+ });
43
+ }
44
+ export async function getLocaleComponentStrings(element) {
45
+ const componentName = element.tagName.toLowerCase();
46
+ const componentLanguage = getComponentClosestLanguage(element);
47
+ let strings;
48
+ try {
49
+ strings = await fetchLocaleStringsForComponent(componentName, componentLanguage);
50
+ }
51
+ catch (e) {
52
+ console.warn(`no locale for ${componentName} (${componentLanguage}) loading default locale en.`);
53
+ strings = await fetchLocaleStringsForComponent(componentName, "en");
54
+ }
55
+ return [strings, componentLanguage];
56
+ }