Skip to content

Commit

Permalink
Merged in DSC-544 (pull request DSpace#162)
Browse files Browse the repository at this point in the history
[DSC-544] Workflow item task not showing correction change request

Approved-by: Giuseppe Digilio
  • Loading branch information
Sufiyan Shaikh authored and atarix83 committed Apr 29, 2022
2 parents 6ecb52c + 443286f commit 2bd53dc
Show file tree
Hide file tree
Showing 15 changed files with 664 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* An interface to represent submission's correction section data.
*/
export interface WorkspaceitemSectionCorrectionObject {
metadata: WorkspaceitemSectionCorrectionMetadataObject[];
bitstream: WorkspaceitemSectionCorrectionBitstreamObject[];
}

export interface WorkspaceitemSectionCorrectionMetadataObject {
metadata: string;
oldValues: string[];
newValues: string[];
label: string;
}

export enum OperationType {
ADD = 'ADD',
REMOVE = 'REMOVE',
MODIFY = 'MODIFY'
}

export interface WorkspaceitemSectionCorrectionBitstreamObject {
filename: string;
operationType: OperationType;
metadata: WorkspaceitemSectionCorrectionMetadataObject[];
policies: WorkspaceitemSectionCorrectionBitstreamPolicyObject[];
}

export interface WorkspaceitemSectionCorrectionBitstreamPolicyObject {
oldValue: string;
newValue: string;
label: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { WorkspaceitemSectionLicenseObject } from './workspaceitem-section-licen
import { WorkspaceitemSectionUploadObject } from './workspaceitem-section-upload.model';
import { WorkspaceitemSectionCcLicenseObject } from './workspaceitem-section-cc-license.model';
import { WorkspaceitemSectionDetectDuplicateObject } from './workspaceitem-section-deduplication.model';
import { WorkspaceitemSectionCorrectionObject } from './workspaceitem-section-correction.model';

/**
* An interface to represent submission's section object.
Expand All @@ -23,4 +24,5 @@ export type WorkspaceitemSectionDataType
| WorkspaceitemSectionCcLicenseObject
| WorkspaceitemSectionAccessesObject
| WorkspaceitemSectionDetectDuplicateObject
| WorkspaceitemSectionCorrectionObject
| string;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div *ngIf="isCorrectionOfItem$ | async">
<span class="badge badge-light">{{'mydspace.results.is-correction' | translate}}</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { TranslateLoader, TranslateModule } from '@ngx-translate/core';

import { ItemCorrectionComponent } from './item-correction.component';
import { TranslateLoaderMock } from '../../../testing/translate-loader.mock';
import { RelationshipService } from '../../../../core/data/relationship.service';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { buildPaginatedList } from '../../../../core/data/paginated-list.model';
import { PageInfo } from '../../../../core/shared/page-info.model';
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
import { cold } from 'jasmine-marbles';

let component: ItemCorrectionComponent;
let fixture: ComponentFixture<ItemCorrectionComponent>;
let relationshipService: any;
const mockRelationshipService = jasmine.createSpyObj('relationshipService',
{
getItemRelationshipsByLabel: jasmine.createSpy('getItemRelationshipsByLabel')
}
);

const relationship = Object.assign(new Relationship(), {
_links: {
self: {
href: 'dspacerest/2'
}
},
id: '1',
uuid: '1',
leftId: 'author1',
rightId: 'publication',
});

const relationshipPaginatedList = buildPaginatedList(new PageInfo(), [relationship]);
const relationshipPaginatedListEmpty = buildPaginatedList(new PageInfo(), [relationship]);
const relationshipPaginatedListRD = createSuccessfulRemoteDataObject(relationshipPaginatedList);
const relationshipPaginatedListEmptyRD = createSuccessfulRemoteDataObject(relationshipPaginatedListEmpty);

describe('ItemCorrectionComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock
}
})
],
declarations: [ItemCorrectionComponent],
providers: [
{ provide: RelationshipService, useValue: mockRelationshipService },
],
schemas: [NO_ERRORS_SCHEMA]
}).overrideComponent(ItemCorrectionComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));

beforeEach(async(() => {
fixture = TestBed.createComponent(ItemCorrectionComponent);
component = fixture.componentInstance;
}));

beforeEach(() => {
relationshipService = TestBed.get(RelationshipService);

});

it('should show a badge when item is a correction', () => {
relationshipService.getItemRelationshipsByLabel.and.returnValue(cold('a', {
a: relationshipPaginatedListRD
}));
fixture.detectChanges();
const badge = fixture.debugElement.query(By.css('.text-muted'));

expect(badge).toBeDefined();
});

it('should not show a badge when item is not a correction', () => {
relationshipService.getItemRelationshipsByLabel.and.returnValue(cold('a', {
a: relationshipPaginatedListEmptyRD
}));
fixture.detectChanges();
const badge = fixture.debugElement.query(By.css('.text-muted'));

expect(badge).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Component, Input, OnInit } from '@angular/core';

import { Observable, of as observableOf } from 'rxjs';
import { catchError, map, startWith } from 'rxjs/operators';

import { Item } from '../../../../core/shared/item.model';
import { getFirstSucceededRemoteListPayload } from '../../../../core/shared/operators';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { RelationshipService } from '../../../../core/data/relationship.service';

/**
* This component represents a badge with correction item information.
*/
@Component({
selector: 'ds-item-correction',
styleUrls: ['./item-correction.component.scss'],
templateUrl: './item-correction.component.html'
})
export class ItemCorrectionComponent implements OnInit {

/**
* The target object
*/
@Input() item: Item;

/**
* A boolean representing if item is a correction of an existing one
*/
isCorrectionOfItem$: Observable<boolean>;

constructor(private relationshipService: RelationshipService) {
}
/**
* Check if item is a correction of an existing one
*/
ngOnInit(): void {
this.isCorrectionOfItem$ = this.relationshipService.getItemRelationshipsByLabel(
this.item,
'isCorrectionOfItem'
).pipe(
getFirstSucceededRemoteListPayload(),
map((list: Relationship[]) => list.length > 0),
startWith(false),
catchError(() => observableOf(false))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ <h3 [innerHTML]="item.firstMetadataValue('dc.title') || ('mydspace.results.no-ti

</div>
</ds-truncatable>
<ds-item-correction [item]="item"></ds-item-correction>
<ds-item-submitter *ngIf="showSubmitter" [object]="object.indexableObject"></ds-item-submitter>
</div>
2 changes: 2 additions & 0 deletions src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ import { ThemedSearchSectionComponent } from './explore/section-component/search
import { ThemedTextSectionComponent } from './explore/section-component/text-section/themed-text-section.component';
import { ThemedBrowseMostElementsComponent } from './browse-most-elements/themed-browse-most-elements.component';
import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
import { ItemCorrectionComponent } from './object-collection/shared/mydspace-item-correction/item-correction.component';
import { MetricsModule } from './metric/metrics.module';
import { SearchChartBarHorizontalComponent } from './search/search-charts/search-chart/search-chart-bar-horizontal/search-chart-bar-horizontal.component';

Expand Down Expand Up @@ -303,6 +304,7 @@ const COMPONENTS = [
ItemListPreviewComponent,
ThemedItemListPreviewComponent,
MyDSpaceItemStatusComponent,
ItemCorrectionComponent,
ItemSubmitterComponent,
ItemDetailPreviewComponent,
ItemDetailPreviewFieldComponent,
Expand Down
8 changes: 6 additions & 2 deletions src/app/submission/objects/submission-objects.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ export class SubmissionObjectEffects {
const selfLink = sectionDefinition._links.self.href || sectionDefinition._links.self;
const sectionId = selfLink.substr(selfLink.lastIndexOf('/') + 1);
const config = sectionDefinition._links.config ? (sectionDefinition._links.config.href || sectionDefinition._links.config) : '';
const enabled = (sectionDefinition.mandatory && sectionDefinition.sectionType !== SectionsType.DetectDuplicate) ||
(isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId));
const enabled = (sectionDefinition.mandatory && (sectionDefinition.sectionType !== SectionsType.DetectDuplicate &&
sectionDefinition.sectionType !== SectionsType.Correction)) ||
(isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId)
&& sectionDefinition.sectionType !== SectionsType.Correction) ||
(isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId)
&& sectionDefinition.sectionType === SectionsType.Correction && !((action.payload.sections[sectionId] as any).empty));
let sectionData;
if (sectionDefinition.sectionType !== SectionsType.SubmissionForm) {
sectionData = (isNotUndefined(action.payload.sections) && isNotUndefined(action.payload.sections[sectionId])) ? action.payload.sections[sectionId] : Object.create(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Component, Inject } from '@angular/core';

import { Observable, of as observableOf } from 'rxjs';

import { renderSectionFor } from '../sections-decorator';
import { SectionsType } from '../sections-type';
import { SectionModelComponent } from '../models/section.model';
import { SectionDataObject } from '../models/section-data.model';
import { SectionsService } from '../sections.service';
import { RoleType } from '../../../core/roles/role-types';
import {
OperationType,
WorkspaceitemSectionCorrectionBitstreamObject,
WorkspaceitemSectionCorrectionMetadataObject,
WorkspaceitemSectionCorrectionObject
} from '../../../core/submission/models/workspaceitem-section-correction.model';

@Component({
selector: 'ds-submission-correction',
templateUrl: './section-correction.component.html'
})
@renderSectionFor(SectionsType.Correction)
export class SubmissionSectionCorrectionComponent extends SectionModelComponent {

/**
* Contain the correction information regarding item's bitstream
*/
public correctionBitstreamData: WorkspaceitemSectionCorrectionBitstreamObject[];

/**
* Contain the correction information regarding item's metadata
*/
public correctionMetadataData: WorkspaceitemSectionCorrectionMetadataObject[];

public roleTypeEnum = RoleType;
public operationType = OperationType;

constructor(protected sectionService: SectionsService,
@Inject('collectionIdProvider') public injectedCollectionId: string,
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
@Inject('submissionIdProvider') public injectedSubmissionId: string) {
super(injectedCollectionId, injectedSectionData, injectedSubmissionId);
}

protected getSectionStatus(): Observable<boolean> {
return observableOf(true);
}

/**
* Retrieve correction metadata list
*/
getItemData(): WorkspaceitemSectionCorrectionMetadataObject[] {
const correctionObject: WorkspaceitemSectionCorrectionObject = this.sectionData.data as WorkspaceitemSectionCorrectionObject;
return correctionObject.metadata;
}

/**
* Retrieve correction bitstream list
*/
getFileData(): WorkspaceitemSectionCorrectionBitstreamObject[] {
const correctionObject: WorkspaceitemSectionCorrectionObject = this.sectionData.data as WorkspaceitemSectionCorrectionObject;
return [...correctionObject?.bitstream].sort((obj1: WorkspaceitemSectionCorrectionBitstreamObject, obj2: WorkspaceitemSectionCorrectionBitstreamObject) => {
return obj1.filename > obj2.filename ? 1 : -1;
}
);
}

getFileOperationLabel(operation: OperationType): string {
let label = '';
switch (operation) {
case OperationType.ADD:
label = 'submission.sections.correction.bitstream.operation.add';
break;
case OperationType.REMOVE:
label = 'submission.sections.correction.bitstream.operation.remove';
break;
case OperationType.MODIFY:
label = 'submission.sections.correction.bitstream.operation.modify';
break;
}

return label;
}

sortMetadataByLabel(metadata: WorkspaceitemSectionCorrectionMetadataObject[]): WorkspaceitemSectionCorrectionMetadataObject[] {
return metadata.sort((obj1: WorkspaceitemSectionCorrectionMetadataObject, obj2: WorkspaceitemSectionCorrectionMetadataObject) => {
return obj1.label > obj2.label ? 1 : -1;
});
}

showTable(): boolean {
return Object.values(this.sectionData.data).length > 0;
}

/* tslint:disable:no-empty */
protected onSectionDestroy() {
}

protected onSectionInit(): void {
this.correctionMetadataData = this.getItemData();
this.correctionBitstreamData = this.getFileData();
}

}

0 comments on commit 2bd53dc

Please sign in to comment.