@esri/solutions-components 0.6.9 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/assets/t9n/crowdsource-manager/resources.json +2 -1
  2. package/dist/assets/t9n/crowdsource-manager/resources_en.json +2 -1
  3. package/dist/assets/t9n/info-card/resources.json +4 -1
  4. package/dist/assets/t9n/info-card/resources_en.json +4 -1
  5. package/dist/assets/t9n/layer-table/resources.json +2 -1
  6. package/dist/assets/t9n/layer-table/resources_en.json +2 -1
  7. package/dist/assets/t9n/map-tools/resources.json +0 -3
  8. package/dist/assets/t9n/map-tools/resources_en.json +0 -3
  9. package/dist/cjs/basemap-gallery_5.cjs.entry.js +6 -61
  10. package/dist/cjs/card-manager_3.cjs.entry.js +22 -12
  11. package/dist/cjs/crowdsource-manager.cjs.entry.js +27 -5
  12. package/dist/cjs/{downloadUtils-1f057ec0.js → downloadUtils-471a6a2d.js} +16 -10
  13. package/dist/cjs/edit-card_2.cjs.entry.js +34 -2
  14. package/dist/cjs/{index.es-a1507f1c.js → index.es-33154f03.js} +1 -1
  15. package/dist/cjs/loader.cjs.js +1 -1
  16. package/dist/cjs/map-select-tools_3.cjs.entry.js +1 -1
  17. package/dist/cjs/public-notification.cjs.entry.js +1 -1
  18. package/dist/cjs/solutions-components.cjs.js +1 -1
  19. package/dist/collection/components/card-manager/card-manager.js +1 -1
  20. package/dist/collection/components/crowdsource-manager/crowdsource-manager.css +23 -2
  21. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +27 -4
  22. package/dist/collection/components/info-card/info-card.css +15 -2
  23. package/dist/collection/components/info-card/info-card.js +34 -1
  24. package/dist/collection/components/layer-table/layer-table.css +20 -0
  25. package/dist/collection/components/layer-table/layer-table.js +5 -1
  26. package/dist/collection/components/map-card/map-card.css +0 -7
  27. package/dist/collection/components/map-card/map-card.js +13 -7
  28. package/dist/collection/components/map-picker/map-picker.css +5 -1
  29. package/dist/collection/components/map-picker/map-picker.js +2 -2
  30. package/dist/collection/components/map-tools/map-tools.css +14 -0
  31. package/dist/collection/components/map-tools/map-tools.js +2 -59
  32. package/dist/collection/utils/downloadUtils.js +15 -9
  33. package/dist/collection/utils/downloadUtils.ts +21 -10
  34. package/dist/components/card-manager2.js +6 -6
  35. package/dist/components/crowdsource-manager.js +28 -5
  36. package/dist/components/downloadUtils.js +15 -9
  37. package/dist/components/info-card2.js +40 -7
  38. package/dist/components/layer-table2.js +6 -2
  39. package/dist/components/map-card2.js +14 -8
  40. package/dist/components/map-picker2.js +3 -3
  41. package/dist/components/map-tools2.js +3 -58
  42. package/dist/esm/basemap-gallery_5.entry.js +6 -61
  43. package/dist/esm/card-manager_3.entry.js +22 -12
  44. package/dist/esm/crowdsource-manager.entry.js +27 -5
  45. package/dist/esm/{downloadUtils-64c27514.js → downloadUtils-8d4c13bb.js} +16 -10
  46. package/dist/esm/edit-card_2.entry.js +34 -2
  47. package/dist/esm/{index.es-b7bc2db1.js → index.es-065c3035.js} +1 -1
  48. package/dist/esm/loader.js +1 -1
  49. package/dist/esm/map-select-tools_3.entry.js +1 -1
  50. package/dist/esm/public-notification.entry.js +1 -1
  51. package/dist/esm/solutions-components.js +1 -1
  52. package/dist/solutions-components/{p-12f06497.entry.js → p-0dd8368d.entry.js} +1 -1
  53. package/dist/solutions-components/p-46352a57.entry.js +6 -0
  54. package/dist/solutions-components/{p-22d06238.js → p-6eb4ba8f.js} +1 -1
  55. package/dist/solutions-components/{p-a26dc184.js → p-95c11620.js} +2 -2
  56. package/dist/solutions-components/p-9eba78eb.entry.js +6 -0
  57. package/dist/solutions-components/{p-b2a52acb.entry.js → p-c26cd409.entry.js} +1 -1
  58. package/dist/solutions-components/p-d4cb29ed.entry.js +6 -0
  59. package/dist/solutions-components/p-fb7ca639.entry.js +6 -0
  60. package/dist/solutions-components/solutions-components.esm.js +1 -1
  61. package/dist/solutions-components/utils/downloadUtils.ts +21 -10
  62. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +17 -0
  63. package/dist/types/components/info-card/info-card.d.ts +23 -0
  64. package/dist/types/components/map-card/map-card.d.ts +4 -0
  65. package/dist/types/components/map-tools/map-tools.d.ts +0 -42
  66. package/dist/types/utils/downloadUtils.d.ts +7 -3
  67. package/package.json +1 -1
  68. package/dist/solutions-components/p-0dce2c3b.entry.js +0 -6
  69. package/dist/solutions-components/p-476eb52c.entry.js +0 -6
  70. package/dist/solutions-components/p-8b8a6c1f.entry.js +0 -6
  71. package/dist/solutions-components/p-97a4001d.entry.js +0 -6
