@esri/solutions-components 0.7.30 → 0.7.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/t9n/crowdsource-reporter/resources.json +7 -5
- package/dist/assets/t9n/crowdsource-reporter/resources_en.json +7 -5
- package/dist/assets/t9n/feature-list/resources.json +1 -1
- package/dist/assets/t9n/feature-list/resources_en.json +1 -1
- package/dist/assets/t9n/layer-list/resources.json +1 -1
- package/dist/assets/t9n/layer-list/resources_en.json +1 -1
- package/dist/cjs/{calcite-flow_4.cjs.entry.js → calcite-flow_5.cjs.entry.js} +286 -19
- package/dist/cjs/card-manager_3.cjs.entry.js +1 -1
- package/dist/cjs/crowdsource-reporter.cjs.entry.js +248 -32
- package/dist/cjs/{downloadUtils-83c6d3c3.js → downloadUtils-10e0de31.js} +2 -2
- package/dist/cjs/{index.es-bd1a93b2.js → index.es-72dc7ab9.js} +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/map-select-tools_3.cjs.entry.js +1 -1
- package/dist/cjs/public-notification.cjs.entry.js +1 -1
- package/dist/cjs/solutions-components.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/create-feature/create-feature.css +50 -0
- package/dist/collection/components/create-feature/create-feature.js +444 -0
- package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.css +10 -1
- package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.js +287 -33
- package/dist/collection/components/feature-list/feature-list.js +1 -0
- package/dist/collection/components/layer-list/layer-list.js +60 -16
- package/dist/collection/demos/create-feature.html +90 -0
- package/dist/collection/demos/crowdsource-reporter.html +26 -11
- package/dist/collection/utils/downloadUtils.js +1 -1
- package/dist/collection/utils/downloadUtils.ts +1 -1
- package/dist/components/create-feature.d.ts +11 -0
- package/dist/components/create-feature.js +11 -0
- package/dist/components/create-feature2.js +278 -0
- package/dist/components/crowdsource-reporter.js +324 -90
- package/dist/components/downloadUtils.js +1 -1
- package/dist/components/feature-list2.js +1 -0
- package/dist/components/layer-list2.js +38 -17
- package/dist/esm/{calcite-flow_4.entry.js → calcite-flow_5.entry.js} +286 -20
- package/dist/esm/card-manager_3.entry.js +1 -1
- package/dist/esm/crowdsource-reporter.entry.js +249 -33
- package/dist/esm/{downloadUtils-d070a467.js → downloadUtils-d297078f.js} +2 -2
- package/dist/esm/{index.es-d48535a2.js → index.es-3b4fa9d0.js} +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/map-select-tools_3.entry.js +1 -1
- package/dist/esm/public-notification.entry.js +1 -1
- package/dist/esm/solutions-components.js +1 -1
- package/dist/solutions-components/demos/create-feature.html +90 -0
- package/dist/solutions-components/demos/crowdsource-reporter.html +26 -11
- package/dist/solutions-components/{p-f120ff40.entry.js → p-09ec8c8f.entry.js} +1 -1
- package/dist/solutions-components/{p-55b835a1.js → p-103c5318.js} +2 -2
- package/dist/solutions-components/{p-309cdea1.entry.js → p-57d49d15.entry.js} +1 -1
- package/dist/solutions-components/{p-b913a4fd.js → p-8ec25bf4.js} +1 -1
- package/dist/solutions-components/{p-f22ff57e.entry.js → p-921f21d5.entry.js} +1 -1
- package/dist/solutions-components/p-d5263cb9.entry.js +17 -0
- package/dist/solutions-components/p-ea17cefb.entry.js +6 -0
- package/dist/solutions-components/solutions-components.esm.js +1 -1
- package/dist/solutions-components/utils/downloadUtils.ts +1 -1
- package/dist/types/components/create-feature/create-feature.d.ts +125 -0
- package/dist/types/components/crowdsource-reporter/crowdsource-reporter.d.ts +146 -12
- package/dist/types/components/feature-list/feature-list.d.ts +1 -0
- package/dist/types/components/layer-list/layer-list.d.ts +6 -0
- package/dist/types/components.d.ts +102 -0
- package/dist/types/preact.d.ts +7 -0
- package/package.json +1 -1
- package/dist/solutions-components/p-2f162664.entry.js +0 -6
- package/dist/solutions-components/p-94ee3ef7.entry.js +0 -17
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
import { Host, h } from "@stencil/core";
|
|
22
22
|
import { getLocaleComponentStrings } from "../../utils/locale";
|
|
23
23
|
import { loadModules } from "../../utils/loadModules";
|
|
24
|
-
import { getAllLayers } from "../../utils/mapViewUtils";
|
|
24
|
+
import { getAllLayers, getLayerOrTable } from "../../utils/mapViewUtils";
|
|
25
|
+
import { queryFeaturesByID } from "../../utils/queryUtils";
|
|
25
26
|
export class CrowdsourceReporter {
|
|
26
27
|
constructor() {
|
|
27
28
|
this.description = undefined;
|
|
@@ -34,6 +35,8 @@ export class CrowdsourceReporter {
|
|
|
34
35
|
this.layers = undefined;
|
|
35
36
|
this.loginTitle = undefined;
|
|
36
37
|
this.mapView = undefined;
|
|
38
|
+
this.layerId = undefined;
|
|
39
|
+
this.objectId = undefined;
|
|
37
40
|
this.reportButtonText = undefined;
|
|
38
41
|
this.reportsHeader = undefined;
|
|
39
42
|
this.reportSubmittedMessage = undefined;
|
|
@@ -51,6 +54,9 @@ export class CrowdsourceReporter {
|
|
|
51
54
|
this._translations = undefined;
|
|
52
55
|
this._hasValidLayers = false;
|
|
53
56
|
this._selectedLayerName = undefined;
|
|
57
|
+
this._reportSubmitted = false;
|
|
58
|
+
this._showSubmitCancelButton = false;
|
|
59
|
+
this._featureCreationFailedErrorMsg = undefined;
|
|
54
60
|
}
|
|
55
61
|
//--------------------------------------------------------------------------
|
|
56
62
|
//
|
|
@@ -82,6 +88,7 @@ export class CrowdsourceReporter {
|
|
|
82
88
|
* @returns Promise when complete
|
|
83
89
|
*/
|
|
84
90
|
async componentWillLoad() {
|
|
91
|
+
this._urlParamsLoaded = false;
|
|
85
92
|
await this._initModules();
|
|
86
93
|
await this._getTranslations();
|
|
87
94
|
}
|
|
@@ -89,7 +96,8 @@ export class CrowdsourceReporter {
|
|
|
89
96
|
* Renders the component.
|
|
90
97
|
*/
|
|
91
98
|
render() {
|
|
92
|
-
|
|
99
|
+
const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
|
|
100
|
+
return (h(Host, null, this._reportSubmitted && h("calcite-alert", { "auto-close": true, class: themeClass, closable: true, icon: "check-circle", kind: "success", onCalciteAlertClose: () => { this._reportSubmitted = false; }, open: true, placement: "top" }, h("div", { slot: "title" }, this._translations.reportSubmit), h("div", { slot: "message" }, this._translations.submitMsg)), this._featureCreationFailedErrorMsg && h("calcite-alert", { "auto-close": true, class: themeClass, closable: true, icon: "x-octagon", kind: "danger", onCalciteAlertClose: () => { this._featureCreationFailedErrorMsg = ""; }, open: true, placement: "top" }, h("div", { slot: "title" }, this._translations.error), h("div", { slot: "message" }, this._featureCreationFailedErrorMsg)), h("div", null, h("calcite-shell", { "content-behind": true }, this._getReporter()))));
|
|
93
101
|
}
|
|
94
102
|
//--------------------------------------------------------------------------
|
|
95
103
|
//
|
|
@@ -109,6 +117,20 @@ export class CrowdsourceReporter {
|
|
|
109
117
|
]);
|
|
110
118
|
this.reactiveUtils = reactiveUtils;
|
|
111
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Set the selected layer id and layer name
|
|
122
|
+
* @param layerId string layerId of the selected layer
|
|
123
|
+
* @param layerName string layerName of the selected layer
|
|
124
|
+
*/
|
|
125
|
+
setSelectedLayer(layerId, layerName) {
|
|
126
|
+
this._selectedLayerId = layerId;
|
|
127
|
+
this._selectedLayerName = layerName;
|
|
128
|
+
//show only current layer on map and hide other valid editable layers
|
|
129
|
+
//if layerId is empty then show all the layers on map
|
|
130
|
+
this._validLayers.forEach(layer => {
|
|
131
|
+
layer.set('visible', !layerId || (layer.id === layerId));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
112
134
|
/**
|
|
113
135
|
* Get the reporter app functionality
|
|
114
136
|
* @protected
|
|
@@ -126,6 +148,12 @@ export class CrowdsourceReporter {
|
|
|
126
148
|
case "feature-details":
|
|
127
149
|
renderLists.push(this.getFeatureDetailsFlowItem());
|
|
128
150
|
break;
|
|
151
|
+
case "reporting-layer-list":
|
|
152
|
+
renderLists.push(this.getChooseCategoryFlowItem());
|
|
153
|
+
break;
|
|
154
|
+
case "feature-create":
|
|
155
|
+
renderLists.push(this.getFeatureCreateFlowItem());
|
|
156
|
+
break;
|
|
129
157
|
}
|
|
130
158
|
});
|
|
131
159
|
const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
|
|
@@ -142,34 +170,156 @@ export class CrowdsourceReporter {
|
|
|
142
170
|
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this.reportsHeader }, this._hasValidLayers &&
|
|
143
171
|
h("calcite-action", { icon: "sort-ascending-arrow", slot: this.isMobile ? "header-menu-actions" : "header-actions-end", text: this._translations.sort, "text-enabled": this.isMobile }), this._hasValidLayers &&
|
|
144
172
|
h("calcite-action", { icon: "filter", slot: this.isMobile ? "header-menu-actions" : "header-actions-end", text: this._translations.filter, "text-enabled": this.isMobile }), this.isMobile && this.getActionToExpandCollapsePanel(), this._hasValidLayers && this.enableNewReports &&
|
|
145
|
-
h("calcite-button", { appearance: "secondary", slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true, "full-width": true }, h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._translations.noLayerToDisplayErrorMsg, onLayerSelect: this.displayFeaturesList.bind(this), onLayersListLoaded: this.layerListLoaded.bind(this), showFeatureCount: true, showNextIcon: true }))));
|
|
173
|
+
h("calcite-button", { appearance: "secondary", onClick: this.navigateToChooseCategory.bind(this), slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true, "full-width": true }, h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._translations.noLayerToDisplayErrorMsg, onLayerSelect: this.displayFeaturesList.bind(this), onLayersListLoaded: this.layerListLoaded.bind(this), ref: el => this._layerList = el, showFeatureCount: true, showNextIcon: true }))));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the layer list for creating a report
|
|
177
|
+
* @returns Choose category flow item
|
|
178
|
+
* @protected
|
|
179
|
+
*/
|
|
180
|
+
getChooseCategoryFlowItem() {
|
|
181
|
+
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._translations.createReportHeader, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), h("div", { class: "width-full", slot: "footer" }, h("calcite-button", { appearance: "secondary", class: "footer-top-button footer-button", disabled: !this._selectedLayerId, onClick: this.navigateToCreateFeature.bind(this), width: "full" }, this._translations.next), h("calcite-button", { appearance: "outline", class: "footer-button", onClick: this.backFromSelectedPanel.bind(this), width: "full" }, this._translations.cancel)), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.chooseCategoryMsg)), h("layer-list", { class: "height-full", layers: this.layers, mapView: this.mapView, noLayerErrorMsg: this._translations.noLayerToDisplayErrorMsg, onLayerSelect: this.highlightSelectedLayer.bind(this), showFeatureCount: false, showNextIcon: false }))));
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get Feature create form of the selected feature layer
|
|
185
|
+
* @returns feature create form
|
|
186
|
+
* @protected
|
|
187
|
+
*/
|
|
188
|
+
getFeatureCreateFlowItem() {
|
|
189
|
+
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.backFromCreateFeaturePanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), this._showSubmitCancelButton && h("div", { class: "width-full", slot: "footer" }, h("calcite-button", { appearance: "secondary", class: "footer-top-button footer-button", onClick: this.onSubmitButtonClick.bind(this), width: "full" }, this._translations.submit), h("calcite-button", { appearance: "outline", class: "footer-button", onClick: this.backFromCreateFeaturePanel.bind(this), width: "full" }, this._translations.cancel)), h("calcite-panel", { "full-height": true, "full-width": true }, h("calcite-notice", { class: "notice-msg", icon: "lightbulb", kind: "success", open: true }, h("div", { slot: "message" }, this._translations.featureEditFormInfoMsg)), h("create-feature", { customizeSubmit: true, mapView: this.mapView, onDrawComplete: this.onDrawComplete.bind(this), onEditingAttachment: this.showSubmitCancelButton.bind(this), onFail: this.createFeatureFailed.bind(this), onSuccess: this.onReportSubmitted.bind(this), ref: el => this._createFeature = el, selectedLayerId: this._selectedLayerId }))));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* When drawing of incident location completed on map show the submit and cancel button
|
|
193
|
+
* @protected
|
|
194
|
+
*/
|
|
195
|
+
onDrawComplete() {
|
|
196
|
+
this._showSubmitCancelButton = true;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* When Add attachment panel is enabled hide the submit and cancel button
|
|
200
|
+
* @protected
|
|
201
|
+
*/
|
|
202
|
+
showSubmitCancelButton(evt) {
|
|
203
|
+
this._showSubmitCancelButton = !evt.detail;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* On back from create feature, call submit editor to destroy the Editor widget instance
|
|
207
|
+
* @protected
|
|
208
|
+
*/
|
|
209
|
+
onSubmitButtonClick() {
|
|
210
|
+
if (this._createFeature) {
|
|
211
|
+
this._createFeature.submit();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* On back from create feature, call close editor to destroy the Editor widget instance
|
|
216
|
+
* @protected
|
|
217
|
+
*/
|
|
218
|
+
backFromCreateFeaturePanel() {
|
|
219
|
+
if (this._createFeature) {
|
|
220
|
+
this._createFeature.close();
|
|
221
|
+
}
|
|
222
|
+
this.backFromSelectedPanel();
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* On creating the feature is failed, show the error message
|
|
226
|
+
* @param evt Event which has feature failed message
|
|
227
|
+
* @protected
|
|
228
|
+
*/
|
|
229
|
+
createFeatureFailed(evt) {
|
|
230
|
+
console.error(evt.detail);
|
|
231
|
+
this._featureCreationFailedErrorMsg = evt.detail.message;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* On submit report navigate to the layer list home page and refresh the layer list
|
|
235
|
+
* @protected
|
|
236
|
+
*/
|
|
237
|
+
onReportSubmitted() {
|
|
238
|
+
this._reportSubmitted = true;
|
|
239
|
+
this.navigateToHomePage();
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Navigates to layer-list
|
|
243
|
+
* @protected
|
|
244
|
+
*/
|
|
245
|
+
navigateToHomePage() {
|
|
246
|
+
if (this._createFeature) {
|
|
247
|
+
this._createFeature.close();
|
|
248
|
+
}
|
|
249
|
+
if (this._layerList) {
|
|
250
|
+
this._layerList.refresh();
|
|
251
|
+
}
|
|
252
|
+
this.setSelectedFeatures([]);
|
|
253
|
+
this._flowItems = ["layer-list"];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Update the selected layer id and name
|
|
257
|
+
* @param evt Event which has details of selected layerId and layerName
|
|
258
|
+
* @protected
|
|
259
|
+
*/
|
|
260
|
+
highlightSelectedLayer(evt) {
|
|
261
|
+
this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* On next button click open the feature create flow item
|
|
265
|
+
* @protected
|
|
266
|
+
*/
|
|
267
|
+
async navigateToCreateFeature() {
|
|
268
|
+
this._showSubmitCancelButton = false;
|
|
269
|
+
this._flowItems = [...this._flowItems, "feature-create"];
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* On report an incident button click open the create a report panel with the layer list
|
|
273
|
+
* @protected
|
|
274
|
+
*/
|
|
275
|
+
navigateToChooseCategory() {
|
|
276
|
+
this._flowItems = [...this._flowItems, "reporting-layer-list"];
|
|
146
277
|
}
|
|
147
278
|
/**
|
|
148
279
|
* When layer list is loaded, we will receive the list of layers, if its means we don't have any valid layer to be listed
|
|
149
280
|
* @param evt Event which has list of layers
|
|
150
281
|
* @protected
|
|
151
282
|
*/
|
|
152
|
-
layerListLoaded(evt) {
|
|
283
|
+
async layerListLoaded(evt) {
|
|
153
284
|
const layersListed = evt.detail;
|
|
154
|
-
|
|
285
|
+
//consider only the layers listed in the layer-list component
|
|
286
|
+
const allMapLayers = await getAllLayers(this.mapView);
|
|
287
|
+
this._validLayers = [];
|
|
288
|
+
allMapLayers.forEach((eachLayer) => {
|
|
289
|
+
if (layersListed.includes(eachLayer.id)) {
|
|
290
|
+
this._validLayers.push(eachLayer);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
//handleMap click on layer list loaded
|
|
294
|
+
this.handleMapClick();
|
|
295
|
+
//update the has valid layer state
|
|
155
296
|
this._hasValidLayers = layersListed.length > 0;
|
|
297
|
+
//navigate to the feature details if URL params found
|
|
298
|
+
if (!this._urlParamsLoaded) {
|
|
299
|
+
this._urlParamsLoaded = true;
|
|
300
|
+
await this.loadFeatureFromURLParams();
|
|
301
|
+
}
|
|
156
302
|
}
|
|
157
303
|
/**On click of layer list item show feature list
|
|
158
304
|
* @param evt Event which has details of selected layerId and layerName
|
|
159
305
|
* @protected
|
|
160
306
|
*/
|
|
161
307
|
displayFeaturesList(evt) {
|
|
162
|
-
this.
|
|
163
|
-
this._selectedLayerName = evt.detail.layerName;
|
|
308
|
+
this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
|
|
164
309
|
this._flowItems = [...this._flowItems, "feature-list"];
|
|
165
310
|
}
|
|
166
311
|
/**
|
|
167
|
-
* On back from
|
|
312
|
+
* On back from selected panel navigate to the previous panel
|
|
168
313
|
* @protected
|
|
169
314
|
*/
|
|
170
|
-
|
|
315
|
+
backFromSelectedPanel() {
|
|
171
316
|
const updatedFlowItems = [...this._flowItems];
|
|
172
317
|
updatedFlowItems.pop();
|
|
318
|
+
//Back to layer list, and return as the flowItems will be reset in navigateToHomePage
|
|
319
|
+
if (updatedFlowItems.length === 1) {
|
|
320
|
+
this.navigateToHomePage();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
173
323
|
this._flowItems = [...updatedFlowItems];
|
|
174
324
|
}
|
|
175
325
|
/**
|
|
@@ -185,7 +335,7 @@ export class CrowdsourceReporter {
|
|
|
185
335
|
* @param evt Event which has details of selected feature
|
|
186
336
|
*/
|
|
187
337
|
async onFeatureSelectFromList(evt) {
|
|
188
|
-
this.
|
|
338
|
+
this.setSelectedFeatures([evt.detail]);
|
|
189
339
|
this._flowItems = [...this._flowItems, "feature-details"];
|
|
190
340
|
}
|
|
191
341
|
/**
|
|
@@ -196,26 +346,50 @@ export class CrowdsourceReporter {
|
|
|
196
346
|
* @protected
|
|
197
347
|
*/
|
|
198
348
|
getFeatureListFlowItem(layerId, layerName) {
|
|
199
|
-
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: layerName, onCalciteFlowItemBack: this.
|
|
200
|
-
h("calcite-button", { appearance: "secondary", slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true }, h("feature-list", { class: "height-full", highlightOnMap: true, mapView: this.mapView, noFeaturesFoundMsg: this._translations.featureErrorMsg, onFeatureSelect: this.onFeatureSelectFromList.bind(this), pageSize: 30, selectedLayerId: layerId }))));
|
|
349
|
+
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: layerName, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, h("calcite-action", { icon: "sort-ascending-arrow", slot: this.isMobile ? "header-menu-actions" : "header-actions-end", text: this._translations.sort, "text-enabled": this.isMobile }), h("calcite-action", { icon: "filter", slot: this.isMobile ? "header-menu-actions" : "header-actions-end", text: this._translations.filter, "text-enabled": this.isMobile }), this.isMobile && this.getActionToExpandCollapsePanel(), this.enableNewReports &&
|
|
350
|
+
h("calcite-button", { appearance: "secondary", onClick: this.navigateToCreateFeature.bind(this), slot: "footer", width: "full" }, this.reportButtonText), h("calcite-panel", { "full-height": true }, h("feature-list", { class: "height-full", highlightOnMap: true, mapView: this.mapView, noFeaturesFoundMsg: this._translations.featureErrorMsg, onFeatureSelect: this.onFeatureSelectFromList.bind(this), pageSize: 30, selectedLayerId: layerId }))));
|
|
201
351
|
}
|
|
202
352
|
/**
|
|
203
353
|
* Returns the calcite-flow item for feature details
|
|
204
354
|
* @returns Node
|
|
205
355
|
*/
|
|
206
356
|
getFeatureDetailsFlowItem() {
|
|
207
|
-
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.
|
|
357
|
+
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.backFromSelectedPanel.bind(this) }, this.isMobile && this.getActionToExpandCollapsePanel(), h("instant-apps-social-share", { autoUpdateShareUrl: false, embed: false, popoverButtonIconScale: "s", ref: el => this._shareNode = el, scale: "m", shareButtonColor: "neutral", shareButtonType: "action", slot: "header-actions-end", socialMedia: true, view: this.mapView }), h("calcite-panel", { "full-height": true }, h("info-card", { allowEditing: false, graphics: this._selectedFeature, isLoading: false, isMobile: false, mapView: this.mapView, onSelectionChanged: this.featureDetailsChanged.bind(this), zoomAndScrollToSelected: true }))));
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Sets the selected features and updates the first feature as the current selected feature
|
|
361
|
+
* @param features Graphics array of the features selected
|
|
362
|
+
*/
|
|
363
|
+
setSelectedFeatures(features) {
|
|
364
|
+
this._selectedFeature = features;
|
|
365
|
+
this.setCurrentFeature(this._selectedFeature.length ? this._selectedFeature[0] : null);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Set the object id of the current selected feature, and also updates the current selected layer details
|
|
369
|
+
* @param selectedFeature Graphic currently shown in feature details
|
|
370
|
+
*/
|
|
371
|
+
setCurrentFeature(selectedFeature) {
|
|
372
|
+
if (selectedFeature && selectedFeature.layer) {
|
|
373
|
+
const layer = selectedFeature.layer;
|
|
374
|
+
this.setSelectedLayer(layer.id, layer.title);
|
|
375
|
+
this._currentFeatureId = selectedFeature.attributes[layer.objectIdField];
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
this.setSelectedLayer('', '');
|
|
379
|
+
this._currentFeatureId = '';
|
|
380
|
+
}
|
|
381
|
+
this._updateShareURL();
|
|
208
382
|
}
|
|
209
383
|
/**
|
|
210
384
|
* On Feature details change update the Layer title and the current selected layer id
|
|
211
385
|
* @param evt Event hold the details of current feature graphic in the info-card
|
|
212
386
|
*/
|
|
213
387
|
featureDetailsChanged(evt) {
|
|
214
|
-
this.
|
|
215
|
-
this._selectedLayerName = evt.detail[0].layer.title;
|
|
388
|
+
this.setCurrentFeature(evt.detail[0]);
|
|
216
389
|
}
|
|
217
390
|
/**
|
|
218
391
|
* Returns the action button to Expand/Collapse side panel in mobile mode
|
|
392
|
+
* @protected
|
|
219
393
|
*/
|
|
220
394
|
getActionToExpandCollapsePanel() {
|
|
221
395
|
return (h("calcite-action", { icon: this._sidePanelCollapsed ? "chevrons-up" : "chevrons-down", onClick: this.toggleSidePanel.bind(this), slot: "header-actions-end", text: this._sidePanelCollapsed ? this._translations.expand : this._translations.collapse }));
|
|
@@ -239,36 +413,26 @@ export class CrowdsourceReporter {
|
|
|
239
413
|
* Handle map click event
|
|
240
414
|
* @param layers Array of layerIds
|
|
241
415
|
*
|
|
242
|
-
*
|
|
416
|
+
* @protected
|
|
243
417
|
*/
|
|
244
|
-
handleMapClick(
|
|
418
|
+
handleMapClick() {
|
|
245
419
|
if (this._mapClickHandle) {
|
|
246
420
|
this._mapClickHandle.remove();
|
|
247
421
|
}
|
|
248
|
-
this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", (
|
|
249
|
-
void this.onMapClick(event, layers);
|
|
250
|
-
});
|
|
422
|
+
this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", this.onMapClick.bind(this));
|
|
251
423
|
}
|
|
252
424
|
/**
|
|
253
425
|
* On map click do hitTest and get the clicked graphics of valid layers and show feature details
|
|
254
|
-
* @param event
|
|
255
|
-
* @param layers
|
|
426
|
+
* @param event IMapClick map click event details
|
|
256
427
|
*
|
|
257
428
|
* @protected
|
|
258
429
|
*/
|
|
259
|
-
async onMapClick(event
|
|
430
|
+
async onMapClick(event) {
|
|
260
431
|
//disable map popup
|
|
261
432
|
this.mapView.popupEnabled = false;
|
|
262
433
|
// only include graphics from valid layers listed in the layer list widget
|
|
263
|
-
const allMapLayers = await getAllLayers(this.mapView);
|
|
264
|
-
const validLayers = [];
|
|
265
|
-
allMapLayers.forEach((eachLayer) => {
|
|
266
|
-
if (layers.includes(eachLayer.id)) {
|
|
267
|
-
validLayers.push(eachLayer);
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
434
|
const opts = {
|
|
271
|
-
include:
|
|
435
|
+
include: this._validLayers
|
|
272
436
|
};
|
|
273
437
|
// Perform a hitTest on the View
|
|
274
438
|
const hitTest = await this.mapView.hitTest(event, opts);
|
|
@@ -281,7 +445,7 @@ export class CrowdsourceReporter {
|
|
|
281
445
|
}
|
|
282
446
|
});
|
|
283
447
|
//update the selectedFeature
|
|
284
|
-
this.
|
|
448
|
+
this.setSelectedFeatures(clickedGraphics);
|
|
285
449
|
//if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
|
|
286
450
|
// eslint-disable-next-line unicorn/prefer-ternary
|
|
287
451
|
if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
|
|
@@ -301,6 +465,59 @@ export class CrowdsourceReporter {
|
|
|
301
465
|
const messages = await getLocaleComponentStrings(this.el);
|
|
302
466
|
this._translations = messages[0];
|
|
303
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Updates the share url for current selected feature
|
|
470
|
+
* @protected
|
|
471
|
+
*/
|
|
472
|
+
_updateShareURL() {
|
|
473
|
+
var _a, _b;
|
|
474
|
+
const url = (_a = this._shareNode) === null || _a === void 0 ? void 0 : _a.shareUrl;
|
|
475
|
+
if (!url) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const urlObj = new URL(url);
|
|
479
|
+
//set the selected layers id
|
|
480
|
+
if (this._selectedLayerId) {
|
|
481
|
+
urlObj.searchParams.set("layerid", this._selectedLayerId);
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
urlObj.searchParams.delete("layerid");
|
|
485
|
+
}
|
|
486
|
+
//Set the selected features objectid
|
|
487
|
+
if ((_b = this._selectedFeature) === null || _b === void 0 ? void 0 : _b.length) {
|
|
488
|
+
urlObj.searchParams.set("oid", this._currentFeatureId);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
urlObj.searchParams.delete("oid");
|
|
492
|
+
}
|
|
493
|
+
//update the url in share component
|
|
494
|
+
this._shareNode.shareUrl = urlObj.href;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Navigates to selected features detail based on the URL params
|
|
498
|
+
* @protected
|
|
499
|
+
*/
|
|
500
|
+
async loadFeatureFromURLParams() {
|
|
501
|
+
if (this.layerId && this.objectId) {
|
|
502
|
+
const layer = await getLayerOrTable(this.mapView, this.layerId);
|
|
503
|
+
if (layer) {
|
|
504
|
+
// only query if we have some ids...query with no ids will result in all features being returned
|
|
505
|
+
const featureSet = await queryFeaturesByID([Number(this.objectId)], layer, [], false, this.mapView.spatialReference);
|
|
506
|
+
if (featureSet.length) {
|
|
507
|
+
//update the selectedFeature
|
|
508
|
+
this._selectedFeature = featureSet;
|
|
509
|
+
//if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
|
|
510
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
511
|
+
if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
|
|
512
|
+
this._flowItems = [...this._flowItems, "feature-details"];
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
this._flowItems = [...this._flowItems];
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
304
521
|
static get is() { return "crowdsource-reporter"; }
|
|
305
522
|
static get originalStyleUrls() {
|
|
306
523
|
return {
|
|
@@ -485,6 +702,40 @@ export class CrowdsourceReporter {
|
|
|
485
702
|
"text": "esri/views/MapView: https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html"
|
|
486
703
|
}
|
|
487
704
|
},
|
|
705
|
+
"layerId": {
|
|
706
|
+
"type": "string",
|
|
707
|
+
"mutable": false,
|
|
708
|
+
"complexType": {
|
|
709
|
+
"original": "string",
|
|
710
|
+
"resolved": "string",
|
|
711
|
+
"references": {}
|
|
712
|
+
},
|
|
713
|
+
"required": false,
|
|
714
|
+
"optional": false,
|
|
715
|
+
"docs": {
|
|
716
|
+
"tags": [],
|
|
717
|
+
"text": "string: Layer id of the feature from URL params"
|
|
718
|
+
},
|
|
719
|
+
"attribute": "layer-id",
|
|
720
|
+
"reflect": false
|
|
721
|
+
},
|
|
722
|
+
"objectId": {
|
|
723
|
+
"type": "string",
|
|
724
|
+
"mutable": false,
|
|
725
|
+
"complexType": {
|
|
726
|
+
"original": "string",
|
|
727
|
+
"resolved": "string",
|
|
728
|
+
"references": {}
|
|
729
|
+
},
|
|
730
|
+
"required": false,
|
|
731
|
+
"optional": false,
|
|
732
|
+
"docs": {
|
|
733
|
+
"tags": [],
|
|
734
|
+
"text": "string: Object id of the feature from URL params"
|
|
735
|
+
},
|
|
736
|
+
"attribute": "object-id",
|
|
737
|
+
"reflect": false
|
|
738
|
+
},
|
|
488
739
|
"reportButtonText": {
|
|
489
740
|
"type": "string",
|
|
490
741
|
"mutable": false,
|
|
@@ -701,7 +952,10 @@ export class CrowdsourceReporter {
|
|
|
701
952
|
"_sidePanelCollapsed": {},
|
|
702
953
|
"_translations": {},
|
|
703
954
|
"_hasValidLayers": {},
|
|
704
|
-
"_selectedLayerName": {}
|
|
955
|
+
"_selectedLayerName": {},
|
|
956
|
+
"_reportSubmitted": {},
|
|
957
|
+
"_showSubmitCancelButton": {},
|
|
958
|
+
"_featureCreationFailedErrorMsg": {}
|
|
705
959
|
};
|
|
706
960
|
}
|
|
707
961
|
static get events() {
|
|
@@ -36,6 +36,23 @@ export class LayerList {
|
|
|
36
36
|
}
|
|
37
37
|
//--------------------------------------------------------------------------
|
|
38
38
|
//
|
|
39
|
+
// Watch handlers
|
|
40
|
+
//
|
|
41
|
+
//--------------------------------------------------------------------------
|
|
42
|
+
//--------------------------------------------------------------------------
|
|
43
|
+
//
|
|
44
|
+
// Methods (public)
|
|
45
|
+
//
|
|
46
|
+
//--------------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Refresh the layer list which will fetch the latest layer count and update the list
|
|
49
|
+
* @returns Promise that resolves when the operation is complete
|
|
50
|
+
*/
|
|
51
|
+
async refresh() {
|
|
52
|
+
await this.setLayers();
|
|
53
|
+
}
|
|
54
|
+
//--------------------------------------------------------------------------
|
|
55
|
+
//
|
|
39
56
|
// Functions (lifecycle)
|
|
40
57
|
//
|
|
41
58
|
//--------------------------------------------------------------------------
|
|
@@ -60,7 +77,7 @@ export class LayerList {
|
|
|
60
77
|
render() {
|
|
61
78
|
return (h(Fragment, null, this._isLoading && h("calcite-loader", { scale: "m" }), !this._isLoading && this.mapView && this._noLayersToDisplay &&
|
|
62
79
|
h("calcite-notice", { class: "error-msg", icon: "layers-reference", kind: "danger", open: true }, h("div", { slot: "title" }, this._translations.error), h("div", { slot: "message" }, this.noLayerErrorMsg ? this.noLayerErrorMsg : this._translations.noLayerToDisplayErrorMsg)), !this._isLoading && this.mapView &&
|
|
63
|
-
h("calcite-list", { "selection-appearance": "border", "selection-mode": this.showNextIcon ? "none" : "single" }, this.renderLayerList())));
|
|
80
|
+
h("calcite-list", { "selection-appearance": "border", "selection-mode": this.showNextIcon ? "none" : "single-persist" }, this.renderLayerList())));
|
|
64
81
|
}
|
|
65
82
|
//--------------------------------------------------------------------------
|
|
66
83
|
//
|
|
@@ -87,21 +104,24 @@ export class LayerList {
|
|
|
87
104
|
this._layerItemsHash = await getMapLayerHash(this.mapView, true);
|
|
88
105
|
const allMapLayers = await getAllLayers(this.mapView);
|
|
89
106
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
90
|
-
|
|
107
|
+
allMapLayers.forEach(async (eachLayer) => {
|
|
91
108
|
var _a, _b;
|
|
92
109
|
//TODO: checking editable condition could be configurable
|
|
93
|
-
if ((eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.type) === "feature" && (eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.editingEnabled) && ((_b = (_a = eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.capabilities) === null || _a === void 0 ? void 0 : _a.operations) === null || _b === void 0 ? void 0 : _b.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
if ((eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.type) === "feature" && (eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.editingEnabled) && ((_b = (_a = eachLayer === null || eachLayer === void 0 ? void 0 : eachLayer.capabilities) === null || _a === void 0 ? void 0 : _a.operations) === null || _b === void 0 ? void 0 : _b.supportsAdd)) {
|
|
111
|
+
this._layerItemsHash[eachLayer.id].supportsAdd = true;
|
|
112
|
+
if (this.showFeatureCount) {
|
|
113
|
+
const q = eachLayer.createQuery();
|
|
114
|
+
const result = eachLayer.queryFeatureCount(q);
|
|
115
|
+
def.push(result);
|
|
116
|
+
void result.then(async (resCount) => {
|
|
117
|
+
const formattedCount = !isNaN(resCount) ? await formatNumber(resCount, {
|
|
118
|
+
places: 0,
|
|
119
|
+
api: 4,
|
|
120
|
+
type: "decimal"
|
|
121
|
+
}) : "";
|
|
122
|
+
this._layerItemsHash[eachLayer.id].formattedFeatureCount = formattedCount;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
105
125
|
}
|
|
106
126
|
});
|
|
107
127
|
await Promise.all(def).then(() => {
|
|
@@ -129,9 +149,9 @@ export class LayerList {
|
|
|
129
149
|
var _a;
|
|
130
150
|
const configuredLayers = ((_a = this.layers) === null || _a === void 0 ? void 0 : _a.length) > 0 ? this.layers : [];
|
|
131
151
|
return Object.keys(hash).reduce((prev, cur) => {
|
|
132
|
-
let showLayer = hash[cur].
|
|
152
|
+
let showLayer = hash[cur].supportsAdd;
|
|
133
153
|
if ((configuredLayers === null || configuredLayers === void 0 ? void 0 : configuredLayers.length) > 0) {
|
|
134
|
-
showLayer = configuredLayers.indexOf(cur) > -1 ? hash[cur].
|
|
154
|
+
showLayer = configuredLayers.indexOf(cur) > -1 ? hash[cur].supportsAdd : false;
|
|
135
155
|
}
|
|
136
156
|
if (showLayer) {
|
|
137
157
|
prev.push(cur);
|
|
@@ -323,5 +343,29 @@ export class LayerList {
|
|
|
323
343
|
}
|
|
324
344
|
}];
|
|
325
345
|
}
|
|
346
|
+
static get methods() {
|
|
347
|
+
return {
|
|
348
|
+
"refresh": {
|
|
349
|
+
"complexType": {
|
|
350
|
+
"signature": "() => Promise<void>",
|
|
351
|
+
"parameters": [],
|
|
352
|
+
"references": {
|
|
353
|
+
"Promise": {
|
|
354
|
+
"location": "global",
|
|
355
|
+
"id": "global::Promise"
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"return": "Promise<void>"
|
|
359
|
+
},
|
|
360
|
+
"docs": {
|
|
361
|
+
"text": "Refresh the layer list which will fetch the latest layer count and update the list",
|
|
362
|
+
"tags": [{
|
|
363
|
+
"name": "returns",
|
|
364
|
+
"text": "Promise that resolves when the operation is complete"
|
|
365
|
+
}]
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
}
|
|
326
370
|
static get elementRef() { return "el"; }
|
|
327
371
|
}
|