Browse Source

UI: Add support manage dashboard layout

pull/11430/head
Vladyslav_Prykhodko 2 years ago
parent
commit
51dfba02f7
  1. 1
      ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts
  2. 173
      ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.html
  3. 34
      ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss
  4. 184
      ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts
  5. 6
      ui-ngx/src/app/shared/models/dashboard.models.ts
  6. 1
      ui-ngx/src/assets/locale/locale.constant-en_US.json

1
ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts

@ -483,6 +483,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
if (!this.widgetEditMode && !this.readonly && this.dashboardUtils.isEmptyDashboard(this.dashboard)) {
this.setEditMode(true, false);
}
this.setEditMode(true, false);
}
private init(data: DashboardPageInitData) {

173
ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.html

@ -26,15 +26,171 @@
</button>
</mat-toolbar>
<div mat-dialog-content fxLayout="column" fxLayoutGap="20px" style="min-width: 300px; overflow: hidden;">
<div fxLayout="row" fxLayoutAlign="start center">
<mat-slide-toggle formControlName="right" color="accent">
{{ 'layout.divider' | translate }}
</mat-slide-toggle>
<div class="tb-form-row space-between">
<div class="fixed-title-width" translate>dashboard.layout</div>
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="layoutType">
<mat-option *ngFor="let type of layoutTypes" [value]="type">
{{ layoutTypeTranslations.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<!-- <div fxLayout="row" fxLayoutAlign="start center">-->
<!-- <mat-slide-toggle formControlName="right" color="accent">-->
<!-- {{ 'layout.divider' | translate }}-->
<!-- </mat-slide-toggle>-->
<!-- </div>-->
<div *ngIf="!isDividerLayout; else dividerLayout" class="tb-form-panel no-padding no-border">
<!-- <div class="tb-form-table tb-layout-breakpoints">-->
<!-- <div class="tb-form-table-header">-->
<!-- <div class="tb-form-table-header-cell tb-icon-breakpoint"></div>-->
<!-- <div class="tb-form-table-header-cell tb-devices-header">Devices</div>-->
<!-- <div class="tb-form-table-header-cell tb-size-header">Size</div>-->
<!-- <div class="tb-form-table-header-cell tb-actions-header"></div>-->
<!-- </div>-->
<!-- <div class="tb-form-table-body">-->
<!-- <div class="tb-form-table-row">-->
<!-- <div class="tb-form-table-row-cell tb-icon-breakpoint"></div>-->
<!-- <div class="tb-form-table-row-cell tb-devices-header">Default</div>-->
<!-- <div class="tb-form-table-row-cell tb-size-header"></div>-->
<!-- <div class="tb-form-table-row-cell tb-actions-header">-->
<!-- <button mat-icon-button class="tb-mat-20"-->
<!-- (click)="openLayoutSettings('main')"-->
<!-- type="button" >-->
<!-- <mat-icon>settings</mat-icon>-->
<!-- </button>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="tb-form-table-row">-->
<!-- <div class="tb-form-table-row-cell tb-icon-breakpoint"></div>-->
<!-- <div class="tb-form-table-row-cell tb-devices-header">Md</div>-->
<!-- <div class="tb-form-table-row-cell tb-size-header"></div>-->
<!-- <div class="tb-form-table-row-cell tb-actions-header">-->
<!-- <button mat-icon-button class="tb-mat-20"-->
<!-- (click)="openLayoutSettings('main')"-->
<!-- type="button" >-->
<!-- <mat-icon>settings</mat-icon>-->
<!-- </button>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="table-container" style="width: 700px">
<table mat-table [dataSource]="dataSource">
<ng-container [matColumnDef]="'icon'">
<mat-header-cell *matHeaderCellDef [style]="{ minWidth: '48px', maxWidth: '48px', width: '48px', textAlign: 'center'}">
</mat-header-cell>
<mat-cell *matCellDef="let breakpoint" [style]="{ minWidth: '48px', maxWidth: '48px', width: '48px', textAlign: 'center'}">
<tb-icon>{{ breakpoint.icon }}</tb-icon>
</mat-cell>
</ng-container>
<ng-container [matColumnDef]="'name'">
<mat-header-cell *matHeaderCellDef style="width: 15%;min-width: 15%;max-width: 15%;padding-left:0">
Breakpoints
</mat-header-cell>
<mat-cell *matCellDef="let breakpoint" style="width: 15%;min-width: 15%;max-width: 15%;">
{{ breakpoint.name }}
</mat-cell>
</ng-container>
<ng-container [matColumnDef]="'descriptionSize'" style="width: 85%;min-width: 85%;max-width: 85%;">
<mat-header-cell *matHeaderCellDef>
Size
</mat-header-cell>
<mat-cell *matCellDef="let breakpoint" style="width: 85%;min-width: 85%;max-width: 85%;">
{{ breakpoint.descriptionSize }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px', textAlign: 'center'}">
</mat-header-cell>
<mat-cell *matCellDef="let breakpoint"
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px'}">
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-icon-button
(click)="openLayoutSettings('main', breakpoint.breakpoint)"
type="button" >
<mat-icon>settings</mat-icon>
</button>
<button mat-icon-button
[disabled]="breakpoint.breakpoint === 'default'"
(click)="deleteBreakpoint(breakpoint.breakpoint)"
type="button" >
<tb-icon>delete</tb-icon>
</button>
</div>
<div fxHide fxShow.lt-lg fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
<mat-icon class="material-icons">more_vert</mat-icon>
</button>
<mat-menu #cellActionsMenu="matMenu" xPosition="before">
<button mat-icon-button
(click)="openLayoutSettings('main', breakpoint.breakpoint)"
type="button" >
<mat-icon>settings</mat-icon>
</button>
<button mat-icon-button
(click)="openLayoutSettings('main')"
type="button" >
<tb-icon>delete</tb-icon>-->
</button>
</mat-menu>
</div>
</mat-cell>
</ng-container>
<mat-header-row class="mat-row-select" *matHeaderRowDef="['icon', 'name', 'descriptionSize', 'actions']; sticky: true"></mat-header-row>
<mat-row *matRowDef="let breakpoint; columns: ['icon', 'name', 'descriptionSize', 'actions']"></mat-row>
</table>
</div>
<button mat-button fxFlex class="tb-add-breakpoint-button"
matTooltip="Add breakpoint"
matTooltipPosition="above"
type="button"
*ngIf="!addBreakpointMode"
(click)="addBreakpoint()">
<mat-icon>add</mat-icon>
</button>
<div *ngIf="addBreakpointMode" class="tb-form-row space-between column-lt-md" [formGroup]="addBreakpointFormGroup">
<div fxLayout="row" fxFlex.lt-md fxLayoutAlign="start center" fxLayoutGap="8px">
<div>Add breakpoint</div>
<mat-form-field fxFlex.lt-md appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="new">
<mat-option *ngFor="let breakpoint of allowLayoutBreakpoints" [value]="breakpoint">
{{ breakpoint }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="row" fxFlex.lt-md fxLayoutAlign="start center" fxLayoutGap="8px">
<div>Copy from</div>
<mat-form-field fxFlex.lt-md appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="copyFrom">
<mat-option *ngFor="let breakpoint of selectedLayoutBreakpoints" [value]="breakpoint">
{{ breakpoint }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayoutGap="8px">
<button mat-icon-button class="tb-mat-20"
type="button" (click)="createdBreakPoint()">
<tb-icon>check</tb-icon>
</button>
<button mat-icon-button class="tb-mat-20"
type="button" (click)="addBreakpoint()">
<tb-icon>close</tb-icon>
</button>
</div>
</div>
</div>
<ng-template #dividerLayout>
<div fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="20px">
<mat-button-toggle-group aria-label="Select width value type"
formControlName="type"
[fxShow]="layoutsFormGroup.get('right').value">
[fxShow]="isDividerLayout">
<mat-button-toggle fxFlex value="percentage">
{{ 'layout.percentage-width' | translate }}
</mat-button-toggle>
@ -72,7 +228,7 @@
<span [matTooltip]="layoutButtonText('main')"
#mainLayoutTooltip="matTooltip"
matTooltipPosition="above">
{{ (layoutsFormGroup.value.right ? 'layout.left' : 'layout.main') | translate }}
{{ (isDividerLayout ? 'layout.left' : 'layout.main') | translate }}
</span>
</button>
<div fxFlex class="tb-layout-preview-element tb-layout-preview-input" *ngIf="showPreviewInputs('main')">
@ -93,7 +249,7 @@
required>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="start center" fxFlex *ngIf="layoutsFormGroup.get('right').value" matTooltip="">
<div fxLayout="column" fxLayoutAlign="start center" fxFlex *ngIf="isDividerLayout" matTooltip="">
<button mat-icon-button
type="button"
matTooltip="{{ 'dashboard.layout-settings' | translate }}"
@ -138,7 +294,7 @@
</div>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="8px" *ngIf="layoutsFormGroup.get('right').value" style="width: 80%">
<div fxLayout="column" fxLayoutAlign="center center" fxLayoutGap="8px" *ngIf="isDividerLayout" style="width: 80%">
<mat-slider *ngIf="layoutsFormGroup.get('type').value === layoutWidthType.PERCENTAGE"
step="1"
min="{{ layoutPercentageSize.MIN }}"
@ -167,6 +323,7 @@
</div>
</div>
</div>
</ng-template>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-button

34
ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.scss

@ -15,6 +15,7 @@
*/
@use '@angular/material' as mat;
@import '../theme.scss';
@import '../scss/constants.scss';
$tb-warn: mat.get-color-from-palette(map-get($tb-theme, warn), text);
@ -121,6 +122,39 @@ $tb-warn: mat.get-color-from-palette(map-get($tb-theme, warn), text);
}
}
}
.tb-layout-breakpoints {
.tb-form-table-header-cell, .tb-form-table-row-cell {
&.tb-icon-breakpoint {
width: 48px;
min-width: 48px;
}
&.tb-devices-header, &.tb-size-header {
flex: 1;
min-width: 120px;
}
&.tb-actions-header {
width: 80px;
min-width: 80px;
display: flex;
justify-content: end;
}
}
}
.tb-add-breakpoint-button {
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: #FFFFFF;
padding: 8px;
border: 2px dashed rgba(0, 0, 0, 0.08);
border-radius: 10px;
}
}
:host ::ng-deep {

184
ui-ngx/src/app/modules/home/components/dashboard-page/layout/manage-dashboard-layouts-dialog.component.ts

@ -14,7 +14,7 @@
/// limitations under the License.
///
import { Component, Inject, SkipSelf, ViewChild } from '@angular/core';
import { Component, Inject, OnDestroy, SkipSelf, ViewChild } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
@ -32,8 +32,14 @@ import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component';
import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { DashboardLayoutId, DashboardStateLayouts, LayoutDimension } from '@app/shared/models/dashboard.models';
import { deepClone, isDefined } from '@core/utils';
import {
DashboardLayout,
DashboardLayoutId,
DashboardStateLayouts,
LayoutDimension, LayoutType, layoutTypes,
layoutTypeTranslationMap
} from '@app/shared/models/dashboard.models';
import { deepClone, isDefined, isEqual } from '@core/utils';
import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
import {
DashboardSettingsDialogComponent,
@ -46,11 +52,21 @@ import {
} from '@home/components/dashboard-page/layout/layout.models';
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;
}
export interface DashboardLayoutSettings {
icon: string;
name: string;
descriptionSize?: string;
layout: DashboardLayout;
breakpoint: string;
}
@Component({
selector: 'tb-manage-dashboard-layouts-dialog',
templateUrl: './manage-dashboard-layouts-dialog.component.html',
@ -58,11 +74,12 @@ export interface ManageDashboardLayoutsDialogData {
styleUrls: ['./manage-dashboard-layouts-dialog.component.scss', '../../../components/dashboard/layout-button.scss']
})
export class ManageDashboardLayoutsDialogComponent extends DialogComponent<ManageDashboardLayoutsDialogComponent, DashboardStateLayouts>
implements ErrorStateMatcher {
implements ErrorStateMatcher, OnDestroy {
@ViewChild('tooltip', {static: true}) tooltip: MatTooltip;
layoutsFormGroup: UntypedFormGroup;
addBreakpointFormGroup: UntypedFormGroup;
layoutWidthType = LayoutWidthType;
@ -70,12 +87,32 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
layoutFixedSize = LayoutFixedSize;
layoutTypes = layoutTypes;
layoutTypeTranslations = layoutTypeTranslationMap;
dataSource: DashboardLayoutDatasource;
addBreakpointMode = false;
private layoutBreakpoints: DashboardLayoutSettings[] = [];
private readonly layouts: DashboardStateLayouts;
private subscriptions: Array<Subscription> = [];
private submitted = false;
private layoutBreakpoint = {
default: 'Default',
xs: 'xs',
sm: 'sm',
md: 'md',
lg: 'lg',
xl: 'xl'
};
allowLayoutBreakpoints = Object.keys(this.layoutBreakpoint);
selectedLayoutBreakpoints = ['default'];
constructor(protected store: Store<AppState>,
protected router: Router,
@Inject(MAT_DIALOG_DATA) private data: ManageDashboardLayoutsDialogData,
@ -89,10 +126,18 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
super(store, router, dialogRef);
this.layouts = this.data.layouts;
this.dataSource = new DashboardLayoutDatasource();
let layoutType = LayoutType.default;
if (isDefined(this.layouts.right)) {
layoutType = LayoutType.divider;
} else if (isDefined(this.layouts.main.gridSettings.layoutType)) {
layoutType = this.layouts.main.gridSettings.layoutType;
}
this.layoutsFormGroup = this.fb.group({
layoutType: [layoutType],
main: [{value: isDefined(this.layouts.main), disabled: true}],
right: [isDefined(this.layouts.right)],
sliderPercentage: [50],
sliderFixed: [this.layoutFixedSize.MIN],
leftWidthPercentage: [50,
@ -106,6 +151,11 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
}
);
this.addBreakpointFormGroup = this.fb.group({
new: [],
copyFrom: []
});
this.subscriptions.push(
this.layoutsFormGroup.get('type').valueChanges.subscribe(
(value) => {
@ -141,7 +191,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
sliderFixed: this.layouts.main.gridSettings.layoutDimension.fixedWidth
}, {emitEvent: false});
} else {
const leftWidthPercentage: number = Number(this.layouts.main.gridSettings.layoutDimension.leftWidthPercentage);
const leftWidthPercentage = Number(this.layouts.main.gridSettings.layoutDimension.leftWidthPercentage);
this.layoutsFormGroup.patchValue({
leftWidthPercentage,
sliderPercentage: leftWidthPercentage,
@ -158,6 +208,31 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
this.layouts.right = this.dashboardUtils.createDefaultLayoutData();
}
this.layoutBreakpoints.push({
icon: 'mdi:monitor',
name: 'Default',
layout: this.layouts.main,
breakpoint: 'default'
});
if (!this.isDividerLayout && this.layouts.main.breakpoints) {
for (const breakpoint of Object.keys(this.layouts.main.breakpoints)) {
this.layoutBreakpoints.push({
icon: 'mdi:monitor',
name: breakpoint,
layout: this.layouts.main.breakpoints[breakpoint],
descriptionSize: MediaBreakpoints[breakpoint],
breakpoint
});
this.selectedLayoutBreakpoints.push(breakpoint);
}
}
this.allowLayoutBreakpoints = Object.keys(this.layoutBreakpoint)
.filter((item) => !this.selectedLayoutBreakpoints.includes(item));
this.dataSource.loadData(this.layoutBreakpoints);
this.subscriptions.push(
this.layoutsFormGroup.get('sliderPercentage').valueChanges
.subscribe(
@ -209,8 +284,13 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
return originalErrorState || customErrorState;
}
openLayoutSettings(layoutId: DashboardLayoutId) {
const gridSettings = deepClone(this.layouts[layoutId].gridSettings);
openLayoutSettings(layoutId: DashboardLayoutId, breakpoint?: string) {
let gridSettings;
if (isDefined(breakpoint) && breakpoint !== 'default') {
gridSettings = deepClone(this.layouts[layoutId].breakpoints[breakpoint].gridSettings);
} else {
gridSettings = deepClone(this.layouts[layoutId].gridSettings);
}
this.dialog.open<DashboardSettingsDialogComponent, DashboardSettingsDialogData,
DashboardSettingsDialogData>(DashboardSettingsDialogComponent, {
disableClose: true,
@ -218,7 +298,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
data: {
settings: null,
gridSettings,
isRightLayout: this.layoutsFormGroup.get('right').value && layoutId === 'right'
isRightLayout: this.isDividerLayout && layoutId === 'right'
}
}).afterClosed().subscribe((data) => {
if (data && data.gridSettings) {
@ -234,14 +314,16 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
save(): void {
this.submitted = true;
const layouts = ['main', 'right'];
for (const l of layouts) {
const control = this.layoutsFormGroup.controls[l];
if (!control.value) {
if (this.layouts[l]) {
delete this.layouts[l];
}
const layoutType = this.layoutsFormGroup.value.layoutType;
this.layouts.main.gridSettings.layoutType = layoutType;
if (!this.isDividerLayout) {
delete this.layouts.right;
for (const breakpoint of Object.values(this.layouts.main.breakpoints)) {
breakpoint.gridSettings.layoutType = layoutType;
}
} else {
delete this.layouts.main.breakpoints;
this.layouts.right.gridSettings.layoutType = layoutType;
}
delete this.layouts.main.gridSettings.layoutDimension;
if (this.layouts.right?.gridSettings) {
@ -271,7 +353,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
buttonFlexValue(): number {
const formValues = this.layoutsFormGroup.value;
if (formValues.right) {
if (this.isDividerLayout) {
if (formValues.type !== LayoutWidthType.FIXED) {
return formValues.leftWidthPercentage;
} else {
@ -296,7 +378,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
}
setFixedLayout(layout: string): void {
if (this.layoutsFormGroup.get('type').value === LayoutWidthType.FIXED && this.layoutsFormGroup.get('right').value) {
if (this.layoutsFormGroup.get('type').value === LayoutWidthType.FIXED && this.isDividerLayout) {
this.layoutsFormGroup.get('fixedLayout').setValue(layout);
this.layoutsFormGroup.get('fixedLayout').markAsDirty();
}
@ -339,7 +421,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
layoutButtonClass(side: DashboardLayoutId, border: boolean = false): string {
const formValues = this.layoutsFormGroup.value;
if (formValues.right) {
if (this.isDividerLayout) {
let classString = border ? 'tb-layout-button-main ' : '';
if (!(formValues.fixedLayout === side || formValues.type === LayoutWidthType.PERCENTAGE)) {
classString += 'tb-fixed-layout-button';
@ -350,7 +432,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
layoutButtonText(side: DashboardLayoutId): string {
const formValues = this.layoutsFormGroup.value;
if (!(formValues.fixedLayout === side || !formValues.right || formValues.type === LayoutWidthType.PERCENTAGE)) {
if (!(formValues.fixedLayout === side || !this.isDividerLayout || formValues.type === LayoutWidthType.PERCENTAGE)) {
if (side === 'main') {
return this.translate.instant('layout.left-side');
} else {
@ -361,6 +443,66 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
showPreviewInputs(side: DashboardLayoutId): boolean {
const formValues = this.layoutsFormGroup.value;
return formValues.right && (formValues.type === LayoutWidthType.PERCENTAGE || formValues.fixedLayout === side);
return this.isDividerLayout && (formValues.type === LayoutWidthType.PERCENTAGE || formValues.fixedLayout === side);
}
get isDividerLayout(): boolean {
return this.layoutsFormGroup.get('layoutType').value === LayoutType.divider;
}
deleteBreakpoint(breakpoint: string): void {
delete this.layouts.main.breakpoints[breakpoint];
if (isEqual(this.layouts.main.breakpoints, {})) {
delete this.layouts.main.breakpoints;
}
this.layoutBreakpoints = this.layoutBreakpoints.filter((item) => item.breakpoint !== breakpoint);
this.dataSource.loadData(this.layoutBreakpoints);
this.layoutsFormGroup.markAsDirty();
}
addBreakpoint() {
this.addBreakpointMode = !this.addBreakpointMode;
if (this.addBreakpointMode) {
this.addBreakpointFormGroup.reset({
new: this.allowLayoutBreakpoints[0],
copyFrom: 'default'
});
}
}
createdBreakPoint() {
const layoutConfig = this.layouts.main;
const newBreakpoint = this.addBreakpointFormGroup.value.new;
const sourceBreakpoint = this.addBreakpointFormGroup.value.copyFrom;
const sourceLayout = sourceBreakpoint === 'default' ? layoutConfig : layoutConfig.breakpoints[sourceBreakpoint];
if (!layoutConfig.breakpoints) {
layoutConfig.breakpoints = {};
}
layoutConfig.breakpoints[newBreakpoint] = {
gridSettings: deepClone(sourceLayout.gridSettings),
widgets: deepClone(sourceLayout.widgets),
};
this.selectedLayoutBreakpoints.push(newBreakpoint);
this.allowLayoutBreakpoints = this.allowLayoutBreakpoints.filter((item) => item !== newBreakpoint);
this.layoutBreakpoints.push({
icon: 'mdi:monitor',
name: newBreakpoint,
layout: this.layouts.main.breakpoints[newBreakpoint],
descriptionSize: MediaBreakpoints[newBreakpoint],
breakpoint: newBreakpoint
});
this.dataSource.loadData(this.layoutBreakpoints);
this.addBreakpointMode = false;
}
}
export class DashboardLayoutDatasource extends TbTableDatasource<DashboardLayoutSettings> {
constructor() {
super();
}
}

6
ui-ngx/src/app/shared/models/dashboard.models.ts

@ -51,7 +51,8 @@ export interface WidgetLayouts {
export enum LayoutType {
default = 'default',
scada = 'scada'
scada = 'scada',
divider = 'divider',
}
export const layoutTypes = Object.keys(LayoutType) as LayoutType[];
@ -59,7 +60,8 @@ export const layoutTypes = Object.keys(LayoutType) as LayoutType[];
export const layoutTypeTranslationMap = new Map<LayoutType, string>(
[
[ LayoutType.default, 'dashboard.layout-type-default' ],
[ LayoutType.scada, 'dashboard.layout-type-scada' ]
[ LayoutType.scada, 'dashboard.layout-type-scada' ],
[ LayoutType.divider, 'dashboard.layout-type-divider' ],
]
);

1
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1170,6 +1170,7 @@
"layout": "Layout",
"layout-type-default": "Default",
"layout-type-scada": "SCADA",
"layout-type-divider": "Divider",
"layout-settings": "Layout settings",
"columns-count": "Columns count",
"columns-count-required": "Columns count is required.",

Loading…
Cancel
Save