Browse Source

Layout improvements.

pull/2150/head
Igor Kulikov 7 years ago
parent
commit
f579add9a7
  1. 4
      ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts
  2. 18
      ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts
  3. 2
      ui-ngx/src/app/modules/home/components/widget/data-keys.component.html
  4. 19
      ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss
  5. 8
      ui-ngx/src/app/modules/home/components/widget/legend-config-panel.component.html
  6. 5
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
  7. 3
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss
  8. 8
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts
  9. 184
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.html
  10. 38
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.scss
  11. 29
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.ts
  12. 11
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.models.ts
  13. 3
      ui-ngx/src/app/modules/home/pages/dashboard/edit-widget.component.ts
  14. 7
      ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.html
  15. 4
      ui-ngx/src/app/shared/components/js-func.component.html
  16. 2
      ui-ngx/src/app/shared/components/json-object-edit.component.html
  17. 4
      ui-ngx/src/app/shared/components/mat-chip-draggable.directive.ts
  18. 170
      ui-ngx/src/app/shared/components/time/timewindow-panel.component.html

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

@ -184,6 +184,10 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo
swap: false,
maxRows: 100,
minCols: this.columns ? this.columns : 24,
maxCols: 3000,
maxItemCols: 1000,
maxItemRows: 1000,
maxItemArea: 1000000,
outerMargin: true,
margin: this.margin ? this.margin : 10,
minItemCols: 1,

18
ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts

