@esri/solutions-components 0.6.9 → 0.6.10

Sign up to get free protection for your applications and to get access to all the features.
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