From 43041f8a89b6f08e3b00803cc7b762ea26addf47 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Thu, 25 Apr 2024 19:14:21 -0400 Subject: [PATCH] NIFI-13100: - Updating API response error handling for canvas based actions. --- .../behavior/draggable-behavior.service.ts | 6 +- .../service/canvas-context-menu.service.ts | 18 +- .../manager/connection-manager.service.ts | 6 +- .../service/manager/label-manager.service.ts | 5 +- .../flow-designer/state/flow/flow.actions.ts | 11 +- .../flow-designer/state/flow/flow.effects.ts | 352 +++++++++++------- .../flow-designer/state/flow/flow.reducer.ts | 21 +- .../state/flow/flow.selectors.ts | 4 - .../pages/flow-designer/state/flow/index.ts | 16 +- .../operation-control.component.ts | 12 +- .../new-canvas-item.component.ts | 19 +- .../create-connection.component.html | 1 + .../create-connection.component.ts | 4 +- .../edit-connection.component.html | 1 + .../edit-connection.component.ts | 7 +- .../label/edit-label/edit-label.component.ts | 3 +- .../port/edit-port/edit-port.component.ts | 3 +- .../edit-process-group.component.html | 1 + .../edit-process-group.component.spec.ts | 3 + .../edit-process-group.component.ts | 4 +- 20 files changed, 286 insertions(+), 211 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts index c68f692c87f4b..5404e91769a57 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/behavior/draggable-behavior.service.ts @@ -322,7 +322,8 @@ export class DraggableBehavior { }, restoreOnFailure: { position: d.position - } + }, + errorStrategy: 'snackbar' }; } @@ -361,7 +362,8 @@ export class DraggableBehavior { }, restoreOnFailure: { bends: connection.bends - } + }, + errorStrategy: 'snackbar' }; } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts index 938152634aa49..3e707b2853650 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/canvas-context-menu.service.ts @@ -599,7 +599,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -640,7 +641,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -710,7 +712,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -741,7 +744,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -768,7 +772,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); @@ -796,7 +801,8 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts index 809f0ed027db8..eef4990c7b081 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/connection-manager.service.ts @@ -356,7 +356,8 @@ export class ConnectionManager { disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(), component: connection }, - restoreOnFailure: restoreOnFailure + restoreOnFailure: restoreOnFailure, + errorStrategy: 'snackbar' }; // updateConnection is not needed here because we don't need any @@ -2012,7 +2013,8 @@ export class ConnectionManager { type: ComponentType.Connection, uri: connectionData.uri, previousDestination: connectionData.component.destination, - payload + payload, + errorStrategy: 'snackbar' } }) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts index cbdbb086dce9a..86428e57aa665 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/service/manager/label-manager.service.ts @@ -348,7 +348,7 @@ export class LabelManager { different = true; } - // only save the updated bends if necessary + // only save the updated dimensions if necessary if (different) { const updateLabel: UpdateComponentRequest = { id: labelData.id, @@ -368,7 +368,8 @@ export class LabelManager { width: widthSet ? labelData.component.width : LabelManager.INITIAL_WIDTH, height: heightSet ? labelData.component.height : LabelManager.INITIAL_HEIGHT } - } + }, + errorStrategy: 'snackbar' }; self.store.dispatch( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts index 0a0f8f4af84a2..3471a4d2b00d0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.actions.ts @@ -153,10 +153,6 @@ export const loadChildProcessGroupSuccess = createAction( props<{ response: ComponentEntity }>() ); -export const flowApiError = createAction(`${CANVAS_PREFIX} Flow Api Error`, props<{ error: string }>()); - -export const clearFlowApiError = createAction(`${CANVAS_PREFIX} Clear Flow Api Error`); - export const startProcessGroupPolling = createAction(`${CANVAS_PREFIX} Start Process Group Polling`); export const stopProcessGroupPolling = createAction(`${CANVAS_PREFIX} Stop Process Group Polling`); @@ -766,11 +762,6 @@ export const saveToFlowRegistrySuccess = createAction( props<{ response: VersionControlInformationEntity }>() ); -export const flowVersionBannerError = createAction( - `${CANVAS_PREFIX} Flow Version Banner Error`, - props<{ error: string }>() -); - export const stopVersionControlRequest = createAction( `${CANVAS_PREFIX} Stop Version Control Request`, props<{ request: ConfirmStopVersionControlRequest }>() @@ -788,6 +779,8 @@ export const stopVersionControlSuccess = createAction( export const flowSnackbarError = createAction(`${CANVAS_PREFIX} Flow Snackbar Error`, props<{ error: string }>()); +export const flowBannerError = createAction(`${CANVAS_PREFIX} Flow Banner Error`, props<{ error: string }>()); + export const openShowLocalChangesDialogRequest = createAction( `${CANVAS_PREFIX} Open Show Local Changes Dialog Request`, props<{ request: OpenLocalChangesDialogRequest }>() diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts index bbfe801474c70..e1828c932751e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.effects.ts @@ -46,7 +46,6 @@ import { DeleteComponentResponse, GroupComponentsDialogRequest, ImportFromRegistryDialogRequest, - LoadProcessGroupRequest, LoadProcessGroupResponse, MoveComponentRequest, SaveVersionDialogRequest, @@ -69,6 +68,7 @@ import { selectCopiedSnippet, selectCurrentParameterContext, selectCurrentProcessGroupId, + selectFlowLoadingStatus, selectInputPort, selectMaxZIndex, selectOutputPort, @@ -130,6 +130,7 @@ import { ChangeComponentVersionDialog } from '../../../../ui/common/change-compo import { SnippetService } from '../../service/snippet.service'; import { selectTransform } from '../transform/transform.selectors'; import { EditLabel } from '../../ui/canvas/items/label/edit-label/edit-label.component'; +import { ErrorHelper } from '../../../../service/error-helper.service'; @Injectable() export class FlowEffects { @@ -150,7 +151,8 @@ export class FlowEffects { private dialog: MatDialog, private propertyTableHelperService: PropertyTableHelperService, private parameterHelperService: ParameterHelperService, - private extensionTypesService: ExtensionTypesService + private extensionTypesService: ExtensionTypesService, + private errorHelper: ErrorHelper ) {} reloadFlow$ = createEffect(() => @@ -174,7 +176,8 @@ export class FlowEffects { this.actions$.pipe( ofType(FlowActions.loadProcessGroup), map((action) => action.request), - switchMap((request: LoadProcessGroupRequest) => + concatLatestFrom(() => this.store.select(selectFlowLoadingStatus)), + switchMap(([request, status]) => combineLatest([ this.flowService.getFlow(request.id), this.flowService.getFlowStatus(), @@ -190,7 +193,9 @@ export class FlowEffects { } }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => + of(this.errorHelper.handleLoadingError(status, errorResponse)) + ) ) ) ) @@ -257,7 +262,9 @@ export class FlowEffects { return FlowActions.openNewProcessGroupDialog({ request: dialogRequest }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => + of(this.snackBarOrFullScreenError(errorResponse)) + ) ); case ComponentType.RemoteProcessGroup: return of(FlowActions.openNewRemoteProcessGroupDialog({ request })); @@ -278,10 +285,12 @@ export class FlowEffects { return FlowActions.openImportFromRegistryDialog({ request: dialogRequest }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => + of(this.snackBarOrFullScreenError(errorResponse)) + ) ); default: - return of(FlowActions.flowApiError({ error: 'Unsupported type of Component.' })); + return of(FlowActions.flowSnackbarError({ error: 'Unsupported type of Component.' })); } }) ) @@ -326,7 +335,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -345,6 +354,7 @@ export class FlowEffects { }) .afterClosed() .subscribe(() => { + this.store.dispatch(ErrorActions.clearBannerErrors()); this.store.dispatch(FlowActions.setDragging({ dragging: false })); }); }) @@ -367,7 +377,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -447,10 +457,10 @@ export class FlowEffects { } }); }), - catchError((error) => { + catchError((errorResponse: HttpErrorResponse) => { this.store.dispatch(FlowActions.stopRemoteProcessGroupPolling()); - return of(FlowActions.flowApiError({ error: error.error })); + return of(this.snackBarOrFullScreenError(errorResponse)); }) ) ) @@ -471,6 +481,7 @@ export class FlowEffects { }) .afterClosed() .subscribe(() => { + this.store.dispatch(ErrorActions.clearBannerErrors()); this.store.dispatch(FlowActions.setDragging({ dragging: false })); }); }) @@ -493,7 +504,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -514,7 +525,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -542,7 +553,7 @@ export class FlowEffects { request: dialogRequest }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -584,7 +595,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -633,7 +644,7 @@ export class FlowEffects { tap({ error: (errorResponse: HttpErrorResponse) => { this.canvasUtils.removeTempEdge(); - this.store.dispatch(FlowActions.flowSnackbarError({ error: errorResponse.error })); + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)); } }) ) @@ -660,7 +671,7 @@ export class FlowEffects { dialogReference.afterClosed().subscribe(() => { this.canvasUtils.removeTempEdge(); - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); }); }) ), @@ -682,7 +693,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -702,7 +713,7 @@ export class FlowEffects { .afterClosed() .subscribe(() => { this.store.dispatch(FlowActions.setDragging({ dragging: false })); - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); }); }) ), @@ -724,7 +735,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -745,7 +756,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -766,7 +777,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -821,6 +832,7 @@ export class FlowEffects { dialogReference.afterClosed().subscribe(() => { this.store.dispatch(FlowActions.setDragging({ dragging: false })); + this.store.dispatch(ErrorActions.clearBannerErrors()); }); } else { this.dialog @@ -855,7 +867,7 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ) ) ) @@ -1057,7 +1069,7 @@ export class FlowEffects { case ComponentType.Label: return of(FlowActions.openEditLabelDialog({ request })); default: - return of(FlowActions.flowApiError({ error: 'Unsupported type of Component.' })); + return of(FlowActions.flowSnackbarError({ error: 'Unsupported type of Component.' })); } }) ) @@ -1078,13 +1090,7 @@ export class FlowEffects { } }) ), - catchError((error) => - of( - FlowActions.flowApiError({ - error: error.error - }) - ) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -1103,7 +1109,7 @@ export class FlowEffects { }) .afterClosed() .subscribe(() => { - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); this.store.dispatch( FlowActions.selectComponents({ request: { @@ -1135,7 +1141,7 @@ export class FlowEffects { }) .afterClosed() .subscribe(() => { - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); this.store.dispatch( FlowActions.selectComponents({ request: { @@ -1185,7 +1191,7 @@ export class FlowEffects { } }) ); - this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)); } }) ) @@ -1258,8 +1264,8 @@ export class FlowEffects { ]; goTo(commands, 'Controller Service'); }, - error: () => { - // TODO - handle error + error: (errorResponse: HttpErrorResponse) => { + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)); } }); }; @@ -1282,6 +1288,7 @@ export class FlowEffects { uri: request.uri, type: request.type, payload: updateProcessorRequest.payload, + errorStrategy: 'banner', postUpdateNavigation: updateProcessorRequest.postUpdateNavigation } }) @@ -1289,7 +1296,7 @@ export class FlowEffects { }); editDialogReference.afterClosed().subscribe((response) => { - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); if (response != 'ROUTED') { this.store.dispatch( @@ -1361,7 +1368,7 @@ export class FlowEffects { }); } - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); this.store.dispatch( FlowActions.selectComponents({ request: { @@ -1410,14 +1417,15 @@ export class FlowEffects { id: request.entity.id, uri: request.uri, type: request.type, - payload + payload, + errorStrategy: 'banner' } }) ); }); editDialogReference.afterClosed().subscribe(() => { - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); if (request.entity.id === currentProcessGroupId) { this.store.dispatch( FlowActions.enterProcessGroup({ @@ -1480,14 +1488,15 @@ export class FlowEffects { id: request.entity.id, uri: request.uri, type: request.type, - payload + payload, + errorStrategy: 'banner' } }) ); }); editDialogReference.afterClosed().subscribe((response) => { - this.store.dispatch(FlowActions.clearFlowApiError()); + this.store.dispatch(ErrorActions.clearBannerErrors()); if (response != 'ROUTED') { this.store.dispatch( @@ -1525,12 +1534,13 @@ export class FlowEffects { }; return FlowActions.updateComponentSuccess({ response: updateComponentResponse }); }), - catchError((error) => { + catchError((errorResponse: HttpErrorResponse) => { const updateComponentFailure: UpdateComponentFailure = { id: request.id, type: request.type, + errorStrategy: request.errorStrategy, restoreOnFailure: request.restoreOnFailure, - error: error.error + errorResponse }; return of(FlowActions.updateComponentFailure({ response: updateComponentFailure })); }) @@ -1560,7 +1570,13 @@ export class FlowEffects { this.actions$.pipe( ofType(FlowActions.updateComponentFailure), map((action) => action.response), - switchMap((response) => of(FlowActions.flowApiError({ error: response.error }))) + switchMap((response) => { + if (response.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(response.errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(response.errorResponse)); + } + }) ) ); @@ -1580,12 +1596,13 @@ export class FlowEffects { }; return FlowActions.updateProcessorSuccess({ response: updateComponentResponse }); }), - catchError((error) => { + catchError((errorResponse: HttpErrorResponse) => { const updateComponentFailure: UpdateComponentFailure = { id: request.id, type: request.type, + errorStrategy: request.errorStrategy, restoreOnFailure: request.restoreOnFailure, - error: error.error + errorResponse }; return of(FlowActions.updateComponentFailure({ response: updateComponentFailure })); }) @@ -1638,7 +1655,7 @@ export class FlowEffects { } }); }), - catchError((error) => of(FlowActions.flowApiError({ error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -1693,7 +1710,7 @@ export class FlowEffects { } }); }), - catchError((error) => of(FlowActions.flowApiError({ error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -1713,7 +1730,7 @@ export class FlowEffects { } }); }), - catchError((error) => of(FlowActions.flowApiError({ error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -1733,7 +1750,7 @@ export class FlowEffects { } }); }), - catchError((error) => of(FlowActions.flowApiError({ error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -1755,7 +1772,7 @@ export class FlowEffects { }; return FlowActions.updateConnectionSuccess({ response: updateComponentResponse }); }), - catchError((error) => { + catchError((errorResponse: HttpErrorResponse) => { this.connectionManager.renderConnection(request.id, { updatePath: true, updateLabel: false @@ -1764,8 +1781,9 @@ export class FlowEffects { const updateComponentFailure: UpdateComponentFailure = { id: request.id, type: request.type, + errorStrategy: request.errorStrategy, restoreOnFailure: request.restoreOnFailure, - error: error.error + errorResponse }; return of(FlowActions.updateComponentFailure({ response: updateComponentFailure })); }) @@ -1896,7 +1914,7 @@ export class FlowEffects { response: deleteResponses }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -1962,7 +1980,7 @@ export class FlowEffects { this.snippetService.copySnippet(response.snippet.id, pasteLocation, processGroupId) ).pipe(map((response) => FlowActions.pasteSuccess({ response }))); }), - catchError((error) => of(FlowActions.flowSnackbarError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -2085,7 +2103,9 @@ export class FlowEffects { response: deleteResponses }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => + of(this.snackBarOrFullScreenError(errorResponse)) + ) ); } else { const snippet: Snippet = requests.reduce( @@ -2161,7 +2181,9 @@ export class FlowEffects { response: deleteResponses }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => + of(this.snackBarOrFullScreenError(errorResponse)) + ) ); } }) @@ -2405,11 +2427,11 @@ export class FlowEffects { }) ); }, - error: (error) => { + error: (errorResponse: HttpErrorResponse) => { this.store.dispatch( FlowActions.showOkDialog({ title: 'Failed to Replay Event', - message: error.error + message: errorResponse.error }) ); } @@ -2445,7 +2467,8 @@ export class FlowEffects { FlowActions.enableComponent({ request: { id: pgId, - type: ComponentType.ProcessGroup + type: ComponentType.ProcessGroup, + errorStrategy: 'snackbar' } }) ); @@ -2486,9 +2509,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); } return of( @@ -2506,9 +2533,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); default: return of( @@ -2562,7 +2593,8 @@ export class FlowEffects { FlowActions.disableComponent({ request: { id: pgId, - type: ComponentType.ProcessGroup + type: ComponentType.ProcessGroup, + errorStrategy: 'snackbar' } }) ); @@ -2603,9 +2635,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); } return of( @@ -2623,9 +2659,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); default: return of( @@ -2679,7 +2719,8 @@ export class FlowEffects { FlowActions.startComponent({ request: { id: pgId, - type: ComponentType.ProcessGroup + type: ComponentType.ProcessGroup, + errorStrategy: 'snackbar' } }) ); @@ -2721,9 +2762,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); } return of( @@ -2744,9 +2789,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); default: return of( @@ -2800,7 +2849,8 @@ export class FlowEffects { FlowActions.stopComponent({ request: { id: pgId, - type: ComponentType.ProcessGroup + type: ComponentType.ProcessGroup, + errorStrategy: 'snackbar' } }) ); @@ -2842,9 +2892,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); } return of( @@ -2865,9 +2919,13 @@ export class FlowEffects { } }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + if (request.errorStrategy === 'banner') { + return of(this.bannerOrFullScreenError(errorResponse)); + } else { + return of(this.snackBarOrFullScreenError(errorResponse)); + } + }) ); default: return of( @@ -2896,13 +2954,7 @@ export class FlowEffects { } }) ), - catchError((errorResponse: HttpErrorResponse) => - of( - FlowActions.flowSnackbarError({ - error: errorResponse.error - }) - ) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -2955,10 +3007,9 @@ export class FlowEffects { } }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); - }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + }) ) ); @@ -2973,7 +3024,7 @@ export class FlowEffects { response }) ), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -3001,7 +3052,7 @@ export class FlowEffects { return FlowActions.openSaveVersionDialog({ request: dialogRequest }); }), - catchError((error) => of(FlowActions.flowSnackbarError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -3083,7 +3134,7 @@ export class FlowEffects { map((response) => { return FlowActions.saveToFlowRegistrySuccess({ response }); }), - catchError((error) => of(FlowActions.flowVersionBannerError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.bannerOrFullScreenError(errorResponse))) ); }) ) @@ -3099,17 +3150,47 @@ export class FlowEffects { ) ); - flowVersionBannerError$ = createEffect(() => + flowBannerError$ = createEffect(() => this.actions$.pipe( - ofType(FlowActions.flowVersionBannerError), + ofType(FlowActions.flowBannerError), map((action) => action.error), switchMap((error) => of(ErrorActions.addBannerError({ error }))) ) ); + flowSnackbarError$ = createEffect(() => + this.actions$.pipe( + ofType(FlowActions.flowSnackbarError), + map((action) => action.error), + tap(() => { + this.dialog.closeAll(); + }), + switchMap((error) => of(ErrorActions.snackBarError({ error }))) + ) + ); + + private bannerOrFullScreenError(errorResponse: HttpErrorResponse) { + if (this.errorHelper.showErrorInContext(errorResponse.status)) { + return FlowActions.flowBannerError({ + error: errorResponse.error + }); + } else { + return ErrorActions.fullScreenError(errorResponse.error); + } + } + + private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) { + if (this.errorHelper.showErrorInContext(errorResponse.status)) { + return FlowActions.flowSnackbarError({ error: errorResponse.error }); + } else { + return ErrorActions.fullScreenError(errorResponse.error); + } + } + ///////////////////////////////// // Stop version control effects ///////////////////////////////// + stopVersionControlRequest$ = createEffect( () => this.actions$.pipe( @@ -3143,7 +3224,7 @@ export class FlowEffects { dialogRef.close(); }); }), - catchError((error) => of(FlowActions.flowSnackbarError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ), { dispatch: false } ); @@ -3161,7 +3242,7 @@ export class FlowEffects { }; return FlowActions.stopVersionControlSuccess({ response: stopResponse }); }), - catchError((errorResponse) => of(FlowActions.flowSnackbarError({ error: errorResponse.error }))) + catchError((errorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -3185,6 +3266,7 @@ export class FlowEffects { ///////////////////////////////// // Commit local changes effects ///////////////////////////////// + openCommitLocalChangesDialogRequest$ = createEffect(() => this.actions$.pipe( ofType(FlowActions.openCommitLocalChangesDialogRequest), @@ -3201,7 +3283,7 @@ export class FlowEffects { return FlowActions.openSaveVersionDialog({ request: dialogRequest }); }), - catchError((error) => of(FlowActions.flowApiError({ error: error.error }))) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -3244,6 +3326,7 @@ export class FlowEffects { ///////////////////////////// // Change version effects ///////////////////////////// + openChangeVersionDialogRequest$ = createEffect(() => this.actions$.pipe( ofType(FlowActions.openChangeVersionDialogRequest), @@ -3252,7 +3335,7 @@ export class FlowEffects { from(this.flowService.getVersionInformation(request.processGroupId)).pipe( tap({ error: (errorResponse: HttpErrorResponse) => - this.store.dispatch(FlowActions.flowSnackbarError({ error: errorResponse.error })) + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)) }) ) ), @@ -3272,7 +3355,7 @@ export class FlowEffects { }) ), catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) + of(this.snackBarOrFullScreenError(errorResponse)) ) ); } else { @@ -3338,9 +3421,7 @@ export class FlowEffects { switchMap((request) => { return from(this.flowService.initiateChangeVersionUpdate(request)).pipe( map((flowUpdate) => FlowActions.changeVersionSuccess({ response: flowUpdate })), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -3378,7 +3459,7 @@ export class FlowEffects { this.flowService.getChangeVersionUpdateRequest(changeVersionRequest.request.requestId).pipe( map((response) => FlowActions.pollChangeVersionSuccess({ response })), catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) + of(this.snackBarOrFullScreenError(errorResponse)) ) ) ); @@ -3402,28 +3483,16 @@ export class FlowEffects { switchMap((response) => from(this.flowService.deleteChangeVersionUpdateRequest(response.request.requestId)).pipe( map(() => FlowActions.reloadFlow()), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) ); - flowSnackbarError$ = createEffect(() => - this.actions$.pipe( - ofType(FlowActions.flowSnackbarError), - map((action) => action.error), - tap(() => { - this.dialog.closeAll(); - }), - switchMap((error) => of(ErrorActions.snackBarError({ error }))) - ) - ); - /////////////////////////////// // Show local changes effects /////////////////////////////// + openLocalChangesDialogRequest = (mode: 'SHOW' | 'REVERT') => createEffect(() => this.actions$.pipe( @@ -3448,7 +3517,7 @@ export class FlowEffects { }) ), catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) + of(this.snackBarOrFullScreenError(errorResponse)) ) ) ) @@ -3525,9 +3594,7 @@ export class FlowEffects { switchMap((request) => { return from(this.flowService.initiateRevertFlowVersion(request)).pipe( map((flowUpdate) => FlowActions.revertChangesSuccess({ response: flowUpdate })), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ); }) ) @@ -3565,7 +3632,7 @@ export class FlowEffects { this.flowService.getRevertChangesUpdateRequest(changeVersionRequest.request.requestId).pipe( map((response) => FlowActions.pollRevertChangesSuccess({ response })), catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) + of(this.snackBarOrFullScreenError(errorResponse)) ) ) ); @@ -3589,9 +3656,7 @@ export class FlowEffects { switchMap((response) => from(this.flowService.deleteRevertChangesUpdateRequest(response.request.requestId)).pipe( map(() => FlowActions.reloadFlow()), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => of(this.snackBarOrFullScreenError(errorResponse))) ) ) ) @@ -3627,7 +3692,8 @@ export class FlowEffects { id: request.id, zIndex: maxZIndex + 1 } - } + }, + errorStrategy: 'snackbar' }; return from(this.flowService.updateComponent(updateRequest)).pipe( @@ -3639,9 +3705,16 @@ export class FlowEffects { }; return FlowActions.updateComponentSuccess({ response: updateResponse }); }), - catchError((errorResponse: HttpErrorResponse) => - of(FlowActions.flowSnackbarError({ error: errorResponse.error })) - ) + catchError((errorResponse: HttpErrorResponse) => { + const updateComponentFailure: UpdateComponentFailure = { + id: updateRequest.id, + type: updateRequest.type, + errorStrategy: updateRequest.errorStrategy, + restoreOnFailure: updateRequest.restoreOnFailure, + errorResponse + }; + return of(FlowActions.updateComponentFailure({ response: updateComponentFailure })); + }) ); }) ) @@ -3663,7 +3736,7 @@ export class FlowEffects { ), tap({ error: (errorResponse: HttpErrorResponse) => { - this.store.dispatch(FlowActions.flowSnackbarError({ error: errorResponse.error })); + this.store.dispatch(this.snackBarOrFullScreenError(errorResponse)); } }) ) @@ -3687,7 +3760,8 @@ export class FlowEffects { id: request.fetchRequest.id }, revision: request.fetchRequest.revision - } + }, + errorStrategy: 'snackbar' } }) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts index 3ce6560e2fe46..962ae96966cd3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.reducer.ts @@ -19,7 +19,6 @@ import { createReducer, on } from '@ngrx/store'; import { changeVersionComplete, changeVersionSuccess, - clearFlowApiError, copySuccess, createComponentComplete, createComponentSuccess, @@ -36,8 +35,8 @@ import { enableComponent, enableComponentSuccess, enableProcessGroupSuccess, - flowApiError, - flowVersionBannerError, + flowBannerError, + flowSnackbarError, groupComponents, groupComponentsSuccess, loadChildProcessGroupSuccess, @@ -163,7 +162,6 @@ export const initialState: FlowState = { allowTransition: false, navigationCollapsed: false, operationCollapsed: false, - error: null, status: 'pending' }; @@ -244,17 +242,11 @@ export const flowReducer = createReducer( } }); }), - on(flowApiError, (state, { error }) => ({ + on(flowBannerError, flowSnackbarError, (state) => ({ ...state, dragging: false, saving: false, - error: error, - status: 'error' as const - })), - on(clearFlowApiError, (state) => ({ - ...state, - error: null, - status: 'pending' as const + versionSaving: false })), on( createProcessor, @@ -449,7 +441,6 @@ export const flowReducer = createReducer( }); } ), - on(runOnceSuccess, (state, { response }) => { return produce(state, (draftState) => { const collection: any[] | null = getComponentCollection(draftState, ComponentType.Processor); @@ -528,10 +519,6 @@ export const flowReducer = createReducer( on(changeVersionComplete, revertChangesComplete, (state) => ({ ...state, changeVersionRequest: null - })), - on(flowVersionBannerError, (state) => ({ - ...state, - versionSaving: false })) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts index 536b5378f8ec1..88f99b1f6f5aa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/flow.selectors.ts @@ -30,10 +30,6 @@ export const selectChangeVersionRequest = createSelector( (state: FlowState) => state.changeVersionRequest ); -export const selectFlow = createSelector(selectFlowState, (state: FlowState) => state.flow); - -export const selectApiError = createSelector(selectFlowState, (state: FlowState) => state.error); - export const selectSaving = createSelector(selectFlowState, (state: FlowState) => state.saving); export const selectVersionSaving = createSelector(selectFlowState, (state: FlowState) => state.versionSaving); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts index 53d89209a8449..f3cf7e11b129e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/state/flow/index.ts @@ -31,6 +31,7 @@ import { VersionedFlowSnapshotMetadataEntity } from '../../../../state/shared'; import { ParameterContextEntity } from '../../../parameter-contexts/state/parameter-context-listing'; +import { HttpErrorResponse } from '@angular/common/http'; export const flowFeatureKey = 'flowState'; @@ -395,6 +396,7 @@ export interface UpdateComponentRequest { type: ComponentType; uri: string; payload: any; + errorStrategy: 'snackbar' | 'banner'; restoreOnFailure?: any; postUpdateNavigation?: string[]; } @@ -408,9 +410,10 @@ export interface UpdateComponentResponse { } export interface UpdateComponentFailure { - error: string; + errorResponse: HttpErrorResponse; id: string; type: ComponentType; + errorStrategy: 'snackbar' | 'banner'; restoreOnFailure?: any; } @@ -639,11 +642,10 @@ export interface FlowState { saving: boolean; navigationCollapsed: boolean; operationCollapsed: boolean; - error: string | null; versionSaving: boolean; changeVersionRequest: FlowUpdateRequestEntity | null; copiedSnippet: CopiedSnippet | null; - status: 'pending' | 'loading' | 'error' | 'success'; + status: 'pending' | 'loading' | 'success'; } export interface RunOnceRequest { @@ -658,6 +660,7 @@ export interface RunOnceResponse { export interface EnableProcessGroupRequest { id: string; type: ComponentType; + errorStrategy: 'snackbar' | 'banner'; } export interface EnableComponentRequest { @@ -665,6 +668,7 @@ export interface EnableComponentRequest { uri: string; type: ComponentType; revision: Revision; + errorStrategy: 'snackbar' | 'banner'; } export interface EnableComponentsRequest { @@ -687,6 +691,7 @@ export interface EnableProcessGroupResponse { export interface DisableProcessGroupRequest { id: string; type: ComponentType; + errorStrategy: 'snackbar' | 'banner'; } export interface DisableComponentRequest { @@ -694,6 +699,7 @@ export interface DisableComponentRequest { uri: string; type: ComponentType; revision: Revision; + errorStrategy: 'snackbar' | 'banner'; } export interface DisableComponentsRequest { @@ -716,6 +722,7 @@ export interface DisableProcessGroupResponse { export interface StartProcessGroupRequest { id: string; type: ComponentType; + errorStrategy: 'snackbar' | 'banner'; } export interface StartComponentRequest { @@ -723,6 +730,7 @@ export interface StartComponentRequest { uri: string; type: ComponentType; revision: Revision; + errorStrategy: 'snackbar' | 'banner'; } export interface StartComponentsRequest { @@ -767,11 +775,13 @@ export interface StopComponentRequest { uri: string; type: ComponentType; revision: Revision; + errorStrategy: 'snackbar' | 'banner'; } export interface StopProcessGroupRequest { id: string; type: ComponentType; + errorStrategy: 'snackbar' | 'banner'; } export interface StopComponentResponse { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts index 42bdbdcd560d9..295af07d6a31d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/graph-controls/operation-control/operation-control.component.ts @@ -289,7 +289,8 @@ export class OperationControl { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -318,7 +319,8 @@ export class OperationControl { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -347,7 +349,8 @@ export class OperationControl { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( @@ -376,7 +379,8 @@ export class OperationControl { id: d.id, uri: d.uri, type: d.type, - revision: this.client.getRevision(d) + revision: this.client.getRevision(d), + errorStrategy: 'snackbar' }); }); this.store.dispatch( diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts index 6a42dc247ad77..04a476f6ca149 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/header/new-canvas-item/new-canvas-item.component.ts @@ -97,26 +97,11 @@ export class NewCanvasItem { } }) ); + } else { + this.store.dispatch(setDragging({ dragging: false })); } // reset dragging state event.source._dragRef.reset(); } - - /** - * TODO - Improve drag boundary by computing the drag render position... - * - * [cdkDragConstrainPosition]="computeDragRenderPos.bind(this)" - * - * @param pos - * @param dragRef - */ - // computeDragRenderPos(pos: any, dragRef: any) { - // const canvasContainer: any = document.getElementById('canvas-container'); - // const rect = canvasContainer.getBoundingClientRect(); - // return { - // x: pos.x, - // y: pos.y < rect.y ? rect.y : pos.y - // } - // } } diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.html index 2ddddf9350aaf..82a73182ecd03 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.html @@ -18,6 +18,7 @@

