diff --git a/src/app/core/json-patch/json-patch-operations.reducer.ts b/src/app/core/json-patch/json-patch-operations.reducer.ts index 4eb5a48d23..14cbf00f65 100644 --- a/src/app/core/json-patch/json-patch-operations.reducer.ts +++ b/src/app/core/json-patch/json-patch-operations.reducer.ts @@ -218,7 +218,7 @@ function newOperation(state: JsonPatchOperationsState, action): JsonPatchOperati * @param state * the current state * @param action - * an LoadSubmissionFormAction + * an FlushPatchOperationsAction * @return SubmissionObjectState * the new state, with the section new validity status. */ diff --git a/src/app/shared/date.util.ts b/src/app/shared/date.util.ts index 90f9ff9b39..8be4235643 100644 --- a/src/app/shared/date.util.ts +++ b/src/app/shared/date.util.ts @@ -1,5 +1,12 @@ import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; +import { isObject } from 'lodash'; + +export function isDateObject(value) { + return isObject(value) && value.hasOwnProperty('day') + && value.hasOwnProperty('month') && value.hasOwnProperty('year'); +} + export function dateToGMTString(date: Date | NgbDateStruct) { let year = ((date instanceof Date) ? date.getFullYear() : date.year).toString(); let month = ((date instanceof Date) ? date.getMonth() + 1 : date.month).toString(); diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index ec78225274..fab5db6151 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -28,6 +28,7 @@ import { RowParser } from './parsers/row-parser'; import { DynamicRowArrayModel } from './ds-dynamic-form-ui/models/ds-dynamic-row-array-model'; import { DsDynamicInputModel } from './ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { FormFieldMetadataValueObject } from './models/form-field-metadata-value.model'; +import { isDateObject } from '../../date.util'; @Injectable() export class FormBuilderService extends DynamicFormService { @@ -108,7 +109,11 @@ export class FormBuilderService extends DynamicFormService { } else if (isObject(controlValue)) { const authority = controlValue.authority || controlValue.id || null; const place = controlModelIndex || controlValue.place; - return new FormFieldMetadataValueObject(controlValue.value, controlLanguage, authority, controlValue.display, place); + if (isDateObject(controlValue)) { + return new FormFieldMetadataValueObject(controlValue, controlLanguage, authority, controlValue, place); + } else { + return new FormFieldMetadataValueObject(controlValue.value, controlLanguage, authority, controlValue.display, place); + } } }; diff --git a/src/app/submission/form/submission-form.component.ts b/src/app/submission/form/submission-form.component.ts index 0bed9173c1..0ea4afd1a4 100644 --- a/src/app/submission/form/submission-form.component.ts +++ b/src/app/submission/form/submission-form.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChange import { Store } from '@ngrx/store'; import { CancelSubmissionFormAction, - LoadSubmissionFormAction, + InitSubmissionFormAction, ResetSubmissionFormAction } from '../objects/submission-objects.actions'; import { hasValue, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; @@ -85,7 +85,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { this.uploadFilesOptions.authToken = this.authService.buildAuthHeader(); this.uploadFilesOptions.url = endpointURL.concat(`/${this.submissionId}`); this.definitionId = this.submissionDefinition.name; - this.store.dispatch(new LoadSubmissionFormAction(this.collectionId, this.submissionId, this.selfUrl, this.submissionDefinition, this.sections, null)); + this.store.dispatch(new InitSubmissionFormAction(this.collectionId, this.submissionId, this.selfUrl, this.submissionDefinition, this.sections, null)); this.changeDetectorRef.detectChanges(); }), @@ -132,8 +132,6 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy { protected getSectionsList(): Observable { return this.submissionService.getSubmissionSections(this.submissionId) .filter((sections: SectionDataObject[]) => isNotEmpty(sections)) - .map((sections: SectionDataObject[]) => { - return sections; - }); + .map((sections: SectionDataObject[]) => sections); } } diff --git a/src/app/submission/objects/submission-objects.actions.ts b/src/app/submission/objects/submission-objects.actions.ts index fba526dece..f12ed6d35c 100644 --- a/src/app/submission/objects/submission-objects.actions.ts +++ b/src/app/submission/objects/submission-objects.actions.ts @@ -24,10 +24,9 @@ import { SectionsType } from '../sections/sections-type'; */ export const SubmissionObjectActionTypes = { // Section types - LOAD_SUBMISSION_FORM: type('dspace/submission/LOAD_SUBMISSION_FORM'), + INIT_SUBMISSION_FORM: type('dspace/submission/INIT_SUBMISSION_FORM'), RESET_SUBMISSION_FORM: type('dspace/submission/RESET_SUBMISSION_FORM'), CANCEL_SUBMISSION_FORM: type('dspace/submission/CANCEL_SUBMISSION_FORM'), - INIT_SUBMISSION_FORM: type('dspace/submission/INIT_SUBMISSION_FORM'), COMPLETE_INIT_SUBMISSION_FORM: type('dspace/submission/COMPLETE_INIT_SUBMISSION_FORM'), SAVE_FOR_LATER_SUBMISSION_FORM: type('dspace/submission/SAVE_FOR_LATER_SUBMISSION_FORM'), SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS: type('dspace/submission/SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS'), @@ -38,7 +37,6 @@ export const SubmissionObjectActionTypes = { SAVE_SUBMISSION_SECTION_FORM: type('dspace/submission/SAVE_SUBMISSION_SECTION_FORM'), SAVE_SUBMISSION_SECTION_FORM_SUCCESS: type('dspace/submission/SAVE_SUBMISSION_SECTION_FORM_SUCCESS'), SAVE_SUBMISSION_SECTION_FORM_ERROR: type('dspace/submission/SAVE_SUBMISSION_SECTION_FORM_ERROR'), - COMPLETE_SAVE_SUBMISSION_FORM: type('dspace/submission/COMPLETE_SAVE_SUBMISSION_FORM'), CHANGE_SUBMISSION_COLLECTION: type('dspace/submission/CHANGE_SUBMISSION_COLLECTION'), SET_ACTIVE_SECTION: type('dspace/submission/SET_ACTIVE_SECTION'), INIT_SECTION: type('dspace/submission/INIT_SECTION'), @@ -47,7 +45,6 @@ export const SubmissionObjectActionTypes = { SECTION_STATUS_CHANGE: type('dspace/submission/SECTION_STATUS_CHANGE'), SECTION_LOADING_STATUS_CHANGE: type('dspace/submission/SECTION_LOADING_STATUS_CHANGE'), UPLOAD_SECTION_DATA: type('dspace/submission/UPLOAD_SECTION_DATA'), - REMOVE_SECTION_ERRORS: type('dspace/submission/REMOVE_SECTION_ERRORS'), SAVE_AND_DEPOSIT_SUBMISSION: type('dspace/submission/SAVE_AND_DEPOSIT_SUBMISSION'), DEPOSIT_SUBMISSION: type('dspace/submission/DEPOSIT_SUBMISSION'), DEPOSIT_SUBMISSION_SUCCESS: type('dspace/submission/DEPOSIT_SUBMISSION_SUCCESS'), @@ -68,9 +65,9 @@ export const SubmissionObjectActionTypes = { DELETE_FILE: type('dspace/submission/DELETE_FILE'), // Errors - INSERT_ERRORS: type('dspace/submission/INSERT_ERRORS'), - DELETE_ERRORS: type('dspace/submission/DELETE_ERRORS'), - CLEAR_ERRORS: type('dspace/submission/CLEAR_ERRORS'), + ADD_SECTION_ERROR: type('dspace/submission/ADD_SECTION_ERROR'), + DELETE_SECTION_ERROR: type('dspace/submission/DELETE_SECTION_ERROR'), + REMOVE_SECTION_ERRORS: type('dspace/submission/REMOVE_SECTION_ERRORS'), }; /* tslint:disable:max-classes-per-file */ @@ -82,7 +79,7 @@ export const SubmissionObjectActionTypes = { * @param {SubmissionSectionError} error */ export class InertSectionErrorsAction implements Action { - type: string = SubmissionObjectActionTypes.INSERT_ERRORS; + type: string = SubmissionObjectActionTypes.ADD_SECTION_ERROR; payload: { submissionId: string; sectionId: string; @@ -101,32 +98,15 @@ export class InertSectionErrorsAction implements Action { * @param {string | SubmissionSectionError} error */ export class DeleteSectionErrorsAction implements Action { - type: string = SubmissionObjectActionTypes.DELETE_ERRORS; + type: string = SubmissionObjectActionTypes.DELETE_SECTION_ERROR; payload: { submissionId: string; sectionId: string; - error: string | SubmissionSectionError | SubmissionSectionError[]; + errors: SubmissionSectionError | SubmissionSectionError[]; }; - constructor(submissionId: string, sectionId: string, error: string | SubmissionSectionError | SubmissionSectionError[]) { - this.payload = { submissionId, sectionId, error }; - } -} - -/** - * Clear all the errors from the given section - * @param {string} submissionId - * @param {string} sectionId - */ -export class ClearSectionErrorsAction implements Action { - type: string = SubmissionObjectActionTypes.CLEAR_ERRORS; - payload: { - submissionId: string; - sectionId: string; - }; - - constructor(submissionId: string, sectionId: string) { - this.payload = { submissionId, sectionId } + constructor(submissionId: string, sectionId: string, errors: SubmissionSectionError | SubmissionSectionError[]) { + this.payload = { submissionId, sectionId, errors }; } } @@ -273,39 +253,6 @@ export class RemoveSectionErrorsAction implements Action { } } -export class InitSubmissionFormAction implements Action { - type = SubmissionObjectActionTypes.INIT_SUBMISSION_FORM; - payload: { - collectionId: string; - definitionId: string; - submissionId: string; - selfUrl: string; - sections: WorkspaceitemSectionsObject; - }; - - /** - * Create a new InitSubmissionFormAction - * - * @param collectionId - * the collection's Id where to deposit - * @param definitionId - * the definition's ID to use - * @param submissionId - * the submission's ID - * @param selfUrl - * the submission's self url - * @param sections - * the submission's sections - */ - constructor(collectionId: string, - definitionId: string, - submissionId: string, - selfUrl: string, - sections: WorkspaceitemSectionsObject) { - this.payload = { collectionId, definitionId, submissionId, selfUrl, sections }; - } -} - // Submission actions export class CompleteInitSubmissionFormAction implements Action { @@ -325,8 +272,8 @@ export class CompleteInitSubmissionFormAction implements Action { } } -export class LoadSubmissionFormAction implements Action { - type = SubmissionObjectActionTypes.LOAD_SUBMISSION_FORM; +export class InitSubmissionFormAction implements Action { + type = SubmissionObjectActionTypes.INIT_SUBMISSION_FORM; payload: { collectionId: string; submissionId: string; @@ -337,7 +284,7 @@ export class LoadSubmissionFormAction implements Action { }; /** - * Create a new LoadSubmissionFormAction + * Create a new InitSubmissionFormAction * * @param collectionId * the collection's Id where to deposit @@ -527,23 +474,6 @@ export class SaveSubmissionSectionFormErrorAction implements Action { } } -export class CompleteSaveSubmissionFormAction implements Action { - type = SubmissionObjectActionTypes.COMPLETE_SAVE_SUBMISSION_FORM; - payload: { - submissionId: string; - }; - - /** - * Create a new CompleteSaveSubmissionFormAction - * - * @param submissionId - * the submission's ID - */ - constructor(submissionId: string) { - this.payload = { submissionId }; - } -} - export class ResetSubmissionFormAction implements Action { type = SubmissionObjectActionTypes.RESET_SUBMISSION_FORM; payload: { @@ -555,7 +485,7 @@ export class ResetSubmissionFormAction implements Action { }; /** - * Create a new LoadSubmissionFormAction + * Create a new ResetSubmissionFormAction * * @param collectionId * the collection's Id where to deposit @@ -737,29 +667,6 @@ export class SectionStatusChangeAction implements Action { } } -export class SectionLoadingStatusChangeAction implements Action { - type = SubmissionObjectActionTypes.SECTION_LOADING_STATUS_CHANGE; - payload: { - submissionId: string; - sectionId: string; - loading: boolean - }; - - /** - * Change the section loading status - * - * @param submissionId - * the submission's ID - * @param sectionId - * the section's ID to change - * @param loading - * the section loading status (true if is loading) - */ - constructor(submissionId: string, sectionId: string, loading: boolean) { - this.payload = { submissionId, sectionId, loading }; - } -} - export class SetActiveSectionAction implements Action { type = SubmissionObjectActionTypes.SET_ACTIVE_SECTION; payload: { @@ -803,7 +710,7 @@ export class NewUploadedFileAction implements Action { * the metadata of the new bitstream */ constructor(submissionId: string, sectionId: string, fileId: string, data: WorkspaceitemSectionUploadFileObject) { - this.payload = { submissionId, sectionId, fileId: fileId, data }; + this.payload = { submissionId, sectionId, fileId, data }; } } @@ -991,10 +898,9 @@ export class SetWorkflowDuplicatedErrorAction implements Action { export type SubmissionObjectAction = DisableSectionAction | InitSectionAction | EnableSectionAction - | LoadSubmissionFormAction + | InitSubmissionFormAction | ResetSubmissionFormAction | CancelSubmissionFormAction - | InitSubmissionFormAction | CompleteInitSubmissionFormAction | ChangeSubmissionCollectionAction | SaveAndDepositSubmissionAction @@ -1010,7 +916,6 @@ export type SubmissionObjectAction = DisableSectionAction | DeleteUploadedFileAction | InertSectionErrorsAction | DeleteSectionErrorsAction - | ClearSectionErrorsAction | UpdateSectionDataAction | RemoveSectionErrorsAction | SaveForLaterSubmissionFormAction @@ -1022,7 +927,6 @@ export type SubmissionObjectAction = DisableSectionAction | SaveSubmissionSectionFormAction | SaveSubmissionSectionFormSuccessAction | SaveSubmissionSectionFormErrorAction - | CompleteSaveSubmissionFormAction | SetActiveSectionAction | SetWorkspaceDuplicatedAction | SetWorkspaceDuplicatedSuccessAction diff --git a/src/app/submission/objects/submission-objects.effects.ts b/src/app/submission/objects/submission-objects.effects.ts index 7d0b0b2399..30efd77464 100644 --- a/src/app/submission/objects/submission-objects.effects.ts +++ b/src/app/submission/objects/submission-objects.effects.ts @@ -11,7 +11,7 @@ import { DiscardSubmissionErrorAction, DiscardSubmissionSuccessAction, InitSectionAction, - LoadSubmissionFormAction, + InitSubmissionFormAction, ResetSubmissionFormAction, SaveAndDepositSubmissionAction, SaveForLaterSubmissionFormAction, @@ -53,8 +53,8 @@ import parseSectionErrors from '../utils/parseSectionErrors'; export class SubmissionObjectEffects { @Effect() loadForm$ = this.actions$ - .ofType(SubmissionObjectActionTypes.LOAD_SUBMISSION_FORM) - .map((action: LoadSubmissionFormAction) => { + .ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM) + .map((action: InitSubmissionFormAction) => { const definition = action.payload.submissionDefinition; const mappedActions = []; definition.sections.forEach((sectionDefinition: SubmissionSectionModel, index: number) => { @@ -90,7 +90,7 @@ export class SubmissionObjectEffects { @Effect() resetForm$ = this.actions$ .ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM) .map((action: ResetSubmissionFormAction) => - new LoadSubmissionFormAction( + new InitSubmissionFormAction( action.payload.collectionId, action.payload.submissionId, action.payload.selfUrl, @@ -331,7 +331,7 @@ export class SubmissionObjectEffects { }); } - // mappedActions.push(new CompleteSaveSubmissionFormAction(submissionId)); + return mappedActions; } diff --git a/src/app/submission/objects/submission-objects.reducer.spec.ts b/src/app/submission/objects/submission-objects.reducer.spec.ts new file mode 100644 index 0000000000..b3c821e5c9 --- /dev/null +++ b/src/app/submission/objects/submission-objects.reducer.spec.ts @@ -0,0 +1,1254 @@ +import { submissionObjectReducer, SubmissionObjectState } from './submission-objects.reducer'; +import { + CancelSubmissionFormAction, + ChangeSubmissionCollectionAction, + CompleteInitSubmissionFormAction, + DeleteSectionErrorsAction, DeleteUploadedFileAction, + DepositSubmissionAction, + DepositSubmissionErrorAction, + DepositSubmissionSuccessAction, + DisableSectionAction, + DiscardSubmissionAction, + DiscardSubmissionSuccessAction, EditFileDataAction, + EnableSectionAction, + InertSectionErrorsAction, + InitSectionAction, + InitSubmissionFormAction, NewUploadedFileAction, + RemoveSectionErrorsAction, + ResetSubmissionFormAction, + SaveAndDepositSubmissionAction, + SaveForLaterSubmissionFormAction, + SaveForLaterSubmissionFormErrorAction, + SaveForLaterSubmissionFormSuccessAction, + SaveSubmissionFormAction, + SaveSubmissionFormErrorAction, + SaveSubmissionFormSuccessAction, + SaveSubmissionSectionFormAction, + SaveSubmissionSectionFormErrorAction, + SaveSubmissionSectionFormSuccessAction, + SectionStatusChangeAction, + UpdateSectionDataAction +} from './submission-objects.actions'; +import { SectionsType } from '../sections/sections-type'; + +describe('submissionReducer', () => { + + const collectionId = '1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb'; + const submissionId = '826'; + const submissionDefinition = { + isDefault: true, + sections: [ + { + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/extraction' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/extraction' + }, + { + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/collection' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/collection' + }, + { + header: 'submit.progressbar.describe.stepone', + mandatory: true, + sectionType: 'submission-form', + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/traditionalpageone', + config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/traditionalpageone' + }, + { + header: 'submit.progressbar.describe.steptwo', + mandatory: true, + sectionType: 'submission-form', + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/traditionalpagetwo', + config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpagetwo' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/traditionalpagetwo' + }, + { + header: 'submit.progressbar.upload', + mandatory: true, + sectionType: 'upload', + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/upload', + config: 'https://rest.api/dspace-spring-rest/api/config/submissionuploads/upload' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/upload' + }, + { + header: 'submit.progressbar.license', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + type: 'submissionsection', + _links: { + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/license' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissionsections/license' + } + ], + name: 'traditional', + type: 'submissiondefinition', + _links: { + collections: 'https://rest.api/dspace-spring-rest/api/config/submissiondefinitions/traditional/collections', + sections: 'https://rest.api/dspace-spring-rest/api/config/submissiondefinitions/traditional/sections', + self: 'https://rest.api/dspace-spring-rest/api/config/submissiondefinitions/traditional' + }, + self: 'https://rest.api/dspace-spring-rest/api/config/submissiondefinitions/traditional' + } as any; + const selfUrl = 'https://rest.api/dspace-spring-rest/api/submission/workspaceitems/826'; + + const initState: SubmissionObjectState = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: false, + sectionType: 'submission-form', + collapsed: false, + enabled: false, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: false, + savePending: false, + depositPending: false + } + }; + + it('should init submission state properly', () => { + const expectedState = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: Object.create(null), + isLoading: true, + savePending: false, + depositPending: false, + } + }; + + const action = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, []); + const newState = submissionObjectReducer({}, action); + + expect(newState).toEqual(expectedState); + }); + + it('should complete submission initialization', () => { + const state = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: false, + sectionType: 'submission-form', + collapsed: false, + enabled: false, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: true, + savePending: false, + depositPending: false + } + }; + const action = new CompleteInitSubmissionFormAction(submissionId); + const newState = submissionObjectReducer(state, action); + + expect(newState).toEqual(initState); + }); + + it('should reset submission state properly', () => { + const expectedState = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: Object.create(null), + isLoading: true, + savePending: false, + depositPending: false, + } + }; + + const action = new ResetSubmissionFormAction(collectionId, submissionId, selfUrl, {}, submissionDefinition); + const newState = submissionObjectReducer(initState, action); + + expect(newState).toEqual(expectedState); + }); + + it('should cancel submission state properly', () => { + const expectedState = Object.create({}); + + const action = new CancelSubmissionFormAction(); + const newState = submissionObjectReducer(initState, action); + + expect(newState).toEqual(expectedState); + }); + + it('should set to true savePendig flag on save', () => { + const expectedState = Object.create({}); + + let action = new SaveSubmissionFormAction(submissionId); + let newState = submissionObjectReducer(initState, action); + + expect(newState[826].savePending).toBeTruthy(); + + action = new SaveForLaterSubmissionFormAction(submissionId); + newState = submissionObjectReducer(initState, action); + + expect(newState[826].savePending).toBeTruthy(); + + action = new SaveAndDepositSubmissionAction(submissionId); + newState = submissionObjectReducer(initState, action); + + expect(newState[826].savePending).toBeTruthy(); + + action = new SaveSubmissionSectionFormAction(submissionId, 'traditionalpageone'); + newState = submissionObjectReducer(initState, action); + + expect(newState[826].savePending).toBeTruthy(); + }); + + it('should set to false savePendig flag once the save is completed', () => { + const state = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: false, + savePending: true, + depositPending: false + } + }; + + let action: any = new SaveSubmissionFormSuccessAction(submissionId, []); + let newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + + action = new SaveForLaterSubmissionFormSuccessAction(submissionId, []); + newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + + action = new SaveSubmissionSectionFormSuccessAction(submissionId, []); + newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + + action = new SaveSubmissionFormErrorAction(submissionId); + newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + + action = new SaveForLaterSubmissionFormErrorAction(submissionId); + newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + + action = new SaveSubmissionSectionFormErrorAction(submissionId); + newState = submissionObjectReducer(state, action); + + expect(newState[826].savePending).toBeFalsy(); + }); + + it('should change submission collection state properly', () => { + const newCollection = '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f'; + const action = new ChangeSubmissionCollectionAction('826', newCollection); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].collection).toEqual(newCollection); + }); + + it('should set to true depositPending flag on deposit', () => { + const newCollection = '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f'; + const action = new DepositSubmissionAction('826'); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].depositPending).toBeTruthy(); + }); + + it('should reset state once the deposit is completed successfully', () => { + const state = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: false, + savePending: false, + depositPending: true + } + }; + + const action: any = new DepositSubmissionSuccessAction(submissionId); + const newState = submissionObjectReducer(state, action); + + expect(newState).toEqual({}); + }); + + it('should set to false depositPending flag once the deposit is completed unsuccessfully', () => { + const newCollection = '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f'; + const action = new DepositSubmissionErrorAction('826'); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].depositPending).toBeFalsy(); + }); + + it('should return same state on discard', () => { + const action: any = new DiscardSubmissionAction(submissionId); + const newState = submissionObjectReducer(initState, action); + + expect(newState).toEqual(initState); + }); + + it('should reset state once the discard action is completed successfully', () => { + const action: any = new DiscardSubmissionSuccessAction(submissionId); + const newState = submissionObjectReducer(initState, action); + + expect(newState).toEqual({}); + }); + + it('should return same state once the discard action is completed unsuccessfully', () => { + const action: any = new DiscardSubmissionAction(submissionId); + const newState = submissionObjectReducer(initState, action); + + expect(newState).toEqual(initState); + }); + + it('should init submission section state properly', () => { + const expectedState = { + header: 'submit.progressbar.describe.stepone', + config: 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + visibility: undefined, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any; + + let action: any = new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, {}, []); + let newState = submissionObjectReducer({}, action); + + action = new InitSectionAction( + submissionId, + 'traditionalpageone', + 'submit.progressbar.describe.stepone', + 'https://rest.api/dspace-spring-rest/api/config/submissionforms/traditionalpageone', + true, + SectionsType.SubmissionForm, + undefined, + true, + {}, + null); + + newState = submissionObjectReducer(newState, action); + + expect(newState[826].sections.traditionalpageone).toEqual(expectedState); + }); + + it('should enable submission section properly', () => { + + const action = new EnableSectionAction(submissionId, 'traditionalpagetwo'); + + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpagetwo.enabled).toBeTruthy(); + }); + + it('should enable submission section properly', () => { + + let action = new EnableSectionAction(submissionId, 'traditionalpagetwo'); + let newState = submissionObjectReducer(initState, action); + + action = new DisableSectionAction(submissionId, 'traditionalpagetwo'); + newState = submissionObjectReducer(newState, action); + + expect(newState[826].sections.traditionalpagetwo.enabled).toBeFalsy(); + }); + + it('should set to true/false submission section status', () => { + + let action = new SectionStatusChangeAction(submissionId, 'traditionalpageone', true); + let newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpageone.isValid).toBeTruthy(); + + action = new SectionStatusChangeAction(submissionId, 'traditionalpageone', false); + newState = submissionObjectReducer(newState, action); + + expect(newState[826].sections.traditionalpageone.isValid).toBeFalsy(); + }); + + it('should update submission section data properly', () => { + const data = { + 'dc.contributor.author': [ + { + value: 'Bergamini, Giuseppe', + language: null, + authority: null, + display: 'Bergamini, Giuseppe', + confidence: -1, + place: 0 + } + ], + 'dc.title': [ + { + value: 'Uno sconosciuto ritratto di Giovanni da Udine', + language: null, + authority: null, + display: 'Uno sconosciuto ritratto di Giovanni da Udine', + confidence: -1, + place: 0 + } + ], + 'dc.date.issued': [ + { + value: '2015', + language: null, + authority: null, + display: '2015', + confidence: -1, + place: 0 + } + ] + } as any; + + const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', data, []); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpageone.data).toEqual(data); + }); + + it('should add submission section errors properly', () => { + const errors = [ + { + path: '/sections/license', + message: 'error.validation.license.notgranted' + } + ]; + + const action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpageone.errors).toEqual(errors); + }); + + it('should remove all submission section errors properly', () => { + const errors = [ + { + path: '/sections/license', + message: 'error.validation.license.notgranted' + } + ]; + + let action: any = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors); + let newState = submissionObjectReducer(initState, action); + + action = new RemoveSectionErrorsAction(submissionId, 'traditionalpageone'); + newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpageone.errors).toEqual([]); + }); + + it('should add submission section error properly', () => { + const error = { + path: '/sections/traditionalpageone/dc.title/0', + message: 'error.validation.traditionalpageone.required' + }; + + const action = new InertSectionErrorsAction(submissionId, 'traditionalpageone', error); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.traditionalpageone.errors).toEqual([error]); + }); + + it('should remove specified submission section error/s properly', () => { + const errors = [ + { + path: '/sections/traditionalpageone/dc.contributor.author', + message: 'error.validation.required' + }, + { + path: '/sections/traditionalpageone/dc.date.issued', + message: 'error.validation.required' + } + ]; + const error = { + path: '/sections/traditionalpageone/dc.contributor.author', + message: 'error.validation.required' + }; + + const expectedErrors = [{ + path: '/sections/traditionalpageone/dc.date.issued', + message: 'error.validation.required' + }]; + + let action: any = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors); + let newState = submissionObjectReducer(initState, action); + + action = new DeleteSectionErrorsAction(submissionId, 'traditionalpageone', error); + newState = submissionObjectReducer(newState, action); + + expect(newState[826].sections.traditionalpageone.errors).toEqual(expectedErrors); + + action = new UpdateSectionDataAction(submissionId, 'traditionalpageone', {}, errors); + newState = submissionObjectReducer(initState, action); + + action = new DeleteSectionErrorsAction(submissionId, 'traditionalpageone', errors); + newState = submissionObjectReducer(newState, action); + + expect(newState[826].sections.traditionalpageone.errors).toEqual([]); + }); + + it('should add a new file', () => { + const uuid = '8cd86fba-70c8-483d-838a-70d28e7ed570'; + const fileData: any = { + uuid: uuid, + metadata: { + 'dc.title': [ + { + value: '28297_389341539060_6452876_n.jpg', + language: null, + authority: null, + display: '28297_389341539060_6452876_n.jpg', + confidence: -1, + place: 0 + } + ] + }, + accessConditions: [], + format: { + id: 16, + shortDescription: 'JPEG', + description: 'Joint Photographic Experts Group/JPEG File Interchange Format (JFIF)', + mimetype: 'image/jpeg', + supportLevel: 0, + internal: false, + extensions: null, + type: 'bitstreamformat' + }, + sizeBytes: 22737, + checkSum: { + checkSumAlgorithm: 'MD5', + value: '8722864dd671912f94a999ac7c4949d2' + }, + url: 'https://rest.api/dspace-spring-rest/api/core/bitstreams/8cd86fba-70c8-483d-838a-70d28e7ed570/content' + }; + const expectedState = { + files: [fileData] + }; + + const action = new NewUploadedFileAction(submissionId, 'upload', uuid, fileData); + const newState = submissionObjectReducer(initState, action); + + expect(newState[826].sections.upload.data).toEqual(expectedState); + }); + + it('should remove a file', () => { + const uuid = '8cd86fba-70c8-483d-838a-70d28e7ed570'; + const uuid2 = '7e2f4ba9-9316-41fd-844a-1ef435f41a42'; + const fileData: any = { + uuid: uuid, + metadata: { + 'dc.title': [ + { + value: '28297_389341539060_6452876_n.jpg', + language: null, + authority: null, + display: '28297_389341539060_6452876_n.jpg', + confidence: -1, + place: 0 + } + ] + }, + accessConditions: [], + format: { + id: 16, + shortDescription: 'JPEG', + description: 'Joint Photographic Experts Group/JPEG File Interchange Format (JFIF)', + mimetype: 'image/jpeg', + supportLevel: 0, + internal: false, + extensions: null, + type: 'bitstreamformat' + }, + sizeBytes: 22737, + checkSum: { + checkSumAlgorithm: 'MD5', + value: '8722864dd671912f94a999ac7c4949d2' + }, + url: 'https://rest.api/dspace-spring-rest/api/core/bitstreams/8cd86fba-70c8-483d-838a-70d28e7ed570/content' + }; + const fileData2: any = { + uuid: uuid2, + metadata: { + 'dc.title': [ + { + value: '28297_389341539060_6452876_n.jpg', + language: null, + authority: null, + display: '28297_389341539060_6452876_n.jpg', + confidence: -1, + place: 0 + } + ] + }, + accessConditions: [], + format: { + id: 16, + shortDescription: 'JPEG', + description: 'Joint Photographic Experts Group/JPEG File Interchange Format (JFIF)', + mimetype: 'image/jpeg', + supportLevel: 0, + internal: false, + extensions: null, + type: 'bitstreamformat' + }, + sizeBytes: 22737, + checkSum: { + checkSumAlgorithm: 'MD5', + value: '8722864dd671912f94a999ac7c4949d2' + }, + url: 'https://rest.api/dspace-spring-rest/api/core/bitstreams/7e2f4ba9-9316-41fd-844a-1ef435f41a42/content' + }; + const state: SubmissionObjectState = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: false, + sectionType: 'submission-form', + collapsed: false, + enabled: false, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: { + files: [fileData, fileData2] + }, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: false, + savePending: false, + depositPending: false + } + }; + const expectedState = { + files: [fileData] + }; + + const action = new DeleteUploadedFileAction(submissionId, 'upload', uuid2); + const newState = submissionObjectReducer(state, action); + + expect(newState[826].sections.upload.data).toEqual(expectedState); + }); + + it('should edit file data', () => { + const uuid = '8cd86fba-70c8-483d-838a-70d28e7ed570'; + const fileData: any = { + uuid: uuid, + metadata: { + 'dc.title': [ + { + value: '28297_389341539060_6452876_n.jpg', + language: null, + authority: null, + display: '28297_389341539060_6452876_n.jpg', + confidence: -1, + place: 0 + } + ] + }, + accessConditions: [], + format: { + id: 16, + shortDescription: 'JPEG', + description: 'Joint Photographic Experts Group/JPEG File Interchange Format (JFIF)', + mimetype: 'image/jpeg', + supportLevel: 0, + internal: false, + extensions: null, + type: 'bitstreamformat' + }, + sizeBytes: 22737, + checkSum: { + checkSumAlgorithm: 'MD5', + value: '8722864dd671912f94a999ac7c4949d2' + }, + url: 'https://rest.api/dspace-spring-rest/api/core/bitstreams/8cd86fba-70c8-483d-838a-70d28e7ed570/content' + }; + const fileData2: any = { + uuid: uuid, + metadata: { + 'dc.title': [ + { + value: 'New title', + language: null, + authority: null, + display: 'New title', + confidence: -1, + place: 0 + } + ] + }, + accessConditions: [], + format: { + id: 16, + shortDescription: 'JPEG', + description: 'Joint Photographic Experts Group/JPEG File Interchange Format (JFIF)', + mimetype: 'image/jpeg', + supportLevel: 0, + internal: false, + extensions: null, + type: 'bitstreamformat' + }, + sizeBytes: 22737, + checkSum: { + checkSumAlgorithm: 'MD5', + value: '8722864dd671912f94a999ac7c4949d2' + }, + url: 'https://rest.api/dspace-spring-rest/api/core/bitstreams/7e2f4ba9-9316-41fd-844a-1ef435f41a42/content' + }; + + const state: SubmissionObjectState = { + 826: { + collection: collectionId, + definition: 'traditional', + selfUrl: selfUrl, + activeSection: null, + sections: { + extraction: { + config: '', + mandatory: true, + sectionType: 'utils', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + collection: { + config: '', + mandatory: true, + sectionType: 'collection', + visibility: { + main: 'HIDDEN', + other: 'HIDDEN' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpageone: { + header: 'submit.progressbar.describe.stepone', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpageone', + mandatory: true, + sectionType: 'submission-form', + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + traditionalpagetwo: { + header: 'submit.progressbar.describe.steptwo', + config: 'https://dspace7.4science.it/or2018/api/config/submissionforms/traditionalpagetwo', + mandatory: false, + sectionType: 'submission-form', + collapsed: false, + enabled: false, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any, + upload: { + header: 'submit.progressbar.upload', + config: 'https://dspace7.4science.it/or2018/api/config/submissionuploads/upload', + mandatory: true, + sectionType: 'upload', + collapsed: false, + enabled: true, + data: { + files: [fileData] + }, + errors: [], + isLoading: false, + isValid: false + } as any, + license: { + header: 'submit.progressbar.license', + config: '', + mandatory: true, + sectionType: 'license', + visibility: { + main: null, + other: 'READONLY' + }, + collapsed: false, + enabled: true, + data: {}, + errors: [], + isLoading: false, + isValid: false + } as any + }, + isLoading: false, + savePending: false, + depositPending: false + } + }; + const expectedState = { + files: [fileData2] + }; + + const action = new EditFileDataAction(submissionId, 'upload', uuid, fileData2); + const newState = submissionObjectReducer(state, action); + + expect(newState[826].sections.upload.data).toEqual(expectedState); + }); + +}); diff --git a/src/app/submission/objects/submission-objects.reducer.ts b/src/app/submission/objects/submission-objects.reducer.ts index 1179591790..be79df2233 100644 --- a/src/app/submission/objects/submission-objects.reducer.ts +++ b/src/app/submission/objects/submission-objects.reducer.ts @@ -1,22 +1,39 @@ -import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util'; +import { hasValue, isNotEmpty, isNotNull, isUndefined } from '../../shared/empty.util'; import { findKey, uniqWith, isEqual, differenceWith } from 'lodash'; import { CompleteInitSubmissionFormAction, DeleteUploadedFileAction, - DisableSectionAction, EditFileDataAction, - EnableSectionAction, NewUploadedFileAction, - LoadSubmissionFormAction, SectionStatusChangeAction, + DisableSectionAction, + EditFileDataAction, + EnableSectionAction, + NewUploadedFileAction, + InitSubmissionFormAction, + SectionStatusChangeAction, SubmissionObjectAction, - SubmissionObjectActionTypes, ClearSectionErrorsAction, InertSectionErrorsAction, - DeleteSectionErrorsAction, ResetSubmissionFormAction, UpdateSectionDataAction, SaveSubmissionFormAction, - CompleteSaveSubmissionFormAction, SetActiveSectionAction, SaveSubmissionSectionFormAction, - DepositSubmissionAction, DepositSubmissionSuccessAction, DepositSubmissionErrorAction, - ChangeSubmissionCollectionAction, SaveSubmissionFormSuccessAction, SaveSubmissionFormErrorAction, - SaveSubmissionSectionFormSuccessAction, SaveSubmissionSectionFormErrorAction, SetWorkspaceDuplicatedAction, - SetWorkflowDuplicatedAction, InitSectionAction, RemoveSectionErrorsAction + SubmissionObjectActionTypes, + InertSectionErrorsAction, + DeleteSectionErrorsAction, + ResetSubmissionFormAction, + UpdateSectionDataAction, + SaveSubmissionFormAction, + SetActiveSectionAction, + SaveSubmissionSectionFormAction, + DepositSubmissionAction, + DepositSubmissionSuccessAction, + DepositSubmissionErrorAction, + ChangeSubmissionCollectionAction, + SaveSubmissionFormSuccessAction, + SaveSubmissionFormErrorAction, + SaveSubmissionSectionFormSuccessAction, + SaveSubmissionSectionFormErrorAction, + SetWorkspaceDuplicatedAction, + SetWorkflowDuplicatedAction, + InitSectionAction, + RemoveSectionErrorsAction, + SaveForLaterSubmissionFormAction, + SaveAndDepositSubmissionAction, SaveForLaterSubmissionFormSuccessAction, SaveForLaterSubmissionFormErrorAction } from './submission-objects.actions'; -import { deleteProperty } from '../../shared/object.util'; import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model'; import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/workspaceitem-section-upload.model'; import { SectionsType } from '../sections/sections-type'; @@ -76,16 +93,12 @@ export function submissionObjectReducer(state = initialState, action: Submission switch (action.type) { // submission form actions - case SubmissionObjectActionTypes.INIT_SUBMISSION_FORM: { - return state; - } - case SubmissionObjectActionTypes.COMPLETE_INIT_SUBMISSION_FORM: { return completeInit(state, action as CompleteInitSubmissionFormAction); } - case SubmissionObjectActionTypes.LOAD_SUBMISSION_FORM: { - return initSubmission(state, action as LoadSubmissionFormAction); + case SubmissionObjectActionTypes.INIT_SUBMISSION_FORM: { + return initSubmission(state, action as InitSubmissionFormAction); } case SubmissionObjectActionTypes.RESET_SUBMISSION_FORM: { @@ -98,40 +111,24 @@ export function submissionObjectReducer(state = initialState, action: Submission case SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM: case SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM: - case SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION: { + case SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION: + case SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM: { return saveSubmission(state, action as SaveSubmissionFormAction); } case SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS: - case SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS: { - return completeSave(state, action as SaveSubmissionFormSuccessAction); - } - + case SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS: + case SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS: case SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR: - case SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_ERROR: { - return completeSave(state, action as SaveSubmissionFormErrorAction); - } - - case SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM: { - return saveSubmission(state, action as SaveSubmissionSectionFormAction); - } - - case SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS: { - return completeSave(state, action as SaveSubmissionSectionFormSuccessAction); - } - + case SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_ERROR: case SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR: { - return completeSave(state, action as SaveSubmissionSectionFormErrorAction); + return completeSave(state, action as SaveSubmissionFormErrorAction); } case SubmissionObjectActionTypes.CHANGE_SUBMISSION_COLLECTION: { return changeCollection(state, action as ChangeSubmissionCollectionAction); } - case SubmissionObjectActionTypes.COMPLETE_SAVE_SUBMISSION_FORM: { - return completeSave(state, action as CompleteSaveSubmissionFormAction); - } - case SubmissionObjectActionTypes.DEPOSIT_SUBMISSION: { return startDeposit(state, action as DepositSubmissionAction); } @@ -174,10 +171,6 @@ export function submissionObjectReducer(state = initialState, action: Submission return updateSectionData(state, action as UpdateSectionDataAction); } - case SubmissionObjectActionTypes.REMOVE_SECTION_ERRORS: { - return removeSectionErrors(state, action as RemoveSectionErrorsAction); - } - case SubmissionObjectActionTypes.DISABLE_SECTION: { return changeSectionState(state, action as DisableSectionAction, false); } @@ -209,16 +202,16 @@ export function submissionObjectReducer(state = initialState, action: Submission } // errors actions - case SubmissionObjectActionTypes.INSERT_ERRORS: { - return insertError(state, action as InertSectionErrorsAction); + case SubmissionObjectActionTypes.ADD_SECTION_ERROR: { + return addError(state, action as InertSectionErrorsAction); } - case SubmissionObjectActionTypes.DELETE_ERRORS: { + case SubmissionObjectActionTypes.DELETE_SECTION_ERROR: { return removeError(state, action as DeleteSectionErrorsAction); } - case SubmissionObjectActionTypes.CLEAR_ERRORS: { - return clearErrorsFromSection(state, action as ClearSectionErrorsAction); + case SubmissionObjectActionTypes.REMOVE_SECTION_ERRORS: { + return removeSectionErrors(state, action as RemoveSectionErrorsAction); } default: { @@ -230,24 +223,25 @@ export function submissionObjectReducer(state = initialState, action: Submission // ------ Submission error functions ------ // const removeError = (state: SubmissionObjectState, action: DeleteSectionErrorsAction): SubmissionObjectState => { - const { submissionId, sectionId, error } = action.payload; + const { submissionId, sectionId, errors } = action.payload; if (hasValue(state[ submissionId ].sections[ sectionId ])) { - let errors = state[ submissionId ].sections[ sectionId ].errors.filter((currentError) => { - return currentError.message !== error && !isEqual(currentError, error); - }); + let filteredErrors; - if (action.payload.error instanceof Array) { - errors = differenceWith(errors, action.payload.error, isEqual); + if (Array.isArray(errors)) { + filteredErrors = differenceWith(errors, errors, isEqual); + } else { + filteredErrors = state[ submissionId ].sections[ sectionId ].errors + .filter((currentError) => currentError.path !== errors.path || !isEqual(currentError, errors)); } return Object.assign({}, state, { [ submissionId ]: Object.assign({}, state[ submissionId ], { sections: Object.assign({}, state[ submissionId ].sections, { - [ sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], { - errors + [ sectionId ]: Object.assign({}, state[ submissionId ].sections [ sectionId ], { + errors: filteredErrors }) - }), + }) }) }); } else { @@ -255,7 +249,7 @@ const removeError = (state: SubmissionObjectState, action: DeleteSectionErrorsAc } }; -const insertError = (state: SubmissionObjectState, action: InertSectionErrorsAction): SubmissionObjectState => { +const addError = (state: SubmissionObjectState, action: InertSectionErrorsAction): SubmissionObjectState => { const { submissionId, sectionId, error } = action.payload; if (hasValue(state[ submissionId ].sections[ sectionId ])) { @@ -275,25 +269,32 @@ const insertError = (state: SubmissionObjectState, action: InertSectionErrorsAct } }; -const clearErrorsFromSection = (state: SubmissionObjectState, action: ClearSectionErrorsAction): SubmissionObjectState => { - const { submissionId, sectionId } = action.payload; - - if (hasValue(state[ submissionId ].sections[ sectionId ])) { - const errors = []; // clear the errors - +/** + * Remove all section's errors. + * + * @param state + * the current state + * @param action + * an RemoveSectionErrorsAction + * @return SubmissionObjectState + * the new state, with the section's errors updated. + */ +function removeSectionErrors(state: SubmissionObjectState, action: RemoveSectionErrorsAction): SubmissionObjectState { + if (isNotEmpty(state[ action.payload.submissionId ]) + && isNotEmpty(state[ action.payload.submissionId ].sections[ action.payload.sectionId])) { return Object.assign({}, state, { - [ submissionId ]: Object.assign({}, state[ submissionId ], { - sections: Object.assign({}, state[ submissionId ].sections, { - [ sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], { - errors + [ 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: [] }) - }), + }) }) }); } else { return state; } -}; +} // ------ Submission functions ------ // @@ -303,11 +304,11 @@ const clearErrorsFromSection = (state: SubmissionObjectState, action: ClearSecti * @param state * the current state * @param action - * an LoadSubmissionFormAction + * an InitSubmissionFormAction | ResetSubmissionFormAction * @return SubmissionObjectState * the new state, with the section removed. */ -function initSubmission(state: SubmissionObjectState, action: LoadSubmissionFormAction | ResetSubmissionFormAction): SubmissionObjectState { +function initSubmission(state: SubmissionObjectState, action: InitSubmissionFormAction | ResetSubmissionFormAction): SubmissionObjectState { const newState = Object.assign({}, state); newState[ action.payload.submissionId ] = { @@ -374,11 +375,16 @@ function completeInit(state: SubmissionObjectState, action: CompleteInitSubmissi * @param state * the current state * @param action - * an SaveSubmissionFormAction + * an SaveSubmissionFormAction | SaveSubmissionSectionFormAction + * | SaveForLaterSubmissionFormAction | SaveAndDepositSubmissionAction * @return SubmissionObjectState * the new state, with the flag set to true. */ -function saveSubmission(state: SubmissionObjectState, action: SaveSubmissionFormAction): SubmissionObjectState { +function saveSubmission(state: SubmissionObjectState, + action: SaveSubmissionFormAction + | SaveSubmissionSectionFormAction + | SaveForLaterSubmissionFormAction + | SaveAndDepositSubmissionAction): SubmissionObjectState { if (hasValue(state[ action.payload.submissionId ])) { return Object.assign({}, state, { [ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], { @@ -399,15 +405,18 @@ function saveSubmission(state: SubmissionObjectState, action: SaveSubmissionForm * @param state * the current state * @param action - * an CompleteSaveSubmissionFormAction | SaveSubmissionFormSuccessAction | SaveSubmissionFormErrorAction + * an SaveSubmissionFormSuccessAction | SaveForLaterSubmissionFormSuccessAction + * | SaveSubmissionSectionFormSuccessAction | SaveSubmissionFormErrorAction + * | SaveForLaterSubmissionFormErrorAction | SaveSubmissionSectionFormErrorAction * @return SubmissionObjectState * the new state, with the flag set to false. */ function completeSave(state: SubmissionObjectState, - action: CompleteSaveSubmissionFormAction - | SaveSubmissionFormSuccessAction - | SaveSubmissionFormErrorAction + action: SaveSubmissionFormSuccessAction + | SaveForLaterSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction + | SaveSubmissionFormErrorAction + | SaveForLaterSubmissionFormErrorAction | SaveSubmissionSectionFormErrorAction): SubmissionObjectState { if (hasValue(state[ action.payload.submissionId ])) { return Object.assign({}, state, { @@ -471,7 +480,7 @@ function endDeposit(state: SubmissionObjectState, action: DepositSubmissionSucce * @param state * the current state * @param action - * an LoadSubmissionFormAction + * an InitSubmissionFormAction * @return SubmissionObjectState * the new state, with the section removed. */ @@ -575,33 +584,6 @@ function updateSectionData(state: SubmissionObjectState, action: UpdateSectionDa } } -/** - * Remove section's errors. - * - * @param state - * the current state - * @param action - * an RemoveSectionErrorsAction - * @return SubmissionObjectState - * the new state, with the section's errors updated. - */ -function removeSectionErrors(state: SubmissionObjectState, action: RemoveSectionErrorsAction): SubmissionObjectState { - if (isNotEmpty(state[ action.payload.submissionId ]) - && isNotEmpty(state[ action.payload.submissionId ].sections[ action.payload.sectionId])) { - return Object.assign({}, state, { - [ 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: [] - }) - }) - }) - }); - } else { - return state; - } -} - /** * Set a section state. * @@ -637,7 +619,7 @@ function changeSectionState(state: SubmissionObjectState, action: EnableSectionA * @param state * the current state * @param action - * an LoadSubmissionFormAction + * an SectionStatusChangeAction * @return SubmissionObjectState * the new state, with the section new validity status. */ @@ -662,75 +644,48 @@ function setIsValid(state: SubmissionObjectState, action: SectionStatusChangeAct // ------ Upload file functions ------ // /** - * Set a new bitstream. + * Set a new file. * * @param state * the current state * @param action * a NewUploadedFileAction action * @return SubmissionObjectState - * the new state, with the new bitstream. + * the new state, with the new file. */ function newFile(state: SubmissionObjectState, action: NewUploadedFileAction): SubmissionObjectState { const filesData = state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data as WorkspaceitemSectionUploadObject; - if (isNotUndefined(filesData.files) - && !hasValue(filesData.files[ action.payload.fileId ])) { - const newData = []; - newData[ action.payload.fileId ] = action.payload.data; - return Object.assign({}, state, { - [ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], { - activeSection: state[ action.payload.submissionId ].activeSection, - sections: Object.assign({}, state[ action.payload.submissionId ].sections, - Object.assign({}, { - [ action.payload.sectionId ]: { - data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, { - files: Object.assign({}, - filesData.files, - newData) - }), - isValid: state[ action.payload.submissionId ].sections[ action.payload.sectionId ].isValid, - errors: state[ action.payload.submissionId ].sections[ action.payload.sectionId ].errors - } - } - ) - ), - isLoading: state[ action.payload.submissionId ].isLoading, - savePending: state[ action.payload.submissionId ].savePending, - }) - }); + let newData; + if (isUndefined(filesData.files)) { + newData = { + files: [action.payload.data] + }; } else { - const newData = []; - newData[ action.payload.fileId ] = action.payload.data; - return Object.assign({}, state, { - [ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], { - activeSection: state[ action.payload.submissionId ].activeSection, - sections: Object.assign({}, state[ action.payload.submissionId ].sections, - Object.assign({}, { - [ action.payload.sectionId ]: { - data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, { - files: newData - }), - isValid: state[ action.payload.submissionId ].sections[ action.payload.sectionId ].isValid, - errors: state[ action.payload.submissionId ].sections[ action.payload.sectionId ].errors - } - }) - ), - isLoading: state[ action.payload.submissionId ].isLoading, - savePending: state[ action.payload.submissionId ].savePending, - }) - }); + newData = filesData; + newData.files.push(action.payload.data) } + + return Object.assign({}, state, { + [ 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 ], { + enabled: true, + data: newData + }) + }) + }) + }); } /** - * Edit a bitstream. + * Edit a file. * * @param state * the current state * @param action * a EditFileDataAction action * @return SubmissionObjectState - * the new state, with the edited bitstream. + * the new state, with the edited file. */ function editFileData(state: SubmissionObjectState, action: EditFileDataAction): SubmissionObjectState { const filesData = state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data as WorkspaceitemSectionUploadObject; @@ -739,6 +694,8 @@ function editFileData(state: SubmissionObjectState, action: EditFileDataAction): filesData.files, { uuid: action.payload.fileId }); if (isNotNull(fileIndex)) { + const newData = Array.from(filesData.files); + newData[fileIndex] = action.payload.data; return Object.assign({}, state, { [ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], { activeSection: state[ action.payload.submissionId ].activeSection, @@ -746,24 +703,10 @@ function editFileData(state: SubmissionObjectState, action: EditFileDataAction): Object.assign({}, { [ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], { data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, { - files: Object.assign({}, - filesData.files, { - [ fileIndex ]: action.payload.data - }) + files: newData }) }) }) - // Object.assign({}, state[action.payload.submissionId].sections[action.payload.sectionId],{ - // [ action.payload.sectionId ]: { - // data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, { - // files: Object.assign({}, - // filesData.files, { - // [ fileIndex ]: action.payload.data - // }) - // }) - // } - // } - // ) ), isLoading: state[ action.payload.submissionId ].isLoading, savePending: state[ action.payload.submissionId ].savePending, @@ -775,44 +718,35 @@ function editFileData(state: SubmissionObjectState, action: EditFileDataAction): } /** - * Delete a bitstream. + * Delete a file. * * @param state * the current state * @param action * a DeleteUploadedFileAction action * @return SubmissionObjectState - * the new state, with the bitstream removed. + * the new state, with the file removed. */ function deleteFile(state: SubmissionObjectState, action: DeleteUploadedFileAction): SubmissionObjectState { const filesData = state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data as WorkspaceitemSectionUploadObject; if (hasValue(filesData.files)) { - const fileIndex = findKey( + const fileIndex: any = findKey( filesData.files, {uuid: action.payload.fileId}); if (isNotNull(fileIndex)) { + const newData = Array.from(filesData.files); + newData.splice(fileIndex, 1); return Object.assign({}, state, { [ action.payload.submissionId ]: Object.assign({}, state[action.payload.submissionId], { - activeSection: state[ action.payload.submissionId ].activeSection, sections: Object.assign({}, state[action.payload.submissionId].sections, Object.assign({}, { [ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], { data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, { - files: deleteProperty(filesData.files, fileIndex) + files: newData }) }) }) - // Object.assign({}, state[action.payload.submissionId].sections[action.payload.sectionId], { - // [ action.payload.sectionId ]: { - // data: Object.assign({}, state[action.payload.submissionId].sections[action.payload.sectionId].data, { - // files: deleteProperty(filesData.files, fileIndex) - // }) - // } - // } - // ) - ), - isLoading: state[action.payload.submissionId].isLoading, - savePending: state[action.payload.submissionId].savePending, + ) }) }); } diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index b5dc2c3dee..0c573e5934 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -131,7 +131,7 @@ export class FormSectionComponent extends SectionModelComponent implements OnDes message: msg + e.toString(), path: '/sections/' + this.sectionData.id }; - this.sectionService.setSectionError(this.submissionId, this.sectionData.id, [sectionError]) + this.sectionService.setSectionError(this.submissionId, this.sectionData.id, sectionError); }) } diff --git a/src/app/submission/sections/sections.directive.ts b/src/app/submission/sections/sections.directive.ts index aa61ca5e88..08d76343d7 100644 --- a/src/app/submission/sections/sections.directive.ts +++ b/src/app/submission/sections/sections.directive.ts @@ -3,7 +3,7 @@ import { ChangeDetectorRef, Directive, Input, OnDestroy, OnInit } from '@angular import { Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; import { Subscription } from 'rxjs/Subscription'; -import { isEmpty, uniq } from 'lodash'; +import { uniq } from 'lodash'; import { SectionsService } from './sections.service'; import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util'; @@ -12,7 +12,7 @@ import { SubmissionState } from '../submission.reducers'; import { SubmissionSectionError, SubmissionSectionObject } from '../objects/submission-objects.reducer'; import parseSectionErrorPaths, { SectionErrorPath } from '../utils/parseSectionErrorPaths'; import { - DeleteSectionErrorsAction, + RemoveSectionErrorsAction, SaveSubmissionSectionFormAction, SetActiveSectionAction } from '../objects/submission-objects.actions'; @@ -143,12 +143,9 @@ export class SectionsDirective implements OnDestroy, OnInit { } public resetErrors() { - this.sectionErrors - .forEach((errorItem) => { - // because it has been deleted, remove the error from the state - const removeAction = new DeleteSectionErrorsAction(this.submissionId, this.sectionId, errorItem); - this.store.dispatch(removeAction); - }) + if (isNotEmpty(this.sectionErrors)) { + this.store.dispatch(new RemoveSectionErrorsAction(this.submissionId, this.sectionId)); + } this.sectionErrors = []; } diff --git a/src/app/submission/sections/sections.service.ts b/src/app/submission/sections/sections.service.ts index b01f58751e..04de7346a6 100644 --- a/src/app/submission/sections/sections.service.ts +++ b/src/app/submission/sections/sections.service.ts @@ -7,10 +7,9 @@ import { isEqual } from 'lodash'; import { hasValue, isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empty.util'; import { - DeleteSectionErrorsAction, DisableSectionAction, EnableSectionAction, - InertSectionErrorsAction, + InertSectionErrorsAction, RemoveSectionErrorsAction, UpdateSectionDataAction } from '../objects/submission-objects.actions'; import { @@ -37,7 +36,7 @@ export class SectionsService { public checkSectionErrors(submissionId, sectionId, formId, currentErrors, prevErrors = []) { if (isEmpty(currentErrors)) { - this.store.dispatch(new DeleteSectionErrorsAction(submissionId, sectionId, currentErrors)); + this.store.dispatch(new RemoveSectionErrorsAction(submissionId, sectionId)); this.store.dispatch(new FormClearErrorsAction(formId)); } else if (!isEqual(currentErrors, prevErrors)) { const dispatchedErrors = []; @@ -148,7 +147,7 @@ export class SectionsService { } } - public setSectionError(submissionId: string, sectionId: string, errors: SubmissionSectionError[]) { - this.store.dispatch(new InertSectionErrorsAction(submissionId, sectionId, errors)); + public setSectionError(submissionId: string, sectionId: string, error: SubmissionSectionError) { + this.store.dispatch(new InertSectionErrorsAction(submissionId, sectionId, error)); } } diff --git a/src/app/submission/sections/upload/file/file.component.ts b/src/app/submission/sections/upload/file/file.component.ts index f522f6c3b7..c3b18a711f 100644 --- a/src/app/submission/sections/upload/file/file.component.ts +++ b/src/app/submission/sections/upload/file/file.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, Input, OnChanges, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { SectionUploadService } from '../section-upload.service'; import { isNotEmpty, isNotNull, isNotUndefined } from '../../../../shared/empty.util'; @@ -31,7 +31,7 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { @Input() configMetadataForm: SubmissionFormsModel; @Input() fileId; @Input() fileIndex; - @Input() fileName + @Input() fileName; @Input() sectionId; @Input() submissionId; @@ -138,15 +138,15 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { accessConditionsToSave.push(accessConditionOpt); } else { accessConditionOpt = Object.assign({}, accessCondition); - accessConditionOpt.name = Array.isArray(accessCondition.name) ? accessCondition.name[0].value : accessCondition.name.value; - accessConditionOpt.groupUUID = Array.isArray(accessCondition.groupUUID) ? accessCondition.groupUUID[0].value : accessCondition.groupUUID.value; + accessConditionOpt.name = this.retrieveValueFromField(accessCondition.name); + accessConditionOpt.groupUUID = this.retrieveValueFromField(accessCondition.groupUUID); if (accessCondition.startDate) { - const startDate = Array.isArray(accessCondition.startDate) ? accessCondition.startDate[0].value : accessCondition.startDate.value; + const startDate = this.retrieveValueFromField(accessCondition.startDate); accessConditionOpt.startDate = dateToGMTString(startDate); accessConditionOpt = deleteProperty(accessConditionOpt, 'endDate'); } if (accessCondition.endDate) { - const endDate = Array.isArray(accessCondition.endDate) ? accessCondition.endDate[0].value : accessCondition.endDate.value; + const endDate = this.retrieveValueFromField(accessCondition.endDate); accessConditionOpt.endDate = dateToGMTString(endDate); accessConditionOpt = deleteProperty(accessConditionOpt, 'startDate'); } @@ -174,8 +174,14 @@ export class UploadSectionFileComponent implements OnChanges, OnInit { ); } + private retrieveValueFromField(field) { + const temp = Array.isArray(field) ? field[0] : field; + return (temp) ? temp.value : undefined; + } + public switchMode() { this.readMode = !this.readMode; this.cdr.detectChanges(); } + } diff --git a/src/app/submission/sections/upload/section-upload.component.ts b/src/app/submission/sections/upload/section-upload.component.ts index c392c52d8f..c3b64ac70d 100644 --- a/src/app/submission/sections/upload/section-upload.component.ts +++ b/src/app/submission/sections/upload/section-upload.component.ts @@ -149,19 +149,19 @@ export class UploadSectionComponent extends SectionModelComponent implements OnI .getUploadedFileList(this.submissionId, this.sectionData.id) .filter((bitstreamList) => isNotUndefined(bitstreamList)) .distinctUntilChanged() - .subscribe((fileList) => { + .subscribe((fileList: any[]) => { let sectionStatus = false; this.fileList = []; this.fileIndexes = []; this.fileNames = []; - if (isNotUndefined(fileList) && Object.keys(fileList).length > 0) { - Object.keys(fileList) - .forEach((key) => { - this.fileList.push(fileList[key]); - this.fileIndexes.push(fileList[key].uuid); - const fileName = fileList[key].metadata['dc.title'][0].display || fileList[key].uuid; - this.fileNames.push(fileName); - }); + this.changeDetectorRef.detectChanges(); + if (isNotUndefined(fileList) && fileList.length > 0) { + fileList.forEach((file, index) => { + this.fileList.push(file); + this.fileIndexes.push(file.uuid); + const fileName = file.metadata['dc.title'][0].display || file.uuid; + this.fileNames.push(fileName); + }); sectionStatus = true; } this.store.dispatch(new SectionStatusChangeAction(this.submissionId,