diff --git a/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.scss b/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.scss index 2c124447..f47c1d06 100644 --- a/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.scss +++ b/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.scss @@ -230,29 +230,29 @@ } // Disabled mat-form-field (e.g. Timezone when not editing) - .mat-form-field-disabled.timezone-field, - .mat-form-field .mdc-text-field--disabled { - opacity: 0.7; - - .mat-select-value, - .mat-select-value-text, - .mat-input-element, - mat-label, - .mat-form-field-label { - color: rgba(0, 0, 0, 0.38) !important; - } - .mat-select-arrow, - .mat-select-arrow svg { - color: rgba(0, 0, 0, 0.38) !important; - fill: rgba(0, 0, 0, 0.38) !important; - } - .mdc-notched-outline__leading, - .mdc-notched-outline__notch, - .mdc-notched-outline__trailing, - .mat-form-field-outline { - border-color: rgba(0, 0, 0, 0.12) !important; - } - } + // .mat-form-field-disabled.timezone-field, + // .mat-form-field .mdc-text-field--disabled { + // opacity: 0.7; + + // .mat-select-value, + // .mat-select-value-text, + // .mat-input-element, + // mat-label, + // .mat-form-field-label { + // color: rgba(0, 0, 0, 0.38) !important; + // } + // .mat-select-arrow, + // .mat-select-arrow svg { + // color: rgba(0, 0, 0, 0.38) !important; + // fill: rgba(0, 0, 0, 0.38) !important; + // } + // .mdc-notched-outline__leading, + // .mdc-notched-outline__notch, + // .mdc-notched-outline__trailing, + // .mat-form-field-outline { + // border-color: rgba(0, 0, 0, 0.12) !important; + // } + // } } // ── Dark theme ──────────────────────────────────────────────────────── @@ -384,29 +384,29 @@ } // Disabled mat-form-field (e.g. Timezone when not editing) - .mat-form-field-disabled.timezone-field, - .mat-form-field .mdc-text-field--disabled { - opacity: 0.7; - - .mat-select-value, - .mat-select-value-text, - .mat-select-value-text span, - .mat-input-element, - mat-label, - .mat-form-field-label { - color: rgba(255, 255, 255, 0.38) !important; - } - .mat-select-arrow, - .mat-select-arrow svg { - color: rgba(255, 255, 255, 0.38) !important; - fill: rgba(255, 255, 255, 0.38) !important; - } - .mdc-notched-outline__leading, - .mdc-notched-outline__notch, - .mdc-notched-outline__trailing { - border-color: rgba(255, 255, 255, 0.12) !important; - } - } + // .mat-form-field-disabled.timezone-field, + // .mat-form-field .mdc-text-field--disabled { + // opacity: 0.7; + + // .mat-select-value, + // .mat-select-value-text, + // .mat-select-value-text span, + // .mat-input-element, + // mat-label, + // .mat-form-field-label { + // color: rgba(255, 255, 255, 0.38) !important; + // } + // .mat-select-arrow, + // .mat-select-arrow svg { + // color: rgba(255, 255, 255, 0.38) !important; + // fill: rgba(255, 255, 255, 0.38) !important; + // } + // .mdc-notched-outline__leading, + // .mdc-notched-outline__notch, + // .mdc-notched-outline__trailing { + // border-color: rgba(255, 255, 255, 0.12) !important; + // } + // } } // ── Snackbars ───────────────────────────────────────────────────────── diff --git a/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.ts b/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.ts index ffe35e6f..cfbde763 100644 --- a/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.ts +++ b/apps/proxy-auth/src/app/otp/organization-details/organization-details.component.ts @@ -50,7 +50,7 @@ export class OrganizationDetailsComponent extends BaseComponent implements OnIni } ngOnInit(): void { - this.organizationForm.get('timeZoneName')?.disable(); + // this.organizationForm.get('timeZoneName')?.disable(); if (this.authToken) { this.otpService .getOrganizationDetails(this.authToken) diff --git a/apps/proxy-auth/src/app/otp/otp.module.ts b/apps/proxy-auth/src/app/otp/otp.module.ts index facf5713..d0c0e021 100644 --- a/apps/proxy-auth/src/app/otp/otp.module.ts +++ b/apps/proxy-auth/src/app/otp/otp.module.ts @@ -46,6 +46,8 @@ import { SubscriptionCenterComponent } from './component/subscription-center/sub import { MatDialogModule } from '@angular/material/dialog'; import { UiConfirmDialogModule } from '@proxy/ui/confirm-dialog'; import { OrganizationDetailsComponent } from './organization-details/organization-details.component'; +import { OverlayContainer } from '@angular/cdk/overlay'; +import { ShadowDomOverlayContainer } from '../shadow-dom-overlay-container'; export const CHAT_COMPONENTS: any[] = [ SendOtpComponent, @@ -106,6 +108,7 @@ export const CHAT_COMPONENTS: any[] = [ OtpService, OtpUtilityService, OtpWidgetService, + { provide: OverlayContainer, useClass: ShadowDomOverlayContainer }, { provide: ProxyBaseUrls.Env, useValue: environment.env }, { provide: ProxyBaseUrls.BaseURL, diff --git a/apps/proxy-auth/src/app/shadow-dom-overlay-container.ts b/apps/proxy-auth/src/app/shadow-dom-overlay-container.ts new file mode 100644 index 00000000..4bf509b7 --- /dev/null +++ b/apps/proxy-auth/src/app/shadow-dom-overlay-container.ts @@ -0,0 +1,56 @@ +import { DOCUMENT } from '@angular/common'; +import { Inject, Injectable } from '@angular/core'; +import { OverlayContainer } from '@angular/cdk/overlay'; +import { Platform } from '@angular/cdk/platform'; + +const CONTAINER_CLASS = 'cdk-overlay-container'; +/** Full-viewport overlay container style so positioning is viewport-based when in shadow root */ +const OVERLAY_CONTAINER_STYLE = + 'position:fixed!important;top:0!important;left:0!important;right:0!important;bottom:0!important;pointer-events:none!important;z-index:1000!important;'; +/** + * OverlayContainer that: + * - When proxy-auth with shadow root exists (script load): attaches the overlay as the + * **first** child of the shadow root with full-viewport fixed style, so it is NOT + * inside the fixed .container and positioning is correct (dropdown below the right field). + * - Otherwise: attaches to document.body (default behaviour). + */ +@Injectable() +export class ShadowDomOverlayContainer extends OverlayContainer { + constructor(@Inject(DOCUMENT) document: Document, _platform: Platform) { + super(document, _platform); + } + + protected override _createContainer(): void { + if (!this._platform.isBrowser) { + return; + } + + const container = this._document.createElement('div'); + container.classList.add(CONTAINER_CLASS); + + const parent = this._getOverlayParent(); + if (parent !== this._document.body) { + container.setAttribute('style', OVERLAY_CONTAINER_STYLE); + const first = parent.firstChild; + if (first) { + parent.insertBefore(container, first); + } else { + parent.appendChild(container); + } + } else { + parent.appendChild(container); + } + this._containerElement = container; + } + + private _getOverlayParent(): HTMLElement { + const host = + (this._document.querySelector('proxy-auth:not([data-master])') as HTMLElement | null) ?? + (this._document.querySelector('proxy-auth') as HTMLElement | null); + + if (host?.shadowRoot) { + return host.shadowRoot as unknown as HTMLElement; + } + return this._document.body; + } +}