315 lines
15 KiB
HTML
315 lines
15 KiB
HTML
<!--
|
|
|
|
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.
|
|
|
|
-->
|
|
<div class="tb-widget-config tb-absolute-fill">
|
|
<div class="tb-widget-config-header" *ngIf="!hideHeader">
|
|
<tb-toggle-select *ngIf="!hideToggleHeader && widgetConfigMode === widgetConfigModes.advanced"
|
|
appearance="fill" [options]="headerOptions" [(ngModel)]="selectedOption">
|
|
</tb-toggle-select>
|
|
<div class="tb-widget-config-header-components">
|
|
<ng-content select=".tb-widget-config-header-prefix"></ng-content>
|
|
<ng-content select=".tb-widget-config-header-suffix"></ng-content>
|
|
</div>
|
|
</div>
|
|
<div *ngIf="widgetConfigMode === widgetConfigModes.advanced; else basicMode" class="tb-widget-config-content">
|
|
<div *ngIf="widgetType !== widgetTypes.static" [class.!hidden]="selectedOption !== 'data'" class="mat-content">
|
|
<ng-container *ngTemplateOutlet="data"></ng-container>
|
|
</div>
|
|
<div [class.!hidden]="selectedOption !== 'appearance'" class="mat-content">
|
|
<ng-container *ngTemplateOutlet="appearance"></ng-container>
|
|
</div>
|
|
<div [class.!hidden]="selectedOption !== 'card'" [formGroup]="widgetSettings" class="mat-content">
|
|
<div class="tb-form-panel">
|
|
<div class="tb-form-panel-title" translate>widget-config.card-title</div>
|
|
<mat-slide-toggle class="mat-slide" formControlName="showTitle">
|
|
{{ 'widget-config.display-title' | translate }}
|
|
</mat-slide-toggle>
|
|
<div class="tb-form-row">
|
|
<div class="fixed-title-width" translate>widget-config.title</div>
|
|
<div class="flex flex-1 flex-row items-center justify-start gap-2">
|
|
<mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
<tb-font-settings formControlName="titleFont"
|
|
clearButton
|
|
[previewText]="widgetSettings.get('title').value"
|
|
[initialPreviewStyle]="widgetSettings.get('titleStyle').value">
|
|
</tb-font-settings>
|
|
<tb-color-input asBoxInput
|
|
colorClearButton
|
|
formControlName="titleColor">
|
|
</tb-color-input>
|
|
</div>
|
|
</div>
|
|
<div class="tb-form-row">
|
|
<div class="fixed-title-width" translate>widget-config.title-tooltip</div>
|
|
<mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="titleTooltip" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="tb-form-row space-between column-xs">
|
|
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
|
|
{{ 'widget-config.display-icon' | translate }}
|
|
</mat-slide-toggle>
|
|
<div class="flex flex-row items-center justify-start gap-2">
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="iconSize">
|
|
</mat-form-field>
|
|
<tb-material-icon-select asBoxInput
|
|
iconClearButton
|
|
[color]="widgetSettings.get('iconColor').value"
|
|
formControlName="titleIcon">
|
|
</tb-material-icon-select>
|
|
<tb-color-input asBoxInput
|
|
colorClearButton
|
|
formControlName="iconColor">
|
|
</tb-color-input>
|
|
</div>
|
|
</div>
|
|
<mat-expansion-panel class="tb-settings">
|
|
<mat-expansion-panel-header>
|
|
<mat-panel-description class="flex items-stretch justify-start" translate>
|
|
widget-config.advanced-title-style
|
|
</mat-panel-description>
|
|
</mat-expansion-panel-header>
|
|
<ng-template matExpansionPanelContent>
|
|
<tb-json-object-edit
|
|
[editorStyle]="{minHeight: '100px'}"
|
|
label="{{ 'widget-config.title-style' | translate }}"
|
|
formControlName="titleStyle"
|
|
></tb-json-object-edit>
|
|
</ng-template>
|
|
</mat-expansion-panel>
|
|
</div>
|
|
<div class="tb-form-panel">
|
|
<div class="tb-form-panel-title" translate>widget-config.card-style</div>
|
|
<div class="tb-form-row space-between">
|
|
<div>{{ 'widget-config.text-color' | translate }}</div>
|
|
<tb-color-input asBoxInput
|
|
colorClearButton
|
|
formControlName="color">
|
|
</tb-color-input>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div>{{ 'widget-config.background-color' | translate }}</div>
|
|
<tb-color-input asBoxInput
|
|
colorClearButton
|
|
formControlName="backgroundColor">
|
|
</tb-color-input>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div>{{ 'widget-config.padding' | translate }}</div>
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="padding" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div>{{ 'widget-config.margin' | translate }}</div>
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="margin" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div>{{ 'widget-config.border-radius' | translate }}</div>
|
|
<mat-form-field appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="borderRadius" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<mat-slide-toggle class="mat-slide slide-block" formControlName="dropShadow">
|
|
{{ 'widget-config.drop-shadow' | translate }}
|
|
</mat-slide-toggle>
|
|
<mat-expansion-panel class="tb-settings">
|
|
<mat-expansion-panel-header>
|
|
<mat-panel-description class="flex items-stretch justify-start" translate>
|
|
widget-config.advanced-widget-style
|
|
</mat-panel-description>
|
|
</mat-expansion-panel-header>
|
|
<ng-template matExpansionPanelContent>
|
|
<tb-json-object-edit
|
|
[editorStyle]="{minHeight: '100px'}"
|
|
label="{{ 'widget-config.widget-style' | translate }}"
|
|
formControlName="widgetStyle"
|
|
></tb-json-object-edit>
|
|
<tb-css
|
|
label="{{ 'widget-config.widget-css' | translate }}"
|
|
formControlName="widgetCss"
|
|
></tb-css>
|
|
</ng-template>
|
|
</mat-expansion-panel>
|
|
</div>
|
|
<div class="tb-form-panel">
|
|
<div class="tb-form-panel-title" translate>widget-config.card-buttons</div>
|
|
<mat-slide-toggle class="mat-slide slide-block" formControlName="enableFullscreen">
|
|
{{ 'widget-config.enable-fullscreen' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
</div>
|
|
<div [class.!hidden]="selectedOption !== 'actions'" [formGroup]="actionsSettings" class="mat-content" style="height: 100%;">
|
|
<div class="tb-form-panel" style="height: 100%;">
|
|
<tb-manage-widget-actions
|
|
[callbacks]="widgetConfigCallbacks"
|
|
[widgetType] = "modelValue.widgetType"
|
|
[actionSources]="modelValue.actionSources"
|
|
formControlName="actions">
|
|
</tb-manage-widget-actions>
|
|
</div>
|
|
</div>
|
|
<div [class.!hidden]="selectedOption !== 'layout'" [formGroup]="layoutSettings" class="mat-content">
|
|
<div class="tb-form-panel" *ngIf="!showLayoutConfig || isDefaultBreakpoint">
|
|
<div class="tb-form-panel-title" translate>widget-config.resize-options</div>
|
|
<div class="tb-form-row">
|
|
<mat-slide-toggle class="mat-slide" formControlName="resizable">
|
|
{{ 'widget-config.resizable' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
<div class="tb-form-row">
|
|
<mat-slide-toggle class="mat-slide" formControlName="preserveAspectRatio">
|
|
{{ 'widget-config.preserve-aspect-ratio' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
</div>
|
|
<div class="tb-form-panel" *ngIf="showLayoutConfig">
|
|
<div class="tb-form-panel-title">{{ (isDefaultBreakpoint ? 'widget-config.mobile' : 'widget-config.list-layout') | translate }}</div>
|
|
<div class="tb-form-row" *ngIf="isDefaultBreakpoint">
|
|
<mat-slide-toggle class="mat-slide" formControlName="mobileHide">
|
|
{{ 'widget-config.mobile-hide' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
<div class="tb-form-row" *ngIf="isDefaultBreakpoint">
|
|
<mat-slide-toggle class="mat-slide" formControlName="desktopHide">
|
|
{{ 'widget-config.desktop-hide' | translate }}
|
|
</mat-slide-toggle>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div translate>widget-config.order</div>
|
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
|
<input matInput formControlName="mobileOrder" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<div class="tb-form-row space-between">
|
|
<div translate>widget-config.height</div>
|
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
|
<input matInput formControlName="mobileHeight" type="number" min="1" step="1" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<ng-template #basicMode>
|
|
<div class="tb-widget-config-content">
|
|
<div class="mat-content" *ngIf="hasBasicModeDirective; else basicModeContent">
|
|
<ng-container #basicModeContainer></ng-container>
|
|
<div class="tb-basic-mode-directive-error" *ngIf="basicModeDirectiveError">{{basicModeDirectiveError}}</div>
|
|
</div>
|
|
<ng-template #basicModeContent>
|
|
<div class="mat-content">
|
|
<ng-container *ngTemplateOutlet="data"></ng-container>
|
|
<ng-container *ngTemplateOutlet="appearance"></ng-container>
|
|
<ng-container [formGroup]="actionsSettings">
|
|
<tb-widget-actions-panel
|
|
formControlName="actions">
|
|
</tb-widget-actions-panel>
|
|
</ng-container>
|
|
</div>
|
|
</ng-template>
|
|
</div>
|
|
</ng-template>
|
|
<ng-template #data>
|
|
<ng-container *ngIf="displayTimewindowConfig" [formGroup]="dataSettings">
|
|
<tb-timewindow-config-panel
|
|
[onlyHistoryTimewindow]="onlyHistoryTimewindow()"
|
|
formControlName="timewindowConfig">
|
|
</tb-timewindow-config-panel>
|
|
</ng-container>
|
|
<div *ngIf="widgetType === widgetTypes.alarm" [formGroup]="dataSettings" class="tb-form-panel">
|
|
<div class="flex flex-row items-center justify-between">
|
|
<div class="tb-form-panel-title" translate>alarm.filter</div>
|
|
<button mat-button color="primary"
|
|
(click)="alarmFilterConfig.reset()">
|
|
{{ 'action.reset' | translate }}
|
|
</button>
|
|
</div>
|
|
<tb-alarm-filter-config #alarmFilterConfig buttonMode="false"
|
|
formControlName="alarmFilterConfig" [initialAlarmFilterConfig]="{}"></tb-alarm-filter-config>
|
|
</div>
|
|
<div *ngIf="widgetType !== widgetTypes.rpc &&
|
|
widgetType !== widgetTypes.alarm &&
|
|
modelValue?.isDataEnabled"
|
|
[formGroup]="dataSettings">
|
|
<tb-datasources
|
|
[configMode]="widgetConfigMode"
|
|
formControlName="datasources">
|
|
</tb-datasources>
|
|
</div>
|
|
<ng-container *ngIf="widgetType === widgetTypes.rpc &&
|
|
modelValue?.isDataEnabled" [formGroup]="targetDeviceSettings">
|
|
<tb-target-device formControlName="targetDevice">
|
|
</tb-target-device>
|
|
</ng-container>
|
|
<div *ngIf="widgetType === widgetTypes.alarm && modelValue?.isDataEnabled"
|
|
[formGroup]="dataSettings" class="tb-form-panel">
|
|
<div class="tb-form-panel-title" translate>widget-config.alarm-source</div>
|
|
<tb-datasource
|
|
formControlName="alarmSource">
|
|
</tb-datasource>
|
|
</div>
|
|
<div *ngIf="displayLimits" class="tb-form-panel" [formGroup]="widgetSettings">
|
|
<div class="tb-form-panel-title" translate>widget-config.limits</div>
|
|
<div class="tb-form-row space-between column-xs">
|
|
<div translate>widget-config.data-page-size</div>
|
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
|
<input matInput formControlName="pageSize" type="number" min="1" step="1">
|
|
</mat-form-field>
|
|
</div>
|
|
</div>
|
|
</ng-template>
|
|
<ng-template #appearance>
|
|
<div *ngIf="displayAppearanceDataSettings" class="tb-form-panel" [formGroup]="widgetSettings">
|
|
<div class="tb-form-panel-title" translate>widget-config.data-settings</div>
|
|
<div *ngIf="displayUnitsConfig" class="tb-form-row space-between">
|
|
<div tb-hint-tooltip-icon="{{'widget-config.default-data-key-parameter-hint' | translate}}" translate>widget-config.units-by-default</div>
|
|
<tb-unit-input
|
|
formControlName="units">
|
|
</tb-unit-input>
|
|
</div>
|
|
<div *ngIf="displayUnitsConfig" class="tb-form-row space-between">
|
|
<div tb-hint-tooltip-icon="{{'widget-config.default-data-key-parameter-hint' | translate}}" translate>widget-config.decimals-by-default</div>
|
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
|
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
<div *ngIf="displayNoDataDisplayMessageConfig" class="tb-form-row column-xs">
|
|
<div class="fixed-title-width" translate>widget-config.no-data-display-message</div>
|
|
<mat-form-field class="flex-1" appearance="outline" subscriptSizing="dynamic">
|
|
<input matInput formControlName="noDataDisplayMessage" placeholder="{{ 'widget-config.set-message' | translate }}">
|
|
</mat-form-field>
|
|
</div>
|
|
</div>
|
|
<div *ngIf="displayAdvancedAppearance" style="height: 100%;" [formGroup]="advancedSettings">
|
|
<tb-widget-settings
|
|
[aliasController]="aliasController"
|
|
[callbacks]="widgetConfigCallbacks"
|
|
[dashboard]="dashboard"
|
|
[widget]="widget"
|
|
[widgetConfig]="modelValue"
|
|
formControlName="settings">
|
|
</tb-widget-settings>
|
|
</div>
|
|
</ng-template>
|
|
</div>
|
|
|