From 4e1f541d0b3674816f73460ec7159134910ed215 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 19:50:59 +0530 Subject: [PATCH 01/10] Implemented #868 - #868 --- src/components/crowdsource-reporter/crowdsource-reporter.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index f9e91860c..cfd1af976 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -1385,6 +1385,7 @@ export class CrowdsourceReporter { onFilterListReset={() => this._handleFilterListReset()} onFilterUpdate={() => this._handleFilterUpdate()} ref={(el) => this._filterList = el} + resetBtn={false} resetFiltersOnDisconnect={false} view={this.mapView} zoomBtn={false} From ca5ad02ea51782eb7b994275419bd3d7f58cf0d7 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 19:52:33 +0530 Subject: [PATCH 02/10] Implemented #731 - #731 --- src/components/crowdsource-reporter/crowdsource-reporter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index cfd1af976..12eb9dc99 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -1717,7 +1717,7 @@ export class CrowdsourceReporter { return this._validLayers.includes(graphic.layer); }) const nonReportingLayerGraphics = clickedGraphics.filter((graphic) => { - return !this._validLayers.includes(graphic.layer) && graphic?.layer?.id; + return !this._validLayers.includes(graphic.layer) && graphic?.layer?.popupEnabled && graphic?.layer?.id; }) // if clicked graphic's layer is one of the reporting layers then show details in layer panel From 12e61ea6dfa9048ac1f61ed2cf8413c7114970b4 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 19:55:34 +0530 Subject: [PATCH 03/10] Implemented #713 - #713 --- src/components/crowdsource-reporter/crowdsource-reporter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index 12eb9dc99..eef9ee5ab 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -748,7 +748,7 @@ export class CrowdsourceReporter { autoClose label="" offsetDistance={0} - placement={this.isMobile ? "leading-start" : "auto"} + placement={this.isMobile ? "leading-start" : "bottom-start"} pointerDisabled referenceElement="sort-popover"> From 3e3edb445b5fd69747649309d8a5d926f83b8270 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 19:58:14 +0530 Subject: [PATCH 04/10] Implemented #810 - #810 --- .../crowdsource-reporter.tsx | 8 ++++---- .../feature-details/feature-details.tsx | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index eef9ee5ab..b2bfc331f 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -1242,10 +1242,10 @@ export class CrowdsourceReporter { */ protected async getRelatedTable(): Promise { const selectedLayer = (this._currentFeature.layer as __esri.FeatureLayer); - const relatedTableIdFromRelnship = selectedLayer.relationships[0].relatedTableId; + const allRelatedTableIds = selectedLayer.relationships.map(a => a.relatedTableId); const allTables = await getAllTables(this.mapView); - const relatedTable = allTables.filter((table) => selectedLayer.url === (table as __esri.FeatureLayer).url && relatedTableIdFromRelnship === (table as __esri.FeatureLayer).layerId); - this._relatedTable = (relatedTable[0] as __esri.FeatureLayer); + const relatedTables = allTables.filter((table) => selectedLayer.url === (table as __esri.FeatureLayer).url && allRelatedTableIds.includes((table as __esri.FeatureLayer).layerId)); + this._relatedTable = (relatedTables[0] as __esri.FeatureLayer); } /** @@ -1399,7 +1399,7 @@ export class CrowdsourceReporter { * @returns Node */ protected getFeatureDetailsFlowItem(): Node { - const showCommentBtn = this._getLayersConfig(this._selectedLayerId)?.comment && this._selectedLayer.relationships.length > 0; + const showCommentBtn = this._getLayersConfig(this._selectedLayerId)?.comment && this._selectedLayer.relationships.length > 0 && this._relatedTable; return ( 0; if (commentsConfigured) { //Get comments table id from map - const relatedTableIdFromRelnship = selectedLayer.relationships[0].relatedTableId; const allTables = await getAllTables(this.mapView); - const allRelatedTables = allTables.filter((table: __esri.FeatureLayer) => selectedLayer.url === table.url && relatedTableIdFromRelnship === table.layerId); - const relatedTable = allRelatedTables?.length > 0 ? allRelatedTables[0] as __esri.FeatureLayer : null; + let relatedTable = null + let validRelationshipId = null; + allTables.some((table) => { + if (selectedLayer.url === (table as __esri.FeatureLayer).url) { + const relationship = selectedLayer.relationships.filter(a => (table as __esri.FeatureLayer).layerId === a.relatedTableId) + if (relationship?.length) { + relatedTable = table; + validRelationshipId = relationship[0].id + return true; + } + } + }); this.relatedTableId = relatedTable?.id ?? ''; //**Get the related records for the current selected feature** @@ -388,7 +397,7 @@ export class FeatureDetails { const relationshipQuery = new this.RelationshipQuery({ objectIds: [objectId], outFields: ['*'], - relationshipId: selectedLayer.relationships[0].id + relationshipId: validRelationshipId }); const result = await selectedLayer.queryRelatedFeatures(relationshipQuery).catch((e) => { console.error(e); From 23002ab6037c943d635c80941edc435cc59c15dc Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 20:01:52 +0530 Subject: [PATCH 05/10] Implemented #732 - #732 --- .../crowdsource-reporter.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index b2bfc331f..4ae57f7ea 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -518,6 +518,24 @@ export class CrowdsourceReporter { } } + /** + * Called each time the my reports toggle is changed + */ + @Watch("showMyReportsOnly") + async showMyReportsOnlyWatchHandler(): Promise { + if (this._editableLayerIds) { + await this._updateFeatures(); + setTimeout(() => { + if (this._layerList) { + void this._layerList.refresh(); + } + if (this._featureList) { + void this._featureList.refresh(); + } + }, 50) + } + } + //-------------------------------------------------------------------------- // // Methods (public) From 5e18f018d4e753a011b6257f066c5a9adaf69776 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 20:03:42 +0530 Subject: [PATCH 06/10] Implemented #605 - #605 --- src/components/feature-list/feature-list.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/feature-list/feature-list.tsx b/src/components/feature-list/feature-list.tsx index 503f7179b..f32737d4b 100644 --- a/src/components/feature-list/feature-list.tsx +++ b/src/components/feature-list/feature-list.tsx @@ -579,8 +579,7 @@ export class FeatureList { id={userInfo?.id} scale="m" slot="content-start" - thumbnail={userInfo?.userProfileUrl} - username={userInfo?.username} />} + thumbnail={userInfo?.userProfileUrl} />} {this.showFeatureSymbol &&
Date: Mon, 23 Sep 2024 20:07:47 +0530 Subject: [PATCH 07/10] Implemented #739 - #739 --- src/components.d.ts | 5 +++++ .../crowdsource-reporter/crowdsource-reporter.tsx | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components.d.ts b/src/components.d.ts index 403ca4a49..9a18fd8f4 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -2054,6 +2054,7 @@ declare global { interface HTMLFeatureDetailsElementEventMap { "loadingStatus": boolean; "commentSelect": __esri.Graphic; + "addComment": void; "featureSelectionChange": { selectedFeature: __esri.Graphic[], selectedFeatureIndex: number }; } interface HTMLFeatureDetailsElement extends Components.FeatureDetails, HTMLStencilElement { @@ -3188,6 +3189,10 @@ declare namespace LocalJSX { * esri/views/MapView: https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html */ "mapView"?: __esri.MapView; + /** + * Emitted on demand when comment icon is clicked + */ + "onAddComment"?: (event: FeatureDetailsCustomEvent) => void; /** * Emitted on demand when comment is selected using the feature-list */ diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index 4ae57f7ea..a5a43bd57 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -1288,6 +1288,13 @@ export class CrowdsourceReporter { await this._featureDetails.refresh(evt.detail.selectedFeature[0]); } + /** + * Shows the add comments panel + */ + protected showAddCommentsPanel(): void { + this._flowItems = [...this._flowItems, "add-comment"] + } + /** * When comment is selected from list store that and show comment details * @param evt Event which has details of selected feature @@ -1447,6 +1454,7 @@ export class CrowdsourceReporter { graphics={this._selectedFeature} layerItemsHash={this._layerItemsHash} mapView={this.mapView} + onAddComment={this.showAddCommentsPanel.bind(this)} onCommentSelect={this.onCommentSelectFromList.bind(this)} onFeatureSelectionChange={this.selectionChanged.bind(this)} onLoadingStatus={(evt) => void this.updatingFeatureDetails(evt.detail)} @@ -1457,7 +1465,7 @@ export class CrowdsourceReporter { {showCommentBtn && this._flowItems = [...this._flowItems, "add-comment"]} + onClick={this.showAddCommentsPanel.bind(this)} slot="footer" width="full" > From 2f05c4a94f91e48d11a0c1b39a95319a429c2e9a Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 20:09:41 +0530 Subject: [PATCH 08/10] Implemented #782 - #782 --- .../crowdsource-reporter.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index a5a43bd57..6f3c67b96 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -1833,17 +1833,19 @@ export class CrowdsourceReporter { /** * Returns the ids of all OR configured layers that support edits with the update capability * @param hash each layer item details - * @param layers list of layers id + * @param layersEditingDisabled list layer ids for which editing is disabled * @returns array of editable layer ids */ protected reduceToConfiguredLayers( - hash: ILayerItemsHash + hash: ILayerItemsHash, + layersEditingDisabled: string[] ): string[] { return Object.keys(hash).reduce((prev, cur) => { // check if reporting options exists consider the visible prop if else just check the supports Add const showLayer = this.reportingOptions ? this._getLayersConfig(cur)?.visible : hash[cur].supportsAdd; - if (showLayer) { + //show layer only when editing is enabled + if (!layersEditingDisabled.includes(cur) && showLayer) { prev.push(cur); } return prev; @@ -1889,12 +1891,16 @@ export class CrowdsourceReporter { protected async getLayersToShowInList(): Promise { const layerItemsHash = await getMapLayerHash(this.mapView, true) as ILayerItemsHash; const allMapLayers = await getAllLayers(this.mapView); + const layersEditingDisabled: string[] = []; allMapLayers.forEach((eachLayer: __esri.FeatureLayer) => { if (eachLayer?.type === "feature" && eachLayer?.editingEnabled && eachLayer?.capabilities?.operations?.supportsAdd) { layerItemsHash[eachLayer.id].supportsAdd = true; } - }) - this._editableLayerIds = this.reduceToConfiguredLayers(layerItemsHash); + if (!eachLayer?.editingEnabled) { + layersEditingDisabled.push(eachLayer.id) + } + }); + this._editableLayerIds = this.reduceToConfiguredLayers(layerItemsHash, layersEditingDisabled); this._layerItemsHash = layerItemsHash; } From 557b5aebcc233f1b343d2108c0f5b0805e97f692 Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 20:11:45 +0530 Subject: [PATCH 09/10] Implemented #751 - #751 --- .../crowdsource-reporter.tsx | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index 6f3c67b96..5ffc2e4d1 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -433,6 +433,11 @@ export class CrowdsourceReporter { */ protected _validLayers: __esri.FeatureLayer[]; + /** + * __esri.FeatureLayer[]: layer from map whom visibility is disabled + */ + protected _nonVisibleValidLayers: __esri.FeatureLayer[]; + /** * __esri.FeatureLayer: Selected feature layer from the layer list */ @@ -676,7 +681,10 @@ export class CrowdsourceReporter { //show only current layer on map and hide other valid editable layers //if layerId is empty then show all the layers on map this._validLayers.forEach(layer => { - layer.set('visible', !layerId || (layer.id === layerId)); + const nonVisibileValidLayer = this._nonVisibleValidLayers.find((l) => l.id === layer.id); + if(!nonVisibileValidLayer) { + layer.set('visible', !layerId || (layer.id === layerId)); + } }) } @@ -1013,6 +1021,7 @@ export class CrowdsourceReporter { protected backFromCreateFeaturePanel(): void { if (this._createFeature) { void this._createFeature.close(); + void this.updateNonVisibleLayersOnMap(false); } //on back form will be closed, so update the form state this.backFromSelectedPanel(); @@ -1060,6 +1069,7 @@ export class CrowdsourceReporter { if (this._showFullPanel) { this.updatePanelState(this._sidePanelCollapsed, false); } + void this.updateNonVisibleLayersOnMap(false); this._reportSubmitted = true; this._updatedProgressBarStatus = 0.25; void this.navigateToHomePage(); @@ -1120,6 +1130,7 @@ export class CrowdsourceReporter { if (evt.detail.layerId && evt.detail.layerName) { await this.setSelectedLayer(evt.detail.layerId, evt.detail.layerName); } + void this.updateNonVisibleLayersOnMap(true); // get the form template elements to pass in create-feature to create a LEVELID field in feature-form this._getFormElements(); this._showSubmitCancelButton = false; @@ -1136,6 +1147,17 @@ export class CrowdsourceReporter { this._flowItems = [...this._flowItems, "reporting-layer-list"]; } + /** + * updates the non visible layer visibility + * @param visible boolean value to set the layers visibility + */ + protected updateNonVisibleLayersOnMap(visible: boolean): void { + const isNonVisibleValidLayerSelected = this._nonVisibleValidLayers.find((layer) => layer.id === this._selectedLayerId); + if (isNonVisibleValidLayerSelected) { + this._selectedLayer.set('visible', visible); + } + } + /** * 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 * @param evt Event which has list of layers @@ -1147,9 +1169,13 @@ export class CrowdsourceReporter { const allMapLayers = await getAllLayers(this.mapView); const reportingEnabledLayerIds = []; this._validLayers = []; + this._nonVisibleValidLayers = []; allMapLayers.forEach((eachLayer: __esri.FeatureLayer) => { if (layersListed.includes(eachLayer.id)) { this._validLayers.push(eachLayer); + if (!eachLayer.visible) { + this._nonVisibleValidLayers.push(eachLayer); + } //create list of reporting enabled layers if (this._getLayersConfig(eachLayer.id)?.reporting && this._layerItemsHash[eachLayer.id] && this._layerItemsHash[eachLayer.id].supportsAdd) { reportingEnabledLayerIds.push(eachLayer.id); From a93cc9e3c26a6a7fdf61e2a78bc5f094f783ecea Mon Sep 17 00:00:00 2001 From: Sumit Zarkar Date: Mon, 23 Sep 2024 20:17:43 +0530 Subject: [PATCH 10/10] Implemented #659, #854, #802 Implemented - #659 - #854 - #802 - Code review comments from previous pull requests --- src/assets/t9n/create-feature/resources.json | 5 ++ .../t9n/create-feature/resources_en.json | 5 ++ .../t9n/create-related-feature/resources.json | 3 ++ .../create-related-feature/resources_en.json | 3 ++ .../t9n/crowdsource-reporter/resources.json | 1 - .../crowdsource-reporter/resources_en.json | 1 - src/components.d.ts | 24 +++++++++- .../create-feature/create-feature.css | 7 ++- .../create-feature/create-feature.tsx | 48 ++++++++++++++++++- .../create-related-feature.css | 10 ++++ .../create-related-feature.tsx | 45 ++++++++++++++--- .../crowdsource-reporter.tsx | 15 ++---- .../feature-details/feature-details.css | 8 ---- .../feature-details/feature-details.tsx | 25 +++++++--- src/components/feature-list/feature-list.tsx | 21 ++++++-- src/components/layer-table/layer-table.tsx | 2 +- 16 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 src/assets/t9n/create-feature/resources.json create mode 100644 src/assets/t9n/create-feature/resources_en.json create mode 100644 src/assets/t9n/create-related-feature/resources.json create mode 100644 src/assets/t9n/create-related-feature/resources_en.json diff --git a/src/assets/t9n/create-feature/resources.json b/src/assets/t9n/create-feature/resources.json new file mode 100644 index 000000000..249869571 --- /dev/null +++ b/src/assets/t9n/create-feature/resources.json @@ -0,0 +1,5 @@ +{ + "chooseCategoryMsg": "Make a selection from the list below.", + "provideDetailsMsg": "Please provide the details.", + "provideLocationMsg": "Enter an address or click on the map to create a feature." +} \ No newline at end of file diff --git a/src/assets/t9n/create-feature/resources_en.json b/src/assets/t9n/create-feature/resources_en.json new file mode 100644 index 000000000..249869571 --- /dev/null +++ b/src/assets/t9n/create-feature/resources_en.json @@ -0,0 +1,5 @@ +{ + "chooseCategoryMsg": "Make a selection from the list below.", + "provideDetailsMsg": "Please provide the details.", + "provideLocationMsg": "Enter an address or click on the map to create a feature." +} \ No newline at end of file diff --git a/src/assets/t9n/create-related-feature/resources.json b/src/assets/t9n/create-related-feature/resources.json new file mode 100644 index 000000000..be2dc8f64 --- /dev/null +++ b/src/assets/t9n/create-related-feature/resources.json @@ -0,0 +1,3 @@ +{ + "provideDetailsMsg": "Please provide the details." +} \ No newline at end of file diff --git a/src/assets/t9n/create-related-feature/resources_en.json b/src/assets/t9n/create-related-feature/resources_en.json new file mode 100644 index 000000000..be2dc8f64 --- /dev/null +++ b/src/assets/t9n/create-related-feature/resources_en.json @@ -0,0 +1,3 @@ +{ + "provideDetailsMsg": "Please provide the details." +} \ No newline at end of file diff --git a/src/assets/t9n/crowdsource-reporter/resources.json b/src/assets/t9n/crowdsource-reporter/resources.json index 6040a9ef2..cf8d42839 100644 --- a/src/assets/t9n/crowdsource-reporter/resources.json +++ b/src/assets/t9n/crowdsource-reporter/resources.json @@ -13,7 +13,6 @@ "invalidConfigurationErrorMsg": "Invalid configuration", "chooseCategoryMsg": "Make a selection from the list below.", "featureErrorMsg": "No records found.", - "featureEditFormInfoMsg": "Please provide the details.", "currentLocationMsg": "Use my current location", "addLocationMsg": "Please add a location.", "submitMsg": "Thank you! Your report was successfully submitted.", diff --git a/src/assets/t9n/crowdsource-reporter/resources_en.json b/src/assets/t9n/crowdsource-reporter/resources_en.json index 6040a9ef2..cf8d42839 100644 --- a/src/assets/t9n/crowdsource-reporter/resources_en.json +++ b/src/assets/t9n/crowdsource-reporter/resources_en.json @@ -13,7 +13,6 @@ "invalidConfigurationErrorMsg": "Invalid configuration", "chooseCategoryMsg": "Make a selection from the list below.", "featureErrorMsg": "No records found.", - "featureEditFormInfoMsg": "Please provide the details.", "currentLocationMsg": "Use my current location", "addLocationMsg": "Please add a location.", "submitMsg": "Thank you! Your report was successfully submitted.", diff --git a/src/components.d.ts b/src/components.d.ts index 9a18fd8f4..3b3e97762 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -165,6 +165,10 @@ export namespace Components { * string: Layer id of the feature layer in which the new feature is to be created */ "selectedLayerId": string; + /** + * boolean: When true the notice message with the current state should be shown + */ + "showGuidingMsg"?: boolean; /** * Submit the created feature * @returns Promise that resolves when the operation is complete @@ -188,6 +192,10 @@ export namespace Components { * __esri.Graphic: https://developers.arcgis.com/javascript/latest/api-reference/esri-Graphic.html */ "selectedFeature": __esri.Graphic; + /** + * boolean: When true the notice message should be shown + */ + "showGuidingMsg"?: boolean; /** * Submit the comment */ @@ -593,9 +601,10 @@ export namespace Components { "pageSize"?: number; /** * Refresh the feature list which will fetch the latest features and update the features list + * @param maintainPageState If true feature list page state will be maintained * @returns Promise that resolves when the operation is complete */ - "refresh": () => Promise; + "refresh": (maintainPageState?: boolean) => Promise; /** * IReportingOptions: Key options for reporting */ @@ -2055,6 +2064,7 @@ declare global { "loadingStatus": boolean; "commentSelect": __esri.Graphic; "addComment": void; + "likeOrDislikeClicked": void; "featureSelectionChange": { selectedFeature: __esri.Graphic[], selectedFeatureIndex: number }; } interface HTMLFeatureDetailsElement extends Components.FeatureDetails, HTMLStencilElement { @@ -2781,6 +2791,10 @@ declare namespace LocalJSX { * string: Layer id of the feature layer in which the new feature is to be created */ "selectedLayerId"?: string; + /** + * boolean: When true the notice message with the current state should be shown + */ + "showGuidingMsg"?: boolean; } interface CreateRelatedFeature { /** @@ -2811,6 +2825,10 @@ declare namespace LocalJSX { * __esri.Graphic: https://developers.arcgis.com/javascript/latest/api-reference/esri-Graphic.html */ "selectedFeature"?: __esri.Graphic; + /** + * boolean: When true the notice message should be shown + */ + "showGuidingMsg"?: boolean; /** * __esri.FeatureLayer: https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html */ @@ -3201,6 +3219,10 @@ declare namespace LocalJSX { * Emitted on demand when the selected index changes */ "onFeatureSelectionChange"?: (event: FeatureDetailsCustomEvent<{ selectedFeature: __esri.Graphic[], selectedFeatureIndex: number }>) => void; + /** + * Emitted on demand when like or dislike button is clicked + */ + "onLikeOrDislikeClicked"?: (event: FeatureDetailsCustomEvent) => void; /** * Emitted on demand when like or dislike button is clicked */ diff --git a/src/components/create-feature/create-feature.css b/src/components/create-feature/create-feature.css index 29ffdb85e..3854e85be 100644 --- a/src/components/create-feature/create-feature.css +++ b/src/components/create-feature/create-feature.css @@ -46,7 +46,7 @@ .search-widget { width: 92% !important; - margin: 5px 0 20px 14px; + margin: 5px 14px 20px 14px; } .display-none { @@ -66,6 +66,11 @@ height: 50%; } +.notice-msg { + padding: 10px; + width: calc(100% - 20px); +} + /* override the padding of the feature form */ .esri-editor__panel-content { padding-block: 10px !important; diff --git a/src/components/create-feature/create-feature.tsx b/src/components/create-feature/create-feature.tsx index 68ee468a6..5156ae254 100644 --- a/src/components/create-feature/create-feature.tsx +++ b/src/components/create-feature/create-feature.tsx @@ -17,7 +17,9 @@ import { Component, Element, EventEmitter, Prop, Fragment, h, Event, Watch, Method, State } from "@stencil/core"; import { loadModules } from "../../utils/loadModules"; import { getAllLayers, getLayerOrTable } from "../../utils/mapViewUtils"; +import CreateFeature_T9n from "../../assets/t9n/create-feature/resources.json"; import { ILayerSourceConfigItem, ILocatorSourceConfigItem, ISearchConfiguration } from "../../utils/interfaces"; +import { getLocaleComponentStrings } from "../../utils/locale"; @Component({ tag: "create-feature", @@ -80,6 +82,11 @@ export class CreateFeature { */ @Prop() enableSearch?: boolean = false; + /** + * boolean: When true the notice message with the current state should be shown + */ + @Prop() showGuidingMsg?: boolean = true; + //-------------------------------------------------------------------------- // // State (internal) @@ -96,6 +103,12 @@ export class CreateFeature { */ @State() _showSearchWidget: boolean; + /** + * Contains the translations for this component. + * All UI strings should be defined here. + */ + @State() _translations: typeof CreateFeature_T9n; + //-------------------------------------------------------------------------- // // Properties (protected) @@ -191,6 +204,11 @@ export class CreateFeature { */ protected _selectedLayer: __esri.FeatureLayer; + /** + * boolean: flag to maintain if user is on template picker page + */ + protected _isTemplatePickerPage = true; + //-------------------------------------------------------------------------- // // Watch handlers @@ -325,6 +343,7 @@ export class CreateFeature { * @returns Promise when complete */ async componentWillLoad(): Promise { + await this._getTranslations(); await this.initModules(); } @@ -343,8 +362,21 @@ export class CreateFeature { const loaderClass = this._editorLoading ? "" : "display-none"; const featureFormClass = this._editorLoading ? "display-none" : ""; const mobileMapClass = this.isMobile ? "show-map" : "display-none"; + let guidingMsg = this._translations.provideDetailsMsg; + if (this._isTemplatePickerPage) { + guidingMsg = this._translations.chooseCategoryMsg; + } else if (this._showSearchWidget) { + guidingMsg = this._translations.provideLocationMsg; + } return ( + {this.showGuidingMsg && +
{guidingMsg}
+
} { if (state === 'creating-features') { this._mapViewContainer?.classList?.replace("hide-map", "show-map"); - this._showSearchWidget = true; + this._isTemplatePickerPage = false; + if (this._selectedLayer && !this._selectedLayer.isTable) { + this._showSearchWidget = true; + } } }); this._editor.viewModel.addHandles(createFeatureHandle); @@ -773,4 +809,14 @@ export class CreateFeature { protected timeout(delay: number): Promise { return new Promise(resolve => setTimeout(resolve, delay)); } + + /** + * Fetches the component's translations + * @returns Promise when complete + * @protected + */ + protected async _getTranslations(): Promise { + const messages = await getLocaleComponentStrings(this.el); + this._translations = messages[0] as typeof CreateFeature_T9n; + } } diff --git a/src/components/create-related-feature/create-related-feature.css b/src/components/create-related-feature/create-related-feature.css index 6847d5e5d..10124846d 100644 --- a/src/components/create-related-feature/create-related-feature.css +++ b/src/components/create-related-feature/create-related-feature.css @@ -9,4 +9,14 @@ .display-none { display: none !important; +} + +/* override the padding of the feature form */ +.esri-editor__panel-content { + padding-block: 10px !important; +} + +.notice-msg { + padding: 10px; + width: calc(100% - 20px); } \ No newline at end of file diff --git a/src/components/create-related-feature/create-related-feature.tsx b/src/components/create-related-feature/create-related-feature.tsx index 057a96cf8..81a5f79d3 100644 --- a/src/components/create-related-feature/create-related-feature.tsx +++ b/src/components/create-related-feature/create-related-feature.tsx @@ -14,8 +14,10 @@ * limitations under the License. */ -import { Component, h, Prop, Element, Event, EventEmitter, Method, Watch, State } from '@stencil/core'; +import { Component, h, Prop, Element, Event, EventEmitter, Method, Watch, State, Fragment} from '@stencil/core'; +import CreateRelatedFeature_T9n from "../../assets/t9n/create-related-feature/resources.json"; import { loadModules } from "../../utils/loadModules"; +import { getLocaleComponentStrings } from '../../utils/locale'; @Component({ tag: 'create-related-feature', @@ -59,6 +61,11 @@ export class CreateRelatedFeature { */ @Prop() customizeSubmit?: boolean = false; + /** + * boolean: When true the notice message should be shown + */ + @Prop() showGuidingMsg?: boolean = true; + //-------------------------------------------------------------------------- // // State (internal) @@ -70,6 +77,12 @@ export class CreateRelatedFeature { */ @State() _editorLoading = false; + /** + * Contains the translations for this component. + * All UI strings should be defined here. + */ + @State() _translations: typeof CreateRelatedFeature_T9n; + //-------------------------------------------------------------------------- // // Properties (protected) @@ -199,6 +212,7 @@ export class CreateRelatedFeature { * @returns Promise when complete */ async componentWillLoad(): Promise { + await this._getTranslations(); await this.initModules(); } @@ -228,11 +242,20 @@ export class CreateRelatedFeature { render() { const loaderClass = this._editorLoading ? "" : "display-none"; return ( - + + {this.showGuidingMsg && +
{this._translations.provideDetailsMsg}
+
} + +
); } @@ -419,4 +442,14 @@ export class CreateRelatedFeature { protected timeout(delay: number): Promise { return new Promise(resolve => setTimeout(resolve, delay)); } + + /** + * Fetches the component's translations + * @returns Promise when complete + * @protected + */ + protected async _getTranslations(): Promise { + const messages = await getLocaleComponentStrings(this.el); + this._translations = messages[0] as typeof CreateRelatedFeature_T9n; + } } diff --git a/src/components/crowdsource-reporter/crowdsource-reporter.tsx b/src/components/crowdsource-reporter/crowdsource-reporter.tsx index 5ffc2e4d1..d5a1780df 100644 --- a/src/components/crowdsource-reporter/crowdsource-reporter.tsx +++ b/src/components/crowdsource-reporter/crowdsource-reporter.tsx @@ -830,6 +830,7 @@ export class CrowdsourceReporter { this._filterActive = false; this._filterUrlParams = null; this._filterInitState = null; + void this._featureList.refresh(); } /** @@ -841,6 +842,7 @@ export class CrowdsourceReporter { //set the filter active state based on the length of applied filters this._filterActive = this._filterList.urlParams.getAll('filter').length > 0; this._filterUrlParams = this._filterList.urlParams.getAll('filter'); + void this._featureList.refresh(); } /** @@ -951,13 +953,6 @@ export class CrowdsourceReporter {
- -
{this._translations.featureEditFormInfoMsg}
-
{ this._filterInitState = await this._filterList.getFilterInitState(); - void this._featureList.refresh(); this.backFromSelectedPanel(); } @@ -1236,10 +1230,6 @@ export class CrowdsourceReporter { (updatedFlowItems[0] === 'feature-list' || updatedFlowItems[updatedFlowItems.length - 2] === 'feature-list'))) { this.updatePanelState(this._sidePanelCollapsed, false); } - // Coming back from feature details refresh the feature list to update the like count - if (this.reportingOptions && this.reportingOptions[this._selectedLayerId]?.like && updatedFlowItems[updatedFlowItems.length - 1] === 'feature-details') { - void this._featureList.refresh(); - } updatedFlowItems.pop(); //Back to layer list, and return as the flowItems will be reset in navigateToHomePage if (updatedFlowItems.length === 1 && updatedFlowItems[0] === 'layer-list') { @@ -1483,6 +1473,7 @@ export class CrowdsourceReporter { onAddComment={this.showAddCommentsPanel.bind(this)} onCommentSelect={this.onCommentSelectFromList.bind(this)} onFeatureSelectionChange={this.selectionChanged.bind(this)} + onLikeOrDislikeClicked={() => { void this._featureList.refresh(true) }} onLoadingStatus={(evt) => void this.updatingFeatureDetails(evt.detail)} ref={el => this._featureDetails = el} reportingOptions={this.reportingOptions} diff --git a/src/components/feature-details/feature-details.css b/src/components/feature-details/feature-details.css index 89c803b0b..f368727c6 100644 --- a/src/components/feature-details/feature-details.css +++ b/src/components/feature-details/feature-details.css @@ -11,11 +11,3 @@ border-block-start: 1px solid var(--calcite-color-border-3); border-block-end: 1px solid var(--calcite-color-border-3); } - -.comment-btn { - display: flex; - gap: 10px; - font-size: var(--calcite-font-size--1); - align-items: center; - padding: 7px 0.75rem; -} \ No newline at end of file diff --git a/src/components/feature-details/feature-details.tsx b/src/components/feature-details/feature-details.tsx index 4767474a0..ad2e7fe49 100644 --- a/src/components/feature-details/feature-details.tsx +++ b/src/components/feature-details/feature-details.tsx @@ -249,6 +249,16 @@ export class FeatureDetails { */ @Event() commentSelect: EventEmitter<__esri.Graphic>; + /** + * Emitted on demand when comment icon is clicked + */ + @Event() addComment: EventEmitter; + + /** + * Emitted on demand when like or dislike button is clicked + */ + @Event() likeOrDislikeClicked: EventEmitter; + /** * Emitted on demand when the selected index changes */ @@ -287,13 +297,13 @@ export class FeatureDetails { {(this._likeFieldAvailable || this._dislikeFieldAvailable || this._commentsAvailable) &&
{this._commentsAvailable && -
- {this._relatedFeaturesOIDs.length} - -
+ { this.addComment.emit() }} + scale='m' + >{this._relatedFeaturesOIDs.length} } {this._likeFieldAvailable && { this._updating = false; console.log(err); diff --git a/src/components/feature-list/feature-list.tsx b/src/components/feature-list/feature-list.tsx index f32737d4b..353b1f798 100644 --- a/src/components/feature-list/feature-list.tsx +++ b/src/components/feature-list/feature-list.tsx @@ -240,11 +240,21 @@ export class FeatureList { /** * Refresh the feature list which will fetch the latest features and update the features list + * @param maintainPageState If true feature list page state will be maintained * @returns Promise that resolves when the operation is complete */ @Method() - async refresh(): Promise { - await this.initializeFeatureItems(); + async refresh(maintainPageState?: boolean): Promise { + if (maintainPageState) { + const event = { + target: { + startItem: this._pagination.startItem + } + } + await this.pageChanged(event) + } else { + await this.initializeFeatureItems(); + } } // @@ -366,11 +376,11 @@ export class FeatureList { if (this._selectedLayer?.definitionExpression) { whereClause = whereClause + ' AND ' + this._selectedLayer.definitionExpression; } - // if layerview has any applied filter, use it + // if layerView has any applied filter, use it if (this.applyLayerViewFilter) { const selectedLayerView = await getFeatureLayerView(this.mapView, this.selectedLayerId); if (selectedLayerView?.filter?.where) { - whereClause = whereClause + ' AND ' + selectedLayerView.filter.where + whereClause = whereClause + ' AND ' + selectedLayerView.filter.where; } } return whereClause; @@ -554,6 +564,7 @@ export class FeatureList { * Get each feature item * @param selectedFeature Each individual feature instance to be listed * @param popupTitle feature popup title + * @param featureSymbol feature symbol preview html * @returns individual feature item to be rendered * @protected */ @@ -599,6 +610,8 @@ export class FeatureList { slot="content-end"> {this._abbreviatedLikeCount} {formattedLikeCount} diff --git a/src/components/layer-table/layer-table.tsx b/src/components/layer-table/layer-table.tsx index 8ba2b8d3c..54cb00ae7 100644 --- a/src/components/layer-table/layer-table.tsx +++ b/src/components/layer-table/layer-table.tsx @@ -918,7 +918,7 @@ export class LayerTable { /** * Update the search expression in layer - * @param searchedIds + * @param searchedIds Array of objectIds satisfying the full search text */ protected _updateSearchDefinitionExpression(searchedIds: number[]): void { const defExp = this._layer.definitionExpression;