Commit 72cfe8e411313e55fd5b88935aa4d0559494c04b
Committed by
GitHub
Merge pull request #5452 from ArtemDzhereleiko/imp/new-widget-settings
[3.3.2] UI: New widget settings layout
Showing
13 changed files
with
603 additions
and
675 deletions
... | ... | @@ -49,7 +49,6 @@ import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias- |
49 | 49 | import { DataKeysComponent } from '@home/components/widget/data-keys.component'; |
50 | 50 | import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; |
51 | 51 | import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; |
52 | -import { LegendConfigPanelComponent } from '@home/components/widget/legend-config-panel.component'; | |
53 | 52 | import { LegendConfigComponent } from '@home/components/widget/legend-config.component'; |
54 | 53 | import { ManageWidgetActionsComponent } from '@home/components/widget/action/manage-widget-actions.component'; |
55 | 54 | import { WidgetActionDialogComponent } from '@home/components/widget/action/widget-action-dialog.component'; |
... | ... | @@ -182,7 +181,6 @@ import { DeviceProfileCommonModule } from '@home/components/profile/device/commo |
182 | 181 | DataKeysComponent, |
183 | 182 | DataKeyConfigComponent, |
184 | 183 | DataKeyConfigDialogComponent, |
185 | - LegendConfigPanelComponent, | |
186 | 184 | LegendConfigComponent, |
187 | 185 | ManageWidgetActionsComponent, |
188 | 186 | WidgetActionDialogComponent, | ... | ... |
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2021 The Thingsboard Authors | |
4 | - | |
5 | - Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | - you may not use this file except in compliance with the License. | |
7 | - You may obtain a copy of the License at | |
8 | - | |
9 | - http://www.apache.org/licenses/LICENSE-2.0 | |
10 | - | |
11 | - Unless required by applicable law or agreed to in writing, software | |
12 | - distributed under the License is distributed on an "AS IS" BASIS, | |
13 | - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | - See the License for the specific language governing permissions and | |
15 | - limitations under the License. | |
16 | - | |
17 | ---> | |
18 | -<form [formGroup]="legendConfigForm"> | |
19 | - <fieldset [disabled]="(isLoading$ | async)"> | |
20 | - <div class="mat-content" style="height: 100%;"> | |
21 | - <div class="mat-padding"> | |
22 | - <section fxLayout="column"> | |
23 | - <mat-form-field> | |
24 | - <mat-label translate>legend.direction</mat-label> | |
25 | - <mat-select matInput formControlName="direction" style="min-width: 150px;"> | |
26 | - <mat-option *ngFor="let direction of legendDirections" [value]="direction"> | |
27 | - {{ legendDirectionTranslations.get(legendDirection[direction]) | translate }} | |
28 | - </mat-option> | |
29 | - </mat-select> | |
30 | - </mat-form-field> | |
31 | - <mat-form-field> | |
32 | - <mat-label translate>legend.position</mat-label> | |
33 | - <mat-select matInput formControlName="position" style="min-width: 150px;"> | |
34 | - <mat-option *ngFor="let pos of legendPositions" [value]="pos" | |
35 | - [disabled]="legendConfigForm.get('direction').value === legendDirection.row && | |
36 | - (pos === legendPosition.left || pos === legendPosition.right)"> | |
37 | - {{ legendPositionTranslations.get(legendPosition[pos]) | translate }} | |
38 | - </mat-option> | |
39 | - </mat-select> | |
40 | - </mat-form-field> | |
41 | - <mat-checkbox formControlName="sortDataKeys"> | |
42 | - {{ 'legend.sort-legend' | translate }} | |
43 | - </mat-checkbox> | |
44 | - <mat-checkbox formControlName="showMin"> | |
45 | - {{ 'legend.show-min' | translate }} | |
46 | - </mat-checkbox> | |
47 | - <mat-checkbox formControlName="showMax"> | |
48 | - {{ 'legend.show-max' | translate }} | |
49 | - </mat-checkbox> | |
50 | - <mat-checkbox formControlName="showAvg"> | |
51 | - {{ 'legend.show-avg' | translate }} | |
52 | - </mat-checkbox> | |
53 | - <mat-checkbox formControlName="showTotal"> | |
54 | - {{ 'legend.show-total' | translate }} | |
55 | - </mat-checkbox> | |
56 | - </section> | |
57 | - </div> | |
58 | - </div> | |
59 | - </fieldset> | |
60 | -</form> |
1 | -/** | |
2 | - * Copyright © 2016-2021 The Thingsboard Authors | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -:host { | |
17 | - width: 100%; | |
18 | - height: 100%; | |
19 | - form, | |
20 | - fieldset { | |
21 | - height: 100%; | |
22 | - } | |
23 | - | |
24 | - .mat-content { | |
25 | - overflow: hidden; | |
26 | - background-color: #fff; | |
27 | - } | |
28 | - | |
29 | - .mat-padding { | |
30 | - padding: 16px; | |
31 | - } | |
32 | -} |
1 | -/// | |
2 | -/// Copyright © 2016-2021 The Thingsboard Authors | |
3 | -/// | |
4 | -/// Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | -/// you may not use this file except in compliance with the License. | |
6 | -/// You may obtain a copy of the License at | |
7 | -/// | |
8 | -/// http://www.apache.org/licenses/LICENSE-2.0 | |
9 | -/// | |
10 | -/// Unless required by applicable law or agreed to in writing, software | |
11 | -/// distributed under the License is distributed on an "AS IS" BASIS, | |
12 | -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | -/// See the License for the specific language governing permissions and | |
14 | -/// limitations under the License. | |
15 | -/// | |
16 | - | |
17 | -import { Component, Inject, InjectionToken, OnInit, ViewContainerRef } from '@angular/core'; | |
18 | -import { OverlayRef } from '@angular/cdk/overlay'; | |
19 | -import { PageComponent } from '@shared/components/page.component'; | |
20 | -import { Store } from '@ngrx/store'; | |
21 | -import { AppState } from '@core/core.state'; | |
22 | -import { FormBuilder, FormGroup } from '@angular/forms'; | |
23 | -import { | |
24 | - LegendConfig, | |
25 | - LegendDirection, | |
26 | - legendDirectionTranslationMap, | |
27 | - LegendPosition, | |
28 | - legendPositionTranslationMap | |
29 | -} from '@shared/models/widget.models'; | |
30 | - | |
31 | -export const LEGEND_CONFIG_PANEL_DATA = new InjectionToken<any>('LegendConfigPanelData'); | |
32 | - | |
33 | -export interface LegendConfigPanelData { | |
34 | - legendConfig: LegendConfig; | |
35 | - legendConfigUpdated: (legendConfig: LegendConfig) => void; | |
36 | -} | |
37 | - | |
38 | -@Component({ | |
39 | - selector: 'tb-legend-config-panel', | |
40 | - templateUrl: './legend-config-panel.component.html', | |
41 | - styleUrls: ['./legend-config-panel.component.scss'] | |
42 | -}) | |
43 | -export class LegendConfigPanelComponent extends PageComponent implements OnInit { | |
44 | - | |
45 | - legendConfigForm: FormGroup; | |
46 | - | |
47 | - legendDirection = LegendDirection; | |
48 | - | |
49 | - legendDirections = Object.keys(LegendDirection); | |
50 | - | |
51 | - legendDirectionTranslations = legendDirectionTranslationMap; | |
52 | - | |
53 | - legendPosition = LegendPosition; | |
54 | - | |
55 | - legendPositions = Object.keys(LegendPosition); | |
56 | - | |
57 | - legendPositionTranslations = legendPositionTranslationMap; | |
58 | - | |
59 | - constructor(@Inject(LEGEND_CONFIG_PANEL_DATA) public data: LegendConfigPanelData, | |
60 | - public overlayRef: OverlayRef, | |
61 | - protected store: Store<AppState>, | |
62 | - public fb: FormBuilder, | |
63 | - public viewContainerRef: ViewContainerRef) { | |
64 | - super(store); | |
65 | - } | |
66 | - | |
67 | - ngOnInit(): void { | |
68 | - this.legendConfigForm = this.fb.group({ | |
69 | - direction: [this.data.legendConfig.direction, []], | |
70 | - position: [this.data.legendConfig.position, []], | |
71 | - sortDataKeys: [this.data.legendConfig.sortDataKeys, []], | |
72 | - showMin: [this.data.legendConfig.showMin, []], | |
73 | - showMax: [this.data.legendConfig.showMax, []], | |
74 | - showAvg: [this.data.legendConfig.showAvg, []], | |
75 | - showTotal: [this.data.legendConfig.showTotal, []] | |
76 | - }); | |
77 | - this.legendConfigForm.get('direction').valueChanges.subscribe((direction: LegendDirection) => { | |
78 | - this.onDirectionChanged(direction); | |
79 | - }); | |
80 | - this.onDirectionChanged(this.data.legendConfig.direction); | |
81 | - this.legendConfigForm.valueChanges.subscribe(() => { | |
82 | - this.update(); | |
83 | - }); | |
84 | - } | |
85 | - | |
86 | - private onDirectionChanged(direction: LegendDirection) { | |
87 | - if (direction === LegendDirection.row) { | |
88 | - let position: LegendPosition = this.legendConfigForm.get('position').value; | |
89 | - if (position !== LegendPosition.bottom && position !== LegendPosition.top) { | |
90 | - position = LegendPosition.bottom; | |
91 | - } | |
92 | - this.legendConfigForm.patchValue( | |
93 | - { | |
94 | - position | |
95 | - }, {emitEvent: false} | |
96 | - ); | |
97 | - } | |
98 | - } | |
99 | - | |
100 | - update() { | |
101 | - const newLegendConfig: LegendConfig = this.legendConfigForm.value; | |
102 | - this.data.legendConfigUpdated(newLegendConfig); | |
103 | - } | |
104 | - | |
105 | -} |
... | ... | @@ -15,9 +15,43 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | -<button cdkOverlayOrigin #legendConfigPanelOrigin="cdkOverlayOrigin" [disabled]="disabled" | |
19 | - type="button" | |
20 | - mat-button mat-raised-button color="primary" (click)="openEditMode()"> | |
21 | - <mat-icon class="material-icons">toc</mat-icon> | |
22 | - <span translate>legend.settings</span> | |
23 | -</button> | |
18 | +<form [formGroup]="legendConfigForm"> | |
19 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
20 | + fxLayoutGap="8px"> | |
21 | + <mat-form-field fxFlex> | |
22 | + <mat-label translate>legend.direction</mat-label> | |
23 | + <mat-select matInput formControlName="direction"> | |
24 | + <mat-option *ngFor="let direction of legendDirections" [value]="direction"> | |
25 | + {{ legendDirectionTranslations.get(legendDirection[direction]) | translate }} | |
26 | + </mat-option> | |
27 | + </mat-select> | |
28 | + </mat-form-field> | |
29 | + <mat-form-field fxFlex> | |
30 | + <mat-label translate>legend.position</mat-label> | |
31 | + <mat-select matInput formControlName="position"> | |
32 | + <mat-option *ngFor="let pos of legendPositions" [value]="pos" | |
33 | + [disabled]="legendConfigForm.get('direction').value === legendDirection.row && | |
34 | + (pos === legendPosition.left || pos === legendPosition.right)"> | |
35 | + {{ legendPositionTranslations.get(legendPosition[pos]) | translate }} | |
36 | + </mat-option> | |
37 | + </mat-select> | |
38 | + </mat-form-field> | |
39 | + </div> | |
40 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row wrap" fxLayoutAlign="space-between center" fxLayoutGap="8px"> | |
41 | + <mat-checkbox formControlName="showMin" fxFlex="48"> | |
42 | + {{ 'legend.show-min' | translate }} | |
43 | + </mat-checkbox> | |
44 | + <mat-checkbox formControlName="showMax" fxFlex="48"> | |
45 | + {{ 'legend.show-max' | translate }} | |
46 | + </mat-checkbox> | |
47 | + <mat-checkbox formControlName="showAvg" fxFlex="48"> | |
48 | + {{ 'legend.show-avg' | translate }} | |
49 | + </mat-checkbox> | |
50 | + <mat-checkbox formControlName="showTotal" fxFlex="48"> | |
51 | + {{ 'legend.show-total' | translate }} | |
52 | + </mat-checkbox> | |
53 | + <mat-checkbox formControlName="sortDataKeys" fxFlex="48"> | |
54 | + {{ 'legend.sort-legend' | translate }} | |
55 | + </mat-checkbox> | |
56 | + </div> | |
57 | +</form> | ... | ... |
... | ... | @@ -14,32 +14,17 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | +import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; | |
18 | +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; | |
19 | +import { isDefined } from '@core/utils'; | |
17 | 20 | import { |
18 | - Component, | |
19 | - forwardRef, | |
20 | - Inject, | |
21 | - Injector, | |
22 | - Input, | |
23 | - OnDestroy, | |
24 | - OnInit, | |
25 | - StaticProvider, | |
26 | - ViewChild, | |
27 | - ViewContainerRef | |
28 | -} from '@angular/core'; | |
29 | -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | |
30 | -import { DOCUMENT } from '@angular/common'; | |
31 | -import { CdkOverlayOrigin, ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; | |
32 | -import { ComponentPortal } from '@angular/cdk/portal'; | |
33 | -import { MediaBreakpoints } from '@shared/models/constants'; | |
34 | -import { BreakpointObserver } from '@angular/cdk/layout'; | |
35 | -import { WINDOW } from '@core/services/window.service'; | |
36 | -import { deepClone } from '@core/utils'; | |
37 | -import { LegendConfig } from '@shared/models/widget.models'; | |
38 | -import { | |
39 | - LEGEND_CONFIG_PANEL_DATA, | |
40 | - LegendConfigPanelComponent, | |
41 | - LegendConfigPanelData | |
42 | -} from '@home/components/widget/legend-config-panel.component'; | |
21 | + LegendConfig, | |
22 | + LegendDirection, | |
23 | + legendDirectionTranslationMap, | |
24 | + LegendPosition, | |
25 | + legendPositionTranslationMap | |
26 | +} from '@shared/models/widget.models'; | |
27 | +import { Subscription } from 'rxjs'; | |
43 | 28 | |
44 | 29 | // @dynamic |
45 | 30 | @Component({ |
... | ... | @@ -58,105 +43,60 @@ export class LegendConfigComponent implements OnInit, OnDestroy, ControlValueAcc |
58 | 43 | |
59 | 44 | @Input() disabled: boolean; |
60 | 45 | |
61 | - @ViewChild('legendConfigPanelOrigin') legendConfigPanelOrigin: CdkOverlayOrigin; | |
62 | - | |
63 | - innerValue: LegendConfig; | |
46 | + legendConfigForm: FormGroup; | |
47 | + legendDirection = LegendDirection; | |
48 | + legendDirections = Object.keys(LegendDirection); | |
49 | + legendDirectionTranslations = legendDirectionTranslationMap; | |
50 | + legendPosition = LegendPosition; | |
51 | + legendPositions = Object.keys(LegendPosition); | |
52 | + legendPositionTranslations = legendPositionTranslationMap; | |
64 | 53 | |
54 | + private legendSettingsFormChanges$: Subscription; | |
55 | + private legendSettingsFormDirectionChanges$: Subscription; | |
65 | 56 | private propagateChange = (_: any) => {}; |
66 | 57 | |
67 | - constructor(private overlay: Overlay, | |
68 | - public viewContainerRef: ViewContainerRef, | |
69 | - public breakpointObserver: BreakpointObserver, | |
70 | - @Inject(DOCUMENT) private document: Document, | |
71 | - @Inject(WINDOW) private window: Window) { | |
58 | + constructor(private fb: FormBuilder) { | |
72 | 59 | } |
73 | 60 | |
74 | 61 | ngOnInit(): void { |
62 | + this.legendConfigForm = this.fb.group({ | |
63 | + direction: [null, []], | |
64 | + position: [null, []], | |
65 | + sortDataKeys: [null, []], | |
66 | + showMin: [null, []], | |
67 | + showMax: [null, []], | |
68 | + showAvg: [null, []], | |
69 | + showTotal: [null, []] | |
70 | + }); | |
71 | + this.legendSettingsFormDirectionChanges$ = this.legendConfigForm.get('direction').valueChanges | |
72 | + .subscribe((direction: LegendDirection) => { | |
73 | + this.onDirectionChanged(direction); | |
74 | + }); | |
75 | + this.legendSettingsFormChanges$ = this.legendConfigForm.valueChanges.subscribe( | |
76 | + () => this.legendConfigUpdated() | |
77 | + ); | |
75 | 78 | } |
76 | 79 | |
77 | - ngOnDestroy(): void { | |
78 | - } | |
79 | - | |
80 | - openEditMode() { | |
81 | - if (this.disabled) { | |
82 | - return; | |
83 | - } | |
84 | - const isGtSm = this.breakpointObserver.isMatched(MediaBreakpoints['gt-sm']); | |
85 | - const position = this.overlay.position(); | |
86 | - const config = new OverlayConfig({ | |
87 | - panelClass: 'tb-legend-config-panel', | |
88 | - backdropClass: 'cdk-overlay-transparent-backdrop', | |
89 | - hasBackdrop: isGtSm, | |
90 | - }); | |
91 | - if (isGtSm) { | |
92 | - config.minWidth = '220px'; | |
93 | - config.maxHeight = '300px'; | |
94 | - const panelHeight = 220; | |
95 | - const panelWidth = 220; | |
96 | - const el = this.legendConfigPanelOrigin.elementRef.nativeElement; | |
97 | - const offset = el.getBoundingClientRect(); | |
98 | - const scrollTop = this.window.pageYOffset || this.document.documentElement.scrollTop || this.document.body.scrollTop || 0; | |
99 | - const scrollLeft = this.window.pageXOffset || this.document.documentElement.scrollLeft || this.document.body.scrollLeft || 0; | |
100 | - const bottomY = offset.bottom - scrollTop; | |
101 | - const leftX = offset.left - scrollLeft; | |
102 | - let originX; | |
103 | - let originY; | |
104 | - let overlayX; | |
105 | - let overlayY; | |
106 | - const wHeight = this.document.documentElement.clientHeight; | |
107 | - const wWidth = this.document.documentElement.clientWidth; | |
108 | - if (bottomY + panelHeight > wHeight) { | |
109 | - originY = 'top'; | |
110 | - overlayY = 'bottom'; | |
111 | - } else { | |
112 | - originY = 'bottom'; | |
113 | - overlayY = 'top'; | |
80 | + private onDirectionChanged(direction: LegendDirection) { | |
81 | + if (direction === LegendDirection.row) { | |
82 | + let position: LegendPosition = this.legendConfigForm.get('position').value; | |
83 | + if (position !== LegendPosition.bottom && position !== LegendPosition.top) { | |
84 | + position = LegendPosition.bottom; | |
114 | 85 | } |
115 | - if (leftX + panelWidth > wWidth) { | |
116 | - originX = 'end'; | |
117 | - overlayX = 'end'; | |
118 | - } else { | |
119 | - originX = 'start'; | |
120 | - overlayX = 'start'; | |
121 | - } | |
122 | - const connectedPosition: ConnectedPosition = { | |
123 | - originX, | |
124 | - originY, | |
125 | - overlayX, | |
126 | - overlayY | |
127 | - }; | |
128 | - config.positionStrategy = position.flexibleConnectedTo(this.legendConfigPanelOrigin.elementRef) | |
129 | - .withPositions([connectedPosition]); | |
130 | - } else { | |
131 | - config.minWidth = '100%'; | |
132 | - config.minHeight = '100%'; | |
133 | - config.positionStrategy = position.global().top('0%').left('0%') | |
134 | - .right('0%').bottom('0%'); | |
86 | + this.legendConfigForm.patchValue({position}, {emitEvent: false} | |
87 | + ); | |
135 | 88 | } |
136 | - | |
137 | - const overlayRef = this.overlay.create(config); | |
138 | - | |
139 | - overlayRef.backdropClick().subscribe(() => { | |
140 | - overlayRef.dispose(); | |
141 | - }); | |
142 | - | |
143 | - const injector = this._createLegendConfigPanelInjector( | |
144 | - overlayRef, | |
145 | - { | |
146 | - legendConfig: deepClone(this.innerValue), | |
147 | - legendConfigUpdated: this.legendConfigUpdated.bind(this) | |
148 | - } | |
149 | - ); | |
150 | - | |
151 | - overlayRef.attach(new ComponentPortal(LegendConfigPanelComponent, this.viewContainerRef, injector)); | |
152 | 89 | } |
153 | 90 | |
154 | - private _createLegendConfigPanelInjector(overlayRef: OverlayRef, data: LegendConfigPanelData): Injector { | |
155 | - const providers: StaticProvider[] = [ | |
156 | - {provide: LEGEND_CONFIG_PANEL_DATA, useValue: data}, | |
157 | - {provide: OverlayRef, useValue: overlayRef} | |
158 | - ]; | |
159 | - return Injector.create({parent: this.viewContainerRef.injector, providers}); | |
91 | + ngOnDestroy(): void { | |
92 | + if (this.legendSettingsFormDirectionChanges$) { | |
93 | + this.legendSettingsFormDirectionChanges$.unsubscribe(); | |
94 | + this.legendSettingsFormDirectionChanges$ = null; | |
95 | + } | |
96 | + if (this.legendSettingsFormChanges$) { | |
97 | + this.legendSettingsFormChanges$.unsubscribe(); | |
98 | + this.legendSettingsFormChanges$ = null; | |
99 | + } | |
160 | 100 | } |
161 | 101 | |
162 | 102 | registerOnChange(fn: any): void { |
... | ... | @@ -168,14 +108,29 @@ export class LegendConfigComponent implements OnInit, OnDestroy, ControlValueAcc |
168 | 108 | |
169 | 109 | setDisabledState(isDisabled: boolean): void { |
170 | 110 | this.disabled = isDisabled; |
111 | + if (this.disabled) { | |
112 | + this.legendConfigForm.disable({emitEvent: false}); | |
113 | + } else { | |
114 | + this.legendConfigForm.enable({emitEvent: false}); | |
115 | + } | |
171 | 116 | } |
172 | 117 | |
173 | - writeValue(obj: LegendConfig): void { | |
174 | - this.innerValue = obj; | |
118 | + writeValue(legendConfig: LegendConfig): void { | |
119 | + if (legendConfig) { | |
120 | + this.legendConfigForm.patchValue({ | |
121 | + direction: legendConfig.direction, | |
122 | + position: legendConfig.position, | |
123 | + sortDataKeys: isDefined(legendConfig.sortDataKeys) ? legendConfig.sortDataKeys : false, | |
124 | + showMin: isDefined(legendConfig.showMin) ? legendConfig.showMin : false, | |
125 | + showMax: isDefined(legendConfig.showMax) ? legendConfig.showMax : false, | |
126 | + showAvg: isDefined(legendConfig.showAvg) ? legendConfig.showAvg : false, | |
127 | + showTotal: isDefined(legendConfig.showTotal) ? legendConfig.showTotal : false | |
128 | + }, {emitEvent: false}); | |
129 | + } | |
130 | + this.onDirectionChanged(legendConfig.direction); | |
175 | 131 | } |
176 | 132 | |
177 | - private legendConfigUpdated(legendConfig: LegendConfig) { | |
178 | - this.innerValue = legendConfig; | |
179 | - this.propagateChange(this.innerValue); | |
133 | + private legendConfigUpdated() { | |
134 | + this.propagateChange(this.legendConfigForm.value); | |
180 | 135 | } |
181 | 136 | } | ... | ... |
... | ... | @@ -82,222 +82,246 @@ |
82 | 82 | </mat-checkbox> |
83 | 83 | </div> |
84 | 84 | </div> |
85 | - <mat-expansion-panel class="tb-datasources" *ngIf="widgetType !== widgetTypes.rpc && | |
86 | - widgetType !== widgetTypes.alarm && | |
87 | - modelValue?.isDataEnabled" [expanded]="true"> | |
88 | - <mat-expansion-panel-header> | |
89 | - <mat-panel-title fxLayout="column"> | |
90 | - <div class="tb-panel-title" translate>widget-config.datasources</div> | |
91 | - <div *ngIf="modelValue?.typeParameters && modelValue?.typeParameters.maxDatasources > -1" | |
92 | - class="tb-panel-hint">{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}</div> | |
93 | - </mat-panel-title> | |
94 | - </mat-expansion-panel-header> | |
95 | - <div *ngIf="datasourcesFormArray().length === 0; else datasourcesTemplate"> | |
96 | - <span translate fxLayoutAlign="center center" | |
97 | - class="tb-prompt">datasource.add-datasource-prompt</span> | |
98 | - </div> | |
99 | - <ng-template #datasourcesTemplate> | |
100 | - <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
101 | - <span style="width: 60px;"></span> | |
102 | - <div fxFlex fxLayout="row" fxLayoutAlign="start center" | |
103 | - style="padding: 0 0 0 10px; margin: 5px;"> | |
104 | - <span translate style="min-width: 120px;">widget-config.datasource-type</span> | |
105 | - <span fxHide fxShow.gt-sm translate fxFlex | |
106 | - style="padding-left: 10px;">widget-config.datasource-parameters</span> | |
107 | - <span style="min-width: 40px;"></span> | |
108 | - </div> | |
85 | + <mat-accordion multi> | |
86 | + <mat-expansion-panel class="tb-datasources" *ngIf="widgetType !== widgetTypes.rpc && | |
87 | + widgetType !== widgetTypes.alarm && | |
88 | + modelValue?.isDataEnabled" [expanded]="true"> | |
89 | + <mat-expansion-panel-header> | |
90 | + <mat-panel-title fxLayout="column"> | |
91 | + <div class="tb-panel-title" translate>widget-config.datasources</div> | |
92 | + <div *ngIf="modelValue?.typeParameters && modelValue?.typeParameters.maxDatasources > -1" | |
93 | + class="tb-panel-hint">{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}</div> | |
94 | + </mat-panel-title> | |
95 | + </mat-expansion-panel-header> | |
96 | + <div *ngIf="datasourcesFormArray().length === 0; else datasourcesTemplate"> | |
97 | + <span translate fxLayoutAlign="center center" | |
98 | + class="tb-prompt">datasource.add-datasource-prompt</span> | |
109 | 99 | </div> |
110 | - <div style="overflow: auto; padding-bottom: 15px;"> | |
111 | - <mat-list dndDropzone dndEffectAllowed="move" | |
112 | - (dndDrop)="onDatasourceDrop($event)" | |
113 | - [dndDisableIf]="disabled" formArrayName="datasources"> | |
114 | - <mat-list-item dndPlaceholderRef | |
115 | - class="dndPlaceholder"> | |
116 | - </mat-list-item> | |
117 | - <mat-list-item *ngFor="let datasourceControl of datasourcesFormArray().controls; let $index = index;" | |
118 | - [dndDraggable]="datasourceControl.value" | |
119 | - (dndMoved)="dndDatasourceMoved($index)" | |
120 | - [dndDisableIf]="disabled" | |
121 | - dndEffectAllowed="move"> | |
122 | - <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
123 | - <div style="width: 60px;"> | |
124 | - <button *ngIf="!disabled" mat-icon-button color="primary" | |
125 | - class="handle" | |
126 | - style="min-width: 40px; margin: 0" | |
127 | - dndHandle | |
128 | - matTooltip="{{ 'action.drag' | translate }}" | |
129 | - matTooltipPosition="above"> | |
130 | - <mat-icon>drag_handle</mat-icon> | |
131 | - </button> | |
132 | - <span>{{$index + 1}}.</span> | |
133 | - </div> | |
134 | - <div class="mat-elevation-z4" fxFlex | |
135 | - fxLayout="row" | |
136 | - fxLayoutAlign="start center" | |
137 | - style="padding: 0 0 0 10px; margin: 5px;"> | |
138 | - <section fxFlex | |
139 | - fxLayout="column" | |
140 | - fxLayoutAlign="center" | |
141 | - fxLayout.gt-sm="row" | |
142 | - fxLayoutAlign.gt-sm="start center"> | |
143 | - <mat-form-field class="tb-datasource-type"> | |
144 | - <mat-select [formControl]="datasourceControl.get('type')"> | |
145 | - <mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType"> | |
146 | - {{ datasourceTypesTranslations.get(datasourceType) | translate }} | |
147 | - </mat-option> | |
148 | - </mat-select> | |
149 | - </mat-form-field> | |
150 | - <section fxLayout="column" class="tb-datasource" [ngSwitch]="datasourceControl.get('type').value"> | |
151 | - <ng-template [ngSwitchCase]="datasourceType.function"> | |
152 | - <mat-form-field floatLabel="always" | |
153 | - class="tb-datasource-name" style="min-width: 200px;"> | |
154 | - <mat-label></mat-label> | |
155 | - <input matInput | |
156 | - placeholder="{{ 'datasource.label' | translate }}" | |
157 | - [formControl]="datasourceControl.get('name')"> | |
158 | - </mat-form-field> | |
159 | - </ng-template> | |
160 | - <ng-template [ngSwitchCase]="datasourceControl.get('type').value === datasourceType.entity || | |
161 | - datasourceControl.get('type').value === datasourceType.entityCount ? datasourceControl.get('type').value : ''"> | |
162 | - <tb-entity-alias-select | |
163 | - [showLabel]="true" | |
164 | - [tbRequired]="true" | |
165 | - [aliasController]="aliasController" | |
166 | - [formControl]="datasourceControl.get('entityAliasId')" | |
167 | - [callbacks]="widgetConfigCallbacks"> | |
168 | - </tb-entity-alias-select> | |
169 | - <tb-filter-select | |
170 | - [showLabel]="true" | |
171 | - [aliasController]="aliasController" | |
172 | - [formControl]="datasourceControl.get('filterId')" | |
173 | - [callbacks]="widgetConfigCallbacks"> | |
174 | - </tb-filter-select> | |
175 | - <mat-form-field *ngIf="datasourceControl.get('type').value === datasourceType.entityCount" | |
176 | - floatLabel="always" | |
177 | - class="tb-datasource-name no-border-top" style="min-width: 200px;"> | |
178 | - <mat-label></mat-label> | |
179 | - <input matInput | |
180 | - placeholder="{{ 'datasource.label' | translate }}" | |
181 | - [formControl]="datasourceControl.get('name')"> | |
182 | - </mat-form-field> | |
183 | - </ng-template> | |
100 | + <ng-template #datasourcesTemplate> | |
101 | + <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
102 | + <span style="width: 60px;"></span> | |
103 | + <div fxFlex fxLayout="row" fxLayoutAlign="start center" | |
104 | + style="padding: 0 0 0 10px; margin: 5px;"> | |
105 | + <span translate style="min-width: 120px;">widget-config.datasource-type</span> | |
106 | + <span fxHide fxShow.gt-sm translate fxFlex | |
107 | + style="padding-left: 10px;">widget-config.datasource-parameters</span> | |
108 | + <span style="min-width: 40px;"></span> | |
109 | + </div> | |
110 | + </div> | |
111 | + <div style="overflow: auto; padding-bottom: 15px;"> | |
112 | + <mat-list dndDropzone dndEffectAllowed="move" | |
113 | + (dndDrop)="onDatasourceDrop($event)" | |
114 | + [dndDisableIf]="disabled" formArrayName="datasources"> | |
115 | + <mat-list-item dndPlaceholderRef | |
116 | + class="dndPlaceholder"> | |
117 | + </mat-list-item> | |
118 | + <mat-list-item *ngFor="let datasourceControl of datasourcesFormArray().controls; let $index = index;" | |
119 | + [dndDraggable]="datasourceControl.value" | |
120 | + (dndMoved)="dndDatasourceMoved($index)" | |
121 | + [dndDisableIf]="disabled" | |
122 | + dndEffectAllowed="move"> | |
123 | + <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
124 | + <div style="width: 60px;"> | |
125 | + <button *ngIf="!disabled" mat-icon-button color="primary" | |
126 | + class="handle" | |
127 | + style="min-width: 40px; margin: 0" | |
128 | + dndHandle | |
129 | + matTooltip="{{ 'action.drag' | translate }}" | |
130 | + matTooltipPosition="above"> | |
131 | + <mat-icon>drag_handle</mat-icon> | |
132 | + </button> | |
133 | + <span>{{$index + 1}}.</span> | |
134 | + </div> | |
135 | + <div class="mat-elevation-z4" fxFlex | |
136 | + fxLayout="row" | |
137 | + fxLayoutAlign="start center" | |
138 | + style="padding: 0 0 0 10px; margin: 5px;"> | |
139 | + <section fxFlex | |
140 | + fxLayout="column" | |
141 | + fxLayoutAlign="center" | |
142 | + fxLayout.gt-sm="row" | |
143 | + fxLayoutAlign.gt-sm="start center"> | |
144 | + <mat-form-field class="tb-datasource-type"> | |
145 | + <mat-select [formControl]="datasourceControl.get('type')"> | |
146 | + <mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType"> | |
147 | + {{ datasourceTypesTranslations.get(datasourceType) | translate }} | |
148 | + </mat-option> | |
149 | + </mat-select> | |
150 | + </mat-form-field> | |
151 | + <section fxLayout="column" class="tb-datasource" [ngSwitch]="datasourceControl.get('type').value"> | |
152 | + <ng-template [ngSwitchCase]="datasourceType.function"> | |
153 | + <mat-form-field floatLabel="always" | |
154 | + class="tb-datasource-name" style="min-width: 200px;"> | |
155 | + <mat-label></mat-label> | |
156 | + <input matInput | |
157 | + placeholder="{{ 'datasource.label' | translate }}" | |
158 | + [formControl]="datasourceControl.get('name')"> | |
159 | + </mat-form-field> | |
160 | + </ng-template> | |
161 | + <ng-template [ngSwitchCase]="datasourceControl.get('type').value === datasourceType.entity || | |
162 | + datasourceControl.get('type').value === datasourceType.entityCount ? datasourceControl.get('type').value : ''"> | |
163 | + <tb-entity-alias-select | |
164 | + [showLabel]="true" | |
165 | + [tbRequired]="true" | |
166 | + [aliasController]="aliasController" | |
167 | + [formControl]="datasourceControl.get('entityAliasId')" | |
168 | + [callbacks]="widgetConfigCallbacks"> | |
169 | + </tb-entity-alias-select> | |
170 | + <tb-filter-select | |
171 | + [showLabel]="true" | |
172 | + [aliasController]="aliasController" | |
173 | + [formControl]="datasourceControl.get('filterId')" | |
174 | + [callbacks]="widgetConfigCallbacks"> | |
175 | + </tb-filter-select> | |
176 | + <mat-form-field *ngIf="datasourceControl.get('type').value === datasourceType.entityCount" | |
177 | + floatLabel="always" | |
178 | + class="tb-datasource-name no-border-top" style="min-width: 200px;"> | |
179 | + <mat-label></mat-label> | |
180 | + <input matInput | |
181 | + placeholder="{{ 'datasource.label' | translate }}" | |
182 | + [formControl]="datasourceControl.get('name')"> | |
183 | + </mat-form-field> | |
184 | + </ng-template> | |
185 | + </section> | |
186 | + <tb-data-keys class="tb-data-keys" fxFlex | |
187 | + [widgetType]="widgetType" | |
188 | + [datasourceType]="datasourceControl.get('type').value" | |
189 | + [maxDataKeys]="modelValue?.typeParameters?.maxDataKeys" | |
190 | + [optDataKeys]="modelValue?.typeParameters?.dataKeysOptional" | |
191 | + [aliasController]="aliasController" | |
192 | + [datakeySettingsSchema]="modelValue?.dataKeySettingsSchema" | |
193 | + [callbacks]="widgetConfigCallbacks" | |
194 | + [entityAliasId]="datasourceControl.get('entityAliasId').value" | |
195 | + [formControl]="datasourceControl.get('dataKeys')"> | |
196 | + </tb-data-keys> | |
184 | 197 | </section> |
185 | - <tb-data-keys class="tb-data-keys" fxFlex | |
186 | - [widgetType]="widgetType" | |
187 | - [datasourceType]="datasourceControl.get('type').value" | |
188 | - [maxDataKeys]="modelValue?.typeParameters?.maxDataKeys" | |
189 | - [optDataKeys]="modelValue?.typeParameters?.dataKeysOptional" | |
190 | - [aliasController]="aliasController" | |
191 | - [datakeySettingsSchema]="modelValue?.dataKeySettingsSchema" | |
192 | - [callbacks]="widgetConfigCallbacks" | |
193 | - [entityAliasId]="datasourceControl.get('entityAliasId').value" | |
194 | - [formControl]="datasourceControl.get('dataKeys')"> | |
195 | - </tb-data-keys> | |
196 | - </section> | |
197 | - <button [disabled]="isLoading$ | async" | |
198 | - type="button" | |
199 | - mat-icon-button color="primary" | |
200 | - style="min-width: 40px;" | |
201 | - (click)="removeDatasource($index)" | |
202 | - matTooltip="{{ 'widget-config.remove-datasource' | translate }}" | |
203 | - matTooltipPosition="above"> | |
204 | - <mat-icon>close</mat-icon> | |
205 | - </button> | |
198 | + <button [disabled]="isLoading$ | async" | |
199 | + type="button" | |
200 | + mat-icon-button color="primary" | |
201 | + style="min-width: 40px;" | |
202 | + (click)="removeDatasource($index)" | |
203 | + matTooltip="{{ 'widget-config.remove-datasource' | translate }}" | |
204 | + matTooltipPosition="above"> | |
205 | + <mat-icon>close</mat-icon> | |
206 | + </button> | |
207 | + </div> | |
206 | 208 | </div> |
207 | - </div> | |
208 | - </mat-list-item> | |
209 | - </mat-list> | |
209 | + </mat-list-item> | |
210 | + </mat-list> | |
211 | + </div> | |
212 | + </ng-template> | |
213 | + <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
214 | + <button [disabled]="isLoading$ | async" | |
215 | + type="button" | |
216 | + mat-raised-button color="primary" | |
217 | + [fxShow]="modelValue?.typeParameters && | |
218 | + (modelValue?.typeParameters.maxDatasources == -1 || datasourcesFormArray().controls.length < modelValue?.typeParameters.maxDatasources)" | |
219 | + (click)="addDatasource()" | |
220 | + matTooltip="{{ 'widget-config.add-datasource' | translate }}" | |
221 | + matTooltipPosition="above"> | |
222 | + <mat-icon>add</mat-icon> | |
223 | + <span translate>action.add</span> | |
224 | + </button> | |
210 | 225 | </div> |
211 | - </ng-template> | |
212 | - <div fxFlex fxLayout="row" fxLayoutAlign="start center"> | |
213 | - <button [disabled]="isLoading$ | async" | |
214 | - type="button" | |
215 | - mat-raised-button color="primary" | |
216 | - [fxShow]="modelValue?.typeParameters && | |
217 | - (modelValue?.typeParameters.maxDatasources == -1 || datasourcesFormArray().controls.length < modelValue?.typeParameters.maxDatasources)" | |
218 | - (click)="addDatasource()" | |
219 | - matTooltip="{{ 'widget-config.add-datasource' | translate }}" | |
220 | - matTooltipPosition="above"> | |
221 | - <mat-icon>add</mat-icon> | |
222 | - <span translate>action.add</span> | |
223 | - </button> | |
224 | - </div> | |
225 | - </mat-expansion-panel> | |
226 | - <mat-expansion-panel class="tb-datasources" *ngIf="widgetType === widgetTypes.rpc && | |
227 | - modelValue?.isDataEnabled" [expanded]="true"> | |
228 | - <mat-expansion-panel-header> | |
229 | - <mat-panel-title> | |
230 | - {{ 'widget-config.target-device' | translate }} | |
231 | - </mat-panel-title> | |
232 | - </mat-expansion-panel-header> | |
233 | - <div [formGroup]="targetDeviceSettings" style="padding: 0 5px;"> | |
234 | - <tb-entity-alias-select fxFlex | |
235 | - [tbRequired]="!widgetEditMode" | |
236 | - [aliasController]="aliasController" | |
237 | - [allowedEntityTypes]="[entityTypes.DEVICE]" | |
238 | - [callbacks]="widgetConfigCallbacks" | |
239 | - formControlName="targetDeviceAliasId"> | |
240 | - </tb-entity-alias-select> | |
241 | - </div> | |
242 | - </mat-expansion-panel> | |
243 | - <mat-expansion-panel class="tb-datasources" *ngIf="widgetType === widgetTypes.alarm && | |
244 | - modelValue?.isDataEnabled" [expanded]="true"> | |
245 | - <mat-expansion-panel-header> | |
246 | - <mat-panel-title> | |
247 | - {{ 'widget-config.alarm-source' | translate }} | |
248 | - </mat-panel-title> | |
249 | - </mat-expansion-panel-header> | |
250 | - <div [formGroup]="alarmSourceSettings" style="padding: 0 5px;"> | |
251 | - <section fxFlex | |
252 | - fxLayout="column" | |
253 | - fxLayoutAlign="center" | |
254 | - fxLayout.gt-sm="row" | |
255 | - fxLayoutAlign.gt-sm="start center"> | |
256 | - <mat-form-field class="tb-datasource-type"> | |
257 | - <mat-select formControlName="type"> | |
258 | - <mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType"> | |
259 | - {{ datasourceTypesTranslations.get(datasourceType) | translate }} | |
260 | - </mat-option> | |
261 | - </mat-select> | |
262 | - </mat-form-field> | |
263 | - <section class="tb-datasource" [ngSwitch]="alarmSourceSettings.get('type').value"> | |
264 | - <ng-template [ngSwitchCase]="datasourceType.entity"> | |
265 | - <tb-entity-alias-select | |
266 | - [showLabel]="true" | |
267 | - [tbRequired]="alarmSourceSettings.get('type').value === datasourceType.entity" | |
268 | - [aliasController]="aliasController" | |
269 | - formControlName="entityAliasId" | |
270 | - [callbacks]="widgetConfigCallbacks"> | |
271 | - </tb-entity-alias-select> | |
272 | - <tb-filter-select | |
273 | - [showLabel]="true" | |
274 | - [aliasController]="aliasController" | |
275 | - formControlName="filterId" | |
276 | - [callbacks]="widgetConfigCallbacks"> | |
277 | - </tb-filter-select> | |
278 | - </ng-template> | |
226 | + </mat-expansion-panel> | |
227 | + <mat-expansion-panel class="tb-datasources" *ngIf="widgetType === widgetTypes.rpc && | |
228 | + modelValue?.isDataEnabled" [expanded]="true"> | |
229 | + <mat-expansion-panel-header> | |
230 | + <mat-panel-title> | |
231 | + {{ 'widget-config.target-device' | translate }} | |
232 | + </mat-panel-title> | |
233 | + </mat-expansion-panel-header> | |
234 | + <div [formGroup]="targetDeviceSettings" style="padding: 0 5px;"> | |
235 | + <tb-entity-alias-select fxFlex | |
236 | + [tbRequired]="!widgetEditMode" | |
237 | + [aliasController]="aliasController" | |
238 | + [allowedEntityTypes]="[entityTypes.DEVICE]" | |
239 | + [callbacks]="widgetConfigCallbacks" | |
240 | + formControlName="targetDeviceAliasId"> | |
241 | + </tb-entity-alias-select> | |
242 | + </div> | |
243 | + </mat-expansion-panel> | |
244 | + <mat-expansion-panel class="tb-datasources" *ngIf="widgetType === widgetTypes.alarm && | |
245 | + modelValue?.isDataEnabled" [expanded]="true"> | |
246 | + <mat-expansion-panel-header> | |
247 | + <mat-panel-title> | |
248 | + {{ 'widget-config.alarm-source' | translate }} | |
249 | + </mat-panel-title> | |
250 | + </mat-expansion-panel-header> | |
251 | + <div [formGroup]="alarmSourceSettings" style="padding: 0 5px;"> | |
252 | + <section fxFlex | |
253 | + fxLayout="column" | |
254 | + fxLayoutAlign="center" | |
255 | + fxLayout.gt-sm="row" | |
256 | + fxLayoutAlign.gt-sm="start center"> | |
257 | + <mat-form-field class="tb-datasource-type"> | |
258 | + <mat-select formControlName="type"> | |
259 | + <mat-option *ngFor="let datasourceType of datasourceTypes" [value]="datasourceType"> | |
260 | + {{ datasourceTypesTranslations.get(datasourceType) | translate }} | |
261 | + </mat-option> | |
262 | + </mat-select> | |
263 | + </mat-form-field> | |
264 | + <section class="tb-datasource" [ngSwitch]="alarmSourceSettings.get('type').value"> | |
265 | + <ng-template [ngSwitchCase]="datasourceType.entity"> | |
266 | + <tb-entity-alias-select | |
267 | + [showLabel]="true" | |
268 | + [tbRequired]="alarmSourceSettings.get('type').value === datasourceType.entity" | |
269 | + [aliasController]="aliasController" | |
270 | + formControlName="entityAliasId" | |
271 | + [callbacks]="widgetConfigCallbacks"> | |
272 | + </tb-entity-alias-select> | |
273 | + <tb-filter-select | |
274 | + [showLabel]="true" | |
275 | + [aliasController]="aliasController" | |
276 | + formControlName="filterId" | |
277 | + [callbacks]="widgetConfigCallbacks"> | |
278 | + </tb-filter-select> | |
279 | + </ng-template> | |
280 | + </section> | |
281 | + <tb-data-keys class="tb-data-keys" fxFlex | |
282 | + [widgetType]="widgetType" | |
283 | + [datasourceType]="alarmSourceSettings.get('type').value" | |
284 | + [aliasController]="aliasController" | |
285 | + [datakeySettingsSchema]="modelValue?.dataKeySettingsSchema" | |
286 | + [callbacks]="widgetConfigCallbacks" | |
287 | + [entityAliasId]="alarmSourceSettings.get('entityAliasId').value" | |
288 | + formControlName="dataKeys"> | |
289 | + </tb-data-keys> | |
279 | 290 | </section> |
280 | - <tb-data-keys class="tb-data-keys" fxFlex | |
281 | - [widgetType]="widgetType" | |
282 | - [datasourceType]="alarmSourceSettings.get('type').value" | |
283 | - [aliasController]="aliasController" | |
284 | - [datakeySettingsSchema]="modelValue?.dataKeySettingsSchema" | |
285 | - [callbacks]="widgetConfigCallbacks" | |
286 | - [entityAliasId]="alarmSourceSettings.get('entityAliasId').value" | |
287 | - formControlName="dataKeys"> | |
288 | - </tb-data-keys> | |
289 | - </section> | |
290 | - </div> | |
291 | - </mat-expansion-panel> | |
291 | + </div> | |
292 | + </mat-expansion-panel> | |
293 | + <mat-expansion-panel [formGroup]="widgetSettings"> | |
294 | + <mat-expansion-panel-header> | |
295 | + <mat-panel-title translate>widget-config.data-settings</mat-panel-title> | |
296 | + </mat-expansion-panel-header> | |
297 | + <ng-template matExpansionPanelContent> | |
298 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
299 | + fxLayoutGap="8px"> | |
300 | + <mat-form-field fxFlex> | |
301 | + <mat-label translate>widget-config.units</mat-label> | |
302 | + <input matInput formControlName="units"> | |
303 | + </mat-form-field> | |
304 | + <mat-form-field fxFlex> | |
305 | + <mat-label translate>widget-config.decimals</mat-label> | |
306 | + <input matInput formControlName="decimals" type="number" min="0" max="15" step="1"> | |
307 | + </mat-form-field> | |
308 | + </div> | |
309 | + </ng-template> | |
310 | + </mat-expansion-panel> | |
311 | + </mat-accordion> | |
292 | 312 | </div> |
293 | 313 | </mat-tab> |
294 | 314 | <mat-tab label="{{ 'widget-config.settings' | translate }}"> |
295 | - <div class="mat-content mat-padding" fxLayout="column" fxLayoutGap="8px"> | |
296 | - <div [formGroup]="widgetSettings" fxLayout="column" fxLayoutGap="8px"> | |
297 | - <span translate>widget-config.general-settings</span> | |
298 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center"> | |
299 | - <div fxLayout="column" fxLayoutAlign="center" fxFlex.sm="40%" fxFlex.gt-sm="30%"> | |
300 | - <mat-form-field fxFlex class="mat-block"> | |
315 | + <div class="mat-content mat-padding" fxLayout="column"> | |
316 | + <div [formGroup]="widgetSettings" fxLayout="column"> | |
317 | + <fieldset class="fields-group" fxLayout="column"> | |
318 | + <legend class="group-title" translate>widget-config.title</legend> | |
319 | + <mat-slide-toggle formControlName="showTitle" style="margin: 8px 0"> | |
320 | + {{ 'widget-config.display-title' | translate }} | |
321 | + </mat-slide-toggle> | |
322 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
323 | + fxLayoutGap="8px"> | |
324 | + <mat-form-field fxFlex> | |
301 | 325 | <mat-label translate>widget-config.title</mat-label> |
302 | 326 | <input matInput formControlName="title"> |
303 | 327 | </mat-form-field> |
... | ... | @@ -306,130 +330,143 @@ |
306 | 330 | <input matInput formControlName="titleTooltip"> |
307 | 331 | </mat-form-field> |
308 | 332 | </div> |
309 | - <div fxFlex [fxShow]="widgetSettings.get('showTitle').value"> | |
310 | - <tb-json-object-edit | |
311 | - [editorStyle]="{minHeight: '100px'}" | |
312 | - required | |
313 | - label="{{ 'widget-config.title-style' | translate }}" | |
314 | - formControlName="titleStyle" | |
315 | - ></tb-json-object-edit> | |
316 | - </div> | |
317 | - </div> | |
318 | - <div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-md="row" fxLayoutAlign.gt-md="start center" fxFlex="100%" | |
319 | - fxLayoutGap="8px"> | |
320 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
321 | - fxLayoutGap="8px" fxFlex.gt-md> | |
322 | - <mat-checkbox fxFlex formControlName="showTitleIcon"> | |
333 | + <fieldset class="fields-group" fxLayout="column" fxLayoutGap="8px" style="margin: 0"> | |
334 | + <legend class="group-title" translate>widget-config.title-icon</legend> | |
335 | + <mat-slide-toggle formControlName="showTitleIcon"> | |
323 | 336 | {{ 'widget-config.display-icon' | translate }} |
324 | - </mat-checkbox> | |
325 | - <tb-material-icon-select fxFlex | |
326 | - formControlName="titleIcon"> | |
327 | - </tb-material-icon-select> | |
328 | - </div> | |
329 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
330 | - fxLayoutGap="8px" fxFlex.gt-md> | |
331 | - <tb-color-input fxFlex | |
332 | - label="{{'widget-config.icon-color' | translate}}" | |
333 | - icon="format_color_fill" | |
334 | - openOnInput | |
335 | - formControlName="iconColor"> | |
336 | - </tb-color-input> | |
337 | - <mat-form-field fxFlex> | |
338 | - <mat-label translate>widget-config.icon-size</mat-label> | |
339 | - <input matInput formControlName="iconSize"> | |
340 | - </mat-form-field> | |
341 | - </div> | |
342 | - </div> | |
343 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
344 | - fxLayoutGap="8px"> | |
345 | - <div fxLayout="column" fxLayoutAlign="center" fxLayoutGap="8px" fxFlex.sm="40%" fxFlex.gt-sm="30%"> | |
346 | - <mat-checkbox formControlName="showTitle"> | |
347 | - {{ 'widget-config.display-title' | translate }} | |
348 | - </mat-checkbox> | |
349 | - <mat-checkbox formControlName="dropShadow"> | |
350 | - {{ 'widget-config.drop-shadow' | translate }} | |
351 | - </mat-checkbox> | |
352 | - <mat-checkbox formControlName="enableFullscreen"> | |
353 | - {{ 'widget-config.enable-fullscreen' | translate }} | |
354 | - </mat-checkbox> | |
355 | - </div> | |
356 | - <div fxFlex> | |
357 | - <tb-json-object-edit | |
358 | - [editorStyle]="{minHeight: '100px'}" | |
359 | - required | |
360 | - label="{{ 'widget-config.widget-style' | translate }}" | |
361 | - formControlName="widgetStyle" | |
362 | - ></tb-json-object-edit> | |
363 | - </div> | |
364 | - </div> | |
365 | - <div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-md="row" fxLayoutAlign.gt-md="start center" | |
366 | - fxFlex="100%" fxLayoutGap="8px"> | |
367 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
368 | - fxLayoutGap="8px" fxFlex.gt-md> | |
369 | - <tb-color-input fxFlex | |
370 | - label="{{'widget-config.background-color' | translate}}" | |
371 | - icon="format_color_fill" | |
372 | - openOnInput | |
373 | - formControlName="backgroundColor"> | |
374 | - </tb-color-input> | |
375 | - <tb-color-input fxFlex | |
376 | - label="{{'widget-config.text-color' | translate}}" | |
377 | - icon="format_color_fill" | |
378 | - openOnInput | |
379 | - formControlName="color"> | |
380 | - </tb-color-input> | |
381 | - </div> | |
382 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
383 | - fxLayoutGap="8px" fxFlex.gt-md> | |
384 | - <mat-form-field fxFlex> | |
385 | - <mat-label translate>widget-config.padding</mat-label> | |
386 | - <input matInput formControlName="padding"> | |
387 | - </mat-form-field> | |
388 | - <mat-form-field fxFlex> | |
389 | - <mat-label translate>widget-config.margin</mat-label> | |
390 | - <input matInput formControlName="margin"> | |
391 | - </mat-form-field> | |
337 | + </mat-slide-toggle> | |
338 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row wrap" fxLayoutAlign="start center" | |
339 | + fxLayoutGap="8px"> | |
340 | + <tb-material-icon-select fxFlex | |
341 | + formControlName="titleIcon"> | |
342 | + </tb-material-icon-select> | |
343 | + <tb-color-input fxFlex | |
344 | + label="{{'widget-config.icon-color' | translate}}" | |
345 | + icon="format_color_fill" | |
346 | + openOnInput | |
347 | + formControlName="iconColor"> | |
348 | + </tb-color-input> | |
349 | + <mat-form-field fxFlex> | |
350 | + <mat-label translate>widget-config.icon-size</mat-label> | |
351 | + <input matInput formControlName="iconSize"> | |
352 | + </mat-form-field> | |
353 | + </div> | |
354 | + </fieldset> | |
355 | + <mat-expansion-panel class="tb-settings"> | |
356 | + <mat-expansion-panel-header> | |
357 | + <mat-panel-description fxLayoutAlign="end" translate> | |
358 | + widget-config.advanced-settings | |
359 | + </mat-panel-description> | |
360 | + </mat-expansion-panel-header> | |
361 | + <ng-template matExpansionPanelContent> | |
362 | + <tb-json-object-edit | |
363 | + [editorStyle]="{minHeight: '100px'}" | |
364 | + required | |
365 | + label="{{ 'widget-config.title-style' | translate }}" | |
366 | + formControlName="titleStyle" | |
367 | + ></tb-json-object-edit> | |
368 | + </ng-template> | |
369 | + </mat-expansion-panel> | |
370 | + </fieldset> | |
371 | + <fieldset class="fields-group" fxLayout="column"> | |
372 | + <legend class="group-title" translate>widget-config.widget-style</legend> | |
373 | + <div fxLayout="column" fxLayoutAlign="center" fxLayout.gt-md="row" fxLayoutAlign.gt-md="start center" | |
374 | + fxFlex="100%" fxLayoutGap="8px" class="tb-widget-style"> | |
375 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
376 | + fxLayoutGap="8px" fxFlex.gt-md> | |
377 | + <tb-color-input fxFlex | |
378 | + label="{{'widget-config.background-color' | translate}}" | |
379 | + icon="format_color_fill" | |
380 | + openOnInput | |
381 | + formControlName="backgroundColor"> | |
382 | + </tb-color-input> | |
383 | + <tb-color-input fxFlex | |
384 | + label="{{'widget-config.text-color' | translate}}" | |
385 | + icon="format_color_fill" | |
386 | + openOnInput | |
387 | + formControlName="color"> | |
388 | + </tb-color-input> | |
389 | + </div> | |
390 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
391 | + fxLayoutGap="8px" fxFlex.gt-md> | |
392 | + <mat-form-field fxFlex> | |
393 | + <mat-label translate>widget-config.padding</mat-label> | |
394 | + <input matInput formControlName="padding"> | |
395 | + </mat-form-field> | |
396 | + <mat-form-field fxFlex> | |
397 | + <mat-label translate>widget-config.margin</mat-label> | |
398 | + <input matInput formControlName="margin"> | |
399 | + </mat-form-field> | |
400 | + </div> | |
392 | 401 | </div> |
393 | - </div> | |
394 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
395 | - fxLayoutGap="8px"> | |
396 | - <mat-form-field fxFlex> | |
397 | - <mat-label translate>widget-config.units</mat-label> | |
398 | - <input matInput formControlName="units"> | |
399 | - </mat-form-field> | |
400 | - <mat-form-field fxFlex> | |
401 | - <mat-label translate>widget-config.decimals</mat-label> | |
402 | - <input matInput formControlName="decimals" type="number" min="0" max="15" step="1"> | |
403 | - </mat-form-field> | |
404 | - </div> | |
405 | - <div [fxShow]="widgetType === widgetTypes.timeseries || widgetType === widgetTypes.latest" | |
406 | - fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
407 | - fxLayoutGap="8px" fxFlex="100%"> | |
408 | - <mat-checkbox fxFlex.gt-xs formControlName="showLegend"> | |
409 | - {{ 'widget-config.display-legend' | translate }} | |
410 | - </mat-checkbox> | |
411 | - <section fxFlex.gt-xs fxLayout="row" fxLayoutAlign="start center" style="margin-bottom: 16px;"> | |
412 | - <tb-legend-config formControlName="legendConfig"> | |
413 | - </tb-legend-config> | |
414 | - </section> | |
415 | - </div> | |
416 | - </div> | |
417 | - <div [formGroup]="layoutSettings" fxLayout="column" fxLayoutGap="8px"> | |
418 | - <span translate>widget-config.mobile-mode-settings</span> | |
419 | - <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
420 | - fxLayoutGap="8px"> | |
421 | - <mat-checkbox formControlName="mobileHide"> | |
422 | - {{ 'widget-config.mobile-hide' | translate }} | |
423 | - </mat-checkbox> | |
424 | - <mat-form-field fxFlex> | |
425 | - <mat-label translate>widget-config.order</mat-label> | |
426 | - <input matInput formControlName="mobileOrder" type="number" step="1"> | |
427 | - </mat-form-field> | |
428 | - <mat-form-field fxFlex> | |
429 | - <mat-label translate>widget-config.height</mat-label> | |
430 | - <input matInput formControlName="mobileHeight" type="number" min="1" max="10" step="1"> | |
431 | - </mat-form-field> | |
432 | - </div> | |
402 | + <mat-slide-toggle formControlName="dropShadow" style="margin-bottom: 8px"> | |
403 | + {{ 'widget-config.drop-shadow' | translate }} | |
404 | + </mat-slide-toggle> | |
405 | + <mat-slide-toggle formControlName="enableFullscreen"> | |
406 | + {{ 'widget-config.enable-fullscreen' | translate }} | |
407 | + </mat-slide-toggle> | |
408 | + <mat-expansion-panel class="tb-settings"> | |
409 | + <mat-expansion-panel-header> | |
410 | + <mat-panel-description fxLayoutAlign="end" translate> | |
411 | + widget-config.advanced-settings | |
412 | + </mat-panel-description> | |
413 | + </mat-expansion-panel-header> | |
414 | + <ng-template matExpansionPanelContent> | |
415 | + <tb-json-object-edit | |
416 | + [editorStyle]="{minHeight: '100px'}" | |
417 | + required | |
418 | + label="{{ 'widget-config.widget-style' | translate }}" | |
419 | + formControlName="widgetStyle" | |
420 | + ></tb-json-object-edit> | |
421 | + </ng-template> | |
422 | + </mat-expansion-panel> | |
423 | + </fieldset> | |
424 | + <fieldset class="fields-group fields-group-slider" fxLayout="column"> | |
425 | + <legend class="group-title" translate>widget-config.legend</legend> | |
426 | + <mat-expansion-panel class="tb-settings"> | |
427 | + <mat-expansion-panel-header fxLayout="row wrap"> | |
428 | + <mat-panel-title> | |
429 | + <mat-slide-toggle formControlName="showLegend" (click)="$event.stopPropagation()" fxLayoutAlign="center"> | |
430 | + {{ 'widget-config.display-legend' | translate }} | |
431 | + </mat-slide-toggle> | |
432 | + </mat-panel-title> | |
433 | + <mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> | |
434 | + widget-config.advanced-settings | |
435 | + </mat-panel-description> | |
436 | + </mat-expansion-panel-header> | |
437 | + <ng-template matExpansionPanelContent> | |
438 | + <tb-legend-config formControlName="legendConfig"></tb-legend-config> | |
439 | + </ng-template> | |
440 | + </mat-expansion-panel> | |
441 | + </fieldset> | |
442 | + <fieldset [formGroup]="layoutSettings" class="fields-group fields-group-slider" fxLayout="column"> | |
443 | + <legend class="group-title" translate>widget-config.mobile-mode-settings</legend> | |
444 | + <mat-expansion-panel class="tb-settings"> | |
445 | + <mat-expansion-panel-header> | |
446 | + <mat-panel-title> | |
447 | + <mat-slide-toggle formControlName="mobileHide" (click)="$event.stopPropagation()" fxLayoutAlign="center"> | |
448 | + {{ 'widget-config.mobile-hide' | translate }} | |
449 | + </mat-slide-toggle> | |
450 | + </mat-panel-title> | |
451 | + <mat-panel-description fxLayoutAlign="end center" fxHide.xs translate> | |
452 | + widget-config.advanced-settings | |
453 | + </mat-panel-description> | |
454 | + </mat-expansion-panel-header> | |
455 | + <ng-template matExpansionPanelContent> | |
456 | + <div fxLayout.xs="column" fxLayoutAlign.xs="center" fxLayout="row" fxLayoutAlign="start center" | |
457 | + fxLayoutGap="8px"> | |
458 | + <mat-form-field fxFlex> | |
459 | + <mat-label translate>widget-config.order</mat-label> | |
460 | + <input matInput formControlName="mobileOrder" type="number" step="1"> | |
461 | + </mat-form-field> | |
462 | + <mat-form-field fxFlex> | |
463 | + <mat-label translate>widget-config.height</mat-label> | |
464 | + <input matInput formControlName="mobileHeight" type="number" min="1" max="10" step="1"> | |
465 | + </mat-form-field> | |
466 | + </div> | |
467 | + </ng-template> | |
468 | + </mat-expansion-panel> | |
469 | + </fieldset> | |
433 | 470 | </div> |
434 | 471 | </div> |
435 | 472 | </mat-tab> | ... | ... |
... | ... | @@ -20,9 +20,6 @@ |
20 | 20 | .tb-advanced-widget-config { |
21 | 21 | height: 100%; |
22 | 22 | } |
23 | - .tb-advanced-widget-config { | |
24 | - height: 100%; | |
25 | - } | |
26 | 23 | .tb-datasources { |
27 | 24 | |
28 | 25 | .handle { |
... | ... | @@ -69,6 +66,28 @@ |
69 | 66 | padding-left: 8px; |
70 | 67 | } |
71 | 68 | } |
69 | + .fields-group { | |
70 | + padding: 0 16px 8px; | |
71 | + margin-bottom: 10px; | |
72 | + border: 1px groove rgba(0, 0, 0, .25); | |
73 | + border-radius: 4px; | |
74 | + legend { | |
75 | + color: rgba(0, 0, 0, .7); | |
76 | + width: fit-content; | |
77 | + } | |
78 | + } | |
79 | + .fields-group-slider { | |
80 | + padding: 0; | |
81 | + legend { | |
82 | + margin-left: 16px; | |
83 | + } | |
84 | + .tb-settings { | |
85 | + padding: 0 16px 8px; | |
86 | + } | |
87 | + } | |
88 | + .tb-widget-style { | |
89 | + margin-top: 16px; | |
90 | + } | |
72 | 91 | } |
73 | 92 | } |
74 | 93 | |
... | ... | @@ -94,6 +113,36 @@ |
94 | 113 | white-space: normal; |
95 | 114 | } |
96 | 115 | .mat-expansion-panel { |
116 | + &.tb-settings { | |
117 | + box-shadow: none; | |
118 | + .mat-content { | |
119 | + overflow: visible; | |
120 | + } | |
121 | + .mat-expansion-panel-header { | |
122 | + padding: 0; | |
123 | + &:hover { | |
124 | + background: none; | |
125 | + } | |
126 | + .mat-expansion-indicator { | |
127 | + padding: 2px; | |
128 | + } | |
129 | + } | |
130 | + .mat-expansion-panel-header-description { | |
131 | + align-items: center; | |
132 | + } | |
133 | + .mat-expansion-panel-body{ | |
134 | + padding: 0; | |
135 | + } | |
136 | + .tb-json-object-panel { | |
137 | + margin: 0 0 8px; | |
138 | + } | |
139 | + .mat-checkbox-layout { | |
140 | + margin: 5px 0; | |
141 | + } | |
142 | + .mat-checkbox-inner-container { | |
143 | + margin-right: 12px; | |
144 | + } | |
145 | + } | |
97 | 146 | &.tb-datasources { |
98 | 147 | &.mat-expanded { |
99 | 148 | overflow: visible; |
... | ... | @@ -152,5 +201,8 @@ |
152 | 201 | } |
153 | 202 | } |
154 | 203 | } |
204 | + .mat-slide-toggle-content { | |
205 | + white-space: normal; | |
206 | + } | |
155 | 207 | } |
156 | 208 | } | ... | ... |
... | ... | @@ -212,11 +212,28 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont |
212 | 212 | showLegend: [null, []], |
213 | 213 | legendConfig: [null, []] |
214 | 214 | }); |
215 | + this.widgetSettings.get('showTitle').valueChanges.subscribe((value: boolean) => { | |
216 | + if (value) { | |
217 | + this.widgetSettings.get('titleStyle').enable({emitEvent: false}); | |
218 | + this.widgetSettings.get('titleTooltip').enable({emitEvent: false}); | |
219 | + this.widgetSettings.get('showTitleIcon').enable({emitEvent: false}); | |
220 | + } else { | |
221 | + this.widgetSettings.get('titleStyle').disable({emitEvent: false}); | |
222 | + this.widgetSettings.get('titleTooltip').disable({emitEvent: false}); | |
223 | + this.widgetSettings.get('showTitleIcon').patchValue(false); | |
224 | + this.widgetSettings.get('showTitleIcon').disable({emitEvent: false}); | |
225 | + } | |
226 | + }); | |
227 | + | |
215 | 228 | this.widgetSettings.get('showTitleIcon').valueChanges.subscribe((value: boolean) => { |
216 | 229 | if (value) { |
217 | 230 | this.widgetSettings.get('titleIcon').enable({emitEvent: false}); |
231 | + this.widgetSettings.get('iconColor').enable({emitEvent: false}); | |
232 | + this.widgetSettings.get('iconSize').enable({emitEvent: false}); | |
218 | 233 | } else { |
219 | 234 | this.widgetSettings.get('titleIcon').disable({emitEvent: false}); |
235 | + this.widgetSettings.get('iconColor').disable({emitEvent: false}); | |
236 | + this.widgetSettings.get('iconSize').disable({emitEvent: false}); | |
220 | 237 | } |
221 | 238 | }); |
222 | 239 | this.widgetSettings.get('showLegend').valueChanges.subscribe((value: boolean) => { |
... | ... | @@ -236,6 +253,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont |
236 | 253 | }); |
237 | 254 | } |
238 | 255 | |
256 | + ngOnDestroy(): void { | |
257 | + this.removeChangeSubscriptions(); | |
258 | + } | |
259 | + | |
239 | 260 | private removeChangeSubscriptions() { |
240 | 261 | if (this.dataSettingsChangesSubscription) { |
241 | 262 | this.dataSettingsChangesSubscription.unsubscribe(); |
... | ... | @@ -376,7 +397,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont |
376 | 397 | iconColor: isDefined(config.iconColor) ? config.iconColor : 'rgba(0, 0, 0, 0.87)', |
377 | 398 | iconSize: isDefined(config.iconSize) ? config.iconSize : '24px', |
378 | 399 | titleTooltip: isDefined(config.titleTooltip) ? config.titleTooltip : '', |
379 | - showTitle: config.showTitle, | |
400 | + showTitle: isDefined(config.showTitle) ? config.showTitle : false, | |
380 | 401 | dropShadow: isDefined(config.dropShadow) ? config.dropShadow : true, |
381 | 402 | enableFullscreen: isDefined(config.enableFullscreen) ? config.enableFullscreen : true, |
382 | 403 | backgroundColor: config.backgroundColor, |
... | ... | @@ -396,11 +417,25 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont |
396 | 417 | }, |
397 | 418 | {emitEvent: false} |
398 | 419 | ); |
420 | + const showTitle: boolean = this.widgetSettings.get('showTitle').value; | |
421 | + if (showTitle) { | |
422 | + this.widgetSettings.get('titleTooltip').enable({emitEvent: false}); | |
423 | + this.widgetSettings.get('titleStyle').enable({emitEvent: false}); | |
424 | + this.widgetSettings.get('showTitleIcon').enable({emitEvent: false}); | |
425 | + } else { | |
426 | + this.widgetSettings.get('titleTooltip').disable({emitEvent: false}); | |
427 | + this.widgetSettings.get('titleStyle').disable({emitEvent: false}); | |
428 | + this.widgetSettings.get('showTitleIcon').disable({emitEvent: false}); | |
429 | + } | |
399 | 430 | const showTitleIcon: boolean = this.widgetSettings.get('showTitleIcon').value; |
400 | 431 | if (showTitleIcon) { |
401 | 432 | this.widgetSettings.get('titleIcon').enable({emitEvent: false}); |
433 | + this.widgetSettings.get('iconColor').enable({emitEvent: false}); | |
434 | + this.widgetSettings.get('iconSize').enable({emitEvent: false}); | |
402 | 435 | } else { |
403 | 436 | this.widgetSettings.get('titleIcon').disable({emitEvent: false}); |
437 | + this.widgetSettings.get('iconColor').disable({emitEvent: false}); | |
438 | + this.widgetSettings.get('iconSize').disable({emitEvent: false}); | |
404 | 439 | } |
405 | 440 | const showLegend: boolean = this.widgetSettings.get('showLegend').value; |
406 | 441 | if (showLegend) { | ... | ... |
... | ... | @@ -92,14 +92,16 @@ export class MaterialIconSelectComponent extends PageComponent implements OnInit |
92 | 92 | } |
93 | 93 | |
94 | 94 | openIconDialog() { |
95 | - this.dialogs.materialIconPicker(this.materialIconFormGroup.get('icon').value).subscribe( | |
96 | - (icon) => { | |
97 | - if (icon) { | |
98 | - this.materialIconFormGroup.patchValue( | |
99 | - {icon}, {emitEvent: true} | |
100 | - ); | |
95 | + if (!this.disabled) { | |
96 | + this.dialogs.materialIconPicker(this.materialIconFormGroup.get('icon').value).subscribe( | |
97 | + (icon) => { | |
98 | + if (icon) { | |
99 | + this.materialIconFormGroup.patchValue( | |
100 | + {icon}, {emitEvent: true} | |
101 | + ); | |
102 | + } | |
101 | 103 | } |
102 | - } | |
103 | - ); | |
104 | + ); | |
105 | + } | |
104 | 106 | } |
105 | 107 | } | ... | ... |
... | ... | @@ -3030,7 +3030,7 @@ |
3030 | 3030 | "title": "Title", |
3031 | 3031 | "title-tooltip": "Title Tooltip", |
3032 | 3032 | "general-settings": "General settings", |
3033 | - "display-title": "Display title", | |
3033 | + "display-title": "Display widget title", | |
3034 | 3034 | "drop-shadow": "Drop shadow", |
3035 | 3035 | "enable-fullscreen": "Enable fullscreen", |
3036 | 3036 | "background-color": "Background color", |
... | ... | @@ -3039,7 +3039,7 @@ |
3039 | 3039 | "margin": "Margin", |
3040 | 3040 | "widget-style": "Widget style", |
3041 | 3041 | "title-style": "Title style", |
3042 | - "mobile-mode-settings": "Mobile mode settings", | |
3042 | + "mobile-mode-settings": "Mobile mode", | |
3043 | 3043 | "order": "Order", |
3044 | 3044 | "height": "Height", |
3045 | 3045 | "mobile-hide": "Hide widget in mobile mode", |
... | ... | @@ -3048,6 +3048,7 @@ |
3048 | 3048 | "timewindow": "Timewindow", |
3049 | 3049 | "use-dashboard-timewindow": "Use dashboard timewindow", |
3050 | 3050 | "display-timewindow": "Display timewindow", |
3051 | + "legend": "Legend", | |
3051 | 3052 | "display-legend": "Display legend", |
3052 | 3053 | "datasources": "Datasources", |
3053 | 3054 | "maximum-datasources": "Maximum { count, plural, 1 {1 datasource is allowed.} other {# datasources are allowed} }", |
... | ... | @@ -3075,9 +3076,12 @@ |
3075 | 3076 | "delete-action": "Delete action", |
3076 | 3077 | "delete-action-title": "Delete widget action", |
3077 | 3078 | "delete-action-text": "Are you sure you want delete widget action with name '{{actionName}}'?", |
3079 | + "title-icon": "Title icon", | |
3078 | 3080 | "display-icon": "Display title icon", |
3079 | 3081 | "icon-color": "Icon color", |
3080 | - "icon-size": "Icon size" | |
3082 | + "icon-size": "Icon size", | |
3083 | + "advanced-settings": "Advanced settings", | |
3084 | + "data-settings": "Data settings" | |
3081 | 3085 | }, |
3082 | 3086 | "widget-type": { |
3083 | 3087 | "import": "Import widget type", | ... | ... |
... | ... | @@ -1631,7 +1631,7 @@ |
1631 | 1631 | "advanced": "Дополнительно", |
1632 | 1632 | "title": "Название", |
1633 | 1633 | "general-settings": "Общие настройки", |
1634 | - "display-title": "Показать название", | |
1634 | + "display-title": "Показать название на виджете", | |
1635 | 1635 | "drop-shadow": "Тень", |
1636 | 1636 | "enable-fullscreen": "Во весь экран", |
1637 | 1637 | "background-color": "Цвет фона", |
... | ... | @@ -1640,7 +1640,7 @@ |
1640 | 1640 | "margin": "Margin", |
1641 | 1641 | "widget-style": "Стиль виджета", |
1642 | 1642 | "title-style": "Стиль названия", |
1643 | - "mobile-mode-settings": "Настройки мобильного режима", | |
1643 | + "mobile-mode-settings": "Мобильный режим", | |
1644 | 1644 | "order": "Порядок", |
1645 | 1645 | "height": "Высота", |
1646 | 1646 | "units": "Специальный символ после значения", |
... | ... | @@ -1648,6 +1648,7 @@ |
1648 | 1648 | "timewindow": "Временное окно", |
1649 | 1649 | "use-dashboard-timewindow": "Использовать временное окно дашборда", |
1650 | 1650 | "display-timewindow": "Показывать временное окно", |
1651 | + "legend": "Легенда", | |
1651 | 1652 | "display-legend": "Показать легенду", |
1652 | 1653 | "datasources": "Источники данных", |
1653 | 1654 | "maximum-datasources": "Максимальной количество источников данных равно {{count}}", |
... | ... | @@ -1673,9 +1674,12 @@ |
1673 | 1674 | "delete-action": "Удалить действие", |
1674 | 1675 | "delete-action-title": "Удалить действие виджета", |
1675 | 1676 | "delete-action-text": "Вы точно хотите удалить действие виджета '{{actionName}}'?", |
1676 | - "display-icon": "Показывать иконку в названии", | |
1677 | + "title-icon": "Иконка в названии виджета", | |
1678 | + "display-icon": "Показывать иконку в названии виджета", | |
1677 | 1679 | "icon-color": "Цвет иконки", |
1678 | - "icon-size": "Размер иконки" | |
1680 | + "icon-size": "Размер иконки", | |
1681 | + "advanced-settings": "Расширенные настройки", | |
1682 | + "data-settings": "Настройки данных" | |
1679 | 1683 | }, |
1680 | 1684 | "widget-type": { |
1681 | 1685 | "import": "Импортировать тип виджета", | ... | ... |
... | ... | @@ -2202,7 +2202,7 @@ |
2202 | 2202 | "advanced": "Додатково", |
2203 | 2203 | "title": "Назва", |
2204 | 2204 | "general-settings": "Загальні налаштування", |
2205 | - "display-title": "Відобразити назву", | |
2205 | + "display-title": "Відобразити назву у віджеті", | |
2206 | 2206 | "drop-shadow": "Тінь", |
2207 | 2207 | "enable-fullscreen": "Увімкнути повноекранний режим", |
2208 | 2208 | "enable-data-export": "Увімкнути експорт даних", |
... | ... | @@ -2212,7 +2212,7 @@ |
2212 | 2212 | "margin": "Границі", |
2213 | 2213 | "widget-style": "Стиль віджетів", |
2214 | 2214 | "title-style": "Стиль заголовка", |
2215 | - "mobile-mode-settings": "Налаштування мобільного режиму", | |
2215 | + "mobile-mode-settings": "мобільний режим", | |
2216 | 2216 | "order": "Порядок", |
2217 | 2217 | "height": "Висота", |
2218 | 2218 | "units": "Спеціальний символ після значення", |
... | ... | @@ -2220,6 +2220,7 @@ |
2220 | 2220 | "timewindow": "Вікно часу", |
2221 | 2221 | "use-dashboard-timewindow": "Використати вікно часу на панелі візуалізації", |
2222 | 2222 | "display-timewindow": "Показувати вікно часу", |
2223 | + "legend": "Легенда", | |
2223 | 2224 | "display-legend": "Показати легенду", |
2224 | 2225 | "datasources": "Джерела даних", |
2225 | 2226 | "maximum-datasources": "Максимально { count, plural, 1 {1 дозволене джерело даних.} other {# дозволені джерела даних } }", |
... | ... | @@ -2245,9 +2246,12 @@ |
2245 | 2246 | "delete-action": "Видалити дію", |
2246 | 2247 | "delete-action-title": "Видалити дію віджета", |
2247 | 2248 | "delete-action-text": "Ви впевнені, що хочете видалити дію віджета '{{actionName}}'?", |
2248 | - "display-icon": "Показувати іконку у назві", | |
2249 | + "title-icon": "Іконка у назві віджету", | |
2250 | + "display-icon": "Показувати іконку у назві віджету", | |
2249 | 2251 | "icon-color": "Колір іконки", |
2250 | - "icon-size": "Розмір іконки" | |
2252 | + "icon-size": "Розмір іконки", | |
2253 | + "advanced-settings": "Розширені налаштування", | |
2254 | + "data-settings": "Налаштування даних" | |
2251 | 2255 | }, |
2252 | 2256 | "widget-type": { |
2253 | 2257 | "import": "Імпортувати тип віджета", | ... | ... |