UI: Improvement VC in mobile mode, fixed catch error message and add validation space in commit message

This commit is contained in:
Vladyslav_Prykhodko 2022-06-27 14:29:57 +03:00
parent a83f99cfd9
commit ced8ff5bd6
20 changed files with 253 additions and 248 deletions

View File

@ -38,11 +38,10 @@ import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.m
import { select, Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { selectIsUserLoaded } from '@core/auth/auth.selectors';
import { catchError, finalize, map, switchMap, takeWhile, tap } from 'rxjs/operators';
import { catchError, finalize, switchMap, takeWhile, tap } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { ActionLoadFinish, ActionLoadStart } from '@core/interceptors/load.actions';
import { NULL_UUID } from '@shared/models/id/has-uuid';
@Injectable({
providedIn: 'root'
@ -184,6 +183,9 @@ export class EntitiesVersionControlService {
(this.translate.instant(entityTypeTranslations.get(entityLoadError.target.entityType).type) as string).toLowerCase();
messageArgs.targetEntityId = entityLoadError.target.id;
break;
case EntityLoadErrorType.RUNTIME:
messageArgs.message = entityLoadError.message.toLowerCase();
break;
}
return this.sanitizer.bypassSecurityTrustHtml(this.translate.instant(messageId, messageArgs));
}

View File

@ -32,64 +32,63 @@
<fieldset class="fields-group" [disabled]="isLoading$ | async">
<legend class="group-title" translate>admin.auto-commit-entities</legend>
<div fxLayout="column">
<div class="tb-control-list">
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div [innerHTML]="entityTypeText(entityTypeFormGroup)"></div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="column" fxLayout.gt-lg="row" fxLayoutGap.gt-lg="16px">
<div fxLayout="row" fxLayoutGap="16px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div formGroupName="config">
<tb-branch-autocomplete
emptyPlaceholder="{{ 'version-control.default' | translate }}"
[selectDefaultBranch]="false"
formControlName="branch">
</tb-branch-autocomplete>
</div>
</div>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px" formGroupName="config">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="saveCredentials">
{{ 'version-control.export-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveAttributes">
{{ 'version-control.export-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveRelations">
{{ 'version-control.export-relations' | translate }}
</mat-checkbox>
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div [innerHTML]="entityTypeText(entityTypeFormGroup)"></div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="column" fxLayout.gt-lg="row" fxLayoutGap.gt-lg="16px">
<div fxLayout="row" fxLayoutGap="16px" fxLayout.xs="column" fxLayoutGap.xs="0px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div formGroupName="config">
<tb-branch-autocomplete
emptyPlaceholder="{{ 'version-control.default' | translate }}"
[selectDefaultBranch]="false"
formControlName="branch">
</tb-branch-autocomplete>
</div>
</div>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px"
fxLayout.xs="column" fxLayoutAlign.xs="start start" fxLayoutGap.xs="0px" formGroupName="config">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="saveCredentials">
{{ 'version-control.export-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveAttributes">
{{ 'version-control.export-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveRelations">
{{ 'version-control.export-relations' | translate }}
</mat-checkbox>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
<div *ngIf="!entityTypesFormGroupArray().length">
<span translate fxLayoutAlign="center center"

View File

@ -37,11 +37,6 @@
}
}
.tb-control-list {
overflow-y: auto;
max-height: 600px;
}
.tb-prompt {
margin: 30px 0;
}

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<section style="min-width: 800px;">
<section style="min-width: 600px;">
<section *ngIf="!versionCreateResult$">
<mat-toolbar>
<h2>{{ 'version-control.create-entities-version' | translate }}</h2>
@ -35,7 +35,8 @@
<mat-form-field class="mat-block" fxFlex>
<mat-label translate>version-control.version-name</mat-label>
<input required matInput formControlName="versionName">
<mat-error *ngIf="createVersionFormGroup.get('versionName').hasError('required')">
<mat-error *ngIf="createVersionFormGroup.get('versionName').hasError('required') ||
createVersionFormGroup.get('versionName').hasError('pattern')">
{{ 'version-control.version-name-required' | translate }}
</mat-error>
</mat-form-field>

View File

@ -20,7 +20,9 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import {
ComplexVersionCreateRequest,
createDefaultEntityTypesVersionCreate,
SyncStrategy, syncStrategyHintMap, syncStrategyTranslationMap,
SyncStrategy,
syncStrategyHintMap,
syncStrategyTranslationMap,
VersionCreateRequestType,
VersionCreationResult
} from '@shared/models/vc.models';
@ -82,7 +84,7 @@ export class ComplexVersionCreateComponent extends PageComponent implements OnIn
ngOnInit(): void {
this.createVersionFormGroup = this.fb.group({
branch: [this.branch, [Validators.required]],
versionName: [null, [Validators.required]],
versionName: [null, [Validators.required, Validators.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],
syncStrategy: [SyncStrategy.MERGE, Validators.required],
entityTypes: [createDefaultEntityTypesVersionCreate(), []],
});

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<section [ngStyle]="versionLoadResult$ ? {minWidth: '500px'} : {minWidth: '800px'}">
<section [ngStyle]="versionLoadResult$ ? {minWidth: '500px'} : {minWidth: '600px'}">
<section *ngIf="!versionLoadResult$">
<mat-toolbar>
<h2>{{ 'version-control.restore-entities-from-version' | translate: {versionName} }}</h2>

View File

@ -19,81 +19,79 @@
<fieldset class="fields-group">
<legend class="group-title" translate>version-control.entities-to-export</legend>
<div fxLayout="column">
<div class="tb-control-list">
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div>{{ entityTypeText(entityTypeFormGroup) }}</div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="row" fxLayoutGap="16px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div fxFlex fxLayout="row" fxLayoutGap="16px" formGroupName="config">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>version-control.sync-strategy</mat-label>
<mat-select formControlName="syncStrategy">
<mat-option [value]="'default'">
{{ 'version-control.default' | translate }}
</mat-option>
<mat-option *ngFor="let strategy of syncStrategies" [value]="strategy">
{{syncStrategyTranslations.get(strategy) | translate}}
</mat-option>
</mat-select>
</mat-form-field>
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="saveCredentials">
{{ 'version-control.export-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveAttributes">
{{ 'version-control.export-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveRelations">
{{ 'version-control.export-relations' | translate }}
</mat-checkbox>
</div>
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div>{{ entityTypeText(entityTypeFormGroup) }}</div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="row" fxLayoutGap="16px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div fxFlex fxLayout="row" fxLayoutGap="16px" formGroupName="config">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>version-control.sync-strategy</mat-label>
<mat-select formControlName="syncStrategy">
<mat-option [value]="'default'">
{{ 'version-control.default' | translate }}
</mat-option>
<mat-option *ngFor="let strategy of syncStrategies" [value]="strategy">
{{syncStrategyTranslations.get(strategy) | translate}}
</mat-option>
</mat-select>
</mat-form-field>
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="saveCredentials">
{{ 'version-control.export-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveAttributes">
{{ 'version-control.export-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="saveRelations">
{{ 'version-control.export-relations' | translate }}
</mat-checkbox>
</div>
</div>
<div fxLayout="row" fxLayoutGap="16px" fxLayoutAlign="start center"
formGroupName="config" style="min-height: 76px;">
<mat-slide-toggle formControlName="allEntities">
{{ 'version-control.all-entities' | translate }}
</mat-slide-toggle>
<tb-entity-list
fxFlex
[fxShow]="!entityTypeFormGroup.get('config').get('allEntities').value"
[entityType]="entityTypeFormGroup.get('entityType').value"
required
formControlName="entityIds">
</tb-entity-list>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
<div fxLayout="row" fxLayoutGap="16px" fxLayoutAlign="start center"
formGroupName="config" style="min-height: 76px;">
<mat-slide-toggle formControlName="allEntities">
{{ 'version-control.all-entities' | translate }}
</mat-slide-toggle>
<tb-entity-list
fxFlex
[fxShow]="!entityTypeFormGroup.get('config').get('allEntities').value"
[entityType]="entityTypeFormGroup.get('entityType').value"
required
formControlName="entityIds">
</tb-entity-list>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
<div *ngIf="!entityTypesFormGroupArray().length">
<span translate fxLayoutAlign="center center"

View File

@ -32,11 +32,6 @@
}
}
.tb-control-list {
overflow-y: auto;
max-height: 600px;
}
.tb-prompt {
margin: 30px 0;
}

View File

@ -19,67 +19,65 @@
<fieldset class="fields-group">
<legend class="group-title" translate>version-control.entities-to-restore</legend>
<div fxLayout="column">
<div class="tb-control-list">
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div>{{ entityTypeText(entityTypeFormGroup) }}</div>
<div *ngFor="let entityTypeFormGroup of entityTypesFormGroupArray(); trackBy: trackByEntityType;
let $index = index; last as isLast;"
fxLayout="row" fxLayoutAlign="start center" [ngStyle]="!isLast ? {paddingBottom: '8px'} : {}">
<mat-expansion-panel class="entity-type-config" fxFlex [formGroup]="entityTypeFormGroup" [expanded]="entityTypesFormGroupExpanded(entityTypeFormGroup)">
<mat-expansion-panel-header>
<div fxFlex fxLayout="row" fxLayoutAlign="start center">
<mat-panel-title>
<div fxLayout="row" fxFlex fxLayoutAlign="start center">
<div>{{ entityTypeText(entityTypeFormGroup) }}</div>
</div>
</mat-panel-title>
<span fxFlex></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="row" fxLayoutGap="32px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div fxFlex fxLayout="row" fxLayoutGap="16px" formGroupName="config">
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox #removeOtherEntitiesCheckbox
formControlName="removeOtherEntities"
(click)="onRemoveOtherEntities(removeOtherEntitiesCheckbox, entityTypeFormGroup, $event)">
{{ 'version-control.remove-other-entities' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="findExistingEntityByName">
{{ 'version-control.find-existing-entity-by-name' | translate }}
</mat-checkbox>
</div>
</mat-panel-title>
<span fxFlex></span>
<button *ngIf="!disabled" mat-icon-button style="min-width: 40px;"
type="button"
(click)="removeEntityType($index)"
matTooltip="{{ 'action.remove' | translate }}"
matTooltipPosition="above">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="entity-type-config-content" fxLayout="column" fxLayoutGap="0.5em">
<mat-divider></mat-divider>
<div fxLayout="row" fxLayoutGap="32px">
<tb-entity-type-select
showLabel
formControlName="entityType"
required
[filterAllowedEntityTypes]="false"
[allowedEntityTypes]="allowedEntityTypes(entityTypeFormGroup)">
</tb-entity-type-select>
<div fxFlex fxLayout="row" fxLayoutGap="16px" formGroupName="config">
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox #removeOtherEntitiesCheckbox
formControlName="removeOtherEntities"
(click)="onRemoveOtherEntities(removeOtherEntitiesCheckbox, entityTypeFormGroup, $event)">
{{ 'version-control.remove-other-entities' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="findExistingEntityByName">
{{ 'version-control.find-existing-entity-by-name' | translate }}
</mat-checkbox>
</div>
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="loadCredentials">
{{ 'version-control.load-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="loadAttributes">
{{ 'version-control.load-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="loadRelations">
{{ 'version-control.load-relations' | translate }}
</mat-checkbox>
</div>
<div fxFlex fxLayout="column" fxLayoutGap="8px">
<mat-checkbox *ngIf="entityTypeFormGroup.get('entityType').value === entityTypes.DEVICE" formControlName="loadCredentials">
{{ 'version-control.load-credentials' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="loadAttributes">
{{ 'version-control.load-attributes' | translate }}
</mat-checkbox>
<mat-checkbox formControlName="loadRelations">
{{ 'version-control.load-relations' | translate }}
</mat-checkbox>
</div>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
</div>
</ng-template>
</mat-expansion-panel>
</div>
<div *ngIf="!entityTypesFormGroupArray().length">
<span translate fxLayoutAlign="center center"

View File

@ -32,11 +32,6 @@
}
}
.tb-control-list {
overflow-y: auto;
max-height: 600px;
}
.tb-prompt {
margin: 30px 0;
}

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<section style="min-width: 400px;">
<section style="min-width: 300px;">
<section *ngIf="!versionCreateResult$">
<mat-toolbar>
<h2>{{ 'version-control.create-entity-version' | translate }}</h2>
@ -34,7 +34,8 @@
<mat-form-field class="mat-block" fxFlex>
<mat-label translate>version-control.version-name</mat-label>
<input required matInput formControlName="versionName">
<mat-error *ngIf="createVersionFormGroup.get('versionName').hasError('required')">
<mat-error *ngIf="createVersionFormGroup.get('versionName').hasError('required') ||
createVersionFormGroup.get('versionName').hasError('pattern')">
{{ 'version-control.version-name-required' | translate }}
</mat-error>
</mat-form-field>

View File

@ -80,7 +80,7 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni
this.createVersionFormGroup = this.fb.group({
branch: [this.branch, [Validators.required]],
versionName: [this.translate.instant('version-control.default-create-entity-version-name',
{entityName: this.entityName}), [Validators.required]],
{entityName: this.entityName}), [Validators.required, Validators.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],
saveRelations: [false, []],
saveAttributes: [true, []],
saveCredentials: [true, []]

View File

@ -19,6 +19,7 @@
.entity-version-diff-view {
position: relative;
&:not(.tb-fullscreen) {
max-height: 95vh;
&.content-ready {
width: 600px;
@media #{$mat-gt-sm} {

View File

@ -161,7 +161,7 @@ export class EntityVersionDiffComponent extends PageComponent implements OnInit,
setTimeout(() => {
this.diffCount = this.differ.getNumDiffs();
this.updateHasNextAndPrevious();
});
}, 1);
});
});
});

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<section [ngStyle]="entityDataInfo ? {minWidth: '400px'} : {}">
<section [ngStyle]="entityDataInfo ? {minWidth: '300px'} : {}">
<section *ngIf="!versionLoadResult$">
<mat-toolbar *ngIf="entityDataInfo">
<h2>{{ 'version-control.restore-entity-from-version' | translate: {versionName} }}</h2>

View File

@ -31,32 +31,36 @@
</tb-branch-autocomplete>
</div>
<span fxFlex></span>
<button *ngIf="singleEntityMode" mat-stroked-button color="primary"
#createVersionButton
[disabled]="(isLoading$ | async)"
(click)="toggleCreateVersion($event, createVersionButton)">
<mat-icon>update</mat-icon>
{{'version-control.create-version' | translate }}
</button>
<button *ngIf="!singleEntityMode" mat-stroked-button color="primary"
#complexCreateVersionButton
[disabled]="(isLoading$ | async)"
(click)="toggleComplexCreateVersion($event, complexCreateVersionButton)">
<mat-icon>update</mat-icon>
{{'version-control.create-entities-version' | translate }}
</button>
<button mat-icon-button [disabled]="isLoading$ | async" (click)="updateData()"
matTooltip="{{ 'action.refresh' | translate }}"
matTooltipPosition="above">
<mat-icon>refresh</mat-icon>
</button>
<button mat-icon-button
[disabled]="isLoading$ | async"
(click)="enterFilterMode()"
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
<mat-icon>search</mat-icon>
</button>
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center end">
<button *ngIf="singleEntityMode" mat-stroked-button color="primary"
#createVersionButton
[disabled]="(isLoading$ | async)"
(click)="toggleCreateVersion($event, createVersionButton)">
<mat-icon>update</mat-icon>
{{'version-control.create-version' | translate }}
</button>
<button *ngIf="!singleEntityMode" mat-stroked-button color="primary"
#complexCreateVersionButton
[disabled]="(isLoading$ | async)"
(click)="toggleComplexCreateVersion($event, complexCreateVersionButton)">
<mat-icon>update</mat-icon>
{{'version-control.create-entities-version' | translate }}
</button>
<div fxLayout="row">
<button mat-icon-button [disabled]="isLoading$ | async" (click)="updateData()"
matTooltip="{{ 'action.refresh' | translate }}"
matTooltipPosition="above">
<mat-icon>refresh</mat-icon>
</button>
<button mat-icon-button
[disabled]="isLoading$ | async"
(click)="enterFilterMode()"
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
<mat-icon>search</mat-icon>
</button>
</div>
</div>
</div>
</mat-toolbar>
<mat-toolbar class="mat-table-toolbar" [fxShow]="textSearchMode">
@ -70,7 +74,7 @@
<mat-label>&nbsp;</mat-label>
<input #searchInput matInput
[(ngModel)]="pageLink.textSearch"
placeholder="{{ 'common.enter-search' | translate }}"/>
placeholder="{{ 'version-control.search' | translate }}"/>
</mat-form-field>
<button mat-icon-button (click)="exitFilterMode()"
matTooltip="{{ 'action.close' | translate }}"

View File

@ -18,11 +18,15 @@ import {
AfterViewInit,
ChangeDetectorRef,
Component,
ElementRef, EventEmitter,
ElementRef,
EventEmitter,
Input,
OnDestroy,
OnInit, Output, Renderer2,
ViewChild, ViewContainerRef
OnInit,
Output,
Renderer2,
ViewChild,
ViewContainerRef
} from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
@ -213,7 +217,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
}
}
}
}, {}, {}, {}, false);
}, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false);
createVersionPopover.tbComponentRef.instance.popoverComponent = createVersionPopover;
}
}
@ -240,7 +244,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
}
}
}
}, {}, {}, {}, false);
}, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false);
complexCreateVersionPopover.tbComponentRef.instance.popoverComponent = complexCreateVersionPopover;
}
}
@ -290,7 +294,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
this.versionRestored.emit();
}
}
}, {}, {}, {}, false);
}, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false);
restoreVersionPopover.tbComponentRef.instance.popoverComponent = restoreVersionPopover;
}
}
@ -312,7 +316,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
onClose: (result: VersionLoadResult | null) => {
restoreEntitiesVersionPopover.hide();
}
}, {}, {}, {}, false);
}, {maxHeight: '100vh', height: '100%', padding: '10px'}, {}, {}, false);
restoreEntitiesVersionPopover.tbComponentRef.instance.popoverComponent = restoreEntitiesVersionPopover;
}
}

