Commit 0b256a1d2c6b07972122ed468879069bfd5f8f4a
1 parent
1d0755f1
Add hide dashboard toolbar settings. Improve dashboard setting dialog. Handle da…
…shboard right layout toggle in mobile app.
Showing
11 changed files
with
254 additions
and
127 deletions
@@ -231,7 +231,6 @@ export class DashboardUtilsService { | @@ -231,7 +231,6 @@ export class DashboardUtilsService { | ||
231 | private createDefaultGridSettings(): GridSettings { | 231 | private createDefaultGridSettings(): GridSettings { |
232 | return { | 232 | return { |
233 | backgroundColor: '#eeeeee', | 233 | backgroundColor: '#eeeeee', |
234 | - color: 'rgba(0,0,0,0.870588)', | ||
235 | columns: 24, | 234 | columns: 24, |
236 | margin: 10, | 235 | margin: 10, |
237 | backgroundSizeMode: '100%' | 236 | backgroundSizeMode: '100%' |
@@ -27,6 +27,7 @@ import { AuthService } from '@core/auth/auth.service'; | @@ -27,6 +27,7 @@ import { AuthService } from '@core/auth/auth.service'; | ||
27 | 27 | ||
28 | const dashboardStateNameHandler = 'tbMobileDashboardStateNameHandler'; | 28 | const dashboardStateNameHandler = 'tbMobileDashboardStateNameHandler'; |
29 | const dashboardLoadedHandler = 'tbMobileDashboardLoadedHandler'; | 29 | const dashboardLoadedHandler = 'tbMobileDashboardLoadedHandler'; |
30 | +const dashboardLayoutHandler = 'tbMobileDashboardLayoutHandler'; | ||
30 | const navigationHandler = 'tbMobileNavigationHandler'; | 31 | const navigationHandler = 'tbMobileNavigationHandler'; |
31 | const mobileHandler = 'tbMobileHandler'; | 32 | const mobileHandler = 'tbMobileHandler'; |
32 | 33 | ||
@@ -43,6 +44,7 @@ export class MobileService { | @@ -43,6 +44,7 @@ export class MobileService { | ||
43 | 44 | ||
44 | private reloadUserObservable: Observable<boolean>; | 45 | private reloadUserObservable: Observable<boolean>; |
45 | private lastDashboardId: string; | 46 | private lastDashboardId: string; |
47 | + private toggleLayoutFunction: () => void; | ||
46 | 48 | ||
47 | constructor(@Inject(WINDOW) private window: Window, | 49 | constructor(@Inject(WINDOW) private window: Window, |
48 | private router: Router, | 50 | private router: Router, |
@@ -65,12 +67,26 @@ export class MobileService { | @@ -65,12 +67,26 @@ export class MobileService { | ||
65 | } | 67 | } |
66 | } | 68 | } |
67 | 69 | ||
68 | - public onDashboardLoaded() { | 70 | + public onDashboardLoaded(hasRightLayout: boolean, rightLayoutOpened: boolean) { |
69 | if (this.mobileApp) { | 71 | if (this.mobileApp) { |
70 | - this.mobileChannel.callHandler(dashboardLoadedHandler); | 72 | + this.mobileChannel.callHandler(dashboardLoadedHandler, hasRightLayout, rightLayoutOpened); |
71 | } | 73 | } |
72 | } | 74 | } |
73 | 75 | ||
76 | + public onDashboardRightLayoutChanged(opened: boolean) { | ||
77 | + if (this.mobileApp) { | ||
78 | + this.mobileChannel.callHandler(dashboardLayoutHandler, opened); | ||
79 | + } | ||
80 | + } | ||
81 | + | ||
82 | + public registerToggleLayoutFunction(toggleLayoutFunction: () => void) { | ||
83 | + this.toggleLayoutFunction = toggleLayoutFunction; | ||
84 | + } | ||
85 | + | ||
86 | + public unregisterToggleLayoutFunction() { | ||
87 | + this.toggleLayoutFunction = null; | ||
88 | + } | ||
89 | + | ||
74 | public handleWidgetMobileAction<T extends MobileActionResult>(type: WidgetMobileActionType, ...args: any[]): | 90 | public handleWidgetMobileAction<T extends MobileActionResult>(type: WidgetMobileActionType, ...args: any[]): |
75 | Observable<WidgetMobileActionResult<T>> { | 91 | Observable<WidgetMobileActionResult<T>> { |
76 | if (this.mobileApp) { | 92 | if (this.mobileApp) { |
@@ -110,6 +126,11 @@ export class MobileService { | @@ -110,6 +126,11 @@ export class MobileService { | ||
110 | const reloadUserMessage: ReloadUserMessage = message.data; | 126 | const reloadUserMessage: ReloadUserMessage = message.data; |
111 | this.reloadUser(reloadUserMessage); | 127 | this.reloadUser(reloadUserMessage); |
112 | break; | 128 | break; |
129 | + case 'toggleDashboardLayout': | ||
130 | + if (this.toggleLayoutFunction) { | ||
131 | + this.toggleLayoutFunction(); | ||
132 | + } | ||
133 | + break; | ||
113 | } | 134 | } |
114 | } | 135 | } |
115 | } | 136 | } |
@@ -149,8 +149,16 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -149,8 +149,16 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
149 | @Input() | 149 | @Input() |
150 | currentState: string; | 150 | currentState: string; |
151 | 151 | ||
152 | + private hideToolbarValue = false; | ||
153 | + | ||
152 | @Input() | 154 | @Input() |
153 | - hideToolbar: boolean; | 155 | + set hideToolbar(hideToolbar: boolean) { |
156 | + this.hideToolbarValue = hideToolbar; | ||
157 | + } | ||
158 | + | ||
159 | + get hideToolbar(): boolean { | ||
160 | + return (this.hideToolbarValue || this.hideToolbarSetting()) && !this.isEdit; | ||
161 | + } | ||
154 | 162 | ||
155 | @Input() | 163 | @Input() |
156 | syncStateWithQueryParam = true; | 164 | syncStateWithQueryParam = true; |
@@ -269,6 +277,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -269,6 +277,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
269 | return !this.widgetEditMode && !this.hideToolbar && | 277 | return !this.widgetEditMode && !this.hideToolbar && |
270 | (this.toolbarAlwaysOpen() || this.isToolbarOpened || this.isEdit || this.showRightLayoutSwitch()); | 278 | (this.toolbarAlwaysOpen() || this.isToolbarOpened || this.isEdit || this.showRightLayoutSwitch()); |
271 | } | 279 | } |
280 | + | ||
272 | set toolbarOpened(toolbarOpened: boolean) { | 281 | set toolbarOpened(toolbarOpened: boolean) { |
273 | } | 282 | } |
274 | 283 | ||
@@ -329,7 +338,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -329,7 +338,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
329 | this.dashboardCtx.aliasController.updateAliases(); | 338 | this.dashboardCtx.aliasController.updateAliases(); |
330 | setTimeout(() => { | 339 | setTimeout(() => { |
331 | this.mobileService.handleDashboardStateName(this.dashboardCtx.stateController.getCurrentStateName()); | 340 | this.mobileService.handleDashboardStateName(this.dashboardCtx.stateController.getCurrentStateName()); |
332 | - this.mobileService.onDashboardLoaded(); | 341 | + this.mobileService.onDashboardLoaded(this.layouts.right.show, this.isRightLayoutOpened); |
333 | }); | 342 | }); |
334 | } | 343 | } |
335 | } | 344 | } |
@@ -340,6 +349,14 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -340,6 +349,14 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
340 | this.isMobile = !state.matches; | 349 | this.isMobile = !state.matches; |
341 | } | 350 | } |
342 | )); | 351 | )); |
352 | + if (this.isMobileApp) { | ||
353 | + this.mobileService.registerToggleLayoutFunction(() => { | ||
354 | + setTimeout(() => { | ||
355 | + this.toggleLayouts(); | ||
356 | + this.cd.detectChanges(); | ||
357 | + }); | ||
358 | + }); | ||
359 | + } | ||
343 | } | 360 | } |
344 | 361 | ||
345 | private init(data: any) { | 362 | private init(data: any) { |
@@ -430,6 +447,9 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -430,6 +447,9 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
430 | } | 447 | } |
431 | 448 | ||
432 | ngOnDestroy(): void { | 449 | ngOnDestroy(): void { |
450 | + if (this.isMobileApp) { | ||
451 | + this.mobileService.unregisterToggleLayoutFunction(); | ||
452 | + } | ||
433 | this.rxSubscriptions.forEach((subscription) => { | 453 | this.rxSubscriptions.forEach((subscription) => { |
434 | subscription.unsubscribe(); | 454 | subscription.unsubscribe(); |
435 | }); | 455 | }); |
@@ -469,6 +489,15 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -469,6 +489,15 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
469 | } | 489 | } |
470 | } | 490 | } |
471 | 491 | ||
492 | + private hideToolbarSetting(): boolean { | ||
493 | + if (this.dashboard.configuration.settings && | ||
494 | + isDefined(this.dashboard.configuration.settings.hideToolbar)) { | ||
495 | + return this.dashboard.configuration.settings.hideToolbar; | ||
496 | + } else { | ||
497 | + return false; | ||
498 | + } | ||
499 | + } | ||
500 | + | ||
472 | public displayTitle(): boolean { | 501 | public displayTitle(): boolean { |
473 | if (this.dashboard.configuration.settings && | 502 | if (this.dashboard.configuration.settings && |
474 | isDefined(this.dashboard.configuration.settings.showTitle)) { | 503 | isDefined(this.dashboard.configuration.settings.showTitle)) { |
@@ -546,15 +575,17 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -546,15 +575,17 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
546 | } | 575 | } |
547 | 576 | ||
548 | public showRightLayoutSwitch(): boolean { | 577 | public showRightLayoutSwitch(): boolean { |
549 | - return this.isMobile && this.layouts.right.show; | 578 | + return this.isMobile && !this.isMobileApp && this.layouts.right.show; |
550 | } | 579 | } |
551 | 580 | ||
552 | public toggleLayouts() { | 581 | public toggleLayouts() { |
553 | this.isRightLayoutOpened = !this.isRightLayoutOpened; | 582 | this.isRightLayoutOpened = !this.isRightLayoutOpened; |
583 | + this.mobileService.onDashboardRightLayoutChanged(this.isRightLayoutOpened); | ||
554 | } | 584 | } |
555 | 585 | ||
556 | public openRightLayout() { | 586 | public openRightLayout() { |
557 | this.isRightLayoutOpened = true; | 587 | this.isRightLayoutOpened = true; |
588 | + this.mobileService.onDashboardRightLayoutChanged(this.isRightLayoutOpened); | ||
558 | } | 589 | } |
559 | 590 | ||
560 | public mainLayoutWidth(): string { | 591 | public mainLayoutWidth(): string { |
@@ -782,7 +813,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | @@ -782,7 +813,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC | ||
782 | this.updateLayouts(layoutsData); | 813 | this.updateLayouts(layoutsData); |
783 | } | 814 | } |
784 | setTimeout(() => { | 815 | setTimeout(() => { |
785 | - this.mobileService.onDashboardLoaded(); | 816 | + this.mobileService.onDashboardLoaded(this.layouts.right.show, this.isRightLayoutOpened); |
786 | }); | 817 | }); |
787 | } | 818 | } |
788 | 819 |
@@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<form (ngSubmit)="save()"> | 18 | +<form (ngSubmit)="save()" style="width: 750px;"> |
19 | <mat-toolbar color="primary"> | 19 | <mat-toolbar color="primary"> |
20 | <h2 translate>{{settings ? 'dashboard.settings' : 'layout.settings'}}</h2> | 20 | <h2 translate>{{settings ? 'dashboard.settings' : 'layout.settings'}}</h2> |
21 | <span fxFlex></span> | 21 | <span fxFlex></span> |
@@ -28,8 +28,8 @@ | @@ -28,8 +28,8 @@ | ||
28 | <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> | 28 | <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> |
29 | </mat-progress-bar> | 29 | </mat-progress-bar> |
30 | <div mat-dialog-content> | 30 | <div mat-dialog-content> |
31 | - <fieldset [disabled]="isLoading$ | async" fxLayout="column" fxLayoutGap="16px"> | ||
32 | - <div *ngIf="settings" [formGroup]="settingsFormGroup"> | 31 | + <fieldset [disabled]="isLoading$ | async"> |
32 | + <div *ngIf="settings" [formGroup]="settingsFormGroup" fxLayout="column"> | ||
33 | <mat-form-field class="mat-block"> | 33 | <mat-form-field class="mat-block"> |
34 | <mat-label translate>dashboard.state-controller</mat-label> | 34 | <mat-label translate>dashboard.state-controller</mat-label> |
35 | <mat-select required formControlName="stateControllerId"> | 35 | <mat-select required formControlName="stateControllerId"> |
@@ -38,112 +38,116 @@ | @@ -38,112 +38,116 @@ | ||
38 | </mat-option> | 38 | </mat-option> |
39 | </mat-select> | 39 | </mat-select> |
40 | </mat-form-field> | 40 | </mat-form-field> |
41 | - <div fxLayout="row" fxLayoutAlign="start center" fxLayout.lt-md="column" fxLayoutAlign.lt-md fxLayoutGap="8px"> | ||
42 | - <mat-checkbox fxFlex formControlName="toolbarAlwaysOpen"> | ||
43 | - {{ 'dashboard.toolbar-always-open' | translate }} | ||
44 | - </mat-checkbox> | ||
45 | - <mat-checkbox fxFlex formControlName="showTitle"> | 41 | + <fieldset class="fields-group" fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px"> |
42 | + <legend class="group-title" translate>dashboard.title-settings</legend> | ||
43 | + <mat-slide-toggle fxFlex formControlName="showTitle"> | ||
46 | {{ 'dashboard.display-title' | translate }} | 44 | {{ 'dashboard.display-title' | translate }} |
47 | - </mat-checkbox> | 45 | + </mat-slide-toggle> |
48 | <tb-color-input fxFlex | 46 | <tb-color-input fxFlex |
49 | label="{{'dashboard.title-color' | translate}}" | 47 | label="{{'dashboard.title-color' | translate}}" |
50 | icon="format_color_fill" | 48 | icon="format_color_fill" |
51 | openOnInput | 49 | openOnInput |
52 | formControlName="titleColor"> | 50 | formControlName="titleColor"> |
53 | </tb-color-input> | 51 | </tb-color-input> |
54 | - </div> | ||
55 | - <div fxLayout="row" fxLayoutAlign="start center" style="margin-bottom: 8px;" | ||
56 | - fxLayout.lt-md="column" fxLayoutAlign.lt-md fxLayoutGap="8px"> | ||
57 | - <mat-checkbox fxFlex formControlName="showDashboardsSelect"> | 52 | + </fieldset> |
53 | + <fieldset class="fields-group" fxLayout="column" fxLayoutGap="8px"> | ||
54 | + <legend class="group-title" translate>dashboard.dashboard-logo-settings</legend> | ||
55 | + <mat-slide-toggle formControlName="showDashboardLogo"> | ||
56 | + {{ 'dashboard.display-dashboard-logo' | translate }} | ||
57 | + </mat-slide-toggle> | ||
58 | + <tb-image-input fxFlex | ||
59 | + label="{{'dashboard.dashboard-logo-image' | translate}}" | ||
60 | + formControlName="dashboardLogoUrl"> | ||
61 | + </tb-image-input> | ||
62 | + </fieldset> | ||
63 | + <fieldset class="fields-group" fxLayout="column" fxLayoutGap="8px"> | ||
64 | + <legend class="group-title" translate>dashboard.toolbar-settings</legend> | ||
65 | + <mat-slide-toggle formControlName="hideToolbar"> | ||
66 | + {{ 'dashboard.hide-toolbar' | translate }} | ||
67 | + </mat-slide-toggle> | ||
68 | + <mat-slide-toggle formControlName="toolbarAlwaysOpen"> | ||
69 | + {{ 'dashboard.toolbar-always-open' | translate }} | ||
70 | + </mat-slide-toggle> | ||
71 | + <mat-slide-toggle formControlName="showDashboardsSelect"> | ||
58 | {{ 'dashboard.display-dashboards-selection' | translate }} | 72 | {{ 'dashboard.display-dashboards-selection' | translate }} |
59 | - </mat-checkbox> | ||
60 | - <mat-checkbox fxFlex formControlName="showEntitiesSelect"> | 73 | + </mat-slide-toggle> |
74 | + <mat-slide-toggle formControlName="showEntitiesSelect"> | ||
61 | {{ 'dashboard.display-entities-selection' | translate }} | 75 | {{ 'dashboard.display-entities-selection' | translate }} |
62 | - </mat-checkbox> | ||
63 | - <mat-checkbox fxFlex formControlName="showFilters"> | 76 | + </mat-slide-toggle> |
77 | + <mat-slide-toggle formControlName="showFilters"> | ||
64 | {{ 'dashboard.display-filters' | translate }} | 78 | {{ 'dashboard.display-filters' | translate }} |
65 | - </mat-checkbox> | ||
66 | - <mat-checkbox fxFlex formControlName="showDashboardTimewindow"> | 79 | + </mat-slide-toggle> |
80 | + <mat-slide-toggle formControlName="showDashboardTimewindow"> | ||
67 | {{ 'dashboard.display-dashboard-timewindow' | translate }} | 81 | {{ 'dashboard.display-dashboard-timewindow' | translate }} |
68 | - </mat-checkbox> | ||
69 | - <mat-checkbox fxFlex formControlName="showDashboardExport"> | 82 | + </mat-slide-toggle> |
83 | + <mat-slide-toggle formControlName="showDashboardExport"> | ||
70 | {{ 'dashboard.display-dashboard-export' | translate }} | 84 | {{ 'dashboard.display-dashboard-export' | translate }} |
71 | - </mat-checkbox> | ||
72 | - <mat-checkbox fxFlex formControlName="showUpdateDashboardImage"> | 85 | + </mat-slide-toggle> |
86 | + <mat-slide-toggle formControlName="showUpdateDashboardImage"> | ||
73 | {{ 'dashboard.display-update-dashboard-image' | translate }} | 87 | {{ 'dashboard.display-update-dashboard-image' | translate }} |
74 | - </mat-checkbox> | ||
75 | - </div> | ||
76 | - <mat-checkbox formControlName="showDashboardLogo"> | ||
77 | - {{ 'dashboard.display-dashboard-logo' | translate }} | ||
78 | - </mat-checkbox> | ||
79 | - <tb-image-input fxFlex *ngIf="settingsFormGroup.get('showDashboardLogo').value" | ||
80 | - label="{{'dashboard.dashboard-logo-image' | translate}}" | ||
81 | - formControlName="dashboardLogoUrl"> | ||
82 | - </tb-image-input> | 88 | + </mat-slide-toggle> |
89 | + </fieldset> | ||
83 | </div> | 90 | </div> |
84 | - <div *ngIf="gridSettings" [formGroup]="gridSettingsFormGroup"> | ||
85 | - <tb-color-input fxFlex | ||
86 | - label="{{'layout.color' | translate}}" | ||
87 | - icon="format_color_fill" | ||
88 | - openOnInput | ||
89 | - formControlName="color"> | ||
90 | - </tb-color-input> | ||
91 | - <mat-form-field class="mat-block"> | ||
92 | - <mat-label translate>dashboard.columns-count</mat-label> | ||
93 | - <input matInput formControlName="columns" type="number" step="any" min="10" | ||
94 | - max="1000" required> | ||
95 | - <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('required')"> | ||
96 | - {{ 'dashboard.columns-count-required' | translate }} | ||
97 | - </mat-error> | ||
98 | - <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('min')"> | ||
99 | - {{ 'dashboard.min-columns-count-message' | translate }} | ||
100 | - </mat-error> | ||
101 | - <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('max')"> | ||
102 | - {{ 'dashboard.max-columns-count-message' | translate }} | ||
103 | - </mat-error> | ||
104 | - </mat-form-field> | ||
105 | - <mat-form-field fxFlex class="mat-block"> | ||
106 | - <mat-label translate>dashboard.widgets-margins</mat-label> | ||
107 | - <input matInput formControlName="margin" type="number" step="any" min="0" | ||
108 | - max="50" required> | ||
109 | - <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('required')"> | ||
110 | - {{ 'dashboard.margin-required' | translate }} | ||
111 | - </mat-error> | ||
112 | - <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('min')"> | ||
113 | - {{ 'dashboard.min-margin-message' | translate }} | ||
114 | - </mat-error> | ||
115 | - <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('max')"> | ||
116 | - {{ 'dashboard.max-margin-message' | translate }} | ||
117 | - </mat-error> | ||
118 | - </mat-form-field> | ||
119 | - <mat-checkbox fxFlex formControlName="autoFillHeight" style="display: block; padding-bottom: 12px;"> | ||
120 | - {{ 'dashboard.autofill-height' | translate }} | ||
121 | - </mat-checkbox> | ||
122 | - <tb-color-input fxFlex | ||
123 | - label="{{'dashboard.background-color' | translate}}" | ||
124 | - icon="format_color_fill" | ||
125 | - openOnInput | ||
126 | - formControlName="backgroundColor"> | ||
127 | - </tb-color-input> | ||
128 | - <tb-image-input fxFlex | ||
129 | - label="{{'dashboard.background-image' | translate}}" | ||
130 | - formControlName="backgroundImageUrl"> | ||
131 | - </tb-image-input> | ||
132 | - <mat-form-field class="mat-block"> | ||
133 | - <mat-label translate>dashboard.background-size-mode</mat-label> | ||
134 | - <mat-select formControlName="backgroundSizeMode"> | ||
135 | - <mat-option value="100%">Fit width</mat-option> | ||
136 | - <mat-option value="auto 100%">Fit height</mat-option> | ||
137 | - <mat-option value="cover">Cover</mat-option> | ||
138 | - <mat-option value="contain">Contain</mat-option> | ||
139 | - <mat-option value="auto">Original size</mat-option> | ||
140 | - </mat-select> | ||
141 | - </mat-form-field> | ||
142 | - <small translate>dashboard.mobile-layout</small> | ||
143 | - <div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs fxLayoutGap="8px" style="margin-top: 8px"> | ||
144 | - <mat-checkbox fxFlex formControlName="mobileAutoFillHeight"> | 91 | + <div *ngIf="gridSettings" [formGroup]="gridSettingsFormGroup" fxLayout="column"> |
92 | + <fieldset class="fields-group" fxLayout="column" fxLayoutGap="8px"> | ||
93 | + <legend class="group-title" translate>dashboard.layout-settings</legend> | ||
94 | + <mat-form-field class="mat-block"> | ||
95 | + <mat-label translate>dashboard.columns-count</mat-label> | ||
96 | + <input matInput formControlName="columns" type="number" step="any" min="10" | ||
97 | + max="1000" required> | ||
98 | + <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('required')"> | ||
99 | + {{ 'dashboard.columns-count-required' | translate }} | ||
100 | + </mat-error> | ||
101 | + <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('min')"> | ||
102 | + {{ 'dashboard.min-columns-count-message' | translate }} | ||
103 | + </mat-error> | ||
104 | + <mat-error *ngIf="gridSettingsFormGroup.get('columns').hasError('max')"> | ||
105 | + {{ 'dashboard.max-columns-count-message' | translate }} | ||
106 | + </mat-error> | ||
107 | + </mat-form-field> | ||
108 | + <mat-form-field fxFlex class="mat-block"> | ||
109 | + <mat-label translate>dashboard.widgets-margins</mat-label> | ||
110 | + <input matInput formControlName="margin" type="number" step="any" min="0" | ||
111 | + max="50" required> | ||
112 | + <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('required')"> | ||
113 | + {{ 'dashboard.margin-required' | translate }} | ||
114 | + </mat-error> | ||
115 | + <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('min')"> | ||
116 | + {{ 'dashboard.min-margin-message' | translate }} | ||
117 | + </mat-error> | ||
118 | + <mat-error *ngIf="gridSettingsFormGroup.get('margin').hasError('max')"> | ||
119 | + {{ 'dashboard.max-margin-message' | translate }} | ||
120 | + </mat-error> | ||
121 | + </mat-form-field> | ||
122 | + <mat-slide-toggle fxFlex formControlName="autoFillHeight" style="display: block; padding-bottom: 12px;"> | ||
123 | + {{ 'dashboard.autofill-height' | translate }} | ||
124 | + </mat-slide-toggle> | ||
125 | + <tb-color-input fxFlex | ||
126 | + label="{{'dashboard.background-color' | translate}}" | ||
127 | + icon="format_color_fill" | ||
128 | + openOnInput | ||
129 | + formControlName="backgroundColor"> | ||
130 | + </tb-color-input> | ||
131 | + <tb-image-input fxFlex | ||
132 | + label="{{'dashboard.background-image' | translate}}" | ||
133 | + formControlName="backgroundImageUrl"> | ||
134 | + </tb-image-input> | ||
135 | + <mat-form-field class="mat-block"> | ||
136 | + <mat-label translate>dashboard.background-size-mode</mat-label> | ||
137 | + <mat-select formControlName="backgroundSizeMode"> | ||
138 | + <mat-option value="100%">Fit width</mat-option> | ||
139 | + <mat-option value="auto 100%">Fit height</mat-option> | ||
140 | + <mat-option value="cover">Cover</mat-option> | ||
141 | + <mat-option value="contain">Contain</mat-option> | ||
142 | + <mat-option value="auto">Original size</mat-option> | ||
143 | + </mat-select> | ||
144 | + </mat-form-field> | ||
145 | + </fieldset> | ||
146 | + <fieldset class="fields-group" fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center" fxLayoutGap="8px"> | ||
147 | + <legend class="group-title" translate>dashboard.mobile-layout</legend> | ||
148 | + <mat-slide-toggle fxFlex formControlName="mobileAutoFillHeight"> | ||
145 | {{ 'dashboard.autofill-height' | translate }} | 149 | {{ 'dashboard.autofill-height' | translate }} |
146 | - </mat-checkbox> | 150 | + </mat-slide-toggle> |
147 | <mat-form-field fxFlex class="mat-block"> | 151 | <mat-form-field fxFlex class="mat-block"> |
148 | <mat-label translate>dashboard.mobile-row-height</mat-label> | 152 | <mat-label translate>dashboard.mobile-row-height</mat-label> |
149 | <input matInput formControlName="mobileRowHeight" type="number" step="any" min="5" | 153 | <input matInput formControlName="mobileRowHeight" type="number" step="any" min="5" |
@@ -158,7 +162,7 @@ | @@ -158,7 +162,7 @@ | ||
158 | {{ 'dashboard.max-mobile-row-height-message' | translate }} | 162 | {{ 'dashboard.max-mobile-row-height-message' | translate }} |
159 | </mat-error> | 163 | </mat-error> |
160 | </mat-form-field> | 164 | </mat-form-field> |
161 | - </div> | 165 | + </fieldset> |
162 | </div> | 166 | </div> |
163 | </fieldset> | 167 | </fieldset> |
164 | </div> | 168 | </div> |
@@ -14,13 +14,19 @@ | @@ -14,13 +14,19 @@ | ||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | :host { | 16 | :host { |
17 | - small { | ||
18 | - white-space: normal; | 17 | + .fields-group { |
18 | + padding: 0 8px 8px; | ||
19 | + margin: 10px 0; | ||
20 | + border: 1px groove rgba(0, 0, 0, .25); | ||
21 | + border-radius: 4px; | ||
22 | + legend { | ||
23 | + color: rgba(0, 0, 0, .7); | ||
24 | + } | ||
19 | } | 25 | } |
20 | } | 26 | } |
21 | 27 | ||
22 | :host ::ng-deep { | 28 | :host ::ng-deep { |
23 | - .mat-checkbox-label { | 29 | + .mat-slide-toggle-content { |
24 | white-space: normal; | 30 | white-space: normal; |
25 | } | 31 | } |
26 | } | 32 | } |
@@ -71,19 +71,33 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | @@ -71,19 +71,33 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | ||
71 | this.gridSettings = this.data.gridSettings; | 71 | this.gridSettings = this.data.gridSettings; |
72 | 72 | ||
73 | if (this.settings) { | 73 | if (this.settings) { |
74 | + const showTitle = isUndefined(this.settings.showTitle) ? true : this.settings.showTitle; | ||
75 | + const showDashboardLogo = isUndefined(this.settings.showDashboardLogo) ? false : this.settings.showDashboardLogo; | ||
76 | + const hideToolbar = isUndefined(this.settings.hideToolbar) ? false : this.settings.hideToolbar; | ||
74 | this.settingsFormGroup = this.fb.group({ | 77 | this.settingsFormGroup = this.fb.group({ |
75 | stateControllerId: [isUndefined(this.settings.stateControllerId) ? 'entity' : this.settings.stateControllerId, []], | 78 | stateControllerId: [isUndefined(this.settings.stateControllerId) ? 'entity' : this.settings.stateControllerId, []], |
76 | - toolbarAlwaysOpen: [isUndefined(this.settings.toolbarAlwaysOpen) ? true : this.settings.toolbarAlwaysOpen, []], | ||
77 | - showTitle: [isUndefined(this.settings.showTitle) ? true : this.settings.showTitle, []], | ||
78 | - titleColor: [isUndefined(this.settings.titleColor) ? 'rgba(0,0,0,0.870588)' : this.settings.titleColor, []], | ||
79 | - showDashboardsSelect: [isUndefined(this.settings.showDashboardsSelect) ? true : this.settings.showDashboardsSelect, []], | ||
80 | - showEntitiesSelect: [isUndefined(this.settings.showEntitiesSelect) ? true : this.settings.showEntitiesSelect, []], | ||
81 | - showFilters: [isUndefined(this.settings.showFilters) ? true : this.settings.showFilters, []], | ||
82 | - showDashboardLogo: [isUndefined(this.settings.showDashboardLogo) ? false : this.settings.showDashboardLogo, []], | ||
83 | - dashboardLogoUrl: [isUndefined(this.settings.dashboardLogoUrl) ? null : this.settings.dashboardLogoUrl, []], | ||
84 | - showDashboardTimewindow: [isUndefined(this.settings.showDashboardTimewindow) ? true : this.settings.showDashboardTimewindow, []], | ||
85 | - showDashboardExport: [isUndefined(this.settings.showDashboardExport) ? true : this.settings.showDashboardExport, []], | ||
86 | - showUpdateDashboardImage: [isUndefined(this.settings.showUpdateDashboardImage) ? true : this.settings.showUpdateDashboardImage, []] | 79 | + showTitle: [showTitle, []], |
80 | + titleColor: [{value: isUndefined(this.settings.titleColor) ? 'rgba(0,0,0,0.870588)' : this.settings.titleColor, | ||
81 | + disabled: !showTitle}, []], | ||
82 | + showDashboardLogo: [showDashboardLogo, []], | ||
83 | + dashboardLogoUrl: [{value: isUndefined(this.settings.dashboardLogoUrl) ? null : this.settings.dashboardLogoUrl, | ||
84 | + disabled: !showDashboardLogo}, []], | ||
85 | + hideToolbar: [hideToolbar, []], | ||
86 | + toolbarAlwaysOpen: [{value: isUndefined(this.settings.toolbarAlwaysOpen) ? true : this.settings.toolbarAlwaysOpen, | ||
87 | + disabled: hideToolbar}, []], | ||
88 | + showDashboardsSelect: [{value: isUndefined(this.settings.showDashboardsSelect) ? true : this.settings.showDashboardsSelect, | ||
89 | + disabled: hideToolbar}, []], | ||
90 | + showEntitiesSelect: [{value: isUndefined(this.settings.showEntitiesSelect) ? true : this.settings.showEntitiesSelect, | ||
91 | + disabled: hideToolbar}, []], | ||
92 | + showFilters: [{value: isUndefined(this.settings.showFilters) ? true : this.settings.showFilters, | ||
93 | + disabled: hideToolbar}, []], | ||
94 | + showDashboardTimewindow: [{value: isUndefined(this.settings.showDashboardTimewindow) ? true : this.settings.showDashboardTimewindow, | ||
95 | + disabled: hideToolbar}, []], | ||
96 | + showDashboardExport: [{value: isUndefined(this.settings.showDashboardExport) ? true : this.settings.showDashboardExport, | ||
97 | + disabled: hideToolbar}, []], | ||
98 | + showUpdateDashboardImage: [ | ||
99 | + {value: isUndefined(this.settings.showUpdateDashboardImage) ? true : this.settings.showUpdateDashboardImage, | ||
100 | + disabled: hideToolbar}, []] | ||
87 | }); | 101 | }); |
88 | this.settingsFormGroup.get('stateControllerId').valueChanges.subscribe( | 102 | this.settingsFormGroup.get('stateControllerId').valueChanges.subscribe( |
89 | (stateControllerId: StateControllerId) => { | 103 | (stateControllerId: StateControllerId) => { |
@@ -92,13 +106,52 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | @@ -92,13 +106,52 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | ||
92 | } | 106 | } |
93 | } | 107 | } |
94 | ); | 108 | ); |
109 | + this.settingsFormGroup.get('showTitle').valueChanges.subscribe( | ||
110 | + (showTitleValue: boolean) => { | ||
111 | + if (showTitleValue) { | ||
112 | + this.settingsFormGroup.get('titleColor').enable(); | ||
113 | + } else { | ||
114 | + this.settingsFormGroup.get('titleColor').disable(); | ||
115 | + } | ||
116 | + } | ||
117 | + ); | ||
118 | + this.settingsFormGroup.get('showDashboardLogo').valueChanges.subscribe( | ||
119 | + (showDashboardLogoValue: boolean) => { | ||
120 | + if (showDashboardLogoValue) { | ||
121 | + this.settingsFormGroup.get('dashboardLogoUrl').enable(); | ||
122 | + } else { | ||
123 | + this.settingsFormGroup.get('dashboardLogoUrl').disable(); | ||
124 | + } | ||
125 | + } | ||
126 | + ); | ||
127 | + this.settingsFormGroup.get('hideToolbar').valueChanges.subscribe( | ||
128 | + (hideToolbarValue: boolean) => { | ||
129 | + if (hideToolbarValue) { | ||
130 | + this.settingsFormGroup.get('toolbarAlwaysOpen').disable(); | ||
131 | + this.settingsFormGroup.get('showDashboardsSelect').disable(); | ||
132 | + this.settingsFormGroup.get('showEntitiesSelect').disable(); | ||
133 | + this.settingsFormGroup.get('showFilters').disable(); | ||
134 | + this.settingsFormGroup.get('showDashboardTimewindow').disable(); | ||
135 | + this.settingsFormGroup.get('showDashboardExport').disable(); | ||
136 | + this.settingsFormGroup.get('showUpdateDashboardImage').disable(); | ||
137 | + } else { | ||
138 | + this.settingsFormGroup.get('toolbarAlwaysOpen').enable(); | ||
139 | + this.settingsFormGroup.get('showDashboardsSelect').enable(); | ||
140 | + this.settingsFormGroup.get('showEntitiesSelect').enable(); | ||
141 | + this.settingsFormGroup.get('showFilters').enable(); | ||
142 | + this.settingsFormGroup.get('showDashboardTimewindow').enable(); | ||
143 | + this.settingsFormGroup.get('showDashboardExport').enable(); | ||
144 | + this.settingsFormGroup.get('showUpdateDashboardImage').enable(); | ||
145 | + } | ||
146 | + } | ||
147 | + ); | ||
95 | } else { | 148 | } else { |
96 | this.settingsFormGroup = this.fb.group({}); | 149 | this.settingsFormGroup = this.fb.group({}); |
97 | } | 150 | } |
98 | 151 | ||
99 | if (this.gridSettings) { | 152 | if (this.gridSettings) { |
153 | + const mobileAutoFillHeight = isUndefined(this.gridSettings.mobileAutoFillHeight) ? false : this.gridSettings.mobileAutoFillHeight; | ||
100 | this.gridSettingsFormGroup = this.fb.group({ | 154 | this.gridSettingsFormGroup = this.fb.group({ |
101 | - color: [this.gridSettings.color || 'rgba(0,0,0,0.870588)', []], | ||
102 | columns: [this.gridSettings.columns || 24, [Validators.required, Validators.min(10), Validators.max(1000)]], | 155 | columns: [this.gridSettings.columns || 24, [Validators.required, Validators.min(10), Validators.max(1000)]], |
103 | margin: [isDefined(this.gridSettings.margin) ? this.gridSettings.margin : 10, | 156 | margin: [isDefined(this.gridSettings.margin) ? this.gridSettings.margin : 10, |
104 | [Validators.required, Validators.min(0), Validators.max(50)]], | 157 | [Validators.required, Validators.min(0), Validators.max(50)]], |
@@ -106,10 +159,19 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | @@ -106,10 +159,19 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | ||
106 | backgroundColor: [this.gridSettings.backgroundColor || 'rgba(0,0,0,0)', []], | 159 | backgroundColor: [this.gridSettings.backgroundColor || 'rgba(0,0,0,0)', []], |
107 | backgroundImageUrl: [this.gridSettings.backgroundImageUrl, []], | 160 | backgroundImageUrl: [this.gridSettings.backgroundImageUrl, []], |
108 | backgroundSizeMode: [this.gridSettings.backgroundSizeMode || '100%', []], | 161 | backgroundSizeMode: [this.gridSettings.backgroundSizeMode || '100%', []], |
109 | - mobileAutoFillHeight: [isUndefined(this.gridSettings.mobileAutoFillHeight) ? false : this.gridSettings.mobileAutoFillHeight, []], | ||
110 | - mobileRowHeight: [isUndefined(this.gridSettings.mobileRowHeight) ? 70 : this.gridSettings.mobileRowHeight, | ||
111 | - [Validators.required, Validators.min(5), Validators.max(200)]] | 162 | + mobileAutoFillHeight: [mobileAutoFillHeight, []], |
163 | + mobileRowHeight: [{ value: isUndefined(this.gridSettings.mobileRowHeight) ? 70 : this.gridSettings.mobileRowHeight, | ||
164 | + disabled: mobileAutoFillHeight}, [Validators.required, Validators.min(5), Validators.max(200)]] | ||
112 | }); | 165 | }); |
166 | + this.gridSettingsFormGroup.get('mobileAutoFillHeight').valueChanges.subscribe( | ||
167 | + (mobileAutoFillHeightValue: boolean) => { | ||
168 | + if (mobileAutoFillHeightValue) { | ||
169 | + this.gridSettingsFormGroup.get('mobileRowHeight').disable(); | ||
170 | + } else { | ||
171 | + this.gridSettingsFormGroup.get('mobileRowHeight').enable(); | ||
172 | + } | ||
173 | + } | ||
174 | + ); | ||
113 | } else { | 175 | } else { |
114 | this.gridSettingsFormGroup = this.fb.group({}); | 176 | this.gridSettingsFormGroup = this.fb.group({}); |
115 | } | 177 | } |
@@ -133,10 +195,10 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | @@ -133,10 +195,10 @@ export class DashboardSettingsDialogComponent extends DialogComponent<DashboardS | ||
133 | let settings: DashboardSettings = null; | 195 | let settings: DashboardSettings = null; |
134 | let gridSettings: GridSettings = null; | 196 | let gridSettings: GridSettings = null; |
135 | if (this.settings) { | 197 | if (this.settings) { |
136 | - settings = {...this.settings, ...this.settingsFormGroup.value}; | 198 | + settings = {...this.settings, ...this.settingsFormGroup.getRawValue()}; |
137 | } | 199 | } |
138 | if (this.gridSettings) { | 200 | if (this.gridSettings) { |
139 | - gridSettings = {...this.gridSettings, ...this.gridSettingsFormGroup.value}; | 201 | + gridSettings = {...this.gridSettings, ...this.gridSettingsFormGroup.getRawValue()}; |
140 | } | 202 | } |
141 | this.dialogRef.close({settings, gridSettings}); | 203 | this.dialogRef.close({settings, gridSettings}); |
142 | } | 204 | } |
@@ -26,7 +26,6 @@ | @@ -26,7 +26,6 @@ | ||
26 | [style.backgroundImage]="backgroundImage" | 26 | [style.backgroundImage]="backgroundImage" |
27 | [ngStyle]="dashboardStyle"> | 27 | [ngStyle]="dashboardStyle"> |
28 | <section *ngIf="layoutCtx.widgets.isEmpty()" fxLayoutAlign="center center" | 28 | <section *ngIf="layoutCtx.widgets.isEmpty()" fxLayoutAlign="center center" |
29 | - [ngStyle]="{'color': layoutCtx.gridSettings.color}" | ||
30 | style="display: flex; z-index: 1; pointer-events: none;" | 29 | style="display: flex; z-index: 1; pointer-events: none;" |
31 | class="mat-headline tb-absolute-fill"> | 30 | class="mat-headline tb-absolute-fill"> |
32 | <span *ngIf="!isEdit"> | 31 | <span *ngIf="!isEdit"> |
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | <mat-icon *ngIf="icon">{{icon}}</mat-icon> | 20 | <mat-icon *ngIf="icon">{{icon}}</mat-icon> |
21 | <span *ngIf="label">{{label}}</span> | 21 | <span *ngIf="label">{{label}}</span> |
22 | </mat-label> | 22 | </mat-label> |
23 | - <div matPrefix class="tb-color-preview" (click)="showColorPicker()" style="margin-right: 5px;"> | 23 | + <div matPrefix class="tb-color-preview" (click)="!disabled && showColorPicker()" style="margin-right: 5px;"> |
24 | <div class="tb-color-result" [ngStyle]="{background: colorFormGroup.get('color').value}"></div> | 24 | <div class="tb-color-result" [ngStyle]="{background: colorFormGroup.get('color').value}"></div> |
25 | </div> | 25 | </div> |
26 | <input matInput formControlName="color" (mousedown)="openOnInput && showColorPicker()" [required]="required"> | 26 | <input matInput formControlName="color" (mousedown)="openOnInput && showColorPicker()" [required]="required"> |
@@ -45,7 +45,6 @@ export interface WidgetLayouts { | @@ -45,7 +45,6 @@ export interface WidgetLayouts { | ||
45 | 45 | ||
46 | export interface GridSettings { | 46 | export interface GridSettings { |
47 | backgroundColor?: string; | 47 | backgroundColor?: string; |
48 | - color?: string; | ||
49 | columns?: number; | 48 | columns?: number; |
50 | margin?: number; | 49 | margin?: number; |
51 | backgroundSizeMode?: string; | 50 | backgroundSizeMode?: string; |
@@ -93,6 +92,7 @@ export interface DashboardSettings { | @@ -93,6 +92,7 @@ export interface DashboardSettings { | ||
93 | showDashboardExport?: boolean; | 92 | showDashboardExport?: boolean; |
94 | showUpdateDashboardImage?: boolean; | 93 | showUpdateDashboardImage?: boolean; |
95 | toolbarAlwaysOpen?: boolean; | 94 | toolbarAlwaysOpen?: boolean; |
95 | + hideToolbar?: boolean; | ||
96 | titleColor?: string; | 96 | titleColor?: string; |
97 | } | 97 | } |
98 | 98 |
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | /// limitations under the License. | 14 | /// limitations under the License. |
15 | /// | 15 | /// |
16 | 16 | ||
17 | -export type WindowMessageType = 'widgetException' | 'widgetEditModeInited' | 'widgetEditUpdated' | 'openDashboardMessage' | 'reloadUserMessage'; | 17 | +export type WindowMessageType = 'widgetException' | 'widgetEditModeInited' | 'widgetEditUpdated' | 'openDashboardMessage' | 'reloadUserMessage' | 'toggleDashboardLayout'; |
18 | 18 | ||
19 | export interface WindowMessage { | 19 | export interface WindowMessage { |
20 | type: WindowMessageType; | 20 | type: WindowMessageType; |
@@ -721,6 +721,7 @@ | @@ -721,6 +721,7 @@ | ||
721 | "maximum-upload-file-size": "Maximum upload file size: {{ size }}", | 721 | "maximum-upload-file-size": "Maximum upload file size: {{ size }}", |
722 | "cannot-upload-file": "Cannot upload file", | 722 | "cannot-upload-file": "Cannot upload file", |
723 | "settings": "Settings", | 723 | "settings": "Settings", |
724 | + "layout-settings": "Layout settings", | ||
724 | "columns-count": "Columns count", | 725 | "columns-count": "Columns count", |
725 | "columns-count-required": "Columns count is required.", | 726 | "columns-count-required": "Columns count is required.", |
726 | "min-columns-count-message": "Only 10 minimum column count is allowed.", | 727 | "min-columns-count-message": "Only 10 minimum column count is allowed.", |
@@ -743,15 +744,19 @@ | @@ -743,15 +744,19 @@ | ||
743 | "mobile-row-height-required": "Mobile row height value is required.", | 744 | "mobile-row-height-required": "Mobile row height value is required.", |
744 | "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", | 745 | "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", |
745 | "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", | 746 | "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", |
747 | + "title-settings": "Title settings", | ||
746 | "display-title": "Display dashboard title", | 748 | "display-title": "Display dashboard title", |
747 | - "toolbar-always-open": "Keep toolbar opened", | ||
748 | "title-color": "Title color", | 749 | "title-color": "Title color", |
750 | + "toolbar-settings": "Toolbar settings", | ||
751 | + "hide-toolbar": "Hide toolbar", | ||
752 | + "toolbar-always-open": "Keep toolbar opened", | ||
749 | "display-dashboards-selection": "Display dashboards selection", | 753 | "display-dashboards-selection": "Display dashboards selection", |
750 | "display-entities-selection": "Display entities selection", | 754 | "display-entities-selection": "Display entities selection", |
751 | "display-filters": "Display filters", | 755 | "display-filters": "Display filters", |
752 | "display-dashboard-timewindow": "Display timewindow", | 756 | "display-dashboard-timewindow": "Display timewindow", |
753 | "display-dashboard-export": "Display export", | 757 | "display-dashboard-export": "Display export", |
754 | "display-update-dashboard-image": "Display update dashboard image", | 758 | "display-update-dashboard-image": "Display update dashboard image", |
759 | + "dashboard-logo-settings": "Dashboard logo settings", | ||
755 | "display-dashboard-logo": "Display logo in dashboard fullscreen mode", | 760 | "display-dashboard-logo": "Display logo in dashboard fullscreen mode", |
756 | "dashboard-logo-image": "Dashboard logo image", | 761 | "dashboard-logo-image": "Dashboard logo image", |
757 | "import": "Import dashboard", | 762 | "import": "Import dashboard", |