Browse Source

Merge remote-tracking branch 'upstream/master' into fix/apiUsageDashboard

pull/10326/head
Vladyslav_Prykhodko 3 years ago
parent
commit
3c85d8ff14
  1. 31
      ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html
  2. 31
      ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts
  3. 16
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-bar.models.ts
  4. 4
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-widget.component.scss
  5. 62
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts
  6. 3
      ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
  7. 33
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html
  8. 38
      ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts
  9. 3
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts
  10. 41
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.html
  11. 21
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts
  12. 75
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html
  13. 147
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts
  14. 5
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts
  15. 16
      ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html
  16. 33
      ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts
  17. 2
      ui-ngx/src/app/shared/models/widget.models.ts
  18. 7
      ui-ngx/src/assets/locale/locale.constant-en_US.json
  19. 6
      ui-ngx/src/form.scss

31
ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html

@ -114,33 +114,10 @@
axisType="xAxis"> axisType="xAxis">
</tb-time-series-chart-axis-settings> </tb-time-series-chart-axis-settings>
</div> </div>
<div *ngIf="chartType === TimeSeriesChartType.default || chartType === TimeSeriesChartType.bar" <tb-time-series-no-aggregation-bar-width-settings
class="tb-form-panel" formGroupName="noAggregationBarWidthSettings"> *ngIf="chartType === TimeSeriesChartType.default || chartType === TimeSeriesChartType.bar"
<div fxLayout="row" fxLayoutAlign="space-between center"> formControlName="noAggregationBarWidthSettings">
<div fxFlex translate>widgets.time-series-chart.no-aggregation-bar-width-strategy</div> </tb-time-series-no-aggregation-bar-width-settings>
<tb-toggle-select formControlName="strategy" selectMediaBreakpoint="xs">
<tb-toggle-option *ngFor="let strategy of timeSeriesChartNoAggregationBarWidthStrategies" [value]="strategy">
{{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }}
</tb-toggle-option>
</tb-toggle-select>
</div>
<div *ngIf="timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings.strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.group"
class="tb-form-row space-between column-xs">
<div translate>widgets.time-series-chart.bar-group-interval-width</div>
<mat-form-field class="medium-width number" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" formControlName="groupIntervalWidth" min="100" step="1" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>ms</span>
</mat-form-field>
</div>
<div *ngIf="timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings.strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.separate"
class="tb-form-row space-between column-xs">
<div translate>widgets.time-series-chart.separate-bar-width</div>
<mat-form-field class="medium-width number" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" formControlName="separateBarWidth" min="100" step="1" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>ms</span>
</mat-form-field>
</div>
</div>
<div class="tb-form-panel tb-slide-toggle"> <div class="tb-form-panel tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="timeSeriesChartWidgetConfigForm.get('showLegend').value" <mat-expansion-panel class="tb-settings" [expanded]="timeSeriesChartWidgetConfigForm.get('showLegend').value"
[disabled]="!timeSeriesChartWidgetConfigForm.get('showLegend').value"> [disabled]="!timeSeriesChartWidgetConfigForm.get('showLegend').value">

31
ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts

@ -45,12 +45,7 @@ import {
TimeSeriesChartWidgetSettings TimeSeriesChartWidgetSettings
} from '@home/components/widget/lib/chart/time-series-chart-widget.models'; } from '@home/components/widget/lib/chart/time-series-chart-widget.models';
import { EChartsTooltipTrigger } from '@home/components/widget/lib/chart/echarts-widget.models'; import { EChartsTooltipTrigger } from '@home/components/widget/lib/chart/echarts-widget.models';
import { import { TimeSeriesChartType } from '@home/components/widget/lib/chart/time-series-chart.models';
timeSeriesChartNoAggregationBarWidthStrategies,
TimeSeriesChartNoAggregationBarWidthStrategy,
timeSeriesChartNoAggregationBarWidthStrategyTranslations,
TimeSeriesChartType
} from '@home/components/widget/lib/chart/time-series-chart.models';
@Component({ @Component({
selector: 'tb-time-series-chart-basic-config', selector: 'tb-time-series-chart-basic-config',
@ -76,12 +71,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon
legendPositionTranslationMap = legendPositionTranslationMap; legendPositionTranslationMap = legendPositionTranslationMap;
TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy;
timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies;
timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations;
timeSeriesChartWidgetConfigForm: UntypedFormGroup; timeSeriesChartWidgetConfigForm: UntypedFormGroup;
tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this);
@ -140,11 +129,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon
yAxis: [settings.yAxis, []], yAxis: [settings.yAxis, []],
xAxis: [settings.xAxis, []], xAxis: [settings.xAxis, []],
noAggregationBarWidthSettings: this.fb.group({ noAggregationBarWidthSettings: [settings.noAggregationBarWidthSettings, []],
strategy: [settings.noAggregationBarWidthSettings.strategy, []],
groupIntervalWidth: [settings.noAggregationBarWidthSettings.groupIntervalWidth, [Validators.min(100)]],
separateBarWidth: [settings.noAggregationBarWidthSettings.separateBarWidth, [Validators.min(100)]],
}),
showLegend: [settings.showLegend, []], showLegend: [settings.showLegend, []],
legendLabelFont: [settings.legendLabelFont, []], legendLabelFont: [settings.legendLabelFont, []],
@ -227,7 +212,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon
} }
protected validatorTriggers(): string[] { protected validatorTriggers(): string[] {
return ['showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate', 'noAggregationBarWidthSettings.strategy']; return ['showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate'];
} }
protected updateValidators(emitEvent: boolean, trigger?: string) { protected updateValidators(emitEvent: boolean, trigger?: string) {
@ -236,8 +221,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon
const showLegend: boolean = this.timeSeriesChartWidgetConfigForm.get('showLegend').value; const showLegend: boolean = this.timeSeriesChartWidgetConfigForm.get('showLegend').value;
const showTooltip: boolean = this.timeSeriesChartWidgetConfigForm.get('showTooltip').value; const showTooltip: boolean = this.timeSeriesChartWidgetConfigForm.get('showTooltip').value;
const tooltipShowDate: boolean = this.timeSeriesChartWidgetConfigForm.get('tooltipShowDate').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetConfigForm.get('tooltipShowDate').value;
const noAggregationBarWidthSettingsStrategy: TimeSeriesChartNoAggregationBarWidthStrategy =
this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('strategy').value;
if (showTitle) { if (showTitle) {
this.timeSeriesChartWidgetConfigForm.get('title').enable(); this.timeSeriesChartWidgetConfigForm.get('title').enable();
@ -266,14 +249,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon
this.timeSeriesChartWidgetConfigForm.get('iconColor').disable(); this.timeSeriesChartWidgetConfigForm.get('iconColor').disable();
} }
if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) {
this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').enable();
this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('separateBarWidth').disable();
} else if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) {
this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').disable();
this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('separateBarWidth').enable();
}
if (showLegend) { if (showLegend) {
this.timeSeriesChartWidgetConfigForm.get('legendLabelFont').enable(); this.timeSeriesChartWidgetConfigForm.get('legendLabelFont').enable();
this.timeSeriesChartWidgetConfigForm.get('legendLabelColor').enable(); this.timeSeriesChartWidgetConfigForm.get('legendLabelColor').enable();

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

@ -19,7 +19,6 @@ import { Interval, IntervalMath } from '@shared/models/time/time.models';
import { LabelFormatterCallback, SeriesLabelOption } from 'echarts/types/src/util/types'; import { LabelFormatterCallback, SeriesLabelOption } from 'echarts/types/src/util/types';
import { import {
TimeSeriesChartDataItem, TimeSeriesChartDataItem,
TimeSeriesChartNoAggregationBarWidthSettings,
TimeSeriesChartNoAggregationBarWidthStrategy TimeSeriesChartNoAggregationBarWidthStrategy
} from '@home/components/widget/lib/chart/time-series-chart.models'; } from '@home/components/widget/lib/chart/time-series-chart.models';
import { CustomSeriesRenderItemParams } from 'echarts'; import { CustomSeriesRenderItemParams } from 'echarts';
@ -38,7 +37,9 @@ export interface BarRenderContext {
barsCount?: number; barsCount?: number;
barIndex?: number; barIndex?: number;
noAggregation: boolean; noAggregation: boolean;
noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings; noAggregationBarWidthStrategy: TimeSeriesChartNoAggregationBarWidthStrategy;
noAggregationWidthRelative?: boolean;
noAggregationWidth?: number;
timeInterval?: Interval; timeInterval?: Interval;
visualSettings?: BarVisualSettings; visualSettings?: BarVisualSettings;
labelOption?: SeriesLabelOption; labelOption?: SeriesLabelOption;
@ -54,16 +55,15 @@ export const renderTimeSeriesBar = (params: CustomSeriesRenderItemParams, api: C
let interval = end - start; let interval = end - start;
const ts = start ? start : time; const ts = start ? start : time;
const noAggregationGroup = renderCtx.noAggregation &&
renderCtx.noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group;
const separateBar = renderCtx.noAggregation && const separateBar = renderCtx.noAggregation &&
renderCtx.noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate; renderCtx.noAggregationBarWidthStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate;
if (renderCtx.noAggregation) { if (renderCtx.noAggregation) {
if (noAggregationGroup) { if (renderCtx.noAggregationWidthRelative) {
interval = renderCtx.noAggregationBarWidthSettings.groupIntervalWidth; const scaleWidth = api.getWidth() / api.size([1,0])[0];
interval = scaleWidth * (renderCtx.noAggregationWidth / 100);
} else { } else {
interval = renderCtx.noAggregationBarWidthSettings.separateBarWidth; interval = renderCtx.noAggregationWidth;
} }
start = time - interval / 2; start = time - interval / 2;
end = time + interval / 2; end = time + interval / 2;

4
ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-widget.component.scss

@ -23,7 +23,7 @@ $maxLegendHeight: 35%;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 8px;
padding: 20px 24px 24px 24px; padding: 20px 24px 24px 24px;
> div:not(.tb-time-series-chart-overlay) { > div:not(.tb-time-series-chart-overlay) {
z-index: 1; z-index: 1;
@ -44,7 +44,7 @@ $maxLegendHeight: 35%;
min-height: 0; min-height: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 8px;
&.legend-top { &.legend-top {
flex-direction: column-reverse; flex-direction: column-reverse;
} }

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

@ -25,7 +25,7 @@ import {
import { ComponentStyle, Font, simpleDateFormat, textStyle } from '@shared/models/widget-settings.models'; import { ComponentStyle, Font, simpleDateFormat, textStyle } from '@shared/models/widget-settings.models';
import { XAXisOption, YAXisOption } from 'echarts/types/dist/shared'; import { XAXisOption, YAXisOption } from 'echarts/types/dist/shared';
import { CustomSeriesOption, LineSeriesOption } from 'echarts/charts'; import { CustomSeriesOption, LineSeriesOption } from 'echarts/charts';
import { formatValue, isDefinedAndNotNull, isUndefinedOrNull, parseFunction } from '@core/utils'; import { formatValue, isDefinedAndNotNull, isUndefined, isUndefinedOrNull, parseFunction } from '@core/utils';
import { LinearGradientObject } from 'zrender/lib/graphic/LinearGradient'; import { LinearGradientObject } from 'zrender/lib/graphic/LinearGradient';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import Axis2D from 'echarts/types/src/coord/cartesian/Axis2D'; import Axis2D from 'echarts/types/src/coord/cartesian/Axis2D';
@ -293,6 +293,7 @@ export interface TimeSeriesChartYAxisSettings extends TimeSeriesChartAxisSetting
min?: number | string; min?: number | string;
max?: number | string; max?: number | string;
intervalCalculator?: string; intervalCalculator?: string;
ticksFormatter?: string;
} }
export interface TimeSeriesChartThreshold { export interface TimeSeriesChartThreshold {
@ -391,10 +392,16 @@ export const timeSeriesChartNoAggregationBarWidthStrategyTranslations = new Map<
] ]
); );
export interface TimeSeriesChartBarWidth {
relative?: boolean;
relativeWidth?: number;
absoluteWidth?: number;
}
export interface TimeSeriesChartNoAggregationBarWidthSettings { export interface TimeSeriesChartNoAggregationBarWidthSettings {
strategy: TimeSeriesChartNoAggregationBarWidthStrategy; strategy: TimeSeriesChartNoAggregationBarWidthStrategy;
groupIntervalWidth?: number; groupWidth?: TimeSeriesChartBarWidth;
separateBarWidth?: number; barWidth?: TimeSeriesChartBarWidth;
} }
export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings { export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings {
@ -435,6 +442,7 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
lineHeight: '1' lineHeight: '1'
}, },
tickLabelColor: timeSeriesChartColorScheme['axis.tickLabel'].light, tickLabelColor: timeSeriesChartColorScheme['axis.tickLabel'].light,
ticksFormatter: null,
showTicks: true, showTicks: true,
ticksColor: timeSeriesChartColorScheme['axis.ticks'].light, ticksColor: timeSeriesChartColorScheme['axis.ticks'].light,
showLine: true, showLine: true,
@ -474,8 +482,16 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = {
}, },
noAggregationBarWidthSettings: { noAggregationBarWidthSettings: {
strategy: TimeSeriesChartNoAggregationBarWidthStrategy.group, strategy: TimeSeriesChartNoAggregationBarWidthStrategy.group,
groupIntervalWidth: 1000, groupWidth: {
separateBarWidth: 1000 relative: true,
relativeWidth: 2,
absoluteWidth: 1000
},
barWidth: {
relative: true,
relativeWidth: 2,
absoluteWidth: 1000
}
}, },
showTooltip: true, showTooltip: true,
tooltipTrigger: EChartsTooltipTrigger.axis, tooltipTrigger: EChartsTooltipTrigger.axis,
@ -633,6 +649,7 @@ export interface TimeSeriesChartYAxis {
units: string; units: string;
option: YAXisOption & ValueAxisBaseOption; option: YAXisOption & ValueAxisBaseOption;
intervalCalculator?: (axis: Axis2D) => number; intervalCalculator?: (axis: Axis2D) => number;
ticksFormatter?: (value: any) => string;
} }
export const createTimeSeriesYAxis = (axisId: string, units: string, export const createTimeSeriesYAxis = (axisId: string, units: string,
@ -642,6 +659,10 @@ export const createTimeSeriesYAxis = (axisId: string, units: string,
settings.tickLabelColor, darkMode, 'axis.tickLabel'); settings.tickLabelColor, darkMode, 'axis.tickLabel');
const yAxisNameStyle = createChartTextStyle(settings.labelFont, const yAxisNameStyle = createChartTextStyle(settings.labelFont,
settings.labelColor, darkMode, 'axis.label'); settings.labelColor, darkMode, 'axis.label');
let ticksFormatter: (value: any) => string;
if (settings.ticksFormatter && settings.ticksFormatter.length) {
ticksFormatter = parseFunction(settings.ticksFormatter, ['value']);
}
const yAxis: TimeSeriesChartYAxis = { const yAxis: TimeSeriesChartYAxis = {
id: axisId, id: axisId,
units, units,
@ -685,7 +706,18 @@ export const createTimeSeriesYAxis = (axisId: string, units: string,
fontWeight: yAxisTickLabelStyle.fontWeight, fontWeight: yAxisTickLabelStyle.fontWeight,
fontFamily: yAxisTickLabelStyle.fontFamily, fontFamily: yAxisTickLabelStyle.fontFamily,
fontSize: yAxisTickLabelStyle.fontSize, fontSize: yAxisTickLabelStyle.fontSize,
formatter: (value: any) => formatValue(value, decimals, units, false) formatter: (value: any) => {
let result: string;
if (ticksFormatter) {
try {
result = ticksFormatter(value);
} catch (_e) {}
}
if (isUndefined(result)) {
result = formatValue(value, decimals, units, false);
}
return result;
}
}, },
splitLine: { splitLine: {
show: settings.showSplitLines, show: settings.showSplitLines,
@ -757,12 +789,12 @@ export const createTimeSeriesXAxisOption = (settings: TimeSeriesChartAxisSetting
export const generateChartData = (dataItems: TimeSeriesChartDataItem[], export const generateChartData = (dataItems: TimeSeriesChartDataItem[],
thresholdItems: TimeSeriesChartThresholdItem[], thresholdItems: TimeSeriesChartThresholdItem[],
timeInterval: Interval, timeInterval: Interval,
stack: boolean,
noAggregation: boolean, noAggregation: boolean,
noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings, noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings,
stack: boolean,
darkMode: boolean): Array<LineSeriesOption | CustomSeriesOption> => { darkMode: boolean): Array<LineSeriesOption | CustomSeriesOption> => {
let series = generateChartSeries(dataItems, timeInterval, let series = generateChartSeries(dataItems, timeInterval,
noAggregation, noAggregationBarWidthSettings, stack, darkMode); stack, noAggregation, noAggregationBarWidthSettings, darkMode);
if (thresholdItems.length) { if (thresholdItems.length) {
const thresholds = generateChartThresholds(thresholdItems, darkMode); const thresholds = generateChartThresholds(thresholdItems, darkMode);
series = series.concat(thresholds); series = series.concat(thresholds);
@ -874,9 +906,9 @@ const createThresholdData = (val: string | number, item: TimeSeriesChartThreshol
const generateChartSeries = (dataItems: TimeSeriesChartDataItem[], const generateChartSeries = (dataItems: TimeSeriesChartDataItem[],
timeInterval: Interval, timeInterval: Interval,
stack: boolean,
noAggregation: boolean, noAggregation: boolean,
noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings, noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings,
stack: boolean,
darkMode: boolean): Array<LineSeriesOption | CustomSeriesOption> => { darkMode: boolean): Array<LineSeriesOption | CustomSeriesOption> => {
const series: Array<LineSeriesOption | CustomSeriesOption> = []; const series: Array<LineSeriesOption | CustomSeriesOption> = [];
const enabledDataItems = dataItems.filter(d => d.enabled); const enabledDataItems = dataItems.filter(d => d.enabled);
@ -895,7 +927,17 @@ const generateChartSeries = (dataItems: TimeSeriesChartDataItem[],
for (const item of enabledDataItems) { for (const item of enabledDataItems) {
if (item.dataKey.settings.type === TimeSeriesChartSeriesType.bar) { if (item.dataKey.settings.type === TimeSeriesChartSeriesType.bar) {
if (!item.barRenderContext) { if (!item.barRenderContext) {
item.barRenderContext = {noAggregation, noAggregationBarWidthSettings}; item.barRenderContext = {noAggregation,
noAggregationBarWidthStrategy: noAggregationBarWidthSettings.strategy};
const targetWidth = noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group ?
noAggregationBarWidthSettings.groupWidth : noAggregationBarWidthSettings.barWidth;
if (targetWidth.relative) {
item.barRenderContext.noAggregationWidthRelative = true;
item.barRenderContext.noAggregationWidth = targetWidth.relativeWidth;
} else {
item.barRenderContext.noAggregationWidthRelative = false;
item.barRenderContext.noAggregationWidth = targetWidth.absoluteWidth;
}
} }
item.barRenderContext.noAggregation = noAggregation; item.barRenderContext.noAggregation = noAggregation;
item.barRenderContext.barsCount = barsCount; item.barRenderContext.barsCount = barsCount;

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

@ -492,8 +492,9 @@ export class TbTimeSeriesChart {
private updateSeries(): Array<LineSeriesOption | CustomSeriesOption> { private updateSeries(): Array<LineSeriesOption | CustomSeriesOption> {
return generateChartData(this.dataItems, this.thresholdItems, return generateChartData(this.dataItems, this.thresholdItems,
this.ctx.timeWindow.interval, this.ctx.timeWindow.interval,
this.settings.stack,
this.noAggregation, this.noAggregation,
this.settings.noAggregationBarWidthSettings, this.settings.stack, this.darkMode); this.settings.noAggregationBarWidthSettings, this.darkMode);
} }
private updateAxes() { private updateAxes() {

33
ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html

@ -41,40 +41,19 @@
<div class="tb-form-panel-title" translate>widgets.time-series-chart.axis.axes</div> <div class="tb-form-panel-title" translate>widgets.time-series-chart.axis.axes</div>
<tb-time-series-chart-axis-settings <tb-time-series-chart-axis-settings
formControlName="yAxis" formControlName="yAxis"
advanced
axisType="yAxis"> axisType="yAxis">
</tb-time-series-chart-axis-settings> </tb-time-series-chart-axis-settings>
<tb-time-series-chart-axis-settings <tb-time-series-chart-axis-settings
formControlName="xAxis" formControlName="xAxis"
advanced
axisType="xAxis"> axisType="xAxis">
</tb-time-series-chart-axis-settings> </tb-time-series-chart-axis-settings>
</div> </div>
<div *ngIf="chartType === TimeSeriesChartType.default || chartType === TimeSeriesChartType.bar" <tb-time-series-no-aggregation-bar-width-settings
class="tb-form-panel" formGroupName="noAggregationBarWidthSettings"> *ngIf="chartType === TimeSeriesChartType.default || chartType === TimeSeriesChartType.bar"
<div fxLayout="row" fxLayoutAlign="space-between center"> formControlName="noAggregationBarWidthSettings">
<div fxFlex translate>widgets.time-series-chart.no-aggregation-bar-width-strategy</div> </tb-time-series-no-aggregation-bar-width-settings>
<tb-toggle-select formControlName="strategy" selectMediaBreakpoint="xs">
<tb-toggle-option *ngFor="let strategy of timeSeriesChartNoAggregationBarWidthStrategies" [value]="strategy">
{{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }}
</tb-toggle-option>
</tb-toggle-select>
</div>
<div *ngIf="timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings.strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.group"
class="tb-form-row space-between column-xs">
<div translate>widgets.time-series-chart.bar-group-interval-width</div>
<mat-form-field class="medium-width number" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" formControlName="groupIntervalWidth" min="100" step="1" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>ms</span>
</mat-form-field>
</div>
<div *ngIf="timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings.strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.separate"
class="tb-form-row space-between column-xs">
<div translate>widgets.time-series-chart.separate-bar-width</div>
<mat-form-field class="medium-width number" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" formControlName="separateBarWidth" min="100" step="1" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>ms</span>
</mat-form-field>
</div>
</div>
<div class="tb-form-panel tb-slide-toggle"> <div class="tb-form-panel tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="timeSeriesChartWidgetSettingsForm.get('showLegend').value" <mat-expansion-panel class="tb-settings" [expanded]="timeSeriesChartWidgetSettingsForm.get('showLegend').value"
[disabled]="!timeSeriesChartWidgetSettingsForm.get('showLegend').value"> [disabled]="!timeSeriesChartWidgetSettingsForm.get('showLegend').value">

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

@ -22,23 +22,17 @@ import {
WidgetSettings, WidgetSettings,
WidgetSettingsComponent WidgetSettingsComponent
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { formatValue, isDefinedAndNotNull, mergeDeep } from '@core/utils'; import { formatValue, isDefinedAndNotNull, mergeDeep } from '@core/utils';
import { DateFormatProcessor, DateFormatSettings } from '@shared/models/widget-settings.models'; import { DateFormatProcessor, DateFormatSettings } from '@shared/models/widget-settings.models';
import {
barChartWithLabelsDefaultSettings
} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models';
import { EChartsTooltipTrigger } from '../../chart/echarts-widget.models'; import { EChartsTooltipTrigger } from '../../chart/echarts-widget.models';
import { import {
timeSeriesChartWidgetDefaultSettings, TimeSeriesChartWidgetSettings timeSeriesChartWidgetDefaultSettings,
TimeSeriesChartWidgetSettings
} from '@home/components/widget/lib/chart/time-series-chart-widget.models'; } from '@home/components/widget/lib/chart/time-series-chart-widget.models';
import { import { TimeSeriesChartType } from '@home/components/widget/lib/chart/time-series-chart.models';
timeSeriesChartNoAggregationBarWidthStrategies,
TimeSeriesChartNoAggregationBarWidthStrategy,
timeSeriesChartNoAggregationBarWidthStrategyTranslations, TimeSeriesChartType
} from '@home/components/widget/lib/chart/time-series-chart.models';
import { WidgetConfigComponentData } from '@home/models/widget-component.models'; import { WidgetConfigComponentData } from '@home/models/widget-component.models';
@Component({ @Component({
@ -65,12 +59,6 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon
legendPositionTranslationMap = legendPositionTranslationMap; legendPositionTranslationMap = legendPositionTranslationMap;
TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy;
timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies;
timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations;
timeSeriesChartWidgetSettingsForm: UntypedFormGroup; timeSeriesChartWidgetSettingsForm: UntypedFormGroup;
tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this);
@ -111,11 +99,7 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon
yAxis: [settings.yAxis, []], yAxis: [settings.yAxis, []],
xAxis: [settings.xAxis, []], xAxis: [settings.xAxis, []],
noAggregationBarWidthSettings: this.fb.group({ noAggregationBarWidthSettings: [settings.noAggregationBarWidthSettings, []],
strategy: [settings.noAggregationBarWidthSettings.strategy, []],
groupIntervalWidth: [settings.noAggregationBarWidthSettings.groupIntervalWidth, [Validators.min(100)]],
separateBarWidth: [settings.noAggregationBarWidthSettings.separateBarWidth, [Validators.min(100)]],
}),
showLegend: [settings.showLegend, []], showLegend: [settings.showLegend, []],
legendLabelFont: [settings.legendLabelFont, []], legendLabelFont: [settings.legendLabelFont, []],
@ -140,23 +124,13 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon
} }
protected validatorTriggers(): string[] { protected validatorTriggers(): string[] {
return ['showLegend', 'showTooltip', 'tooltipShowDate', 'noAggregationBarWidthSettings.strategy']; return ['showLegend', 'showTooltip', 'tooltipShowDate'];
} }
protected updateValidators(emitEvent: boolean) { protected updateValidators(emitEvent: boolean) {
const showLegend: boolean = this.timeSeriesChartWidgetSettingsForm.get('showLegend').value; const showLegend: boolean = this.timeSeriesChartWidgetSettingsForm.get('showLegend').value;
const showTooltip: boolean = this.timeSeriesChartWidgetSettingsForm.get('showTooltip').value; const showTooltip: boolean = this.timeSeriesChartWidgetSettingsForm.get('showTooltip').value;
const tooltipShowDate: boolean = this.timeSeriesChartWidgetSettingsForm.get('tooltipShowDate').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetSettingsForm.get('tooltipShowDate').value;
const noAggregationBarWidthSettingsStrategy: TimeSeriesChartNoAggregationBarWidthStrategy =
this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('strategy').value;
if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) {
this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').enable();
this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('separateBarWidth').disable();
} else if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) {
this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').disable();
this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('separateBarWidth').enable();
}
if (showLegend) { if (showLegend) {
this.timeSeriesChartWidgetSettingsForm.get('legendLabelFont').enable(); this.timeSeriesChartWidgetSettingsForm.get('legendLabelFont').enable();

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

@ -28,6 +28,7 @@ import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@an
import { import {
WidgetAction, WidgetAction,
WidgetActionType, WidgetActionType,
widgetActionTypes,
widgetActionTypeTranslationMap, widgetActionTypeTranslationMap,
widgetType widgetType
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
@ -88,7 +89,7 @@ export class WidgetActionComponent implements ControlValueAccessor, OnInit, Vali
@Input() @Input()
callbacks: WidgetActionCallbacks; callbacks: WidgetActionCallbacks;
widgetActionTypes = Object.keys(WidgetActionType); widgetActionTypes = widgetActionTypes;
widgetActionTypeTranslations = widgetActionTypeTranslationMap; widgetActionTypeTranslations = widgetActionTypeTranslationMap;
widgetActionType = WidgetActionType; widgetActionType = WidgetActionType;

41
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.html

@ -56,21 +56,32 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="tb-form-row space-between column-xs"> <div class="tb-form-panel no-padding stroked">
<mat-slide-toggle class="mat-slide" formControlName="showTickLabels"> <div class="tb-form-row no-border space-between column-xs">
<div translate>widgets.time-series-chart.axis.tick-labels</div> <mat-slide-toggle class="mat-slide" formControlName="showTickLabels">
</mat-slide-toggle> <div translate>widgets.time-series-chart.axis.tick-labels</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px"> </mat-slide-toggle>
<tb-font-settings formControlName="tickLabelFont" <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
clearButton <tb-font-settings formControlName="tickLabelFont"
disabledLineHeight clearButton
forceSizeUnit="px" disabledLineHeight
previewText="100"> forceSizeUnit="px"
</tb-font-settings> previewText="100">
<tb-color-input asBoxInput </tb-font-settings>
colorClearButton <tb-color-input asBoxInput
formControlName="tickLabelColor"> colorClearButton
</tb-color-input> formControlName="tickLabelColor">
</tb-color-input>
</div>
</div>
<div *ngIf="axisType === 'yAxis' && advanced" class="tb-form-row no-border">
<tb-js-func fxFlex
formControlName="ticksFormatter"
[globalVariables]="functionScopeVariables"
[functionArgs]="['value']"
functionTitle="{{ 'widgets.time-series-chart.axis.ticks-formatter-function' | translate }}"
helpId="widget/lib/flot/ticks_formatter_fn">
</tb-js-func>
</div> </div>
</div> </div>
<div class="tb-form-row space-between"> <div class="tb-form-row space-between">

21
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts

@ -22,9 +22,9 @@ import {
TimeSeriesChartAxisSettings, TimeSeriesChartAxisSettings,
TimeSeriesChartYAxisSettings TimeSeriesChartYAxisSettings
} from '@home/components/widget/lib/chart/time-series-chart.models'; } from '@home/components/widget/lib/chart/time-series-chart.models';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { merge } from 'rxjs'; import { merge } from 'rxjs';
import { coerceBoolean } from '@shared/decorators/coercion';
import { WidgetService } from '@core/http/widget.service';
@Component({ @Component({
selector: 'tb-time-series-chart-axis-settings', selector: 'tb-time-series-chart-axis-settings',
@ -48,20 +48,26 @@ export class TimeSeriesChartAxisSettingsComponent implements OnInit, ControlValu
timeSeriesAxisPositionTranslations = timeSeriesAxisPositionTranslations; timeSeriesAxisPositionTranslations = timeSeriesAxisPositionTranslations;
functionScopeVariables = this.widgetService.getWidgetScopeVariables();
@Input() @Input()
disabled: boolean; disabled: boolean;
@Input() @Input()
axisType: 'xAxis' | 'yAxis' = 'xAxis'; axisType: 'xAxis' | 'yAxis' = 'xAxis';
@Input()
@coerceBoolean()
advanced = false;
private modelValue: TimeSeriesChartAxisSettings | TimeSeriesChartYAxisSettings; private modelValue: TimeSeriesChartAxisSettings | TimeSeriesChartYAxisSettings;
private propagateChange = null; private propagateChange = null;
public axisSettingsFormGroup: UntypedFormGroup; public axisSettingsFormGroup: UntypedFormGroup;
constructor(protected store: Store<AppState>, constructor(private fb: UntypedFormBuilder,
private fb: UntypedFormBuilder) { private widgetService: WidgetService,) {
} }
ngOnInit(): void { ngOnInit(): void {
@ -88,6 +94,7 @@ export class TimeSeriesChartAxisSettingsComponent implements OnInit, ControlValu
splitLinesColor: [null, []] splitLinesColor: [null, []]
}); });
if (this.axisType === 'yAxis') { if (this.axisType === 'yAxis') {
this.axisSettingsFormGroup.addControl('ticksFormatter', this.fb.control(null, []));
this.axisSettingsFormGroup.addControl('min', this.fb.control(null, [])); this.axisSettingsFormGroup.addControl('min', this.fb.control(null, []));
this.axisSettingsFormGroup.addControl('max', this.fb.control(null, [])); this.axisSettingsFormGroup.addControl('max', this.fb.control(null, []));
} }
@ -143,9 +150,15 @@ export class TimeSeriesChartAxisSettingsComponent implements OnInit, ControlValu
if (showTickLabels) { if (showTickLabels) {
this.axisSettingsFormGroup.get('tickLabelFont').enable({emitEvent: false}); this.axisSettingsFormGroup.get('tickLabelFont').enable({emitEvent: false});
this.axisSettingsFormGroup.get('tickLabelColor').enable({emitEvent: false}); this.axisSettingsFormGroup.get('tickLabelColor').enable({emitEvent: false});
if (this.axisType === 'yAxis') {
this.axisSettingsFormGroup.get('ticksFormatter').enable({emitEvent: false});
}
} else { } else {
this.axisSettingsFormGroup.get('tickLabelFont').disable({emitEvent: false}); this.axisSettingsFormGroup.get('tickLabelFont').disable({emitEvent: false});
this.axisSettingsFormGroup.get('tickLabelColor').disable({emitEvent: false}); this.axisSettingsFormGroup.get('tickLabelColor').disable({emitEvent: false});
if (this.axisType === 'yAxis') {
this.axisSettingsFormGroup.get('ticksFormatter').disable({emitEvent: false});
}
} }
if (showTicks) { if (showTicks) {
this.axisSettingsFormGroup.get('ticksColor').enable({emitEvent: false}); this.axisSettingsFormGroup.get('ticksColor').enable({emitEvent: false});

75
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html

@ -0,0 +1,75 @@
<!--
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-form-panel" [formGroup]="barWidthSettingsFormGroup">
<div fxLayout="row" fxLayoutAlign="space-between center">
<div fxFlex translate>widgets.time-series-chart.no-aggregation-bar-width-strategy</div>
<tb-toggle-select formControlName="strategy" selectMediaBreakpoint="xs">
<tb-toggle-option *ngFor="let strategy of timeSeriesChartNoAggregationBarWidthStrategies" [value]="strategy">
{{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }}
</tb-toggle-option>
</tb-toggle-select>
</div>
<ng-container *ngIf="barWidthSettingsFormGroup.get('strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.group">
<ng-container
*ngTemplateOutlet="barWidth;
context: {
formGroup: barWidthSettingsFormGroup.get('groupWidth'),
label: 'widgets.time-series-chart.bar-group-width'
}">
</ng-container>
</ng-container>
<ng-container *ngIf="barWidthSettingsFormGroup.get('strategy').value === TimeSeriesChartNoAggregationBarWidthStrategy.separate">
<ng-container
*ngTemplateOutlet="barWidth;
context: {
formGroup: barWidthSettingsFormGroup.get('barWidth'),
label: 'widgets.time-series-chart.bar-width'
}">
</ng-container>
</ng-container>
</div>
<ng-template #barWidth let-label="label" let-formGroup="formGroup">
<div class="tb-form-row space-between column-lt-md" [formGroup]="formGroup">
<div translate>{{ label }}</div>
<div fxLayout="row" fxFlex.lt-md fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field class="medium-width" fxFlex.lt-md appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="relative">
<mat-select-trigger>
{{ (formGroup.get('relative').value ?
'widgets.time-series-chart.bar-width-relative' :
'widgets.time-series-chart.bar-width-absolute') | translate }}
</mat-select-trigger>
<mat-option [value]="true">
{{ 'widgets.time-series-chart.bar-width-relative' | translate }}
</mat-option>
<mat-option [value]="false">
{{ 'widgets.time-series-chart.bar-width-absolute' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="formGroup.get('relative').value" class="number fixed-width" appearance="outline" subscriptSizing="dynamic">
<input required matInput type="number" formControlName="relativeWidth" min="0.1" max="100" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>%</span>
</mat-form-field>
<mat-form-field *ngIf="!formGroup.get('relative').value" class="number fixed-width" appearance="outline" subscriptSizing="dynamic">
<input required matInput type="number" formControlName="absoluteWidth" min="100" step="1" placeholder="{{ 'widget-config.set' | translate }}"/>
<span matSuffix>ms</span>
</mat-form-field>
</div>
</div>
</ng-template>

147
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts

@ -0,0 +1,147 @@
///
/// 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.
///
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import {
ControlValueAccessor,
NG_VALUE_ACCESSOR,
UntypedFormBuilder,
UntypedFormGroup,
Validators
} from '@angular/forms';
import {
TimeSeriesChartNoAggregationBarWidthSettings,
timeSeriesChartNoAggregationBarWidthStrategies,
TimeSeriesChartNoAggregationBarWidthStrategy,
timeSeriesChartNoAggregationBarWidthStrategyTranslations
} from '@home/components/widget/lib/chart/time-series-chart.models';
import { merge } from 'rxjs';
@Component({
selector: 'tb-time-series-no-aggregation-bar-width-settings',
templateUrl: './time-series-no-aggregation-bar-width-settings.component.html',
styleUrls: ['./../../widget-settings.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TimeSeriesNoAggregationBarWidthSettingsComponent),
multi: true
}
]
})
export class TimeSeriesNoAggregationBarWidthSettingsComponent implements OnInit, ControlValueAccessor {
TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy;
timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies;
timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations;
@Input()
disabled: boolean;
private modelValue: TimeSeriesChartNoAggregationBarWidthSettings;
private propagateChange = null;
public barWidthSettingsFormGroup: UntypedFormGroup;
constructor(private fb: UntypedFormBuilder) {
}
ngOnInit(): void {
this.barWidthSettingsFormGroup = this.fb.group({
strategy: [null, []],
groupWidth: this.fb.group({
relative: [null, []],
relativeWidth: [null, [Validators.required, Validators.min(0.1), Validators.max(100)]],
absoluteWidth: [null, [Validators.required, Validators.min(100)]]
}),
barWidth: this.fb.group({
relative: [null, []],
relativeWidth: [null, [Validators.required, Validators.min(0.1), Validators.max(100)]],
absoluteWidth: [null, [Validators.required, Validators.min(100)]]
})
});
this.barWidthSettingsFormGroup.valueChanges.subscribe(() => {
this.updateModel();
});
merge(this.barWidthSettingsFormGroup.get('strategy').valueChanges,
this.barWidthSettingsFormGroup.get('groupWidth.relative').valueChanges,
this.barWidthSettingsFormGroup.get('barWidth.relative').valueChanges)
.subscribe(() => {
this.updateValidators();
});
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(_fn: any): void {
}
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
if (isDisabled) {
this.barWidthSettingsFormGroup.disable({emitEvent: false});
} else {
this.barWidthSettingsFormGroup.enable({emitEvent: false});
this.updateValidators();
}
}
writeValue(value: TimeSeriesChartNoAggregationBarWidthSettings): void {
this.modelValue = value;
this.barWidthSettingsFormGroup.patchValue(
value, {emitEvent: false}
);
this.updateValidators();
}
private updateValidators() {
const strategy: TimeSeriesChartNoAggregationBarWidthStrategy =
this.barWidthSettingsFormGroup.get('strategy').value;
const groupWidthRelative: boolean = this.barWidthSettingsFormGroup.get('groupWidth.relative').value;
const barWidthRelative: boolean = this.barWidthSettingsFormGroup.get('barWidth.relative').value;
if (strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) {
this.barWidthSettingsFormGroup.get('groupWidth').enable({emitEvent: false});
this.barWidthSettingsFormGroup.get('barWidth').disable({emitEvent: false});
if (groupWidthRelative) {
this.barWidthSettingsFormGroup.get('groupWidth').get('relativeWidth').enable({emitEvent: false});
this.barWidthSettingsFormGroup.get('groupWidth').get('absoluteWidth').disable({emitEvent: false});
} else {
this.barWidthSettingsFormGroup.get('groupWidth').get('relativeWidth').disable({emitEvent: false});
this.barWidthSettingsFormGroup.get('groupWidth').get('absoluteWidth').enable({emitEvent: false});
}
} else if (strategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) {
this.barWidthSettingsFormGroup.get('groupWidth').disable({emitEvent: false});
this.barWidthSettingsFormGroup.get('barWidth').enable({emitEvent: false});
if (barWidthRelative) {
this.barWidthSettingsFormGroup.get('barWidth').get('relativeWidth').enable({emitEvent: false});
this.barWidthSettingsFormGroup.get('barWidth').get('absoluteWidth').disable({emitEvent: false});
} else {
this.barWidthSettingsFormGroup.get('barWidth').get('relativeWidth').disable({emitEvent: false});
this.barWidthSettingsFormGroup.get('barWidth').get('absoluteWidth').enable({emitEvent: false});
}
}
}
private updateModel() {
this.modelValue = this.barWidthSettingsFormGroup.getRawValue();
this.propagateChange(this.modelValue);
}
}

5
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts

@ -106,6 +106,9 @@ import { EntityAliasInputComponent } from '@home/components/widget/lib/settings/
import { import {
TimeSeriesChartThresholdSettingsPanelComponent TimeSeriesChartThresholdSettingsPanelComponent
} from '@home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings-panel.component'; } from '@home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings-panel.component';
import {
TimeSeriesNoAggregationBarWidthSettingsComponent
} from '@home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -146,6 +149,7 @@ import {
TimeSeriesChartThresholdsPanelComponent, TimeSeriesChartThresholdsPanelComponent,
TimeSeriesChartThresholdRowComponent, TimeSeriesChartThresholdRowComponent,
TimeSeriesChartThresholdSettingsPanelComponent, TimeSeriesChartThresholdSettingsPanelComponent,
TimeSeriesNoAggregationBarWidthSettingsComponent,
DataKeyInputComponent, DataKeyInputComponent,
EntityAliasInputComponent EntityAliasInputComponent
], ],
@ -192,6 +196,7 @@ import {
TimeSeriesChartThresholdsPanelComponent, TimeSeriesChartThresholdsPanelComponent,
TimeSeriesChartThresholdRowComponent, TimeSeriesChartThresholdRowComponent,
TimeSeriesChartThresholdSettingsPanelComponent, TimeSeriesChartThresholdSettingsPanelComponent,
TimeSeriesNoAggregationBarWidthSettingsComponent,
DataKeyInputComponent, DataKeyInputComponent,
EntityAliasInputComponent EntityAliasInputComponent
], ],

16
ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html

@ -120,7 +120,21 @@
}} }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<div formGroupName="additionalConfig"> <div formGroupName="additionalConfig" class="tb-form-panel no-padding no-border">
<div class="tb-form-row space-between" formGroupName="icon">
<mat-slide-toggle formControlName="enabled" class="mat-slide">
{{ 'icon.icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
[color]="templateConfigurationForm.get('MOBILE_APP.additionalConfig.icon.color').value"
formControlName="icon">
</tb-material-icon-select>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
</div>
<tb-notification-action-button-configuration <tb-notification-action-button-configuration
formControlName="onClick" formControlName="onClick"
hideButtonText hideButtonText

33
ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts

@ -34,7 +34,7 @@ import {
} from '@shared/models/notification.models'; } from '@shared/models/notification.models';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { isDefinedAndNotNull } from '@core/utils'; import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -112,8 +112,16 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co
this.destroy$.complete(); this.destroy$.complete();
} }
writeValue(value: any) { writeValue(value: Partial<DeliveryMethodsTemplates>) {
this.templateConfigurationForm.patchValue(value, {emitEvent: false}); const settings = deepClone(value);
if (isDefinedAndNotNull(settings)) {
for (const method of Object.values(NotificationDeliveryMethod)) {
if (isDefinedAndNotNull(settings[method]?.enabled)) {
delete settings[method].enabled;
}
}
}
this.templateConfigurationForm.patchValue(settings, {emitEvent: false});
} }
registerOnChange(fn: any): void { registerOnChange(fn: any): void {
@ -160,6 +168,9 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co
case NotificationDeliveryMethod.WEB: case NotificationDeliveryMethod.WEB:
form.get('additionalConfig.icon.enabled').updateValueAndValidity({onlySelf: true}); form.get('additionalConfig.icon.enabled').updateValueAndValidity({onlySelf: true});
break; break;
case NotificationDeliveryMethod.MOBILE_APP:
form.get('additionalConfig.icon.enabled').updateValueAndValidity({onlySelf: true});
break;
} }
} }
}); });
@ -225,9 +236,25 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co
subject: ['', [Validators.required, Validators.maxLength(50)]], subject: ['', [Validators.required, Validators.maxLength(50)]],
body: ['', [Validators.required, Validators.maxLength(150)]], body: ['', [Validators.required, Validators.maxLength(150)]],
additionalConfig: this.fb.group({ additionalConfig: this.fb.group({
icon: this.fb.group({
enabled: [false],
icon: [{value: 'notifications', disabled: true}, Validators.required],
color: [{value: '#757575', disabled: true}]
}),
onClick: [null] onClick: [null]
}) })
}); });
deliveryMethodForm.get('additionalConfig.icon.enabled').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe((value) => {
if (value) {
deliveryMethodForm.get('additionalConfig.icon.icon').enable({emitEvent: false});
deliveryMethodForm.get('additionalConfig.icon.color').enable({emitEvent: false});
} else {
deliveryMethodForm.get('additionalConfig.icon.icon').disable({emitEvent: false});
deliveryMethodForm.get('additionalConfig.icon.color').disable({emitEvent: false});
}
});
break; break;
case NotificationDeliveryMethod.MICROSOFT_TEAMS: case NotificationDeliveryMethod.MICROSOFT_TEAMS:
deliveryMethodForm = this.fb.group({ deliveryMethodForm = this.fb.group({

2
ui-ngx/src/app/shared/models/widget.models.ts

@ -555,6 +555,8 @@ export enum WidgetMobileActionType {
takeScreenshot = 'takeScreenshot' takeScreenshot = 'takeScreenshot'
} }
export const widgetActionTypes = Object.keys(WidgetActionType) as WidgetActionType[];
export const widgetActionTypeTranslationMap = new Map<WidgetActionType, string>( export const widgetActionTypeTranslationMap = new Map<WidgetActionType, string>(
[ [
[ WidgetActionType.openDashboardState, 'widget-action.open-dashboard-state' ], [ WidgetActionType.openDashboardState, 'widget-action.open-dashboard-state' ],

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

@ -6632,8 +6632,10 @@
"no-aggregation-bar-width-strategy": "Bar width strategy for non-aggregated data", "no-aggregation-bar-width-strategy": "Bar width strategy for non-aggregated data",
"no-aggregation-bar-width-strategy-group": "Group", "no-aggregation-bar-width-strategy-group": "Group",
"no-aggregation-bar-width-strategy-separate": "Separate", "no-aggregation-bar-width-strategy-separate": "Separate",
"bar-group-interval-width": "Bar group interval width", "bar-group-width": "Bar group width",
"separate-bar-width": "Separate bar width", "bar-width": "Bar width",
"bar-width-relative": "Percentage of time window",
"bar-width-absolute": "Absolute (ms)",
"threshold": { "threshold": {
"thresholds": "Thresholds", "thresholds": "Thresholds",
"source": "Source", "source": "Source",
@ -6678,6 +6680,7 @@
"position-top": "Top", "position-top": "Top",
"position-bottom": "Bottom", "position-bottom": "Bottom",
"tick-labels": "Tick labels", "tick-labels": "Tick labels",
"ticks-formatter-function": "Ticks formatter function",
"show-ticks": "Show ticks", "show-ticks": "Show ticks",
"show-line": "Show line", "show-line": "Show line",
"show-split-lines": "Show split lines", "show-split-lines": "Show split lines",

6
ui-ngx/src/form.scss

@ -29,9 +29,11 @@
@media #{$breakpoint} { @media #{$breakpoint} {
@include form-row-column; @include form-row-column;
.mat-mdc-form-field, tb-unit-input { .mat-mdc-form-field, tb-unit-input {
width: auto; &:not(.fixed-width) {
&.medium-width {
width: auto; width: auto;
&.medium-width {
width: auto;
}
} }
} }
} }

Loading…
Cancel
Save