mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
74199: Admin search dialogs - sidebar search list element implementations - intermediate commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
|
@listableObjectComponent('JournalIssueSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-journal-issue-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "JournalIssue" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class JournalIssueSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
/**
|
||||||
|
* Get the description of the Journal Issue by returning its volume number(s) and/or issue number(s)
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
const volumeNumbers = this.allMetadataValues(['publicationvolume.volumeNumber']);
|
||||||
|
const issueNumbers = this.allMetadataValues(['publicationissue.issueNumber']);
|
||||||
|
let description = '';
|
||||||
|
if (isNotEmpty(volumeNumbers)) {
|
||||||
|
description += volumeNumbers.join(', ');
|
||||||
|
}
|
||||||
|
if (isNotEmpty(description) && isNotEmpty(issueNumbers)) {
|
||||||
|
description += ' - ';
|
||||||
|
}
|
||||||
|
if (isNotEmpty(issueNumbers)) {
|
||||||
|
description += issueNumbers.join(', ');
|
||||||
|
}
|
||||||
|
return this.undefinedIfEmpty(description);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
|
@listableObjectComponent('JournalVolumeSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-journal-volume-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "JournalVolume" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class JournalVolumeSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
/**
|
||||||
|
* Get the description of the Journal Volume by returning the journal title and volume number(s) (between parentheses)
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
const titles = this.allMetadataValues(['journal.title']);
|
||||||
|
const numbers = this.allMetadataValues(['publicationvolume.volumeNumber']);
|
||||||
|
let description = '';
|
||||||
|
if (isNotEmpty(titles)) {
|
||||||
|
description += titles.join(', ');
|
||||||
|
}
|
||||||
|
if (isNotEmpty(numbers)) {
|
||||||
|
if (isNotEmpty(description)) {
|
||||||
|
description += ' ';
|
||||||
|
}
|
||||||
|
description += numbers.map((n) => `(${n})`).join(' ');
|
||||||
|
}
|
||||||
|
return this.undefinedIfEmpty(description);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,31 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
|
@listableObjectComponent('JournalSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-journal-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "Journal" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class JournalSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
/**
|
||||||
|
* Get the description of the Journal by returning its ISSN(s)
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
const issns = this.allMetadataValues(['creativeworkseries.issn']);
|
||||||
|
let description = '';
|
||||||
|
if (isNotEmpty(issns)) {
|
||||||
|
description += issns.join(', ');
|
||||||
|
}
|
||||||
|
return this.undefinedIfEmpty(description);
|
||||||
|
}
|
||||||
|
}
|
@@ -18,6 +18,9 @@ import { JournalIssueSearchResultListElementComponent } from './item-list-elemen
|
|||||||
import { JournalVolumeSearchResultListElementComponent } from './item-list-elements/search-result-list-elements/journal-volume/journal-volume-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 { 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';
|
import { JournalVolumeSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component';
|
||||||
|
import { JournalVolumeSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/journal-volume/journal-volume-sidebar-search-list-element.component';
|
||||||
|
import { JournalIssueSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/journal-issue/journal-issue-sidebar-search-list-element.component';
|
||||||
|
import { JournalSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/journal/journal-sidebar-search-list-element.component';
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
JournalComponent,
|
JournalComponent,
|
||||||
@@ -34,7 +37,10 @@ const ENTRY_COMPONENTS = [
|
|||||||
JournalVolumeSearchResultListElementComponent,
|
JournalVolumeSearchResultListElementComponent,
|
||||||
JournalIssueSearchResultGridElementComponent,
|
JournalIssueSearchResultGridElementComponent,
|
||||||
JournalVolumeSearchResultGridElementComponent,
|
JournalVolumeSearchResultGridElementComponent,
|
||||||
JournalSearchResultGridElementComponent
|
JournalSearchResultGridElementComponent,
|
||||||
|
JournalVolumeSidebarSearchListElementComponent,
|
||||||
|
JournalIssueSidebarSearchListElementComponent,
|
||||||
|
JournalSidebarSearchListElementComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
|
@listableObjectComponent('OrgUnitSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-org-unit-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "OrgUnit" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class OrgUnitSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
/**
|
||||||
|
* Get the title of the Org Unit by returning its legal name
|
||||||
|
*/
|
||||||
|
getTitle(): string {
|
||||||
|
return this.firstMetadataValue('organization.legalName');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of the Org Unit by returning its dc.description
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
return this.firstMetadataValue('dc.description');
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
|
||||||
|
import { LinkService } from '../../../../../core/cache/builders/link.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
@listableObjectComponent('PersonSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-person-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "Person" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class PersonSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
constructor(protected truncatableService: TruncatableService,
|
||||||
|
protected linkService: LinkService,
|
||||||
|
protected translateService: TranslateService) {
|
||||||
|
super(truncatableService, linkService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the Person by returning a combination of its family name and given name (or "No name found")
|
||||||
|
*/
|
||||||
|
getTitle(): string {
|
||||||
|
const familyName = this.firstMetadataValue('person.familyName');
|
||||||
|
const givenName = this.firstMetadataValue('person.givenName');
|
||||||
|
let title = '';
|
||||||
|
if (isNotEmpty(familyName)) {
|
||||||
|
title = familyName;
|
||||||
|
}
|
||||||
|
if (isNotEmpty(title)) {
|
||||||
|
title += ', ';
|
||||||
|
}
|
||||||
|
if (isNotEmpty(givenName)) {
|
||||||
|
title += givenName;
|
||||||
|
}
|
||||||
|
return this.defaultIfEmpty(title, this.translateService.instant('person.listelement.no-title'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of the Person by returning its job title(s)
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
const titles = this.allMetadataValues(['person.jobTitle']);
|
||||||
|
let description = '';
|
||||||
|
if (isNotEmpty(titles)) {
|
||||||
|
description += titles.join(', ');
|
||||||
|
}
|
||||||
|
return this.undefinedIfEmpty(description);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SidebarSearchListElementComponent } from '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { isNotEmpty } from '../../../../../shared/empty.util';
|
||||||
|
|
||||||
|
@listableObjectComponent('ProjectSearchResult', ViewMode.ListElement, Context.SideBarSearchModal)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-project-sidebar-search-list-element',
|
||||||
|
templateUrl: '../../../../../shared/object-list/sidebar-search-list-element/sidebar-search-list-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "Project" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
|
export class ProjectSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
/**
|
||||||
|
* Projects currently don't support a description
|
||||||
|
*/
|
||||||
|
getDescription(): string {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,9 @@ import { NameVariantModalComponent } from './submission/name-variant-modal/name-
|
|||||||
import { OrgUnitInputSuggestionsComponent } from './submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component';
|
import { OrgUnitInputSuggestionsComponent } from './submission/item-list-elements/org-unit/org-unit-suggestions/org-unit-input-suggestions.component';
|
||||||
import { OrgUnitSearchResultListSubmissionElementComponent } from './submission/item-list-elements/org-unit/org-unit-search-result-list-submission-element.component';
|
import { OrgUnitSearchResultListSubmissionElementComponent } from './submission/item-list-elements/org-unit/org-unit-search-result-list-submission-element.component';
|
||||||
import { ExternalSourceEntryListSubmissionElementComponent } from './submission/item-list-elements/external-source-entry/external-source-entry-list-submission-element.component';
|
import { ExternalSourceEntryListSubmissionElementComponent } from './submission/item-list-elements/external-source-entry/external-source-entry-list-submission-element.component';
|
||||||
|
import { OrgUnitSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/org-unit/org-unit-sidebar-search-list-element.component';
|
||||||
|
import { PersonSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/person/person-sidebar-search-list-element.component';
|
||||||
|
import { ProjectSidebarSearchListElementComponent } from './item-list-elements/sidebar-search-list-elements/project/project-sidebar-search-list-element.component';
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
OrgUnitComponent,
|
OrgUnitComponent,
|
||||||
@@ -50,7 +53,10 @@ const ENTRY_COMPONENTS = [
|
|||||||
NameVariantModalComponent,
|
NameVariantModalComponent,
|
||||||
OrgUnitSearchResultListSubmissionElementComponent,
|
OrgUnitSearchResultListSubmissionElementComponent,
|
||||||
OrgUnitInputSuggestionsComponent,
|
OrgUnitInputSuggestionsComponent,
|
||||||
ExternalSourceEntryListSubmissionElementComponent
|
ExternalSourceEntryListSubmissionElementComponent,
|
||||||
|
OrgUnitSidebarSearchListElementComponent,
|
||||||
|
PersonSidebarSearchListElementComponent,
|
||||||
|
ProjectSidebarSearchListElementComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
<span>Test display for sidebar-search list elements</span>
|
|
@@ -12,6 +12,10 @@ import { SidebarSearchListElementComponent } from '../../sidebar-search-list-ele
|
|||||||
selector: 'ds-publication-sidebar-search-list-element',
|
selector: 'ds-publication-sidebar-search-list-element',
|
||||||
templateUrl: '../../sidebar-search-list-element.component.html'
|
templateUrl: '../../sidebar-search-list-element.component.html'
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link ItemSearchResult} of type "Publication" within the context of
|
||||||
|
* a sidebar search modal
|
||||||
|
*/
|
||||||
export class PublicationSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
export class PublicationSidebarSearchListElementComponent extends SidebarSearchListElementComponent<ItemSearchResult, Item> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
<ds-truncatable-part *ngIf="parentTitle$ | async" [maxLines]="1"><div class="text-secondary">{{ parentTitle$ | async }}</div></ds-truncatable-part>
|
<ds-truncatable-part *ngIf="parentTitle$ && parentTitle$ | async" [maxLines]="1"><div class="text-secondary">{{ parentTitle$ | async }}</div></ds-truncatable-part>
|
||||||
<ds-truncatable-part [maxLines]="1"><div class="text-primary">{{ title }}</div></ds-truncatable-part>
|
<ds-truncatable-part *ngIf="title" [maxLines]="1"><div class="text-primary">{{ title }}</div></ds-truncatable-part>
|
||||||
<ds-truncatable-part [maxLines]="1"><div class="text-secondary">{{ description }}</div></ds-truncatable-part>
|
<ds-truncatable-part *ngIf="description" [maxLines]="1"><div class="text-secondary">{{ description }}</div></ds-truncatable-part>
|
||||||
|
@@ -2,7 +2,7 @@ import { SearchResult } from '../../search/search-result.model';
|
|||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { SearchResultListElementComponent } from '../search-result-list-element/search-result-list-element.component';
|
import { SearchResultListElementComponent } from '../search-result-list-element/search-result-list-element.component';
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { hasValue } from '../../empty.util';
|
import { hasValue, isNotEmpty } from '../../empty.util';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { TruncatableService } from '../../truncatable/truncatable.service';
|
import { TruncatableService } from '../../truncatable/truncatable.service';
|
||||||
import { LinkService } from '../../../core/cache/builders/link.service';
|
import { LinkService } from '../../../core/cache/builders/link.service';
|
||||||
@@ -10,14 +10,31 @@ import { find, map } from 'rxjs/operators';
|
|||||||
import { ChildHALResource } from '../../../core/shared/child-hal-resource.model';
|
import { ChildHALResource } from '../../../core/shared/child-hal-resource.model';
|
||||||
import { followLink } from '../../utils/follow-link-config.model';
|
import { followLink } from '../../utils/follow-link-config.model';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-sidebar-search-list-element',
|
selector: 'ds-sidebar-search-list-element',
|
||||||
templateUrl: './sidebar-search-list-element.component.html'
|
templateUrl: './sidebar-search-list-element.component.html'
|
||||||
})
|
})
|
||||||
|
/**
|
||||||
|
* Component displaying a list element for a {@link SearchResult} in the sidebar search modal
|
||||||
|
* It displays the name of the parent, title and description of the object. All of which are customizable in the child
|
||||||
|
* component by overriding the relevant methods of this component
|
||||||
|
*/
|
||||||
export class SidebarSearchListElementComponent<T extends SearchResult<K>, K extends DSpaceObject> extends SearchResultListElementComponent<T, K> {
|
export class SidebarSearchListElementComponent<T extends SearchResult<K>, K extends DSpaceObject> extends SearchResultListElementComponent<T, K> {
|
||||||
|
/**
|
||||||
|
* Observable for the title of the parent object (displayed above the object's title)
|
||||||
|
*/
|
||||||
parentTitle$: Observable<string>;
|
parentTitle$: Observable<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title for the object to display
|
||||||
|
*/
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description to display below the title
|
||||||
|
*/
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
public constructor(protected truncatableService: TruncatableService,
|
public constructor(protected truncatableService: TruncatableService,
|
||||||
@@ -25,6 +42,9 @@ export class SidebarSearchListElementComponent<T extends SearchResult<K>, K exte
|
|||||||
super(truncatableService);
|
super(truncatableService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the component variables
|
||||||
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
if (hasValue(this.dso)) {
|
if (hasValue(this.dso)) {
|
||||||
@@ -34,23 +54,92 @@ export class SidebarSearchListElementComponent<T extends SearchResult<K>, K exte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the object's parent
|
||||||
|
* Retrieve the parent by using the object's parent link and retrieving its 'dc.title' metadata
|
||||||
|
*/
|
||||||
|
getParentTitle(): Observable<string> {
|
||||||
|
return this.getParent().pipe(
|
||||||
|
map((parentRD: RemoteData<DSpaceObject>) => {
|
||||||
|
return parentRD ? parentRD.payload.firstMetadataValue('dc.title') : undefined;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parent of the object
|
||||||
|
*/
|
||||||
|
getParent(): Observable<RemoteData<DSpaceObject>> {
|
||||||
|
if (typeof (this.dso as any).getParentLinkKey === 'function') {
|
||||||
|
const propertyName = (this.dso as any).getParentLinkKey();
|
||||||
|
return this.linkService.resolveLink(this.dso, followLink(propertyName))[propertyName].pipe(
|
||||||
|
find((parentRD: RemoteData<ChildHALResource & DSpaceObject>) => parentRD.hasSucceeded || parentRD.statusCode === 204)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return observableOf(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the object
|
||||||
|
* Default: "dc.title"
|
||||||
|
*/
|
||||||
getTitle(): string {
|
getTitle(): string {
|
||||||
return this.firstMetadataValue('dc.title');
|
return this.firstMetadataValue('dc.title');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description of the object
|
||||||
|
* Default: "(dc.publisher, dc.date.issued) authors"
|
||||||
|
*/
|
||||||
getDescription(): string {
|
getDescription(): string {
|
||||||
// TODO: Expand description
|
const publisher = this.firstMetadataValue('dc.publisher');
|
||||||
return this.firstMetadataValue('dc.publisher');
|
const date = this.firstMetadataValue('dc.date.issued');
|
||||||
|
const authors = this.allMetadataValues(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']);
|
||||||
|
let description = '';
|
||||||
|
if (isNotEmpty(publisher) || isNotEmpty(date)) {
|
||||||
|
description += '(';
|
||||||
|
}
|
||||||
|
if (isNotEmpty(publisher)) {
|
||||||
|
description += publisher;
|
||||||
|
}
|
||||||
|
if (isNotEmpty(date)) {
|
||||||
|
if (isNotEmpty(publisher)) {
|
||||||
|
description += ', ';
|
||||||
|
}
|
||||||
|
description += date;
|
||||||
|
}
|
||||||
|
if (isNotEmpty(description)) {
|
||||||
|
description += ') ';
|
||||||
|
}
|
||||||
|
if (isNotEmpty(authors)) {
|
||||||
|
authors.forEach((author, i) => {
|
||||||
|
description += author;
|
||||||
|
if (i < (authors.length - 1)) {
|
||||||
|
description += '; ';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this.undefinedIfEmpty(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
getParentTitle(): Observable<string> {
|
/**
|
||||||
// TODO: Remove cast to "any" and replace with proper type-check
|
* Return undefined if the provided string is empty
|
||||||
const propertyName = (this.dso as any).getParentLinkKey();
|
* @param value Value to check
|
||||||
return this.linkService.resolveLink(this.dso, followLink(propertyName))[propertyName].pipe(
|
*/
|
||||||
find((parentRD: RemoteData<ChildHALResource & DSpaceObject>) => parentRD.hasSucceeded || parentRD.statusCode === 204),
|
undefinedIfEmpty(value: string) {
|
||||||
map((parentRD: RemoteData<ChildHALResource & DSpaceObject>) => {
|
return this.defaultIfEmpty(value, undefined);
|
||||||
return parentRD.payload.firstMetadataValue('dc.title');
|
}
|
||||||
})
|
|
||||||
);
|
/**
|
||||||
|
* Return a default value if the provided string is empty
|
||||||
|
* @param value Value to check
|
||||||
|
* @param def Default in case value is empty
|
||||||
|
*/
|
||||||
|
defaultIfEmpty(value: string, def: string) {
|
||||||
|
if (isNotEmpty(value)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return def;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2194,6 +2194,8 @@
|
|||||||
|
|
||||||
"person.listelement.badge": "Person",
|
"person.listelement.badge": "Person",
|
||||||
|
|
||||||
|
"person.listelement.no-title": "No name found",
|
||||||
|
|
||||||
"person.page.birthdate": "Birth Date",
|
"person.page.birthdate": "Birth Date",
|
||||||
|
|
||||||
"person.page.email": "Email Address",
|
"person.page.email": "Email Address",
|
||||||
|
Reference in New Issue
Block a user