@esri/solutions-components 0.7.9 → 0.7.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/dist/cjs/basemap-gallery_7.cjs.entry.js +1 -1
  2. package/dist/cjs/calcite-alert_3.cjs.entry.js +1 -1
  3. package/dist/cjs/calcite-combobox_6.cjs.entry.js +1 -1
  4. package/dist/cjs/card-manager_3.cjs.entry.js +154 -17
  5. package/dist/cjs/crowdsource-manager.cjs.entry.js +2 -1
  6. package/dist/cjs/{downloadUtils-95e4a5b2.js → downloadUtils-8f50633d.js} +2 -2
  7. package/dist/cjs/{index.es-a88403f8.js → index.es-140aa937.js} +2 -2
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/cjs/map-select-tools_3.cjs.entry.js +2 -2
  10. package/dist/cjs/{mapViewUtils-b7d9e71c.js → mapViewUtils-569e9644.js} +17 -0
  11. package/dist/cjs/public-notification.cjs.entry.js +2 -2
  12. package/dist/cjs/solutions-components.cjs.js +1 -1
  13. package/dist/collection/components/crowdsource-manager/crowdsource-manager.js +3 -1
  14. package/dist/collection/components/layer-table/layer-table.js +145 -16
  15. package/dist/collection/components/map-card/map-card.js +10 -0
  16. package/dist/collection/components/map-picker/map-picker.js +1 -1
  17. package/dist/collection/demos/crowdsource-manager.html +21 -3
  18. package/dist/collection/utils/queryUtils.js +16 -0
  19. package/dist/collection/utils/queryUtils.ts +21 -0
  20. package/dist/components/crowdsource-manager.js +3 -1
  21. package/dist/components/layer-table2.js +144 -16
  22. package/dist/components/map-card2.js +10 -0
  23. package/dist/components/map-picker2.js +1 -1
  24. package/dist/components/map-select-tools2.js +1 -1
  25. package/dist/components/queryUtils.js +17 -1
  26. package/dist/components/refine-selection2.js +1 -1
  27. package/dist/esm/basemap-gallery_7.entry.js +1 -1
  28. package/dist/esm/calcite-alert_3.entry.js +1 -1
  29. package/dist/esm/calcite-combobox_6.entry.js +1 -1
  30. package/dist/esm/card-manager_3.entry.js +154 -17
  31. package/dist/esm/crowdsource-manager.entry.js +2 -1
  32. package/dist/esm/{downloadUtils-83dd2143.js → downloadUtils-9dee8bc0.js} +2 -2
  33. package/dist/esm/{index.es-0c98e2f3.js → index.es-54e86c8e.js} +2 -2
  34. package/dist/esm/loader.js +1 -1
  35. package/dist/esm/map-select-tools_3.entry.js +2 -2
  36. package/dist/esm/{mapViewUtils-3ff1c264.js → mapViewUtils-066602d5.js} +17 -1
  37. package/dist/esm/public-notification.entry.js +2 -2
  38. package/dist/esm/solutions-components.js +1 -1
  39. package/dist/solutions-components/demos/crowdsource-manager.html +21 -3
  40. package/dist/solutions-components/{p-a9bbd352.entry.js → p-13bfc206.entry.js} +1 -1
  41. package/dist/solutions-components/{p-d6050d57.js → p-1bdd64a0.js} +2 -2
  42. package/dist/solutions-components/{p-b7e2c75b.js → p-531d91d6.js} +1 -1
  43. package/dist/solutions-components/p-623321ac.entry.js +6 -0
  44. package/dist/solutions-components/{p-dcd6e7b9.entry.js → p-6656c53e.entry.js} +1 -1
  45. package/dist/solutions-components/{p-a5d924a9.entry.js → p-683cded6.entry.js} +1 -1
  46. package/dist/solutions-components/{p-95ebc2e5.entry.js → p-c2b20b85.entry.js} +1 -1
  47. package/dist/solutions-components/p-c7ff24df.entry.js +6 -0
  48. package/dist/solutions-components/{p-b030a151.js → p-dfdb8411.js} +1 -1
  49. package/dist/solutions-components/p-e726ae50.entry.js +6 -0
  50. package/dist/solutions-components/solutions-components.esm.js +1 -1
  51. package/dist/solutions-components/utils/queryUtils.ts +21 -0
  52. package/dist/types/components/crowdsource-manager/crowdsource-manager.d.ts +4 -4
  53. package/dist/types/components/layer-table/layer-table.d.ts +44 -1
  54. package/dist/types/utils/queryUtils.d.ts +11 -0
  55. package/package.json +1 -1
  56. package/dist/solutions-components/p-c556ed60.entry.js +0 -6
  57. package/dist/solutions-components/p-c9b4d52f.entry.js +0 -6
  58. package/dist/solutions-components/p-f7870ec1.entry.js +0 -6
