UI: Fixed timewindows writeValue is being called twice, first time with a phantom null value

This commit is contained in:
Vladyslav_Prykhodko 2023-05-25 17:38:26 +03:00
parent d33d968aa9
commit fa8decd293
7 changed files with 66 additions and 95 deletions

View File

@ -107,6 +107,7 @@
tooltipPosition="below" tooltipPosition="below"
aggregation="true" aggregation="true"
timezone="true" timezone="true"
isNgModel
[(ngModel)]="dashboardCtx.dashboardTimewindow"> [(ngModel)]="dashboardCtx.dashboardTimewindow">
</tb-timewindow> </tb-timewindow>
<tb-filters-edit [fxShow]="!isEdit && displayFilters()" <tb-filters-edit [fxShow]="!isEdit && displayFilters()"

View File

@ -40,9 +40,11 @@
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs="center start" class="title-container"> <div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs="center start" class="title-container">
<span *ngIf="entitiesTableConfig.tableTitle" class="tb-entity-table-title">{{ entitiesTableConfig.tableTitle }}</span> <span *ngIf="entitiesTableConfig.tableTitle" class="tb-entity-table-title">{{ entitiesTableConfig.tableTitle }}</span>
<tb-anchor #entityTableHeader></tb-anchor> <tb-anchor #entityTableHeader></tb-anchor>
<tb-timewindow *ngIf="entitiesTableConfig.useTimePageLink" [(ngModel)]="timewindow" <tb-timewindow *ngIf="entitiesTableConfig.useTimePageLink"
(ngModelChange)="onTimewindowChange()" [(ngModel)]="timewindow" (ngModelChange)="onTimewindowChange()"
asButton strokedButton historyOnly [forAllTimeEnabled]="entitiesTableConfig.forAllTimeEnabled"></tb-timewindow> asButton strokedButton historyOnly isNgModel
[forAllTimeEnabled]="entitiesTableConfig.forAllTimeEnabled">
</tb-timewindow>
</div> </div>
<span fxFlex></span> <span fxFlex></span>
<div [fxShow]="addEnabled()"> <div [fxShow]="addEnabled()">

View File

