Browse Source

Merge remote-tracking branch 'upstream/master' into edge-3.3

pull/4918/head
Volodymyr Babak 5 years ago
parent
commit
0245ef20d7
  1. 3
      ui-ngx/src/app/modules/home/components/alias/aliases-entity-select.component.ts
  2. 30
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.html
  3. 5
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.scss
  4. 46
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.ts
  5. 4
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html
  6. 24
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts
  7. 16
      ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts
  8. 2
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html
  9. 8
      ui-ngx/src/app/modules/home/components/widget/widget.component.ts
  10. 8
      ui-ngx/src/app/modules/home/models/dashboard-component.models.ts
  11. 3
      ui-ngx/src/app/shared/components/time/timewindow.component.ts
  12. 1
      ui-ngx/src/assets/locale/locale.constant-en_US.json

3
ui-ngx/src/app/modules/home/components/alias/aliases-entity-select.component.ts

@ -15,6 +15,7 @@
///
import {
ChangeDetectorRef,
Component,
Injector,
Input,
@ -73,6 +74,7 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
constructor(private translate: TranslateService,
private overlay: Overlay,
private cd: ChangeDetectorRef,
private breakpointObserver: BreakpointObserver,
private viewContainerRef: ViewContainerRef) {
}
@ -179,6 +181,7 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
displayValue = this.translate.instant('entity.entities');
}
this.displayValue = displayValue;
this.cd.detectChanges();
}
private updateEntityAliasesInfo() {

30
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.html

@ -28,10 +28,32 @@
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar>
<div mat-dialog-content style="position: relative;">
<fieldset [disabled]="(isLoading$ | async) || (takingScreenshot$ | async)" fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="16px">
<div class="tb-image-preview-container">
<div *ngIf="!safeImageUrl; else elseBlock">{{ 'dashboard.no-image' | translate }}</div>
<ng-template #elseBlock><img class="tb-image-preview" [src]="safeImageUrl" /></ng-template>
<fieldset [disabled]="(isLoading$ | async) || (takingScreenshot$ | async)" fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="8px">
<div [formGroup]="dashboardRectFormGroup" fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="center center">
<mat-form-field class="rect-field">
<mat-label>Top %</mat-label>
<input matInput formControlName="top" type="number" step="1" min="0" max="100">
</mat-form-field>
<div fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="center center">
<mat-form-field class="rect-field">
<mat-label>Left %</mat-label>
<input matInput formControlName="left" type="number" step="1" min="0" max="100">
</mat-form-field>
<div class="tb-image-preview-container">
<div *ngIf="!safeImageUrl; else elseBlock">{{ 'dashboard.no-image' | translate }}</div>
<ng-template #elseBlock><img class="tb-image-preview" [src]="safeImageUrl" /></ng-template>
</div>
<mat-form-field class="rect-field">
<mat-label>Right %</mat-label>
<input matInput formControlName="right" type="number" step="1" min="0" max="100">
</mat-form-field>
</div>
<mat-form-field class="rect-field">
<mat-label>Bottom %</mat-label>
<input matInput formControlName="bottom" type="number" step="1" min="0" max="100">
</mat-form-field>
</div>
<div [formGroup]="dashboardRectFormGroup" fxFlex fxLayout="row" fxLayoutGap="8px">
</div>
<button mat-raised-button color="accent"
type="button"

5
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.scss

@ -17,6 +17,11 @@
$previewSize: 300px !default;
:host {
mat-form-field.rect-field {
max-width: 60px;
}
.tb-image-preview {
width: auto;
max-width: $previewSize - 2;

46
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-image-dialog.component.ts

@ -18,7 +18,7 @@ import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { DashboardId } from '@shared/models/id/dashboard-id';
@ -27,6 +27,7 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import html2canvas from 'html2canvas';
import { map, share } from 'rxjs/operators';
import { BehaviorSubject, from } from 'rxjs';
import { isNumber } from '@core/utils';
export interface DashboardImageDialogData {
dashboardId: DashboardId;
@ -55,6 +56,7 @@ export class DashboardImageDialogComponent extends DialogComponent<DashboardImag
safeImageUrl?: SafeUrl;
dashboardElement: HTMLElement;
dashboardRectFormGroup: FormGroup;
dashboardImageFormGroup: FormGroup;
constructor(protected store: Store<AppState>,
@ -69,6 +71,14 @@ export class DashboardImageDialogComponent extends DialogComponent<DashboardImag
this.dashboardId = this.data.dashboardId;
this.updateImage(this.data.currentImage);
this.dashboardElement = this.data.dashboardElement;
const clientRect = this.dashboardElement.getBoundingClientRect();
this.dashboardRectFormGroup = this.fb.group({
left: [0, [Validators.min(0), Validators.max(100)]],
top: [0, [Validators.min(0), Validators.max(100)]],
right: [100, [Validators.min(0), Validators.max(100)]],
bottom: [100, [Validators.min(0), Validators.max(100)]]
});
this.dashboardImageFormGroup = this.fb.group({
dashboardImage: [this.data.currentImage]
@ -81,13 +91,45 @@ export class DashboardImageDialogComponent extends DialogComponent<DashboardImag
);
}
private convertUserPercent(percent: any, defaultValue: number): number {
let result: number;
if (isNumber(percent)) {
result = Math.max(0, Math.min(100, percent)) / 100;
} else {
result = defaultValue;
}
return result;
}
takeScreenShot() {
this.takingScreenshotSubject.next(true);
const rect = this.dashboardElement.getBoundingClientRect();
const leftVal = this.convertUserPercent(this.dashboardRectFormGroup.get('left').value, 0);
const topVal = this.convertUserPercent(this.dashboardRectFormGroup.get('top').value, 0);
const rightVal = this.convertUserPercent(this.dashboardRectFormGroup.get('right').value, 100);
const bottomVal = this.convertUserPercent(this.dashboardRectFormGroup.get('bottom').value, 100);
const left = leftVal * rect.width;
const top = topVal * rect.height;
const right = rightVal * rect.width;
const bottom = bottomVal * rect.height;
const x = rect.left + left;
const y = rect.top + top;
let width = right - left;
let height = bottom - top;
width = Math.max(1, width);
height = Math.max(1, height);
from(html2canvas(this.dashboardElement, {
logging: false,
useCORS: true,
foreignObjectRendering: false,
scale: 512 / this.dashboardElement.clientWidth
scale: 512 / width,
x,
y,
width,
height
})).pipe(
map(canvas => canvas.toDataURL())).subscribe(
(image) => {

4
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html

@ -81,7 +81,7 @@
(click)="isFullscreen = !isFullscreen">
<mat-icon>{{ isFullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
</button>
<button [fxShow]="currentDashboardId && !isEdit && isTenantAdmin() && displayUpdateDashboardImage()" mat-icon-button
<button [fxShow]="currentDashboardId && !isEdit && !isMobileApp && isTenantAdmin() && displayUpdateDashboardImage()" mat-icon-button
matTooltip="{{'dashboard.update-image' | translate}}"
matTooltipPosition="below"
(click)="updateDashboardImage($event)">
@ -226,8 +226,6 @@
<mat-drawer class="tb-details-drawer"
[opened]="isEditingWidget || isAddingWidget"
(openedStart)="detailsDrawerOpenedStart()"
(opened)="detailsDrawerOpened()"
(closedStart)="detailsDrawerClosedStart()"
(closed)="detailsDrawerClosed()"
mode="over"
position="end">

24
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts

@ -15,6 +15,7 @@
///
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component, ElementRef,
Inject,
@ -134,7 +135,7 @@ import {
templateUrl: './dashboard-page.component.html',
styleUrls: ['./dashboard-page.component.scss'],
encapsulation: ViewEncapsulation.None,
// changeDetection: ChangeDetectionStrategy.OnPush
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardPageComponent extends PageComponent implements IDashboardController, OnInit, OnDestroy {
@ -425,9 +426,9 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
}
public runChangeDetection() {
/*setTimeout(() => {
this.ngZone.run(() => {
this.cd.detectChanges();
});*/
});
}
public openToolbar() {
@ -731,6 +732,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
const widget = importData.widget;
const layoutId = importData.layoutId;
this.layouts[layoutId].layoutCtx.widgets.addWidgetId(widget.id);
this.runChangeDetection();
}
}
);
@ -885,28 +887,17 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
} else if (this.isAddingWidget) {
this.isAddingWidgetClosed = false;
}
setTimeout(() => {
this.cd.detach();
}, 0);
}
detailsDrawerOpened() {
this.cd.reattach();
}
detailsDrawerClosedStart() {
this.cd.detach();
}
detailsDrawerClosed() {
this.isEditingWidgetClosed = true;
this.isAddingWidgetClosed = true;
this.cd.reattach();
}
private addWidgetToLayout(widget: Widget, layoutId: DashboardLayoutId) {
this.dashboardUtils.addWidgetToLayout(this.dashboard, this.dashboardCtx.state, layoutId, widget);
this.layouts[layoutId].layoutCtx.widgets.addWidgetId(widget.id);
this.runChangeDetection();
}
private selectTargetLayout(): Observable<DashboardLayoutId> {
@ -1060,6 +1051,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
pos, this.entityAliasesUpdated.bind(this), this.filtersUpdated.bind(this)).subscribe(
(widget) => {
layoutCtx.widgets.addWidgetId(widget.id);
this.runChangeDetection();
});
}
@ -1068,6 +1060,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
pos).subscribe(
(widget) => {
layoutCtx.widgets.addWidgetId(widget.id);
this.runChangeDetection();
});
}
@ -1086,6 +1079,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
if (res) {
if (layoutCtx.widgets.removeWidgetId(widget.id)) {
this.dashboardUtils.removeWidgetFromLayout(this.dashboard, this.dashboardCtx.state, layoutCtx.id, widget.id);
this.runChangeDetection();
}
}
});

