UNPKG

hslayers-ng

Version:
561 lines (548 loc) 32 kB
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