@@ -7,7 +7,7 @@ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/
7
7
  import { l as loadModules } from './loadModules.js';
8
8
  import { g as getLocaleComponentStrings } from './locale.js';
9
9
  import { b as goToSelection, g as getLayerOrTable } from './mapViewUtils.js';
10
- import { b as queryAllIds, c as queryFeaturesByGlobalID } from './queryUtils.js';
10
+ import { b as queryFeatureIds, c as queryAllIds, d as queryFeaturesByGlobalID } from './queryUtils.js';
11
11
  import { d as downloadCSV } from './downloadUtils.js';
12
12
  import { d as defineCustomElement$C } from './action.js';
13
13
  import { d as defineCustomElement$B } from './action-bar.js';
@@ -59,6 +59,10 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
59
59
  * number[]: A list of all IDs for the current layer
60
60
  */
61
61
  this._allIds = [];
62
+ /**
63
+ * boolean: When true the ctrl key is currently pressed
64
+ */
65
+ this._ctrlIsPressed = false;
62
66
  /**
63
67
  * boolean: When true the default global id provided via url param has been honored and should now be ignored
64
68
  */
@@ -67,6 +71,14 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
67
71
  * boolean: When true the default OID provided via url param has been honored and should now be ignored
68
72
  */
69
73
  this._defaultOidHonored = false;
74
+ /**
75
+ * boolean: When true the shift key is currently pressed
76
+ */
77
+ this._shiftIsPressed = false;
78
+ /**
79
+ * boolean: When true any onChange handeling will be skipped
80
+ */
81
+ this._skipOnChange = false;
70
82
  /**
71
83
  * bool: When true the table is being sorted
72
84
  */
@@ -157,6 +169,15 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
157
169
  }
158
170
  });
159
171
  }
172
+ /**
173
+ * watch for changes in map info and recheck the tool infos
174
+ */
175
+ async mapInfoWatchHandler() {
176
+ var _a;
177
+ if (((_a = this._toolInfos) === null || _a === void 0 ? void 0 : _a.length) > 0) {
178
+ this._initToolInfos();
179
+ }
180
+ }
160
181
  /**
161
182
  * watch for changes in map view and get the first layer
162
183
  */
@@ -271,6 +292,8 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
271
292
  async componentDidLoad() {
272
293
  this._resizeObserver.observe(this._toolbar);
273
294
  document.onclick = (e) => this._handleDocumentClick(e);
295
+ document.onkeydown = (e) => this._handleKeyDown(e);
296
+ document.onkeyup = (e) => this._handleKeyUp(e);
274
297
  }