View File

@ -34,3 +34,8 @@
}
}
}
:host ::ng-deep {
.mat-checkbox-layout {
white-space: normal !important;
}
}

View File

@ -178,13 +178,15 @@ export interface EntityTypeLoadResult {
export enum EntityLoadErrorType {
DEVICE_CREDENTIALS_CONFLICT = 'DEVICE_CREDENTIALS_CONFLICT',
MISSING_REFERENCED_ENTITY = 'MISSING_REFERENCED_ENTITY'
MISSING_REFERENCED_ENTITY = 'MISSING_REFERENCED_ENTITY',
RUNTIME = 'RUNTIME'
}
export const entityLoadErrorTranslationMap = new Map<EntityLoadErrorType, string>(
[
[EntityLoadErrorType.DEVICE_CREDENTIALS_CONFLICT, 'version-control.device-credentials-conflict'],
[EntityLoadErrorType.MISSING_REFERENCED_ENTITY, 'version-control.missing-referenced-entity']
[EntityLoadErrorType.MISSING_REFERENCED_ENTITY, 'version-control.missing-referenced-entity'],
[EntityLoadErrorType.RUNTIME, 'version-control.runtime-failed']
]
);
@ -192,6 +194,7 @@ export interface EntityLoadError {
type: EntityLoadErrorType;
source: EntityId;
target: EntityId;
message?: string;
}
export interface VersionLoadResult {

View File

@ -3318,6 +3318,7 @@
"version-control": {
"version-control": "Version control",
"management": "Version control management",
"search": "Search versions",
"branch": "Branch",
"default": "Default",
"select-branch": "Select branch",
@ -3378,7 +3379,8 @@
"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>."
"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",