@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
@@ -60,6 +60,7 @@ export class CrowdsourceManager {
60
60
  this._expandPopup = false;
61
61
  this._translations = undefined;
62
62
  this._layoutMode = ELayoutMode.GRID;
63
+ this._mapInfo = undefined;
63
64
  this._mapView = undefined;
64
65
  this._panelOpen = true;
65
66
  this._tableOnly = false;
@@ -388,7 +389,7 @@ export class CrowdsourceManager {
388
389
  return true;
389
390
  }
390
391
  });
391
- return mapInfo;
392
+ return Object.assign({}, mapInfo);
392
393
  }
393
394
  /**
394
395
  * Set the current map info when maps change
@@ -992,6 +993,7 @@ export class CrowdsourceManager {
992
993
  "_expandPopup": {},
993
994
  "_translations": {},
994
995
  "_layoutMode": {},
996
+ "_mapInfo": {},
995
997
  "_mapView": {},
996
998
  "_panelOpen": {},
997
999
  "_tableOnly": {}
@@ -22,7 +22,7 @@ import { Host, h } from "@stencil/core";
22
22
  import { loadModules } from "../../utils/loadModules";
23
23
  import { getLocaleComponentStrings } from "../../utils/locale";
24
24
  import { getLayerOrTable, goToSelection } from "../../utils/mapViewUtils";
25
- import { queryAllIds, queryFeaturesByGlobalID } from "../../utils/queryUtils";
25
+ import { queryAllIds, queryFeatureIds, queryFeaturesByGlobalID } from "../../utils/queryUtils";
26
26
  import * as downloadUtils from "../../utils/downloadUtils";
27
27
  import "@esri/instant-apps-components/dist/components/instant-apps-social-share";
28
28
  export class LayerTable {
@@ -31,6 +31,10 @@ export class LayerTable {
31
31
  * number[]: A list of all IDs for the current layer
32
32
  */
33
33
  this._allIds = [];
34
+ /**
35
+ * boolean: When true the ctrl key is currently pressed
36
+ */
37
+ this._ctrlIsPressed = false;
34
38
  /**
35
39
  * boolean: When true the default global id provided via url param has been honored and should now be ignored
36
40
  */
@@ -39,6 +43,14 @@ export class LayerTable {
39
43
  * boolean: When true the default OID provided via url param has been honored and should now be ignored
40
44
  */
41
45
  this._defaultOidHonored = false;
46
+ /**
47
+ * boolean: When true the shift key is currently pressed
48
+ */
49
+ this._shiftIsPressed = false;
50
+ /**
51
+ * boolean: When true any onChange handeling will be skipped
52
+ */
53
+ this._skipOnChange = false;
42
54
  /**
43
55
  * bool: When true the table is being sorted
44
56
  */
@@ -129,6 +141,15 @@ export class LayerTable {
129
141
  }
130
142
  });
131
143
  }
144
+ /**
145
+ * watch for changes in map info and recheck the tool infos
146
+ */
147
+ async mapInfoWatchHandler() {
148
+ var _a;
149
+ if (((_a = this._toolInfos) === null || _a === void 0 ? void 0 : _a.length) > 0) {
150
+ this._initToolInfos();
151
+ }
152
+ }
132
153
  /**
133
154
  * watch for changes in map view and get the first layer
134
155
  */
@@ -243,6 +264,8 @@ export class LayerTable {
243
264
  async componentDidLoad() {
244
265
  this._resizeObserver.observe(this._toolbar);
245
266
  document.onclick = (e) => this._handleDocumentClick(e);
267
+ document.onkeydown = (e) => this._handleKeyDown(e);
268
+ document.onkeyup = (e) => this._handleKeyUp(e);
246
269
  }
247
270
  /**
248
271
  * Called after the component is rendered
@@ -722,18 +745,8 @@ export class LayerTable {
722
745
  this._initColumnsInfo();
723
746
  this._checkEditEnabled();
724
747
  await this._table.when(() => {
725
- this._table.highlightIds.on("change", () => {
726
- // https://github.com/Esri/solutions-components/issues/365
727
- this._selectedIndexes = this._table.highlightIds.toArray().reverse();
728
- if (this._showOnlySelected) {
729
- if (this._featuresSelected()) {
730
- this._table.filterBySelection();
731
- }
732
- else {
733
- this._toggleShowSelected();
734
- }
735
- }
736
- this.featureSelectionChange.emit(this._selectedIndexes);
748
+ this._table.highlightIds.on("change", (evt) => {
749
+ void this._handleOnChange(evt);
737
750
  });
738
751
  this.reactiveUtils.watch(() => this._table.activeSortOrders, (sortOrders) => {
739
752
  var _a, _b, _c, _d;
@@ -743,6 +756,93 @@ export class LayerTable {
743
756
  });
744
757
  }
745
758
  }
759
+ async _handleOnChange(evt) {
760
+ const ids = [...this._table.highlightIds.toArray()];
761
+ if (!this._skipOnChange) {
762
+ if (!this._ctrlIsPressed && !this._shiftIsPressed) {
763
+ if (this._selectedIndexes.length > 0) {
764
+ this._skipOnChange = true;
765
+ // only readd in specific case where we have multiple selected and then click one of the currently selected
766
+ const reAdd = this._selectedIndexes.length > 1 && evt.removed.length === 1;
767
+ const newIndexes = reAdd ? evt.removed : ids.filter(id => this._selectedIndexes.indexOf(id) < 0);
768
+ this._clearSelection();
769
+ this._selectedIndexes = [...newIndexes];
770
+ if (newIndexes.length > 0) {
771
+ this._table.highlightIds.add(newIndexes[0]);
772
+ }
773
+ }
774
+ else {
775
+ // https://github.com/Esri/solutions-components/issues/365
776
+ this._selectedIndexes = ids.reverse();
777
+ }
778
+ }
779
+ else if (this._ctrlIsPressed) {
780
+ this._selectedIndexes = ids.reverse();
781
+ }
782
+ else if (this._shiftIsPressed) {
783
+ this._skipOnChange = true;
784
+ this._previousCurrentId = this._currentId;
785
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
786
+ if (this._previousCurrentId !== this._currentId) {
787
+ // query the layer based on current sort and filters then grab between the current id and previous id
788
+ const orderBy = this._table.activeSortOrders.reduce((prev, cur) => {
789
+ prev.push(`${cur.fieldName} ${cur.direction}`);
790
+ return prev;
791
+ }, []);
792
+ const oids = await queryFeatureIds(this._layer, this._layer.definitionExpression, orderBy);
793
+ let isBetween = false;
794
+ const _start = this._table.viewModel.getObjectIdIndex(this._previousCurrentId);
795
+ const _end = this._table.viewModel.getObjectIdIndex(this._currentId);
796
+ const startIndex = _start < _end ? _start : _end;
797
+ const endIndex = _end > _start ? _end : _start;
798
+ this._selectedIndexes = oids.reduce((prev, cur) => {
799
+ const id = cur;
800
+ const index = this._table.viewModel.getObjectIdIndex(id);
801
+ if ((id === this._currentId || id === this._previousCurrentId)) {
802
+ isBetween = !isBetween;
803
+ if (prev.indexOf(id) < 0) {
804
+ prev.push(id);
805
+ }
806
+ }
807
+ // The oids are sorted so after we have reached the start or end oid add all ids even if the index is -1.
808
+ // Index of -1 will occur for features between the start and and oid if
809
+ // you select a row then scroll faster than the FeatureTable loads the data to select the next id
810
+ if (isBetween && prev.indexOf(id) < 0) {
811
+ prev.push(id);
812
+ }
813
+ // Also add index based check.
814
+ // In some cases the FeatureTable and Layer query will have differences in how null/undefined field values are sorted
815
+ if ((this._selectedIndexes.indexOf(id) > -1 || (index >= startIndex && index <= endIndex)) && prev.indexOf(id) < 0 && index > -1) {
816
+ prev.push(id);
817
+ }
818
+ return prev;
819
+ }, []);
820
+ this._table.highlightIds.addMany(this._selectedIndexes.filter(i => ids.indexOf(i) < 0));
821
+ }
822
+ }
823
+ this._finishOnChange();
824
+ }
825
+ else {
826
+ this._skipOnChange = false;
827
+ }
828
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
829
+ }
830
+ /**
831
+ * Handle any updates after a selection change has occured and emit the results
832
+ *
833
+ * @returns void
834
+ */
835
+ _finishOnChange() {
836
+ if (this._showOnlySelected) {
837
+ if (this._featuresSelected()) {
838
+ this._table.filterBySelection();
839
+ }
840
+ else {
841
+ this._toggleShowSelected();
842
+ }
843
+ }
844
+ this.featureSelectionChange.emit(this._selectedIndexes);
845
+ }
746
846
  /**
747
847
  * Reset basic table props
748
848
  *
@@ -878,6 +978,24 @@ export class LayerTable {
878
978
  }
879
979
  }
880
980
  }
981
+ /**
982
+ * Keep track of key down for ctrl and shift
983
+ *
984
+ * @returns void
985
+ */
986
+ _handleKeyDown(e) {
987
+ this._ctrlIsPressed = e.ctrlKey;
988
+ this._shiftIsPressed = e.shiftKey;
989
+ }
990
+ /**
991
+ * Keep track of key up for ctrl and shift
992
+ *
993
+ * @returns void
994
+ */
995
+ _handleKeyUp(e) {
996
+ this._ctrlIsPressed = e.ctrlKey;
997
+ this._shiftIsPressed = e.shiftKey;
998
+ }
881
999
  /**
882
1000
  * Show filter component in modal
883
1001
  *
@@ -885,15 +1003,19 @@ export class LayerTable {
885
1003
  */
886
1004
  _filterModal() {
887
1005
  var _a, _b, _c;
888
- 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 }))));
1006
+ 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 }))));
889
1007
  }
890
1008
  /**
891
1009
  * Close the filter modal
892
1010
  *
893
1011
  * @returns void
894
1012
  */
895
- _closeFilter() {
896
- this._filterOpen = false;
1013
+ async _closeFilter() {
1014
+ if (this._filterOpen) {
1015
+ // reset allIds
1016
+ this._allIds = await queryAllIds(this._layer);
1017
+ this._filterOpen = false;
1018
+ }
897
1019
  }
898
1020
  /**
899
1021
  * Show delete confirmation message
@@ -966,8 +1088,10 @@ export class LayerTable {
966
1088
  _selectAll() {
967
1089
  const ids = this._allIds;
968
1090
  this._table.highlightIds.removeAll();
1091
+ this._skipOnChange = true;
969
1092
  this._table.highlightIds.addMany(ids);
970
1093
  this._selectedIndexes = ids;
1094
+ this._finishOnChange();
971
1095
  }
972
1096
  /**
973
1097
  * Toggle the show only selected flag
@@ -1027,8 +1151,10 @@ export class LayerTable {
1027
1151
  }
1028
1152
  return prev;
1029
1153
  }, []).sort((a, b) => a - b);
1154
+ this._skipOnChange = true;
1030
1155
  this._table.highlightIds.addMany(ids);
1031
1156
  this._selectedIndexes = ids;
1157
+ this._finishOnChange();
1032
1158
  }
1033
1159
  /**
1034
1160
  * Export all selected rows as CSV
@@ -1513,6 +1639,9 @@ export class LayerTable {
1513
1639
  }, {
1514
1640
  "propName": "_controlsThatFit",
1515
1641
  "methodName": "_controlsThatFitWatchHandler"
1642
+ }, {
1643
+ "propName": "mapInfo",
1644
+ "methodName": "mapInfoWatchHandler"
1516
1645
  }, {
1517
1646
  "propName": "mapView",
1518
1647
  "methodName": "mapViewWatchHandler"
@@ -126,6 +126,7 @@ export class MapCard {
126
126
  // on the first render use the default webmap id if provided otherwise use the first child of the provided mapInfos
127
127
  const loadDefaultMap = !this._defaultWebmapHonored && this.defaultWebmapId;
128
128
  const defaultMap = (_a = this.mapInfos) === null || _a === void 0 ? void 0 : _a.filter(i => i.id === this.defaultWebmapId);
129
+ const mapConfigChanged = JSON.stringify(webMapInfo) !== JSON.stringify(this._webMapInfo);
129
130
  this._webMapInfo = loadDefaultMap && defaultMap ? defaultMap[0] :
130
131
  !(webMapInfo === null || webMapInfo === void 0 ? void 0 : webMapInfo.id) && this.mapInfos.length > 0 ? this.mapInfos[0] : webMapInfo;
131
132
  const id = this._webMapInfo.id;
@@ -156,6 +157,15 @@ export class MapCard {
156
157
  this._defaultWebmapHonored = true;
157
158
  this._mapPicker.setMapByID(id);
158
159
  }
160
+ else if (mapConfigChanged) {
161
+ // Map is the same so no need to reload but we need to update for any changes from the config
162
+ this._searchConfiguration = this._webMapInfo.searchConfiguration;
163
+ this.beforeMapChanged.emit();
164
+ this.mapChanged.emit({
165
+ id: id,
166
+ mapView: this.mapView
167
+ });
168
+ }
159
169
  }
160
170
  /**
161
171
  * Add/remove the home widget base on enableHome prop
@@ -132,7 +132,7 @@ export class MapPicker {
132
132
  * @protected
133
133
  */
134
134
  _getMapNameList(show) {
135
- const listClass = show ? "map-list" : "display-none";
135
+ const listClass = show ? "map-list border-bottom-1" : "display-none";
136
136
  return (h("div", { class: listClass }, h("calcite-list", { id: "mapList", ref: (el) => this._list = el, selectionAppearance: "border", selectionMode: "single" }, this.mapInfos.map(mapInfo => {
137
137
  return (h("calcite-list-item", { label: mapInfo.name, onClick: () => this._webMapSelected(mapInfo), selected: mapInfo.id === this._loadedId, value: mapInfo.id }));
138
138
  }))));
@@ -94,10 +94,10 @@
94
94
  operator: " AND ",
95
95
  expressions: [
96
96
  {
97
- definitionExpression: "OBJECTID > 700",
97
+ definitionExpression: "OBJECTID > 690",
98
98
  id: 1701793260225,
99
99
  index: 0,
100
- name: "greater than 700",
100
+ name: "greater than 690",
101
101
  active: false
102
102
  }
103
103
  ]
@@ -145,7 +145,25 @@
145
145
  }, {
146
146
  id: "b422923b7a4c4958b9788118255f2f0a",
147
147
  name: "Floor aware map"
148
- }]
148
+ }, {
149
+ id: "5dc8ae351ff34280a75f7ffe1115b36b",
150
+ name: "Standalone table",
151
+ filterConfig: {
152
+ "mapId": "5dc8ae351ff34280a75f7ffe1115b36b",
153
+ "layerExpressions": [{
154
+ "id": "18c4a8cda15-layer-2",
155
+ "title": "Table_1",
156
+ "operator": " AND ",
157
+ "expressions": [{
158
+ "definitionExpression": "OBJECTID > 14",
159
+ "id": 1702486334825,
160
+ "index": 0,
161
+ "name": "> 14",
162
+ "active": false
163
+ }]
164
+ }]
165
+ }
166
+ }, ]
149
167
  ];
