mirror of https://github.com/apache/nifi.git
[NIFI-13099] status history error handling (#8703)
* [NIFI-13099] - Error handling for Status History * Error handling for current user * Error handling for extension types * Error handling for flow configuration * Error handling for component state * Error handling for cluster summary * Error handling for System Diagnostics * review feedback * use SystemDiagnosticsActions.systemDiagnosticsSnackbarError * review feedback * review feedback * use snackbar This closes #8703
This commit is contained in:
parent
a230eba67b
commit
658e83b7ec
|
@ -21,7 +21,7 @@
|
||||||
</header>
|
</header>
|
||||||
<div class="px-5 flex-1 flex flex-col gap-y-2">
|
<div class="px-5 flex-1 flex flex-col gap-y-2">
|
||||||
<h3 class="text-xl bold primary-color">NiFi Cluster</h3>
|
<h3 class="text-xl bold primary-color">NiFi Cluster</h3>
|
||||||
|
<error-banner></error-banner>
|
||||||
@if (getTabLinks(); as tabs) {
|
@if (getTabLinks(); as tabs) {
|
||||||
<!-- Don't show the tab bar if there is only 1 tab to show -->
|
<!-- Don't show the tab bar if there is only 1 tab to show -->
|
||||||
<div class="cluster-tabs" [class.hidden]="tabs.length === 1">
|
<div class="cluster-tabs" [class.hidden]="tabs.length === 1">
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { CurrentUser } from '../../../state/current-user';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
import { selectCurrentRoute } from '../../../state/router/router.selectors';
|
import { selectCurrentRoute } from '../../../state/router/router.selectors';
|
||||||
import { resetSystemDiagnostics } from '../../../state/system-diagnostics/system-diagnostics.actions';
|
import { resetSystemDiagnostics } from '../../../state/system-diagnostics/system-diagnostics.actions';
|
||||||
|
import { clearBannerErrors } from '../../../state/error/error.actions';
|
||||||
|
|
||||||
interface TabLink {
|
interface TabLink {
|
||||||
label: string;
|
label: string;
|
||||||
|
@ -82,6 +83,7 @@ export class Cluster implements OnInit, OnDestroy {
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.store.dispatch(resetClusterState());
|
this.store.dispatch(resetClusterState());
|
||||||
this.store.dispatch(resetSystemDiagnostics());
|
this.store.dispatch(resetSystemDiagnostics());
|
||||||
|
this.store.dispatch(clearBannerErrors());
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { ClusterListingEffects } from '../state/cluster-listing/cluster-listing.
|
||||||
import { ClusterRoutingModule } from './cluster-routing.module';
|
import { ClusterRoutingModule } from './cluster-routing.module';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
import { MatIconButton } from '@angular/material/button';
|
import { MatIconButton } from '@angular/material/button';
|
||||||
|
import { ErrorBanner } from '../../../ui/common/error-banner/error-banner.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Cluster],
|
declarations: [Cluster],
|
||||||
|
@ -37,7 +38,8 @@ import { MatIconButton } from '@angular/material/button';
|
||||||
StoreModule.forFeature(clusterFeatureKey, reducers),
|
StoreModule.forFeature(clusterFeatureKey, reducers),
|
||||||
EffectsModule.forFeature(ClusterListingEffects),
|
EffectsModule.forFeature(ClusterListingEffects),
|
||||||
MatTabsModule,
|
MatTabsModule,
|
||||||
MatIconButton
|
MatIconButton,
|
||||||
|
ErrorBanner
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ClusterModule {}
|
export class ClusterModule {}
|
||||||
|
|
|
@ -16,14 +16,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Actions, concatLatestFrom, createEffect, ofType } from '@ngrx/effects';
|
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
import { ActionCreator, Creator, Store } from '@ngrx/store';
|
import { ActionCreator, Creator, Store } from '@ngrx/store';
|
||||||
import { NiFiState } from '../../../../state';
|
import { NiFiState } from '../../../../state';
|
||||||
import { ErrorHelper } from '../../../../service/error-helper.service';
|
import { ErrorHelper } from '../../../../service/error-helper.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import * as ClusterListingActions from './cluster-listing.actions';
|
import * as ClusterListingActions from './cluster-listing.actions';
|
||||||
import { catchError, from, map, of, switchMap, take, tap } from 'rxjs';
|
import { catchError, filter, from, map, of, switchMap, take, tap } from 'rxjs';
|
||||||
import { SystemDiagnosticsService } from '../../../../service/system-diagnostics.service';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { selectClusterListingStatus } from './cluster-listing.selectors';
|
import { selectClusterListingStatus } from './cluster-listing.selectors';
|
||||||
import { reloadSystemDiagnostics } from '../../../../state/system-diagnostics/system-diagnostics.actions';
|
import { reloadSystemDiagnostics } from '../../../../state/system-diagnostics/system-diagnostics.actions';
|
||||||
|
@ -35,6 +34,7 @@ import { ClusterNodeDetailDialog } from '../../ui/cluster-node-listing/cluster-n
|
||||||
import * as ErrorActions from '../../../../state/error/error.actions';
|
import * as ErrorActions from '../../../../state/error/error.actions';
|
||||||
import { SelectClusterNodeRequest } from './index';
|
import { SelectClusterNodeRequest } from './index';
|
||||||
import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors';
|
import { selectCurrentUser } from '../../../../state/current-user/current-user.selectors';
|
||||||
|
import { concatLatestFrom } from '@ngrx/operators';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ClusterListingEffects {
|
export class ClusterListingEffects {
|
||||||
|
@ -43,7 +43,6 @@ export class ClusterListingEffects {
|
||||||
private store: Store<NiFiState>,
|
private store: Store<NiFiState>,
|
||||||
private errorHelper: ErrorHelper,
|
private errorHelper: ErrorHelper,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private systemDiagnosticsService: SystemDiagnosticsService,
|
|
||||||
private clusterService: ClusterService,
|
private clusterService: ClusterService,
|
||||||
private dialog: MatDialog
|
private dialog: MatDialog
|
||||||
) {}
|
) {}
|
||||||
|
@ -51,12 +50,6 @@ export class ClusterListingEffects {
|
||||||
loadClusterListing$ = createEffect(() =>
|
loadClusterListing$ = createEffect(() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(ClusterListingActions.loadClusterListing),
|
ofType(ClusterListingActions.loadClusterListing),
|
||||||
concatLatestFrom(() => this.store.select(selectCurrentUser)),
|
|
||||||
tap(([, currentUser]) => {
|
|
||||||
if (currentUser.systemPermissions.canRead) {
|
|
||||||
this.store.dispatch(reloadSystemDiagnostics({ request: { nodewise: true } }));
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
concatLatestFrom(() => [this.store.select(selectClusterListingStatus)]),
|
concatLatestFrom(() => [this.store.select(selectClusterListingStatus)]),
|
||||||
switchMap(([, listingStatus]) =>
|
switchMap(([, listingStatus]) =>
|
||||||
from(this.clusterService.getClusterListing()).pipe(
|
from(this.clusterService.getClusterListing()).pipe(
|
||||||
|
@ -69,6 +62,22 @@ export class ClusterListingEffects {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
loadClusterListingSuccess$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(ClusterListingActions.loadClusterListingSuccess),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentUser)),
|
||||||
|
filter(([, currentUser]) => currentUser.systemPermissions.canRead),
|
||||||
|
map(() =>
|
||||||
|
reloadSystemDiagnostics({
|
||||||
|
request: {
|
||||||
|
nodewise: true,
|
||||||
|
errorStrategy: 'banner'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
confirmAndDisconnectNode$ = createEffect(
|
confirmAndDisconnectNode$ = createEffect(
|
||||||
() =>
|
() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
|
|
|
@ -41,13 +41,6 @@ export const setDisconnectionAcknowledged = createAction(
|
||||||
props<{ disconnectionAcknowledged: boolean }>()
|
props<{ disconnectionAcknowledged: boolean }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
export const clusterSummaryApiError = createAction(
|
|
||||||
`${CLUSTER_SUMMARY_STATE_PREFIX} Cluster Summary Api Error`,
|
|
||||||
props<{ error: string }>()
|
|
||||||
);
|
|
||||||
|
|
||||||
export const clearClusterSummaryApiError = createAction(`${CLUSTER_SUMMARY_STATE_PREFIX} Clear About Api Error`);
|
|
||||||
|
|
||||||
export const searchCluster = createAction(
|
export const searchCluster = createAction(
|
||||||
`${CLUSTER_SUMMARY_STATE_PREFIX} Search Cluster`,
|
`${CLUSTER_SUMMARY_STATE_PREFIX} Search Cluster`,
|
||||||
props<{ request: ClusterSearchRequest }>()
|
props<{ request: ClusterSearchRequest }>()
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
import { concatLatestFrom } from '@ngrx/operators';
|
import { concatLatestFrom } from '@ngrx/operators';
|
||||||
import * as ClusterSummaryActions from './cluster-summary.actions';
|
import * as ClusterSummaryActions from './cluster-summary.actions';
|
||||||
|
import { acknowledgeClusterConnectionChange, setDisconnectionAcknowledged } from './cluster-summary.actions';
|
||||||
import { asyncScheduler, catchError, delay, filter, from, interval, map, of, switchMap, takeUntil, tap } from 'rxjs';
|
import { asyncScheduler, catchError, delay, filter, from, interval, map, of, switchMap, takeUntil, tap } from 'rxjs';
|
||||||
import { ClusterService } from '../../service/cluster.service';
|
import { ClusterService } from '../../service/cluster.service';
|
||||||
import { selectClusterSummary } from './cluster-summary.selectors';
|
import { selectClusterSummary } from './cluster-summary.selectors';
|
||||||
|
@ -27,7 +28,6 @@ import { Store } from '@ngrx/store';
|
||||||
import { ClusterSummary, ClusterSummaryState } from './index';
|
import { ClusterSummary, ClusterSummaryState } from './index';
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import * as ErrorActions from '../error/error.actions';
|
import * as ErrorActions from '../error/error.actions';
|
||||||
import { acknowledgeClusterConnectionChange, setDisconnectionAcknowledged } from './cluster-summary.actions';
|
|
||||||
import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component';
|
import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component';
|
||||||
import { MEDIUM_DIALOG } from '../../index';
|
import { MEDIUM_DIALOG } from '../../index';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
@ -66,7 +66,15 @@ export class ClusterSummaryEffects {
|
||||||
response
|
response
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((error) => of(ClusterSummaryActions.clusterSummaryApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(
|
||||||
|
ErrorActions.snackBarError({
|
||||||
|
error: `Failed to load cluster summary - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -138,7 +146,13 @@ export class ClusterSummaryEffects {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((errorResponse: HttpErrorResponse) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(ErrorActions.snackBarError({ error: errorResponse.error }))
|
of(
|
||||||
|
ErrorActions.snackBarError({
|
||||||
|
error: `Failed to search cluster summary - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
|
})
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import { ClusterSummaryState } from './index';
|
import { ClusterSummaryState } from './index';
|
||||||
import {
|
import {
|
||||||
clearClusterSummaryApiError,
|
|
||||||
clusterSummaryApiError,
|
|
||||||
loadClusterSummary,
|
loadClusterSummary,
|
||||||
loadClusterSummarySuccess,
|
loadClusterSummarySuccess,
|
||||||
searchClusterSuccess,
|
searchClusterSuccess,
|
||||||
|
@ -30,7 +28,6 @@ export const initialState: ClusterSummaryState = {
|
||||||
disconnectionAcknowledged: false,
|
disconnectionAcknowledged: false,
|
||||||
clusterSummary: null,
|
clusterSummary: null,
|
||||||
searchResults: null,
|
searchResults: null,
|
||||||
error: null,
|
|
||||||
status: 'pending'
|
status: 'pending'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,19 +40,8 @@ export const clusterSummaryReducer = createReducer(
|
||||||
on(loadClusterSummarySuccess, (state, { response }) => ({
|
on(loadClusterSummarySuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
clusterSummary: response.clusterSummary,
|
clusterSummary: response.clusterSummary,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
})),
|
||||||
on(clusterSummaryApiError, (state, { error }) => ({
|
|
||||||
...state,
|
|
||||||
error,
|
|
||||||
status: 'error' as const
|
|
||||||
})),
|
|
||||||
on(clearClusterSummaryApiError, (state) => ({
|
|
||||||
...state,
|
|
||||||
error: null,
|
|
||||||
status: 'pending' as const
|
|
||||||
})),
|
|
||||||
on(searchClusterSuccess, (state, { response }) => ({
|
on(searchClusterSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
searchResults: response
|
searchResults: response
|
||||||
|
|
|
@ -46,6 +46,5 @@ export interface ClusterSummaryState {
|
||||||
disconnectionAcknowledged: boolean;
|
disconnectionAcknowledged: boolean;
|
||||||
clusterSummary: ClusterSummary | null;
|
clusterSummary: ClusterSummary | null;
|
||||||
searchResults: ClusterSearchResults | null;
|
searchResults: ClusterSearchResults | null;
|
||||||
error: string | null;
|
status: 'pending' | 'loading' | 'success';
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,6 @@ export const loadComponentStateSuccess = createAction(
|
||||||
|
|
||||||
export const openComponentStateDialog = createAction(`${COMPONENT_STATE_PREFIX} Open Component State Dialog`);
|
export const openComponentStateDialog = createAction(`${COMPONENT_STATE_PREFIX} Open Component State Dialog`);
|
||||||
|
|
||||||
export const componentStateApiError = createAction(
|
|
||||||
`${COMPONENT_STATE_PREFIX} Component State API error`,
|
|
||||||
props<{ error: string }>()
|
|
||||||
);
|
|
||||||
|
|
||||||
export const clearComponentState = createAction(`${COMPONENT_STATE_PREFIX} Clear Component State`);
|
export const clearComponentState = createAction(`${COMPONENT_STATE_PREFIX} Clear Component State`);
|
||||||
|
|
||||||
export const reloadComponentState = createAction(`${COMPONENT_STATE_PREFIX} Reload Component State`);
|
export const reloadComponentState = createAction(`${COMPONENT_STATE_PREFIX} Reload Component State`);
|
||||||
|
|
|
@ -21,14 +21,16 @@ import { concatLatestFrom } from '@ngrx/operators';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { NiFiState } from '../index';
|
import { NiFiState } from '../index';
|
||||||
import * as ComponentStateActions from './component-state.actions';
|
import * as ComponentStateActions from './component-state.actions';
|
||||||
|
import { resetComponentState } from './component-state.actions';
|
||||||
import { catchError, from, map, of, switchMap, tap } from 'rxjs';
|
import { catchError, from, map, of, switchMap, tap } from 'rxjs';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ComponentStateService } from '../../service/component-state.service';
|
import { ComponentStateService } from '../../service/component-state.service';
|
||||||
import { ComponentStateDialog } from '../../ui/common/component-state/component-state.component';
|
import { ComponentStateDialog } from '../../ui/common/component-state/component-state.component';
|
||||||
import { resetComponentState } from './component-state.actions';
|
|
||||||
import { selectComponentUri } from './component-state.selectors';
|
import { selectComponentUri } from './component-state.selectors';
|
||||||
import { isDefinedAndNotNull } from '../shared';
|
import { isDefinedAndNotNull } from '../shared';
|
||||||
import { LARGE_DIALOG } from '../../index';
|
import { LARGE_DIALOG } from '../../index';
|
||||||
|
import * as ErrorActions from '../error/error.actions';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ComponentStateEffects {
|
export class ComponentStateEffects {
|
||||||
|
@ -53,10 +55,12 @@ export class ComponentStateEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
of(
|
||||||
ComponentStateActions.componentStateApiError({
|
ErrorActions.snackBarError({
|
||||||
error: error.error
|
error: `Failed to get the component state for ${request.componentName}. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -99,10 +103,12 @@ export class ComponentStateEffects {
|
||||||
from(
|
from(
|
||||||
this.componentStateService.clearComponentState({ componentUri }).pipe(
|
this.componentStateService.clearComponentState({ componentUri }).pipe(
|
||||||
map(() => ComponentStateActions.reloadComponentState()),
|
map(() => ComponentStateActions.reloadComponentState()),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
of(
|
||||||
ComponentStateActions.componentStateApiError({
|
ErrorActions.addBannerError({
|
||||||
error: error.error
|
error: `Failed to clear the component state. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -126,10 +132,12 @@ export class ComponentStateEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
of(
|
||||||
ComponentStateActions.componentStateApiError({
|
ErrorActions.addBannerError({
|
||||||
error: error.error
|
error: `Failed to reload the component state. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,11 +18,10 @@
|
||||||
import { ComponentStateState } from './index';
|
import { ComponentStateState } from './index';
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
resetComponentState,
|
|
||||||
loadComponentStateSuccess,
|
|
||||||
componentStateApiError,
|
|
||||||
getComponentStateAndOpenDialog,
|
getComponentStateAndOpenDialog,
|
||||||
reloadComponentStateSuccess
|
loadComponentStateSuccess,
|
||||||
|
reloadComponentStateSuccess,
|
||||||
|
resetComponentState
|
||||||
} from './component-state.actions';
|
} from './component-state.actions';
|
||||||
|
|
||||||
export const initialState: ComponentStateState = {
|
export const initialState: ComponentStateState = {
|
||||||
|
@ -30,8 +29,7 @@ export const initialState: ComponentStateState = {
|
||||||
componentUri: null,
|
componentUri: null,
|
||||||
componentState: null,
|
componentState: null,
|
||||||
canClear: null,
|
canClear: null,
|
||||||
status: 'pending',
|
status: 'pending'
|
||||||
error: null
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const componentStateReducer = createReducer(
|
export const componentStateReducer = createReducer(
|
||||||
|
@ -45,15 +43,9 @@ export const componentStateReducer = createReducer(
|
||||||
})),
|
})),
|
||||||
on(loadComponentStateSuccess, reloadComponentStateSuccess, (state, { response }) => ({
|
on(loadComponentStateSuccess, reloadComponentStateSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
error: null,
|
|
||||||
status: 'success' as const,
|
status: 'success' as const,
|
||||||
componentState: response.componentState
|
componentState: response.componentState
|
||||||
})),
|
})),
|
||||||
on(componentStateApiError, (state, { error }) => ({
|
|
||||||
...state,
|
|
||||||
error,
|
|
||||||
status: 'error' as const
|
|
||||||
})),
|
|
||||||
on(resetComponentState, () => ({
|
on(resetComponentState, () => ({
|
||||||
...initialState
|
...initialState
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -66,6 +66,5 @@ export interface ComponentStateState {
|
||||||
componentUri: string | null;
|
componentUri: string | null;
|
||||||
componentState: ComponentState | null;
|
componentState: ComponentState | null;
|
||||||
canClear: boolean | null;
|
canClear: boolean | null;
|
||||||
error: string | null;
|
status: 'pending' | 'loading' | 'success';
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,6 @@ export const loadCurrentUserSuccess = createAction(
|
||||||
props<{ response: LoadCurrentUserResponse }>()
|
props<{ response: LoadCurrentUserResponse }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
export const currentUserApiError = createAction('[Current User] Current User Api Error', props<{ error: string }>());
|
|
||||||
|
|
||||||
export const clearCurrentUserApiError = createAction('[Current User] Clear Current User Api Error');
|
|
||||||
|
|
||||||
export const startCurrentUserPolling = createAction('[Current User] Start Current User Polling');
|
export const startCurrentUserPolling = createAction('[Current User] Start Current User Polling');
|
||||||
|
|
||||||
export const stopCurrentUserPolling = createAction('[Current User] Stop Current User Polling');
|
export const stopCurrentUserPolling = createAction('[Current User] Stop Current User Polling');
|
||||||
|
|
|
@ -20,12 +20,14 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
import * as UserActions from './current-user.actions';
|
import * as UserActions from './current-user.actions';
|
||||||
import { asyncScheduler, catchError, from, interval, map, of, switchMap, takeUntil } from 'rxjs';
|
import { asyncScheduler, catchError, from, interval, map, of, switchMap, takeUntil } from 'rxjs';
|
||||||
import { CurrentUserService } from '../../service/current-user.service';
|
import { CurrentUserService } from '../../service/current-user.service';
|
||||||
|
import { ErrorHelper } from '../../service/error-helper.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CurrentUserEffects {
|
export class CurrentUserEffects {
|
||||||
constructor(
|
constructor(
|
||||||
private actions$: Actions,
|
private actions$: Actions,
|
||||||
private userService: CurrentUserService
|
private userService: CurrentUserService,
|
||||||
|
private errorHelper: ErrorHelper
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
loadCurrentUser$ = createEffect(() =>
|
loadCurrentUser$ = createEffect(() =>
|
||||||
|
@ -41,7 +43,7 @@ export class CurrentUserEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) => of(UserActions.currentUserApiError({ error: error.error })))
|
catchError((error) => of(this.errorHelper.fullScreenError(error)))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,12 +18,7 @@
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import { CurrentUserState } from './index';
|
import { CurrentUserState } from './index';
|
||||||
import { Permissions } from '../shared';
|
import { Permissions } from '../shared';
|
||||||
import {
|
import { loadCurrentUser, loadCurrentUserSuccess } from './current-user.actions';
|
||||||
clearCurrentUserApiError,
|
|
||||||
loadCurrentUser,
|
|
||||||
loadCurrentUserSuccess,
|
|
||||||
currentUserApiError
|
|
||||||
} from './current-user.actions';
|
|
||||||
|
|
||||||
export const NO_PERMISSIONS: Permissions = {
|
export const NO_PERMISSIONS: Permissions = {
|
||||||
canRead: false,
|
canRead: false,
|
||||||
|
@ -45,7 +40,6 @@ export const initialState: CurrentUserState = {
|
||||||
tenantsPermissions: NO_PERMISSIONS,
|
tenantsPermissions: NO_PERMISSIONS,
|
||||||
componentRestrictionPermissions: []
|
componentRestrictionPermissions: []
|
||||||
},
|
},
|
||||||
error: null,
|
|
||||||
status: 'pending'
|
status: 'pending'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,17 +52,6 @@ export const currentUserReducer = createReducer(
|
||||||
on(loadCurrentUserSuccess, (state, { response }) => ({
|
on(loadCurrentUserSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
user: response.user,
|
user: response.user,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
|
||||||
on(currentUserApiError, (state, { error }) => ({
|
|
||||||
...state,
|
|
||||||
error: error,
|
|
||||||
status: 'error' as const
|
|
||||||
})),
|
|
||||||
on(clearCurrentUserApiError, (state) => ({
|
|
||||||
...state,
|
|
||||||
error: null,
|
|
||||||
status: 'pending' as const
|
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
|
@ -45,6 +45,5 @@ export interface CurrentUser {
|
||||||
|
|
||||||
export interface CurrentUserState {
|
export interface CurrentUserState {
|
||||||
user: CurrentUser;
|
user: CurrentUser;
|
||||||
error: string | null;
|
status: 'pending' | 'loading' | 'success';
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
LoadExtensionTypesForPoliciesResponse,
|
LoadExtensionTypesForPoliciesResponse,
|
||||||
LoadExtensionTypesForSettingsResponse
|
LoadExtensionTypesForSettingsResponse
|
||||||
} from './index';
|
} from './index';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
export const loadExtensionTypesForCanvas = createAction('[Extension Types] Load Extension Types For Canvas');
|
export const loadExtensionTypesForCanvas = createAction('[Extension Types] Load Extension Types For Canvas');
|
||||||
|
|
||||||
|
@ -45,7 +46,5 @@ export const loadExtensionTypesForPoliciesSuccess = createAction(
|
||||||
|
|
||||||
export const extensionTypesApiError = createAction(
|
export const extensionTypesApiError = createAction(
|
||||||
'[Extension Types] Extension Types Api Error',
|
'[Extension Types] Extension Types Api Error',
|
||||||
props<{ error: string }>()
|
props<{ error: HttpErrorResponse }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
export const clearExtensionTypesApiError = createAction('[Extension Types] Clear Extension Types Api Error');
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
import * as ExtensionTypesActions from './extension-types.actions';
|
import * as ExtensionTypesActions from './extension-types.actions';
|
||||||
import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
|
import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
|
||||||
import { ExtensionTypesService } from '../../service/extension-types.service';
|
import { ExtensionTypesService } from '../../service/extension-types.service';
|
||||||
|
import * as ErrorActions from '../error/error.actions';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExtensionTypesEffects {
|
export class ExtensionTypesEffects {
|
||||||
|
@ -46,7 +48,7 @@ export class ExtensionTypesEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) => of(ExtensionTypesActions.extensionTypesApiError({ error: error.error })))
|
catchError((error) => of(ExtensionTypesActions.extensionTypesApiError({ error })))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -81,7 +83,7 @@ export class ExtensionTypesEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) => of(ExtensionTypesActions.extensionTypesApiError({ error: error.error })))
|
catchError((error) => of(ExtensionTypesActions.extensionTypesApiError({ error })))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -116,7 +118,25 @@ export class ExtensionTypesEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) => of(ExtensionTypesActions.extensionTypesApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(ExtensionTypesActions.extensionTypesApiError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
extensionTypesApiError$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(ExtensionTypesActions.extensionTypesApiError),
|
||||||
|
map((action) => action.error),
|
||||||
|
switchMap((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(
|
||||||
|
ErrorActions.snackBarError({
|
||||||
|
error: `Failed to load extension types. You may not be able to create new Processors, Controller Services, Reporting Tasks, Parameter Providers, or Flow Analysis Rules. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import { ExtensionTypesState } from './index';
|
import { ExtensionTypesState } from './index';
|
||||||
import {
|
import {
|
||||||
clearExtensionTypesApiError,
|
|
||||||
extensionTypesApiError,
|
|
||||||
loadExtensionTypesForCanvas,
|
loadExtensionTypesForCanvas,
|
||||||
loadExtensionTypesForCanvasSuccess,
|
loadExtensionTypesForCanvasSuccess,
|
||||||
loadExtensionTypesForPoliciesSuccess,
|
loadExtensionTypesForPoliciesSuccess,
|
||||||
|
@ -34,7 +32,6 @@ export const initialState: ExtensionTypesState = {
|
||||||
registryClientTypes: [],
|
registryClientTypes: [],
|
||||||
flowAnalysisRuleTypes: [],
|
flowAnalysisRuleTypes: [],
|
||||||
parameterProviderTypes: [],
|
parameterProviderTypes: [],
|
||||||
error: null,
|
|
||||||
status: 'pending'
|
status: 'pending'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,7 +46,6 @@ export const extensionTypesReducer = createReducer(
|
||||||
processorTypes: response.processorTypes,
|
processorTypes: response.processorTypes,
|
||||||
controllerServiceTypes: response.controllerServiceTypes,
|
controllerServiceTypes: response.controllerServiceTypes,
|
||||||
prioritizerTypes: response.prioritizers,
|
prioritizerTypes: response.prioritizers,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
})),
|
||||||
on(loadExtensionTypesForSettingsSuccess, (state, { response }) => ({
|
on(loadExtensionTypesForSettingsSuccess, (state, { response }) => ({
|
||||||
|
@ -59,7 +55,6 @@ export const extensionTypesReducer = createReducer(
|
||||||
registryClientTypes: response.registryClientTypes,
|
registryClientTypes: response.registryClientTypes,
|
||||||
parameterProviderTypes: response.parameterProviderTypes,
|
parameterProviderTypes: response.parameterProviderTypes,
|
||||||
flowAnalysisRuleTypes: response.flowAnalysisRuleTypes,
|
flowAnalysisRuleTypes: response.flowAnalysisRuleTypes,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
})),
|
||||||
on(loadExtensionTypesForPoliciesSuccess, (state, { response }) => ({
|
on(loadExtensionTypesForPoliciesSuccess, (state, { response }) => ({
|
||||||
|
@ -69,17 +64,6 @@ export const extensionTypesReducer = createReducer(
|
||||||
reportingTaskTypes: response.reportingTaskTypes,
|
reportingTaskTypes: response.reportingTaskTypes,
|
||||||
parameterProviderTypes: response.parameterProviderTypes,
|
parameterProviderTypes: response.parameterProviderTypes,
|
||||||
flowAnalysisRuleTypes: response.flowAnalysisRuleTypes,
|
flowAnalysisRuleTypes: response.flowAnalysisRuleTypes,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
|
||||||
on(extensionTypesApiError, (state, { error }) => ({
|
|
||||||
...state,
|
|
||||||
error: error,
|
|
||||||
status: 'error' as const
|
|
||||||
})),
|
|
||||||
on(clearExtensionTypesApiError, (state) => ({
|
|
||||||
...state,
|
|
||||||
error: null,
|
|
||||||
status: 'pending' as const
|
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,6 +49,5 @@ export interface ExtensionTypesState {
|
||||||
registryClientTypes: DocumentedType[];
|
registryClientTypes: DocumentedType[];
|
||||||
flowAnalysisRuleTypes: DocumentedType[];
|
flowAnalysisRuleTypes: DocumentedType[];
|
||||||
parameterProviderTypes: DocumentedType[];
|
parameterProviderTypes: DocumentedType[];
|
||||||
error: string | null;
|
status: 'pending' | 'loading' | 'success';
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,3 @@ export const loadFlowConfigurationSuccess = createAction(
|
||||||
'[Flow Configuration] Load Flow Configuration Success',
|
'[Flow Configuration] Load Flow Configuration Success',
|
||||||
props<{ response: LoadFlowConfigurationResponse }>()
|
props<{ response: LoadFlowConfigurationResponse }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
export const flowConfigurationApiError = createAction(
|
|
||||||
'[Flow Configuration] Flow Configuration Api Error',
|
|
||||||
props<{ error: string }>()
|
|
||||||
);
|
|
||||||
|
|
||||||
export const flowConfigurationAboutApiError = createAction('[Flow Configuration] Clear Flow Configuration Api Error');
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||||
import * as FlowConfigurationActions from './flow-configuration.actions';
|
import * as FlowConfigurationActions from './flow-configuration.actions';
|
||||||
import { catchError, from, map, of, switchMap } from 'rxjs';
|
import { catchError, from, map, of, switchMap } from 'rxjs';
|
||||||
import { FlowConfigurationService } from '../../service/flow-configuration.service';
|
import { FlowConfigurationService } from '../../service/flow-configuration.service';
|
||||||
|
import * as ErrorActions from '../error/error.actions';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FlowConfigurationEffects {
|
export class FlowConfigurationEffects {
|
||||||
|
@ -39,8 +41,14 @@ export class FlowConfigurationEffects {
|
||||||
response
|
response
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(FlowConfigurationActions.flowConfigurationApiError({ error: error.error }))
|
of(
|
||||||
|
ErrorActions.snackBarError({
|
||||||
|
error: `Failed to load Flow Configuration. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
|
})
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,16 +17,10 @@
|
||||||
|
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import { FlowConfigurationState } from './index';
|
import { FlowConfigurationState } from './index';
|
||||||
import {
|
import { loadFlowConfiguration, loadFlowConfigurationSuccess } from './flow-configuration.actions';
|
||||||
flowConfigurationApiError,
|
|
||||||
flowConfigurationAboutApiError,
|
|
||||||
loadFlowConfiguration,
|
|
||||||
loadFlowConfigurationSuccess
|
|
||||||
} from './flow-configuration.actions';
|
|
||||||
|
|
||||||
export const initialState: FlowConfigurationState = {
|
export const initialState: FlowConfigurationState = {
|
||||||
flowConfiguration: null,
|
flowConfiguration: null,
|
||||||
error: null,
|
|
||||||
status: 'pending'
|
status: 'pending'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,17 +33,6 @@ export const flowConfigurationReducer = createReducer(
|
||||||
on(loadFlowConfigurationSuccess, (state, { response }) => ({
|
on(loadFlowConfigurationSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
flowConfiguration: response.flowConfiguration,
|
flowConfiguration: response.flowConfiguration,
|
||||||
error: null,
|
|
||||||
status: 'success' as const
|
status: 'success' as const
|
||||||
})),
|
|
||||||
on(flowConfigurationApiError, (state, { error }) => ({
|
|
||||||
...state,
|
|
||||||
error: error,
|
|
||||||
status: 'error' as const
|
|
||||||
})),
|
|
||||||
on(flowConfigurationAboutApiError, (state) => ({
|
|
||||||
...state,
|
|
||||||
error: null,
|
|
||||||
status: 'pending' as const
|
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
|
@ -34,6 +34,5 @@ export interface FlowConfiguration {
|
||||||
|
|
||||||
export interface FlowConfigurationState {
|
export interface FlowConfigurationState {
|
||||||
flowConfiguration: FlowConfiguration | null;
|
flowConfiguration: FlowConfiguration | null;
|
||||||
error: string | null;
|
status: 'pending' | 'loading' | 'success';
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,5 @@ export interface StatusHistoryResponse {
|
||||||
export interface StatusHistoryState {
|
export interface StatusHistoryState {
|
||||||
statusHistory: StatusHistoryEntity;
|
statusHistory: StatusHistoryEntity;
|
||||||
loadedTimestamp: string;
|
loadedTimestamp: string;
|
||||||
error: string | null;
|
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
status: 'pending' | 'loading' | 'error' | 'success';
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ export const openStatusHistoryDialog = createAction(
|
||||||
props<{ request: StatusHistoryRequest | NodeStatusHistoryRequest }>()
|
props<{ request: StatusHistoryRequest | NodeStatusHistoryRequest }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
export const statusHistoryApiError = createAction(
|
export const statusHistoryBannerError = createAction(
|
||||||
`${STATUS_HISTORY_PREFIX} Load Status History error`,
|
`${STATUS_HISTORY_PREFIX} Status History Banner Error`,
|
||||||
props<{ error: string }>()
|
props<{ error: string }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ import { StatusHistoryRequest } from './index';
|
||||||
import { catchError, filter, from, map, of, switchMap, tap } from 'rxjs';
|
import { catchError, filter, from, map, of, switchMap, tap } from 'rxjs';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { StatusHistory } from '../../ui/common/status-history/status-history.component';
|
import { StatusHistory } from '../../ui/common/status-history/status-history.component';
|
||||||
|
import * as ErrorActions from '../../state/error/error.actions';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { ErrorHelper } from '../../service/error-helper.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StatusHistoryEffects {
|
export class StatusHistoryEffects {
|
||||||
|
@ -32,7 +35,8 @@ export class StatusHistoryEffects {
|
||||||
private actions$: Actions,
|
private actions$: Actions,
|
||||||
private store: Store<NiFiState>,
|
private store: Store<NiFiState>,
|
||||||
private statusHistoryService: StatusHistoryService,
|
private statusHistoryService: StatusHistoryService,
|
||||||
private dialog: MatDialog
|
private dialog: MatDialog,
|
||||||
|
private errorHelper: ErrorHelper
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
reloadComponentStatusHistory$ = createEffect(() =>
|
reloadComponentStatusHistory$ = createEffect(() =>
|
||||||
|
@ -55,12 +59,8 @@ export class StatusHistoryEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
this.bannerOrFullScreenError(errorResponse)
|
||||||
StatusHistoryActions.statusHistoryApiError({
|
|
||||||
error: error.error
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -86,13 +86,7 @@ export class StatusHistoryEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) => this.bannerOrFullScreenError(errorResponse))
|
||||||
of(
|
|
||||||
StatusHistoryActions.statusHistoryApiError({
|
|
||||||
error: error.error
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -119,12 +113,8 @@ export class StatusHistoryEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
this.snackBarOrFullScreenError(errorResponse)
|
||||||
StatusHistoryActions.statusHistoryApiError({
|
|
||||||
error: error.error
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -150,13 +140,7 @@ export class StatusHistoryEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) => this.snackBarOrFullScreenError(errorResponse))
|
||||||
of(
|
|
||||||
StatusHistoryActions.statusHistoryApiError({
|
|
||||||
error: error.error
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -210,4 +194,30 @@ export class StatusHistoryEffects {
|
||||||
),
|
),
|
||||||
{ dispatch: false }
|
{ dispatch: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
statusHistoryBannerError$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(StatusHistoryActions.statusHistoryBannerError),
|
||||||
|
map((action) => action.error),
|
||||||
|
switchMap((error) => of(ErrorActions.addBannerError({ error })))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
private bannerOrFullScreenError(errorResponse: HttpErrorResponse) {
|
||||||
|
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
|
||||||
|
const error = `Failed to reload Status History. - [${errorResponse.error || errorResponse.status}]`;
|
||||||
|
return of(StatusHistoryActions.statusHistoryBannerError({ error }));
|
||||||
|
} else {
|
||||||
|
return of(ErrorActions.fullScreenError(errorResponse.error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) {
|
||||||
|
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
|
||||||
|
const error = `Failed to load Status History. - [${errorResponse.error || errorResponse.status}]`;
|
||||||
|
return of(ErrorActions.snackBarError({ error }));
|
||||||
|
} else {
|
||||||
|
return of(ErrorActions.fullScreenError(errorResponse.error));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,18 +19,18 @@ import { StatusHistoryEntity, StatusHistoryState } from './index';
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
clearStatusHistory,
|
clearStatusHistory,
|
||||||
reloadStatusHistory,
|
getStatusHistoryAndOpenDialog,
|
||||||
loadStatusHistorySuccess,
|
loadStatusHistorySuccess,
|
||||||
statusHistoryApiError,
|
reloadStatusHistory,
|
||||||
viewStatusHistoryComplete,
|
|
||||||
reloadStatusHistorySuccess,
|
reloadStatusHistorySuccess,
|
||||||
getStatusHistoryAndOpenDialog
|
statusHistoryBannerError,
|
||||||
|
viewNodeStatusHistoryComplete,
|
||||||
|
viewStatusHistoryComplete
|
||||||
} from './status-history.actions';
|
} from './status-history.actions';
|
||||||
|
|
||||||
export const initialState: StatusHistoryState = {
|
export const initialState: StatusHistoryState = {
|
||||||
statusHistory: {} as StatusHistoryEntity,
|
statusHistory: {} as StatusHistoryEntity,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
error: null,
|
|
||||||
loadedTimestamp: ''
|
loadedTimestamp: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,15 +44,13 @@ export const statusHistoryReducer = createReducer(
|
||||||
|
|
||||||
on(loadStatusHistorySuccess, reloadStatusHistorySuccess, (state, { response }) => ({
|
on(loadStatusHistorySuccess, reloadStatusHistorySuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
error: null,
|
|
||||||
status: 'success' as const,
|
status: 'success' as const,
|
||||||
loadedTimestamp: response.statusHistory.statusHistory.generated,
|
loadedTimestamp: response.statusHistory.statusHistory.generated,
|
||||||
statusHistory: response.statusHistory
|
statusHistory: response.statusHistory
|
||||||
})),
|
})),
|
||||||
|
|
||||||
on(statusHistoryApiError, (state, { error }) => ({
|
on(statusHistoryBannerError, (state) => ({
|
||||||
...state,
|
...state,
|
||||||
error,
|
|
||||||
status: 'error' as const
|
status: 'error' as const
|
||||||
})),
|
})),
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ export const statusHistoryReducer = createReducer(
|
||||||
...initialState
|
...initialState
|
||||||
})),
|
})),
|
||||||
|
|
||||||
on(viewStatusHistoryComplete, () => ({
|
on(viewStatusHistoryComplete, viewNodeStatusHistoryComplete, () => ({
|
||||||
...initialState
|
...initialState
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
|
@ -91,6 +91,7 @@ export interface SystemDiagnosticSnapshot {
|
||||||
|
|
||||||
export interface SystemDiagnosticsRequest {
|
export interface SystemDiagnosticsRequest {
|
||||||
nodewise: boolean;
|
nodewise: boolean;
|
||||||
|
errorStrategy?: 'banner' | 'snackbar';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemDiagnosticsResponse {
|
export interface SystemDiagnosticsResponse {
|
||||||
|
@ -100,7 +101,6 @@ export interface SystemDiagnosticsResponse {
|
||||||
export interface SystemDiagnosticsState {
|
export interface SystemDiagnosticsState {
|
||||||
systemDiagnostics: SystemDiagnostics | null;
|
systemDiagnostics: SystemDiagnostics | null;
|
||||||
loadedTimestamp: string;
|
loadedTimestamp: string;
|
||||||
error: string | null;
|
|
||||||
status: 'pending' | 'loading' | 'error' | 'success';
|
status: 'pending' | 'loading' | 'error' | 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,13 @@ export const getSystemDiagnosticsAndOpenDialog = createAction(
|
||||||
|
|
||||||
export const openSystemDiagnosticsDialog = createAction(`${SYSTEM_DIAGNOSTICS_PREFIX} Open System Diagnostics Dialog`);
|
export const openSystemDiagnosticsDialog = createAction(`${SYSTEM_DIAGNOSTICS_PREFIX} Open System Diagnostics Dialog`);
|
||||||
|
|
||||||
export const systemDiagnosticsApiError = createAction(
|
export const systemDiagnosticsSnackbarError = createAction(
|
||||||
`${SYSTEM_DIAGNOSTICS_PREFIX} Load System Diagnostics Error`,
|
`${SYSTEM_DIAGNOSTICS_PREFIX} Load System Diagnostics Snackbar Error`,
|
||||||
|
props<{ error: string }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const systemDiagnosticsBannerError = createAction(
|
||||||
|
`${SYSTEM_DIAGNOSTICS_PREFIX} Load System Diagnostics Banner Error`,
|
||||||
props<{ error: string }>()
|
props<{ error: string }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@ import { catchError, from, map, of, switchMap, tap } from 'rxjs';
|
||||||
import { SystemDiagnosticsRequest } from './index';
|
import { SystemDiagnosticsRequest } from './index';
|
||||||
import { SystemDiagnosticsDialog } from '../../ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component';
|
import { SystemDiagnosticsDialog } from '../../ui/common/system-diagnostics-dialog/system-diagnostics-dialog.component';
|
||||||
import { LARGE_DIALOG } from '../../index';
|
import { LARGE_DIALOG } from '../../index';
|
||||||
|
import * as ErrorActions from '../error/error.actions';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemDiagnosticsEffects {
|
export class SystemDiagnosticsEffects {
|
||||||
|
@ -49,13 +51,24 @@ export class SystemDiagnosticsEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) => {
|
||||||
of(
|
if (request.errorStrategy === 'snackbar') {
|
||||||
SystemDiagnosticsActions.systemDiagnosticsApiError({
|
return of(
|
||||||
error: error.error
|
SystemDiagnosticsActions.systemDiagnosticsSnackbarError({
|
||||||
|
error: `Failed to reload System Diagnostics. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return of(
|
||||||
|
SystemDiagnosticsActions.systemDiagnosticsBannerError({
|
||||||
|
error: `Failed to reload System Diagnostics. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
)
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -74,10 +87,12 @@ export class SystemDiagnosticsEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((error) =>
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
of(
|
of(
|
||||||
SystemDiagnosticsActions.systemDiagnosticsApiError({
|
SystemDiagnosticsActions.systemDiagnosticsSnackbarError({
|
||||||
error: error.error
|
error: `Failed to load System Diagnostics. - [${
|
||||||
|
errorResponse.error || errorResponse.status
|
||||||
|
}]`
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -110,4 +125,20 @@ export class SystemDiagnosticsEffects {
|
||||||
),
|
),
|
||||||
{ dispatch: false }
|
{ dispatch: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
systemDiagnosticsBannerError$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(SystemDiagnosticsActions.systemDiagnosticsBannerError),
|
||||||
|
map((action) => action.error),
|
||||||
|
switchMap((error) => of(ErrorActions.addBannerError({ error })))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
systemDiagnosticsSnackbarError$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(SystemDiagnosticsActions.systemDiagnosticsSnackbarError),
|
||||||
|
map((action) => action.error),
|
||||||
|
switchMap((error) => of(ErrorActions.snackBarError({ error })))
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,19 @@
|
||||||
import { SystemDiagnosticsState } from './index';
|
import { SystemDiagnosticsState } from './index';
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
reloadSystemDiagnostics,
|
|
||||||
loadSystemDiagnosticsSuccess,
|
|
||||||
resetSystemDiagnostics,
|
|
||||||
systemDiagnosticsApiError,
|
|
||||||
viewSystemDiagnosticsComplete,
|
|
||||||
getSystemDiagnosticsAndOpenDialog,
|
getSystemDiagnosticsAndOpenDialog,
|
||||||
reloadSystemDiagnosticsSuccess
|
loadSystemDiagnosticsSuccess,
|
||||||
|
reloadSystemDiagnostics,
|
||||||
|
reloadSystemDiagnosticsSuccess,
|
||||||
|
resetSystemDiagnostics,
|
||||||
|
systemDiagnosticsBannerError,
|
||||||
|
systemDiagnosticsSnackbarError,
|
||||||
|
viewSystemDiagnosticsComplete
|
||||||
} from './system-diagnostics.actions';
|
} from './system-diagnostics.actions';
|
||||||
|
|
||||||
export const initialSystemDiagnosticsState: SystemDiagnosticsState = {
|
export const initialSystemDiagnosticsState: SystemDiagnosticsState = {
|
||||||
systemDiagnostics: null,
|
systemDiagnostics: null,
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
error: null,
|
|
||||||
loadedTimestamp: ''
|
loadedTimestamp: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,15 +44,13 @@ export const systemDiagnosticsReducer = createReducer(
|
||||||
|
|
||||||
on(loadSystemDiagnosticsSuccess, reloadSystemDiagnosticsSuccess, (state, { response }) => ({
|
on(loadSystemDiagnosticsSuccess, reloadSystemDiagnosticsSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
error: null,
|
|
||||||
status: 'success' as const,
|
status: 'success' as const,
|
||||||
loadedTimestamp: response.systemDiagnostics.aggregateSnapshot.statsLastRefreshed,
|
loadedTimestamp: response.systemDiagnostics.aggregateSnapshot.statsLastRefreshed,
|
||||||
systemDiagnostics: response.systemDiagnostics
|
systemDiagnostics: response.systemDiagnostics
|
||||||
})),
|
})),
|
||||||
|
|
||||||
on(systemDiagnosticsApiError, (state, { error }) => ({
|
on(systemDiagnosticsBannerError, systemDiagnosticsSnackbarError, (state) => ({
|
||||||
...state,
|
...state,
|
||||||
error,
|
|
||||||
status: 'error' as const
|
status: 'error' as const
|
||||||
})),
|
})),
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,6 @@ export const selectSystemDiagnosticsLoadedTimestamp = createSelector(
|
||||||
(state: SystemDiagnosticsState) => state.loadedTimestamp
|
(state: SystemDiagnosticsState) => state.loadedTimestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectSystemDiagnosticsError = createSelector(
|
|
||||||
selectSystemDiagnosticsState,
|
|
||||||
(state: SystemDiagnosticsState) => state.error
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectSystemDiagnosticsStatus = createSelector(
|
export const selectSystemDiagnosticsStatus = createSelector(
|
||||||
selectSystemDiagnosticsState,
|
selectSystemDiagnosticsState,
|
||||||
(state: SystemDiagnosticsState) => state.status
|
(state: SystemDiagnosticsState) => state.status
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
<div class="component-state-dialog" tabindex="0">
|
<div class="component-state-dialog" tabindex="0">
|
||||||
<h2 mat-dialog-title>Component State</h2>
|
<h2 mat-dialog-title>Component State</h2>
|
||||||
|
<error-banner></error-banner>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<div class="flex flex-col justify-between gap-y-5">
|
<div class="flex flex-col justify-between gap-y-5">
|
||||||
@if (componentName$ | async; as componentName) {
|
@if (componentName$ | async; as componentName) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AfterViewInit, Component, DestroyRef, inject, Input } from '@angular/core';
|
import { AfterViewInit, Component, DestroyRef, inject, Input, OnDestroy } from '@angular/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||||
|
@ -39,6 +39,8 @@ import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { selectClusterSummary } from '../../../state/cluster-summary/cluster-summary.selectors';
|
import { selectClusterSummary } from '../../../state/cluster-summary/cluster-summary.selectors';
|
||||||
|
import { ErrorBanner } from '../error-banner/error-banner.component';
|
||||||
|
import { clearBannerErrors } from '../../../state/error/error.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'component-state',
|
selector: 'component-state',
|
||||||
|
@ -54,11 +56,12 @@ import { selectClusterSummary } from '../../../state/cluster-summary/cluster-sum
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule
|
MatInputModule,
|
||||||
|
ErrorBanner
|
||||||
],
|
],
|
||||||
styleUrls: ['./component-state.component.scss']
|
styleUrls: ['./component-state.component.scss']
|
||||||
})
|
})
|
||||||
export class ComponentStateDialog implements AfterViewInit {
|
export class ComponentStateDialog implements AfterViewInit, OnDestroy {
|
||||||
@Input() initialSortColumn: 'key' | 'value' = 'key';
|
@Input() initialSortColumn: 'key' | 'value' = 'key';
|
||||||
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
@Input() initialSortDirection: 'asc' | 'desc' = 'asc';
|
||||||
|
|
||||||
|
@ -140,6 +143,10 @@ export class ComponentStateDialog implements AfterViewInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.store.dispatch(clearBannerErrors());
|
||||||
|
}
|
||||||
|
|
||||||
processStateMap(stateMap: StateMap, clusterState: boolean): StateItem[] {
|
processStateMap(stateMap: StateMap, clusterState: boolean): StateItem[] {
|
||||||
const stateEntries: StateEntry[] = stateMap.state ? stateMap.state : [];
|
const stateEntries: StateEntry[] = stateMap.state ? stateMap.state : [];
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<div resizable (resized)="resized()" [minHeight]="720" [minWidth]="887" class="flex flex-col status-history-container">
|
<div resizable (resized)="resized()" [minHeight]="720" [minWidth]="887" class="flex flex-col status-history-container">
|
||||||
@if (statusHistoryState$ | async; as statusHistoryState) {
|
@if (statusHistoryState$ | async; as statusHistoryState) {
|
||||||
<h2 mat-dialog-title>Status History</h2>
|
<h2 mat-dialog-title>Status History</h2>
|
||||||
|
<error-banner></error-banner>
|
||||||
<div class="status-history flex flex-col grow">
|
<div class="status-history flex flex-col grow">
|
||||||
<mat-dialog-content class="grow flex flex-1">
|
<mat-dialog-content class="grow flex flex-1">
|
||||||
<form [formGroup]="statusHistoryForm" class="flex flex-1 h-full">
|
<form [formGroup]="statusHistoryForm" class="flex flex-1 h-full">
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AfterViewInit, Component, DestroyRef, inject, Inject, OnInit } from '@angular/core';
|
import { AfterViewInit, Component, DestroyRef, inject, Inject, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||||
import { StatusHistoryService } from '../../../service/status-history.service';
|
import { StatusHistoryService } from '../../../service/status-history.service';
|
||||||
import { AsyncPipe, NgStyle } from '@angular/common';
|
import { AsyncPipe, NgStyle } from '@angular/common';
|
||||||
|
@ -51,6 +51,8 @@ import { Resizable } from '../resizable/resizable.component';
|
||||||
import { Instance, NIFI_NODE_CONFIG, Stats } from './index';
|
import { Instance, NIFI_NODE_CONFIG, Stats } from './index';
|
||||||
import { StatusHistoryChart } from './status-history-chart/status-history-chart.component';
|
import { StatusHistoryChart } from './status-history-chart/status-history-chart.component';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { ErrorBanner } from '../error-banner/error-banner.component';
|
||||||
|
import { clearBannerErrors } from '../../../state/error/error.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'status-history',
|
selector: 'status-history',
|
||||||
|
@ -68,11 +70,12 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
Resizable,
|
Resizable,
|
||||||
StatusHistoryChart,
|
StatusHistoryChart,
|
||||||
NgStyle
|
NgStyle,
|
||||||
|
ErrorBanner
|
||||||
],
|
],
|
||||||
styleUrls: ['./status-history.component.scss']
|
styleUrls: ['./status-history.component.scss']
|
||||||
})
|
})
|
||||||
export class StatusHistory implements OnInit, AfterViewInit {
|
export class StatusHistory implements OnInit, OnDestroy, AfterViewInit {
|
||||||
request: StatusHistoryRequest;
|
request: StatusHistoryRequest;
|
||||||
statusHistoryState$ = this.store.select(selectStatusHistoryState);
|
statusHistoryState$ = this.store.select(selectStatusHistoryState);
|
||||||
componentDetails$ = this.store.select(selectStatusHistoryComponentDetails);
|
componentDetails$ = this.store.select(selectStatusHistoryComponentDetails);
|
||||||
|
@ -197,6 +200,10 @@ export class StatusHistory implements OnInit, AfterViewInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.store.dispatch(clearBannerErrors());
|
||||||
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
// when the selected descriptor changes, update the chart
|
// when the selected descriptor changes, update the chart
|
||||||
this.statusHistoryForm
|
this.statusHistoryForm
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
@if ((systemDiagnostics$ | async)?.aggregateSnapshot; as systemDiagnostics) {
|
@if ((systemDiagnostics$ | async)?.aggregateSnapshot; as systemDiagnostics) {
|
||||||
<h2 mat-dialog-title>System Diagnostics</h2>
|
<h2 mat-dialog-title>System Diagnostics</h2>
|
||||||
|
<error-banner></error-banner>
|
||||||
<div class="system-diagnostics">
|
<div class="system-diagnostics">
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
import { MatTabsModule } from '@angular/material/tabs';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
@ -33,6 +33,8 @@ import { TextTip } from '../tooltips/text-tip/text-tip.component';
|
||||||
import { NifiTooltipDirective } from '../tooltips/nifi-tooltip.directive';
|
import { NifiTooltipDirective } from '../tooltips/nifi-tooltip.directive';
|
||||||
import { isDefinedAndNotNull } from '../../../state/shared';
|
import { isDefinedAndNotNull } from '../../../state/shared';
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
import { ErrorBanner } from '../error-banner/error-banner.component';
|
||||||
|
import { clearBannerErrors } from '../../../state/error/error.actions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'system-diagnostics-dialog',
|
selector: 'system-diagnostics-dialog',
|
||||||
|
@ -43,12 +45,13 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
NifiTooltipDirective,
|
NifiTooltipDirective,
|
||||||
MatProgressBarModule
|
MatProgressBarModule,
|
||||||
|
ErrorBanner
|
||||||
],
|
],
|
||||||
templateUrl: './system-diagnostics-dialog.component.html',
|
templateUrl: './system-diagnostics-dialog.component.html',
|
||||||
styleUrls: ['./system-diagnostics-dialog.component.scss']
|
styleUrls: ['./system-diagnostics-dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class SystemDiagnosticsDialog implements OnInit {
|
export class SystemDiagnosticsDialog implements OnInit, OnDestroy {
|
||||||
systemDiagnostics$ = this.store.select(selectSystemDiagnostics);
|
systemDiagnostics$ = this.store.select(selectSystemDiagnostics);
|
||||||
loadedTimestamp$ = this.store.select(selectSystemDiagnosticsLoadedTimestamp);
|
loadedTimestamp$ = this.store.select(selectSystemDiagnosticsLoadedTimestamp);
|
||||||
status$ = this.store.select(selectSystemDiagnosticsStatus);
|
status$ = this.store.select(selectSystemDiagnosticsStatus);
|
||||||
|
@ -69,11 +72,16 @@ export class SystemDiagnosticsDialog implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.store.dispatch(clearBannerErrors());
|
||||||
|
}
|
||||||
|
|
||||||
refreshSystemDiagnostics() {
|
refreshSystemDiagnostics() {
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
reloadSystemDiagnostics({
|
reloadSystemDiagnostics({
|
||||||
request: {
|
request: {
|
||||||
nodewise: false
|
nodewise: false,
|
||||||
|
errorStrategy: 'banner'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue