-
+
-
+
+
widgets.qr-code.qr-code-text-pattern
{{ 'widgets.qr-code.qr-code-text-pattern-required' | translate }}
-
-
-
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/qrcode-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/qrcode-widget-settings.component.ts
index 06e8d7d079..c9c43d2951 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/qrcode-widget-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/qrcode-widget-settings.component.ts
@@ -14,22 +14,19 @@
/// limitations under the License.
///
-import { Component, ViewChild } from '@angular/core';
+import { Component } from '@angular/core';
import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
-import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
-import { JsFuncComponent } from '@shared/components/js-func.component';
@Component({
selector: 'tb-qrcode-widget-settings',
templateUrl: './qrcode-widget-settings.component.html',
- styleUrls: []
+ styleUrls: ['./widget-settings.scss']
})
export class QrCodeWidgetSettingsComponent extends WidgetSettingsComponent {
- @ViewChild('qrCodeTextFunctionComponent', {static: true}) qrCodeTextFunctionComponent: JsFuncComponent;
-
qrCodeWidgetSettingsForm: FormGroup;
constructor(protected store: Store,
@@ -51,8 +48,8 @@ export class QrCodeWidgetSettingsComponent extends WidgetSettingsComponent {
protected onSettingsSet(settings: WidgetSettings) {
this.qrCodeWidgetSettingsForm = this.fb.group({
- qrCodeTextPattern: [settings.qrCodeTextPattern, []],
- useQrCodeTextFunction: [settings.useQrCodeTextFunction, []],
+ qrCodeTextPattern: [settings.qrCodeTextPattern, [Validators.required]],
+ useQrCodeTextFunction: [settings.useQrCodeTextFunction, [Validators.required]],
qrCodeTextFunction: [settings.qrCodeTextFunction, []]
});
}
@@ -64,13 +61,11 @@ export class QrCodeWidgetSettingsComponent extends WidgetSettingsComponent {
protected updateValidators(emitEvent: boolean) {
const useQrCodeTextFunction: boolean = this.qrCodeWidgetSettingsForm.get('useQrCodeTextFunction').value;
if (useQrCodeTextFunction) {
- this.qrCodeWidgetSettingsForm.get('qrCodeTextPattern').setValidators([]);
- this.qrCodeWidgetSettingsForm.get('qrCodeTextFunction').setValidators([Validators.required,
- (control: AbstractControl) => this.qrCodeTextFunctionComponent.validate(control as FormControl)
- ]);
+ this.qrCodeWidgetSettingsForm.get('qrCodeTextPattern').disable();
+ this.qrCodeWidgetSettingsForm.get('qrCodeTextFunction').enable();
} else {
- this.qrCodeWidgetSettingsForm.get('qrCodeTextPattern').setValidators([Validators.required]);
- this.qrCodeWidgetSettingsForm.get('qrCodeTextFunction').setValidators([]);
+ this.qrCodeWidgetSettingsForm.get('qrCodeTextPattern').enable();
+ this.qrCodeWidgetSettingsForm.get('qrCodeTextFunction').disable();
}
this.qrCodeWidgetSettingsForm.get('qrCodeTextPattern').updateValueAndValidity({emitEvent});
this.qrCodeWidgetSettingsForm.get('qrCodeTextFunction').updateValueAndValidity({emitEvent});
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.html
new file mode 100644
index 0000000000..bf568fc3eb
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.html
@@ -0,0 +1,67 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.ts
new file mode 100644
index 0000000000..b2433dfde0
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-key-settings.component.ts
@@ -0,0 +1,80 @@
+///
+/// Copyright © 2016-2022 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 } from '@angular/core';
+import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Store } from '@ngrx/store';
+import { AppState } from '@core/core.state';
+
+@Component({
+ selector: 'tb-timeseries-table-key-settings',
+ templateUrl: './timeseries-table-key-settings.component.html',
+ styleUrls: ['./widget-settings.scss']
+})
+export class TimeseriesTableKeySettingsComponent extends WidgetSettingsComponent {
+
+ timeseriesTableKeySettingsForm: FormGroup;
+
+ constructor(protected store: Store,
+ private fb: FormBuilder) {
+ super(store);
+ }
+
+ protected settingsForm(): FormGroup {
+ return this.timeseriesTableKeySettingsForm;
+ }
+
+ protected defaultSettings(): WidgetSettings {
+ return {
+ useCellStyleFunction: false,
+ cellStyleFunction: '',
+ useCellContentFunction: false,
+ cellContentFunction: ''
+ };
+ }
+
+ protected onSettingsSet(settings: WidgetSettings) {
+ this.timeseriesTableKeySettingsForm = this.fb.group({
+ useCellStyleFunction: [settings.useCellStyleFunction, []],
+ cellStyleFunction: [settings.cellStyleFunction, [Validators.required]],
+ useCellContentFunction: [settings.useCellContentFunction, []],
+ cellContentFunction: [settings.cellContentFunction, [Validators.required]],
+ });
+ }
+
+ protected validatorTriggers(): string[] {
+ return ['useCellStyleFunction', 'useCellContentFunction'];
+ }
+
+ protected updateValidators(emitEvent: boolean) {
+ const useCellStyleFunction: boolean = this.timeseriesTableKeySettingsForm.get('useCellStyleFunction').value;
+ const useCellContentFunction: boolean = this.timeseriesTableKeySettingsForm.get('useCellContentFunction').value;
+ if (useCellStyleFunction) {
+ this.timeseriesTableKeySettingsForm.get('cellStyleFunction').enable();
+ } else {
+ this.timeseriesTableKeySettingsForm.get('cellStyleFunction').disable();
+ }
+ if (useCellContentFunction) {
+ this.timeseriesTableKeySettingsForm.get('cellContentFunction').enable();
+ } else {
+ this.timeseriesTableKeySettingsForm.get('cellContentFunction').disable();
+ }
+ this.timeseriesTableKeySettingsForm.get('cellStyleFunction').updateValueAndValidity({emitEvent});
+ this.timeseriesTableKeySettingsForm.get('cellContentFunction').updateValueAndValidity({emitEvent});
+ }
+
+}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.html
new file mode 100644
index 0000000000..b005b45ce8
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.html
@@ -0,0 +1,74 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.ts
new file mode 100644
index 0000000000..1d8d26ead3
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-latest-key-settings.component.ts
@@ -0,0 +1,96 @@
+///
+/// Copyright © 2016-2022 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 } from '@angular/core';
+import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Store } from '@ngrx/store';
+import { AppState } from '@core/core.state';
+
+@Component({
+ selector: 'tb-timeseries-table-latest-key-settings',
+ templateUrl: './timeseries-table-latest-key-settings.component.html',
+ styleUrls: ['./widget-settings.scss']
+})
+export class TimeseriesTableLatestKeySettingsComponent extends WidgetSettingsComponent {
+
+ timeseriesTableLatestKeySettingsForm: FormGroup;
+
+ constructor(protected store: Store,
+ private fb: FormBuilder) {
+ super(store);
+ }
+
+ protected settingsForm(): FormGroup {
+ return this.timeseriesTableLatestKeySettingsForm;
+ }
+
+ protected defaultSettings(): WidgetSettings {
+ return {
+ show: true,
+ useCellStyleFunction: false,
+ cellStyleFunction: '',
+ useCellContentFunction: false,
+ cellContentFunction: ''
+ };
+ }
+
+ protected onSettingsSet(settings: WidgetSettings) {
+ this.timeseriesTableLatestKeySettingsForm = this.fb.group({
+ show: [settings.show, []],
+ order: [settings.order, []],
+ useCellStyleFunction: [settings.useCellStyleFunction, []],
+ cellStyleFunction: [settings.cellStyleFunction, [Validators.required]],
+ useCellContentFunction: [settings.useCellContentFunction, []],
+ cellContentFunction: [settings.cellContentFunction, [Validators.required]],
+ });
+ }
+
+ protected validatorTriggers(): string[] {
+ return ['show', 'useCellStyleFunction', 'useCellContentFunction'];
+ }
+
+ protected updateValidators(emitEvent: boolean) {
+ const show: boolean = this.timeseriesTableLatestKeySettingsForm.get('show').value;
+ if (show) {
+ this.timeseriesTableLatestKeySettingsForm.get('order').enable();
+ this.timeseriesTableLatestKeySettingsForm.get('useCellStyleFunction').enable({emitEvent: false});
+ this.timeseriesTableLatestKeySettingsForm.get('useCellContentFunction').enable({emitEvent: false});
+ const useCellStyleFunction: boolean = this.timeseriesTableLatestKeySettingsForm.get('useCellStyleFunction').value;
+ const useCellContentFunction: boolean = this.timeseriesTableLatestKeySettingsForm.get('useCellContentFunction').value;
+ if (useCellStyleFunction) {
+ this.timeseriesTableLatestKeySettingsForm.get('cellStyleFunction').enable();
+ } else {
+ this.timeseriesTableLatestKeySettingsForm.get('cellStyleFunction').disable();
+ }
+ if (useCellContentFunction) {
+ this.timeseriesTableLatestKeySettingsForm.get('cellContentFunction').enable();
+ } else {
+ this.timeseriesTableLatestKeySettingsForm.get('cellContentFunction').disable();
+ }
+ } else {
+ this.timeseriesTableLatestKeySettingsForm.get('order').disable();
+ this.timeseriesTableLatestKeySettingsForm.get('useCellStyleFunction').disable({emitEvent: false});
+ this.timeseriesTableLatestKeySettingsForm.get('cellStyleFunction').disable();
+ this.timeseriesTableLatestKeySettingsForm.get('useCellContentFunction').disable({emitEvent: false});
+ this.timeseriesTableLatestKeySettingsForm.get('cellContentFunction').disable();
+ }
+ this.timeseriesTableLatestKeySettingsForm.get('order').updateValueAndValidity({emitEvent});
+ this.timeseriesTableLatestKeySettingsForm.get('cellStyleFunction').updateValueAndValidity({emitEvent});
+ this.timeseriesTableLatestKeySettingsForm.get('cellContentFunction').updateValueAndValidity({emitEvent});
+ }
+
+}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.html
new file mode 100644
index 0000000000..5f90fd6aed
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.html
@@ -0,0 +1,95 @@
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.ts
new file mode 100644
index 0000000000..d28b4f081a
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/timeseries-table-widget-settings.component.ts
@@ -0,0 +1,98 @@
+///
+/// Copyright © 2016-2022 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 } from '@angular/core';
+import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Store } from '@ngrx/store';
+import { AppState } from '@core/core.state';
+
+@Component({
+ selector: 'tb-timeseries-table-widget-settings',
+ templateUrl: './timeseries-table-widget-settings.component.html',
+ styleUrls: ['./widget-settings.scss']
+})
+export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsComponent {
+
+ timeseriesTableWidgetSettingsForm: FormGroup;
+
+ constructor(protected store: Store,
+ private fb: FormBuilder) {
+ super(store);
+ }
+
+ protected settingsForm(): FormGroup {
+ return this.timeseriesTableWidgetSettingsForm;
+ }
+
+ protected defaultSettings(): WidgetSettings {
+ return {
+ enableSearch: true,
+ enableStickyHeader: true,
+ enableStickyAction: true,
+ reserveSpaceForHiddenAction: 'true',
+ showTimestamp: true,
+ showMilliseconds: false,
+ displayPagination: true,
+ useEntityLabel: false,
+ defaultPageSize: 10,
+ hideEmptyLines: false,
+ disableStickyHeader: false,
+ useRowStyleFunction: false,
+ rowStyleFunction: ''
+ };
+ }
+
+ protected onSettingsSet(settings: WidgetSettings) {
+ this.timeseriesTableWidgetSettingsForm = this.fb.group({
+ enableSearch: [settings.enableSearch, []],
+ enableStickyHeader: [settings.enableStickyHeader, []],
+ enableStickyAction: [settings.enableStickyAction, []],
+ reserveSpaceForHiddenAction: [settings.reserveSpaceForHiddenAction, []],
+ showTimestamp: [settings.showTimestamp, []],
+ showMilliseconds: [settings.showMilliseconds, []],
+ displayPagination: [settings.displayPagination, []],
+ useEntityLabel: [settings.useEntityLabel, []],
+ defaultPageSize: [settings.defaultPageSize, [Validators.min(1)]],
+ hideEmptyLines: [settings.hideEmptyLines, []],
+ disableStickyHeader: [settings.disableStickyHeader, []],
+ useRowStyleFunction: [settings.useRowStyleFunction, []],
+ rowStyleFunction: [settings.rowStyleFunction, [Validators.required]]
+ });
+ }
+
+ protected validatorTriggers(): string[] {
+ return ['useRowStyleFunction', 'displayPagination'];
+ }
+
+ protected updateValidators(emitEvent: boolean) {
+ const useRowStyleFunction: boolean = this.timeseriesTableWidgetSettingsForm.get('useRowStyleFunction').value;
+ const displayPagination: boolean = this.timeseriesTableWidgetSettingsForm.get('displayPagination').value;
+ if (useRowStyleFunction) {
+ this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').enable();
+ } else {
+ this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').disable();
+ }
+ if (displayPagination) {
+ this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').enable();
+ } else {
+ this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').disable();
+ }
+ this.timeseriesTableWidgetSettingsForm.get('rowStyleFunction').updateValueAndValidity({emitEvent});
+ this.timeseriesTableWidgetSettingsForm.get('defaultPageSize').updateValueAndValidity({emitEvent});
+ }
+
+}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts
index 7a10d51465..e31eef1f87 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts
@@ -20,10 +20,22 @@ import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';
import { SharedHomeComponentsModule } from '@home/components/shared-home-components.module';
import { IWidgetSettingsComponent } from '@shared/models/widget.models';
+import {
+ TimeseriesTableWidgetSettingsComponent
+} from '@home/components/widget/lib/settings/timeseries-table-widget-settings.component';
+import {
+ TimeseriesTableKeySettingsComponent
+} from '@home/components/widget/lib/settings/timeseries-table-key-settings.component';
+import {
+ TimeseriesTableLatestKeySettingsComponent
+} from '@home/components/widget/lib/settings/timeseries-table-latest-key-settings.component';
@NgModule({
declarations: [
- QrCodeWidgetSettingsComponent
+ QrCodeWidgetSettingsComponent,
+ TimeseriesTableWidgetSettingsComponent,
+ TimeseriesTableKeySettingsComponent,
+ TimeseriesTableLatestKeySettingsComponent
],
imports: [
CommonModule,
@@ -31,12 +43,18 @@ import { IWidgetSettingsComponent } from '@shared/models/widget.models';
SharedHomeComponentsModule
],
exports: [
- QrCodeWidgetSettingsComponent
+ QrCodeWidgetSettingsComponent,
+ TimeseriesTableWidgetSettingsComponent,
+ TimeseriesTableKeySettingsComponent,
+ TimeseriesTableLatestKeySettingsComponent
]
})
export class WidgetSettingsModule {
}
export const widgetSettingsComponentsMap: {[key: string]: Type} = {
- 'tb-qrcode-widget-settings': QrCodeWidgetSettingsComponent
+ 'tb-qrcode-widget-settings': QrCodeWidgetSettingsComponent,
+ 'tb-timeseries-table-widget-settings': TimeseriesTableWidgetSettingsComponent,
+ 'tb-timeseries-table-key-settings': TimeseriesTableKeySettingsComponent,
+ 'tb-timeseries-table-latest-key-settings': TimeseriesTableLatestKeySettingsComponent
};
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.scss
new file mode 100644
index 0000000000..4b9e0edd97
--- /dev/null
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.scss
@@ -0,0 +1,113 @@
+/**
+ * Copyright © 2016-2022 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 {
+ .tb-widget-settings {
+ .fields-group {
+ padding: 0 16px 8px;
+ margin-bottom: 10px;
+ border: 1px groove rgba(0, 0, 0, .25);
+ border-radius: 4px;
+
+ legend {
+ color: rgba(0, 0, 0, .7);
+ width: fit-content;
+ }
+
+ legend + * {
+ margin-top: 16px;
+ }
+
+ &.fields-group-slider {
+ padding: 0;
+
+ legend {
+ margin-left: 16px;
+ }
+
+ .tb-settings {
+ margin-top: 0;
+ padding: 0 16px 8px;
+ }
+ }
+ }
+ }
+}
+
+:host ::ng-deep {
+ .tb-widget-settings {
+ .mat-checkbox-label {
+ white-space: normal;
+ }
+
+ .mat-expansion-panel {
+ &.tb-settings {
+ box-shadow: none;
+
+ .mat-content {
+ overflow: visible;
+ }
+
+ .mat-expansion-panel-header {
+ padding: 0;
+
+ &:hover {
+ background: none;
+ }
+
+ .mat-expansion-indicator {
+ padding: 2px;
+ }
+ }
+
+ .mat-expansion-panel-header-description {
+ align-items: center;
+ }
+
+ .mat-expansion-panel-body {
+ padding: 0;
+ }
+
+ .mat-checkbox-layout {
+ margin: 5px 0;
+ }
+
+ .mat-checkbox-inner-container {
+ margin-right: 12px;
+ }
+ }
+
+ .mat-expansion-panel-content {
+ font: inherit;
+ }
+ }
+
+ .mat-slide {
+ margin: 8px 0;
+ }
+
+ .slide-block {
+ display: block;
+
+ &:not(:last-child) {
+ margin-bottom: 8px;
+ }
+ }
+
+ .mat-slide-toggle-content {
+ white-space: normal;
+ }
+ }
+}
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts
index 9226c4e1f1..15919447ea 100644
--- a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts
@@ -43,6 +43,7 @@ import { JsonFormComponentData } from '@shared/components/json-form/json-form-co
import { IWidgetSettingsComponent, Widget, WidgetSettings } from '@shared/models/widget.models';
import { widgetSettingsComponentsMap } from '@home/components/widget/lib/settings/widget-settings.module';
import { Dashboard } from '@shared/models/dashboard.models';
+import { WidgetService } from '@core/http/widget.service';
@Component({
selector: 'tb-widget-settings',
@@ -100,6 +101,7 @@ export class WidgetSettingsComponent implements ControlValueAccessor, OnInit, On
constructor(private translate: TranslateService,
private cfr: ComponentFactoryResolver,
+ private widgetService: WidgetService,
private fb: FormBuilder) {
this.widgetSettingsFormGroup = this.fb.group({
settings: [null, Validators.required]
@@ -143,6 +145,7 @@ export class WidgetSettingsComponent implements ControlValueAccessor, OnInit, On
if (this.definedSettingsComponent) {
this.definedSettingsComponent.dashboard = this.dashboard;
this.definedSettingsComponent.widget = this.widget;
+ this.definedSettingsComponent.functionScopeVariables = this.widgetService.getWidgetScopeVariables();
this.definedSettingsComponent.settings = this.widgetSettingsFormData.model;
this.changeSubscription = this.definedSettingsComponent.settingsChanged.subscribe((settings) => {
this.updateModel(settings);
@@ -196,6 +199,7 @@ export class WidgetSettingsComponent implements ControlValueAccessor, OnInit, On
this.definedSettingsComponent = this.definedSettingsComponentRef.instance;
this.definedSettingsComponent.dashboard = this.dashboard;
this.definedSettingsComponent.widget = this.widget;
+ this.definedSettingsComponent.functionScopeVariables = this.widgetService.getWidgetScopeVariables();
this.changeSubscription = this.definedSettingsComponent.settingsChanged.subscribe((settings) => {
this.updateModel(settings);
});
diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html
index 549230d6a3..13c03b7945 100644
--- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html
+++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html
@@ -265,6 +265,12 @@
[(ngModel)]="widget.dataKeySettingsDirective"
(ngModelChange)="isDirty = true"/>
+
+ widget.latest-data-key-settings-form-selector
+
+
diff --git a/ui-ngx/src/app/shared/components/js-func.component.html b/ui-ngx/src/app/shared/components/js-func.component.html
index 3769e1ff45..a5f4040af1 100644
--- a/ui-ngx/src/app/shared/components/js-func.component.html
+++ b/ui-ngx/src/app/shared/components/js-func.component.html
@@ -19,7 +19,8 @@
tb-fullscreen
[fullscreen]="fullscreen" fxLayout="column">
-
+
+
-
diff --git a/ui-ngx/src/app/shared/components/js-func.component.scss b/ui-ngx/src/app/shared/components/js-func.component.scss
index 6cb0154c88..3a7ddc3d09 100644
--- a/ui-ngx/src/app/shared/components/js-func.component.scss
+++ b/ui-ngx/src/app/shared/components/js-func.component.scss
@@ -26,9 +26,12 @@
.tb-js-func-panel {
height: calc(100% - 80px);
- margin-left: 15px;
border: 1px solid #c0c0c0;
+ &:not(.tb-js-func-title) {
+ margin-left: 15px;
+ }
+
#tb-javascript-input {
width: 100%;
min-width: 200px;
diff --git a/ui-ngx/src/app/shared/components/js-func.component.ts b/ui-ngx/src/app/shared/components/js-func.component.ts
index 439677ffe5..be78c7480c 100644
--- a/ui-ngx/src/app/shared/components/js-func.component.ts
+++ b/ui-ngx/src/app/shared/components/js-func.component.ts
@@ -69,6 +69,8 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor,
toastTargetId = `jsFuncEditor-${guid()}`;
+ @Input() functionTitle: string;
+
@Input() functionName: string;
@Input() functionArgs: Array;
diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts
index bbb2ea56d2..1f3cece5cb 100644
--- a/ui-ngx/src/app/shared/models/widget.models.ts
+++ b/ui-ngx/src/app/shared/models/widget.models.ts
@@ -615,6 +615,7 @@ export interface WidgetSize {
export interface IWidgetSettingsComponent {
dashboard: Dashboard;
widget: Widget;
+ functionScopeVariables: string[];
settings: WidgetSettings;
settingsChanged: Observable;
validate();
@@ -630,12 +631,18 @@ export abstract class WidgetSettingsComponent extends PageComponent implements
widget: Widget;
+ functionScopeVariables: string[];
+
settingsValue: WidgetSettings;
private settingsSet = false;
set settings(value: WidgetSettings) {
- this.settingsValue = value || this.defaultSettings();
+ if (!value) {
+ this.settingsValue = this.defaultSettings();
+ } else {
+ this.settingsValue = {...this.defaultSettings(), ...value};
+ }
if (!this.settingsSet) {
this.settingsSet = true;
this.setupSettings(this.settingsValue);
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json
index f904f10930..47d22d9b3f 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -3001,6 +3001,7 @@
"image-preview": "Image preview",
"settings-form-selector": "Settings form selector",
"data-key-settings-form-selector": "Data key settings form selector",
+ "latest-data-key-settings-form-selector": "Latest data key settings form selector",
"javascript": "Javascript",
"js": "JS",
"remove-widget-type-title": "Are you sure you want to remove the widget type '{{widgetName}}'?",
@@ -3366,6 +3367,32 @@
"drawCircleMarkerButton": "Create circle marker",
"rotateButton": "Rotate polygon"
}
+ },
+ "table": {
+ "common-table-settings": "Common Table Settings",
+ "enable-search": "Enable search",
+ "enable-sticky-header": "Always display header",
+ "enable-sticky-action": "Always display actions column",
+ "hidden-cell-button-display-mode": "Hidden cell button actions display mode",
+ "show-empty-space-hidden-action": "Show empty space instead of hidden cell button action",
+ "dont-reserve-space-hidden-action": "Don't reserve space for hidden action buttons",
+ "display-timestamp": "Display timestamp column",
+ "display-milliseconds": "Display timestamp milliseconds",
+ "display-pagination": "Display pagination",
+ "default-page-size": "Default page size",
+ "use-entity-label-tab-name": "Use entity label in tab name",
+ "hide-empty-lines": "Hide empty lines",
+ "row-style": "Row style",
+ "use-row-style-function": "Use row style function",
+ "row-style-function": "Row style function",
+ "cell-style": "Cell style",
+ "use-cell-style-function": "Use cell style function",
+ "cell-style-function": "Cell style function",
+ "cell-content": "Cell content",
+ "use-cell-content-function": "Use cell content function",
+ "cell-content-function": "Cell content function",
+ "show-latest-data-column": "Show latest data column",
+ "latest-data-column-order": "Latest data column order"
}
},
"icon": {