Browse Source

UI: Change models and for advanced color telemetry subscribe

pull/10557/head
Vladyslav_Prykhodko 2 years ago
parent
commit
96aafa840f
  1. 4
      ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html
  2. 9
      ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts
  3. 42
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts
  4. 26
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
  5. 18
      ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.models.ts
  6. 24
      ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.ts
  7. 32
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-row.component.ts
  8. 9
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-thresholds-panel.component.ts
  9. 6
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts
  10. 13
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts
  11. 10
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts
  12. 7
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/entity-alias-input.component.ts
  13. 8
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts
  14. 30
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source-data-key.component.ts
  15. 10
      ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts
  16. 80
      ui-ngx/src/app/shared/models/widget-settings.models.ts

4
ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/battery-level-basic-config.component.html

@ -114,8 +114,6 @@
<tb-color-settings formControlName="batteryLevelColor" <tb-color-settings formControlName="batteryLevelColor"
rangeAdvancedMode rangeAdvancedMode
gradientAdvancedMode gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController" [aliasController]="aliasController"
[dataKeyCallbacks]="callbacks" [dataKeyCallbacks]="callbacks"
[datasource]="datasource" [datasource]="datasource"
@ -127,8 +125,6 @@
<tb-color-settings formControlName="batteryShapeColor" <tb-color-settings formControlName="batteryShapeColor"
rangeAdvancedMode rangeAdvancedMode
gradientAdvancedMode gradientAdvancedMode
minValue="0"
maxValue="100"
[aliasController]="aliasController" [aliasController]="aliasController"
[dataKeyCallbacks]="callbacks" [dataKeyCallbacks]="callbacks"
[datasource]="datasource" [datasource]="datasource"

9
ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts

@ -21,7 +21,8 @@ import {
filterIncludingColorRanges, filterIncludingColorRanges,
Font, Font,
simpleDateFormat, simpleDateFormat,
sortedColorRange sortedColorRange,
ValueSourceType
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
import { LegendPosition } from '@shared/models/widget.models'; import { LegendPosition } from '@shared/models/widget.models';
import { import {
@ -37,7 +38,6 @@ import {
TimeSeriesChartSettings, TimeSeriesChartSettings,
TimeSeriesChartThreshold, TimeSeriesChartThreshold,
timeSeriesChartThresholdDefaultSettings, timeSeriesChartThresholdDefaultSettings,
TimeSeriesChartThresholdType,
TimeSeriesChartTooltipWidgetSettings, TimeSeriesChartTooltipWidgetSettings,
TimeSeriesChartVisualMapPiece, TimeSeriesChartVisualMapPiece,
TimeSeriesChartXAxisSettings, TimeSeriesChartXAxisSettings,
@ -50,7 +50,8 @@ import {
ChartAnimationSettings, ChartAnimationSettings,
chartColorScheme, chartColorScheme,
ChartFillType, ChartFillType,
ChartLabelPosition, ChartLineType, ChartLabelPosition,
ChartLineType,
ChartShape ChartShape
} from '@home/components/widget/lib/chart/chart.models'; } from '@home/components/widget/lib/chart/chart.models';
@ -219,7 +220,7 @@ export const rangeChartDefaultSettings: RangeChartWidgetSettings = {
export const rangeChartTimeSeriesSettings = (settings: RangeChartWidgetSettings, rangeItems: RangeItem[], export const rangeChartTimeSeriesSettings = (settings: RangeChartWidgetSettings, rangeItems: RangeItem[],
decimals: number, units: string): DeepPartial<TimeSeriesChartSettings> => { decimals: number, units: string): DeepPartial<TimeSeriesChartSettings> => {
let thresholds: DeepPartial<TimeSeriesChartThreshold>[] = settings.showRangeThresholds ? getMarkPoints(rangeItems).map(item => ({ let thresholds: DeepPartial<TimeSeriesChartThreshold>[] = settings.showRangeThresholds ? getMarkPoints(rangeItems).map(item => ({
...{type: TimeSeriesChartThresholdType.constant, ...{type: ValueSourceType.constant,
yAxisId: 'default', yAxisId: 'default',
units, units,
decimals, decimals,

42
ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts

@ -26,7 +26,9 @@ import {
DateFormatProcessor, DateFormatProcessor,
DateFormatSettings, DateFormatSettings,
Font, Font,
tsToFormatTimeUnit tsToFormatTimeUnit,
ValueSourceType,
ValueSourceTypeConfig
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
import { import {
CallbackDataParams, CallbackDataParams,
@ -66,7 +68,6 @@ import {
FormattedData, FormattedData,
WidgetComparisonSettings WidgetComparisonSettings
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { AbstractControl, ValidationErrors } from '@angular/forms'; import { AbstractControl, ValidationErrors } from '@angular/forms';
import { MarkLine2DDataItemOption } from 'echarts/types/src/component/marker/MarkLineModel'; import { MarkLine2DDataItemOption } from 'echarts/types/src/component/marker/MarkLineModel';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
@ -88,7 +89,8 @@ import {
chartColorScheme, chartColorScheme,
ChartFillSettings, ChartFillSettings,
ChartFillType, ChartFillType,
ChartLabelPosition, ChartLineType, ChartLabelPosition,
ChartLineType,
ChartShape, ChartShape,
createChartTextStyle, createChartTextStyle,
createLinearOpacityGradient, createLinearOpacityGradient,
@ -522,23 +524,6 @@ export const timeSeriesThresholdLabelPositionTranslations = new Map<ThresholdLab
] ]
); );
export enum TimeSeriesChartThresholdType {
constant = 'constant',
latestKey = 'latestKey',
entity = 'entity'
}
export const timeSeriesThresholdTypes = Object.keys(TimeSeriesChartThresholdType) as TimeSeriesChartThresholdType[];
export const timeSeriesThresholdTypeTranslations = new Map<TimeSeriesChartThresholdType, string>(
[
[TimeSeriesChartThresholdType.constant, 'widgets.time-series-chart.threshold.type-constant'],
[TimeSeriesChartThresholdType.latestKey, 'widgets.time-series-chart.threshold.type-latest-key'],
[TimeSeriesChartThresholdType.entity, 'widgets.time-series-chart.threshold.type-entity']
]
);
export enum TimeSeriesChartStateSourceType { export enum TimeSeriesChartStateSourceType {
constant = 'constant', constant = 'constant',
range = 'range' range = 'range'
@ -737,14 +722,7 @@ export const defaultTimeSeriesChartXAxisSettings: TimeSeriesChartXAxisSettings =
export type TimeSeriesChartYAxes = {[id: TimeSeriesChartYAxisId]: TimeSeriesChartYAxisSettings}; export type TimeSeriesChartYAxes = {[id: TimeSeriesChartYAxisId]: TimeSeriesChartYAxisSettings};
export interface TimeSeriesChartThreshold { export interface TimeSeriesChartThreshold extends ValueSourceTypeConfig {
type: TimeSeriesChartThresholdType;
value?: number;
latestKey?: string;
latestKeyType?: DataKeyType.attribute | DataKeyType.timeseries;
entityAlias?: string;
entityKey?: string;
entityKeyType?: DataKeyType.attribute | DataKeyType.timeseries;
yAxisId: TimeSeriesChartYAxisId; yAxisId: TimeSeriesChartYAxisId;
units?: string; units?: string;
decimals?: number; decimals?: number;
@ -769,17 +747,17 @@ export const timeSeriesChartThresholdValid = (threshold: TimeSeriesChartThreshol
return false; return false;
} }
switch (threshold.type) { switch (threshold.type) {
case TimeSeriesChartThresholdType.constant: case ValueSourceType.constant:
if (isUndefinedOrNull(threshold.value)) { if (isUndefinedOrNull(threshold.value)) {
return false; return false;
} }
break; break;
case TimeSeriesChartThresholdType.latestKey: case ValueSourceType.latestKey:
if (!threshold.latestKey || !threshold.latestKeyType) { if (!threshold.latestKey || !threshold.latestKeyType) {
return false; return false;
} }
break; break;
case TimeSeriesChartThresholdType.entity: case ValueSourceType.entity:
if (!threshold.entityAlias || !threshold.entityKey || !threshold.entityKeyType) { if (!threshold.entityAlias || !threshold.entityKey || !threshold.entityKeyType) {
return false; return false;
} }
@ -799,7 +777,7 @@ export const timeSeriesChartThresholdValidator = (control: AbstractControl): Val
}; };
export const timeSeriesChartThresholdDefaultSettings: TimeSeriesChartThreshold = { export const timeSeriesChartThresholdDefaultSettings: TimeSeriesChartThreshold = {
type: TimeSeriesChartThresholdType.constant, type: ValueSourceType.constant,
yAxisId: 'default', yAxisId: 'default',
units: null, units: null,
decimals: 0, decimals: 0,

26
ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts

@ -37,7 +37,6 @@ import {
TimeSeriesChartThreshold, TimeSeriesChartThreshold,
timeSeriesChartThresholdDefaultSettings, timeSeriesChartThresholdDefaultSettings,
TimeSeriesChartThresholdItem, TimeSeriesChartThresholdItem,
TimeSeriesChartThresholdType,
timeSeriesChartTooltipFormatter, timeSeriesChartTooltipFormatter,
TimeSeriesChartTooltipTrigger, TimeSeriesChartTooltipTrigger,
TimeSeriesChartTooltipValueFormatFunction, TimeSeriesChartTooltipValueFormatFunction,
@ -60,7 +59,7 @@ import {
getFocusedSeriesIndex, getFocusedSeriesIndex,
measureAxisNameSize measureAxisNameSize
} from '@home/components/widget/lib/chart/echarts-widget.models'; } from '@home/components/widget/lib/chart/echarts-widget.models';
import { DateFormatProcessor } from '@shared/models/widget-settings.models'; import { DateFormatProcessor, ValueSourceType } from '@shared/models/widget-settings.models';
import { formattedDataFormDatasourceData, formatValue, isDefinedAndNotNull, isEqual, mergeDeep } from '@core/utils'; import { formattedDataFormDatasourceData, formatValue, isDefinedAndNotNull, isEqual, mergeDeep } from '@core/utils';
import { DataKey, Datasource, DatasourceType, FormattedData, widgetType } from '@shared/models/widget.models'; import { DataKey, Datasource, DatasourceType, FormattedData, widgetType } from '@shared/models/widget.models';
import * as echarts from 'echarts/core'; import * as echarts from 'echarts/core';
@ -255,7 +254,7 @@ export class TbTimeSeriesChart {
item.latestData = latestData; item.latestData = latestData;
} }
for (const item of this.thresholdItems) { for (const item of this.thresholdItems) {
if (item.settings.type === TimeSeriesChartThresholdType.latestKey && item.latestDataKey) { if (item.settings.type === ValueSourceType.latestKey && item.latestDataKey) {
const data = this.ctx.latestData.find(d => d.dataKey === item.latestDataKey); const data = this.ctx.latestData.find(d => d.dataKey === item.latestDataKey);
if (data.data[0]) { if (data.data[0]) {
item.value = parseThresholdData(data.data[0][1]); item.value = parseThresholdData(data.data[0][1]);
@ -435,7 +434,7 @@ export class TbTimeSeriesChart {
let latestDataKey: DataKey = null; let latestDataKey: DataKey = null;
let entityDataKey: DataKey = null; let entityDataKey: DataKey = null;
let value = null; let value = null;
if (threshold.type === TimeSeriesChartThresholdType.latestKey) { if (threshold.type === ValueSourceType.latestKey) {
if (this.ctx.datasources.length) { if (this.ctx.datasources.length) {
for (const datasource of this.ctx.datasources) { for (const datasource of this.ctx.datasources) {
latestDataKey = datasource.latestDataKeys?.find(d => latestDataKey = datasource.latestDataKeys?.find(d =>
@ -450,7 +449,7 @@ export class TbTimeSeriesChart {
if (!latestDataKey) { if (!latestDataKey) {
continue; continue;
} }
} else if (threshold.type === TimeSeriesChartThresholdType.entity) { } else if (threshold.type === ValueSourceType.entity) {
const entityAliasId = this.ctx.aliasController.getEntityAliasId(threshold.entityAlias); const entityAliasId = this.ctx.aliasController.getEntityAliasId(threshold.entityAlias);
if (!entityAliasId) { if (!entityAliasId) {
continue; continue;
@ -464,14 +463,15 @@ export class TbTimeSeriesChart {
}; };
if (datasource) { if (datasource) {
datasource.dataKeys.push(entityDataKey); datasource.dataKeys.push(entityDataKey);
} else {
datasource = {
type: DatasourceType.entity,
name: threshold.entityAlias,
aliasName: threshold.entityAlias,
entityAliasId,
dataKeys: [entityDataKey]
};
} }
datasource = {
type: DatasourceType.entity,
name: threshold.entityAlias,
aliasName: threshold.entityAlias,
entityAliasId,
dataKeys: [ entityDataKey ]
};
thresholdDatasources.push(datasource); thresholdDatasources.push(datasource);
} else { // constant } else { // constant
value = threshold.value; value = threshold.value;
@ -567,7 +567,7 @@ export class TbTimeSeriesChart {
let update = false; let update = false;
if (subscription.data) { if (subscription.data) {
for (const item of this.thresholdItems) { for (const item of this.thresholdItems) {
if (item.settings.type === TimeSeriesChartThresholdType.entity) { if (item.settings.type === ValueSourceType.entity) {
const data = subscription.data.find(d => d.dataKey.settings?.thresholdItemId === item.id); const data = subscription.data.find(d => d.dataKey.settings?.thresholdItemId === item.id);
if (data.data[0]) { if (data.data[0]) {
item.value = parseThresholdData(data.data[0][1]); item.value = parseThresholdData(data.data[0][1]);

18
ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.models.ts

@ -20,8 +20,8 @@ import { FontSettings } from '@home/components/widget/lib/settings.models';
import { import {
AdvancedColorRange, AdvancedColorRange,
ColorSettings, ColorSettings,
ValueSourceDataKeyType, ValueSourceType,
ValueSourceWithDataKey ValueSourceTypeConfig
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { isDefinedAndNotNull } from '@core/utils'; import { isDefinedAndNotNull } from '@core/utils';
@ -34,8 +34,8 @@ export interface AttributeSourceProperty {
} }
export interface FixedLevelColors { export interface FixedLevelColors {
from?: ValueSourceWithDataKey | number; from?: ValueSourceTypeConfig | number;
to?: ValueSourceWithDataKey | number; to?: ValueSourceTypeConfig | number;
color: string; color: string;
} }
@ -112,7 +112,7 @@ export interface DigitalGaugeSettings {
hideValue?: boolean; hideValue?: boolean;
hideMinMax?: boolean; hideMinMax?: boolean;
showTicks?: boolean; showTicks?: boolean;
ticksValue?: ValueSourceWithDataKey[]; ticksValue?: ValueSourceTypeConfig[];
ticks?: number[]; ticks?: number[];
colorTicks?: string; colorTicks?: string;
tickWidth?: number; tickWidth?: number;
@ -127,14 +127,14 @@ export const backwardCompatibilityFixedLevelColors = (fixedLevelColors) => {
const valueSourceWithDataKey: AdvancedColorRange[] = []; const valueSourceWithDataKey: AdvancedColorRange[] = [];
fixedLevelColors.forEach(fixedLevelColor => valueSourceWithDataKey.push({ fixedLevelColors.forEach(fixedLevelColor => valueSourceWithDataKey.push({
from: { from: {
type: fixedLevelColor?.from?.valueSource === 'predefinedValue' ? ValueSourceDataKeyType.constant : ValueSourceDataKeyType.entity, type: fixedLevelColor?.from?.valueSource === 'predefinedValue' ? ValueSourceType.constant : ValueSourceType.entity,
value: fixedLevelColor?.from?.value || null, value: fixedLevelColor?.from?.value || null,
entityAlias: fixedLevelColor?.from?.entityAlias || '', entityAlias: fixedLevelColor?.from?.entityAlias || '',
entityKey: fixedLevelColor?.from?.attribute || '', entityKey: fixedLevelColor?.from?.attribute || '',
entityKeyType: DataKeyType.attribute entityKeyType: DataKeyType.attribute
}, },
to: { to: {
type: fixedLevelColor?.to?.valueSource === 'predefinedValue' ? ValueSourceDataKeyType.constant : ValueSourceDataKeyType.entity, type: fixedLevelColor?.to?.valueSource === 'predefinedValue' ? ValueSourceType.constant : ValueSourceType.entity,
value: fixedLevelColor?.to?.value || null, value: fixedLevelColor?.to?.value || null,
entityAlias: fixedLevelColor?.to?.entityAlias || '', entityAlias: fixedLevelColor?.to?.entityAlias || '',
entityKey: fixedLevelColor?.to?.attribute || '', entityKey: fixedLevelColor?.to?.attribute || '',
@ -146,10 +146,10 @@ export const backwardCompatibilityFixedLevelColors = (fixedLevelColors) => {
}; };
export const backwardCompatibilityTicks = (ticksValue) => { export const backwardCompatibilityTicks = (ticksValue) => {
const ticks: ValueSourceWithDataKey[] = []; const ticks: ValueSourceTypeConfig[] = [];
if (ticksValue?.length && isDefinedAndNotNull(ticksValue[0]?.valueSource)) { if (ticksValue?.length && isDefinedAndNotNull(ticksValue[0]?.valueSource)) {
ticksValue.forEach(tick => ticks.push({ ticksValue.forEach(tick => ticks.push({
type: tick?.valueSource === 'predefinedValue' ? ValueSourceDataKeyType.constant : ValueSourceDataKeyType.entity, type: tick?.valueSource === 'predefinedValue' ? ValueSourceType.constant : ValueSourceType.entity,
value: tick?.value || null, value: tick?.value || null,
entityAlias: tick?.entityAlias || '', entityAlias: tick?.entityAlias || '',
entityKey: tick?.attribute || '', entityKey: tick?.attribute || '',

24
ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.ts

@ -34,8 +34,8 @@ import { EMPTY, Observable } from 'rxjs';
import { import {
ColorProcessor, ColorProcessor,
ColorType, ColorType,
ValueSourceDataKeyType, ValueSourceType,
ValueSourceWithDataKey ValueSourceTypeConfig
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
import GenericOptions = CanvasGauges.GenericOptions; import GenericOptions = CanvasGauges.GenericOptions;
@ -281,13 +281,18 @@ export class TbCanvasDigitalGauge {
color: this.localSettings.gaugeColor color: this.localSettings.gaugeColor
}); });
function setLevelColor(levelSetting, color: string) { function setLevelColor(levelSetting: ValueSourceTypeConfig | number, color: string) {
if (levelSetting.type === ValueSourceDataKeyType.constant && isFinite(levelSetting.value)) { if (typeof levelSetting === 'number') {
predefineLevelColors.push({
value: levelSetting,
color
});
} else if (levelSetting.type === ValueSourceType.constant && isFinite(levelSetting.value)) {
predefineLevelColors.push({ predefineLevelColors.push({
value: levelSetting.value, value: levelSetting.value,
color color
}); });
} else if (levelSetting.type === ValueSourceDataKeyType.latestKey || levelSetting.type === ValueSourceDataKeyType.entity) { } else if (levelSetting.type === ValueSourceType.latestKey || levelSetting.type === ValueSourceType.entity) {
try { try {
levelColorsDatasource = ColorProcessor.generateDatasource( levelColorsDatasource = ColorProcessor.generateDatasource(
this.ctx, levelColorsDatasource, levelSetting, {color, index: predefineLevelColors.length} this.ctx, levelColorsDatasource, levelSetting, {color, index: predefineLevelColors.length}
@ -296,11 +301,6 @@ export class TbCanvasDigitalGauge {
return; return;
} }
predefineLevelColors.push(null); predefineLevelColors.push(null);
} else if (isFinite(levelSetting)) {
predefineLevelColors.push({
value: levelSetting,
color
});
} }
} }
@ -320,12 +320,12 @@ export class TbCanvasDigitalGauge {
return predefineLevelColors; return predefineLevelColors;
} }
settingTicksSubscribe(options: ValueSourceWithDataKey[]): number[] { settingTicksSubscribe(options: ValueSourceTypeConfig[]): number[] {
let ticksDatasource: Datasource[] = []; let ticksDatasource: Datasource[] = [];
const predefineTicks: number[] = []; const predefineTicks: number[] = [];
for (const tick of options) { for (const tick of options) {
if (tick.type === ValueSourceDataKeyType.constant && isFinite(tick.value)) { if (tick.type === ValueSourceType.constant && isFinite(tick.value)) {
predefineTicks.push(tick.value); predefineTicks.push(tick.value);
} else { } else {
try { try {

32
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-row.component.ts

@ -36,10 +36,7 @@ import {
} from '@angular/forms'; } from '@angular/forms';
import { import {
TimeSeriesChartThreshold, TimeSeriesChartThreshold,
TimeSeriesChartThresholdType, TimeSeriesChartYAxisId
TimeSeriesChartYAxisId,
timeSeriesThresholdTypes,
timeSeriesThresholdTypeTranslations
} from '@home/components/widget/lib/chart/time-series-chart.models'; } from '@home/components/widget/lib/chart/time-series-chart.models';
import { import {
TimeSeriesChartThresholdsPanelComponent TimeSeriesChartThresholdsPanelComponent
@ -50,6 +47,11 @@ import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.comp
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import {
ValueSourceTypes,
ValueSourceType,
ValueSourceTypeTranslation
} from '@shared/models/widget-settings.models';
@Component({ @Component({
selector: 'tb-time-series-chart-threshold-row', selector: 'tb-time-series-chart-threshold-row',
@ -70,11 +72,11 @@ export class TimeSeriesChartThresholdRowComponent implements ControlValueAccesso
DatasourceType = DatasourceType; DatasourceType = DatasourceType;
TimeSeriesChartThresholdType = TimeSeriesChartThresholdType; TimeSeriesChartThresholdType = ValueSourceType;
timeSeriesThresholdTypes = timeSeriesThresholdTypes; timeSeriesThresholdTypes = ValueSourceTypes;
timeSeriesThresholdTypeTranslations = timeSeriesThresholdTypeTranslations; timeSeriesThresholdTypeTranslations = ValueSourceTypeTranslation;
get aliasController(): IAliasController { get aliasController(): IAliasController {
return this.thresholdsPanel.aliasController; return this.thresholdsPanel.aliasController;
@ -209,12 +211,12 @@ export class TimeSeriesChartThresholdRowComponent implements ControlValueAccesso
decimals: value.decimals, decimals: value.decimals,
}, {emitEvent: false} }, {emitEvent: false}
); );
if (value.type === TimeSeriesChartThresholdType.latestKey) { if (value.type === ValueSourceType.latestKey) {
this.latestKeyFormControl.patchValue({ this.latestKeyFormControl.patchValue({
type: value.latestKeyType, type: value.latestKeyType,
name: value.latestKey name: value.latestKey
}, {emitEvent: false}); }, {emitEvent: false});
} else if (value.type === TimeSeriesChartThresholdType.entity) { } else if (value.type === ValueSourceType.entity) {
this.entityKeyFormControl.patchValue({ this.entityKeyFormControl.patchValue({
type: value.entityKeyType, type: value.entityKeyType,
name: value.entityKey name: value.entityKey
@ -227,18 +229,18 @@ export class TimeSeriesChartThresholdRowComponent implements ControlValueAccesso
} }
private updateValidators() { private updateValidators() {
const type: TimeSeriesChartThresholdType = this.thresholdFormGroup.get('type').value; const type: ValueSourceType = this.thresholdFormGroup.get('type').value;
if (type === TimeSeriesChartThresholdType.constant) { if (type === ValueSourceType.constant) {
this.thresholdFormGroup.get('value').enable({emitEvent: false}); this.thresholdFormGroup.get('value').enable({emitEvent: false});
this.thresholdFormGroup.get('entityAlias').disable({emitEvent: false}); this.thresholdFormGroup.get('entityAlias').disable({emitEvent: false});
this.latestKeyFormControl.disable({emitEvent: false}); this.latestKeyFormControl.disable({emitEvent: false});
this.entityKeyFormControl.disable({emitEvent: false}); this.entityKeyFormControl.disable({emitEvent: false});
} else if (type === TimeSeriesChartThresholdType.latestKey) { } else if (type === ValueSourceType.latestKey) {
this.thresholdFormGroup.get('value').disable({emitEvent: false}); this.thresholdFormGroup.get('value').disable({emitEvent: false});
this.thresholdFormGroup.get('entityAlias').disable({emitEvent: false}); this.thresholdFormGroup.get('entityAlias').disable({emitEvent: false});
this.latestKeyFormControl.enable({emitEvent: false}); this.latestKeyFormControl.enable({emitEvent: false});
this.entityKeyFormControl.disable({emitEvent: false}); this.entityKeyFormControl.disable({emitEvent: false});
} else if (type === TimeSeriesChartThresholdType.entity) { } else if (type === ValueSourceType.entity) {
this.thresholdFormGroup.get('value').disable({emitEvent: false}); this.thresholdFormGroup.get('value').disable({emitEvent: false});
this.thresholdFormGroup.get('entityAlias').enable({emitEvent: false}); this.thresholdFormGroup.get('entityAlias').enable({emitEvent: false});
this.latestKeyFormControl.disable({emitEvent: false}); this.latestKeyFormControl.disable({emitEvent: false});
@ -255,11 +257,11 @@ export class TimeSeriesChartThresholdRowComponent implements ControlValueAccesso
this.modelValue.lineColor = value.lineColor; this.modelValue.lineColor = value.lineColor;
this.modelValue.units = value.units; this.modelValue.units = value.units;
this.modelValue.decimals = value.decimals; this.modelValue.decimals = value.decimals;
if (value.type === TimeSeriesChartThresholdType.latestKey) { if (value.type === ValueSourceType.latestKey) {
const latestKey: DataKey = this.latestKeyFormControl.value; const latestKey: DataKey = this.latestKeyFormControl.value;
this.modelValue.latestKey = latestKey?.name; this.modelValue.latestKey = latestKey?.name;
this.modelValue.latestKeyType = (latestKey?.type as any); this.modelValue.latestKeyType = (latestKey?.type as any);
} else if (value.type === TimeSeriesChartThresholdType.entity) { } else if (value.type === ValueSourceType.entity) {
const entityKey: DataKey = this.entityKeyFormControl.value; const entityKey: DataKey = this.entityKeyFormControl.value;
this.modelValue.entityKey = entityKey?.name; this.modelValue.entityKey = entityKey?.name;
this.modelValue.entityKeyType = (entityKey?.type as any); this.modelValue.entityKeyType = (entityKey?.type as any);

9
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-thresholds-panel.component.ts

@ -29,9 +29,9 @@ import {
import { import {
TimeSeriesChartThreshold, TimeSeriesChartThreshold,
timeSeriesChartThresholdDefaultSettings, timeSeriesChartThresholdDefaultSettings,
TimeSeriesChartThresholdType,
timeSeriesChartThresholdValid, timeSeriesChartThresholdValid,
timeSeriesChartThresholdValidator, TimeSeriesChartYAxisId timeSeriesChartThresholdValidator,
TimeSeriesChartYAxisId
} from '@home/components/widget/lib/chart/time-series-chart.models'; } from '@home/components/widget/lib/chart/time-series-chart.models';
import { mergeDeep } from '@core/utils'; import { mergeDeep } from '@core/utils';
import { IAliasController } from '@core/api/widget-api.models'; import { IAliasController } from '@core/api/widget-api.models';
@ -39,6 +39,7 @@ import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.comp
import { DataKey, Datasource, WidgetConfig } from '@shared/models/widget.models'; import { DataKey, Datasource, WidgetConfig } from '@shared/models/widget.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { ValueSourceType } from '@shared/models/widget-settings.models';
@Component({ @Component({
selector: 'tb-time-series-chart-thresholds-panel', selector: 'tb-time-series-chart-thresholds-panel',
@ -169,7 +170,7 @@ export class TimeSeriesChartThresholdsPanelComponent implements ControlValueAcce
const result: TimeSeriesChartThreshold[] = []; const result: TimeSeriesChartThreshold[] = [];
const latestKeys = this.datasource?.latestDataKeys || []; const latestKeys = this.datasource?.latestDataKeys || [];
for (const threshold of thresholds) { for (const threshold of thresholds) {
if (threshold.type === TimeSeriesChartThresholdType.latestKey) { if (threshold.type === ValueSourceType.latestKey) {
const found = latestKeys.find(k => this.isThresholdKey(k, threshold)); const found = latestKeys.find(k => this.isThresholdKey(k, threshold));
if (found) { if (found) {
result.push(threshold); result.push(threshold);
@ -191,7 +192,7 @@ export class TimeSeriesChartThresholdsPanelComponent implements ControlValueAcce
const existingThresholdKeys = latestKeys.filter(k => k.settings?.__thresholdKey === true); const existingThresholdKeys = latestKeys.filter(k => k.settings?.__thresholdKey === true);
const foundThresholdKeys: DataKey[] = []; const foundThresholdKeys: DataKey[] = [];
for (const threshold of thresholds) { for (const threshold of thresholds) {
if (threshold.type === TimeSeriesChartThresholdType.latestKey) { if (threshold.type === ValueSourceType.latestKey) {
const found = existingThresholdKeys.find(k => this.isThresholdKey(k, threshold)); const found = existingThresholdKeys.find(k => this.isThresholdKey(k, threshold));
if (!found) { if (!found) {
const newKey = this.dataKeyCallbacks.generateDataKey(threshold.latestKey, threshold.latestKeyType, const newKey = this.dataKeyCallbacks.generateDataKey(threshold.latestKey, threshold.latestKeyType,

6
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-range-list.component.ts

@ -30,7 +30,7 @@ import {
AdvancedColorRange, AdvancedColorRange,
ColorRange, ColorRange,
ColorRangeSettings, ColorRangeSettings,
ValueSourceDataKeyType ValueSourceType
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
import { TbPopoverComponent } from '@shared/components/popover.component'; import { TbPopoverComponent } from '@shared/components/popover.component';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
@ -197,10 +197,10 @@ export class ColorRangeListComponent implements OnInit, ControlValueAccessor, On
public addAdvancedRange() { public addAdvancedRange() {
const advancedRange: AdvancedColorRange = { const advancedRange: AdvancedColorRange = {
from: { from: {
type: ValueSourceDataKeyType.constant type: ValueSourceType.constant
}, },
to: { to: {
type: ValueSourceDataKeyType.constant type: ValueSourceType.constant
}, },
color: null color: null
}; };

13
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings-panel.component.ts

@ -30,7 +30,7 @@ import { deepClone } from '@core/utils';
import { WidgetService } from '@core/http/widget.service'; import { WidgetService } from '@core/http/widget.service';
import { ColorSettingsComponent } from '@home/components/widget/lib/settings/common/color-settings.component'; import { ColorSettingsComponent } from '@home/components/widget/lib/settings/common/color-settings.component';
import { IAliasController } from '@core/api/widget-api.models'; import { IAliasController } from '@core/api/widget-api.models';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { Datasource } from '@shared/models/widget.models'; import { Datasource } from '@shared/models/widget.models';
@ -73,10 +73,12 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
gradientAdvancedMode = false; gradientAdvancedMode = false;
@Input() @Input()
minValue: string; @coerceNumber()
minValue: number;
@Input() @Input()
maxValue: string; @coerceNumber()
maxValue: number;
colorType = ColorType; colorType = ColorType;
@ -99,7 +101,7 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
{ {
type: [this.colorSettings?.type || ColorType.constant, []], type: [this.colorSettings?.type || ColorType.constant, []],
color: [this.colorSettings?.color, []], color: [this.colorSettings?.color, []],
gradient: [this.colorSettings?.gradient || defaultGradient(+this.minValue, +this.maxValue), []], gradient: [this.colorSettings?.gradient || defaultGradient(this.minValue, this.maxValue), []],
rangeList: [this.colorSettings?.rangeList, []], rangeList: [this.colorSettings?.rangeList, []],
colorFunction: [this.colorSettings?.colorFunction, []] colorFunction: [this.colorSettings?.colorFunction, []]
} }
@ -110,8 +112,7 @@ export class ColorSettingsPanelComponent extends PageComponent implements OnInit
} }
copyColorSettings(comp: ColorSettingsComponent) { copyColorSettings(comp: ColorSettingsComponent) {
const sourceSettings = deepClone(comp.modelValue); this.colorSettings = deepClone(comp.modelValue);
this.colorSettings = sourceSettings;
this.colorSettingsFormGroup.patchValue({ this.colorSettingsFormGroup.patchValue({
type: this.colorSettings.type, type: this.colorSettings.type,
color: this.colorSettings.color, color: this.colorSettings.color,

10
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/color-settings.component.ts

@ -33,7 +33,7 @@ import {
} from '@home/components/widget/lib/settings/common/color-settings-panel.component'; } from '@home/components/widget/lib/settings/common/color-settings-panel.component';
import { IAliasController } from '@core/api/widget-api.models'; import { IAliasController } from '@core/api/widget-api.models';
import { deepClone, isDefinedAndNotNull } from '@core/utils'; import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { Datasource } from '@shared/models/widget.models'; import { Datasource } from '@shared/models/widget.models';
@ -102,10 +102,12 @@ export class ColorSettingsComponent implements OnInit, ControlValueAccessor, OnD
gradientAdvancedMode = false; gradientAdvancedMode = false;
@Input() @Input()
minValue: string; @coerceNumber()
minValue: number;
@Input() @Input()
maxValue: string; @coerceNumber()
maxValue: number;
colorType = ColorType; colorType = ColorType;
@ -113,7 +115,7 @@ export class ColorSettingsComponent implements OnInit, ControlValueAccessor, OnD
colorStyle: ComponentStyle = {}; colorStyle: ComponentStyle = {};
private propagateChange = (v: any) => { }; private propagateChange: (v: any) => void = () => { };
constructor(private popoverService: TbPopoverService, constructor(private popoverService: TbPopoverService,
private renderer: Renderer2, private renderer: Renderer2,

7
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/entity-alias-input.component.ts

@ -15,7 +15,6 @@
/// ///
import { import {
ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef,
forwardRef, forwardRef,
@ -36,7 +35,6 @@ import { coerceBoolean } from '@shared/decorators/coercion';
import { IAliasController } from '@core/api/widget-api.models'; import { IAliasController } from '@core/api/widget-api.models';
import { map, mergeMap } from 'rxjs/operators'; import { map, mergeMap } from 'rxjs/operators';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { TimeSeriesChartThresholdType } from '@home/components/widget/lib/chart/time-series-chart.models';
@Component({ @Component({
selector: 'tb-entity-alias-input', selector: 'tb-entity-alias-input',
@ -78,8 +76,7 @@ export class EntityAliasInputComponent implements ControlValueAccessor, OnInit {
private propagateChange = (_val: any) => {}; private propagateChange = (_val: any) => {};
constructor(private fb: UntypedFormBuilder, constructor(private fb: UntypedFormBuilder) {
private cd: ChangeDetectorRef) {
} }
ngOnInit() { ngOnInit() {
@ -151,6 +148,4 @@ export class EntityAliasInputComponent implements ControlValueAccessor, OnInit {
const value = this.entityAliasFormControl.value; const value = this.entityAliasFormControl.value;
this.propagateChange(value); this.propagateChange(value);
} }
protected readonly TimeSeriesChartThresholdType = TimeSeriesChartThresholdType;
} }

8
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/gradient.component.ts

@ -24,7 +24,7 @@ import {
UntypedFormBuilder, UntypedFormBuilder,
UntypedFormGroup UntypedFormGroup
} from '@angular/forms'; } from '@angular/forms';
import { AdvancedGradient, ColorGradientSettings, ValueSourceDataKeyType } from '@shared/models/widget-settings.models'; import { AdvancedGradient, ColorGradientSettings, ValueSourceType } from '@shared/models/widget-settings.models';
import { TbPopoverComponent } from '@shared/components/popover.component'; import { TbPopoverComponent } from '@shared/components/popover.component';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
@ -101,12 +101,12 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
}), }),
gradientAdvanced: this.fb.group({ gradientAdvanced: this.fb.group({
start: this.fb.group({ start: this.fb.group({
source: [{type: ValueSourceDataKeyType.constant}], source: [{type: ValueSourceType.constant}],
color: ['rgba(0, 255, 0, 1)'] color: ['rgba(0, 255, 0, 1)']
}), }),
gradientList: this.fb.array([]), gradientList: this.fb.array([]),
end: this.fb.group({ end: this.fb.group({
source: [{type: ValueSourceDataKeyType.constant}], source: [{type: ValueSourceType.constant}],
color: ['rgba(255, 0, 0, 1)'] color: ['rgba(255, 0, 0, 1)']
}) })
}) })
@ -241,7 +241,7 @@ export class GradientComponent implements OnInit, ControlValueAccessor, OnDestro
addGradient(advanced = false) { addGradient(advanced = false) {
if (advanced) { if (advanced) {
this.advancedGradientListFormArray.push( this.advancedGradientListFormArray.push(
this.advancedGradientControl({source: {type: ValueSourceDataKeyType.constant}, color: 'rgba(0,0,0,0.87)'}) this.advancedGradientControl({source: {type: ValueSourceType.constant}, color: 'rgba(0,0,0,0.87)'})
); );
} else { } else {
this.gradientListFormArray.push(this.colorGradientControl('rgba(0,0,0,0.87)')); this.gradientListFormArray.push(this.colorGradientControl('rgba(0,0,0,0.87)'));

30
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source-data-key.component.ts

@ -31,9 +31,9 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { DataKey, Datasource, DatasourceType } from '@app/shared/models/widget.models'; import { DataKey, Datasource, DatasourceType } from '@app/shared/models/widget.models';
import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models';
import { import {
ValueSourceDataKeyType, ValueSourceType,
ValueSourceDataKeyTypes, ValueSourceTypes,
ValueSourceDataKeyTypeTranslation ValueSourceTypeTranslation
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
@Component({ @Component({
@ -53,9 +53,9 @@ export class ValueSourceDataKeyComponent extends PageComponent implements OnInit
dataKeyType = DataKeyType; dataKeyType = DataKeyType;
datasourceType = DatasourceType; datasourceType = DatasourceType;
valueSourceDataKeyType = ValueSourceDataKeyType; valueSourceDataKeyType = ValueSourceType;
valueSourceDataKeyTypes = ValueSourceDataKeyTypes; valueSourceDataKeyTypes = ValueSourceTypes;
valueSourceDataKeyTypeTranslation = ValueSourceDataKeyTypeTranslation; valueSourceDataKeyTypeTranslation = ValueSourceTypeTranslation;
@Input() @Input()
disabled: boolean; disabled: boolean;
@ -86,7 +86,7 @@ export class ValueSourceDataKeyComponent extends PageComponent implements OnInit
ngOnInit(): void { ngOnInit(): void {
this.valueSourceFormGroup = this.fb.group({ this.valueSourceFormGroup = this.fb.group({
type: [ValueSourceDataKeyType.constant, []], type: [ValueSourceType.constant, []],
value: [null, [Validators.required]], value: [null, [Validators.required]],
entityAlias: [null, [Validators.required]] entityAlias: [null, [Validators.required]]
}); });
@ -134,12 +134,12 @@ export class ValueSourceDataKeyComponent extends PageComponent implements OnInit
entityAlias: value.entityAlias entityAlias: value.entityAlias
}, {emitEvent: false} }, {emitEvent: false}
); );
if (value.type === ValueSourceDataKeyType.latestKey) { if (value.type === ValueSourceType.latestKey) {
this.latestKeyFormControl.patchValue({ this.latestKeyFormControl.patchValue({
type: value.latestKeyType, type: value.latestKeyType,
name: value.latestKey name: value.latestKey
}, {emitEvent: false}); }, {emitEvent: false});
} else if (value.type === ValueSourceDataKeyType.entity) { } else if (value.type === ValueSourceType.entity) {
this.entityKeyFormControl.patchValue({ this.entityKeyFormControl.patchValue({
type: value.entityKeyType, type: value.entityKeyType,
name: value.entityKey name: value.entityKey
@ -156,11 +156,11 @@ export class ValueSourceDataKeyComponent extends PageComponent implements OnInit
this.modelValue.value = value.value; this.modelValue.value = value.value;
this.modelValue.entityAlias = value.entityAlias; this.modelValue.entityAlias = value.entityAlias;
if (value.type === ValueSourceDataKeyType.latestKey) { if (value.type === ValueSourceType.latestKey) {
const latestKey: DataKey = this.latestKeyFormControl.value; const latestKey: DataKey = this.latestKeyFormControl.value;
this.modelValue.latestKey = latestKey?.name; this.modelValue.latestKey = latestKey?.name;
this.modelValue.latestKeyType = (latestKey?.type as any); this.modelValue.latestKeyType = (latestKey?.type as any);
} else if (value.type === ValueSourceDataKeyType.entity) { } else if (value.type === ValueSourceType.entity) {
const entityKey: DataKey = this.entityKeyFormControl.value; const entityKey: DataKey = this.entityKeyFormControl.value;
this.modelValue.entityKey = entityKey?.name; this.modelValue.entityKey = entityKey?.name;
this.modelValue.entityKeyType = (entityKey?.type as any); this.modelValue.entityKeyType = (entityKey?.type as any);
@ -169,18 +169,18 @@ export class ValueSourceDataKeyComponent extends PageComponent implements OnInit
} }
private updateValidators(): void { private updateValidators(): void {
const type: ValueSourceDataKeyType = this.valueSourceFormGroup.get('type').value; const type: ValueSourceType = this.valueSourceFormGroup.get('type').value;
if (type === ValueSourceDataKeyType.constant) { if (type === ValueSourceType.constant) {
this.valueSourceFormGroup.get('value').enable({emitEvent: false}); this.valueSourceFormGroup.get('value').enable({emitEvent: false});
this.valueSourceFormGroup.get('entityAlias').disable({emitEvent: false}); this.valueSourceFormGroup.get('entityAlias').disable({emitEvent: false});
this.latestKeyFormControl.disable({emitEvent: false}); this.latestKeyFormControl.disable({emitEvent: false});
this.entityKeyFormControl.disable({emitEvent: false}); this.entityKeyFormControl.disable({emitEvent: false});
} else if (type === ValueSourceDataKeyType.latestKey) { } else if (type === ValueSourceType.latestKey) {
this.valueSourceFormGroup.get('value').disable({emitEvent: false}); this.valueSourceFormGroup.get('value').disable({emitEvent: false});
this.valueSourceFormGroup.get('entityAlias').disable({emitEvent: false}); this.valueSourceFormGroup.get('entityAlias').disable({emitEvent: false});
this.latestKeyFormControl.enable({emitEvent: false}); this.latestKeyFormControl.enable({emitEvent: false});
this.entityKeyFormControl.disable({emitEvent: false}); this.entityKeyFormControl.disable({emitEvent: false});
} else if (type === ValueSourceDataKeyType.entity) { } else if (type === ValueSourceType.entity) {
this.valueSourceFormGroup.get('value').disable({emitEvent: false}); this.valueSourceFormGroup.get('value').disable({emitEvent: false});
this.valueSourceFormGroup.get('entityAlias').enable({emitEvent: false}); this.valueSourceFormGroup.get('entityAlias').enable({emitEvent: false});
this.latestKeyFormControl.disable({emitEvent: false}); this.latestKeyFormControl.disable({emitEvent: false});

10
ui-ngx/src/app/modules/home/components/widget/lib/settings/gauge/digital-gauge-widget-settings.component.ts

@ -35,8 +35,8 @@ import {
ColorType, ColorType,
constantColor, constantColor,
simpleDateFormat, simpleDateFormat,
ValueSourceDataKeyType, ValueSourceType,
ValueSourceWithDataKey ValueSourceTypeConfig
} from '@shared/models/widget-settings.models'; } from '@shared/models/widget-settings.models';
@Component({ @Component({
@ -348,7 +348,7 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent
settingsForm.setControl('ticksValue', this.prepareTicksValueFormArray(settings.ticksValue), {emitEvent: false}); settingsForm.setControl('ticksValue', this.prepareTicksValueFormArray(settings.ticksValue), {emitEvent: false});
} }
private prepareTicksValueFormArray(ticksValue: ValueSourceWithDataKey[] | undefined): UntypedFormArray { private prepareTicksValueFormArray(ticksValue: ValueSourceTypeConfig[] | undefined): UntypedFormArray {
const ticksValueControls: Array<AbstractControl> = []; const ticksValueControls: Array<AbstractControl> = [];
if (ticksValue) { if (ticksValue) {
ticksValue.forEach((tickValue) => { ticksValue.forEach((tickValue) => {
@ -371,8 +371,8 @@ export class DigitalGaugeWidgetSettingsComponent extends WidgetSettingsComponent
} }
public addTickValue() { public addTickValue() {
const tickValue: ValueSourceWithDataKey = { const tickValue: ValueSourceTypeConfig = {
type: ValueSourceDataKeyType.constant type: ValueSourceType.constant
}; };
const tickValuesArray = this.digitalGaugeWidgetSettingsForm.get('ticksValue') as UntypedFormArray; const tickValuesArray = this.digitalGaugeWidgetSettingsForm.get('ticksValue') as UntypedFormArray;
const tickValueControl = this.fb.control(tickValue, []); const tickValueControl = this.fb.control(tickValue, []);

80
ui-ngx/src/app/shared/models/widget-settings.models.ts

@ -25,7 +25,7 @@ import {
TargetDeviceType, TargetDeviceType,
widgetType widgetType
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
import { ChangeDetectorRef, EventEmitter, Injector } from '@angular/core'; import { EventEmitter, Injector } from '@angular/core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { DateAgoPipe } from '@shared/pipe/date-ago.pipe'; import { DateAgoPipe } from '@shared/pipe/date-ago.pipe';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -37,7 +37,7 @@ import { map } from 'rxjs/operators';
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { AVG_MONTH, DAY, HOUR, Interval, IntervalMath, MINUTE, SECOND, YEAR } from '@shared/models/time/time.models'; import { AVG_MONTH, DAY, HOUR, Interval, IntervalMath, MINUTE, SECOND, YEAR } from '@shared/models/time/time.models';
import moment from 'moment'; import moment from 'moment';
import tinycolor, { ColorInput } from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { WidgetContext } from '@home/models/widget-component.models'; import { WidgetContext } from '@home/models/widget-component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
@ -106,24 +106,24 @@ export interface ColorRange {
color: string; color: string;
} }
export enum ValueSourceDataKeyType { export enum ValueSourceType {
constant = 'constant', constant = 'constant',
latestKey = 'latestKey', latestKey = 'latestKey',
entity = 'entity' entity = 'entity'
} }
export const ValueSourceDataKeyTypes = Object.keys(ValueSourceDataKeyType) as ValueSourceDataKeyType[]; export const ValueSourceTypes = Object.keys(ValueSourceType) as ValueSourceType[];
export const ValueSourceDataKeyTypeTranslation = new Map<ValueSourceDataKeyType, string>( export const ValueSourceTypeTranslation = new Map<ValueSourceType, string>(
[ [
[ValueSourceDataKeyType.constant, 'widgets.value-source.type-constant'], [ValueSourceType.constant, 'widgets.value-source.type-constant'],
[ValueSourceDataKeyType.latestKey, 'widgets.value-source.type-latest-key'], [ValueSourceType.latestKey, 'widgets.value-source.type-latest-key'],
[ValueSourceDataKeyType.entity, 'widgets.value-source.type-entity'] [ValueSourceType.entity, 'widgets.value-source.type-entity']
] ]
); );
export interface ValueSourceWithDataKey { export interface ValueSourceTypeConfig {
type: ValueSourceDataKeyType; type: ValueSourceType;
value?: number; value?: number;
latestKeyType?: DataKeyType.attribute | DataKeyType.timeseries; latestKeyType?: DataKeyType.attribute | DataKeyType.timeseries;
latestKey?: string; latestKey?: string;
@ -133,8 +133,8 @@ export interface ValueSourceWithDataKey {
} }
export interface AdvancedColorRange { export interface AdvancedColorRange {
from?: ValueSourceWithDataKey; from?: ValueSourceTypeConfig;
to?: ValueSourceWithDataKey; to?: ValueSourceTypeConfig;
color: string; color: string;
} }
@ -226,7 +226,7 @@ export interface ColorRangeSettings {
} }
export interface AdvancedGradient { export interface AdvancedGradient {
source: ValueSourceWithDataKey; source: ValueSourceTypeConfig;
color: string; color: string;
} }
@ -272,11 +272,11 @@ export const defaultGradient = (minValue?: number, maxValue?: number): ColorGrad
gradient: ['rgba(0, 255, 0, 1)', 'rgba(255, 0, 0, 1)'], gradient: ['rgba(0, 255, 0, 1)', 'rgba(255, 0, 0, 1)'],
gradientAdvanced: [ gradientAdvanced: [
{ {
source: {type: ValueSourceDataKeyType.constant}, source: {type: ValueSourceType.constant},
color: 'rgba(0, 255, 0, 1)' color: 'rgba(0, 255, 0, 1)'
}, },
{ {
source: {type: ValueSourceDataKeyType.constant}, source: {type: ValueSourceType.constant},
color: 'rgba(255, 0, 0, 1)' color: 'rgba(255, 0, 0, 1)'
} }
], ],
@ -369,9 +369,9 @@ export abstract class ColorProcessor {
static generateDatasource( static generateDatasource(
ctx: WidgetContext, ctx: WidgetContext,
datasources: Datasource[], datasources: Datasource[],
valueSource: ValueSourceWithDataKey, valueSource: ValueSourceTypeConfig,
settings: DataKeySettings): Datasource[]{ settings: DataKeySettings): Datasource[]{
if (valueSource.type === ValueSourceDataKeyType.latestKey) { if (valueSource.type === ValueSourceType.latestKey) {
if (ctx.datasources.length) { if (ctx.datasources.length) {
if (isDefinedAndNotNull(ctx.datasources[0].aliasName)) { if (isDefinedAndNotNull(ctx.datasources[0].aliasName)) {
datasources = this.parseDatasource(ctx, valueSource, ctx.datasources[0].aliasName, settings, datasources, true); datasources = this.parseDatasource(ctx, valueSource, ctx.datasources[0].aliasName, settings, datasources, true);
@ -379,24 +379,24 @@ export abstract class ColorProcessor {
datasources = this.parseDatasource(ctx, valueSource, '', settings, datasources, true); datasources = this.parseDatasource(ctx, valueSource, '', settings, datasources, true);
} }
} }
} else if (valueSource.type === ValueSourceDataKeyType.entity) { } else if (valueSource.type === ValueSourceType.entity) {
datasources = this.parseDatasource(ctx, valueSource, valueSource.entityAlias, settings, datasources, false); datasources = this.parseDatasource(ctx, valueSource, valueSource.entityAlias, settings, datasources, false);
} }
return datasources; return datasources;
} }
static parseDatasource(ctx: WidgetContext, static parseDatasource(ctx: WidgetContext,
valueSource: ValueSourceWithDataKey, valueSource: ValueSourceTypeConfig,
entityAlias: string, settings: DataKeySettings, entityAlias: string,
datasources: Datasource[], settings: DataKeySettings,
isLatest: boolean) { datasources: Datasource[],
let dataKey: DataKey = null; isLatest: boolean) {
const dataKeySettings = [settings]; const dataKeySettings = [settings];
const entityAliasId = ctx.aliasController.getEntityAliasId(entityAlias); const entityAliasId = ctx.aliasController.getEntityAliasId(entityAlias);
let datasource = datasources.find(d => let datasource = datasources.find(d =>
entityAlias ? (d.entityAliasId === entityAliasId) : (d.deviceId === ctx.datasources[0].deviceId) entityAlias ? (d.entityAliasId === entityAliasId) : (d.deviceId === ctx.datasources[0].deviceId)
); );
dataKey = { const dataKey: DataKey = {
type: isLatest ? valueSource.latestKeyType : valueSource.entityKeyType, type: isLatest ? valueSource.latestKeyType : valueSource.entityKeyType,
name: isLatest ? valueSource.latestKey : valueSource.entityKey, name: isLatest ? valueSource.latestKey : valueSource.entityKey,
label: isLatest ? valueSource.latestKey : valueSource.entityKey, label: isLatest ? valueSource.latestKey : valueSource.entityKey,
@ -448,23 +448,23 @@ class RangeColorProcessor extends ColorProcessor {
private advancedRangeSourcesSubscription: IWidgetSubscription; private advancedRangeSourcesSubscription: IWidgetSubscription;
private progress; private progress: number;
constructor(protected settings: ColorSettings, constructor(protected settings: ColorSettings,
protected ctx: WidgetContext) { protected ctx: WidgetContext) {
super(settings); super(settings);
} }
advancedRangeSubscribe(options: ColorRangeSettings){ private advancedRangeSubscribe(options: ColorRangeSettings){
let advancedRangeDatasource: Datasource[] = []; let advancedRangeDatasource: Datasource[] = [];
let index = 0; let index = 0;
function setRangeColor(rangeSetting: ValueSourceWithDataKey, color: string) { function setRangeColor(rangeSetting: ValueSourceTypeConfig, color: string) {
if (rangeSetting.type === ValueSourceDataKeyType.constant && isFinite(rangeSetting.value)) { if (rangeSetting.type === ValueSourceType.constant && isFinite(rangeSetting.value)) {
index++; index++;
} else { } else {
try { try {
advancedRangeDatasource = this.generateDatasource(this.ctx, advancedRangeDatasource, advancedRangeDatasource = ColorProcessor.generateDatasource(this.ctx, advancedRangeDatasource,
rangeSetting, {color, index}); rangeSetting, {color, index});
} catch (e) { } catch (e) {
return; return;
@ -492,7 +492,7 @@ class RangeColorProcessor extends ColorProcessor {
} }
} }
subscribeAttributes(datasource: Datasource[]): Observable<IWidgetSubscription> { private subscribeAttributes(datasource: Datasource[]): Observable<IWidgetSubscription> {
if (!datasource.length) { if (!datasource.length) {
return EMPTY; return EMPTY;
} }
@ -513,7 +513,7 @@ class RangeColorProcessor extends ColorProcessor {
return this.ctx.subscriptionApi.createSubscription(levelColorsSourcesSubscriptionOptions, true); return this.ctx.subscriptionApi.createSubscription(levelColorsSourcesSubscriptionOptions, true);
} }
updateAttribute(data: Array<DatasourceData>) { private updateAttribute(data: Array<DatasourceData>) {
for (const keyData of data) { for (const keyData of data) {
if (keyData && keyData.data && keyData.data[0]) { if (keyData && keyData.data && keyData.data[0]) {
const attrValue = keyData.data[0][1]; const attrValue = keyData.data[0][1];
@ -606,8 +606,8 @@ class GradientColorProcessor extends ColorProcessor {
private progress: number; private progress: number;
private minValue: number; private readonly minValue: number;
private maxValue: number; private readonly maxValue: number;
private advancedGradientSourcesSubscription: IWidgetSubscription; private advancedGradientSourcesSubscription: IWidgetSubscription;
@ -633,7 +633,7 @@ class GradientColorProcessor extends ColorProcessor {
} }
} }
calculateProgress(current: number, min: number, max: number) { private calculateProgress(current: number, min: number, max: number) {
if (current < min) { if (current < min) {
return 0; return 0;
} else if (current > max) { } else if (current > max) {
@ -642,7 +642,7 @@ class GradientColorProcessor extends ColorProcessor {
return (current - min) / (max - min); return (current - min) / (max - min);
} }
getProgressColor(progress: number, levelColors: Array<AdvancedGradient | string>): string { private getProgressColor(progress: number, levelColors: Array<AdvancedGradient | string>): string {
const colorsCount = levelColors.length; const colorsCount = levelColors.length;
const inc = colorsCount > 1 ? (1 / (colorsCount - 1)) : 1; const inc = colorsCount > 1 ? (1 / (colorsCount - 1)) : 1;
const colorsRange = []; const colorsRange = [];
@ -683,12 +683,12 @@ class GradientColorProcessor extends ColorProcessor {
return colorsRange[colorsRange.length - 1].rgbString; return colorsRange[colorsRange.length - 1].rgbString;
} }
advancedRangeSubscribe(options: Array<AdvancedGradient>){ private advancedRangeSubscribe(options: Array<AdvancedGradient>){
let advancedGradientDatasource: Datasource[] = []; let advancedGradientDatasource: Datasource[] = [];
let index = 0; let index = 0;
function setGradientColor(gradientSetting: ValueSourceWithDataKey) { function setGradientColor(gradientSetting: ValueSourceTypeConfig) {
if (gradientSetting.type === ValueSourceDataKeyType.constant && isFinite(gradientSetting.value)) { if (gradientSetting.type === ValueSourceType.constant && isFinite(gradientSetting.value)) {
index++; index++;
} else { } else {
try { try {
@ -715,7 +715,7 @@ class GradientColorProcessor extends ColorProcessor {
} }
} }
subscribeAttributes(datasource: Datasource[]): Observable<IWidgetSubscription> { private subscribeAttributes(datasource: Datasource[]): Observable<IWidgetSubscription> {
if (!datasource.length) { if (!datasource.length) {
return EMPTY; return EMPTY;
} }
@ -736,7 +736,7 @@ class GradientColorProcessor extends ColorProcessor {
return this.ctx.subscriptionApi.createSubscription(levelColorsSourcesSubscriptionOptions, true); return this.ctx.subscriptionApi.createSubscription(levelColorsSourcesSubscriptionOptions, true);
} }
updateAttribute(data: Array<DatasourceData>) { private updateAttribute(data: Array<DatasourceData>) {
for (const keyData of data) { for (const keyData of data) {
if (keyData && keyData.data && keyData.data[0]) { if (keyData && keyData.data && keyData.data[0]) {
const attrValue = keyData.data[0][1]; const attrValue = keyData.data[0][1];

Loading…
Cancel
Save