16
ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts

@ -15,7 +15,7 @@
///
import {
AfterViewInit,
AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef,
Component,
DoCheck,
Input,
@ -59,7 +59,8 @@ import { UtilsService } from '@core/services/utils.service';
@Component({
selector: 'tb-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
styleUrls: ['./dashboard.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardComponent extends PageComponent implements IDashboardComponent, DoCheck, OnInit, OnDestroy, AfterViewInit, OnChanges {
@ -178,6 +179,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
private breakpointObserver: BreakpointObserver,
private differs: IterableDiffers,
private kvDiffers: KeyValueDiffers,
private cd: ChangeDetectorRef,
private ngZone: NgZone) {
super(store);
this.authUser = getCurrentAuthUser(store);
@ -249,6 +251,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
let updateLayoutOpts = false;
let updateEditingOpts = false;
let updateWidgets = false;
let updateDashboardTimewindow = false;
for (const propName of Object.keys(changes)) {
const change = changes[propName];
if (!change.firstChange && change.currentValue !== change.previousValue) {
@ -261,13 +264,16 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
} else if (['widgets', 'widgetLayouts'].includes(propName)) {
updateWidgets = true;
} else if (propName === 'dashboardTimewindow') {
this.dashboardTimewindowChangedSubject.next(this.dashboardTimewindow);
updateDashboardTimewindow = true;
}
}
}
if (updateWidgets) {
this.updateWidgets();
} else if (updateDashboardTimewindow) {
this.dashboardTimewindowChangedSubject.next(this.dashboardTimewindow);
}
if (updateMobileOpts) {
this.updateMobileOpts();
}
@ -528,6 +534,10 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
this.updateWidgetLayouts();
}
public detectChanges() {
this.cd.detectChanges();
}
private detectRowSize(isMobile: boolean, autofillHeight: boolean, parentHeight?: number): number | null {
let rowHeight = null;
if (!autofillHeight) {

2
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html

@ -51,7 +51,7 @@
</section>
</ng-template>
</mat-tab>
<mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}">
<mat-tab label="{{ 'device-profile.lwm2m.servers' | translate }}">
<ng-template matTabContent>
<section [formGroup]="lwm2mDeviceProfileFormGroup">
<div class="mat-padding">

8
ui-ngx/src/app/modules/home/components/widget/widget.component.ts

@ -468,10 +468,13 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
);
}
private detectChanges() {
private detectChanges(detectDashboardChanges = false) {
if (!this.destroyed) {
try {
this.cd.detectChanges();
if (detectDashboardChanges) {
this.widgetContext.dashboard.detectChanges();
}
} catch (e) {
// console.log(e);
}
@ -491,6 +494,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
}
if (!this.widgetContext.inited && this.isReady()) {
this.widgetContext.inited = true;
this.widgetContext.dashboard.detectChanges();
if (this.cafs.init) {
this.cafs.init();
this.cafs.init = null;
@ -878,7 +882,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
timeWindowUpdated: (subscription, timeWindowConfig) => {
this.ngZone.run(() => {
this.widget.config.timewindow = timeWindowConfig;
this.detectChanges();
this.detectChanges(true);
});
}
};

8
ui-ngx/src/app/modules/home/models/dashboard-component.models.ts

@ -79,6 +79,7 @@ export interface IDashboardComponent {
pauseChangeNotifications();
resumeChangeNotifications();
notifyLayoutUpdated();
detectChanges();
}
declare type DashboardWidgetUpdateOperation = 'add' | 'remove' | 'update';
@ -342,7 +343,7 @@ export class DashboardWidget implements GridsterItem, IDashboardWidget {
widget.id = guid();
}
this.widgetId = widget.id;
this.updateWidgetParams();
this.updateWidgetParams(false);
}
gridsterItemComponent$(): Observable<GridsterItemComponentInterface> {
@ -353,7 +354,7 @@ export class DashboardWidget implements GridsterItem, IDashboardWidget {
}
}
updateWidgetParams() {
updateWidgetParams(detectChanges = true) {
this.color = this.widget.config.color || 'rgba(0, 0, 0, 0.87)';
this.backgroundColor = this.widget.config.backgroundColor || '#fff';
this.padding = this.widget.config.padding || '8px';
@ -405,6 +406,9 @@ export class DashboardWidget implements GridsterItem, IDashboardWidget {
this.customHeaderActions = this.widgetContext.customHeaderActions ? this.widgetContext.customHeaderActions : [];
this.widgetActions = this.widgetContext.widgetActions ? this.widgetContext.widgetActions : [];
if (detectChanges) {
this.dashboard.detectChanges();
}
}
@enumerable(true)

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

@ -15,6 +15,7 @@
///
import {
ChangeDetectorRef,
Component,
forwardRef,
Inject,
@ -158,6 +159,7 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
private millisecondsToTimeStringPipe: MillisecondsToTimeStringPipe,
private datePipe: DatePipe,
private overlay: Overlay,
private cd: ChangeDetectorRef,
public viewContainerRef: ViewContainerRef,
public breakpointObserver: BreakpointObserver,
@Inject(DOCUMENT) private document: Document,
@ -313,6 +315,7 @@ export class TimewindowComponent implements OnInit, OnDestroy, ControlValueAcces
} else {
this.innerValue.displayTimezoneAbbr = '';
}
this.cd.detectChanges();
}
hideLabel() {

1
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1234,7 +1234,6 @@
"required": " value is required.",
"mode": "Security config mode",
"pattern_hex_dec": "{ count, plural, 0 {must be hex decimal format} other {must be # characters} }",
"bootstrap-tab": "Bootstrap",
"servers": "Servers",
"short-id": "Short ID",
"short-id-tip": "Short Server ID",

Loading…
Cancel
Save