mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
w2p 51851 - finished relation display on entity pages
This commit is contained in:
@@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"item": {
|
"item": {
|
||||||
"page": {
|
"page": {
|
||||||
"author": "Author",
|
"author": "Authors",
|
||||||
"abstract": "Abstract",
|
"abstract": "Abstract",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"uri": "URI",
|
"uri": "URI",
|
||||||
@@ -45,6 +45,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"relationships": {
|
||||||
|
"isPublicationOf": "Publications",
|
||||||
|
"isProjectOf": "Projects",
|
||||||
|
"isOrgUnitOf": "Org Units",
|
||||||
|
"isAuthorOf": "Authors",
|
||||||
|
"isPersonOf": "Authors"
|
||||||
|
},
|
||||||
"person": {
|
"person": {
|
||||||
"page": {
|
"page": {
|
||||||
"jobtitle": "Job Title",
|
"jobtitle": "Job Title",
|
||||||
@@ -54,7 +61,6 @@
|
|||||||
"orcid": "ORCID",
|
"orcid": "ORCID",
|
||||||
"birthdate": "Birth Date",
|
"birthdate": "Birth Date",
|
||||||
"staffid": "Staff ID",
|
"staffid": "Staff ID",
|
||||||
"publications": "Publications",
|
|
||||||
"link": {
|
"link": {
|
||||||
"full": "Show all metadata"
|
"full": "Show all metadata"
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<div class="container" *ngVar="(itemRDObs | async) as itemRD">
|
<div class="container" *ngVar="(itemRDObs | async) as itemRD">
|
||||||
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
||||||
<div *ngIf="itemRD?.payload as item">
|
<div *ngIf="itemRD?.payload as entity">
|
||||||
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
|
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
|
||||||
<div class="simple-view-link">
|
<div class="simple-view-link">
|
||||||
<a class="btn btn-outline-primary col-4" [routerLink]="['/items/' + item.id]">
|
<a class="btn btn-outline-primary col-4" [routerLink]="['/items/' + item.id]">
|
||||||
|
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import { SharedModule } from './../shared/shared.module';
|
import { SharedModule } from './../shared/shared.module';
|
||||||
|
import { EntityPageFieldsComponent } from './simple/entity-types/shared/entity-page-fields.component';
|
||||||
import { GenericItemPageFieldComponent } from './simple/field-components/specific-field/generic/generic-item-page-field.component';
|
import { GenericItemPageFieldComponent } from './simple/field-components/specific-field/generic/generic-item-page-field.component';
|
||||||
|
|
||||||
import { ItemPageComponent } from './simple/item-page.component';
|
import { ItemPageComponent } from './simple/item-page.component';
|
||||||
@@ -19,10 +20,11 @@ import { FileSectionComponent } from './simple/field-components/file-section/fil
|
|||||||
import { CollectionsComponent } from './field-components/collections/collections.component';
|
import { CollectionsComponent } from './field-components/collections/collections.component';
|
||||||
import { FullItemPageComponent } from './full/full-item-page.component';
|
import { FullItemPageComponent } from './full/full-item-page.component';
|
||||||
import { FullFileSectionComponent } from './full/field-components/file-section/full-file-section.component';
|
import { FullFileSectionComponent } from './full/field-components/file-section/full-file-section.component';
|
||||||
import { ItemPageFieldsComponent } from './simple/entity-types/item/item-page-fields.component';
|
import { PublicationPageFieldsComponent } from './simple/entity-types/publication/publication-page-fields.component';
|
||||||
import { OrgUnitPageFieldsComponent } from './simple/entity-types/orgunit/orgunit-page-fields.component';
|
import { OrgUnitPageFieldsComponent } from './simple/entity-types/orgunit/orgunit-page-fields.component';
|
||||||
import { PersonPageFieldsComponent } from './simple/entity-types/person/person-page-fields.component';
|
import { PersonPageFieldsComponent } from './simple/entity-types/person/person-page-fields.component';
|
||||||
import { ProjectPageFieldsComponent } from './simple/entity-types/project/project-page-fields.component';
|
import { ProjectPageFieldsComponent } from './simple/entity-types/project/project-page-fields.component';
|
||||||
|
import { RelatedEntitiesComponent } from './simple/related-entities/related-entities-component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -45,14 +47,16 @@ import { ProjectPageFieldsComponent } from './simple/entity-types/project/projec
|
|||||||
FileSectionComponent,
|
FileSectionComponent,
|
||||||
CollectionsComponent,
|
CollectionsComponent,
|
||||||
FullFileSectionComponent,
|
FullFileSectionComponent,
|
||||||
ItemPageFieldsComponent,
|
PublicationPageFieldsComponent,
|
||||||
ProjectPageFieldsComponent,
|
ProjectPageFieldsComponent,
|
||||||
OrgUnitPageFieldsComponent,
|
OrgUnitPageFieldsComponent,
|
||||||
PersonPageFieldsComponent,
|
PersonPageFieldsComponent,
|
||||||
|
RelatedEntitiesComponent,
|
||||||
|
EntityPageFieldsComponent,
|
||||||
GenericItemPageFieldComponent
|
GenericItemPageFieldComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
ItemPageFieldsComponent,
|
PublicationPageFieldsComponent,
|
||||||
ProjectPageFieldsComponent,
|
ProjectPageFieldsComponent,
|
||||||
OrgUnitPageFieldsComponent,
|
OrgUnitPageFieldsComponent,
|
||||||
PersonPageFieldsComponent
|
PersonPageFieldsComponent
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
|
||||||
import {
|
|
||||||
DEFAULT_ENTITY_TYPE,
|
|
||||||
rendersEntityType
|
|
||||||
} from '../../../../shared/entities/entity-type-decorator';
|
|
||||||
import { ElementViewMode } from '../../../../shared/view-mode';
|
|
||||||
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
|
||||||
|
|
||||||
@rendersEntityType('Item', ElementViewMode.Full)
|
|
||||||
@rendersEntityType(DEFAULT_ENTITY_TYPE, ElementViewMode.Full)
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-item-page-fields',
|
|
||||||
styleUrls: ['./item-page-fields.component.scss'],
|
|
||||||
templateUrl: './item-page-fields.component.html',
|
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
||||||
})
|
|
||||||
export class ItemPageFieldsComponent {
|
|
||||||
|
|
||||||
constructor(@Inject(ITEM) public item: Item) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -24,6 +24,18 @@
|
|||||||
</ds-generic-item-page-field>
|
</ds-generic-item-page-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-md-6">
|
<div class="col-xs-12 col-md-6">
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="people$ | async"
|
||||||
|
[label]="'relationships.isPersonOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="projects$ | async"
|
||||||
|
[label]="'relationships.isProjectOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="publications$ | async"
|
||||||
|
[label]="'relationships.isPublicationOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
<ds-generic-item-page-field [item]="item"
|
<ds-generic-item-page-field [item]="item"
|
||||||
[fields]="['orgunit.identifier.description']"
|
[fields]="['orgunit.identifier.description']"
|
||||||
[label]="'orgunit.page.description'">
|
[label]="'orgunit.page.description'">
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
||||||
import { ElementViewMode } from '../../../../shared/view-mode';
|
import { ElementViewMode } from '../../../../shared/view-mode';
|
||||||
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
||||||
|
import {
|
||||||
|
EntityPageFieldsComponent, filterRelationsByTypeLabel,
|
||||||
|
relationsToItems
|
||||||
|
} from '../shared/entity-page-fields.component';
|
||||||
|
|
||||||
@rendersEntityType('OrgUnit', ElementViewMode.Full)
|
@rendersEntityType('OrgUnit', ElementViewMode.Full)
|
||||||
@Component({
|
@Component({
|
||||||
@@ -10,9 +16,34 @@ import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.
|
|||||||
styleUrls: ['./orgunit-page-fields.component.scss'],
|
styleUrls: ['./orgunit-page-fields.component.scss'],
|
||||||
templateUrl: './orgunit-page-fields.component.html'
|
templateUrl: './orgunit-page-fields.component.html'
|
||||||
})
|
})
|
||||||
export class OrgUnitPageFieldsComponent {
|
export class OrgUnitPageFieldsComponent extends EntityPageFieldsComponent implements OnInit {
|
||||||
|
|
||||||
constructor(@Inject(ITEM) public item: Item) {
|
people$: Observable<Item[]>;
|
||||||
|
projects$: Observable<Item[]>;
|
||||||
|
publications$: Observable<Item[]>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(ITEM) public item: Item,
|
||||||
|
private ids: ItemDataService
|
||||||
|
) {
|
||||||
|
super(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
ngOnInit(): void {
|
||||||
|
super.ngOnInit();
|
||||||
|
|
||||||
|
this.people$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isPersonOfOrgUnit'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.projects$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isProjectOfOrgUnit'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.publications$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isPublicationOfOrgUnit'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
@@ -24,13 +24,18 @@
|
|||||||
</ds-generic-item-page-field>
|
</ds-generic-item-page-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-md-6">
|
<div class="col-xs-12 col-md-6">
|
||||||
<ng-container *ngVar="(publications$ | async) as publications">
|
<ds-related-entities
|
||||||
<ds-metadata-field-wrapper *ngIf="publications && publications.length > 0" [label]="'person.page.publications' | translate">
|
[entities]="publications$ | async"
|
||||||
<span *ngFor="let publ of publications; let last=last;">
|
[label]="'relationships.isPublicationOf' | translate">
|
||||||
{{publ.name}}<span *ngIf="!last" [innerHTML]="separator"></span>
|
</ds-related-entities>
|
||||||
</span>
|
<ds-related-entities
|
||||||
</ds-metadata-field-wrapper>
|
[entities]="projects$ | async"
|
||||||
</ng-container>
|
[label]="'relationships.isProjectOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="orgunits$ | async"
|
||||||
|
[label]="'relationships.isOrgUnitOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
<ds-generic-item-page-field [item]="item"
|
<ds-generic-item-page-field [item]="item"
|
||||||
[fields]="['person.identifier.jobtitle']"
|
[fields]="['person.identifier.jobtitle']"
|
||||||
[label]="'person.page.jobtitle'">
|
[label]="'person.page.jobtitle'">
|
||||||
|
@@ -1,67 +1,14 @@
|
|||||||
import { Component, Inject, OnInit } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { distinctUntilChanged, filter, flatMap, map } from 'rxjs/operators';
|
|
||||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
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/entities/relationship-type.model';
|
|
||||||
import { Relationship } from '../../../../core/shared/entities/relationship.model';
|
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { getRemoteDataPayload } from '../../../../core/shared/operators';
|
|
||||||
import { hasValue } from '../../../../shared/empty.util';
|
|
||||||
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
||||||
import { ElementViewMode } from '../../../../shared/view-mode';
|
|
||||||
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
||||||
|
import { ElementViewMode } from '../../../../shared/view-mode';
|
||||||
const compareArraysUsing = <T>(mapFn: (t: T) => any) =>
|
import {
|
||||||
(a: T[], b: T[]): boolean => {
|
EntityPageFieldsComponent, filterRelationsByTypeLabel,
|
||||||
if (!Array.isArray(a) || ! Array.isArray(b)) {
|
relationsToItems
|
||||||
return false
|
} from '../shared/entity-page-fields.component';
|
||||||
}
|
|
||||||
|
|
||||||
const aIds = a.map(mapFn);
|
|
||||||
const bIds = b.map(mapFn);
|
|
||||||
|
|
||||||
return aIds.length === bIds.length &&
|
|
||||||
aIds.every((e) => bIds.includes(e)) &&
|
|
||||||
bIds.every((e) => aIds.includes(e));
|
|
||||||
};
|
|
||||||
|
|
||||||
const compareArraysUsingIds = <T extends { id: string }>() =>
|
|
||||||
compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined);
|
|
||||||
|
|
||||||
const filterRelationsByTypeLabel = (label: string) =>
|
|
||||||
(source: Observable<[Relationship[], RelationshipType[]]>): Observable<Relationship[]> =>
|
|
||||||
source.pipe(
|
|
||||||
map(([relsCurrentPage, relTypesCurrentPage]) =>
|
|
||||||
relsCurrentPage.filter((rel: Relationship, idx: number) =>
|
|
||||||
hasValue(relTypesCurrentPage[idx]) && (relTypesCurrentPage[idx].leftLabel === label ||
|
|
||||||
relTypesCurrentPage[idx].rightLabel === label)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
distinctUntilChanged(compareArraysUsingIds())
|
|
||||||
);
|
|
||||||
|
|
||||||
const relationsToItems = (thisId: string, ids: ItemDataService) =>
|
|
||||||
(source: Observable<Relationship[]>): Observable<Item[]> =>
|
|
||||||
source.pipe(
|
|
||||||
flatMap((rels: Relationship[]) =>
|
|
||||||
Observable.zip(
|
|
||||||
...rels.map((rel: Relationship) => {
|
|
||||||
let queryId = rel.leftId;
|
|
||||||
if (rel.leftId === thisId) {
|
|
||||||
queryId = rel.rightId;
|
|
||||||
}
|
|
||||||
return ids.findById(queryId);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
),
|
|
||||||
map((arr: Array<RemoteData<Item>>) =>
|
|
||||||
arr
|
|
||||||
.filter((d: RemoteData<Item>) => d.hasSucceeded)
|
|
||||||
.map((d: RemoteData<Item>) => d.payload)),
|
|
||||||
distinctUntilChanged(compareArraysUsingIds()),
|
|
||||||
);
|
|
||||||
|
|
||||||
@rendersEntityType('Person', ElementViewMode.Full)
|
@rendersEntityType('Person', ElementViewMode.Full)
|
||||||
@Component({
|
@Component({
|
||||||
@@ -69,7 +16,7 @@ const relationsToItems = (thisId: string, ids: ItemDataService) =>
|
|||||||
styleUrls: ['./person-page-fields.component.scss'],
|
styleUrls: ['./person-page-fields.component.scss'],
|
||||||
templateUrl: './person-page-fields.component.html'
|
templateUrl: './person-page-fields.component.html'
|
||||||
})
|
})
|
||||||
export class PersonPageFieldsComponent implements OnInit {
|
export class PersonPageFieldsComponent extends EntityPageFieldsComponent {
|
||||||
publications$: Observable<Item[]>;
|
publications$: Observable<Item[]>;
|
||||||
projects$: Observable<Item[]>;
|
projects$: Observable<Item[]>;
|
||||||
orgUnits$: Observable<Item[]>;
|
orgUnits$: Observable<Item[]>;
|
||||||
@@ -77,46 +24,25 @@ export class PersonPageFieldsComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(ITEM) public item: Item,
|
@Inject(ITEM) public item: Item,
|
||||||
private ids: ItemDataService
|
private ids: ItemDataService
|
||||||
) {}
|
) {
|
||||||
|
super(item);
|
||||||
|
}
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
const relsCurrentPage$ = this.item.relationships.pipe(
|
super.ngOnInit();
|
||||||
filter((rd: RemoteData<PaginatedList<Relationship>>) => rd.hasSucceeded),
|
|
||||||
getRemoteDataPayload(),
|
|
||||||
map((pl: PaginatedList<Relationship>) => pl.page),
|
|
||||||
distinctUntilChanged(compareArraysUsingIds())
|
|
||||||
);
|
|
||||||
|
|
||||||
const relTypesCurrentPage$ = relsCurrentPage$.pipe(
|
this.publications$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
flatMap((rels: Relationship[]) =>
|
|
||||||
Observable.zip(
|
|
||||||
...rels.map((rel: Relationship) => rel.relationshipType),
|
|
||||||
(...arr: Array<RemoteData<RelationshipType>>) =>
|
|
||||||
arr.map((d: RemoteData<RelationshipType>) => d.payload)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
distinctUntilChanged(compareArraysUsingIds())
|
|
||||||
);
|
|
||||||
|
|
||||||
const resolvedRelsAndTypes$ = Observable.combineLatest(
|
|
||||||
relsCurrentPage$,
|
|
||||||
relTypesCurrentPage$
|
|
||||||
);
|
|
||||||
|
|
||||||
this.publications$ = resolvedRelsAndTypes$.pipe(
|
|
||||||
filterRelationsByTypeLabel('isPublicationOfAuthor'),
|
filterRelationsByTypeLabel('isPublicationOfAuthor'),
|
||||||
relationsToItems(this.item.id, this.ids)
|
relationsToItems(this.item.id, this.ids)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.projects$ = resolvedRelsAndTypes$.pipe(
|
this.projects$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
filterRelationsByTypeLabel('isProjectOfPerson'),
|
filterRelationsByTypeLabel('isProjectOfPerson'),
|
||||||
relationsToItems(this.item.id, this.ids)
|
relationsToItems(this.item.id, this.ids)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.orgUnits$ = resolvedRelsAndTypes$.pipe(
|
this.orgUnits$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
filterRelationsByTypeLabel('isOrgUnitOfPerson'),
|
filterRelationsByTypeLabel('isOrgUnitOfPerson'),
|
||||||
relationsToItems(this.item.id, this.ids)
|
relationsToItems(this.item.id, this.ids)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,18 @@
|
|||||||
</ds-generic-item-page-field>
|
</ds-generic-item-page-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-md-6">
|
<div class="col-xs-12 col-md-6">
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="people$ | async"
|
||||||
|
[label]="'relationships.isPersonOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="publications$ | async"
|
||||||
|
[label]="'relationships.isPublicationOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="orgunits$ | async"
|
||||||
|
[label]="'relationships.isOrgUnitOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
<ds-generic-item-page-field [item]="item"
|
<ds-generic-item-page-field [item]="item"
|
||||||
[fields]="['project.identifier.description']"
|
[fields]="['project.identifier.description']"
|
||||||
[label]="'project.page.description'">
|
[label]="'project.page.description'">
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
import { rendersEntityType } from '../../../../shared/entities/entity-type-decorator';
|
||||||
import { ElementViewMode } from '../../../../shared/view-mode';
|
import { ElementViewMode } from '../../../../shared/view-mode';
|
||||||
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
||||||
|
import {
|
||||||
|
EntityPageFieldsComponent, filterRelationsByTypeLabel,
|
||||||
|
relationsToItems
|
||||||
|
} from '../shared/entity-page-fields.component';
|
||||||
|
|
||||||
@rendersEntityType('Project', ElementViewMode.Full)
|
@rendersEntityType('Project', ElementViewMode.Full)
|
||||||
@Component({
|
@Component({
|
||||||
@@ -10,9 +16,34 @@ import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.
|
|||||||
styleUrls: ['./project-page-fields.component.scss'],
|
styleUrls: ['./project-page-fields.component.scss'],
|
||||||
templateUrl: './project-page-fields.component.html'
|
templateUrl: './project-page-fields.component.html'
|
||||||
})
|
})
|
||||||
export class ProjectPageFieldsComponent {
|
export class ProjectPageFieldsComponent extends EntityPageFieldsComponent implements OnInit {
|
||||||
|
people$: Observable<Item[]>;
|
||||||
|
publications$: Observable<Item[]>;
|
||||||
|
orgUnits$: Observable<Item[]>;
|
||||||
|
|
||||||
constructor(@Inject(ITEM) public item: Item) {
|
constructor(
|
||||||
|
@Inject(ITEM) public item: Item,
|
||||||
|
private ids: ItemDataService
|
||||||
|
) {
|
||||||
|
super(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
super.ngOnInit();
|
||||||
|
|
||||||
|
this.people$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isPersonOfProject'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.publications$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isPublicationOfProject'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.orgUnits$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isOrgUnitOfProject'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,21 @@
|
|||||||
</ds-metadata-field-wrapper>
|
</ds-metadata-field-wrapper>
|
||||||
<ds-item-page-file-section [item]="item"></ds-item-page-file-section>
|
<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-date-field [item]="item"></ds-item-page-date-field>
|
||||||
<ds-item-page-author-field [item]="item"></ds-item-page-author-field>
|
<ds-item-page-author-field *ngIf="!(authors$ | async)" [item]="item"></ds-item-page-author-field>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-md-6">
|
<div class="col-xs-12 col-md-6">
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="authors$ | async"
|
||||||
|
[label]="'relationships.isAuthorOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="projects$ | async"
|
||||||
|
[label]="'relationships.isProjectOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
|
<ds-related-entities
|
||||||
|
[entities]="orgunits$ | async"
|
||||||
|
[label]="'relationships.isOrgUnitOf' | translate">
|
||||||
|
</ds-related-entities>
|
||||||
<ds-item-page-abstract-field [item]="item"></ds-item-page-abstract-field>
|
<ds-item-page-abstract-field [item]="item"></ds-item-page-abstract-field>
|
||||||
<ds-item-page-uri-field [item]="item"></ds-item-page-uri-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-collections [item]="item"></ds-item-page-collections>
|
@@ -0,0 +1,54 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||||
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
import {
|
||||||
|
DEFAULT_ENTITY_TYPE,
|
||||||
|
rendersEntityType
|
||||||
|
} from '../../../../shared/entities/entity-type-decorator';
|
||||||
|
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
||||||
|
import { ElementViewMode } from '../../../../shared/view-mode';
|
||||||
|
import {
|
||||||
|
EntityPageFieldsComponent,
|
||||||
|
filterRelationsByTypeLabel, relationsToItems
|
||||||
|
} from '../shared/entity-page-fields.component';
|
||||||
|
|
||||||
|
@rendersEntityType('Publication', ElementViewMode.Full)
|
||||||
|
@rendersEntityType(DEFAULT_ENTITY_TYPE, ElementViewMode.Full)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-publication-page-fields',
|
||||||
|
styleUrls: ['./publication-page-fields.component.scss'],
|
||||||
|
templateUrl: './publication-page-fields.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class PublicationPageFieldsComponent extends EntityPageFieldsComponent implements OnInit {
|
||||||
|
authors$: Observable<Item[]>;
|
||||||
|
projects$: Observable<Item[]>;
|
||||||
|
orgUnits$: Observable<Item[]>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(ITEM) public item: Item,
|
||||||
|
private ids: ItemDataService
|
||||||
|
) {
|
||||||
|
super(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
super.ngOnInit();
|
||||||
|
|
||||||
|
this.authors$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isAuthorOfPublication'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.projects$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isProjectOfPublication'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.orgUnits$ = this.resolvedRelsAndTypes$.pipe(
|
||||||
|
filterRelationsByTypeLabel('isOrgUnitOfPublication'),
|
||||||
|
relationsToItems(this.item.id, this.ids)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,100 @@
|
|||||||
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
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/entities/relationship-type.model';
|
||||||
|
import { Relationship } from '../../../../core/shared/entities/relationship.model';
|
||||||
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
import { getRemoteDataPayload } from '../../../../core/shared/operators';
|
||||||
|
import { hasValue } from '../../../../shared/empty.util';
|
||||||
|
import { ITEM } from '../../../../shared/entities/switcher/entity-type-switcher.component';
|
||||||
|
|
||||||
|
const compareArraysUsing = <T>(mapFn: (t: T) => any) =>
|
||||||
|
(a: T[], b: T[]): boolean => {
|
||||||
|
if (!Array.isArray(a) || ! Array.isArray(b)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const aIds = a.map(mapFn);
|
||||||
|
const bIds = b.map(mapFn);
|
||||||
|
|
||||||
|
return aIds.length === bIds.length &&
|
||||||
|
aIds.every((e) => bIds.includes(e)) &&
|
||||||
|
bIds.every((e) => aIds.includes(e));
|
||||||
|
};
|
||||||
|
|
||||||
|
const compareArraysUsingIds = <T extends { id: string }>() =>
|
||||||
|
compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined);
|
||||||
|
|
||||||
|
export const filterRelationsByTypeLabel = (label: string) =>
|
||||||
|
(source: Observable<[Relationship[], RelationshipType[]]>): Observable<Relationship[]> =>
|
||||||
|
source.pipe(
|
||||||
|
map(([relsCurrentPage, relTypesCurrentPage]) =>
|
||||||
|
relsCurrentPage.filter((rel: Relationship, idx: number) =>
|
||||||
|
hasValue(relTypesCurrentPage[idx]) && (relTypesCurrentPage[idx].leftLabel === label ||
|
||||||
|
relTypesCurrentPage[idx].rightLabel === label)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
distinctUntilChanged(compareArraysUsingIds())
|
||||||
|
);
|
||||||
|
|
||||||
|
export const relationsToItems = (thisId: string, ids: ItemDataService) =>
|
||||||
|
(source: Observable<Relationship[]>): Observable<Item[]> =>
|
||||||
|
source.pipe(
|
||||||
|
flatMap((rels: Relationship[]) =>
|
||||||
|
Observable.zip(
|
||||||
|
...rels.map((rel: Relationship) => {
|
||||||
|
let queryId = rel.leftId;
|
||||||
|
if (rel.leftId === thisId) {
|
||||||
|
queryId = rel.rightId;
|
||||||
|
}
|
||||||
|
return ids.findById(queryId);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
),
|
||||||
|
map((arr: Array<RemoteData<Item>>) =>
|
||||||
|
arr
|
||||||
|
.filter((d: RemoteData<Item>) => d.hasSucceeded)
|
||||||
|
.map((d: RemoteData<Item>) => d.payload)),
|
||||||
|
distinctUntilChanged(compareArraysUsingIds()),
|
||||||
|
);
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-entity-page-fields',
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
export class EntityPageFieldsComponent implements OnInit {
|
||||||
|
resolvedRelsAndTypes$: Observable<[Relationship[], RelationshipType[]]>
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(ITEM) public item: Item
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
const relsCurrentPage$ = this.item.relationships.pipe(
|
||||||
|
filter((rd: RemoteData<PaginatedList<Relationship>>) => rd.hasSucceeded),
|
||||||
|
getRemoteDataPayload(),
|
||||||
|
map((pl: PaginatedList<Relationship>) => pl.page),
|
||||||
|
distinctUntilChanged(compareArraysUsingIds())
|
||||||
|
);
|
||||||
|
|
||||||
|
const relTypesCurrentPage$ = relsCurrentPage$.pipe(
|
||||||
|
flatMap((rels: Relationship[]) =>
|
||||||
|
Observable.zip(
|
||||||
|
...rels.map((rel: Relationship) => rel.relationshipType),
|
||||||
|
(...arr: Array<RemoteData<RelationshipType>>) =>
|
||||||
|
arr.map((d: RemoteData<RelationshipType>) => d.payload)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
distinctUntilChanged(compareArraysUsingIds())
|
||||||
|
);
|
||||||
|
|
||||||
|
this.resolvedRelsAndTypes$ = Observable.combineLatest(
|
||||||
|
relsCurrentPage$,
|
||||||
|
relTypesCurrentPage$
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import * as viewMode from '../../../shared/view-mode';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-related-entities',
|
||||||
|
styleUrls: ['./related-entities.component.scss'],
|
||||||
|
templateUrl: './related-entities.component.html'
|
||||||
|
})
|
||||||
|
export class RelatedEntitiesComponent {
|
||||||
|
@Input() entities: Item[];
|
||||||
|
@Input() label: string;
|
||||||
|
ElementViewMode = viewMode.ElementViewMode
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
<ds-metadata-field-wrapper *ngIf="entities && entities.length > 0" [label]="label">
|
||||||
|
<ds-entity-type-switcher *ngFor="let entity of entities"
|
||||||
|
[object]="entity" [viewMode]="ElementViewMode.SetElement">
|
||||||
|
</ds-entity-type-switcher>
|
||||||
|
</ds-metadata-field-wrapper>
|
@@ -3,7 +3,7 @@
|
|||||||
[routerLink]="['/items/' + item.id]" class="lead"
|
[routerLink]="['/items/' + item.id]" class="lead"
|
||||||
[innerHTML]="getFirstValue('orgunit.identifier.name')"></a>
|
[innerHTML]="getFirstValue('orgunit.identifier.name')"></a>
|
||||||
<span class="text-muted">
|
<span class="text-muted">
|
||||||
<ds-truncatable-part [id]="item.id" [minLines]="1">
|
<ds-truncatable-part [id]="item.id" [minLines]="3">
|
||||||
<span *ngIf="item.filterMetadata(['orgunit.identifier.description']).length > 0"
|
<span *ngIf="item.filterMetadata(['orgunit.identifier.description']).length > 0"
|
||||||
class="item-list-authors">
|
class="item-list-authors">
|
||||||
<ds-truncatable-part [id]="item.id" [minLines]="3"><span
|
<ds-truncatable-part [id]="item.id" [minLines]="3"><span
|
||||||
|
@@ -4,10 +4,10 @@
|
|||||||
[innerHTML]="getFirstValue('dc.title')"></a>
|
[innerHTML]="getFirstValue('dc.title')"></a>
|
||||||
<span class="text-muted">
|
<span class="text-muted">
|
||||||
<ds-truncatable-part [id]="item.id" [minLines]="1">
|
<ds-truncatable-part [id]="item.id" [minLines]="1">
|
||||||
(<span *ngIf="item.findMetadata('dc.publisher')" class="item-list-publisher"
|
<ng-container *ngIf="item.findMetadata('dc.publisher') || item.findMetadata('dc.date.issued')">(<span class="item-list-publisher"
|
||||||
[innerHTML]="getFirstValue('dc.publisher')">, </span><span
|
[innerHTML]="getFirstValue('dc.publisher')">, </span><span
|
||||||
*ngIf="item.findMetadata('dc.date.issued')" class="item-list-date"
|
*ngIf="item.findMetadata('dc.date.issued')" class="item-list-date"
|
||||||
[innerHTML]="getFirstValue('dc.date.issued')"></span>)
|
[innerHTML]="getFirstValue('dc.date.issued')"></span>)</ng-container>
|
||||||
<span *ngIf="item.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']).length > 0"
|
<span *ngIf="item.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']).length > 0"
|
||||||
class="item-list-authors">
|
class="item-list-authors">
|
||||||
<span *ngFor="let author of getValues(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">
|
<span *ngFor="let author of getValues(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">
|
@@ -3,13 +3,13 @@ import { DEFAULT_ENTITY_TYPE, rendersEntityType } from '../../../../entities/ent
|
|||||||
import { ElementViewMode } from '../../../../view-mode';
|
import { ElementViewMode } from '../../../../view-mode';
|
||||||
import { EntitySearchResultComponent } from '../entity-search-result-component';
|
import { EntitySearchResultComponent } from '../entity-search-result-component';
|
||||||
|
|
||||||
@rendersEntityType('Item', ElementViewMode.SetElement)
|
@rendersEntityType('Publication', ElementViewMode.SetElement)
|
||||||
@rendersEntityType(DEFAULT_ENTITY_TYPE, ElementViewMode.SetElement)
|
@rendersEntityType(DEFAULT_ENTITY_TYPE, ElementViewMode.SetElement)
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-list-element',
|
selector: 'ds-publication-list-element',
|
||||||
styleUrls: ['./item-list-element.component.scss'],
|
styleUrls: ['./publication-list-element.component.scss'],
|
||||||
templateUrl: './item-list-element.component.html'
|
templateUrl: './publication-list-element.component.html'
|
||||||
})
|
})
|
||||||
|
|
||||||
export class ItemListElementComponent extends EntitySearchResultComponent {
|
export class PublicationListElementComponent extends EntitySearchResultComponent {
|
||||||
}
|
}
|
@@ -10,7 +10,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { NgxPaginationModule } from 'ngx-pagination';
|
import { NgxPaginationModule } from 'ngx-pagination';
|
||||||
import { EntityTypeSwitcherComponent } from './entities/switcher/entity-type-switcher.component';
|
import { EntityTypeSwitcherComponent } from './entities/switcher/entity-type-switcher.component';
|
||||||
import { EntitySearchResultComponent } from './object-list/item-list-element/entity-types/entity-search-result-component';
|
import { EntitySearchResultComponent } from './object-list/item-list-element/entity-types/entity-search-result-component';
|
||||||
import { ItemListElementComponent } from './object-list/item-list-element/entity-types/item/item-list-element.component';
|
import { PublicationListElementComponent } from './object-list/item-list-element/entity-types/publication/publication-list-element.component';
|
||||||
import { OrgUnitListElementComponent } from './object-list/item-list-element/entity-types/orgunit/orgunit-list-element.component';
|
import { OrgUnitListElementComponent } from './object-list/item-list-element/entity-types/orgunit/orgunit-list-element.component';
|
||||||
import { PersonListElementComponent } from './object-list/item-list-element/entity-types/person/person-list-element.component';
|
import { PersonListElementComponent } from './object-list/item-list-element/entity-types/person/person-list-element.component';
|
||||||
import { ProjectListElementComponent } from './object-list/item-list-element/entity-types/project/project-list-element.component';
|
import { ProjectListElementComponent } from './object-list/item-list-element/entity-types/project/project-list-element.component';
|
||||||
@@ -109,7 +109,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
CollectionGridElementComponent,
|
CollectionGridElementComponent,
|
||||||
CommunityGridElementComponent,
|
CommunityGridElementComponent,
|
||||||
SearchResultGridElementComponent,
|
SearchResultGridElementComponent,
|
||||||
ItemListElementComponent,
|
PublicationListElementComponent,
|
||||||
PersonListElementComponent,
|
PersonListElementComponent,
|
||||||
OrgUnitListElementComponent,
|
OrgUnitListElementComponent,
|
||||||
ProjectListElementComponent
|
ProjectListElementComponent
|
||||||
|
Reference in New Issue
Block a user