Commit 534db078ff12b8a0603f9a0d8ceb3877bd2da687
1 parent
969c0363
Dashboard page fixes and improvements
Showing
8 changed files
with
92 additions
and
92 deletions
... | ... | @@ -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 | } | ... | ... |