@@ -153,7 +153,11 @@ export class LayerTable {
153
153
  const tableNodeClass = this._fetchingData ? "display-none" : "";
154
154
  const loadingClass = this._fetchingData ? "" : "display-none";
155
155
  const alertActionClass = this._alertShowAction ? "" : "display-none";
156
- return (h(Host, null, h("calcite-shell", null, this._getTableControlRow("header"), h("div", { class: "height-full width-full" }, h("calcite-panel", { class: "height-full width-full" }, h("calcite-loader", { class: loadingClass, label: this._translations.fetchingData, scale: "l" }), h("div", { class: tableNodeClass, ref: this.onTableNodeCreate }))), h("calcite-alert", { icon: this._alertIcon, kind: this._alertKind, label: "", onCalciteAlertClose: () => this._alertClosed(), open: this._alertOpen, placement: "top" }, h("div", { slot: "title" }, this._alertTitle), h("div", { slot: "message" }, this._alertMessage), h("calcite-link", { class: alertActionClass, onClick: this._alertActionFunction, slot: "link" }, this._alertActionText)))));
156
+ const total = this._allIds.length.toString();
157
+ const selected = this._selectedIndexes.length.toString();
158
+ return (h(Host, null, h("calcite-shell", null, this._getTableControlRow("header"), h("div", { class: "height-full width-full" }, h("calcite-panel", { class: "height-full width-full" }, h("calcite-loader", { class: loadingClass, label: this._translations.fetchingData, scale: "l" }), h("div", { class: tableNodeClass, ref: this.onTableNodeCreate })), h("div", { class: "bottom-left background text-color" }, this._translations.recordsSelected
159
+ .replace("{{total}}", total)
160
+ .replace("{{selected}}", selected))), h("calcite-alert", { icon: this._alertIcon, kind: this._alertKind, label: "", onCalciteAlertClose: () => this._alertClosed(), open: this._alertOpen, placement: "top" }, h("div", { slot: "title" }, this._alertTitle), h("div", { slot: "message" }, this._alertMessage), h("calcite-link", { class: alertActionClass, onClick: this._alertActionFunction, slot: "link" }, this._alertActionText)))));
157
161
  }
158
162
  //--------------------------------------------------------------------------
159
163
  //
@@ -23,10 +23,3 @@
23
23
  .map-height {
24
24
  height: calc(100% - 58px);
25
25
  }
