Skip to content

Commit

Permalink
feat(geo): highlight unavailable layer in map tool
Browse files Browse the repository at this point in the history
(cherry picked from commit faede586c61032b301313f0415999190d9c5b4eb)
  • Loading branch information
aziz rabhi authored and alecarn committed Nov 26, 2024
1 parent 09c11e2 commit 5a11c8d
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export class LayerContextDirective implements OnInit, OnDestroy {
}
this.contextLayers = [];

this.layerService.unavailableLayers = [];
const layersAndIndex$ = merge(
...context.layers.map((layerOptions: LayerOptions) => {
return this.layerService.createAsyncLayer(layerOptions, context.uri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ export type AnyDataSourceOptions =
| TileArcGISRestDataSourceOptions
| MVTDataSourceOptions
| ClusterDataSourceOptions;

export type AnyDataSourceOptionsWithParams =
| FeatureDataSourceOptions
| WFSDataSourceOptions
| WMSDataSourceOptions
| CartoDataSourceOptions
| ArcGISRestDataSourceOptions
| ArcGISRestImageDataSourceOptions
| TileArcGISRestDataSourceOptions;
210 changes: 126 additions & 84 deletions packages/geo/src/lib/layer/layer-item/layer-item.component.html
Original file line number Diff line number Diff line change
@@ -1,92 +1,134 @@
<mat-list-item class="igo-layer-list-item">
<mat-checkbox
*ngIf="selectionMode"
class="layerCheck"
matListItemIcon
(change)="check()"
[checked]="layerCheck"
>
</mat-checkbox>
<span
matListItemTitle
class="igo-layer-title"
[matTooltip]="tooltipText"
matTooltipShowDelay="500"
(click)="toggleLegendOnClick()"
>
{{ layer.title }}
</span>

<div matListItemMeta>
<button
*ngIf="!selectionMode"
mat-icon-button
[color]="layer.visible ? 'primary' : 'default'"
collapsibleButton
tooltip-position="below"
matTooltipShowDelay="500"
[matTooltip]="eyeTooltip | translate"
(click)="toggleVisibility($event)"
>
<mat-icon
aria-hidden="false"
matBadge="?"
matBadgeColor="accent"
matBadgeSize="small"
matBadgePosition="after"
[matBadgeHidden]="queryBadgeHidden$ | async"
[ngClass]="{ disabled: (inResolutionRange$ | async) === false }"
>{{ (layer.visible$ | async) ? 'visibility' : 'visibility_off' }}
</mat-icon>
</button>

<button
<ng-container *ngIf="!unavailableLayer; else showUnavailableLayer">
<mat-list-item class="igo-layer-list-item">
<mat-checkbox
*ngIf="selectionMode"
class="selection-eye"
mat-icon-button
[color]="layer.visible ? 'primary' : 'default'"
collapsibleButton
tooltip-position="below"
class="layerCheck"
matListItemIcon
(change)="check()"
[checked]="layerCheck"
>
</mat-checkbox>
<span
matListItemTitle
class="igo-layer-title"
[matTooltip]="tooltipText"
matTooltipShowDelay="500"
[matTooltip]="
layer.visible
? ('igo.geo.layer.hideLayer' | translate)
: ('igo.geo.layer.showLayer' | translate)
"
(click)="toggleVisibility($event)"
(click)="toggleLegendOnClick()"
>
<mat-icon
aria-hidden="false"
matBadge="?"
matBadgeColor="accent"
matBadgeSize="small"
matBadgePosition="after"
[matBadgeHidden]="queryBadgeHidden$ | async"
[ngClass]="{ disabled: (inResolutionRange$ | async) === false }"
>{{ layer.visible ? 'visibility' : 'visibility_off' }}
</mat-icon>
</button>
{{ layer.title }}
</span>

<button
*ngIf="!selectionMode"
class="actions-button"
tooltip-position="below"
matTooltipShowDelay="500"
[matTooltip]="'igo.geo.layer.moreOptions' | translate"
mat-icon-button
color="primary"
(click)="toggleLayerTool()"
<div matListItemMeta>
<button
*ngIf="!selectionMode"
mat-icon-button
[color]="layer.visible ? 'primary' : 'default'"
collapsibleButton
tooltip-position="below"
matTooltipShowDelay="500"
[matTooltip]="eyeTooltip | translate"
(click)="toggleVisibility($event)"
>
<mat-icon
aria-hidden="false"
matBadge="?"
matBadgeColor="accent"
matBadgeSize="small"
matBadgePosition="after"
[matBadgeHidden]="queryBadgeHidden$ | async"
[ngClass]="{ disabled: (inResolutionRange$ | async) === false }"
>{{ (layer.visible$ | async) ? 'visibility' : 'visibility_off' }}
</mat-icon>
</button>

<button
*ngIf="selectionMode"
class="selection-eye"
mat-icon-button
[color]="layer.visible ? 'primary' : 'default'"
collapsibleButton
tooltip-position="below"
matTooltipShowDelay="500"
[matTooltip]="
layer.visible
? ('igo.geo.layer.hideLayer' | translate)
: ('igo.geo.layer.showLayer' | translate)
"
(click)="toggleVisibility($event)"
>
<mat-icon
aria-hidden="false"
matBadge="?"
matBadgeColor="accent"
matBadgeSize="small"
matBadgePosition="after"
[matBadgeHidden]="queryBadgeHidden$ | async"
[ngClass]="{ disabled: (inResolutionRange$ | async) === false }"
>{{ layer.visible ? 'visibility' : 'visibility_off' }}
</mat-icon>
</button>

<button
*ngIf="!selectionMode"
class="actions-button"
tooltip-position="below"
matTooltipShowDelay="500"
[matTooltip]="'igo.geo.layer.moreOptions' | translate"
mat-icon-button
color="primary"
(click)="toggleLayerTool()"
>
<mat-icon>more_horiz</mat-icon>
</button>
</div>
</mat-list-item>

<div #legend class="igo-layer-legend-container">
<igo-layer-legend
*ngIf="showLegend$ | async"
[layer]="layer"
[updateLegendOnResolutionChange]="updateLegendOnResolutionChange"
>
<mat-icon>more_horiz</mat-icon>
</button>
</igo-layer-legend>
</div>
</mat-list-item>
</ng-container>

<div #legend class="igo-layer-legend-container">
<igo-layer-legend
*ngIf="showLegend$ | async"
[layer]="layer"
[updateLegendOnResolutionChange]="updateLegendOnResolutionChange"
<ng-template #showUnavailableLayer>
<mat-list-item
class="igo-layer-list-item unavailable-layer"
*ngIf="unavailableLayerTitle"
>
</igo-layer-legend>
</div>
<span
matListItemTitle
class="igo-layer-title"
[matTooltip]="unavailableLayerTitle"
tooltip-position="below"
matTooltipShowDelay="500"
>
{{ unavailableLayerTitle }}
</span>
<div matListItemMeta>
<div
class="align-disabled-button-with-tooltip"
[matTooltip]="'igo.geo.layer.unavailableLayer' | translate"
tooltip-position="below"
matTooltipShowDelay="500"
>
<button mat-icon-button disabled="true">
<mat-icon aria-hidden="false" color="warn" svgIcon="alert-outline">
</mat-icon>
</button>
</div>
<button
mat-icon-button
color="warn"
[matTooltip]="'igo.geo.layer.deleteLayer' | translate"
tooltip-position="below"
matTooltipShowDelay="500"
(click)="deleteUnavailableLayer(unavailableLayer)"
>
<mat-icon aria-hidden="false" svgIcon="delete"> </mat-icon>
</button>
</div>
</mat-list-item>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@
width: 16px;
padding-right: 0px;
}

.align-disabled-button-with-tooltip {
display: inline-block;
}
}
89 changes: 57 additions & 32 deletions packages/geo/src/lib/layer/layer-item/layer-item.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { BehaviorSubject, Subscription } from 'rxjs';
import { MetadataLayerOptions } from '../../metadata/shared/metadata.interface';
import { layerIsQueryable } from '../../query/shared/query.utils';
import { LayerLegendComponent } from '../layer-legend/layer-legend.component';
import { AnyLayerOptions } from '../shared';
import { Layer } from '../shared/layers/layer';
import { TooltipType } from '../shared/layers/layer.interface';

Expand Down Expand Up @@ -131,6 +132,22 @@ export class LayerItemComponent implements OnInit, OnDestroy {

@Input() changeDetection;

@Input() unavailableLayer: AnyLayerOptions;

get unavailableLayerTitle(): string | undefined {
if (
this.unavailableLayer.sourceOptions &&
'params' in this.unavailableLayer.sourceOptions
) {
return this.unavailableLayer.sourceOptions.params.LAYERS;
} else if (
this.unavailableLayer.sourceOptions &&
'layer' in this.unavailableLayer?.sourceOptions

Check failure on line 145 in packages/geo/src/lib/layer/layer-item/layer-item.component.ts

View workflow job for this annotation

GitHub Actions / Analyze Pull Rrequest

Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError
) {
return this.unavailableLayer.sourceOptions.layer;
}
}

get opacity() {
return this.layer.opacity * 100;
}
Expand All @@ -148,7 +165,9 @@ export class LayerItemComponent implements OnInit, OnDestroy {
}
}

@Output() action: EventEmitter<Layer> = new EventEmitter<Layer>(undefined);
@Output() action: EventEmitter<Layer | AnyLayerOptions> = new EventEmitter<
Layer | AnyLayerOptions
>(undefined);
@Output() checkbox = new EventEmitter<{
layer: Layer;
check: boolean;
Expand All @@ -162,46 +181,48 @@ export class LayerItemComponent implements OnInit, OnDestroy {
) {}

ngOnInit() {
if (
this.layer.visible &&
this.expandLegendIfVisible &&
this.layer.firstLoadComponent === true
) {
this.layer.firstLoadComponent = false;
this.layer.legendCollapsed = false;
}
this.toggleLegend(this.layer.legendCollapsed);
this.updateQueryBadge();

const resolution$ = this.layer.map.viewController.resolution$;
this.resolution$$ = resolution$.subscribe(() => {
this.onResolutionChange();
});
this.tooltipText = this.computeTooltip();
if (!this.unavailableLayer) {
if (
this.layer.visible &&
this.expandLegendIfVisible &&
this.layer.firstLoadComponent === true
) {
this.layer.firstLoadComponent = false;
this.layer.legendCollapsed = false;
}
this.toggleLegend(this.layer.legendCollapsed);
this.updateQueryBadge();

this.network$$ = this.networkService
.currentState()
.subscribe((state: ConnectionState) => {
this.state = state;
const resolution$ = this.layer.map.viewController.resolution$;
this.resolution$$ = resolution$.subscribe(() => {
this.onResolutionChange();
});
this.tooltipText = this.computeTooltip();

this.network$$ = this.networkService
.currentState()
.subscribe((state: ConnectionState) => {
this.state = state;
this.onResolutionChange();
});

this.layers$$ = this.layers$.subscribe(() => {
if (this.layer && this.layer.options.active) {
this.layerTool$.next(true);
this.renderer.addClass(this.elRef.nativeElement, this.focusedCls);
}
});

this.layers$$ = this.layers$.subscribe(() => {
if (this.layer && this.layer.options.active) {
this.layerTool$.next(true);
this.renderer.addClass(this.elRef.nativeElement, this.focusedCls);
if (this.changeDetection) {
this.changeDetection.subscribe(() => this.cdRef.detectChanges());
}
});

if (this.changeDetection) {
this.changeDetection.subscribe(() => this.cdRef.detectChanges());
}
}

ngOnDestroy() {
this.resolution$$.unsubscribe();
this.network$$.unsubscribe();
this.layers$$.unsubscribe();
this.resolution$$?.unsubscribe();
this.network$$?.unsubscribe();
this.layers$$?.unsubscribe();
}

toggleLegend(collapsed: boolean) {
Expand Down Expand Up @@ -282,4 +303,8 @@ export class LayerItemComponent implements OnInit, OnDestroy {
this.layerCheck = !this.layerCheck;
this.checkbox.emit({ layer: this.layer, check: this.layerCheck });
}

deleteUnavailableLayer(anyLayerOptions: AnyLayerOptions) {
this.action.emit(anyLayerOptions);
}
}
Loading

0 comments on commit 5a11c8d

Please sign in to comment.