@esri/solutions-components 0.7.30 → 0.7.31
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} +235 -19
- package/dist/cjs/card-manager_3.cjs.entry.js +1 -1
- package/dist/cjs/crowdsource-reporter.cjs.entry.js +221 -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 +23 -0
- package/dist/collection/components/create-feature/create-feature.js +361 -0
- package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.css +10 -1
- package/dist/collection/components/crowdsource-reporter/crowdsource-reporter.js +260 -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/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 +226 -0
- package/dist/components/crowdsource-reporter.js +297 -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} +235 -20
- package/dist/esm/card-manager_3.entry.js +1 -1
- package/dist/esm/crowdsource-reporter.entry.js +222 -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/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-b4e2cac4.entry.js +17 -0
- package/dist/solutions-components/p-bb6562ab.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 +107 -0
- package/dist/types/components/crowdsource-reporter/crowdsource-reporter.d.ts +132 -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 +89 -0
- package/dist/types/preact.d.ts +6 -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
|
//
|
|
@@ -89,7 +95,8 @@ export class CrowdsourceReporter {
|
|
|
89
95
|
* Renders the component.
|
|
90
96
|
*/
|
|
91
97
|
render() {
|
|
92
|
-
|
|
98
|
+
const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
|
|
99
|
+
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
100
|
}
|
|
94
101
|
//--------------------------------------------------------------------------
|
|
95
102
|
//
|
|
@@ -109,6 +116,15 @@ export class CrowdsourceReporter {
|
|
|
109
116
|
]);
|
|
110
117
|
this.reactiveUtils = reactiveUtils;
|
|
111
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Set the selected layer id and layer name
|
|
121
|
+
* @param layerId string layerId of the selected layer
|
|
122
|
+
* @param layerName string layerName of the selected layer
|
|
123
|
+
*/
|
|
124
|
+
setSelectedLayer(layerId, layerName) {
|
|
125
|
+
this._selectedLayerId = layerId;
|
|
126
|
+
this._selectedLayerName = layerName;
|
|
127
|
+
}
|
|
112
128
|
/**
|
|
113
129
|
* Get the reporter app functionality
|
|
114
130
|
* @protected
|
|
@@ -126,6 +142,12 @@ export class CrowdsourceReporter {
|
|
|
126
142
|
case "feature-details":
|
|
127
143
|
renderLists.push(this.getFeatureDetailsFlowItem());
|
|
128
144
|
break;
|
|
145
|
+
case "reporting-layer-list":
|
|
146
|
+
renderLists.push(this.getChooseCategoryFlowItem());
|
|
147
|
+
break;
|
|
148
|
+
case "feature-create":
|
|
149
|
+
renderLists.push(this.getFeatureCreateFlowItem());
|
|
150
|
+
break;
|
|
129
151
|
}
|
|
130
152
|
});
|
|
131
153
|
const themeClass = this.theme === "dark" ? "calcite-mode-dark" : "calcite-mode-light";
|
|
@@ -142,34 +164,135 @@ export class CrowdsourceReporter {
|
|
|
142
164
|
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this.reportsHeader }, this._hasValidLayers &&
|
|
143
165
|
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
166
|
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 }))));
|
|
167
|
+
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 }))));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get the layer list for creating a report
|
|
171
|
+
* @returns Choose category flow item
|
|
172
|
+
* @protected
|
|
173
|
+
*/
|
|
174
|
+
getChooseCategoryFlowItem() {
|
|
175
|
+
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 }))));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get Feature create form of the selected feature layer
|
|
179
|
+
* @returns feature create form
|
|
180
|
+
* @protected
|
|
181
|
+
*/
|
|
182
|
+
getFeatureCreateFlowItem() {
|
|
183
|
+
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", { mapView: this.mapView, onDrawComplete: this.showSubmitCancelButton.bind(this), onFail: this.createFeatureFailed.bind(this), onSuccess: this.navigateHomePage.bind(this), ref: el => this._createFeature = el, selectedLayerId: this._selectedLayerId }))));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* When drawing of incident location completed on map show the submit and cancel button
|
|
187
|
+
* @protected
|
|
188
|
+
*/
|
|
189
|
+
showSubmitCancelButton() {
|
|
190
|
+
this._showSubmitCancelButton = true;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* On back from create feature, call submit editor to destroy the Editor widget instance
|
|
194
|
+
* @protected
|
|
195
|
+
*/
|
|
196
|
+
onSubmitButtonClick() {
|
|
197
|
+
if (this._createFeature) {
|
|
198
|
+
this._createFeature.submit();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* On back from create feature, call close editor to destroy the Editor widget instance
|
|
203
|
+
* @protected
|
|
204
|
+
*/
|
|
205
|
+
backFromCreateFeaturePanel() {
|
|
206
|
+
if (this._createFeature) {
|
|
207
|
+
this._createFeature.close();
|
|
208
|
+
}
|
|
209
|
+
this.backFromSelectedPanel();
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* On creating the feature is failed, show the error message
|
|
213
|
+
* @param evt Event which has feature failed message
|
|
214
|
+
* @protected
|
|
215
|
+
*/
|
|
216
|
+
createFeatureFailed(evt) {
|
|
217
|
+
console.error(evt.detail);
|
|
218
|
+
this._featureCreationFailedErrorMsg = evt.detail.message;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* On submit report navigate to the layer list home page and refresh the layer list
|
|
222
|
+
* @protected
|
|
223
|
+
*/
|
|
224
|
+
navigateHomePage() {
|
|
225
|
+
this._reportSubmitted = true;
|
|
226
|
+
if (this._layerList) {
|
|
227
|
+
this._layerList.refresh();
|
|
228
|
+
}
|
|
229
|
+
this._flowItems = ["layer-list"];
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Update the selected layer id and name
|
|
233
|
+
* @param evt Event which has details of selected layerId and layerName
|
|
234
|
+
* @protected
|
|
235
|
+
*/
|
|
236
|
+
highlightSelectedLayer(evt) {
|
|
237
|
+
this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* On next button click open the feature create flow item
|
|
241
|
+
* @protected
|
|
242
|
+
*/
|
|
243
|
+
async navigateToCreateFeature() {
|
|
244
|
+
this._showSubmitCancelButton = false;
|
|
245
|
+
this._flowItems = [...this._flowItems, "feature-create"];
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* On report an incident button click open the create a report panel with the layer list
|
|
249
|
+
* @protected
|
|
250
|
+
*/
|
|
251
|
+
navigateToChooseCategory() {
|
|
252
|
+
this._flowItems = [...this._flowItems, "reporting-layer-list"];
|
|
146
253
|
}
|
|
147
254
|
/**
|
|
148
255
|
* 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
256
|
* @param evt Event which has list of layers
|
|
150
257
|
* @protected
|
|
151
258
|
*/
|
|
152
|
-
layerListLoaded(evt) {
|
|
259
|
+
async layerListLoaded(evt) {
|
|
153
260
|
const layersListed = evt.detail;
|
|
154
|
-
|
|
261
|
+
//consider only the layers listed in the layer-list component
|
|
262
|
+
const allMapLayers = await getAllLayers(this.mapView);
|
|
263
|
+
this._validLayers = [];
|
|
264
|
+
allMapLayers.forEach((eachLayer) => {
|
|
265
|
+
if (layersListed.includes(eachLayer.id)) {
|
|
266
|
+
this._validLayers.push(eachLayer);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
//handleMap click on layer list loaded
|
|
270
|
+
this.handleMapClick();
|
|
271
|
+
//update the has valid layer state
|
|
155
272
|
this._hasValidLayers = layersListed.length > 0;
|
|
273
|
+
//navigate to the feature details if URL params found
|
|
274
|
+
await this.loadFeatureFromURLParams();
|
|
156
275
|
}
|
|
157
276
|
/**On click of layer list item show feature list
|
|
158
277
|
* @param evt Event which has details of selected layerId and layerName
|
|
159
278
|
* @protected
|
|
160
279
|
*/
|
|
161
280
|
displayFeaturesList(evt) {
|
|
162
|
-
this.
|
|
163
|
-
this._selectedLayerName = evt.detail.layerName;
|
|
281
|
+
this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName);
|
|
164
282
|
this._flowItems = [...this._flowItems, "feature-list"];
|
|
165
283
|
}
|
|
166
284
|
/**
|
|
167
|
-
* On back from
|
|
285
|
+
* On back from selected panel navigate to the previous panel
|
|
168
286
|
* @protected
|
|
169
287
|
*/
|
|
170
|
-
|
|
288
|
+
backFromSelectedPanel() {
|
|
171
289
|
const updatedFlowItems = [...this._flowItems];
|
|
172
290
|
updatedFlowItems.pop();
|
|
291
|
+
//clear the selected layer and feature when back to layer list
|
|
292
|
+
if (updatedFlowItems.length === 1) {
|
|
293
|
+
this.setSelectedLayer('', '');
|
|
294
|
+
this.setSelectedFeatures([]);
|
|
295
|
+
}
|
|
173
296
|
this._flowItems = [...updatedFlowItems];
|
|
174
297
|
}
|
|
175
298
|
/**
|
|
@@ -185,7 +308,7 @@ export class CrowdsourceReporter {
|
|
|
185
308
|
* @param evt Event which has details of selected feature
|
|
186
309
|
*/
|
|
187
310
|
async onFeatureSelectFromList(evt) {
|
|
188
|
-
this.
|
|
311
|
+
this.setSelectedFeatures([evt.detail]);
|
|
189
312
|
this._flowItems = [...this._flowItems, "feature-details"];
|
|
190
313
|
}
|
|
191
314
|
/**
|
|
@@ -196,26 +319,50 @@ export class CrowdsourceReporter {
|
|
|
196
319
|
* @protected
|
|
197
320
|
*/
|
|
198
321
|
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 }))));
|
|
322
|
+
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 &&
|
|
323
|
+
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
324
|
}
|
|
202
325
|
/**
|
|
203
326
|
* Returns the calcite-flow item for feature details
|
|
204
327
|
* @returns Node
|
|
205
328
|
*/
|
|
206
329
|
getFeatureDetailsFlowItem() {
|
|
207
|
-
return (h("calcite-flow-item", { collapsed: this.isMobile && this._sidePanelCollapsed, heading: this._selectedLayerName, onCalciteFlowItemBack: this.
|
|
330
|
+
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 }))));
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Sets the selected features and updates the first feature as the current selected feature
|
|
334
|
+
* @param features Graphics array of the features selected
|
|
335
|
+
*/
|
|
336
|
+
setSelectedFeatures(features) {
|
|
337
|
+
this._selectedFeature = features;
|
|
338
|
+
this.setCurrentFeature(this._selectedFeature.length ? this._selectedFeature[0] : null);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Set the object id of the current selected feature, and also updates the current selected layer details
|
|
342
|
+
* @param selectedFeature Graphic currently shown in feature details
|
|
343
|
+
*/
|
|
344
|
+
setCurrentFeature(selectedFeature) {
|
|
345
|
+
if (selectedFeature && selectedFeature.layer) {
|
|
346
|
+
const layer = selectedFeature.layer;
|
|
347
|
+
this.setSelectedLayer(layer.id, layer.title);
|
|
348
|
+
this._currentFeatureId = selectedFeature.attributes[layer.objectIdField];
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
this.setSelectedLayer('', '');
|
|
352
|
+
this._currentFeatureId = '';
|
|
353
|
+
}
|
|
354
|
+
this._updateShareURL();
|
|
208
355
|
}
|
|
209
356
|
/**
|
|
210
357
|
* On Feature details change update the Layer title and the current selected layer id
|
|
211
358
|
* @param evt Event hold the details of current feature graphic in the info-card
|
|
212
359
|
*/
|
|
213
360
|
featureDetailsChanged(evt) {
|
|
214
|
-
this.
|
|
215
|
-
this._selectedLayerName = evt.detail[0].layer.title;
|
|
361
|
+
this.setCurrentFeature(evt.detail[0]);
|
|
216
362
|
}
|
|
217
363
|
/**
|
|
218
364
|
* Returns the action button to Expand/Collapse side panel in mobile mode
|
|
365
|
+
* @protected
|
|
219
366
|
*/
|
|
220
367
|
getActionToExpandCollapsePanel() {
|
|
221
368
|
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 +386,26 @@ export class CrowdsourceReporter {
|
|
|
239
386
|
* Handle map click event
|
|
240
387
|
* @param layers Array of layerIds
|
|
241
388
|
*
|
|
242
|
-
*
|
|
389
|
+
* @protected
|
|
243
390
|
*/
|
|
244
|
-
handleMapClick(
|
|
391
|
+
handleMapClick() {
|
|
245
392
|
if (this._mapClickHandle) {
|
|
246
393
|
this._mapClickHandle.remove();
|
|
247
394
|
}
|
|
248
|
-
this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", (
|
|
249
|
-
void this.onMapClick(event, layers);
|
|
250
|
-
});
|
|
395
|
+
this._mapClickHandle = this.reactiveUtils.on(() => this.mapView, "click", this.onMapClick.bind(this));
|
|
251
396
|
}
|
|
252
397
|
/**
|
|
253
398
|
* On map click do hitTest and get the clicked graphics of valid layers and show feature details
|
|
254
|
-
* @param event
|
|
255
|
-
* @param layers
|
|
399
|
+
* @param event IMapClick map click event details
|
|
256
400
|
*
|
|
257
401
|
* @protected
|
|
258
402
|
*/
|
|
259
|
-
async onMapClick(event
|
|
403
|
+
async onMapClick(event) {
|
|
260
404
|
//disable map popup
|
|
261
405
|
this.mapView.popupEnabled = false;
|
|
262
406
|
// 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
407
|
const opts = {
|
|
271
|
-
include:
|
|
408
|
+
include: this._validLayers
|
|
272
409
|
};
|
|
273
410
|
// Perform a hitTest on the View
|
|
274
411
|
const hitTest = await this.mapView.hitTest(event, opts);
|
|
@@ -281,7 +418,7 @@ export class CrowdsourceReporter {
|
|
|
281
418
|
}
|
|
282
419
|
});
|
|
283
420
|
//update the selectedFeature
|
|
284
|
-
this.
|
|
421
|
+
this.setSelectedFeatures(clickedGraphics);
|
|
285
422
|
//if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
|
|
286
423
|
// eslint-disable-next-line unicorn/prefer-ternary
|
|
287
424
|
if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
|
|
@@ -301,6 +438,59 @@ export class CrowdsourceReporter {
|
|
|
301
438
|
const messages = await getLocaleComponentStrings(this.el);
|
|
302
439
|
this._translations = messages[0];
|
|
303
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Updates the share url for current selected feature
|
|
443
|
+
* @returns
|
|
444
|
+
* @protected
|
|
445
|
+
*/
|
|
446
|
+
_updateShareURL() {
|
|
447
|
+
var _a, _b;
|
|
448
|
+
const url = (_a = this._shareNode) === null || _a === void 0 ? void 0 : _a.shareUrl;
|
|
449
|
+
if (!url) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const urlObj = new URL(url);
|
|
453
|
+
//set the selected layers id
|
|
454
|
+
if (this._selectedLayerId) {
|
|
455
|
+
urlObj.searchParams.set("layerid", this._selectedLayerId);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
urlObj.searchParams.delete("layerid");
|
|
459
|
+
}
|
|
460
|
+
//Set the selected features objectid
|
|
461
|
+
if ((_b = this._selectedFeature) === null || _b === void 0 ? void 0 : _b.length) {
|
|
462
|
+
urlObj.searchParams.set("oid", this._currentFeatureId);
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
urlObj.searchParams.delete("oid");
|
|
466
|
+
}
|
|
467
|
+
//update the url in share component
|
|
468
|
+
this._shareNode.shareUrl = urlObj.href;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Navigates to selected features detail based on the URL params
|
|
472
|
+
*/
|
|
473
|
+
async loadFeatureFromURLParams() {
|
|
474
|
+
if (this.layerId && this.objectId) {
|
|
475
|
+
const layer = await getLayerOrTable(this.mapView, this.layerId);
|
|
476
|
+
if (layer) {
|
|
477
|
+
// only query if we have some ids...query with no ids will result in all features being returned
|
|
478
|
+
const featureSet = await queryFeaturesByID([Number(this.objectId)], layer, [], false, this.mapView.spatialReference);
|
|
479
|
+
if (featureSet.length) {
|
|
480
|
+
//update the selectedFeature
|
|
481
|
+
this._selectedFeature = featureSet;
|
|
482
|
+
//if featureDetails not open then add it to the list else just reInit flowItems which will update details with newly selected features
|
|
483
|
+
// eslint-disable-next-line unicorn/prefer-ternary
|
|
484
|
+
if (this._flowItems.length && this._flowItems[this._flowItems.length - 1] !== "feature-details") {
|
|
485
|
+
this._flowItems = [...this._flowItems, "feature-details"];
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
this._flowItems = [...this._flowItems];
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
304
494
|
static get is() { return "crowdsource-reporter"; }
|
|
305
495
|
static get originalStyleUrls() {
|
|
306
496
|
return {
|
|
@@ -485,6 +675,40 @@ export class CrowdsourceReporter {
|
|
|
485
675
|
"text": "esri/views/MapView: https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html"
|
|
486
676
|
}
|
|
487
677
|
},
|
|
678
|
+
"layerId": {
|
|
679
|
+
"type": "string",
|
|
680
|
+
"mutable": false,
|
|
681
|
+
"complexType": {
|
|
682
|
+
"original": "string",
|
|
683
|
+
"resolved": "string",
|
|
684
|
+
"references": {}
|
|
685
|
+
},
|
|
686
|
+
"required": false,
|
|
687
|
+
"optional": false,
|
|
688
|
+
"docs": {
|
|
689
|
+
"tags": [],
|
|
690
|
+
"text": "string: Layer id of the feature from URL params"
|
|
691
|
+
},
|
|
692
|
+
"attribute": "layer-id",
|
|
693
|
+
"reflect": false
|
|
694
|
+
},
|
|
695
|
+
"objectId": {
|
|
696
|
+
"type": "string",
|
|
697
|
+
"mutable": false,
|
|
698
|
+
"complexType": {
|
|
699
|
+
"original": "string",
|
|
700
|
+
"resolved": "string",
|
|
701
|
+
"references": {}
|
|
702
|
+
},
|
|
703
|
+
"required": false,
|
|
704
|
+
"optional": false,
|
|
705
|
+
"docs": {
|
|
706
|
+
"tags": [],
|
|
707
|
+
"text": "string: Object id of the feature from URL params"
|
|
708
|
+
},
|
|
709
|
+
"attribute": "object-id",
|
|
710
|
+
"reflect": false
|
|
711
|
+
},
|
|
488
712
|
"reportButtonText": {
|
|
489
713
|
"type": "string",
|
|
490
714
|
"mutable": false,
|
|
@@ -701,7 +925,10 @@ export class CrowdsourceReporter {
|
|
|
701
925
|
"_sidePanelCollapsed": {},
|
|
702
926
|
"_translations": {},
|
|
703
927
|
"_hasValidLayers": {},
|
|
704
|
-
"_selectedLayerName": {}
|
|
928
|
+
"_selectedLayerName": {},
|
|
929
|
+
"_reportSubmitted": {},
|
|
930
|
+
"_showSubmitCancelButton": {},
|
|
931
|
+
"_featureCreationFailedErrorMsg": {}
|
|
705
932
|
};
|
|
706
933
|
}
|
|
707
934
|
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
|
}
|
|
@@ -93,23 +93,38 @@
|
|
|
93
93
|
const demo = document.getElementById("demo");
|
|
94
94
|
let custom = null;
|
|
95
95
|
let portal;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
switch (
|
|
96
|
+
let locale = 'en'
|
|
97
|
+
//Support webmap, portal and locale URL parameter
|
|
98
|
+
//Also, set search params to reporter component - layerId, objectId, center, level etc.
|
|
99
|
+
let urlObj = new URL(window.location)
|
|
100
|
+
for (const [key, value] of urlObj.searchParams.entries()) {
|
|
101
|
+
switch (key) {
|
|
102
102
|
case "webmap":
|
|
103
103
|
custom = {
|
|
104
|
-
id:
|
|
104
|
+
id: value
|
|
105
105
|
};
|
|
106
106
|
break;
|
|
107
107
|
case "portal":
|
|
108
|
-
portal =
|
|
109
|
-
|
|
108
|
+
portal = value;
|
|
109
|
+
break;
|
|
110
|
+
case "locale":
|
|
111
|
+
locale = value;
|
|
112
|
+
break;
|
|
113
|
+
case 'layerid':
|
|
114
|
+
demo.layerId = value;
|
|
115
|
+
break;
|
|
116
|
+
case 'oid':
|
|
117
|
+
demo.objectId = value;
|
|
118
|
+
case 'center' || 'level':
|
|
119
|
+
demo[key] = value;
|
|
110
120
|
break;
|
|
111
121
|
}
|
|
112
|
-
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Set the locale before the JSAPI loads
|
|
125
|
+
esriConfig.locale = locale;
|
|
126
|
+
demo.lang = locale;
|
|
127
|
+
|
|
113
128
|
//update the portalUrl if found in urlParams
|
|
114
129
|
//esriConfig.portalUrl = "https://solutions.mapsdevext.arcgis.com";
|
|
115
130
|
if (portal) {
|
|
@@ -117,7 +132,6 @@
|
|
|
117
132
|
}
|
|
118
133
|
|
|
119
134
|
let portalItem = {
|
|
120
|
-
//id: "b5bdcb1e5d684dd3b21a2d44b8e4f928"
|
|
121
135
|
//id: "f8c4d99deb3c483cac296cc261e18a25", //blank no layers
|
|
122
136
|
//id: "a7e880f7afbb471991d43c8c4f1438ac" // Se mapping
|
|
123
137
|
//id: "c720e337ff814fe4a83bc244c46f8e43" //15 Layers
|
|
@@ -125,6 +139,7 @@
|
|
|
125
139
|
//id: "dda88d905a6748a5ab46bea5be795f33" // screening layers
|
|
126
140
|
id: "b5bdcb1e5d684dd3b21a2d44b8e4f928" //Popup content
|
|
127
141
|
//id: "d399ec39959a4aac8617ae4f05dd6785" //Arcade
|
|
142
|
+
//id: "024e8a5e73a34c5aade9632d651c5750" //Attachments
|
|
128
143
|
}
|
|
129
144
|
const webMap = new WebMap({
|
|
130
145
|
portalItem: custom ?? portalItem
|
|
@@ -540,7 +540,7 @@ export function _prepareAttributeValue(attributeValue, attributeType, attributeD
|
|
|
540
540
|
if (attributeDomain && attributeDomain.type === "coded-value") {
|
|
541
541
|
// "coded-value" domain field
|
|
542
542
|
const value = attributeDomain.getName(attributeValue);
|
|
543
|
-
return value.toString();
|
|
543
|
+
return value === null || value === void 0 ? void 0 : value.toString();
|
|
544
544
|
}
|
|
545
545
|
else {
|
|
546
546
|
// Non-domain field or unsupported domain type
|
|
@@ -769,7 +769,7 @@ export function _prepareAttributeValue(
|
|
|
769
769
|
if (attributeDomain && (attributeDomain as __esri.CodedValueDomain).type === "coded-value") {
|
|
770
770
|
// "coded-value" domain field
|
|
771
771
|
const value = (attributeDomain as __esri.CodedValueDomain).getName(attributeValue);
|
|
772
|
-
return value
|
|
772
|
+
return value?.toString();
|
|
773
773
|
} else {
|
|
774
774
|
// Non-domain field or unsupported domain type
|
|
775
775
|
let value = attributeValue;
|