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 1df19d7496..51f01c7a1b 100644
--- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts
+++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts
@@ -18,6 +18,7 @@ import { Injectable } from '@angular/core';
import { UtilsService } from '@core/services/utils.service';
import { TimeService } from '@core/services/time.service';
import {
+ BreakpointInfo,
BreakpointLayoutInfo,
Dashboard,
DashboardConfiguration,
@@ -51,12 +52,15 @@ import { initModelFromDefaultTimewindow } from '@shared/models/time/time.models'
import { AlarmSearchStatus } from '@shared/models/alarm.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { BackgroundType, colorBackground, isBackgroundSettings } from '@shared/models/widget-settings.models';
+import { MediaBreakpoints } from '@shared/models/constants';
@Injectable({
providedIn: 'root'
})
export class DashboardUtilsService {
+ private systemBreakpoints: BreakpointInfo[];
+
constructor(private utils: UtilsService,
private timeService: TimeService) {
}
@@ -996,4 +1000,21 @@ export class DashboardUtilsService {
};
}
+ private loadSystemBreakpoints() {
+ this.systemBreakpoints=[{id: 'default'}];
+ const dashboardMediaBreakpointIds = ['xs', 'sm', 'md', 'lg', 'xl'];
+ dashboardMediaBreakpointIds.forEach(breakpoint => {
+ const value = MediaBreakpoints[breakpoint];
+ const minWidth = value.match(/min-width:\s*(\d+)px/);
+ const maxWidth = value.match(/max-width:\s*(\d+)px/);
+ this.systemBreakpoints.push({id: breakpoint, minWidth: minWidth?.[1], maxWidth: maxWidth?.[1]});
+ });
+ }
+
+ getListBreakpoint(): BreakpointInfo[] {
+ if(!this.systemBreakpoints) {
+ this.loadSystemBreakpoints();
+ }
+ return this.systemBreakpoints;
+ }
}
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html
index a20c118f2a..e69be1e684 100644
--- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html
+++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.html
@@ -58,9 +58,9 @@
view_compact
{{'layout.layouts' | translate}}
-
-
+
;
breakpoint: string;
widgets: LayoutWidgetsArray;
widgetLayouts: WidgetLayouts;
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts
index 451c9ed7f5..31bbf5e2ab 100644
--- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts
+++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts
@@ -343,21 +343,4 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo
return this.layoutCtx.layoutData.default;
}
- createBreakpointConfig(breakpoint: string) {
- const currentDashboard = this.dashboardCtx.getDashboard();
- const dashboardConfiguration = currentDashboard.configuration;
- const states = dashboardConfiguration.states;
- const state = states[this.dashboardCtx.state];
- const layout = state.layouts[this.layoutCtx.id];
- if (!layout.breakpoints) {
- layout.breakpoints = {};
- }
- layout.breakpoints[breakpoint] = {
- gridSettings: deepClone(layout.gridSettings),
- widgets: deepClone(layout.widgets),
- };
- this.layoutCtx.layoutData =
- this.dashboardUtils.getStateLayoutsData(currentDashboard, this.dashboardCtx.state)[this.layoutCtx.id];
- }
-
}
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts
index a905e5c079..6aa69c51af 100644
--- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts
+++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts
@@ -22,7 +22,6 @@ export interface ILayoutController {
pasteWidget($event: MouseEvent);
pasteWidgetReference($event: MouseEvent);
updatedCurrentBreakpoint(breakpoint?: string, showLayout?: boolean);
- createBreakpointConfig(breakpoint?: string);
}
export enum LayoutWidthType {
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 c879b755b3..11e81c332f 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
@@ -33,6 +33,7 @@ import { DialogComponent } from '@app/shared/components/dialog.component';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import {
+ BreakpointInfo,
DashboardLayout,
DashboardLayoutId,
DashboardStateLayouts,
@@ -53,7 +54,6 @@ import {
import { Subscription } from 'rxjs';
import { MatTooltip } from '@angular/material/tooltip';
import { TbTableDatasource } from '@shared/components/table/table-datasource.abstract';
-import { MediaBreakpoints } from '@shared/models/constants';
export interface ManageDashboardLayoutsDialogData {
layouts: DashboardStateLayouts;
@@ -101,16 +101,10 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent,
@@ -128,6 +122,11 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent {
+ this.breakpointsData[breakpoint.id] = breakpoint;
+ });
+
let layoutType = LayoutType.default;
if (isDefined(this.layouts.right)) {
layoutType = LayoutType.divider;
@@ -217,7 +216,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent !this.selectedBreakpointIds.includes(item));
this.dataSource.loadData(this.layoutBreakpoints);
@@ -259,15 +258,6 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent {
- this.dataSource = new DashboardLayoutDatasource();
- this.dataSource.loadData(this.layoutBreakpoints);
- }
- ));
}
ngOnDestroy(): void {
@@ -491,11 +481,13 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent
-
- {{ layout }}
+
+ {{ breakpointId }}
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.scss b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.scss
similarity index 90%
rename from ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.scss
rename to ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.scss
index 253ce75901..278afa87ad 100644
--- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.scss
+++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.scss
@@ -16,10 +16,14 @@
:host {
pointer-events: all;
width: min-content; //for Safari
+
+ .hidden {
+ display: none;
+ }
}
:host ::ng-deep {
- .mat-mdc-select.select-dashboard-layout {
+ .mat-mdc-select.select-dashboard-breakpoint {
.mat-mdc-select-value {
max-width: 200px;
}
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.ts
new file mode 100644
index 0000000000..f00c3e2557
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-breakpoint.component.ts
@@ -0,0 +1,69 @@
+///
+/// Copyright © 2016-2024 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.
+///
+
+import { Component, Input, OnDestroy, OnInit } from '@angular/core';
+import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
+import { Subscription } from 'rxjs';
+import { BreakpointInfo } from '@shared/models/dashboard.models';
+import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
+
+@Component({
+ selector: 'tb-select-dashboard-breakpoint',
+ templateUrl: './select-dashboard-breakpoint.component.html',
+ styleUrls: ['./select-dashboard-breakpoint.component.scss']
+})
+export class SelectDashboardBreakpointComponent implements OnInit, OnDestroy {
+
+ @Input()
+ dashboardCtrl: DashboardPageComponent;
+
+ selectedBreakpoint = 'default';
+
+ breakpointsData: {[breakpointId in string]: BreakpointInfo} = {};
+
+ breakpointIds: Array = ['default'];
+
+ private layoutDataChanged$: Subscription;
+
+ constructor(private dashboardUtils: DashboardUtilsService) {
+ this.dashboardUtils.getListBreakpoint().forEach((breakpoint) => {
+ this.breakpointsData[breakpoint.id] = breakpoint;
+ });
+ }
+
+ ngOnInit() {
+ this.layoutDataChanged$ = this.dashboardCtrl.layouts.main.layoutCtx.layoutDataChanged.subscribe(() => {
+ if (this.dashboardCtrl.layouts.main.layoutCtx.layoutData) {
+ this.breakpointIds = Object.keys(this.dashboardCtrl.layouts.main.layoutCtx?.layoutData);
+ if (this.breakpointIds.indexOf(this.dashboardCtrl.layouts.main.layoutCtx.breakpoint) > -1) {
+ this.selectedBreakpoint = this.dashboardCtrl.layouts.main.layoutCtx.breakpoint;
+ } else {
+ this.selectedBreakpoint = 'default';
+ this.dashboardCtrl.layouts.main.layoutCtx.breakpoint = this.selectedBreakpoint;
+ }
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this.layoutDataChanged$.unsubscribe();
+ }
+
+ selectLayoutChanged() {
+ this.dashboardCtrl.layouts.main.layoutCtx.ctrl.updatedCurrentBreakpoint(this.selectedBreakpoint);
+ this.dashboardCtrl.updateLayoutSizes();
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.ts
deleted file mode 100644
index ccce03bd20..0000000000
--- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/select-dashboard-layout.component.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-///
-/// Copyright © 2016-2024 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.
-///
-
-import { Component, Input, OnDestroy, OnInit } from '@angular/core';
-import { DashboardPageComponent } from '@home/components/dashboard-page/dashboard-page.component';
-import { Subscription } from 'rxjs';
-
-@Component({
- selector: 'tb-select-dashboard-layout',
- templateUrl: './select-dashboard-layout.component.html',
- styleUrls: ['./select-dashboard-layout.component.scss']
-})
-export class SelectDashboardLayoutComponent implements OnInit, OnDestroy {
-
- @Input()
- dashboardCtrl: DashboardPageComponent;
-
- layout = {
- default: 'Default',
- xs: 'xs',
- sm: 'sm',
- md: 'md',
- lg: 'lg',
- xl: 'xl'
- };
-
- layouts = Object.keys(this.layout);
-
- selectLayout = 'default';
-
- private allowBreakpointsSize = new Set();
-
- private stateChanged$: Subscription;
-
- constructor() { }
-
- ngOnInit() {
- this.stateChanged$ = this.dashboardCtrl.dashboardCtx.stateChanged.subscribe(() => {
- if (this.dashboardCtrl.layouts.main.layoutCtx.layoutData) {
- this.allowBreakpointsSize = new Set(Object.keys(this.dashboardCtrl.layouts.main.layoutCtx?.layoutData));
- } else {
- this.allowBreakpointsSize.add('default');
- }
- if (this.allowBreakpointsSize.has(this.dashboardCtrl.layouts.main.layoutCtx.breakpoint)) {
- this.selectLayout = this.dashboardCtrl.layouts.main.layoutCtx.breakpoint;
- } else {
- this.selectLayout = 'default';
- this.dashboardCtrl.layouts.main.layoutCtx.breakpoint = this.selectLayout;
- }
- });
- }
-
- ngOnDestroy() {
- this.stateChanged$.unsubscribe();
- }
-
- selectLayoutChanged() {
- if (!this.dashboardCtrl.layouts.main.layoutCtx.layoutData[this.selectLayout]) {
- this.dashboardCtrl.layouts.main.layoutCtx.ctrl.createBreakpointConfig(this.selectLayout);
- }
- this.dashboardCtrl.layouts.main.layoutCtx.ctrl.updatedCurrentBreakpoint(this.selectLayout);
- this.dashboardCtrl.updateLayoutSizes();
- }
-}
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 66d5cc6162..94d58d767c 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
@@ -176,8 +176,8 @@ import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/ba
import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delete-timeseries-panel.component';
import { MoveWidgetsDialogComponent } from '@home/components/dashboard-page/layout/move-widgets-dialog.component';
import {
- SelectDashboardLayoutComponent
-} from '@home/components/dashboard-page/layout/select-dashboard-layout.component';
+ SelectDashboardBreakpointComponent
+} from '@home/components/dashboard-page/layout/select-dashboard-breakpoint.component';
@NgModule({
declarations:
@@ -288,7 +288,7 @@ import {
DashboardPageComponent,
DashboardStateComponent,
DashboardLayoutComponent,
- SelectDashboardLayoutComponent,
+ SelectDashboardBreakpointComponent,
EditWidgetComponent,
DashboardWidgetSelectComponent,
AddWidgetDialogComponent,
@@ -422,7 +422,7 @@ import {
DashboardPageComponent,
DashboardStateComponent,
DashboardLayoutComponent,
- SelectDashboardLayoutComponent,
+ SelectDashboardBreakpointComponent,
EditWidgetComponent,
DashboardWidgetSelectComponent,
AddWidgetDialogComponent,
diff --git a/ui-ngx/src/app/shared/models/dashboard.models.ts b/ui-ngx/src/app/shared/models/dashboard.models.ts
index 074c1e787a..1d22ffbcfb 100644
--- a/ui-ngx/src/app/shared/models/dashboard.models.ts
+++ b/ui-ngx/src/app/shared/models/dashboard.models.ts
@@ -85,10 +85,10 @@ export interface GridSettings {
export interface DashboardLayout {
widgets: WidgetLayouts;
gridSettings: GridSettings;
- breakpoints?: {[breakpoint: string]: Omit};
+ breakpoints?: {[breakpointId: string]: Omit};
}
-export declare type DashboardLayoutInfo = {[breakpoint: string]: BreakpointLayoutInfo};
+export declare type DashboardLayoutInfo = {[breakpointId: string]: BreakpointLayoutInfo};
export interface BreakpointLayoutInfo {
widgetIds?: string[];
@@ -96,6 +96,12 @@ export interface BreakpointLayoutInfo {
gridSettings?: GridSettings;
}
+export interface BreakpointInfo {
+ id: string;
+ maxWidth?: number;
+ minWidth?: number;
+}
+
export interface LayoutDimension {
type?: LayoutDimensionType;
fixedWidth?: number;