Create Connection

@if (breadcrumbs$ | async; as breadcrumbs) {
+ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts index f0207890b7083..020368e86fc06 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/create-connection/create-connection.component.ts @@ -57,6 +57,7 @@ import { DestinationRemoteProcessGroup } from '../destination/destination-remote import { BreadcrumbEntity } from '../../../../../state/shared'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; import { CanvasUtils } from '../../../../../service/canvas-utils.service'; +import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; @Component({ selector: 'create-connection', @@ -85,7 +86,8 @@ import { CanvasUtils } from '../../../../../service/canvas-utils.service'; SourceProcessGroup, DestinationProcessGroup, SourceRemoteProcessGroup, - DestinationRemoteProcessGroup + DestinationRemoteProcessGroup, + ErrorBanner ], templateUrl: './create-connection.component.html', styleUrls: ['./create-connection.component.scss'] diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.html index 889881b1c3b49..18d1c4edc12c3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.html @@ -19,6 +19,7 @@

{{ connectionReadonly || sourceReadonly || destinationReadonly ? 'Connection Details' : 'Edit Connection' }}

+ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts index 6db35840894bd..bd2e1b53ad1b2 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/connection/edit-connection/edit-connection.component.ts @@ -55,6 +55,7 @@ import { DestinationProcessGroup } from '../destination/destination-process-grou import { SourceRemoteProcessGroup } from '../source/source-remote-process-group/source-remote-process-group.component'; import { DestinationRemoteProcessGroup } from '../destination/destination-remote-process-group/destination-remote-process-group.component'; import { BreadcrumbEntity } from '../../../../../state/shared'; +import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; @Component({ selector: 'edit-connection', @@ -83,7 +84,8 @@ import { BreadcrumbEntity } from '../../../../../state/shared'; SourceProcessGroup, DestinationProcessGroup, SourceRemoteProcessGroup, - DestinationRemoteProcessGroup + DestinationRemoteProcessGroup, + ErrorBanner ], templateUrl: './edit-connection.component.html', styleUrls: ['./edit-connection.component.scss'] @@ -414,7 +416,8 @@ export class EditConnectionComponent { type: ComponentType.Connection, uri: this.dialogRequest.entity.uri, previousDestination: this.previousDestination, - payload + payload, + errorStrategy: 'banner' } }) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts index abf2ed0ce9123..116c24719fe8e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/label/edit-label/edit-label.component.ts @@ -108,7 +108,8 @@ export class EditLabel { id: this.request.entity.id, type: this.request.type, uri: this.request.uri, - payload + payload, + errorStrategy: 'banner' } }) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts index 26c0f30dae2af..69ffb16ba0421 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/port/edit-port/edit-port.component.ts @@ -120,7 +120,8 @@ export class EditPort { id: this.request.entity.id, type: this.request.type, uri: this.request.uri, - payload + payload, + errorStrategy: 'banner' } }) ); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.html b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.html index 8951c4f941e1a..281baba1c30e4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.html +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.html @@ -17,6 +17,7 @@

{{ readonly ? 'Process Group Details' : 'Edit Process Group' }}

+ diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts index 2d4086c000dca..1a1eaffe4e48e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.spec.ts @@ -21,6 +21,8 @@ import { EditProcessGroup } from './edit-process-group.component'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; +import { provideMockStore } from '@ngrx/store/testing'; +import { initialState } from '../../../../../state/flow/flow.reducer'; describe('EditProcessGroup', () => { let component: EditProcessGroup; @@ -110,6 +112,7 @@ describe('EditProcessGroup', () => { imports: [EditProcessGroup, NoopAnimationsModule], providers: [ { provide: MAT_DIALOG_DATA, useValue: data }, + provideMockStore({ initialState }), { provide: ClusterConnectionService, useValue: { diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts index 252b328c4ee85..da70e2efdb951 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-frontend/src/main/nifi/src/app/pages/flow-designer/ui/canvas/items/process-group/edit-process-group/edit-process-group.component.ts @@ -36,6 +36,7 @@ import { ParameterContextEntity } from '../../../../../../parameter-contexts/sta import { ControllerServiceTable } from '../../../../../../../ui/common/controller-service/controller-service-table/controller-service-table.component'; import { EditComponentDialogRequest } from '../../../../../state/flow'; import { ClusterConnectionService } from '../../../../../../../service/cluster-connection.service'; +import { ErrorBanner } from '../../../../../../../ui/common/error-banner/error-banner.component'; @Component({ selector: 'edit-process-group', @@ -55,7 +56,8 @@ import { ClusterConnectionService } from '../../../../../../../service/cluster-c NifiSpinnerDirective, NifiTooltipDirective, FormsModule, - ControllerServiceTable + ControllerServiceTable, + ErrorBanner ], styleUrls: ['./edit-process-group.component.scss'] })