mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge pull request #497 from atmire/w2p-65195_dynamic-component-refactoring
Dynamic component loading refactoring
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div class="row" *ngIf="item">
|
||||
<div class="col-10 relationship">
|
||||
<ds-item-type-switcher [object]="item" [viewMode]="viewMode"></ds-item-type-switcher>
|
||||
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="btn-group relationship-action-buttons">
|
||||
|
@@ -5,7 +5,6 @@ import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { EditRelationshipComponent } from './edit-relationship.component';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { ResourceType } from '../../../../core/shared/resource-type';
|
||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
|
@@ -4,7 +4,7 @@ import { cloneDeep } from 'lodash';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { ItemViewMode } from '../../../../shared/items/item-type-decorator';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
|
||||
@Component({
|
||||
// tslint:disable-next-line:component-selector
|
||||
@@ -31,7 +31,7 @@ export class EditRelationshipComponent implements OnChanges {
|
||||
/**
|
||||
* The view-mode we're currently on
|
||||
*/
|
||||
viewMode = ItemViewMode.Element;
|
||||
viewMode = ViewMode.ListElement;
|
||||
|
||||
constructor(private objectUpdatesService: ObjectUpdatesService) {
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import { ItemPageFieldComponent } from '../item-page-field.component';
|
||||
/**
|
||||
* This component can be used to represent metadata on a simple item page.
|
||||
* It is the most generic way of displaying metadata values
|
||||
* It expects 4 parameters: The item, a seperator, the metadata keys and an i18n key
|
||||
* It expects 4 parameters: The item, a separator, the metadata keys and an i18n key
|
||||
*/
|
||||
export class GenericItemPageFieldComponent extends ItemPageFieldComponent {
|
||||
|
||||
|
@@ -4,12 +4,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loader';
|
||||
import { Observable } from 'rxjs';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { ItemPageFieldComponent } from './item-page-field.component';
|
||||
import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
|
||||
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
||||
<div *ngIf="itemRD?.payload as item">
|
||||
<ds-item-type-switcher [object]="item" [viewMode]="viewMode"></ds-item-type-switcher>
|
||||
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
|
||||
</div>
|
||||
</div>
|
||||
<ds-error *ngIf="itemRD?.hasFailed" message="{{'error.item' | translate}}"></ds-error>
|
||||
|
@@ -1,21 +1,18 @@
|
||||
|
||||
import { mergeMap, filter, map, take, tap } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
||||
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
import { MetadataService } from '../../core/metadata/metadata.service';
|
||||
|
||||
import { fadeInOut } from '../../shared/animations/fade';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { redirectToPageNotFoundOn404 } from '../../core/shared/operators';
|
||||
import { ItemViewMode } from '../../shared/items/item-type-decorator';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
|
||||
/**
|
||||
* This component renders a simple item page.
|
||||
@@ -44,7 +41,7 @@ export class ItemPageComponent implements OnInit {
|
||||
/**
|
||||
* The view-mode we're currently on
|
||||
*/
|
||||
viewMode = ItemViewMode.Full;
|
||||
viewMode = ViewMode.StandalonePage;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@@ -53,6 +50,9 @@ export class ItemPageComponent implements OnInit {
|
||||
private metadataService: MetadataService,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Initialize instance variables
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.itemRD$ = this.route.data.pipe(
|
||||
map((data) => data.item as RemoteData<Item>),
|
||||
|
@@ -1,72 +1,72 @@
|
||||
<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]="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 [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 [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>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<ds-metadata-representation-list
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[itemType]="'Person'"
|
||||
[metadataField]="'dc.contributor.author'"
|
||||
[label]="'relationships.isAuthorOf' | translate">
|
||||
</ds-metadata-representation-list>
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isProjectOfPublication'"
|
||||
[label]="'relationships.isProjectOf' | translate">
|
||||
</ds-related-items>
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isOrgUnitOfPublication'"
|
||||
[label]="'relationships.isOrgUnitOf' | translate">
|
||||
</ds-related-items>
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isJournalIssueOfPublication'"
|
||||
[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>
|
||||
|
@@ -3,19 +3,16 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loader';
|
||||
import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { createRelationshipsObservable } from '../shared/item.component.spec';
|
||||
import { PublicationComponent } from './publication.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { MetadataMap } from '../../../../core/shared/metadata.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
@@ -45,7 +42,6 @@ describe('PublicationComponent', () => {
|
||||
})],
|
||||
declarations: [PublicationComponent, GenericItemPageFieldComponent, TruncatePipe],
|
||||
providers: [
|
||||
{provide: ITEM, useValue: mockItem},
|
||||
{provide: ItemDataService, useValue: {}},
|
||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
||||
{provide: TruncatableService, useValue: {}}
|
||||
@@ -60,6 +56,7 @@ describe('PublicationComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(PublicationComponent);
|
||||
comp = fixture.componentInstance;
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
|
@@ -1,12 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import {
|
||||
DEFAULT_ITEM_TYPE, ItemViewMode,
|
||||
rendersItemType
|
||||
} from '../../../../shared/items/item-type-decorator';
|
||||
import { ItemComponent } from '../shared/item.component';
|
||||
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
|
||||
@rendersItemType('Publication', ItemViewMode.Full)
|
||||
@rendersItemType(DEFAULT_ITEM_TYPE, ItemViewMode.Full)
|
||||
/**
|
||||
* Component that represents a publication Item page
|
||||
*/
|
||||
|
||||
@listableObjectComponent('Publication', ViewMode.StandalonePage)
|
||||
@listableObjectComponent(Item, ViewMode.StandalonePage)
|
||||
@Component({
|
||||
selector: 'ds-publication',
|
||||
styleUrls: ['./publication.component.scss'],
|
||||
|
@@ -7,17 +7,14 @@ import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loader';
|
||||
import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { ItemComponent } from './item.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { VarDirective } from '../../../../shared/utils/var.directive';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
@@ -56,7 +53,6 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
||||
})],
|
||||
declarations: [component, GenericItemPageFieldComponent, TruncatePipe],
|
||||
providers: [
|
||||
{provide: ITEM, useValue: mockItem},
|
||||
{provide: ItemDataService, useValue: {}},
|
||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
||||
{provide: TruncatableService, useValue: {}}
|
||||
@@ -71,6 +67,7 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(component);
|
||||
comp = fixture.componentInstance;
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { Component, Inject, Input } from '@angular/core';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item',
|
||||
@@ -10,9 +9,5 @@ import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.compo
|
||||
* A generic component for displaying metadata and relations of an item
|
||||
*/
|
||||
export class ItemComponent {
|
||||
|
||||
constructor(
|
||||
@Inject(ITEM) public item: Item
|
||||
) {}
|
||||
|
||||
@Input() object: Item;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<ds-metadata-field-wrapper *ngIf="representations$ && (representations$ | async)?.length > 0" [label]="label">
|
||||
<ds-item-type-switcher *ngFor="let rep of (representations$ | async)"
|
||||
[object]="rep" [viewMode]="viewMode">
|
||||
</ds-item-type-switcher>
|
||||
<ds-metadata-representation-loader *ngFor="let rep of (representations$ | async)"
|
||||
[mdRepresentation]="rep">
|
||||
</ds-metadata-representation-loader>
|
||||
<div *ngIf="(representations$ | async)?.length < total" class="mt-2">
|
||||
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
|
||||
</div>
|
||||
|
@@ -83,8 +83,8 @@ describe('MetadataRepresentationListComponent', () => {
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
it('should load 2 item-type-switcher components', () => {
|
||||
const fields = fixture.debugElement.queryAll(By.css('ds-item-type-switcher'));
|
||||
it('should load 2 ds-metadata-representation-loader components', () => {
|
||||
const fields = fixture.debugElement.queryAll(By.css('ds-metadata-representation-loader'));
|
||||
expect(fields.length).toBe(2);
|
||||
});
|
||||
|
||||
|
@@ -1,11 +1,10 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MetadataRepresentation } from '../../../core/shared/metadata-representation/metadata-representation.model';
|
||||
import { ItemViewMode } from '../../../shared/items/item-type-decorator';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { zip as observableZip, combineLatest as observableCombineLatest, of as observableOf } from 'rxjs';
|
||||
import { combineLatest as observableCombineLatest, of as observableOf, zip as observableZip } from 'rxjs';
|
||||
import { MetadataValue } from '../../../core/shared/metadata.models';
|
||||
import { MetadatumRepresentation } from '../../../core/shared/metadata-representation/metadatum/metadatum-representation.model';
|
||||
import { filter, map, switchMap } from 'rxjs/operators';
|
||||
@@ -56,12 +55,6 @@ export class MetadataRepresentationListComponent implements OnInit {
|
||||
*/
|
||||
representations$: Observable<MetadataRepresentation[]>;
|
||||
|
||||
/**
|
||||
* The view-mode we're currently on
|
||||
* @type {ElementViewMode}
|
||||
*/
|
||||
viewMode = ItemViewMode.Metadata;
|
||||
|
||||
/**
|
||||
* The originally provided limit
|
||||
* Used for resetting the limit to the original value when collapsing the list
|
||||
|
@@ -1,14 +1,12 @@
|
||||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { ItemViewMode } from '../../../shared/items/item-type-decorator';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||
import { FindAllOptions } from '../../../core/data/request.models';
|
||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { hasNoValue, hasValueOperator } from '../../../shared/empty.util';
|
||||
import { Subscription } from 'rxjs/internal/Subscription';
|
||||
import { ViewMode } from '../../../core/shared/view-mode.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-related-items',
|
||||
@@ -61,7 +59,7 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
|
||||
* The view-mode we're currently on
|
||||
* @type {ElementViewMode}
|
||||
*/
|
||||
viewMode = ItemViewMode.Element;
|
||||
viewMode = ViewMode.ListElement;
|
||||
|
||||
/**
|
||||
* Whether or not the list is currently expanded to show all related items
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<ds-metadata-field-wrapper *ngIf="(items$ | async)?.payload?.page?.length > 0" [label]="label">
|
||||
<ds-item-type-switcher *ngFor="let item of (items$ | async)?.payload?.page"
|
||||
<ds-listable-object-component-loader *ngFor="let item of (items$ | async)?.payload?.page"
|
||||
[object]="item" [viewMode]="viewMode">
|
||||
</ds-item-type-switcher>
|
||||
</ds-listable-object-component-loader>
|
||||
<div *ngIf="(items$ | async)?.payload?.page?.length < (items$ | async)?.payload?.totalElements" class="mt-2" id="view-more">
|
||||
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
|
||||
</div>
|
||||
|
@@ -61,7 +61,7 @@ describe('RelatedItemsComponent', () => {
|
||||
}));
|
||||
|
||||
it(`should load ${mockItems.length} item-type-switcher components`, () => {
|
||||
const fields = fixture.debugElement.queryAll(By.css('ds-item-type-switcher'));
|
||||
const fields = fixture.debugElement.queryAll(By.css('ds-listable-object-component-loader'));
|
||||
expect(fields.length).toBe(mockItems.length);
|
||||
});
|
||||
|
||||
|
@@ -7,7 +7,6 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { SubmissionState } from '../../submission/submission.reducers';
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { MyDSpaceResult } from '../my-dspace-result.model';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
|
||||
@@ -15,6 +14,7 @@ import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
|
||||
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
|
||||
import { NotificationType } from '../../shared/notifications/models/notification-type';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { SearchResult } from '../../+search-page/search-result.model';
|
||||
|
||||
/**
|
||||
* This component represents the whole mydspace page header
|
||||
@@ -25,7 +25,10 @@ import { hasValue } from '../../shared/empty.util';
|
||||
templateUrl: './my-dspace-new-submission.component.html'
|
||||
})
|
||||
export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
||||
@Output() uploadEnd = new EventEmitter<Array<MyDSpaceResult<DSpaceObject>>>();
|
||||
/**
|
||||
* Output that emits the workspace item when the upload has completed
|
||||
*/
|
||||
@Output() uploadEnd = new EventEmitter<Array<SearchResult<DSpaceObject>>>();
|
||||
|
||||
/**
|
||||
* The UploaderOptions object
|
||||
|
@@ -39,7 +39,8 @@
|
||||
</button>
|
||||
</div>
|
||||
<ds-my-dspace-results [searchResults]="resultsRD$ | async"
|
||||
[searchConfig]="searchOptions$ | async"></ds-my-dspace-results>
|
||||
[searchConfig]="searchOptions$ | async"
|
||||
[context]="context$ | async"></ds-my-dspace-results>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,7 +8,7 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||
import { switchMap, tap, } from 'rxjs/operators';
|
||||
import { map, switchMap, tap, } from 'rxjs/operators';
|
||||
|
||||
import { PaginatedList } from '../core/data/paginated-list';
|
||||
import { RemoteData } from '../core/data/remote-data';
|
||||
@@ -20,7 +20,6 @@ import { SearchService } from '../+search-page/search-service/search.service';
|
||||
import { SearchSidebarService } from '../+search-page/search-sidebar/search-sidebar.service';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { getSucceededRemoteData } from '../core/shared/operators';
|
||||
import { MyDSpaceResult } from './my-dspace-result.model';
|
||||
import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service';
|
||||
import { SearchConfigurationOption } from '../+search-page/search-switch-configuration/search-configuration-option.model';
|
||||
import { RoleType } from '../core/roles/role-types';
|
||||
@@ -28,6 +27,8 @@ import { SearchConfigurationService } from '../+search-page/search-service/searc
|
||||
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
||||
import { ViewMode } from '../core/shared/view-mode.model';
|
||||
import { MyDSpaceRequest } from '../core/data/request.models';
|
||||
import { SearchResult } from '../+search-page/search-result.model';
|
||||
import { Context } from '../core/shared/context.model';
|
||||
|
||||
export const MYDSPACE_ROUTE = '/mydspace';
|
||||
export const SEARCH_CONFIG_SERVICE: InjectionToken<SearchConfigurationService> = new InjectionToken<SearchConfigurationService>('searchConfigurationService');
|
||||
@@ -63,7 +64,7 @@ export class MyDSpacePageComponent implements OnInit {
|
||||
/**
|
||||
* The current search results
|
||||
*/
|
||||
resultsRD$: BehaviorSubject<RemoteData<PaginatedList<MyDSpaceResult<DSpaceObject>>>> = new BehaviorSubject(null);
|
||||
resultsRD$: BehaviorSubject<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>> = new BehaviorSubject(null);
|
||||
|
||||
/**
|
||||
* The current paginated search options
|
||||
@@ -93,7 +94,12 @@ export class MyDSpacePageComponent implements OnInit {
|
||||
/**
|
||||
* List of available view mode
|
||||
*/
|
||||
viewModeList = [ViewMode.List, ViewMode.Detail];
|
||||
viewModeList = [ViewMode.ListElement, ViewMode.DetailedListElement];
|
||||
|
||||
/**
|
||||
* The current context of this page: workspace or workflow
|
||||
*/
|
||||
context$: Observable<Context>;
|
||||
|
||||
constructor(private service: SearchService,
|
||||
private sidebarService: SearchSidebarService,
|
||||
@@ -111,6 +117,9 @@ export class MyDSpacePageComponent implements OnInit {
|
||||
*
|
||||
* Listen to changes in the scope
|
||||
* If something changes, update the list of scopes for the dropdown
|
||||
*
|
||||
* Listen to changes in the configuration
|
||||
* If something changes, update the current context
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.configurationList$ = this.searchConfigService.getAvailableConfigurationOptions();
|
||||
@@ -126,6 +135,17 @@ export class MyDSpacePageComponent implements OnInit {
|
||||
switchMap((scopeId) => this.service.getScopes(scopeId))
|
||||
);
|
||||
|
||||
this.context$ = this.searchConfigService.getCurrentConfiguration('workspace')
|
||||
.pipe(
|
||||
map((configuration: string) => {
|
||||
if (configuration === 'workspace') {
|
||||
return Context.Workspace
|
||||
} else {
|
||||
return Context.Workflow
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -7,19 +7,20 @@ import { MyDspacePageRoutingModule } from './my-dspace-page-routing.module';
|
||||
import { MyDSpacePageComponent } from './my-dspace-page.component';
|
||||
import { SearchPageModule } from '../+search-page/search-page.module';
|
||||
import { MyDSpaceResultsComponent } from './my-dspace-results/my-dspace-results.component';
|
||||
import { WorkspaceitemMyDSpaceResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workspaceitem-my-dspace-result/workspaceitem-my-dspace-result-list-element.component';
|
||||
import { ItemMyDSpaceResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/item-my-dspace-result/item-my-dspace-result-list-element.component';
|
||||
import { WorkflowitemMyDSpaceResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workflowitem-my-dspace-result/workflowitem-my-dspace-result-list-element.component';
|
||||
import { ClaimedMyDSpaceResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-my-dspace-result/claimed-my-dspace-result-list-element.component';
|
||||
import { PoolMyDSpaceResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/pool-my-dspace-result/pool-my-dspace-result-list-element.component';
|
||||
import { WorkspaceItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component';
|
||||
import { ClaimedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component';
|
||||
import { PoolSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component';
|
||||
import { MyDSpaceNewSubmissionComponent } from './my-dspace-new-submission/my-dspace-new-submission.component';
|
||||
import { ItemMyDSpaceResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/item-my-dspace-result/item-my-dspace-result-detail-element.component';
|
||||
import { WorkspaceitemMyDSpaceResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/workspaceitem-my-dspace-result/workspaceitem-my-dspace-result-detail-element.component';
|
||||
import { WorkflowitemMyDSpaceResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/workflowitem-my-dspace-result/workflowitem-my-dspace-result-detail-element.component';
|
||||
import { ClaimedMyDSpaceResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/claimed-my-dspace-result/claimed-my-dspace-result-detail-element.component';
|
||||
import { PoolMyDSpaceResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/pool-my-dspace-result/pool-my-dspace-result-detail-lement.component';
|
||||
import { ItemSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/item-search-result/item-search-result-detail-element.component';
|
||||
import { WorkspaceItemSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/workspace-item-search-result/workspace-item-search-result-detail-element.component';
|
||||
import { WorkflowItemSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/workflow-item-search-result/workflow-item-search-result-detail-element.component';
|
||||
import { ClaimedTaskSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component';
|
||||
import { MyDSpaceGuard } from './my-dspace.guard';
|
||||
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
||||
import { SearchResultListElementComponent } from '../shared/object-list/search-result-list-element/search-result-list-element.component';
|
||||
import { ItemSearchResultListElementSubmissionComponent } from '../shared/object-list/my-dspace-result-list-element/item-search-result/item-search-result-list-element-submission.component';
|
||||
import { WorkflowItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component';
|
||||
import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -31,33 +32,34 @@ import { MyDSpaceConfigurationService } from './my-dspace-configuration.service'
|
||||
declarations: [
|
||||
MyDSpacePageComponent,
|
||||
MyDSpaceResultsComponent,
|
||||
ItemMyDSpaceResultListElementComponent,
|
||||
WorkspaceitemMyDSpaceResultListElementComponent,
|
||||
WorkflowitemMyDSpaceResultListElementComponent,
|
||||
ClaimedMyDSpaceResultListElementComponent,
|
||||
PoolMyDSpaceResultListElementComponent,
|
||||
ItemMyDSpaceResultDetailElementComponent,
|
||||
WorkspaceitemMyDSpaceResultDetailElementComponent,
|
||||
WorkflowitemMyDSpaceResultDetailElementComponent,
|
||||
ClaimedMyDSpaceResultDetailElementComponent,
|
||||
PoolMyDSpaceResultDetailElementComponent,
|
||||
MyDSpaceNewSubmissionComponent
|
||||
WorkspaceItemSearchResultListElementComponent,
|
||||
WorkflowItemSearchResultListElementComponent,
|
||||
ClaimedSearchResultListElementComponent,
|
||||
PoolSearchResultListElementComponent,
|
||||
ItemSearchResultDetailElementComponent,
|
||||
WorkspaceItemSearchResultDetailElementComponent,
|
||||
WorkflowItemSearchResultDetailElementComponent,
|
||||
ClaimedTaskSearchResultDetailElementComponent,
|
||||
PoolSearchResultDetailElementComponent,
|
||||
MyDSpaceNewSubmissionComponent,
|
||||
ItemSearchResultListElementSubmissionComponent
|
||||
],
|
||||
providers: [
|
||||
MyDSpaceGuard,
|
||||
MyDSpaceConfigurationService
|
||||
],
|
||||
entryComponents: [
|
||||
ItemMyDSpaceResultListElementComponent,
|
||||
WorkspaceitemMyDSpaceResultListElementComponent,
|
||||
WorkflowitemMyDSpaceResultListElementComponent,
|
||||
ClaimedMyDSpaceResultListElementComponent,
|
||||
PoolMyDSpaceResultListElementComponent,
|
||||
ItemMyDSpaceResultDetailElementComponent,
|
||||
WorkspaceitemMyDSpaceResultDetailElementComponent,
|
||||
WorkflowitemMyDSpaceResultDetailElementComponent,
|
||||
ClaimedMyDSpaceResultDetailElementComponent,
|
||||
PoolMyDSpaceResultDetailElementComponent
|
||||
SearchResultListElementComponent,
|
||||
WorkspaceItemSearchResultListElementComponent,
|
||||
WorkflowItemSearchResultListElementComponent,
|
||||
ClaimedSearchResultListElementComponent,
|
||||
PoolSearchResultListElementComponent,
|
||||
ItemSearchResultDetailElementComponent,
|
||||
WorkspaceItemSearchResultDetailElementComponent,
|
||||
WorkflowItemSearchResultDetailElementComponent,
|
||||
ClaimedTaskSearchResultDetailElementComponent,
|
||||
PoolSearchResultDetailElementComponent,
|
||||
ItemSearchResultListElementSubmissionComponent
|
||||
]
|
||||
})
|
||||
|
||||
|
@@ -1,19 +0,0 @@
|
||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||
import { MetadataMap } from '../core/shared/metadata.models';
|
||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||
|
||||
/**
|
||||
* Represents a search result object of a certain (<T>) DSpaceObject
|
||||
*/
|
||||
export class MyDSpaceResult<T extends DSpaceObject> implements ListableObject {
|
||||
/**
|
||||
* The DSpaceObject that was found
|
||||
*/
|
||||
indexableObject: T;
|
||||
|
||||
/**
|
||||
* The metadata that was used to find this item, hithighlighted
|
||||
*/
|
||||
hitHighlights: MetadataMap;
|
||||
|
||||
}
|
@@ -4,7 +4,8 @@
|
||||
[hasBorder]="hasBorder"
|
||||
[sortConfig]="searchConfig.sort"
|
||||
[objects]="searchResults"
|
||||
[hideGear]="true">
|
||||
[hideGear]="true"
|
||||
[context]="context">
|
||||
</ds-viewable-collection>
|
||||
</div>
|
||||
<ds-loading *ngIf="isLoading()" message="{{'loading.mydspace-results' | translate}}"></ds-loading>
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||
import { MyDSpaceResult } from '../my-dspace-result.model';
|
||||
import { SearchOptions } from '../../+search-page/search-options.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
import { isEmpty } from '../../shared/empty.util';
|
||||
import { SearchResult } from '../../+search-page/search-result.model';
|
||||
import { Context } from '../../core/shared/context.model';
|
||||
|
||||
/**
|
||||
* Component that represents all results for mydspace page
|
||||
@@ -25,7 +25,7 @@ export class MyDSpaceResultsComponent {
|
||||
/**
|
||||
* The actual search result objects
|
||||
*/
|
||||
@Input() searchResults: RemoteData<PaginatedList<MyDSpaceResult<DSpaceObject>>>;
|
||||
@Input() searchResults: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>;
|
||||
|
||||
/**
|
||||
* The current configuration of the search
|
||||
@@ -37,6 +37,10 @@ export class MyDSpaceResultsComponent {
|
||||
*/
|
||||
@Input() viewMode: ViewMode;
|
||||
|
||||
/**
|
||||
* The current context for the search results
|
||||
*/
|
||||
@Input() context: Context;
|
||||
/**
|
||||
* A boolean representing if search results entry are separated by a line
|
||||
*/
|
||||
|
@@ -1,13 +1,12 @@
|
||||
import { autoserialize, inheritSerialization } from 'cerialize';
|
||||
import { MetadataMap } from '../core/shared/metadata.models';
|
||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||
import { NormalizedObject } from '../core/cache/models/normalized-object.model';
|
||||
|
||||
/**
|
||||
* Represents a normalized version of a search result object of a certain DSpaceObject
|
||||
*/
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedSearchResult implements ListableObject {
|
||||
export class NormalizedSearchResult {
|
||||
/**
|
||||
* The UUID of the DSpaceObject that was found
|
||||
*/
|
||||
@@ -19,5 +18,4 @@ export class NormalizedSearchResult implements ListableObject {
|
||||
*/
|
||||
@autoserialize
|
||||
hitHighlights: MetadataMap;
|
||||
|
||||
}
|
||||
|
@@ -71,7 +71,7 @@ export class SearchFiltersComponent implements OnInit {
|
||||
/**
|
||||
* @returns {string} The base path to the search page, or the current page when inPlaceSearch is true
|
||||
*/
|
||||
private getSearchLink(): string {
|
||||
getSearchLink(): string {
|
||||
if (this.inPlaceSearch) {
|
||||
return './';
|
||||
}
|
||||
|
@@ -3,14 +3,14 @@ import { URLCombiner } from '../core/url-combiner/url-combiner';
|
||||
import 'core-js/library/fn/object/entries';
|
||||
import { SearchFilter } from './search-filter.model';
|
||||
import { DSpaceObjectType } from '../core/shared/dspace-object-type.model';
|
||||
import { SetViewMode } from '../shared/view-mode';
|
||||
import { ViewMode } from '../core/shared/view-mode.model';
|
||||
|
||||
/**
|
||||
* This model class represents all parameters needed to request information about a certain search request
|
||||
*/
|
||||
export class SearchOptions {
|
||||
configuration?: string;
|
||||
view?: SetViewMode = SetViewMode.List;
|
||||
view?: ViewMode = ViewMode.ListElement;
|
||||
scope?: string;
|
||||
query?: string;
|
||||
dsoType?: DSpaceObjectType;
|
||||
|
@@ -5,7 +5,6 @@ import { SharedModule } from '../shared/shared.module';
|
||||
import { SearchPageRoutingModule } from './search-page-routing.module';
|
||||
import { SearchPageComponent } from './search-page.component';
|
||||
import { SearchResultsComponent } from './search-results/search-results.component';
|
||||
import { ItemSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component';
|
||||
import { CommunitySearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'
|
||||
import { CollectionSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component';
|
||||
import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component';
|
||||
@@ -44,9 +43,6 @@ const components = [
|
||||
SearchResultsComponent,
|
||||
SearchSidebarComponent,
|
||||
SearchSettingsComponent,
|
||||
ItemSearchResultGridElementComponent,
|
||||
CollectionSearchResultGridElementComponent,
|
||||
CommunitySearchResultGridElementComponent,
|
||||
SearchFiltersComponent,
|
||||
SearchFilterComponent,
|
||||
SearchFacetFilterComponent,
|
||||
@@ -84,9 +80,6 @@ const components = [
|
||||
SearchConfigurationService
|
||||
],
|
||||
entryComponents: [
|
||||
ItemSearchResultGridElementComponent,
|
||||
CollectionSearchResultGridElementComponent,
|
||||
CommunitySearchResultGridElementComponent,
|
||||
SearchFacetFilterComponent,
|
||||
SearchRangeFilterComponent,
|
||||
SearchTextFilterComponent,
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||
import { MetadataMap } from '../core/shared/metadata.models';
|
||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||
import { GenericConstructor } from '../core/shared/generic-constructor';
|
||||
|
||||
/**
|
||||
* Represents a search result object of a certain (<T>) DSpaceObject
|
||||
@@ -16,4 +17,10 @@ export class SearchResult<T extends DSpaceObject> implements ListableObject {
|
||||
*/
|
||||
hitHighlights: MetadataMap;
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
return [this.constructor as GenericConstructor<ListableObject>];
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
[config]="searchConfig.pagination"
|
||||
[sortConfig]="searchConfig.sort"
|
||||
[objects]="searchResults"
|
||||
[linkType]="linkType"
|
||||
[hideGear]="true">
|
||||
</ds-viewable-collection></div>
|
||||
<ds-loading *ngIf="hasNoValue(searchResults) || hasNoValue(searchResults.payload) || searchResults.isLoading" message="{{'loading.search-results' | translate}}"></ds-loading>
|
||||
|
@@ -2,12 +2,13 @@ import { Component, Input } from '@angular/core';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||
import { SetViewMode } from '../../shared/view-mode';
|
||||
import { SearchOptions } from '../search-options.model';
|
||||
import { SearchResult } from '../search-result.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { hasNoValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
import { CollectionElementLinkType } from '../../shared/object-collection/collection-element-link.type';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-search-results',
|
||||
@@ -24,6 +25,11 @@ import { SortOptions } from '../../core/cache/models/sort-options.model';
|
||||
export class SearchResultsComponent {
|
||||
hasNoValue = hasNoValue;
|
||||
|
||||
/**
|
||||
* The link type of the listed search results
|
||||
*/
|
||||
@Input() linkType: CollectionElementLinkType;
|
||||
|
||||
/**
|
||||
* The actual search result objects
|
||||
*/
|
||||
@@ -42,7 +48,7 @@ export class SearchResultsComponent {
|
||||
/**
|
||||
* The current view-mode of the list
|
||||
*/
|
||||
@Input() viewMode: SetViewMode;
|
||||
@Input() viewMode: ViewMode;
|
||||
|
||||
/**
|
||||
* An optional configuration to filter the result on one type
|
||||
|
@@ -12,19 +12,12 @@ const searchResultMap = new Map();
|
||||
* @param {GenericConstructor<ListableObject>} domainConstructor The constructor of the DSpaceObject
|
||||
* @returns Decorator function that performs the actual mapping on initialization of the component
|
||||
*/
|
||||
export function searchResultFor(domainConstructor: GenericConstructor<ListableObject>, configuration: string = null) {
|
||||
export function searchResultFor(domainConstructor: GenericConstructor<ListableObject>) {
|
||||
return function decorator(searchResult: any) {
|
||||
if (!searchResult) {
|
||||
return;
|
||||
}
|
||||
if (isNull(configuration)) {
|
||||
searchResultMap.set(domainConstructor, searchResult);
|
||||
} else {
|
||||
if (!searchResultMap.get(configuration)) {
|
||||
searchResultMap.set(configuration, new Map());
|
||||
}
|
||||
searchResultMap.get(configuration).set(domainConstructor, searchResult);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,10 +26,6 @@ export function searchResultFor(domainConstructor: GenericConstructor<ListableOb
|
||||
* @param {GenericConstructor<ListableObject>} domainConstructor The DSpaceObject's constructor for which the search result component is requested
|
||||
* @returns The component's constructor that matches the given DSpaceObject
|
||||
*/
|
||||
export function getSearchResultFor(domainConstructor: GenericConstructor<ListableObject>, configuration: string = null) {
|
||||
if (isNull(configuration) || configuration === 'default' || hasNoValue(searchResultMap.get(configuration))) {
|
||||
export function getSearchResultFor(domainConstructor: GenericConstructor<ListableObject>) {
|
||||
return searchResultMap.get(domainConstructor);
|
||||
} else {
|
||||
return searchResultMap.get(configuration).get(domainConstructor);
|
||||
}
|
||||
}
|
||||
|
@@ -5,9 +5,6 @@ import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { SearchService } from './search.service';
|
||||
import { ItemDataService } from './../../core/data/item-data.service';
|
||||
import { SetViewMode } from '../../shared/view-mode';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
|
||||
import { Router, UrlTree } from '@angular/router';
|
||||
import { RequestService } from '../../core/data/request.service';
|
||||
@@ -66,7 +63,7 @@ describe('SearchService', () => {
|
||||
|
||||
it('should return list view mode', () => {
|
||||
searchService.getViewMode().subscribe((viewMode) => {
|
||||
expect(viewMode).toBe(ViewMode.List);
|
||||
expect(viewMode).toBe(ViewMode.ListElement);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -125,38 +122,38 @@ describe('SearchService', () => {
|
||||
});
|
||||
|
||||
it('should call the navigate method on the Router with view mode list parameter as a parameter when setViewMode is called', () => {
|
||||
searchService.setViewMode(ViewMode.List);
|
||||
searchService.setViewMode(ViewMode.ListElement);
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/search'], {
|
||||
queryParams: { view: ViewMode.List, page: 1 },
|
||||
queryParams: { view: ViewMode.ListElement, page: 1 },
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
});
|
||||
|
||||
it('should call the navigate method on the Router with view mode grid parameter as a parameter when setViewMode is called', () => {
|
||||
searchService.setViewMode(ViewMode.Grid);
|
||||
searchService.setViewMode(ViewMode.GridElement);
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/search'], {
|
||||
queryParams: { view: ViewMode.Grid, page: 1 },
|
||||
queryParams: { view: ViewMode.GridElement, page: 1 },
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
});
|
||||
|
||||
it('should return ViewMode.List when the viewMode is set to ViewMode.List in the ActivatedRoute', () => {
|
||||
let viewMode = ViewMode.Grid;
|
||||
let viewMode = ViewMode.GridElement;
|
||||
spyOn(routeService, 'getQueryParamMap').and.returnValue(observableOf(new Map([
|
||||
[ 'view', ViewMode.List ],
|
||||
[ 'view', ViewMode.ListElement ],
|
||||
])));
|
||||
|
||||
searchService.getViewMode().subscribe((mode) => viewMode = mode);
|
||||
expect(viewMode).toEqual(ViewMode.List);
|
||||
expect(viewMode).toEqual(ViewMode.ListElement);
|
||||
});
|
||||
|
||||
it('should return ViewMode.Grid when the viewMode is set to ViewMode.Grid in the ActivatedRoute', () => {
|
||||
let viewMode = ViewMode.List;
|
||||
let viewMode = ViewMode.ListElement;
|
||||
spyOn(routeService, 'getQueryParamMap').and.returnValue(observableOf(new Map([
|
||||
[ 'view', ViewMode.Grid ],
|
||||
[ 'view', ViewMode.GridElement ],
|
||||
])));
|
||||
searchService.getViewMode().subscribe((mode) => viewMode = mode);
|
||||
expect(viewMode).toEqual(ViewMode.Grid);
|
||||
expect(viewMode).toEqual(ViewMode.GridElement);
|
||||
});
|
||||
|
||||
describe('when search is called', () => {
|
||||
|
@@ -160,7 +160,7 @@ export class SearchService implements OnDestroy {
|
||||
let co = DSpaceObject;
|
||||
if (dsos.payload[index]) {
|
||||
const constructor: GenericConstructor<ListableObject> = dsos.payload[index].constructor as GenericConstructor<ListableObject>;
|
||||
co = getSearchResultFor(constructor, searchOptions.configuration);
|
||||
co = getSearchResultFor(constructor);
|
||||
return Object.assign(new co(), object, {
|
||||
indexableObject: dsos.payload[index]
|
||||
});
|
||||
@@ -341,7 +341,7 @@ export class SearchService implements OnDestroy {
|
||||
if (isNotEmpty(params.get('view')) && hasValue(params.get('view'))) {
|
||||
return params.get('view');
|
||||
} else {
|
||||
return ViewMode.List;
|
||||
return ViewMode.ListElement;
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -354,7 +354,7 @@ export class SearchService implements OnDestroy {
|
||||
this.routeService.getQueryParameterValue('pageSize').pipe(first())
|
||||
.subscribe((pageSize) => {
|
||||
let queryParams = { view: viewMode, page: 1 };
|
||||
if (viewMode === ViewMode.Detail) {
|
||||
if (viewMode === ViewMode.DetailedListElement) {
|
||||
queryParams = Object.assign(queryParams, {pageSize: '1'});
|
||||
} else if (pageSize === '1') {
|
||||
queryParams = Object.assign(queryParams, {pageSize: '10'});
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
||||
|
||||
import { CacheableObject } from '../../cache/object-cache.reducer';
|
||||
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
|
||||
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
|
||||
import { EPerson } from './eperson.model';
|
||||
import { mapsTo, relationship } from '../../cache/builders/build-decorators';
|
||||
@@ -9,7 +8,7 @@ import { Group } from './group.model';
|
||||
|
||||
@mapsTo(EPerson)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
export class NormalizedEPerson extends NormalizedDSpaceObject<EPerson> implements CacheableObject, ListableObject {
|
||||
export class NormalizedEPerson extends NormalizedDSpaceObject<EPerson> implements CacheableObject {
|
||||
/**
|
||||
* A string representing the unique handle of this EPerson
|
||||
*/
|
||||
|
@@ -1,14 +1,13 @@
|
||||
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
||||
|
||||
import { CacheableObject } from '../../cache/object-cache.reducer';
|
||||
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
|
||||
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
|
||||
import { mapsTo, relationship } from '../../cache/builders/build-decorators';
|
||||
import { Group } from './group.model';
|
||||
|
||||
@mapsTo(Group)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
export class NormalizedGroup extends NormalizedDSpaceObject<Group> implements CacheableObject, ListableObject {
|
||||
export class NormalizedGroup extends NormalizedDSpaceObject<Group> implements CacheableObject {
|
||||
|
||||
/**
|
||||
* List of Groups that this Group belong to
|
||||
|
@@ -2,6 +2,7 @@ import { ListableObject } from '../../shared/object-collection/shared/listable-o
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { MetadataSchema } from './metadata-schema.model';
|
||||
import { ResourceType } from '../shared/resource-type';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
|
||||
/**
|
||||
* Class the represents a metadata field
|
||||
@@ -50,4 +51,11 @@ export class MetadataField implements ListableObject {
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
return [this.constructor as GenericConstructor<ListableObject>];
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { ResourceType } from '../shared/resource-type';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
|
||||
/**
|
||||
* Class that represents a metadata schema
|
||||
@@ -26,4 +27,11 @@ export class MetadataSchema implements ListableObject {
|
||||
* The namespace of this metadata schema
|
||||
*/
|
||||
namespace: string;
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
return [this.constructor as GenericConstructor<ListableObject>];
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import { MetadataSchema } from './metadata-schema.model';
|
||||
*/
|
||||
@mapsTo(MetadataField)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedMetadataField extends NormalizedObject<MetadataField> implements ListableObject {
|
||||
export class NormalizedMetadataField extends NormalizedObject<MetadataField> {
|
||||
|
||||
/**
|
||||
* The identifier of this normalized metadata field
|
||||
|
@@ -9,7 +9,7 @@ import { MetadataSchema } from './metadata-schema.model';
|
||||
*/
|
||||
@mapsTo(MetadataSchema)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedMetadataSchema extends NormalizedObject<MetadataSchema> implements ListableObject {
|
||||
export class NormalizedMetadataSchema extends NormalizedObject<MetadataSchema> {
|
||||
/**
|
||||
* The unique identifier for this schema
|
||||
*/
|
||||
|
@@ -55,22 +55,24 @@ describe('RegistryService', () => {
|
||||
});
|
||||
|
||||
const mockSchemasList = [
|
||||
{
|
||||
Object.assign(new MetadataSchema(), {
|
||||
id: 1,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1',
|
||||
prefix: 'dc',
|
||||
namespace: 'http://dublincore.org/documents/dcmi-terms/',
|
||||
type: MetadataSchema.type
|
||||
},
|
||||
{
|
||||
}),
|
||||
Object.assign(new MetadataSchema(), {
|
||||
|
||||
id: 2,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2',
|
||||
prefix: 'mock',
|
||||
namespace: 'http://dspace.org/mockschema',
|
||||
type: MetadataSchema.type
|
||||
}
|
||||
})
|
||||
];
|
||||
const mockFieldsList = [
|
||||
Object.assign(new MetadataField(),
|
||||
{
|
||||
id: 1,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8',
|
||||
@@ -79,7 +81,8 @@ describe('RegistryService', () => {
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0],
|
||||
type: MetadataField.type
|
||||
},
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
{
|
||||
id: 2,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9',
|
||||
@@ -88,7 +91,8 @@ describe('RegistryService', () => {
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0],
|
||||
type: MetadataField.type
|
||||
},
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
{
|
||||
id: 3,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10',
|
||||
@@ -97,7 +101,8 @@ describe('RegistryService', () => {
|
||||
scopeNote: 'test scope note',
|
||||
schema: mockSchemasList[1],
|
||||
type: MetadataField.type
|
||||
},
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
{
|
||||
id: 4,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11',
|
||||
@@ -106,7 +111,7 @@ describe('RegistryService', () => {
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[1],
|
||||
type: MetadataField.type
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
const pageInfo = new PageInfo();
|
||||
|
@@ -400,7 +400,7 @@ export class RegistryService {
|
||||
distinctUntilChanged()
|
||||
);
|
||||
|
||||
const serializedSchema = new DSpaceRESTv2Serializer(getMapsToType(MetadataSchema.type)).serialize(schema as NormalizedMetadataSchema);
|
||||
const serializedSchema = new DSpaceRESTv2Serializer(getMapsToType(MetadataSchema.type)).serialize(schema);
|
||||
|
||||
const request$ = endpoint$.pipe(
|
||||
take(1),
|
||||
|
@@ -1,12 +1,13 @@
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { TypedObject } from '../cache/object-cache.reducer';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { GenericConstructor } from './generic-constructor';
|
||||
|
||||
/**
|
||||
* Class object representing a browse entry
|
||||
* This class is not normalized because browse entries do not have self links
|
||||
*/
|
||||
export class BrowseEntry implements ListableObject, TypedObject {
|
||||
export class BrowseEntry implements ListableObject {
|
||||
static type = new ResourceType('browseEntry');
|
||||
|
||||
/**
|
||||
@@ -28,4 +29,11 @@ export class BrowseEntry implements ListableObject, TypedObject {
|
||||
* The count of this browse entry
|
||||
*/
|
||||
count: number;
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
return [this.constructor as GenericConstructor<ListableObject>];
|
||||
}
|
||||
}
|
||||
|
13
src/app/core/shared/context.model.ts
Normal file
13
src/app/core/shared/context.model.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* This enumeration represents all possible ways of representing a group of objects in the UI
|
||||
*/
|
||||
|
||||
export enum Context {
|
||||
Undefined = 'undefined',
|
||||
ItemPage = 'itemPage',
|
||||
Search = 'search',
|
||||
Workflow = 'workflow',
|
||||
Workspace = 'workspace',
|
||||
AdminMenu = 'adminMenu',
|
||||
SubmissionModal = 'submissionModal',
|
||||
}
|
@@ -12,6 +12,7 @@ import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { GenericConstructor } from './generic-constructor';
|
||||
|
||||
/**
|
||||
* An abstract model class for a DSpaceObject.
|
||||
@@ -109,7 +110,7 @@ export class DSpaceObject implements CacheableObject, ListableObject {
|
||||
* Like [[firstMetadata]], but only returns a string value, or `undefined`.
|
||||
*
|
||||
* @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]].
|
||||
* @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done.
|
||||
* @param {MetadataValueFilter} valueFilter The value filter to use. If unspecified, no filtering will be done.
|
||||
* @returns {string} the first matching string value, or `undefined`.
|
||||
*/
|
||||
firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string {
|
||||
@@ -146,4 +147,10 @@ export class DSpaceObject implements CacheableObject, ListableObject {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
return [this.constructor as GenericConstructor<ListableObject>];
|
||||
}
|
||||
}
|
||||
|
@@ -5,12 +5,18 @@ import { DSpaceObject } from './dspace-object.model';
|
||||
import { Collection } from './collection.model';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { Bitstream } from './bitstream.model';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { PaginatedList } from '../data/paginated-list';
|
||||
import { Relationship } from './item-relationships/relationship.model';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { getSucceededRemoteData } from './operators';
|
||||
import { GenericConstructor } from './generic-constructor';
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { DEFAULT_ENTITY_TYPE } from '../../shared/metadata-representation/metadata-representation.decorator';
|
||||
|
||||
/**
|
||||
* Class representing a DSpace Item
|
||||
*/
|
||||
export class Item extends DSpaceObject {
|
||||
static type = new ResourceType('item');
|
||||
|
||||
@@ -110,4 +116,14 @@ export class Item extends DSpaceObject {
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
getRenderTypes(): Array<string | GenericConstructor<ListableObject>> {
|
||||
let entityType = this.firstMetadataValue('relationship.type');
|
||||
if (isEmpty(entityType)) {
|
||||
entityType = DEFAULT_ENTITY_TYPE;
|
||||
}
|
||||
return [entityType, ...super.getRenderTypes()];
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,8 @@
|
||||
*/
|
||||
|
||||
export enum ViewMode {
|
||||
List = 'list',
|
||||
Grid = 'grid',
|
||||
Detail = 'detail'
|
||||
ListElement = 'listElement',
|
||||
GridElement = 'gridElement',
|
||||
DetailedListElement = 'detailedListElement',
|
||||
StandalonePage = 'standalonePage',
|
||||
}
|
||||
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-issue-search-result-grid-element>
|
@@ -1,15 +1,17 @@
|
||||
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 { JournalIssueGridElementComponent } 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';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
|
||||
mockItemWithMetadata.hitHighlights = {};
|
||||
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
const mockItem = Object.assign(new Item(), {
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -33,18 +35,41 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
}
|
||||
});
|
||||
|
||||
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', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
describe('JournalIssueGridElementComponent', getEntityGridElementTestComponent(JournalIssueGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'journal-title']));
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
declarations: [JournalIssueGridElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalIssueGridElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalIssueGridElementComponent);
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe(`when the journal issue is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it(`should contain a JournalIssueSearchResultGridElementComponent`, () => {
|
||||
const journalIssueGridElement = fixture.debugElement.query(By.css(`ds-journal-issue-search-result-grid-element`));
|
||||
expect(journalIssueGridElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
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';
|
||||
|
||||
@rendersItemType('JournalIssue', ItemViewMode.Card)
|
||||
@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> {
|
||||
}
|
||||
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-volume-search-result-grid-element>
|
@@ -1,15 +1,17 @@
|
||||
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 { JournalVolumeGridElementComponent } 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';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
|
||||
mockItemWithMetadata.hitHighlights = {};
|
||||
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
const mockItem = Object.assign(new Item(), {
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -33,18 +35,41 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
}
|
||||
});
|
||||
|
||||
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', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
describe('JournalVolumeGridElementComponent', getEntityGridElementTestComponent(JournalVolumeGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'description']));
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
declarations: [JournalVolumeGridElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalVolumeGridElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalVolumeGridElementComponent);
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe(`when the journal volume is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it(`should contain a JournalVolumeSearchResultGridElementComponent`, () => {
|
||||
const journalVolumeGridElement = fixture.debugElement.query(By.css(`ds-journal-volume-search-result-grid-element`));
|
||||
expect(journalVolumeGridElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
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';
|
||||
|
||||
@rendersItemType('JournalVolume', ItemViewMode.Card)
|
||||
@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> {
|
||||
}
|
||||
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-search-result-grid-element>
|
@@ -1,15 +1,17 @@
|
||||
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 { JournalGridElementComponent } 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';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = new ItemSearchResult();
|
||||
mockItemWithMetadata.hitHighlights = {};
|
||||
mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
const mockItem = Object.assign(new Item(), {
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -39,18 +41,41 @@ mockItemWithMetadata.indexableObject = Object.assign(new Item(), {
|
||||
}
|
||||
});
|
||||
|
||||
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', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
describe('JournalGridElementComponent', getEntityGridElementTestComponent(JournalGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['editor', 'publisher', 'description']));
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopAnimationsModule],
|
||||
declarations: [JournalGridElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalGridElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalGridElementComponent);
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe(`when the journal is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it(`should contain a JournalGridElementComponent`, () => {
|
||||
const journalGridElement = fixture.debugElement.query(By.css(`ds-journal-search-result-grid-element`));
|
||||
expect(journalGridElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
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';
|
||||
|
||||
@rendersItemType('Journal', ItemViewMode.Card)
|
||||
@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> {
|
||||
}
|
||||
|
@@ -0,0 +1,36 @@
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</a>
|
||||
<span *ngIf="linkType == linkTypes.None" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</span>
|
||||
<div class="card-body">
|
||||
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
|
||||
<h4 class="card-title" [innerHTML]="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 *ngIf="linkType != linkTypes.None" class="text-center">
|
||||
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]"
|
||||
class="lead btn btn-primary viewButton">View</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ds-truncatable>
|
@@ -0,0 +1,49 @@
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../../core/shared/page-info.model';
|
||||
import { getEntityGridElementTestComponent } from '../../../../../shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.spec';
|
||||
import { JournalIssueSearchResultGridElementComponent } from './journal-issue-search-result-grid-element.component';
|
||||
|
||||
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('JournalIssueSearchResultGridElementComponent', getEntityGridElementTestComponent(JournalIssueSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'journal-title']));
|
@@ -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 search result of the type Journal Issue
|
||||
*/
|
||||
export class JournalIssueSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</a>
|
||||
<span *ngIf="linkType == linkTypes.None" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</span>
|
||||
<div class="card-body">
|
||||
<ds-item-type-badge [object]="dso"></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 *ngIf="linkType != linkTypes.None" class="text-center">
|
||||
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]"
|
||||
class="lead btn btn-primary viewButton">View</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ds-truncatable>
|
@@ -0,0 +1,49 @@
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../../core/shared/page-info.model';
|
||||
import { getEntityGridElementTestComponent } from '../../../../../shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.spec';
|
||||
import { JournalVolumeSearchResultGridElementComponent } from './journal-volume-search-result-grid-element.component';
|
||||
|
||||
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('JournalVolumeSearchResultGridElementComponent', getEntityGridElementTestComponent(JournalVolumeSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['date', 'description']));
|
@@ -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 search result of the type Journal Volume
|
||||
*/
|
||||
export class JournalVolumeSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<div class="card" [@focusShadow]="(isCollapsed$ | async)?'blur':'focus'">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</a>
|
||||
<span *ngIf="linkType == linkTypes.None" class="card-img-top full-width">
|
||||
<div>
|
||||
<ds-grid-thumbnail [thumbnail]="dso.getThumbnail() | async">
|
||||
</ds-grid-thumbnail>
|
||||
</div>
|
||||
</span>
|
||||
<div class="card-body">
|
||||
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||
<ds-truncatable-part [id]="dso.id" [minLines]="3" type="h4">
|
||||
<h4 class="card-title" [innerHTML]="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">{{firstMetadataValue('creativework.editor')}}</span>
|
||||
<span *ngIf="dso.hasMetadata('creativework.publisher')" class="item-publisher">
|
||||
<span>, </span>
|
||||
{{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 *ngIf="linkType != linkTypes.None" class="text-center">
|
||||
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="['/items/' + dso.id]"
|
||||
class="lead btn btn-primary viewButton">View</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ds-truncatable>
|
@@ -0,0 +1,55 @@
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
|
||||
import { PaginatedList } from '../../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../../core/shared/page-info.model';
|
||||
import { getEntityGridElementTestComponent } from '../../../../../shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.spec';
|
||||
import { JournalSearchResultGridElementComponent } from './journal-search-result-grid-element.component';
|
||||
|
||||
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('JournalSearchResultGridElementComponent', getEntityGridElementTestComponent(JournalSearchResultGridElementComponent, mockItemWithMetadata, mockItemWithoutMetadata, ['editor', 'publisher', 'description']));
|
@@ -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 search result of the type Journal
|
||||
*/
|
||||
export class JournalSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-issue-search-result-list-element>
|
@@ -1,17 +1,13 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { JournalIssueListElementComponent } 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/item-type-switcher.component';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
|
||||
let journalIssueListElementComponent: JournalIssueListElementComponent;
|
||||
let fixture: ComponentFixture<JournalIssueListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -34,28 +30,22 @@ const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
]
|
||||
}
|
||||
});
|
||||
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
describe('JournalIssueListElementComponent', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ JournalIssueListElementComponent , TruncatePipe],
|
||||
declarations: [JournalIssueListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: ITEM, useValue: mockItemWithMetadata},
|
||||
{ provide: TruncatableService, useValue: {} }
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
|
||||
schemas: [ NO_ERRORS_SCHEMA ]
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalIssueListElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
@@ -63,55 +53,19 @@ describe('JournalIssueListElementComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalIssueListElementComponent);
|
||||
journalIssueListElementComponent = fixture.componentInstance;
|
||||
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe('When the item has a journal identifier', () => {
|
||||
describe(`when the journal issue is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
journalIssueListElementComponent.item = mockItemWithMetadata;
|
||||
comp.object = mockItem;
|
||||
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();
|
||||
it(`should contain a JournalIssueListElementComponent`, () => {
|
||||
const journalIssueListElement = fixture.debugElement.query(By.css(`ds-journal-issue-search-result-list-element`));
|
||||
expect(journalIssueListElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When the item has no journal identifier', () => {
|
||||
beforeEach(() => {
|
||||
journalIssueListElementComponent.item = 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.item = 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.item = 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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
|
||||
import { 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';
|
||||
|
||||
@rendersItemType('JournalIssue', ItemViewMode.Element)
|
||||
@listableObjectComponent('JournalIssue', ViewMode.ListElement)
|
||||
@Component({
|
||||
selector: 'ds-journal-issue-list-element',
|
||||
styleUrls: ['./journal-issue-list-element.component.scss'],
|
||||
@@ -11,5 +13,5 @@ import { TypedItemSearchResultListElementComponent } from '../../../../shared/ob
|
||||
/**
|
||||
* 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> {
|
||||
}
|
||||
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-volume-search-result-list-element>
|
@@ -1,17 +1,13 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { JournalVolumeListElementComponent } 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/item-type-switcher.component';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
|
||||
let journalVolumeListElementComponent: JournalVolumeListElementComponent;
|
||||
let fixture: ComponentFixture<JournalVolumeListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -34,28 +30,22 @@ const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
]
|
||||
}
|
||||
});
|
||||
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
describe('JournalVolumeListElementComponent', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ JournalVolumeListElementComponent , TruncatePipe],
|
||||
declarations: [JournalVolumeListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: ITEM, useValue: mockItemWithMetadata},
|
||||
{ provide: TruncatableService, useValue: {} }
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
|
||||
schemas: [ NO_ERRORS_SCHEMA ]
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalVolumeListElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
@@ -63,55 +53,18 @@ describe('JournalVolumeListElementComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalVolumeListElementComponent);
|
||||
journalVolumeListElementComponent = fixture.componentInstance;
|
||||
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe('When the item has a journal title', () => {
|
||||
describe(`when the journal volume is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
journalVolumeListElementComponent.item = mockItemWithMetadata;
|
||||
comp.object = mockItem;
|
||||
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.item = 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.item = 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.item = 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();
|
||||
it(`should contain a JournalVolumeListElementComponent`, () => {
|
||||
const journalVolumeListElement = fixture.debugElement.query(By.css(`ds-journal-volume-search-result-list-element`));
|
||||
expect(journalVolumeListElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
|
||||
import { 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';
|
||||
|
||||
@rendersItemType('JournalVolume', ItemViewMode.Element)
|
||||
@listableObjectComponent('JournalVolume', ViewMode.ListElement)
|
||||
@Component({
|
||||
selector: 'ds-journal-volume-list-element',
|
||||
styleUrls: ['./journal-volume-list-element.component.scss'],
|
||||
@@ -11,5 +13,5 @@ import { TypedItemSearchResultListElementComponent } from '../../../../shared/ob
|
||||
/**
|
||||
* 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> {
|
||||
}
|
||||
|
@@ -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: {} }" [linkType]="linkType"></ds-journal-search-result-list-element>
|
@@ -1,17 +1,13 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { JournalListElementComponent } 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/item-type-switcher.component';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
|
||||
let journalListElementComponent: JournalListElementComponent;
|
||||
let fixture: ComponentFixture<JournalListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
@@ -28,28 +24,22 @@ const mockItemWithMetadata: Item = Object.assign(new Item(), {
|
||||
]
|
||||
}
|
||||
});
|
||||
const mockItemWithoutMetadata: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
describe('JournalListElementComponent', () => {
|
||||
let comp;
|
||||
let fixture;
|
||||
|
||||
const truncatableServiceStub: any = {
|
||||
isCollapsed: (id: number) => observableOf(true),
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ JournalListElementComponent , TruncatePipe],
|
||||
declarations: [JournalListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ provide: ITEM, useValue: mockItemWithMetadata},
|
||||
{ provide: TruncatableService, useValue: {} }
|
||||
{ provide: TruncatableService, useValue: truncatableServiceStub },
|
||||
],
|
||||
|
||||
schemas: [ NO_ERRORS_SCHEMA ]
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(JournalListElementComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
@@ -57,31 +47,18 @@ describe('JournalListElementComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalListElementComponent);
|
||||
journalListElementComponent = fixture.componentInstance;
|
||||
|
||||
comp = fixture.componentInstance;
|
||||
}));
|
||||
|
||||
describe('When the item has an issn', () => {
|
||||
describe(`when the journal is rendered`, () => {
|
||||
beforeEach(() => {
|
||||
journalListElementComponent.item = mockItemWithMetadata;
|
||||
comp.object = mockItem;
|
||||
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.item = mockItemWithoutMetadata;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should not show the journals span', () => {
|
||||
const issnField = fixture.debugElement.query(By.css('span.item-list-journals'));
|
||||
expect(issnField).toBeNull();
|
||||
it(`should contain a JournalListElementComponent`, () => {
|
||||
const journalListElement = fixture.debugElement.query(By.css(`ds-journal-search-result-list-element`));
|
||||
expect(journalListElement).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { TypedItemSearchResultListElementComponent } from '../../../../shared/object-list/item-list-element/item-types/typed-item-search-result-list-element.component';
|
||||
import { 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';
|
||||
|
||||
@rendersItemType('Journal', ItemViewMode.Element)
|
||||
@listableObjectComponent('Journal', ViewMode.ListElement)
|
||||
@Component({
|
||||
selector: 'ds-journal-list-element',
|
||||
styleUrls: ['./journal-list-element.component.scss'],
|
||||
@@ -11,5 +13,5 @@ import { TypedItemSearchResultListElementComponent } from '../../../../shared/ob
|
||||
/**
|
||||
* 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> {
|
||||
}
|
||||
|
@@ -0,0 +1,25 @@
|
||||
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer"
|
||||
[routerLink]="['/items/' + dso.id]" class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></a>
|
||||
<span *ngIf="linkType == linkTypes.None"
|
||||
class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></span>
|
||||
<span class="text-muted">
|
||||
<ds-truncatable-part [id]="dso.id" [minLines]="1">
|
||||
<span *ngIf="dso.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="dso.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>
|
@@ -0,0 +1,125 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
import { JournalIssueSearchResultListElementComponent } from './journal-issue-search-result-list-element.component';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
|
||||
|
||||
let journalIssueListElementComponent: JournalIssueSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<JournalIssueSearchResultListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: 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: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
describe('JournalIssueSearchResultListElementComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [JournalIssueSearchResultListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ 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();
|
||||
});
|
||||
});
|
||||
});
|
@@ -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 search result of the type Journal Issue
|
||||
*/
|
||||
export class JournalIssueSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer"
|
||||
[routerLink]="['/items/' + dso.id]" class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></a>
|
||||
<span *ngIf="linkType == linkTypes.None"
|
||||
class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></span>
|
||||
<span class="text-muted">
|
||||
<ds-truncatable-part [id]="dso.id" [minLines]="1">
|
||||
<span *ngIf="dso.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="dso.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>
|
@@ -0,0 +1,124 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { JournalVolumeSearchResultListElementComponent } from './journal-volume-search-result-list-element.component';
|
||||
import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
|
||||
|
||||
let journalVolumeListElementComponent: JournalVolumeSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<JournalVolumeSearchResultListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: 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: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
describe('JournalVolumeSearchResultListElementComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [JournalVolumeSearchResultListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ 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();
|
||||
});
|
||||
});
|
||||
});
|
@@ -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 search result of the type Journal Volume
|
||||
*/
|
||||
export class JournalVolumeSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||
<ds-truncatable [id]="dso.id">
|
||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer"
|
||||
[routerLink]="['/items/' + dso.id]" class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></a>
|
||||
<span *ngIf="linkType == linkTypes.None"
|
||||
class="lead"
|
||||
[innerHTML]="firstMetadataValue('dc.title')"></span>
|
||||
<span class="text-muted">
|
||||
<ds-truncatable-part [id]="dso.id" [minLines]="1">
|
||||
<span *ngIf="dso.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>
|
@@ -0,0 +1,96 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { JournalSearchResultListElementComponent } from './journal-search-result-list-element.component';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe';
|
||||
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
|
||||
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||
|
||||
let journalListElementComponent: JournalSearchResultListElementComponent;
|
||||
let fixture: ComponentFixture<JournalSearchResultListElementComponent>;
|
||||
|
||||
const mockItemWithMetadata: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: 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: ItemSearchResult = Object.assign(
|
||||
new ItemSearchResult(),
|
||||
{
|
||||
indexableObject: Object.assign(new Item(), {
|
||||
bitstreams: observableOf({}),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
language: 'en_US',
|
||||
value: 'This is just another title'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
describe('JournalSearchResultListElementComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [JournalSearchResultListElementComponent, TruncatePipe],
|
||||
providers: [
|
||||
{ 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();
|
||||
});
|
||||
});
|
||||
});
|
@@ -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 search result of the type Journal
|
||||
*/
|
||||
export class JournalSearchResultListElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
|
||||
}
|
@@ -1,54 +1,54 @@
|
||||
<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]="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>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isJournalVolumeOfIssue'"
|
||||
[label]="'relationships.isSingleVolumeOf' | translate">
|
||||
</ds-related-items>
|
||||
<ds-related-items
|
||||
class="mb-1 mt-1"
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isPublicationOfJournalIssue'"
|
||||
[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>
|
||||
|
@@ -1,13 +1,8 @@
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { JournalIssueComponent } from './journal-issue.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import {
|
||||
createRelationshipsObservable,
|
||||
getItemPageFieldsTest
|
||||
} from '../../../../+item-page/simple/item-types/shared/item.component.spec';
|
||||
import { createRelationshipsObservable, getItemPageFieldsTest } from '../../../../+item-page/simple/item-types/shared/item.component.spec';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { ItemComponent } from '../../../../+item-page/simple/item-types/shared/item.component';
|
||||
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
|
||||
@rendersItemType('JournalIssue', ItemViewMode.Full)
|
||||
@listableObjectComponent('JournalIssue', ViewMode.StandalonePage)
|
||||
@Component({
|
||||
selector: 'ds-journal-issue',
|
||||
styleUrls: ['./journal-issue.component.scss'],
|
||||
|
@@ -1,37 +1,37 @@
|
||||
<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]="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>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isJournalOfVolume'"
|
||||
[label]="'relationships.isSingleJournalOf' | translate">
|
||||
</ds-related-items>
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isIssueOfJournalVolume'"
|
||||
[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>
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { ItemComponent } from '../../../../+item-page/simple/item-types/shared/item.component';
|
||||
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
|
||||
@rendersItemType('JournalVolume', ItemViewMode.Full)
|
||||
@listableObjectComponent('JournalVolume', ViewMode.StandalonePage)
|
||||
@Component({
|
||||
selector: 'ds-journal-volume',
|
||||
styleUrls: ['./journal-volume.component.scss'],
|
||||
|
@@ -1,42 +1,42 @@
|
||||
<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]="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>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<ds-related-items
|
||||
[parentItem]="item"
|
||||
[parentItem]="object"
|
||||
[relationType]="'isVolumeOfJournal'"
|
||||
[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>
|
||||
|
@@ -1,19 +1,16 @@
|
||||
import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||
import { ITEM } from '../../../../shared/items/switcher/item-type-switcher.component';
|
||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loader';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||
import { JournalComponent } from './journal.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { GenericItemPageFieldComponent } from '../../../../+item-page/simple/field-components/specific-field/generic/generic-item-page-field.component';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
@@ -55,7 +52,6 @@ describe('JournalComponent', () => {
|
||||
})],
|
||||
declarations: [JournalComponent, GenericItemPageFieldComponent, TruncatePipe],
|
||||
providers: [
|
||||
{provide: ITEM, useValue: mockItem},
|
||||
{provide: ItemDataService, useValue: {}},
|
||||
{provide: TruncatableService, useValue: {}}
|
||||
],
|
||||
@@ -69,6 +65,7 @@ describe('JournalComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
fixture = TestBed.createComponent(JournalComponent);
|
||||
comp = fixture.componentInstance;
|
||||
comp.object = mockItem;
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ItemViewMode, rendersItemType } from '../../../../shared/items/item-type-decorator';
|
||||
import { ItemComponent } from '../../../../+item-page/simple/item-types/shared/item.component';
|
||||
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
|
||||
@rendersItemType('Journal', ItemViewMode.Full)
|
||||
@listableObjectComponent('Journal', ViewMode.StandalonePage)
|
||||
@Component({
|
||||
selector: 'ds-journal',
|
||||
styleUrls: ['./journal.component.scss'],
|
||||
|
@@ -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({
|
||||
|
@@ -0,0 +1 @@
|
||||
<ds-org-unit-search-result-grid-element [object]="{ indexableObject: object, hitHighlights: {} }" [linkType]="linkType"></ds-org-unit-search-result-grid-element>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user