Add virtual metadata fields for journals

This commit is contained in:
Art Lowel
2019-01-08 13:12:12 +01:00
parent cf9cf00fe6
commit 72fb18d92f
11 changed files with 191 additions and 11 deletions

View File

@@ -32,6 +32,8 @@
"uri": "URI",
"files": "Files",
"collections": "Collections",
"subject": "Keywords",
"citation": "Citation",
"filesection": {
"download": "Download",
"name": "Name:",
@@ -95,7 +97,8 @@
"page": {
"issn": "ISSN",
"publisher": "Publisher",
"description": "Description"
"description": "Description",
"editor": "Editor-in-Chief"
}
},
"journalvolume": {
@@ -110,7 +113,16 @@
"number": "Number",
"issuedate": "Issue Date",
"description": "Description",
"keyword": "Keywords"
"keyword": "Keywords",
"journal-title": "Journal Title",
"journal-issn": "Journal ISSN"
}
},
"publication": {
"page": {
"journal-title": "Journal Title",
"journal-issn": "Journal ISSN",
"volume-title": "Volume Title"
}
},
"nav": {

View File

@@ -29,6 +29,7 @@ import { JournalComponent } from './simple/entity-types/journal/journal.componen
import { JournalVolumeComponent } from './simple/entity-types/journal-volume/journal-volume.component';
import { JournalIssueComponent } from './simple/entity-types/journal-issue/journal-issue.component';
import { EntityComponent } from './simple/entity-types/shared/entity.component';
import { RelatedEntitiesSearchComponent } from './simple/related-entities/related-entities-search/related-entities-search.component';
@NgModule({
imports: [
@@ -61,7 +62,8 @@ import { EntityComponent } from './simple/entity-types/shared/entity.component';
GenericItemPageFieldComponent,
JournalComponent,
JournalIssueComponent,
JournalVolumeComponent
JournalVolumeComponent,
RelatedEntitiesSearchComponent
],
entryComponents: [
PublicationComponent,

View File

@@ -14,6 +14,14 @@
[fields]="['journalissue.issuedate']"
[label]="'journalissue.page.issuedate'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.title']"
[label]="'journalissue.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.identifier.issn']"
[label]="'journalissue.page.journal-issn'">
</ds-generic-item-page-field>
</div>
<div class="col-xs-12 col-md-6">
<ds-related-entities
@@ -21,6 +29,7 @@
[label]="'relationships.isSingleVolumeOf' | translate">
</ds-related-entities>
<ds-related-entities
class="mb-1 mt-1"
[entities]="publications$ | async"
[label]="'relationships.isPublicationOfJournalIssue' | translate">
</ds-related-entities>

View File

@@ -14,6 +14,10 @@
[fields]="['journal.publisher']"
[label]="'journal.page.publisher'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.contributor.editor']"
[label]="'journal.page.editor'">
</ds-generic-item-page-field>
</div>
<div class="col-xs-12 col-md-6">
<ds-related-entities
@@ -30,4 +34,9 @@
</a>
</div>
</div>
<div class="mt-5 w-100">
<ds-related-entities-search [item]="item"
[relationType]="'isJournalOfPublication'">
</ds-related-entities-search>
</div>
</div>

View File

@@ -50,12 +50,9 @@
</a>
</div>
</div>
<div class="pt-2 w-100">
<ds-filtered-search-page
[fixedFilterQuery]="fixedFilterQuery"
[fixedFilter$]="fixedFilter$"
[searchEnabled]="false"
[sideBarWidth]="4">
</ds-filtered-search-page>
<div class="mt-5 w-100">
<ds-related-entities-search [item]="item"
[relationType]="'isAuthorOfPublication'">
</ds-related-entities-search>
</div>
</div>

View File

@@ -7,6 +7,18 @@
<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"
[fields]="['journal.title']"
[label]="'publication.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.identifier.issn']"
[label]="'publication.page.journal-issn'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalvolume.identifier.name']"
[label]="'publication.page.volume-title'">
</ds-generic-item-page-field>
</div>
<div class="col-xs-12 col-md-6">
<ds-related-entities
@@ -26,6 +38,15 @@
[label]="'relationships.isJournalIssueOf' | translate">
</ds-related-entities>
<ds-item-page-abstract-field [item]="item"></ds-item-page-abstract-field>
<ds-generic-item-page-field [item]="item"
[fields]="['dc.subject']"
[separator]="','"
[label]="'item.page.subject'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[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>
<div>

View File

@@ -0,0 +1,6 @@
<ds-filtered-search-page
[fixedFilterQuery]="fixedFilter"
[fixedFilter$]="fixedFilter$"
[searchEnabled]="searchEnabled"
[sideBarWidth]="sideBarWidth">
</ds-filtered-search-page>

View File

@@ -0,0 +1,56 @@
import { RelatedEntitiesSearchComponent } from './related-entities-search.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule } from '@ngx-translate/core';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
import { Item } from '../../../../core/shared/item.model';
describe('RelatedEntitiesSearchComponent', () => {
let comp: RelatedEntitiesSearchComponent;
let fixture: ComponentFixture<RelatedEntitiesSearchComponent>;
let fixedFilterService: SearchFixedFilterService;
const mockItem = Object.assign(new Item(), {
id: 'id1'
});
const mockRelationType = 'publicationsOfAuthor';
const mockRelationEntityType = 'publication';
const mockFilter= `f.${mockRelationType}=${mockItem.id}`;
const fixedFilterServiceStub = {
getFilterByRelation: () => mockFilter
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
declarations: [RelatedEntitiesSearchComponent],
providers: [
{ provide: SearchFixedFilterService, useValue: fixedFilterServiceStub }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RelatedEntitiesSearchComponent);
comp = fixture.componentInstance;
fixedFilterService = (comp as any).fixedFilterService;
comp.relationType = mockRelationType;
comp.item = mockItem;
comp.relationEntityType = mockRelationEntityType;
fixture.detectChanges();
});
it('should create a fixedFilter', () => {
expect(comp.fixedFilter).toEqual(mockFilter);
});
it('should create a fixedFilter$', () => {
comp.fixedFilter$.subscribe((fixedFilter) => {
expect(fixedFilter).toEqual(mockRelationEntityType);
})
});
});

View File

@@ -0,0 +1,59 @@
import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Item } from '../../../../core/shared/item.model';
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
import { isNotEmpty } from '../../../../shared/empty.util';
import { of } from 'rxjs/internal/observable/of';
@Component({
selector: 'ds-related-entities-search',
templateUrl: './related-entities-search.component.html'
})
export class RelatedEntitiesSearchComponent implements OnInit {
/**
* The type of relationship to fetch items for
* e.g. 'isAuthorOfPublication'
*/
@Input() relationType: string;
/**
* The item to render relationships for
*/
@Input() item: Item;
/**
* The entity type of the relationship items to be displayed
* e.g. 'publication'
* This determines the title of the search results (if search is enabled)
*/
@Input() relationEntityType: string;
/**
* Whether or not the search bar and title should be displayed (defaults to true)
* @type {boolean}
*/
@Input() searchEnabled = true;
/**
* The ratio of the sidebar's width compared to the search results (1-12) (defaults to 4)
* @type {number}
*/
@Input() sideBarWidth = 4;
fixedFilter: string;
fixedFilter$: Observable<string>;
constructor(private fixedFilterService: SearchFixedFilterService) {
}
ngOnInit(): void {
if (isNotEmpty(this.relationType) && isNotEmpty(this.item)) {
this.fixedFilter = this.fixedFilterService.getFilterByRelation(this.relationType, this.item.id);
}
if (isNotEmpty(this.relationEntityType)) {
this.fixedFilter$ = of(this.relationEntityType);
}
}
}

View File

@@ -73,4 +73,13 @@ export class SearchFixedFilterService {
return `query=relation.${relationType}:${itemUUID}`;
}
/**
* Get the filter for a relation with the item's UUID
* @param relationType The type of relation e.g. 'isAuthorOfPublication'
* @param itemUUID The item's UUID
*/
getFilterByRelation(relationType: string, itemUUID: string): string {
return `f.${relationType}=${itemUUID}`;
}
}

View File

@@ -91,7 +91,7 @@ const effects = [
SearchBooleanFilterComponent,
],
exports: [
FilteredSearchPageComponent
FilteredSearchPageComponent,
]
})