corrections-after-review
This commit is contained in:
		
							parent
							
								
									97657284a8
								
							
						
					
					
						commit
						97a70366fa
					
				@ -17,13 +17,13 @@
 | 
			
		||||
import {
 | 
			
		||||
  ChangeDetectionStrategy,
 | 
			
		||||
  ChangeDetectorRef,
 | 
			
		||||
  Component, ElementRef, HostBinding,
 | 
			
		||||
  Component, ElementRef, EventEmitter, HostBinding,
 | 
			
		||||
  Inject,
 | 
			
		||||
  Injector,
 | 
			
		||||
  Input,
 | 
			
		||||
  NgZone,
 | 
			
		||||
  OnDestroy,
 | 
			
		||||
  OnInit, Optional,
 | 
			
		||||
  OnInit, Optional, Renderer2,
 | 
			
		||||
  StaticProvider,
 | 
			
		||||
  ViewChild,
 | 
			
		||||
  ViewContainerRef,
 | 
			
		||||
@ -136,7 +136,11 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 | 
			
		||||
import cssjs from '@core/css/css';
 | 
			
		||||
import { DOCUMENT } from '@angular/common';
 | 
			
		||||
import { IAliasController } from '@core/api/widget-api.models';
 | 
			
		||||
import { LayoutType, LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
 | 
			
		||||
import { MatButton } from '@angular/material/button';
 | 
			
		||||
import { VersionControlComponent } from '@home/components/vc/version-control.component';
 | 
			
		||||
import { TbPopoverService } from '@shared/components/popover.service';
 | 
			
		||||
import { tap } from 'rxjs/operators';
 | 
			
		||||
import { LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
 | 
			
		||||
 | 
			
		||||
// @dynamic
 | 
			
		||||
@Component({
 | 
			
		||||
@ -292,6 +296,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
    ]
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  updateBreadcrumbs = new EventEmitter();
 | 
			
		||||
 | 
			
		||||
  private rxSubscriptions = new Array<Subscription>();
 | 
			
		||||
 | 
			
		||||
  get toolbarOpened(): boolean {
 | 
			
		||||
@ -331,6 +337,8 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
              private fb: FormBuilder,
 | 
			
		||||
              private dialog: MatDialog,
 | 
			
		||||
              private translate: TranslateService,
 | 
			
		||||
              private popoverService: TbPopoverService,
 | 
			
		||||
              private renderer: Renderer2,
 | 
			
		||||
              private ngZone: NgZone,
 | 
			
		||||
              @Optional() @Inject('embeddedValue') private embeddedValue,
 | 
			
		||||
              private overlay: Overlay,
 | 
			
		||||
@ -653,15 +661,15 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public mainLayoutWidth(): string {
 | 
			
		||||
    if (this.isEditingWidget && this.editingLayoutCtx.id === LayoutType.MAIN) {
 | 
			
		||||
    if (this.isEditingWidget && this.editingLayoutCtx.id === 'main') {
 | 
			
		||||
      return '100%';
 | 
			
		||||
    } else {
 | 
			
		||||
      return this.layouts.right.show && !this.isMobile ? this.calculateWidth(LayoutType.MAIN) : '100%';
 | 
			
		||||
      return this.layouts.right.show && !this.isMobile ? this.calculateWidth('main') : '100%';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public mainLayoutHeight(): string {
 | 
			
		||||
    if (!this.isEditingWidget || this.editingLayoutCtx.id === LayoutType.MAIN) {
 | 
			
		||||
    if (!this.isEditingWidget || this.editingLayoutCtx.id === 'main') {
 | 
			
		||||
      return '100%';
 | 
			
		||||
    } else {
 | 
			
		||||
      return '0px';
 | 
			
		||||
@ -669,10 +677,10 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public rightLayoutWidth(): string {
 | 
			
		||||
    if (this.isEditingWidget && this.editingLayoutCtx.id === LayoutType.RIGHT) {
 | 
			
		||||
    if (this.isEditingWidget && this.editingLayoutCtx.id === 'right') {
 | 
			
		||||
      return '100%';
 | 
			
		||||
    } else {
 | 
			
		||||
      return this.isMobile ? '100%' : this.calculateWidth(LayoutType.RIGHT);
 | 
			
		||||
      return this.isMobile ? '100%' : this.calculateWidth('right');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -689,7 +697,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
      }
 | 
			
		||||
      if (layoutDimension) {
 | 
			
		||||
        if (layoutDimension.type === LayoutWidthType.PERCENTAGE) {
 | 
			
		||||
          if (layout === LayoutType.RIGHT) {
 | 
			
		||||
          if (layout === 'right') {
 | 
			
		||||
            return (100 - layoutDimension.leftWidthPercentage) + '%';
 | 
			
		||||
          } else {
 | 
			
		||||
            return layoutDimension.leftWidthPercentage + '%';
 | 
			
		||||
@ -1432,4 +1440,52 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toggleVersionControl($event: Event, versionControlButton: MatButton) {
 | 
			
		||||
    if ($event) {
 | 
			
		||||
      $event.stopPropagation();
 | 
			
		||||
    }
 | 
			
		||||
    const trigger = versionControlButton._elementRef.nativeElement;
 | 
			
		||||
    if (this.popoverService.hasPopover(trigger)) {
 | 
			
		||||
      this.popoverService.hidePopover(trigger);
 | 
			
		||||
    } else {
 | 
			
		||||
      const versionControlPopover = this.popoverService.displayPopover(trigger, this.renderer,
 | 
			
		||||
        this.viewContainerRef, VersionControlComponent, 'leftTop', true, null,
 | 
			
		||||
        {
 | 
			
		||||
          detailsMode: true,
 | 
			
		||||
          active: true,
 | 
			
		||||
          singleEntityMode: true,
 | 
			
		||||
          externalEntityId: this.dashboard.externalId || this.dashboard.id,
 | 
			
		||||
          entityId: this.dashboard.id,
 | 
			
		||||
          entityName: this.dashboard.name,
 | 
			
		||||
          onBeforeCreateVersion: () => {
 | 
			
		||||
            return this.dashboardService.saveDashboard(this.dashboard).pipe(
 | 
			
		||||
              tap((dashboard) => {
 | 
			
		||||
                this.dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard);
 | 
			
		||||
                this.prevDashboard = deepClone(this.dashboard);
 | 
			
		||||
              })
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        }, {}, {}, {}, true);
 | 
			
		||||
      versionControlPopover.tbComponentRef.instance.popoverComponent = versionControlPopover;
 | 
			
		||||
      versionControlPopover.tbComponentRef.instance.versionRestored.subscribe(() => {
 | 
			
		||||
        this.dashboardService.getDashboard(this.currentDashboardId).subscribe((dashboard) => {
 | 
			
		||||
          dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard);
 | 
			
		||||
          const data = {
 | 
			
		||||
            dashboard,
 | 
			
		||||
            widgetEditMode: false,
 | 
			
		||||
            currentDashboardId: this.currentDashboardId
 | 
			
		||||
          } as any;
 | 
			
		||||
          this.init(data);
 | 
			
		||||
          this.dashboardCtx.stateController.cleanupPreservedStates();
 | 
			
		||||
          this.dashboardCtx.stateController.resetState();
 | 
			
		||||
          this.setEditMode(true, false);
 | 
			
		||||
          this.updateBreadcrumbs.emit();
 | 
			
		||||
          this.ngZone.run(() => {
 | 
			
		||||
            this.cd.detectChanges();
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,8 +28,3 @@ export enum LayoutWidthType {
 | 
			
		||||
  FIXED = "fixed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum LayoutType {
 | 
			
		||||
  MAIN = "main",
 | 
			
		||||
  RIGHT = "right",
 | 
			
		||||
  LEFT = "left"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,30 +38,31 @@
 | 
			
		||||
        </mat-checkbox>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="8px">
 | 
			
		||||
        <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" style="width: 100%;">
 | 
			
		||||
        <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="2%" style="width: 100%;">
 | 
			
		||||
          <button fxFlex="{{buttonFlexValue()}}"
 | 
			
		||||
                  type="button"
 | 
			
		||||
                  mat-raised-button
 | 
			
		||||
                  color="primary"
 | 
			
		||||
                  class="tb-layout-button"
 | 
			
		||||
                  (click)="openLayoutSettings(LayoutType.MAIN)"
 | 
			
		||||
                  (click)="openLayoutSettings('main')"
 | 
			
		||||
                  >
 | 
			
		||||
            <span >{{ (layoutsFormGroup.value.right ? 'layout.left' : 'layout.main')  | translate }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button fxFlex
 | 
			
		||||
                  [fxShow]="layoutsFormGroup.get(LayoutType.RIGHT).value"
 | 
			
		||||
                  [fxShow]="layoutsFormGroup.get('right').value"
 | 
			
		||||
                  type="button"
 | 
			
		||||
                  mat-raised-button
 | 
			
		||||
                  color="primary"
 | 
			
		||||
                  class="tb-layout-button"
 | 
			
		||||
                  (click)="openLayoutSettings(LayoutType.RIGHT)">
 | 
			
		||||
                  (click)="openLayoutSettings('right')">
 | 
			
		||||
            <span >{{ 'layout.right' | translate }}</span>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div fxLayout="column"
 | 
			
		||||
             fxLayoutAlign="start center"
 | 
			
		||||
             fxLayoutGap="8px"
 | 
			
		||||
             [fxShow]="layoutsFormGroup.get(LayoutType.RIGHT).value">
 | 
			
		||||
             style="width: 100%;"
 | 
			
		||||
             [fxShow]="layoutsFormGroup.get('right').value">
 | 
			
		||||
          <mat-button-toggle-group aria-label="Select width value type"
 | 
			
		||||
                                   formControlName="type"
 | 
			
		||||
                                   style="width: 100%;">
 | 
			
		||||
@ -72,9 +73,8 @@
 | 
			
		||||
              {{ 'layout.fixed-width' | translate }}
 | 
			
		||||
            </mat-button-toggle>
 | 
			
		||||
          </mat-button-toggle-group>
 | 
			
		||||
          <div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.PERCENTAGE">
 | 
			
		||||
            <div
 | 
			
		||||
                 fxLayoutAlign="start center"
 | 
			
		||||
          <div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.PERCENTAGE" style="width: 100%;">
 | 
			
		||||
            <div fxLayoutAlign="start center"
 | 
			
		||||
                 fxLayoutGap="8px"
 | 
			
		||||
                 style="width: 100%;">
 | 
			
		||||
              <mat-slider min="10"
 | 
			
		||||
@ -86,11 +86,10 @@
 | 
			
		||||
                          [value]="layoutsFormGroup.get('leftWidthPercentage').value"
 | 
			
		||||
                          [displayWith]="formatSliderTooltipLabel">
 | 
			
		||||
              </mat-slider>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
            <div fxLayout="column">
 | 
			
		||||
            <div fxFlex fxLayout="column" style="width: 100%;">
 | 
			
		||||
              <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" style="width: 100%;">
 | 
			
		||||
                <mat-form-field class="mat-block">
 | 
			
		||||
                <mat-form-field fxFlex class="mat-block">
 | 
			
		||||
                  <mat-label>{{ 'layout.left-width' | translate }}</mat-label>
 | 
			
		||||
                  <input matInput
 | 
			
		||||
                         formControlName="leftWidthPercentage"
 | 
			
		||||
@ -99,6 +98,15 @@
 | 
			
		||||
                         step="1"
 | 
			
		||||
                         min="10"
 | 
			
		||||
                         max="90">
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('required')">
 | 
			
		||||
                    {{ 'layout.left-width-percentage-required' | translate }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('max')">
 | 
			
		||||
                    {{ 'layout.value-max-error' | translate: { max: 90 } }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('leftWidthPercentage').hasError('min')">
 | 
			
		||||
                    {{ 'layout.value-min-error' | translate: { min: 10 } }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                </mat-form-field>
 | 
			
		||||
                <mat-form-field fxFlex class="mat-block">
 | 
			
		||||
                  <mat-label>{{ 'layout.right-width' | translate }}</mat-label>
 | 
			
		||||
@ -108,6 +116,15 @@
 | 
			
		||||
                         step="1"
 | 
			
		||||
                         min="10"
 | 
			
		||||
                         max="90">
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('required')">
 | 
			
		||||
                    {{ 'layout.right-width-percentage-required' | translate }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('max')">
 | 
			
		||||
                    {{ 'layout.value-max-error' | translate: { max: 90 } }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                  <mat-error *ngIf="layoutsFormGroup.get('rightWidthPercentage').hasError('min')">
 | 
			
		||||
                    {{ 'layout.value-min-error' | translate: { min: 10 } }}
 | 
			
		||||
                  </mat-error>
 | 
			
		||||
                </mat-form-field>
 | 
			
		||||
              </div>
 | 
			
		||||
              <label class="tb-hint">{{'layout.layout-min-max' | translate: { min: 10, max: 90, units: "%" } }}</label>
 | 
			
		||||
@ -115,8 +132,9 @@
 | 
			
		||||
          </div>
 | 
			
		||||
          <div [fxShow]="layoutsFormGroup.get('type').value === LayoutWidthType.FIXED"
 | 
			
		||||
               fxLayout="column"
 | 
			
		||||
               style="width: 100%;"
 | 
			
		||||
               fxLayoutAlign="start center">
 | 
			
		||||
            <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" class="tb-layout-fixed-container">
 | 
			
		||||
            <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" class="tb-layout-fixed-container" style="width: 100%;">
 | 
			
		||||
              <label>{{ 'layout.pick-fixed-side' | translate }}</label>
 | 
			
		||||
              <mat-radio-group aria-label="Select side"
 | 
			
		||||
                               formControlName="fixedLayout"
 | 
			
		||||
@ -139,8 +157,16 @@
 | 
			
		||||
                       type="number"
 | 
			
		||||
                       step="1"
 | 
			
		||||
                       min="150"
 | 
			
		||||
                       max="1700"
 | 
			
		||||
                       required>
 | 
			
		||||
                       max="1700">
 | 
			
		||||
                <mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('required')">
 | 
			
		||||
                  {{ 'layout.layout-fixed-width-required' | translate }}
 | 
			
		||||
                </mat-error>
 | 
			
		||||
                <mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('max')">
 | 
			
		||||
                  {{ 'layout.value-max-error' | translate: { max: 1700 } }}
 | 
			
		||||
                </mat-error>
 | 
			
		||||
                <mat-error *ngIf="layoutsFormGroup.get('fixedWidth').hasError('min')">
 | 
			
		||||
                  {{ 'layout.value-min-error' | translate: { min: 150 } }}
 | 
			
		||||
                </mat-error>
 | 
			
		||||
              </mat-form-field>
 | 
			
		||||
              <label class="tb-hint">{{ 'layout.layout-min-max' | translate: {min: 150, max: 1700, units: "px" } }}</label>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
/// limitations under the License.
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
import { ChangeDetectorRef, Component, Inject, OnInit, SkipSelf} from '@angular/core';
 | 
			
		||||
import { Component, Inject, OnInit, SkipSelf} from '@angular/core';
 | 
			
		||||
import { ErrorStateMatcher } from '@angular/material/core';
 | 
			
		||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
 | 
			
		||||
import { Store } from '@ngrx/store';
 | 
			
		||||
@ -31,7 +31,8 @@ import {
 | 
			
		||||
  DashboardSettingsDialogComponent,
 | 
			
		||||
  DashboardSettingsDialogData
 | 
			
		||||
} from '@home/components/dashboard-page/dashboard-settings-dialog.component';
 | 
			
		||||
import { LayoutType, LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
 | 
			
		||||
import { LayoutWidthType } from "@home/components/dashboard-page/layout/layout.models";
 | 
			
		||||
import { Subscription } from "rxjs";
 | 
			
		||||
 | 
			
		||||
export interface ManageDashboardLayoutsDialogData {
 | 
			
		||||
  layouts: DashboardStateLayouts;
 | 
			
		||||
@ -52,7 +53,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
 | 
			
		||||
  LayoutWidthType = LayoutWidthType;
 | 
			
		||||
 | 
			
		||||
  LayoutType = LayoutType;
 | 
			
		||||
  subscriptions: Array<Subscription>;
 | 
			
		||||
 | 
			
		||||
  submitted = false;
 | 
			
		||||
 | 
			
		||||
@ -65,19 +66,18 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
              private utils: UtilsService,
 | 
			
		||||
              private dashboardUtils: DashboardUtilsService,
 | 
			
		||||
              private translate: TranslateService,
 | 
			
		||||
              private dialog: MatDialog,
 | 
			
		||||
              private cd: ChangeDetectorRef) {
 | 
			
		||||
              private dialog: MatDialog) {
 | 
			
		||||
    super(store, router, dialogRef);
 | 
			
		||||
 | 
			
		||||
    this.layouts = this.data.layouts;
 | 
			
		||||
    this.layoutsFormGroup = this.fb.group({
 | 
			
		||||
        main:  [{value: isDefined(this.layouts.main), disabled: true}, []],
 | 
			
		||||
        right: [isDefined(this.layouts.right), []],
 | 
			
		||||
        leftWidthPercentage: [50, [Validators.min(10), Validators.max(90)]],
 | 
			
		||||
        rightWidthPercentage: [50, [Validators.min(10), Validators.max(90)]],
 | 
			
		||||
        leftWidthPercentage: [50, [Validators.min(10), Validators.max(90), Validators.required]],
 | 
			
		||||
        rightWidthPercentage: [50, [Validators.min(10), Validators.max(90), Validators.required]],
 | 
			
		||||
        type: [LayoutWidthType.PERCENTAGE, []],
 | 
			
		||||
        fixedWidth: [150, [Validators.min(150), Validators.max(1700)]],
 | 
			
		||||
        fixedLayout: [LayoutType.MAIN, []]
 | 
			
		||||
        fixedWidth: [150, [Validators.min(150), Validators.max(1700), Validators.required]],
 | 
			
		||||
        fixedLayout: ['main', []]
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -99,20 +99,29 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!this.layouts[LayoutType.MAIN]) {
 | 
			
		||||
      this.layouts[LayoutType.MAIN] = this.dashboardUtils.createDefaultLayoutData();
 | 
			
		||||
    if (!this.layouts['main']) {
 | 
			
		||||
      this.layouts['main'] = this.dashboardUtils.createDefaultLayoutData();
 | 
			
		||||
    }
 | 
			
		||||
    if (!this.layouts[LayoutType.RIGHT]) {
 | 
			
		||||
      this.layouts[LayoutType.RIGHT] = this.dashboardUtils.createDefaultLayoutData();
 | 
			
		||||
    if (!this.layouts['right']) {
 | 
			
		||||
      this.layouts['right'] = this.dashboardUtils.createDefaultLayoutData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.layoutsFormGroup.get('leftWidthPercentage').valueChanges.subscribe((value) => this.layoutControlChange('rightWidthPercentage', value));
 | 
			
		||||
    this.layoutsFormGroup.get('rightWidthPercentage').valueChanges.subscribe((value) => this.layoutControlChange('leftWidthPercentage', value));
 | 
			
		||||
    const leftWidthPercentageSub = this.layoutsFormGroup.get('leftWidthPercentage').valueChanges
 | 
			
		||||
      .subscribe((value) => this.layoutControlChange('rightWidthPercentage', value));
 | 
			
		||||
    const rightWidthPercentageSub = this.layoutsFormGroup.get('rightWidthPercentage').valueChanges
 | 
			
		||||
      .subscribe((value) => this.layoutControlChange('leftWidthPercentage', value));
 | 
			
		||||
    this.subscriptions = [leftWidthPercentageSub, rightWidthPercentageSub];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy(): void {
 | 
			
		||||
    for (let subscription of this.subscriptions) {
 | 
			
		||||
      subscription.unsubscribe();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
 | 
			
		||||
    const originalErrorState = this.errorStateMatcher.isErrorState(control, form);
 | 
			
		||||
    const customErrorState = !!(control && control.invalid && this.submitted);
 | 
			
		||||
@ -143,7 +152,8 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
 | 
			
		||||
  save(): void {
 | 
			
		||||
    this.submitted = true;
 | 
			
		||||
    for (const l of Object.keys(this.layoutsFormGroup.controls)) {
 | 
			
		||||
    const layouts = ['main', 'right'];
 | 
			
		||||
    for (const l of layouts) {
 | 
			
		||||
      const control = this.layoutsFormGroup.controls[l];
 | 
			
		||||
      if (!control.value) {
 | 
			
		||||
        if (this.layouts[l]) {
 | 
			
		||||
@ -165,7 +175,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
      } else {
 | 
			
		||||
        layoutDimension.fixedWidth = formValues.fixedWidth;
 | 
			
		||||
        layoutDimension.fixedLayout = formValues.fixedLayout;
 | 
			
		||||
        if (formValues.fixedLayout === LayoutType.MAIN) {
 | 
			
		||||
        if (formValues.fixedLayout === 'main') {
 | 
			
		||||
          this.layouts.main.gridSettings.layoutDimension = layoutDimension;
 | 
			
		||||
        } else {
 | 
			
		||||
          this.layouts.right.gridSettings.layoutDimension = layoutDimension;
 | 
			
		||||
@ -177,7 +187,7 @@ export class ManageDashboardLayoutsDialogComponent extends DialogComponent<Manag
 | 
			
		||||
 | 
			
		||||
  buttonFlexValue(): number {
 | 
			
		||||
    if (this.layoutsFormGroup.get('right').value && this.layoutsFormGroup.value.type !== LayoutWidthType.FIXED) {
 | 
			
		||||
      return this.layoutsFormGroup.get('leftWidthPercentage').value;
 | 
			
		||||
      return this.layoutsFormGroup.get('leftWidthPercentage').value - 1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -59,7 +59,9 @@
 | 
			
		||||
        "read-more": "Read more",
 | 
			
		||||
        "hide": "Hide",
 | 
			
		||||
        "done": "Done",
 | 
			
		||||
        "print": "Print"
 | 
			
		||||
        "print": "Print",
 | 
			
		||||
        "restore": "Restore",
 | 
			
		||||
        "confirm": "Confirm"
 | 
			
		||||
    },
 | 
			
		||||
    "aggregation": {
 | 
			
		||||
        "aggregation": "Aggregation",
 | 
			
		||||
@ -322,6 +324,30 @@
 | 
			
		||||
        "queue-submit-strategy": "Submit strategy",
 | 
			
		||||
        "queue-processing-strategy": "Processing strategy",
 | 
			
		||||
        "queue-configuration": "Queue configuration",
 | 
			
		||||
        "repository-settings": "Repository settings",
 | 
			
		||||
        "repository-url": "Repository URL",
 | 
			
		||||
        "repository-url-required": "Repository URL is required.",
 | 
			
		||||
        "default-branch": "Default branch name",
 | 
			
		||||
        "authentication-settings": "Authentication settings",
 | 
			
		||||
        "auth-method": "Authentication method",
 | 
			
		||||
        "auth-method-username-password": "Password / access token",
 | 
			
		||||
        "auth-method-private-key": "Private key",
 | 
			
		||||
        "password-access-token": "Password / access token",
 | 
			
		||||
        "change-password-access-token": "Change password / access token",
 | 
			
		||||
        "private-key": "Private key",
 | 
			
		||||
        "drop-private-key-file-or": "Drag and drop a private key file or",
 | 
			
		||||
        "passphrase": "Passphrase",
 | 
			
		||||
        "enter-passphrase": "Enter passphrase",
 | 
			
		||||
        "change-passphrase": "Change passphrase",
 | 
			
		||||
        "check-access": "Check access",
 | 
			
		||||
        "check-repository-access-success": "Repository access successfully verified!",
 | 
			
		||||
        "delete-repository-settings-title": "Are you sure you want to delete repository settings?",
 | 
			
		||||
        "delete-repository-settings-text": "Be careful, after the confirmation the repository settings will be removed and version control feature will be unavailable.",
 | 
			
		||||
        "auto-commit-settings": "Auto-commit settings",
 | 
			
		||||
        "auto-commit-entities": "Auto-commit entities",
 | 
			
		||||
        "no-auto-commit-entities-prompt": "No entities configured for auto-commit",
 | 
			
		||||
        "delete-auto-commit-settings-title": "Are you sure you want to delete auto-commit settings?",
 | 
			
		||||
        "delete-auto-commit-settings-text": "Be careful, after the confirmation the auto-commit settings will be removed and auto-commit will be disabled for all entities.",
 | 
			
		||||
        "2fa":  {
 | 
			
		||||
            "2fa": "Two-factor authentication",
 | 
			
		||||
            "available-providers": "Available providers",
 | 
			
		||||
@ -1819,6 +1845,9 @@
 | 
			
		||||
        "type-current-tenant": "Current Tenant",
 | 
			
		||||
        "type-current-user": "Current User",
 | 
			
		||||
        "type-current-user-owner": "Current User Owner",
 | 
			
		||||
        "type-widgets-bundle": "Widgets bundle",
 | 
			
		||||
        "type-widgets-bundles": "Widgets bundles",
 | 
			
		||||
        "list-of-widgets-bundles": "{ count, plural, 1 {One widgets bundle} other {List of # widget bundles} }",
 | 
			
		||||
        "search": "Search entities",
 | 
			
		||||
        "selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected",
 | 
			
		||||
        "entity-name": "Entity name",
 | 
			
		||||
@ -2470,7 +2499,12 @@
 | 
			
		||||
        "right-width": "Right column (%)",
 | 
			
		||||
        "pick-fixed-side": "Fixed side: ",
 | 
			
		||||
        "layout-fixed-width": "Fixed width (px)",
 | 
			
		||||
        "layout-min-max": "Minimum width: {{min}}{{units}}, maximum width: {{max}}{{units}}"
 | 
			
		||||
        "layout-min-max": "Minimum width: {{min}}{{units}}, maximum width: {{max}}{{units}}",
 | 
			
		||||
        "value-min-error": "Value must be more then {{min}}",
 | 
			
		||||
        "value-max-error": "Value must be less then {{max}}",
 | 
			
		||||
        "layout-fixed-width-required": "Fixed width is required",
 | 
			
		||||
        "right-width-percentage-required": "Right percentage is required",
 | 
			
		||||
        "left-width-percentage-required": "Left percentage is required"
 | 
			
		||||
    },
 | 
			
		||||
    "legend": {
 | 
			
		||||
        "direction": "Legend direction",
 | 
			
		||||
@ -2480,11 +2514,13 @@
 | 
			
		||||
        "show-min": "Show min value",
 | 
			
		||||
        "show-avg": "Show average value",
 | 
			
		||||
        "show-total": "Show total value",
 | 
			
		||||
        "show-latest": "Show latest value",
 | 
			
		||||
        "settings": "Legend settings",
 | 
			
		||||
        "min": "min",
 | 
			
		||||
        "max": "max",
 | 
			
		||||
        "avg": "avg",
 | 
			
		||||
        "total": "total",
 | 
			
		||||
        "latest": "latest",
 | 
			
		||||
        "comparison-time-ago": {
 | 
			
		||||
            "previousInterval": "(previous interval)",
 | 
			
		||||
            "customInterval": "(custom interval)",
 | 
			
		||||
@ -2900,11 +2936,13 @@
 | 
			
		||||
    },
 | 
			
		||||
    "queue": {
 | 
			
		||||
        "queue-name": "Queue",
 | 
			
		||||
        "no-queues-found": "No queues found.",
 | 
			
		||||
        "no-queues-matching": "No queues matching '{{queue}}' were found.",
 | 
			
		||||
        "select-name": "Select queue name",
 | 
			
		||||
        "name": "Name",
 | 
			
		||||
        "name-required": "Queue name is required!",
 | 
			
		||||
        "name-unique": "Queue name is not unique!",
 | 
			
		||||
        "name-pattern": "Queue name contains a character other than ASCII alphanumerics, '.', '_' and '-'!",
 | 
			
		||||
        "queue-required": "Queue is required!",
 | 
			
		||||
        "topic-required": "Queue topic is required!",
 | 
			
		||||
        "poll-interval-required": "Poll interval is required!",
 | 
			
		||||
@ -2936,18 +2974,25 @@
 | 
			
		||||
        "add" : "Add queue",
 | 
			
		||||
        "details": "Queue details",
 | 
			
		||||
        "topic": "Topic",
 | 
			
		||||
        "submit-strategy": "Submit Strategy",
 | 
			
		||||
        "processing-strategy": "Processing Strategy",
 | 
			
		||||
        "submit-settings": "Submit settings",
 | 
			
		||||
        "submit-strategy": "Strategy type *",
 | 
			
		||||
        "grouping-parameter": "Grouping parameter",
 | 
			
		||||
        "processing-settings": "Retries processing settings",
 | 
			
		||||
        "processing-strategy": "Processing type *",
 | 
			
		||||
        "retries-settings": "Retries settings",
 | 
			
		||||
        "polling-settings": "Polling settings",
 | 
			
		||||
        "batch-processing": "Batch processing",
 | 
			
		||||
        "poll-interval": "Poll interval",
 | 
			
		||||
        "partitions": "Partitions",
 | 
			
		||||
        "consumer-per-partition": "Consumer per partition",
 | 
			
		||||
        "immediate-processing": "Immediate processing",
 | 
			
		||||
        "consumer-per-partition": "Send message poll for each consumer",
 | 
			
		||||
        "consumer-per-partition-hint": "Enable separate consumer(s) per each partition",
 | 
			
		||||
        "processing-timeout": "Processing timeout, ms",
 | 
			
		||||
        "processing-timeout": "Processing within, ms",
 | 
			
		||||
        "batch-size": "Batch size",
 | 
			
		||||
        "retries": "Retries (0 - unlimited)",
 | 
			
		||||
        "failure-percentage": "Failure Percentage",
 | 
			
		||||
        "pause-between-retries": "Pause between retries",
 | 
			
		||||
        "max-pause-between-retries": "Maximal pause between retries",
 | 
			
		||||
        "retries": "Number of retries (0 – unlimited)",
 | 
			
		||||
        "failure-percentage": "Percentage of failure messages for skipping retries",
 | 
			
		||||
        "pause-between-retries": "Retry within, sec",
 | 
			
		||||
        "max-pause-between-retries": "Additional retry within, sec",
 | 
			
		||||
        "delete": "Delete queue",
 | 
			
		||||
        "copyId": "Copy queue Id",
 | 
			
		||||
        "idCopiedMessage": "Queue Id has been copied to clipboard",
 | 
			
		||||
@ -2979,6 +3024,19 @@
 | 
			
		||||
            "retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "server-error": {
 | 
			
		||||
        "general": "General server error",
 | 
			
		||||
        "authentication": "Authentication error",
 | 
			
		||||
        "jwt-token-expired": "JWT token expired",
 | 
			
		||||
        "tenant-trial-expired": "Tenant trial expired",
 | 
			
		||||
        "credentials-expired": "Credentials expired",
 | 
			
		||||
        "permission-denied": "Permission denied",
 | 
			
		||||
        "invalid-arguments": "Invalid arguments",
 | 
			
		||||
        "bad-request-params": "Bad request params",
 | 
			
		||||
        "item-not-found": "Item not found",
 | 
			
		||||
        "too-many-requests": "Too many requests",
 | 
			
		||||
        "too-many-updates": "Too many updates"
 | 
			
		||||
    },
 | 
			
		||||
    "tenant": {
 | 
			
		||||
        "tenant": "Tenant",
 | 
			
		||||
        "tenants": "Tenants",
 | 
			
		||||
@ -3008,9 +3066,7 @@
 | 
			
		||||
        "tenant-required": "Tenant is required",
 | 
			
		||||
        "search": "Search tenants",
 | 
			
		||||
        "selected-tenants": "{ count, plural, 1 {1 tenant} other {# tenants} } selected",
 | 
			
		||||
        "isolated-tb-core": "Processing in isolated ThingsBoard Core container",
 | 
			
		||||
        "isolated-tb-rule-engine": "Processing in isolated ThingsBoard Rule Engine container",
 | 
			
		||||
        "isolated-tb-core-details": "Requires separate microservice(s) per isolated Tenant",
 | 
			
		||||
        "isolated-tb-rule-engine-details": "Requires separate microservice(s) per isolated Tenant"
 | 
			
		||||
    },
 | 
			
		||||
    "tenant-profile": {
 | 
			
		||||
@ -3049,75 +3105,101 @@
 | 
			
		||||
        "export-failed-error": "Unable to export tenant profile: {{error}}",
 | 
			
		||||
        "tenant-profile-file": "Tenant profile file",
 | 
			
		||||
        "invalid-tenant-profile-file-error": "Unable to import tenant profile: Invalid tenant profile data structure.",
 | 
			
		||||
        "maximum-devices": "Maximum number of devices (0 - unlimited)",
 | 
			
		||||
        "maximum-devices-required": "Maximum number of devices is required.",
 | 
			
		||||
        "maximum-devices-range": "Minimum number of devices can't be negative",
 | 
			
		||||
        "maximum-assets": "Maximum number of assets (0 - unlimited)",
 | 
			
		||||
        "maximum-assets-required": "Maximum number of assets is required.",
 | 
			
		||||
        "maximum-assets-range": "Maximum number of assets can't be negative",
 | 
			
		||||
        "maximum-customers": "Maximum number of customers (0 - unlimited)",
 | 
			
		||||
        "maximum-customers-required": "Maximum number of customers is required.",
 | 
			
		||||
        "maximum-customers-range": "Maximum number of customers can't be negative",
 | 
			
		||||
        "maximum-users": "Maximum number of users (0 - unlimited)",
 | 
			
		||||
        "maximum-users-required": "Maximum number of users is required.",
 | 
			
		||||
        "maximum-users-range": "Maximum number of users can't be negative",
 | 
			
		||||
        "maximum-dashboards": "Maximum number of dashboards (0 - unlimited)",
 | 
			
		||||
        "maximum-dashboards-required": "Maximum number of dashboards is required.",
 | 
			
		||||
        "maximum-dashboards-range": "Maximum number of dashboards can't be negative",
 | 
			
		||||
        "maximum-rule-chains": "Maximum number of rule chains (0 - unlimited)",
 | 
			
		||||
        "maximum-rule-chains-required": "Maximum number of rule chains is required.",
 | 
			
		||||
        "maximum-rule-chains-range": "Maximum number of rule chains can't be negative",
 | 
			
		||||
        "maximum-resources-sum-data-size": "Maximum sum of resource files size in bytes (0 - unlimited)",
 | 
			
		||||
        "maximum-resources-sum-data-size-required": "Maximum sum of resource files size is required.",
 | 
			
		||||
        "maximum-resources-sum-data-size-range": "Maximum sum of resource files size can`t be negative",
 | 
			
		||||
        "maximum-ota-packages-sum-data-size": "Maximum sum of ota package files size in bytes (0 - unlimited)",
 | 
			
		||||
        "maximum-ota-package-sum-data-size-required": "Maximum sum of ota package files size is required.",
 | 
			
		||||
        "maximum-ota-package-sum-data-size-range": "Maximum sum of ota package files size can`t be negative",
 | 
			
		||||
        "transport-tenant-msg-rate-limit": "Transport tenant messages rate limit.",
 | 
			
		||||
        "transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages rate limit.",
 | 
			
		||||
        "transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points rate limit.",
 | 
			
		||||
        "transport-device-msg-rate-limit": "Transport device messages rate limit.",
 | 
			
		||||
        "transport-device-telemetry-msg-rate-limit": "Transport device telemetry messages rate limit.",
 | 
			
		||||
        "transport-device-telemetry-data-points-rate-limit": "Transport device telemetry data points rate limit.",
 | 
			
		||||
        "max-transport-messages": "Maximum number of transport messages (0 - unlimited)",
 | 
			
		||||
        "max-transport-messages-required": "Maximum number of transport messages is required.",
 | 
			
		||||
        "max-transport-messages-range": "Maximum number of transport messages can't be negative",
 | 
			
		||||
        "max-transport-data-points": "Maximum number of transport data points (0 - unlimited)",
 | 
			
		||||
        "max-transport-data-points-required": "Maximum number of transport data points is required.",
 | 
			
		||||
        "max-transport-data-points-range": "Maximum number of transport data points can't be negative",
 | 
			
		||||
        "max-r-e-executions": "Maximum number of Rule Engine executions (0 - unlimited)",
 | 
			
		||||
        "max-r-e-executions-required": "Maximum number of Rule Engine executions is required.",
 | 
			
		||||
        "max-r-e-executions-range": "Maximum number of Rule Engine executions can't be negative",
 | 
			
		||||
        "max-j-s-executions": "Maximum number of JavaScript executions (0 - unlimited)",
 | 
			
		||||
        "max-j-s-executions-required": "Maximum number of JavaScript executions is required.",
 | 
			
		||||
        "max-j-s-executions-range": "Maximum number of JavaScript executions can't be negative",
 | 
			
		||||
        "max-d-p-storage-days": "Maximum number of data points storage days (0 - unlimited)",
 | 
			
		||||
        "max-d-p-storage-days-required": "Maximum number of data points storage days is required.",
 | 
			
		||||
        "max-d-p-storage-days-range": "Maximum number of data points storage days can't be negative",
 | 
			
		||||
        "default-storage-ttl-days": "Default storage TTL days (0 - unlimited)",
 | 
			
		||||
        "default-storage-ttl-days-required": "Default storage TTL days is required.",
 | 
			
		||||
        "default-storage-ttl-days-range": "Default storage TTL days can't be negative",
 | 
			
		||||
        "alarms-ttl-days": "Alarms TTL days (0 - unlimited)",
 | 
			
		||||
        "advanced-settings": "Advanced settings",
 | 
			
		||||
        "entities": "Entities",
 | 
			
		||||
        "rule-engine": "Rule Engine",
 | 
			
		||||
        "time-to-live": "Time-to-live",
 | 
			
		||||
        "alarms-and-notifications": "Alarms and notifications",
 | 
			
		||||
        "ota-files-in-bytes": "OTA files in bytes",
 | 
			
		||||
        "ws-title": "WS",
 | 
			
		||||
        "unlimited": "(0 - unlimited)",
 | 
			
		||||
        "maximum-devices": "Devices maximum number",
 | 
			
		||||
        "maximum-devices-required": "Devices maximum number is required.",
 | 
			
		||||
        "maximum-devices-range": "Devices maximum number can't be negative",
 | 
			
		||||
        "maximum-assets": "Assets maximum number",
 | 
			
		||||
        "maximum-assets-required": "Assets maximum number is required.",
 | 
			
		||||
        "maximum-assets-range": "Assets maximum number can't be negative",
 | 
			
		||||
        "maximum-customers": "Customers maximum number",
 | 
			
		||||
        "maximum-customers-required": "Customers maximum number is required.",
 | 
			
		||||
        "maximum-customers-range": "Customers maximum number can't be negative",
 | 
			
		||||
        "maximum-users": "Users maximum number",
 | 
			
		||||
        "maximum-users-required": "Users maximum number is required.",
 | 
			
		||||
        "maximum-users-range": "Users maximum number can't be negative",
 | 
			
		||||
        "maximum-dashboards": "Dashboards maximum number",
 | 
			
		||||
        "maximum-dashboards-required": "Dashboards maximum number is required.",
 | 
			
		||||
        "maximum-dashboards-range": "Dashboards maximum number can't be negative",
 | 
			
		||||
        "maximum-rule-chains": "Rule chains maximum number",
 | 
			
		||||
        "maximum-rule-chains-required": "Rule chains maximum number is required.",
 | 
			
		||||
        "maximum-rule-chains-range": "Rule chains maximum number can't be negative",
 | 
			
		||||
        "maximum-resources-sum-data-size": "Resource files sum size",
 | 
			
		||||
        "maximum-resources-sum-data-size-required": "Resource files sum size is required.",
 | 
			
		||||
        "maximum-resources-sum-data-size-range": "Resource files sum size can`t be negative",
 | 
			
		||||
        "maximum-ota-packages-sum-data-size": "OTA package files sum size",
 | 
			
		||||
        "maximum-ota-package-sum-data-size-required": "OTA package files sum size is required.",
 | 
			
		||||
        "maximum-ota-package-sum-data-size-range": "OTA package files sum size can`t be negative",
 | 
			
		||||
        "transport-tenant-msg-rate-limit": "Transport tenant messages",
 | 
			
		||||
        "transport-tenant-telemetry-msg-rate-limit": "Transport tenant telemetry messages",
 | 
			
		||||
        "transport-tenant-telemetry-data-points-rate-limit": "Transport tenant telemetry data points",
 | 
			
		||||
        "transport-device-msg-rate-limit": "Transport device messages",
 | 
			
		||||
        "transport-device-telemetry-msg-rate-limit": "Transport device telemetry messages",
 | 
			
		||||
        "transport-device-telemetry-data-points-rate-limit": "Transport device telemetry data points",
 | 
			
		||||
        "tenant-entity-export-rate-limit": "Entity version creation",
 | 
			
		||||
        "tenant-entity-import-rate-limit": "Entity version load",
 | 
			
		||||
        "max-transport-messages": "Transport messages maximum number",
 | 
			
		||||
        "max-transport-messages-required": "Transport messages maximum number is required.",
 | 
			
		||||
        "max-transport-messages-range": "Transport messages maximum number can't be negative",
 | 
			
		||||
        "max-transport-data-points": "Transport data points maximum number ",
 | 
			
		||||
        "max-transport-data-points-required": "Transport data points maximum number  is required.",
 | 
			
		||||
        "max-transport-data-points-range": "Transport data points maximum number  can't be negative",
 | 
			
		||||
        "max-r-e-executions": "Rule Engine executions maximum number",
 | 
			
		||||
        "max-r-e-executions-required": "Rule Engine executions maximum number is required.",
 | 
			
		||||
        "max-r-e-executions-range": "Rule Engine executions maximum number can't be negative",
 | 
			
		||||
        "max-j-s-executions": "JavaScript executions maximum number ",
 | 
			
		||||
        "max-j-s-executions-required": "JavaScript executions maximum number  is required.",
 | 
			
		||||
        "max-j-s-executions-range": "JavaScript executions maximum number  can't be negative",
 | 
			
		||||
        "max-d-p-storage-days": "Data points storage days maximum number",
 | 
			
		||||
        "max-d-p-storage-days-required": "Data points storage days maximum number is required.",
 | 
			
		||||
        "max-d-p-storage-days-range": "Data points storage days maximum number can't be negative",
 | 
			
		||||
        "default-storage-ttl-days": "Storage TTL days by default",
 | 
			
		||||
        "default-storage-ttl-days-required": "Storage TTL days by default is required.",
 | 
			
		||||
        "default-storage-ttl-days-range": "Storage TTL days by default can't be negative",
 | 
			
		||||
        "alarms-ttl-days": "Alarms TTL days",
 | 
			
		||||
        "alarms-ttl-days-required": "Alarms TTL days required",
 | 
			
		||||
        "alarms-ttl-days-days-range": "Alarms TTL days can't be negative",
 | 
			
		||||
        "rpc-ttl-days": "RPC TTL days (0 - unlimited)",
 | 
			
		||||
        "rpc-ttl-days": "RPC TTL days",
 | 
			
		||||
        "rpc-ttl-days-required": "RPC TTL days required",
 | 
			
		||||
        "rpc-ttl-days-days-range": "RPC TTL days can't be negative",
 | 
			
		||||
        "max-rule-node-executions-per-message": "Maximum number of rule node executions per message (0 - unlimited)",
 | 
			
		||||
        "max-rule-node-executions-per-message-required": "Maximum number of rule node executions per message is required.",
 | 
			
		||||
        "max-rule-node-executions-per-message-range": "Maximum number of rule node executions per message can't be negative",
 | 
			
		||||
        "max-emails": "Maximum number of emails sent (0 - unlimited)",
 | 
			
		||||
        "max-emails-required": "Maximum number of emails sent is required.",
 | 
			
		||||
        "max-emails-range": "Maximum number of emails sent can't be negative",
 | 
			
		||||
        "max-sms": "Maximum number of SMS sent (0 - unlimited)",
 | 
			
		||||
        "max-sms-required": "Maximum number of SMS sent is required.",
 | 
			
		||||
        "max-sms-range": "Maximum number of SMS sent can't be negative",
 | 
			
		||||
        "max-created-alarms": "Maximum number of alarms created (0 - unlimited)",
 | 
			
		||||
        "max-created-alarms-required": "Maximum number of alarms created is required.",
 | 
			
		||||
        "max-created-alarms-range": "Maximum number of alarms created can't be negative",
 | 
			
		||||
        "max-rule-node-executions-per-message": "Rule node per message executions maximum number",
 | 
			
		||||
        "max-rule-node-executions-per-message-required": "MRule node per message executions maximum number is required.",
 | 
			
		||||
        "max-rule-node-executions-per-message-range": "Rule node per message executions maximum number can't be negative",
 | 
			
		||||
        "max-emails": "Emails sent maximum number",
 | 
			
		||||
        "max-emails-required": "Emails sent maximum number is required.",
 | 
			
		||||
        "max-emails-range": "Emails sent maximum number can't be negative",
 | 
			
		||||
        "max-sms": "SMS sent maximum number",
 | 
			
		||||
        "max-sms-required": "SMS sent maximum number is required.",
 | 
			
		||||
        "max-sms-range": "SMS sent maximum number can't be negative",
 | 
			
		||||
        "max-created-alarms": "Alarms created maximum number",
 | 
			
		||||
        "max-created-alarms-required": "Alarms created maximum number is required.",
 | 
			
		||||
        "max-created-alarms-range": "Alarms created maximum number be negative",
 | 
			
		||||
        "no-queue": "No Queue configured",
 | 
			
		||||
        "add-queue": "Add Queue",
 | 
			
		||||
        "queues-with-count": "Queues ({{count}})"
 | 
			
		||||
        "queues-with-count": "Queues ({{count}})",
 | 
			
		||||
        "tenant-rest-limits": "REST requests for tenant",
 | 
			
		||||
        "customer-rest-limits": "REST requests for customer",
 | 
			
		||||
        "incorrect-pattern-for-rate-limits": "The format is comma separated pairs of capacity and period (in seconds) with a colon between, e.g. 100:1,2000:60",
 | 
			
		||||
        "too-small-value-zero": "The value must be bigger than 0",
 | 
			
		||||
        "too-small-value-one": "The value must be bigger than 1",
 | 
			
		||||
        "cassandra-tenant-limits-configuration": "Cassandra query for tenant",
 | 
			
		||||
        "ws-limit-max-sessions-per-tenant": "Sessions per tenant maximum number",
 | 
			
		||||
        "ws-limit-max-sessions-per-customer": "Sessions per customer maximum number",
 | 
			
		||||
        "ws-limit-max-sessions-per-regular-user": "Sessions per regular user maximum number",
 | 
			
		||||
        "ws-limit-max-sessions-per-public-user": "Sessions per public user maximum number",
 | 
			
		||||
        "ws-limit-queue-per-session": "Message queue per session maximum size",
 | 
			
		||||
        "ws-limit-max-subscriptions-per-tenant": "Subscriptions per tenant maximum number",
 | 
			
		||||
        "ws-limit-max-subscriptions-per-customer": "Subscriptions per customer maximum number",
 | 
			
		||||
        "ws-limit-max-subscriptions-per-regular-user": "Subscriptions per regular user maximum number",
 | 
			
		||||
        "ws-limit-max-subscriptions-per-public-user": "Subscriptions per public user maximum number",
 | 
			
		||||
        "ws-limit-updates-per-session": "WS updates per session"
 | 
			
		||||
    },
 | 
			
		||||
    "timeinterval": {
 | 
			
		||||
        "seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }",
 | 
			
		||||
@ -3246,6 +3328,73 @@
 | 
			
		||||
        "json-value-invalid": "JSON value has an invalid format",
 | 
			
		||||
        "json-value-required": "JSON value is required."
 | 
			
		||||
    },
 | 
			
		||||
    "version-control": {
 | 
			
		||||
        "version-control": "Version control",
 | 
			
		||||
        "management": "Version control management",
 | 
			
		||||
        "search": "Search versions",
 | 
			
		||||
        "branch": "Branch",
 | 
			
		||||
        "default": "Default",
 | 
			
		||||
        "select-branch": "Select branch",
 | 
			
		||||
        "branch-required": "Branch is required",
 | 
			
		||||
        "create-entity-version": "Create entity version",
 | 
			
		||||
        "version-name": "Version name",
 | 
			
		||||
        "version-name-required": "Version name is required",
 | 
			
		||||
        "author": "Author",
 | 
			
		||||
        "export-relations": "Export relations",
 | 
			
		||||
        "export-attributes": "Export attributes",
 | 
			
		||||
        "export-credentials": "Export credentials",
 | 
			
		||||
        "entity-versions": "Entity versions",
 | 
			
		||||
        "versions": "Versions",
 | 
			
		||||
        "created-time": "Created time",
 | 
			
		||||
        "version-id": "Version ID",
 | 
			
		||||
        "no-entity-versions-text": "No entity versions found",
 | 
			
		||||
        "no-versions-text": "No versions found",
 | 
			
		||||
        "copy-full-version-id": "Copy full version id",
 | 
			
		||||
        "create-version": "Create version",
 | 
			
		||||
        "creating-version": "Creating version... Please wait",
 | 
			
		||||
        "nothing-to-commit": "No changes to commit",
 | 
			
		||||
        "restore-version": "Restore version",
 | 
			
		||||
        "restore-entity-from-version": "Restore entity from version '{{versionName}}'",
 | 
			
		||||
        "restoring-entity-version": "Restoring entity version... Please wait",
 | 
			
		||||
        "load-relations": "Load relations",
 | 
			
		||||
        "load-attributes": "Load attributes",
 | 
			
		||||
        "load-credentials": "Load credentials",
 | 
			
		||||
        "compare-with-current": "Compare with current",
 | 
			
		||||
        "diff-entity-with-version": "Diff with entity version '{{versionName}}'",
 | 
			
		||||
        "previous-difference": "Previous Difference",
 | 
			
		||||
        "next-difference": "Next Difference",
 | 
			
		||||
        "current": "Current",
 | 
			
		||||
        "differences": "{ count, plural, 1 {1 difference} other {# differences} }",
 | 
			
		||||
        "create-entities-version": "Create entities version",
 | 
			
		||||
        "default-sync-strategy": "Default sync strategy",
 | 
			
		||||
        "sync-strategy-merge": "Merge",
 | 
			
		||||
        "sync-strategy-overwrite": "Overwrite",
 | 
			
		||||
        "entities-to-export": "Entities to export",
 | 
			
		||||
        "entities-to-restore": "Entities to restore",
 | 
			
		||||
        "sync-strategy": "Sync strategy",
 | 
			
		||||
        "all-entities": "All entities",
 | 
			
		||||
        "no-entities-to-export-prompt": "Please specify entities to export",
 | 
			
		||||
        "no-entities-to-restore-prompt": "Please specify entities to restore",
 | 
			
		||||
        "add-entity-type": "Add entity type",
 | 
			
		||||
        "remove-all": "Remove all",
 | 
			
		||||
        "version-create-result": "{ added, plural, 0 {No entities} 1 {1 entity} other {# entities} } added.<br/>{ modified, plural, 0 {No entities} 1 {1 entity} other {# entities} } modified.<br/>{ removed, plural, 0 {No entities} 1 {1 entity} other {# entities} } removed.",
 | 
			
		||||
        "remove-other-entities": "Remove other entities",
 | 
			
		||||
        "find-existing-entity-by-name": "Find existing entity by name",
 | 
			
		||||
        "restore-entities-from-version": "Restore entities from version '{{versionName}}'",
 | 
			
		||||
        "restoring-entities-from-version": "Restoring entities... Please wait",
 | 
			
		||||
        "no-entities-restored": "No entities restored",
 | 
			
		||||
        "created": "{{created}} created",
 | 
			
		||||
        "updated": "{{updated}} updated",
 | 
			
		||||
        "deleted": "{{deleted}} deleted",
 | 
			
		||||
        "remove-other-entities-confirm-text": "Be careful! This will permanently <b>delete</b> <b>all</b> current entities<br/>not present in the version you want to restore.<br/><br/>Please type <b>remove other entities</b> to confirm.",
 | 
			
		||||
        "auto-commit-to-branch": "auto-commit to <b>{{ branch }}</b> branch",
 | 
			
		||||
        "default-create-entity-version-name": "{{entityName}} update",
 | 
			
		||||
        "sync-strategy-merge-hint": "Creates or updates selected entities in the repository. All other repository entities are <b>not modified</b>.",
 | 
			
		||||
        "sync-strategy-overwrite-hint": "Creates or updates selected entities in the repository. All other repository entities are <b>deleted</b>.",
 | 
			
		||||
        "device-credentials-conflict": "Failed to load the device with external id <b>{{entityId}}</b><br/>due to the same credentials are already present in the database for another device.<br/>Please consider disabling the <b>load credentials</b> setting in the restore form.",
 | 
			
		||||
        "missing-referenced-entity": "Failed to load the <b>{{sourceEntityTypeName}}</b> with external id <b>{{sourceEntityId}}</b><br/>because it references missing <b>{{targetEntityTypeName}}</b> with id <b>{{targetEntityId}}</b>.",
 | 
			
		||||
        "runtime-failed": "<b>Failed:</b> {{message}}"
 | 
			
		||||
    },
 | 
			
		||||
    "widget": {
 | 
			
		||||
        "widget-library": "Widgets Library",
 | 
			
		||||
        "widget-bundle": "Widgets Bundle",
 | 
			
		||||
@ -4235,6 +4384,7 @@
 | 
			
		||||
            "default-map-zoom-level": "Default map zoom level (0 - 20)",
 | 
			
		||||
            "default-map-center-position": "Default map center position (0,0)",
 | 
			
		||||
            "disable-scroll-zooming": "Disable scroll zooming",
 | 
			
		||||
            "disable-double-click-zooming": "Disable double click zooming",
 | 
			
		||||
            "disable-zoom-control-buttons": "Disable zoom control buttons",
 | 
			
		||||
            "fit-map-bounds": "Fit map bounds to cover all markers",
 | 
			
		||||
            "use-default-map-center-position": "Use default map center position",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user