@ -24,6 +24,7 @@ import {
EventEmitter, EventEmitter,
Input, Input,
OnChanges, OnChanges,
OnDestroy,
OnInit, OnInit,
SimpleChanges, SimpleChanges,
ViewChild ViewChild
@ -72,7 +73,7 @@ import { EntityDetailsPanelComponent } from '@home/components/entity/entity-deta
styleUrls: ['./entities-table.component.scss'], styleUrls: ['./entities-table.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class EntitiesTableComponent extends PageComponent implements IEntitiesTableComponent, AfterViewInit, OnInit, OnChanges { export class EntitiesTableComponent extends PageComponent implements IEntitiesTableComponent, AfterViewInit, OnInit, OnChanges, OnDestroy {
@Input() @Input()
entitiesTableConfig: EntityTableConfig<BaseData<HasId>>; entitiesTableConfig: EntityTableConfig<BaseData<HasId>>;
@ -162,6 +163,7 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
} }
ngOnDestroy() { ngOnDestroy() {
super.ngOnDestroy();
if (this.widgetResize$) { if (this.widgetResize$) {
this.widgetResize$.disconnect(); this.widgetResize$.disconnect();
} }
@ -366,12 +368,10 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
); );
if (this.displayPagination) { if (this.displayPagination) {
paginatorSubscription$ = this.paginator.page.asObservable().pipe( paginatorSubscription$ = this.paginator.page.asObservable().pipe(
map((data) => { map((data) => ({
return { page: data.pageIndex === 0 ? null : data.pageIndex,
page: data.pageIndex === 0 ? null : data.pageIndex, pageSize: data.pageSize === this.defaultPageSize ? null : data.pageSize
pageSize: data.pageSize === this.defaultPageSize ? null : data.pageSize }))
};
})
); );
} }
this.updateDataSubscription = ((this.displayPagination ? merge(sortSubscription$, paginatorSubscription$) this.updateDataSubscription = ((this.displayPagination ? merge(sortSubscription$, paginatorSubscription$)
@ -421,8 +421,8 @@ export class EntitiesTableComponent extends PageComponent implements IEntitiesTa
} }
} }
private getTimePageLinkInterval(): {startTime?: number, endTime?: number} { private getTimePageLinkInterval(): {startTime?: number; endTime?: number} {
const interval: {startTime?: number, endTime?: number} = {}; const interval: {startTime?: number; endTime?: number} = {};
switch (this.timewindow.history.historyType) { switch (this.timewindow.history.historyType) {
case HistoryWindowType.LAST_INTERVAL: case HistoryWindowType.LAST_INTERVAL:
const currentTime = Date.now(); const currentTime = Date.now();

View File

@ -14,7 +14,16 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { AfterViewInit, ChangeDetectorRef, Component, Input, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; import {
AfterViewInit,
ChangeDetectorRef,
Component,
Input,
OnDestroy,
OnInit,
ViewChild,
ViewContainerRef
} from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
@ -32,7 +41,7 @@ import { Subscription } from 'rxjs';
templateUrl: './event-table.component.html', templateUrl: './event-table.component.html',
styleUrls: ['./event-table.component.scss'] styleUrls: ['./event-table.component.scss']
}) })
export class EventTableComponent implements OnInit, AfterViewInit { export class EventTableComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() @Input()
tenantId: string; tenantId: string;

View File

@ -50,6 +50,7 @@
historyOnly="{{widget.onlyHistoryTimewindow}}" historyOnly="{{widget.onlyHistoryTimewindow}}"
alwaysDisplayTypePrefix alwaysDisplayTypePrefix
timezone="true" timezone="true"
isNgModel
[isEdit]="isEdit" [isEdit]="isEdit"
[(ngModel)]="widgetComponent.widget.config.timewindow" [(ngModel)]="widgetComponent.widget.config.timewindow"
(ngModelChange)="widgetComponent.onTimewindowChanged($event)"> (ngModelChange)="widgetComponent.onTimewindowChanged($event)">

View File

@ -46,7 +46,7 @@
(click)="toggleTimewindow($event)" (click)="toggleTimewindow($event)"
matTooltip="{{ 'timewindow.edit' | translate }}" matTooltip="{{ 'timewindow.edit' | translate }}"
[matTooltipPosition]="tooltipPosition"> [matTooltipPosition]="tooltipPosition">
{{innerValue?.displayValue}} <span [fxShow]="innerValue?.displayTimezoneAbbr !== ''">| <span class="timezone-abbr">{{innerValue.displayTimezoneAbbr}}</span></span> {{innerValue?.displayValue}} <span [fxShow]="innerValue?.displayTimezoneAbbr !== ''">| <span class="timezone-abbr">{{innerValue?.displayTimezoneAbbr}}</span></span>
</span> </span>
<button *ngIf="direction === 'right'" [disabled]="timewindowDisabled" mat-icon-button class="tb-mat-32" <button *ngIf="direction === 'right'" [disabled]="timewindowDisabled" mat-icon-button class="tb-mat-32"
type="button" type="button"

View File

@ -21,8 +21,6 @@ import {
forwardRef, forwardRef,
Injector, Injector,
Input, Input,
OnDestroy,
OnInit,
StaticProvider, StaticProvider,
ViewContainerRef ViewContainerRef
} from '@angular/core'; } from '@angular/core';
@ -68,7 +66,7 @@ import { coerceBoolean } from '@shared/decorators/coercion';
} }
] ]
}) })
export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAccessor { export class TimewindowComponent implements ControlValueAccessor {
historyOnlyValue = false; historyOnlyValue = false;
@ -91,76 +89,38 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
@coerceBoolean() @coerceBoolean()
forAllTimeEnabled = false; forAllTimeEnabled = false;
alwaysDisplayTypePrefixValue = false; @Input()
@coerceBoolean()
alwaysDisplayTypePrefix = false;
@Input() @Input()
set alwaysDisplayTypePrefix(val) { @coerceBoolean()
this.alwaysDisplayTypePrefixValue = coerceBooleanProperty(val); quickIntervalOnly = false;
}
get alwaysDisplayTypePrefix() {
return this.alwaysDisplayTypePrefixValue;
}
quickIntervalOnlyValue = false;
@Input() @Input()
set quickIntervalOnly(val) { @coerceBoolean()
this.quickIntervalOnlyValue = coerceBooleanProperty(val); aggregation = false;
}
get quickIntervalOnly() {
return this.quickIntervalOnlyValue;
}
aggregationValue = false;
@Input() @Input()
set aggregation(val) { @coerceBoolean()
this.aggregationValue = coerceBooleanProperty(val); timezone = false;
}
get aggregation() {
return this.aggregationValue;
}
timezoneValue = false;
@Input() @Input()
set timezone(val) { @coerceBoolean()
this.timezoneValue = coerceBooleanProperty(val); isToolbar = false;
}
get timezone() {
return this.timezoneValue;
}
isToolbarValue = false;
@Input() @Input()
set isToolbar(val) { @coerceBoolean()
this.isToolbarValue = coerceBooleanProperty(val); asButton = false;
}
get isToolbar() {
return this.isToolbarValue;
}
asButtonValue = false;
@Input()
set asButton(val) {
this.asButtonValue = coerceBooleanProperty(val);
}
get asButton() {
return this.asButtonValue;
}
@Input() @Input()
@coerceBoolean() @coerceBoolean()
strokedButton = false; strokedButton = false;
@Input()
@coerceBoolean()
isNgModel = false;
isEditValue = false; isEditValue = false;
@Input() @Input()
@ -179,7 +139,9 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
@Input() @Input()
tooltipPosition: TooltipPosition = 'above'; tooltipPosition: TooltipPosition = 'above';
@Input() disabled: boolean; @Input()
@coerceBoolean()
disabled: boolean;
innerValue: Timewindow; innerValue: Timewindow;
@ -187,6 +149,8 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
private propagateChange = (_: any) => {}; private propagateChange = (_: any) => {};
private _isControlInitialized = false;
constructor(private overlay: Overlay, constructor(private overlay: Overlay,
private translate: TranslateService, private translate: TranslateService,
private timeService: TimeService, private timeService: TimeService,
@ -198,12 +162,6 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
public breakpointObserver: BreakpointObserver) { public breakpointObserver: BreakpointObserver) {
} }
ngOnInit(): void {
}
ngOnDestroy(): void {
}
toggleTimewindow($event: Event) { toggleTimewindow($event: Event) {
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
@ -215,7 +173,6 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
maxHeight: '80vh', maxHeight: '80vh',
height: 'min-content' height: 'min-content'
}); });
config.hasBackdrop = true;
const connectedPosition: ConnectedPosition = { const connectedPosition: ConnectedPosition = {
originX: 'start', originX: 'start',
originY: 'bottom', originY: 'bottom',
@ -262,18 +219,17 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
} }
private onHistoryOnlyChanged(): boolean { private onHistoryOnlyChanged(): boolean {
if (this.historyOnlyValue && this.innerValue) { if (this.historyOnlyValue && this.innerValue && this.innerValue.selectedTab !== TimewindowType.HISTORY) {
if (this.innerValue.selectedTab !== TimewindowType.HISTORY) { this.innerValue.selectedTab = TimewindowType.HISTORY;
this.innerValue.selectedTab = TimewindowType.HISTORY; this.updateDisplayValue();
this.updateDisplayValue(); return true;
return true;
}
} }
return false; return false;
} }
registerOnChange(fn: any): void { registerOnChange(fn: any): void {
this.propagateChange = fn; this.propagateChange = fn;
this._isControlInitialized = true;
} }
registerOnTouched(fn: any): void { registerOnTouched(fn: any): void {
@ -285,14 +241,16 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
} }
writeValue(obj: Timewindow): void { writeValue(obj: Timewindow): void {
this.innerValue = initModelFromDefaultTimewindow(obj, this.quickIntervalOnly, this.timeService); if (this._isControlInitialized || !this.isNgModel) {
this.timewindowDisabled = this.isTimewindowDisabled(); this.innerValue = initModelFromDefaultTimewindow(obj, this.quickIntervalOnly, this.timeService);
if (this.onHistoryOnlyChanged()) { this.timewindowDisabled = this.isTimewindowDisabled();
setTimeout(() => { if (this.onHistoryOnlyChanged()) {
this.notifyChanged(); setTimeout(() => {
}); this.notifyChanged();
} else { });
this.updateDisplayValue(); } else {
this.updateDisplayValue();
}
} }
} }