From 28a9625fb0ac37b87a0fdeaf06cf6512ca049b61 Mon Sep 17 00:00:00 2001 From: hamou Date: Tue, 29 Oct 2024 17:07:45 +0100 Subject: [PATCH] Remove an action from the map and the list --- .../arlas-wui-root.component.html | 2 + .../arlas-wui-root.component.ts | 33 +++++++--- .../rasters-manager.component.ts | 38 +++++++++-- src/app/services/resultlist.service.ts | 66 +++++++++++++++++-- src/app/services/visualize.service.ts | 45 +++++++++---- 5 files changed, 153 insertions(+), 31 deletions(-) diff --git a/src/app/components/arlas-wui-root/arlas-wui-root.component.html b/src/app/components/arlas-wui-root/arlas-wui-root.component.html index 9b678808..00978243 100644 --- a/src/app/components/arlas-wui-root/arlas-wui-root.component.html +++ b/src/app/components/arlas-wui-root/arlas-wui-root.component.html @@ -166,6 +166,7 @@ [fetchState]="previewListContrib.fetchState" [globalActionsList]="[]" [isGeoSortEnabled]="resultListConfigPerContId.get(previewListContrib.identifier)?.isGeoSortActived" [options]="resultListConfigPerContId.get(previewListContrib.identifier)?.options" + [activatedActionsPerItem]="resultlistService.activeActionsPerContId?.get(previewListContrib.identifier)" [displayFilters]="false" (thumbnailFitEvent)="resultListConfigPerContId.get(previewListContrib.identifier).fitThumbnail = $event" (visibleItems)="updateMapStyleFromScroll($event, previewListContrib.collection)" @@ -208,6 +209,7 @@ [defautMode]="resultListConfigPerContId.get(list.identifier)?.defautMode" [selectedGridItem]="resultListConfigPerContId.get(list.identifier)?.selectedGridItem" [fetchState]="list.fetchState" + [activatedActionsPerItem]="resultlistService.activeActionsPerContId?.get(list.identifier)" (visibleItems)="updateMapStyleFromScroll($event, list.collection)" (onChangeItems)="updateMapStyleFromChange($event, list.collection)" [globalActionsList]="resultListConfigPerContId.get(list.identifier)?.globalActionsList" diff --git a/src/app/components/arlas-wui-root/arlas-wui-root.component.ts b/src/app/components/arlas-wui-root/arlas-wui-root.component.ts index 0cdb809d..a93ffa4d 100644 --- a/src/app/components/arlas-wui-root/arlas-wui-root.component.ts +++ b/src/app/components/arlas-wui-root/arlas-wui-root.component.ts @@ -277,7 +277,7 @@ export class ArlasWuiRootComponent implements OnInit, AfterViewInit, OnDestroy { private dialog: MatDialog, private generateAoiDialog: MatDialog, private processService: ProcessService, - private resultlistService: ResultlistService, + public resultlistService: ResultlistService, private exportService: ArlasExportCsvService, private collectionService: ArlasCollectionService ) { @@ -460,17 +460,24 @@ export class ArlasWuiRootComponent implements OnInit, AfterViewInit, OnDestroy { this.resultlistContributors.forEach(c => { const listActionsId = c.actionToTriggerOnClick.map(a => a.id); const mapcontributor = this.mapglContributors.find(mc => mc.collection === c.collection); - if (!!mapcontributor && !listActionsId.includes('zoomToFeature')) { - c.addAction({ id: 'zoomToFeature', label: 'Zoom to', cssClass: '', tooltip: 'Zoom to product' }); - } if (!!this.resultListConfigPerContId.get(c.identifier)) { if (!!this.resultListConfigPerContId.get(c.identifier).visualisationLink && !listActionsId.includes('visualize')) { - c.addAction({ id: 'visualize', label: 'Visualize', cssClass: '', tooltip: 'Visualize on the map' }); + c.addAction({ + id: 'visualize', label: 'Visualize', icon: 'visibility', cssClass: '', tooltip: 'Visualize on the map', + reverseAction: { + id: 'dev', label: 'Remove from map', cssClass: '', tooltip: 'Remove from map', icon: 'visibility_off' + }, + fields: this.visualizeService.getVisuFields(this.resultListConfigPerContId.get(c.identifier).visualisationLink), + hide: true + } as any); } if (!!this.resultListConfigPerContId.get(c.identifier).downloadLink && !listActionsId.includes('download')) { c.addAction({ id: 'download', label: 'Download', cssClass: '', tooltip: 'Download' }); } } + if (!!mapcontributor && !listActionsId.includes('zoomToFeature')) { + c.addAction({ id: 'zoomToFeature', label: 'Zoom to', cssClass: '', tooltip: 'Zoom to product' }); + } }); this.declareResultlistExportCsv(); @@ -1441,11 +1448,17 @@ export class ArlasWuiRootComponent implements OnInit, AfterViewInit, OnDestroy { case 'visualize': if (!!this.resultListConfigPerContId.get(listContributor.identifier)) { const urlVisualisationTemplate = this.resultListConfigPerContId.get(listContributor.identifier).visualisationLink; - this.visualizeService.getVisuInfo(data.elementidentifier, collection, urlVisualisationTemplate).subscribe(url => { - this.visualizeService.displayDataOnMap(url, - data.elementidentifier, this.collectionToDescription.get(collection).geometry_path, - this.collectionToDescription.get(collection).centroid_path, collection); - }); + if (!data.action.activated) { + this.visualizeService.getVisuInfo(data.elementidentifier, collection, urlVisualisationTemplate).subscribe(url => { + this.visualizeService.displayDataOnMap(url, + data.elementidentifier, this.collectionToDescription.get(collection).geometry_path, + this.collectionToDescription.get(collection).centroid_path, collection); + }); + this.resultlistService.addAction(listContributor.identifier, data.elementidentifier.idValue, data.action); + } else { + this.visualizeService.removeRasters(data.elementidentifier.idValue); + this.resultlistService.removeAction(listContributor.identifier, data.elementidentifier.idValue, data.action.id); + } } break; case 'download': diff --git a/src/app/components/map/raster-layers-manager/rasters-manager.component.ts b/src/app/components/map/raster-layers-manager/rasters-manager.component.ts index 29597f9e..7058a843 100644 --- a/src/app/components/map/raster-layers-manager/rasters-manager.component.ts +++ b/src/app/components/map/raster-layers-manager/rasters-manager.component.ts @@ -17,24 +17,54 @@ * under the License. */ -import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { VisualizeService } from '../../../services/visualize.service'; -import { AoiEdition } from 'arlas-web-components'; +import { ResultlistService } from '../../../services/resultlist.service'; +import { Subject, takeUntil } from 'rxjs'; +import { ArlasCollaborativesearchService } from 'arlas-wui-toolkit'; +import { CollaborationEvent, OperationEnum } from 'arlas-web-core'; @Component({ selector: 'arlas-rasters-manager', templateUrl: './rasters-manager.component.html', styleUrls: ['./rasters-manager.component.scss'] }) -export class RastersManagerComponent { +export class RastersManagerComponent implements OnInit, OnDestroy { - public constructor(private visualisationService: VisualizeService) { + /** Destroy subscriptions */ + private _onDestroy$ = new Subject(); + public constructor( + private visualisationService: VisualizeService, + private resultlistService: ResultlistService, + private collaborativeSearchService: ArlasCollaborativesearchService + ) { } + + public ngOnInit(): void { + this.visualisationService.rasterRemoved$.pipe(takeUntil(this._onDestroy$)).subscribe({ + next: (id) => { + this.resultlistService.removeItemActions(id, 'visualize'); + } + }); + /** Remove the raster once an arlas filter is applied */ + this.collaborativeSearchService.collaborationBus.pipe(takeUntil(this._onDestroy$)).subscribe({ + next: (ce: CollaborationEvent) => { + if (ce.operation === OperationEnum.add) { + this.removeLayers(); + } + } + }); } /** Removes all raster layers from the map. */ public removeLayers() { this.visualisationService.removeRasters(); + this.resultlistService.removeActions('visualize'); + } + + public ngOnDestroy(): void { + this._onDestroy$.next(true); + this._onDestroy$.complete(); } } diff --git a/src/app/services/resultlist.service.ts b/src/app/services/resultlist.service.ts index 433e2fa7..c30aeddd 100644 --- a/src/app/services/resultlist.service.ts +++ b/src/app/services/resultlist.service.ts @@ -19,8 +19,8 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { CellBackgroundStyleEnum } from 'arlas-web-components'; -import { ResultListContributor } from 'arlas-web-contributors'; +import { CellBackgroundStyleEnum, ActionHandler } from 'arlas-web-components'; +import { Action, ResultListContributor } from 'arlas-web-contributors'; import { getParamValue } from 'arlas-wui-toolkit'; @@ -33,7 +33,7 @@ export class ResultlistService { public resultlistConfigs = []; public resultlistConfigPerContId = new Map(); public previewlistContrib: ResultListContributor = null; - + public activeActionsPerContId = new Map>>(); public selectedListTabIndex = 0; public listOpen = false; @@ -64,10 +64,68 @@ export class ResultlistService { this.listOpen = !this.listOpen; const queryParams = Object.assign({}, this.activatedRoute.snapshot.queryParams); queryParams['ro'] = this.listOpen + ''; - this.router.navigate([], {replaceUrl: true, queryParams: queryParams}); + this.router.navigate([], { replaceUrl: true, queryParams: queryParams }); } public isThumbnailProtected(): boolean { return this.resultlistContributors[this.selectedListTabIndex].fieldsConfiguration?.useHttpThumbnails ?? false; } + + public addAction(contId: string, itemId: string, action: Action) { + if (ActionHandler.isReversible(action)) { + if (!this.activeActionsPerContId.get(contId)) { + this.activeActionsPerContId.set(contId, new Map()); + } + const activeActions = this.activeActionsPerContId.get(contId); + if (!activeActions.get(itemId)) { + activeActions.set(itemId, new Set()); + } + const actions = activeActions.get(itemId); + actions.add(action.id); + this.activeActionsPerContId.set(contId, new Map(activeActions)); + + } + } + + /** Remove an activated action for a given item and given contributor */ + public removeAction(contId: string, itemId: string, actionId: string) { + if (!this.activeActionsPerContId.get(contId)) { + return; + } + const activeActions = this.activeActionsPerContId.get(contId); + if (!activeActions.get(itemId)) { + return; + } + const actions = activeActions.get(itemId); + if (!actions) { + return; + } + actions.delete(actionId); + this.activeActionsPerContId.set(contId, new Map(activeActions)); + } + + /** Removes an activated action for all items and all contributors */ + public removeActions(actionId: string) { + if (this.activeActionsPerContId) { + this.activeActionsPerContId.forEach((actionsPerItem, contId) => { + actionsPerItem.forEach((actions, itemId) => { + actions.delete(actionId); + }); + this.activeActionsPerContId.set(contId, new Map(actionsPerItem)); + }); + } + } + + /** Removes an activated action for a given item in all contributors */ + public removeItemActions(itemId: string, actionId: string) { + if (this.activeActionsPerContId) { + this.activeActionsPerContId.forEach((actionsPerItem, contId) => { + const actions = actionsPerItem.get(itemId); + if (!!actions) { + actions.delete(actionId); + } + this.activeActionsPerContId.set(contId, new Map(actionsPerItem)); + }); + } + } } diff --git a/src/app/services/visualize.service.ts b/src/app/services/visualize.service.ts index bb8a2a45..c83d3639 100644 --- a/src/app/services/visualize.service.ts +++ b/src/app/services/visualize.service.ts @@ -30,7 +30,7 @@ import { getElementFromJsonObject } from 'arlas-web-contributors/utils/utils'; import { projType } from 'arlas-web-core'; import { ArlasCollaborativesearchService } from 'arlas-wui-toolkit'; import { Popup } from 'mapbox-gl'; -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import { map } from 'rxjs/operators'; import { parse } from 'wellknown'; @@ -44,6 +44,10 @@ export class VisualizeService { public isWMTSOnMap = false; public isRasterOnMap = false; + /** emits the item's identifier of removed raster */ + private rasterRemovedSource = new Subject(); + public rasterRemoved$ = this.rasterRemovedSource.asObservable(); + public constructor(public collaborativeService: ArlasCollaborativesearchService, private translateService: TranslateService, private snackBar: MatSnackBar ) { } @@ -66,6 +70,20 @@ export class VisualizeService { }); } + + public getVisuFields(urlTemplate): string[] { + if (urlTemplate.indexOf('{') >= 0) { + const fields = urlTemplate.split(/[{}]/).filter(v => v.length > 0); + if (fields) { + return fields + .filter(f => f !== 'x') + .filter(f => f !== 'y') + .filter(f => f !== 'z'); + } + } + return []; + } + public getVisuInfo(elementidentifier: ElementIdentifier, collection: string, urlTemplate: string): Observable { @@ -92,17 +110,13 @@ export class VisualizeService { if (urlTemplate.indexOf('{') < 0) { return urlTemplate; } else { - const fields = urlTemplate.split(/[{}]/).filter(v => v.length > 0); - fields - .filter(f => f !== 'x') - .filter(f => f !== 'y') - .filter(f => f !== 'z').forEach(field => { - if (data.hits[0].data[field] === undefined) { - return undefined; - } else { - urlTemplate = urlTemplate.replace('{' + field + '}', data.hits[0].data[field]); - } - }); + this.getVisuFields(urlTemplate).forEach(field => { + if (data.hits[0].data[field] === undefined) { + return undefined; + } else { + urlTemplate = urlTemplate.replace('{' + field + '}', data.hits[0].data[field]); + } + }); } return urlTemplate; })); @@ -200,7 +214,7 @@ export class VisualizeService { this.getBoundsAndCenter(elementidentifier.idFieldName, elementidentifier.idValue, geometryPath, centroidPath, collection) .subscribe(d => { - this.addWMTS(url, 25, d.box, elementidentifier.idValue); + this.addRaster(url, 25, d.box, elementidentifier.idValue); this.fitbounds = d.bounds; }); } else { @@ -237,6 +251,7 @@ export class VisualizeService { }); this.map.on('click', CROSS_LAYER_PREFIX + id, (e) => { this.removeRasters(id); + this.notifyRasterRemoved(id); }); this.map.on('mousemove', CROSS_LAYER_PREFIX + id, (e) => { this.map.getCanvas().style.cursor = 'pointer'; @@ -247,6 +262,10 @@ export class VisualizeService { this.handlePopup(lat, lng, id); } + public notifyRasterRemoved(id: string) { + this.rasterRemovedSource.next(id); + } + public handlePopup(lat, lng, id) { const popup = new Popup({ closeButton: false,