Commit 534db078ff12b8a0603f9a0d8ceb3877bd2da687

Authored by Igor Kulikov
1 parent 969c0363

Dashboard page fixes and improvements

... ... @@ -17,7 +17,7 @@
17 17 -->
18 18 <div fxLayout="column" class="mat-content mat-padding">
19 19 <div fxLayout="row" *ngFor="let alias of entityAliasesInfo | keyvalue">
20   - <mat-form-field>
  20 + <mat-form-field fxFlex>
21 21 <mat-label>{{alias.value.alias}}</mat-label>
22 22 <mat-select [(ngModel)]="alias.value.selectedId"
23 23 (ngModelChange)="currentAliasEntityChanged(alias.key, alias.value.selectedId)">
... ...
... ... @@ -22,6 +22,7 @@ export const ALIASES_ENTITY_SELECT_PANEL_DATA = new InjectionToken<any>('Aliases
22 22
23 23 export interface AliasesEntitySelectPanelData {
24 24 aliasController: IAliasController;
  25 + entityAliasesInfo: {[aliasId: string]: AliasInfo};
25 26 }
26 27
27 28 @Component({
... ... @@ -31,18 +32,10 @@ export interface AliasesEntitySelectPanelData {
31 32 })
32 33 export class AliasesEntitySelectPanelComponent {
33 34
34   - entityAliasesInfo: {[aliasId: string]: AliasInfo} = {};
  35 + entityAliasesInfo: {[aliasId: string]: AliasInfo};
35 36
36 37 constructor(@Inject(ALIASES_ENTITY_SELECT_PANEL_DATA) public data: AliasesEntitySelectPanelData) {
37   - const allEntityAliases = this.data.aliasController.getEntityAliases();
38   - for (const aliasId of Object.keys(allEntityAliases)) {
39   - const aliasInfo = this.data.aliasController.getInstantAliasInfo(aliasId);
40   - if (aliasInfo && !aliasInfo.resolveMultiple && aliasInfo.currentEntity
41   - && aliasInfo.resolvedEntities.length > 1) {
42   - this.entityAliasesInfo[aliasId] = deepClone(aliasInfo);
43   - this.entityAliasesInfo[aliasId].selectedId = aliasInfo.currentEntity.id;
44   - }
45   - }
  38 + this.entityAliasesInfo = this.data.entityAliasesInfo;
46 39 }
47 40
48 41 public currentAliasEntityChanged(aliasId: string, selectedId: string) {
... ...
... ... @@ -19,13 +19,13 @@
19 19 <button mat-icon-button
20 20 cdkOverlayOrigin #aliasEntitySelectPanelOrigin="cdkOverlayOrigin"
21 21 (click)="openEditMode()"
22   - matTooltip="{{ 'entity.select-entities' | translate }}"
  22 + matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
23 23 [matTooltipPosition]="tooltipPosition">
24 24 <mat-icon class="material-icons">devices_other</mat-icon>
25 25 </button>
26 26 <span fxHide.lt-lg
27 27 (click)="openEditMode()"
28   - matTooltip="{{ 'entity.select-entities' | translate }}"
  28 + matTooltip="{{ hasSelectableAliasEntities ? ('entity.select-entities' | translate) : '' }}"
29 29 [matTooltipPosition]="tooltipPosition">
30 30 {{displayValue}}
31 31 </span>
... ...
... ... @@ -14,23 +14,21 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import { Component, Inject, Input, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
  17 +import { Component, Input, OnDestroy, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
18 18 import { TooltipPosition } from '@angular/material/tooltip';
19   -import { IAliasController } from '@core/api/widget-api.models';
  19 +import { AliasInfo, IAliasController } from '@core/api/widget-api.models';
20 20 import { CdkOverlayOrigin, ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
21 21 import { TranslateService } from '@ngx-translate/core';
22 22 import { Subscription } from 'rxjs';
23 23 import { BreakpointObserver } from '@angular/cdk/layout';
24   -import { DOCUMENT } from '@angular/common';
25   -import { WINDOW } from '@core/services/window.service';
26 24 import { ComponentPortal, PortalInjector } from '@angular/cdk/portal';
27 25 import {
28 26 ALIASES_ENTITY_SELECT_PANEL_DATA,
29 27 AliasesEntitySelectPanelComponent,
30 28 AliasesEntitySelectPanelData
31 29 } from './aliases-entity-select-panel.component';
  30 +import { deepClone } from '@core/utils';
32 31
33   -// @dynamic
34 32 @Component({
35 33 selector: 'tb-aliases-entity-select',
36 34 templateUrl: './aliases-entity-select.component.html',
... ... @@ -38,8 +36,17 @@ import {
38 36 })
39 37 export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
40 38
  39 + aliasControllerValue: IAliasController;
  40 +
41 41 @Input()
42   - aliasController: IAliasController;
  42 + set aliasController(aliasController: IAliasController) {
  43 + this.aliasControllerValue = aliasController;
  44 + this.setupAliasController(this.aliasControllerValue);
  45 + }
  46 +
  47 + get aliasController(): IAliasController {
  48 + return this.aliasControllerValue;
  49 + }
43 50
44 51 @Input()
45 52 tooltipPosition: TooltipPosition = 'above';
... ... @@ -49,32 +56,43 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
49 56 @ViewChild('aliasEntitySelectPanelOrigin') aliasEntitySelectPanelOrigin: CdkOverlayOrigin;
50 57
51 58 displayValue: string;
  59 + entityAliasesInfo: {[aliasId: string]: AliasInfo} = {};
  60 + hasSelectableAliasEntities = false;
52 61
53 62 private rxSubscriptions = new Array<Subscription>();
54 63
55 64 constructor(private translate: TranslateService,
56 65 private overlay: Overlay,
57 66 private breakpointObserver: BreakpointObserver,
58   - private viewContainerRef: ViewContainerRef,
59   - @Inject(DOCUMENT) private document: Document,
60   - @Inject(WINDOW) private window: Window) {
  67 + private viewContainerRef: ViewContainerRef) {
  68 + }
  69 +
  70 + private setupAliasController(aliasController: IAliasController) {
  71 + this.rxSubscriptions.forEach((subscription) => {
  72 + subscription.unsubscribe();
  73 + });
  74 + this.rxSubscriptions.length = 0;
  75 + if (aliasController) {
  76 + this.rxSubscriptions.push(aliasController.entityAliasesChanged.subscribe(
  77 + () => {
  78 + setTimeout(() => {
  79 + this.updateDisplayValue();
  80 + this.updateEntityAliasesInfo();
  81 + }, 0);
  82 + }
  83 + ));
  84 + this.rxSubscriptions.push(aliasController.entityAliasResolved.subscribe(
  85 + () => {
  86 + setTimeout(() => {
  87 + this.updateDisplayValue();
  88 + this.updateEntityAliasesInfo();
  89 + }, 0);
  90 + }
  91 + ));
  92 + }
61 93 }
62 94
63 95 ngOnInit(): void {
64   - this.rxSubscriptions.push(this.aliasController.entityAliasesChanged.subscribe(
65   - () => {
66   - setTimeout(() => {
67   - this.updateDisplayValue();
68   - }, 0);
69   - }
70   - ));
71   - this.rxSubscriptions.push(this.aliasController.entityAliasResolved.subscribe(
72   - () => {
73   - setTimeout(() => {
74   - this.updateDisplayValue();
75   - }, 0);
76   - }
77   - ));
78 96 }
79 97
80 98 ngOnDestroy(): void {
... ... @@ -85,48 +103,20 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
85 103 }
86 104
87 105 openEditMode() {
88   - if (this.disabled) {
  106 + if (this.disabled || !this.hasSelectableAliasEntities) {
89 107 return;
90 108 }
91   - const panelHeight = this.breakpointObserver.isMatched('min-height: 350px') ? 250 : 150;
92   - const panelWidth = 300;
93 109 const position = this.overlay.position();
94 110 const config = new OverlayConfig({
95 111 panelClass: 'tb-aliases-entity-select-panel',
96 112 backdropClass: 'cdk-overlay-transparent-backdrop',
97 113 hasBackdrop: true,
98 114 });
99   - const el = this.aliasEntitySelectPanelOrigin.elementRef.nativeElement;
100   - const offset = el.getBoundingClientRect();
101   - const scrollTop = this.window.pageYOffset || this.document.documentElement.scrollTop || this.document.body.scrollTop || 0;
102   - const scrollLeft = this.window.pageXOffset || this.document.documentElement.scrollLeft || this.document.body.scrollLeft || 0;
103   - const bottomY = offset.bottom - scrollTop;
104   - const leftX = offset.left - scrollLeft;
105   - let originX;
106   - let originY;
107   - let overlayX;
108   - let overlayY;
109   - const wHeight = this.document.documentElement.clientHeight;
110   - const wWidth = this.document.documentElement.clientWidth;
111   - if (bottomY + panelHeight > wHeight) {
112   - originY = 'top';
113   - overlayY = 'bottom';
114   - } else {
115   - originY = 'bottom';
116   - overlayY = 'top';
117   - }
118   - if (leftX + panelWidth > wWidth) {
119   - originX = 'end';
120   - overlayX = 'end';
121   - } else {
122   - originX = 'start';
123   - overlayX = 'start';
124   - }
125 115 const connectedPosition: ConnectedPosition = {
126   - originX,
127   - originY,
128   - overlayX,
129   - overlayY
  116 + originX: 'start',
  117 + originY: 'bottom',
  118 + overlayX: 'start',
  119 + overlayY: 'top'
130 120 };
131 121 config.positionStrategy = position.flexibleConnectedTo(this.aliasEntitySelectPanelOrigin.elementRef)
132 122 .withPositions([connectedPosition]);
... ... @@ -138,7 +128,8 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
138 128 const injector = this._createAliasesEntitySelectPanelInjector(
139 129 overlayRef,
140 130 {
141   - aliasController: this.aliasController
  131 + aliasController: this.aliasController,
  132 + entityAliasesInfo: this.entityAliasesInfo
142 133 }
143 134 );
144 135 overlayRef.attach(new ComponentPortal(AliasesEntitySelectPanelComponent, this.viewContainerRef, injector));
... ... @@ -180,4 +171,19 @@ export class AliasesEntitySelectComponent implements OnInit, OnDestroy {
180 171 this.displayValue = displayValue;
181 172 }
182 173
  174 + private updateEntityAliasesInfo() {
  175 + const allEntityAliases = this.aliasController.getEntityAliases();
  176 + this.entityAliasesInfo = {};
  177 + this.hasSelectableAliasEntities = false;
  178 + for (const aliasId of Object.keys(allEntityAliases)) {
  179 + const aliasInfo = this.aliasController.getInstantAliasInfo(aliasId);
  180 + if (aliasInfo && !aliasInfo.resolveMultiple && aliasInfo.currentEntity
  181 + && aliasInfo.resolvedEntities.length > 1) {
  182 + this.entityAliasesInfo[aliasId] = deepClone(aliasInfo);
  183 + this.entityAliasesInfo[aliasId].selectedId = aliasInfo.currentEntity.id;
  184 + this.hasSelectableAliasEntities = true;
  185 + }
  186 + }
  187 + }
  188 +
183 189 }
... ...
... ... @@ -18,7 +18,7 @@
18 18 <div fxFlex fxLayout="column" class="tb-progress-cover" fxLayoutAlign="center center"
19 19 [ngStyle]="dashboardStyle"
20 20 [style.backgroundImage]="backgroundImage"
21   - [fxShow]="(((isLoading$ | async) && !this.ignoreLoading) || this.dashboardLoading) && !isEdit">
  21 + [fxShow]="(isLoading$ | async) && !ignoreLoading && !isEdit">
22 22 <mat-spinner color="warn" mode="indeterminate" diameter="100">
23 23 </mat-spinner>
24 24 </div>
... ...
... ... @@ -122,7 +122,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
122 122 dashboardClass: string;
123 123
124 124 @Input()
125   - ignoreLoading: boolean;
  125 + ignoreLoading = true;
126 126
127 127 @Input()
128 128 dashboardTimewindow: Timewindow;
... ... @@ -154,8 +154,6 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
154 154
155 155 widgetContextMenuEvent: MouseEvent;
156 156
157   - dashboardLoading = true;
158   -
159 157 dashboardWidgets = new DashboardWidgets(this,
160 158 this.differs.find([]).create<Widget>((index, item) => {
161 159 return item;
... ... @@ -282,7 +280,6 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
282 280 private updateWidgets() {
283 281 this.dashboardWidgets.setWidgets(this.widgets, this.widgetLayouts);
284 282 this.dashboardWidgets.doCheck();
285   - this.dashboardLoading = false;
286 283 }
287 284
288 285 private updateWidgetLayouts() {
... ...
... ... @@ -159,7 +159,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
159 159 widgets: null,
160 160 widgetLayouts: {},
161 161 gridSettings: {},
162   - ignoreLoading: false,
  162 + ignoreLoading: true,
163 163 ctrl: null,
164 164 dashboardCtrl: this
165 165 }
... ... @@ -171,7 +171,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
171 171 widgets: null,
172 172 widgetLayouts: {},
173 173 gridSettings: {},
174   - ignoreLoading: false,
  174 + ignoreLoading: true,
175 175 ctrl: null,
176 176 dashboardCtrl: this
177 177 }
... ...
... ... @@ -193,21 +193,25 @@ export class EntityStateControllerComponent extends StateControllerComponent imp
193 193
194 194 public getStateName(index: number): string {
195 195 let result = '';
196   - if (this.stateObject[index]) {
197   - let stateName = this.states[this.stateObject[index].id].name;
198   - stateName = this.utils.customTranslation(stateName, stateName);
199   - const params = this.stateObject[index].params;
200   - const targetParams = params && params.targetEntityParamName ? params[params.targetEntityParamName] : params;
201   - const entityName = targetParams && targetParams.entityName ? targetParams.entityName : '';
202   - const entityLabel = targetParams && targetParams.entityLabel ? targetParams.entityLabel : '';
203   - result = this.utils.insertVariable(stateName, 'entityName', entityName);
204   - result = this.utils.insertVariable(result, 'entityLabel', entityLabel);
205   - for (const prop of Object.keys(params)) {
206   - if (params[prop] && params[prop].entityName) {
207   - result = this.utils.insertVariable(result, prop + ':entityName', params[prop].entityName);
208   - }
209   - if (params[prop] && params[prop].entityLabel) {
210   - result = this.utils.insertVariable(result, prop + ':entityLabel', params[prop].entityLabel);
  196 + const state = this.stateObject[index];
  197 + if (state) {
  198 + const dashboardState = this.states[state.id];
  199 + if (dashboardState) {
  200 + let stateName = dashboardState.name;
  201 + stateName = this.utils.customTranslation(stateName, stateName);
  202 + const params = this.stateObject[index].params;
  203 + const targetParams = params && params.targetEntityParamName ? params[params.targetEntityParamName] : params;
  204 + const entityName = targetParams && targetParams.entityName ? targetParams.entityName : '';
  205 + const entityLabel = targetParams && targetParams.entityLabel ? targetParams.entityLabel : '';
  206 + result = this.utils.insertVariable(stateName, 'entityName', entityName);
  207 + result = this.utils.insertVariable(result, 'entityLabel', entityLabel);
  208 + for (const prop of Object.keys(params)) {
  209 + if (params[prop] && params[prop].entityName) {
  210 + result = this.utils.insertVariable(result, prop + ':entityName', params[prop].entityName);
  211 + }
  212 + if (params[prop] && params[prop].entityLabel) {
  213 + result = this.utils.insertVariable(result, prop + ':entityLabel', params[prop].entityLabel);
  214 + }
211 215 }
212 216 }
213 217 }
... ...