UI: Add unit conversion in dashboard filter
This commit is contained in:
		
							parent
							
								
									19405416be
								
							
						
					
					
						commit
						59f23ba25d
					
				@ -26,24 +26,36 @@
 | 
			
		||||
    </button>
 | 
			
		||||
  </mat-toolbar>
 | 
			
		||||
  <div mat-dialog-content>
 | 
			
		||||
    <fieldset [disabled]="isLoading$ | async" class="flex flex-col">
 | 
			
		||||
      <mat-checkbox formControlName="editable" style="margin-bottom: 16px;">
 | 
			
		||||
        {{ 'filter.editable' | translate }}
 | 
			
		||||
      </mat-checkbox>
 | 
			
		||||
      <div class="flex flex-row items-center justify-start gap-2">
 | 
			
		||||
        <mat-form-field class="mat-block flex-1">
 | 
			
		||||
          <mat-label translate>filter.display-label</mat-label>
 | 
			
		||||
          <input matInput formControlName="label">
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
        <mat-checkbox formControlName="autogeneratedLabel">
 | 
			
		||||
          {{ 'filter.autogenerated-label' | translate }}
 | 
			
		||||
        </mat-checkbox>
 | 
			
		||||
    <div class="tb-form-panel no-padding no-border">
 | 
			
		||||
      <div class="tb-form-row">
 | 
			
		||||
        <mat-slide-toggle class="mat-slide" formControlName="editable">
 | 
			
		||||
          <div tb-hint-tooltip-icon="{{ 'filter.editable-hint' | translate }}">
 | 
			
		||||
            {{ 'filter.editable' | translate }}
 | 
			
		||||
          </div>
 | 
			
		||||
        </mat-slide-toggle>
 | 
			
		||||
      </div>
 | 
			
		||||
      <mat-form-field class="mat-block">
 | 
			
		||||
        <mat-label translate>filter.order-priority</mat-label>
 | 
			
		||||
        <input matInput type="number" formControlName="order">
 | 
			
		||||
      </mat-form-field>
 | 
			
		||||
    </fieldset>
 | 
			
		||||
      <div class="tb-form-row space-between">
 | 
			
		||||
        <mat-slide-toggle class="mat-slide" formControlName="autogeneratedLabel">
 | 
			
		||||
          <div tb-hint-tooltip-icon="{{ 'filter.custom-label-hint' | translate }}">
 | 
			
		||||
            {{ 'filter.custom-label' | translate }}
 | 
			
		||||
          </div>
 | 
			
		||||
        </mat-slide-toggle>
 | 
			
		||||
        <mat-form-field subscriptSizing="dynamic" appearance="outline" class="medium-width flex-xs">
 | 
			
		||||
          <input matInput placeholder="{{ 'filter.display-label' | translate}}" formControlName="label">
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="tb-form-row space-between">
 | 
			
		||||
        <div class="min-w-44" translate>filter.order-priority</div>
 | 
			
		||||
        <mat-form-field subscriptSizing="dynamic" appearance="outline" class="medium-width flex-xs">
 | 
			
		||||
          <input matInput type="number" formControlName="order">
 | 
			
		||||
        </mat-form-field>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="tb-form-row space-between" *ngIf="showUniInput">
 | 
			
		||||
        <div class="min-w-44" translate>filter.unit</div>
 | 
			
		||||
        <tb-unit-input supportsUnitConversion formControlName="unit" class="medium-width flex-xs">
 | 
			
		||||
        </tb-unit-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <div mat-dialog-actions class="flex items-center justify-end">
 | 
			
		||||
    <button mat-button color="primary"
 | 
			
		||||
 | 
			
		||||
@ -14,18 +14,21 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { Component, Inject, OnInit, SkipSelf } from '@angular/core';
 | 
			
		||||
import { Component, Inject, SkipSelf } from '@angular/core';
 | 
			
		||||
