Split typed list/grid elements into normal and search result

This commit is contained in:
lotte
2019-10-03 16:26:58 +02:00
parent 5b6aa951ad
commit 9badabade6
146 changed files with 2094 additions and 860 deletions

View File

@@ -216,9 +216,9 @@ describe('ItemMetadataComponent', () => {
});
it('it should call reinstateFieldUpdates on the objectUpdatesService with the correct url and metadata', () => {
expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.item.metadataAsList);
expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.item, { metadata: Metadata.toMetadataMap(comp.item.metadataAsList) }));
expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.item.metadataAsList);
expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.object.metadataAsList);
expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.object, { metadata: Metadata.toMetadataMap(comp.object.metadataAsList) }));
expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.object.metadataAsList);
});
});

View File

@@ -117,7 +117,7 @@ describe('EditRelationshipListComponent', () => {
fixture = TestBed.createComponent(EditRelationshipListComponent);
comp = fixture.componentInstance;
de = fixture.debugElement;
comp.item = item;
comp.object = item;
comp.url = url;
comp.relationshipLabel = relationshipType.leftLabel;
fixture.detectChanges();

View File

@@ -113,7 +113,7 @@ describe('EditRelationshipComponent', () => {
comp.url = url;
comp.fieldUpdate = fieldUpdate1;
comp.item = item;
comp.object = item;
fixture.detectChanges();
});

View File

@@ -32,7 +32,7 @@ describe('ModifyItemOverviewComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(ModifyItemOverviewComponent);
comp = fixture.componentInstance;
comp.item = mockItem;
comp.object = mockItem;
fixture.detectChanges();
});

View File

@@ -31,7 +31,7 @@ describe('ItemPageAbstractFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageAbstractFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges();
}));

View File

@@ -32,7 +32,7 @@ describe('ItemPageAuthorFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageAuthorFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(field, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(field, mockValue);
fixture.detectChanges();
}));

View File

@@ -31,7 +31,7 @@ describe('ItemPageDateFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageDateFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges();
}));

View File

@@ -33,7 +33,7 @@ describe('GenericItemPageFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(GenericItemPageFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.fields = mockFields;
comp.label = mockLabel;
fixture.detectChanges();

View File

@@ -40,7 +40,7 @@ describe('ItemPageFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.fields = mockFields;
comp.label = mockLabel;
fixture.detectChanges();

View File

@@ -31,7 +31,7 @@ describe('ItemPageTitleFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageTitleFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges();
}));

View File

@@ -31,7 +31,7 @@ describe('ItemPageUriFieldComponent', () => {
beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageUriFieldComponent);
comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.object = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges();
}));

View File

@@ -1,27 +1,27 @@
<h2 class="item-page-title-field">
{{'publication.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
{{'publication.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="object?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-xs-12 col-md-4">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
<ds-thumbnail [thumbnail]="this.object.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<ds-item-page-file-section [item]="item"></ds-item-page-file-section>
<ds-item-page-date-field [item]="item"></ds-item-page-date-field>
<ds-item-page-author-field *ngIf="!(authors$ | async)" [item]="item"></ds-item-page-author-field>
<ds-generic-item-page-field [item]="item"
<ds-item-page-file-section [item]="object"></ds-item-page-file-section>
<ds-item-page-date-field [item]="object"></ds-item-page-date-field>
<ds-item-page-author-field *ngIf="!(authors$ | async)" [item]="object"></ds-item-page-author-field>
<ds-generic-item-page-field [item]="object"
[fields]="['journal.title']"
[label]="'publication.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['journal.identifier.issn']"
[label]="'publication.page.journal-issn'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['journalvolume.identifier.name']"
[label]="'publication.page.volume-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['dc.publisher']"
[label]="'publication.page.publisher'">
</ds-generic-item-page-field>
@@ -43,25 +43,25 @@
[items]="journalIssues$ | async"
[label]="'relationships.isJournalIssueOf' | translate">
</ds-related-items>
<ds-item-page-abstract-field [item]="item"></ds-item-page-abstract-field>
<ds-generic-item-page-field [item]="item"
<ds-item-page-abstract-field [item]="object"></ds-item-page-abstract-field>
<ds-generic-item-page-field [item]="object"
[fields]="['dc.description']"
[label]="'publication.page.description'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['dc.subject']"
[separator]="','"
[label]="'item.page.subject'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['dc.identifier.citation']"
[label]="'item.page.citation'">
</ds-generic-item-page-field>
<ds-item-page-uri-field [item]="item"></ds-item-page-uri-field>
<ds-item-page-collections [item]="item"></ds-item-page-collections>
<ds-item-page-uri-field [item]="object"></ds-item-page-uri-field>
<ds-item-page-collections [item]="object"></ds-item-page-collections>
<div>
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id + '/full']">
<a class="btn btn-outline-primary" [routerLink]="['/items/' + object.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>

View File

@@ -44,15 +44,15 @@ export class PublicationComponent extends ItemComponent implements OnInit {
this.authors$ = this.buildRepresentations('Person', 'dc.contributor.author');
this.projects$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isProjectOfPublication')
getRelatedItemsByTypeLabel(this.object.id, 'isProjectOfPublication')
);
this.orgUnits$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isOrgUnitOfPublication')
getRelatedItemsByTypeLabel(this.object.id, 'isOrgUnitOfPublication')
);
this.journalIssues$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isJournalIssueOfPublication')
getRelatedItemsByTypeLabel(this.object.id, 'isJournalIssueOfPublication')
);
}

View File

