UI: Entities version create/restore progress and error handling
This commit is contained in:
parent
6ea1ac0c8e
commit
9a893dd330
@ -53,12 +53,14 @@ import { forkJoin, Observable, of, ReplaySubject, Subject, throwError, timer } f
|
|||||||
import { CancelAnimationFrame } from '@core/services/raf.service';
|
import { CancelAnimationFrame } from '@core/services/raf.service';
|
||||||
import { EntityType } from '@shared/models/entity-type.models';
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
import {
|
import {
|
||||||
createLabelFromDatasource, createLabelFromPattern,
|
createLabelFromPattern,
|
||||||
deepClone, flatFormattedData,
|
deepClone,
|
||||||
|
flatFormattedData,
|
||||||
formattedDataFormDatasourceData,
|
formattedDataFormDatasourceData,
|
||||||
isDefined,
|
isDefined,
|
||||||
isDefinedAndNotNull,
|
isDefinedAndNotNull,
|
||||||
isEqual
|
isEqual,
|
||||||
|
parseHttpErrorMessage
|
||||||
} from '@core/utils';
|
} from '@core/utils';
|
||||||
import { EntityId } from '@app/shared/models/id/entity-id';
|
import { EntityId } from '@app/shared/models/id/entity-id';
|
||||||
import * as moment_ from 'moment';
|
import * as moment_ from 'moment';
|
||||||
@ -801,10 +803,10 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
this.rpcErrorText = 'Request Timeout.';
|
this.rpcErrorText = 'Request Timeout.';
|
||||||
} else {
|
} else {
|
||||||
this.rpcErrorText = 'Error : ' + rejection.status + ' - ' + rejection.statusText;
|
this.rpcErrorText = 'Error : ' + rejection.status + ' - ' + rejection.statusText;
|
||||||
const error = this.extractRejectionErrorText(rejection);
|
const error = parseHttpErrorMessage(rejection, this.ctx.translate);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.rpcErrorText += '</br>';
|
this.rpcErrorText += '</br>';
|
||||||
this.rpcErrorText += error;
|
this.rpcErrorText += error.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.callbacks.onRpcFailed(this);
|
this.callbacks.onRpcFailed(this);
|
||||||
@ -816,40 +818,6 @@ export class WidgetSubscription implements IWidgetSubscription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extractRejectionErrorText(rejection: HttpErrorResponse) {
|
|
||||||
let error = null;
|
|
||||||
if (rejection.error) {
|
|
||||||
error = rejection.error;
|
|
||||||
try {
|
|
||||||
error = rejection.error ? JSON.parse(rejection.error) : null;
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
if (error && !error.message) {
|
|
||||||
error = this.prepareMessageFromData(error);
|
|
||||||
} else if (error && error.message) {
|
|
||||||
error = error.message;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private prepareMessageFromData(data) {
|
|
||||||
if (typeof data === 'object' && data.constructor === ArrayBuffer) {
|
|
||||||
const msg = String.fromCharCode.apply(null, new Uint8Array(data));
|
|
||||||
try {
|
|
||||||
const msgObj = JSON.parse(msg);
|
|
||||||
if (msgObj.message) {
|
|
||||||
return msgObj.message;
|
|
||||||
} else {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update(isTimewindowTypeChanged = false) {
|
update(isTimewindowTypeChanged = false) {
|
||||||
if (this.type !== widgetType.rpc) {
|
if (this.type !== widgetType.rpc) {
|
||||||
this.widgetTimewindowChangedSubject.next(this.timeWindowConfig);
|
this.widgetTimewindowChangedSubject.next(this.timeWindowConfig);
|
||||||
|
|||||||
@ -38,10 +38,11 @@ import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.m
|
|||||||
import { select, Store } from '@ngrx/store';
|
import { select, Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { selectIsUserLoaded } from '@core/auth/auth.selectors';
|
import { selectIsUserLoaded } from '@core/auth/auth.selectors';
|
||||||
import { catchError, finalize, switchMap, takeWhile, tap } from 'rxjs/operators';
|
import { catchError, finalize, map, switchMap, takeWhile, tap } from 'rxjs/operators';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
import { ActionLoadFinish, ActionLoadStart } from '@core/interceptors/load.actions';
|
import { ActionLoadFinish, ActionLoadStart } from '@core/interceptors/load.actions';
|
||||||
|
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -135,7 +136,24 @@ export class EntitiesVersionControlService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public loadEntitiesVersion(request: VersionLoadRequest, config?: RequestConfig): Observable<VersionLoadResult> {
|
public loadEntitiesVersion(request: VersionLoadRequest, config?: RequestConfig): Observable<VersionLoadResult> {
|
||||||
return this.http.post<VersionLoadResult>('/api/entities/vc/entity', request, defaultHttpOptionsFromConfig(config));
|
this.store.dispatch(new ActionLoadStart());
|
||||||
|
return this.http.post<string>('/api/entities/vc/entity', request,
|
||||||
|
defaultHttpOptionsFromConfig({...config, ...{ignoreLoading: true}})).pipe(
|
||||||
|
switchMap((requestId) => {
|
||||||
|
return timer(0, 2000).pipe(
|
||||||
|
switchMap(() => this.getVersionLoadRequestStatus(requestId, config)),
|
||||||
|
takeWhile((res) => !res.done, true),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
finalize(() => {
|
||||||
|
this.store.dispatch(new ActionLoadFinish());
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVersionLoadRequestStatus(requestId: string, config?: RequestConfig): Observable<VersionLoadResult> {
|
||||||
|
return this.http.get<VersionLoadResult>(`/api/entities/vc/entity/${requestId}/status`,
|
||||||
|
defaultHttpOptionsFromConfig({...config, ...{ignoreLoading: true}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public compareEntityDataToVersion(branch: string,
|
public compareEntityDataToVersion(branch: string,
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import { ActionLoadFinish, ActionLoadStart } from './load.actions';
|
|||||||
import { ActionNotificationShow } from '@app/core/notification/notification.actions';
|
import { ActionNotificationShow } from '@app/core/notification/notification.actions';
|
||||||
import { DialogService } from '@core/services/dialog.service';
|
import { DialogService } from '@core/services/dialog.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { parseHttpErrorMessage } from '@core/utils';
|
||||||
|
|
||||||
let tmpHeaders = {};
|
let tmpHeaders = {};
|
||||||
|
|
||||||
@ -131,43 +132,12 @@ export class GlobalHttpInterceptor implements HttpInterceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unhandled && !ignoreErrors) {
|
if (unhandled && !ignoreErrors) {
|
||||||
let error = null;
|
const errorMessageWithTimeout = parseHttpErrorMessage(errorResponse, this.translate, req.responseType);
|
||||||
if (req.responseType === 'text') {
|
this.showError(errorMessageWithTimeout.message, errorMessageWithTimeout.timeout);
|
||||||
try {
|
|
||||||
error = errorResponse.error ? JSON.parse(errorResponse.error) : null;
|
|
||||||
} catch (e) {}
|
|
||||||
} else {
|
|
||||||
error = errorResponse.error;
|
|
||||||
}
|
|
||||||
if (error && !error.message) {
|
|
||||||
this.showError(this.prepareMessageFromData(error));
|
|
||||||
} else if (error && error.message) {
|
|
||||||
this.showError(error.message, error.timeout ? error.timeout : 0);
|
|
||||||
} else {
|
|
||||||
this.showError('Unhandled error code ' + (error ? error.status : '\'Unknown\''));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return throwError(errorResponse);
|
return throwError(errorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
private prepareMessageFromData(data) {
|
|
||||||
if (typeof data === 'object' && data.constructor === ArrayBuffer) {
|
|
||||||
const msg = String.fromCharCode.apply(null, new Uint8Array(data));
|
|
||||||
try {
|
|
||||||
const msgObj = JSON.parse(msg);
|
|
||||||
if (msgObj.message) {
|
|
||||||
return msgObj.message;
|
|
||||||
} else {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private retryRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
private retryRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
const thisTimeout = 1000 + Math.random() * 3000;
|
const thisTimeout = 1000 + Math.random() * 3000;
|
||||||
return of(null).pipe(
|
return of(null).pipe(
|
||||||
|
|||||||
@ -21,6 +21,10 @@ import { Datasource, DatasourceData, FormattedData, ReplaceInfo } from '@app/sha
|
|||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
||||||
import { EntityType, baseDetailsPageByEntityType } from '@shared/models/entity-type.models';
|
import { EntityType, baseDetailsPageByEntityType } from '@shared/models/entity-type.models';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { letterSpacing } from 'html2canvas/dist/types/css/property-descriptors/letter-spacing';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { serverErrorCodesTranslations } from '@shared/models/constants';
|
||||||
|
|
||||||
const varsRegex = /\${([^}]*)}/g;
|
const varsRegex = /\${([^}]*)}/g;
|
||||||
|
|
||||||
@ -664,3 +668,53 @@ export function randomAlphanumeric(length: number): string {
|
|||||||
export function getEntityDetailsPageURL(id: string, entityType: EntityType): string {
|
export function getEntityDetailsPageURL(id: string, entityType: EntityType): string {
|
||||||
return `${baseDetailsPageByEntityType.get(entityType)}/${id}`;
|
return `${baseDetailsPageByEntityType.get(entityType)}/${id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseHttpErrorMessage(errorResponse: HttpErrorResponse,
|
||||||
|
translate: TranslateService, responseType?: string): {message: string, timeout: number} {
|
||||||
|
let error = null;
|
||||||
|
let errorMessage: string;
|
||||||
|
let timeout = 0;
|
||||||
|
if (responseType === 'text') {
|
||||||
|
try {
|
||||||
|
error = errorResponse.error ? JSON.parse(errorResponse.error) : null;
|
||||||
|
} catch (e) {}
|
||||||
|
} else {
|
||||||
|
error = errorResponse.error;
|
||||||
|
}
|
||||||
|
if (error && !error.message) {
|
||||||
|
errorMessage = prepareMessageFromData(error);
|
||||||
|
} else if (error && error.message) {
|
||||||
|
errorMessage = error.message;
|
||||||
|
timeout = error.timeout ? error.timeout : 0;
|
||||||
|
} else {
|
||||||
|
errorMessage = `Unhandled error code ${error ? error.status : '\'Unknown\''}`;
|
||||||
|
}
|
||||||
|
if (isObject(errorMessage)) {
|
||||||
|
let errorText = `${errorResponse.status}: `;
|
||||||
|
let errorKey = null;
|
||||||
|
if ((errorMessage as any).errorCode) {
|
||||||
|
errorKey = serverErrorCodesTranslations.get((errorMessage as any).errorCode);
|
||||||
|
}
|
||||||
|
errorText += errorKey ? translate.instant(errorKey) : errorResponse.statusText;
|
||||||
|
errorMessage = errorText;
|
||||||
|
}
|
||||||
|
return {message: errorMessage, timeout};
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareMessageFromData(data): string {
|
||||||
|
if (typeof data === 'object' && data.constructor === ArrayBuffer) {
|
||||||
|
const msg = String.fromCharCode.apply(null, new Uint8Array(data));
|
||||||
|
try {
|
||||||
|
const msgObj = JSON.parse(msg);
|
||||||
|
if (msgObj.message) {
|
||||||
|
return msgObj.message;
|
||||||
|
} else {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<section style="min-width: 800px;">
|
<section style="min-width: 800px;">
|
||||||
<section *ngIf="!resultMessage">
|
<section *ngIf="!versionCreateResult$">
|
||||||
<mat-toolbar>
|
<mat-toolbar>
|
||||||
<h2>{{ 'version-control.create-entities-version' | translate }}</h2>
|
<h2>{{ 'version-control.create-entities-version' | translate }}</h2>
|
||||||
<span fxFlex></span>
|
<span fxFlex></span>
|
||||||
@ -69,9 +69,11 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section *ngIf="versionCreateResult$">
|
||||||
<section *ngIf="resultMessage">
|
<section *ngIf="resultMessage">
|
||||||
<div class="mat-title vc-result-message" [innerHtml]="resultMessage"></div>
|
<div class="mat-title vc-result-message" [innerHtml]="resultMessage"></div>
|
||||||
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
</section>
|
||||||
|
<div *ngIf="(versionCreateResult$ | async)?.done || hasError; else progress" fxLayoutAlign="end center" fxLayoutGap="8px">
|
||||||
<button mat-button color="primary"
|
<button mat-button color="primary"
|
||||||
type="button"
|
type="button"
|
||||||
[disabled]="(isLoading$ | async)"
|
[disabled]="(isLoading$ | async)"
|
||||||
@ -79,5 +81,13 @@
|
|||||||
{{ 'action.close' | translate }}
|
{{ 'action.close' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-template #progress>
|
||||||
|
<section fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<div class="mat-title vc-result-message progress">
|
||||||
|
<span translate>version-control.creating-version</span>
|
||||||
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ng-template>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { PageComponent } from '@shared/components/page.component';
|
import { PageComponent } from '@shared/components/page.component';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
@ -30,13 +30,16 @@ import { EntitiesVersionControlService } from '@core/http/entities-version-contr
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { share } from 'rxjs/operators';
|
||||||
|
import { parseHttpErrorMessage } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-complex-version-create',
|
selector: 'tb-complex-version-create',
|
||||||
templateUrl: './complex-version-create.component.html',
|
templateUrl: './complex-version-create.component.html',
|
||||||
styleUrls: ['./version-control.scss']
|
styleUrls: ['./version-control.scss']
|
||||||
})
|
})
|
||||||
export class ComplexVersionCreateComponent extends PageComponent implements OnInit {
|
export class ComplexVersionCreateComponent extends PageComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
branch: string;
|
branch: string;
|
||||||
@ -57,10 +60,16 @@ export class ComplexVersionCreateComponent extends PageComponent implements OnIn
|
|||||||
|
|
||||||
resultMessage: SafeHtml;
|
resultMessage: SafeHtml;
|
||||||
|
|
||||||
|
hasError = false;
|
||||||
|
|
||||||
versionCreateResult: VersionCreationResult = null;
|
versionCreateResult: VersionCreationResult = null;
|
||||||
|
|
||||||
versionCreateBranch: string = null;
|
versionCreateBranch: string = null;
|
||||||
|
|
||||||
|
versionCreateResult$: Observable<VersionCreationResult>;
|
||||||
|
|
||||||
|
private versionCreateResultSubscription: Subscription;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
private entitiesVersionControlService: EntitiesVersionControlService,
|
private entitiesVersionControlService: EntitiesVersionControlService,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
@ -79,6 +88,13 @@ export class ComplexVersionCreateComponent extends PageComponent implements OnIn
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
super.ngOnDestroy();
|
||||||
|
if (this.versionCreateResultSubscription) {
|
||||||
|
this.versionCreateResultSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cancel(): void {
|
cancel(): void {
|
||||||
if (this.onClose) {
|
if (this.onClose) {
|
||||||
this.onClose(this.versionCreateResult, this.versionCreateBranch);
|
this.onClose(this.versionCreateResult, this.versionCreateBranch);
|
||||||
@ -93,11 +109,20 @@ export class ComplexVersionCreateComponent extends PageComponent implements OnIn
|
|||||||
entityTypes: this.createVersionFormGroup.get('entityTypes').value,
|
entityTypes: this.createVersionFormGroup.get('entityTypes').value,
|
||||||
type: VersionCreateRequestType.COMPLEX
|
type: VersionCreateRequestType.COMPLEX
|
||||||
};
|
};
|
||||||
this.entitiesVersionControlService.saveEntitiesVersion(request).subscribe((result) => {
|
|
||||||
if (!result.added && !result.modified && !result.removed) {
|
this.versionCreateResult$ = this.entitiesVersionControlService.saveEntitiesVersion(request, {ignoreErrors: true}).pipe(
|
||||||
|
share()
|
||||||
|
);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.versionCreateResultSubscription = this.versionCreateResult$.subscribe((result) => {
|
||||||
|
if (result.done && !result.added && !result.modified && !result.removed) {
|
||||||
this.resultMessage = this.sanitizer.bypassSecurityTrustHtml(this.translate.instant('version-control.nothing-to-commit'));
|
this.resultMessage = this.sanitizer.bypassSecurityTrustHtml(this.translate.instant('version-control.nothing-to-commit'));
|
||||||
} else {
|
} else {
|
||||||
this.resultMessage = this.sanitizer.bypassSecurityTrustHtml(this.translate.instant('version-control.version-create-result',
|
this.resultMessage = this.sanitizer.bypassSecurityTrustHtml(result.error ? result.error : this.translate.instant('version-control.version-create-result',
|
||||||
{added: result.added, modified: result.modified, removed: result.removed}));
|
{added: result.added, modified: result.modified, removed: result.removed}));
|
||||||
}
|
}
|
||||||
this.versionCreateResult = result;
|
this.versionCreateResult = result;
|
||||||
@ -106,6 +131,14 @@ export class ComplexVersionCreateComponent extends PageComponent implements OnIn
|
|||||||
if (this.popoverComponent) {
|
if (this.popoverComponent) {
|
||||||
this.popoverComponent.updatePosition();
|
this.popoverComponent.updatePosition();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.hasError = true;
|
||||||
|
this.resultMessage = this.sanitizer.bypassSecurityTrustHtml(parseHttpErrorMessage(error, this.translate).message);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<section [ngStyle]="versionLoadResult ? {minWidth: '500px'} : {minWidth: '800px'}">
|
<section [ngStyle]="versionLoadResult$ ? {minWidth: '500px'} : {minWidth: '800px'}">
|
||||||
<section *ngIf="!versionLoadResult">
|
<section *ngIf="!versionLoadResult$">
|
||||||
<mat-toolbar>
|
<mat-toolbar>
|
||||||
<h2>{{ 'version-control.restore-entities-from-version' | translate: {versionName} }}</h2>
|
<h2>{{ 'version-control.restore-entities-from-version' | translate: {versionName} }}</h2>
|
||||||
<span fxFlex></span>
|
<span fxFlex></span>
|
||||||
@ -48,13 +48,13 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section *ngIf="versionLoadResult">
|
<section *ngIf="versionLoadResult$">
|
||||||
<div *ngIf="!entityTypeLoadResults.length && !errorMessage" class="mat-title vc-result-message">
|
<div *ngIf="(versionLoadResult$ | async)?.done && !entityTypeLoadResults?.length && !errorMessage" class="mat-title vc-result-message">
|
||||||
{{ 'version-control.no-entities-restored' | translate }}
|
{{ 'version-control.no-entities-restored' | translate }}
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="errorMessage" class="mat-title vc-result-message error" [innerHTML]="errorMessage"></div>
|
<div *ngIf="errorMessage" class="mat-title vc-result-message error" [innerHTML]="errorMessage"></div>
|
||||||
<div *ngFor="let entityTypeLoadResult of entityTypeLoadResults" class="mat-title vc-result-message">{{ entityTypeLoadResultMessage(entityTypeLoadResult) }}</div>
|
<div *ngFor="let entityTypeLoadResult of entityTypeLoadResults" class="mat-title vc-result-message">{{ entityTypeLoadResultMessage(entityTypeLoadResult) }}</div>
|
||||||
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
<div *ngIf="(versionLoadResult$ | async)?.done || hasError; else progress" fxLayoutAlign="end center" fxLayoutGap="8px">
|
||||||
<button mat-button color="primary"
|
<button mat-button color="primary"
|
||||||
type="button"
|
type="button"
|
||||||
[disabled]="(isLoading$ | async)"
|
[disabled]="(isLoading$ | async)"
|
||||||
@ -62,5 +62,13 @@
|
|||||||
{{ 'action.close' | translate }}
|
{{ 'action.close' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-template #progress>
|
||||||
|
<section fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<div class="mat-title vc-result-message progress">
|
||||||
|
<span translate>version-control.restoring-entities-from-version</span>
|
||||||
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ng-template>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { PageComponent } from '@shared/components/page.component';
|
import { PageComponent } from '@shared/components/page.component';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
@ -28,15 +28,18 @@ import { AppState } from '@core/core.state';
|
|||||||
import { EntitiesVersionControlService } from '@core/http/entities-version-control.service';
|
import { EntitiesVersionControlService } from '@core/http/entities-version-control.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { entityTypeTranslations } from '@shared/models/entity-type.models';
|
import { entityTypeTranslations } from '@shared/models/entity-type.models';
|
||||||
import { SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { share } from 'rxjs/operators';
|
||||||
|
import { parseHttpErrorMessage } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-complex-version-load',
|
selector: 'tb-complex-version-load',
|
||||||
templateUrl: './complex-version-load.component.html',
|
templateUrl: './complex-version-load.component.html',
|
||||||
styleUrls: ['./version-control.scss']
|
styleUrls: ['./version-control.scss']
|
||||||
})
|
})
|
||||||
export class ComplexVersionLoadComponent extends PageComponent implements OnInit {
|
export class ComplexVersionLoadComponent extends PageComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
branch: string;
|
branch: string;
|
||||||
@ -61,10 +64,17 @@ export class ComplexVersionLoadComponent extends PageComponent implements OnInit
|
|||||||
|
|
||||||
errorMessage: SafeHtml;
|
errorMessage: SafeHtml;
|
||||||
|
|
||||||
|
hasError = false;
|
||||||
|
|
||||||
|
versionLoadResult$: Observable<VersionLoadResult>;
|
||||||
|
|
||||||
|
private versionLoadResultSubscription: Subscription;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
private entitiesVersionControlService: EntitiesVersionControlService,
|
private entitiesVersionControlService: EntitiesVersionControlService,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
|
private sanitizer: DomSanitizer,
|
||||||
private fb: FormBuilder) {
|
private fb: FormBuilder) {
|
||||||
super(store);
|
super(store);
|
||||||
}
|
}
|
||||||
@ -75,6 +85,13 @@ export class ComplexVersionLoadComponent extends PageComponent implements OnInit
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
super.ngOnDestroy();
|
||||||
|
if (this.versionLoadResultSubscription) {
|
||||||
|
this.versionLoadResultSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
entityTypeLoadResultMessage(result: EntityTypeLoadResult): string {
|
entityTypeLoadResultMessage(result: EntityTypeLoadResult): string {
|
||||||
const entityType = result.entityType;
|
const entityType = result.entityType;
|
||||||
let message = this.translate.instant(entityTypeTranslations.get(entityType).typePlural) + ': ';
|
let message = this.translate.instant(entityTypeTranslations.get(entityType).typePlural) + ': ';
|
||||||
@ -105,7 +122,14 @@ export class ComplexVersionLoadComponent extends PageComponent implements OnInit
|
|||||||
entityTypes: this.loadVersionFormGroup.get('entityTypes').value,
|
entityTypes: this.loadVersionFormGroup.get('entityTypes').value,
|
||||||
type: VersionLoadRequestType.ENTITY_TYPE
|
type: VersionLoadRequestType.ENTITY_TYPE
|
||||||
};
|
};
|
||||||
this.entitiesVersionControlService.loadEntitiesVersion(request).subscribe((result) => {
|
this.versionLoadResult$ = this.entitiesVersionControlService.loadEntitiesVersion(request, {ignoreErrors: true}).pipe(
|
||||||
|
share()
|
||||||
|
);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
|
this.versionLoadResultSubscription = this.versionLoadResult$.subscribe((result) => {
|
||||||
this.versionLoadResult = result;
|
this.versionLoadResult = result;
|
||||||
this.entityTypeLoadResults = (result.result || []).filter(res => res.created || res.updated || res.deleted);
|
this.entityTypeLoadResults = (result.result || []).filter(res => res.created || res.updated || res.deleted);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
@ -115,6 +139,14 @@ export class ComplexVersionLoadComponent extends PageComponent implements OnInit
|
|||||||
if (this.popoverComponent) {
|
if (this.popoverComponent) {
|
||||||
this.popoverComponent.updatePosition();
|
this.popoverComponent.updatePosition();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.hasError = true;
|
||||||
|
this.errorMessage = this.sanitizer.bypassSecurityTrustHtml(parseHttpErrorMessage(error, this.translate).message);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section *ngIf="versionCreateResult$">
|
<section *ngIf="versionCreateResult$">
|
||||||
<section *ngIf="(versionCreateResult$ | async)?.done; else progress">
|
<section *ngIf="(versionCreateResult$ | async)?.done || resultMessage; else progress">
|
||||||
<section *ngIf="resultMessage">
|
<section *ngIf="resultMessage">
|
||||||
<div class="mat-title vc-result-message">{{ resultMessage }}</div>
|
<div class="mat-title vc-result-message">{{ resultMessage }}</div>
|
||||||
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import { Observable, of, Subscription } from 'rxjs';
|
|||||||
import { EntityType } from '@shared/models/entity-type.models';
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
import { share } from 'rxjs/operators';
|
import { share } from 'rxjs/operators';
|
||||||
|
import { parseHttpErrorMessage } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-entity-version-create',
|
selector: 'tb-entity-version-create',
|
||||||
@ -113,7 +114,7 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni
|
|||||||
},
|
},
|
||||||
type: VersionCreateRequestType.SINGLE_ENTITY
|
type: VersionCreateRequestType.SINGLE_ENTITY
|
||||||
};
|
};
|
||||||
this.versionCreateResult$ = this.entitiesVersionControlService.saveEntitiesVersion(request).pipe(
|
this.versionCreateResult$ = this.entitiesVersionControlService.saveEntitiesVersion(request, {ignoreErrors: true}).pipe(
|
||||||
share()
|
share()
|
||||||
);
|
);
|
||||||
this.cd.detectChanges();
|
this.cd.detectChanges();
|
||||||
@ -133,6 +134,13 @@ export class EntityVersionCreateComponent extends PageComponent implements OnIni
|
|||||||
this.onClose(result, request.branch);
|
this.onClose(result, request.branch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.resultMessage = parseHttpErrorMessage(error, this.translate).message;
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<section [ngStyle]="entityDataInfo ? {minWidth: '400px'} : {}">
|
<section [ngStyle]="entityDataInfo ? {minWidth: '400px'} : {}">
|
||||||
<section *ngIf="!errorMessage">
|
<section *ngIf="!versionLoadResult$">
|
||||||
<mat-toolbar *ngIf="entityDataInfo">
|
<mat-toolbar *ngIf="entityDataInfo">
|
||||||
<h2>{{ 'version-control.restore-entity-from-version' | translate: {versionName} }}</h2>
|
<h2>{{ 'version-control.restore-entity-from-version' | translate: {versionName} }}</h2>
|
||||||
<span fxFlex></span>
|
<span fxFlex></span>
|
||||||
@ -55,6 +55,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section *ngIf="versionLoadResult$">
|
||||||
|
<section *ngIf="(versionLoadResult$ | async)?.done || errorMessage; else progress">
|
||||||
<section *ngIf="errorMessage">
|
<section *ngIf="errorMessage">
|
||||||
<div class="mat-title vc-result-message error" [innerHTML]="errorMessage"></div>
|
<div class="mat-title vc-result-message error" [innerHTML]="errorMessage"></div>
|
||||||
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
<div fxLayoutAlign="end center" fxLayoutGap="8px">
|
||||||
@ -66,4 +68,14 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</section>
|
||||||
|
<ng-template #progress>
|
||||||
|
<section fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<div class="mat-title vc-result-message progress">
|
||||||
|
<span translate>version-control.restoring-entity-version</span>
|
||||||
|
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ng-template>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -14,12 +14,12 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, Sanitizer } from '@angular/core';
|
||||||
import { PageComponent } from '@shared/components/page.component';
|
import { PageComponent } from '@shared/components/page.component';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
EntityDataInfo,
|
EntityDataInfo,
|
||||||
SingleEntityVersionLoadRequest,
|
SingleEntityVersionLoadRequest, VersionCreationResult,
|
||||||
VersionLoadRequestType,
|
VersionLoadRequestType,
|
||||||
VersionLoadResult
|
VersionLoadResult
|
||||||
} from '@shared/models/vc.models';
|
} from '@shared/models/vc.models';
|
||||||
@ -29,15 +29,17 @@ import { EntitiesVersionControlService } from '@core/http/entities-version-contr
|
|||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { TbPopoverComponent } from '@shared/components/popover.component';
|
import { TbPopoverComponent } from '@shared/components/popover.component';
|
||||||
import { delay } from 'rxjs/operators';
|
import { delay, share } from 'rxjs/operators';
|
||||||
import { SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { parseHttpErrorMessage } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-entity-version-restore',
|
selector: 'tb-entity-version-restore',
|
||||||
templateUrl: './entity-version-restore.component.html',
|
templateUrl: './entity-version-restore.component.html',
|
||||||
styleUrls: ['./version-control.scss']
|
styleUrls: ['./version-control.scss']
|
||||||
})
|
})
|
||||||
export class EntityVersionRestoreComponent extends PageComponent implements OnInit {
|
export class EntityVersionRestoreComponent extends PageComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
branch: string;
|
branch: string;
|
||||||
@ -63,10 +65,15 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn
|
|||||||
|
|
||||||
errorMessage: SafeHtml;
|
errorMessage: SafeHtml;
|
||||||
|
|
||||||
|
versionLoadResult$: Observable<VersionLoadResult>;
|
||||||
|
|
||||||
|
private versionLoadResultSubscription: Subscription;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
private entitiesVersionControlService: EntitiesVersionControlService,
|
private entitiesVersionControlService: EntitiesVersionControlService,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
|
private sanitizer: DomSanitizer,
|
||||||
private fb: FormBuilder) {
|
private fb: FormBuilder) {
|
||||||
super(store);
|
super(store);
|
||||||
}
|
}
|
||||||
@ -86,6 +93,13 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
super.ngOnDestroy();
|
||||||
|
if (this.versionLoadResultSubscription) {
|
||||||
|
this.versionLoadResultSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cancel(): void {
|
cancel(): void {
|
||||||
if (this.onClose) {
|
if (this.onClose) {
|
||||||
this.onClose(null);
|
this.onClose(null);
|
||||||
@ -104,7 +118,15 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn
|
|||||||
},
|
},
|
||||||
type: VersionLoadRequestType.SINGLE_ENTITY
|
type: VersionLoadRequestType.SINGLE_ENTITY
|
||||||
};
|
};
|
||||||
this.entitiesVersionControlService.loadEntitiesVersion(request).subscribe((result) => {
|
this.versionLoadResult$ = this.entitiesVersionControlService.loadEntitiesVersion(request, {ignoreErrors: true}).pipe(
|
||||||
|
share()
|
||||||
|
);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
|
this.versionLoadResultSubscription = this.versionLoadResult$.subscribe((result) => {
|
||||||
|
if (result.done) {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
this.errorMessage = this.entitiesVersionControlService.entityLoadErrorToMessage(result.error);
|
this.errorMessage = this.entitiesVersionControlService.entityLoadErrorToMessage(result.error);
|
||||||
this.cd.detectChanges();
|
this.cd.detectChanges();
|
||||||
@ -116,6 +138,14 @@ export class EntityVersionRestoreComponent extends PageComponent implements OnIn
|
|||||||
this.onClose(result);
|
this.onClose(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.errorMessage = this.sanitizer.bypassSecurityTrustHtml(parseHttpErrorMessage(error, this.translate).message);
|
||||||
|
this.cd.detectChanges();
|
||||||
|
if (this.popoverComponent) {
|
||||||
|
this.popoverComponent.updatePosition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ import {
|
|||||||
import cssjs from '@core/css/css';
|
import cssjs from '@core/css/css';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { hashCode, isDefined, isNumber } from '@core/utils';
|
import { hashCode, isDefined, isNumber, parseHttpErrorMessage } from '@core/utils';
|
||||||
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
|
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
|
||||||
import { emptyPageData, PageData } from '@shared/models/page/page-data';
|
import { emptyPageData, PageData } from '@shared/models/page/page-data';
|
||||||
import {
|
import {
|
||||||
@ -520,7 +520,7 @@ class PersistentDatasource implements DataSource<PersistentRpcData> {
|
|||||||
this.subscription.rpcErrorText = 'Request Timeout.';
|
this.subscription.rpcErrorText = 'Request Timeout.';
|
||||||
} else {
|
} else {
|
||||||
this.subscription.rpcErrorText = 'Error : ' + rejection.status + ' - ' + rejection.statusText;
|
this.subscription.rpcErrorText = 'Error : ' + rejection.status + ' - ' + rejection.statusText;
|
||||||
const error = this.extractRejectionErrorText(rejection);
|
const error = parseHttpErrorMessage(rejection, this.translate);
|
||||||
if (error) {
|
if (error) {
|
||||||
this.subscription.rpcErrorText += '</br>';
|
this.subscription.rpcErrorText += '</br>';
|
||||||
this.subscription.rpcErrorText += error.message || '';
|
this.subscription.rpcErrorText += error.message || '';
|
||||||
@ -534,40 +534,6 @@ class PersistentDatasource implements DataSource<PersistentRpcData> {
|
|||||||
return rpcSubject.asObservable();
|
return rpcSubject.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
extractRejectionErrorText(rejection: HttpErrorResponse) {
|
|
||||||
let error = null;
|
|
||||||
if (rejection.error) {
|
|
||||||
error = rejection.error;
|
|
||||||
try {
|
|
||||||
error = rejection.error ? JSON.parse(rejection.error) : null;
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
if (error && !error.message) {
|
|
||||||
error = this.prepareMessageFromData(error);
|
|
||||||
} else if (error && error.message) {
|
|
||||||
error = error.message;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareMessageFromData(data) {
|
|
||||||
if (typeof data === 'object' && data.constructor === ArrayBuffer) {
|
|
||||||
const msg = String.fromCharCode.apply(null, new Uint8Array(data));
|
|
||||||
try {
|
|
||||||
const msgObj = JSON.parse(msg);
|
|
||||||
if (msgObj.message) {
|
|
||||||
return msgObj.message;
|
|
||||||
} else {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty(): Observable<boolean> {
|
isEmpty(): Observable<boolean> {
|
||||||
return this.persistentSubject.pipe(
|
return this.persistentSubject.pipe(
|
||||||
map((requests) => !requests.length)
|
map((requests) => !requests.length)
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import { InjectionToken } from '@angular/core';
|
import { InjectionToken } from '@angular/core';
|
||||||
import { IModulesMap } from '@modules/common/modules-map.models';
|
import { IModulesMap } from '@modules/common/modules-map.models';
|
||||||
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
|
||||||
export const Constants = {
|
export const Constants = {
|
||||||
serverErrorCode: {
|
serverErrorCode: {
|
||||||
@ -38,6 +39,20 @@ export const Constants = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const serverErrorCodesTranslations = new Map<number, string>([
|
||||||
|
[Constants.serverErrorCode.general, 'server-error.general'],
|
||||||
|
[Constants.serverErrorCode.authentication, 'server-error.authentication'],
|
||||||
|
[Constants.serverErrorCode.jwtTokenExpired, 'server-error.jwt-token-expired'],
|
||||||
|
[Constants.serverErrorCode.tenantTrialExpired, 'server-error.tenant-trial-expired'],
|
||||||
|
[Constants.serverErrorCode.credentialsExpired, 'server-error.credentials-expired'],
|
||||||
|
[Constants.serverErrorCode.permissionDenied, 'server-error.permission-denied'],
|
||||||
|
[Constants.serverErrorCode.invalidArguments, 'server-error.invalid-arguments'],
|
||||||
|
[Constants.serverErrorCode.badRequestParams, 'server-error.bad-request-params'],
|
||||||
|
[Constants.serverErrorCode.itemNotFound, 'server-error.item-not-found'],
|
||||||
|
[Constants.serverErrorCode.tooManyRequests, 'server-error.too-many-requests'],
|
||||||
|
[Constants.serverErrorCode.tooManyUpdates, 'server-error.too-many-updates'],
|
||||||
|
]);
|
||||||
|
|
||||||
export const MediaBreakpoints = {
|
export const MediaBreakpoints = {
|
||||||
xs: 'screen and (max-width: 599px)',
|
xs: 'screen and (max-width: 599px)',
|
||||||
sm: 'screen and (min-width: 600px) and (max-width: 959px)',
|
sm: 'screen and (min-width: 600px) and (max-width: 959px)',
|
||||||
|
|||||||
@ -197,6 +197,7 @@ export interface EntityLoadError {
|
|||||||
export interface VersionLoadResult {
|
export interface VersionLoadResult {
|
||||||
result: Array<EntityTypeLoadResult>;
|
result: Array<EntityTypeLoadResult>;
|
||||||
error: EntityLoadError;
|
error: EntityLoadError;
|
||||||
|
done: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeExportData {
|
export interface AttributeExportData {
|
||||||
|
|||||||
@ -3000,6 +3000,19 @@
|
|||||||
"retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack"
|
"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": "Tenant",
|
"tenant": "Tenant",
|
||||||
"tenants": "Tenants",
|
"tenants": "Tenants",
|
||||||
@ -3310,6 +3323,7 @@
|
|||||||
"nothing-to-commit": "No changes to commit",
|
"nothing-to-commit": "No changes to commit",
|
||||||
"restore-version": "Restore version",
|
"restore-version": "Restore version",
|
||||||
"restore-entity-from-version": "Restore entity from version '{{versionName}}'",
|
"restore-entity-from-version": "Restore entity from version '{{versionName}}'",
|
||||||
|
"restoring-entity-version": "Restoring entity version... Please wait",
|
||||||
"load-relations": "Load relations",
|
"load-relations": "Load relations",
|
||||||
"load-attributes": "Load attributes",
|
"load-attributes": "Load attributes",
|
||||||
"load-credentials": "Load credentials",
|
"load-credentials": "Load credentials",
|
||||||
@ -3335,6 +3349,7 @@
|
|||||||
"remove-other-entities": "Remove other entities",
|
"remove-other-entities": "Remove other entities",
|
||||||
"find-existing-entity-by-name": "Find existing entity by name",
|
"find-existing-entity-by-name": "Find existing entity by name",
|
||||||
"restore-entities-from-version": "Restore entities from version '{{versionName}}'",
|
"restore-entities-from-version": "Restore entities from version '{{versionName}}'",
|
||||||
|
"restoring-entities-from-version": "Restoring entities... Please wait",
|
||||||
"no-entities-restored": "No entities restored",
|
"no-entities-restored": "No entities restored",
|
||||||
"created": "{{created}} created",
|
"created": "{{created}} created",
|
||||||
"updated": "{{updated}} updated",
|
"updated": "{{updated}} updated",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user