import { ErrorStateMatcher } from '@angular/material/core';
 | 
			
		||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
 | 
			
		||||
import { FormGroupDirective, NgForm, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
 | 
			
		||||
import { Router } from '@angular/router';
 | 
			
		||||
import { DialogComponent } from '@app/shared/components/dialog.component';
 | 
			
		||||
import {
 | 
			
		||||
  BooleanOperation, createDefaultFilterPredicateUserInfo,
 | 
			
		||||
  EntityKeyValueType, generateUserFilterValueLabel,
 | 
			
		||||
  KeyFilterPredicateUserInfo, NumericOperation,
 | 
			
		||||
  BooleanOperation,
 | 
			
		||||
  createDefaultFilterPredicateUserInfo,
 | 
			
		||||
  EntityKeyValueType,
 | 
			
		||||
  generateUserFilterValueLabel,
 | 
			
		||||
  KeyFilterPredicateUserInfo,
 | 
			
		||||
  NumericOperation,
 | 
			
		||||
  StringOperation
 | 
			
		||||
} from '@shared/models/query/query.models';
 | 
			
		||||
import { TranslateService } from '@ngx-translate/core';
 | 
			
		||||
@ -47,11 +50,12 @@ export interface FilterUserInfoDialogData {
 | 
			
		||||
})
 | 
			
		||||
