Intermediate commit detect duplicate

This commit is contained in:
Giuseppe
2018-09-26 16:53:04 +02:00
parent b67984be8f
commit 618e689258
15 changed files with 277 additions and 191 deletions

View File

@@ -18,6 +18,8 @@ export class JsonPatchOperationPathCombiner {
constructor(rootElement, ...subRootElements: string[]) { constructor(rootElement, ...subRootElements: string[]) {
this._rootElement = rootElement; this._rootElement = rootElement;
this._subRootElement = subRootElements.join('/'); this._subRootElement = subRootElements.join('/');
console.log(subRootElements);
console.log(this._subRootElement);
} }
get rootElement(): string { get rootElement(): string {

View File

@@ -1,6 +1,6 @@
import { Item } from '../../shared/item.model'; import { Item } from '../../shared/item.model';
export interface WorkspaceitemSectionDetectDuplicateObject { export interface WorkspaceitemSectionDeduplicationObject {
matches: { matches: {
[itemId: string]: DetectDuplicateMatch; [itemId: string]: DetectDuplicateMatch;
}; };

View File

@@ -33,7 +33,7 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) if (isNotEmpty(data.payload)
&& isNotEmpty(data.payload._links) && isNotEmpty(data.payload._links)
&& (data.statusCode === '201' || data.statusCode === '200')) { && (data.statusCode === '201' || data.statusCode === '200' || data.statusCode === 'OK')) {
const dataDefinition = this.processResponse<NormalizedObject | ConfigObject, SubmissionResourceType>(data.payload, request.href); const dataDefinition = this.processResponse<NormalizedObject | ConfigObject, SubmissionResourceType>(data.payload, request.href);
return new SubmissionSuccessResponse(dataDefinition[Object.keys(dataDefinition)[0]], data.statusCode, this.processPageInfo(data.payload)); return new SubmissionSuccessResponse(dataDefinition[Object.keys(dataDefinition)[0]], data.statusCode, this.processPageInfo(data.payload));
} else if (isEmpty(data.payload) && data.statusCode === '204') { } else if (isEmpty(data.payload) && data.statusCode === '204') {

View File

@@ -71,6 +71,7 @@ import { DsDatePickerComponent } from './form/builder/ds-dynamic-form-ui/models/
import { DsDynamicLookupComponent } from './form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component'; import { DsDynamicLookupComponent } from './form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component';
import { MockAdminGuard } from './mocks/mock-admin-guard.service'; import { MockAdminGuard } from './mocks/mock-admin-guard.service';
import { AlertsComponent } from './alerts/alerts.component'; import { AlertsComponent } from './alerts/alerts.component';
import { ObjNgFor } from './utils/object-ngfor.pipe';
const MODULES = [ const MODULES = [
// Do NOT include UniversalModule, HttpModule, or JsonpModule here // Do NOT include UniversalModule, HttpModule, or JsonpModule here
@@ -98,7 +99,8 @@ const PIPES = [
FileSizePipe, FileSizePipe,
SafeUrlPipe, SafeUrlPipe,
TruncatePipe, TruncatePipe,
ConsolePipe ConsolePipe,
ObjNgFor
]; ];
const COMPONENTS = [ const COMPONENTS = [

View File

@@ -1,81 +0,0 @@
<ds-item-list-preview
[item]="item"
[object]="object"
></ds-item-list-preview>
<div *ngIf="isWorkFlow" class="mt-2">
<form>
<div class="form-group mb-2">
<label class="mb-1" for="submitterDecision"><strong> {{'submission.sections.detect-duplicate.submitter-decision' | translate}} </strong></label><br>
<span id="submitterDecision" class="badge badge-pill {{decisionLabelClass}}">
{{submitterDecision$ | async}}
</span>
</div>
<div class="form-group" *ngIf="submitterNote">
<label for="submitterNote"><strong>{{'submission.sections.detect-duplicate.submitter-note' | translate}}</strong></label>
<textarea class="form-control" id="submitterNote" rows="3" readonly>{{submitterNote}}</textarea>
</div>
</form>
</div>
<div class="mt-3 mb-2" *ngIf="!hasDecision">
<button type="button"
class="btn btn-warning"
ngbTooltip="{{'submission.sections.detect-duplicate.duplicate-help' | translate}}"
[disabled]="(processingVerify | async) || (processingReject | async)"
(click)="openModal(modal)">
<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 type="button"
class="btn btn-success"
ngbTooltip="{{'submission.sections.detect-duplicate.not-duplicate-help' | translate}}"
[disabled]="(processingReject | async) || (processingVerify | async)"
(click)="setAsNotDuplicate()">
<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>
</div>
<div class="mt-3 mb-2" *ngIf="hasDecision">
<button type="button"
class="btn btn-danger"
ngbTooltip="{{'submission.sections.detect-duplicate.clear-decision-help' | translate}}"
(click)="clearDecision()">
<span> {{'submission.sections.detect-duplicate.clear-decision' | translate}}</span>
</button>
</div>
<ng-template #modal let-c="close" let-d="dismiss">
<div class="modal-header">
<h4 class="modal-title">{{'submission.workflow.tasks.claimed.reject.reason.title' | translate}}</h4>
<button type="button"
class="close"
aria-label="Close"
(click)="d('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-info" role="alert">
{{'submission.sections.detect-duplicate.note-help' | translate}}
</div>
<form (ngSubmit)="setAsDuplicate();" [formGroup]="rejectForm" >
<textarea class="w-100"
formControlName="reason"
rows="4"
placeholder="{{'submission.sections.detect-duplicate.note-placeholder' | translate}}"></textarea>
<button id="btn-chat"
class="btn btn-danger btn-lg btn-block mt-3"
[disabled]="!rejectForm.valid"
type="submit">
<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)">{{'submission.sections.detect-duplicate.duplicate' | translate}}</span>
</button>
</form>
</div>
</ng-template>

View File

@@ -0,0 +1,51 @@
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
}
}

View File

@@ -3,48 +3,55 @@
[object]="object" [object]="object"
></ds-item-list-preview> ></ds-item-list-preview>
<div *ngIf="isWorkFlow" class="mt-2">
<form>
<div class="form-group mb-2">
<label class="mb-1" for="submitterDecision"><strong> {{'submission.sections.detect-duplicate.submitter-decision' | translate}} </strong></label><br>
<span id="submitterDecision" class="badge badge-pill {{decisionLabelClass}}">
{{submitterDecision$ | async}}
</span>
</div>
<div class="form-group" *ngIf="submitterNote">
<label for="submitterNote"><strong>{{'submission.sections.detect-duplicate.submitter-note' | translate}}</strong></label>
<textarea class="form-control" id="submitterNote" rows="3" readonly>{{submitterNote}}</textarea>
</div>
</form>
</div>
<div class="mt-3 mb-2" *ngIf="!hasDecision"> <!--<button (click)="toggleSubmitterDecision()"-->
<!--class="btn btn-link">-->
<!--<span *ngIf="isWorkFlow && !showSubmitterDecision"> <i class="fa fa-angle-double-down"></i> Show submitter decision</span>-->
<!--<span *ngIf="isWorkFlow && showSubmitterDecision"> <i class="fa fa-angle-double-up"></i> Hide submitter decision</span>-->
<!--</button>-->
<!--<div *ngIf="showSubmitterDecision">-->
<div>
<label><strong> {{submitterDecisionLabel | async}} </strong>
<span [ngClass]="{'label': true,
'label-warning': match.submitterDecision == 'verify',
'label-success': match.submitterDecision == 'reject',
'label-default': (match.submitterDecision == undefined || match.submitterDecision == null)}">
{{submitterDecisionTxt}}
</span>
</label>
</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="!hasDecision">
<button type="button" <button type="button"
class="btn btn-warning" class="btn btn-warning"
ngbTooltip="{{'submission.sections.detect-duplicate.duplicate-help' | translate}}" ngbTooltip="{{'submission.sections.deduplication.duplicated_help' | translate}}"
[disabled]="(processingVerify | async) || (processingReject | async)"
(click)="openModal(modal)"> (click)="openModal(modal)">
<span *ngIf="(processingVerify | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> <span> {{duplicatedBtnLabel | async}}</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.detect-duplicate.not-duplicate-help' | translate}}" ngbTooltip="{{'submission.sections.deduplication.not_duplicated_help' | translate}}"
[disabled]="(processingReject | async) || (processingVerify | async)"
(click)="setAsNotDuplicate()"> (click)="setAsNotDuplicate()">
<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>
<span> {{'submission.sections.deduplication.not_duplicated' | translate}}</span>
</button>
</div> </div>
<div class="mt-3 mb-2" *ngIf="hasDecision"> <div class="mb-3" *ngIf="hasDecision">
<button type="button" <button type="button"
class="btn btn-danger" class="btn btn-danger"
ngbTooltip="{{'submission.sections.detect-duplicate.clear-decision-help' | translate}}" ngbTooltip="{{'submission.sections.deduplication.clear_decision_help' | translate}}"
(click)="clearDecision()"> (click)="clearDecision()">
<span> {{'submission.sections.detect-duplicate.clear-decision' | translate}}</span> <span> {{'submission.sections.deduplication.clear_decision' | translate}}</span>
</button> </button>
</div> </div>
@@ -60,19 +67,18 @@
</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.detect-duplicate.note-help' | translate}} {{'submission.sections.deduplication.note_help' | translate}}
</div> </div>
<form (ngSubmit)="setAsDuplicate();" [formGroup]="rejectForm" > <form (ngSubmit)="setAsDuplicate();" [formGroup]="rejectForm" >
<textarea class="w-100" <textarea class="w-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 id="btn-chat"
class="btn btn-danger btn-lg btn-block mt-3" class="btn btn-danger btn-lg btn-block mt-3"
[disabled]="!rejectForm.valid" [disabled]="!rejectForm.valid"
type="submit"> type="submit">
<span *ngIf="(processingReject | async)"><i class='fa fa-circle-o-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}</span> <span>{{'submission.sections.deduplication.duplicated' | translate}}</span>
<span *ngIf="!(processingReject | async)">{{'submission.sections.detect-duplicate.duplicate' | translate}}</span>
</button> </button>
</form> </form>
</div> </div>

View File

@@ -4,7 +4,9 @@ import { DetectDuplicateMatch } from '../../../../core/submission/models/workspa
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 { DetectDuplicateService } from '../detect-duplicate.service'; import { Store } from '@ngrx/store';
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';
@@ -13,8 +15,9 @@ import { SubmissionScopeType } from '../../../../core/submission/submission-scop
import { DuplicateDecisionValue } from '../models/duplicate-decision-value'; import { DuplicateDecisionValue } from '../models/duplicate-decision-value';
import { DuplicateDecision } from '../models/duplicate-decision.model'; import { DuplicateDecision } from '../models/duplicate-decision.model';
import { DuplicateDecisionType } from '../models/duplicate-decision-type'; import { DuplicateDecisionType } from '../models/duplicate-decision-type';
import { SaveSubmissionSectionFormAction } from '../../../objects/submission-objects.actions';
import { match } from 'minimatch';
import { isNotEmpty } from '../../../../shared/empty.util'; import { isNotEmpty } from '../../../../shared/empty.util';
import { SectionsService } from '../../sections.service';
@Component({ @Component({
selector: 'ds-duplicate-match', selector: 'ds-duplicate-match',
@@ -33,8 +36,7 @@ export class DuplicateMatchComponent implements OnInit {
isWorkFlow = false; isWorkFlow = false;
showSubmitterDecision = false; showSubmitterDecision = false;
decisionType: DuplicateDecisionType; decisionType: DuplicateDecisionType;
submitterDecision$: Observable<string>; submitterDecisionTxt: string;
submitterNote: string;
hasDecision: boolean; hasDecision: boolean;
@@ -42,18 +44,16 @@ export class DuplicateMatchComponent implements OnInit {
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>;
constructor(private detectDuplicateService: DetectDuplicateService, duplicatedBtnLabel: Observable<string>;
private formBuilder: FormBuilder, submitterDecisionLabel: Observable<string>;
private modalService: NgbModal,
private operationsBuilder: JsonPatchOperationsBuilder, constructor(private deduplicationService: DeduplicationService,
private sectionService: SectionsService,
private submissionService: SubmissionService, private submissionService: SubmissionService,
private modalService: NgbModal,
private formBuilder: FormBuilder,
private store: Store<SubmissionState>,
protected operationsBuilder: JsonPatchOperationsBuilder,
private translate: TranslateService) { private translate: TranslateService) {
} }
@@ -72,55 +72,51 @@ export class DuplicateMatchComponent implements OnInit {
: this.match.submitterDecision !== null; : this.match.submitterDecision !== null;
if (this.match.submitterDecision) { if (this.match.submitterDecision) {
this.submitterDecision$ = (this.match.submitterDecision === DuplicateDecisionValue.Reject) ? if (this.match.submitterDecision === 'verify') {
this.translate.get('submission.sections.detect-duplicate.not-duplicate') : this.submitterDecisionTxt = 'It\'s a duplicate';
this.translate.get('submission.sections.detect-duplicate.duplicate'); } else {
this.decisionLabelClass = (this.match.submitterDecision === DuplicateDecisionValue.Reject) ? 'badge-success' : 'badge-warning'; this.submitterDecisionTxt = 'It\'s not a duplicate';
this.submitterNote = this.match.submitterNote; }
} else { } else {
this.submitterDecision$ = this.translate.get('submission.sections.detect-duplicate.no-decision'); this.submitterDecisionTxt = 'Not decided';
this.decisionLabelClass = 'badge-light';
} }
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionId); this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionId);
this.duplicateBtnLabel$ = this.isWorkFlow ? this.duplicatedBtnLabel = this.isWorkFlow ?
((this.match.submitterDecision === DuplicateDecisionValue.Verify) ? this.translate.get('submission.sections.deduplication.duplicated_ctrl')
this.translate.get('submission.sections.detect-duplicate.confirm-duplicate') : : this.translate.get('submission.sections.deduplication.duplicated');
this.translate.get('submission.sections.detect-duplicate.duplicate-ctrl'))
: this.translate.get('submission.sections.detect-duplicate.duplicate');
this.notDuplicateBtnLabel$ = (this.isWorkFlow && this.match.submitterDecision === DuplicateDecisionValue.Reject) ? this.submitterDecisionLabel = this.isWorkFlow ?
this.translate.get('submission.sections.detect-duplicate.confirm-not-duplicate') : this.translate.get('submission.sections.deduplication.submitter_decision')
this.translate.get('submission.sections.detect-duplicate.not-duplicate'); : this.translate.get('submission.sections.deduplication.your_decision');
} }
setAsDuplicate() { setAsDuplicate() {
this.processingVerify = Observable.of(true);
const decision = new DuplicateDecision( const decision = new DuplicateDecision(
DuplicateDecisionValue.Verify, DuplicateDecisionValue.Verify,
this.decisionType, this.decisionType,
this.rejectForm.get('reason').value); this.rejectForm.get('reason').value);
console.log('Setting item #' + this.item.uuid + ' as duplicated...');
this.dispatchAction(decision); this.dispatchAction(decision);
this.modalRef.dismiss(); this.modalRef.dismiss();
} }
setAsNotDuplicate() { setAsNotDuplicate() {
this.processingReject = Observable.of(true);
const decision = new DuplicateDecision( const decision = new DuplicateDecision(
DuplicateDecisionValue.Reject, DuplicateDecisionValue.Reject,
this.decisionType); this.decisionType);
console.log('Setting item #' + this.item.uuid + ' as not duplicated...');
this.dispatchAction(decision); this.dispatchAction(decision);
} }
clearDecision() { clearDecision() {
console.log('Clearing item #' + this.item.uuid + ' from previous decision...');
const decision = new DuplicateDecision( const decision = new DuplicateDecision(
DuplicateDecisionValue.Undo, DuplicateDecisionValue.Undo,
this.decisionType); this.decisionType);
console.log('Setting item #' + this.item.uuid + ' as not duplicated...');
this.dispatchAction(decision); this.dispatchAction(decision);
} }
@@ -132,15 +128,50 @@ export class DuplicateMatchComponent implements OnInit {
note: isNotEmpty(decision.note) ? decision.note : null note: isNotEmpty(decision.note) ? decision.note : null
}; };
// dispatch patch operation only when section is active this.operationsBuilder.add(this.pathCombiner.getPath(pathDecision), payload, false, true);
this.sectionService.isSectionActive(this.submissionId, this.sectionId) this.store.dispatch(new SaveSubmissionSectionFormAction(this.submissionId, this.sectionId));
.filter((isActive: boolean) => isActive) // Call workflow action
.take(1) // const decision = clear ? null : duplicate ? 'verify' : 'reject';
.subscribe(() => { // const pathDecision = this.isWorkFlow ? 'workflowDecision' : 'submitterDecision';
this.operationsBuilder.add(this.pathCombiner.getPath(pathDecision), payload, false, true); // this.operationsBuilder.add(this.pathCombiner.getPath(pathDecision), decision, false, true);
this.detectDuplicateService.saveDuplicateDecision(this.submissionId, this.sectionId) //
}); // if (!clear && duplicate) {
// 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) {

View File

@@ -0,0 +1,5 @@
export enum DuplicateDecisionType {
WORKSPACE = 'WORKSPACE',
WORKFLOW = 'WORKFLOW',
ADMIN = 'ADMIN'
}

View File

@@ -0,0 +1,5 @@
export enum DuplicateDecisionValue {
Reject = 'reject',
Verify = 'verify',
Undo = ''
}

View File

@@ -0,0 +1,57 @@
import { DuplicateDecisionType } from './duplicate-decision-type';
import { DuplicateDecisionValue } from './duplicate-decision-value';
import { isNotNull } from '../../../../shared/empty.util';
export class DuplicateDecision {
private _value: DuplicateDecisionValue;
private _type: DuplicateDecisionType;
private _note: string;
private _date: any;
public constructor(value = null, type = null, note = null) {
if (isNotNull(value)) {
this.value = value;
}
if (isNotNull(type)) {
this.type = type;
}
if (isNotNull(note)) {
this.note = note;
}
}
get value(): DuplicateDecisionValue {
return this._value;
}
set value(value: DuplicateDecisionValue) {
this._value = value;
}
get type(): DuplicateDecisionType {
return this._type;
}
set type(value: DuplicateDecisionType) {
this._type = value;
}
get date(): any {
return this._date;
}
set date(value: any) {
this._date = value;
}
get note(): string {
return this._note;
}
set note(value: string) {
this._note = value;
}
}

View File

@@ -1,11 +1,18 @@
<ds-loading *ngIf="isLoading" message="Loading..."></ds-loading> <ds-loading *ngIf="isLoading" message="Loading..."></ds-loading>
<ng-container *ngIf="(totalMatch$ | async) === 0"> <ng-container *ngIf="(sectionData$ | async)?.matches.length == 0">
<ds-alert [type]="AlertTypeEnum.Info" [content]="('submission.sections.detect-duplicate.disclaimer-no-match' | translate)"></ds-alert> <div class="row">
<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 *ngIf="(totalMatch$ | async) > 0"> <ng-container
<ds-alert [type]="AlertTypeEnum.Warning" [content]="(disclaimer | async)"></ds-alert> *ngIf="(totalMatch$ | async) > 0">
<div class="alert alert-danger" role="alert">
{{ disclaimer | async }}
</div>
<ds-pagination <ds-pagination
[paginationOptions]="config" [paginationOptions]="config"

View File

@@ -1,19 +1,18 @@
import { SectionsType } from '../sections-type'; import { SectionsType } from '../sections-type';
import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, Inject, 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',
@@ -23,8 +22,7 @@ import { hasValue } from '../../../shared/empty.util';
}) })
@renderSectionFor(SectionsType.DetectDuplicate) @renderSectionFor(SectionsType.DetectDuplicate)
export class DetectDuplicateSectionComponent extends SectionModelComponent implements OnDestroy, OnInit { export class DetectDuplicateSectionComponent extends SectionModelComponent implements OnInit {
public AlertTypeEnum = AlertType;
public isLoading = true; public isLoading = true;
public sectionData$: Observable<any>; public sectionData$: Observable<any>;
public matches = {}; public matches = {};
@@ -35,11 +33,9 @@ export class DetectDuplicateSectionComponent extends SectionModelComponent imple
isWorkFlow = false; isWorkFlow = false;
disclaimer: Observable<string>; disclaimer: Observable<string>;
sub: Subscription;
constructor(private detectDuplicateService: DetectDuplicateService, constructor(protected store: Store<SubmissionState>,
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,
@@ -53,34 +49,28 @@ export class DetectDuplicateSectionComponent extends SectionModelComponent imple
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.sectionData$ = this.detectDuplicateService.getDuplicateMatches(this.submissionId, this.sectionData.id); this.sectionData$ = this.store.select(submissionSectionDataFromIdSelector(this.submissionId, this.sectionData.id))
.filter((sd) => isNotEmpty(sd))
.startWith({matches: {}})
.distinctUntilChanged();
this.totalMatch$ = this.detectDuplicateService.getDuplicateTotalMatches(this.submissionId, this.sectionData.id); this.totalMatch$ = this.store.select(submissionSectionDataFromIdSelector(this.submissionId, this.sectionData.id))
.filter((sd) => isNotEmpty(sd))
.startWith({matches: {}})
.map((sd) => Object.keys(sd.matches).length)
.distinctUntilChanged();
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.detect-duplicate.disclaimer-ctrl') this.translate.get('submission.sections.deduplication.disclaimer_ctrl')
: this.translate.get('submission.sections.detect-duplicate.disclaimer'); : this.translate.get('submission.sections.deduplication.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) {
this.config.currentPage = page; this.config.currentPage = page;
} }
ngOnDestroy(): void {
if (hasValue(this.sub)) {
this.sub.unsubscribe();
}
}
} }

View File

@@ -5,5 +5,5 @@ export enum SectionsType {
CcLicense = 'cclicense', CcLicense = 'cclicense',
collection = 'collection', collection = 'collection',
Recycle = 'recycle', Recycle = 'recycle',
Deduplication = 'deduplication' DetectDuplicate = 'detect-duplicate'
} }

View File

@@ -86,8 +86,19 @@ export class UploadSectionComponent extends SectionModelComponent implements OnI
.subscribe((collectionData) => { .subscribe((collectionData) => {
this.collectionName = collectionData.payload.name; this.collectionName = collectionData.payload.name;
console.log(collectionData.payload.defaultAccessConditions);
const defaultAccessConditions$ = collectionData.payload.defaultAccessConditions
|| Observable.of(
new RemoteData(
false,
false,
true,
undefined,
undefined
));
// Default Access Conditions // Default Access Conditions
this.subs.push(collectionData.payload.defaultAccessConditions this.subs.push(defaultAccessConditions$
.filter((accessConditions) => isNotUndefined((accessConditions.payload))) .filter((accessConditions) => isNotUndefined((accessConditions.payload)))
.take(1) .take(1)
.subscribe((defaultAccessConditions) => { .subscribe((defaultAccessConditions) => {