Skip to content

Commit 7b19047

Browse files
113169: Moved the MetadataValue#isVirtual & MetadataValue#virtualValue to the new MetadataService
1 parent 179e7e0 commit 7b19047

11 files changed

Lines changed: 101 additions & 63 deletions

src/app/core/data/relationship-data.service.spec.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ import { FindListOptions } from './find-list-options.model';
2323
import { testSearchDataImplementation } from './base/search-data.spec';
2424
import { MetadataValue } from '../shared/metadata.models';
2525
import { MetadataRepresentationType } from '../shared/metadata-representation/metadata-representation.model';
26+
import { TestBed } from '@angular/core/testing';
27+
import { ItemDataService } from './item-data.service';
28+
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
29+
import { HALEndpointService } from '../shared/hal-endpoint.service';
30+
import { PAGINATED_RELATIONS_TO_ITEMS_OPERATOR } from '../../item-page/simple/item-types/shared/item-relationships-utils';
31+
import { Store } from '@ngrx/store';
32+
import { provideMockStore } from '@ngrx/store/testing';
2633

2734
describe('RelationshipDataService', () => {
2835
let service: RelationshipDataService;
@@ -128,18 +135,6 @@ describe('RelationshipDataService', () => {
128135
findByHref: createSuccessfulRemoteDataObject$(relatedItems[0])
129136
});
130137

131-
function initTestService() {
132-
return new RelationshipDataService(
133-
requestService,
134-
rdbService,
135-
halService,
136-
objectCache,
137-
itemService,
138-
null,
139-
jasmine.createSpy('paginatedRelationsToItems').and.returnValue((v) => v),
140-
);
141-
}
142-
143138
const getRequestEntry$ = (successful: boolean) => {
144139
return observableOf({
145140
response: { isSuccessful: successful, payload: relationships } as any
@@ -148,11 +143,25 @@ describe('RelationshipDataService', () => {
148143

149144
beforeEach(() => {
150145
requestService = getMockRequestService(getRequestEntry$(true));
151-
service = initTestService();
146+
147+
TestBed.configureTestingModule({
148+
providers: [
149+
{ provide: RequestService, useValue: requestService },
150+
{ provide: RemoteDataBuildService, useValue: rdbService },
151+
{ provide: HALEndpointService, useValue: halService },
152+
{ provide: ObjectCacheService, useValue: objectCache },
153+
{ provide: ItemDataService, useValue: itemService },
154+
{ provide: RequestService, useValue: requestService },
155+
{ provide: PAGINATED_RELATIONS_TO_ITEMS_OPERATOR, useValue: jasmine.createSpy('paginatedRelationsToItems').and.returnValue((v) => v) },
156+
{ provide: Store, useValue: provideMockStore() },
157+
RelationshipDataService,
158+
],
159+
});
160+
service = TestBed.inject(RelationshipDataService);
152161
});
153162

154163
describe('composition', () => {
155-
const initService = () => new RelationshipDataService(null, null, null, null, null, null, null);
164+
const initService = () => new RelationshipDataService(null, null, null, null, null, null, null, null);
156165

157166
testSearchDataImplementation(initService);
158167
});

src/app/core/data/relationship-data.service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { MetadataRepresentation } from '../shared/metadata-representation/metada
5151
import { MetadatumRepresentation } from '../shared/metadata-representation/metadatum/metadatum-representation.model';
5252
import { ItemMetadataRepresentation } from '../shared/metadata-representation/item/item-metadata-representation.model';
5353
import { DSpaceObject } from '../shared/dspace-object.model';
54+
import { MetadataService } from '../metadata/metadata.service';
5455

5556
const relationshipListsStateSelector = (state: AppState) => state.relationshipLists;
5657

@@ -89,6 +90,7 @@ export class RelationshipDataService extends IdentifiableDataService<Relationshi
8990
protected rdbService: RemoteDataBuildService,
9091
protected halService: HALEndpointService,
9192
protected objectCache: ObjectCacheService,
93+
protected metadataService: MetadataService,
9294
protected itemService: ItemDataService,
9395
protected appStore: Store<AppState>,
9496
@Inject(PAGINATED_RELATIONS_TO_ITEMS_OPERATOR) private paginatedRelationsToItems: (thisId: string) => (source: Observable<RemoteData<PaginatedList<Relationship>>>) => Observable<RemoteData<PaginatedList<Item>>>,
@@ -563,8 +565,8 @@ export class RelationshipDataService extends IdentifiableDataService<Relationshi
563565
* @param itemType The type of item this metadata value represents (will only be used when no related item can be found, as a fallback)
564566
*/
565567
resolveMetadataRepresentation(metadatum: MetadataValue, parentItem: DSpaceObject, itemType: string): Observable<MetadataRepresentation> {
566-
if (metadatum.isVirtual) {
567-
return this.findById(metadatum.virtualValue, true, false, followLink('leftItem'), followLink('rightItem')).pipe(
568+
if (this.metadataService.isVirtual(metadatum)) {
569+
return this.findById(this.metadataService.virtualValue(metadatum), true, false, followLink('leftItem'), followLink('rightItem')).pipe(
568570
getFirstSucceededRemoteData(),
569571
switchMap((relRD: RemoteData<Relationship>) =>
570572
observableCombineLatest(relRD.payload.leftItem, relRD.payload.rightItem).pipe(
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { MetadataService } from './metadata.service';
4+
5+
describe('MetadataService', () => {
6+
let service: MetadataService;
7+
8+
beforeEach(() => {
9+
TestBed.configureTestingModule({});
10+
service = TestBed.inject(MetadataService);
11+
});
12+
13+
it('should be created', () => {
14+
expect(service).toBeTruthy();
15+
});
16+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Injectable } from '@angular/core';
2+
import { hasValue } from '../../shared/empty.util';
3+
import { MetadataValue, VIRTUAL_METADATA_PREFIX } from '../shared/metadata.models';
4+
5+
/**
6+
* Service for working with DSpace object metadata.
7+
*/
8+
@Injectable({
9+
providedIn: 'root',
10+
})
11+
export class MetadataService {
12+
13+
/**
14+
* Returns true if this Metadata authority key starts with 'virtual::'
15+
*/
16+
public isVirtual(metadataValue: MetadataValue | undefined): boolean {
17+
return hasValue(metadataValue?.authority) && metadataValue.authority.startsWith(VIRTUAL_METADATA_PREFIX);
18+
}
19+
20+
/**
21+
* If this is a virtual Metadata, it returns everything in the authority key after 'virtual::'.
22+
*
23+
* Returns undefined otherwise.
24+
*/
25+
public virtualValue(metadataValue: MetadataValue | undefined): string {
26+
if (this.isVirtual) {
27+
return metadataValue.authority.substring(metadataValue.authority.indexOf(VIRTUAL_METADATA_PREFIX) + VIRTUAL_METADATA_PREFIX.length);
28+
} else {
29+
return undefined;
30+
}
31+
}
32+
33+
}

src/app/core/shared/metadata.models.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* eslint-disable max-classes-per-file */
22
import { v4 as uuidv4 } from 'uuid';
33
import { autoserialize, Serialize, Deserialize } from 'cerialize';
4-
import { hasValue } from '../../shared/empty.util';
54

65
export const VIRTUAL_METADATA_PREFIX = 'virtual::';
76

@@ -53,24 +52,6 @@ export class MetadataValue implements MetadataValueInterface {
5352
@autoserialize
5453
confidence: number;
5554

56-
/**
57-
* Returns true if this Metadatum's authority key starts with 'virtual::'
58-
*/
59-
get isVirtual(): boolean {
60-
return hasValue(this.authority) && this.authority.startsWith(VIRTUAL_METADATA_PREFIX);
61-
}
62-
63-
/**
64-
* If this is a virtual Metadatum, it returns everything in the authority key after 'virtual::'.
65-
* Returns undefined otherwise.
66-
*/
67-
get virtualValue(): string {
68-
if (this.isVirtual) {
69-
return this.authority.substring(this.authority.indexOf(VIRTUAL_METADATA_PREFIX) + VIRTUAL_METADATA_PREFIX.length);
70-
} else {
71-
return undefined;
72-
}
73-
}
7455
}
7556

7657
/** Constraints for matching metadata values. */

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="d-flex flex-row ds-value-row" *ngVar="mdValue.newValue.isVirtual as isVirtual" role="row"
1+
<div class="d-flex flex-row ds-value-row" *ngVar="metadataService.isVirtual(mdValue.newValue) as isVirtual" role="row"
22
cdkDrag (cdkDragStarted)="dragging.emit(true)" (cdkDragEnded)="dragging.emit(false)"
33
[ngClass]="{ 'ds-warning': mdValue.reordered || mdValue.change === DsoEditMetadataChangeTypeEnum.UPDATE, 'ds-danger': mdValue.change === DsoEditMetadataChangeTypeEnum.REMOVE, 'ds-success': mdValue.change === DsoEditMetadataChangeTypeEnum.ADD, 'h-100': isOnlyValue }">
44
<div class="flex-grow-1 ds-flex-cell ds-value-cell d-flex align-items-center" *ngVar="(mdRepresentation$ | async) as mdRepresentation" role="cell">

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { map } from 'rxjs/operators';
1212
import { getItemPageRoute } from '../../../item-page/item-page-routing-paths';
1313
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
1414
import { EMPTY } from 'rxjs/internal/observable/empty';
15+
import { MetadataService } from '../../../core/metadata/metadata.service';
1516

1617
@Component({
1718
selector: 'ds-dso-edit-metadata-value',
@@ -97,8 +98,11 @@ export class DsoEditMetadataValueComponent implements OnInit {
9798
*/
9899
mdRepresentationName$: Observable<string | null>;
99100

100-
constructor(protected relationshipService: RelationshipDataService,
101-
protected dsoNameService: DSONameService) {
101+
constructor(
102+
protected relationshipService: RelationshipDataService,
103+
protected dsoNameService: DSONameService,
104+
protected metadataService: MetadataService,
105+
) {
102106
}
103107

104108
ngOnInit(): void {
@@ -109,7 +113,7 @@ export class DsoEditMetadataValueComponent implements OnInit {
109113
* Initialise potential properties of a virtual metadata value
110114
*/
111115
initVirtualProperties(): void {
112-
this.mdRepresentation$ = this.mdValue.newValue.isVirtual ?
116+
this.mdRepresentation$ = this.metadataService.isVirtual(this.mdValue.newValue) ?
113117
this.relationshipService.resolveMetadataRepresentation(this.mdValue.newValue, this.dso, 'Item')
114118
.pipe(
115119
map((mdRepresentation: MetadataRepresentation) =>

src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '../../../core/shared/metadata-representation/metadatum/metadatum-representation.model';
1616
import { BrowseService } from '../../../core/browse/browse.service';
1717
import { BrowseDefinitionDataService } from '../../../core/browse/browse-definition-data.service';
18+
import { MetadataService } from '../../../core/metadata/metadata.service';
1819

1920
@Component({
2021
selector: 'ds-metadata-representation-list',
@@ -62,6 +63,7 @@ export class MetadataRepresentationListComponent extends AbstractIncrementalList
6263
constructor(
6364
public relationshipService: RelationshipDataService,
6465
protected browseDefinitionDataService: BrowseDefinitionDataService,
66+
protected metadataService: MetadataService,
6567
) {
6668
super();
6769
}
@@ -87,7 +89,7 @@ export class MetadataRepresentationListComponent extends AbstractIncrementalList
8789
.slice((this.objects.length * this.incrementBy), (this.objects.length * this.incrementBy) + this.incrementBy)
8890
.map((metadatum: any) => Object.assign(new MetadataValue(), metadatum))
8991
.map((metadatum: MetadataValue) => {
90-
if (metadatum.isVirtual) {
92+
if (this.metadataService.isVirtual(metadatum)) {
9193
return this.relationshipService.resolveMetadataRepresentation(metadatum, this.parentItem, this.itemType);
9294
} else {
9395
// Check for a configured browse link and return a standard metadata representation

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<ng-container *ngTemplateOutlet="startTemplate?.templateRef; context: { $implicit: model };"></ng-container>
1111
<!-- Should be *ngIf instead of class d-none, but that breaks the #componentViewContainer reference-->
1212
<div [ngClass]="{'form-row': model.hasLanguages || isRelationship,
13-
'd-none': value?.isVirtual && (model.hasSelectableMetadata || context?.index > 0)}">
13+
'd-none': this.metadataService.isVirtual(value) && (model.hasSelectableMetadata || context?.index > 0)}">
1414
<div [ngClass]="getClass('grid', 'control')">
1515
<div>
1616
<ng-container #componentViewContainer></ng-container>
@@ -51,7 +51,7 @@
5151
</div>
5252
</div>
5353
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
54-
<ng-container *ngIf="value?.isVirtual">
54+
<ng-container *ngIf="this.metadataService.isVirtual(value)">
5555
<ds-existing-metadata-list-element
5656
*ngIf="model.hasSelectableMetadata"
5757
[reoRel]="relationshipValue$ | async"

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.spec.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,12 @@ import { DsDatePickerInlineComponent } from './models/date-picker-inline/dynamic
6868
import { DsDynamicTypeBindRelationService } from './ds-dynamic-type-bind-relation.service';
6969
import { RelationshipDataService } from '../../../../core/data/relationship-data.service';
7070
import { SelectableListService } from '../../../object-list/selectable-list/selectable-list.service';
71-
import { ItemDataService } from '../../../../core/data/item-data.service';
7271
import { Store } from '@ngrx/store';
7372
import { SubmissionObjectDataService } from '../../../../core/submission/submission-object-data.service';
7473
import { Item } from '../../../../core/shared/item.model';
7574
import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model';
7675
import { of as observableOf } from 'rxjs';
7776
import { createSuccessfulRemoteDataObject } from '../../../remote-data.utils';
78-
import { FormService } from '../../form.service';
7977
import { SubmissionService } from '../../../../submission/submission.service';
8078
import { FormBuilderService } from '../form-builder.service';
8179
import { NgxMaskModule } from 'ngx-mask';
@@ -221,11 +219,9 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
221219
{ provide: DsDynamicTypeBindRelationService, useValue: getMockDsDynamicTypeBindRelationService() },
222220
{ provide: RelationshipDataService, useValue: {} },
223221
{ provide: SelectableListService, useValue: {} },
224-
{ provide: ItemDataService, useValue: {} },
225222
{ provide: Store, useValue: {} },
226223
{ provide: RelationshipDataService, useValue: {} },
227224
{ provide: SelectableListService, useValue: {} },
228-
{ provide: FormService, useValue: {} },
229225
{ provide: FormBuilderService, useValue: {} },
230226
{ provide: SubmissionService, useValue: {} },
231227
{
@@ -234,7 +230,6 @@ describe('DsDynamicFormControlContainerComponent test suite', () => {
234230
findById: () => observableOf(createSuccessfulRemoteDataObject(testWSI))
235231
}
236232
},
237-
{ provide: NgZone, useValue: new NgZone({}) },
238233
{ provide: APP_CONFIG, useValue: environment }
239234
],
240235
schemas: [CUSTOM_ELEMENTS_SCHEMA]

0 commit comments

Comments
 (0)