Browse Source

Merge pull request #8062 from ArtemDzhereleiko/AD/refactoring/timewindow

Refactoring time window component
pull/8260/head
Igor Kulikov 4 years ago
committed by GitHub
parent
commit
5d54716ec6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 431
      ui-ngx/src/app/shared/components/time/timewindow-panel.component.html
  2. 16
      ui-ngx/src/app/shared/components/time/timewindow-panel.component.scss
  3. 134
      ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts
  4. 18
      ui-ngx/src/app/shared/components/time/timewindow.component.html
  5. 133
      ui-ngx/src/app/shared/components/time/timewindow.component.ts

431
ui-ngx/src/app/shared/components/time/timewindow-panel.component.html

@ -15,222 +15,229 @@
limitations under the License.
-->
<form [formGroup]="timewindowForm" (ngSubmit)="update()">
<fieldset [disabled]="(isLoading$ | async)">
<div class="mat-content" fxLayout="column">
<mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}"
(selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
<mat-tab label="{{ 'timewindow.realtime' | translate }}">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-top: 8px; padding-left: 16px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
(ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
<div formGroupName="realtime" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group *ngIf="!quickIntervalOnly" [fxShow]="isEdit || (!timewindow.hideLastInterval && !timewindow.hideQuickInterval)"
formControlName="realtimeType">
<mat-radio-button [value]="realtimeTypes.LAST_INTERVAL" color="primary">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-right: 8px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideLastInterval"
(ngModelChange)="onHideLastIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column">
<span translate>timewindow.last</span>
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</section>
</mat-radio-button>
<mat-radio-button [value]="realtimeTypes.INTERVAL" color="primary">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-right: 8px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideQuickInterval"
(ngModelChange)="onHideQuickIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column">
<span translate>timewindow.interval</span>
<tb-quick-time-interval
formControlName="quickInterval"
onlyCurrentInterval="true"
[fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
style="padding-top: 8px"></tb-quick-time-interval>
</section>
</section>
</mat-radio-button>
</mat-radio-group>
<tb-timeinterval *ngIf="!isEdit && !timewindow.hideLastInterval && timewindow.hideQuickInterval"
formControlName="timewindowMs"
predefinedName="timewindow.last"
required
style="padding-top: 8px;"></tb-timeinterval>
<tb-quick-time-interval *ngIf="quickIntervalOnly || !isEdit && timewindow.hideLastInterval && !timewindow.hideQuickInterval"
formControlName="quickInterval"
onlyCurrentInterval="true"
required
style="padding-top: 8px"></tb-quick-time-interval>
</div>
</section>
</section>
</mat-tab>
<mat-tab label="{{ 'timewindow.history' | translate }}">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-top: 8px; padding-left: 16px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
(ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
<div formGroupName="history" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group formControlName="historyType">
<mat-radio-button [value]="historyTypes.LAST_INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.last</span>
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.FIXED" color="primary">
<section fxLayout="column">
<span translate>timewindow.time-period</span>
<tb-datetime-period
formControlName="fixedTimewindow"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.FIXED"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.FIXED"
style="padding-top: 8px;"></tb-datetime-period>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.interval</span>
<tb-quick-time-interval
formControlName="quickInterval"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.INTERVAL"
style="padding-top: 8px"></tb-quick-time-interval>
</section>
</mat-radio-button>
</mat-radio-group>
</div>
</section>
</section>
</mat-tab>
</mat-tab-group>
<div *ngIf="aggregation" formGroupName="aggregation" class="mat-content mat-padding" fxLayout="column">
<section fxLayout="row">
<section fxLayout="column" fxLayoutAlign="start center" [fxShow]="isEdit">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideAggregation"
(ngModelChange)="onHideAggregationChanged()"></mat-checkbox>
</section>
<section fxFlex fxLayout="column" [fxShow]="isEdit || !timewindow.hideAggregation">
<mat-form-field>
<mat-label translate>aggregation.function</mat-label>
<mat-select formControlName="type" style="min-width: 150px;">
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
{{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</section>
<form [formGroup]="timewindowForm" class="mat-content">
<mat-tab-group [ngClass]="{'tb-headless': historyOnly}"
(selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
<mat-tab label="{{ 'timewindow.realtime' | translate }}">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center"
style="padding-top: 8px; padding-left: 16px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
(ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="row" *ngIf="timewindowForm.get('aggregation.type').value === aggregationTypes.NONE">
<section fxLayout="column" fxLayoutAlign="start center" [fxShow]="isEdit">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideAggInterval"
(ngModelChange)="onHideAggIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideAggInterval">
<div class="limit-slider-container" fxLayout="row" fxLayoutAlign="start center"
fxLayout.xs="column" fxLayoutAlign.xs="stretch">
<label translate>aggregation.limit</label>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex>
<mat-slider fxFlex
discrete
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"><input matSliderThumb formControlName="limit" />
</mat-slider>
<mat-form-field class="limit-slider-value">
<input matInput formControlName="limit" type="number" step="1"
[value]="timewindowForm.get('aggregation.limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"/>
</mat-form-field>
</div>
</div>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
<div formGroupName="realtime" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group *ngIf="!quickIntervalOnly"
[fxShow]="isEdit || (!timewindow.hideLastInterval && !timewindow.hideQuickInterval)"
formControlName="realtimeType">
<mat-radio-button [value]="realtimeTypes.LAST_INTERVAL" color="primary">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-right: 8px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideLastInterval"
(ngModelChange)="onHideLastIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column">
<span translate>timewindow.last</span>
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</section>
</mat-radio-button>
<mat-radio-button [value]="realtimeTypes.INTERVAL" color="primary">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center" style="padding-right: 8px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideQuickInterval"
(ngModelChange)="onHideQuickIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column">
<span translate>timewindow.interval</span>
<tb-quick-time-interval
formControlName="quickInterval"
onlyCurrentInterval="true"
[fxShow]="timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME &&
timewindowForm.get('realtime.realtimeType').value === realtimeTypes.INTERVAL"
style="padding-top: 8px"></tb-quick-time-interval>
</section>
</section>
</mat-radio-button>
</mat-radio-group>
<tb-timeinterval *ngIf="!isEdit && !timewindow.hideLastInterval && timewindow.hideQuickInterval"
formControlName="timewindowMs"
predefinedName="timewindow.last"
required
style="padding-top: 8px;"></tb-timeinterval>
<tb-quick-time-interval
*ngIf="quickIntervalOnly || !isEdit && timewindow.hideLastInterval && !timewindow.hideQuickInterval"
formControlName="quickInterval"
onlyCurrentInterval="true"
required
style="padding-top: 8px"></tb-quick-time-interval>
</div>
</section>
</section>
<ng-container *ngTemplateOutlet="additionalData">
</ng-container>
</mat-tab>
<mat-tab label="{{ 'timewindow.history' | translate }}">
<section fxLayout="row">
<section *ngIf="isEdit" fxLayout="column" fxLayoutAlign="start center"
style="padding-top: 8px; padding-left: 16px;">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideInterval"
(ngModelChange)="onHideIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideInterval">
<div formGroupName="history" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group formControlName="historyType">
<mat-radio-button [value]="historyTypes.LAST_INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.last</span>
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.FIXED" color="primary">
<section fxLayout="column">
<span translate>timewindow.time-period</span>
<tb-datetime-period
formControlName="fixedTimewindow"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.FIXED"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.FIXED"
style="padding-top: 8px;"></tb-datetime-period>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.INTERVAL" color="primary">
<section fxLayout="column">
<span translate>timewindow.interval</span>
<tb-quick-time-interval
formControlName="quickInterval"
class="history-time-input"
[fxShow]="timewindowForm.get('history.historyType').value === historyTypes.INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history.historyType').value === historyTypes.INTERVAL"
style="padding-top: 8px"></tb-quick-time-interval>
</section>
</mat-radio-button>
</mat-radio-group>
</div>
</section>
</section>
<ng-container *ngTemplateOutlet="additionalData">
</ng-container>
</mat-tab>
</mat-tab-group>
<ng-template #additionalData>
<div *ngIf="aggregation" formGroupName="aggregation" class="mat-content mat-padding" fxLayout="column">
<section fxLayout="row">
<section fxLayout="column" fxLayoutAlign="start center" [fxShow]="isEdit">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideAggregation"
(ngModelChange)="onHideAggregationChanged()"></mat-checkbox>
</section>
<section fxFlex fxLayout="column" [fxShow]="isEdit || !timewindow.hideAggregation">
<mat-form-field>
<mat-label translate>aggregation.function</mat-label>
<mat-select formControlName="type" style="min-width: 150px;">
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
{{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</section>
</div>
<div formGroupName="realtime"
*ngIf="aggregation && timewindowForm.get('aggregation.type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.REALTIME" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[isEdit]="isEdit"
[(hideFlag)]="timewindow.hideAggInterval"
(hideFlagChange)="onHideAggIntervalChanged()"
[min]="minRealtimeAggInterval()" [max]="maxRealtimeAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div formGroupName="history"
*ngIf="aggregation && timewindowForm.get('aggregation.type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.HISTORY" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[isEdit]="isEdit"
[(hideFlag)]="timewindow.hideAggInterval"
(hideFlagChange)="onHideAggIntervalChanged()"
[min]="minHistoryAggInterval()" [max]="maxHistoryAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div *ngIf="timezone" class="mat-content mat-padding" fxLayout="row">
</section>
<section fxLayout="row" *ngIf="timewindowForm.get('aggregation.type').value === aggregationTypes.NONE">
<section fxLayout="column" fxLayoutAlign="start center" [fxShow]="isEdit">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideTimezone"
(ngModelChange)="onHideTimezoneChanged()"></mat-checkbox>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideAggInterval"
(ngModelChange)="onHideAggIntervalChanged()"></mat-checkbox>
</section>
<section fxLayout="column" fxFlex [fxShow]="isEdit || !timewindow.hideAggInterval">
<div class="limit-slider-container" fxLayout="row" fxLayoutAlign="start center"
fxLayout.xs="column" fxLayoutAlign.xs="stretch">
<label translate>aggregation.limit</label>
<div fxLayout="row" fxLayoutAlign="start center" fxFlex>
<mat-slider fxFlex
discrete
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"><input matSliderThumb formControlName="limit"/>
</mat-slider>
<mat-form-field class="limit-slider-value">
<input matInput formControlName="limit" type="number" step="1"
[value]="timewindowForm.get('aggregation.limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"/>
</mat-form-field>
</div>
</div>
</section>
<tb-timezone-select fxFlex [fxShow]="isEdit || !timewindow.hideTimezone"
localBrowserTimezonePlaceholderOnEmpty="true"
formControlName="timezone">
</tb-timezone-select>
</div>
<div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center">
<button type="button"
mat-button
[disabled]="(isLoading$ | async)"
(click)="cancel()">
{{ 'action.cancel' | translate }}
</button>
<button type="submit"
mat-raised-button
color="primary"
[disabled]="(isLoading$ | async) || timewindowForm.invalid || !timewindowForm.dirty">
{{ 'action.update' | translate }}
</button>
</div>
</section>
</div>
<div formGroupName="realtime"
*ngIf="aggregation && timewindowForm.get('aggregation.type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.REALTIME" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[isEdit]="isEdit"
[(hideFlag)]="timewindow.hideAggInterval"
(hideFlagChange)="onHideAggIntervalChanged()"
[min]="minRealtimeAggInterval()" [max]="maxRealtimeAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div formGroupName="history"
*ngIf="aggregation && timewindowForm.get('aggregation.type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.HISTORY" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[isEdit]="isEdit"
[(hideFlag)]="timewindow.hideAggInterval"
(hideFlagChange)="onHideAggIntervalChanged()"
[min]="minHistoryAggInterval()" [max]="maxHistoryAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div *ngIf="timezone" class="mat-content mat-padding" fxLayout="row">
<section fxLayout="column" fxLayoutAlign="start center" [fxShow]="isEdit">
<label class="tb-small hide-label" translate>timewindow.hide</label>
<mat-checkbox [ngModelOptions]="{standalone: true}" [(ngModel)]="timewindow.hideTimezone"
(ngModelChange)="onHideTimezoneChanged()"></mat-checkbox>
</section>
<tb-timezone-select fxFlex [fxShow]="isEdit || !timewindow.hideTimezone"
localBrowserTimezonePlaceholderOnEmpty="true"
formControlName="timezone">
</tb-timezone-select>
</div>
</fieldset>
</ng-template>
</form>
<div fxLayout="row" class="tb-panel-actions" fxLayoutAlign="end center">
<button type="button"
mat-button
[disabled]="(isLoading$ | async)"
(click)="cancel()">
{{ 'action.cancel' | translate }}
</button>
<button type="button"
mat-raised-button
color="primary"
(click)="update()"
[disabled]="(isLoading$ | async) || timewindowForm.invalid || !timewindowForm.dirty">
{{ 'action.update' | translate }}
</button>
</div>

16
ui-ngx/src/app/shared/components/time/timewindow-panel.component.scss

@ -16,16 +16,14 @@
@import "../../../../scss/constants";
:host {
width: 100%;
height: 100%;
form,
fieldset {
height: 100%;
}
display: flex;
flex-direction: column;
max-height: 100%;
max-width: 100%;
background-color: #fff;
.mat-content {
overflow: hidden;
background-color: #fff;
}
.mat-padding {
@ -70,7 +68,6 @@
:host ::ng-deep {
.mat-mdc-radio-button {
display: block;
margin-bottom: 16px;
.mdc-form-field {
align-items: start;
> label {
@ -78,4 +75,7 @@
}
}
}
.mat-mdc-tab-group:not(.tb-headless) {
height: 100%;
}
}

134
ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts

@ -25,14 +25,13 @@ import {
Timewindow,
TimewindowType
} from '@shared/models/time/time.models';
import { OverlayRef } from '@angular/cdk/overlay';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { TimeService } from '@core/services/time.service';
export const TIMEWINDOW_PANEL_DATA = new InjectionToken<any>('TimewindowPanelData');
import { isDefined } from '@core/utils';
import { OverlayRef } from '@angular/cdk/overlay';
export interface TimewindowPanelData {
historyOnly: boolean;
@ -43,6 +42,8 @@ export interface TimewindowPanelData {
isEdit: boolean;
}
export const TIMEWINDOW_PANEL_DATA = new InjectionToken<any>('TimewindowPanelData');
@Component({
selector: 'tb-timewindow-panel',
templateUrl: './timewindow-panel.component.html',
@ -62,8 +63,6 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
timewindow: Timewindow;
result: Timewindow;
timewindowForm: UntypedFormGroup;
historyTypes = HistoryWindowType;
@ -78,6 +77,8 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
aggregationTypesTranslations = aggregationTranslations;
result: Timewindow;
constructor(@Inject(TIMEWINDOW_PANEL_DATA) public data: TimewindowPanelData,
public overlayRef: OverlayRef,
protected store: Store<AppState>,
@ -101,77 +102,60 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit {
const hideAggInterval = this.timewindow.hideAggInterval || false;
const hideTimezone = this.timewindow.hideTimezone || false;
const realtime = this.timewindow.realtime;
const history = this.timewindow.history;
const aggregation = this.timewindow.aggregation;
this.timewindowForm = this.fb.group({
realtime: this.fb.group(
{
realtimeType: this.fb.control({
value: this.timewindow.realtime && typeof this.timewindow.realtime.realtimeType !== 'undefined'
? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL,
disabled: hideInterval
}),
timewindowMs: this.fb.control({
value: this.timewindow.realtime && typeof this.timewindow.realtime.timewindowMs !== 'undefined'
? this.timewindow.realtime.timewindowMs : null,
disabled: hideInterval || hideLastInterval
}),
interval: [
this.timewindow.realtime && typeof this.timewindow.realtime.interval !== 'undefined'
? this.timewindow.realtime.interval : null
],
quickInterval: this.fb.control({
value: this.timewindow.realtime && typeof this.timewindow.realtime.quickInterval !== 'undefined'
? this.timewindow.realtime.quickInterval : null,
disabled: hideInterval || hideQuickInterval
})
}
),
history: this.fb.group(
{
historyType: this.fb.control({
value: this.timewindow.history && typeof this.timewindow.history.historyType !== 'undefined'
? this.timewindow.history.historyType : HistoryWindowType.LAST_INTERVAL,
disabled: hideInterval
}),
timewindowMs: this.fb.control({
value: this.timewindow.history && typeof this.timewindow.history.timewindowMs !== 'undefined'
? this.timewindow.history.timewindowMs : null,
disabled: hideInterval
}),
interval: [
this.timewindow.history && typeof this.timewindow.history.interval !== 'undefined'
? this.timewindow.history.interval : null
],
fixedTimewindow: this.fb.control({
value: this.timewindow.history && typeof this.timewindow.history.fixedTimewindow !== 'undefined'
? this.timewindow.history.fixedTimewindow : null,
disabled: hideInterval
}),
quickInterval: this.fb.control({
value: this.timewindow.history && typeof this.timewindow.history.quickInterval !== 'undefined'
? this.timewindow.history.quickInterval : null,
disabled: hideInterval
})
}
),
aggregation: this.fb.group(
{
type: this.fb.control({
value: this.timewindow.aggregation && typeof this.timewindow.aggregation.type !== 'undefined'
? this.timewindow.aggregation.type : null,
disabled: hideAggregation
}),
limit: this.fb.control({
value: this.timewindow.aggregation && typeof this.timewindow.aggregation.limit !== 'undefined'
? this.checkLimit(this.timewindow.aggregation.limit) : null,
disabled: hideAggInterval
}, [])
}
),
timezone: this.fb.control({
value: this.timewindow.timezone !== 'undefined'
? this.timewindow.timezone : null,
disabled: hideTimezone
})
realtime: this.fb.group({
realtimeType: [{
value: isDefined(realtime?.realtimeType) ? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL,
disabled: hideInterval
}],
timewindowMs: [{
value: isDefined(realtime?.timewindowMs) ? this.timewindow.realtime.timewindowMs : null,
disabled: hideInterval || hideLastInterval
}],
interval: [isDefined(realtime?.interval) ? this.timewindow.realtime.interval : null],
quickInterval: [{
value: isDefined(realtime?.quickInterval) ? this.timewindow.realtime.quickInterval : null,
disabled: hideInterval || hideQuickInterval
}]
}),
history: this.fb.group({
historyType: [{
value: isDefined(history?.historyType) ? this.timewindow.history.historyType : HistoryWindowType.LAST_INTERVAL,
disabled: hideInterval
}],
timewindowMs: [{
value: isDefined(history?.timewindowMs) ? this.timewindow.history.timewindowMs : null,
disabled: hideInterval
}],
interval: [ isDefined(history?.interval) ? this.timewindow.history.interval : null
],
fixedTimewindow: [{
value: isDefined(history?.fixedTimewindow) ? this.timewindow.history.fixedTimewindow : null,
disabled: hideInterval
}],
quickInterval: [{
value: isDefined(history?.quickInterval) ? this.timewindow.history.quickInterval : null,
disabled: hideInterval
}]
}),
aggregation: this.fb.group({
type: [{
value: isDefined(aggregation?.type) ? this.timewindow.aggregation.type : null,
disabled: hideAggregation
}],
limit: [{
value: isDefined(aggregation?.limit) ? this.checkLimit(this.timewindow.aggregation.limit) : null,
disabled: hideAggInterval
}, []]
}),
timezone: [{
value: isDefined(this.timewindow.timezone) ? this.timewindow.timezone : null,
disabled: hideTimezone
}]
});
this.updateValidators();
this.timewindowForm.get('aggregation.type').valueChanges.subscribe(() => {

18
ui-ngx/src/app/shared/components/time/timewindow.component.html

@ -15,30 +15,34 @@
limitations under the License.
-->
<button *ngIf="asButton" cdkOverlayOrigin #timewindowPanelOrigin="cdkOverlayOrigin" [disabled]="timewindowDisabled"
<button *ngIf="asButton"
[disabled]="timewindowDisabled"
type="button"
mat-raised-button color="primary" (click)="openEditMode()">
mat-raised-button color="primary"
(click)="toggleTimewindow($event)">
<mat-icon class="material-icons">query_builder</mat-icon>
<span>{{innerValue?.displayValue}}</span>
</button>
<section *ngIf="!asButton" cdkOverlayOrigin #timewindowPanelOrigin="cdkOverlayOrigin"
class="tb-timewindow" fxLayout="row" fxLayoutAlign="start center">
<section *ngIf="!asButton"
class="tb-timewindow"
fxLayout="row"
fxLayoutAlign="start center">
<button *ngIf="direction === 'left'" [disabled]="timewindowDisabled" mat-icon-button class="tb-mat-32"
type="button"
(click)="openEditMode()"
(click)="toggleTimewindow($event)"
matTooltip="{{ 'timewindow.edit' | translate }}"
[matTooltipPosition]="tooltipPosition">
<mat-icon class="material-icons">query_builder</mat-icon>
</button>
<span [fxHide]="hideLabel()"
(click)="openEditMode()"
(click)="toggleTimewindow($event)"
matTooltip="{{ 'timewindow.edit' | translate }}"
[matTooltipPosition]="tooltipPosition">
{{innerValue?.displayValue}} <span [fxShow]="innerValue?.displayTimezoneAbbr !== ''">| <span class="timezone-abbr">{{innerValue.displayTimezoneAbbr}}</span></span>
</span>
<button *ngIf="direction === 'right'" [disabled]="timewindowDisabled" mat-icon-button class="tb-mat-32"
type="button"
(click)="openEditMode()"
(click)="toggleTimewindow($event)"
matTooltip="{{ 'timewindow.edit' | translate }}"
[matTooltipPosition]="tooltipPosition">
<mat-icon class="material-icons">query_builder</mat-icon>

133
ui-ngx/src/app/shared/components/time/timewindow.component.ts

@ -17,14 +17,13 @@
import {
ChangeDetectorRef,
Component,
ElementRef,
forwardRef,
Inject,
Injector,
Input,
OnDestroy,
OnInit,
StaticProvider,
ViewChild,
ViewContainerRef
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@ -40,21 +39,16 @@ import {
Timewindow,
TimewindowType
} from '@shared/models/time/time.models';
import { DatePipe, DOCUMENT } from '@angular/common';
import { CdkOverlayOrigin, ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import {
TIMEWINDOW_PANEL_DATA,
TimewindowPanelComponent,
TimewindowPanelData
} from '@shared/components/time/timewindow-panel.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { DatePipe } from '@angular/common';
import { TIMEWINDOW_PANEL_DATA, TimewindowPanelComponent } from '@shared/components/time/timewindow-panel.component';
import { MediaBreakpoints } from '@shared/models/constants';
import { BreakpointObserver } from '@angular/cdk/layout';
import { WINDOW } from '@core/services/window.service';
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 { ComponentPortal } from '@angular/cdk/portal';
// @dynamic
@Component({
@ -174,24 +168,21 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
@Input() disabled: boolean;
@ViewChild('timewindowPanelOrigin') timewindowPanelOrigin: CdkOverlayOrigin;
innerValue: Timewindow;
timewindowDisabled: boolean;
private propagateChange = (_: any) => {};
constructor(private translate: TranslateService,
constructor(private overlay: Overlay,
private translate: TranslateService,
private timeService: TimeService,
private millisecondsToTimeStringPipe: MillisecondsToTimeStringPipe,
private datePipe: DatePipe,
private overlay: Overlay,
private cd: ChangeDetectorRef,
private nativeElement: ElementRef,
public viewContainerRef: ViewContainerRef,
public breakpointObserver: BreakpointObserver,
@Inject(DOCUMENT) private document: Document,
@Inject(WINDOW) private window: Window) {
public breakpointObserver: BreakpointObserver) {
}
ngOnInit(): void {
@ -200,82 +191,51 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
ngOnDestroy(): void {
}
openEditMode() {
if (this.timewindowDisabled) {
return;
toggleTimewindow($event: Event) {
if ($event) {
$event.stopPropagation();
}
const isGtXs = this.breakpointObserver.isMatched(MediaBreakpoints['gt-xs']);
const position = this.overlay.position();
const config = new OverlayConfig({
panelClass: 'tb-timewindow-panel',
backdropClass: 'cdk-overlay-transparent-backdrop',
hasBackdrop: isGtXs,
hasBackdrop: true,
maxHeight: '80vh',
height: 'min-content'
});
if (isGtXs) {
config.minWidth = '417px';
config.maxHeight = '550px';
const panelHeight = 375;
const panelWidth = 417;
const el = this.timewindowPanelOrigin.elementRef.nativeElement;
const offset = el.getBoundingClientRect();
const scrollTop = this.window.pageYOffset || this.document.documentElement.scrollTop || this.document.body.scrollTop || 0;
const scrollLeft = this.window.pageXOffset || this.document.documentElement.scrollLeft || this.document.body.scrollLeft || 0;
const bottomY = offset.bottom - scrollTop;
const leftX = offset.left - scrollLeft;
let originX;
let originY;
let overlayX;
let overlayY;
const wHeight = this.document.documentElement.clientHeight;
const wWidth = this.document.documentElement.clientWidth;
if (bottomY + panelHeight > wHeight) {
originY = 'top';
overlayY = 'bottom';
} else {
originY = 'bottom';
overlayY = 'top';
}
if (leftX + panelWidth > wWidth) {
originX = 'end';
overlayX = 'end';
} else {
originX = 'start';
overlayX = 'start';
}
const connectedPosition: ConnectedPosition = {
originX,
originY,
overlayX,
overlayY
};
config.positionStrategy = position.flexibleConnectedTo(this.timewindowPanelOrigin.elementRef)
.withPositions([connectedPosition]);
} else {
config.minWidth = '100%';
config.minHeight = '100%';
config.positionStrategy = position.global().top('0%').left('0%')
.right('0%').bottom('0%');
}
config.hasBackdrop = true;
const connectedPosition: ConnectedPosition = {
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top'
};
config.positionStrategy = this.overlay.position().flexibleConnectedTo(this.nativeElement)
.withPositions([connectedPosition]);
const overlayRef = this.overlay.create(config);
overlayRef.backdropClick().subscribe(() => {
overlayRef.dispose();
});
const injector = this._createTimewindowPanelInjector(
overlayRef,
const providers: StaticProvider[] = [
{
provide: TIMEWINDOW_PANEL_DATA,
useValue: {
timewindow: deepClone(this.innerValue),
historyOnly: this.historyOnly,
quickIntervalOnly: this.quickIntervalOnly,
aggregation: this.aggregation,
timezone: this.timezone,
isEdit: this.isEdit
}
},
{
timewindow: deepClone(this.innerValue),
historyOnly: this.historyOnly,
quickIntervalOnly: this.quickIntervalOnly,
aggregation: this.aggregation,
timezone: this.timezone,
isEdit: this.isEdit
provide: OverlayRef,
useValue: overlayRef
}
);
const componentRef = overlayRef.attach(new ComponentPortal(TimewindowPanelComponent, this.viewContainerRef, injector));
];
const injector = Injector.create({parent: this.viewContainerRef.injector, providers});
const componentRef = overlayRef.attach(new ComponentPortal(TimewindowPanelComponent,
this.viewContainerRef, injector));
componentRef.onDestroy(() => {
if (componentRef.instance.result) {
this.innerValue = componentRef.instance.result;
@ -284,14 +244,7 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
this.notifyChanged();
}
});
}
private _createTimewindowPanelInjector(overlayRef: OverlayRef, data: TimewindowPanelData): Injector {
const providers: StaticProvider[] = [
{provide: TIMEWINDOW_PANEL_DATA, useValue: data},
{provide: OverlayRef, useValue: overlayRef}
];
return Injector.create({parent: this.viewContainerRef.injector, providers});
this.cd.detectChanges();
}
private onHistoryOnlyChanged(): boolean {

Loading…
Cancel
Save