diff --git a/ui-ngx/src/app/core/interceptors/entity-conflict.interceptor.ts b/ui-ngx/src/app/core/interceptors/entity-conflict.interceptor.ts index e34aca7007..e4db59ec66 100644 --- a/ui-ngx/src/app/core/interceptors/entity-conflict.interceptor.ts +++ b/ui-ngx/src/app/core/interceptors/entity-conflict.interceptor.ts @@ -75,7 +75,7 @@ export class EntityConflictInterceptor implements HttpInterceptor { return next.handle(this.updateRequestVersion(request)); } (request.params as HttpParams & { interceptorConfig: InterceptorConfig }).interceptorConfig.ignoreErrors = true; - return throwError(() => new Error(error.error.message)); + return throwError(() => error); } return of(null); }) diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index f7efca5d40..109d5f014b 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -86,7 +86,7 @@ import { Authority } from '@shared/models/authority.enum'; import { DialogService } from '@core/services/dialog.service'; import { EntityService } from '@core/http/entity.service'; import { AliasController } from '@core/api/alias-controller'; -import { BehaviorSubject, Observable, of, Subject, Subscription } from 'rxjs'; +import { BehaviorSubject, Observable, of, Subject, Subscription, throwError } from 'rxjs'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { DashboardService } from '@core/http/dashboard.service'; import { @@ -156,6 +156,7 @@ import { MoveWidgetsDialogComponent, MoveWidgetsDialogResult } from '@home/components/dashboard-page/layout/move-widgets-dialog.component'; +import { HttpStatusCode } from '@angular/common/http'; // @dynamic @Component({ @@ -1203,15 +1204,31 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC data: widget }; this.window.parent.postMessage(JSON.stringify(message), '*'); + this.setEditMode(false, false); } else { + let reInitDashboard = false; this.dashboardService.saveDashboard(this.dashboard).pipe( - catchError(() => { - this.setEditMode(false, true); - return of(null); + catchError((err) => { + if (err.status === HttpStatusCode.Conflict) { + reInitDashboard = true; + return this.dashboardService.getDashboard(this.dashboard.id.id).pipe( + map(dashboard => this.dashboardUtils.validateAndUpdateDashboard(dashboard)) + ); + } + return throwError(() => err); }) - ).subscribe(() => { - this.dashboard.version = this.dashboard.version + 1; + ).subscribe((dashboard) => { this.setEditMode(false, false); + this.dashboard = dashboard; + if (reInitDashboard) { + const dashboardPageInitData: DashboardPageInitData = { + dashboard, + currentDashboardId: dashboard.id ? dashboard.id.id : null, + widgetEditMode: false, + singlePageMode: false + }; + this.init(dashboardPageInitData); + } }); } } diff --git a/ui-ngx/src/app/modules/home/components/entity/entity-details-panel.component.ts b/ui-ngx/src/app/modules/home/components/entity/entity-details-panel.component.ts index c283a57c4f..1ec56028af 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entity-details-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/entity/entity-details-panel.component.ts @@ -40,11 +40,12 @@ import { UntypedFormGroup } from '@angular/forms'; import { EntityComponent } from './entity.component'; import { TbAnchorComponent } from '@shared/components/tb-anchor.component'; import { EntityAction } from '@home/models/entity/entity-component.models'; -import { Observable, of, ReplaySubject, Subscription } from 'rxjs'; +import { Observable, ReplaySubject, Subscription, throwError } from 'rxjs'; import { MatTab, MatTabGroup } from '@angular/material/tabs'; import { EntityTabsComponent } from '@home/components/entity/entity-tabs.component'; import { deepClone, mergeDeep } from '@core/utils'; import { catchError } from 'rxjs/operators'; +import { HttpStatusCode } from '@angular/common/http'; @Component({ selector: 'tb-entity-details-panel', @@ -290,7 +291,12 @@ export class EntityDetailsPanelComponent extends PageComponent implements AfterV } this.entitiesTableConfig.saveEntity(editingEntity, this.editingEntity) .pipe( - catchError(() => of(this.entity)) + catchError((err) => { + if (err.status === HttpStatusCode.Conflict) { + return this.entitiesTableConfig.loadEntity(this.currentEntityId); + } + return throwError(() => err); + }) ) .subscribe( (entity) => { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts index aa7f62e33b..508d07ea0d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts @@ -113,7 +113,7 @@ export class WidgetComponentService { hasBasicMode: this.utils.editWidgetInfo.hasBasicMode, basicModeDirective: this.utils.editWidgetInfo.basicModeDirective, defaultConfig: this.utils.editWidgetInfo.defaultConfig - }, new WidgetTypeId('1'), new TenantId( NULL_UUID ), undefined, null + }, new WidgetTypeId('1'), new TenantId( NULL_UUID ), undefined, undefined ); } const initSubject = new ReplaySubject(); diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts index 614787233d..3ca2036369 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts +++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.ts @@ -59,12 +59,13 @@ import { SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult } from '@home/pages/widget/save-widget-type-as-dialog.component'; -import { forkJoin, mergeMap, of, Subscription } from 'rxjs'; +import { forkJoin, mergeMap, of, Subscription, throwError } from 'rxjs'; import { ResizeObserver } from '@juggle/resize-observer'; import { widgetEditorCompleter } from '@home/pages/widget/widget-editor.models'; import { Observable } from 'rxjs/internal/Observable'; import { catchError, map, tap } from 'rxjs/operators'; import { beautifyCss, beautifyHtml, beautifyJs } from '@shared/models/beautify.models'; +import { HttpStatusCode } from '@angular/common/http'; import Timeout = NodeJS.Timeout; // @dynamic @@ -583,9 +584,11 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe } return of(widgetTypeDetails); }), - catchError(() => { - this.undoWidget(); - return of(null); + catchError((err) => { + if (id && err.status === HttpStatusCode.Conflict) { + return this.widgetService.getWidgetTypeById(id.id); + } + return throwError(() => err); }), ).subscribe({ next: (widgetTypeDetails) => { @@ -619,7 +622,7 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe config.title = this.widget.widgetName; this.widget.defaultConfig = JSON.stringify(config); this.isDirty = false; - this.widgetService.saveWidgetTypeDetails(this.widget, undefined, undefined, null).pipe( + this.widgetService.saveWidgetTypeDetails(this.widget, undefined, undefined, undefined).pipe( mergeMap((widget) => { if (saveWidgetAsData.widgetBundleId) { return this.widgetService.addWidgetFqnToWidgetBundle(saveWidgetAsData.widgetBundleId, widget.fqn).pipe(