150
168
  }
151
169
  </script>
@@ -165,6 +165,22 @@ export async function queryFeaturesByGeometry(start, layer, geometry, featuresCo
165
165
  queryFeaturesByGeometry(start += num, layer, geometry, featuresCollection) :
166
166
  Promise.resolve(featuresCollection);
167
167
  }
168
+ /**
169
+ * Query the layer for feature ids that match the provided where clause.
170
+ * If no where clause is provided all features will be returned.
171
+ *
172
+ * @param layer the layer to retrieve features from
173
+ * @param where the where clause for the query
174
+ * @param orderBy any sort order to apply to the query
175
+ *
176
+ * @returns Promise with the ids from the layer that match the where and are sorted as defined by orderBy
177
+ */
178
+ export async function queryFeatureIds(layer, where, orderBy) {
179
+ const query = layer.createQuery();
180
+ query.where = where ? where : "1=1";
181
+ query.orderByFields = orderBy;
182
+ return await layer.queryObjectIds(query);
183
+ }
168
184
  /**
169
185
  * Query the layer for the extent of features with the provided OIDs
170
186
  *
@@ -212,6 +212,27 @@ export async function queryFeaturesByGeometry(
212
212
  Promise.resolve(featuresCollection);
213
213
  }
214
214
 
215
+ /**
216
+ * Query the layer for feature ids that match the provided where clause.
217
+ * If no where clause is provided all features will be returned.
218
+ *
219
+ * @param layer the layer to retrieve features from
220
+ * @param where the where clause for the query
221
+ * @param orderBy any sort order to apply to the query
222
+ *
223
+ * @returns Promise with the ids from the layer that match the where and are sorted as defined by orderBy
224
+ */
225
+ export async function queryFeatureIds(
226
+ layer: any,
227
+ where: any,
228
+ orderBy: any
229
+ ): Promise<number[]> {
230
+ const query = layer.createQuery();
231
+ query.where = where ? where : "1=1";
232
+ query.orderByFields = orderBy;
233
+ return await layer.queryObjectIds(query);
234
+ }
235
+
215
236
  /**
216
237
  * Query the layer for the extent of features with the provided OIDs
217
238
  *
@@ -106,6 +106,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
106
106
  this._expandPopup = false;
107
107
  this._translations = undefined;
108
108
  this._layoutMode = ELayoutMode.GRID;
109
+ this._mapInfo = undefined;
109
110
  this._mapView = undefined;
110
111
  this._panelOpen = true;
111
112
  this._tableOnly = false;
@@ -434,7 +435,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
434
435
  return true;
435
436
  }
436
437
  });
437
- return mapInfo;
438
+ return Object.assign({}, mapInfo);
438
439
  }
439
440
  /**
440
441
  * Set the current map info when maps change
@@ -524,6 +525,7 @@ const CrowdsourceManager$1 = /*@__PURE__*/ proxyCustomElement(class CrowdsourceM
524
525
  "_expandPopup": [32],
525
526
  "_translations": [32],
526
527
  "_layoutMode": [32],
528
+ "_mapInfo": [32],
527
529
  "_mapView": [32],
528
530
  "_panelOpen": [32],
529
531
  "_tableOnly": [32]