diff --git a/apps/webcomponents/src/app/AppOverlayContainer.ts b/apps/webcomponents/src/app/AppOverlayContainer.ts deleted file mode 100644 index 73c6f3249f..0000000000 --- a/apps/webcomponents/src/app/AppOverlayContainer.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { OverlayContainer } from '@angular/cdk/overlay' -import { Platform } from '@angular/cdk/platform' -import { DOCUMENT } from '@angular/common' -import { Inject, Injectable, OnDestroy } from '@angular/core' - -@Injectable() -export class AppOverlayContainer extends OverlayContainer implements OnDestroy { - private selector: string - - constructor( - @Inject(DOCUMENT) private document: Document, - platform: Platform - ) { - super(document, platform) - } - - setSelector(selector: string) { - this.selector = selector - } - ngOnDestroy() { - super.ngOnDestroy() - } - - protected _createContainer(): void { - const container: HTMLDivElement = this.document.createElement('div') - container.classList.add('app-overlay-container') - const element: Element | null = this.document - .querySelector(this.selector) - .shadowRoot.querySelector('#angular-app-root') - if (element !== null) { - element.appendChild(container) - this._containerElement = container - } else { - console.error( - 'Material CDK Overlay creation failed ! ' + - 'It can work only with gn-search-input webcomponent. ' + - 'You have to add an element with id="angular-app-root" (in the shadowDOM) to which the overlay will be appended.' - ) - } - } -} diff --git a/apps/webcomponents/src/app/components/base.component.ts b/apps/webcomponents/src/app/components/base.component.ts index 0c3a3b63e7..f31461387a 100644 --- a/apps/webcomponents/src/app/components/base.component.ts +++ b/apps/webcomponents/src/app/components/base.component.ts @@ -1,4 +1,11 @@ -import { Component, Injector, Input, OnChanges, OnInit } from '@angular/core' +import { + Component, + ElementRef, + Injector, + Input, + OnChanges, + OnInit, +} from '@angular/core' import { LinkClassifierService, LinkUsage, @@ -10,6 +17,8 @@ import { TranslateService } from '@ngx-translate/core' import { firstValueFrom } from 'rxjs' import { DatasetDistribution } from '@geonetwork-ui/common/domain/record' import { RecordsRepositoryInterface } from '@geonetwork-ui/common/domain/records-repository.interface' +import { OverlayContainer } from '@angular/cdk/overlay' +import { WebcomponentOverlayContainer } from '../webcomponent-overlay-container' export const apiConfiguration = new Configuration() @@ -40,6 +49,12 @@ export class BaseComponent implements OnChanges, OnInit { this.searchService = injector.get(SearchApiService) this.recordsRepository = injector.get(RecordsRepositoryInterface) this.linkClassifier = injector.get(LinkClassifierService) + + const elementRef = injector.get(ElementRef) + const overlayContainer = injector.get( + OverlayContainer + ) as WebcomponentOverlayContainer + overlayContainer.setRoot(elementRef.nativeElement.shadowRoot) } ngOnInit() { diff --git a/apps/webcomponents/src/app/components/gn-search-input/gn-search-input.component.html b/apps/webcomponents/src/app/components/gn-search-input/gn-search-input.component.html index 4abf44b912..1b159ba380 100644 --- a/apps/webcomponents/src/app/components/gn-search-input/gn-search-input.component.html +++ b/apps/webcomponents/src/app/components/gn-search-input/gn-search-input.component.html @@ -1,3 +1 @@ -
- -
+ diff --git a/apps/webcomponents/src/app/webcomponent-overlay-container.ts b/apps/webcomponents/src/app/webcomponent-overlay-container.ts new file mode 100644 index 0000000000..6a2415c7ac --- /dev/null +++ b/apps/webcomponents/src/app/webcomponent-overlay-container.ts @@ -0,0 +1,32 @@ +import { OverlayContainer } from '@angular/cdk/overlay' +import { Platform } from '@angular/cdk/platform' +import { DOCUMENT } from '@angular/common' +import { Inject, Injectable } from '@angular/core' + +@Injectable() +export class WebcomponentOverlayContainer extends OverlayContainer { + private componentRoot: HTMLElement + + constructor( + @Inject(DOCUMENT) private document: Document, + platform: Platform + ) { + super(document, platform) + } + + setRoot(componentRoot: HTMLElement) { + this.componentRoot = componentRoot + } + + protected _createContainer(): void { + const container: HTMLDivElement = this.document.createElement('div') + container.classList.add('gn-ui-overlay-container') + if (!this.componentRoot) { + throw new Error( + 'Angular CDK OverlayContainer was used without proper initialization.' + ) + } + this.componentRoot.appendChild(container) + this._containerElement = container + } +} diff --git a/apps/webcomponents/src/app/webcomponents.module.ts b/apps/webcomponents/src/app/webcomponents.module.ts index 452151d851..fa0f1cf47e 100644 --- a/apps/webcomponents/src/app/webcomponents.module.ts +++ b/apps/webcomponents/src/app/webcomponents.module.ts @@ -1,6 +1,5 @@ import { OverlayContainer } from '@angular/cdk/overlay' -import { Platform } from '@angular/cdk/platform' -import { CommonModule, DOCUMENT } from '@angular/common' +import { CommonModule } from '@angular/common' import { CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from '@angular/core' import { createCustomElement } from '@angular/elements' import { MatIconModule } from '@angular/material/icon' @@ -12,6 +11,7 @@ import { UiElementsModule } from '@geonetwork-ui/ui/elements' import { UiInputsModule } from '@geonetwork-ui/ui/inputs' import { UiSearchModule } from '@geonetwork-ui/ui/search' import { + EmbeddedTranslateLoader, TRANSLATE_DEFAULT_CONFIG, UtilI18nModule, } from '@geonetwork-ui/util/i18n' @@ -20,7 +20,7 @@ import { StoreModule } from '@ngrx/store' import { StoreDevtoolsModule } from '@ngrx/store-devtools' import { TranslateLoader, TranslateModule } from '@ngx-translate/core' import { AppComponent } from './app.component' -import { AppOverlayContainer } from './AppOverlayContainer' +import { WebcomponentOverlayContainer } from './webcomponent-overlay-container' import { apiConfiguration, BaseComponent } from './components/base.component' import { GnAggregatedRecordsComponent } from './components/gn-aggregated-records/gn-aggregated-records.component' import { GnFacetsComponent } from './components/gn-facets/gn-facets.component' @@ -31,7 +31,6 @@ import { GnMapViewerComponent } from './components/gn-map-viewer/gn-map-viewer.c import { FeatureMapModule } from '@geonetwork-ui/feature/map' import { GnDatasetViewChartComponent } from './components/gn-dataset-view-chart/gn-dataset-view-chart.component' import { FeatureDatavizModule } from '@geonetwork-ui/feature/dataviz' -import { EmbeddedTranslateLoader } from '@geonetwork-ui/util/i18n' import { FeatureAuthModule } from '@geonetwork-ui/feature/auth' import { BrowserAnimationsModule } from '@angular/platform-browser/animations' @@ -90,12 +89,7 @@ const CUSTOM_ELEMENTS: [new (...args) => BaseComponent, string][] = [ }, { provide: OverlayContainer, - useFactory: (document: Document, platform: Platform) => { - const container = new AppOverlayContainer(document, platform) - container.setSelector('gn-search-input') - return container - }, - deps: [DOCUMENT, Platform], + useClass: WebcomponentOverlayContainer, }, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/apps/webcomponents/src/styles.css b/apps/webcomponents/src/styles.css index 4814c8c96c..e614fc4a34 100644 --- a/apps/webcomponents/src/styles.css +++ b/apps/webcomponents/src/styles.css @@ -51,7 +51,7 @@ min-width: 1px; min-height: 1px; } -.app-overlay-container { +.gn-ui-overlay-container { position: absolute; z-index: 1000; pointer-events: none; @@ -60,7 +60,7 @@ height: 100%; width: 100%; } -.app-overlay-container:empty { +.gn-ui-overlay-container:empty { display: none; }