mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 07:23:03 +00:00
Changes in order to keep server side validation errors into the submission form state
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../shared/ngrx/type';
|
||||
import { SectionVisibility, SubmissionSectionError } from './submission-objects.reducer';
|
||||
import { SectionVisibility, SubmissionError, SubmissionSectionError } from './submission-objects.reducer';
|
||||
import { WorkspaceitemSectionUploadFileObject } from '../../core/submission/models/workspaceitem-section-upload-file.model';
|
||||
import {
|
||||
WorkspaceitemSectionDataType,
|
||||
@@ -206,7 +206,8 @@ export class UpdateSectionDataAction implements Action {
|
||||
submissionId: string;
|
||||
sectionId: string;
|
||||
data: WorkspaceitemSectionDataType;
|
||||
errors: SubmissionSectionError[];
|
||||
errorsToShow: SubmissionSectionError[];
|
||||
serverValidationErrors: SubmissionSectionError[];
|
||||
metadata: string[];
|
||||
};
|
||||
|
||||
@@ -219,17 +220,20 @@ export class UpdateSectionDataAction implements Action {
|
||||
* the section's ID to add
|
||||
* @param data
|
||||
* the section's data
|
||||
* @param errors
|
||||
* the section's errors
|
||||
* @param errorsToShow
|
||||
* the list of the section's errors to show
|
||||
* @param serverValidationErrors
|
||||
* the list of the section errors detected by the server
|
||||
* @param metadata
|
||||
* the section's metadata
|
||||
*/
|
||||
constructor(submissionId: string,
|
||||
sectionId: string,
|
||||
data: WorkspaceitemSectionDataType,
|
||||
errors: SubmissionSectionError[],
|
||||
errorsToShow: SubmissionSectionError[],
|
||||
serverValidationErrors: SubmissionSectionError[],
|
||||
metadata?: string[]) {
|
||||
this.payload = { submissionId, sectionId, data, errors, metadata };
|
||||
this.payload = { submissionId, sectionId, data, errorsToShow, serverValidationErrors, metadata };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +312,7 @@ export class InitSubmissionFormAction implements Action {
|
||||
submissionDefinition: SubmissionDefinitionsModel;
|
||||
sections: WorkspaceitemSectionsObject;
|
||||
item: Item;
|
||||
errors: SubmissionSectionError[];
|
||||
errors: SubmissionError;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -333,7 +337,7 @@ export class InitSubmissionFormAction implements Action {
|
||||
submissionDefinition: SubmissionDefinitionsModel,
|
||||
sections: WorkspaceitemSectionsObject,
|
||||
item: Item,
|
||||
errors: SubmissionSectionError[]) {
|
||||
errors: SubmissionError) {
|
||||
this.payload = { collectionId, submissionId, selfUrl, submissionDefinition, sections, item, errors };
|
||||
}
|
||||
}
|
||||
|
@@ -5,16 +5,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { isEqual, union } from 'lodash';
|
||||
|
||||
import { from as observableFrom, Observable, of as observableOf } from 'rxjs';
|
||||
import {
|
||||
catchError,
|
||||
filter,
|
||||
map,
|
||||
mergeMap,
|
||||
switchMap,
|
||||
take,
|
||||
tap,
|
||||
withLatestFrom
|
||||
} from 'rxjs/operators';
|
||||
import { catchError, filter, map, mergeMap, switchMap, take, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
|
||||
import { WorkflowItem } from '../../core/submission/models/workflowitem.model';
|
||||
import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/workspaceitem-section-upload.model';
|
||||
@@ -52,13 +43,13 @@ import {
|
||||
UpdateSectionDataAction,
|
||||
UpdateSectionDataSuccessAction
|
||||
} from './submission-objects.actions';
|
||||
import {SubmissionObjectEntry, SubmissionSectionError, SubmissionSectionObject} from './submission-objects.reducer';
|
||||
import { SubmissionObjectEntry, SubmissionSectionError, SubmissionSectionObject } from './submission-objects.reducer';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
|
||||
import { SubmissionObjectDataService } from '../../core/submission/submission-object-data.service';
|
||||
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||
import parseSectionErrorPaths, {SectionErrorPath} from '../utils/parseSectionErrorPaths';
|
||||
import parseSectionErrorPaths, { SectionErrorPath } from '../utils/parseSectionErrorPaths';
|
||||
import { FormState } from '../../shared/form/form.reducer';
|
||||
|
||||
@Injectable()
|
||||
@@ -83,7 +74,7 @@ export class SubmissionObjectEffects {
|
||||
} else {
|
||||
sectionData = action.payload.item.metadata;
|
||||
}
|
||||
const sectionErrors = null;
|
||||
const sectionErrors = isNotEmpty(action.payload.errors) ? (action.payload.errors[sectionId] || null) : null;
|
||||
mappedActions.push(
|
||||
new InitSectionAction(
|
||||
action.payload.submissionId,
|
||||
@@ -232,10 +223,7 @@ export class SubmissionObjectEffects {
|
||||
switchMap(([action, state]: [DepositSubmissionAction, any]) => {
|
||||
return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl).pipe(
|
||||
map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)),
|
||||
catchError((error) => {
|
||||
console.log('submission error', error);
|
||||
return observableOf(new DepositSubmissionErrorAction(action.payload.submissionId));
|
||||
}));
|
||||
catchError((error) => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId))));
|
||||
}));
|
||||
|
||||
/**
|
||||
@@ -297,7 +285,7 @@ export class SubmissionObjectEffects {
|
||||
return item$.pipe(
|
||||
map((item: Item) => item.metadata),
|
||||
filter((metadata) => !isEqual(action.payload.data, metadata)),
|
||||
map((metadata: any) => new UpdateSectionDataAction(action.payload.submissionId, action.payload.sectionId, metadata, action.payload.errors, action.payload.metadata))
|
||||
map((metadata: any) => new UpdateSectionDataAction(action.payload.submissionId, action.payload.sectionId, metadata, action.payload.errorsToShow, action.payload.serverValidationErrors, action.payload.metadata))
|
||||
);
|
||||
} else {
|
||||
return observableOf(new UpdateSectionDataSuccessAction());
|
||||
@@ -413,7 +401,7 @@ export class SubmissionObjectEffects {
|
||||
|
||||
const sectionForm = getForm(forms, currentState, sectionId);
|
||||
const filteredErrors = filterErrors(sectionForm, sectionErrors, currentState.sections[sectionId].sectionType, notify);
|
||||
mappedActions.push(new UpdateSectionDataAction(submissionId, sectionId, sectionData, filteredErrors));
|
||||
mappedActions.push(new UpdateSectionDataAction(submissionId, sectionId, sectionData, filteredErrors, sectionErrors));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -28,7 +28,8 @@ import {
|
||||
SaveSubmissionSectionFormAction,
|
||||
SaveSubmissionSectionFormErrorAction,
|
||||
SaveSubmissionSectionFormSuccessAction,
|
||||
SectionStatusChangeAction, SubmissionObjectAction,
|
||||
SectionStatusChangeAction,
|
||||
SubmissionObjectAction,
|
||||
UpdateSectionDataAction
|
||||
} from './submission-objects.actions';
|
||||
import { SectionsType } from '../sections/sections-type';
|
||||
@@ -68,7 +69,7 @@ describe('submissionReducer test suite', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const action = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, new Item(), []);
|
||||
const action = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, new Item(), null);
|
||||
const newState = submissionObjectReducer({}, action);
|
||||
|
||||
expect(newState).toEqual(expectedState);
|
||||
@@ -242,7 +243,7 @@ describe('submissionReducer test suite', () => {
|
||||
isValid: false
|
||||
} as any;
|
||||
|
||||
let action: any = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, new Item(), []);
|
||||
let action: any = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, new Item(), null);
|
||||
let newState = submissionObjectReducer({}, action);
|
||||
|
||||
action = new InitSectionAction(
|
||||
@@ -329,7 +330,7 @@ describe('submissionReducer test suite', () => {
|
||||
]
|
||||
} as any;
|
||||
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', data, []);
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', data, [], []);
|
||||
const newState = submissionObjectReducer(initState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.data).toEqual(data);
|
||||
@@ -340,7 +341,7 @@ describe('submissionReducer test suite', () => {
|
||||
} as any;
|
||||
const metadata = ['dc.title', 'dc.contributor.author'];
|
||||
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', data, [], metadata);
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', data, [], [], metadata);
|
||||
const newState = submissionObjectReducer(initState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.metadata).toEqual(metadata);
|
||||
@@ -354,10 +355,10 @@ describe('submissionReducer test suite', () => {
|
||||
}
|
||||
];
|
||||
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors);
|
||||
const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors, errors);
|
||||
const newState = submissionObjectReducer(initState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.errors).toEqual(errors);
|
||||
expect(newState[826].sections.traditionalpageone.errorsToShow).toEqual(errors);
|
||||
});
|
||||
|
||||
it('should remove all submission section errors properly', () => {
|
||||
@@ -366,7 +367,7 @@ describe('submissionReducer test suite', () => {
|
||||
|
||||
newState = submissionObjectReducer(initState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.errors).toEqual([]);
|
||||
expect(newState[826].sections.traditionalpageone.errorsToShow).toEqual([]);
|
||||
});
|
||||
|
||||
it('should add submission section error properly', () => {
|
||||
@@ -378,7 +379,7 @@ describe('submissionReducer test suite', () => {
|
||||
const action = new InertSectionErrorsAction(submissionId, 'traditionalpageone', error);
|
||||
const newState = submissionObjectReducer(initState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.errors).toEqual([error]);
|
||||
expect(newState[826].sections.traditionalpageone.errorsToShow).toEqual([error]);
|
||||
});
|
||||
|
||||
it('should remove specified submission section error/s properly', () => {
|
||||
@@ -402,21 +403,21 @@ describe('submissionReducer test suite', () => {
|
||||
message: 'error.validation.required'
|
||||
}];
|
||||
|
||||
let action: any = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors);
|
||||
let action: any = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors, errors);
|
||||
let newState = submissionObjectReducer(initState, action);
|
||||
|
||||
action = new DeleteSectionErrorsAction(submissionId, 'traditionalpageone', error);
|
||||
newState = submissionObjectReducer(newState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.errors).toEqual(expectedErrors);
|
||||
expect(newState[826].sections.traditionalpageone.errorsToShow).toEqual(expectedErrors);
|
||||
|
||||
action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors);
|
||||
action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors, errors);
|
||||
newState = submissionObjectReducer(initState, action);
|
||||
|
||||
action = new DeleteSectionErrorsAction(submissionId, 'traditionalpageone', errors);
|
||||
newState = submissionObjectReducer(newState, action);
|
||||
|
||||
expect(newState[826].sections.traditionalpageone.errors).toEqual([]);
|
||||
expect(newState[826].sections.traditionalpageone.errorsToShow).toEqual([]);
|
||||
});
|
||||
|
||||
it('should add a new file', () => {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { hasValue, isNotEmpty, isNotNull, isUndefined } from '../../shared/empty.util';
|
||||
import { hasValue, isEmpty, isNotEmpty, isNotNull, isUndefined } from '../../shared/empty.util';
|
||||
import { differenceWith, findKey, isEqual, uniqWith } from 'lodash';
|
||||
|
||||
import {
|
||||
@@ -97,9 +97,14 @@ export interface SubmissionSectionObject {
|
||||
data: WorkspaceitemSectionDataType;
|
||||
|
||||
/**
|
||||
* The list of the section errors
|
||||
* The list of the section's errors to show
|
||||
*/
|
||||
errors: SubmissionSectionError[];
|
||||
errorsToShow: SubmissionSectionError[];
|
||||
|
||||
/**
|
||||
* The list of the section's errors detected by the server
|
||||
*/
|
||||
serverValidationErrors: SubmissionSectionError[];
|
||||
|
||||
/**
|
||||
* A boolean representing if this section is loading
|
||||
@@ -117,6 +122,13 @@ export interface SubmissionSectionObject {
|
||||
formId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface to represent section error
|
||||
*/
|
||||
export interface SubmissionError {
|
||||
[submissionId: string]: SubmissionSectionError[];
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface to represent section error
|
||||
*/
|
||||
@@ -332,7 +344,7 @@ const removeError = (state: SubmissionObjectState, action: DeleteSectionErrorsAc
|
||||
if (Array.isArray(errors)) {
|
||||
filteredErrors = differenceWith(errors, errors, isEqual);
|
||||
} else {
|
||||
filteredErrors = state[ submissionId ].sections[ sectionId ].errors
|
||||
filteredErrors = state[ submissionId ].sections[ sectionId ].errorsToShow
|
||||
.filter((currentError) => currentError.path !== errors.path || !isEqual(currentError, errors));
|
||||
}
|
||||
|
||||
@@ -340,7 +352,7 @@ const removeError = (state: SubmissionObjectState, action: DeleteSectionErrorsAc
|
||||
[ submissionId ]: Object.assign({}, state[ submissionId ], {
|
||||
sections: Object.assign({}, state[ submissionId ].sections, {
|
||||
[ sectionId ]: Object.assign({}, state[ submissionId ].sections [ sectionId ], {
|
||||
errors: filteredErrors
|
||||
errorsToShow: filteredErrors
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -354,13 +366,13 @@ const addError = (state: SubmissionObjectState, action: InertSectionErrorsAction
|
||||
const { submissionId, sectionId, error } = action.payload;
|
||||
|
||||
if (hasValue(state[ submissionId ].sections[ sectionId ])) {
|
||||
const errors = uniqWith(state[ submissionId ].sections[ sectionId ].errors.concat(error), isEqual);
|
||||
const errorsToShow = uniqWith(state[ submissionId ].sections[ sectionId ].errorsToShow.concat(error), isEqual);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
[ submissionId ]: Object.assign({}, state[ submissionId ], {
|
||||
activeSection: state[ action.payload.submissionId ].activeSection, sections: Object.assign({}, state[ submissionId ].sections, {
|
||||
[ sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], {
|
||||
errors
|
||||
errorsToShow
|
||||
})
|
||||
}),
|
||||
})
|
||||
@@ -378,7 +390,7 @@ const addError = (state: SubmissionObjectState, action: InertSectionErrorsAction
|
||||
* @param action
|
||||
* a RemoveSectionErrorsAction
|
||||
* @return SubmissionObjectState
|
||||
* the new state, with the section's errors updated.
|
||||
* the new state, with the section's errorsToShow updated.
|
||||
*/
|
||||
function removeSectionErrors(state: SubmissionObjectState, action: RemoveSectionErrorsAction): SubmissionObjectState {
|
||||
if (isNotEmpty(state[ action.payload.submissionId ])
|
||||
@@ -387,7 +399,7 @@ function removeSectionErrors(state: SubmissionObjectState, action: RemoveSection
|
||||
[ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], {
|
||||
sections: Object.assign({}, state[ action.payload.submissionId ].sections, {
|
||||
[ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], {
|
||||
errors: []
|
||||
errorsToShow: []
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -644,9 +656,10 @@ function initSection(state: SubmissionObjectState, action: InitSectionAction): S
|
||||
collapsed: false,
|
||||
enabled: action.payload.enabled,
|
||||
data: action.payload.data,
|
||||
errors: action.payload.errors || [],
|
||||
errorsToShow: [],
|
||||
serverValidationErrors: action.payload.errors || [],
|
||||
isLoading: false,
|
||||
isValid: false
|
||||
isValid: isEmpty(action.payload.errors)
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -702,7 +715,8 @@ function updateSectionData(state: SubmissionObjectState, action: UpdateSectionDa
|
||||
[ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], {
|
||||
enabled: true,
|
||||
data: action.payload.data,
|
||||
errors: action.payload.errors,
|
||||
errorsToShow: action.payload.errorsToShow,
|
||||
serverValidationErrors: action.payload.serverValidationErrors,
|
||||
metadata: reduceSectionMetadata(action.payload.metadata, state[ action.payload.submissionId ].sections [ action.payload.sectionId ].metadata)
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user