Dashboard page fixes and improvements

This commit is contained in:
Igor Kulikov 2020-04-29 11:33:42 +03:00
parent 969c03637d
commit 534db078ff
8 changed files with 92 additions and 92 deletions

View File

@ -17,7 +17,7 @@
-->
<div fxLayout="column" class="mat-content mat-padding">
<div fxLayout="row" *ngFor="let alias of entityAliasesInfo | keyvalue">
<mat-form-field>
<mat-form-field fxFlex>
<mat-label>{{alias.value.alias}}</mat-label>
<mat-select [(ngModel)]="alias.value.selectedId"
(ngModelChange)="currentAliasEntityChanged(alias.key, alias.value.selectedId)">

View File

@ -22,6 +22,7 @@ export const ALIASES_ENTITY_SELECT_PANEL_DATA = new InjectionToken<any>('Aliases
export interface AliasesEntitySelectPanelData {
aliasController: IAliasController;
entityAliasesInfo: {[aliasId: string]: AliasInfo};
}
@Component({
@ -31,18 +32,10 @@ export interface AliasesEntitySelectPanelData {
})
export class AliasesEntitySelectPanelComponent {
entityAliasesInfo: {[aliasId: string]: AliasInfo} = {};
entityAliasesInfo: {[aliasId: string]: AliasInfo};
constructor(@Inject(ALIASES_ENTITY_SELECT_PANEL_DATA) public data: AliasesEntitySelectPanelData) {
const allEntityAliases = this.data.aliasController.getEntityAliases();
for (const aliasId of Object.keys(allEntityAliases)) {
const aliasInfo = this.data.aliasController.getInstantAliasInfo(aliasId);
if (aliasInfo && !aliasInfo.resolveMultiple && aliasInfo.currentEntity
&& aliasInfo.resolvedEntities.length > 1) {
this.entityAliasesInfo[aliasId] = deepClone(aliasInfo);
this.entityAliasesInfo[aliasId].selectedId = aliasInfo.currentEntity.id;
}
}
this.entityAliasesInfo = this.data.entityAliasesInfo;
}
public currentAliasEntityChanged(aliasId: string, selectedId: string) {

View File

@ -19,13 +19,13 @@
<button mat-icon-button
cdkOverlayOrigin #aliasEntitySelectPanelOrigin="cdkOverlayOrigin"
(click)="openEditMode()"
matTooltip="{{ 'entity.select-entities' | translate }}"
matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
[matTooltipPosition]="tooltipPosition">
<mat-icon class="material-icons">devices_other</mat-icon>
</button>
<span fxHide.lt-lg
(click)="openEditMode()"
matTooltip="{{ 'entity.select-entities' | translate }}"
matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
[matTooltipPosition]="tooltipPosition">
{{displayValue}}
</span>

View File

@ -14,23 +14,21 @@
/// limitations under the License.
///
import { Component, Inject, Input, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { Component, Input, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { TooltipPosition } from '@angular/material/tooltip';
import { IAliasController } from '@core/api/widget-api.models';
import { AliasInfo, IAliasController } from '@core/api/widget-api.models';
import { CdkOverlayOrigin, ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs';
import { BreakpointObserver } from '@angular/cdk/layout';
import { DOCUMENT } from '@angular/common';
import { WINDOW } from '@core/services/window.service';
import { ComponentPortal, PortalInjector } from '@angular/cdk/portal';
import {
ALIASES_ENTITY_SELECT_PANEL_DATA,
AliasesEntitySelectPanelComponent,
AliasesEntitySelectPanelData
} from './aliases-entity-select-panel.component';
import { deepClone } from '@core/utils';
// @dynamic
@Component({
selector: 'tb-aliases-entity-select',
templateUrl: './aliases-entity-select.component.html',
@ -38,8 +36,17 @@ import {
})
export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
aliasControllerValue: IAliasController;
@Input()
aliasController: IAliasController;
set aliasController(aliasController: IAliasController) {
this.aliasControllerValue = aliasController;
this.setupAliasController(this.aliasControllerValue);
}
get aliasController(): IAliasController {
return this.aliasControllerValue;
}
@Input()
tooltipPosition: TooltipPosition = 'above';
@ -49,32 +56,43 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
@ViewChild('aliasEntitySelectPanelOrigin') aliasEntitySelectPanelOrigin: CdkOverlayOrigin;
displayValue: string;
entityAliasesInfo: {[aliasId: string]: AliasInfo} = {};
hasSelectableAliasEntities = false;
private rxSubscriptions = new Array<Subscription>();
constructor(private translate: TranslateService,
private overlay: Overlay,
private breakpointObserver: BreakpointObserver,
private viewContainerRef: ViewContainerRef,
@Inject(DOCUMENT) private document: Document,
@Inject(WINDOW) private window: Window) {
private viewContainerRef: ViewContainerRef) {
}
private setupAliasController(aliasController: IAliasController) {
this.rxSubscriptions.forEach((subscription) => {
subscription.unsubscribe();
});
this.rxSubscriptions.length = 0;
if (aliasController) {
this.rxSubscriptions.push(aliasController.entityAliasesChanged.subscribe(
() => {
setTimeout(() => {
this.updateDisplayValue();
this.updateEntityAliasesInfo();
}, 0);
}
));
this.rxSubscriptions.push(aliasController.entityAliasResolved.subscribe(
() => {
setTimeout(() => {
this.updateDisplayValue();
this.updateEntityAliasesInfo();
}, 0);
}
));
}
}
ngOnInit(): void {
this.rxSubscriptions.push(this.aliasController.entityAliasesChanged.subscribe(
() => {
setTimeout(() => {
this.updateDisplayValue();
}, 0);
}
));
this.rxSubscriptions.push(this.aliasController.entityAliasResolved.subscribe(
() => {
setTimeout(() => {
this.updateDisplayValue();
}, 0);
}
));
}
ngOnDestroy(): void {
@ -85,48 +103,20 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
}
openEditMode() {
if (this.disabled) {
if (this.disabled || !this.hasSelectableAliasEntities) {
return;
}
const panelHeight = this.breakpointObserver.isMatched('min-height: 350px') ? 250 : 150;
const panelWidth = 300;
const position = this.overlay.position();
const config = new OverlayConfig({
panelClass: 'tb-aliases-entity-select-panel',
backdropClass: 'cdk-overlay-transparent-backdrop',
hasBackdrop: true,
});
const el = this.aliasEntitySelectPanelOrigin.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
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top'
};
config.positionStrategy = position.flexibleConnectedTo(this.aliasEntitySelectPanelOrigin.elementRef)
.withPositions([connectedPosition]);
@ -138,7 +128,8 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
const injector = this._createAliasesEntitySelectPanelInjector(
overlayRef,
{
aliasController: this.aliasController
aliasController: this.aliasController,
entityAliasesInfo: this.entityAliasesInfo
}
);
overlayRef.attach(new ComponentPortal(AliasesEntitySelectPanelComponent, this.viewContainerRef, injector));
@ -180,4 +171,19 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
this.displayValue = displayValue;
}
private updateEntityAliasesInfo() {
const allEntityAliases = this.aliasController.getEntityAliases();
this.entityAliasesInfo = {};
this.hasSelectableAliasEntities = false;
for (const aliasId of Object.keys(allEntityAliases)) {
const aliasInfo = this.aliasController.getInstantAliasInfo(aliasId);
if (aliasInfo && !aliasInfo.resolveMultiple && aliasInfo.currentEntity
&& aliasInfo.resolvedEntities.length > 1) {
this.entityAliasesInfo[aliasId] = deepClone(aliasInfo);
this.entityAliasesInfo[aliasId].selectedId = aliasInfo.currentEntity.id;
this.hasSelectableAliasEntities = true;
}
}
}
}

View File

@ -18,7 +18,7 @@
<div fxFlex fxLayout="column" class="tb-progress-cover" fxLayoutAlign="center center"
[ngStyle]="dashboardStyle"
[style.backgroundImage]="backgroundImage"
[fxShow]="(((isLoading$ | async) && !this.ignoreLoading) || this.dashboardLoading) && !isEdit">
[fxShow]="(isLoading$ | async) && !ignoreLoading && !isEdit">
<mat-spinner color="warn" mode="indeterminate" diameter="100">
</mat-spinner>
</div>

View File

@ -122,7 +122,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
dashboardClass: string;
@Input()
ignoreLoading: boolean;
ignoreLoading = true;
@Input()
dashboardTimewindow: Timewindow;
@ -154,8 +154,6 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
widgetContextMenuEvent: MouseEvent;
dashboardLoading = true;
dashboardWidgets = new DashboardWidgets(this,
this.differs.find([]).create<Widget>((index, item) => {
return item;
@ -282,7 +280,6 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
private updateWidgets() {
this.dashboardWidgets.setWidgets(this.widgets, this.widgetLayouts);
this.dashboardWidgets.doCheck();
this.dashboardLoading = false;
}
private updateWidgetLayouts() {

View File

@ -159,7 +159,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
widgets: null,
widgetLayouts: {},
gridSettings: {},
ignoreLoading: false,
ignoreLoading: true,
ctrl: null,
dashboardCtrl: this
}
@ -171,7 +171,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
widgets: null,
widgetLayouts: {},
gridSettings: {},
ignoreLoading: false,
ignoreLoading: true,
ctrl: null,
dashboardCtrl: this
}

View File

@ -193,8 +193,11 @@ export class EntityStateControllerComponent extends StateControllerComponent imp
public getStateName(index: number): string {
let result = '';
if (this.stateObject[index]) {
let stateName = this.states[this.stateObject[index].id].name;
const state = this.stateObject[index];
if (state) {
const dashboardState = this.states[state.id];
if (dashboardState) {
let stateName = dashboardState.name;
stateName = this.utils.customTranslation(stateName, stateName);
const params = this.stateObject[index].params;
const targetParams = params && params.targetEntityParamName ? params[params.targetEntityParamName] : params;
@ -211,6 +214,7 @@ export class EntityStateControllerComponent extends StateControllerComponent imp
}
}
}
}
return result;
}