@ -299,14 +299,16 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
writeValue(obj: WidgetActionsData): void {
this.innerValue = obj;
setTimeout(() => {
this.dataSource.setActions(this.innerValue);
if (this.viewsInited) {
this.resetSortAndFilter(true);
} else {
this.dirtyValue = true;
}
}, 0);
if (this.innerValue) {
setTimeout(() => {
this.dataSource.setActions(this.innerValue);
if (this.viewsInited) {
this.resetSortAndFilter(true);
} else {
this.dirtyValue = true;
}
}, 0);
}
}
private onActionsUpdated() {

2
ui-ngx/src/app/modules/home/components/widget/data-keys.component.html

@ -29,7 +29,7 @@
<div class="tb-color-preview" (click)="showColorPicker(key)" style="margin-right: 5px;">
<div class="tb-color-result" [ngStyle]="{background: key.color}"></div>
</div>
<div style="flex: 1; min-width: 0px;" fxLayout="row">
<div class="tb-chip-labels">
<div class="tb-chip-label">
<span *ngIf="datasourceType !== datasourceTypes.function && widgetType !== widgetTypes.alarm">
<span *ngIf="key.type === dataKeyTypes.attribute"

19
ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss

@ -30,14 +30,19 @@
}
}
.tb-chip-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tb-chip-labels {
display: flex;
flex-direction: row;
min-width: 0px;
.tb-chip-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tb-chip-separator {
white-space: pre;
.tb-chip-separator {
white-space: pre;
}
}
.mat-chip-remove.mat-icon {

8
ui-ngx/src/app/modules/home/components/widget/legend-config-panel.component.html

@ -38,16 +38,16 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox fxFlex formControlName="showMin">
<mat-checkbox formControlName="showMin">
{{ 'legend.show-min' | translate }}
</mat-checkbox>
<mat-checkbox fxFlex formControlName="showMax">
<mat-checkbox formControlName="showMax">
{{ 'legend.show-max' | translate }}
</mat-checkbox>
<mat-checkbox fxFlex formControlName="showAvg">
<mat-checkbox formControlName="showAvg">
{{ 'legend.show-avg' | translate }}
</mat-checkbox>
<mat-checkbox fxFlex formControlName="showTotal">
<mat-checkbox formControlName="showTotal">
{{ 'legend.show-total' | translate }}
</mat-checkbox>
</section>

5
ui-ngx/src/app/modules/home/components/widget/widget-config.component.html

@ -22,11 +22,10 @@
<div *ngIf="widgetType === widgetTypes.timeseries || widgetType === widgetTypes.alarm"
fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="center" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="start center">
<div fxLayout="column" fxLayoutGap="8px" fxFlex>
<mat-checkbox fxFlex formControlName="useDashboardTimewindow">
<mat-checkbox formControlName="useDashboardTimewindow">
{{ 'widget-config.use-dashboard-timewindow' | translate }}
</mat-checkbox>
<mat-checkbox fxFlex
formControlName="displayTimewindow">
<mat-checkbox formControlName="displayTimewindow">
{{ 'widget-config.display-timewindow' | translate }}
</mat-checkbox>
</div>

3
ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss

@ -26,6 +26,9 @@
}
.tb-datasource-type {
min-width: 110px;
@media #{$mat-gt-sm} {
max-width: 110px;
}
}
.tb-datasource {
@media #{$mat-gt-sm} {

8
ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts

@ -163,6 +163,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
} else {
this.datasourceTypes = [DatasourceType.function, DatasourceType.entity];
}
this.dataSettings = this.fb.group({});
this.targetDeviceSettings = this.fb.group({});
this.alarmSourceSettings = this.fb.group({});
this.advancedSettings = this.fb.group({});
this.widgetSettings = this.fb.group({
title: [null, []],
showTitleIcon: [null, []],
@ -574,7 +578,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
}
public displayAdvanced(): boolean {
return this.modelValue.settingsSchema && this.modelValue.settingsSchema.schema;
return this.modelValue && this.modelValue.settingsSchema && this.modelValue.settingsSchema.schema;
}
public removeDatasource(index: number) {
@ -772,7 +776,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont
valid: false
}
};
} else {
} else if (this.modelValue) {
const config = this.modelValue.config;
if (this.widgetType === widgetType.rpc && this.modelValue.isDataEnabled) {
if (!config.targetDeviceAliasIds || !config.targetDeviceAliasIds.length) {

184
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.html

@ -120,59 +120,90 @@
'tb-dashboard-toolbar-opened': toolbarOpened,
'tb-dashboard-toolbar-animated': isToolbarOpenedAnimate,
'tb-dashboard-toolbar-closed': !toolbarOpened }">
<section *ngIf="!widgetEditMode" class="tb-dashboard-title" fxLayout="row" fxLayoutAlign="center center"
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
<h3 [fxShow]="!isEdit && displayTitle()">{{ dashboard.title }}</h3>
<mat-form-field [fxShow]="isEdit" class="mat-block" style="height: 30px;">
<mat-label translate [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">dashboard.title</mat-label>
<input matInput class="tb-dashboard-title"
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}"
required name="title" [(ngModel)]="dashboard.title">
</mat-form-field>
</section>
<div class="tb-absolute-fill tb-dashboard-layouts" fxLayout="{{forceDashboardMobileMode ? 'column' : 'row'}}"
[ngClass]="{ 'tb-padded' : !widgetEditMode && (isEdit || displayTitle()), 'tb-shrinked' : isEditingWidget }">
<mat-drawer-container class="tb-absolute-fill">
<mat-drawer *ngIf="layouts.right.show"
id="tb-right-layout"
[ngStyle]="{minWidth: rightLayoutWidth(),
maxWidth: rightLayoutWidth(),
height: rightLayoutHeight(),
borderLeft: 'none'}"
disableClose="true"
position="end"
[mode]="isMobile ? 'over' : 'side'"
[(opened)]="rightLayoutOpened">
<tb-dashboard-layout style="height: 100%;"
[layoutCtx]="layouts.right.layoutCtx"
[dashboardCtx]="dashboardCtx"
[isEdit]="isEdit"
[isEditingWidget]="isEditingWidget"
[isMobile]="forceDashboardMobileMode"
[widgetEditMode]="widgetEditMode">
</tb-dashboard-layout>
</mat-drawer>
<mat-drawer-content [fxShow]="layouts.main.show"
id="tb-main-layout"
[ngStyle]="{width: mainLayoutWidth(),
height: mainLayoutHeight()}">
<tb-dashboard-layout
[layoutCtx]="layouts.main.layoutCtx"
[dashboardCtx]="dashboardCtx"
[isEdit]="isEdit"
[isEditingWidget]="isEditingWidget"
[isMobile]="forceDashboardMobileMode"
[widgetEditMode]="widgetEditMode">
</tb-dashboard-layout>
</mat-drawer-content>
</mat-drawer-container>
</div>
<mat-drawer-container hasBackdrop="false" class="tb-widget-details-sidenav">
<mat-drawer-container hasBackdrop="false" class="tb-absolute-fill tb-dashboard-drawer-container">
<mat-drawer-content fxLayout="column" fxLayoutAlign="center start">
<section *ngIf="!widgetEditMode" class="tb-dashboard-title"
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
<h3 [fxShow]="!isEdit && displayTitle()">{{ dashboard.title }}</h3>
<mat-form-field [fxShow]="isEdit" class="mat-block">
<mat-label translate [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">dashboard.title</mat-label>
<input matInput class="tb-dashboard-title"
[ngStyle]="{'color': dashboard.configuration.settings.titleColor}"
required name="title" [(ngModel)]="dashboard.title">
</mat-form-field>
</section>
<mat-drawer-container class="tb-dashboard-layouts" fxFlex
[ngClass]="{ 'tb-shrinked' : isEditingWidget }">
<mat-drawer *ngIf="layouts.right.show"
id="tb-right-layout"
[ngStyle]="{minWidth: rightLayoutWidth(),
maxWidth: rightLayoutWidth(),
height: rightLayoutHeight(),
borderLeft: 'none'}"
disableClose="true"
position="end"
[mode]="isMobile ? 'over' : 'side'"
[(opened)]="rightLayoutOpened">
<tb-dashboard-layout style="height: 100%;"
[layoutCtx]="layouts.right.layoutCtx"
[dashboardCtx]="dashboardCtx"
[isEdit]="isEdit"
[isEditingWidget]="isEditingWidget"
[isMobile]="forceDashboardMobileMode"
[widgetEditMode]="widgetEditMode">
</tb-dashboard-layout>
</mat-drawer>
<mat-drawer-content [fxShow]="layouts.main.show"
id="tb-main-layout"
[ngStyle]="{width: mainLayoutWidth(),
height: mainLayoutHeight()}">
<tb-dashboard-layout
[layoutCtx]="layouts.main.layoutCtx"
[dashboardCtx]="dashboardCtx"
[isEdit]="isEdit"
[isEditingWidget]="isEditingWidget"
[isMobile]="forceDashboardMobileMode"
[widgetEditMode]="widgetEditMode">
</tb-dashboard-layout>
</mat-drawer-content>
</mat-drawer-container>
<section fxLayout="row" class="layout-wrap tb-footer-buttons" fxLayoutAlign="start end">
<tb-footer-fab-buttons [fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
relative
[footerFabButtons]="addWidgetFabButtons">
</tb-footer-fab-buttons>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': !isEdit || isAddingWidget}"
[disabled]="isLoading$ | async"
(click)="saveDashboard()"
matTooltip="{{ 'action.apply-changes' | translate }}"
matTooltipPosition="above">
<mat-icon>done</mat-icon>
</button>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': isAddingWidget || (isLoading$ | async)}"
[disabled]="isLoading$ | async"
(click)="toggleDashboardEditMode()"
matTooltip="{{ (isEdit ? 'action.decline-changes': 'action.enter-edit-mode') | translate }}"
matTooltipPosition="above">
<mat-icon>{{ isEdit ? 'close' : 'edit' }}</mat-icon>
</button>
</section>
<section class="tb-powered-by-footer" [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
<span>Powered by <a href="https://thingsboard.io" target="_blank">Thingsboard v.{{ thingsboardVersion }}</a></span>
</section>
</mat-drawer-content>
<mat-drawer class="tb-details-drawer"
[opened]="isEditingWidget"
[opened]="isEditingWidget || isAddingWidget"
(openedStart)="detailsDrawerOpenedStart()"
(opened)="detailsDrawerOpened()"
(closedStart)="detailsDrawerClosedStart()"
(closed)="detailsDrawerClosed()"
mode="over"
position="end">
<tb-details-panel *ngIf="isEditingWidget" fxFlex
<tb-details-panel *ngIf="!isEditingWidgetClosed" fxFlex
headerTitle="{{editingWidget?.config.title}}"
headerSubtitle="{{ editingWidgetSubtitle }}"
[isReadOnly]="false"
@ -185,21 +216,14 @@
<div [tb-help]="helpLinkIdForWidgetType()"></div>
</div>
<tb-edit-widget #tbEditWidget
[dashboard]="dashboard"
[aliasController]="dashboardCtx.aliasController"
[widgetEditMode]="widgetEditMode"
[widget]="editingWidget"
[widgetLayout]="editingWidgetLayout">
[dashboard]="dashboard"
[aliasController]="dashboardCtx.aliasController"
[widgetEditMode]="widgetEditMode"
[widget]="editingWidget"
[widgetLayout]="editingWidgetLayout">
</tb-edit-widget>
</tb-details-panel>
</mat-drawer>
</mat-drawer-container>
<mat-drawer-container *ngIf="!widgetEditMode" hasBackdrop="false" class="tb-select-widget-sidenav">
<mat-drawer class="tb-details-drawer"
[opened]="isAddingWidget"
mode="over"
position="end">
<tb-details-panel *ngIf="isAddingWidget" fxFlex
<tb-details-panel *ngIf="!isAddingWidgetClosed && !widgetEditMode" fxFlex
headerTitle="{{'dashboard.select-widget-title' | translate}}"
headerHeightPx="120"
[isReadOnly]="true"
@ -218,40 +242,12 @@
</div>
</div>
<tb-dashboard-widget-select *ngIf="isAddingWidget"
[aliasController]="dashboardCtx.aliasController"
[widgetsBundle]="widgetsBundle"
(widgetSelected)="addWidgetFromType($event)">
[aliasController]="dashboardCtx.aliasController"
[widgetsBundle]="widgetsBundle"
(widgetSelected)="addWidgetFromType($event)">
</tb-dashboard-widget-select>
</tb-details-panel>
</mat-drawer>
</mat-drawer-container>
<!--tb-details-sidenav TODO -->
<section fxLayout="row" class="layout-wrap tb-footer-buttons" fxLayoutAlign="start end">
<tb-footer-fab-buttons [fxShow]="!isAddingWidget && isEdit && !widgetEditMode"
relative
[footerFabButtons]="addWidgetFabButtons">
</tb-footer-fab-buttons>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': !isEdit || isAddingWidget}"
[disabled]="isLoading$ | async"
(click)="saveDashboard()"
matTooltip="{{ 'action.apply-changes' | translate }}"
matTooltipPosition="above">
<mat-icon>done</mat-icon>
</button>
<button *ngIf="(isTenantAdmin() || isSystemAdmin()) && !forceFullscreen"
mat-fab color="accent" class="tb-btn-footer"
[ngClass]="{'tb-hide': isAddingWidget || (isLoading$ | async)}"
[disabled]="isLoading$ | async"
(click)="toggleDashboardEditMode()"
matTooltip="{{ (isEdit ? 'action.decline-changes': 'action.enter-edit-mode') | translate }}"
matTooltipPosition="above">
<mat-icon>{{ isEdit ? 'close' : 'edit' }}</mat-icon>
</button>
</section>
</section>
<section class="tb-powered-by-footer" [ngStyle]="{'color': dashboard.configuration.settings.titleColor}">
<span>Powered by <a href="https://thingsboard.io" target="_blank">Thingsboard v.{{ thingsboardVersion }}</a></span>
</section>
</div>

38
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.scss

@ -32,9 +32,9 @@ div.tb-dashboard-page {
background-color: #eee;
}
section.tb-dashboard-title {
position: absolute;
top: 0;
left: 20px;
position: relative;
padding-left: 20px;
max-height: 60px;
mat-form-field {
.mat-form-field-infix {
width: 100%;
@ -47,17 +47,6 @@ div.tb-dashboard-page {
letter-spacing: .005em;
}
}
div.tb-padded {
top: 60px;
}
section.tb-padded {
top: 60px;
}
div.tb-shrinked {
width: 40%;
}
section.tb-dashboard-toolbar {
position: absolute;
@ -106,21 +95,16 @@ div.tb-dashboard-page {
transition: margin-top .3s cubic-bezier(.55, 0, .55, .2) .2s;
}
}
}
.tb-dashboard-layouts {
/*md-backdrop {
z-index: 1;
}*/
#tb-right-layout {
mat-drawer {
z-index: 1;
}
mat-drawer-container.tb-dashboard-drawer-container {
mat-drawer-container.tb-dashboard-layouts {
width: 100%;
&.tb-shrinked {
width: 40%;
}
}
}
mat-drawer-container.tb-widget-details-sidenav {
position: initial;
mat-drawer.tb-details-drawer {
@media #{$mat-gt-sm} {
width: 85% !important;
@ -136,10 +120,6 @@ div.tb-dashboard-page {
}
}
mat-drawer-container.tb-select-widget-sidenav {
position: initial;
}
section.tb-powered-by-footer {
position: absolute;
right: 25px;

29
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.component.ts

@ -104,9 +104,11 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
isFullscreen = false;
isEdit = false;
isEditingWidget = false;
isEditingWidgetClosed = true;
isMobile = !this.breakpointObserver.isMatched(MediaBreakpoints['gt-sm']);
forceDashboardMobileMode = false;
isAddingWidget = false;
isAddingWidgetClosed = true;
widgetsBundle: WidgetsBundle = null;
isToolbarOpened = false;
@ -284,8 +286,10 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
this.isFullscreen = false;
this.isEdit = false;
this.isEditingWidget = false;
this.isEditingWidgetClosed = true;
this.forceDashboardMobileMode = false;
this.isAddingWidget = false;
this.isAddingWidgetClosed = true;
this.widgetsBundle = null;
this.isToolbarOpened = false;
@ -694,6 +698,31 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
this.isAddingWidget = false;
}
detailsDrawerOpenedStart() {
if (this.isEditingWidget) {
this.isEditingWidgetClosed = false;
} else if (this.isAddingWidget) {
this.isAddingWidgetClosed = false;
}
setTimeout(() => {
this.cd.detach();
}, 0);
}
detailsDrawerOpened() {
this.cd.reattach();
}
detailsDrawerClosedStart() {
this.cd.detach();
}
detailsDrawerClosed() {
this.isEditingWidgetClosed = true;
this.isAddingWidgetClosed = true;
this.cd.reattach();
}
private addWidgetToLayout(widget: Widget, layoutId: DashboardLayoutId) {
this.dashboardUtils.addWidgetToLayout(this.dashboard, this.dashboardCtx.state, layoutId, widget);
this.layouts[layoutId].layoutCtx.widgets.addWidgetId(widget.id);

11
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-page.models.ts

@ -77,6 +77,8 @@ export class LayoutWidgetsArray implements Iterable<Widget> {
private widgetIds: string[] = [];
private pointer = 0;
private loaded = false;
constructor(private dashboard: Dashboard) {
}
@ -84,8 +86,17 @@ export class LayoutWidgetsArray implements Iterable<Widget> {
return this.widgetIds.length;
}
isLoading() {
return !this.loaded;
}
isEmpty() {
return this.loaded && this.widgetIds.length === 0;
}
setWidgetIds(widgetIds: string[]) {
this.widgetIds = widgetIds;
this.loaded = true;
}
addWidgetId(widgetId: string) {

3
ui-ngx/src/app/modules/home/pages/dashboard/edit-widget.component.ts

@ -102,6 +102,9 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan
}
private loadWidgetConfig() {
if (!this.widget) {
return;
}
const widgetInfo = this.widgetComponentService.getInstantWidgetInfo(this.widget);
const rawSettingsSchema = widgetInfo.typeSettingsSchema || widgetInfo.settingsSchema;
const rawDataKeySettingsSchema = widgetInfo.typeDataKeySettingsSchema || widgetInfo.dataKeySettingsSchema;

7
ui-ngx/src/app/modules/home/pages/dashboard/layout/dashboard-layout.component.html

@ -16,10 +16,15 @@
-->
<hotkeys-cheatsheet></hotkeys-cheatsheet>
<div fxLayout="column" class="tb-progress-cover" fxLayoutAlign="center center"
*ngIf="layoutCtx.widgets.isLoading()">
<mat-spinner color="warn" mode="indeterminate" diameter="100">
</mat-spinner>
</div>
<div class="mat-content" style="position: relative; width: 100%; height: 100%;"
[style.backgroundImage]="backgroundImage"
[ngStyle]="dashboardStyle">
<section *ngIf="layoutCtx.widgets.size() === 0" fxLayoutAlign="center center"
<section *ngIf="layoutCtx.widgets.isEmpty()" fxLayoutAlign="center center"
[ngStyle]="{'color': layoutCtx.gridSettings.color}"
style="text-transform: uppercase; display: flex; z-index: 1; pointer-events: none;"
class="mat-headline tb-absolute-fill">

4
ui-ngx/src/app/shared/components/js-func.component.html

@ -31,8 +31,8 @@
<mat-icon class="material-icons">{{ fullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
</button>
</div>
<div fxFlex="0%" id="tb-javascript-panel" class="tb-js-func-panel" fxLayout="column" tb-toast toastTarget="jsFuncEditor">
<div fxFlex #javascriptEditor id="tb-javascript-input" [ngClass]="{'fill-height': fillHeight}"></div>
<div id="tb-javascript-panel" class="tb-js-func-panel" fxLayout="column" tb-toast toastTarget="jsFuncEditor">
<div #javascriptEditor id="tb-javascript-input" [ngClass]="{'fill-height': fillHeight}"></div>
</div>
<div fxLayout="row" fxLayoutAlign="start center" style="height: 40px;">
<label class="tb-title no-padding">}</label>

2
ui-ngx/src/app/shared/components/json-object-edit.component.html

@ -30,7 +30,7 @@
<mat-icon class="material-icons">{{ fullscreen ? 'fullscreen_exit' : 'fullscreen' }}</mat-icon>
</button>
</div>
<div fxFlex="0%" id="tb-json-panel" tb-toast toastTarget="jsonObjectEditor"
<div id="tb-json-panel" tb-toast toastTarget="jsonObjectEditor"
class="tb-json-object-panel" fxLayout="column">
<div #jsonEditor id="tb-json-input" [ngStyle]="editorStyle" [ngClass]="{'fill-height': fillHeight}"></div>
</div>

4
ui-ngx/src/app/shared/components/mat-chip-draggable.directive.ts

@ -144,7 +144,7 @@ class DraggableChip {
const dataTransfer = event.dataTransfer;
dataTransfer.effectAllowed = 'copyMove';
dataTransfer.dropEffect = 'move';
dataTransfer.setData('text/plain', this.index() + '');
dataTransfer.setData('text', this.index() + '');
}
}
@ -222,7 +222,7 @@ class DraggableChip {
return;
}
event = (event as any).originalEvent || event;
const droppedItemIndex = parseInt(event.dataTransfer.getData('text/plain'), 10);
const droppedItemIndex = parseInt(event.dataTransfer.getData('text'), 10);
const currentIndex = this.index();
let newIndex;
if (this.dropPosition === 'before') {

170
ui-ngx/src/app/shared/components/time/timewindow-panel.component.html

@ -17,94 +17,92 @@
-->
<form [formGroup]="timewindowForm" (ngSubmit)="update()">
<fieldset [disabled]="(isLoading$ | async)">
<div class="mat-content" style="height: 100%;" fxFlex fxLayout="column">
<section fxLayout="column">
<mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}"
(selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
<mat-tab label="{{ 'timewindow.realtime' | translate }}">
<div formGroupName="realtime" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME"
style="padding-top: 8px;"></tb-timeinterval>
</div>
</mat-tab>
<mat-tab label="{{ 'timewindow.history' | translate }}">
<div formGroupName="history" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group formControlName="historyType">
<mat-radio-button [value]="historyTypes.LAST_INTERVAL" color="primary">
<section fxLayout="column">
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[fxShow]="timewindowForm.get('history').get('historyType').value === historyTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history').get('historyType').value === historyTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.FIXED" color="primary">
<section fxLayout="column">
<span translate>timewindow.time-period</span>
<tb-datetime-period
formControlName="fixedTimewindow"
[fxShow]="timewindowForm.get('history').get('historyType').value === historyTypes.FIXED"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history').get('historyType').value === historyTypes.FIXED"
style="padding-top: 8px;"></tb-datetime-period>
</section>
</mat-radio-button>
</mat-radio-group>
</div>
</mat-tab>
</mat-tab-group>
<div *ngIf="aggregation" formGroupName="aggregation" class="mat-content mat-padding" fxLayout="column">
<mat-form-field>
<mat-label translate>aggregation.function</mat-label>
<mat-select matInput formControlName="type" style="min-width: 150px;">
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
{{ aggregationTypesTranslations.get(aggregation) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<div *ngIf="timewindowForm.get('aggregation').get('type').value === aggregationTypes.NONE"
class="limit-slider-container"
fxLayout="row" fxLayoutAlign="start center">
<span translate>aggregation.limit</span>
<mat-slider fxFlex formControlName="limit"
thumbLabel
[value]="timewindowForm.get('aggregation').get('limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}">
</mat-slider>
<mat-form-field style="max-width: 80px;">
<input matInput formControlName="limit" type="number" step="1"
[value]="timewindowForm.get('aggregation').get('limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"/>
</mat-form-field>
<div class="mat-content" style="height: 100%;" fxLayout="column">
<mat-tab-group dynamicHeight [ngClass]="{'tb-headless': historyOnly}"
(selectedIndexChange)="timewindowForm.markAsDirty()" [(selectedIndex)]="timewindow.selectedTab">
<mat-tab label="{{ 'timewindow.realtime' | translate }}">
<div formGroupName="realtime" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[required]="timewindow.selectedTab === timewindowTypes.REALTIME"
style="padding-top: 8px;"></tb-timeinterval>
</div>
</mat-tab>
<mat-tab label="{{ 'timewindow.history' | translate }}">
<div formGroupName="history" class="mat-content mat-padding" style="padding-top: 8px;">
<mat-radio-group formControlName="historyType">
<mat-radio-button [value]="historyTypes.LAST_INTERVAL" color="primary">
<section fxLayout="column">
<tb-timeinterval
formControlName="timewindowMs"
predefinedName="timewindow.last"
[fxShow]="timewindowForm.get('history').get('historyType').value === historyTypes.LAST_INTERVAL"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history').get('historyType').value === historyTypes.LAST_INTERVAL"
style="padding-top: 8px;"></tb-timeinterval>
</section>
</mat-radio-button>
<mat-radio-button [value]="historyTypes.FIXED" color="primary">
<section fxLayout="column">
<span translate>timewindow.time-period</span>
<tb-datetime-period
formControlName="fixedTimewindow"
[fxShow]="timewindowForm.get('history').get('historyType').value === historyTypes.FIXED"
[required]="timewindow.selectedTab === timewindowTypes.HISTORY &&
timewindowForm.get('history').get('historyType').value === historyTypes.FIXED"
style="padding-top: 8px;"></tb-datetime-period>
</section>
</mat-radio-button>
</mat-radio-group>
</div>
</mat-tab>
</mat-tab-group>
<div *ngIf="aggregation" formGroupName="aggregation" class="mat-content mat-padding" fxLayout="column">
<mat-form-field>
<mat-label translate>aggregation.function</mat-label>
<mat-select matInput formControlName="type" style="min-width: 150px;">
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
{{ aggregationTypesTranslations.get(aggregation) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<div *ngIf="timewindowForm.get('aggregation').get('type').value === aggregationTypes.NONE"
class="limit-slider-container"
fxLayout="row" fxLayoutAlign="start center">
<span translate>aggregation.limit</span>
<mat-slider fxFlex formControlName="limit"
thumbLabel
[value]="timewindowForm.get('aggregation').get('limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}">
</mat-slider>
<mat-form-field style="max-width: 80px;">
<input matInput formControlName="limit" type="number" step="1"
[value]="timewindowForm.get('aggregation').get('limit').value"
min="{{minDatapointsLimit()}}"
max="{{maxDatapointsLimit()}}"/>
</mat-form-field>
</div>
<div formGroupName="realtime"
*ngIf="aggregation && timewindowForm.get('aggregation').get('type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.REALTIME" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[min]="minRealtimeAggInterval()" [max]="maxRealtimeAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div formGroupName="history"
*ngIf="aggregation && timewindowForm.get('aggregation').get('type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.HISTORY" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[min]="minHistoryAggInterval()" [max]="maxHistoryAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
</section>
</div>
<div formGroupName="realtime"
*ngIf="aggregation && timewindowForm.get('aggregation').get('type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.REALTIME" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[min]="minRealtimeAggInterval()" [max]="maxRealtimeAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<div formGroupName="history"
*ngIf="aggregation && timewindowForm.get('aggregation').get('type').value !== aggregationTypes.NONE &&
timewindow.selectedTab === timewindowTypes.HISTORY" class="mat-content mat-padding" fxLayout="column">
<tb-timeinterval
formControlName="interval"
[min]="minHistoryAggInterval()" [max]="maxHistoryAggInterval()"
predefinedName="aggregation.group-interval">
</tb-timeinterval>
</div>
<span fxFlex></span>
<div fxLayout="row" class="tb-panel-actions">
<span fxFlex></span>

Loading…
Cancel
Save