275
298
  /**
276
299
  * Called after the component is rendered
@@ -750,18 +773,8 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
750
773
  this._initColumnsInfo();
751
774
  this._checkEditEnabled();
752
775
  await this._table.when(() => {
753
- this._table.highlightIds.on("change", () => {
754
- // https://github.com/Esri/solutions-components/issues/365
755
- this._selectedIndexes = this._table.highlightIds.toArray().reverse();
756
- if (this._showOnlySelected) {
757
- if (this._featuresSelected()) {
758
- this._table.filterBySelection();
759
- }
760
- else {
761
- this._toggleShowSelected();
762
- }
763
- }
764
- this.featureSelectionChange.emit(this._selectedIndexes);
776
+ this._table.highlightIds.on("change", (evt) => {
777
+ void this._handleOnChange(evt);
765
778
  });
766
779
  this.reactiveUtils.watch(() => this._table.activeSortOrders, (sortOrders) => {
767
780
  var _a, _b, _c, _d;
@@ -771,6 +784,93 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
771
784
  });
772
785
  }
773
786
  }
787
+ async _handleOnChange(evt) {
788
+ const ids = [...this._table.highlightIds.toArray()];
789
+ if (!this._skipOnChange) {
790
+ if (!this._ctrlIsPressed && !this._shiftIsPressed) {
791
+ if (this._selectedIndexes.length > 0) {
792
+ this._skipOnChange = true;
793
+ // only readd in specific case where we have multiple selected and then click one of the currently selected
794
+ const reAdd = this._selectedIndexes.length > 1 && evt.removed.length === 1;
795
+ const newIndexes = reAdd ? evt.removed : ids.filter(id => this._selectedIndexes.indexOf(id) < 0);
796
+ this._clearSelection();
797
+ this._selectedIndexes = [...newIndexes];
798
+ if (newIndexes.length > 0) {
799
+ this._table.highlightIds.add(newIndexes[0]);
800
+ }
801
+ }
802
+ else {
803
+ // https://github.com/Esri/solutions-components/issues/365
804
+ this._selectedIndexes = ids.reverse();
805
+ }
806
+ }
807
+ else if (this._ctrlIsPressed) {
808
+ this._selectedIndexes = ids.reverse();
809
+ }
810
+ else if (this._shiftIsPressed) {
811
+ this._skipOnChange = true;
812
+ this._previousCurrentId = this._currentId;
813
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
814
+ if (this._previousCurrentId !== this._currentId) {
815
+ // query the layer based on current sort and filters then grab between the current id and previous id
816
+ const orderBy = this._table.activeSortOrders.reduce((prev, cur) => {
817
+ prev.push(`${cur.fieldName} ${cur.direction}`);
818
+ return prev;
819
+ }, []);
820
+ const oids = await queryFeatureIds(this._layer, this._layer.definitionExpression, orderBy);
821
+ let isBetween = false;
822
+ const _start = this._table.viewModel.getObjectIdIndex(this._previousCurrentId);
823
+ const _end = this._table.viewModel.getObjectIdIndex(this._currentId);
824
+ const startIndex = _start < _end ? _start : _end;
825
+ const endIndex = _end > _start ? _end : _start;
826
+ this._selectedIndexes = oids.reduce((prev, cur) => {
827
+ const id = cur;
828
+ const index = this._table.viewModel.getObjectIdIndex(id);
829
+ if ((id === this._currentId || id === this._previousCurrentId)) {
830
+ isBetween = !isBetween;
831
+ if (prev.indexOf(id) < 0) {
832
+ prev.push(id);
833
+ }
834
+ }
835
+ // The oids are sorted so after we have reached the start or end oid add all ids even if the index is -1.
836
+ // Index of -1 will occur for features between the start and and oid if
837
+ // you select a row then scroll faster than the FeatureTable loads the data to select the next id
838
+ if (isBetween && prev.indexOf(id) < 0) {
839
+ prev.push(id);
840
+ }
841
+ // Also add index based check.
842
+ // In some cases the FeatureTable and Layer query will have differences in how null/undefined field values are sorted
843
+ if ((this._selectedIndexes.indexOf(id) > -1 || (index >= startIndex && index <= endIndex)) && prev.indexOf(id) < 0 && index > -1) {
844
+ prev.push(id);
845
+ }
846
+ return prev;
847
+ }, []);
848
+ this._table.highlightIds.addMany(this._selectedIndexes.filter(i => ids.indexOf(i) < 0));
849
+ }
850
+ }
851
+ this._finishOnChange();
852
+ }
853
+ else {
854
+ this._skipOnChange = false;
855
+ }
856
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
857
+ }
858
+ /**
859
+ * Handle any updates after a selection change has occured and emit the results
860
+ *
861
+ * @returns void
862
+ */
863
+ _finishOnChange() {
864
+ if (this._showOnlySelected) {
865
+ if (this._featuresSelected()) {
866
+ this._table.filterBySelection();
867
+ }
868
+ else {
869
+ this._toggleShowSelected();
870
+ }
871
+ }
872
+ this.featureSelectionChange.emit(this._selectedIndexes);
873
+ }
774
874
  /**
775
875
  * Reset basic table props
776
876
  *
@@ -906,6 +1006,24 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
906
1006
  }
907
1007
  }
908
1008
  }
1009
+ /**
1010
+ * Keep track of key down for ctrl and shift
1011
+ *
1012
+ * @returns void
1013
+ */
1014
+ _handleKeyDown(e) {
1015
+ this._ctrlIsPressed = e.ctrlKey;
1016
+ this._shiftIsPressed = e.shiftKey;
1017
+ }
1018
+ /**
1019
+ * Keep track of key up for ctrl and shift
1020
+ *
1021
+ * @returns void
1022
+ */
1023
+ _handleKeyUp(e) {
1024
+ this._ctrlIsPressed = e.ctrlKey;
1025
+ this._shiftIsPressed = e.shiftKey;
1026
+ }
909
1027
  /**
910
1028
  * Show filter component in modal
911
1029
  *
@@ -913,15 +1031,19 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
913
1031
  */
914
1032
  _filterModal() {
915
1033
  var _a, _b, _c;
916
- return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
1034
+ return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: async () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: async () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
917
1035
  }
918
1036
  /**
919
1037
  * Close the filter modal
920
1038
  *
921
1039
  * @returns void
922
1040
  */
