UI: Added support difference dashboard layout for one state
This commit is contained in:
parent
ea662bc26a
commit
963160efa6
@ -18,11 +18,11 @@ import { Injectable } from '@angular/core';
|
|||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { TimeService } from '@core/services/time.service';
|
import { TimeService } from '@core/services/time.service';
|
||||||
import {
|
import {
|
||||||
|
BreakpointLayoutInfo,
|
||||||
Dashboard,
|
Dashboard,
|
||||||
DashboardConfiguration,
|
DashboardConfiguration,
|
||||||
DashboardLayout,
|
DashboardLayout,
|
||||||
DashboardLayoutId,
|
DashboardLayoutId,
|
||||||
DashboardLayoutInfo,
|
|
||||||
DashboardLayoutsInfo,
|
DashboardLayoutsInfo,
|
||||||
DashboardState,
|
DashboardState,
|
||||||
DashboardStateLayouts,
|
DashboardStateLayouts,
|
||||||
@ -520,16 +520,14 @@ export class DashboardUtilsService {
|
|||||||
for (const l of Object.keys(state.layouts)) {
|
for (const l of Object.keys(state.layouts)) {
|
||||||
const layout: DashboardLayout = state.layouts[l];
|
const layout: DashboardLayout = state.layouts[l];
|
||||||
if (layout) {
|
if (layout) {
|
||||||
result[l] = {
|
result[l]= {
|
||||||
widgetIds: [],
|
default: this.getBreakpointLayoutData(layout)
|
||||||
widgetLayouts: {},
|
};
|
||||||
gridSettings: {}
|
if (layout.breakpoints) {
|
||||||
} as DashboardLayoutInfo;
|
for (const breakpoint of Object.keys(layout.breakpoints)) {
|
||||||
for (const id of Object.keys(layout.widgets)) {
|
result[l][breakpoint] = this.getBreakpointLayoutData(layout.breakpoints[breakpoint]);
|
||||||
result[l].widgetIds.push(id);
|
}
|
||||||
}
|
}
|
||||||
result[l].widgetLayouts = layout.widgets;
|
|
||||||
result[l].gridSettings = layout.gridSettings;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -538,6 +536,20 @@ export class DashboardUtilsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getBreakpointLayoutData(layout: DashboardLayout): BreakpointLayoutInfo {
|
||||||
|
const result: BreakpointLayoutInfo = {
|
||||||
|
widgetIds: [],
|
||||||
|
widgetLayouts: {},
|
||||||
|
gridSettings: {}
|
||||||
|
};
|
||||||
|
for (const id of Object.keys(layout.widgets)) {
|
||||||
|
result.widgetIds.push(id);
|
||||||
|
}
|
||||||
|
result.widgetLayouts = layout.widgets;
|
||||||
|
result.gridSettings = layout.gridSettings;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public getWidgetsArray(dashboard: Dashboard): Array<Widget> {
|
public getWidgetsArray(dashboard: Dashboard): Array<Widget> {
|
||||||
const widgetsArray: Array<Widget> = [];
|
const widgetsArray: Array<Widget> = [];
|
||||||
const dashboardConfiguration = dashboard.configuration;
|
const dashboardConfiguration = dashboard.configuration;
|
||||||
@ -564,11 +576,15 @@ export class DashboardUtilsService {
|
|||||||
originalColumns?: number,
|
originalColumns?: number,
|
||||||
originalSize?: {sizeX: number; sizeY: number},
|
originalSize?: {sizeX: number; sizeY: number},
|
||||||
row?: number,
|
row?: number,
|
||||||
column?: number): void {
|
column?: number,
|
||||||
|
breakpoint = 'default'): void {
|
||||||
const dashboardConfiguration = dashboard.configuration;
|
const dashboardConfiguration = dashboard.configuration;
|
||||||
const states = dashboardConfiguration.states;
|
const states = dashboardConfiguration.states;
|
||||||
const state = states[targetState];
|
const state = states[targetState];
|
||||||
const layout = state.layouts[targetLayout];
|
let layout = state.layouts[targetLayout];
|
||||||
|
if (breakpoint !== 'default' && layout.breakpoints?.[breakpoint]) {
|
||||||
|
layout = layout.breakpoints[breakpoint];
|
||||||
|
}
|
||||||
const layoutCount = Object.keys(state.layouts).length;
|
const layoutCount = Object.keys(state.layouts).length;
|
||||||
if (!widget.id) {
|
if (!widget.id) {
|
||||||
widget.id = this.utils.guid();
|
widget.id = this.utils.guid();
|
||||||
@ -626,12 +642,17 @@ export class DashboardUtilsService {
|
|||||||
public removeWidgetFromLayout(dashboard: Dashboard,
|
public removeWidgetFromLayout(dashboard: Dashboard,
|
||||||
targetState: string,
|
targetState: string,
|
||||||
targetLayout: DashboardLayoutId,
|
targetLayout: DashboardLayoutId,
|
||||||
widgetId: string) {
|
widgetId: string,
|
||||||
|
breakpoint: string) {
|
||||||
const dashboardConfiguration = dashboard.configuration;
|
const dashboardConfiguration = dashboard.configuration;
|
||||||
const states = dashboardConfiguration.states;
|
const states = dashboardConfiguration.states;
|
||||||
const state = states[targetState];
|
const state = states[targetState];
|
||||||
const layout = state.layouts[targetLayout];
|
const layout = state.layouts[targetLayout];
|
||||||
|
if (layout.breakpoints[breakpoint]) {
|
||||||
|
delete layout.breakpoints[breakpoint].widgets[widgetId];
|
||||||
|
} else {
|
||||||
delete layout.widgets[widgetId];
|
delete layout.widgets[widgetId];
|
||||||
|
}
|
||||||
this.removeUnusedWidgets(dashboard);
|
this.removeUnusedWidgets(dashboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,11 +721,19 @@ export class DashboardUtilsService {
|
|||||||
for (const s of Object.keys(states)) {
|
for (const s of Object.keys(states)) {
|
||||||
const state = states[s];
|
const state = states[s];
|
||||||
for (const l of Object.keys(state.layouts)) {
|
for (const l of Object.keys(state.layouts)) {
|
||||||
const layout = state.layouts[l];
|
const layout: DashboardLayout = state.layouts[l];
|
||||||
if (layout.widgets[widgetId]) {
|
if (layout.widgets[widgetId]) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (layout.breakpoints) {
|
||||||
|
for (const breakpoint of Object.keys(layout.breakpoints)) {
|
||||||
|
if (layout.breakpoints[breakpoint].widgets[widgetId]) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
|||||||
@ -56,6 +56,7 @@ export interface WidgetReference {
|
|||||||
widgetId: string;
|
widgetId: string;
|
||||||
originalSize: WidgetSize;
|
originalSize: WidgetSize;
|
||||||
originalColumns: number;
|
originalColumns: number;
|
||||||
|
breakpoint: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuleNodeConnection {
|
export interface RuleNodeConnection {
|
||||||
@ -85,7 +86,8 @@ export class ItemBufferService {
|
|||||||
private ruleChainService: RuleChainService,
|
private ruleChainService: RuleChainService,
|
||||||
private utils: UtilsService) {}
|
private utils: UtilsService) {}
|
||||||
|
|
||||||
public prepareWidgetItem(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget): WidgetItem {
|
public prepareWidgetItem(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId,
|
||||||
|
widget: Widget, breakpoint: string): WidgetItem {
|
||||||
const aliasesInfo: AliasesInfo = {
|
const aliasesInfo: AliasesInfo = {
|
||||||
datasourceAliases: {},
|
datasourceAliases: {},
|
||||||
targetDeviceAlias: null
|
targetDeviceAlias: null
|
||||||
@ -93,8 +95,8 @@ export class ItemBufferService {
|
|||||||
const filtersInfo: FiltersInfo = {
|
const filtersInfo: FiltersInfo = {
|
||||||
datasourceFilters: {}
|
datasourceFilters: {}
|
||||||
};
|
};
|
||||||
const originalColumns = this.getOriginalColumns(dashboard, sourceState, sourceLayout);
|
const originalColumns = this.getOriginalColumns(dashboard, sourceState, sourceLayout, breakpoint);
|
||||||
const originalSize = this.getOriginalSize(dashboard, sourceState, sourceLayout, widget);
|
const originalSize = this.getOriginalSize(dashboard, sourceState, sourceLayout, widget, breakpoint);
|
||||||
const datasources: Datasource[] = widget.type === widgetType.alarm ? [widget.config.alarmSource] : widget.config.datasources;
|
const datasources: Datasource[] = widget.type === widgetType.alarm ? [widget.config.alarmSource] : widget.config.datasources;
|
||||||
if (widget.config && dashboard.configuration
|
if (widget.config && dashboard.configuration
|
||||||
&& dashboard.configuration.entityAliases) {
|
&& dashboard.configuration.entityAliases) {
|
||||||
@ -146,13 +148,14 @@ export class ItemBufferService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public copyWidget(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget): void {
|
public copyWidget(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget, breakpoint: string): void {
|
||||||
const widgetItem = this.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget);
|
const widgetItem = this.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget, breakpoint);
|
||||||
this.storeSet(WIDGET_ITEM, widgetItem);
|
this.storeSet(WIDGET_ITEM, widgetItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public copyWidgetReference(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget): void {
|
public copyWidgetReference(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId,
|
||||||
const widgetReference = this.prepareWidgetReference(dashboard, sourceState, sourceLayout, widget);
|
widget: Widget, breakpoint: string): void {
|
||||||
|
const widgetReference = this.prepareWidgetReference(dashboard, sourceState, sourceLayout, widget, breakpoint);
|
||||||
this.storeSet(WIDGET_REFERENCE, widgetReference);
|
this.storeSet(WIDGET_REFERENCE, widgetReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,11 +163,11 @@ export class ItemBufferService {
|
|||||||
return this.storeHas(WIDGET_ITEM);
|
return this.storeHas(WIDGET_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
public canPasteWidgetReference(dashboard: Dashboard, state: string, layout: DashboardLayoutId): boolean {
|
public canPasteWidgetReference(dashboard: Dashboard, state: string, layout: DashboardLayoutId, breakpoint: string): boolean {
|
||||||
const widgetReference: WidgetReference = this.storeGet(WIDGET_REFERENCE);
|
const widgetReference: WidgetReference = this.storeGet(WIDGET_REFERENCE);
|
||||||
if (widgetReference) {
|
if (widgetReference) {
|
||||||
if (widgetReference.dashboardId === dashboard.id.id) {
|
if (widgetReference.dashboardId === dashboard.id.id) {
|
||||||
if ((widgetReference.sourceState !== state || widgetReference.sourceLayout !== layout)
|
if ((widgetReference.sourceState !== state || widgetReference.sourceLayout !== layout || widgetReference.breakpoint !== breakpoint)
|
||||||
&& dashboard.configuration.widgets[widgetReference.widgetId]) {
|
&& dashboard.configuration.widgets[widgetReference.widgetId]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -387,13 +390,17 @@ export class ItemBufferService {
|
|||||||
return ruleChainImport;
|
return ruleChainImport;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOriginalColumns(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId): number {
|
private getOriginalColumns(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId,
|
||||||
|
breakpoint: string): number {
|
||||||
let originalColumns = 24;
|
let originalColumns = 24;
|
||||||
let gridSettings = null;
|
let gridSettings = null;
|
||||||
const state = dashboard.configuration.states[sourceState];
|
const state = dashboard.configuration.states[sourceState];
|
||||||
const layoutCount = Object.keys(state.layouts).length;
|
const layoutCount = Object.keys(state.layouts).length;
|
||||||
if (state) {
|
if (state) {
|
||||||
const layout = state.layouts[sourceLayout];
|
let layout = state.layouts[sourceLayout];
|
||||||
|
if (breakpoint !== 'default') {
|
||||||
|
layout = layout.breakpoints[breakpoint];
|
||||||
|
}
|
||||||
if (layout) {
|
if (layout) {
|
||||||
gridSettings = layout.gridSettings;
|
gridSettings = layout.gridSettings;
|
||||||
|
|
||||||
@ -407,8 +414,12 @@ export class ItemBufferService {
|
|||||||
return originalColumns;
|
return originalColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOriginalSize(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget): WidgetSize {
|
private getOriginalSize(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget,
|
||||||
const layout = dashboard.configuration.states[sourceState].layouts[sourceLayout];
|
breakpoint: string): WidgetSize {
|
||||||
|
let layout = dashboard.configuration.states[sourceState].layouts[sourceLayout];
|
||||||
|
if (breakpoint !== 'default') {
|
||||||
|
layout = layout.breakpoints[breakpoint];
|
||||||
|
}
|
||||||
const widgetLayout = layout.widgets[widget.id];
|
const widgetLayout = layout.widgets[widget.id];
|
||||||
return {
|
return {
|
||||||
sizeX: widgetLayout.sizeX,
|
sizeX: widgetLayout.sizeX,
|
||||||
@ -432,16 +443,17 @@ export class ItemBufferService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private prepareWidgetReference(dashboard: Dashboard, sourceState: string,
|
private prepareWidgetReference(dashboard: Dashboard, sourceState: string,
|
||||||
sourceLayout: DashboardLayoutId, widget: Widget): WidgetReference {
|
sourceLayout: DashboardLayoutId, widget: Widget, breakpoint: string): WidgetReference {
|
||||||
const originalColumns = this.getOriginalColumns(dashboard, sourceState, sourceLayout);
|
const originalColumns = this.getOriginalColumns(dashboard, sourceState, sourceLayout, breakpoint);
|
||||||
const originalSize = this.getOriginalSize(dashboard, sourceState, sourceLayout, widget);
|
const originalSize = this.getOriginalSize(dashboard, sourceState, sourceLayout, widget, breakpoint);
|
||||||
return {
|
return {
|
||||||
dashboardId: dashboard.id.id,
|
dashboardId: dashboard.id.id,
|
||||||
sourceState,
|
sourceState,
|
||||||
sourceLayout,
|
sourceLayout,
|
||||||
widgetId: widget.id,
|
widgetId: widget.id,
|
||||||
originalSize,
|
originalSize,
|
||||||
originalColumns
|
originalColumns,
|
||||||
|
breakpoint
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,9 @@
|
|||||||
<mat-icon>view_compact</mat-icon>
|
<mat-icon>view_compact</mat-icon>
|
||||||
{{'layout.layouts' | translate}}
|
{{'layout.layouts' | translate}}
|
||||||
</button>
|
</button>
|
||||||
|
<tb-select-dashboard-layout
|
||||||
|
[dashboardCtrl]="this">
|
||||||
|
</tb-select-dashboard-layout>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<tb-states-component fxFlex.lt-md
|
<tb-states-component fxFlex.lt-md
|
||||||
|
|||||||
@ -40,7 +40,6 @@ import { Store } from '@ngrx/store';
|
|||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { AuthService } from '@core/auth/auth.service';
|
|
||||||
import {
|
import {
|
||||||
Dashboard,
|
Dashboard,
|
||||||
DashboardConfiguration,
|
DashboardConfiguration,
|
||||||
@ -66,7 +65,7 @@ import {
|
|||||||
IDashboardController,
|
IDashboardController,
|
||||||
LayoutWidgetsArray
|
LayoutWidgetsArray
|
||||||
} from './dashboard-page.models';
|
} from './dashboard-page.models';
|
||||||
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||||
import { MediaBreakpoints } from '@shared/models/constants';
|
import { MediaBreakpoints } from '@shared/models/constants';
|
||||||
import { AuthUser } from '@shared/models/user.model';
|
import { AuthUser } from '@shared/models/user.model';
|
||||||
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
||||||
@ -83,7 +82,7 @@ import { Authority } from '@shared/models/authority.enum';
|
|||||||
import { DialogService } from '@core/services/dialog.service';
|
import { DialogService } from '@core/services/dialog.service';
|
||||||
import { EntityService } from '@core/http/entity.service';
|
import { EntityService } from '@core/http/entity.service';
|
||||||
import { AliasController } from '@core/api/alias-controller';
|
import { AliasController } from '@core/api/alias-controller';
|
||||||
import { Observable, of, Subscription } from 'rxjs';
|
import { Observable, of, Subject, Subscription } from 'rxjs';
|
||||||
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||||
import { DashboardService } from '@core/http/dashboard.service';
|
import { DashboardService } from '@core/http/dashboard.service';
|
||||||
import {
|
import {
|
||||||
@ -138,14 +137,14 @@ import {
|
|||||||
DashboardImageDialogData,
|
DashboardImageDialogData,
|
||||||
DashboardImageDialogResult
|
DashboardImageDialogResult
|
||||||
} from '@home/components/dashboard-page/dashboard-image-dialog.component';
|
} from '@home/components/dashboard-page/dashboard-image-dialog.component';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
import { SafeUrl } from '@angular/platform-browser';
|
||||||
import cssjs from '@core/css/css';
|
import cssjs from '@core/css/css';
|
||||||
import { DOCUMENT } from '@angular/common';
|
import { DOCUMENT } from '@angular/common';
|
||||||
import { IAliasController } from '@core/api/widget-api.models';
|
import { IAliasController } from '@core/api/widget-api.models';
|
||||||
import { MatButton } from '@angular/material/button';
|
import { MatButton } from '@angular/material/button';
|
||||||
import { VersionControlComponent } from '@home/components/vc/version-control.component';
|
import { VersionControlComponent } from '@home/components/vc/version-control.component';
|
||||||
import { TbPopoverService } from '@shared/components/popover.service';
|
import { TbPopoverService } from '@shared/components/popover.service';
|
||||||
import { map, tap } from 'rxjs/operators';
|
import { distinctUntilChanged, map, skip, tap } from 'rxjs/operators';
|
||||||
import { LayoutFixedSize, LayoutWidthType } from '@home/components/dashboard-page/layout/layout.models';
|
import { LayoutFixedSize, LayoutWidthType } from '@home/components/dashboard-page/layout/layout.models';
|
||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
import { ResizeObserver } from '@juggle/resize-observer';
|
import { ResizeObserver } from '@juggle/resize-observer';
|
||||||
@ -268,6 +267,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
getDashboard: () => this.dashboard,
|
getDashboard: () => this.dashboard,
|
||||||
dashboardTimewindow: null,
|
dashboardTimewindow: null,
|
||||||
state: null,
|
state: null,
|
||||||
|
breakpoint: null,
|
||||||
stateController: null,
|
stateController: null,
|
||||||
stateChanged: null,
|
stateChanged: null,
|
||||||
stateId: null,
|
stateId: null,
|
||||||
@ -280,24 +280,28 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
show: false,
|
show: false,
|
||||||
layoutCtx: {
|
layoutCtx: {
|
||||||
id: 'main',
|
id: 'main',
|
||||||
|
breakpoint: 'default',
|
||||||
widgets: null,
|
widgets: null,
|
||||||
widgetLayouts: {},
|
widgetLayouts: {},
|
||||||
gridSettings: {},
|
gridSettings: {},
|
||||||
ignoreLoading: true,
|
ignoreLoading: true,
|
||||||
ctrl: null,
|
ctrl: null,
|
||||||
dashboardCtrl: this
|
dashboardCtrl: this,
|
||||||
|
layoutData: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
show: false,
|
show: false,
|
||||||
layoutCtx: {
|
layoutCtx: {
|
||||||
id: 'right',
|
id: 'right',
|
||||||
|
breakpoint: 'default',
|
||||||
widgets: null,
|
widgets: null,
|
||||||
widgetLayouts: {},
|
widgetLayouts: {},
|
||||||
gridSettings: {},
|
gridSettings: {},
|
||||||
ignoreLoading: true,
|
ignoreLoading: true,
|
||||||
ctrl: null,
|
ctrl: null,
|
||||||
dashboardCtrl: this
|
dashboardCtrl: this,
|
||||||
|
layoutData: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -331,6 +335,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
|
|
||||||
@ViewChild('dashboardWidgetSelect') dashboardWidgetSelectComponent: DashboardWidgetSelectComponent;
|
@ViewChild('dashboardWidgetSelect') dashboardWidgetSelectComponent: DashboardWidgetSelectComponent;
|
||||||
|
|
||||||
|
private changeMobileSize = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
@Inject(WINDOW) private window: Window,
|
@Inject(WINDOW) private window: Window,
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
@ -339,7 +345,6 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private utils: UtilsService,
|
private utils: UtilsService,
|
||||||
private dashboardUtils: DashboardUtilsService,
|
private dashboardUtils: DashboardUtilsService,
|
||||||
private authService: AuthService,
|
|
||||||
private entityService: EntityService,
|
private entityService: EntityService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private widgetComponentService: WidgetComponentService,
|
private widgetComponentService: WidgetComponentService,
|
||||||
@ -357,7 +362,6 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
private overlay: Overlay,
|
private overlay: Overlay,
|
||||||
private viewContainerRef: ViewContainerRef,
|
private viewContainerRef: ViewContainerRef,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
public elRef: ElementRef,
|
public elRef: ElementRef,
|
||||||
private injector: Injector) {
|
private injector: Injector) {
|
||||||
super(store);
|
super(store);
|
||||||
@ -402,13 +406,56 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
this.rxSubscriptions.push(this.breakpointObserver
|
this.rxSubscriptions.push(
|
||||||
.observe(MediaBreakpoints['gt-sm'])
|
this.changeMobileSize.pipe(
|
||||||
.subscribe((state: BreakpointState) => {
|
distinctUntilChanged(),
|
||||||
this.isMobile = !state.matches;
|
).subscribe((state) => {
|
||||||
|
this.isMobile = state;
|
||||||
|
this.updateLayoutSizes();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.rxSubscriptions.push(
|
||||||
|
this.breakpointObserver.observe([
|
||||||
|
MediaBreakpoints.xs,
|
||||||
|
MediaBreakpoints.sm,
|
||||||
|
MediaBreakpoints.md,
|
||||||
|
MediaBreakpoints.lg,
|
||||||
|
MediaBreakpoints.xl
|
||||||
|
]).pipe(
|
||||||
|
map(value => {
|
||||||
|
if (value.breakpoints[MediaBreakpoints.xs]) {
|
||||||
|
return 'xs';
|
||||||
|
} else if (value.breakpoints[MediaBreakpoints.sm]) {
|
||||||
|
return 'sm';
|
||||||
|
} else if (value.breakpoints[MediaBreakpoints.md]) {
|
||||||
|
return 'md';
|
||||||
|
} else if (value.breakpoints[MediaBreakpoints.lg]) {
|
||||||
|
return 'lg';
|
||||||
|
} else {
|
||||||
|
return 'xl';
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
tap((value) => {
|
||||||
|
this.dashboardCtx.breakpoint = value;
|
||||||
|
this.changeMobileSize.next(value === 'xs' || value === 'sm');
|
||||||
|
}),
|
||||||
|
distinctUntilChanged((prev, next) => {
|
||||||
|
if (this.layouts.right.show || this.isEdit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const allowAdditionalPrevLayout = !!this.layouts.main.layoutCtx.layoutData?.[prev];
|
||||||
|
const allowAdditionalNextLayout = !!this.layouts.main.layoutCtx?.layoutData?.[next];
|
||||||
|
return !(allowAdditionalNextLayout || allowAdditionalPrevLayout !== allowAdditionalNextLayout);
|
||||||
|
}),
|
||||||
|
skip(1)
|
||||||
|
).subscribe((value) => {
|
||||||
|
this.layouts.main.layoutCtx.ctrl.updatedCurrentBreakpoint();
|
||||||
this.updateLayoutSizes();
|
this.updateLayoutSizes();
|
||||||
}
|
}
|
||||||
));
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (this.isMobileApp && this.syncStateWithQueryParam) {
|
if (this.isMobileApp && this.syncStateWithQueryParam) {
|
||||||
this.mobileService.registerToggleLayoutFunction(() => {
|
this.mobileService.registerToggleLayoutFunction(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -694,7 +741,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
this.mobileService.onDashboardRightLayoutChanged(this.isRightLayoutOpened);
|
this.mobileService.onDashboardRightLayoutChanged(this.isRightLayoutOpened);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateLayoutSizes() {
|
public updateLayoutSizes() {
|
||||||
let changeMainLayoutSize = false;
|
let changeMainLayoutSize = false;
|
||||||
let changeRightLayoutSize = false;
|
let changeRightLayoutSize = false;
|
||||||
if (this.dashboardCtx.state) {
|
if (this.dashboardCtx.state) {
|
||||||
@ -1025,21 +1072,14 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
this.updateLayout(layout, layoutInfo);
|
this.updateLayout(layout, layoutInfo);
|
||||||
} else {
|
} else {
|
||||||
layout.show = false;
|
layout.show = false;
|
||||||
this.updateLayout(layout, {widgetIds: [], widgetLayouts: {}, gridSettings: null});
|
this.updateLayout(layout, {default: {widgetIds: [], widgetLayouts: {}, gridSettings: null}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateLayout(layout: DashboardPageLayout, layoutInfo: DashboardLayoutInfo) {
|
private updateLayout(layout: DashboardPageLayout, layoutInfo: DashboardLayoutInfo) {
|
||||||
if (layoutInfo.gridSettings) {
|
layout.layoutCtx.layoutData = layoutInfo;
|
||||||
layout.layoutCtx.gridSettings = layoutInfo.gridSettings;
|
layout.layoutCtx.ctrl?.updatedCurrentBreakpoint(null, layout.show);
|
||||||
}
|
|
||||||
layout.layoutCtx.widgets.setWidgetIds(layoutInfo.widgetIds);
|
|
||||||
layout.layoutCtx.widgetLayouts = layoutInfo.widgetLayouts;
|
|
||||||
if (layout.show && layout.layoutCtx.ctrl) {
|
|
||||||
layout.layoutCtx.ctrl.reload();
|
|
||||||
}
|
|
||||||
layout.layoutCtx.ignoreLoading = true;
|
|
||||||
this.updateLayoutSizes();
|
this.updateLayoutSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,8 +1198,10 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private addWidgetToLayout(widget: Widget, layoutId: DashboardLayoutId) {
|
private addWidgetToLayout(widget: Widget, layoutId: DashboardLayoutId) {
|
||||||
this.dashboardUtils.addWidgetToLayout(this.dashboard, this.dashboardCtx.state, layoutId, widget);
|
const layoutCtx = this.layouts[layoutId].layoutCtx;
|
||||||
this.layouts[layoutId].layoutCtx.widgets.addWidgetId(widget.id);
|
this.dashboardUtils.addWidgetToLayout(this.dashboard, this.dashboardCtx.state, layoutId, widget, undefined,
|
||||||
|
undefined, -1, -1, layoutCtx.breakpoint);
|
||||||
|
layoutCtx.widgets.addWidgetId(widget.id);
|
||||||
this.runChangeDetection();
|
this.runChangeDetection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1303,12 +1345,12 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
|
|
||||||
copyWidget($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
copyWidget($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
||||||
this.itembuffer.copyWidget(this.dashboard,
|
this.itembuffer.copyWidget(this.dashboard,
|
||||||
this.dashboardCtx.state, layoutCtx.id, widget);
|
this.dashboardCtx.state, layoutCtx.id, widget, layoutCtx.breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyWidgetReference($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
copyWidgetReference($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
||||||
this.itembuffer.copyWidgetReference(this.dashboard,
|
this.itembuffer.copyWidgetReference(this.dashboard,
|
||||||
this.dashboardCtx.state, layoutCtx.id, widget);
|
this.dashboardCtx.state, layoutCtx.id, widget, layoutCtx.breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteWidget($event: Event, layoutCtx: DashboardPageLayoutContext, pos: WidgetPosition) {
|
pasteWidget($event: Event, layoutCtx: DashboardPageLayoutContext, pos: WidgetPosition) {
|
||||||
@ -1343,7 +1385,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
).subscribe((res) => {
|
).subscribe((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
if (layoutCtx.widgets.removeWidgetId(widget.id)) {
|
if (layoutCtx.widgets.removeWidgetId(widget.id)) {
|
||||||
this.dashboardUtils.removeWidgetFromLayout(this.dashboard, this.dashboardCtx.state, layoutCtx.id, widget.id);
|
this.dashboardUtils.removeWidgetFromLayout(this.dashboard, this.dashboardCtx.state, layoutCtx.id,
|
||||||
|
widget.id, layoutCtx.breakpoint);
|
||||||
this.runChangeDetection();
|
this.runChangeDetection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1352,7 +1395,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
|
|
||||||
exportWidget($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget, widgetTitle: string) {
|
exportWidget($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget, widgetTitle: string) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.importExport.exportWidget(this.dashboard, this.dashboardCtx.state, layoutCtx.id, widget, widgetTitle);
|
this.importExport.exportWidget(this.dashboard, this.dashboardCtx.state, layoutCtx.id, widget, widgetTitle, layoutCtx.breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
widgetClicked($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
widgetClicked($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) {
|
||||||
@ -1402,7 +1445,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
|
|||||||
action: ($event) => {
|
action: ($event) => {
|
||||||
layoutCtx.ctrl.pasteWidgetReference($event);
|
layoutCtx.ctrl.pasteWidgetReference($event);
|
||||||
},
|
},
|
||||||
enabled: this.itembuffer.canPasteWidgetReference(this.dashboard, this.dashboardCtx.state, layoutCtx.id),
|
enabled: this.itembuffer.canPasteWidgetReference(this.dashboard, this.dashboardCtx.state, layoutCtx.id, layoutCtx.breakpoint),
|
||||||
value: 'action.paste-reference',
|
value: 'action.paste-reference',
|
||||||
icon: 'content_paste',
|
icon: 'content_paste',
|
||||||
shortcut: 'M-I'
|
shortcut: 'M-I'
|
||||||
|
|||||||
@ -14,7 +14,13 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { Dashboard, DashboardLayoutId, GridSettings, WidgetLayouts } from '@app/shared/models/dashboard.models';
|
import {
|
||||||
|
Dashboard,
|
||||||
|
DashboardLayoutId,
|
||||||
|
DashboardLayoutInfo,
|
||||||
|
GridSettings,
|
||||||
|
WidgetLayouts
|
||||||
|
} from '@app/shared/models/dashboard.models';
|
||||||
import { Widget, WidgetPosition } from '@app/shared/models/widget.models';
|
import { Widget, WidgetPosition } from '@app/shared/models/widget.models';
|
||||||
import { Timewindow } from '@shared/models/time/time.models';
|
import { Timewindow } from '@shared/models/time/time.models';
|
||||||
import { IAliasController, IStateController } from '@core/api/widget-api.models';
|
import { IAliasController, IStateController } from '@core/api/widget-api.models';
|
||||||
@ -34,6 +40,7 @@ export interface DashboardPageInitData {
|
|||||||
export interface DashboardContext {
|
export interface DashboardContext {
|
||||||
instanceId: string;
|
instanceId: string;
|
||||||
state: string;
|
state: string;
|
||||||
|
breakpoint: string;
|
||||||
getDashboard: () => Dashboard;
|
getDashboard: () => Dashboard;
|
||||||
dashboardTimewindow: Timewindow;
|
dashboardTimewindow: Timewindow;
|
||||||
aliasController: IAliasController;
|
aliasController: IAliasController;
|
||||||
@ -63,6 +70,8 @@ export interface IDashboardController {
|
|||||||
|
|
||||||
export interface DashboardPageLayoutContext {
|
export interface DashboardPageLayoutContext {
|
||||||
id: DashboardLayoutId;
|
id: DashboardLayoutId;
|
||||||
|
layoutData: DashboardLayoutInfo;
|
||||||
|
breakpoint: string;
|
||||||
widgets: LayoutWidgetsArray;
|
widgets: LayoutWidgetsArray;
|
||||||
widgetLayouts: WidgetLayouts;
|
widgetLayouts: WidgetLayouts;
|
||||||
gridSettings: GridSettings;
|
gridSettings: GridSettings;
|
||||||
|
|||||||
@ -36,6 +36,8 @@ import { TbCheatSheetComponent } from '@shared/components/cheatsheet.component';
|
|||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
import { ImagePipe } from '@shared/pipe/image.pipe';
|
import { ImagePipe } from '@shared/pipe/image.pipe';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
import { deepClone, isNotEmptyStr } from '@core/utils';
|
||||||
|
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-dashboard-layout',
|
selector: 'tb-dashboard-layout',
|
||||||
@ -95,7 +97,8 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo
|
|||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private itembuffer: ItemBufferService,
|
private itembuffer: ItemBufferService,
|
||||||
private imagePipe: ImagePipe,
|
private imagePipe: ImagePipe,
|
||||||
private sanitizer: DomSanitizer) {
|
private sanitizer: DomSanitizer,
|
||||||
|
private dashboardUtils: DashboardUtilsService,) {
|
||||||
super(store);
|
super(store);
|
||||||
this.initHotKeys();
|
this.initHotKeys();
|
||||||
}
|
}
|
||||||
@ -161,7 +164,7 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo
|
|||||||
new Hotkey('ctrl+i', (event: KeyboardEvent) => {
|
new Hotkey('ctrl+i', (event: KeyboardEvent) => {
|
||||||
if (this.isEdit && !this.isEditingWidget && !this.widgetEditMode) {
|
if (this.isEdit && !this.isEditingWidget && !this.widgetEditMode) {
|
||||||
if (this.itembuffer.canPasteWidgetReference(this.dashboardCtx.getDashboard(),
|
if (this.itembuffer.canPasteWidgetReference(this.dashboardCtx.getDashboard(),
|
||||||
this.dashboardCtx.state, this.layoutCtx.id)) {
|
this.dashboardCtx.state, this.layoutCtx.id, this.layoutCtx.breakpoint)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.pasteWidgetReference(event);
|
this.pasteWidgetReference(event);
|
||||||
}
|
}
|
||||||
@ -268,4 +271,45 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo
|
|||||||
this.layoutCtx.dashboardCtrl.pasteWidgetReference($event, this.layoutCtx, pos);
|
this.layoutCtx.dashboardCtrl.pasteWidgetReference($event, this.layoutCtx, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatedCurrentBreakpoint(breakpoint?: string, showLayout = true) {
|
||||||
|
if (!isNotEmptyStr(breakpoint)) {
|
||||||
|
breakpoint = this.dashboardCtx.breakpoint;
|
||||||
|
}
|
||||||
|
this.layoutCtx.breakpoint = breakpoint;
|
||||||
|
const layoutInfo = this.getLayoutDataForBreakpoint(breakpoint);
|
||||||
|
if (layoutInfo.gridSettings) {
|
||||||
|
this.layoutCtx.gridSettings = layoutInfo.gridSettings;
|
||||||
|
}
|
||||||
|
this.layoutCtx.widgets.setWidgetIds(layoutInfo.widgetIds);
|
||||||
|
this.layoutCtx.widgetLayouts = layoutInfo.widgetLayouts;
|
||||||
|
if (showLayout && this.layoutCtx.ctrl) {
|
||||||
|
this.layoutCtx.ctrl.reload();
|
||||||
|
}
|
||||||
|
this.layoutCtx.ignoreLoading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getLayoutDataForBreakpoint(breakpoint: string) {
|
||||||
|
if (this.layoutCtx.layoutData[breakpoint]) {
|
||||||
|
return this.layoutCtx.layoutData[breakpoint];
|
||||||
|
}
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ export interface ILayoutController {
|
|||||||
selectWidget(widgetId: string, delay?: number);
|
selectWidget(widgetId: string, delay?: number);
|
||||||
pasteWidget($event: MouseEvent);
|
pasteWidget($event: MouseEvent);
|
||||||
pasteWidgetReference($event: MouseEvent);
|
pasteWidgetReference($event: MouseEvent);
|
||||||
|
updatedCurrentBreakpoint(breakpoint?: string, showLayout?: boolean);
|
||||||
|
createBreakpointConfig(breakpoint?: string);
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LayoutWidthType {
|
export enum LayoutWidthType {
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<mat-select
|
||||||
|
class="select-dashboard-layout"
|
||||||
|
[(ngModel)]="selectLayout"
|
||||||
|
(ngModelChange)="selectLayoutChanged()">
|
||||||
|
<mat-option *ngFor="let layout of layouts" [value]="layout">
|
||||||
|
{{ layout }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
:host {
|
||||||
|
pointer-events: all;
|
||||||
|
width: min-content; //for Safari
|
||||||
|
}
|
||||||
|
|
||||||
|
:host ::ng-deep {
|
||||||
|
.mat-mdc-select.select-dashboard-layout {
|
||||||
|
.mat-mdc-select-value {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
.mat-mdc-select-arrow {
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
///
|
||||||
|
/// 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<string>();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -171,6 +171,9 @@ import {
|
|||||||
import { WidgetConfigComponentsModule } from '@home/components/widget/config/widget-config-components.module';
|
import { WidgetConfigComponentsModule } from '@home/components/widget/config/widget-config-components.module';
|
||||||
import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/basic-widget-config.module';
|
import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/basic-widget-config.module';
|
||||||
import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delete-timeseries-panel.component';
|
import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delete-timeseries-panel.component';
|
||||||
|
import {
|
||||||
|
SelectDashboardLayoutComponent
|
||||||
|
} from '@home/components/dashboard-page/layout/select-dashboard-layout.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations:
|
declarations:
|
||||||
@ -280,6 +283,7 @@ import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delet
|
|||||||
DashboardPageComponent,
|
DashboardPageComponent,
|
||||||
DashboardStateComponent,
|
DashboardStateComponent,
|
||||||
DashboardLayoutComponent,
|
DashboardLayoutComponent,
|
||||||
|
SelectDashboardLayoutComponent,
|
||||||
EditWidgetComponent,
|
EditWidgetComponent,
|
||||||
DashboardWidgetSelectComponent,
|
DashboardWidgetSelectComponent,
|
||||||
AddWidgetDialogComponent,
|
AddWidgetDialogComponent,
|
||||||
@ -411,6 +415,7 @@ import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delet
|
|||||||
DashboardPageComponent,
|
DashboardPageComponent,
|
||||||
DashboardStateComponent,
|
DashboardStateComponent,
|
||||||
DashboardLayoutComponent,
|
DashboardLayoutComponent,
|
||||||
|
SelectDashboardLayoutComponent,
|
||||||
EditWidgetComponent,
|
EditWidgetComponent,
|
||||||
DashboardWidgetSelectComponent,
|
DashboardWidgetSelectComponent,
|
||||||
AddWidgetDialogComponent,
|
AddWidgetDialogComponent,
|
||||||
|
|||||||
@ -198,8 +198,9 @@ export class ImportExportService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public exportWidget(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget, widgetTitle: string) {
|
public exportWidget(dashboard: Dashboard, sourceState: string, sourceLayout: DashboardLayoutId, widget: Widget,
|
||||||
const widgetItem = this.itembuffer.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget);
|
widgetTitle: string, breakpoint: string) {
|
||||||
|
const widgetItem = this.itembuffer.prepareWidgetItem(dashboard, sourceState, sourceLayout, widget, breakpoint);
|
||||||
const widgetDefaultName = this.widgetService.getWidgetInfoFromCache(widget.typeFullFqn).widgetName;
|
const widgetDefaultName = this.widgetService.getWidgetInfoFromCache(widget.typeFullFqn).widgetName;
|
||||||
let fileName = widgetDefaultName + (isNotEmptyStr(widgetTitle) ? `_${widgetTitle}` : '');
|
let fileName = widgetDefaultName + (isNotEmptyStr(widgetTitle) ? `_${widgetTitle}` : '');
|
||||||
fileName = fileName.toLowerCase().replace(/\W/g, '_');
|
fileName = fileName.toLowerCase().replace(/\W/g, '_');
|
||||||
|
|||||||
@ -67,9 +67,12 @@ export interface GridSettings {
|
|||||||
export interface DashboardLayout {
|
export interface DashboardLayout {
|
||||||
widgets: WidgetLayouts;
|
widgets: WidgetLayouts;
|
||||||
gridSettings: GridSettings;
|
gridSettings: GridSettings;
|
||||||
|
breakpoints?: {[breakpoint: string]: Omit<DashboardLayout, 'breakpoints'>};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DashboardLayoutInfo {
|
export declare type DashboardLayoutInfo = {[breakpoint: string]: BreakpointLayoutInfo};
|
||||||
|
|
||||||
|
export interface BreakpointLayoutInfo {
|
||||||
widgetIds?: string[];
|
widgetIds?: string[];
|
||||||
widgetLayouts?: WidgetLayouts;
|
widgetLayouts?: WidgetLayouts;
|
||||||
gridSettings?: GridSettings;
|
gridSettings?: GridSettings;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user