diff --git a/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts b/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts index 9f120a87dd..228b52d7c7 100644 --- a/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts +++ b/src/app/+item-page/simple/item-types/shared/item-relationships-utils.ts @@ -117,9 +117,8 @@ export const getRelatedItemsByTypeLabel = (thisId: string, label: string) => * @param parentId The id of the parent item * @param itemType The type of relation this list resembles (for creating representations) * @param metadata The list of original Metadatum objects - * @param ids The ItemDataService to use for fetching Items from the Rest API */ -export const relationsToRepresentations = (parentId: string, itemType: string, metadata: MetadataValue[], ids: ItemDataService) => +export const relationsToRepresentations = (parentId: string, itemType: string, metadata: MetadataValue[]) => (source: Observable): Observable => source.pipe( flatMap((rels: Relationship[]) => @@ -139,7 +138,7 @@ export const relationsToRepresentations = (parentId: string, itemType: string, m return leftItem.payload; } }), - map((item: Item) => Object.assign(new ItemMetadataRepresentation(), item)) + map((item: Item) => Object.assign(new ItemMetadataRepresentation(metadatum), item)) ); } } else { diff --git a/src/app/+item-page/simple/item-types/shared/item.component.spec.ts b/src/app/+item-page/simple/item-types/shared/item.component.spec.ts index 3f525e6a25..4414d9a713 100644 --- a/src/app/+item-page/simple/item-types/shared/item.component.spec.ts +++ b/src/app/+item-page/simple/item-types/shared/item.component.spec.ts @@ -413,7 +413,7 @@ describe('ItemComponent', () => { representations.subscribe((reps: MetadataRepresentation[]) => { expect(reps[0].getValue()).toEqual('First value'); expect(reps[1].getValue()).toEqual('Second value'); - expect(reps[2].getValue()).toEqual('related item'); + expect(reps[2].getValue()).toEqual('Third value'); expect(reps[3].getValue()).toEqual('Fourth value'); }); }); diff --git a/src/app/+item-page/simple/item-types/shared/item.component.ts b/src/app/+item-page/simple/item-types/shared/item.component.ts index 556496fe49..297a333eeb 100644 --- a/src/app/+item-page/simple/item-types/shared/item.component.ts +++ b/src/app/+item-page/simple/item-types/shared/item.component.ts @@ -1,7 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; import { Observable , zip as observableZip, combineLatest as observableCombineLatest } from 'rxjs'; import { distinctUntilChanged, filter, flatMap, map } from 'rxjs/operators'; -import { ItemDataService } from '../../../../core/data/item-data.service'; import { PaginatedList } from '../../../../core/data/paginated-list'; import { RemoteData } from '../../../../core/data/remote-data'; import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model'; @@ -10,49 +9,7 @@ import { Item } from '../../../../core/shared/item.model'; import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators'; import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component'; import { MetadataRepresentation } from '../../../../core/shared/metadata-representation/metadata-representation.model'; -import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; -import { MetadatumRepresentation } from '../../../../core/shared/metadata-representation/metadatum/metadatum-representation.model'; -import { of } from 'rxjs/internal/observable/of'; -import { MetadataValue } from '../../../../core/shared/metadata.models'; -import { compareArraysUsingIds } from './item-relationships-utils'; - -/** - * Operator for turning a list of relationships into a list of metadatarepresentations given the original metadata - * @param thisId The id of the parent item - * @param itemType The type of relation this list resembles (for creating representations) - * @param metadata The list of original Metadatum objects - */ -export const relationsToRepresentations = (thisId: string, itemType: string, metadata: MetadataValue[]) => - (source: Observable): Observable => - source.pipe( - flatMap((rels: Relationship[]) => - observableZip( - ...metadata - .map((metadatum: any) => Object.assign(new MetadataValue(), metadatum)) - .map((metadatum: MetadataValue) => { - if (metadatum.isVirtual) { - const matchingRels = rels.filter((rel: Relationship) => ('' + rel.id) === metadatum.virtualValue); - if (matchingRels.length > 0) { - const matchingRel = matchingRels[0]; - return observableCombineLatest(matchingRel.leftItem, matchingRel.rightItem).pipe( - filter(([leftItem, rightItem]) => leftItem.hasSucceeded && rightItem.hasSucceeded), - map(([leftItem, rightItem]) => { - if (leftItem.payload.id === thisId) { - return rightItem.payload; - } else if (rightItem.payload.id === thisId) { - return leftItem.payload; - } - }), - map((item: Item) => Object.assign(new ItemMetadataRepresentation(), item)) - ); - } - } else { - return of(Object.assign(new MetadatumRepresentation(itemType), metadatum)); - } - }) - ) - ) - ); +import { compareArraysUsingIds, relationsToRepresentations } from './item-relationships-utils'; @Component({ selector: 'ds-item', diff --git a/src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.spec.ts b/src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.spec.ts index f02625e8c7..da2af9f2c1 100644 --- a/src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.spec.ts +++ b/src/app/+item-page/simple/metadata-representation-list/metadata-representation-list.component.spec.ts @@ -7,7 +7,7 @@ import { ItemMetadataRepresentation } from '../../../core/shared/metadata-repres const itemType = 'type'; const metadataRepresentation1 = new MetadatumRepresentation(itemType); -const metadataRepresentation2 = new ItemMetadataRepresentation(); +const metadataRepresentation2 = new ItemMetadataRepresentation(Object.assign({})); const representations = [metadataRepresentation1, metadataRepresentation2]; describe('MetadataRepresentationListComponent', () => { diff --git a/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.spec.ts b/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.spec.ts index f31f8617ad..791fc43fbe 100644 --- a/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.spec.ts +++ b/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.spec.ts @@ -1,21 +1,27 @@ import { MetadataRepresentationType } from '../metadata-representation.model'; -import { ItemMetadataRepresentation, ItemTypeToValue } from './item-metadata-representation.model'; +import { ItemMetadataRepresentation } from './item-metadata-representation.model'; import { Item } from '../../item.model'; -import { MetadataMap, MetadataValue } from '../../metadata.models'; +import { MetadataValue } from '../../metadata.models'; describe('ItemMetadataRepresentation', () => { const valuePrefix = 'Test value for '; const item = new Item(); + const itemType = 'Item Type'; let itemMetadataRepresentation: ItemMetadataRepresentation; - const metadataMap = new MetadataMap(); - for (const key of Object.keys(ItemTypeToValue)) { - metadataMap[ItemTypeToValue[key]] = [Object.assign(new MetadataValue(), { - value: `${valuePrefix}${ItemTypeToValue[key]}` - })]; - } - item.metadata = metadataMap; + item.metadata = { + 'dc.title': [ + { + value: `${valuePrefix}dc.title` + } + ] as MetadataValue[], + 'dc.contributor.author': [ + { + value: `${valuePrefix}dc.contributor.author` + } + ] as MetadataValue[] + }; - for (const itemType of Object.keys(ItemTypeToValue)) { + for (const metadataField of Object.keys(item.metadata)) { describe(`when creating an ItemMetadataRepresentation`, () => { beforeEach(() => { item.metadata['relationship.type'] = [ @@ -23,8 +29,7 @@ describe('ItemMetadataRepresentation', () => { value: itemType }) ]; - - itemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(), item); + itemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(item.metadata[metadataField][0]), item); }); it('should have a representation type of item', () => { @@ -32,7 +37,7 @@ describe('ItemMetadataRepresentation', () => { }); it('should return the correct value when calling getValue', () => { - expect(itemMetadataRepresentation.getValue()).toEqual(`${valuePrefix}${ItemTypeToValue[itemType]}`); + expect(itemMetadataRepresentation.getValue()).toEqual(`${valuePrefix}${metadataField}`); }); it('should return the correct item type', () => { diff --git a/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.ts b/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.ts index 7ec1445613..b688673b65 100644 --- a/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.ts +++ b/src/app/core/shared/metadata-representation/item/item-metadata-representation.model.ts @@ -1,21 +1,22 @@ import { Item } from '../../item.model'; import { MetadataRepresentation, MetadataRepresentationType } from '../metadata-representation.model'; -import { hasValue } from '../../../../shared/empty.util'; - -/** - * An object to convert item types into the metadata field it should render for the item's value - */ -export const ItemTypeToValue = { - Default: 'dc.title', - Person: 'dc.contributor.author', - OrgUnit: 'dc.title' -}; +import { MetadataValue } from '../../metadata.models'; /** * This class determines which fields to use when rendering an Item as a metadata value. */ export class ItemMetadataRepresentation extends Item implements MetadataRepresentation { + /** + * The virtual metadata value representing this item + */ + virtualMetadata: MetadataValue; + + constructor(virtualMetadata: MetadataValue) { + super(); + this.virtualMetadata = virtualMetadata; + } + /** * The type of item this item can be represented as */ @@ -34,13 +35,7 @@ export class ItemMetadataRepresentation extends Item implements MetadataRepresen * Get the value to display, depending on the itemType */ getValue(): string { - let metadata; - if (hasValue(ItemTypeToValue[this.itemType])) { - metadata = ItemTypeToValue[this.itemType]; - } else { - metadata = ItemTypeToValue.Default; - } - return this.firstMetadataValue(metadata); + return this.virtualMetadata.value; } } diff --git a/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.html b/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.html index ea429e87c6..0977413722 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.html +++ b/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.html @@ -1,13 +1,13 @@ - - + - - + + diff --git a/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.ts index d59e5c6cc3..21d0d9f86b 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/orgunit/orgunit-metadata-list-element.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { MetadataRepresentationType } from '../../../../core/shared/metadata-representation/metadata-representation.model'; import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator'; -import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component'; +import { ItemMetadataRepresentationListElementComponent } from '../../../../shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; @rendersItemType('OrgUnit', ItemViewMode.Element, MetadataRepresentationType.Item) @Component({ @@ -11,5 +11,5 @@ import { TypedItemSearchResultListElementComponent } from '../../../../shared/ob /** * The component for displaying a list element for an item of the type OrgUnit */ -export class OrgUnitMetadataListElementComponent extends TypedItemSearchResultListElementComponent { +export class OrgUnitMetadataListElementComponent extends ItemMetadataRepresentationListElementComponent { } diff --git a/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.html b/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.html index 1125c2fb9b..69cf463b3f 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.html +++ b/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.html @@ -1,15 +1,15 @@ - - + - - + + diff --git a/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.ts index b036768d0a..35fbcd1173 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/person/person-metadata-list-element.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator'; import { MetadataRepresentationType } from '../../../../core/shared/metadata-representation/metadata-representation.model'; -import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component'; +import { ItemMetadataRepresentationListElementComponent } from '../../../../shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; @rendersItemType('Person', ItemViewMode.Element, MetadataRepresentationType.Item) @Component({ @@ -11,5 +11,5 @@ import { TypedItemSearchResultListElementComponent } from '../../../../shared/ob /** * The component for displaying a list element for an item of the type Person */ -export class PersonMetadataListElementComponent extends TypedItemSearchResultListElementComponent { +export class PersonMetadataListElementComponent extends ItemMetadataRepresentationListElementComponent { } diff --git a/src/app/shared/items/switcher/item-type-switcher.component.spec.ts b/src/app/shared/items/switcher/item-type-switcher.component.spec.ts index 76389201c5..1c1612744a 100644 --- a/src/app/shared/items/switcher/item-type-switcher.component.spec.ts +++ b/src/app/shared/items/switcher/item-type-switcher.component.spec.ts @@ -28,7 +28,7 @@ const mockItem: Item = Object.assign(new Item(), { ] } }); -const mockItemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(), mockItem); +const mockItemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(Object.assign({})), mockItem); let viewMode = ItemViewMode.Full; describe('ItemTypeSwitcherComponent', () => { diff --git a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts index 5ffa068951..269207bef8 100644 --- a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts +++ b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts @@ -5,7 +5,7 @@ import { ItemMetadataListElementComponent } from './item-metadata-list-element.c import { By } from '@angular/platform-browser'; import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; -const mockItemMetadataRepresentation = new ItemMetadataRepresentation(); +const mockItemMetadataRepresentation = new ItemMetadataRepresentation(Object.assign({})); describe('ItemMetadataListElementComponent', () => { let comp: ItemMetadataListElementComponent; diff --git a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts new file mode 100644 index 0000000000..0fdca0d429 --- /dev/null +++ b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts @@ -0,0 +1,17 @@ +import { MetadataRepresentationListElementComponent } from '../metadata-representation-list-element.component'; +import { Component, Inject } from '@angular/core'; +import { ITEM } from '../../../items/switcher/item-type-switcher.component'; +import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; + +@Component({ + selector: 'ds-item-metadata-representation-list-element', + template: '' +}) +/** + * An abstract class for displaying a single ItemMetadataRepresentation + */ +export class ItemMetadataRepresentationListElementComponent extends MetadataRepresentationListElementComponent { + constructor(@Inject(ITEM) public metadataRepresentation: ItemMetadataRepresentation) { + super(metadataRepresentation); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 903f907fc0..ed9f8efa93 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -146,6 +146,7 @@ import { DsoInputSuggestionsComponent } from './input-suggestions/dso-input-sugg import { TypedItemSearchResultGridElementComponent } from './object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component'; import { PublicationGridElementComponent } from './object-grid/item-grid-element/item-types/publication/publication-grid-element.component'; import { ItemTypeBadgeComponent } from './object-list/item-type-badge/item-type-badge.component'; +import { ItemMetadataRepresentationListElementComponent } from './object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -316,7 +317,8 @@ const ENTRY_COMPONENTS = [ StartsWithTextComponent, PlainTextMetadataListElementComponent, ItemMetadataListElementComponent, - MetadataRepresentationListElementComponent + MetadataRepresentationListElementComponent, + ItemMetadataRepresentationListElementComponent ]; const SHARED_ITEM_PAGE_COMPONENTS = [