26
-
27
- /* Not sure how else to do this
28
- tried navigation gamepad settings but enabled: false still shows this */
29
-
30
- .esri-zoom {
31
- display: none !important;
32
- }
@@ -73,12 +73,14 @@ export class MapCard {
73
73
  * @protected
74
74
  */
75
75
  async _initModules() {
76
- const [WebMap, MapView] = await loadModules([
76
+ const [WebMap, MapView, Home] = await loadModules([
77
77
  "esri/WebMap",
78
- "esri/views/MapView"
78
+ "esri/views/MapView",
79
+ "esri/widgets/Home"
79
80
  ]);
80
81
  this.WebMap = WebMap;
81
82
  this.MapView = MapView;
83
+ this.Home = Home;
82
84
  }
83
85
  /**
84
86
  * Load the webmap for the provided webMapInfo
@@ -104,13 +106,17 @@ export class MapCard {
104
106
  map: webMap,
105
107
  resizeAlign: "top-left"
106
108
  });
109
+ this._loadedId = id;
110
+ this._searchConfiguration = this._webMapInfo.searchConfiguration;
111
+ this.mapChanged.emit({
112
+ id: id,
113
+ mapView: this.mapView
114
+ });
107
115
  await this.mapView.when(() => {
108
- this._loadedId = id;
109
- this._searchConfiguration = this._webMapInfo.searchConfiguration;
110
- this.mapChanged.emit({
111
- id: id,
112
- mapView: this.mapView
116
+ const home = new this.Home({
117
+ view: this.mapView
113
118
  });
119
+ this.mapView.ui.add(home, { position: "top-left", index: 3 });
114
120
  this.mapView.ui.add(this._mapTools, { position: "top-right", index: 0 });
115
121
  });
116
122
  }
@@ -49,7 +49,7 @@
49
49
  overflow: hidden;
50
50
  animation: calcite-scrim-fade-in var(--calcite-internal-animation-timing-medium) ease-in-out;
51
51
  background-color: var(--calcite-scrim-background);
52
- z-index: 1;
52
+ z-index: 1000;
53
53
  width: 100%;
54
54
  height: -moz-fit-content;
55
55
  height: fit-content;
@@ -58,3 +58,7 @@
58
58
  .display-none {
59
59
  display: none;
60
60
  }
61
+
62
+ .action-bar-color {
63
+ background-color: var(--calcite-ui-border-3) !important;
64
+ }
@@ -95,7 +95,7 @@ export class MapPicker {
95
95
  _getMapPicker() {
96
96
  var _a;
97
97
  const mapListIcon = this._mapListExpanded ? "chevron-up" : "chevron-down";
98
- return (h("calcite-button", { alignment: "icon-end-space-between", appearance: "solid", class: "width-full height-full", iconEnd: mapListIcon, kind: "neutral", onClick: () => this._chooseMap(), width: "full" }, (_a = this._webMapInfo) === null || _a === void 0 ? void 0 : _a.name));
98
+ return (h("calcite-button", { alignment: "icon-end-space-between", appearance: "transparent", class: "width-full height-full", iconEnd: mapListIcon, kind: "neutral", onClick: () => this._chooseMap(), width: "full" }, (_a = this._webMapInfo) === null || _a === void 0 ? void 0 : _a.name));
99
99
  }
100
100
  /**
101
101
  * Create the toolbar (controls used for map and app interactions)
@@ -105,7 +105,7 @@ export class MapPicker {
105
105
  * @protected
106
106
  */
107
107
  _getToolbar() {
108
- return (h("div", { class: "display-flex" }, h("calcite-action-bar", { class: "border-bottom-1 action-bar-size", "expand-disabled": true, layout: "horizontal", slot: "header" }, this._getMapPicker())));
108
+ return (h("div", { class: "display-flex" }, h("calcite-action-bar", { class: "action-bar-color border-bottom-1 action-bar-size", "expand-disabled": true, layout: "horizontal", slot: "header" }, this._getMapPicker())));
109
109
  }
110
110
  /**
111
111
  * Get a pick list for all maps in mapInfos
@@ -29,3 +29,17 @@
29
29
  .margin-top-1-2 {
30
30
  margin-top: 0.5rem;
31
31
  }
32
+
33
+ .square-40 {
34
+ width: 40px;
35
+ height: 40px;
36
+ }
37
+
38
+ .width-40 {
39
+ width: 40px;
40
+ }
41
+
42
+ .square-40-41 {
43
+ width: 40px;
44
+ height: 41px;
45
+ }
@@ -37,14 +37,6 @@ export class MapTools {
37
37
  // Watch handlers
38
38
  //
39
39
  //--------------------------------------------------------------------------
40
- /**
41
- * Store the home extent when the map view changes
42
- */
43
- async mapViewWatchHandler() {
44
- await this.mapView.when(() => {
45
- this._homeExtent = this.mapView.extent;
46
- });
47
- }
48
40
  /**
49
41
  * When the _showBasemapWidget property is true display the basemap gallery
50
42
  */
@@ -107,7 +99,7 @@ export class MapTools {
107
99
  const searchClass = this._showSearchWidget ? "" : "display-none";
108
100
  const basemapClass = this._showBasemapWidget ? "" : "display-none";
109
101
  const legendClass = this._showLegendWidget ? "" : "display-none";
110
- return (h(Host, null, h("div", null, h("calcite-action", { alignment: "center", class: "border", compact: false, icon: toggleIcon, onClick: () => { this._toggleTools(); }, text: "" }), h("calcite-action-bar", { class: `border margin-top-1-2 ${toolsClass}`, "expand-disabled": true, layout: this.layout }, this._getActionGroup("home", false, this._translations.home, () => void this._goHome()), this._getActionGroup("plus", false, this._translations.zoomIn, () => void this._zoomIn()), this._getActionGroup("minus", false, this._translations.zoomOut, () => void this._zoomOut()), this._getActionGroup("legend", false, this._translations.legend, () => this._showLegend()), this._getActionGroup("magnifying-glass", false, this._translations.search, () => this._search()), this._getActionGroup("expand", false, this._translations.expand, () => this._expand()), this._getActionGroup("basemap", false, this._translations.basemap, () => this._toggleBasemapPicker()))), h("basemap-gallery", { class: basemapClass, mapView: this.mapView, ref: (el) => { this._basemapElement = el; } }), h("map-search", { class: searchClass, mapView: this.mapView, ref: (el) => { this._searchElement = el; }, searchConfiguration: this.searchConfiguration }), h("map-legend", { class: legendClass, mapView: this.mapView, ref: (el) => { this._legendElement = el; } })));
102
+ return (h(Host, null, h("div", null, h("calcite-action", { alignment: "center", class: "border square-40", compact: false, icon: toggleIcon, onClick: () => { this._toggleTools(); }, scale: "s", text: "" }), h("calcite-action-bar", { class: `width-40 border margin-top-1-2 ${toolsClass}`, "expand-disabled": true, layout: this.layout }, this._getActionGroup("legend", false, this._translations.legend, () => this._showLegend()), this._getActionGroup("magnifying-glass", false, this._translations.search, () => this._search()), this._getActionGroup("expand", false, this._translations.expand, () => this._expand()), this._getActionGroup("basemap", false, this._translations.basemap, () => this._toggleBasemapPicker()))), h("basemap-gallery", { class: basemapClass, mapView: this.mapView, ref: (el) => { this._basemapElement = el; } }), h("map-search", { class: searchClass, mapView: this.mapView, ref: (el) => { this._searchElement = el; }, searchConfiguration: this.searchConfiguration }), h("map-legend", { class: legendClass, mapView: this.mapView, ref: (el) => { this._legendElement = el; } })));
111
103
  }
112
104
  //--------------------------------------------------------------------------
113
105
  //
@@ -127,17 +119,7 @@ export class MapTools {
127
119
  * @protected
128
120
  */
129
121
  _getActionGroup(icon, disabled, tip, func) {
130
- return (h("calcite-action-group", null, h("calcite-action", { alignment: "center", compact: false, disabled: disabled, icon: icon, id: icon, onClick: func, text: "" }, h("calcite-icon", { icon: "cheveron-up", scale: "s", slot: "icon" })), h("calcite-tooltip", { label: "", placement: "bottom", "reference-element": icon }, h("span", null, tip))));
131
- }
132
- /**
133
- * Go to the exent that was first used when loading the map
134
- *
135
- * @returns void
136
- *
137
- * @protected
138
- */
139
- async _goHome() {
140
- await this.mapView.goTo(this._homeExtent);
122
+ return (h("calcite-action-group", { class: "square-40-41" }, h("calcite-action", { alignment: "center", class: "square-40", compact: false, disabled: disabled, icon: icon, id: icon, onClick: func, scale: "s", text: "" }, h("calcite-icon", { icon: "cheveron-up", scale: "s", slot: "icon" })), h("calcite-tooltip", { label: "", placement: "trailing", "reference-element": icon }, h("span", null, tip))));
141
123
  }
142
124
  // need to discuss this with the team
143
125
  _showLegend() {
@@ -149,42 +131,6 @@ export class MapTools {
149
131
  this._showSearchWidget = !this._showSearchWidget;
150
132
  this._showTools = false;
151
133
  }
152
- /**
153
- * Fixed zoom in
154
- *
155
- * @returns void
156
- *
157
- * @protected
158
- */
159
- async _zoomIn() {
160
- await this._zoom(this.mapView.zoom + 1);
161
- }
162
- /**
163
- * Fixed zoom out
164
- *
165
- * @returns void
166
- *
167
- * @protected
168
- */
169
- async _zoomOut() {
170
- await this._zoom(this.mapView.zoom - 1);
171
- }
172
- /**
173
- * Zoom in/out at the maps current center point
174
- *
175
- * @param zoom Number to zoom level to go to
176
- *
177
- * @returns void
178
- *
179
- * @protected
180
- */
181
- async _zoom(zoom) {
182
- var _a;
183
- await ((_a = this.mapView) === null || _a === void 0 ? void 0 : _a.goTo({
184
- target: this.mapView.center,
185
- zoom
186
- }));
187
- }
188
134
  /**
189
135
  * Show/Hide the basemap picker
190
136
  *
@@ -342,9 +288,6 @@ export class MapTools {
342
288
  static get elementRef() { return "el"; }
343
289
  static get watchers() {
344
290
  return [{
345
- "propName": "mapView",
346
- "methodName": "mapViewWatchHandler"
347
- }, {
348
291
  "propName": "_showBasemapWidget",
349
292
  "methodName": "_showBasemapWidgetWatchHandler"
350
293
  }, {
@@ -324,8 +324,8 @@ export function _getFieldNamesFromFieldExpressions(fieldExpressions) {
324
324
  * all attributes are exported
325
325
  * @param attributeFormats Empty object to hold the formats for each attribute in a feature; the object is filled
326
326
  * with formats by this function
327
- * @returns A Promise resolving to the format of a single label, e.g., for ILabelFormat type "pattern":
328
- * "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}"
327
+ * @returns A Promise resolving to the format of a single label with fields coerced to lowercase, e.g.,
328
+ * for ILabelFormat type "pattern": "{name}|{street}|{city}, {state} {zip}"
329
329
  */
330
330
  export async function _getLabelFormat(layer, formatUsingLayerPopup, attributeFormats) {
331
331
  var _a, _b, _c, _d, _e, _f;
@@ -338,7 +338,7 @@ export async function _getLabelFormat(layer, formatUsingLayerPopup, attributeFor
338
338
  // Extract any format info that we have
339
339
  fieldInfo => {
340
340
  if (fieldInfo.format) {
341
- attributeFormats[fieldInfo.fieldName] = fieldInfo.format;
341
+ attributeFormats[fieldInfo.fieldName.toLowerCase()] = fieldInfo.format;
342
342
  }
343
343
  });
344
344
  // What is the nature of the label content?
@@ -447,11 +447,14 @@ export async function _prepareLabels(layer, ids, formatUsingLayerPopup = true, i
447
447
  // Get the features to export
448
448
  const featureSet = await queryFeaturesByID(ids, layer, [], false);
449
449
  // Get field data types. Do we have any domain-based fields?
450
+ const attributeOrigNames = {};
450
451
  const attributeTypes = {};
451
452
  const attributeDomains = {};
452
453
  layer.fields.forEach(field => {
453
- attributeTypes[field.name] = field.type;
454
- attributeDomains[field.name] = field.domain;
454
+ const lowercaseFieldname = field.name.toLowerCase();
455
+ attributeOrigNames[lowercaseFieldname] = field.name;
456
+ attributeDomains[lowercaseFieldname] = field.domain;
457
+ attributeTypes[lowercaseFieldname] = field.type;
455
458
  });
456
459
  const attributeFormats = {};
457
460
  // Get the label formatting, if any
@@ -462,7 +465,7 @@ export async function _prepareLabels(layer, ids, formatUsingLayerPopup = true, i
462
465
  await _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomains, includeHeaderNames)
463
466
  : labelFormat.type == "pattern" ?
464
467
  // Export attributes in format
465
- await _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDomains, attributeFormats, labelFormat.format, includeHeaderNames)
468
+ await _prepareLabelsFromPattern(featureSet, attributeOrigNames, attributeTypes, attributeDomains, attributeFormats, labelFormat.format, includeHeaderNames)
466
469
  :
467
470
  // Export attributes in expression
468
471
  await _prepareLabelsUsingExecutor(featureSet, labelFormat.format);
@@ -482,7 +485,8 @@ export async function _prepareLabelsFromAll(featureSet, attributeTypes, attribut
482
485
  // Export all attributes
483
486
  const labels = featureSet.map(feature => {
484
487
  return Object.keys(feature.attributes).map((attributeName) => {
485
- return _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], null, intl);
488
+ const lowercaseFieldname = attributeName.toLowerCase();
489
+ return _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname], null, intl);
486
490
  });
487
491
  });
488
492
  // Add header names
@@ -500,6 +504,7 @@ export async function _prepareLabelsFromAll(featureSet, attributeTypes, attribut
500
504
  * Creates labels from attributes in a layer popup.
501
505
  *
502
506
  * @param featureSet Features to convert to labels
507
+ * @param attributeOrigNames Mapping from lowercase field names to original field names
503
508
  * @param attributeTypes Type for each attribute in a feature
504
509
  * @param attributeDomains Domains for each attribute in a feature
505
510
  * @param attributeFormats Formats for each attribute in a feature
@@ -507,7 +512,7 @@ export async function _prepareLabelsFromAll(featureSet, attributeTypes, attribut
507
512
  * @param includeHeaderNames Add the label format at the front of the list of generated labels
508
513
  * @returns Promise resolving with list of labels, each of which is a list of label lines
509
514
  */
510
- export async function _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDomains, attributeFormats, labelFormat, includeHeaderNames = false) {
515
+ export async function _prepareLabelsFromPattern(featureSet, attributeOrigNames, attributeTypes, attributeDomains, attributeFormats, labelFormat, includeHeaderNames = false) {
511
516
  const [intl] = await loadModules(["esri/intl"]);
512
517
  // Find the label fields that we need to replace with values
513
518
  const attributeExpressionMatches = _getFieldExpressionsFromLabel(labelFormat);
@@ -517,7 +522,8 @@ export async function _prepareLabelsFromPattern(featureSet, attributeTypes, attr
517
522
  let labelPrep = labelFormat;
518
523
  // Replace non-Arcade fields in this feature
519
524
  attributeNames.forEach((attributeName, i) => {
520
- const value = _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], attributeFormats[attributeName], intl);
525
+ const lowercaseFieldname = attributeName.toLowerCase();
526
+ const value = _prepareAttributeValue(feature.attributes[attributeOrigNames[lowercaseFieldname]], attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname], attributeFormats[lowercaseFieldname], intl);
521
527
  labelPrep = labelPrep.replace(attributeExpressionMatches[i], value);
522
528
  });
523
529
  // Split label into lines
@@ -24,6 +24,10 @@ import { IExportInfo, IExportInfos } from "../utils/interfaces";
24
24
 
25
25
  export { ILabel } from "./pdfUtils";
26
26
 
27
+ export interface IAttributeOrigNames {
28
+ [lowercaseName: string]: string;
29
+ }
30
+
27
31
  export interface IAttributeDomains {
28
32
  [attributeName: string]: __esri.CodedValueDomain | __esri.RangeDomain | __esri.InheritedDomain | null;
29
33
  }
@@ -436,8 +440,8 @@ export function _getFieldNamesFromFieldExpressions(
436
440
  * all attributes are exported
437
441
  * @param attributeFormats Empty object to hold the formats for each attribute in a feature; the object is filled
438
442
  * with formats by this function
439
- * @returns A Promise resolving to the format of a single label, e.g., for ILabelFormat type "pattern":
440
- * "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}"
443
+ * @returns A Promise resolving to the format of a single label with fields coerced to lowercase, e.g.,
444
+ * for ILabelFormat type "pattern": "{name}|{street}|{city}, {state} {zip}"
441
445
  */
442
446
  export async function _getLabelFormat(
443
447
  layer: __esri.FeatureLayer,
@@ -454,7 +458,7 @@ export async function _getLabelFormat(
454
458
  // Extract any format info that we have
455
459
  fieldInfo => {
456
460
  if (fieldInfo.format) {
457
- attributeFormats[fieldInfo.fieldName] = fieldInfo.format;
461
+ attributeFormats[fieldInfo.fieldName.toLowerCase()] = fieldInfo.format;
458
462
  }
459
463
  }
460
464
  );
@@ -586,12 +590,15 @@ export async function _prepareLabels(
586
590
  const featureSet = await queryFeaturesByID(ids, layer, [], false);
587
591
 
588
592
  // Get field data types. Do we have any domain-based fields?
593
+ const attributeOrigNames: IAttributeOrigNames = {};
589
594
  const attributeTypes: IAttributeTypes = {};
590
595
  const attributeDomains: IAttributeDomains = {};
591
596
  layer.fields.forEach(
592
597
  field => {
593
- attributeTypes[field.name] = field.type;
594
- attributeDomains[field.name] = field.domain;
598
+ const lowercaseFieldname = field.name.toLowerCase();
599
+ attributeOrigNames[lowercaseFieldname] = field.name;
600
+ attributeDomains[lowercaseFieldname] = field.domain;
601
+ attributeTypes[lowercaseFieldname] = field.type;
595
602
  }
596
603
  );
597
604
  const attributeFormats: IAttributeFormats = {};
@@ -605,7 +612,7 @@ export async function _prepareLabels(
605
612
  await _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomains, includeHeaderNames)
606
613
  : labelFormat.type == "pattern" ?
607
614
  // Export attributes in format
608
- await _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDomains,
615
+ await _prepareLabelsFromPattern(featureSet, attributeOrigNames, attributeTypes, attributeDomains,
609
616
  attributeFormats, labelFormat.format as string, includeHeaderNames)
610
617
  :
611
618
  // Export attributes in expression
@@ -636,8 +643,9 @@ export async function _prepareLabelsFromAll(
636
643
  feature => {
637
644
  return Object.keys(feature.attributes).map(
638
645
  (attributeName: string) => {
646
+ const lowercaseFieldname = attributeName.toLowerCase();
639
647
  return _prepareAttributeValue(feature.attributes[attributeName],
640
- attributeTypes[attributeName], attributeDomains[attributeName],
648
+ attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname],
641
649
  null, intl);
642
650
  }
643
651
  );
@@ -661,6 +669,7 @@ export async function _prepareLabelsFromAll(
661
669
  * Creates labels from attributes in a layer popup.
662
670
  *
663
671
  * @param featureSet Features to convert to labels
672
+ * @param attributeOrigNames Mapping from lowercase field names to original field names
664
673
  * @param attributeTypes Type for each attribute in a feature
665
674
  * @param attributeDomains Domains for each attribute in a feature
666
675
  * @param attributeFormats Formats for each attribute in a feature
@@ -670,6 +679,7 @@ export async function _prepareLabelsFromAll(
670
679
  */
671
680
  export async function _prepareLabelsFromPattern(
672
681
  featureSet: __esri.Graphic[],
682
+ attributeOrigNames: IAttributeOrigNames,
673
683
  attributeTypes: IAttributeTypes,
674
684
  attributeDomains: IAttributeDomains,
675
685
  attributeFormats: IAttributeFormats,
@@ -690,9 +700,10 @@ export async function _prepareLabelsFromPattern(
690
700
  // Replace non-Arcade fields in this feature
691
701
  attributeNames.forEach(
692
702
  (attributeName: string, i: number) => {
693
- const value = _prepareAttributeValue(feature.attributes[attributeName],
694
- attributeTypes[attributeName], attributeDomains[attributeName],
695
- attributeFormats[attributeName], intl);
703
+ const lowercaseFieldname = attributeName.toLowerCase();
704
+ const value = _prepareAttributeValue(feature.attributes[attributeOrigNames[lowercaseFieldname]],
705
+ attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname],
706
+ attributeFormats[lowercaseFieldname], intl);
696
707
  labelPrep = labelPrep.replace(attributeExpressionMatches[i], value);
697
708
 
698
709
  },
@@ -7,8 +7,8 @@ import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal
7
7
  import { g as getLocaleComponentStrings } from './locale.js';
8
8
  import { q as queryFeaturesByID } from './queryUtils.js';
9
9
  import { g as getLayer } from './mapViewUtils.js';
10
- import { d as defineCustomElement$a } from './action.js';
11
- import { d as defineCustomElement$9 } from './alert.js';
10
+ import { d as defineCustomElement$a } from './alert.js';
11
+ import { d as defineCustomElement$9 } from './button.js';
12
12
  import { d as defineCustomElement$8 } from './chip.js';
13
13
  import { d as defineCustomElement$7 } from './icon.js';
14
14
  import { d as defineCustomElement$6 } from './loader.js';
@@ -84,7 +84,7 @@ const CardManager = /*@__PURE__*/ proxyCustomElement(class CardManager extends H
84
84
  var _a, _b;
85
85
  const featuresClass = ((_a = this._graphics) === null || _a === void 0 ? void 0 : _a.length) > 0 ? "" : "display-none";
86
86
  const messageClass = ((_b = this._graphics) === null || _b === void 0 ? void 0 : _b.length) > 0 ? "display-none" : "";
87
- return (h(Host, null, h("div", { class: "border-rounded overflow-auto height-full" }, h("calcite-shell", { class: "position-relative padding-1 " + featuresClass }, h("div", null, h("info-card", { graphics: this._graphics, isLoading: this._cardLoading, mapView: this.mapView, zoomAndScrollToSelected: this.zoomAndScrollToSelected }))), h("div", { class: "padding-1 " + messageClass }, h("calcite-notice", { icon: "table", open: true }, h("div", { slot: "message" }, this._translations.selectFeaturesToStart))))));
87
+ return (h(Host, null, h("div", { class: "border-rounded overflow-auto height-full" }, h("calcite-shell", { class: "position-relative " + featuresClass }, h("div", null, h("info-card", { graphics: this._graphics, isLoading: this._cardLoading, mapView: this.mapView, zoomAndScrollToSelected: this.zoomAndScrollToSelected }))), h("div", { class: "padding-1 " + messageClass }, h("calcite-notice", { icon: "table", open: true }, h("div", { slot: "message" }, this._translations.selectFeaturesToStart))))));
88
88
  }
89
89
  //--------------------------------------------------------------------------
90
90
  //
@@ -115,19 +115,19 @@ function defineCustomElement() {
115
115
  if (typeof customElements === "undefined") {
116
116
  return;
117
117
  }
118
- const components = ["card-manager", "calcite-action", "calcite-alert", "calcite-chip", "calcite-icon", "calcite-loader", "calcite-notice", "calcite-shell", "calcite-tooltip", "edit-card", "info-card"];
118
+ const components = ["card-manager", "calcite-alert", "calcite-button", "calcite-chip", "calcite-icon", "calcite-loader", "calcite-notice", "calcite-shell", "calcite-tooltip", "edit-card", "info-card"];
119
119
  components.forEach(tagName => { switch (tagName) {
120
120
  case "card-manager":
121
121
  if (!customElements.get(tagName)) {
122
122
  customElements.define(tagName, CardManager);
123
123
  }
124
124
  break;
125
- case "calcite-action":
125
+ case "calcite-alert":
126
126
  if (!customElements.get(tagName)) {
127
127
  defineCustomElement$a();
128
128
  }
129
129
  break;
130
- case "calcite-alert":
130
+ case "calcite-button":
131
131
  if (!customElements.get(tagName)) {
132
132
  defineCustomElement$9();
133
133
  }
@@ -48,7 +48,7 @@ import { d as defineCustomElement$4 } from './map-picker2.js';
48
48
  import { d as defineCustomElement$3 } from './map-search2.js';
49
49
  import { d as defineCustomElement$2 } from './map-tools2.js';
50
50
 
51
- const crowdsourceManagerCss = ":host{display:block;--calcite-label-margin-bottom:0px}.padding-1-2{padding:0.5rem}.display-flex{display:flex}.width-full{width:100%}.width-1-2{position:relative;width:50%}.width-1-3{position:relative;width:33.33%}.width-2-3{position:relative;width:66.66%}.width-0{width:0}.height-full{height:100%}.height-1-2{position:relative;height:50%}.height-0{height:0}.toggle-node{width:51px;height:51px}.overflow-hidden{overflow:hidden}.flex-column{flex-direction:column}.border{border:1px solid var(--calcite-ui-border-3)}.border-bottom{border-bottom:1px solid var(--calcite-ui-border-3)}.position-relative{position:relative}.height-50{height:50%}.adjusted-height-50{height:calc(50% - 0.5rem)}.adjusted-height-100{height:calc(100% - 1rem)}.display-none{display:none}.height-53{height:53px}.position-absolute-53{position:absolute;top:53px}.display-grid{display:grid}";
51
+ const crowdsourceManagerCss = ":host{display:block;--calcite-label-margin-bottom:0px}.padding-1-2{padding:0.5rem}.display-flex{display:flex}.width-full{width:100%}.width-1-2{position:relative;width:50%}.width-1-3{position:relative;width:33.33%}.width-2-3{position:relative;width:66.66%}.width-0{width:0}.height-full{height:100%}.height-1-2{position:relative;height:50%}.height-0{height:0}.toggle-node{width:51px;height:51px}.overflow-hidden{overflow:hidden}.flex-column{flex-direction:column}.border{border:1px solid var(--calcite-ui-border-3)}.border-bottom{border-bottom:1px solid var(--calcite-ui-border-3)}.position-relative{position:relative}.height-50{height:50%}.adjusted-height-50{height:calc(50% - 0.5rem - 25px)}.adjusted-height-100{height:calc(100% - 1rem - 50px)}.adjusted-height-100-50{height:calc(100% - 50px)}.display-none{display:none}.height-53{height:53px}.position-absolute-53{position:absolute;top:53px}.display-grid{display:grid}.height-49-px{height:49px}.height-50-px{height:50px}.padding-inline-end-75{padding-inline-end:0.75rem}.align-items-center{align-items:center}";
52
52
 
53
53
  const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceManager extends HTMLElement {
54
54
  constructor() {
@@ -60,6 +60,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
60
60
  this.mapInfos = [];
61
61
  this.searchConfiguration = undefined;
62
62
  this.zoomAndScrollToSelected = false;
63
+ this._expandPopup = false;
63
64
  this._translations = undefined;
64
65
  this._layoutMode = ELayoutMode.GRID;
65
66
  this._mapView = undefined;
@@ -91,6 +92,9 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
91
92
  */
92
93
  async mapChanged(evt) {
93
94
  const mapChange = evt.detail;
95
+ // close popup by default when the map changes otherwise other components that rely on the view don't work since it
96
+ // doesn't seem to fully load when it's not visible
97
+ this._expandPopup = false;
94
98
  this._mapInfo = this._getMapInfo(mapChange.id);
95
99
  this._mapView = mapChange.mapView;
96
100
  this._mapView.popupEnabled = false;
@@ -227,7 +231,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
227
231
  */
228
232
  _getMapAndCard(layoutMode, panelOpen, hideMap) {
229
233
  const mapSizeClass = this._getMapSizeClass(layoutMode, panelOpen);
230
- return this.classicGrid ? (h("div", { class: `${mapSizeClass} overflow-hidden` }, this._getCardNode(layoutMode, hideMap), this._getMapNode(layoutMode, hideMap))) : (h("div", { class: `${mapSizeClass} overflow-hidden` }, this._getMapNode(layoutMode, hideMap), this._getCardNode(layoutMode, hideMap)));
234
+ return this.classicGrid ? (h("div", { class: `${mapSizeClass} overflow-hidden` }, this._getCardNode(layoutMode, hideMap), this._getMapNode(layoutMode, hideMap))) : (h("div", { class: `${mapSizeClass} overflow-hidden` }, this._getMapNode(layoutMode, hideMap), this._getPopupExpandNode(), this._getCardNode(layoutMode, hideMap)));
231
235
  }
232
236
  /**
233
237
  * Get the map node based for the current layout options
@@ -241,9 +245,27 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
241
245
  _getMapNode(layoutMode, hideMap) {
242
246
  const mapDisplayClass = this.classicGrid && layoutMode === ELayoutMode.GRID ? "display-flex height-full width-1-2" :
243
247
  layoutMode === ELayoutMode.GRID && !hideMap ? "" : "display-none";
244
- const mapContainerClass = this.classicGrid && layoutMode === ELayoutMode.GRID ? "width-full" : "adjusted-height-50";
248
+ const mapContainerClass = this.classicGrid && layoutMode === ELayoutMode.GRID ? "width-full" : this._expandPopup ? "height-50-px" : "adjusted-height-50";
245
249
  return (h("div", { class: `${mapContainerClass} overflow-hidden ${mapDisplayClass}` }, h("map-card", { class: "width-full", mapInfos: this.mapInfos })));
246
250
  }
251
+ /**
252
+ * Get the expand node for the popup information
253
+ *
254
+ * @returns the expand node
255
+ * @protected
256
+ */
257
+ _getPopupExpandNode() {
258
+ const icon = this._expandPopup ? "chevrons-down" : "chevrons-up";
259
+ return (h("div", { class: "height-49-px calcite-mode-dark" }, h("calcite-panel", null, h("div", { class: "display-flex align-items-center", slot: "header-content" }, h("calcite-icon", { class: "padding-inline-end-75", icon: "information", scale: "s" }), h("div", null, this._translations.information)), h("calcite-action", { class: "height-49-px", icon: icon, onClick: () => this._togglePopup(), slot: "header-actions-end" }))));
260
+ }
261
+ /**
262
+ * Toggle the popup information
263
+ *
264
+ * @protected
265
+ */
266
+ _togglePopup() {
267
+ this._expandPopup = !this._expandPopup;
268
+ }
247
269
  /**
248
270
  * Get the card node based for the current layout options
249
271
  *
@@ -255,9 +277,9 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
255
277
  */
256
278
  _getCardNode(layoutMode, hideMap) {
257
279
  const cardManagerHeight = this.classicGrid && layoutMode === ELayoutMode.GRID ? "" :
258
- layoutMode === ELayoutMode.GRID && !hideMap ? "adjusted-height-50" : "adjusted-height-100";
280
+ layoutMode === ELayoutMode.GRID && !this._expandPopup && !hideMap ? "adjusted-height-50" : "adjusted-height-100";
259
281
  const cardManagerContainer = this.classicGrid && layoutMode === ELayoutMode.GRID ?
260
- "width-full adjusted-height-100" : "width-50 height-full";
282
+ "width-full adjusted-height-100" : this._expandPopup ? "width-50 adjusted-height-100-50" : "width-50 height-full";
261
283
  return (h("div", { class: `padding-1-2 ${cardManagerContainer}` }, h("card-manager", { class: `${cardManagerHeight} width-full`, mapView: this === null || this === void 0 ? void 0 : this._mapView, zoomAndScrollToSelected: this.zoomAndScrollToSelected })));
262
284
  }
263
285
  /**
@@ -325,6 +347,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
325
347
  "mapInfos": [16],
326
348
  "searchConfiguration": [16],
327
349
  "zoomAndScrollToSelected": [4, "zoom-and-scroll-to-selected"],
350
+ "_expandPopup": [32],
328
351
  "_translations": [32],
329
352
  "_layoutMode": [32],
330
353
  "_mapView": [32],
@@ -2520,8 +2520,8 @@ function _getFieldNamesFromFieldExpressions(fieldExpressions) {
2520
2520
  * all attributes are exported
2521
2521
  * @param attributeFormats Empty object to hold the formats for each attribute in a feature; the object is filled
2522
2522
  * with formats by this function
2523
- * @returns A Promise resolving to the format of a single label, e.g., for ILabelFormat type "pattern":
2524
- * "{NAME}|{STREET}|{CITY}, {STATE} {ZIP}"
2523
+ * @returns A Promise resolving to the format of a single label with fields coerced to lowercase, e.g.,
2524
+ * for ILabelFormat type "pattern": "{name}|{street}|{city}, {state} {zip}"
2525
2525
  */
2526
2526
  async function _getLabelFormat(layer, formatUsingLayerPopup, attributeFormats) {
2527
2527
  var _a, _b, _c, _d, _e, _f;
@@ -2534,7 +2534,7 @@ async function _getLabelFormat(layer, formatUsingLayerPopup, attributeFormats) {
2534
2534
  // Extract any format info that we have
2535
2535
  fieldInfo => {
2536
2536
  if (fieldInfo.format) {
2537
- attributeFormats[fieldInfo.fieldName] = fieldInfo.format;
2537
+ attributeFormats[fieldInfo.fieldName.toLowerCase()] = fieldInfo.format;
2538
2538
  }
2539
2539
  });
2540
2540
  // What is the nature of the label content?
@@ -2643,11 +2643,14 @@ async function _prepareLabels(layer, ids, formatUsingLayerPopup = true, includeH
2643
2643
  // Get the features to export
2644
2644
  const featureSet = await queryFeaturesByID(ids, layer, [], false);
2645
2645
  // Get field data types. Do we have any domain-based fields?
2646
+ const attributeOrigNames = {};
2646
2647
  const attributeTypes = {};
2647
2648
  const attributeDomains = {};
2648
2649
  layer.fields.forEach(field => {
2649
- attributeTypes[field.name] = field.type;
2650
- attributeDomains[field.name] = field.domain;
2650
+ const lowercaseFieldname = field.name.toLowerCase();
2651
+ attributeOrigNames[lowercaseFieldname] = field.name;
2652
+ attributeDomains[lowercaseFieldname] = field.domain;
2653
+ attributeTypes[lowercaseFieldname] = field.type;
2651
2654
  });
2652
2655
  const attributeFormats = {};
2653
2656
  // Get the label formatting, if any
@@ -2658,7 +2661,7 @@ async function _prepareLabels(layer, ids, formatUsingLayerPopup = true, includeH
2658
2661
  await _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomains, includeHeaderNames)
2659
2662
  : labelFormat.type == "pattern" ?
2660
2663
  // Export attributes in format
2661
- await _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDomains, attributeFormats, labelFormat.format, includeHeaderNames)
2664
+ await _prepareLabelsFromPattern(featureSet, attributeOrigNames, attributeTypes, attributeDomains, attributeFormats, labelFormat.format, includeHeaderNames)
2662
2665
  :
2663
2666
  // Export attributes in expression
2664
2667
  await _prepareLabelsUsingExecutor(featureSet, labelFormat.format);
@@ -2678,7 +2681,8 @@ async function _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomain
2678
2681
  // Export all attributes
2679
2682
  const labels = featureSet.map(feature => {
2680
2683
  return Object.keys(feature.attributes).map((attributeName) => {
2681
- return _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], null, intl);
2684
+ const lowercaseFieldname = attributeName.toLowerCase();
2685
+ return _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname], null, intl);
2682
2686
  });
2683
2687
  });
2684
2688
  // Add header names
@@ -2696,6 +2700,7 @@ async function _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomain
2696
2700
  * Creates labels from attributes in a layer popup.
2697
2701
  *
2698
2702
  * @param featureSet Features to convert to labels
2703
+ * @param attributeOrigNames Mapping from lowercase field names to original field names
2699
2704
  * @param attributeTypes Type for each attribute in a feature
2700
2705
  * @param attributeDomains Domains for each attribute in a feature
2701
2706
  * @param attributeFormats Formats for each attribute in a feature
@@ -2703,7 +2708,7 @@ async function _prepareLabelsFromAll(featureSet, attributeTypes, attributeDomain
2703
2708
  * @param includeHeaderNames Add the label format at the front of the list of generated labels
2704
2709
  * @returns Promise resolving with list of labels, each of which is a list of label lines
2705
2710
  */
2706
- async function _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDomains, attributeFormats, labelFormat, includeHeaderNames = false) {
2711
+ async function _prepareLabelsFromPattern(featureSet, attributeOrigNames, attributeTypes, attributeDomains, attributeFormats, labelFormat, includeHeaderNames = false) {
2707
2712
  const [intl] = await loadModules(["esri/intl"]);
2708
2713
  // Find the label fields that we need to replace with values
2709
2714
  const attributeExpressionMatches = _getFieldExpressionsFromLabel(labelFormat);
@@ -2713,7 +2718,8 @@ async function _prepareLabelsFromPattern(featureSet, attributeTypes, attributeDo
2713
2718
  let labelPrep = labelFormat;
2714
2719
  // Replace non-Arcade fields in this feature
2715
2720
  attributeNames.forEach((attributeName, i) => {
2716
- const value = _prepareAttributeValue(feature.attributes[attributeName], attributeTypes[attributeName], attributeDomains[attributeName], attributeFormats[attributeName], intl);
2721
+ const lowercaseFieldname = attributeName.toLowerCase();
2722
+ const value = _prepareAttributeValue(feature.attributes[attributeOrigNames[lowercaseFieldname]], attributeTypes[lowercaseFieldname], attributeDomains[lowercaseFieldname], attributeFormats[lowercaseFieldname], intl);
2717
2723
  labelPrep = labelPrep.replace(attributeExpressionMatches[i], value);
2718
2724
  });
2719
2725
  // Split label into lines