From b4f130d8b956acdc8a8a7d0f0ec8393c4e1418d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Lafreni=C3=A8re?= <53181414+PhilippeLafreniere18@users.noreply.github.com> Date: Tue, 14 Mar 2023 10:27:19 -0400 Subject: [PATCH] feat(search/catalog): add visible/non-visible badge icon on layers (#1184) * feat(ilayer/catalog): add eye badge control for layer visibility * feat(catalog): add visible/non-visible badge icon * fix gh actions * remove primary eye if visible --- .../lib/badge-icon/badge-icon.directive.ts | 21 ++++++- .../catalog-browser-group.component.html | 1 + .../catalog-browser-group.component.ts | 3 + .../catalog-browser-layer.component.html | 8 ++- .../catalog-browser-layer.component.ts | 56 +++++++++++++++---- .../catalog-browser.component.html | 2 + .../search-results-add-button.component.html | 10 ++-- .../search-results-add-button.component.ts | 37 ++++++++++-- packages/geo/src/locale/en.geo.json | 1 + packages/geo/src/locale/fr.geo.json | 1 + 10 files changed, 115 insertions(+), 25 deletions(-) diff --git a/packages/common/src/lib/badge-icon/badge-icon.directive.ts b/packages/common/src/lib/badge-icon/badge-icon.directive.ts index d8090f5806..079b680fac 100644 --- a/packages/common/src/lib/badge-icon/badge-icon.directive.ts +++ b/packages/common/src/lib/badge-icon/badge-icon.directive.ts @@ -48,6 +48,20 @@ export class IgoBadgeIconDirective implements OnInit { } private inheritColor = false; + @Input() + set igoMatBadgeColor(value: string) { + this.color = value; + this.updateColor(); + } + private color; + + @Input() + set igoMatBadgeBackgroundColor(value: string) { + this.backgroundColor = value; + this.updateColor(); + } + private backgroundColor; + get badge() { return this.el.nativeElement.querySelector('.mat-badge-content'); } @@ -82,7 +96,10 @@ export class IgoBadgeIconDirective implements OnInit { return; } - if (this.inheritColor) { + if (this.color || this.backgroundColor) { + this.badge.style.color = this.color ? this.color : ''; + this.badge.style.background = this.backgroundColor ? this.backgroundColor : ''; + } else if (this.inheritColor) { if (this.inverseColor) { this.badge.style.color = 'currentColor'; this.badge.style.background = 'none'; @@ -90,7 +107,7 @@ export class IgoBadgeIconDirective implements OnInit { this.badge.style.color = ''; this.badge.style.background = 'currentColor'; } - } else { + } else if (!this.inheritColor) { if (this.inverseColor) { this.badge.style.color = window .getComputedStyle(this.badge, null) diff --git a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-group.component.html b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-group.component.html index 2fa4b97418..4bbcb92434 100644 --- a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-group.component.html +++ b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-group.component.html @@ -62,6 +62,7 @@

diff --git a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-layer.component.ts b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-layer.component.ts index cc6b5e8bb2..089f4c71c5 100644 --- a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-layer.component.ts +++ b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser-layer.component.ts @@ -16,6 +16,7 @@ import { LayerService } from '../../layer/shared/layer.service'; import { first } from 'rxjs/operators'; import { Layer, TooltipType } from '../../layer/shared/layers'; import { MetadataLayerOptions } from '../../metadata/shared/metadata.interface'; +import { IgoMap } from '../../map'; /** * Catalog browser layer item @@ -29,7 +30,10 @@ import { MetadataLayerOptions } from '../../metadata/shared/metadata.interface'; export class CatalogBrowserLayerComponent implements OnInit, OnDestroy { public inRange$: BehaviorSubject = new BehaviorSubject(true); public isPreview$: BehaviorSubject = new BehaviorSubject(false); + public isVisible$: BehaviorSubject = new BehaviorSubject(false); private isPreview$$: Subscription; + private resolution$$: Subscription; + private layers$$: Subscription; private lastTimeoutRequest; public layerLegendShown$: BehaviorSubject = new BehaviorSubject(false); @@ -46,6 +50,8 @@ export class CatalogBrowserLayerComponent implements OnInit, OnDestroy { */ @Input() layer: CatalogItemLayer; + @Input() map: IgoMap; + /** * Whether the layer is already added to the map */ @@ -78,12 +84,22 @@ export class CatalogBrowserLayerComponent implements OnInit, OnDestroy { constructor(private layerService: LayerService ) {} ngOnInit(): void { - this.isInResolutionsRange(); this.isPreview$$ = this.isPreview$.subscribe(value => this.addedLayerIsPreview.emit(value)); + + this.layers$$ = this.map.layers$.subscribe(() => { + this.isVisible(); + }); + + this.resolution$$ = this.map.viewController.resolution$.subscribe((resolution) => { + this.isInResolutionsRange(resolution); + this.isVisible(); + }); } ngOnDestroy() { this.isPreview$$.unsubscribe(); + this.resolution$$.unsubscribe(); + this.layers$$.unsubscribe(); } computeTitleTooltip(): string { @@ -194,22 +210,42 @@ export class CatalogBrowserLayerComponent implements OnInit, OnDestroy { return !(!this.layer.address || this.layer.address.split('.').length === 1); } - isInResolutionsRange(): boolean { - const minResolution = this.layer.options.minResolution || 0; - const maxResolution = this.layer.options.maxResolution || Infinity; + isInResolutionsRange(resolution: number) { + const minResolution = (!this.layer.options.minResolution || Number.isNaN(this.layer.options.minResolution)) + ? 0 : this.layer.options.minResolution; + const maxResolution = (!this.layer.options.maxResolution || Number.isNaN(this.layer.options.maxResolution)) + ? Infinity : this.layer.options.maxResolution; this.inRange$.next( - this.resolution >= minResolution && this.resolution <= maxResolution + resolution >= minResolution && resolution <= maxResolution ); - return this.inRange$.value; + } + + isVisible() { + if (this.layer?.id) { + const oLayer = this.map.getLayerById(this.layer?.id); + oLayer ? this.isVisible$.next(oLayer.visible) : this.isVisible$.next(false); + } + } + + getBadgeIcon() { + if (this.inRange$.getValue()) { + return this.isVisible$.getValue() ? '' : 'eye-off'; + } else { + return 'eye-off'; + } } computeTooltip(): string { if (this.added) { - return this.isPreview$.value - ? 'igo.geo.catalog.layer.addToMap' - : this.inRange$.value + if (this.isPreview$.value) { + return 'igo.geo.catalog.layer.addToMap'; + } else if (this.inRange$.value) { + return this.isVisible$.value ? 'igo.geo.catalog.layer.removeFromMap' - : 'igo.geo.catalog.layer.removeFromMapOutRange'; + : 'igo.geo.catalog.layer.removeFromMapNotVisible'; + } else { + return 'igo.geo.catalog.layer.removeFromMapOutRange'; + } } else { return this.inRange$.value ? 'igo.geo.catalog.layer.addToMap' diff --git a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser.component.html b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser.component.html index c1fb5118ce..9e4a7976d1 100644 --- a/packages/geo/src/lib/catalog/catalog-browser/catalog-browser.component.html +++ b/packages/geo/src/lib/catalog/catalog-browser/catalog-browser.component.html @@ -4,6 +4,7 @@ diff --git a/packages/geo/src/lib/search/search-results/search-results-add-button.component.ts b/packages/geo/src/lib/search/search-results/search-results-add-button.component.ts index 81dff4c140..975f3d065a 100644 --- a/packages/geo/src/lib/search/search-results/search-results-add-button.component.ts +++ b/packages/geo/src/lib/search/search-results/search-results-add-button.component.ts @@ -20,14 +20,14 @@ import { Subscription, BehaviorSubject } from 'rxjs'; changeDetection: ChangeDetectionStrategy.OnPush }) export class SearchResultAddButtonComponent implements OnInit, OnDestroy { - public tooltip$: BehaviorSubject = new BehaviorSubject( - 'igo.geo.catalog.layer.addToMap' - ); private resolution$$: Subscription; + private layers$$: Subscription; public inRange$: BehaviorSubject = new BehaviorSubject(true); + public isVisible$: BehaviorSubject = new BehaviorSubject(false); + public isPreview$: BehaviorSubject = new BehaviorSubject(false); private layersSubcriptions = []; @@ -69,14 +69,18 @@ export class SearchResultAddButtonComponent implements OnInit, OnDestroy { lay => lay.id === this.layer.data.sourceOptions.id ) !== -1; } + this.layers$$ = this.map.layers$.subscribe(() => { + this.isVisible(); + }); this.resolution$$ = this.map.viewController.resolution$.subscribe(value => { this.isInResolutionsRange(value); - this.tooltip$.next(this.computeTooltip()); + this.isVisible(); }); } ngOnDestroy() { this.resolution$$.unsubscribe(); + this.layers$$.unsubscribe(); } /** @@ -194,11 +198,32 @@ export class SearchResultAddButtonComponent implements OnInit, OnDestroy { ); } + isVisible() { + if (this.layer?.data?.sourceOptions?.id) { + const oLayer = this.map.getLayerById(this.layer.data.sourceOptions.id); + oLayer ? this.isVisible$.next(oLayer.visible) : this.isVisible$.next(false); + } + } + + getBadgeIcon() { + if (this.inRange$.value) { + return this.isVisible$.value ? '' : 'eye-off'; + } else { + return 'eye-off'; + } + } + computeTooltip(): string { if (this.added) { - return this.inRange$.value + if (this.isPreview$.value) { + return 'igo.geo.catalog.layer.addToMap'; + } else if (this.inRange$.value) { + return this.isVisible$.value ? 'igo.geo.catalog.layer.removeFromMap' - : 'igo.geo.catalog.layer.removeFromMapOutRange'; + : 'igo.geo.catalog.layer.removeFromMapNotVisible'; + } else { + return 'igo.geo.catalog.layer.removeFromMapOutRange'; + } } else { return this.inRange$.value ? 'igo.geo.catalog.layer.addToMap' diff --git a/packages/geo/src/locale/en.geo.json b/packages/geo/src/locale/en.geo.json index 65a953c21a..07fe5af10e 100644 --- a/packages/geo/src/locale/en.geo.json +++ b/packages/geo/src/locale/en.geo.json @@ -6,6 +6,7 @@ "layer.addToMapOutRange": "Add to map. The layer is not visible at the current scale. Please zoom in/out", "layer.removeFromMap": "Remove from map", "layer.removeFromMapOutRange": "Remove from map. The layer is not visible at the current scale. Please zoom in/out", + "layer.removeFromMapNotVisible": "Remove from map. The layer is visible at the current scale but is not active. Toggle the map tool to adjust layer visibility.", "group.addToMap": "Add all layers from this group to map", "group.removeFromMap": "Remove all layers from this group to map", "baseLayers": "Baselayers", diff --git a/packages/geo/src/locale/fr.geo.json b/packages/geo/src/locale/fr.geo.json index e1e50f6eca..354933875c 100644 --- a/packages/geo/src/locale/fr.geo.json +++ b/packages/geo/src/locale/fr.geo.json @@ -6,6 +6,7 @@ "layer.addToMapOutRange": "Ajouter à la carte. La donnée est non visible à l'échelle active. Veuillez zoomer +/- si vous voulez l'apercevoir à la carte.", "layer.removeFromMap": "Retirer de la carte", "layer.removeFromMapOutRange": "Retirer de la carte. La donnée est non visible à l'échelle active. Veuillez zoomer +/- si vous voulez l'apercevoir à la carte.", + "layer.removeFromMapNotVisible": "Retirer de la carte. La donnée est visible à l'échelle active, mais n'est pas activée. Veuillez basculer vers l'outil carte pour la rendre visible.", "group.addToMap": "Ajouter toutes les couches de ce groupe à la carte", "group.removeFromMap": "Retirer toutes les couches de ce groupe de la carte", "baseLayers": "Fonds de carte",