export class FilterUserInfoDialogComponent extends
 | 
			
		||||
  DialogComponent<FilterUserInfoDialogComponent, KeyFilterPredicateUserInfo>
 | 
			
		||||
  implements OnInit, ErrorStateMatcher {
 | 
			
		||||
  implements ErrorStateMatcher {
 | 
			
		||||
 | 
			
		||||
  filterUserInfoFormGroup: UntypedFormGroup;
 | 
			
		||||
 | 
			
		||||
  submitted = false;
 | 
			
		||||
  showUniInput = false;
 | 
			
		||||
 | 
			
		||||
  constructor(protected store: Store<AppState>,
 | 
			
		||||
              protected router: Router,
 | 
			
		||||
@ -68,10 +72,14 @@ export class FilterUserInfoDialogComponent extends
 | 
			
		||||
      {
 | 
			
		||||
        editable: [userInfo.editable],
 | 
			
		||||
        label: [userInfo.label],
 | 
			
		||||
        autogeneratedLabel: [userInfo.autogeneratedLabel],
 | 
			
		||||
        autogeneratedLabel: [!userInfo.autogeneratedLabel],
 | 
			
		||||
        order: [userInfo.order]
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
    if (this.data.valueType === EntityKeyValueType.NUMERIC) {
 | 
			
		||||
      this.showUniInput = true;
 | 
			
		||||
      this.filterUserInfoFormGroup.addControl('unit', this.fb.control(userInfo.unit), {emitEvent: false});
 | 
			
		||||
    }
 | 
			
		||||
    this.onAutogeneratedLabelChange();
 | 
			
		||||
    if (!this.data.readonly) {
 | 
			
		||||
      this.filterUserInfoFormGroup.get('autogeneratedLabel').valueChanges.pipe(
 | 
			
		||||
@ -85,7 +93,7 @@ export class FilterUserInfoDialogComponent extends
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private onAutogeneratedLabelChange() {
 | 
			
		||||
    const autogeneratedLabel: boolean = this.filterUserInfoFormGroup.get('autogeneratedLabel').value;
 | 
			
		||||
    const autogeneratedLabel: boolean = !this.filterUserInfoFormGroup.get('autogeneratedLabel').value;
 | 
			
		||||
    if (autogeneratedLabel) {
 | 
			
		||||
      const generatedLabel = generateUserFilterValueLabel(this.data.key, this.data.valueType, this.data.operation, this.translate);
 | 
			
		||||
      this.filterUserInfoFormGroup.get('label').patchValue(generatedLabel, {emitEvent: false});
 | 
			
		||||
@ -95,9 +103,6 @@ export class FilterUserInfoDialogComponent extends
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
 | 
			
		||||
    const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
 | 
			
		||||
    const customErrorState = !!(control && control.invalid && this.submitted);
 | 
			
		||||
@ -112,6 +117,7 @@ export class FilterUserInfoDialogComponent extends
 | 
			
		||||
    this.submitted = true;
 | 
			
		||||
    if (this.filterUserInfoFormGroup.valid) {
 | 
			
		||||
      const keyFilterPredicateUserInfo: KeyFilterPredicateUserInfo = this.filterUserInfoFormGroup.getRawValue();
 | 
			
		||||
      keyFilterPredicateUserInfo.autogeneratedLabel = !keyFilterPredicateUserInfo.autogeneratedLabel;;
 | 
			
		||||
      this.dialogRef.close(keyFilterPredicateUserInfo);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
    limitations under the License.
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
<form [formGroup]="userFilterFormGroup" (ngSubmit)="save()" style="width: 400px;">
 | 
			
		||||
<form [formGroup]="userFilterFormGroup" (ngSubmit)="save()" style="width: 400px;" class="user-filter-dialog">
 | 
			
		||||
  <mat-toolbar color="primary">
 | 
			
		||||
    <h2>{{ filter.filter }}</h2>
 | 
			
		||||
    <span class="flex-1"></span>
 | 
			
		||||
@ -42,6 +42,10 @@
 | 
			
		||||
            <mat-form-field class="mat-block">
 | 
			
		||||
              <mat-label>{{ userInputControl.get('label').value }}</mat-label>
 | 
			
		||||
              <input required type="number" matInput [formControl]="userInputControl.get('value')">
 | 
			
		||||
              <div matSuffix class="mr-2"
 | 
			
		||||
                   [class.!hidden]="!userInputControl.get('unitSymbol').value">
 | 
			
		||||
                {{ userInputControl.get('unitSymbol').value }}
 | 
			
		||||
              </div>
 | 
			
		||||
            </mat-form-field>
 | 
			
		||||
          </ng-template>
 | 
			
		||||
          <ng-template [ngSwitchCase]="valueTypeEnum.DATE_TIME">
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2025 The Thingsboard Authors
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
:host ::ng-deep {
 | 
			
		||||
  .user-filter-dialog {
 | 
			
		||||
    .mat-mdc-form-field.mat-mdc-form-field-has-icon-suffix.mat-form-field-hide-placeholder {
 | 
			
		||||
      .mat-mdc-form-field-icon-suffix {
 | 
			
		||||
        place-self: center;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .mat-mdc-form-field.mat-mdc-form-field-has-icon-suffix {
 | 
			
		||||
      .mat-mdc-form-field-icon-suffix {
 | 
			
		||||
        place-self: baseline;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -14,31 +14,26 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { Component, DestroyRef, Inject, OnInit, SkipSelf } from '@angular/core';
 | 
			
		||||
import { Component, DestroyRef, Inject, SkipSelf } from '@angular/core';
 | 
			
		||||
import { ErrorStateMatcher } from '@angular/material/core';
 | 
			
		||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
import { AppState } from '@core/core.state';
 | 
			
		||||
import {
 | 
			
		||||
  AbstractControl, UntypedFormArray,
 | 
			
		||||
  UntypedFormBuilder,
 | 
			
		||||
  UntypedFormControl,
 | 
			
		||||
  UntypedFormGroup,
 | 
			
		||||
  FormGroupDirective,
 | 
			
		||||
  NgForm,
 | 
			
		||||
  Validators
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import { FormArray, FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
 | 
			
		||||
import { Router } from '@angular/router';
 | 
			
		||||
import { DialogComponent } from '@app/shared/components/dialog.component';
 | 
			
		||||
import { TranslateService } from '@ngx-translate/core';
 | 
			
		||||
import {
 | 
			
		||||
  EntityKeyValueType,
 | 
			
		||||
  Filter, FilterPredicateValue,
 | 
			
		||||
  Filter,
 | 
			
		||||
  FilterPredicateValue,
 | 
			
		||||
  filterToUserFilterInfoList,
 | 
			
		||||
  UserFilterInputInfo
 | 
			
		||||
} from '@shared/models/query/query.models';
 | 
			
		||||
import { isDefinedAndNotNull } from '@core/utils';
 | 
			
		||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
 | 
			
		||||
import { UnitService } from '@core/services/unit.service';
 | 
			
		||||
import { getSourceTbUnitSymbol, TbUnitConverter } from '@shared/models/unit.models';
 | 
			
		||||
 | 
			
		||||
export interface UserFilterDialogData {
 | 
			
		||||
  filter: Filter;
 | 
			
		||||
@ -48,14 +43,14 @@ export interface UserFilterDialogData {
 | 
			
		||||
  selector: 'tb-user-filter-dialog',
 | 
			
		||||
  templateUrl: './user-filter-dialog.component.html',
 | 
			
		||||
  providers: [{provide: ErrorStateMatcher, useExisting: UserFilterDialogComponent}],
 | 
			
		||||
  styleUrls: []
 | 
			
		||||
  styleUrls: ['./user-filter-dialog.component.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class UserFilterDialogComponent extends DialogComponent<UserFilterDialogComponent, Filter>
 | 
			
		||||
  implements OnInit, ErrorStateMatcher {
 | 
			
		||||
  implements ErrorStateMatcher {
 | 
			
		||||
 | 
			
		||||
  filter: Filter;
 | 
			
		||||
 | 
			
		||||
  userFilterFormGroup: UntypedFormGroup;
 | 
			
		||||
  userFilterFormGroup: FormGroup;
 | 
			
		||||
 | 
			
		||||
  valueTypeEnum = EntityKeyValueType;
 | 
			
		||||
 | 
			
		||||
@ -66,14 +61,15 @@ export class UserFilterDialogComponent extends DialogComponent<UserFilterDialogC
 | 
			
		||||
              @Inject(MAT_DIALOG_DATA) public data: UserFilterDialogData,
 | 
			
		||||
              @SkipSelf() private errorStateMatcher: ErrorStateMatcher,
 | 
			
		||||
              public dialogRef: MatDialogRef<UserFilterDialogComponent, Filter>,
 | 
			
		||||
              private fb: UntypedFormBuilder,
 | 
			
		||||
              public translate: TranslateService,
 | 
			
		||||
              private destroyRef: DestroyRef) {
 | 
			
		||||
              private fb: FormBuilder,
 | 
			
		||||
              private translate: TranslateService,
 | 
			
		||||
              private destroyRef: DestroyRef,
 | 
			
		||||
              private unitService: UnitService) {
 | 
			
		||||
    super(store, router, dialogRef);
 | 
			
		||||
    this.filter = data.filter;
 | 
			
		||||
    const userInputs = filterToUserFilterInfoList(this.filter, translate);
 | 
			
		||||
    const userInputs = filterToUserFilterInfoList(this.filter, this.translate);
 | 
			
		||||
 | 
			
		||||
    const userInputControls: Array<AbstractControl> = [];
 | 
			
		||||
    const userInputControls: Array<FormGroup> = [];
 | 
			
		||||
    for (const userInput of userInputs) {
 | 
			
		||||
      userInputControls.push(this.createUserInputFormControl(userInput));
 | 
			
		||||
    }
 | 
			
		||||
@ -83,12 +79,21 @@ export class UserFilterDialogComponent extends DialogComponent<UserFilterDialogC
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private createUserInputFormControl(userInput: UserFilterInputInfo): AbstractControl {
 | 
			
		||||
  private createUserInputFormControl(userInput: UserFilterInputInfo): FormGroup {
 | 
			
		||||
    const predicateValue: FilterPredicateValue<string | number | boolean> = (userInput.info.keyFilterPredicate as any).value;
 | 
			
		||||
    const value = isDefinedAndNotNull(predicateValue.userValue) ? predicateValue.userValue : predicateValue.defaultValue;
 | 
			
		||||
    let value = isDefinedAndNotNull(predicateValue.userValue) ? predicateValue.userValue : predicateValue.defaultValue;
 | 
			
		||||
    let unitSymbol = '';
 | 
			
		||||
    let valueConvertor: TbUnitConverter;
 | 
			
		||||
    if (userInput.valueType === EntityKeyValueType.NUMERIC) {
 | 
			
		||||
      unitSymbol = this.unitService.getTargetUnitSymbol(userInput.unit);
 | 
			
		||||
      const sourceUnit = getSourceTbUnitSymbol(userInput.unit);
 | 
			
		||||
      value = this.unitService.convertUnitValue(value as number, userInput.unit);
 | 
			
		||||
      valueConvertor = this.unitService.geUnitConverter(unitSymbol, sourceUnit);
 | 
			
		||||
    }
 | 
			
		||||
    const userInputControl = this.fb.group({
 | 
			
		||||
      label: [userInput.label],
 | 
			
		||||
      valueType: [userInput.valueType],
 | 
			
		||||
      unitSymbol: [unitSymbol],
 | 
			
		||||
      value: [value,
 | 
			
		||||
        userInput.valueType === EntityKeyValueType.NUMERIC ||
 | 
			
		||||
        userInput.valueType === EntityKeyValueType.DATE_TIME  ? [Validators.required] : []]
 | 
			
		||||
@ -96,19 +101,20 @@ export class UserFilterDialogComponent extends DialogComponent<UserFilterDialogC
 | 
			
		||||
    userInputControl.get('value').valueChanges.pipe(
 | 
			
		||||
      takeUntilDestroyed(this.destroyRef)
 | 
			
		||||
    ).subscribe(userValue => {
 | 
			
		||||
      (userInput.info.keyFilterPredicate as any).value.userValue = userValue;
 | 
			
		||||
      let value = userValue;
 | 
			
		||||
      if (valueConvertor) {
 | 
			
		||||
        value = valueConvertor(value as number);
 | 
			
		||||
      }
 | 
			
		||||
      (userInput.info.keyFilterPredicate as any).value.userValue = value;
 | 
			
		||||
    });
 | 
			
		||||
    return userInputControl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  userInputsFormArray(): UntypedFormArray {
 | 
			
		||||
    return this.userFilterFormGroup.get('userInputs') as UntypedFormArray;
 | 
			
		||||
  userInputsFormArray(): FormArray {
 | 
			
		||||
    return this.userFilterFormGroup.get('userInputs') as FormArray;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
 | 
			
		||||
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
 | 
			
		||||
    const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
 | 
			
		||||
    const customErrorState = !!(control && control.invalid && this.submitted);
 | 
			
		||||
    return originalErrorState || customErrorState;
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ import { AlarmInfo, AlarmSearchStatus, AlarmSeverity } from '../alarm.models';
 | 
			
		||||
import { DatePipe } from '@angular/common';
 | 
			
		||||
import { UserId } from '../id/user-id';
 | 
			
		||||
import { Direction } from '@shared/models/page/sort-order';
 | 
			
		||||
import { TbUnit } from '@shared/models/unit.models';
 | 
			
		||||
 | 
			
		||||
export enum EntityKeyType {
 | 
			
		||||
  ATTRIBUTE = 'ATTRIBUTE',
 | 
			
		||||
@ -179,7 +180,8 @@ export function createDefaultFilterPredicateUserInfo(): KeyFilterPredicateUserIn
 | 
			
		||||
    editable: true,
 | 
			
		||||
    label: '',
 | 
			
		||||
    autogeneratedLabel: true,
 | 
			
		||||
    order: 0
 | 
			
		||||
    order: 0,
 | 
			
		||||
    unit: ''
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -373,6 +375,7 @@ export interface KeyFilterPredicateUserInfo {
 | 
			
		||||
  label: string;
 | 
			
		||||
  autogeneratedLabel: boolean;
 | 
			
		||||
  order?: number;
 | 
			
		||||
  unit?: TbUnit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface KeyFilterPredicateInfo {
 | 
			
		||||
@ -621,6 +624,7 @@ export interface UserFilterInputInfo {
 | 
			
		||||
  label: string;
 | 
			
		||||
  valueType: EntityKeyValueType;
 | 
			
		||||
  info: KeyFilterPredicateInfo;
 | 
			
		||||
  unit: TbUnit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function filterToUserFilterInfoList(filter: Filter, translate: TranslateService): Array<UserFilterInputInfo> {
 | 
			
		||||
@ -654,6 +658,7 @@ export function predicateInfoToUserFilterInfoList(key: EntityKey,
 | 
			
		||||
      const userInput: UserFilterInputInfo = {
 | 
			
		||||
        info: predicateInfo,
 | 
			
		||||
        label: predicateInfo.userInfo.label,
 | 
			
		||||
        unit: predicateInfo.userInfo.unit,
 | 
			
		||||
        valueType
 | 
			
		||||
      };
 | 
			
		||||
      if (predicateInfo.userInfo.autogeneratedLabel) {
 | 
			
		||||
@ -882,7 +887,7 @@ export function entityDataToEntityInfo(entityData: EntityData): EntityInfo {
 | 
			
		||||
          if (additionalInfoJson && additionalInfoJson.description) {
 | 
			
		||||
            entityInfo.entityDescription = additionalInfoJson.description;
 | 
			
		||||
          }
 | 
			
		||||
        } catch (e) {}
 | 
			
		||||
        } catch (e) {/**/}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (fields.queueName && fields.serviceId) {
 | 
			
		||||
 | 
			
		||||
@ -2951,6 +2951,7 @@
 | 
			
		||||
         "missing-key-filters-error": "Key filters is missing for filter '{{filter}}'.",
 | 
			
		||||
         "filter": "Filter",
 | 
			
		||||
         "editable": "Editable",
 | 
			
		||||
         "editable-hint": "Allow user to change the filter value in dashboards.",
 | 
			
		||||
         "no-filters-found": "No filters found.",
 | 
			
		||||
         "no-filter-text": "No filter specified",
 | 
			
		||||
         "add-filter-prompt": "Please add filter",
 | 
			
		||||
@ -2991,7 +2992,9 @@
 | 
			
		||||
         "user-parameters": "User parameters",
 | 
			
		||||
         "display-label": "Label to display",
 | 
			
		||||
         "autogenerated-label": "Auto generate label",
 | 
			
		||||
         "order-priority": "Field order priority",
 | 
			
		||||
         "custom-label": "Custom label",
 | 
			
		||||
         "custom-label-hint": "Enable to set your own label for the filter. When disabled, a label will be generated automatically.",
 | 
			
		||||
         "order-priority": "Display order",
 | 
			
		||||
         "key-filter": "Key filter",
 | 
			
		||||
         "key-filters": "Key filters",
 | 
			
		||||
         "key-name": "Key name",
 | 
			
		||||
@ -3035,7 +3038,8 @@
 | 
			
		||||
         "switch-to-dynamic-value": "Switch to dynamic value",
 | 
			
		||||
         "switch-to-default-value": "Switch to default value",
 | 
			
		||||
         "inherit-owner": "Inherit from owner",
 | 
			
		||||
         "source-attribute-not-set": "If source attribute isn't set"
 | 
			
		||||
         "source-attribute-not-set": "If source attribute isn't set",
 | 
			
		||||
         "unit": "Unit"
 | 
			
		||||
    },
 | 
			
		||||
    "fullscreen": {
 | 
			
		||||
        "expand": "Expand to fullscreen",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user