#150 Intermediate commit

This commit is contained in:
Jonas Van Goolen
2017-11-02 10:53:18 +01:00
parent 491d40c026
commit e7e129f80f
11 changed files with 137 additions and 35 deletions

View File

@@ -71,18 +71,27 @@ export class SearchPageComponent implements OnInit, OnDestroy {
this.query = params.query || ''; this.query = params.query || '';
this.scope = params.scope; this.scope = params.scope;
const page = +params.page || this.searchOptions.pagination.currentPage; const page = +params.page || this.searchOptions.pagination.currentPage;
const pageSize = +params.pageSize || this.searchOptions.pagination.pageSize; let pageSize = +params.pageSize || this.searchOptions.pagination.pageSize;
let pageSizeOptions: number[] = [5, 10, 20, 40, 60, 80, 100];
if (isNotEmpty(params.view) && params.view === ViewMode.Grid) {
pageSize = 12;
pageSizeOptions = [12, 24, 36, 48 , 50, 62, 74, 84];
// pageSize = 9;
// pageSizeOptions = [9, 18, 27, 36 , 45, 54, 63, 72];
}
const sortDirection = +params.sortDirection || this.searchOptions.sort.direction; const sortDirection = +params.sortDirection || this.searchOptions.sort.direction;
const pagination = Object.assign({}, const pagination = Object.assign({},
this.searchOptions.pagination, this.searchOptions.pagination,
{ currentPage: page, pageSize: pageSize } { currentPage: page, pageSize: pageSize, pageSizeOptions: pageSizeOptions}
); );
const sort = Object.assign({}, const sort = Object.assign({},
this.searchOptions.sort, this.searchOptions.sort,
{ direction: sortDirection, field: params.sortField } { direction: sortDirection, field: params.sortField }
); );
this.updateSearchResults({ this.updateSearchResults({
pagination: pagination, pagination: pagination,
sort: sort sort: sort
@@ -98,6 +107,7 @@ export class SearchPageComponent implements OnInit, OnDestroy {
private updateSearchResults(searchOptions) { private updateSearchResults(searchOptions) {
this.resultsRDObs = this.service.search(this.query, this.scope, searchOptions); this.resultsRDObs = this.service.search(this.query, this.scope, searchOptions);
this.searchOptions = searchOptions;
} }
ngOnDestroy() { ngOnDestroy() {

View File

@@ -1,6 +1,9 @@
@import '../../styles/custom_variables';
.card-title{ .card-title{
line-height: 1em; line-height: $line-height-base;
height:3em; height:$headings-line-height;
font-size:$headings-font-size;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@@ -8,29 +11,35 @@
.card-text { .card-text {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
line-height: 1em; line-height: $line-height-base;
margin-bottom:10px; margin-bottom:$card-block-margin-base*2;
} }
.card-text.item-authors { .card-text.item-authors {
height: 1em; height: $line-height-base;
} }
.card-text.item-abstract { .card-text.item-abstract {
height: 5em; height: $content-line-height;
} }
.viewButton{ .viewButton{
display:block; display:table;
margin:auto;
width: $card-button-width;
} }
.card{ .card{
padding:10px; margin-bottom: $card-block-margin-base *3;
margin-bottom: 15px; height: 98%;
} }
.card-img-top ::ng-deep img .card-img-top ::ng-deep img
{ {
height: 120px; height: $card-thumbnail-height;
width: 100%; width: 100%;
object-fit: cover; object-fit: cover;
margin-bottom: 10px;
} }
.card-block{
margin: $card-block-margin-base;
}

View File

@@ -0,0 +1,4 @@
<div class="thumbnail">
<img *ngIf="thumbnail" [src]="thumbnail.content" (error)="errorHandler($event)"/>
<img *ngIf="!thumbnail" [src]="holderSource | dsSafeUrl"/>
</div>

View File

@@ -0,0 +1 @@
@import '../../../styles/variables.scss';

View File

@@ -0,0 +1,42 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ThumbnailComponent } from './thumbnail.component';
import { Bitstream } from '../../core/shared/bitstream.model';
import { SafeUrlPipe } from '../../shared/utils/safe-url-pipe';
describe('ThumbnailComponent', () => {
let comp: ThumbnailComponent;
let fixture: ComponentFixture<ThumbnailComponent>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ThumbnailComponent, SafeUrlPipe]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ThumbnailComponent);
comp = fixture.componentInstance; // BannerComponent test instance
de = fixture.debugElement.query(By.css('div.thumbnail'));
el = de.nativeElement;
});
it('should display image', () => {
comp.thumbnail = new Bitstream();
comp.thumbnail.content = 'test.url';
fixture.detectChanges();
const image: HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute('src')).toBe(comp.thumbnail.content);
});
it('should display placeholder', () => {
fixture.detectChanges();
const image: HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute('src')).toBe(comp.holderSource);
});
});

View File

@@ -0,0 +1,30 @@
import { Component, Input } from '@angular/core';
import { Bitstream } from '../../core/shared/bitstream.model';
/**
* This component renders a given Bitstream as a thumbnail.
* One input parameter of type Bitstream is expected.
* If no Bitstream is provided, a holderjs image will be rendered instead.
*/
@Component({
selector: 'ds-grid-thumbnail',
styleUrls: ['./grid-thumbnail.component.scss'],
templateUrl: './grid-thumbnail.component.html'
})
export class GridThumbnailComponent {
@Input() thumbnail: Bitstream;
data: any = {};
/**
* The default 'holder.js' image
*/
holderSource = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjYwIiBoZWlnaHQ9IjE4MCIgdmlld0JveD0iMCAwIDI2MCAxODAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjwhLS0KU291cmNlIFVSTDogaG9sZGVyLmpzLzEwMCV4MTgwL3RleHQ6Tm8gVGh1bWJuYWlsCkNyZWF0ZWQgd2l0aCBIb2xkZXIuanMgMi42LjAuCkxlYXJuIG1vcmUgYXQgaHR0cDovL2hvbGRlcmpzLmNvbQooYykgMjAxMi0yMDE1IEl2YW4gTWFsb3BpbnNreSAtIGh0dHA6Ly9pbXNreS5jbwotLT48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwhW0NEQVRBWyNob2xkZXJfMTVmNzJmMmFlMGIgdGV4dCB7IGZpbGw6I0FBQUFBQTtmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxM3B0IH0gXV0+PC9zdHlsZT48L2RlZnM+PGcgaWQ9ImhvbGRlcl8xNWY3MmYyYWUwYiI+PHJlY3Qgd2lkdGg9IjI2MCIgaGVpZ2h0PSIxODAiIGZpbGw9IiNFRUVFRUUiLz48Zz48dGV4dCB4PSI3Mi4yNDIxODc1IiB5PSI5NiI+Tm8gVGh1bWJuYWlsPC90ZXh0PjwvZz48L2c+PC9zdmc+';
errorHandler(event) {
event.currentTarget.src = this.holderSource;
}
}

View File

@@ -1,17 +1,18 @@
<div class="card"> <div class="card">
<a [routerLink]="['/items/' + object.id]" class="card-img-top"> <a [routerLink]="['/items/' + object.id]" class="card-img-top">
<ds-thumbnail [thumbnail]="object.getThumbnail()"> <ds-grid-thumbnail [thumbnail]="object.getThumbnail()">
</ds-thumbnail> </ds-grid-thumbnail>
</a> </a>
<div class="card-block"> <div class="card-block">
<h4 class="card-title">{{object.findMetadata('dc.title')}}</h4> <h4 class="card-title">{{object.findMetadata('dc.title')}}</h4>
<p *ngIf="object.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']);" class="item-authors card-text">
<p *ngIf="object.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']);" class="item-authors card-text text-muted">
<span *ngFor="let authorMd of object.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">{{authorMd.value}} <span *ngFor="let authorMd of object.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">{{authorMd.value}}
<span *ngIf="!last">; </span> <span *ngIf="!last">; </span>
</span> </span>
<span *ngIf="object.findMetadata('dc.date.issued')">{{object.findMetadata("dc.date.issued")}}</span>
</p> </p>
(<span *ngIf="object.findMetadata('dc.publisher')" class="item-list-publisher">{{object.findMetadata("dc.publisher")}}, </span><span *ngIf="object.findMetadata('dc.date.issued')" class="item-list-date">{{object.findMetadata("dc.date.issued")}}</span>)
<p *ngIf="object.findMetadata('dc.description.abstract')" class="item-abstract card-text">{{object.findMetadata("dc.description.abstract") | dsTruncate:[200] }}</p> <p *ngIf="object.findMetadata('dc.description.abstract')" class="item-abstract card-text">{{object.findMetadata("dc.description.abstract") | dsTruncate:[200] }}</p>

View File

@@ -10,14 +10,12 @@
(sortDirectionChange)="onSortDirectionChange($event)" (sortDirectionChange)="onSortDirectionChange($event)"
(sortFieldChange)="onSortDirectionChange($event)" (sortFieldChange)="onSortDirectionChange($event)"
(paginationChange)="onPaginationChange($event)"> (paginationChange)="onPaginationChange($event)">
<ul *ngIf="objects.hasSucceeded | async" @fadeIn> <div class="row" *ngIf="objects.hasSucceeded | async" @fadeIn>
<div class="row">
<div class="col-lg-4 col-sm-4 col-xs-12 " <div class="col-lg-4 col-sm-4 col-xs-12 "
*ngFor="let object of (objects.payload | async) | paginate: { itemsPerPage: (pageInfo | async)?.elementsPerPage, currentPage: (pageInfo | async)?.currentPage, totalItems: (pageInfo | async)?.totalElements }"> *ngFor="let object of (objects.payload | async) | paginate: { itemsPerPage: (pageInfo | async)?.elementsPerPage, currentPage: (pageInfo | async)?.currentPage, totalItems: (pageInfo | async)?.totalElements }">
<ds-wrapper-grid-element [object]="object"></ds-wrapper-grid-element> <ds-wrapper-grid-element [object]="object"></ds-wrapper-grid-element>
</div> </div>
</div> </div>
</ul>
<ds-error *ngIf="objects.hasFailed | async" message="{{'error.objects' | translate}}"></ds-error> <ds-error *ngIf="objects.hasFailed | async" message="{{'error.objects' | translate}}"></ds-error>
<ds-loading *ngIf="objects.isLoading | async" message="{{'loading.objects' | translate}}"></ds-loading> <ds-loading *ngIf="objects.isLoading | async" message="{{'loading.objects' | translate}}"></ds-loading>
</ds-pagination> </ds-pagination>

View File

@@ -1,24 +1,29 @@
<div class="card"> <div class="card">
<a [routerLink]="['/items/' + dso.id]" class="card-img-top"> <a [routerLink]="['/items/' + dso.id]" class="card-img-top">
<ds-thumbnail [thumbnail]="dso.getThumbnail()"> <ds-grid-thumbnail [thumbnail]="dso.getThumbnail()">
</ds-thumbnail> </ds-grid-thumbnail>
</a> </a>
<div class="card-block"> <div class="card-block">
<h4 class="card-title">{{dso.findMetadata('dc.title')}}</h4> <p class="card-title" [innerHTML]="dso.findMetadata('dc.title')"></p>
<p *ngIf="dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']);" <p *ngIf="dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])"
class="item-authors card-text"> class="item-authors card-text text-muted">
<span <span
*ngFor="let authorMd of dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">{{authorMd.value}} *ngFor="let authorMd of dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let first=first;">
<span *ngIf="!last">; </span> <span *ngIf="first" [innerHTML]="authorMd.value">
<span
*ngIf="dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']).length>1">, ...</span>
</span>
</span> </span>
</p> <span *ngIf="dso.findMetadata('dc.date.issued')"
(<span *ngIf="dso.findMetadata('dc.publisher')" class="item-list-date">
class="item-list-publisher">{{dso.findMetadata("dc.publisher")}}, </span><span <span *ngIf="dso.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']).length>1">,</span>
*ngIf="dso.findMetadata('dc.date.issued')" class="item-list-date">{{dso.findMetadata("dc.date.issued")}}</span>) {{dso.findMetadata("dc.date.issued")}}</span>
<p *ngIf="dso.findMetadata('dc.description.abstract')" class="item-abstract card-text">
{{dso.findMetadata("dc.description.abstract") | dsTruncate:[200] }}</p> </p>
<p class="item-abstract card-text" [innerHTML]="getFirstValue('dc.description.abstract') | dsTruncate:[200]">
</p>
<a [routerLink]="['/items/' + dso.id]" class="lead btn btn-primary viewButton">View</a> <a [routerLink]="['/items/' + dso.id]" class="lead btn btn-primary viewButton">View</a>
</div> </div>

View File

@@ -40,6 +40,7 @@ import { ThumbnailComponent } from '../thumbnail/thumbnail.component';
import { SearchFormComponent } from './search-form/search-form.component'; import { SearchFormComponent } from './search-form/search-form.component';
import { SearchResultGridElementComponent } from '../object-grid/search-result-grid-element/search-result-grid-element.component'; import { SearchResultGridElementComponent } from '../object-grid/search-result-grid-element/search-result-grid-element.component';
import { ViewModeSwitchComponent } from './view-mode-switch/view-mode-switch.component'; import { ViewModeSwitchComponent } from './view-mode-switch/view-mode-switch.component';
import { GridThumbnailComponent } from '../object-grid/grid-thumbnail/grid-thumbnail.component';
import { VarDirective } from './utils/var.directive'; import { VarDirective } from './utils/var.directive';
const MODULES = [ const MODULES = [
@@ -78,6 +79,7 @@ const COMPONENTS = [
PaginationComponent, PaginationComponent,
SearchFormComponent, SearchFormComponent,
ThumbnailComponent, ThumbnailComponent,
GridThumbnailComponent,
WrapperListElementComponent, WrapperListElementComponent,
ViewModeSwitchComponent ViewModeSwitchComponent
]; ];

View File

@@ -1,3 +1,3 @@
$content-spacing: $spacer * 1.5; $content-spacing: $spacer * 1.5;
$button-height: $input-btn-padding-y * 2 + $input-btn-line-height + calculateRem($input-btn-border-width*2); $button-height: $input-btn-padding-y * 2 + $input-btn-line-height + calculateRem($input-btn-border-width*2);