mirror of https://github.com/apache/nifi.git
[NIFI-13589] improve loading and error handling for jolt UI (#9155)
* [NIFI-13589] improve loading and error handling for jolt UI * remove unused state * cleanup more state * show errors in center of page This closes #9155
This commit is contained in:
parent
e46c7db1ec
commit
30e8df676e
|
@ -97,7 +97,7 @@
|
||||||
(codeMirrorLoaded)="initSpecEditor($event)"></ngx-codemirror>
|
(codeMirrorLoaded)="initSpecEditor($event)"></ngx-codemirror>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap">
|
<div class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap">
|
||||||
@if (joltState.validate().saving) {
|
@if (joltState.validate().loading) {
|
||||||
<i
|
<i
|
||||||
class="fa fa-refresh fa-spin mr-2"
|
class="fa fa-refresh fa-spin mr-2"
|
||||||
nifiTooltip
|
nifiTooltip
|
||||||
|
@ -293,7 +293,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 mt-2 justify-start">
|
<div class="flex flex-1 mt-2 justify-start">
|
||||||
<div class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap">
|
<div class="w-full overflow-ellipsis overflow-hidden whitespace-nowrap">
|
||||||
@if (joltState.transform().saving) {
|
@if (joltState.transform().loading) {
|
||||||
<i
|
<i
|
||||||
class="fa fa-refresh fa-spin mr-2"
|
class="fa fa-refresh fa-spin mr-2"
|
||||||
nifiTooltip
|
nifiTooltip
|
||||||
|
@ -381,9 +381,15 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="flex flex-1 justify-center items-center">
|
@if (processorDetailsLoading$ | async) {
|
||||||
<i class="fa fa-warning caution-color mr-2"></i>An error has occurred loading the editor.
|
<div class="h-full flex items-center justify-center">
|
||||||
</div>
|
<mat-spinner color="primary"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
} @else if (processorDetailsError()) {
|
||||||
|
<div class="flex flex-1 justify-center items-center">
|
||||||
|
<i class="fa fa-warning caution-color mr-2"></i>{{ processorDetailsError() }}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -26,6 +26,8 @@ import {
|
||||||
selectEditableFromRoute,
|
selectEditableFromRoute,
|
||||||
selectJoltTransformJsonProcessorDetailsState,
|
selectJoltTransformJsonProcessorDetailsState,
|
||||||
selectProcessorDetails,
|
selectProcessorDetails,
|
||||||
|
selectProcessorDetailsError,
|
||||||
|
selectProcessorDetailsLoading,
|
||||||
selectProcessorIdFromRoute,
|
selectProcessorIdFromRoute,
|
||||||
selectRevisionFromRoute
|
selectRevisionFromRoute
|
||||||
} from '../state/jolt-transform-json-processor-details/jolt-transform-json-processor-details.selectors';
|
} from '../state/jolt-transform-json-processor-details/jolt-transform-json-processor-details.selectors';
|
||||||
|
@ -84,6 +86,8 @@ export class JoltTransformJsonUi implements OnDestroy {
|
||||||
transform: this.store.selectSignal(selectJoltTransformJsonTransformState)
|
transform: this.store.selectSignal(selectJoltTransformJsonTransformState)
|
||||||
};
|
};
|
||||||
processorDetails$ = this.store.select(selectProcessorDetails);
|
processorDetails$ = this.store.select(selectProcessorDetails);
|
||||||
|
processorDetailsLoading$ = this.store.select(selectProcessorDetailsLoading);
|
||||||
|
processorDetailsError = this.store.selectSignal(selectProcessorDetailsError);
|
||||||
editable: boolean = false;
|
editable: boolean = false;
|
||||||
createNew: (existingEntries: string[]) => Observable<MapTableEntry> =
|
createNew: (existingEntries: string[]) => Observable<MapTableEntry> =
|
||||||
this.mapTableHelperService.createNewEntry('Attribute');
|
this.mapTableHelperService.createNewEntry('Attribute');
|
||||||
|
|
|
@ -39,6 +39,7 @@ import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
import { JoltTransformJsonTransformEffects } from '../state/jolt-transform-json-transform/jolt-transform-json-transform.effects';
|
import { JoltTransformJsonTransformEffects } from '../state/jolt-transform-json-transform/jolt-transform-json-transform.effects';
|
||||||
import { JoltTransformJsonValidateEffects } from '../state/jolt-transform-json-validate/jolt-transform-json-validate.effects';
|
import { JoltTransformJsonValidateEffects } from '../state/jolt-transform-json-validate/jolt-transform-json-validate.effects';
|
||||||
import { JoltTransformJsonPropertyEffects } from '../state/jolt-transform-json-property/jolt-transform-json-property.effects';
|
import { JoltTransformJsonPropertyEffects } from '../state/jolt-transform-json-property/jolt-transform-json-property.effects';
|
||||||
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [JoltTransformJsonUi],
|
declarations: [JoltTransformJsonUi],
|
||||||
|
@ -70,7 +71,8 @@ import { JoltTransformJsonPropertyEffects } from '../state/jolt-transform-json-p
|
||||||
ComponentContext,
|
ComponentContext,
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MapTable
|
MapTable,
|
||||||
|
MatProgressSpinnerModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class JoltTransformJsonUiModule {}
|
export class JoltTransformJsonUiModule {}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface JoltTransformJsonProcessorDetailsState {
|
export interface JoltTransformJsonProcessorDetailsState {
|
||||||
saving: boolean;
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
processorDetails: ProcessorDetails | null;
|
processorDetails: ProcessorDetails | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,5 +37,5 @@ export const loadProcessorDetailsSuccess = createAction(
|
||||||
|
|
||||||
export const loadProcessorDetailsFailure = createAction(
|
export const loadProcessorDetailsFailure = createAction(
|
||||||
`${JOLT_TRANSFORM_JSON_PROCESSOR_DETAILS_PREFIX} Load Processor Details Failure`,
|
`${JOLT_TRANSFORM_JSON_PROCESSOR_DETAILS_PREFIX} Load Processor Details Failure`,
|
||||||
props<{ response: HttpErrorResponse }>()
|
props<{ response: string }>()
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,9 +43,19 @@ export class JoltTransformJsonProcessorDetailsEffects {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
catchError((errorResponse: HttpErrorResponse) => {
|
catchError((errorResponse: HttpErrorResponse) => {
|
||||||
|
let errorMessage = 'An unspecified error occurred.';
|
||||||
|
|
||||||
|
if (errorResponse.status !== 0) {
|
||||||
|
if (typeof errorResponse.error === 'string') {
|
||||||
|
errorMessage = errorResponse.error;
|
||||||
|
} else {
|
||||||
|
errorMessage = errorResponse.message || `${errorResponse.status}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return of(
|
return of(
|
||||||
loadProcessorDetailsFailure({
|
loadProcessorDetailsFailure({
|
||||||
response: errorResponse
|
response: errorMessage
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
import { JoltTransformJsonProcessorDetailsState } from './index';
|
import { JoltTransformJsonProcessorDetailsState } from './index';
|
||||||
import { createReducer, on } from '@ngrx/store';
|
import { createReducer, on } from '@ngrx/store';
|
||||||
import {
|
import {
|
||||||
|
loadProcessorDetails,
|
||||||
loadProcessorDetailsFailure,
|
loadProcessorDetailsFailure,
|
||||||
loadProcessorDetailsSuccess,
|
loadProcessorDetailsSuccess,
|
||||||
resetJoltTransformJsonProcessorDetailsState
|
resetJoltTransformJsonProcessorDetailsState
|
||||||
} from './jolt-transform-json-processor-details.actions';
|
} from './jolt-transform-json-processor-details.actions';
|
||||||
|
|
||||||
export const initialState: JoltTransformJsonProcessorDetailsState = {
|
export const initialState: JoltTransformJsonProcessorDetailsState = {
|
||||||
saving: false,
|
loading: false,
|
||||||
|
error: null,
|
||||||
processorDetails: null
|
processorDetails: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,12 +35,20 @@ export const joltTransformJsonProcessorDetailsReducer = createReducer(
|
||||||
on(resetJoltTransformJsonProcessorDetailsState, () => ({
|
on(resetJoltTransformJsonProcessorDetailsState, () => ({
|
||||||
...initialState
|
...initialState
|
||||||
})),
|
})),
|
||||||
|
on(loadProcessorDetails, (state) => ({
|
||||||
|
...state,
|
||||||
|
error: null,
|
||||||
|
loading: true
|
||||||
|
})),
|
||||||
on(loadProcessorDetailsSuccess, (state, { response }) => ({
|
on(loadProcessorDetailsSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
processorDetails: response
|
processorDetails: response,
|
||||||
|
loading: false
|
||||||
})),
|
})),
|
||||||
on(loadProcessorDetailsFailure, (state) => ({
|
on(loadProcessorDetailsFailure, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
processorDetails: null
|
processorDetails: null,
|
||||||
|
error: response,
|
||||||
|
loading: false
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
|
@ -34,9 +34,14 @@ export const selectProcessorDetails = createSelector(
|
||||||
(state: JoltTransformJsonProcessorDetailsState) => state.processorDetails
|
(state: JoltTransformJsonProcessorDetailsState) => state.processorDetails
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectSaving = createSelector(
|
export const selectProcessorDetailsLoading = createSelector(
|
||||||
selectJoltTransformJsonProcessorDetailsState,
|
selectJoltTransformJsonProcessorDetailsState,
|
||||||
(state: JoltTransformJsonProcessorDetailsState) => state.saving
|
(state: JoltTransformJsonProcessorDetailsState) => state.loading
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectProcessorDetailsError = createSelector(
|
||||||
|
selectJoltTransformJsonProcessorDetailsState,
|
||||||
|
(state: JoltTransformJsonProcessorDetailsState) => state.error
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectProcessorIdFromRoute = createSelector(selectCurrentRoute, (route) => {
|
export const selectProcessorIdFromRoute = createSelector(selectCurrentRoute, (route) => {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
export interface JoltTransformJsonTransformState {
|
export interface JoltTransformJsonTransformState {
|
||||||
saving: boolean;
|
loading: boolean;
|
||||||
transformationResponse?: TransformJoltSpecSuccess | null;
|
transformationResponse?: TransformJoltSpecSuccess | null;
|
||||||
transformationFailureResponse?: HttpErrorResponse | null;
|
transformationFailureResponse?: HttpErrorResponse | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
} from './jolt-transform-json-transform.actions';
|
} from './jolt-transform-json-transform.actions';
|
||||||
|
|
||||||
export const initialState: JoltTransformJsonTransformState = {
|
export const initialState: JoltTransformJsonTransformState = {
|
||||||
saving: false,
|
loading: false,
|
||||||
transformationResponse: null,
|
transformationResponse: null,
|
||||||
transformationFailureResponse: null
|
transformationFailureResponse: null
|
||||||
};
|
};
|
||||||
|
@ -37,16 +37,16 @@ export const joltTransformJsonTransformReducer = createReducer(
|
||||||
})),
|
})),
|
||||||
on(transformJoltSpec, (state) => ({
|
on(transformJoltSpec, (state) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: true
|
loading: true
|
||||||
})),
|
})),
|
||||||
on(transformJoltSpecSuccess, (state, { response }) => ({
|
on(transformJoltSpecSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
loading: false,
|
||||||
transformationResponse: response
|
transformationResponse: response
|
||||||
})),
|
})),
|
||||||
on(transformJoltSpecFailure, (state, { response }) => ({
|
on(transformJoltSpecFailure, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
loading: false,
|
||||||
transformationResponse: null,
|
transformationResponse: null,
|
||||||
transformationFailureResponse: response
|
transformationFailureResponse: response
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -27,8 +27,3 @@ export const selectJoltTransformJsonTransformState = createSelector(
|
||||||
selectJoltTransformJsonUiState,
|
selectJoltTransformJsonUiState,
|
||||||
(state: JoltTransformJsonUiState) => state[joltTransformJsonTransformFeatureKey]
|
(state: JoltTransformJsonUiState) => state[joltTransformJsonTransformFeatureKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectSaving = createSelector(
|
|
||||||
selectJoltTransformJsonTransformState,
|
|
||||||
(state: JoltTransformJsonTransformState) => state.saving
|
|
||||||
);
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
|
||||||
export interface JoltTransformJsonValidateState {
|
export interface JoltTransformJsonValidateState {
|
||||||
saving: boolean | null;
|
loading: boolean | null;
|
||||||
validationResponse?: ValidateJoltSpecSuccess | null;
|
validationResponse?: ValidateJoltSpecSuccess | null;
|
||||||
validationFailureResponse?: HttpErrorResponse | null;
|
validationFailureResponse?: HttpErrorResponse | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {
|
||||||
} from './jolt-transform-json-validate.actions';
|
} from './jolt-transform-json-validate.actions';
|
||||||
|
|
||||||
export const initialState: JoltTransformJsonValidateState = {
|
export const initialState: JoltTransformJsonValidateState = {
|
||||||
saving: false,
|
loading: false,
|
||||||
validationResponse: null,
|
validationResponse: null,
|
||||||
validationFailureResponse: null
|
validationFailureResponse: null
|
||||||
};
|
};
|
||||||
|
@ -38,21 +38,21 @@ export const joltTransformJsonValidateReducer = createReducer(
|
||||||
})),
|
})),
|
||||||
on(validateJoltSpec, (state) => ({
|
on(validateJoltSpec, (state) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: true
|
loading: true
|
||||||
})),
|
})),
|
||||||
on(validateJoltSpecSuccess, (state, { response }) => ({
|
on(validateJoltSpecSuccess, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
loading: false,
|
||||||
validationResponse: response
|
validationResponse: response
|
||||||
})),
|
})),
|
||||||
on(validateJoltSpecFailure, (state, { response }) => ({
|
on(validateJoltSpecFailure, (state, { response }) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: false,
|
loading: false,
|
||||||
validationFailureResponse: response
|
validationFailureResponse: response
|
||||||
})),
|
})),
|
||||||
on(resetValidateJoltSpecState, (state) => ({
|
on(resetValidateJoltSpecState, (state) => ({
|
||||||
...state,
|
...state,
|
||||||
saving: null,
|
loading: null,
|
||||||
validationResponse: null,
|
validationResponse: null,
|
||||||
validationFailureResponse: null
|
validationFailureResponse: null
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -27,8 +27,3 @@ export const selectJoltTransformJsonValidateState = createSelector(
|
||||||
selectJoltTransformJsonUiState,
|
selectJoltTransformJsonUiState,
|
||||||
(state: JoltTransformJsonUiState) => state[joltTransformJsonValidateFeatureKey]
|
(state: JoltTransformJsonUiState) => state[joltTransformJsonValidateFeatureKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectSaving = createSelector(
|
|
||||||
selectJoltTransformJsonValidateState,
|
|
||||||
(state: JoltTransformJsonValidateState) => state.saving
|
|
||||||
);
|
|
||||||
|
|
Loading…
Reference in New Issue