From dae8704c8d213b8cfbe8d44c4680c8ca4f2d9e05 Mon Sep 17 00:00:00 2001 From: Dmitriymush Date: Tue, 5 Apr 2022 13:56:44 +0300 Subject: [PATCH] 6371:dashboard_layouts_width_sizing --- .../core/services/dashboard-utils.service.ts | 46 ++++--- .../dashboard-page.component.ts | 53 ++++++-- .../dashboard-page/dashboard-page.models.ts | 10 +- .../layout/dashboard-layout.component.html | 2 +- .../layout/dashboard-layout.component.scss | 9 +- .../dashboard-page/layout/layout.models.ts | 11 ++ ...ge-dashboard-layouts-dialog.component.html | 127 +++++++++++++++--- ...ge-dashboard-layouts-dialog.component.scss | 33 +++++ ...nage-dashboard-layouts-dialog.component.ts | 89 +++++++++++- .../components/dashboard/layout-button.scss | 4 +- .../home/components/home-components.module.ts | 4 +- .../src/app/shared/models/dashboard.models.ts | 11 +- .../assets/locale/locale.constant-en_US.json | 10 +- 13 files changed, 347 insertions(+), 62 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss diff --git a/ui-ngx/src/app/core/services/dashboard-utils.service.ts b/ui-ngx/src/app/core/services/dashboard-utils.service.ts index e95990e530..500e7247fa 100644 --- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts +++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts @@ -287,12 +287,12 @@ export class DashboardUtilsService { let addedCount = 0; let removedCount = 0; for (const l of Object.keys(state.layouts)) { - if (!newLayouts[l]) { + if (!newLayouts[l] && l !== 'layoutDimension') { removedCount++; } } - for (const l of Object.keys(newLayouts)) { - if (!state.layouts[l]) { + for (const l of Object.keys(newLayouts) ) { + if (!state.layouts[l] && l !== 'layoutDimension') { addedCount++; } } @@ -301,17 +301,21 @@ export class DashboardUtilsService { let newColumns; if (addedCount) { for (const l of Object.keys(state.layouts)) { - newColumns = state.layouts[l].gridSettings.columns * (layoutsCount - addedCount) / layoutsCount; - if (newColumns > 0) { - state.layouts[l].gridSettings.columns = newColumns; + if(l !== 'layoutDimension') { + newColumns = state.layouts[l].gridSettings.columns * (layoutsCount - addedCount) / layoutsCount; + if (newColumns > 0) { + state.layouts[l].gridSettings.columns = newColumns; + } } } } if (removedCount) { for (const l of Object.keys(state.layouts)) { - newColumns = state.layouts[l].gridSettings.columns * (layoutsCount + removedCount) / layoutsCount; - if (newColumns > 0) { - state.layouts[l].gridSettings.columns = newColumns; + if(l !== 'layoutDimension') { + newColumns = state.layouts[l].gridSettings.columns * (layoutsCount + removedCount) / layoutsCount; + if (newColumns > 0) { + state.layouts[l].gridSettings.columns = newColumns; + } } } } @@ -335,18 +339,20 @@ export class DashboardUtilsService { if (state) { const result: DashboardLayoutsInfo = {}; for (const l of Object.keys(state.layouts)) { - const layout: DashboardLayout = state.layouts[l]; - if (layout) { - result[l] = { - widgetIds: [], - widgetLayouts: {}, - gridSettings: {} - } as DashboardLayoutInfo; - for (const id of Object.keys(layout.widgets)) { - result[l].widgetIds.push(id); + if(l !== 'layoutDimension') { + const layout: DashboardLayout = state.layouts[l]; + if (layout) { + result[l] = { + widgetIds: [], + widgetLayouts: {}, + gridSettings: {} + } as DashboardLayoutInfo; + for (const id of Object.keys(layout.widgets)) { + result[l].widgetIds.push(id); + } + result[l].widgetLayouts = layout.widgets; + result[l].gridSettings = layout.gridSettings; } - result[l].widgetLayouts = layout.widgets; - result[l].gridSettings = layout.gridSettings; } } return result; diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index c360846941..9c2a521acd 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -266,7 +266,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC ctrl: null, dashboardCtrl: this } - } + }, + layoutDimension: null }; addWidgetFabButtons: FooterFabButtons = { @@ -654,7 +655,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC if (this.isEditingWidget && this.editingLayoutCtx.id === 'main') { return '100%'; } else { - return this.layouts.right.show && !this.isMobile ? '50%' : '100%'; + return this.layouts.right.show && !this.isMobile ? this.calculateWidth('main') : '100%'; } } @@ -670,10 +671,32 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC if (this.isEditingWidget && this.editingLayoutCtx.id === 'right') { return '100%'; } else { - return this.isMobile ? '100%' : '50%'; + return this.isMobile ? '100%' : this.calculateWidth('right'); } } + private calculateWidth(layout: string): string { + const layoutDimension = this.dashboard.configuration.states[this.dashboardCtx.state].layouts.layoutDimension; + if (layoutDimension) { + if (layoutDimension.type === 'percentage') { + if(layout === 'right') { + return (100 - layoutDimension.leftWidthPercentage) + '%'; + } else { + return layoutDimension.leftWidthPercentage + '%'; + } + } else { + if (layoutDimension.fixedLayout === layout) { + return layoutDimension.fixedWidth + 'px'; + } else { + const layoutWidth = this.dashboardContainer.nativeElement.getBoundingClientRect().width - layoutDimension.fixedWidth; + return layoutWidth + 'px'; + } + } + } else { + return '50%'; + } + } + public rightLayoutHeight(): string { if (!this.isEditingWidget || this.editingLayoutCtx.id === 'right') { return '100%'; @@ -887,13 +910,15 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC } for (const l of Object.keys(this.layouts)) { const layout: DashboardPageLayout = this.layouts[l]; - if (layoutsData[l]) { - layout.show = true; - const layoutInfo: DashboardLayoutInfo = layoutsData[l]; - this.updateLayout(layout, layoutInfo); - } else { - layout.show = false; - this.updateLayout(layout, {widgetIds: [], widgetLayouts: {}, gridSettings: null}); + if(l !== 'layoutDimension') { + if (layoutsData[l]) { + layout.show = true; + const layoutInfo: DashboardLayoutInfo = layoutsData[l]; + this.updateLayout(layout, layoutInfo); + } else { + layout.show = false; + this.updateLayout(layout, {widgetIds: [], widgetLayouts: {}, gridSettings: null}); + } } } } @@ -942,9 +967,11 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC private resetHighlight() { for (const l of Object.keys(this.layouts)) { - if (this.layouts[l].layoutCtx) { - if (this.layouts[l].layoutCtx.ctrl) { - this.layouts[l].layoutCtx.ctrl.resetHighlight(); + if(l !== 'layoutDimension' ) { + if (this.layouts[l].layoutCtx) { + if (this.layouts[l].layoutCtx.ctrl) { + this.layouts[l].layoutCtx.ctrl.resetHighlight(); + } } } } diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts index 4fadc96039..de11bf24f2 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts @@ -14,7 +14,13 @@ /// limitations under the License. /// -import { Dashboard, DashboardLayoutId, GridSettings, WidgetLayouts } from '@app/shared/models/dashboard.models'; +import { + Dashboard, + DashboardLayoutId, + GridSettings, + LayoutDimension, + WidgetLayouts +} from '@app/shared/models/dashboard.models'; import { Widget, WidgetPosition } from '@app/shared/models/widget.models'; import { Timewindow } from '@shared/models/time/time.models'; import { IAliasController, IStateController } from '@core/api/widget-api.models'; @@ -68,7 +74,7 @@ export interface DashboardPageLayout { layoutCtx: DashboardPageLayoutContext; } -export declare type DashboardPageLayouts = {[key in DashboardLayoutId]: DashboardPageLayout}; +export declare type DashboardPageLayouts = {[key in DashboardLayoutId | 'layoutDimension']: DashboardPageLayout & LayoutDimension}; export class LayoutWidgetsArray implements Iterable { diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.html index 4e7d11255b..3c3e6b9110 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.html @@ -34,7 +34,7 @@ -
+
- {{ 'layout.main' | translate }} + {{ (layoutsFormGroup.value.right ? 'layout.left' : 'layout.main') | translate }} {{ 'layout.right' | translate }}
-
- - +
+
+ + +
+
+ + + {{ 'layout.percentage-width' | translate }} + + + {{ 'layout.fixed-width' | translate }} + + +
+
+ +
+
+
+ + {{ 'layout.left-width' | translate }} + + + + {{ 'layout.right-width' | translate }} + + +
+ {{'layout.layout-min-max' | translate: { min: 10, max: 90 } }} +
+
+
+
+ + + + {{ 'layout.left' | translate }} + + + {{ 'layout.right' | translate }} + + +
+
+ + {{ 'layout.layout-fixed-width' | translate }} + + + {{ 'layout.layout-min-max' | translate: {min: 150, max: 1700 } }} +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss new file mode 100644 index 0000000000..b660dc60d0 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + ::ng-deep .mat-slider-wrapper { + + .mat-slider-thumb-container { + .mat-slider-thumb-label { + width: 35px; + height: 35px; + } + } + } + + .tb-layout-fixed-container { + width: 100%; + min-width: 368px; + padding: 8px 8px 8px 0; + min-height: 48px; + } +} diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts index bc61fd46e4..cebaa4c7ae 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts @@ -19,7 +19,7 @@ import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms'; +import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { UtilsService } from '@core/services/utils.service'; @@ -31,6 +31,8 @@ import { DashboardSettingsDialogComponent, DashboardSettingsDialogData } from '@home/components/dashboard-page/dashboard-settings-dialog.component'; +import { MatSliderChange } from "@angular/material/slider"; +import { LaouytType, LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models"; export interface ManageDashboardLayoutsDialogData { layouts: DashboardStateLayouts; @@ -40,7 +42,7 @@ export interface ManageDashboardLayoutsDialogData { selector: 'tb-manage-dashboard-layouts-dialog', templateUrl: './manage-dashboard-layouts-dialog.component.html', providers: [{provide: ErrorStateMatcher, useExisting: ManageDashboardLayoutsDialogComponent}], - styleUrls: ['../../../components/dashboard/layout-button.scss'] + styleUrls: ['./manage-dashboard-layouts-dialog.component.scss', '../../../components/dashboard/layout-button.scss'] }) export class ManageDashboardLayoutsDialogComponent extends DialogComponent implements OnInit, ErrorStateMatcher { @@ -67,14 +69,29 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent 90) { + widthValue = 90; + } else if (Number(($event.target as any).value) < 10) { + widthValue = 10; + } else { + widthValue = Number(($event.target as any).value); + } + if(layout === LaouytType.MAIN) { + this.layoutsFormGroup.get('leftWidthPercentage').setValue(widthValue); + } else { + this.layoutsFormGroup.get('leftWidthPercentage').setValue(100 - widthValue); + } + this.layoutsFormGroup.markAsDirty(); + } + + formatSliderTooltipLabel(value: number):string { + return `${value}|${100 - value}`; + } + + sliderChange($event: MatSliderChange) { + this.layoutsFormGroup.get('leftWidthPercentage').setValue($event.value); + } } diff --git a/ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss b/ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss index 89d036db08..9b80660c1f 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss +++ b/ui-ngx/src/app/modules/home/components/dashboard/layout-button.scss @@ -17,7 +17,9 @@ button.tb-layout-button { width: 100%; height: 100%; - padding: 40px 20px; + padding: 40px 10px; + transition-duration: 0.5s; + transition-property: max-width; } &::ng-deep { diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 0c58328e46..1b26096084 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -17,6 +17,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@app/shared/shared.module'; +import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { AddEntityDialogComponent } from '@home/components/entity/add-entity-dialog.component'; import { EntitiesTableComponent } from '@home/components/entity/entities-table.component'; import { DetailsPanelComponent } from '@home/components/details-panel.component'; @@ -277,7 +278,8 @@ import { EntityDetailsPageComponent } from '@home/components/entity/entity-detai SnmpDeviceProfileTransportModule, StatesControllerModule, DeviceCredentialsModule, - DeviceProfileCommonModule + DeviceProfileCommonModule, + MatButtonToggleModule ], exports: [ EntitiesTableComponent, diff --git a/ui-ngx/src/app/shared/models/dashboard.models.ts b/ui-ngx/src/app/shared/models/dashboard.models.ts index 4332e484f6..c6dd45aa22 100644 --- a/ui-ngx/src/app/shared/models/dashboard.models.ts +++ b/ui-ngx/src/app/shared/models/dashboard.models.ts @@ -69,9 +69,18 @@ export interface DashboardLayoutInfo { gridSettings?: GridSettings; } +export interface LayoutDimension { + type?: LayoutType, + fixedWidth?: number, + fixedLayout?: DashboardLayoutId, + leftWidthPercentage?: number +} + export declare type DashboardLayoutId = 'main' | 'right'; -export declare type DashboardStateLayouts = {[key in DashboardLayoutId]?: DashboardLayout}; +export declare type LayoutType = 'percentage' | 'fixed'; + +export declare type DashboardStateLayouts = {[key in DashboardLayoutId | 'layoutDimension']?: DashboardLayout & LayoutDimension }; export declare type DashboardLayoutsInfo = {[key in DashboardLayoutId]?: DashboardLayoutInfo}; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 4021f7af29..4bd1802fe6 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2344,7 +2344,15 @@ "color": "Color", "main": "Main", "right": "Right", - "select": "Select target layout" + "left": "Left", + "select": "Select target layout", + "percentage-width": "Percentage width (%)", + "fixed-width": "Fixed width (px)", + "left-width": "Left width (%)", + "right-width": "Right width (%)", + "pick-fixed-side": "Fixed side: ", + "layout-fixed-width": "Fixed width (px)", + "layout-min-max": "Width should not be lower then {{min}} and higher then {{max}}" }, "legend": { "direction": "Legend direction",