mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Final commit detect duplicate
This commit is contained in:
@@ -299,11 +299,11 @@
|
|||||||
"submit.progressbar.describe.stepone": "Describe",
|
"submit.progressbar.describe.stepone": "Describe",
|
||||||
"submit.progressbar.describe.steptwo": "Describe",
|
"submit.progressbar.describe.steptwo": "Describe",
|
||||||
"submit.progressbar.describe.stepcustom": "Describe",
|
"submit.progressbar.describe.stepcustom": "Describe",
|
||||||
"submit.progressbar.describe.deduplication": "Potential duplicates",
|
|
||||||
"submit.progressbar.describe.recycle": "Recycle",
|
"submit.progressbar.describe.recycle": "Recycle",
|
||||||
"submit.progressbar.upload": "Upload files",
|
"submit.progressbar.upload": "Upload files",
|
||||||
"submit.progressbar.license": "Deposit license",
|
"submit.progressbar.license": "Deposit license",
|
||||||
"submit.progressbar.cclicense": "Creative commons license",
|
"submit.progressbar.cclicense": "Creative commons license",
|
||||||
|
"submit.progressbar.detect-duplicate": "Potential duplicates",
|
||||||
|
|
||||||
"upload": {
|
"upload": {
|
||||||
"info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging&dropping them everywhere in the page</strong>",
|
"info": "Here you will find all the files currently in the item. You can update the fle metadata and access conditions or <strong>upload additional files just dragging&dropping them everywhere in the page</strong>",
|
||||||
@@ -321,20 +321,26 @@
|
|||||||
"group-label": "Group"
|
"group-label": "Group"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deduplication": {
|
"detect-duplicate": {
|
||||||
"duplicated": "It's a duplicate",
|
"duplicate-detected": "Potential duplicate detected",
|
||||||
"not_duplicated": "It's not a duplicate",
|
"duplicate": "It's a duplicate",
|
||||||
"duplicated_ctrl": "Mark the record to merge",
|
"not-duplicate": "It's not a duplicate",
|
||||||
"duplicated_help": "Click here if this is a duplicate of your item",
|
"confirm-duplicate": "Confirm (It's a duplicate)",
|
||||||
"not_duplicated_help": "Click here if this is not a duplicate of your item",
|
"confirm-not-duplicate": "Confirm (It's not a duplicate)",
|
||||||
"note_help": "Please enter your reason for the duplication into the box below.",
|
"duplicate-ctrl": "Mark the record to merge",
|
||||||
"note_placeholder": "Describe the reason of duplication",
|
"duplicate-help": "Click here if this is a duplicate of your item",
|
||||||
"clear_decision": "Undo",
|
"not-duplicate-help": "Click here if this is not a duplicate of your item",
|
||||||
"clear_decision_help": "Click for clear the decision about this pontential duplicate",
|
"note-help": "Please enter your reason for the duplication into the box below.",
|
||||||
"your_decision": "Your choice:",
|
"note-placeholder": "Describe the reason of duplication",
|
||||||
"submitter_decision": "Submitter choice:",
|
"clear-decision": "Undo",
|
||||||
|
"clear-decision-help": "Click for clear the decision about this pontential duplicate",
|
||||||
|
"decision-success-notice": "Choice registered successfully",
|
||||||
|
"no-decision": "No decision yet",
|
||||||
|
"submitter-decision": "Submitter decision:",
|
||||||
|
"submitter-note": "Submitter note:",
|
||||||
"disclaimer": "The system has identified some potential duplicates. Please carefully review the list and flag each occurency with the appropriate choice or discard this submission.",
|
"disclaimer": "The system has identified some potential duplicates. Please carefully review the list and flag each occurency with the appropriate choice or discard this submission.",
|
||||||
"disclaimer_ctrl": "The system has identified some potential duplicates. Please carefully review the list and the submitter comments and perform the appropriate action."
|
"disclaimer-ctrl": "The system has identified some potential duplicates. Please carefully review the list and the submitter comments and perform the appropriate action.",
|
||||||
|
"disclaimer-no-match": "All your feedback on potential duplicates have been registered correctly."
|
||||||
},
|
},
|
||||||
"recycle": {
|
"recycle": {
|
||||||
"disclaimer": "The following existent information are not valid within the selected collection. Please copy them to the appropriate metadata if applicable. Use the discard button to remove these information when done."
|
"disclaimer": "The following existent information are not valid within the selected collection. Please copy them to the appropriate metadata if applicable. Use the discard button to remove these information when done."
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
|
import { Item } from '../../shared/item.model';
|
||||||
import { WorkspaceitemSectionUploadFileObject } from './workspaceitem-section-upload-file.model';
|
|
||||||
import { FormFieldChangedObject } from '../../../shared/form/builder/models/form-field-unexpected-object.model';
|
|
||||||
|
|
||||||
import { DSpaceObject } from '../../shared/dspace-object.model';
|
export interface WorkspaceitemSectionDetectDuplicateObject {
|
||||||
|
matches: {
|
||||||
export interface WorkspaceitemSectionDeduplicationObject {
|
[itemId: string]: DetectDuplicateMatch;
|
||||||
matches: DeduplicationSchema[];
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeduplicationSchema {
|
export interface DetectDuplicateMatch {
|
||||||
submitterDecision?: string; // [reject|verify]
|
submitterDecision?: string; // [reject|verify]
|
||||||
submitterNote?: string;
|
submitterNote?: string;
|
||||||
submitterTime?: string; // (readonly)
|
submitterTime?: string; // (readonly)
|
||||||
@@ -17,5 +15,7 @@ export interface DeduplicationSchema {
|
|||||||
workflowNote?: string;
|
workflowNote?: string;
|
||||||
workflowTime?: string; // (readonly)
|
workflowTime?: string; // (readonly)
|
||||||
|
|
||||||
matchObject?: DSpaceObject; // item, workspaceItem, workflowItem
|
adminDecision?: string;
|
||||||
|
|
||||||
|
matchObject?: Item;
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import { WorkspaceitemSectionUploadObject } from './workspaceitem-section-upload
|
|||||||
import { isNotEmpty, isNotNull } from '../../../shared/empty.util';
|
import { isNotEmpty, isNotNull } from '../../../shared/empty.util';
|
||||||
import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model';
|
import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model';
|
||||||
import { WorkspaceitemSectionRecycleObject } from './workspaceitem-section-recycle.model';
|
import { WorkspaceitemSectionRecycleObject } from './workspaceitem-section-recycle.model';
|
||||||
import { WorkspaceitemSectionDeduplicationObject } from './workspaceitem-section-deduplication.model';
|
import { WorkspaceitemSectionDetectDuplicateObject } from './workspaceitem-section-deduplication.model';
|
||||||
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
|
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
|
||||||
|
|
||||||
export class WorkspaceitemSectionsObject {
|
export class WorkspaceitemSectionsObject {
|
||||||
@@ -61,5 +61,5 @@ export type WorkspaceitemSectionDataType
|
|||||||
| WorkspaceitemSectionFormObject
|
| WorkspaceitemSectionFormObject
|
||||||
| WorkspaceitemSectionLicenseObject
|
| WorkspaceitemSectionLicenseObject
|
||||||
| WorkspaceitemSectionRecycleObject
|
| WorkspaceitemSectionRecycleObject
|
||||||
| WorkspaceitemSectionDeduplicationObject
|
| WorkspaceitemSectionDetectDuplicateObject
|
||||||
| string;
|
| string;
|
||||||
|
@@ -52,12 +52,9 @@ export const SubmissionObjectActionTypes = {
|
|||||||
DISCARD_SUBMISSION: type('dspace/submission/DISCARD_SUBMISSION'),
|
DISCARD_SUBMISSION: type('dspace/submission/DISCARD_SUBMISSION'),
|
||||||
DISCARD_SUBMISSION_SUCCESS: type('dspace/submission/DISCARD_SUBMISSION_SUCCESS'),
|
DISCARD_SUBMISSION_SUCCESS: type('dspace/submission/DISCARD_SUBMISSION_SUCCESS'),
|
||||||
DISCARD_SUBMISSION_ERROR: type('dspace/submission/DISCARD_SUBMISSION_ERROR'),
|
DISCARD_SUBMISSION_ERROR: type('dspace/submission/DISCARD_SUBMISSION_ERROR'),
|
||||||
SET_WORKSPACE_DUPLICATION: type('/sections/deduplication/SET_WORKSPACE_DUPLICATION'),
|
SET_DUPLICATE_DECISION: type('dspace/submission/SET_DUPLICATE_DECISION'),
|
||||||
SET_WORKSPACE_DUPLICATION_SUCCESS: type('/sections/deduplication/SET_WORKSPACE_DUPLICATION_SUCCESS'),
|
SET_DUPLICATE_DECISION_SUCCESS: type('dspace/submission/SET_DUPLICATE_DECISION_SUCCESS'),
|
||||||
SET_WORKSPACE_DUPLICATION_ERROR: type('/sections/deduplication/SET_WORKSPACE_DUPLICATION_ERROR'),
|
SET_DUPLICATE_DECISION_ERROR: type('dspace/submission/SET_DUPLICATE_DECISION_ERROR'),
|
||||||
SET_WORKFLOW_DUPLICATION: type('/sections/deduplication/SET_WORKFLOW_DUPLICATION'),
|
|
||||||
SET_WORKFLOW_DUPLICATION_SUCCESS: type('/sections/deduplication/SET_WORKFLOW_DUPLICATION_SUCCESS'),
|
|
||||||
SET_WORKFLOW_DUPLICATION_ERROR: type('/sections/deduplication/SET_WORKFLOW_DUPLICATION_ERROR'),
|
|
||||||
|
|
||||||
// Upload file types
|
// Upload file types
|
||||||
NEW_FILE: type('dspace/submission/NEW_FILE'),
|
NEW_FILE: type('dspace/submission/NEW_FILE'),
|
||||||
@@ -763,129 +760,63 @@ export class DeleteUploadedFileAction implements Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetWorkspaceDuplicatedAction implements Action {
|
export class SetDuplicateDecisionAction implements Action {
|
||||||
type = SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION;
|
type = SubmissionObjectActionTypes.SET_DUPLICATE_DECISION;
|
||||||
payload: {
|
payload: {
|
||||||
index: number;
|
submissionId: string;
|
||||||
decision: string;
|
sectionId: string;
|
||||||
note?: string
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SetWorkspaceDuplicatedAction
|
* Create a new SetDuplicateDecisionAction
|
||||||
*
|
*
|
||||||
* @param index
|
* @param submissionId
|
||||||
* the index in matches array
|
* the submission's ID
|
||||||
* @param decision
|
* @param sectionId
|
||||||
* the submitter's decision ('verify'|'reject'|null)
|
* the section's ID
|
||||||
* @param note
|
|
||||||
* the submitter's note, for 'verify' decision only
|
|
||||||
*/
|
*/
|
||||||
constructor(payload: any) {
|
constructor(submissionId: string, sectionId: string) {
|
||||||
this.payload = payload;
|
this.payload = { submissionId, sectionId };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetWorkspaceDuplicatedSuccessAction implements Action {
|
export class SetDuplicateDecisionSuccessAction implements Action {
|
||||||
type = SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION_SUCCESS;
|
type = SubmissionObjectActionTypes.SET_DUPLICATE_DECISION_SUCCESS;
|
||||||
payload: {
|
payload: {
|
||||||
index: number;
|
submissionId: string;
|
||||||
decision: string;
|
sectionId: string;
|
||||||
note?: string
|
submissionObject: SubmissionObject[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SetWorkspaceDuplicatedSuccessAction
|
* Create a new SetDuplicateDecisionSuccessAction
|
||||||
*
|
*
|
||||||
* @param index
|
* @param submissionId
|
||||||
* the index in matches array
|
* the submission's ID
|
||||||
* @param decision
|
* @param sectionId
|
||||||
* the submitter's decision ('verify'|'reject'|null)
|
* the section's ID
|
||||||
* @param note
|
* @param submissionObjects
|
||||||
* the submitter's note, for 'verify' decision only
|
* the submission's Object
|
||||||
*/
|
*/
|
||||||
constructor(payload: any) {
|
constructor(submissionId: string, sectionId: string, submissionObject: SubmissionObject[]) {
|
||||||
this.payload = payload;
|
this.payload = { submissionId, sectionId, submissionObject };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SetWorkspaceDuplicatedErrorAction implements Action {
|
export class SetDuplicateDecisionErrorAction implements Action {
|
||||||
type = SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION_ERROR;
|
type = SubmissionObjectActionTypes.SET_DUPLICATE_DECISION_ERROR;
|
||||||
payload: {
|
payload: {
|
||||||
index: number;
|
submissionId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SetWorkspaceDuplicatedErrorAction
|
* Create a new SetDuplicateDecisionErrorAction
|
||||||
*
|
*
|
||||||
* @param index
|
* @param submissionId
|
||||||
* the index in matches array
|
* the submission's ID
|
||||||
*/
|
*/
|
||||||
constructor(index: number) {
|
constructor(submissionId: string) {
|
||||||
this.payload = { index };
|
this.payload = { submissionId };
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetWorkflowDuplicatedAction implements Action {
|
|
||||||
type = SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION;
|
|
||||||
payload: {
|
|
||||||
index: number;
|
|
||||||
decision: string;
|
|
||||||
note?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new SetWorkflowDuplicatedAction
|
|
||||||
*
|
|
||||||
* @param index
|
|
||||||
* the index in matches array
|
|
||||||
* @param decision
|
|
||||||
* the controller's decision ('verify'|'reject'|null)
|
|
||||||
* @param note
|
|
||||||
* the controller's note, for 'verify' decision only
|
|
||||||
*/
|
|
||||||
constructor(payload: any) {
|
|
||||||
this.payload = payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetWorkflowDuplicatedSuccessAction implements Action {
|
|
||||||
type = SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION_SUCCESS;
|
|
||||||
payload: {
|
|
||||||
index: number;
|
|
||||||
decision: string;
|
|
||||||
note?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new SetWorkflowDuplicatedSuccessAction
|
|
||||||
*
|
|
||||||
* @param index
|
|
||||||
* the index in matches array
|
|
||||||
* @param decision
|
|
||||||
* the controller's decision ('verify'|'reject'|null)
|
|
||||||
* @param note
|
|
||||||
* the controller's note, for 'verify' decision only
|
|
||||||
*/
|
|
||||||
constructor(payload: any) {
|
|
||||||
this.payload = payload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetWorkflowDuplicatedErrorAction implements Action {
|
|
||||||
type = SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION_ERROR;
|
|
||||||
payload: {
|
|
||||||
index: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new SetWorkflowDuplicatedErrorAction
|
|
||||||
*
|
|
||||||
* @param index
|
|
||||||
* the index in matches array
|
|
||||||
*/
|
|
||||||
constructor(index: number) {
|
|
||||||
this.payload = { index };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,9 +859,6 @@ export type SubmissionObjectAction = DisableSectionAction
|
|||||||
| SaveSubmissionSectionFormSuccessAction
|
| SaveSubmissionSectionFormSuccessAction
|
||||||
| SaveSubmissionSectionFormErrorAction
|
| SaveSubmissionSectionFormErrorAction
|
||||||
| SetActiveSectionAction
|
| SetActiveSectionAction
|
||||||
| SetWorkspaceDuplicatedAction
|
| SetDuplicateDecisionAction
|
||||||
| SetWorkspaceDuplicatedSuccessAction
|
| SetDuplicateDecisionSuccessAction
|
||||||
| SetWorkspaceDuplicatedErrorAction
|
| SetDuplicateDecisionErrorAction;
|
||||||
| SetWorkflowDuplicatedAction
|
|
||||||
| SetWorkflowDuplicatedSuccessAction
|
|
||||||
| SetWorkflowDuplicatedErrorAction;
|
|
||||||
|
@@ -22,12 +22,7 @@ import {
|
|||||||
SaveSubmissionSectionFormAction,
|
SaveSubmissionSectionFormAction,
|
||||||
SaveSubmissionSectionFormErrorAction,
|
SaveSubmissionSectionFormErrorAction,
|
||||||
SaveSubmissionSectionFormSuccessAction,
|
SaveSubmissionSectionFormSuccessAction,
|
||||||
SetWorkflowDuplicatedAction,
|
SetDuplicateDecisionAction, SetDuplicateDecisionErrorAction, SetDuplicateDecisionSuccessAction,
|
||||||
SetWorkflowDuplicatedErrorAction,
|
|
||||||
SetWorkflowDuplicatedSuccessAction,
|
|
||||||
SetWorkspaceDuplicatedAction,
|
|
||||||
SetWorkspaceDuplicatedErrorAction,
|
|
||||||
SetWorkspaceDuplicatedSuccessAction,
|
|
||||||
SubmissionObjectActionTypes,
|
SubmissionObjectActionTypes,
|
||||||
UpdateSectionDataAction
|
UpdateSectionDataAction
|
||||||
} from './submission-objects.actions';
|
} from './submission-objects.actions';
|
||||||
@@ -43,11 +38,13 @@ import { Workflowitem } from '../../core/submission/models/workflowitem.model';
|
|||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
|
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { DeduplicationService } from '../sections/deduplication/deduplication.service';
|
import { DetectDuplicateService } from '../sections/detect-duplicate/detect-duplicate.service';
|
||||||
import { SubmissionState } from '../submission.reducers';
|
import { SubmissionState } from '../submission.reducers';
|
||||||
import { SubmissionObjectEntry } from './submission-objects.reducer';
|
import { SubmissionObjectEntry } from './submission-objects.reducer';
|
||||||
import { SubmissionSectionModel } from '../../core/shared/config/config-submission-section.model';
|
import { SubmissionSectionModel } from '../../core/shared/config/config-submission-section.model';
|
||||||
import parseSectionErrors from '../utils/parseSectionErrors';
|
import parseSectionErrors from '../utils/parseSectionErrors';
|
||||||
|
import { SectionsType } from '../sections/sections-type';
|
||||||
|
import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubmissionObjectEffects {
|
export class SubmissionObjectEffects {
|
||||||
@@ -60,7 +57,7 @@ export class SubmissionObjectEffects {
|
|||||||
definition.sections.forEach((sectionDefinition: SubmissionSectionModel, index: number) => {
|
definition.sections.forEach((sectionDefinition: SubmissionSectionModel, index: number) => {
|
||||||
const sectionId = sectionDefinition._links.self.substr(sectionDefinition._links.self.lastIndexOf('/') + 1);
|
const sectionId = sectionDefinition._links.self.substr(sectionDefinition._links.self.lastIndexOf('/') + 1);
|
||||||
const config = sectionDefinition._links.config || '';
|
const config = sectionDefinition._links.config || '';
|
||||||
const enabled = sectionDefinition.mandatory || (isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId));
|
const enabled = (sectionDefinition.mandatory && sectionDefinition.sectionType !== SectionsType.DetectDuplicate) || (isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId));
|
||||||
const sectionData = (isNotUndefined(action.payload.sections) && isNotUndefined(action.payload.sections[sectionId])) ? action.payload.sections[sectionId] : Object.create(null);
|
const sectionData = (isNotUndefined(action.payload.sections) && isNotUndefined(action.payload.sections[sectionId])) ? action.payload.sections[sectionId] : Object.create(null);
|
||||||
const sectionErrors = null;
|
const sectionErrors = null;
|
||||||
mappedActions.push(
|
mappedActions.push(
|
||||||
@@ -127,9 +124,7 @@ export class SubmissionObjectEffects {
|
|||||||
.map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => {
|
.map(([action, currentState]: [SaveSubmissionFormSuccessAction | SaveSubmissionSectionFormSuccessAction, any]) => {
|
||||||
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId);
|
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId);
|
||||||
})
|
})
|
||||||
.mergeMap((actions) => {
|
.mergeMap((actions) => Observable.from(actions));
|
||||||
return Observable.from(actions);
|
|
||||||
});
|
|
||||||
|
|
||||||
@Effect() saveSection$ = this.actions$
|
@Effect() saveSection$ = this.actions$
|
||||||
.ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM)
|
.ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM)
|
||||||
@@ -143,6 +138,31 @@ export class SubmissionObjectEffects {
|
|||||||
.catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId)));
|
.catch(() => Observable.of(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@Effect() saveDuplicateDecision$ = this.actions$
|
||||||
|
.ofType(SubmissionObjectActionTypes.SET_DUPLICATE_DECISION)
|
||||||
|
.switchMap((action: SetDuplicateDecisionAction) => {
|
||||||
|
return this.operationsService.jsonPatchByResourceID(
|
||||||
|
this.submissionService.getSubmissionObjectLinkName(),
|
||||||
|
action.payload.submissionId,
|
||||||
|
'sections',
|
||||||
|
action.payload.sectionId)
|
||||||
|
.map((response: SubmissionObject[]) => new SetDuplicateDecisionSuccessAction(action.payload.submissionId, action.payload.sectionId, response))
|
||||||
|
.catch(() => Observable.of(new SetDuplicateDecisionErrorAction(action.payload.submissionId)));
|
||||||
|
});
|
||||||
|
|
||||||
|
@Effect({dispatch: false}) setDuplicateDecisionSuccess$ = this.actions$
|
||||||
|
.ofType(SubmissionObjectActionTypes.SET_DUPLICATE_DECISION_SUCCESS)
|
||||||
|
.do(() => this.notificationsService.success(null, this.translate.get('submission.sections.detect-duplicate.decision-success-notice')));
|
||||||
|
|
||||||
|
/* @Effect() setDuplicateDecisionSuccess$ = this.actions$
|
||||||
|
.ofType(SubmissionObjectActionTypes.SET_DUPLICATE_DECISION_SUCCESS)
|
||||||
|
.withLatestFrom(this.store$)
|
||||||
|
.map(([action, currentState]: [SetDuplicateDecisionSuccessAction, any]) => {
|
||||||
|
this.notificationsService.success(null, this.translate.get('submission.sections.detect-duplicate.decision-success-notice'));
|
||||||
|
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId], action.payload.submissionObject, action.payload.submissionId, false);
|
||||||
|
})
|
||||||
|
.mergeMap((actions) => Observable.from(actions));*/
|
||||||
|
|
||||||
@Effect() saveAndDepositSection$ = this.actions$
|
@Effect() saveAndDepositSection$ = this.actions$
|
||||||
.ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION)
|
.ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION)
|
||||||
.withLatestFrom(this.store$)
|
.withLatestFrom(this.store$)
|
||||||
@@ -202,79 +222,13 @@ export class SubmissionObjectEffects {
|
|||||||
.ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR)
|
.ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR)
|
||||||
.do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')));
|
.do(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')));
|
||||||
|
|
||||||
@Effect()
|
|
||||||
public wsDuplication: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION)
|
|
||||||
.map((action: SetWorkspaceDuplicatedAction) => {
|
|
||||||
// return this.deduplicationService.setWorkspaceDuplicated(action.payload)
|
|
||||||
// .first()
|
|
||||||
// .map((response) => {
|
|
||||||
console.log('Effect of SET_WORKSPACE_DUPLICATION');
|
|
||||||
// TODO JSON PATCH
|
|
||||||
// const pathCombiner = new JsonPatchOperationPathCombiner('sections', 'deduplication');
|
|
||||||
// const path = ''; // `metadata/${metadataKey}`; // TODO
|
|
||||||
// this.operationsBuilder.add(pathCombiner.getPath(path), action.payload, true);
|
|
||||||
return new SetWorkspaceDuplicatedSuccessAction(action.payload);
|
|
||||||
})
|
|
||||||
.catch((error) => Observable.of(new SetWorkspaceDuplicatedErrorAction(error)));
|
|
||||||
|
|
||||||
@Effect({dispatch: false})
|
|
||||||
public wsDuplicationSuccess: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION_SUCCESS)
|
|
||||||
// TODO
|
|
||||||
.do((action: SetWorkspaceDuplicatedAction) => {
|
|
||||||
console.log('Effect of SET_WORKSPACE_DUPLICATION_SUCCESS');
|
|
||||||
this.deduplicationService.setWorkspaceDuplicationSuccess(action.payload);
|
|
||||||
});
|
|
||||||
|
|
||||||
@Effect({dispatch: false})
|
|
||||||
public wsDuplicationError: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION_ERROR)
|
|
||||||
.do((action: SetWorkspaceDuplicatedAction) => {
|
|
||||||
console.log('Effect of SET_WORKSPACE_DUPLICATION_ERROR');
|
|
||||||
this.deduplicationService.setWorkspaceDuplicationError(action.payload);
|
|
||||||
});
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
public wfDuplication: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION)
|
|
||||||
.map((action: SetWorkflowDuplicatedAction) => {
|
|
||||||
// return this.deduplicationService.setWorkflowDuplicated(action.payload)
|
|
||||||
// .first()
|
|
||||||
// .map((response) => {
|
|
||||||
console.log('Effect of SET_WORKFLOW_DUPLICATION');
|
|
||||||
// TODO JSON PATCH
|
|
||||||
// const pathCombiner = new JsonPatchOperationPathCombiner('sections', 'deduplication');
|
|
||||||
// const path = ''; // `metadata/${metadataKey}`; // TODO
|
|
||||||
// this.operationsBuilder.add(pathCombiner.getPath(path), action.payload, true);
|
|
||||||
return new SetWorkflowDuplicatedSuccessAction(action.payload);
|
|
||||||
})
|
|
||||||
.catch((error) => Observable.of(new SetWorkflowDuplicatedErrorAction(error)));
|
|
||||||
|
|
||||||
@Effect({dispatch: false})
|
|
||||||
public wfDuplicationSuccess: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION_SUCCESS)
|
|
||||||
// TODO
|
|
||||||
.do((action: SetWorkflowDuplicatedAction) => {
|
|
||||||
console.log('Effect of SET_WORKFLOW_DUPLICATION_SUCCESS');
|
|
||||||
this.deduplicationService.setWorkflowDuplicationSuccess(action.payload);
|
|
||||||
});
|
|
||||||
|
|
||||||
@Effect({dispatch: false})
|
|
||||||
public wfDuplicationError: Observable<Action> = this.actions$
|
|
||||||
.ofType(SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION_ERROR)
|
|
||||||
.do((action: SetWorkflowDuplicatedAction) => {
|
|
||||||
console.log('Effect of SET_WORKFLOW_DUPLICATION_ERROR');
|
|
||||||
this.deduplicationService.setWorkflowDuplicationError(action.payload);
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(private actions$: Actions,
|
constructor(private actions$: Actions,
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private operationsService: JsonPatchOperationsService<SubmitDataResponseDefinitionObject>,
|
private operationsService: JsonPatchOperationsService<SubmitDataResponseDefinitionObject>,
|
||||||
private sectionService: SectionsService,
|
private sectionService: SectionsService,
|
||||||
private store$: Store<any>,
|
private store$: Store<any>,
|
||||||
private submissionService: SubmissionService,
|
private submissionService: SubmissionService,
|
||||||
private deduplicationService: DeduplicationService,
|
private deduplicationService: DetectDuplicateService,
|
||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,11 +247,13 @@ export class SubmissionObjectEffects {
|
|||||||
return canDeposit;
|
return canDeposit;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected parseSaveResponse(currentState: SubmissionObjectEntry, response: SubmissionObject[], submissionId: string) {
|
protected parseSaveResponse(currentState: SubmissionObjectEntry, response: SubmissionObject[], submissionId: string, notify: boolean = true) {
|
||||||
const mappedActions = [];
|
const mappedActions = [];
|
||||||
|
|
||||||
if (isNotEmpty(response)) {
|
if (isNotEmpty(response)) {
|
||||||
this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'));
|
if (notify) {
|
||||||
|
this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'));
|
||||||
|
}
|
||||||
|
|
||||||
// to avoid dispatching an action for every error, create an array of errors per section
|
// to avoid dispatching an action for every error, create an array of errors per section
|
||||||
response.forEach((item: Workspaceitem | Workflowitem) => {
|
response.forEach((item: Workspaceitem | Workflowitem) => {
|
||||||
@@ -307,19 +263,20 @@ export class SubmissionObjectEffects {
|
|||||||
|
|
||||||
if (errors && !isEmpty(errors)) {
|
if (errors && !isEmpty(errors)) {
|
||||||
errorsList = parseSectionErrors(errors);
|
errorsList = parseSectionErrors(errors);
|
||||||
this.notificationsService.warning(null, this.translate.get('submission.sections.general.sections_not_valid'));
|
if (notify) {
|
||||||
|
this.notificationsService.warning(null, this.translate.get('submission.sections.general.sections_not_valid'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sections = (item.sections && isNotEmpty(item.sections)) ? item.sections : {};
|
const sections: WorkspaceitemSectionsObject = (item.sections && isNotEmpty(item.sections)) ? item.sections : {};
|
||||||
|
|
||||||
const sectionsKeys: string[] = union(Object.keys(sections), Object.keys(errorsList));
|
const sectionsKeys: string[] = union(Object.keys(sections), Object.keys(errorsList));
|
||||||
|
|
||||||
sectionsKeys
|
sectionsKeys
|
||||||
.forEach((sectionId) => {
|
.forEach((sectionId) => {
|
||||||
const sectionErrors = errorsList[sectionId] || [];
|
const sectionErrors = errorsList[sectionId] || [];
|
||||||
const sectionData = sections[sectionId] || {};
|
const sectionData = sections[sectionId] || {};
|
||||||
if (!currentState.sections[sectionId].enabled) {
|
if (notify && !currentState.sections[sectionId].enabled) {
|
||||||
this.submissionService.notifyNewSection(sectionId);
|
this.submissionService.notifyNewSection(submissionId, sectionId, currentState.sections[sectionId].sectionType);
|
||||||
}
|
}
|
||||||
mappedActions.push(new UpdateSectionDataAction(submissionId, sectionId, sectionData, sectionErrors));
|
mappedActions.push(new UpdateSectionDataAction(submissionId, sectionId, sectionData, sectionErrors));
|
||||||
});
|
});
|
||||||
|
@@ -27,16 +27,18 @@ import {
|
|||||||
SaveSubmissionFormErrorAction,
|
SaveSubmissionFormErrorAction,
|
||||||
SaveSubmissionSectionFormSuccessAction,
|
SaveSubmissionSectionFormSuccessAction,
|
||||||
SaveSubmissionSectionFormErrorAction,
|
SaveSubmissionSectionFormErrorAction,
|
||||||
SetWorkspaceDuplicatedAction,
|
|
||||||
SetWorkflowDuplicatedAction,
|
|
||||||
InitSectionAction,
|
InitSectionAction,
|
||||||
RemoveSectionErrorsAction,
|
RemoveSectionErrorsAction,
|
||||||
SaveForLaterSubmissionFormAction,
|
SaveForLaterSubmissionFormAction,
|
||||||
SaveAndDepositSubmissionAction, SaveForLaterSubmissionFormSuccessAction, SaveForLaterSubmissionFormErrorAction
|
SaveAndDepositSubmissionAction,
|
||||||
|
SaveForLaterSubmissionFormSuccessAction,
|
||||||
|
SaveForLaterSubmissionFormErrorAction,
|
||||||
|
SetDuplicateDecisionAction, SetDuplicateDecisionSuccessAction, SetDuplicateDecisionErrorAction
|
||||||
} from './submission-objects.actions';
|
} from './submission-objects.actions';
|
||||||
import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model';
|
import { WorkspaceitemSectionDataType } from '../../core/submission/models/workspaceitem-sections.model';
|
||||||
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';
|
||||||
|
import { WorkspaceitemSectionDetectDuplicateObject } from '../../core/submission/models/workspaceitem-section-deduplication.model';
|
||||||
|
|
||||||
export interface SectionVisibility {
|
export interface SectionVisibility {
|
||||||
main: any;
|
main: any;
|
||||||
@@ -74,6 +76,7 @@ export interface SubmissionObjectEntry {
|
|||||||
sections?: SubmissionSectionEntry;
|
sections?: SubmissionSectionEntry;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
savePending?: boolean;
|
savePending?: boolean;
|
||||||
|
saveDecisionPending?: boolean;
|
||||||
depositPending?: boolean;
|
depositPending?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,15 +195,6 @@ export function submissionObjectReducer(state = initialState, action: Submission
|
|||||||
return deleteFile(state, action as DeleteUploadedFileAction);
|
return deleteFile(state, action as DeleteUploadedFileAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deduplication
|
|
||||||
case SubmissionObjectActionTypes.SET_WORKSPACE_DUPLICATION: {
|
|
||||||
return updateDeduplication(state, action as SetWorkspaceDuplicatedAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
case SubmissionObjectActionTypes.SET_WORKFLOW_DUPLICATION: {
|
|
||||||
return updateDeduplication(state, action as SetWorkflowDuplicatedAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// errors actions
|
// errors actions
|
||||||
case SubmissionObjectActionTypes.ADD_SECTION_ERROR: {
|
case SubmissionObjectActionTypes.ADD_SECTION_ERROR: {
|
||||||
return addError(state, action as InertSectionErrorsAction);
|
return addError(state, action as InertSectionErrorsAction);
|
||||||
@@ -214,6 +208,19 @@ export function submissionObjectReducer(state = initialState, action: Submission
|
|||||||
return removeSectionErrors(state, action as RemoveSectionErrorsAction);
|
return removeSectionErrors(state, action as RemoveSectionErrorsAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detect duplicate
|
||||||
|
case SubmissionObjectActionTypes.SET_DUPLICATE_DECISION: {
|
||||||
|
return startSaveDecision(state, action as SetDuplicateDecisionAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SubmissionObjectActionTypes.SET_DUPLICATE_DECISION_SUCCESS: {
|
||||||
|
return setDuplicateMatches(state, action as SetDuplicateDecisionSuccessAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
case SubmissionObjectActionTypes.SET_DUPLICATE_DECISION: {
|
||||||
|
return endSaveDecision(state, action as SetDuplicateDecisionErrorAction);
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -319,6 +326,7 @@ function initSubmission(state: SubmissionObjectState, action: InitSubmissionForm
|
|||||||
sections: Object.create(null),
|
sections: Object.create(null),
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
savePending: false,
|
savePending: false,
|
||||||
|
saveDecisionPending: false,
|
||||||
depositPending: false,
|
depositPending: false,
|
||||||
};
|
};
|
||||||
return newState;
|
return newState;
|
||||||
@@ -740,7 +748,7 @@ function deleteFile(state: SubmissionObjectState, action: DeleteUploadedFileActi
|
|||||||
[ action.payload.submissionId ]: Object.assign({}, state[action.payload.submissionId], {
|
[ action.payload.submissionId ]: Object.assign({}, state[action.payload.submissionId], {
|
||||||
sections: Object.assign({}, state[action.payload.submissionId].sections,
|
sections: Object.assign({}, state[action.payload.submissionId].sections,
|
||||||
Object.assign({}, {
|
Object.assign({}, {
|
||||||
[ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], {
|
[ 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, {
|
data: Object.assign({}, state[ action.payload.submissionId ].sections[ action.payload.sectionId ].data, {
|
||||||
files: newData
|
files: newData
|
||||||
})
|
})
|
||||||
@@ -754,25 +762,74 @@ function deleteFile(state: SubmissionObjectState, action: DeleteUploadedFileActi
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------ Detect duplicate functions ------ //
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a Workspace deduplication match.
|
* Set decision flag to true
|
||||||
*
|
*
|
||||||
* @param state
|
* @param state
|
||||||
* the current state
|
* the current state
|
||||||
* @param action
|
* @param action
|
||||||
* a SetWorkspaceDuplicatedAction or SetWorkflowDuplicatedAction
|
* an SetDuplicateDecisionAction
|
||||||
* @return SubmissionObjectState
|
* @return SubmissionObjectState
|
||||||
* the new state, with the match parameter changed.
|
* the new state, with the decision flag changed.
|
||||||
*/
|
*/
|
||||||
function updateDeduplication(state: SubmissionObjectState, action: SetWorkspaceDuplicatedAction|SetWorkflowDuplicatedAction): SubmissionObjectState {
|
function startSaveDecision(state: SubmissionObjectState, action: SetDuplicateDecisionAction): SubmissionObjectState {
|
||||||
const matches = Object.assign([], (state[(action.payload as any).submissionId].sections.deduplication.data as any).matches);
|
if (hasValue(state[ action.payload.submissionId ])) {
|
||||||
const newMatch = (action.payload as any).data;
|
return Object.assign({}, state, {
|
||||||
matches.forEach( (match, i) => {
|
[ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], {
|
||||||
if (i === action.payload.index) {
|
saveDecisionPending: true,
|
||||||
matches.splice(i, 1, Object.assign({}, match, newMatch));
|
})
|
||||||
return;
|
});
|
||||||
}
|
} else {
|
||||||
});
|
return state;
|
||||||
// const updatedMatches = Object.assign({}, matches, newMatch);
|
}
|
||||||
return Object.assign({}, state, {[(action.payload as any).submissionId]: {sections: {deduplication: {data: {matches}}}}});
|
}
|
||||||
|
|
||||||
|
function setDuplicateMatches(state: SubmissionObjectState, action: SetDuplicateDecisionSuccessAction) {
|
||||||
|
const index: any = findKey(
|
||||||
|
action.payload.submissionObject,
|
||||||
|
{id: parseInt(action.payload.submissionId, 10)});
|
||||||
|
const sectionData = action.payload.submissionObject[index].sections[ action.payload.sectionId ] as WorkspaceitemSectionDetectDuplicateObject;
|
||||||
|
const newData = (sectionData && sectionData.matches) ? sectionData : Object.create({});
|
||||||
|
|
||||||
|
if (hasValue(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,
|
||||||
|
Object.assign({}, {
|
||||||
|
[ action.payload.sectionId ]: Object.assign({}, state[ action.payload.submissionId ].sections [ action.payload.sectionId ], {
|
||||||
|
enabled: true,
|
||||||
|
data: newData
|
||||||
|
})
|
||||||
|
})
|
||||||
|
),
|
||||||
|
saveDecisionPending: false
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set decision flag to false
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* the current state
|
||||||
|
* @param action
|
||||||
|
* an SetDuplicateDecisionSuccessAction or SetDuplicateDecisionErrorAction
|
||||||
|
* @return SubmissionObjectState
|
||||||
|
* the new state, with the decision flag changed.
|
||||||
|
*/
|
||||||
|
function endSaveDecision(state: SubmissionObjectState, action: SetDuplicateDecisionSuccessAction | SetDuplicateDecisionErrorAction): SubmissionObjectState {
|
||||||
|
if (hasValue(state[ action.payload.submissionId ])) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
[ action.payload.submissionId ]: Object.assign({}, state[ action.payload.submissionId ], {
|
||||||
|
saveDecisionPending: false,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { SubmissionState } from '../../submission.reducers';
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import { HttpHeaders } from '@angular/common/http';
|
|
||||||
import { HttpOptions } from '../../../core/dspace-rest-v2/dspace-rest-v2.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class DeduplicationService {
|
|
||||||
|
|
||||||
constructor(private store: Store<SubmissionState>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// setWorkspaceDuplicated(payload: any): Observable<any> {
|
|
||||||
// const options: HttpOptions = Object.create({});
|
|
||||||
// let headers = new HttpHeaders();
|
|
||||||
// headers = headers.append('Content-Type', 'application/json');
|
|
||||||
// options.headers = headers;
|
|
||||||
// // TODO REST CALL
|
|
||||||
// // return this.restService.postToEndpoint('workspace/deduplication', payload, null, options);
|
|
||||||
// return Observable.of(payload);
|
|
||||||
// }
|
|
||||||
|
|
||||||
setWorkspaceDuplicationSuccess(payload: any): void {
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setWorkspaceDuplicationError(payload: any): void {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// setWorkflowDuplicated(payload: any): Observable<any> {
|
|
||||||
// const options: HttpOptions = Object.create({});
|
|
||||||
// let headers = new HttpHeaders();
|
|
||||||
// headers = headers.append('Content-Type', 'application/json');
|
|
||||||
// options.headers = headers;
|
|
||||||
// // TODO REST CALL
|
|
||||||
// // return this.restService.postToEndpoint('workflow/deduplication', payload, null, options);
|
|
||||||
// return Observable.of(payload);
|
|
||||||
// }
|
|
||||||
|
|
||||||
setWorkflowDuplicationSuccess(payload: any): void {
|
|
||||||
// TODO Update the redux store
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setWorkflowDuplicationError(payload: any): void {
|
|
||||||
// TODO Update the redux store
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,57 +1,50 @@
|
|||||||
<!--<ds-item-list-preview-->
|
<ds-item-list-preview
|
||||||
<!--[item]="item"-->
|
[item]="item"
|
||||||
<!--[object]="object"-->
|
[object]="object"
|
||||||
<!--></ds-item-list-preview>-->
|
></ds-item-list-preview>
|
||||||
|
|
||||||
|
<div *ngIf="isWorkFlow" class="mt-2">
|
||||||
<!--<button (click)="toggleSubmitterDecision()"-->
|
<form>
|
||||||
<!--class="btn btn-link">-->
|
<div class="form-group mb-2">
|
||||||
<!--<span *ngIf="isWorkFlow && !showSubmitterDecision"> <i class="fa fa-angle-double-down"></i> Show submitter decision</span>-->
|
<label class="mb-1" for="submitterDecision"><strong> {{'submission.sections.detect-duplicate.submitter-decision' | translate}} </strong></label><br>
|
||||||
<!--<span *ngIf="isWorkFlow && showSubmitterDecision"> <i class="fa fa-angle-double-up"></i> Hide submitter decision</span>-->
|
<span id="submitterDecision" class="badge badge-pill {{decisionLabelClass}}">
|
||||||
<!--</button>-->
|
{{submitterDecision$ | async}}
|
||||||
|
</span>
|
||||||
<!--<div *ngIf="showSubmitterDecision">-->
|
</div>
|
||||||
<div>
|
<div class="form-group" *ngIf="submitterNote">
|
||||||
<label><strong> {{submitterDecisionLabel | async}} </strong>
|
<label for="submitterNote"><strong>{{'submission.sections.detect-duplicate.submitter-note' | translate}}</strong></label>
|
||||||
<span [ngClass]="{'label': true,
|
<textarea class="form-control" id="submitterNote" rows="3" readonly>{{submitterNote}}</textarea>
|
||||||
'label-warning': match.submitterDecision == 'verify',
|
</div>
|
||||||
'label-success': match.submitterDecision == 'reject',
|
</form>
|
||||||
'label-default': (match.submitterDecision == undefined || match.submitterDecision == null)}">
|
|
||||||
{{submitterDecisionTxt}}
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<!--<div>-->
|
|
||||||
<!--<label><strong> Explaination: </strong>-->
|
|
||||||
<!--<span class="label">-->
|
|
||||||
<!--I want to provide the fulltext of this article-->
|
|
||||||
<!--</span>-->
|
|
||||||
<!--</label>-->
|
|
||||||
<!--</div>-->
|
|
||||||
|
|
||||||
<div class="mb-3" *ngIf="!decidedYet">
|
<div class="mt-3 mb-2" *ngIf="!hasDecision">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-warning"
|
class="btn btn-warning"
|
||||||
ngbTooltip="{{'submission.sections.deduplication.duplicated_help' | translate}}"
|
ngbTooltip="{{'submission.sections.detect-duplicate.duplicate-help' | translate}}"
|
||||||
|
[disabled]="(processingVerify | async) || (processingReject | async)"
|
||||||
(click)="openModal(modal)">
|
(click)="openModal(modal)">
|
||||||
<span> {{duplicatedBtnLabel | async}}</span>
|
<span *ngIf="(processingVerify | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span>
|
||||||
|
<span *ngIf="!(processingVerify | async)">{{duplicateBtnLabel$ | async}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-success"
|
class="btn btn-success"
|
||||||
ngbTooltip="{{'submission.sections.deduplication.not_duplicated_help' | translate}}"
|
ngbTooltip="{{'submission.sections.detect-duplicate.not-duplicate-help' | translate}}"
|
||||||
(click)="setAsNotDuplicated()">
|
[disabled]="(processingReject | async) || (processingVerify | async)"
|
||||||
|
(click)="setAsNotDuplicate()">
|
||||||
<span> {{'submission.sections.deduplication.not_duplicated' | translate}}</span>
|
<span *ngIf="(processingReject | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span>
|
||||||
|
<span *ngIf="!(processingReject | async)">{{notDuplicateBtnLabel$ | async}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3" *ngIf="decidedYet">
|
<div class="mt-3 mb-2" *ngIf="hasDecision">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-danger"
|
class="btn btn-danger"
|
||||||
ngbTooltip="{{'submission.sections.deduplication.clear_decision_help' | translate}}"
|
ngbTooltip="{{'submission.sections.detect-duplicate.clear-decision-help' | translate}}"
|
||||||
(click)="clearDecision()">
|
(click)="clearDecision()">
|
||||||
<span> {{'submission.sections.deduplication.clear_decision' | translate}}</span>
|
<span> {{'submission.sections.detect-duplicate.clear-decision' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -67,20 +60,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="alert alert-info" role="alert">
|
<div class="alert alert-info" role="alert">
|
||||||
{{'submission.sections.deduplication.note_help' | translate}}
|
{{'submission.sections.detect-duplicate.note-help' | translate}}
|
||||||
</div>
|
</div>
|
||||||
<form (ngSubmit)="setAsDuplicated();" [formGroup]="rejectForm" >
|
<form (ngSubmit)="setAsDuplicate();" [formGroup]="rejectForm" >
|
||||||
<textarea
|
<textarea class="w-100"
|
||||||
style="width: 100%"
|
formControlName="reason"
|
||||||
formControlName="reason"
|
rows="4"
|
||||||
rows="4"
|
placeholder="{{'submission.sections.detect-duplicate.note-placeholder' | translate}}"></textarea>
|
||||||
placeholder="{{'submission.sections.deduplication.note_placeholder' | translate}}"></textarea>
|
<button id="btn-chat"
|
||||||
<button
|
class="btn btn-danger btn-lg btn-block mt-3"
|
||||||
id="btn-chat"
|
[disabled]="!rejectForm.valid"
|
||||||
class="btn btn-danger btn-lg btn-block mt-3"
|
type="submit">
|
||||||
[disabled]="!rejectForm.valid"
|
<span *ngIf="(processingReject | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span>
|
||||||
type="submit">
|
<span *ngIf="!(processingReject | async)">{{'submission.sections.detect-duplicate.duplicate' | translate}}</span>
|
||||||
<span>{{'submission.sections.deduplication.duplicated' | translate}}</span>
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,164 +1,146 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { DeduplicationSchema } from '../../../../core/submission/models/workspaceitem-section-deduplication.model';
|
import { DetectDuplicateMatch } from '../../../../core/submission/models/workspaceitem-section-deduplication.model';
|
||||||
import { SubmissionService } from '../../../submission.service';
|
import { SubmissionService } from '../../../submission.service';
|
||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { Store } from '@ngrx/store';
|
import { DetectDuplicateService } from '../detect-duplicate.service';
|
||||||
import { SubmissionState } from '../../../submission.reducers';
|
|
||||||
import { DeduplicationService } from '../deduplication.service';
|
|
||||||
import { JsonPatchOperationsBuilder } from '../../../../core/json-patch/builder/json-patch-operations-builder';
|
import { JsonPatchOperationsBuilder } from '../../../../core/json-patch/builder/json-patch-operations-builder';
|
||||||
import { JsonPatchOperationPathCombiner } from '../../../../core/json-patch/builder/json-patch-operation-path-combiner';
|
import { JsonPatchOperationPathCombiner } from '../../../../core/json-patch/builder/json-patch-operation-path-combiner';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { SubmissionScopeType } from '../../../../core/submission/submission-scope-type';
|
import { SubmissionScopeType } from '../../../../core/submission/submission-scope-type';
|
||||||
|
import { DuplicateDecisionValue } from '../models/duplicate-decision-value';
|
||||||
|
import { DuplicateDecision } from '../models/duplicate-decision.model';
|
||||||
|
import { DuplicateDecisionType } from '../models/duplicate-decision-type';
|
||||||
|
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||||
|
import { SectionsService } from '../../sections.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-deduplication-match',
|
selector: 'ds-duplicate-match',
|
||||||
templateUrl: 'deduplication-match.component.html',
|
templateUrl: 'duplicate-match.component.html',
|
||||||
})
|
})
|
||||||
|
|
||||||
export class DeduplicationMatchComponent implements OnInit {
|
export class DuplicateMatchComponent implements OnInit {
|
||||||
@Input()
|
@Input() sectionId: string;
|
||||||
sectionId: string;
|
@Input() itemId: string;
|
||||||
@Input()
|
@Input() match: DetectDuplicateMatch;
|
||||||
match: DeduplicationSchema;
|
@Input() submissionId: string;
|
||||||
@Input()
|
@Input() index: string;
|
||||||
submissionId: string;
|
|
||||||
@Input()
|
|
||||||
index: string;
|
|
||||||
|
|
||||||
object = {hitHighlights: []};
|
object = {hitHighlights: []};
|
||||||
item: Item;
|
item: Item;
|
||||||
isWorkFlow = false;
|
isWorkFlow = false;
|
||||||
showSubmitterDecision = false;
|
showSubmitterDecision = false;
|
||||||
submitterDecisionTxt: string;
|
decisionType: DuplicateDecisionType;
|
||||||
|
submitterDecision$: Observable<string>;
|
||||||
|
submitterNote: string;
|
||||||
|
|
||||||
decidedYet: boolean;
|
hasDecision: boolean;
|
||||||
|
|
||||||
closeResult: string; // for modal
|
closeResult: string; // for modal
|
||||||
rejectForm: FormGroup;
|
rejectForm: FormGroup;
|
||||||
modalRef: NgbModalRef;
|
modalRef: NgbModalRef;
|
||||||
pathCombiner: JsonPatchOperationPathCombiner;
|
pathCombiner: JsonPatchOperationPathCombiner;
|
||||||
|
public processingVerify: Observable<boolean> = Observable.of(false);
|
||||||
|
public processingReject: Observable<boolean> = Observable.of(false);
|
||||||
|
decisionLabelClass: string;
|
||||||
|
duplicateBtnLabel$: Observable<string>;
|
||||||
|
notDuplicateBtnLabel$: Observable<string>;
|
||||||
|
|
||||||
duplicatedBtnLabel: Observable<string>;
|
constructor(private detectDuplicateService: DetectDuplicateService,
|
||||||
submitterDecisionLabel: Observable<string>;
|
|
||||||
|
|
||||||
constructor(private deduplicationService: DeduplicationService,
|
|
||||||
private submissionService: SubmissionService,
|
|
||||||
private modalService: NgbModal,
|
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private store: Store<SubmissionState>,
|
private modalService: NgbModal,
|
||||||
protected operationsBuilder: JsonPatchOperationsBuilder,
|
private operationsBuilder: JsonPatchOperationsBuilder,
|
||||||
|
private sectionService: SectionsService,
|
||||||
|
private submissionService: SubmissionService,
|
||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if ((this.match.matchObject as any).item) {
|
|
||||||
// WSI & WFI
|
|
||||||
this.item = Object.assign(new Item(), (this.match.matchObject as any).item);
|
|
||||||
} else {
|
|
||||||
// Item
|
|
||||||
this.item = Object.assign(new Item(), this.match.matchObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isWorkFlow = this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkflowItem;
|
this.isWorkFlow = this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkflowItem;
|
||||||
|
this.decisionType = this.isWorkFlow ? DuplicateDecisionType.WORKFLOW : DuplicateDecisionType.WORKSPACE;
|
||||||
|
this.item = Object.assign(new Item(), this.match.matchObject);
|
||||||
|
|
||||||
this.rejectForm = this.formBuilder.group({
|
this.rejectForm = this.formBuilder.group({
|
||||||
reason: ['', Validators.required]
|
reason: ['', Validators.required]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.decidedYet = this.isWorkFlow ?
|
this.hasDecision = this.isWorkFlow ?
|
||||||
this.match.workflowDecision !== null ? true : false
|
this.match.workflowDecision !== null
|
||||||
: this.match.submitterDecision !== null ? true : false;
|
: this.match.submitterDecision !== null;
|
||||||
|
|
||||||
if (this.match.submitterDecision) {
|
if (this.match.submitterDecision) {
|
||||||
if (this.match.submitterDecision === 'verify') {
|
this.submitterDecision$ = (this.match.submitterDecision === DuplicateDecisionValue.Reject) ?
|
||||||
this.submitterDecisionTxt = 'It\'s a duplicate';
|
this.translate.get('submission.sections.detect-duplicate.not-duplicate') :
|
||||||
} else {
|
this.translate.get('submission.sections.detect-duplicate.duplicate');
|
||||||
this.submitterDecisionTxt = 'It\'s not a duplicate';
|
this.decisionLabelClass = (this.match.submitterDecision === DuplicateDecisionValue.Reject) ? 'badge-success' : 'badge-warning';
|
||||||
}
|
this.submitterNote = this.match.submitterNote;
|
||||||
} else {
|
} else {
|
||||||
this.submitterDecisionTxt = 'Not decided';
|
this.submitterDecision$ = this.translate.get('submission.sections.detect-duplicate.no-decision');
|
||||||
|
this.decisionLabelClass = 'badge-light';
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionId, 'matches', this.index);
|
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionId);
|
||||||
|
|
||||||
this.duplicatedBtnLabel = this.isWorkFlow ?
|
this.duplicateBtnLabel$ = this.isWorkFlow ?
|
||||||
this.translate.get('submission.sections.deduplication.duplicated_ctrl')
|
((this.match.submitterDecision === DuplicateDecisionValue.Verify) ?
|
||||||
: this.translate.get('submission.sections.deduplication.duplicated');
|
this.translate.get('submission.sections.detect-duplicate.confirm-duplicate') :
|
||||||
|
this.translate.get('submission.sections.detect-duplicate.duplicate-ctrl'))
|
||||||
|
: this.translate.get('submission.sections.detect-duplicate.duplicate');
|
||||||
|
|
||||||
this.submitterDecisionLabel = this.isWorkFlow ?
|
this.notDuplicateBtnLabel$ = (this.isWorkFlow && this.match.submitterDecision === DuplicateDecisionValue.Reject) ?
|
||||||
this.translate.get('submission.sections.deduplication.submitter_decision')
|
this.translate.get('submission.sections.detect-duplicate.confirm-not-duplicate') :
|
||||||
: this.translate.get('submission.sections.deduplication.your_decision');
|
this.translate.get('submission.sections.detect-duplicate.not-duplicate');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setAsDuplicated() {
|
setAsDuplicate() {
|
||||||
console.log('Setting item #' + this.item.uuid + ' as duplicated...');
|
this.processingVerify = Observable.of(true);
|
||||||
this.dispatchAction(true);
|
const decision = new DuplicateDecision(
|
||||||
|
DuplicateDecisionValue.Verify,
|
||||||
|
this.decisionType,
|
||||||
|
this.rejectForm.get('reason').value);
|
||||||
|
|
||||||
|
this.dispatchAction(decision);
|
||||||
this.modalRef.dismiss();
|
this.modalRef.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
setAsNotDuplicated() {
|
setAsNotDuplicate() {
|
||||||
console.log('Setting item #' + this.item.uuid + ' as not duplicated...');
|
this.processingReject = Observable.of(true);
|
||||||
this.dispatchAction(false);
|
const decision = new DuplicateDecision(
|
||||||
|
DuplicateDecisionValue.Reject,
|
||||||
|
this.decisionType);
|
||||||
|
|
||||||
|
this.dispatchAction(decision);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearDecision() {
|
clearDecision() {
|
||||||
console.log('Clearing item #' + this.item.uuid + ' from previous decision...');
|
const decision = new DuplicateDecision(
|
||||||
|
DuplicateDecisionValue.Undo,
|
||||||
|
this.decisionType);
|
||||||
|
|
||||||
|
this.dispatchAction(decision);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private dispatchAction(duplicated: boolean, clear?: boolean): void {
|
private dispatchAction(decision: DuplicateDecision): void {
|
||||||
|
const pathDecision = Array.of('matches', this.itemId, this.isWorkFlow ? 'workflowDecision' : 'submitterDecision').join('/');
|
||||||
const payload = {
|
const payload = {
|
||||||
submissionId: this.submissionId,
|
value: isNotEmpty(decision.value) ? decision.value : null,
|
||||||
index: this.index,
|
note: isNotEmpty(decision.note) ? decision.note : null
|
||||||
data: {} as DeduplicationSchema
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call workflow action
|
// dispatch patch operation only when section is active
|
||||||
const decision = clear ? null : duplicated ? 'verify' : 'reject';
|
this.sectionService.isSectionActive(this.submissionId, this.sectionId)
|
||||||
const pathDecision = this.isWorkFlow ? 'workflowDecision' : 'submitterDecision';
|
.filter((isActive: boolean) => isActive)
|
||||||
this.operationsBuilder.add(this.pathCombiner.getPath(pathDecision), decision, false, true);
|
.take(1)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.operationsBuilder.add(this.pathCombiner.getPath(pathDecision), payload, false, true);
|
||||||
|
this.detectDuplicateService.saveDuplicateDecision(this.submissionId, this.sectionId)
|
||||||
|
});
|
||||||
|
|
||||||
if (!clear && duplicated) {
|
|
||||||
const note = this.rejectForm.get('reason').value;
|
|
||||||
const pathNote = this.isWorkFlow ? 'workflowNote' : 'submitterNote';
|
|
||||||
this.operationsBuilder.add(this.pathCombiner.getPath(pathNote), note, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// const now = new Date();
|
|
||||||
// const time = now.getUTCFullYear() + '/' + now.getUTCMonth() + 1 + '/' + now.getDay();
|
|
||||||
|
|
||||||
// if (this.isWorkFlow) {
|
|
||||||
// // Call workflow action
|
|
||||||
// payload.data.workflowDecision = clear ? null : duplicated ? 'verify' : 'reject';
|
|
||||||
// // payload.data.workflowTime = time;
|
|
||||||
// if (!clear && duplicated) {
|
|
||||||
// const note = this.rejectForm.get('reason').value;
|
|
||||||
// payload.data.workflowNote = note;
|
|
||||||
// }
|
|
||||||
// // Dispatch WorkFLOW action
|
|
||||||
// // this.store.dispatch(new SetWorkflowDuplicatedAction(payload));
|
|
||||||
// const path = 'workflowDecision'
|
|
||||||
// this.operationsBuilder.add(this.pathCombiner.getPath(path), payload.data.workflowDecision, false, true);
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// // Call workspace action
|
|
||||||
// payload.data.submitterDecision = clear ? null : duplicated ? 'verify' : 'reject';
|
|
||||||
// // payload.data.submitterTime = time;
|
|
||||||
// if (!clear && duplicated) {
|
|
||||||
// const note = this.rejectForm.get('reason').value;
|
|
||||||
// payload.data.submitterNote = note;
|
|
||||||
// }
|
|
||||||
// // Dispatch workSPACE action
|
|
||||||
// this.store.dispatch(new SetWorkspaceDuplicatedAction(payload));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleSubmitterDecision() {
|
|
||||||
this.showSubmitterDecision = !this.showSubmitterDecision;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openModal(modal) {
|
openModal(modal) {
|
||||||
|
@@ -1,38 +1,32 @@
|
|||||||
<ds-loading *ngIf="isLoading" message="Loading..."></ds-loading>
|
<ds-loading *ngIf="isLoading" message="Loading..."></ds-loading>
|
||||||
|
|
||||||
<ng-container *ngIf="(sectionDataObs | async)?.matches.length == 0">
|
<ng-container *ngIf="(totalMatch$ | async) === 0">
|
||||||
<div class="row">
|
<ds-alert [type]="AlertTypeEnum.Info" [content]="('submission.sections.detect-duplicate.disclaimer-no-match' | translate)"></ds-alert>
|
||||||
<div class="col-md-12">
|
|
||||||
<h3 class="text-center"><span class="text-muted">No duplicated yet.</span></h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container
|
<ng-container *ngIf="(totalMatch$ | async) > 0">
|
||||||
*ngIf="(sectionDataObs | async)?.matches.length > 0">
|
<ds-alert [type]="AlertTypeEnum.Warning" [content]="(disclaimer | async)"></ds-alert>
|
||||||
<div class="alert alert-danger" role="alert">
|
|
||||||
{{ disclaimer | async }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
[paginationOptions]="config"
|
[paginationOptions]="config"
|
||||||
[collectionSize]="(sectionDataObs | async)?.matches.length"
|
[collectionSize]="(totalMatch$ | async)"
|
||||||
[sortOptions]="sortConfig"
|
[sortOptions]="sortConfig"
|
||||||
[hideGear]="true"
|
[hideGear]="true"
|
||||||
[hidePagerWhenSinglePage]="false"
|
[hidePagerWhenSinglePage]="false"
|
||||||
(pageChange)="setPage($event)">
|
(pageChange)="setPage($event)">
|
||||||
|
|
||||||
<ul class="list-unstyled">
|
<ul class="list-unstyled">
|
||||||
<li *ngFor="let match of (sectionDataObs | async)?.matches
|
<li *ngFor="let item of (sectionData$ | async)?.matches | dsObjNgFor
|
||||||
| paginate: {id: config.id, itemsPerPage: config.pageSize, currentPage: config.currentPage}; let i = index"
|
| paginate: {id: config.id, itemsPerPage: config.pageSize, currentPage: config.currentPage}; let i = index; let l = last"
|
||||||
class="mt-4 mb-4">
|
class="mt-4 mb-4"
|
||||||
|
[class.border-bottom]="!l">
|
||||||
<ds-deduplication-match
|
<ds-duplicate-match
|
||||||
*ngVar="(i + (config.currentPage-1)*config.pageSize) as totalIndex"
|
*ngVar="(i + (config.currentPage-1)*config.pageSize) as totalIndex"
|
||||||
[sectionId]="sectionData.id"
|
[sectionId]="sectionData.id"
|
||||||
[match]="match"
|
[match]="item.value"
|
||||||
[submissionId]="submissionId"
|
[submissionId]="submissionId"
|
||||||
[index]=totalIndex></ds-deduplication-match>
|
[index]=totalIndex
|
||||||
|
[itemId]="item.key"></ds-duplicate-match>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</ds-pagination>
|
</ds-pagination>
|
||||||
|
@@ -1,40 +1,45 @@
|
|||||||
import { SectionsType } from '../sections-type';
|
import { SectionsType } from '../sections-type';
|
||||||
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { SectionModelComponent } from '../models/section.model';
|
import { SectionModelComponent } from '../models/section.model';
|
||||||
import { renderSectionFor } from '../sections-decorator';
|
import { renderSectionFor } from '../sections-decorator';
|
||||||
import { SectionDataObject } from '../models/section-data.model';
|
import { SectionDataObject } from '../models/section-data.model';
|
||||||
import { SubmissionState } from '../../submission.reducers';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
|
||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { submissionSectionDataFromIdSelector } from '../../selectors';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { isNotEmpty } from '../../../shared/empty.util';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { SubmissionService } from '../../submission.service';
|
import { SubmissionService } from '../../submission.service';
|
||||||
import { SubmissionScopeType } from '../../../core/submission/submission-scope-type';
|
import { SubmissionScopeType } from '../../../core/submission/submission-scope-type';
|
||||||
|
import { AlertType } from '../../../shared/alerts/aletrs-type';
|
||||||
|
import { DetectDuplicateService } from './detect-duplicate.service';
|
||||||
|
import { SectionsService } from '../sections.service';
|
||||||
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-deduplication-section',
|
selector: 'ds-deduplication-section',
|
||||||
// styleUrls: ['./section-deduplication.component.scss'],
|
// styleUrls: ['./section-deduplication.component.scss'],
|
||||||
templateUrl: './section-deduplication.component.html',
|
templateUrl: './section-detect-duplicate.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.Default
|
changeDetection: ChangeDetectionStrategy.Default
|
||||||
})
|
})
|
||||||
|
|
||||||
@renderSectionFor(SectionsType.Deduplication)
|
@renderSectionFor(SectionsType.DetectDuplicate)
|
||||||
export class DeduplicationSectionComponent extends SectionModelComponent implements OnInit {
|
export class DetectDuplicateSectionComponent extends SectionModelComponent implements OnDestroy, OnInit {
|
||||||
|
public AlertTypeEnum = AlertType;
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public sectionDataObs: Observable<any>;
|
public sectionData$: Observable<any>;
|
||||||
public matches = [];
|
public matches = {};
|
||||||
|
public totalMatch$: Observable<number>;
|
||||||
|
|
||||||
config: PaginationComponentOptions;
|
config: PaginationComponentOptions;
|
||||||
sortConfig: SortOptions;
|
sortConfig: SortOptions;
|
||||||
|
|
||||||
isWorkFlow = false;
|
isWorkFlow = false;
|
||||||
disclaimer: Observable<string>;
|
disclaimer: Observable<string>;
|
||||||
|
sub: Subscription;
|
||||||
|
|
||||||
constructor(protected store: Store<SubmissionState>,
|
constructor(private detectDuplicateService: DetectDuplicateService,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
|
private sectionService: SectionsService,
|
||||||
private submissionService: SubmissionService,
|
private submissionService: SubmissionService,
|
||||||
@Inject('collectionIdProvider') public injectedCollectionId: string,
|
@Inject('collectionIdProvider') public injectedCollectionId: string,
|
||||||
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
|
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
|
||||||
@@ -48,26 +53,34 @@ export class DeduplicationSectionComponent extends SectionModelComponent impleme
|
|||||||
this.config.pageSize = 2;
|
this.config.pageSize = 2;
|
||||||
this.sortConfig = new SortOptions('dc.title', SortDirection.ASC);
|
this.sortConfig = new SortOptions('dc.title', SortDirection.ASC);
|
||||||
|
|
||||||
this.sectionDataObs = this.store.select(submissionSectionDataFromIdSelector(this.submissionId, this.sectionData.id))
|
this.sectionData$ = this.detectDuplicateService.getDuplicateMatches(this.submissionId, this.sectionData.id);
|
||||||
.filter((sd) => isNotEmpty(sd))
|
|
||||||
.startWith({matches: []})
|
this.totalMatch$ = this.detectDuplicateService.getDuplicateTotalMatches(this.submissionId, this.sectionData.id);
|
||||||
.distinctUntilChanged()
|
|
||||||
.map((sd) => {
|
|
||||||
return sd;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.isWorkFlow = this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkflowItem;
|
this.isWorkFlow = this.submissionService.getSubmissionScope() === SubmissionScopeType.WorkflowItem;
|
||||||
|
|
||||||
this.disclaimer = this.isWorkFlow ?
|
this.disclaimer = this.isWorkFlow ?
|
||||||
this.translate.get('submission.sections.deduplication.disclaimer_ctrl')
|
this.translate.get('submission.sections.detect-duplicate.disclaimer-ctrl')
|
||||||
: this.translate.get('submission.sections.deduplication.disclaimer');
|
: this.translate.get('submission.sections.detect-duplicate.disclaimer');
|
||||||
|
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
|
||||||
|
this.sub = this.totalMatch$
|
||||||
|
.map((totalMatches: number) => totalMatches === 0)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.subscribe((status: boolean) => {
|
||||||
|
this.sectionService.setSectionStatus(this.submissionId, this.sectionData.id, status);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setPage(page) {
|
setPage(page) {
|
||||||
console.log('Select page #', page);
|
|
||||||
this.config.currentPage = page;
|
this.config.currentPage = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (hasValue(this.sub)) {
|
||||||
|
this.sub.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { SubmissionState } from '../../submission.reducers';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { SetDuplicateDecisionAction } from '../../objects/submission-objects.actions';
|
||||||
|
import { submissionSectionDataFromIdSelector } from '../../selectors';
|
||||||
|
import { WorkspaceitemSectionDetectDuplicateObject } from '../../../core/submission/models/workspaceitem-section-deduplication.model';
|
||||||
|
import { isEmpty } from '../../../shared/empty.util';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DetectDuplicateService {
|
||||||
|
|
||||||
|
constructor(private store: Store<SubmissionState>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuplicateMatches(submissionId: string, sectionId: string) {
|
||||||
|
return this.store.select(submissionSectionDataFromIdSelector(submissionId, sectionId))
|
||||||
|
.map((sectionData: WorkspaceitemSectionDetectDuplicateObject) => {
|
||||||
|
return (isEmpty(sectionData)) ? {matches: {}} : sectionData
|
||||||
|
})
|
||||||
|
.startWith({matches: {}})
|
||||||
|
.distinctUntilChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
getDuplicateTotalMatches(submissionId: string, sectionId: string) {
|
||||||
|
return this.getDuplicateMatches(submissionId, sectionId)
|
||||||
|
.map((sectionData: WorkspaceitemSectionDetectDuplicateObject) => Object.keys(sectionData.matches).length)
|
||||||
|
.distinctUntilChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveDuplicateDecision(submissionId: string, sectionId: string): void {
|
||||||
|
this.store.dispatch(new SetDuplicateDecisionAction(submissionId, sectionId));
|
||||||
|
}
|
||||||
|
}
|
@@ -134,7 +134,7 @@ export class SectionsDirective implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
public setFocus(event) {
|
public setFocus(event) {
|
||||||
if (!this.active) {
|
if (!this.active) {
|
||||||
this.store.dispatch(new SetActiveSectionAction(this.submissionId, this.sectionId));
|
this.submissionService.setActiveSection(this.submissionId, this.sectionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ import { hasValue, isEmpty, isNotEmpty, isNotUndefined } from '../../shared/empt
|
|||||||
import {
|
import {
|
||||||
DisableSectionAction,
|
DisableSectionAction,
|
||||||
EnableSectionAction,
|
EnableSectionAction,
|
||||||
InertSectionErrorsAction, RemoveSectionErrorsAction,
|
InertSectionErrorsAction, RemoveSectionErrorsAction, SectionStatusChangeAction,
|
||||||
UpdateSectionDataAction
|
UpdateSectionDataAction
|
||||||
} from '../objects/submission-objects.actions';
|
} from '../objects/submission-objects.actions';
|
||||||
import {
|
import {
|
||||||
@@ -24,12 +24,14 @@ import parseSectionErrorPaths, { SectionErrorPath } from '../utils/parseSectionE
|
|||||||
import { FormAddError, FormClearErrorsAction, FormRemoveErrorAction } from '../../shared/form/form.actions';
|
import { FormAddError, FormClearErrorsAction, FormRemoveErrorAction } from '../../shared/form/form.actions';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { SubmissionService } from '../submission.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SectionsService {
|
export class SectionsService {
|
||||||
|
|
||||||
constructor(private notificationsService: NotificationsService,
|
constructor(private notificationsService: NotificationsService,
|
||||||
private scrollToService: ScrollToService,
|
private scrollToService: ScrollToService,
|
||||||
|
private submissionService: SubmissionService,
|
||||||
private store: Store<SubmissionState>,
|
private store: Store<SubmissionState>,
|
||||||
private translate: TranslateService) {
|
private translate: TranslateService) {
|
||||||
}
|
}
|
||||||
@@ -86,6 +88,12 @@ export class SectionsService {
|
|||||||
.distinctUntilChanged();
|
.distinctUntilChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isSectionActive(submissionId, sectionId): Observable<boolean> {
|
||||||
|
return this.submissionService.getActiveSectionId(submissionId)
|
||||||
|
.map((activeSectionId: string) => sectionId === activeSectionId)
|
||||||
|
.distinctUntilChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public isSectionEnabled(submissionId, sectionId): Observable<boolean> {
|
public isSectionEnabled(submissionId, sectionId): Observable<boolean> {
|
||||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId))
|
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId))
|
||||||
.filter((sectionObj) => hasValue(sectionObj))
|
.filter((sectionObj) => hasValue(sectionObj))
|
||||||
@@ -150,4 +158,8 @@ export class SectionsService {
|
|||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setSectionStatus(submissionId: string, sectionId: string, status: boolean) {
|
||||||
|
this.store.dispatch(new SectionStatusChangeAction(submissionId, sectionId, status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,9 +29,9 @@ import { UploadSectionFileEditComponent } from './sections/upload/file/edit/file
|
|||||||
import { UploadSectionFileViewComponent } from './sections/upload/file/view/file-view.component';
|
import { UploadSectionFileViewComponent } from './sections/upload/file/view/file-view.component';
|
||||||
import { AccessConditionsComponent } from './sections/upload/accessConditions/accessConditions.component';
|
import { AccessConditionsComponent } from './sections/upload/accessConditions/accessConditions.component';
|
||||||
import { RecycleSectionComponent } from './sections/recycle/section-recycle.component';
|
import { RecycleSectionComponent } from './sections/recycle/section-recycle.component';
|
||||||
import { DeduplicationSectionComponent } from './sections/deduplication/section-deduplication.component';
|
import { DetectDuplicateSectionComponent } from './sections/detect-duplicate/section-detect-duplicate.component';
|
||||||
import { DeduplicationMatchComponent } from './sections/deduplication/match/deduplication-match.component';
|
import { DuplicateMatchComponent } from './sections/detect-duplicate/duplicate-match/duplicate-match.component';
|
||||||
import { DeduplicationService } from './sections/deduplication/deduplication.service';
|
import { DetectDuplicateService } from './sections/detect-duplicate/detect-duplicate.service';
|
||||||
import { SubmissionSubmitComponent } from './submit/submission-submit.component';
|
import { SubmissionSubmitComponent } from './submit/submission-submit.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -62,8 +62,8 @@ import { SubmissionSubmitComponent } from './submit/submission-submit.component'
|
|||||||
UploadSectionFileEditComponent,
|
UploadSectionFileEditComponent,
|
||||||
UploadSectionFileViewComponent,
|
UploadSectionFileViewComponent,
|
||||||
RecycleSectionComponent,
|
RecycleSectionComponent,
|
||||||
DeduplicationSectionComponent,
|
DetectDuplicateSectionComponent,
|
||||||
DeduplicationMatchComponent,
|
DuplicateMatchComponent,
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
DefaultSectionComponent,
|
DefaultSectionComponent,
|
||||||
@@ -72,7 +72,7 @@ import { SubmissionSubmitComponent } from './submit/submission-submit.component'
|
|||||||
LicenseSectionComponent,
|
LicenseSectionComponent,
|
||||||
SectionContainerComponent,
|
SectionContainerComponent,
|
||||||
RecycleSectionComponent,
|
RecycleSectionComponent,
|
||||||
DeduplicationSectionComponent],
|
DetectDuplicateSectionComponent],
|
||||||
exports: [
|
exports: [
|
||||||
SubmissionEditComponent,
|
SubmissionEditComponent,
|
||||||
SubmissionFormComponent,
|
SubmissionFormComponent,
|
||||||
@@ -83,7 +83,7 @@ import { SubmissionSubmitComponent } from './submit/submission-submit.component'
|
|||||||
SectionsService,
|
SectionsService,
|
||||||
SubmissionRestService,
|
SubmissionRestService,
|
||||||
SubmissionUploadsConfigService,
|
SubmissionUploadsConfigService,
|
||||||
DeduplicationService
|
DetectDuplicateService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SubmissionModule {
|
export class SubmissionModule {
|
||||||
|
@@ -7,7 +7,7 @@ import { Store } from '@ngrx/store';
|
|||||||
|
|
||||||
import { submissionSelector, SubmissionState } from './submission.reducers';
|
import { submissionSelector, SubmissionState } from './submission.reducers';
|
||||||
import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util';
|
import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util';
|
||||||
import { SaveSubmissionFormAction } from './objects/submission-objects.actions';
|
import { SaveSubmissionFormAction, SetActiveSectionAction } from './objects/submission-objects.actions';
|
||||||
import {
|
import {
|
||||||
SubmissionObjectEntry,
|
SubmissionObjectEntry,
|
||||||
SubmissionSectionEntry,
|
SubmissionSectionEntry,
|
||||||
@@ -26,6 +26,8 @@ import { RouteService } from '../shared/services/route.service';
|
|||||||
import { SectionsType } from './sections/sections-type';
|
import { SectionsType } from './sections/sections-type';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NotificationsService } from '../shared/notifications/notifications.service';
|
import { NotificationsService } from '../shared/notifications/notifications.service';
|
||||||
|
import { ScrollToConfigOptions, ScrollToService } from '@nicky-lenaers/ngx-scroll-to';
|
||||||
|
import { NotificationOptions } from '../shared/notifications/models/notification-options.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SubmissionService {
|
export class SubmissionService {
|
||||||
@@ -38,6 +40,7 @@ export class SubmissionService {
|
|||||||
protected restService: SubmissionRestService,
|
protected restService: SubmissionRestService,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
|
protected scrollToService: ScrollToService,
|
||||||
protected store: Store<SubmissionState>,
|
protected store: Store<SubmissionState>,
|
||||||
protected translate: TranslateService) {
|
protected translate: TranslateService) {
|
||||||
}
|
}
|
||||||
@@ -79,6 +82,7 @@ export class SubmissionService {
|
|||||||
const availableSections: SectionDataObject[] = [];
|
const availableSections: SectionDataObject[] = [];
|
||||||
Object.keys(sections)
|
Object.keys(sections)
|
||||||
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
|
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
|
||||||
|
// .filter((sectionId) => sections[sectionId].sectionType !== SectionsType.DetectDuplicate || isNotEmpty(sections[sectionId].data))
|
||||||
.forEach((sectionId) => {
|
.forEach((sectionId) => {
|
||||||
const sectionObject: SectionDataObject = Object.create({});
|
const sectionObject: SectionDataObject = Object.create({});
|
||||||
sectionObject.config = sections[sectionId].config;
|
sectionObject.config = sections[sectionId].config;
|
||||||
@@ -105,6 +109,7 @@ export class SubmissionService {
|
|||||||
Object.keys(sections)
|
Object.keys(sections)
|
||||||
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
|
.filter((sectionId) => !this.isSectionHidden(sections[sectionId] as SubmissionSectionObject))
|
||||||
.filter((sectionId) => !sections[sectionId].enabled)
|
.filter((sectionId) => !sections[sectionId].enabled)
|
||||||
|
.filter((sectionId) => sections[sectionId].sectionType !== SectionsType.DetectDuplicate)
|
||||||
.forEach((sectionId) => {
|
.forEach((sectionId) => {
|
||||||
const sectionObject: SectionDataObject = Object.create({});
|
const sectionObject: SectionDataObject = Object.create({});
|
||||||
sectionObject.header = sections[sectionId].header;
|
sectionObject.header = sections[sectionId].header;
|
||||||
@@ -196,6 +201,13 @@ export class SubmissionService {
|
|||||||
.startWith(false);
|
.startWith(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSubmissionDuplicateDecisionProcessingStatus(submissionId: string): Observable<boolean> {
|
||||||
|
return this.getSubmissionObject(submissionId)
|
||||||
|
.map((state: SubmissionObjectEntry) => state.saveDecisionPending)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.startWith(false);
|
||||||
|
}
|
||||||
|
|
||||||
redirectToMyDSpace() {
|
redirectToMyDSpace() {
|
||||||
const previousUrl = this.routeService.getPreviousUrl();
|
const previousUrl = this.routeService.getPreviousUrl();
|
||||||
if (isEmpty(previousUrl)) {
|
if (isEmpty(previousUrl)) {
|
||||||
@@ -205,12 +217,28 @@ export class SubmissionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyNewSection(sectionId: string, sectionType?: SectionsType) {
|
notifyNewSection(submissionId: string, sectionId: string, sectionType?: SectionsType) {
|
||||||
this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId})
|
|
||||||
.take(1)
|
if (sectionType === SectionsType.DetectDuplicate) {
|
||||||
.subscribe((m) => {
|
this.setActiveSection(submissionId, sectionId);
|
||||||
this.notificationsService.info(null, m, null, true);
|
this.translate.get('submission.sections.detect-duplicate.duplicate-detected', {sectionId})
|
||||||
});
|
.take(1)
|
||||||
|
.subscribe((msg) => {
|
||||||
|
this.notificationsService.warning(null, msg, new NotificationOptions(0));
|
||||||
|
});
|
||||||
|
const config: ScrollToConfigOptions = {
|
||||||
|
target: sectionId,
|
||||||
|
offset: -70
|
||||||
|
};
|
||||||
|
|
||||||
|
this.scrollToService.scrollTo(config);
|
||||||
|
} else {
|
||||||
|
this.translate.get('submission.sections.general.metadata-extracted-new-section', {sectionId})
|
||||||
|
.take(1)
|
||||||
|
.subscribe((msg) => {
|
||||||
|
this.notificationsService.info(null, msg, null, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
retrieveSubmission(submissionId): Observable<SubmissionObject> {
|
retrieveSubmission(submissionId): Observable<SubmissionObject> {
|
||||||
return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId)
|
return this.restService.getDataById(this.getSubmissionObjectLinkName(), submissionId)
|
||||||
@@ -219,6 +247,10 @@ export class SubmissionService {
|
|||||||
.map((submissionObjects: SubmissionObject[]) => submissionObjects[0]);
|
.map((submissionObjects: SubmissionObject[]) => submissionObjects[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setActiveSection(submissionId, sectionId) {
|
||||||
|
this.store.dispatch(new SetActiveSectionAction(submissionId, sectionId));
|
||||||
|
}
|
||||||
|
|
||||||
startAutoSave(submissionId) {
|
startAutoSave(submissionId) {
|
||||||
this.stopAutoSave();
|
this.stopAutoSave();
|
||||||
console.log('AUTOSAVE ON!!!');
|
console.log('AUTOSAVE ON!!!');
|
||||||
|
Reference in New Issue
Block a user