diff --git a/erdblick_app/app/feature.panel.component.ts b/erdblick_app/app/feature.panel.component.ts index 079da421..b1b882f2 100644 --- a/erdblick_app/app/feature.panel.component.ts +++ b/erdblick_app/app/feature.panel.component.ts @@ -184,13 +184,12 @@ export class FeaturePanelComponent implements OnInit { filterByValues = true; filterOnlyFeatureIds = false; filterGeometryEntries = false; + jsonTree = ""; @ViewChild('inspectionMenu') inspectionMenu!: Menu; inspectionMenuItems: MenuItem[] | undefined; inspectionMenuVisible: boolean = false; - @Input() jsonTree = ""; - constructor(private clipboardService: ClipboardService, public inspectionService: InspectionService, public jumpService: JumpTargetService, @@ -336,7 +335,7 @@ export class FeaturePanelComponent implements OnInit { const address = sourceDataRef.address; const mapId = this.inspectionService.selectedMapIdName; - this.inspectionService.sourceData.next({ + this.inspectionService.selectedSourceData.next({ tileId: Number(tileId), layerId: String(layerId), mapId: String(mapId), diff --git a/erdblick_app/app/inspection.panel.component.ts b/erdblick_app/app/inspection.panel.component.ts index 3d7e535d..598c0e19 100644 --- a/erdblick_app/app/inspection.panel.component.ts +++ b/erdblick_app/app/inspection.panel.component.ts @@ -9,6 +9,7 @@ interface InspectorTab { icon: string, component: any, inputs?: Record, + onClose?: any, } @Component({ @@ -64,11 +65,17 @@ export class InspectionPanelComponent implements OnInit this.inspectionService.featureTree.pipe(distinctUntilChanged()).subscribe((tree: string) => { this.reset(); + + // TODO: Create a new FeaturePanelComponent instance for each unique selected feature + // then we can get rid of all the service's View Component logic/functions. + // reset() Would then completely clear the tabs. + this.tabs[0].title = this.inspectionService.selectedFeatureIdName; }); - this.inspectionService.sourceData.pipe(distinctUntilChanged()).subscribe(data => { + this.inspectionService.selectedSourceData.pipe(distinctUntilChanged()).subscribe(selection => { this.reset(); - this.pushSourceDataInspector(data); + if (selection) + this.pushSourceDataInspector(selection); }) } @@ -82,9 +89,12 @@ export class InspectionPanelComponent implements OnInit pushFeatureInspector() { let tab = { - title: "Feature", + title: "", icon: "pi-sitemap", component: FeaturePanelComponent, + onClose: () => { + this.inspectionService.featureTree.next(""); + }, } this.tabs = [...this.tabs, tab]; @@ -99,6 +109,9 @@ export class InspectionPanelComponent implements OnInit inputs: { sourceData: data }, + onClose: () => { + this.inspectionService.selectedSourceData.next(null); + }, } this.tabs = [...this.tabs, tab]; @@ -113,6 +126,11 @@ export class InspectionPanelComponent implements OnInit onGoBack(event: any) { event.stopPropagation(); - this.activeIndex = Math.max(0, this.activeIndex - 1); + if (this.activeIndex > 0) { + const onClose = this.tabs[this.activeIndex]['onClose']; + if (onClose) + onClose(); + this.activeIndex = this.activeIndex - 1; + } } } diff --git a/erdblick_app/app/inspection.service.ts b/erdblick_app/app/inspection.service.ts index 2ae47716..6553ce09 100644 --- a/erdblick_app/app/inspection.service.ts +++ b/erdblick_app/app/inspection.service.ts @@ -1,6 +1,6 @@ import {Injectable} from "@angular/core"; import {TreeTableNode} from "primeng/api"; -import {BehaviorSubject, distinctUntilChanged, filter, ReplaySubject} from "rxjs"; +import {BehaviorSubject, distinctUntilChanged, distinctUntilKeyChanged, filter, ReplaySubject} from "rxjs"; import {MapService} from "./map.service"; import {Feature, TileSourceDataLayer} from "../../build/libs/core/erdblick-core"; import {FeatureWrapper} from "./features.model"; @@ -39,7 +39,7 @@ export class InspectionService { selectedFeatureIdName: string = ""; selectedMapIdName: string = ""; selectedFeature: FeatureWrapper | null = null; - sourceData: ReplaySubject = new ReplaySubject(); + selectedSourceData = new BehaviorSubject(null); constructor(private mapService: MapService, private jumpService: JumpTargetService, @@ -63,15 +63,40 @@ export class InspectionService { this.parametersService.setSelectedFeature(this.selectedMapIdName, this.selectedFeatureIdName); }); - this.parametersService.parameters.pipe(filter( - parameters => parameters.selected.length == 2)).subscribe(parameters => { - const [mapId, featureId] = parameters.selected; - if (mapId != this.selectedMapIdName || featureId != this.selectedFeatureIdName) { - this.jumpService.highlightFeature(mapId, featureId).then(() => { - if (this.selectedFeature) { - this.mapService.focusOnFeature(this.selectedFeature); + let isNotifyingParametersChange = false; + this.parametersService.parameters.pipe(distinctUntilChanged()).subscribe(parameters => { + try { + if (isNotifyingParametersChange) + return; + + isNotifyingParametersChange = true; + if (parameters.selected.length == 2) { + const [mapId, featureId] = parameters.selected; + if (mapId != this.selectedMapIdName || featureId != this.selectedFeatureIdName) { + this.jumpService.highlightFeature(mapId, featureId); + if (this.selectedFeature != null) { + this.mapService.focusOnFeature(this.selectedFeature); + } } - }); + + this.selectedSourceData.next(this.parametersService.getSelectedSourceData()); + } + } finally { + isNotifyingParametersChange = false; + } + }); + + this.selectedSourceData.pipe(distinctUntilChanged()).subscribe(selection => { + try { + if (isNotifyingParametersChange) + return; + isNotifyingParametersChange = true; + if (selection) + this.parametersService.setSelectedSourceData(selection); + else + this.parametersService.unsetSelectedSourceData(); + } finally { + isNotifyingParametersChange = false; } }); } diff --git a/erdblick_app/app/parameters.service.ts b/erdblick_app/app/parameters.service.ts index 90a495ab..3e18d443 100644 --- a/erdblick_app/app/parameters.service.ts +++ b/erdblick_app/app/parameters.service.ts @@ -3,7 +3,7 @@ import {BehaviorSubject, Subject} from "rxjs"; import {Cartesian3, Cartographic, CesiumMath, Camera} from "./cesium"; import {Params, Router} from "@angular/router"; import {ErdblickStyle} from "./style.service"; -import {InspectionService} from "./inspection.service"; +import {InspectionService, SelectedSourceData} from "./inspection.service"; export const MAX_NUM_TILES_TO_LOAD = 2048; export const MAX_NUM_TILES_TO_VISUALIZE = 512; @@ -31,7 +31,7 @@ interface ErdblickParameters extends Record { tilesLoadLimit: number, tilesVisualizeLimit: number, enabledCoordsTileIds: Array, - sourceDataInspector: Array, + selectedSourceData: Array, } interface ParameterDescriptor { @@ -142,7 +142,7 @@ const erdblickParameters: Record = { default: ["WGS84"], urlParam: false }, - sourceDataInspector: { + selectedSourceData: { converter: JSON.parse, validator: Array.isArray, default: [], @@ -176,19 +176,6 @@ export class ParametersService { this.saveParameters(); } }); -/* - this.inspectionService.showSourceDataEvent.subscribe(event => { - this.p().sourceDataInspector = [ - ...Object.values(event) - ]; - this.parameters.next(this.p()); - }); - - this.inspectionService.showFeatureInspectorEvent.subscribe(event => { - this.p().sourceDataInspector = []; - }); - - */ } get replaceUrl() { @@ -201,29 +188,31 @@ export class ParametersService { return this.parameters.getValue(); } - setSelectedSourceData(tileId: Number, layerId: string, mapId: string, address: Number) { - this.p().sourceDataInspector = [ - tileId, - layerId, - mapId, - address, + public setSelectedSourceData(selection: SelectedSourceData) { + this.p().selectedSourceData = [ + selection.tileId, + selection.layerId, + selection.mapId, + selection.address.toString(), ]; this.parameters.next(this.p()); } - unsetSelectedSourceData() { - this.p().sourceDataInspector = []; + public unsetSelectedSourceData() { + this.p().selectedSourceData = []; this.parameters.next(this.p()); } - getSelectedSourceData() { - const sd = this.p().sourceDataInspector; + public getSelectedSourceData(): SelectedSourceData | null { + const sd = this.p().selectedSourceData; + if (!sd || !sd.length) + return null; return { tileId: sd[0], - layerId: sd[0], - mapId: sd[0], - address: sd[0], + layerId: sd[1], + mapId: sd[2], + address: BigInt(sd[3] || '0'), }; }