@@ -1,14 +1,12 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Input, 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';
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
import { Item } from '../../../../core/shared/item.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.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';
@@ -66,13 +64,13 @@ export class ItemComponent implements OnInit {
* Resolved relationships and types together in one observable
*/
resolvedRelsAndTypes$: Observable<[Relationship[], RelationshipType[]]>;
@Input() object: Item;
constructor(
@Inject(ITEM) public item: Item
) {}
ngOnInit(): void {
const relationships$ = this.item.relationships;
const relationships$ = this.object.relationships;
if (relationships$) {
const relsCurrentPage$ = relationships$.pipe(
filter((rd: RemoteData<PaginatedList<Relationship>>) => rd.hasSucceeded),
@@ -104,8 +102,8 @@ export class ItemComponent implements OnInit {
* @param metadataField The metadata field that resembles the item type.
*/
buildRepresentations(itemType: string, metadataField: string): Observable<MetadataRepresentation[]> {
const metadata = this.item.findMetadataSortedByPlace(metadataField);
const relsCurrentPage$ = this.item.relationships.pipe(
const metadata = this.object.findMetadataSortedByPlace(metadataField);
const relsCurrentPage$ = this.object.relationships.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((pl: PaginatedList<Relationship>) => pl.page),
@@ -113,7 +111,7 @@ export class ItemComponent implements OnInit {
);
return relsCurrentPage$.pipe(
relationsToRepresentations(this.item.id, itemType, metadata)
relationsToRepresentations(this.object.id, itemType, metadata)
);
}

View File

@@ -38,7 +38,7 @@ describe('RelatedEntitiesSearchComponent', () => {
comp = fixture.componentInstance;
fixedFilterService = (comp as any).fixedFilterService;
comp.relationType = mockRelationType;
comp.item = mockItem;
comp.object = mockItem;
comp.relationEntityType = mockRelationEntityType;
fixture.detectChanges();
});

View File

@@ -1,30 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('creativework.datePublished')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('creativework.datePublished')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="dso.hasMetadata('journal.title')" class="item-journal-title card-text">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('journal.title')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-journal-issue-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-issue-search-result-grid-element>

View File

@@ -1,18 +1,17 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../shared/animations/focus';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('JournalIssue', ViewMode.GridElement)
@Component({
selector: 'ds-journal-issue-grid-element',
styleUrls: ['./journal-issue-grid-element.component.scss'],
templateUrl: './journal-issue-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal Issue
*/
export class JournalIssueGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class JournalIssueGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,30 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('creativework.datePublished')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('creativework.datePublished')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="dso.hasMetadata('dc.description')" class="item-description card-text">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-journal-volume-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-volume-search-result-grid-element>

View File

@@ -1,18 +1,17 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../shared/animations/focus';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('JournalVolume', ViewMode.GridElement)
@Component({
selector: 'ds-journal-volume-grid-element',
styleUrls: ['./journal-volume-grid-element.component.scss'],
templateUrl: './journal-volume-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal Volume
*/
export class JournalVolumeGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class JournalVolumeGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,35 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('creativework.editor')"
class="item-publisher card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="1">
<span class="item-editor">{{dso.firstMetadataValue('creativework.editor')}}</span>
<span *ngIf="dso.hasMetadata('creativework.publisher')" class="item-publisher">
<span>, </span>
{{dso.firstMetadataValue('creativework.publisher')}}
</span>
</ds-truncatable-part>
</p>
<p *ngIf="dso.hasMetadata('dc.description')" class="item-description card-text">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-journal-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-search-result-grid-element>

View File

@@ -1,18 +1,18 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../shared/animations/focus';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('Journal', ViewMode.GridElement)
@Component({
selector: 'ds-journal-grid-element',
styleUrls: ['./journal-grid-element.component.scss'],
templateUrl: './journal-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal
*/
export class JournalGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class JournalGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -0,0 +1,32 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('creativework.datePublished')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('creativework.datePublished')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="item.hasMetadata('journal.title')" class="item-journal-title card-text">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('journal.title')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,50 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { JournalIssueSearchResultGridElementComponent } from './journal-issue-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'creativework.datePublished': [
{
language: null,
value: '2015-06-26'
}
],
'journal.title': [
{
language: 'en_US',
value: 'The journal title'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalIssueGridElementComponent', getEntityGridElementTestComponent(JournalIssueSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'journal-title']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { focusShadow } from '../../../../../shared/animations/focus';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('JournalIssueSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-journal-issue-search-result-grid-element',
styleUrls: ['./journal-issue-search-result-grid-element.component.scss'],
templateUrl: './journal-issue-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal Issue
*/
export class JournalIssueSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,32 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('creativework.datePublished')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('creativework.datePublished')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="item.hasMetadata('dc.description')" class="item-description card-text">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,50 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { JournalVolumeSearchResultGridElementComponent } from './journal-volume-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'creativework.datePublished': [
{
language: null,
value: '2015-06-26'
}
],
'dc.description': [
{
language: 'en_US',
value: 'A description for the journal volume'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalVolumeGridElementComponent', getEntityGridElementTestComponent(JournalVolumeSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'description']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { focusShadow } from '../../../../../shared/animations/focus';
@listableObjectComponent('JournalVolumeSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-journal-volume-search-result-grid-element',
styleUrls: ['./journal-volume-search-result-grid-element.component.scss'],
templateUrl: './journal-volume-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal Volume
*/
export class JournalVolumeSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,37 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('creativework.editor')"
class="item-publisher card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span class="item-editor">{{item.firstMetadataValue('creativework.editor')}}</span>
<span *ngIf="item.hasMetadata('creativework.publisher')" class="item-publisher">
<span>, </span>
{{item.firstMetadataValue('creativework.publisher')}}
</span>
</ds-truncatable-part>
</p>
<p *ngIf="item.hasMetadata('dc.description')" class="item-description card-text">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,56 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { JournalSearchResultGridElementComponent } from './journal-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'creativework.editor': [
{
language: 'en_US',
value: 'Smith, Donald'
}
],
'creativework.publisher': [
{
language: 'en_US',
value: 'A company'
}
],
'dc.description': [
{
language: 'en_US',
value: 'This is the description'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalGridElementComponent', getEntityGridElementTestComponent(JournalSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['editor', 'publisher', 'description']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../../shared/animations/focus';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('JournalSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-journal-search-result-grid-element',
styleUrls: ['./journal-search-result-grid-element.component.scss'],
templateUrl: './journal-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Journal
*/
export class JournalSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -1,21 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['publicationvolume.volumeNumber']).length > 0"
class="item-list-journal-issues">
<span *ngFor="let value of allMetadataValues(['publicationvolume.volumeNumber']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
<span *ngIf="item.allMetadata(['publicationissue.issueNumber']).length > 0"
class="item-list-journal-issue-numbers">
<span *ngFor="let value of allMetadataValues(['publicationissue.issueNumber']); let last=last;">
<span> - </span><span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
<ds-journal-issue-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-issue-search-result-list-element>

View File

@@ -69,7 +69,7 @@ describe('JournalIssueListElementComponent', () => {
describe('When the item has a journal identifier', () => {
beforeEach(() => {
journalIssueListElementComponent.item = mockItemWithMetadata;
journalIssueListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -81,7 +81,7 @@ describe('JournalIssueListElementComponent', () => {
describe('When the item has no journal identifier', () => {
beforeEach(() => {
journalIssueListElementComponent.item = mockItemWithoutMetadata;
journalIssueListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
@@ -93,7 +93,7 @@ describe('JournalIssueListElementComponent', () => {
describe('When the item has a journal number', () => {
beforeEach(() => {
journalIssueListElementComponent.item = mockItemWithMetadata;
journalIssueListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -105,7 +105,7 @@ describe('JournalIssueListElementComponent', () => {
describe('When the item has no journal number', () => {
beforeEach(() => {
journalIssueListElementComponent.item = mockItemWithoutMetadata;
journalIssueListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('JournalIssue', ViewMode.ListElement)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Journal Issue
*/
export class JournalIssueListElementComponent extends TypedItemSearchResultListElementComponent {
export class JournalIssueListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,21 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['journal.title']).length > 0"
class="item-list-journal-volumes">
<span *ngFor="let value of allMetadataValues(['journal.title']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
<span *ngIf="item.allMetadata(['publicationvolume.volumeNumber']).length > 0"
class="item-list-journal-volume-identifiers">
<span *ngFor="let value of allMetadataValues(['publicationvolume.volumeNumber']); let last=last;">
<span> (</span><span [innerHTML]="value"><span [innerHTML]="value"></span></span><span>)</span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
<ds-journal-volume-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-volume-search-result-list-element>

View File

@@ -69,7 +69,7 @@ describe('JournalVolumeListElementComponent', () => {
describe('When the item has a journal title', () => {
beforeEach(() => {
journalVolumeListElementComponent.item = mockItemWithMetadata;
journalVolumeListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -81,7 +81,7 @@ describe('JournalVolumeListElementComponent', () => {
describe('When the item has no journal title', () => {
beforeEach(() => {
journalVolumeListElementComponent.item = mockItemWithoutMetadata;
journalVolumeListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
@@ -93,7 +93,7 @@ describe('JournalVolumeListElementComponent', () => {
describe('When the item has a journal identifier', () => {
beforeEach(() => {
journalVolumeListElementComponent.item = mockItemWithMetadata;
journalVolumeListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -105,7 +105,7 @@ describe('JournalVolumeListElementComponent', () => {
describe('When the item has no journal identifier', () => {
beforeEach(() => {
journalVolumeListElementComponent.item = mockItemWithoutMetadata;
journalVolumeListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('JournalVolume', ViewMode.ListElement)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Journal Volume
*/
export class JournalVolumeListElementComponent extends TypedItemSearchResultListElementComponent {
export class JournalVolumeListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,15 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['creativeworkseries.issn']).length > 0"
class="item-list-journals">
<span *ngFor="let value of allMetadataValues(['creativeworkseries.issn']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
<ds-journal-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-journal-search-result-list-element>

View File

@@ -63,7 +63,7 @@ describe('JournalListElementComponent', () => {
describe('When the item has an issn', () => {
beforeEach(() => {
journalListElementComponent.item = mockItemWithMetadata;
journalListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -75,7 +75,7 @@ describe('JournalListElementComponent', () => {
describe('When the item has no issn', () => {
beforeEach(() => {
journalListElementComponent.item = mockItemWithoutMetadata;
journalListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('Journal', ViewMode.ListElement)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Journal
*/
export class JournalListElementComponent extends TypedItemSearchResultListElementComponent {
export class JournalListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -0,0 +1,23 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['publicationvolume.volumeNumber']).length > 0"
class="item-list-journal-issues">
<span *ngFor="let value of allMetadataValues(['publicationvolume.volumeNumber']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
<span *ngIf="item.allMetadata(['publicationissue.issueNumber']).length > 0"
class="item-list-journal-issue-numbers">
<span *ngFor="let value of allMetadataValues(['publicationissue.issueNumber']); let last=last;">
<span> - </span><span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,117 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { JournalIssueSearchResultListElementComponent } from './journal-issue-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.component';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let journalIssueListElementComponent: JournalIssueSearchResultListElementComponent;
let fixture: ComponentFixture<JournalIssueSearchResultListElementComponent>;
const mockItemWithMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'publicationvolume.volumeNumber': [
{
language: 'en_US',
value: '1234'
}
],
'publicationissue.issueNumber': [
{
language: 'en_US',
value: '5678'
}
]
}
});
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalIssueListElementComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ JournalIssueSearchResultListElementComponent , TruncatePipe],
providers: [
{ provide: ITEM, useValue: mockItemWithMetadata},
{ provide: TruncatableService, useValue: {} }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(JournalIssueSearchResultListElementComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(JournalIssueSearchResultListElementComponent);
journalIssueListElementComponent = fixture.componentInstance;
}));
describe('When the item has a journal identifier', () => {
beforeEach(() => {
journalIssueListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the journal issues span', () => {
const journalIdentifierField = fixture.debugElement.query(By.css('span.item-list-journal-issues'));
expect(journalIdentifierField).not.toBeNull();
});
});
describe('When the item has no journal identifier', () => {
beforeEach(() => {
journalIssueListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the journal issues span', () => {
const journalIdentifierField = fixture.debugElement.query(By.css('span.item-list-journal-issues'));
expect(journalIdentifierField).toBeNull();
});
});
describe('When the item has a journal number', () => {
beforeEach(() => {
journalIssueListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the journal issue numbers span', () => {
const journalNumberField = fixture.debugElement.query(By.css('span.item-list-journal-issue-numbers'));
expect(journalNumberField).not.toBeNull();
});
});
describe('When the item has no journal number', () => {
beforeEach(() => {
journalIssueListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the journal issue numbers span', () => {
const journalNumberField = fixture.debugElement.query(By.css('span.item-list-journal-issue-numbers'));
expect(journalNumberField).toBeNull();
});
});
});

View File

@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('JournalIssueSearchResult', ViewMode.ListElement)
@Component({
selector: 'ds-journal-issue-search-result-list-element',
styleUrls: ['./journal-issue-search-result-list-element.component.scss'],
templateUrl: './journal-issue-search-result-list-element.component.html'
})
/**
* The component for displaying a list element for an item of the type Journal Issue
*/
export class JournalIssueSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,23 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['journal.title']).length > 0"
class="item-list-journal-volumes">
<span *ngFor="let value of allMetadataValues(['journal.title']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
<span *ngIf="item.allMetadata(['publicationvolume.volumeNumber']).length > 0"
class="item-list-journal-volume-identifiers">
<span *ngFor="let value of allMetadataValues(['publicationvolume.volumeNumber']); let last=last;">
<span> (</span><span [innerHTML]="value"><span [innerHTML]="value"></span></span><span>)</span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,117 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { JournalVolumeSearchResultListElementComponent } from './journal-volume-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.component';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let journalVolumeListElementComponent: JournalVolumeSearchResultListElementComponent;
let fixture: ComponentFixture<JournalVolumeSearchResultListElementComponent>;
const mockItemWithMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'journal.title': [
{
language: 'en_US',
value: 'This is just another journal title'
}
],
'publicationvolume.volumeNumber': [
{
language: 'en_US',
value: '1234'
}
]
}
});
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalVolumeListElementComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ JournalVolumeSearchResultListElementComponent , TruncatePipe],
providers: [
{ provide: ITEM, useValue: mockItemWithMetadata},
{ provide: TruncatableService, useValue: {} }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(JournalVolumeSearchResultListElementComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(JournalVolumeSearchResultListElementComponent);
journalVolumeListElementComponent = fixture.componentInstance;
}));
describe('When the item has a journal title', () => {
beforeEach(() => {
journalVolumeListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the journal title span', () => {
const journalTitleField = fixture.debugElement.query(By.css('span.item-list-journal-volumes'));
expect(journalTitleField).not.toBeNull();
});
});
describe('When the item has no journal title', () => {
beforeEach(() => {
journalVolumeListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the journal title span', () => {
const journalTitleField = fixture.debugElement.query(By.css('span.item-list-journal-volumes'));
expect(journalTitleField).toBeNull();
});
});
describe('When the item has a journal identifier', () => {
beforeEach(() => {
journalVolumeListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the journal identifiers span', () => {
const journalIdentifierField = fixture.debugElement.query(By.css('span.item-list-journal-volume-identifiers'));
expect(journalIdentifierField).not.toBeNull();
});
});
describe('When the item has no journal identifier', () => {
beforeEach(() => {
journalVolumeListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the journal identifiers span', () => {
const journalIdentifierField = fixture.debugElement.query(By.css('span.item-list-journal-volume-identifiers'));
expect(journalIdentifierField).toBeNull();
});
});
});

View File

@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
@listableObjectComponent('JournalVolumeSearchResult', ViewMode.ListElement)
@Component({
selector: 'ds-journal-volume-search-result-list-element',
styleUrls: ['./journal-volume-search-result-list-element.component.scss'],
templateUrl: './journal-volume-search-result-list-element.component.html'
})
/**
* The component for displaying a list element for an item of the type Journal Volume
*/
export class JournalVolumeSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,17 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['creativeworkseries.issn']).length > 0"
class="item-list-journals">
<span *ngFor="let value of allMetadataValues(['creativeworkseries.issn']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,87 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { JournalSearchResultListElementComponent } from './journal-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.component';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let journalListElementComponent: JournalSearchResultListElementComponent;
let fixture: ComponentFixture<JournalSearchResultListElementComponent>;
const mockItemWithMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'creativeworkseries.issn': [
{
language: 'en_US',
value: '1234'
}
]
}
});
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('JournalListElementComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ JournalSearchResultListElementComponent , TruncatePipe],
providers: [
{ provide: ITEM, useValue: mockItemWithMetadata},
{ provide: TruncatableService, useValue: {} }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(JournalSearchResultListElementComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(JournalSearchResultListElementComponent);
journalListElementComponent = fixture.componentInstance;
}));
describe('When the item has an issn', () => {
beforeEach(() => {
journalListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the journals span', () => {
const issnField = fixture.debugElement.query(By.css('span.item-list-journals'));
expect(issnField).not.toBeNull();
});
});
describe('When the item has no issn', () => {
beforeEach(() => {
journalListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the journals span', () => {
const issnField = fixture.debugElement.query(By.css('span.item-list-journals'));
expect(issnField).toBeNull();
});
});
});

View File

@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
@listableObjectComponent('JournalSearchResult', ViewMode.ListElement)
@Component({
selector: 'ds-journal-search-result-list-element',
styleUrls: ['./journal-search-result-list-element.component.scss'],
templateUrl: './journal-search-result-list-element.component.html'
})
/**
* The component for displaying a list element for an item of the type Journal
*/
export class JournalSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
}

View File

@@ -1,28 +1,28 @@
<h2 class="item-page-title-field">
{{'journalissue.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
{{'journalissue.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="object?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-xs-12 col-md-4">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
<ds-thumbnail [thumbnail]="this.object.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['publicationvolume.volumeNumber']"
[label]="'journalvolume.page.volume'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['publicationissue.issueNumber']"
[label]="'journalissue.page.number'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['creativework.datePublished']"
[label]="'journalissue.page.issuedate'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['journal.title']"
[label]="'journalissue.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['creativeworkseries.issn']"
[label]="'journalissue.page.journal-issn'">
</ds-generic-item-page-field>
@@ -37,16 +37,16 @@
[items]="publications$ | async"
[label]="'relationships.isPublicationOfJournalIssue' | translate">
</ds-related-items>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['dc.description']"
[label]="'journalissue.page.description'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['creativework.keywords']"
[label]="'journalissue.page.keyword'">
</ds-generic-item-page-field>
<div>
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id + '/full']">
<a class="btn btn-outline-primary" [routerLink]="['/items/' + object.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>

View File

@@ -32,10 +32,10 @@ export class JournalIssueComponent extends ItemComponent {
if (isNotEmpty(this.resolvedRelsAndTypes$)) {
this.volumes$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isJournalVolumeOfIssue')
getRelatedItemsByTypeLabel(this.object.id, 'isJournalVolumeOfIssue')
);
this.publications$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isPublicationOfJournalIssue')
getRelatedItemsByTypeLabel(this.object.id, 'isPublicationOfJournalIssue')
);
}
}

View File

@@ -1,16 +1,16 @@
<h2 class="item-page-title-field">
{{'journalvolume.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
{{'journalvolume.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="object?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-xs-12 col-md-4">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
<ds-thumbnail [thumbnail]="this.object.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['publicationvolume.volumeNumber']"
[label]="'journalvolume.page.volume'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['creativework.datePublished']"
[label]="'journalvolume.page.issuedate'">
</ds-generic-item-page-field>
@@ -24,12 +24,12 @@
[items]="issues$ | async"
[label]="'relationships.isIssueOf' | translate">
</ds-related-items>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['dc.description']"
[label]="'journalvolume.page.description'">
</ds-generic-item-page-field>
<div>
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id + '/full']">
<a class="btn btn-outline-primary" [routerLink]="['/items/' + object.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>

View File

@@ -32,10 +32,10 @@ export class JournalVolumeComponent extends ItemComponent {
if (isNotEmpty(this.resolvedRelsAndTypes$)) {
this.journals$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isJournalOfVolume')
getRelatedItemsByTypeLabel(this.object.id, 'isJournalOfVolume')
);
this.issues$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isIssueOfJournalVolume')
getRelatedItemsByTypeLabel(this.object.id, 'isIssueOfJournalVolume')
);
}
}

View File

@@ -1,20 +1,20 @@
<h2 class="item-page-title-field">
{{'journal.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
{{'journal.page.titleprefix' | translate}}<ds-metadata-values [mdValues]="object?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-xs-12 col-md-4">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
<ds-thumbnail [thumbnail]="this.object.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<ds-generic-item-page-field class="item-page-fields" [item]="item"
<ds-generic-item-page-field class="item-page-fields" [item]="object"
[fields]="['creativeworkseries.issn']"
[label]="'journal.page.issn'">
</ds-generic-item-page-field>
<ds-generic-item-page-field class="item-page-fields" [item]="item"
<ds-generic-item-page-field class="item-page-fields" [item]="object"
[fields]="['creativework.publisher']"
[label]="'journal.page.publisher'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
<ds-generic-item-page-field [item]="object"
[fields]="['creativework.editor']"
[label]="'journal.page.editor'">
</ds-generic-item-page-field>
@@ -24,18 +24,18 @@
[items]="volumes$ | async"
[label]="'relationships.isVolumeOf' | translate">
</ds-related-items>
<ds-generic-item-page-field class="item-page-fields" [item]="item"
<ds-generic-item-page-field class="item-page-fields" [item]="object"
[fields]="['dc.description']"
[label]="'journal.page.description'">
</ds-generic-item-page-field>
<div>
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id + '/full']">
<a class="btn btn-outline-primary" [routerLink]="['/items/' + object.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="mt-5 w-100">
<ds-related-entities-search [item]="item"
<ds-related-entities-search [item]="object"
[relationType]="'isJournalOfPublication'">
</ds-related-entities-search>
</div>

View File

@@ -27,7 +27,7 @@ export class JournalComponent extends ItemComponent {
if (isNotEmpty(this.resolvedRelsAndTypes$)) {
this.volumes$ = this.resolvedRelsAndTypes$.pipe(
getRelatedItemsByTypeLabel(this.item.id, 'isVolumeOfJournal')
getRelatedItemsByTypeLabel(this.object.id, 'isVolumeOfJournal')
);
}
}

View File

@@ -12,6 +12,12 @@ import { TooltipModule } from 'ngx-bootstrap';
import { JournalIssueGridElementComponent } from './item-grid-elements/journal-issue/journal-issue-grid-element.component';
import { JournalVolumeGridElementComponent } from './item-grid-elements/journal-volume/journal-volume-grid-element.component';
import { JournalGridElementComponent } from './item-grid-elements/journal/journal-grid-element.component';
import { JournalSearchResultListElementComponent } from './item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component';
import { JournalSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component';
import { JournalIssueSearchResultListElementComponent } from './item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component';
import { JournalVolumeSearchResultListElementComponent } from './item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component';
import { JournalIssueSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component';
import { JournalVolumeSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component';
const ENTRY_COMPONENTS = [
JournalComponent,
@@ -22,7 +28,13 @@ const ENTRY_COMPONENTS = [
JournalVolumeListElementComponent,
JournalIssueGridElementComponent,
JournalVolumeGridElementComponent,
JournalGridElementComponent
JournalGridElementComponent,
JournalSearchResultListElementComponent,
JournalIssueSearchResultListElementComponent,
JournalVolumeSearchResultListElementComponent,
JournalIssueSearchResultGridElementComponent,
JournalVolumeSearchResultGridElementComponent,
JournalSearchResultGridElementComponent
];
@NgModule({

View File

@@ -1,35 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('organization.legalName')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('organization.foundingDate')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('organization.foundingDate')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="dso.hasMetadata('organization.address.addressCountry')"
class="item-location card-text">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span class="item-country">{{dso.firstMetadataValue('organization.address.addressCountry')}}</span>
<span *ngIf="dso.hasMetadata('organization.address.addressLocality')" class="item-city">
<span>, </span>
{{dso.firstMetadataValue('organization.address.addressLocality')}}
</span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-orgunit-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-orgunit-search-result-grid-element>

View File

@@ -1,18 +1,17 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../shared/animations/focus';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('OrgUnit', ViewMode.GridElement)
@Component({
selector: 'ds-orgunit-grid-element',
styleUrls: ['./orgunit-grid-element.component.scss'],
templateUrl: './orgunit-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Organisation Unit
*/
export class OrgunitGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class OrgunitGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,30 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('person.familyName') + ', ' + dso.firstMetadataValue('person.givenName')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('person.email')" class="item-email card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('person.email')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="dso.hasMetadata('person.jobTitle')" class="item-jobtitle card-text">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('person.jobTitle')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-person-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-person-search-result-grid-element>

View File

@@ -1,18 +1,17 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { focusShadow } from '../../../../shared/animations/focus';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('Person', ViewMode.GridElement)
@Component({
selector: 'ds-person-grid-element',
styleUrls: ['./person-grid-element.component.scss'],
templateUrl: './person-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Person
*/
export class PersonGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class PersonGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,25 +1 @@
<ds-truncatable [id]="dso.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="dso.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="dso.hasMetadata('dc.description')" class="item-description card-text text-muted">
<ds-truncatable-part [id]="dso.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + dso.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
<ds-project-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-project-search-result-grid-element>

View File

@@ -1,18 +1,17 @@
import { Component } from '@angular/core';
import { focusShadow } from '../../../../shared/animations/focus';
import { TypedItemSearchResultGridElementComponent } from '../../../../shared/object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('Project', ViewMode.GridElement)
@Component({
selector: 'ds-project-grid-element',
styleUrls: ['./project-grid-element.component.scss'],
templateUrl: './project-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Project
*/
export class ProjectGridElementComponent extends TypedItemSearchResultGridElementComponent {
export class ProjectGridElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -0,0 +1,37 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('organization.legalName')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('organization.foundingDate')" class="item-date card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('organization.foundingDate')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="item.hasMetadata('organization.address.addressCountry')"
class="item-location card-text">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span class="item-country">{{item.firstMetadataValue('organization.address.addressCountry')}}</span>
<span *ngIf="item.hasMetadata('organization.address.addressLocality')" class="item-city">
<span>, </span>
{{item.firstMetadataValue('organization.address.addressLocality')}}
</span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,56 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { OrgunitSearchResultGridElementComponent } from './orgunit-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'organization.foundingDate': [
{
language: null,
value: '2015-06-26'
}
],
'organization.address.addressCountry': [
{
language: 'en_US',
value: 'Belgium'
}
],
'organization.address.addressLocality': [
{
language: 'en_US',
value: 'Brussels'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('OrgunitGridElementComponent', getEntityGridElementTestComponent(OrgunitSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'country', 'city']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { focusShadow } from '../../../../../shared/animations/focus';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('OrgUnitSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-orgunit-search-result-grid-element',
styleUrls: ['./orgunit-search-result-grid-element.component.scss'],
templateUrl: './orgunit-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Organisation Unit
*/
export class OrgunitSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,32 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="this.item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('person.familyName') + ', ' + item.firstMetadataValue('person.givenName')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('person.email')" class="item-email card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span [innerHTML]="firstMetadataValue('person.email')"></span>
</ds-truncatable-part>
</p>
<p *ngIf="item.hasMetadata('person.jobTitle')" class="item-jobtitle card-text">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('person.jobTitle')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,50 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { PersonSearchResultGridElementComponent } from './person-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'person.email': [
{
language: 'en_US',
value: 'Smith-Donald@gmail.com'
}
],
'person.jobTitle': [
{
language: 'en_US',
value: 'Web Developer'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('PersonGridElementComponent', getEntityGridElementTestComponent(PersonSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['email', 'jobtitle']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { focusShadow } from '../../../../../shared/animations/focus';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('PersonSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-person-search-result-grid-element',
styleUrls: ['./person-search-result-grid-element.component.scss'],
templateUrl: './person-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Person
*/
export class PersonSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,27 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
<a [routerLink]="['/items/' + item.id]" class="card-img-top full-width">
<div>
<ds-grid-thumbnail [thumbnail]="item.getThumbnail() | async">
</ds-grid-thumbnail>
</div>
</a>
<div class="card-body">
<ds-item-type-badge [object]="object"></ds-item-type-badge>
<ds-truncatable-part [id]="item.id" [minLines]="3" type="h4">
<h4 class="card-title" [innerHTML]="item.firstMetadataValue('dc.title')"></h4>
</ds-truncatable-part>
<p *ngIf="item.hasMetadata('dc.description')" class="item-description card-text text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span [innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</p>
<div class="text-center">
<a [routerLink]="['/items/' + item.id]"
class="lead btn btn-primary viewButton">View</a>
</div>
</div>
</div>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,44 @@
import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { getEntityGridElementTestComponent } from '../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component.spec';
import { ProjectSearchResultGridElementComponent } from './project-grid-element.component';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { PageInfo } from '../../../../core/shared/page-info.model';
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithMetadata.hitHighlights = {};
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'dc.description': [
{
language: 'en_US',
value: 'The project description'
}
]
}
});
const mockItemWithoutMetadata: ItemSearchResult = new ItemSearchResult();
mockItemWithoutMetadata.hitHighlights = {};
mockItemWithoutMetadata.indexableObject = Object.assign(new Item(), {
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('ProjectGridElementComponent', getEntityGridElementTestComponent(ProjectSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['description']));

View File

@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { SearchResultGridElementComponent } from '../../../../../shared/object-grid/search-result-grid-element/search-result-grid-element.component';
import { Item } from '../../../../../core/shared/item.model';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { focusShadow } from '../../../../../shared/animations/focus';
@listableObjectComponent('ProjectSearchResult', ViewMode.GridElement)
@Component({
selector: 'ds-project-search-result-grid-element',
styleUrls: ['./project-search-result-grid-element.component.scss'],
templateUrl: './project-search-result-grid-element.component.html',
animations: [focusShadow]
})
/**
* The component for displaying a grid element for an item of the type Project
*/
export class ProjectSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
}

View File

@@ -1,13 +1,13 @@
<ng-template #descTemplate>
<span class="text-muted">
<span *ngIf="item.allMetadata(['dc.description']).length > 0"
<span *ngIf="object.allMetadata(['dc.description']).length > 0"
class="item-list-job-title">
<span [innerHTML]="firstMetadataValue(['dc.description'])"></span>
</span>
</span>
</ng-template>
<ds-truncatable [id]="item.id">
<a [routerLink]="['/items/' + item.id]"
<ds-truncatable [id]="object.id">
<a [routerLink]="['/items/' + object.id]"
[innerHTML]="firstMetadataValue('organization.legalName')"
[tooltip]="descTemplate"></a>
</ds-truncatable>

View File

@@ -1,8 +1,9 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { Context } from '../../../../core/shared/context.model';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('OrgUnit', ViewMode.ListElement, Context.ItemPage)
@Component({
@@ -12,5 +13,5 @@ import { Context } from '../../../../core/shared/context.model';
/**
* The component for displaying a list element for an item of the type OrgUnit
*/
export class OrgunitItemPageListElementComponent extends TypedItemSearchResultListElementComponent {
export class OrgunitItemPageListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,16 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('organization.legalName')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span *ngIf="item.allMetadata(['dc.description']).length > 0"
class="item-list-orgunit-description">
<ds-truncatable-part [id]="item.id" [minLines]="3"><span
[innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
<ds-orgunit-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-orgunit-search-result-list-element>

View File

@@ -63,7 +63,7 @@ describe('OrgUnitListElementComponent', () => {
describe('When the item has an orgunit description', () => {
beforeEach(() => {
orgUnitListElementComponent.item = mockItemWithMetadata;
orgUnitListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -75,7 +75,7 @@ describe('OrgUnitListElementComponent', () => {
describe('When the item has no orgunit description', () => {
beforeEach(() => {
orgUnitListElementComponent.item = mockItemWithoutMetadata;
orgUnitListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('OrgUnit', ViewMode.ListElement)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Organisation Unit
*/
export class OrgUnitListElementComponent extends TypedItemSearchResultListElementComponent {
export class OrgUnitListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,6 +1,6 @@
<ng-template #descTemplate>
<span class="text-muted">
<span *ngIf="item.allMetadata(['person.jobTitle']).length > 0"
<span *ngIf="object.allMetadata(['person.jobTitle']).length > 0"
class="item-list-job-title">
<span *ngFor="let value of allMetadataValues(['person.jobTitle']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
@@ -8,8 +8,8 @@
</span>
</span>
</ng-template>
<ds-truncatable [id]="item.id">
<a [routerLink]="['/items/' + item.id]"
<ds-truncatable [id]="object.id">
<a [routerLink]="['/items/' + object.id]"
[innerHTML]="firstMetadataValue('person.familyName') + ', ' + firstMetadataValue('person.givenName')"
[tooltip]="descTemplate"></a>
</ds-truncatable>

View File

@@ -1,8 +1,9 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { Context } from '../../../../core/shared/context.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('OrgUnit', ViewMode.ListElement, Context.ItemPage)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Person
*/
export class PersonItemPageListElementComponent extends TypedItemSearchResultListElementComponent {
export class PersonItemPageListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,15 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('person.familyName') + ', ' + firstMetadataValue('person.givenName')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['person.jobTitle']).length > 0"
class="item-list-job-title">
<span *ngFor="let value of allMetadataValues(['person.jobTitle']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
<ds-person-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-person-search-result-list-element>

View File

@@ -5,7 +5,6 @@ import { PersonListElementComponent } from './person-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.component';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let personListElementComponent: PersonListElementComponent;
@@ -45,7 +44,6 @@ describe('PersonListElementComponent', () => {
TestBed.configureTestingModule({
declarations: [ PersonListElementComponent , TruncatePipe],
providers: [
{ provide: ITEM, useValue: mockItemWithMetadata},
{ provide: TruncatableService, useValue: {} }
],
@@ -63,7 +61,7 @@ describe('PersonListElementComponent', () => {
describe('When the item has a job title', () => {
beforeEach(() => {
personListElementComponent.item = mockItemWithMetadata;
personListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
@@ -75,7 +73,7 @@ describe('PersonListElementComponent', () => {
describe('When the item has no job title', () => {
beforeEach(() => {
personListElementComponent.item = mockItemWithoutMetadata;
personListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { ViewMode } from '../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@listableObjectComponent('Person', ViewMode.ListElement)
@Component({
@@ -12,5 +13,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh
/**
* The component for displaying a list element for an item of the type Person
*/
export class PersonListElementComponent extends TypedItemSearchResultListElementComponent {
export class PersonListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -1,16 +1 @@
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<!--<span class="text-muted">-->
<!--<ds-truncatable-part [id]="item.id" [minLines]="1">-->
<!--<span *ngIf="item.allMetadata(['project.identifier.status']).length > 0"-->
<!--class="item-list-status">-->
<!--<span *ngFor="let value of allMetadataValues(['project.identifier.status']); let last=last;">-->
<!--<span [innerHTML]="value"><span [innerHTML]="value"></span></span>-->
<!--</span>-->
<!--</span>-->
<!--</ds-truncatable-part>-->
<!--</span>-->
</ds-truncatable>
<ds-project-search-result-list-element [object]="{ indexableObject: object, hitHighlights: {} }"></ds-project-search-result-list-element>

View File

@@ -1,7 +1,8 @@
import { Component } from '@angular/core';
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
import { metadataRepresentationComponent } from '../../../../shared/metadata-representation/metadata-representation.decorator';
import { MetadataRepresentationType } from '../../../../core/shared/metadata-representation/metadata-representation.model';
import { AbstractListableElementComponent } from '../../../../shared/object-collection/shared/object-collection-element/abstract-listable-element.component';
import { Item } from '../../../../core/shared/item.model';
@metadataRepresentationComponent('Project', MetadataRepresentationType.PlainText)
@Component({
@@ -12,5 +13,5 @@ import { MetadataRepresentationType } from '../../../../core/shared/metadata-rep
/**
* The component for displaying a list element for an item of the type Project
*/
export class ProjectListElementComponent extends TypedItemSearchResultListElementComponent {
export class ProjectListElementComponent extends AbstractListableElementComponent<Item> {
}

View File

@@ -0,0 +1,17 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('organization.legalName')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="3">
<span *ngIf="item.allMetadata(['dc.description']).length > 0"
class="item-list-orgunit-description">
<ds-truncatable-part [id]="item.id" [minLines]="3"><span
[innerHTML]="firstMetadataValue('dc.description')"></span>
</ds-truncatable-part>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,87 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { OrgunitSearchResultListElementComponent } from './orgunit-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { ITEM } from '../../../../shared/items/switcher/listable-object-component-loader.component';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let orgUnitListElementComponent: OrgunitSearchResultListElementComponent;
let fixture: ComponentFixture<OrgunitSearchResultListElementComponent>;
const mockItemWithMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'dc.description': [
{
language: 'en_US',
value: 'A description about the OrgUnit'
}
]
}
});
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('OrgUnitListElementComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ OrgunitSearchResultListElementComponent , TruncatePipe],
providers: [
{ provide: ITEM, useValue: mockItemWithMetadata},
{ provide: TruncatableService, useValue: {} }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(OrgunitSearchResultListElementComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(OrgunitSearchResultListElementComponent);
orgUnitListElementComponent = fixture.componentInstance;
}));
describe('When the item has an orgunit description', () => {
beforeEach(() => {
orgUnitListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the description span', () => {
const orgunitDescriptionField = fixture.debugElement.query(By.css('span.item-list-orgunit-description'));
expect(orgunitDescriptionField).not.toBeNull();
});
});
describe('When the item has no orgunit description', () => {
beforeEach(() => {
orgUnitListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the description span', () => {
const orgunitDescriptionField = fixture.debugElement.query(By.css('span.item-list-orgunit-description'));
expect(orgunitDescriptionField).toBeNull();
});
});
});

View File

@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('OrgUnitSearchResult', ViewMode.ListElement)
@Component({
selector: 'ds-orgunit-search-result-list-element',
styleUrls: ['./orgunit-search-result-list-element.component.scss'],
templateUrl: './orgunit-search-result-list-element.component.html'
})
/**
* The component for displaying a list element for an item of the type Organisation Unit
*/
export class OrgunitSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,17 @@
<ng-container *ngVar="object.indexableObject as item">
<ds-truncatable [id]="item.id">
<a
[routerLink]="['/items/' + item.id]" class="lead"
[innerHTML]="firstMetadataValue('person.familyName') + ', ' + firstMetadataValue('person.givenName')"></a>
<span class="text-muted">
<ds-truncatable-part [id]="item.id" [minLines]="1">
<span *ngIf="item.allMetadata(['person.jobTitle']).length > 0"
class="item-list-job-title">
<span *ngFor="let value of allMetadataValues(['person.jobTitle']); let last=last;">
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
</span>
</span>
</ds-truncatable-part>
</span>
</ds-truncatable>
</ng-container>

View File

@@ -0,0 +1,85 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { PersonSearchResultListElementComponent } from './person-list-element.component';
import { of as observableOf } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
let personListElementComponent: PersonSearchResultListElementComponent;
let fixture: ComponentFixture<PersonSearchResultListElementComponent>;
const mockItemWithMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
],
'person.jobTitle': [
{
language: 'en_US',
value: 'Developer'
}
]
}
});
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
bitstreams: observableOf({}),
metadata: {
'dc.title': [
{
language: 'en_US',
value: 'This is just another title'
}
]
}
});
describe('PersonListElementComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PersonSearchResultListElementComponent , TruncatePipe],
providers: [
{ provide: TruncatableService, useValue: {} }
],
schemas: [ NO_ERRORS_SCHEMA ]
}).overrideComponent(PersonSearchResultListElementComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
}).compileComponents();
}));
beforeEach(async(() => {
fixture = TestBed.createComponent(PersonSearchResultListElementComponent);
personListElementComponent = fixture.componentInstance;
}));
describe('When the item has a job title', () => {
beforeEach(() => {
personListElementComponent.object = mockItemWithMetadata;
fixture.detectChanges();
});
it('should show the job title span', () => {
const jobTitleField = fixture.debugElement.query(By.css('span.item-list-job-title'));
expect(jobTitleField).not.toBeNull();
});
});
describe('When the item has no job title', () => {
beforeEach(() => {
personListElementComponent.object = mockItemWithoutMetadata;
fixture.detectChanges();
});
it('should not show the job title span', () => {
const jobTitleField = fixture.debugElement.query(By.css('span.item-list-job-title'));
expect(jobTitleField).toBeNull();
});
});
});

View File

@@ -0,0 +1,18 @@
import { Component } from '@angular/core';
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { ViewMode } from '../../../../../core/shared/view-mode.model';
import { Item } from '../../../../../core/shared/item.model';
@listableObjectComponent('PersonSearchResult', ViewMode.ListElement)
@Component({
selector: 'ds-person-search-result-list-element',
styleUrls: ['./person-search-result-list-element.component.scss'],
templateUrl: './person-search-result-list-element.component.html'
})
/**
* The component for displaying a list element for an item of the type Person
*/
export class PersonSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
}

View File

@@ -0,0 +1,16 @@
<ds-truncatable [id]="object.id">
<a
[routerLink]="['/items/' + object.id]" class="lead"
[innerHTML]="firstMetadataValue('dc.title')"></a>
<!--<span class="text-muted">-->
<!--<ds-truncatable-part [id]="item.id" [minLines]="1">-->
<!--<span *ngIf="item.allMetadata(['project.identifier.status']).length > 0"-->
<!--class="item-list-status">-->
<!--<span *ngFor="let value of allMetadataValues(['project.identifier.status']); let last=last;">-->
<!--<span [innerHTML]="value"><span [innerHTML]="value"></span></span>-->
<!--</span>-->
<!--</span>-->
<!--</ds-truncatable-part>-->
<!--</span>-->
</ds-truncatable>

Some files were not shown because too many files have changed in this diff Show More