mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 10:34:15 +00:00
Added more comments
This commit is contained in:
@@ -24,7 +24,7 @@ import {
|
|||||||
SaveSubmissionFormSuccessAction,
|
SaveSubmissionFormSuccessAction,
|
||||||
SaveSubmissionSectionFormAction,
|
SaveSubmissionSectionFormAction,
|
||||||
SaveSubmissionSectionFormErrorAction,
|
SaveSubmissionSectionFormErrorAction,
|
||||||
SaveSubmissionSectionFormSuccessAction,
|
SaveSubmissionSectionFormSuccessAction, SubmissionObjectAction,
|
||||||
SubmissionObjectActionTypes,
|
SubmissionObjectActionTypes,
|
||||||
UpdateSectionDataAction
|
UpdateSectionDataAction
|
||||||
} from './submission-objects.actions';
|
} from './submission-objects.actions';
|
||||||
@@ -48,6 +48,9 @@ import { SubmissionJsonPatchOperationsService } from '../../core/submission/subm
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubmissionObjectEffects {
|
export class SubmissionObjectEffects {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [InitSectionAction] for every submission sections and dispatch a [CompleteInitSubmissionFormAction]
|
||||||
|
*/
|
||||||
@Effect() loadForm$ = this.actions$.pipe(
|
@Effect() loadForm$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM),
|
ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM),
|
||||||
map((action: InitSubmissionFormAction) => {
|
map((action: InitSubmissionFormAction) => {
|
||||||
@@ -83,6 +86,9 @@ export class SubmissionObjectEffects {
|
|||||||
));
|
));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [InitSubmissionFormAction]
|
||||||
|
*/
|
||||||
@Effect() resetForm$ = this.actions$.pipe(
|
@Effect() resetForm$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM),
|
ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM),
|
||||||
map((action: ResetSubmissionFormAction) =>
|
map((action: ResetSubmissionFormAction) =>
|
||||||
@@ -95,6 +101,9 @@ export class SubmissionObjectEffects {
|
|||||||
null
|
null
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [SaveSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() saveSubmission$ = this.actions$.pipe(
|
@Effect() saveSubmission$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM),
|
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM),
|
||||||
switchMap((action: SaveSubmissionFormAction) => {
|
switchMap((action: SaveSubmissionFormAction) => {
|
||||||
@@ -106,6 +115,9 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [SaveForLaterSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() saveForLaterSubmission$ = this.actions$.pipe(
|
@Effect() saveForLaterSubmission$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM),
|
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM),
|
||||||
switchMap((action: SaveForLaterSubmissionFormAction) => {
|
switchMap((action: SaveForLaterSubmissionFormAction) => {
|
||||||
@@ -117,6 +129,9 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call parseSaveResponse and dispatch actions
|
||||||
|
*/
|
||||||
@Effect() saveSubmissionSuccess$ = this.actions$.pipe(
|
@Effect() saveSubmissionSuccess$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS),
|
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS),
|
||||||
withLatestFrom(this.store$),
|
withLatestFrom(this.store$),
|
||||||
@@ -125,6 +140,9 @@ export class SubmissionObjectEffects {
|
|||||||
}),
|
}),
|
||||||
mergeMap((actions) => observableFrom(actions)));
|
mergeMap((actions) => observableFrom(actions)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [SaveSubmissionSectionFormSuccessAction] or a [SaveSubmissionSectionFormErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() saveSection$ = this.actions$.pipe(
|
@Effect() saveSection$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM),
|
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM),
|
||||||
switchMap((action: SaveSubmissionSectionFormAction) => {
|
switchMap((action: SaveSubmissionSectionFormAction) => {
|
||||||
@@ -137,11 +155,17 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on error
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) saveError$ = this.actions$.pipe(
|
@Effect({dispatch: false}) saveError$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR),
|
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR),
|
||||||
withLatestFrom(this.store$),
|
withLatestFrom(this.store$),
|
||||||
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice'))));
|
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice'))));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call parseSaveResponse and dispatch actions or dispatch [SaveSubmissionFormErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() saveAndDeposit$ = this.actions$.pipe(
|
@Effect() saveAndDeposit$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
|
ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
|
||||||
withLatestFrom(this.store$),
|
withLatestFrom(this.store$),
|
||||||
@@ -161,6 +185,9 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [DepositSubmissionSuccessAction] or a [DepositSubmissionErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() depositSubmission$ = this.actions$.pipe(
|
@Effect() depositSubmission$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION),
|
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION),
|
||||||
withLatestFrom(this.store$),
|
withLatestFrom(this.store$),
|
||||||
@@ -170,20 +197,32 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on success and redirect to MyDSpace page
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) saveForLaterSubmissionSuccess$ = this.actions$.pipe(
|
@Effect({dispatch: false}) saveForLaterSubmissionSuccess$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS),
|
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS),
|
||||||
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))),
|
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))),
|
||||||
tap(() => this.submissionService.redirectToMyDSpace()));
|
tap(() => this.submissionService.redirectToMyDSpace()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on success and redirect to MyDSpace page
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$.pipe(
|
@Effect({dispatch: false}) depositSubmissionSuccess$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS),
|
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS),
|
||||||
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))),
|
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))),
|
||||||
tap(() => this.submissionService.redirectToMyDSpace()));
|
tap(() => this.submissionService.redirectToMyDSpace()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on error
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) depositSubmissionError$ = this.actions$.pipe(
|
@Effect({dispatch: false}) depositSubmissionError$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR),
|
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR),
|
||||||
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))));
|
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a [DiscardSubmissionSuccessAction] or a [DiscardSubmissionErrorAction] on error
|
||||||
|
*/
|
||||||
@Effect() discardSubmission$ = this.actions$.pipe(
|
@Effect() discardSubmission$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION),
|
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION),
|
||||||
switchMap((action: DepositSubmissionAction) => {
|
switchMap((action: DepositSubmissionAction) => {
|
||||||
@@ -192,11 +231,17 @@ export class SubmissionObjectEffects {
|
|||||||
catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId))));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on success and redirect to MyDSpace page
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$.pipe(
|
@Effect({dispatch: false}) discardSubmissionSuccess$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS),
|
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS),
|
||||||
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))),
|
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))),
|
||||||
tap(() => this.submissionService.redirectToMyDSpace()));
|
tap(() => this.submissionService.redirectToMyDSpace()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification on error
|
||||||
|
*/
|
||||||
@Effect({dispatch: false}) discardSubmissionError$ = this.actions$.pipe(
|
@Effect({dispatch: false}) discardSubmissionError$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR),
|
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR),
|
||||||
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))));
|
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))));
|
||||||
@@ -210,6 +255,12 @@ export class SubmissionObjectEffects {
|
|||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the submission object retrieved from REST haven't section errors
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
* The submission object retrieved from REST
|
||||||
|
*/
|
||||||
protected canDeposit(response: SubmissionObject[]) {
|
protected canDeposit(response: SubmissionObject[]) {
|
||||||
let canDeposit = true;
|
let canDeposit = true;
|
||||||
|
|
||||||
@@ -225,7 +276,26 @@ export class SubmissionObjectEffects {
|
|||||||
return canDeposit;
|
return canDeposit;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected parseSaveResponse(currentState: SubmissionObjectEntry, response: SubmissionObject[], submissionId: string, notify: boolean = true) {
|
/**
|
||||||
|
* Parse the submission object retrieved from REST haven't section errors and return actions to dispatch
|
||||||
|
*
|
||||||
|
* @param currentState
|
||||||
|
* The current SubmissionObjectEntry
|
||||||
|
* @param response
|
||||||
|
* The submission object retrieved from REST
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param notify
|
||||||
|
* A boolean that indicate if show notification or not
|
||||||
|
* @return SubmissionObjectAction[]
|
||||||
|
* List of SubmissionObjectAction to dispatch
|
||||||
|
*/
|
||||||
|
protected parseSaveResponse(
|
||||||
|
currentState: SubmissionObjectEntry,
|
||||||
|
response: SubmissionObject[],
|
||||||
|
submissionId: string,
|
||||||
|
notify: boolean = true): SubmissionObjectAction[] {
|
||||||
|
|
||||||
const mappedActions = [];
|
const mappedActions = [];
|
||||||
|
|
||||||
if (isNotEmpty(response)) {
|
if (isNotEmpty(response)) {
|
||||||
|
@@ -38,42 +38,138 @@ import { WorkspaceitemSectionDataType } from '../../core/submission/models/works
|
|||||||
import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/workspaceitem-section-upload.model';
|
import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/workspaceitem-section-upload.model';
|
||||||
import { SectionsType } from '../sections/sections-type';
|
import { SectionsType } from '../sections/sections-type';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent section visibility
|
||||||
|
*/
|
||||||
export interface SectionVisibility {
|
export interface SectionVisibility {
|
||||||
main: any;
|
main: any;
|
||||||
other: any;
|
other: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent section object state
|
||||||
|
*/
|
||||||
export interface SubmissionSectionObject {
|
export interface SubmissionSectionObject {
|
||||||
|
/**
|
||||||
|
* The section header
|
||||||
|
*/
|
||||||
header: string;
|
header: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The section configuration url
|
||||||
|
*/
|
||||||
config: string;
|
config: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this section is mandatory
|
||||||
|
*/
|
||||||
mandatory: boolean;
|
mandatory: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The section type
|
||||||
|
*/
|
||||||
sectionType: SectionsType;
|
sectionType: SectionsType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The section visibility
|
||||||
|
*/
|
||||||
visibility: SectionVisibility;
|
visibility: SectionVisibility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this section is collapsed
|
||||||
|
*/
|
||||||
collapsed: boolean,
|
collapsed: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this section is enabled
|
||||||
|
*/
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The section data object
|
||||||
|
*/
|
||||||
data: WorkspaceitemSectionDataType;
|
data: WorkspaceitemSectionDataType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of the section errors
|
||||||
|
*/
|
||||||
errors: SubmissionSectionError[];
|
errors: SubmissionSectionError[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this section is loading
|
||||||
|
*/
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this section is valid
|
||||||
|
*/
|
||||||
isValid: boolean;
|
isValid: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent section error
|
||||||
|
*/
|
||||||
export interface SubmissionSectionError {
|
export interface SubmissionSectionError {
|
||||||
|
/**
|
||||||
|
* A string representing error path
|
||||||
|
*/
|
||||||
path: string;
|
path: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error message
|
||||||
|
*/
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent SubmissionSectionObject entry
|
||||||
|
*/
|
||||||
export interface SubmissionSectionEntry {
|
export interface SubmissionSectionEntry {
|
||||||
[sectionId: string]: SubmissionSectionObject;
|
[sectionId: string]: SubmissionSectionObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent submission object state
|
||||||
|
*/
|
||||||
export interface SubmissionObjectEntry {
|
export interface SubmissionObjectEntry {
|
||||||
|
/**
|
||||||
|
* The collection this submission belonging to
|
||||||
|
*/
|
||||||
collection?: string,
|
collection?: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configuration name tha define this submission
|
||||||
|
*/
|
||||||
definition?: string,
|
definition?: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The submission self url
|
||||||
|
*/
|
||||||
selfUrl?: string;
|
selfUrl?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The submission active section
|
||||||
|
*/
|
||||||
activeSection?: string;
|
activeSection?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of submission's sections
|
||||||
|
*/
|
||||||
sections?: SubmissionSectionEntry;
|
sections?: SubmissionSectionEntry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if this submission is loading
|
||||||
|
*/
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if a submission save operation is pending
|
||||||
|
*/
|
||||||
savePending?: boolean;
|
savePending?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if a submission deposit operation is pending
|
||||||
|
*/
|
||||||
depositPending?: boolean;
|
depositPending?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,9 +35,20 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
|
|||||||
import { SubmissionService } from '../submission.service';
|
import { SubmissionService } from '../submission.service';
|
||||||
import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model';
|
import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service that provides methods used in submission process.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SectionsService {
|
export class SectionsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize service variables
|
||||||
|
* @param {NotificationsService} notificationsService
|
||||||
|
* @param {ScrollToService} scrollToService
|
||||||
|
* @param {SubmissionService} submissionService
|
||||||
|
* @param {Store<SubmissionState>} store
|
||||||
|
* @param {TranslateService} translate
|
||||||
|
*/
|
||||||
constructor(private notificationsService: NotificationsService,
|
constructor(private notificationsService: NotificationsService,
|
||||||
private scrollToService: ScrollToService,
|
private scrollToService: ScrollToService,
|
||||||
private submissionService: SubmissionService,
|
private submissionService: SubmissionService,
|
||||||
@@ -45,17 +56,35 @@ export class SectionsService {
|
|||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the list of the current section errors with the previous one,
|
||||||
|
* and dispatch actions to add/remove to/from the section state
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The workspaceitem self url
|
||||||
|
* @param formId
|
||||||
|
* The [SubmissionDefinitionsModel] that define submission configuration
|
||||||
|
* @param currentErrors
|
||||||
|
* The [SubmissionSectionError] that define submission sections init data
|
||||||
|
* @param prevErrors
|
||||||
|
* The [SubmissionSectionError] that define submission sections init errors
|
||||||
|
*/
|
||||||
public checkSectionErrors(
|
public checkSectionErrors(
|
||||||
submissionId: string,
|
submissionId: string,
|
||||||
sectionId: string,
|
sectionId: string,
|
||||||
formId: string,
|
formId: string,
|
||||||
currentErrors: SubmissionSectionError[],
|
currentErrors: SubmissionSectionError[],
|
||||||
prevErrors: SubmissionSectionError[] = []) {
|
prevErrors: SubmissionSectionError[] = []) {
|
||||||
|
// Remove previous error list if the current is empty
|
||||||
if (isEmpty(currentErrors)) {
|
if (isEmpty(currentErrors)) {
|
||||||
this.store.dispatch(new RemoveSectionErrorsAction(submissionId, sectionId));
|
this.store.dispatch(new RemoveSectionErrorsAction(submissionId, sectionId));
|
||||||
this.store.dispatch(new FormClearErrorsAction(formId));
|
this.store.dispatch(new FormClearErrorsAction(formId));
|
||||||
} else if (!isEqual(currentErrors, prevErrors)) {
|
} else if (!isEqual(currentErrors, prevErrors)) { // compare previous error list with the current one
|
||||||
const dispatchedErrors = [];
|
const dispatchedErrors = [];
|
||||||
|
|
||||||
|
// Itereate over the current error list
|
||||||
currentErrors.forEach((error: SubmissionSectionError) => {
|
currentErrors.forEach((error: SubmissionSectionError) => {
|
||||||
const errorPaths: SectionErrorPath[] = parseSectionErrorPaths(error.path);
|
const errorPaths: SectionErrorPath[] = parseSectionErrorPaths(error.path);
|
||||||
|
|
||||||
@@ -63,7 +92,7 @@ export class SectionsService {
|
|||||||
if (path.fieldId) {
|
if (path.fieldId) {
|
||||||
const fieldId = path.fieldId.replace(/\./g, '_');
|
const fieldId = path.fieldId.replace(/\./g, '_');
|
||||||
|
|
||||||
// Dispatch action to the form state;
|
// Dispatch action to add form error to the state;
|
||||||
const formAddErrorAction = new FormAddError(formId, fieldId, path.fieldIndex, error.message);
|
const formAddErrorAction = new FormAddError(formId, fieldId, path.fieldIndex, error.message);
|
||||||
this.store.dispatch(formAddErrorAction);
|
this.store.dispatch(formAddErrorAction);
|
||||||
dispatchedErrors.push(fieldId);
|
dispatchedErrors.push(fieldId);
|
||||||
@@ -71,6 +100,7 @@ export class SectionsService {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Itereate over the previous error list
|
||||||
prevErrors.forEach((error: SubmissionSectionError) => {
|
prevErrors.forEach((error: SubmissionSectionError) => {
|
||||||
const errorPaths: SectionErrorPath[] = parseSectionErrorPaths(error.path);
|
const errorPaths: SectionErrorPath[] = parseSectionErrorPaths(error.path);
|
||||||
|
|
||||||
@@ -79,6 +109,7 @@ export class SectionsService {
|
|||||||
const fieldId = path.fieldId.replace(/\./g, '_');
|
const fieldId = path.fieldId.replace(/\./g, '_');
|
||||||
|
|
||||||
if (!dispatchedErrors.includes(fieldId)) {
|
if (!dispatchedErrors.includes(fieldId)) {
|
||||||
|
// Dispatch action to remove form error from the state;
|
||||||
const formRemoveErrorAction = new FormRemoveErrorAction(formId, fieldId, path.fieldIndex);
|
const formRemoveErrorAction = new FormRemoveErrorAction(formId, fieldId, path.fieldIndex);
|
||||||
this.store.dispatch(formRemoveErrorAction);
|
this.store.dispatch(formRemoveErrorAction);
|
||||||
}
|
}
|
||||||
@@ -88,20 +119,58 @@ export class SectionsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [RemoveSectionErrorsAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
public dispatchRemoveSectionErrors(submissionId, sectionId) {
|
public dispatchRemoveSectionErrors(submissionId, sectionId) {
|
||||||
this.store.dispatch(new RemoveSectionErrorsAction(submissionId, sectionId));
|
this.store.dispatch(new RemoveSectionErrorsAction(submissionId, sectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the data object for the specified section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<WorkspaceitemSectionDataType>
|
||||||
|
* observable of [WorkspaceitemSectionDataType]
|
||||||
|
*/
|
||||||
public getSectionData(submissionId: string, sectionId: string): Observable<WorkspaceitemSectionDataType> {
|
public getSectionData(submissionId: string, sectionId: string): Observable<WorkspaceitemSectionDataType> {
|
||||||
return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the error list object data for the specified section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<SubmissionSectionError>
|
||||||
|
* observable of array of [SubmissionSectionError]
|
||||||
|
*/
|
||||||
public getSectionErrors(submissionId: string, sectionId: string): Observable<SubmissionSectionError[]> {
|
public getSectionErrors(submissionId: string, sectionId: string): Observable<SubmissionSectionError[]> {
|
||||||
return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionErrorsFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the state object for the specified section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<SubmissionSectionObject>
|
||||||
|
* observable of [SubmissionSectionObject]
|
||||||
|
*/
|
||||||
public getSectionState(submissionId: string, sectionId: string): Observable<SubmissionSectionObject> {
|
public getSectionState(submissionId: string, sectionId: string): Observable<SubmissionSectionObject> {
|
||||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)),
|
filter((sectionObj: SubmissionSectionObject) => hasValue(sectionObj)),
|
||||||
@@ -109,6 +178,16 @@ export class SectionsService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given section is valid
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* Emits true whenever a given section should be valid
|
||||||
|
*/
|
||||||
public isSectionValid(submissionId: string, sectionId: string): Observable<boolean> {
|
public isSectionValid(submissionId: string, sectionId: string): Observable<boolean> {
|
||||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
filter((sectionObj) => hasValue(sectionObj)),
|
filter((sectionObj) => hasValue(sectionObj)),
|
||||||
@@ -116,12 +195,32 @@ export class SectionsService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given section is active
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* Emits true whenever a given section should be active
|
||||||
|
*/
|
||||||
public isSectionActive(submissionId: string, sectionId: string): Observable<boolean> {
|
public isSectionActive(submissionId: string, sectionId: string): Observable<boolean> {
|
||||||
return this.submissionService.getActiveSectionId(submissionId).pipe(
|
return this.submissionService.getActiveSectionId(submissionId).pipe(
|
||||||
map((activeSectionId: string) => sectionId === activeSectionId),
|
map((activeSectionId: string) => sectionId === activeSectionId),
|
||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given section is enabled
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* Emits true whenever a given section should be enabled
|
||||||
|
*/
|
||||||
public isSectionEnabled(submissionId: string, sectionId: string): Observable<boolean> {
|
public isSectionEnabled(submissionId: string, sectionId: string): Observable<boolean> {
|
||||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
filter((sectionObj) => hasValue(sectionObj)),
|
filter((sectionObj) => hasValue(sectionObj)),
|
||||||
@@ -129,6 +228,18 @@ export class SectionsService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given section is a read only section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @param submissionScope
|
||||||
|
* The submission scope
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* Emits true whenever a given section should be read only
|
||||||
|
*/
|
||||||
public isSectionReadOnly(submissionId: string, sectionId: string, submissionScope: SubmissionScopeType): Observable<boolean> {
|
public isSectionReadOnly(submissionId: string, sectionId: string, submissionScope: SubmissionScopeType): Observable<boolean> {
|
||||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
||||||
filter((sectionObj) => hasValue(sectionObj)),
|
filter((sectionObj) => hasValue(sectionObj)),
|
||||||
@@ -140,6 +251,16 @@ export class SectionsService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given section is a read only available
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* Emits true whenever a given section should be available
|
||||||
|
*/
|
||||||
public isSectionAvailable(submissionId: string, sectionId: string): Observable<boolean> {
|
public isSectionAvailable(submissionId: string, sectionId: string): Observable<boolean> {
|
||||||
return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
|
return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
|
||||||
filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)),
|
filter((submissionState: SubmissionObjectEntry) => isNotUndefined(submissionState)),
|
||||||
@@ -149,8 +270,15 @@ export class SectionsService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
public addSection(submissionId: string,
|
/**
|
||||||
sectionId: string) {
|
* Dispatch a new [EnableSectionAction] to add a new section and move page target to it
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
|
public addSection(submissionId: string, sectionId: string) {
|
||||||
this.store.dispatch(new EnableSectionAction(submissionId, sectionId));
|
this.store.dispatch(new EnableSectionAction(submissionId, sectionId));
|
||||||
const config: ScrollToConfigOptions = {
|
const config: ScrollToConfigOptions = {
|
||||||
target: sectionId,
|
target: sectionId,
|
||||||
@@ -160,11 +288,31 @@ export class SectionsService {
|
|||||||
this.scrollToService.scrollTo(config);
|
this.scrollToService.scrollTo(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [DisableSectionAction] to remove section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
public removeSection(submissionId: string, sectionId: string) {
|
public removeSection(submissionId: string, sectionId: string) {
|
||||||
this.store.dispatch(new DisableSectionAction(submissionId, sectionId))
|
this.store.dispatch(new DisableSectionAction(submissionId, sectionId))
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateSectionData(submissionId: string, sectionId: string, data, errors = []) {
|
/**
|
||||||
|
* Dispatch a new [UpdateSectionDataAction] to update section state with new data and errors
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @param data
|
||||||
|
* The section data
|
||||||
|
* @param errors
|
||||||
|
* The list of section errors
|
||||||
|
*/
|
||||||
|
public updateSectionData(submissionId: string, sectionId: string, data: WorkspaceitemSectionDataType, errors: SubmissionSectionError[] = []) {
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
const isAvailable$ = this.isSectionAvailable(submissionId, sectionId);
|
const isAvailable$ = this.isSectionAvailable(submissionId, sectionId);
|
||||||
const isEnabled$ = this.isSectionEnabled(submissionId, sectionId);
|
const isEnabled$ = this.isSectionEnabled(submissionId, sectionId);
|
||||||
@@ -182,10 +330,30 @@ export class SectionsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [InertSectionErrorsAction] to update section state with new error
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @param error
|
||||||
|
* The section error
|
||||||
|
*/
|
||||||
public setSectionError(submissionId: string, sectionId: string, error: SubmissionSectionError) {
|
public setSectionError(submissionId: string, sectionId: string, error: SubmissionSectionError) {
|
||||||
this.store.dispatch(new InertSectionErrorsAction(submissionId, sectionId, error));
|
this.store.dispatch(new InertSectionErrorsAction(submissionId, sectionId, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SectionStatusChangeAction] to update section state with new status
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
* @param status
|
||||||
|
* The section status
|
||||||
|
*/
|
||||||
public setSectionStatus(submissionId: string, sectionId: string, status: boolean) {
|
public setSectionStatus(submissionId: string, sectionId: string, status: boolean) {
|
||||||
this.store.dispatch(new SectionStatusChangeAction(submissionId, sectionId, status));
|
this.store.dispatch(new SectionStatusChangeAction(submissionId, sectionId, status));
|
||||||
}
|
}
|
||||||
|
@@ -777,7 +777,7 @@ describe('SubmissionService test suite', () => {
|
|||||||
service.notifyNewSection(submissionId, sectionId);
|
service.notifyNewSection(submissionId, sectionId);
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
expect((service as any).notificationsService.info).toHaveBeenCalledWith(null, 'test', null, true);
|
expect((service as any).notificationsService.info).toHaveBeenCalledWith(null, 'submission.sections.general.metadata-extracted-new-section', null, true);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -890,7 +890,7 @@ describe('SubmissionService test suite', () => {
|
|||||||
const duration = config.submission.autosave.timer * (1000 * 60);
|
const duration = config.submission.autosave.timer * (1000 * 60);
|
||||||
|
|
||||||
service.startAutoSave('826');
|
service.startAutoSave('826');
|
||||||
const sub = (service as any).timerObs.subscribe();
|
const sub = (service as any).timer$.subscribe();
|
||||||
|
|
||||||
tick(duration / 2);
|
tick(duration / 2);
|
||||||
expect((service as any).store.dispatch).not.toHaveBeenCalled();
|
expect((service as any).store.dispatch).not.toHaveBeenCalled();
|
||||||
|
@@ -44,12 +44,32 @@ import { RemoteData } from '../core/data/remote-data';
|
|||||||
import { ErrorResponse } from '../core/cache/response.models';
|
import { ErrorResponse } from '../core/cache/response.models';
|
||||||
import { RemoteDataError } from '../core/data/remote-data-error';
|
import { RemoteDataError } from '../core/data/remote-data-error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service that provides methods used in submission process.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubmissionService {
|
export class SubmissionService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription
|
||||||
|
*/
|
||||||
protected autoSaveSub: Subscription;
|
protected autoSaveSub: Subscription;
|
||||||
protected timerObs: Observable<any>;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observable used as timer
|
||||||
|
*/
|
||||||
|
protected timer$: Observable<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize service variables
|
||||||
|
* @param {GlobalConfig} EnvConfig
|
||||||
|
* @param {NotificationsService} notificationsService
|
||||||
|
* @param {SubmissionRestService} restService
|
||||||
|
* @param {Router} restSerroutervice
|
||||||
|
* @param {RouteService} routeService
|
||||||
|
* @param {Store<SubmissionState>} store
|
||||||
|
* @param {TranslateService} translate
|
||||||
|
*/
|
||||||
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected restService: SubmissionRestService,
|
protected restService: SubmissionRestService,
|
||||||
@@ -59,28 +79,74 @@ export class SubmissionService {
|
|||||||
protected translate: TranslateService) {
|
protected translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [ChangeSubmissionCollectionAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param collectionId
|
||||||
|
* The collection id
|
||||||
|
*/
|
||||||
changeSubmissionCollection(submissionId, collectionId) {
|
changeSubmissionCollection(submissionId, collectionId) {
|
||||||
this.store.dispatch(new ChangeSubmissionCollectionAction(submissionId, collectionId));
|
this.store.dispatch(new ChangeSubmissionCollectionAction(submissionId, collectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a REST call to create a new workspaceitem and return response
|
||||||
|
*
|
||||||
|
* @return Observable<SubmissionObject>
|
||||||
|
* observable of SubmissionObject
|
||||||
|
*/
|
||||||
createSubmission(): Observable<SubmissionObject> {
|
createSubmission(): Observable<SubmissionObject> {
|
||||||
return this.restService.postToEndpoint('workspaceitems', {}).pipe(
|
return this.restService.postToEndpoint('workspaceitems', {}).pipe(
|
||||||
map((workspaceitem: SubmissionObject) => workspaceitem[0]),
|
map((workspaceitem: SubmissionObject) => workspaceitem[0]),
|
||||||
catchError(() => observableOf({})))
|
catchError(() => observableOf({})))
|
||||||
}
|
}
|
||||||
|
|
||||||
depositSubmission(selfUrl: string): Observable<any> {
|
/**
|
||||||
|
* Perform a REST call to deposit a workspaceitem and return response
|
||||||
|
*
|
||||||
|
* @param selfUrl
|
||||||
|
* The workspaceitem self url
|
||||||
|
* @return Observable<SubmissionObject>
|
||||||
|
* observable of SubmissionObject
|
||||||
|
*/
|
||||||
|
depositSubmission(selfUrl: string): Observable<SubmissionObject[]> {
|
||||||
const options: HttpOptions = Object.create({});
|
const options: HttpOptions = Object.create({});
|
||||||
let headers = new HttpHeaders();
|
let headers = new HttpHeaders();
|
||||||
headers = headers.append('Content-Type', 'text/uri-list');
|
headers = headers.append('Content-Type', 'text/uri-list');
|
||||||
options.headers = headers;
|
options.headers = headers;
|
||||||
return this.restService.postToEndpoint('workflowitems', selfUrl, null, options);
|
return this.restService.postToEndpoint('workflowitems', selfUrl, null, options) as Observable<SubmissionObject[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
discardSubmission(submissionId: string): Observable<any> {
|
/**
|
||||||
return this.restService.deleteById(submissionId);
|
* Perform a REST call to delete a workspaceitem and return response
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<SubmissionObject>
|
||||||
|
* observable of SubmissionObject
|
||||||
|
*/
|
||||||
|
discardSubmission(submissionId: string): Observable<SubmissionObject[]> {
|
||||||
|
return this.restService.deleteById(submissionId) as Observable<SubmissionObject[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [InitSubmissionFormAction]
|
||||||
|
*
|
||||||
|
* @param collectionId
|
||||||
|
* The collection id
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param selfUrl
|
||||||
|
* The workspaceitem self url
|
||||||
|
* @param submissionDefinition
|
||||||
|
* The [SubmissionDefinitionsModel] that define submission configuration
|
||||||
|
* @param sections
|
||||||
|
* The [WorkspaceitemSectionsObject] that define submission sections init data
|
||||||
|
* @param errors
|
||||||
|
* The [SubmissionSectionError] that define submission sections init errors
|
||||||
|
*/
|
||||||
dispatchInit(
|
dispatchInit(
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
submissionId: string,
|
submissionId: string,
|
||||||
@@ -91,36 +157,90 @@ export class SubmissionService {
|
|||||||
this.store.dispatch(new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, sections, errors));
|
this.store.dispatch(new InitSubmissionFormAction(collectionId, submissionId, selfUrl, submissionDefinition, sections, errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SaveAndDepositSubmissionAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
dispatchDeposit(submissionId) {
|
dispatchDeposit(submissionId) {
|
||||||
this.store.dispatch(new SaveAndDepositSubmissionAction(submissionId));
|
this.store.dispatch(new SaveAndDepositSubmissionAction(submissionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [DiscardSubmissionAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
dispatchDiscard(submissionId) {
|
dispatchDiscard(submissionId) {
|
||||||
this.store.dispatch(new DiscardSubmissionAction(submissionId));
|
this.store.dispatch(new DiscardSubmissionAction(submissionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SaveSubmissionFormAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
dispatchSave(submissionId) {
|
dispatchSave(submissionId) {
|
||||||
this.store.dispatch(new SaveSubmissionFormAction(submissionId));
|
this.store.dispatch(new SaveSubmissionFormAction(submissionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SaveForLaterSubmissionFormAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
dispatchSaveForLater(submissionId) {
|
dispatchSaveForLater(submissionId) {
|
||||||
this.store.dispatch(new SaveForLaterSubmissionFormAction(submissionId));
|
this.store.dispatch(new SaveForLaterSubmissionFormAction(submissionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SaveSubmissionSectionFormAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
dispatchSaveSection(submissionId, sectionId) {
|
dispatchSaveSection(submissionId, sectionId) {
|
||||||
this.store.dispatch(new SaveSubmissionSectionFormAction(submissionId, sectionId));
|
this.store.dispatch(new SaveSubmissionSectionFormAction(submissionId, sectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the id of the current focused section for the specified submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<string>
|
||||||
|
* observable of section id
|
||||||
|
*/
|
||||||
getActiveSectionId(submissionId: string): Observable<string> {
|
getActiveSectionId(submissionId: string): Observable<string> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
map((submission: SubmissionObjectEntry) => submission.activeSection));
|
map((submission: SubmissionObjectEntry) => submission.activeSection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the [SubmissionObjectEntry] for the specified submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<SubmissionObjectEntry>
|
||||||
|
* observable of SubmissionObjectEntry
|
||||||
|
*/
|
||||||
getSubmissionObject(submissionId: string): Observable<SubmissionObjectEntry> {
|
getSubmissionObject(submissionId: string): Observable<SubmissionObjectEntry> {
|
||||||
return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
|
return this.store.select(submissionObjectFromIdSelector(submissionId)).pipe(
|
||||||
filter((submission: SubmissionObjectEntry) => isNotUndefined(submission)));
|
filter((submission: SubmissionObjectEntry) => isNotUndefined(submission)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of the active [SectionDataObject] belonging to the specified submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<SubmissionObjectEntry>
|
||||||
|
* observable with the list of active submission's sections
|
||||||
|
*/
|
||||||
getSubmissionSections(submissionId: string): Observable<SectionDataObject[]> {
|
getSubmissionSections(submissionId: string): Observable<SectionDataObject[]> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
find((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
|
find((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
|
||||||
@@ -146,6 +266,14 @@ export class SubmissionService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a list of the disabled [SectionDataObject] belonging to the specified submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<SubmissionObjectEntry>
|
||||||
|
* observable with the list of disabled submission's sections
|
||||||
|
*/
|
||||||
getDisabledSectionsList(submissionId: string): Observable<SectionDataObject[]> {
|
getDisabledSectionsList(submissionId: string): Observable<SectionDataObject[]> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
|
filter((submission: SubmissionObjectEntry) => isNotUndefined(submission.sections) && !submission.isLoading),
|
||||||
@@ -167,6 +295,12 @@ export class SubmissionService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the correct REST endpoint link path depending on the page route
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* link path
|
||||||
|
*/
|
||||||
getSubmissionObjectLinkName(): string {
|
getSubmissionObjectLinkName(): string {
|
||||||
const url = this.router.routerState.snapshot.url;
|
const url = this.router.routerState.snapshot.url;
|
||||||
if (url.startsWith('/workspaceitems') || url.startsWith('/submit')) {
|
if (url.startsWith('/workspaceitems') || url.startsWith('/submit')) {
|
||||||
@@ -178,6 +312,12 @@ export class SubmissionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the submission scope
|
||||||
|
*
|
||||||
|
* @return SubmissionScopeType
|
||||||
|
* the SubmissionScopeType
|
||||||
|
*/
|
||||||
getSubmissionScope(): SubmissionScopeType {
|
getSubmissionScope(): SubmissionScopeType {
|
||||||
let scope: SubmissionScopeType;
|
let scope: SubmissionScopeType;
|
||||||
switch (this.getSubmissionObjectLinkName()) {
|
switch (this.getSubmissionObjectLinkName()) {
|
||||||
@@ -194,6 +334,14 @@ export class SubmissionService {
|
|||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the validity status of the submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* observable with submission validity status
|
||||||
|
*/
|
||||||
getSubmissionStatus(submissionId: string): Observable<boolean> {
|
getSubmissionStatus(submissionId: string): Observable<boolean> {
|
||||||
return this.store.select(submissionSelector).pipe(
|
return this.store.select(submissionSelector).pipe(
|
||||||
map((submissions: SubmissionState) => submissions.objects[submissionId]),
|
map((submissions: SubmissionState) => submissions.objects[submissionId]),
|
||||||
@@ -219,6 +367,14 @@ export class SubmissionService {
|
|||||||
startWith(false));
|
startWith(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the save processing status of the submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* observable with submission save processing status
|
||||||
|
*/
|
||||||
getSubmissionSaveProcessingStatus(submissionId: string): Observable<boolean> {
|
getSubmissionSaveProcessingStatus(submissionId: string): Observable<boolean> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
map((state: SubmissionObjectEntry) => state.savePending),
|
map((state: SubmissionObjectEntry) => state.savePending),
|
||||||
@@ -226,6 +382,14 @@ export class SubmissionService {
|
|||||||
startWith(false));
|
startWith(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the deposit processing status of the submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* observable with submission deposit processing status
|
||||||
|
*/
|
||||||
getSubmissionDepositProcessingStatus(submissionId: string): Observable<boolean> {
|
getSubmissionDepositProcessingStatus(submissionId: string): Observable<boolean> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
map((state: SubmissionObjectEntry) => state.depositPending),
|
map((state: SubmissionObjectEntry) => state.depositPending),
|
||||||
@@ -233,27 +397,50 @@ export class SubmissionService {
|
|||||||
startWith(false));
|
startWith(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
isSectionHidden(sectionData: SubmissionSectionObject) {
|
/**
|
||||||
|
* Return the visibility status of the specified section
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return boolean
|
||||||
|
* true if section is hidden, false otherwise
|
||||||
|
*/
|
||||||
|
isSectionHidden(sectionData: SubmissionSectionObject): boolean {
|
||||||
return (isNotUndefined(sectionData.visibility)
|
return (isNotUndefined(sectionData.visibility)
|
||||||
&& sectionData.visibility.main === 'HIDDEN'
|
&& sectionData.visibility.main === 'HIDDEN'
|
||||||
&& sectionData.visibility.other === 'HIDDEN');
|
&& sectionData.visibility.other === 'HIDDEN');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the loading status of the submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @return Observable<boolean>
|
||||||
|
* observable with submission loading status
|
||||||
|
*/
|
||||||
isSubmissionLoading(submissionId: string): Observable<boolean> {
|
isSubmissionLoading(submissionId: string): Observable<boolean> {
|
||||||
return this.getSubmissionObject(submissionId).pipe(
|
return this.getSubmissionObject(submissionId).pipe(
|
||||||
map((submission: SubmissionObjectEntry) => submission.isLoading),
|
map((submission: SubmissionObjectEntry) => submission.isLoading),
|
||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a notification when a new section is added to submission form
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) {
|
notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) {
|
||||||
this.translate.get('submission.sections.general.metadata-extracted-new-section', { sectionId }).pipe(
|
const m = this.translate.instant('submission.sections.general.metadata-extracted-new-section', { sectionId });
|
||||||
first())
|
|
||||||
.subscribe((m) => {
|
|
||||||
this.notificationsService.info(null, m, null, true);
|
this.notificationsService.info(null, m, null, true);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to MyDspace page
|
||||||
|
*/
|
||||||
redirectToMyDSpace() {
|
redirectToMyDSpace() {
|
||||||
this.routeService.getPreviousUrl().pipe(
|
this.routeService.getPreviousUrl().pipe(
|
||||||
first()
|
first()
|
||||||
@@ -267,10 +454,27 @@ export class SubmissionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [CancelSubmissionFormAction]
|
||||||
|
*/
|
||||||
resetAllSubmissionObjects() {
|
resetAllSubmissionObjects() {
|
||||||
this.store.dispatch(new CancelSubmissionFormAction());
|
this.store.dispatch(new CancelSubmissionFormAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [ResetSubmissionFormAction]
|
||||||
|
*
|
||||||
|
* @param collectionId
|
||||||
|
* The collection id
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param selfUrl
|
||||||
|
* The workspaceitem self url
|
||||||
|
* @param submissionDefinition
|
||||||
|
* The [SubmissionDefinitionsModel] that define submission configuration
|
||||||
|
* @param sections
|
||||||
|
* The [WorkspaceitemSectionsObject] that define submission sections init data
|
||||||
|
*/
|
||||||
resetSubmissionObject(
|
resetSubmissionObject(
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
submissionId: string,
|
submissionId: string,
|
||||||
@@ -281,6 +485,12 @@ export class SubmissionService {
|
|||||||
this.store.dispatch(new ResetSubmissionFormAction(collectionId, submissionId, selfUrl, sections, submissionDefinition));
|
this.store.dispatch(new ResetSubmissionFormAction(collectionId, submissionId, selfUrl, sections, submissionDefinition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a REST call to retrieve an existing workspaceitem/workflowitem and return response
|
||||||
|
*
|
||||||
|
* @return Observable<RemoteData<SubmissionObject>>
|
||||||
|
* observable of RemoteData<SubmissionObject>
|
||||||
|
*/
|
||||||
retrieveSubmission(submissionId): Observable<RemoteData<SubmissionObject>> {
|
retrieveSubmission(submissionId): Observable<RemoteData<SubmissionObject>> {
|
||||||
return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId).pipe(
|
return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId).pipe(
|
||||||
find((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)),
|
find((submissionObjects: SubmissionObject[]) => isNotUndefined(submissionObjects)),
|
||||||
@@ -302,21 +512,38 @@ export class SubmissionService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a new [SetActiveSectionAction]
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
* @param sectionId
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
setActiveSection(submissionId, sectionId) {
|
setActiveSection(submissionId, sectionId) {
|
||||||
this.store.dispatch(new SetActiveSectionAction(submissionId, sectionId));
|
this.store.dispatch(new SetActiveSectionAction(submissionId, sectionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow to save automatically the submission
|
||||||
|
*
|
||||||
|
* @param submissionId
|
||||||
|
* The submission id
|
||||||
|
*/
|
||||||
startAutoSave(submissionId) {
|
startAutoSave(submissionId) {
|
||||||
this.stopAutoSave();
|
this.stopAutoSave();
|
||||||
// AUTOSAVE submission
|
// AUTOSAVE submission
|
||||||
// Retrieve interval from config and convert to milliseconds
|
// Retrieve interval from config and convert to milliseconds
|
||||||
const duration = this.EnvConfig.submission.autosave.timer * (1000 * 60);
|
const duration = this.EnvConfig.submission.autosave.timer * (1000 * 60);
|
||||||
// Dispatch save action after given duration
|
// Dispatch save action after given duration
|
||||||
this.timerObs = observableTimer(duration, duration);
|
this.timer$ = observableTimer(duration, duration);
|
||||||
this.autoSaveSub = this.timerObs
|
this.autoSaveSub = this.timer$
|
||||||
.subscribe(() => this.store.dispatch(new SaveSubmissionFormAction(submissionId)));
|
.subscribe(() => this.store.dispatch(new SaveSubmissionFormAction(submissionId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribe subscription to timer
|
||||||
|
*/
|
||||||
stopAutoSave() {
|
stopAutoSave() {
|
||||||
if (hasValue(this.autoSaveSub)) {
|
if (hasValue(this.autoSaveSub)) {
|
||||||
this.autoSaveSub.unsubscribe();
|
this.autoSaveSub.unsubscribe();
|
||||||
|
@@ -1,9 +1,28 @@
|
|||||||
import { hasValue } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent the path of a section error
|
||||||
|
*/
|
||||||
export interface SectionErrorPath {
|
export interface SectionErrorPath {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The section id
|
||||||
|
*/
|
||||||
sectionId: string;
|
sectionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The form field id
|
||||||
|
*/
|
||||||
fieldId?: string;
|
fieldId?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The form field index
|
||||||
|
*/
|
||||||
fieldIndex?: number;
|
fieldIndex?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The complete path
|
||||||
|
*/
|
||||||
originalPath: string;
|
originalPath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +31,7 @@ const regex = /([^\/]+)/g;
|
|||||||
const regexShort = /\/sections\/(.*)/;
|
const regexShort = /\/sections\/(.*)/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the following method accept an array of section path strings and return a path object
|
* The following method accept an array of section path strings and return a path object
|
||||||
* @param {string | string[]} path
|
* @param {string | string[]} path
|
||||||
* @returns {SectionErrorPath[]}
|
* @returns {SectionErrorPath[]}
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user