UI: Improve aggregated value card widget. Improve data key aggregation config form.
This commit is contained in:
		
							parent
							
								
									943788f25e
								
							
						
					
					
						commit
						1422558ac6
					
				@ -64,6 +64,9 @@
 | 
			
		||||
    <tb-color-settings formControlName="color">
 | 
			
		||||
    </tb-color-settings>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="tb-arrow-field">
 | 
			
		||||
    <mat-checkbox formControlName="showArrow"></mat-checkbox>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div class="tb-form-table-row-cell-buttons">
 | 
			
		||||
    <button type="button"
 | 
			
		||||
            mat-icon-button
 | 
			
		||||
 | 
			
		||||
@ -49,10 +49,10 @@
 | 
			
		||||
 | 
			
		||||
  .tb-aggregation-field {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    min-width: 150px;
 | 
			
		||||
    min-width: 120px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tb-units-field, .tb-decimals-field, .tb-font-field, .tb-color-field {
 | 
			
		||||
  .tb-units-field, .tb-decimals-field, .tb-font-field, .tb-color-field, tb-arrow-field {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    place-content: center;
 | 
			
		||||
@ -69,14 +69,13 @@
 | 
			
		||||
    min-width: 60px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tb-font-field {
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    min-width: 40px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tb-color-field {
 | 
			
		||||
  .tb-font-field, .tb-color-field, .tb-arrow-field {
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    min-width: 40px;
 | 
			
		||||
    display: none;
 | 
			
		||||
    @media #{$mat-gt-xs} {
 | 
			
		||||
      display: block;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tb-units-field, .tb-decimals-field {
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ import {
 | 
			
		||||
  ComparisonResultType,
 | 
			
		||||
  DataKey,
 | 
			
		||||
  DataKeyConfigMode,
 | 
			
		||||
  DatasourceType, Widget,
 | 
			
		||||
  DatasourceType, JsonSettingsSchema, Widget,
 | 
			
		||||
  widgetType
 | 
			
		||||
} from '@shared/models/widget.models';
 | 
			
		||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
@ -104,6 +104,14 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
    return this.widgetConfigComponent.widget;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get latestDataKeySettingsSchema(): JsonSettingsSchema {
 | 
			
		||||
    return this.widgetConfigComponent.modelValue?.latestDataKeySettingsSchema;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get latestDataKeySettingsDirective(): string {
 | 
			
		||||
    return this.widgetConfigComponent.modelValue?.latestDataKeySettingsDirective;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get isEntityDatasource(): boolean {
 | 
			
		||||
    return [DatasourceType.device, DatasourceType.entity].includes(this.datasourceType);
 | 
			
		||||
  }
 | 
			
		||||
@ -124,7 +132,8 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
      units: [null, []],
 | 
			
		||||
      decimals: [null, []],
 | 
			
		||||
      font: [null, []],
 | 
			
		||||
      color: [null, []]
 | 
			
		||||
      color: [null, []],
 | 
			
		||||
      showArrow: [null, []]
 | 
			
		||||
    });
 | 
			
		||||
    this.keyRowFormGroup.valueChanges.subscribe(
 | 
			
		||||
      () => this.updateModel()
 | 
			
		||||
@ -172,7 +181,8 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
        units: value?.units,
 | 
			
		||||
        decimals: value?.decimals,
 | 
			
		||||
        font: settings.font,
 | 
			
		||||
        color: settings.color
 | 
			
		||||
        color: settings.color,
 | 
			
		||||
        showArrow: settings.showArrow
 | 
			
		||||
      }, {emitEvent: false}
 | 
			
		||||
    );
 | 
			
		||||
    this.cd.markForCheck();
 | 
			
		||||
@ -190,8 +200,8 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
        data: {
 | 
			
		||||
          dataKey: deepClone(this.modelValue),
 | 
			
		||||
          dataKeyConfigMode: DataKeyConfigMode.general,
 | 
			
		||||
          dataKeySettingsSchema: null,
 | 
			
		||||
          dataKeySettingsDirective: null,
 | 
			
		||||
          dataKeySettingsSchema: this.latestDataKeySettingsSchema,
 | 
			
		||||
          dataKeySettingsDirective: this.latestDataKeySettingsDirective,
 | 
			
		||||
          dashboard: null,
 | 
			
		||||
          aliasController: null,
 | 
			
		||||
          widget: this.widget,
 | 
			
		||||
@ -207,6 +217,11 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
      }).afterClosed().subscribe((updatedDataKey) => {
 | 
			
		||||
      if (updatedDataKey) {
 | 
			
		||||
        this.modelValue = updatedDataKey;
 | 
			
		||||
        const settings: AggregatedValueCardKeySettings = (this.modelValue.settings || {});
 | 
			
		||||
        this.keyRowFormGroup.get('position').patchValue(settings.position, {emitEvent: false});
 | 
			
		||||
        this.keyRowFormGroup.get('font').patchValue(settings.font, {emitEvent: false});
 | 
			
		||||
        this.keyRowFormGroup.get('color').patchValue(settings.color, {emitEvent: false});
 | 
			
		||||
        this.keyRowFormGroup.get('showArrow').patchValue(settings.showArrow, {emitEvent: false});
 | 
			
		||||
        this.keyRowFormGroup.get('units').patchValue(this.modelValue.units, {emitEvent: false});
 | 
			
		||||
        this.keyRowFormGroup.get('decimals').patchValue(this.modelValue.decimals, {emitEvent: false});
 | 
			
		||||
        this.updateModel();
 | 
			
		||||
@ -220,6 +235,7 @@ export class AggregatedDataKeyRowComponent implements ControlValueAccessor, OnIn
 | 
			
		||||
    this.modelValue.settings.position = value.position;
 | 
			
		||||
    this.modelValue.settings.font = value.font;
 | 
			
		||||
    this.modelValue.settings.color = value.color;
 | 
			
		||||
    this.modelValue.settings.showArrow = value.showArrow;
 | 
			
		||||
    this.modelValue.units = value.units;
 | 
			
		||||
    this.modelValue.decimals = value.decimals;
 | 
			
		||||
    this.propagateChange(this.modelValue);
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@
 | 
			
		||||
      <div class="tb-form-table-header-cell tb-decimals-header" translate>widget-config.decimals-short</div>
 | 
			
		||||
      <div class="tb-form-table-header-cell tb-font-header" translate>widgets.aggregated-value-card.font</div>
 | 
			
		||||
      <div class="tb-form-table-header-cell tb-color-header" translate>widgets.aggregated-value-card.color</div>
 | 
			
		||||
      <div class="tb-form-table-header-cell tb-arrow-header" translate>widgets.aggregated-value-card.arrow</div>
 | 
			
		||||
      <div class="tb-form-table-header-cell tb-actions-header"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div *ngIf="keysFormArray().controls.length; else noKeys" class="tb-form-table-body">
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@
 | 
			
		||||
 | 
			
		||||
    &.tb-aggregation-header {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      min-width: 150px;
 | 
			
		||||
      min-width: 120px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.tb-units-header {
 | 
			
		||||
@ -38,14 +38,13 @@
 | 
			
		||||
      min-width: 60px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.tb-font-header {
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      min-width: 40px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.tb-color-header {
 | 
			
		||||
    &.tb-font-header, &.tb-color-header, &.tb-arrow-header {
 | 
			
		||||
      width: 40px;
 | 
			
		||||
      min-width: 40px;
 | 
			
		||||
      display: none;
 | 
			
		||||
      @media #{$mat-gt-xs} {
 | 
			
		||||
        display: block;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.tb-actions-header {
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@
 | 
			
		||||
  </tb-datasources>
 | 
			
		||||
  <div class="tb-form-panel">
 | 
			
		||||
    <div class="tb-form-panel-title" translate>widget-config.appearance</div>
 | 
			
		||||
    <div class="tb-form-row">
 | 
			
		||||
    <div class="tb-form-row column-xs">
 | 
			
		||||
      <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showTitle">
 | 
			
		||||
        {{ 'widget-config.title' | translate }}
 | 
			
		||||
      </mat-slide-toggle>
 | 
			
		||||
@ -48,7 +48,7 @@
 | 
			
		||||
        </tb-color-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="tb-form-row">
 | 
			
		||||
    <div class="tb-form-row column-xs">
 | 
			
		||||
      <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showIcon">
 | 
			
		||||
        {{ 'widgets.value-card.icon' | translate }}
 | 
			
		||||
      </mat-slide-toggle>
 | 
			
		||||
@ -68,7 +68,7 @@
 | 
			
		||||
        </tb-color-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="tb-form-row">
 | 
			
		||||
    <div class="tb-form-row column-xs">
 | 
			
		||||
      <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showSubtitle">
 | 
			
		||||
        {{ 'widgets.aggregated-value-card.subtitle' | translate }}
 | 
			
		||||
      </mat-slide-toggle>
 | 
			
		||||
@ -80,8 +80,10 @@
 | 
			
		||||
                          clearButton
 | 
			
		||||
                          [previewText]="aggregatedValueCardWidgetConfigForm.get('subtitle').value">
 | 
			
		||||
        </tb-font-settings>
 | 
			
		||||
        <tb-color-settings formControlName="subtitleColor">
 | 
			
		||||
        </tb-color-settings>
 | 
			
		||||
        <tb-color-input asBoxInput
 | 
			
		||||
                        colorClearButton
 | 
			
		||||
                        formControlName="subtitleColor">
 | 
			
		||||
        </tb-color-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="tb-form-row column-xs">
 | 
			
		||||
@ -93,16 +95,27 @@
 | 
			
		||||
        <tb-font-settings formControlName="dateFont"
 | 
			
		||||
                          [previewText]="datePreviewFn">
 | 
			
		||||
        </tb-font-settings>
 | 
			
		||||
        <tb-color-settings formControlName="dateColor">
 | 
			
		||||
        </tb-color-settings>
 | 
			
		||||
        <tb-color-input asBoxInput
 | 
			
		||||
                        colorClearButton
 | 
			
		||||
                        formControlName="dateColor">
 | 
			
		||||
        </tb-color-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="tb-form-row space-between">
 | 
			
		||||
      <mat-slide-toggle class="mat-slide" formControlName="showChart">
 | 
			
		||||
    <div class="tb-form-row column-xs">
 | 
			
		||||
      <mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showChart">
 | 
			
		||||
        {{ 'widgets.aggregated-value-card.chart' | translate }}
 | 
			
		||||
      </mat-slide-toggle>
 | 
			
		||||
      <tb-color-settings formControlName="chartColor">
 | 
			
		||||
      </tb-color-settings>
 | 
			
		||||
      <div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
 | 
			
		||||
        <tb-unit-input class="flex" formControlName="chartUnits"></tb-unit-input>
 | 
			
		||||
        <mat-form-field appearance="outline" class="flex number" subscriptSizing="dynamic">
 | 
			
		||||
          <input matInput formControlName="chartDecimals" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
 | 
			
		||||
          <div matSuffix fxHide.lt-md translate>widget-config.decimals-suffix</div>
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
        <tb-color-input asBoxInput
 | 
			
		||||
                        colorClearButton
 | 
			
		||||
                        formControlName="chartColor">
 | 
			
		||||
        </tb-color-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <tb-aggregated-data-keys-panel
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ export class AggregatedValueCardBasicConfigComponent extends BasicWidgetConfigCo
 | 
			
		||||
 | 
			
		||||
  protected setupDefaults(configData: WidgetConfigComponentData) {
 | 
			
		||||
    this.setupDefaultDatasource(configData, [
 | 
			
		||||
        { name: 'watermeter', label: 'Watermeter', type: DataKeyType.timeseries }
 | 
			
		||||
        { name: 'watermeter', label: 'Watermeter', type: DataKeyType.timeseries, units: 'm³', decimals: 0 }
 | 
			
		||||
      ],
 | 
			
		||||
      createDefaultAggregatedValueLatestDataKeys('watermeter', 'm³')
 | 
			
		||||
    );
 | 
			
		||||
@ -141,6 +141,8 @@ export class AggregatedValueCardBasicConfigComponent extends BasicWidgetConfigCo
 | 
			
		||||
      dateColor: [settings.dateColor, []],
 | 
			
		||||
 | 
			
		||||
      showChart: [settings.showChart, []],
 | 
			
		||||
      chartUnits: [dataKey?.units, []],
 | 
			
		||||
      chartDecimals: [dataKey?.decimals, []],
 | 
			
		||||
      chartColor: [settings.chartColor, []],
 | 
			
		||||
 | 
			
		||||
      values: [this.getValues(configData.config.datasources, keyName), []],
 | 
			
		||||
@ -181,6 +183,13 @@ export class AggregatedValueCardBasicConfigComponent extends BasicWidgetConfigCo
 | 
			
		||||
    this.widgetConfig.config.settings.dateColor = config.dateColor;
 | 
			
		||||
 | 
			
		||||
    this.widgetConfig.config.settings.showChart = config.showChart;
 | 
			
		||||
 | 
			
		||||
    const dataKey = getDataKey(this.widgetConfig.config.datasources);
 | 
			
		||||
    if (dataKey) {
 | 
			
		||||
      dataKey.units = config.chartUnits;
 | 
			
		||||
      dataKey.decimals = config.chartDecimals;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.widgetConfig.config.settings.chartColor = config.chartColor;
 | 
			
		||||
 | 
			
		||||
    this.setValues(config.values, this.widgetConfig.config.datasources);
 | 
			
		||||
@ -253,8 +262,12 @@ export class AggregatedValueCardBasicConfigComponent extends BasicWidgetConfigCo
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (showChart) {
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartUnits').enable();
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartDecimals').enable();
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartColor').enable();
 | 
			
		||||
    } else {
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartUnits').disable();
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartDecimals').disable();
 | 
			
		||||
      this.aggregatedValueCardWidgetConfigForm.get('chartColor').disable();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -78,76 +78,87 @@
 | 
			
		||||
        </tb-js-func>
 | 
			
		||||
      </section>
 | 
			
		||||
      <ng-container *ngIf="widgetType === widgetTypes.latest && modelValue.type === dataKeyTypes.timeseries">
 | 
			
		||||
        <mat-form-field subscriptSizing="dynamic">
 | 
			
		||||
          <mat-label translate>datakey.aggregation</mat-label>
 | 
			
		||||
          <mat-select formControlName="aggregationType" style="min-width: 150px;">
 | 
			
		||||
            <mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
 | 
			
		||||
              {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
 | 
			
		||||
            </mat-option>
 | 
			
		||||
          </mat-select>
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
        <div class="tb-hint after-fields">
 | 
			
		||||
          {{ dataKeyFormGroup.get('aggregationType').value ? (dataKeyAggregationTypeHintTranslations.get(aggregationTypes[dataKeyFormGroup.get('aggregationType').value]) | translate) : '' }}
 | 
			
		||||
          <section *ngIf="dataKeyFormGroup.get('aggregationType').value !== aggregationTypes.NONE">
 | 
			
		||||
            {{ 'datakey.aggregation-type-hint-common' | translate }}
 | 
			
		||||
          </section>
 | 
			
		||||
        <div class="tb-form-row column">
 | 
			
		||||
          <div class="tb-form-row space-between no-border no-padding">
 | 
			
		||||
            <div>{{ 'datakey.aggregation' | translate }}</div>
 | 
			
		||||
            <mat-form-field class="medium-width" subscriptSizing="dynamic" appearance="outline">
 | 
			
		||||
              <mat-select formControlName="aggregationType">
 | 
			
		||||
                <mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
 | 
			
		||||
                  {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
              </mat-select>
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="tb-form-hint tb-primary-fill">
 | 
			
		||||
            {{ dataKeyFormGroup.get('aggregationType').value ? (dataKeyAggregationTypeHintTranslations.get(aggregationTypes[dataKeyFormGroup.get('aggregationType').value]) | translate) : '' }}
 | 
			
		||||
            <section *ngIf="dataKeyFormGroup.get('aggregationType').value !== aggregationTypes.NONE">
 | 
			
		||||
              {{ 'datakey.aggregation-type-hint-common' | translate }}
 | 
			
		||||
            </section>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </ng-container>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div *ngIf="dataKeyFormGroup.get('aggregationType').value && dataKeyFormGroup.get('aggregationType').value !== aggregationTypes.NONE"
 | 
			
		||||
         class="tb-form-panel tb-slide-toggle">
 | 
			
		||||
         class="tb-form-panel">
 | 
			
		||||
      <div class="tb-form-panel-title" translate>datakey.delta-calculation</div>
 | 
			
		||||
      <mat-expansion-panel class="tb-settings" [expanded]="dataKeyFormGroup.get('comparisonEnabled').value" [disabled]="!dataKeyFormGroup.get('comparisonEnabled').value">
 | 
			
		||||
      <div class="tb-form-panel stroked tb-slide-toggle">
 | 
			
		||||
        <mat-expansion-panel class="tb-settings" [expanded]="dataKeyFormGroup.get('comparisonEnabled').value" [disabled]="!dataKeyFormGroup.get('comparisonEnabled').value">
 | 
			
		||||
        <mat-expansion-panel-header fxLayout="row wrap">
 | 
			
		||||
          <mat-panel-title fxLayout="column" fxLayoutAlign="center start">
 | 
			
		||||
          <mat-panel-title fxLayout="column" fxLayoutAlign="center start" fxLayoutGap="8px">
 | 
			
		||||
            <mat-slide-toggle class="mat-slide" formControlName="comparisonEnabled" (click)="$event.stopPropagation()">
 | 
			
		||||
              {{ 'datakey.enable-delta-calculation' | translate }}
 | 
			
		||||
            </mat-slide-toggle>
 | 
			
		||||
            <mat-hint class="tb-hint" style="line-height: 15px; padding-left: 52px;">{{ 'datakey.enable-delta-calculation-hint' | translate }}</mat-hint>
 | 
			
		||||
            <mat-hint class="tb-form-hint tb-primary-fill">{{ 'datakey.enable-delta-calculation-hint' | translate }}</mat-hint>
 | 
			
		||||
          </mat-panel-title>
 | 
			
		||||
        </mat-expansion-panel-header>
 | 
			
		||||
        <ng-template matExpansionPanelContent>
 | 
			
		||||
          <section fxLayout="column" *ngIf="dataKeyFormGroup.get('comparisonEnabled').value">
 | 
			
		||||
            <mat-form-field fxFlex class="mat-block">
 | 
			
		||||
              <mat-label translate>widgets.chart.time-for-comparison</mat-label>
 | 
			
		||||
              <mat-select formControlName="timeForComparison">
 | 
			
		||||
                <mat-option [value]="'previousInterval'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-previous-interval' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
                <mat-option [value]="'days'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-days' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
                <mat-option [value]="'weeks'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-weeks' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
                <mat-option [value]="'months'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-months' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
                <mat-option [value]="'years'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-years' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
                <mat-option [value]="'customInterval'">
 | 
			
		||||
                  {{ 'widgets.chart.time-for-comparison-custom-interval' | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
              </mat-select>
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
            <mat-form-field *ngIf="dataKeyFormGroup.get('timeForComparison').value === 'customInterval'" fxFlex class="mat-block">
 | 
			
		||||
              <mat-label translate>widgets.chart.custom-interval-value</mat-label>
 | 
			
		||||
              <input required matInput type="number" min="0" formControlName="comparisonCustomIntervalValue">
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
            <mat-form-field style="padding-bottom: 16px;">
 | 
			
		||||
              <mat-label translate>datakey.delta-calculation-result</mat-label>
 | 
			
		||||
              <mat-select formControlName="comparisonResultType" style="min-width: 150px;">
 | 
			
		||||
                <mat-option *ngFor="let comparisonResultType of comparisonResults" [value]="comparisonResultType">
 | 
			
		||||
                  {{ comparisonResultTypeTranslations.get(comparisonResultTypes[comparisonResultType]) | translate }}
 | 
			
		||||
                </mat-option>
 | 
			
		||||
              </mat-select>
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
          </section>
 | 
			
		||||
          <ng-container *ngIf="dataKeyFormGroup.get('comparisonEnabled').value">
 | 
			
		||||
            <div class="tb-form-row space-between">
 | 
			
		||||
              <div>{{ 'widgets.chart.time-for-comparison' | translate }}</div>
 | 
			
		||||
              <mat-form-field class="medium-width" subscriptSizing="dynamic" appearance="outline">
 | 
			
		||||
                <mat-select formControlName="timeForComparison">
 | 
			
		||||
                  <mat-option [value]="'previousInterval'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-previous-interval' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                  <mat-option [value]="'days'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-days' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                  <mat-option [value]="'weeks'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-weeks' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                  <mat-option [value]="'months'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-months' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                  <mat-option [value]="'years'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-years' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                  <mat-option [value]="'customInterval'">
 | 
			
		||||
                    {{ 'widgets.chart.time-for-comparison-custom-interval' | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                </mat-select>
 | 
			
		||||
              </mat-form-field>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div *ngIf="dataKeyFormGroup.get('timeForComparison').value === 'customInterval'" class="tb-form-row space-between">
 | 
			
		||||
              <div>{{ 'widgets.chart.custom-interval-value' | translate }}</div>
 | 
			
		||||
              <mat-form-field class="medium-width number" subscriptSizing="dynamic" appearance="outline">
 | 
			
		||||
                <input required matInput type="number" min="0" formControlName="comparisonCustomIntervalValue">
 | 
			
		||||
              </mat-form-field>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="tb-form-row space-between">
 | 
			
		||||
              <div>{{ 'datakey.delta-calculation-result' | translate }}</div>
 | 
			
		||||
              <mat-form-field class="medium-width" subscriptSizing="dynamic" appearance="outline">
 | 
			
		||||
                <mat-select formControlName="comparisonResultType" style="min-width: 150px;">
 | 
			
		||||
                  <mat-option *ngFor="let comparisonResultType of comparisonResults" [value]="comparisonResultType">
 | 
			
		||||
                    {{ comparisonResultTypeTranslations.get(comparisonResultTypes[comparisonResultType]) | translate }}
 | 
			
		||||
                  </mat-option>
 | 
			
		||||
                </mat-select>
 | 
			
		||||
              </mat-form-field>
 | 
			
		||||
            </div>
 | 
			
		||||
          </ng-container>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </mat-expansion-panel>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="tb-form-panel tb-slide-toggle"
 | 
			
		||||
         *ngIf="(modelValue.type === dataKeyTypes.timeseries || modelValue.type === dataKeyTypes.attribute || modelValue.type === dataKeyTypes.count) && showPostProcessing">
 | 
			
		||||
      <mat-expansion-panel class="tb-settings" [expanded]="dataKeyFormGroup.get('usePostProcessing').value" [disabled]="!dataKeyFormGroup.get('usePostProcessing').value">
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../../theme";
 | 
			
		||||
@import "../../../../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
.tb-datasource-list-item {
 | 
			
		||||
  &.mat-mdc-list-item {
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
 | 
			
		||||
<ng-template #subtitleTpl>
 | 
			
		||||
  <div *ngIf="showSubtitle" class="tb-aggregated-value-card-subtitle"
 | 
			
		||||
       [style]="subtitleStyle" [style.color]="subtitleColor.color">{{ subtitle$ | async }}</div>
 | 
			
		||||
       [style]="subtitleStyle" [style.color]="subtitleColor">{{ subtitle$ | async }}</div>
 | 
			
		||||
</ng-template>
 | 
			
		||||
<ng-template #valuesTpl>
 | 
			
		||||
  <div *ngIf="showValues" class="tb-aggregated-value-card-values">
 | 
			
		||||
@ -73,7 +73,7 @@
 | 
			
		||||
  </div>
 | 
			
		||||
</ng-template>
 | 
			
		||||
<ng-template #dateTpl>
 | 
			
		||||
  <div *ngIf="showDate" [style]="dateStyle" [style.color]="dateColor.color" [innerHTML]="dateFormat.formatted"></div>
 | 
			
		||||
  <div *ngIf="showDate" [style]="dateStyle" [style.color]="dateColor" [innerHTML]="dateFormat.formatted"></div>
 | 
			
		||||
</ng-template>
 | 
			
		||||
<ng-template #valueTpl let-value="value">
 | 
			
		||||
  <div class="tb-aggregated-value-card-value" [style]="value.style" [style.color]="value.color.color">
 | 
			
		||||
 | 
			
		||||
@ -36,9 +36,9 @@ import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import {
 | 
			
		||||
  backgroundStyle,
 | 
			
		||||
  ColorProcessor,
 | 
			
		||||
  ComponentStyle,
 | 
			
		||||
  DateFormatProcessor, getDataKey,
 | 
			
		||||
  DateFormatProcessor,
 | 
			
		||||
  getDataKey,
 | 
			
		||||
  getLatestSingleTsValue,
 | 
			
		||||
  overlayStyle,
 | 
			
		||||
  textStyle
 | 
			
		||||
@ -47,7 +47,7 @@ import { DatePipe } from '@angular/common';
 | 
			
		||||
import { TbFlot } from '@home/components/widget/lib/flot-widget';
 | 
			
		||||
import { TbFlotKeySettings, TbFlotSettings } from '@home/components/widget/lib/flot-widget.models';
 | 
			
		||||
import { DataKey } from '@shared/models/widget.models';
 | 
			
		||||
import { formatNumberValue, formatValue, isDefined, isNumeric } from '@core/utils';
 | 
			
		||||
import { formatNumberValue, formatValue, isDefined } from '@core/utils';
 | 
			
		||||
import { map } from 'rxjs/operators';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@ -72,19 +72,19 @@ export class AggregatedValueCardWidgetComponent implements OnInit, AfterViewInit
 | 
			
		||||
  showSubtitle = true;
 | 
			
		||||
  subtitle$: Observable<string>;
 | 
			
		||||
  subtitleStyle: ComponentStyle = {};
 | 
			
		||||
  subtitleColor: ColorProcessor;
 | 
			
		||||
  subtitleColor: string;
 | 
			
		||||
 | 
			
		||||
  showValues = false;
 | 
			
		||||
 | 
			
		||||
  values: {[key: string]: AggregatedValueCardValue} = {};
 | 
			
		||||
 | 
			
		||||
  showChart = true;
 | 
			
		||||
  chartColor: ColorProcessor;
 | 
			
		||||
  chartColor: string;
 | 
			
		||||
 | 
			
		||||
  showDate = true;
 | 
			
		||||
  dateFormat: DateFormatProcessor;
 | 
			
		||||
  dateStyle: ComponentStyle = {};
 | 
			
		||||
  dateColor: ColorProcessor;
 | 
			
		||||
  dateColor: string;
 | 
			
		||||
 | 
			
		||||
  backgroundStyle: ComponentStyle = {};
 | 
			
		||||
  overlayStyle: ComponentStyle = {};
 | 
			
		||||
@ -108,7 +108,7 @@ export class AggregatedValueCardWidgetComponent implements OnInit, AfterViewInit
 | 
			
		||||
    const subtitle = this.settings.subtitle;
 | 
			
		||||
    this.subtitle$ = this.ctx.registerLabelPattern(subtitle, this.subtitle$);
 | 
			
		||||
    this.subtitleStyle = textStyle(this.settings.subtitleFont, '0.25px');
 | 
			
		||||
    this.subtitleColor =  ColorProcessor.fromSettings(this.settings.subtitleColor);
 | 
			
		||||
    this.subtitleColor =  this.settings.subtitleColor;
 | 
			
		||||
 | 
			
		||||
    const dataKey = getDataKey(this.ctx.defaultSubscription.datasources);
 | 
			
		||||
    if (dataKey?.name && this.ctx.defaultSubscription.firstDatasource?.latestDataKeys?.length) {
 | 
			
		||||
@ -123,7 +123,7 @@ export class AggregatedValueCardWidgetComponent implements OnInit, AfterViewInit
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.showChart = this.settings.showChart;
 | 
			
		||||
    this.chartColor = ColorProcessor.fromSettings(this.settings.chartColor);
 | 
			
		||||
    this.chartColor = this.settings.chartColor;
 | 
			
		||||
    if (this.showChart) {
 | 
			
		||||
      if (this.ctx.defaultSubscription.firstDatasource?.dataKeys?.length) {
 | 
			
		||||
        this.flotDataKey = this.ctx.defaultSubscription.firstDatasource?.dataKeys[0];
 | 
			
		||||
@ -132,14 +132,14 @@ export class AggregatedValueCardWidgetComponent implements OnInit, AfterViewInit
 | 
			
		||||
          showLines: true,
 | 
			
		||||
          lineWidth: 2
 | 
			
		||||
        } as TbFlotKeySettings;
 | 
			
		||||
        this.flotDataKey.color = this.chartColor.color;
 | 
			
		||||
        this.flotDataKey.color = this.chartColor;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.showDate = this.settings.showDate;
 | 
			
		||||
    this.dateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.dateFormat);
 | 
			
		||||
    this.dateStyle = textStyle(this.settings.dateFont,  '0.25px');
 | 
			
		||||
    this.dateColor = ColorProcessor.fromSettings(this.settings.dateColor);
 | 
			
		||||
    this.dateColor = this.settings.dateColor;
 | 
			
		||||
 | 
			
		||||
    this.backgroundStyle = backgroundStyle(this.settings.background);
 | 
			
		||||
    this.overlayStyle = overlayStyle(this.settings.background.overlay);
 | 
			
		||||
@ -188,17 +188,11 @@ export class AggregatedValueCardWidgetComponent implements OnInit, AfterViewInit
 | 
			
		||||
  public onDataUpdated() {
 | 
			
		||||
    const tsValue = getLatestSingleTsValue(this.ctx.data);
 | 
			
		||||
    let ts;
 | 
			
		||||
    let value;
 | 
			
		||||
    if (tsValue) {
 | 
			
		||||
      ts = tsValue[0];
 | 
			
		||||
      value = tsValue[1];
 | 
			
		||||
    }
 | 
			
		||||
    this.subtitleColor.update(value);
 | 
			
		||||
    this.dateColor.update(value);
 | 
			
		||||
 | 
			
		||||
    if (this.showChart) {
 | 
			
		||||
      this.chartColor.update(value);
 | 
			
		||||
      this.flot.updateSeriesColor(this.chartColor.color);
 | 
			
		||||
      this.flot.update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,6 @@ import {
 | 
			
		||||
  constantColor,
 | 
			
		||||
  DateFormatSettings,
 | 
			
		||||
  Font,
 | 
			
		||||
  iconStyle,
 | 
			
		||||
  lastUpdateAgoDateFormat,
 | 
			
		||||
  textStyle
 | 
			
		||||
} from '@shared/models/widget-settings.models';
 | 
			
		||||
@ -36,13 +35,13 @@ export interface AggregatedValueCardWidgetSettings {
 | 
			
		||||
  showSubtitle: boolean;
 | 
			
		||||
  subtitle: string;
 | 
			
		||||
  subtitleFont: Font;
 | 
			
		||||
  subtitleColor: ColorSettings;
 | 
			
		||||
  subtitleColor: string;
 | 
			
		||||
  showDate: boolean;
 | 
			
		||||
  dateFormat: DateFormatSettings;
 | 
			
		||||
  dateFont: Font;
 | 
			
		||||
  dateColor: ColorSettings;
 | 
			
		||||
  dateColor: string;
 | 
			
		||||
  showChart: boolean;
 | 
			
		||||
  chartColor: ColorSettings;
 | 
			
		||||
  chartColor: string;
 | 
			
		||||
  background: BackgroundSettings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -83,7 +82,8 @@ export interface AggregatedValueCardValue {
 | 
			
		||||
  downArrow: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const computeAggregatedCardValue = (dataKeys: DataKey[], keyName: string, position: AggregatedValueCardKeyPosition): AggregatedValueCardValue => {
 | 
			
		||||
export const computeAggregatedCardValue =
 | 
			
		||||
  (dataKeys: DataKey[], keyName: string, position: AggregatedValueCardKeyPosition): AggregatedValueCardValue => {
 | 
			
		||||
  const key = dataKeys.find(dataKey => ( dataKey.name === keyName && (dataKey.settings?.position === position ||
 | 
			
		||||
                                         (!dataKey.settings?.position && position === AggregatedValueCardKeyPosition.center)) ));
 | 
			
		||||
  if (key) {
 | 
			
		||||
@ -123,7 +123,7 @@ export const aggregatedValueCardDefaultSettings: AggregatedValueCardWidgetSettin
 | 
			
		||||
    weight: '400',
 | 
			
		||||
    lineHeight: '16px'
 | 
			
		||||
  },
 | 
			
		||||
  subtitleColor: constantColor('rgba(0, 0, 0, 0.38)'),
 | 
			
		||||
  subtitleColor: 'rgba(0, 0, 0, 0.38)',
 | 
			
		||||
  showDate: true,
 | 
			
		||||
  dateFormat: lastUpdateAgoDateFormat(),
 | 
			
		||||
  dateFont: {
 | 
			
		||||
@ -134,9 +134,9 @@ export const aggregatedValueCardDefaultSettings: AggregatedValueCardWidgetSettin
 | 
			
		||||
    weight: '400',
 | 
			
		||||
    lineHeight: '16px'
 | 
			
		||||
  },
 | 
			
		||||
  dateColor: constantColor('rgba(0, 0, 0, 0.38)'),
 | 
			
		||||
  dateColor: 'rgba(0, 0, 0, 0.38)',
 | 
			
		||||
  showChart: true,
 | 
			
		||||
  chartColor: constantColor('rgba(0, 0, 0, 0.87)'),
 | 
			
		||||
  chartColor: 'rgba(0, 0, 0, 0.87)',
 | 
			
		||||
  background: {
 | 
			
		||||
    type: BackgroundType.color,
 | 
			
		||||
    color: '#fff',
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../theme";
 | 
			
		||||
@import "../../../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
  .fields-group {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../../theme";
 | 
			
		||||
@import "../../../../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
:host ::ng-deep {
 | 
			
		||||
  .mat-button-toggle-group.tb-notification-unread-toggle-group {
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,6 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../../scss/constants";
 | 
			
		||||
@import "../../../../../../theme";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
  form.tb-dialog-container {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,6 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../../theme";
 | 
			
		||||
@import "../../../../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,6 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../../../scss/constants";
 | 
			
		||||
@import "../../../../../../theme";
 | 
			
		||||
 | 
			
		||||
:host-context(.tb-fullscreen-dialog .mat-mdc-dialog-container) {
 | 
			
		||||
  width: 820px;
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
@import "../../../../theme";
 | 
			
		||||
@import "../../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
  .mini-button {
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@ import { Component, forwardRef, OnDestroy } from '@angular/core';
 | 
			
		||||
import { Color, ColorPickerControl } from '@iplab/ngx-color-picker';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms';
 | 
			
		||||
import { isString } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
export enum ColorType {
 | 
			
		||||
  hex = 'hex',
 | 
			
		||||
@ -87,8 +88,9 @@ export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  writeValue(value: string): void {
 | 
			
		||||
    this.setValue = !!value;
 | 
			
		||||
    this.control.setValueFrom(value || '#fff');
 | 
			
		||||
    const valid = this.isValidColorValue(value);
 | 
			
		||||
    this.setValue = valid;
 | 
			
		||||
    this.control.setValueFrom(valid ? value : '#fff');
 | 
			
		||||
    this.modelValue = value;
 | 
			
		||||
 | 
			
		||||
    if (this.control.initType === ColorType.hexa) {
 | 
			
		||||
@ -101,6 +103,10 @@ export class ColorPickerComponent implements ControlValueAccessor, OnDestroy {
 | 
			
		||||
    this.presentationControl.patchValue(this.presentations.indexOf(this.control.initType), {emitEvent: false});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private isValidColorValue(value: string): boolean {
 | 
			
		||||
    return value && isString(value) && value.trim().length > 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateModel() {
 | 
			
		||||
    const color: string = this.getValueByType(this.control.value, this.presentations[this.presentationControl.value]);
 | 
			
		||||
    if (this.modelValue !== color) {
 | 
			
		||||
 | 
			
		||||
@ -53,22 +53,24 @@
 | 
			
		||||
      </ng-container>
 | 
			
		||||
    </div>
 | 
			
		||||
  </cdk-virtual-scroll-viewport>
 | 
			
		||||
  <button *ngIf="!showAllSubject.value" class="tb-material-icons-show-more" mat-button color="primary" (click)="showAllSubject.next(true)">
 | 
			
		||||
    {{ 'action.show-more' | translate }}
 | 
			
		||||
  </button>
 | 
			
		||||
  <ng-container *ngIf="notFound">
 | 
			
		||||
    <div class="tb-no-data-available" [ngStyle]="{width: iconsPanelWidth}">
 | 
			
		||||
      <div class="tb-no-data-bg"></div>
 | 
			
		||||
      <div class="tb-no-data-text">{{ 'icon.no-icons-found' | translate:{iconSearch: searchIconControl.value} }}</div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-container>
 | 
			
		||||
  <div *ngIf="iconClearButton" class="tb-material-icons-panel-buttons">
 | 
			
		||||
    <button mat-button
 | 
			
		||||
  <div class="tb-material-icons-panel-buttons" *ngIf="iconClearButton || !showAllSubject.value">
 | 
			
		||||
    <button *ngIf="iconClearButton"
 | 
			
		||||
            mat-button
 | 
			
		||||
            color="primary"
 | 
			
		||||
            type="button"
 | 
			
		||||
            (click)="clearIcon()"
 | 
			
		||||
            [disabled]="!selectedIcon">
 | 
			
		||||
      {{ 'action.clear' | translate }}
 | 
			
		||||
    </button>
 | 
			
		||||
    <span fxFlex></span>
 | 
			
		||||
    <button *ngIf="!showAllSubject.value" class="tb-material-icons-show-more" mat-button color="primary" (click)="showAllSubject.next(true)">
 | 
			
		||||
      {{ 'action.show-more' | translate }}
 | 
			
		||||
    </button>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@
 | 
			
		||||
    letter-spacing: 0.25px;
 | 
			
		||||
    color: rgba(0, 0, 0, 0.87);
 | 
			
		||||
  }
 | 
			
		||||
  .tb-material-icons-title, .tb-material-icons-search, .tb-material-icons-show-more {
 | 
			
		||||
  .tb-material-icons-title, .tb-material-icons-search {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
  }
 | 
			
		||||
  .tb-material-icons-viewport {
 | 
			
		||||
@ -64,6 +64,6 @@
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    gap: 16px;
 | 
			
		||||
    align-items: flex-start;
 | 
			
		||||
    align-self: flex-start;
 | 
			
		||||
    align-self: stretch;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,6 @@
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@import "../../../theme";
 | 
			
		||||
@import "../../../scss/constants";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
 | 
			
		||||
@ -149,7 +149,7 @@ type ValueColorFunction = (value: any) => string;
 | 
			
		||||
export abstract class ColorProcessor {
 | 
			
		||||
 | 
			
		||||
  static fromSettings(color: ColorSettings): ColorProcessor {
 | 
			
		||||
    const settings = color || constantColor('rgba(0, 0, 0, 0.87)');
 | 
			
		||||
    const settings = color || constantColor(null);
 | 
			
		||||
    switch (settings.type) {
 | 
			
		||||
      case ColorType.constant:
 | 
			
		||||
        return new ConstantColorProcessor(settings);
 | 
			
		||||
@ -192,7 +192,7 @@ class RangeColorProcessor extends ColorProcessor {
 | 
			
		||||
    if (this.settings.rangeList?.length && isDefinedAndNotNull(value) && isNumeric(value)) {
 | 
			
		||||
      const num = Number(value);
 | 
			
		||||
      for (const range of this.settings.rangeList) {
 | 
			
		||||
        if (this.constantRange(range) && range.from === num) {
 | 
			
		||||
        if (RangeColorProcessor.constantRange(range) && range.from === num) {
 | 
			
		||||
          return range.color;
 | 
			
		||||
        } else if ((!isNumber(range.from) || num >= range.from) && (!isNumber(range.to) || num < range.to)) {
 | 
			
		||||
          return range.color;
 | 
			
		||||
@ -202,7 +202,7 @@ class RangeColorProcessor extends ColorProcessor {
 | 
			
		||||
    return this.settings.color;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private constantRange(range: ColorRange): boolean {
 | 
			
		||||
  private static constantRange(range: ColorRange): boolean {
 | 
			
		||||
    return isNumber(range.from) && isNumber(range.to) && range.from === range.to;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5756,6 +5756,7 @@
 | 
			
		||||
            "position-left-bottom": "Left bottom",
 | 
			
		||||
            "font": "Font",
 | 
			
		||||
            "color": "Color",
 | 
			
		||||
            "arrow": "Arrow",
 | 
			
		||||
            "display-up-down-arrow": "Display Up/Down arrow",
 | 
			
		||||
            "add-value": "Add value",
 | 
			
		||||
            "remove-value": "Remove value",
 | 
			
		||||
 | 
			
		||||
@ -16,12 +16,16 @@
 | 
			
		||||
 | 
			
		||||
@import './scss/constants';
 | 
			
		||||
 | 
			
		||||
@mixin form-row-column($breakpoint) {
 | 
			
		||||
@mixin form-row-column() {
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  align-items: stretch;
 | 
			
		||||
  gap: 12px;
 | 
			
		||||
  padding: 12px 7px 12px 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@mixin form-row-column-breakpoint($breakpoint) {
 | 
			
		||||
  @media #{$breakpoint} {
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    align-items: stretch;
 | 
			
		||||
    gap: 12px;
 | 
			
		||||
    padding: 12px 7px 12px 16px;
 | 
			
		||||
    @include form-row-column;
 | 
			
		||||
    .mat-mdc-form-field, tb-unit-input {
 | 
			
		||||
      width: auto;
 | 
			
		||||
      &.medium-width {
 | 
			
		||||
@ -132,6 +136,16 @@
 | 
			
		||||
    font-size: 12px;
 | 
			
		||||
    color: #808080;
 | 
			
		||||
  }
 | 
			
		||||
  .tb-form-hint {
 | 
			
		||||
    padding: 12px 16px;
 | 
			
		||||
    font-size: var(--mdc-typography-caption-font-size, 12px);
 | 
			
		||||
    line-height: var(--mdc-typography-caption-line-height, 20px);
 | 
			
		||||
    font-weight: var(--mdc-typography-caption-font-weight, 400);
 | 
			
		||||
    letter-spacing: var(--mdc-typography-caption-letter-spacing, 0.0333333333em);
 | 
			
		||||
    color: rgba(0, 0, 0, 0.6);
 | 
			
		||||
    white-space: normal;
 | 
			
		||||
    border-radius: 6px;
 | 
			
		||||
  }
 | 
			
		||||
  .tb-form-row {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    display: flex;
 | 
			
		||||
@ -142,11 +156,12 @@
 | 
			
		||||
    border: 1px solid rgba(0, 0, 0, 0.12);
 | 
			
		||||
    border-radius: 6px;
 | 
			
		||||
    &.column {
 | 
			
		||||
      @include form-row-column;
 | 
			
		||||
      &-xs {
 | 
			
		||||
        @include form-row-column($mat-xs)
 | 
			
		||||
        @include form-row-column-breakpoint($mat-xs)
 | 
			
		||||
      }
 | 
			
		||||
      &-lt-md {
 | 
			
		||||
        @include form-row-column($mat-lt-md)
 | 
			
		||||
        @include form-row-column-breakpoint($mat-lt-md)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    &.no-border {
 | 
			
		||||
@ -450,7 +465,7 @@
 | 
			
		||||
      left: 0;
 | 
			
		||||
      right: 0;
 | 
			
		||||
      bottom: 0;
 | 
			
		||||
      background: #305680;
 | 
			
		||||
      background: $tb-primary-color;
 | 
			
		||||
      mask-image: url(/assets/home/no_data_folder_bg.svg);
 | 
			
		||||
      mask-repeat: no-repeat;
 | 
			
		||||
      mask-size: contain;
 | 
			
		||||
@ -470,6 +485,23 @@
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .tb-primary-fill {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    &:before {
 | 
			
		||||
      display: block;
 | 
			
		||||
      height: auto;
 | 
			
		||||
      content: "";
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: 0;
 | 
			
		||||
      bottom: 0;
 | 
			
		||||
      left: 0;
 | 
			
		||||
      right: 0;
 | 
			
		||||
      background: $tb-primary-color;
 | 
			
		||||
      opacity: 0.04;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  button.mat-mdc-button-base.tb-box-button, .tb-form-table-row-cell-buttons button.mat-mdc-icon-button.mat-mdc-button-base {
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    min-width: 40px;
 | 
			
		||||
 | 
			
		||||
@ -30,3 +30,10 @@ $mat-gt-xl: "screen and (min-width: 1920px)";
 | 
			
		||||
$mat-md-lg: "screen and (min-width: 960px) and (max-width: 1819px)";
 | 
			
		||||
 | 
			
		||||
$primary-hue-3: rgb(207, 216, 220) !default;
 | 
			
		||||
 | 
			
		||||
$tb-primary-color: #305680;
 | 
			
		||||
$tb-secondary-color: #527dad;
 | 
			
		||||
$tb-hue3-color: #a7c1de;
 | 
			
		||||
 | 
			
		||||
$tb-dark-primary-color: #9fa8da;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,12 +21,6 @@
 | 
			
		||||
@include mat.all-component-typographies();
 | 
			
		||||
@include mat.core();
 | 
			
		||||
 | 
			
		||||
$tb-primary-color: #305680;
 | 
			
		||||
$tb-secondary-color: #527dad;
 | 
			
		||||
$tb-hue3-color: #a7c1de;
 | 
			
		||||
 | 
			
		||||
$tb-dark-primary-color: #9fa8da;
 | 
			
		||||
 | 
			
		||||
$tb-mat-indigo: (
 | 
			
		||||
  50: #e8eaf6,
 | 
			
		||||
  100: #c5cae9,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user