hslayers-ng
Version:
HSLayers-NG mapping library
561 lines (548 loc) • 32 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ViewContainerRef, Directive, Injectable, NgZone, ViewChild, Component, ElementRef, PLATFORM_ID, DestroyRef, Input, NgModule } from '@angular/core';
import { pipe, takeUntil, NEVER, EMPTY, combineLatestWith, startWith, map, delay, fromEvent, filter, timer, throwError } from 'rxjs';
import * as i1 from '@angular/common';
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { HsConfig } from 'hslayers-ng/config';
import { HsEventBusService } from 'hslayers-ng/services/event-bus';
import { HsExternalService } from 'hslayers-ng/services/external';
import { HsLayoutService } from 'hslayers-ng/services/layout';
import { HsLogService } from 'hslayers-ng/services/log';
import { HsPanelContainerService, HsOverlayContainerService } from 'hslayers-ng/services/panels';
import { catchError, defaultIfEmpty, map as map$1 } from 'rxjs/operators';
import { debounce } from 'hslayers-ng/services/utils';
import { transform } from 'ol/proj';
import { HsShareUrlService, HS_PRMS } from 'hslayers-ng/services/share';
import { HsMapService } from 'hslayers-ng/services/map';
import { HsLanguageService, HsMissingTranslationHandler, HsTranslateLoader } from 'hslayers-ng/services/language';
import * as i3 from 'hslayers-ng/components/sidebar';
import { HsSidebarModule } from 'hslayers-ng/components/sidebar';
import * as i4 from 'hslayers-ng/common/panels';
import { HsPanelHelpersModule } from 'hslayers-ng/common/panels';
import * as i5 from 'hslayers-ng/common/toast';
import { HsToastComponent } from 'hslayers-ng/common/toast';
import * as i6 from 'hslayers-ng/common/dialogs';
import { HsDialogContainerComponent } from 'hslayers-ng/common/dialogs';
import { HttpResponse, provideHttpClient, withInterceptors, HttpClient } from '@angular/common/http';
import { provideTranslateService, provideMissingTranslationHandler, TranslateLoader } from '@ngx-translate/core';
import { HsCommonLaymanService } from 'hslayers-ng/common/layman';
class HsMapHostDirective {
constructor() {
this.viewContainerRef = inject(ViewContainerRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: HsMapHostDirective, isStandalone: false, selector: "[hsMapHost]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapHostDirective, decorators: [{
type: Directive,
args: [{
selector: '[hsMapHost]',
standalone: false,
}]
}] });
/**
* A safer version of takeUntilDestroyed that handles edge cases around component destruction.
* Based on: https://github.com/angular/angular/issues/54527#issuecomment-2098254508
*/
function safeTakeUntilDestroyed(destroyRef) {
return pipe(takeUntil(
// NEVER is an observable that never emits any value
NEVER.pipe(
// When component is destroyed, takeUntilDestroyed will complete the NEVER observable
takeUntilDestroyed(destroyRef),
// If takeUntilDestroyed throws (e.g., "View destroyed" error),
// we catch it and return EMPTY to safely complete
catchError(() => EMPTY),
// Since NEVER never emits, we provide a default value when it completes
// This ensures the takeUntil always gets a value to complete with
defaultIfEmpty(null))));
}
class HsMapDirective {
constructor() {
this.viewContainerRef = inject(ViewContainerRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: HsMapDirective, isStandalone: true, selector: "[map]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapDirective, decorators: [{
type: Directive,
args: [{
selector: '[map]',
standalone: true,
}]
}] });
class HslayersService {
//TODO: remove
//missingLRFunctionsWarned: any;
constructor() {
this.hsLanguageService = inject(HsLanguageService);
this.hsMapService = inject(HsMapService);
this.hsConfig = inject(HsConfig);
this.hsLayoutService = inject(HsLayoutService);
this.log = inject(HsLogService);
this.hsEventBusService = inject(HsEventBusService);
this.embeddedEnabled = true;
this.hsLayoutService.layoutLoads.subscribe(({ element, innerElement }) => {
// Initialization function for HSLayers elements and their sizes.
// Stores element and container references and sets event listeners for map resizing.
if (window.innerWidth < this.hsConfig.mobileBreakpoint ||
this.hsConfig.sidebarClosed) {
this.hsLayoutService.sidebarExpanded = false;
this.hsLayoutService.sidebarLabels = false;
}
else {
this.hsLayoutService.sidebarExpanded = true;
}
const translateService = this.hsLanguageService.getTranslator();
if (!translateService.getFallbackLang()) {
this.hsLanguageService.initLanguages();
}
if (this.initCalled) {
return;
}
this.hsMapService.loaded().then(() => {
this.initSizeListeners();
setTimeout(() => {
this.mapSizeUpdates();
}, 750);
this.initCalled = true;
});
});
this.hsEventBusService.mapSizeUpdates.subscribe(() => {
this.mapSizeUpdates();
});
}
/**
* Add event listeners for updating HS element and map size after browser resizing or complete load of application.
*/
initSizeListeners() {
window.addEventListener('resize', () => {
debounce(function () {
this.mapSizeUpdates();
this.hsEventBusService.layoutResizes.next();
}, 300, false, this)();
});
}
/**
* Update map size.
*/
mapSizeUpdates() {
const map = this.hsMapService.mapElement;
if (map === null) {
return;
}
if (this.hsMapService.map) {
this.hsMapService.map.updateSize();
if (window.innerWidth < this.hsConfig.mobileBreakpoint ||
this.hsLayoutService.mainpanel) {
this.hsLayoutService.sidebarLabels = false;
}
else {
this.hsLayoutService.sidebarLabels = true;
}
}
else {
this.log.log('Map not yet initialized!');
return;
}
const neededSize = {
width: map.offsetWidth,
height: map.offsetHeight,
};
this.hsEventBusService.sizeChanges.next(neededSize);
}
/**
* Do complete reset of map (view, layers) according to app config
*/
resetMap() {
this.hsMapService.reset();
this.hsEventBusService.mapResets.next();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: () => [] });
class HsMapComponent {
constructor() {
this.hsMapService = inject(HsMapService);
this.hslayersService = inject(HslayersService);
this.hsConfig = inject(HsConfig);
this.hsEventBusService = inject(HsEventBusService);
this.hsLayoutService = inject(HsLayoutService);
this.hsShareUrlService = inject(HsShareUrlService);
this.zone = inject(NgZone);
this.unregisterMapSyncCenterHandlerSubscription =
this.hsEventBusService.mapCenterSynchronizations.subscribe((data) => {
this.onCenterSync(data);
});
}
ngAfterViewInit() {
const visibleLayersParam = this.hsShareUrlService.getParamValue(HS_PRMS.visibleLayers);
this.hsMapService.permalink = this.hsShareUrlService.getParamValue(HS_PRMS.permalink);
this.hsMapService.externalCompositionId =
this.hsShareUrlService.getParamValue(HS_PRMS.composition) ||
this.hsConfig.defaultComposition;
if (visibleLayersParam) {
this.hsMapService.visibleLayersInUrl = visibleLayersParam.split(';');
}
this.zone.runOutsideAngular(() => this.hsMapService.init(this.map.nativeElement));
if (this.hsShareUrlService.getParamValue(HS_PRMS.pureMap) ||
this.hsConfig.pureMap == true) {
this.hsLayoutService.puremapApp = true;
}
this.hsMapService.getMap().updateSize();
}
ngOnDestroy() {
this.unregisterMapSyncCenterHandlerSubscription.unsubscribe();
this.hsMapService.getMap().getInteractions().clear();
}
/**
* This gets called from Cesium map, to
* synchronize center and resolution between Ol and Cesium maps
* @param data - Coordinates in lon/lat and resolution
*/
onCenterSync(data) {
const center = data.center;
if (!center) {
return;
}
const toProj = this.hsMapService.getCurrentProj();
const transformed = transform([center[0], center[1]], 'EPSG:4326', toProj);
this.hsMapService.moveToAndZoom(transformed[0], transformed[1], this.zoomForResolution(center[2]));
}
/**
* Calculates zoom level for a given resolution
* @param resolution - Resolution
* @returns Zoom level for resolution. If resolution
* was greater than 156543.03390625 return 0
*/
zoomForResolution(resolution) {
let zoom = 0;
//Sometimes resolution is under 0.
resolution = Math.abs(resolution);
let r = 156543.03390625; // resolution for zoom 0
while (resolution < r) {
r /= 2.0;
zoom++;
if (resolution > r) {
return zoom;
}
}
return zoom; // resolution was greater than 156543.03390625 so return 0
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: HsMapComponent, isStandalone: true, selector: "hs-map", viewQueries: [{ propertyName: "map", first: true, predicate: ["map"], descendants: true }], ngImport: i0, template: "<div #map class=\"hs-ol-map hs-flex-fill d-flex\"></div>\n" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsMapComponent, decorators: [{
type: Component,
args: [{ selector: 'hs-map', imports: [HsMapDirective], template: "<div #map class=\"hs-ol-map hs-flex-fill d-flex\"></div>\n" }]
}], ctorParameters: () => [], propDecorators: { map: [{
type: ViewChild,
args: ['map']
}] } });
class HslayersComponent {
constructor() {
this.hsConfig = inject(HsConfig);
this.elementRef = inject(ElementRef);
this.hsLayoutService = inject(HsLayoutService);
this.hsLog = inject(HsLogService);
this.hsEventBusService = inject(HsEventBusService);
this.hsPanelContainerService = inject(HsPanelContainerService);
this.hsOverlayContainerService = inject(HsOverlayContainerService);
this.hsExternalService = inject(HsExternalService);
this.ngZone = inject(NgZone);
this.platformId = inject(PLATFORM_ID);
this.destroyRef = inject(DestroyRef);
this.panState = {
/**
* Maximum and minimum values in 'vh' units of how much the panel can be 'moved' by panning
* Final values are controlled by css variables
*/
MIN_HEIGHT: 20, // vh
MAX_HEIGHT: 70, // vh
isProcessing: false,
/**
* Threshold in px
*/
TOGGLE_THRESHOLD: 200,
};
this.sidebarPosition = toSignal(this.hsLayoutService.sidebarPosition);
this.sidebarVisible = toSignal(this.hsLayoutService.sidebarVisible);
this.toastPosition = toSignal(this.hsLayoutService.sidebarPosition$.pipe(combineLatestWith(this.hsConfig.configChanges.pipe(startWith(this.hsConfig))), map(([sidebarPosition, _]) => {
return (this.hsConfig.toastPosition ??
(sidebarPosition === 'left' ? 'bottom-right' : 'bottom-left'));
})));
}
async ngOnInit() {
if (this.config) {
this.hsConfig.update(this.config);
}
if (this.id) {
this.hsConfig.setAppId(this.id);
}
this.hsLayoutService.layoutElement =
this.elementRef.nativeElement.querySelector('.hs-layout');
this.hsLayoutService.contentWrapper =
this.elementRef.nativeElement.querySelector('.hs-content-wrapper');
if (window.innerWidth < 600 && isPlatformBrowser(this.platformId)) {
const viewport = document.querySelector('meta[name="viewport"]');
viewport.setAttribute('content', 'width=device-width, initial-scale=0.6, maximum-scale=2, user-scalable=no');
}
// const appInUrl = this.hsShareUrlService.getParamValue('app');
// if (appInUrl != undefined) {
// this.HsLayoutService.scrollTo(this.elementRef);
// }
this.hsLayoutService.layoutLoads.next({
element: this.elementRef.nativeElement,
innerElement: '.hs-map-space',
});
this.hsLayoutService.mapSpaceRef.next(this.mapHost.viewContainerRef);
this.hsLayoutService.sidebarPosition
.pipe(delay(0), takeUntilDestroyed(this.destroyRef))
.subscribe((position) => {
if (position === 'left') {
this.hsLayoutService.contentWrapper.classList.add('flex-reverse');
this.hsLayoutService.sidebarRight = false;
}
});
window.addEventListener('resize', debounce(() => {
this.hsLayoutService.updPanelSpaceWidth();
this.hsLayoutService.updSidebarPosition();
}, 50, false, this));
}
async ngAfterViewInit() {
this.hsLayoutService.layoutElement = this.hslayout.nativeElement;
const hsapp = this.elementRef.nativeElement;
hsapp.style.overflow = 'hidden';
if (window.innerWidth < this.hsConfig.mobileBreakpoint) {
document.body.style.margin = '0px';
}
if (getComputedStyle(hsapp).display == 'inline') {
hsapp.style.display = 'block';
this.hsLog.warn('Main element (<hslayers>) needs display property to be defined...fallback value added');
}
//Minimal value expected for clientHeight of hsapp element at the initiation in case of WINDOWED mode
//In comparison with clientHeight used to distinguish between full and windowed mode.
const minHeight = window.devicePixelRatio <= 1 ? 350 : 300 * window.devicePixelRatio;
//In case the app height is not set on hslayers element, height is determined by
//the main panel height which vary from 0 if no mainpanel is set to 90 or even 208 in some cases .
//Value of 300 or less /would mean that height is not set we need do something
if (hsapp.clientHeight < minHeight) {
const heightBefore = hsapp.clientHeight;
hsapp.style.height = '100%';
//If its still the same, height is not set on parents nor on hslayers element - we want fullscreen app
if (hsapp.clientHeight == heightBefore) {
hsapp.style.height = '100svh';
this.hsLog.warn(`Main element (<hslayers>) needs height property to be defined...fallback value added`);
}
else if (hsapp.clientHeight < heightBefore) {
/*
* If the value was set, but is lower than recommended - use the value but write a warning.
*/
hsapp.style.height = heightBefore;
this.hsLog.warn(`Height of the element <hslayers> is lower than recommended value of ${minHeight}px.`);
}
}
this.mapSpace = this.hsLayoutService.contentWrapper.querySelector('.hs-map-space');
this.panelSpace = this.hsLayoutService.contentWrapper.querySelector('.hs-panelspace');
const canHover = window.matchMedia('(hover: hover)').matches;
if (!canHover) {
const { default: Hammer } = await import('hammerjs');
this.ngZone.runOutsideAngular(() => {
const panRecognizer = new Hammer(this.hsLayoutService.layoutElement.querySelector('.hs-panelspace-expander'), {
'recognizers': [
[Hammer.Pan, { direction: Hammer.DIRECTION_VERTICAL }],
],
cssProps: {
touchCallout: 'none',
contentZooming: 'none',
tapHighlightColor: 'rgba(0,0,0,0)',
},
});
// Handle pan start
fromEvent(panRecognizer, 'panstart')
.pipe(filter(() => !this.panState.isProcessing), safeTakeUntilDestroyed(this.destroyRef))
.subscribe((e) => {
// Dynamically set the map space height to freeze it in its current height
// because of performance reasons
const currentMapHeight = this.mapSpace.getBoundingClientRect().height;
this.mapSpace.style.flex = `0 0 ${currentMapHeight}px`;
this.panelSpace.classList.add('dragging');
});
// Handle pan move
fromEvent(panRecognizer, 'panmove')
.pipe(filter(() => !this.panState.isProcessing), safeTakeUntilDestroyed(this.destroyRef))
.subscribe((e) => this.updatePanelHeight(e));
// Handle pan end
fromEvent(panRecognizer, 'panend')
.pipe(safeTakeUntilDestroyed(this.destroyRef))
.subscribe((e) => this.snapToNearestHeight(e));
});
}
}
/**
* Updates the height of the panel space based on the pan event.
*
* @param e The pan event object.
*/
updatePanelHeight(e) {
const viewportHeight = window.innerHeight;
// Calculate the new height of the panel space in viewport height units (vh).
// Clamp the new height to be within the minimum and maximum allowed heights.
const newHeightVh = Math.max(this.panState.MIN_HEIGHT, Math.min(this.panState.MAX_HEIGHT, ((window.innerHeight - e.center.y) / viewportHeight) * 100));
// Set the style height of the panel space to the clamped height.
this.panelSpace.style.height = `${newHeightVh}vh`;
}
/**
* Snaps the panel space to the nearest height.
*/
/**
* Snaps the panel space to the nearest height based on the pan event.
*
* @param e The pan event object.
*/
snapToNearestHeight(e) {
const panelspace = this.panelSpace;
/**
* Remove the dragging class and inline style height from the panel space
* to visually indicate the end of dragging and allow it to snap to its nearest height.
*/
panelspace.classList.remove('dragging');
panelspace.style.removeProperty('height');
this.mapSpace.style.removeProperty('flex');
// Check if the absolute delta Y of the pan event exceeds the toggle threshold.
if (Math.abs(e.deltaY) >= this.panState.TOGGLE_THRESHOLD) {
panelspace.classList.toggle('panel-collapsed');
}
// Set a timeout to allow for visual adjustments before notifying about map size updates.
timer(300)
.pipe(safeTakeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.ngZone.run(() => {
this.hsEventBusService.mapSizeUpdates.next();
this.panState.isProcessing = false;
});
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.3", type: HslayersComponent, isStandalone: false, selector: "hslayers", inputs: { config: "config", id: "id" }, viewQueries: [{ propertyName: "hslayout", first: true, predicate: ["hslayout"], descendants: true }, { propertyName: "mapHost", first: true, predicate: HsMapHostDirective, descendants: true, static: true }], ngImport: i0, template: "<div #hslayout class=\"hs-layout hsl hs-page-wrapper\"\n style=\"display:block; position: relative; width: 100%; height: 100%; min-height: inherit !important; max-height:100vh;\">\n <div class=\"hs-content-wrapper d-flex w-100 h-100\" [ngClass]=\"{\n 'hs-open': hsLayoutService.sidebarExpanded && sidebarVisible, \n 'hs-sb-right': sidebarPosition() === 'right' && sidebarVisible, \n 'hs-sb-left': sidebarPosition() === 'left' && sidebarVisible, \n 'hs-sb-bottom': sidebarPosition() === 'bottom'\n }\">\n <!-- ng-if=\"HsLayoutService.componentEnabled('guiOverlay')\" -->\n <div class=\"hs-map-space d-flex\">\n <hs-map class=\"hs-flex-fill d-flex\"/>\n <ng-template hsMapHost></ng-template>\n <hs-panel-container [service]=\"hsOverlayContainerService\"></hs-panel-container>\n </div>\n <div class=\"hs-panelspace buttons\" [hidden]=\"!sidebarVisible()\"\n [ngClass]=\"{'labels': hsLayoutService.sidebarLabels}\">\n <div class=\"hs-panelspace-expander-container bg-white d-none d-mw-md-block w-100\">\n <span class=\"hs-panelspace-expander bg-transparent text-primary py-0 w-100\"\n [ngClass]=\"{'disabled': !(hsLayoutService.sidebarExpanded && sidebarVisible)}\">\n <div class=\"drag-handle pt-1\"></div>\n </span>\n </div>\n <div class=\"hs-panelspace-wrapper me-1 d-block\">\n <hs-sidebar class=\"border-0\" />\n <div class=\"hs-panelplace\">\n @if (hsLayoutService.mainpanel === 'sidebar') {\n <hs-mini-sidebar />\n }\n <hs-panel-container [service]=\"hsPanelContainerService\" class=\"hs-panelplace\">\n </hs-panel-container>\n </div>\n </div>\n </div>\n <hs-toast aria-live=\"polite\" aria-atomic=\"true\" [position]=\"toastPosition()\"></hs-toast>\n <div class=\"hs-dialog-area\"></div>\n </div>\n <hs-dialog-container></hs-dialog-container>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HsMapComponent, selector: "hs-map" }, { kind: "component", type: i3.HsMiniSidebarComponent, selector: "hs-mini-sidebar" }, { kind: "component", type: i3.HsSidebarComponent, selector: "hs-sidebar" }, { kind: "component", type: i4.HsPanelContainerComponent, selector: "hs-panel-container", inputs: ["service", "data", "reusePanelObserver", "panelObserver"], outputs: ["init"] }, { kind: "component", type: i5.HsToastComponent, selector: "hs-toast", inputs: ["position"] }, { kind: "component", type: i6.HsDialogContainerComponent, selector: "hs-dialog-container" }, { kind: "directive", type: HsMapHostDirective, selector: "[hsMapHost]" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersComponent, decorators: [{
type: Component,
args: [{ selector: 'hslayers', standalone: false, template: "<div #hslayout class=\"hs-layout hsl hs-page-wrapper\"\n style=\"display:block; position: relative; width: 100%; height: 100%; min-height: inherit !important; max-height:100vh;\">\n <div class=\"hs-content-wrapper d-flex w-100 h-100\" [ngClass]=\"{\n 'hs-open': hsLayoutService.sidebarExpanded && sidebarVisible, \n 'hs-sb-right': sidebarPosition() === 'right' && sidebarVisible, \n 'hs-sb-left': sidebarPosition() === 'left' && sidebarVisible, \n 'hs-sb-bottom': sidebarPosition() === 'bottom'\n }\">\n <!-- ng-if=\"HsLayoutService.componentEnabled('guiOverlay')\" -->\n <div class=\"hs-map-space d-flex\">\n <hs-map class=\"hs-flex-fill d-flex\"/>\n <ng-template hsMapHost></ng-template>\n <hs-panel-container [service]=\"hsOverlayContainerService\"></hs-panel-container>\n </div>\n <div class=\"hs-panelspace buttons\" [hidden]=\"!sidebarVisible()\"\n [ngClass]=\"{'labels': hsLayoutService.sidebarLabels}\">\n <div class=\"hs-panelspace-expander-container bg-white d-none d-mw-md-block w-100\">\n <span class=\"hs-panelspace-expander bg-transparent text-primary py-0 w-100\"\n [ngClass]=\"{'disabled': !(hsLayoutService.sidebarExpanded && sidebarVisible)}\">\n <div class=\"drag-handle pt-1\"></div>\n </span>\n </div>\n <div class=\"hs-panelspace-wrapper me-1 d-block\">\n <hs-sidebar class=\"border-0\" />\n <div class=\"hs-panelplace\">\n @if (hsLayoutService.mainpanel === 'sidebar') {\n <hs-mini-sidebar />\n }\n <hs-panel-container [service]=\"hsPanelContainerService\" class=\"hs-panelplace\">\n </hs-panel-container>\n </div>\n </div>\n </div>\n <hs-toast aria-live=\"polite\" aria-atomic=\"true\" [position]=\"toastPosition()\"></hs-toast>\n <div class=\"hs-dialog-area\"></div>\n </div>\n <hs-dialog-container></hs-dialog-container>\n</div>\n" }]
}], ctorParameters: () => [], propDecorators: { config: [{
type: Input
}], id: [{
type: Input
}], hslayout: [{
type: ViewChild,
args: ['hslayout']
}], mapHost: [{
type: ViewChild,
args: [HsMapHostDirective, { static: true }]
}] } });
class HsLayoutHostDirective {
constructor() {
this.viewContainerRef = inject(ViewContainerRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsLayoutHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: HsLayoutHostDirective, isStandalone: false, selector: "[hslayout]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HsLayoutHostDirective, decorators: [{
type: Directive,
args: [{
selector: '[hslayout]',
standalone: false,
}]
}] });
const HsAuthInterceptor = (req, next) => {
const authService = inject(HsCommonLaymanService);
if (authService.layman()?.url &&
req.url.includes(authService.layman()?.url)) {
return next(req).pipe(map$1((event) => {
// Check for HttpResponse (success case)
if (event instanceof HttpResponse) {
if (event.body?.['authenticated'] === false &&
authService.isAuthenticated()) {
// Unauthorized request sent to backend -> logout
authService.logout$.next();
}
}
return event;
}), catchError((error) => {
if (error.status === 403) {
//Unauthorized access, Unsuccessful OAuth2 authentication/HTTP Header authentication
//https://github.com/LayerManager/layman/blob/master/src/layman/error_list.py
// --> logout
authService.logout$.next();
}
// Re-throw the error
return throwError(() => error);
}));
}
return next(req);
};
class HslayersModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.2.3", ngImport: i0, type: HslayersModule, declarations: [HsMapHostDirective, HslayersComponent, HsLayoutHostDirective], imports: [CommonModule,
HsMapComponent,
HsSidebarModule,
HsPanelHelpersModule,
HsToastComponent,
HsDialogContainerComponent], exports: [HslayersComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersModule, providers: [
provideHttpClient(withInterceptors([HsAuthInterceptor])),
provideTranslateService({
loader: {
provide: TranslateLoader,
useClass: HsTranslateLoader,
deps: [HsConfig, HttpClient],
},
missingTranslationHandler: provideMissingTranslationHandler(HsMissingTranslationHandler),
}),
], imports: [CommonModule,
HsSidebarModule,
HsPanelHelpersModule,
HsToastComponent,
HsDialogContainerComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: HslayersModule, decorators: [{
type: NgModule,
args: [{
declarations: [HsMapHostDirective, HslayersComponent, HsLayoutHostDirective],
imports: [
CommonModule,
HsMapComponent,
HsSidebarModule,
HsPanelHelpersModule,
HsToastComponent,
HsDialogContainerComponent,
],
exports: [HslayersComponent],
providers: [
provideHttpClient(withInterceptors([HsAuthInterceptor])),
provideTranslateService({
loader: {
provide: TranslateLoader,
useClass: HsTranslateLoader,
deps: [HsConfig, HttpClient],
},
missingTranslationHandler: provideMissingTranslationHandler(HsMissingTranslationHandler),
}),
],
}]
}] });
/*
* Main hslayers-ng entrypoint
*/
/**
* Generated bundle index. Do not edit.
*/
export { HsLayoutHostDirective, HsMapComponent, HsMapDirective, HsMapHostDirective, HslayersComponent, HslayersModule, HslayersService, safeTakeUntilDestroyed };
//# sourceMappingURL=hslayers-ng-core.mjs.map