diff --git a/ui-ngx/src/app/core/services/utils.service.ts b/ui-ngx/src/app/core/services/utils.service.ts
index e585b2a19a..a6065dfe62 100644
--- a/ui-ngx/src/app/core/services/utils.service.ts
+++ b/ui-ngx/src/app/core/services/utils.service.ts
@@ -17,7 +17,7 @@
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
///
-import { ElementRef, Inject, Injectable, NgZone } from '@angular/core';
+import { Inject, Injectable, NgZone } from '@angular/core';
import { WINDOW } from '@core/services/window.service';
import { ExceptionData } from '@app/shared/models/error.models';
import {
@@ -45,7 +45,7 @@ import { alarmFields, alarmSeverityTranslations, alarmStatusTranslations } from
import { materialColors } from '@app/shared/models/material.models';
import { WidgetInfo } from '@home/models/widget-component.models';
import jsonSchemaDefaults from 'json-schema-defaults';
-import { fromEvent, Observable, Subscription } from 'rxjs';
+import { Observable } from 'rxjs';
import { publishReplay, refCount } from 'rxjs/operators';
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
import {
@@ -57,8 +57,6 @@ import {
import { EntityId } from '@shared/models/id/entity-id';
import { DatePipe } from '@angular/common';
import { entityTypeTranslations } from '@shared/models/entity-type.models';
-import { OverlayRef } from '@angular/cdk/overlay';
-import { ResizeObserver } from '@juggle/resize-observer';
const i18nRegExp = new RegExp(`{${i18nPrefix}:[^{}]+}`, 'g');
@@ -530,24 +528,4 @@ export class UtilsService {
return base64toObj(b64Encoded);
}
- public updateOverlayMaxHeigth(overlay: OverlayRef, observeElementRef?: ElementRef): Subscription {
- const observeElement = observeElementRef ? observeElementRef.nativeElement : overlay.overlayElement.children[0];
-
- const setMaxHeigthOverlay = () => {
- const top = observeElement.getBoundingClientRect().top;
- const viewport = window.innerHeight;
- overlay.updateSize({
- maxHeight: viewport - top
- });
- };
-
- const observer = new ResizeObserver(() => {
- setMaxHeigthOverlay();
- observer.unobserve(observeElement);
- });
- observer.observe(observeElement);
-
- return fromEvent(window, 'resize').subscribe(() => setMaxHeigthOverlay());
- }
-
}
diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts
index adc741fcdd..5c13a71552 100644
--- a/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts
+++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-filter-config.component.ts
@@ -31,7 +31,7 @@ import {
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { AlarmFilterConfig, alarmFilterConfigEquals } from '@shared/models/query/query.models';
import { coerceBoolean } from '@shared/decorators/coercion';
-import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
+import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import {
AlarmAssigneeOption,
@@ -44,8 +44,8 @@ import { MatChipInputEvent } from '@angular/material/chips';
import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes';
import { TranslateService } from '@ngx-translate/core';
import { deepClone } from '@core/utils';
-import { Subscription } from 'rxjs';
-import { UtilsService } from '@core/services/utils.service';
+import { fromEvent, Subscription } from 'rxjs';
+import { POSITION_MAP } from '@shared/components/popover.models';
export const ALARM_FILTER_CONFIG_DATA = new InjectionToken('AlarmFilterConfigData');
@@ -128,7 +128,6 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal
private translate: TranslateService,
private overlay: Overlay,
private nativeElement: ElementRef,
- private utils: UtilsService,
private viewContainerRef: ViewContainerRef) {
}
@@ -202,14 +201,9 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal
minWidth: ''
});
config.hasBackdrop = true;
- const connectedPosition: ConnectedPosition = {
- originX: 'start',
- originY: 'bottom',
- overlayX: 'start',
- overlayY: 'top'
- };
- config.positionStrategy = this.overlay.position().flexibleConnectedTo(this.nativeElement)
- .withPositions([connectedPosition]);
+ config.positionStrategy = this.overlay.position()
+ .flexibleConnectedTo(this.nativeElement)
+ .withPositions([POSITION_MAP.bottomLeft]);
this.alarmFilterOverlayRef = this.overlay.create(config);
this.alarmFilterOverlayRef.backdropClick().subscribe(() => {
@@ -217,7 +211,9 @@ export class AlarmFilterConfigComponent implements OnInit, OnDestroy, ControlVal
});
this.alarmFilterOverlayRef.attach(new TemplatePortal(this.alarmFilterPanel,
this.viewContainerRef));
- this.resizeWindows = this.utils.updateOverlayMaxHeigth(this.alarmFilterOverlayRef);
+ this.resizeWindows = fromEvent(window, 'resize').subscribe(() => {
+ this.alarmFilterOverlayRef.updatePosition();
+ });
}
cancel() {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts
index b9b8d6e65c..d005f1d9c7 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts
@@ -42,7 +42,7 @@ import cssjs from '@core/css/css';
import { sortItems } from '@shared/models/page/page-link';
import { Direction } from '@shared/models/page/sort-order';
import { CollectionViewer, DataSource, SelectionModel } from '@angular/cdk/collections';
-import { BehaviorSubject, forkJoin, merge, Observable, Subject, Subscription } from 'rxjs';
+import { BehaviorSubject, forkJoin, fromEvent, merge, Observable, Subject, Subscription } from 'rxjs';
import { emptyPageData, PageData } from '@shared/models/page/page-data';
import { debounceTime, distinctUntilChanged, map, take, takeUntil, tap } from 'rxjs/operators';
import { MatPaginator } from '@angular/material/paginator';
@@ -123,6 +123,7 @@ import {
} from '@home/components/alarm/alarm-filter-config.component';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { FormBuilder } from '@angular/forms';
+import { DEFAULT_OVERLAY_POSITIONS } from '@shared/components/popover.models';
interface AlarmsTableWidgetSettings extends TableWidgetSettings {
alarmsTitle: string;
@@ -572,14 +573,9 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
height: 'fit-content',
maxHeight: '75vh'
});
- const connectedPosition: ConnectedPosition = {
- originX: 'end',
- originY: 'bottom',
- overlayX: 'end',
- overlayY: 'top'
- };
- config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement)
- .withPositions([connectedPosition]);
+ config.positionStrategy = this.overlay.position()
+ .flexibleConnectedTo(target as HTMLElement)
+ .withPositions(DEFAULT_OVERLAY_POSITIONS);
const overlayRef = this.overlay.create(config);
overlayRef.backdropClick().subscribe(() => {
@@ -614,10 +610,12 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit,
const componentRef = overlayRef.attach(new ComponentPortal(AlarmFilterConfigComponent,
this.viewContainerRef, injector));
- const resizeWindows = this.utils.updateOverlayMaxHeigth(overlayRef, componentRef.location);
+ const resizeWindows$ = fromEvent(window, 'resize').subscribe(() => {
+ overlayRef.updatePosition();
+ });
componentRef.onDestroy(() => {
- resizeWindows.unsubscribe();
+ resizeWindows$.unsubscribe();
if (componentRef.instance.panelResult) {
const result = componentRef.instance.panelResult;
const alarmFilter = this.entityService.resolveAlarmFilter(result, false);
diff --git a/ui-ngx/src/app/shared/components/popover.models.ts b/ui-ngx/src/app/shared/components/popover.models.ts
index b9ca5e9d59..5b1fd1dee3 100644
--- a/ui-ngx/src/app/shared/components/popover.models.ts
+++ b/ui-ngx/src/app/shared/components/popover.models.ts
@@ -71,6 +71,9 @@ export const POSITION_MAP: { [key: string]: ConnectionPositionPair } = {
export const DEFAULT_POPOVER_POSITIONS = [POSITION_MAP.top, POSITION_MAP.right, POSITION_MAP.bottom, POSITION_MAP.left];
+export const DEFAULT_OVERLAY_POSITIONS = [POSITION_MAP.bottomLeft, POSITION_MAP.bottomRight, POSITION_MAP.topLeft,
+ POSITION_MAP.topRight, POSITION_MAP.left, POSITION_MAP.right];
+
export function getPlacementName(position: ConnectedOverlayPositionChange): PopoverPlacement | undefined {
for (const placement in POSITION_MAP) {
if (
diff --git a/ui-ngx/src/app/shared/components/time/quick-time-interval.component.scss b/ui-ngx/src/app/shared/components/time/quick-time-interval.component.scss
index ff3a9c5438..74af632802 100644
--- a/ui-ngx/src/app/shared/components/time/quick-time-interval.component.scss
+++ b/ui-ngx/src/app/shared/components/time/quick-time-interval.component.scss
@@ -17,6 +17,7 @@
:host {
min-width: 355px;
+ display: block;
@media #{$mat-xs} {
min-width: 0;
diff --git a/ui-ngx/src/app/shared/components/time/timewindow.component.ts b/ui-ngx/src/app/shared/components/time/timewindow.component.ts
index 6205667245..6482ec0dd9 100644
--- a/ui-ngx/src/app/shared/components/time/timewindow.component.ts
+++ b/ui-ngx/src/app/shared/components/time/timewindow.component.ts
@@ -18,9 +18,13 @@ import {
ChangeDetectorRef,
Component,
ElementRef,
- forwardRef, HostBinding,
+ forwardRef,
+ HostBinding,
Injector,
- Input, OnChanges, OnInit, SimpleChanges,
+ Input,
+ OnChanges,
+ OnInit,
+ SimpleChanges,
StaticProvider,
ViewContainerRef
} from '@angular/core';
@@ -47,15 +51,18 @@ import { TimeService } from '@core/services/time.service';
import { TooltipPosition } from '@angular/material/tooltip';
import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
-import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
+import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { coerceBoolean } from '@shared/decorators/coercion';
import {
ComponentStyle,
- defaultTimewindowStyle, iconStyle,
+ defaultTimewindowStyle,
+ iconStyle,
textStyle,
TimewindowStyle
} from '@shared/models/widget-settings.models';
+import { DEFAULT_OVERLAY_POSITIONS } from '@shared/components/popover.models';
+import { fromEvent } from 'rxjs';
// @dynamic
@Component({
@@ -223,14 +230,10 @@ export class TimewindowComponent implements ControlValueAccessor, OnInit, OnChan
maxHeight: '80vh',
height: 'min-content'
});
- const connectedPosition: ConnectedPosition = {
- originX: 'start',
- originY: 'bottom',
- overlayX: 'start',
- overlayY: 'top'
- };
- config.positionStrategy = this.overlay.position().flexibleConnectedTo(this.nativeElement)
- .withPositions([connectedPosition]);
+
+ config.positionStrategy = this.overlay.position()
+ .flexibleConnectedTo(this.nativeElement)
+ .withPositions(DEFAULT_OVERLAY_POSITIONS);
const overlayRef = this.overlay.create(config);
overlayRef.backdropClick().subscribe(() => {
@@ -257,7 +260,11 @@ export class TimewindowComponent implements ControlValueAccessor, OnInit, OnChan
const injector = Injector.create({parent: this.viewContainerRef.injector, providers});
const componentRef = overlayRef.attach(new ComponentPortal(TimewindowPanelComponent,
this.viewContainerRef, injector));
+ const resizeWindows$ = fromEvent(window, 'resize').subscribe(() => {
+ overlayRef.updatePosition();
+ });
componentRef.onDestroy(() => {
+ resizeWindows$.unsubscribe();
if (componentRef.instance.result) {
this.innerValue = componentRef.instance.result;
this.timewindowDisabled = this.isTimewindowDisabled();