923
- _closeFilter() {
924
- this._filterOpen = false;
1041
+ async _closeFilter() {
1042
+ if (this._filterOpen) {
1043
+ // reset allIds
1044
+ this._allIds = await queryAllIds(this._layer);
1045
+ this._filterOpen = false;
1046
+ }
925
1047
  }
926
1048
  /**
927
1049
  * Show delete confirmation message
@@ -994,8 +1116,10 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
994
1116
  _selectAll() {
995
1117
  const ids = this._allIds;
996
1118
  this._table.highlightIds.removeAll();
1119
+ this._skipOnChange = true;
997
1120
  this._table.highlightIds.addMany(ids);
998
1121
  this._selectedIndexes = ids;
1122
+ this._finishOnChange();
999
1123
  }
1000
1124
  /**
1001
1125
  * Toggle the show only selected flag
@@ -1055,8 +1179,10 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
1055
1179
  }
1056
1180
  return prev;
1057
1181
  }, []).sort((a, b) => a - b);
1182
+ this._skipOnChange = true;
1058
1183
  this._table.highlightIds.addMany(ids);
1059
1184
  this._selectedIndexes = ids;
1185
+ this._finishOnChange();
1060
1186
  }
1061
1187
  /**
1062
1188
  * Export all selected rows as CSV
@@ -1209,6 +1335,7 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
1209
1335
  "enableCSV": ["enableCSVWatchHandler"],
1210
1336
  "enableInlineEdit": ["enableInlineEditWatchHandler"],
1211
1337
  "_controlsThatFit": ["_controlsThatFitWatchHandler"],
1338
+ "mapInfo": ["mapInfoWatchHandler"],
1212
1339
  "mapView": ["mapViewWatchHandler"],
1213
1340
  "_layer": ["_layerWatchHandler"],
1214
1341
  "_selectedIndexes": ["_selectedIndexesWatchHandler"],
@@ -1248,6 +1375,7 @@ const LayerTable = /*@__PURE__*/ proxyCustomElement(class LayerTable extends HTM
1248
1375
  "enableCSV": ["enableCSVWatchHandler"],
1249
1376
  "enableInlineEdit": ["enableInlineEditWatchHandler"],
1250
1377
  "_controlsThatFit": ["_controlsThatFitWatchHandler"],
1378
+ "mapInfo": ["mapInfoWatchHandler"],
1251
1379
  "mapView": ["mapViewWatchHandler"],
1252
1380
  "_layer": ["_layerWatchHandler"],
1253
1381
  "_selectedIndexes": ["_selectedIndexesWatchHandler"],
@@ -136,6 +136,7 @@ const MapCard = /*@__PURE__*/ proxyCustomElement(class MapCard extends HTMLEleme
136
136
  // on the first render use the default webmap id if provided otherwise use the first child of the provided mapInfos
137
137
  const loadDefaultMap = !this._defaultWebmapHonored && this.defaultWebmapId;
138
138
  const defaultMap = (_a = this.mapInfos) === null || _a === void 0 ? void 0 : _a.filter(i => i.id === this.defaultWebmapId);
139
+ const mapConfigChanged = JSON.stringify(webMapInfo) !== JSON.stringify(this._webMapInfo);
139
140
  this._webMapInfo = loadDefaultMap && defaultMap ? defaultMap[0] :
140
141
  !(webMapInfo === null || webMapInfo === void 0 ? void 0 : webMapInfo.id) && this.mapInfos.length > 0 ? this.mapInfos[0] : webMapInfo;
141
142
  const id = this._webMapInfo.id;
@@ -166,6 +167,15 @@ const MapCard = /*@__PURE__*/ proxyCustomElement(class MapCard extends HTMLEleme
166
167
  this._defaultWebmapHonored = true;
167
168
  this._mapPicker.setMapByID(id);
168
169
  }
170
+ else if (mapConfigChanged) {
171
+ // Map is the same so no need to reload but we need to update for any changes from the config
172
+ this._searchConfiguration = this._webMapInfo.searchConfiguration;
173
+ this.beforeMapChanged.emit();
174
+ this.mapChanged.emit({
175
+ id: id,
176
+ mapView: this.mapView
177
+ });
178
+ }
169
179
  }
170
180
  /**
171
181
  * Add/remove the home widget base on enableHome prop
@@ -141,7 +141,7 @@ const MapPicker = /*@__PURE__*/ proxyCustomElement(class MapPicker extends HTMLE
141
141
  * @protected
142
142
  */
143
143
  _getMapNameList(show) {
144
- const listClass = show ? "map-list" : "display-none";
144
+ const listClass = show ? "map-list border-bottom-1" : "display-none";
145
145
  return (h("div", { class: listClass }, h("calcite-list", { id: "mapList", ref: (el) => this._list = el, selectionAppearance: "border", selectionMode: "single" }, this.mapInfos.map(mapInfo => {
146
146
  return (h("calcite-list-item", { label: mapInfo.name, onClick: () => this._webMapSelected(mapInfo), selected: mapInfo.id === this._loadedId, value: mapInfo.id }));
147
147
  }))));
@@ -6,7 +6,7 @@
6
6
  import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
7
7
  import { l as loadModules } from './loadModules.js';
8
8
  import { b as goToSelection, h as highlightFeatures, e as getFeatureLayerView } from './mapViewUtils.js';
9
- import { d as queryObjectIds, g as getQueryGeoms, e as queryFeaturesByGeometry } from './queryUtils.js';
9
+ import { e as queryObjectIds, g as getQueryGeoms, f as queryFeaturesByGeometry } from './queryUtils.js';
10
10
  import { E as EWorkflowType } from './interfaces.js';
11
11
  import { s as state } from './publicNotificationStore.js';
12
12
  import { a as getComponentClosestLanguage, g as getLocaleComponentStrings } from './locale.js';
@@ -122,6 +122,22 @@ async function queryFeaturesByGeometry(start, layer, geometry, featuresCollectio
122
122
  queryFeaturesByGeometry(start += num, layer, geometry, featuresCollection) :
123
123
  Promise.resolve(featuresCollection);
124
124
  }
125
+ /**
126
+ * Query the layer for feature ids that match the provided where clause.
127
+ * If no where clause is provided all features will be returned.
128
+ *
129
+ * @param layer the layer to retrieve features from
130
+ * @param where the where clause for the query
131
+ * @param orderBy any sort order to apply to the query
132
+ *
133
+ * @returns Promise with the ids from the layer that match the where and are sorted as defined by orderBy
134
+ */
135
+ async function queryFeatureIds(layer, where, orderBy) {
136
+ const query = layer.createQuery();
137
+ query.where = where ? where : "1=1";
138
+ query.orderByFields = orderBy;
139
+ return await layer.queryObjectIds(query);
140
+ }
125
141
  /**
126
142
  * Query the layer for the extent of features with the provided OIDs
127
143
  *
@@ -179,4 +195,4 @@ async function _intersectQuery(geometry, layer) {
179
195
  return layer.queryObjectIds(q);
180
196
  }
181
197
 
182
- export { queryExtent as a, queryAllIds as b, queryFeaturesByGlobalID as c, queryObjectIds as d, queryFeaturesByGeometry as e, getQueryGeoms as g, queryFeaturesByID as q };
198
+ export { queryExtent as a, queryFeatureIds as b, queryAllIds as c, queryFeaturesByGlobalID as d, queryObjectIds as e, queryFeaturesByGeometry as f, getQueryGeoms as g, queryFeaturesByID as q };
@@ -6,7 +6,7 @@
6
6
  import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
7
7
  import { e as ESelectionMode, b as EDrawMode, E as EWorkflowType } from './interfaces.js';
8
8
  import { e as getFeatureLayerView, f as getIdSets, i as highlightAllFeatures } from './mapViewUtils.js';
9
- import { e as queryFeaturesByGeometry } from './queryUtils.js';
9
+ import { f as queryFeaturesByGeometry } from './queryUtils.js';
10
10
  import { s as state } from './publicNotificationStore.js';
11
11
  import { g as getLocaleComponentStrings } from './locale.js';
12
12
  import { d as defineCustomElement$s } from './action.js';
@@ -521,7 +521,7 @@ const MapPicker = class {
521
521
  * @protected
522
522
  */
523
523
  _getMapNameList(show) {
524
- const listClass = show ? "map-list" : "display-none";
524
+ const listClass = show ? "map-list border-bottom-1" : "display-none";
525
525
  return (h("div", { class: listClass }, h("calcite-list", { id: "mapList", ref: (el) => this._list = el, selectionAppearance: "border", selectionMode: "single" }, this.mapInfos.map(mapInfo => {
526
526
  return (h("calcite-list-item", { label: mapInfo.name, onClick: () => this._webMapSelected(mapInfo), selected: mapInfo.id === this._loadedId, value: mapInfo.id }));
527
527
  }))));
@@ -13,7 +13,7 @@ import { c as connectMessages, s as setUpMessages, d as disconnectMessages, u as
13
13
  import { K as KindIcons } from './resources-6e00e0d1.js';
14
14
  import { l as loadModules } from './loadModules-cea493da.js';
15
15
  import { g as getLocaleComponentStrings } from './locale-834c52c6.js';
16
- import { l as getAllLayers } from './mapViewUtils-3ff1c264.js';
16
+ import { m as getAllLayers } from './mapViewUtils-066602d5.js';
17
17
  import './guid-36c6c6a5.js';
18
18
  import './resources-cdc36705.js';
19
19
  import './key-af303047.js';
@@ -22,7 +22,7 @@ import { d as debounce } from './debounce-229b1a22.js';
22
22
  import { c as connectConditionalSlotComponent, d as disconnectConditionalSlotComponent } from './conditionalSlot-1149b5cb.js';
23
23
  import { i as isActivationKey } from './key-af303047.js';
24
24
  import { g as getLocaleComponentStrings } from './locale-834c52c6.js';
25
- import { m as getMapLayerHash, n as getMapTableHash } from './mapViewUtils-3ff1c264.js';
25
+ import { n as getMapLayerHash, o as getMapTableHash } from './mapViewUtils-066602d5.js';
26
26
  import { s as state } from './publicNotificationStore-9362d7ae.js';
27
27
  import './resources-cdc36705.js';
28
28
  import './browser-b4c16201.js';
@@ -5,9 +5,9 @@
5
5
  */
6
6
  import { r as registerInstance, h, H as Host, g as getElement, c as createEvent } from './index-7183ce4a.js';
7
7
  import { g as getLocaleComponentStrings } from './locale-834c52c6.js';
8
- import { q as queryFeaturesByID, a as getLayerOrTable, g as goToSelection, b as queryAllIds, c as queryFeaturesByGlobalID } from './mapViewUtils-3ff1c264.js';
8
+ import { q as queryFeaturesByID, a as getLayerOrTable, g as goToSelection, b as queryFeatureIds, c as queryAllIds, d as queryFeaturesByGlobalID } from './mapViewUtils-066602d5.js';
9
9
  import { l as loadModules } from './loadModules-cea493da.js';
10
- import { d as downloadCSV } from './downloadUtils-83dd2143.js';
10
+ import { d as downloadCSV } from './downloadUtils-9dee8bc0.js';
11
11
  import './esri-loader-eda07632.js';
12
12
  import './_commonjsHelpers-d5f9d613.js';
13
13
  import './interfaces-341e3ab3.js';
@@ -112,6 +112,10 @@ const LayerTable = class {
112
112
  * number[]: A list of all IDs for the current layer
113
113
  */
114
114
  this._allIds = [];
115
+ /**
116
+ * boolean: When true the ctrl key is currently pressed
117
+ */
118
+ this._ctrlIsPressed = false;
115
119
  /**
116
120
  * boolean: When true the default global id provided via url param has been honored and should now be ignored
117
121
  */
@@ -120,6 +124,14 @@ const LayerTable = class {
120
124
  * boolean: When true the default OID provided via url param has been honored and should now be ignored
121
125
  */
122
126
  this._defaultOidHonored = false;
127
+ /**
128
+ * boolean: When true the shift key is currently pressed
129
+ */
130
+ this._shiftIsPressed = false;
131
+ /**
132
+ * boolean: When true any onChange handeling will be skipped
133
+ */
134
+ this._skipOnChange = false;
123
135
  /**
124
136
  * bool: When true the table is being sorted
125
137
  */
@@ -210,6 +222,15 @@ const LayerTable = class {
210
222
  }
211
223
  });
212
224
  }
225
+ /**
226
+ * watch for changes in map info and recheck the tool infos
227
+ */
228
+ async mapInfoWatchHandler() {
229
+ var _a;
230
+ if (((_a = this._toolInfos) === null || _a === void 0 ? void 0 : _a.length) > 0) {
231
+ this._initToolInfos();
232
+ }
233
+ }
213
234
  /**
214
235
  * watch for changes in map view and get the first layer
215
236
  */
@@ -324,6 +345,8 @@ const LayerTable = class {
324
345
  async componentDidLoad() {
325
346
  this._resizeObserver.observe(this._toolbar);
326
347
  document.onclick = (e) => this._handleDocumentClick(e);
348
+ document.onkeydown = (e) => this._handleKeyDown(e);
349
+ document.onkeyup = (e) => this._handleKeyUp(e);
327
350
  }
328
351
  /**
329
352
  * Called after the component is rendered
@@ -803,18 +826,8 @@ const LayerTable = class {
803
826
  this._initColumnsInfo();
804
827
  this._checkEditEnabled();
805
828
  await this._table.when(() => {
806
- this._table.highlightIds.on("change", () => {
807
- // https://github.com/Esri/solutions-components/issues/365
808
- this._selectedIndexes = this._table.highlightIds.toArray().reverse();
809
- if (this._showOnlySelected) {
810
- if (this._featuresSelected()) {
811
- this._table.filterBySelection();
812
- }
813
- else {
814
- this._toggleShowSelected();
815
- }
816
- }
817
- this.featureSelectionChange.emit(this._selectedIndexes);
829
+ this._table.highlightIds.on("change", (evt) => {
830
+ void this._handleOnChange(evt);
818
831
  });
819
832
  this.reactiveUtils.watch(() => this._table.activeSortOrders, (sortOrders) => {
820
833
  var _a, _b, _c, _d;
@@ -824,6 +837,93 @@ const LayerTable = class {
824
837
  });
825
838
  }
826
839
  }
840
+ async _handleOnChange(evt) {
841
+ const ids = [...this._table.highlightIds.toArray()];
842
+ if (!this._skipOnChange) {
843
+ if (!this._ctrlIsPressed && !this._shiftIsPressed) {
844
+ if (this._selectedIndexes.length > 0) {
845
+ this._skipOnChange = true;
846
+ // only readd in specific case where we have multiple selected and then click one of the currently selected
847
+ const reAdd = this._selectedIndexes.length > 1 && evt.removed.length === 1;
848
+ const newIndexes = reAdd ? evt.removed : ids.filter(id => this._selectedIndexes.indexOf(id) < 0);
849
+ this._clearSelection();
850
+ this._selectedIndexes = [...newIndexes];
851
+ if (newIndexes.length > 0) {
852
+ this._table.highlightIds.add(newIndexes[0]);
853
+ }
854
+ }
855
+ else {
856
+ // https://github.com/Esri/solutions-components/issues/365
857
+ this._selectedIndexes = ids.reverse();
858
+ }
859
+ }
860
+ else if (this._ctrlIsPressed) {
861
+ this._selectedIndexes = ids.reverse();
862
+ }
863
+ else if (this._shiftIsPressed) {
864
+ this._skipOnChange = true;
865
+ this._previousCurrentId = this._currentId;
866
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
867
+ if (this._previousCurrentId !== this._currentId) {
868
+ // query the layer based on current sort and filters then grab between the current id and previous id
869
+ const orderBy = this._table.activeSortOrders.reduce((prev, cur) => {
870
+ prev.push(`${cur.fieldName} ${cur.direction}`);
871
+ return prev;
872
+ }, []);
873
+ const oids = await queryFeatureIds(this._layer, this._layer.definitionExpression, orderBy);
874
+ let isBetween = false;
875
+ const _start = this._table.viewModel.getObjectIdIndex(this._previousCurrentId);
876
+ const _end = this._table.viewModel.getObjectIdIndex(this._currentId);
877
+ const startIndex = _start < _end ? _start : _end;
878
+ const endIndex = _end > _start ? _end : _start;
879
+ this._selectedIndexes = oids.reduce((prev, cur) => {
880
+ const id = cur;
881
+ const index = this._table.viewModel.getObjectIdIndex(id);
882
+ if ((id === this._currentId || id === this._previousCurrentId)) {
883
+ isBetween = !isBetween;
884
+ if (prev.indexOf(id) < 0) {
885
+ prev.push(id);
886
+ }
887
+ }
888
+ // The oids are sorted so after we have reached the start or end oid add all ids even if the index is -1.
889
+ // Index of -1 will occur for features between the start and and oid if
890
+ // you select a row then scroll faster than the FeatureTable loads the data to select the next id
891
+ if (isBetween && prev.indexOf(id) < 0) {
892
+ prev.push(id);
893
+ }
894
+ // Also add index based check.
895
+ // In some cases the FeatureTable and Layer query will have differences in how null/undefined field values are sorted
896
+ if ((this._selectedIndexes.indexOf(id) > -1 || (index >= startIndex && index <= endIndex)) && prev.indexOf(id) < 0 && index > -1) {
897
+ prev.push(id);
898
+ }
899
+ return prev;
900
+ }, []);
901
+ this._table.highlightIds.addMany(this._selectedIndexes.filter(i => ids.indexOf(i) < 0));
902
+ }
903
+ }
904
+ this._finishOnChange();
905
+ }
906
+ else {
907
+ this._skipOnChange = false;
908
+ }
909
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
910
+ }
911
+ /**
912
+ * Handle any updates after a selection change has occured and emit the results
913
+ *
914
+ * @returns void
915
+ */
916
+ _finishOnChange() {
917
+ if (this._showOnlySelected) {
918
+ if (this._featuresSelected()) {
919
+ this._table.filterBySelection();
920
+ }
921
+ else {
922
+ this._toggleShowSelected();
923
+ }
924
+ }
925
+ this.featureSelectionChange.emit(this._selectedIndexes);
926
+ }
827
927
  /**
828
928
  * Reset basic table props
829
929
  *
@@ -959,6 +1059,24 @@ const LayerTable = class {
959
1059
  }
960
1060
  }
961
1061
  }
1062
+ /**
1063
+ * Keep track of key down for ctrl and shift
1064
+ *
1065
+ * @returns void
1066
+ */
1067
+ _handleKeyDown(e) {
1068
+ this._ctrlIsPressed = e.ctrlKey;
1069
+ this._shiftIsPressed = e.shiftKey;
1070
+ }
1071
+ /**
1072
+ * Keep track of key up for ctrl and shift
1073
+ *
1074
+ * @returns void
1075
+ */
1076
+ _handleKeyUp(e) {
1077
+ this._ctrlIsPressed = e.ctrlKey;
1078
+ this._shiftIsPressed = e.shiftKey;
1079
+ }
962
1080
  /**
963
1081
  * Show filter component in modal
964
1082
  *
@@ -966,15 +1084,19 @@ const LayerTable = class {
966
1084
  */
967
1085
  _filterModal() {
968
1086
  var _a, _b, _c;
969
- return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
1087
+ return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: async () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: async () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
970
1088
  }
971
1089
  /**
972
1090
  * Close the filter modal
973
1091
  *
974
1092
  * @returns void
975
1093
  */
976
- _closeFilter() {
977
- this._filterOpen = false;
1094
+ async _closeFilter() {
1095
+ if (this._filterOpen) {
1096
+ // reset allIds
1097
+ this._allIds = await queryAllIds(this._layer);
1098
+ this._filterOpen = false;
1099
+ }
978
1100
  }
979
1101
  /**
980
1102
  * Show delete confirmation message
@@ -1047,8 +1169,10 @@ const LayerTable = class {
1047
1169
  _selectAll() {
1048
1170
  const ids = this._allIds;
1049
1171
  this._table.highlightIds.removeAll();
1172
+ this._skipOnChange = true;
1050
1173
  this._table.highlightIds.addMany(ids);
1051
1174
  this._selectedIndexes = ids;
1175
+ this._finishOnChange();
1052
1176
  }
1053
1177
  /**
1054
1178
  * Toggle the show only selected flag
@@ -1108,8 +1232,10 @@ const LayerTable = class {
1108
1232
  }
1109
1233
  return prev;
1110
1234
  }, []).sort((a, b) => a - b);
1235
+ this._skipOnChange = true;
1111
1236
  this._table.highlightIds.addMany(ids);
1112
1237
  this._selectedIndexes = ids;
1238
+ this._finishOnChange();
1113
1239
  }
1114
1240
  /**
1115
1241
  * Export all selected rows as CSV
@@ -1262,6 +1388,7 @@ const LayerTable = class {
1262
1388
  "enableCSV": ["enableCSVWatchHandler"],
1263
1389
  "enableInlineEdit": ["enableInlineEditWatchHandler"],
1264
1390
  "_controlsThatFit": ["_controlsThatFitWatchHandler"],
1391
+ "mapInfo": ["mapInfoWatchHandler"],
1265
1392
  "mapView": ["mapViewWatchHandler"],
1266
1393
  "_layer": ["_layerWatchHandler"],
1267
1394
  "_selectedIndexes": ["_selectedIndexesWatchHandler"],
@@ -1375,6 +1502,7 @@ const MapCard = class {
1375
1502
  // on the first render use the default webmap id if provided otherwise use the first child of the provided mapInfos
1376
1503
  const loadDefaultMap = !this._defaultWebmapHonored && this.defaultWebmapId;
1377
1504
  const defaultMap = (_a = this.mapInfos) === null || _a === void 0 ? void 0 : _a.filter(i => i.id === this.defaultWebmapId);
1505
+ const mapConfigChanged = JSON.stringify(webMapInfo) !== JSON.stringify(this._webMapInfo);
1378
1506
  this._webMapInfo = loadDefaultMap && defaultMap ? defaultMap[0] :
1379
1507
  !(webMapInfo === null || webMapInfo === void 0 ? void 0 : webMapInfo.id) && this.mapInfos.length > 0 ? this.mapInfos[0] : webMapInfo;
1380
1508
  const id = this._webMapInfo.id;
@@ -1405,6 +1533,15 @@ const MapCard = class {
1405
1533
  this._defaultWebmapHonored = true;
1406
1534
  this._mapPicker.setMapByID(id);
1407
1535
  }
1536
+ else if (mapConfigChanged) {
1537
+ // Map is the same so no need to reload but we need to update for any changes from the config
1538
+ this._searchConfiguration = this._webMapInfo.searchConfiguration;
1539
+ this.beforeMapChanged.emit();
1540
+ this.mapChanged.emit({
1541
+ id: id,
1542
+ mapView: this.mapView
1543
+ });
1544
+ }
1408
1545
  }
1409
1546
  /**
1410
1547
  * Add/remove the home widget base on enableHome prop
@@ -51,6 +51,7 @@ const CrowdsourceManager = class {
51
51
  this._expandPopup = false;
52
52
  this._translations = undefined;
53
53
  this._layoutMode = ELayoutMode.GRID;
54
+ this._mapInfo = undefined;
54
55
  this._mapView = undefined;
55
56
  this._panelOpen = true;
56
57
  this._tableOnly = false;
@@ -379,7 +380,7 @@ const CrowdsourceManager = class {
379
380
  return true;
380
381
  }
381
382
  });
382
- return mapInfo;
383
+ return Object.assign({}, mapInfo);
383
384
  }
384
385
  /**
385
386
  * Set the current map info when maps change