diff --git a/package.json b/package.json index f2bb074ff4..662b4b627f 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "methods": "1.1.2", "morgan": "1.9.0", "ngx-pagination": "3.0.1", + "object-fit-images": "^3.2.3", "pem": "1.12.3", "reflect-metadata": "0.1.10", "rxjs": "5.4.3", diff --git a/src/app/+collection-page/collection-page.component.html b/src/app/+collection-page/collection-page.component.html index fe5b2a1f16..05b4d6f11e 100644 --- a/src/app/+collection-page/collection-page.component.html +++ b/src/app/+collection-page/collection-page.component.html @@ -41,13 +41,13 @@

{{'collection.page.browse.recent.head' | translate}}

- - +
diff --git a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html index b04e93ff71..f78b212bee 100644 --- a/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html +++ b/src/app/+community-page/sub-collection-list/community-page-sub-collection-list.component.html @@ -2,12 +2,8 @@

{{'community.sub-collection-list.head' | translate}}

diff --git a/src/app/+home-page/top-level-community-list/top-level-community-list.component.html b/src/app/+home-page/top-level-community-list/top-level-community-list.component.html index a34951afe0..4eebb53e1e 100644 --- a/src/app/+home-page/top-level-community-list/top-level-community-list.component.html +++ b/src/app/+home-page/top-level-community-list/top-level-community-list.component.html @@ -1,15 +1,13 @@ -
-

{{'home.top-level-communities.head' | translate}}

-

{{'home.top-level-communities.help' | translate}}

- - -
- - -
+
+

{{'home.top-level-communities.head' | translate}}

+

{{'home.top-level-communities.help' | translate}}

+ + +
+ +
diff --git a/src/app/+search-page/search-page.component.ts b/src/app/+search-page/search-page.component.ts index 153402d11f..d50f5e9442 100644 --- a/src/app/+search-page/search-page.component.ts +++ b/src/app/+search-page/search-page.component.ts @@ -51,7 +51,22 @@ export class SearchPageComponent implements OnInit, OnDestroy { ); this.scopeListRDObs = communityService.findAll(); // Initial pagination config + const pagination: PaginationComponentOptions = new PaginationComponentOptions(); + pagination.id = 'search-results-pagination'; + pagination.currentPage = 1; + pagination.pageSize = 10; + + // TODO Update to accommodate view switcher + this.route.queryParams.map((params) => { + if (isNotEmpty(params.view) && params.view == 'grid') { + pagination.pageSize = 12; + } + }); + + + const sort: SortOptions = new SortOptions(); this.searchOptions = this.service.searchOptions; + } ngOnInit(): void { diff --git a/src/app/+search-page/search-page.module.ts b/src/app/+search-page/search-page.module.ts index 6519d1e92a..be99a0eae4 100644 --- a/src/app/+search-page/search-page.module.ts +++ b/src/app/+search-page/search-page.module.ts @@ -7,6 +7,9 @@ import { SearchResultsComponent } from './search-results/search-results.componen import { ItemSearchResultListElementComponent } from '../object-list/search-result-list-element/item-search-result/item-search-result-list-element.component'; import { CollectionSearchResultListElementComponent } from '../object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component'; import { CommunitySearchResultListElementComponent } from '../object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; +import { ItemSearchResultGridElementComponent } from '../object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component'; +import { CommunitySearchResultGridElementComponent } from '../object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component' +import { CollectionSearchResultGridElementComponent } from '../object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; import { SearchService } from './search-service/search.service'; import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component'; import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; @@ -37,6 +40,10 @@ const effects = [ ItemSearchResultListElementComponent, CollectionSearchResultListElementComponent, CommunitySearchResultListElementComponent, + ItemSearchResultGridElementComponent, + CollectionSearchResultGridElementComponent, + CommunitySearchResultGridElementComponent, + CommunitySearchResultListElementComponent, SearchFiltersComponent, SearchFilterComponent, SearchFacetFilterComponent @@ -49,7 +56,11 @@ const effects = [ entryComponents: [ ItemSearchResultListElementComponent, CollectionSearchResultListElementComponent, - CommunitySearchResultListElementComponent + CommunitySearchResultListElementComponent, + ItemSearchResultGridElementComponent, + CollectionSearchResultGridElementComponent, + CommunitySearchResultGridElementComponent, ] }) -export class SearchPageModule { } +export class SearchPageModule { +} diff --git a/src/app/+search-page/search-result.model.ts b/src/app/+search-page/search-result.model.ts index 2dd9130ee8..602d8ac9c2 100644 --- a/src/app/+search-page/search-result.model.ts +++ b/src/app/+search-page/search-result.model.ts @@ -1,6 +1,6 @@ import { DSpaceObject } from '../core/shared/dspace-object.model'; import { Metadatum } from '../core/shared/metadatum.model'; -import { ListableObject } from '../object-list/listable-object/listable-object.model'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; export class SearchResult implements ListableObject { diff --git a/src/app/+search-page/search-results/search-results.component.html b/src/app/+search-page/search-results/search-results.component.html index 70e315671b..1b9bd7d52a 100644 --- a/src/app/+search-page/search-results/search-results.component.html +++ b/src/app/+search-page/search-results/search-results.component.html @@ -1,10 +1,10 @@

{{ 'search.results.head' | translate }}

- -
+ diff --git a/src/app/+search-page/search-service/search.service.ts b/src/app/+search-page/search-service/search.service.ts index 4b5ba7b702..5258756bfb 100644 --- a/src/app/+search-page/search-service/search.service.ts +++ b/src/app/+search-page/search-service/search.service.ts @@ -9,10 +9,10 @@ import { SearchOptions } from '../search-options.model'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { Metadatum } from '../../core/shared/metadatum.model'; import { Item } from '../../core/shared/item.model'; -import { ItemSearchResult } from '../../object-list/search-result-list-element/item-search-result/item-search-result.model'; import { SearchFilterConfig } from './search-filter-config.model'; import { FilterType } from './filter-type.model'; import { FacetValue } from './facet-value.model'; +import { ItemSearchResult } from '../../object-collection/shared/item-search-result.model'; import { ViewMode } from '../../+search-page/search-options.model'; import { Router, NavigationExtras, ActivatedRoute } from '@angular/router'; import { RouteService } from '../../shared/route.service'; diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 572efecada..a17a6b31ce 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -3,7 +3,7 @@ import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { CacheableObject } from '../cache/object-cache.reducer'; import { RemoteData } from '../data/remote-data'; import { ResourceType } from './resource-type'; -import { ListableObject } from '../../object-list/listable-object/listable-object.model'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; import { Observable } from 'rxjs/Observable'; /** diff --git a/src/app/object-collection/object-collection.component.html b/src/app/object-collection/object-collection.component.html new file mode 100644 index 0000000000..e651c18290 --- /dev/null +++ b/src/app/object-collection/object-collection.component.html @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/app/object-collection/object-collection.component.scss b/src/app/object-collection/object-collection.component.scss new file mode 100644 index 0000000000..da97dd7a62 --- /dev/null +++ b/src/app/object-collection/object-collection.component.scss @@ -0,0 +1 @@ +@import '../../styles/variables.scss'; diff --git a/src/app/object-collection/object-collection.component.ts b/src/app/object-collection/object-collection.component.ts new file mode 100644 index 0000000000..25761073e4 --- /dev/null +++ b/src/app/object-collection/object-collection.component.ts @@ -0,0 +1,113 @@ +import { Component, EventEmitter, + Input, + OnInit, + Output, SimpleChanges, OnChanges, ChangeDetectorRef } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { Observable } from 'rxjs/Observable'; + +import { RemoteData } from '../core/data/remote-data'; +import { PageInfo } from '../core/shared/page-info.model'; + +import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; + +import { SortDirection } from '../core/cache/models/sort-options.model'; + +import { ListableObject } from './shared/listable-object.model'; +import { hasValue, isNotEmpty } from '../shared/empty.util'; +@Component({ + selector: 'ds-viewable-collection', + styleUrls: ['./object-collection.component.scss'], + templateUrl: './object-collection.component.html', +}) +export class ObjectCollectionComponent implements OnChanges, OnInit { + + @Input() objects: RemoteData; + @Input() config?: PaginationComponentOptions; + pageInfo: Observable; + + /** + * An event fired when the page is changed. + * Event's payload equals to the newly selected page. + */ + @Output() pageChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the page wsize is changed. + * Event's payload equals to the newly selected page size. + */ + @Output() pageSizeChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort direction is changed. + * Event's payload equals to the newly selected sort direction. + */ + @Output() sortDirectionChange: EventEmitter = new EventEmitter(); + + @Output() paginationChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort field is changed. + * Event's payload equals to the newly selected sort field. + */ + @Output() sortFieldChange: EventEmitter = new EventEmitter(); + data: any = {}; + defaultViewMode: string ='list'; + + ngOnChanges(changes: SimpleChanges) { + if (changes.objects && !changes.objects.isFirstChange()) { + this.pageInfo = this.objects.pageInfo; + } + } + + ngOnInit(): void { + this.pageInfo = this.objects.pageInfo; + } + + /** + * @param route + * Route is a singleton service provided by Angular. + * @param router + * Router is a singleton service provided by Angular. + */ + constructor(private cdRef: ChangeDetectorRef, private route: ActivatedRoute, + private router: Router) { + } + + getViewMode(): string { + // TODO Update to accommodate view switcher + + this.route.queryParams.map((params) => { + if (isNotEmpty(params.view) && hasValue(params.view)) { + return params.view; + } else { + return this.defaultViewMode; + } + }); + return this.defaultViewMode; + } + + setViewMode(viewMode: string) { + this.defaultViewMode = viewMode; + } + onPageChange(event) { + this.pageChange.emit(event); + } + + onPageSizeChange(event) { + this.pageSizeChange.emit(event); + } + + onSortDirectionChange(event) { + this.sortDirectionChange.emit(event); + } + + onSortFieldChange(event) { + this.sortFieldChange.emit(event); + } + + onPaginationChange(event) { + this.paginationChange.emit(event); + } + +} diff --git a/src/app/object-collection/shared/item-search-result.model.ts b/src/app/object-collection/shared/item-search-result.model.ts new file mode 100644 index 0000000000..75d56a2488 --- /dev/null +++ b/src/app/object-collection/shared/item-search-result.model.ts @@ -0,0 +1,5 @@ +import { SearchResult } from '../../+search-page/search-result.model'; +import { Item } from '../../core/shared/item.model'; + +export class ItemSearchResult extends SearchResult { +} diff --git a/src/app/object-list/listable-object/listable-object.model.ts b/src/app/object-collection/shared/listable-object.model.ts similarity index 100% rename from src/app/object-list/listable-object/listable-object.model.ts rename to src/app/object-collection/shared/listable-object.model.ts diff --git a/src/app/object-grid/collection-grid-element/collection-grid-element.component.html b/src/app/object-grid/collection-grid-element/collection-grid-element.component.html new file mode 100644 index 0000000000..5dc717cf54 --- /dev/null +++ b/src/app/object-grid/collection-grid-element/collection-grid-element.component.html @@ -0,0 +1,12 @@ +
+ + + + +
+

{{object.name}}

+

{{object.shortDescription}}

+ View + +
+
diff --git a/src/app/object-grid/collection-grid-element/collection-grid-element.component.scss b/src/app/object-grid/collection-grid-element/collection-grid-element.component.scss new file mode 100644 index 0000000000..48e2b121d4 --- /dev/null +++ b/src/app/object-grid/collection-grid-element/collection-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../styles/variables.scss'; +@import '../grid-card-styling.scss'; diff --git a/src/app/object-grid/collection-grid-element/collection-grid-element.component.ts b/src/app/object-grid/collection-grid-element/collection-grid-element.component.ts new file mode 100644 index 0000000000..80be3d75b3 --- /dev/null +++ b/src/app/object-grid/collection-grid-element/collection-grid-element.component.ts @@ -0,0 +1,14 @@ +import { Component, Inject } from '@angular/core'; + +import { Collection } from '../../core/shared/collection.model'; +import { ObjectGridElementComponent } from '../object-grid-element/object-grid-element.component'; +import { gridElementFor } from '../grid-element-decorator'; + +@Component({ + selector: 'ds-collection-grid-element', + styleUrls: ['./collection-grid-element.component.scss'], + templateUrl: './collection-grid-element.component.html' +}) + +@gridElementFor(Collection) +export class CollectionGridElementComponent extends ObjectGridElementComponent {} diff --git a/src/app/object-grid/community-grid-element/community-grid-element.component.html b/src/app/object-grid/community-grid-element/community-grid-element.component.html new file mode 100644 index 0000000000..e4ea3dcb13 --- /dev/null +++ b/src/app/object-grid/community-grid-element/community-grid-element.component.html @@ -0,0 +1,12 @@ +
+ + + + + +
+

{{object.name}}

+

{{object.shortDescription}}

+ View +
+
diff --git a/src/app/object-grid/community-grid-element/community-grid-element.component.scss b/src/app/object-grid/community-grid-element/community-grid-element.component.scss new file mode 100644 index 0000000000..48e2b121d4 --- /dev/null +++ b/src/app/object-grid/community-grid-element/community-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../styles/variables.scss'; +@import '../grid-card-styling.scss'; diff --git a/src/app/object-grid/community-grid-element/community-grid-element.component.ts b/src/app/object-grid/community-grid-element/community-grid-element.component.ts new file mode 100644 index 0000000000..e29e037c5d --- /dev/null +++ b/src/app/object-grid/community-grid-element/community-grid-element.component.ts @@ -0,0 +1,14 @@ +import { Component, Input, Inject } from '@angular/core'; + +import { Community } from '../../core/shared/community.model'; +import { ObjectGridElementComponent } from '../object-grid-element/object-grid-element.component'; +import { gridElementFor} from '../grid-element-decorator'; + +@Component({ + selector: 'ds-community-grid-element', + styleUrls: ['./community-grid-element.component.scss'], + templateUrl: './community-grid-element.component.html' +}) + +@gridElementFor(Community) +export class CommunityGridElementComponent extends ObjectGridElementComponent {} diff --git a/src/app/object-grid/grid-card-styling.scss b/src/app/object-grid/grid-card-styling.scss new file mode 100644 index 0000000000..52b78524b0 --- /dev/null +++ b/src/app/object-grid/grid-card-styling.scss @@ -0,0 +1,36 @@ +.card-title{ + line-height: 1em; + height:3em; + overflow: hidden; + text-overflow: ellipsis; +} + +.card-text { + overflow: hidden; + text-overflow: ellipsis; + line-height: 1em; + margin-bottom:10px; +} +.card-text.item-authors { + height: 1em; +} +.card-text.item-abstract { + height: 5em; + +} +.viewButton{ + display:block; +} + +.card{ + padding:10px; + margin-bottom: 15px; +} + +.card-img-top ::ng-deep img +{ + height: 120px; + width: 100%; + object-fit: cover; + margin-bottom: 10px; +} diff --git a/src/app/object-grid/grid-element-decorator.ts b/src/app/object-grid/grid-element-decorator.ts new file mode 100644 index 0000000000..cd5ebbcaeb --- /dev/null +++ b/src/app/object-grid/grid-element-decorator.ts @@ -0,0 +1,16 @@ +import { GenericConstructor } from '../core/shared/generic-constructor'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; + +const gridElementMap = new Map(); +export function gridElementFor(gridable: GenericConstructor) { + return function decorator(objectElement: any) { + if (!objectElement) { + return; + } + gridElementMap.set(gridable, objectElement); + }; +} + +export function getGridElementFor(gridable: GenericConstructor) { + return gridElementMap.get(gridable); +} diff --git a/src/app/object-grid/item-grid-element/item-grid-element.component.html b/src/app/object-grid/item-grid-element/item-grid-element.component.html new file mode 100644 index 0000000000..ea7b894896 --- /dev/null +++ b/src/app/object-grid/item-grid-element/item-grid-element.component.html @@ -0,0 +1,20 @@ +
+ + + + + +
+

{{object.findMetadata('dc.title')}}

+

+ {{authorMd.value}} + ; + +

+ ({{object.findMetadata("dc.publisher")}}, {{object.findMetadata("dc.date.issued")}}) + +

{{object.findMetadata("dc.description.abstract") | dsTruncate:[200] }}

+ + View +
+
diff --git a/src/app/object-grid/item-grid-element/item-grid-element.component.scss b/src/app/object-grid/item-grid-element/item-grid-element.component.scss new file mode 100644 index 0000000000..48e2b121d4 --- /dev/null +++ b/src/app/object-grid/item-grid-element/item-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../styles/variables.scss'; +@import '../grid-card-styling.scss'; diff --git a/src/app/object-grid/item-grid-element/item-grid-element.component.ts b/src/app/object-grid/item-grid-element/item-grid-element.component.ts new file mode 100644 index 0000000000..c651ccfc9c --- /dev/null +++ b/src/app/object-grid/item-grid-element/item-grid-element.component.ts @@ -0,0 +1,14 @@ +import { Component, Input, Inject } from '@angular/core'; + +import { Item } from '../../core/shared/item.model'; +import { gridElementFor } from '../grid-element-decorator'; +import { ObjectGridElementComponent } from '../object-grid-element/object-grid-element.component'; + +@Component({ + selector: 'ds-item-grid-element', + styleUrls: ['./item-grid-element.component.scss'], + templateUrl: './item-grid-element.component.html' +}) + +@gridElementFor(Item) +export class ItemGridElementComponent extends ObjectGridElementComponent {} diff --git a/src/app/object-grid/object-grid-element/object-grid-element.component.html b/src/app/object-grid/object-grid-element/object-grid-element.component.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/object-grid/object-grid-element/object-grid-element.component.scss b/src/app/object-grid/object-grid-element/object-grid-element.component.scss new file mode 100644 index 0000000000..0351acf15f --- /dev/null +++ b/src/app/object-grid/object-grid-element/object-grid-element.component.scss @@ -0,0 +1,6 @@ +@import '../../../styles/variables.scss'; +@import '../grid-card-styling.scss'; +:host { + display: block; + margin-bottom: $spacer; +} diff --git a/src/app/object-grid/object-grid-element/object-grid-element.component.ts b/src/app/object-grid/object-grid-element/object-grid-element.component.ts new file mode 100644 index 0000000000..c3ab5e39e3 --- /dev/null +++ b/src/app/object-grid/object-grid-element/object-grid-element.component.ts @@ -0,0 +1,14 @@ +import { Component, Inject } from '@angular/core'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; + +@Component({ + selector: 'ds-object-grid-element', + styleUrls: ['./object-grid-element.component.scss'], + templateUrl: './object-grid-element.component.html' +}) +export class ObjectGridElementComponent { + object: T; + public constructor(@Inject('objectElementProvider') public gridable: ListableObject) { + this.object = gridable as T; + } +} diff --git a/src/app/object-grid/object-grid.component.html b/src/app/object-grid/object-grid.component.html new file mode 100644 index 0000000000..2ad9c11a8f --- /dev/null +++ b/src/app/object-grid/object-grid.component.html @@ -0,0 +1,23 @@ + +
    +
    +
    + +
    +
    +
+ + +
diff --git a/src/app/object-grid/object-grid.component.scss b/src/app/object-grid/object-grid.component.scss new file mode 100644 index 0000000000..da97dd7a62 --- /dev/null +++ b/src/app/object-grid/object-grid.component.scss @@ -0,0 +1 @@ +@import '../../styles/variables.scss'; diff --git a/src/app/object-grid/object-grid.component.ts b/src/app/object-grid/object-grid.component.ts new file mode 100644 index 0000000000..b316fe37c2 --- /dev/null +++ b/src/app/object-grid/object-grid.component.ts @@ -0,0 +1,86 @@ +import { + Component, EventEmitter, + Input, + ViewEncapsulation, + ChangeDetectionStrategy, + OnInit, + Output, SimpleChanges, OnChanges, ChangeDetectorRef, DoCheck +} from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { RemoteData } from '../core/data/remote-data'; +import { PageInfo } from '../core/shared/page-info.model'; + +import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; + +import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model'; +import { fadeIn } from '../shared/animations/fade'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; + +@Component({ + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated, + selector: 'ds-object-grid', + styleUrls: [ './object-grid.component.scss' ], + templateUrl: './object-grid.component.html', + animations: [fadeIn] +}) + +export class ObjectGridComponent implements OnChanges, OnInit { + + @Input() objects: RemoteData; + @Input() config: PaginationComponentOptions; + @Input() sortConfig: SortOptions; + @Input() hideGear = false; + @Input() hidePagerWhenSinglePage = true; + pageInfo: Observable; + + /** + * An event fired when the page is changed. + * Event's payload equals to the newly selected page. + */ + @Output() pageChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the page wsize is changed. + * Event's payload equals to the newly selected page size. + */ + @Output() pageSizeChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort direction is changed. + * Event's payload equals to the newly selected sort direction. + */ + @Output() sortDirectionChange: EventEmitter = new EventEmitter(); + + @Output() paginationChange: EventEmitter = new EventEmitter(); + + /** + * An event fired when the sort field is changed. + * Event's payload equals to the newly selected sort field. + */ + @Output() sortFieldChange: EventEmitter = new EventEmitter(); + data: any = {}; + + ngOnChanges(changes: SimpleChanges) { + if (changes.objects && !changes.objects.isFirstChange()) { + this.pageInfo = this.objects.pageInfo; + } + } + + ngOnInit(): void { + this.pageInfo = this.objects.pageInfo; + this.config.pageSize = 4; + } + + /** + * @param route + * Route is a singleton service provided by Angular. + * @param router + * Router is a singleton service provided by Angular. + */ + constructor(private cdRef: ChangeDetectorRef) { + } + + +} diff --git a/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html new file mode 100644 index 0000000000..914fb49487 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html @@ -0,0 +1,2 @@ + +
diff --git a/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.scss b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.scss new file mode 100644 index 0000000000..790f794381 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../../styles/variables.scss'; +@import '../../grid-card-styling.scss'; diff --git a/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.ts b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.ts new file mode 100644 index 0000000000..aa1d495dba --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +import { gridElementFor } from '../../grid-element-decorator'; +import { CollectionSearchResult } from './collection-search-result.model'; +import { SearchResultGridElementComponent } from '../search-result-grid-element.component'; +import { Collection } from '../../../core/shared/collection.model'; + +@Component({ + selector: 'ds-collection-search-result-grid-element', + styleUrls: ['../search-result-grid-element.component.scss', 'collection-search-result-grid-element.component.scss'], + templateUrl: 'collection-search-result-grid-element.component.html' +}) + +@gridElementFor(CollectionSearchResult) +export class CollectionSearchResultGridElementComponent extends SearchResultGridElementComponent {} diff --git a/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result.model.ts b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result.model.ts new file mode 100644 index 0000000000..fa7945dedd --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/collection-search-result/collection-search-result.model.ts @@ -0,0 +1,5 @@ +import { SearchResult } from '../../../+search-page/search-result.model'; +import { Collection } from '../../../core/shared/collection.model'; + +export class CollectionSearchResult extends SearchResult { +} diff --git a/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html new file mode 100644 index 0000000000..d09ef7d668 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html @@ -0,0 +1,2 @@ + +
diff --git a/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.scss b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.scss new file mode 100644 index 0000000000..790f794381 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../../styles/variables.scss'; +@import '../../grid-card-styling.scss'; diff --git a/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.ts b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.ts new file mode 100644 index 0000000000..1ce9e1d09a --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; + +import { CommunitySearchResult } from './community-search-result.model'; +import { Community } from '../../../core/shared/community.model'; +import { gridElementFor } from '../../grid-element-decorator'; +import { SearchResultGridElementComponent } from '../search-result-grid-element.component'; + +@Component({ + selector: 'ds-community-search-result-grid-element', + styleUrls: ['../search-result-grid-element.component.scss', 'community-search-result-grid-element.component.scss'], + templateUrl: 'community-search-result-grid-element.component.html' +}) + +@gridElementFor(CommunitySearchResult) +export class CommunitySearchResultGridElementComponent extends SearchResultGridElementComponent { + +} diff --git a/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result.model.ts b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result.model.ts new file mode 100644 index 0000000000..79ea34b6cd --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/community-search-result/community-search-result.model.ts @@ -0,0 +1,5 @@ +import { SearchResult } from '../../../+search-page/search-result.model'; +import { Community } from '../../../core/shared/community.model'; + +export class CommunitySearchResult extends SearchResult { +} diff --git a/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html new file mode 100644 index 0000000000..c6e1bc6b14 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html @@ -0,0 +1,27 @@ +
+ + + + +
+

{{dso.findMetadata('dc.title')}}

+ +

+ {{authorMd.value}} + ; + +

+ ({{dso.findMetadata("dc.publisher")}}, {{dso.findMetadata("dc.date.issued")}}) + +

+ {{dso.findMetadata("dc.description.abstract") | dsTruncate:[200] }}

+ +
+ View + +
+ diff --git a/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.scss b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.scss new file mode 100644 index 0000000000..790f794381 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../../styles/variables.scss'; +@import '../../grid-card-styling.scss'; diff --git a/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.ts b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.ts new file mode 100644 index 0000000000..7a82803c9b --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; + +import { gridElementFor } from '../../grid-element-decorator'; +import { SearchResultGridElementComponent } from '../search-result-grid-element.component'; +import { Item } from '../../../core/shared/item.model'; +import { ItemSearchResult } from '../../../object-collection/shared/item-search-result.model'; + +@Component({ + selector: 'ds-item-search-result-grid-element', + styleUrls: ['../search-result-grid-element.component.scss', 'item-search-result-grid-element.component.scss'], + templateUrl: 'item-search-result-grid-element.component.html' +}) + +@gridElementFor(ItemSearchResult) +export class ItemSearchResultGridElementComponent extends SearchResultGridElementComponent {} diff --git a/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.scss b/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.scss new file mode 100644 index 0000000000..0f2684f1f1 --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.scss @@ -0,0 +1,8 @@ + @import '../../../styles/variables.scss'; + @import '../grid-card-styling.scss'; +:host { + /deep/ em { + font-weight: bold; + font-style: normal; + } +} diff --git a/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.ts b/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.ts new file mode 100644 index 0000000000..ba98a58d4b --- /dev/null +++ b/src/app/object-grid/search-result-grid-element/search-result-grid-element.component.ts @@ -0,0 +1,57 @@ +import { Component, Inject } from '@angular/core'; + +import { SearchResult } from '../../+search-page/search-result.model'; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { Metadatum } from '../../core/shared/metadatum.model'; +import { isEmpty, hasNoValue } from '../../shared/empty.util'; +import { ObjectGridElementComponent } from '../object-grid-element/object-grid-element.component'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; + +@Component({ + selector: 'ds-search-result-grid-element', + template: `` +}) + +export class SearchResultGridElementComponent, K extends DSpaceObject> extends ObjectGridElementComponent { + dso: K; + + public constructor(@Inject('objectElementProvider') public gridable: ListableObject) { + super(gridable); + this.dso = this.object.dspaceObject; + } + + getValues(keys: string[]): string[] { + const results: string[] = new Array(); + this.object.hitHighlights.forEach( + (md: Metadatum) => { + if (keys.indexOf(md.key) > -1) { + results.push(md.value); + } + } + ); + if (isEmpty(results)) { + this.dso.filterMetadata(keys).forEach( + (md: Metadatum) => { + results.push(md.value); + } + ); + } + return results; + } + + getFirstValue(key: string): string { + let result: string; + this.object.hitHighlights.some( + (md: Metadatum) => { + if (key === md.key) { + result = md.value; + return true; + } + } + ); + if (hasNoValue(result)) { + result = this.dso.findMetadata(key); + } + return result; + } +} diff --git a/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.html b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.html new file mode 100644 index 0000000000..b613b16055 --- /dev/null +++ b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.html @@ -0,0 +1 @@ + diff --git a/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.scss b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.scss new file mode 100644 index 0000000000..48e2b121d4 --- /dev/null +++ b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.scss @@ -0,0 +1,2 @@ +@import '../../../styles/variables.scss'; +@import '../grid-card-styling.scss'; diff --git a/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.ts b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.ts new file mode 100644 index 0000000000..bd15a0d443 --- /dev/null +++ b/src/app/object-grid/wrapper-grid-element/wrapper-grid-element.component.ts @@ -0,0 +1,27 @@ +import { Component, Input, Injector, ReflectiveInjector, OnInit } from '@angular/core'; +import { GenericConstructor } from '../../core/shared/generic-constructor'; +import { getGridElementFor } from '../grid-element-decorator'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; + +@Component({ + selector: 'ds-wrapper-grid-element', + styleUrls: ['./wrapper-grid-element.component.scss'], + templateUrl: './wrapper-grid-element.component.html' +}) +export class WrapperGridElementComponent implements OnInit { + @Input() object: ListableObject; + objectInjector: Injector; + + constructor(private injector: Injector) {} + + ngOnInit(): void { + this.objectInjector = ReflectiveInjector.resolveAndCreate( + [{provide: 'objectElementProvider', useFactory: () => (this.object) }], this.injector); + + } + + getGridElement(): string { + const f: GenericConstructor = this.object.constructor as GenericConstructor; + return getGridElementFor(f); + } +} diff --git a/src/app/object-list/list-element-decorator.ts b/src/app/object-list/list-element-decorator.ts index 64a747d4a5..aa044755ea 100644 --- a/src/app/object-list/list-element-decorator.ts +++ b/src/app/object-list/list-element-decorator.ts @@ -1,5 +1,5 @@ -import { ListableObject } from './listable-object/listable-object.model'; import { GenericConstructor } from '../core/shared/generic-constructor'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; const listElementMap = new Map(); export function listElementFor(listable: GenericConstructor) { diff --git a/src/app/object-list/object-list-element/object-list-element.component.ts b/src/app/object-list/object-list-element/object-list-element.component.ts index df39a7d18d..24f0ec1d93 100644 --- a/src/app/object-list/object-list-element/object-list-element.component.ts +++ b/src/app/object-list/object-list-element/object-list-element.component.ts @@ -1,5 +1,5 @@ import { Component, Inject } from '@angular/core'; -import { ListableObject } from '../listable-object/listable-object.model'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; @Component({ selector: 'ds-object-list-element', diff --git a/src/app/object-list/object-list.component.ts b/src/app/object-list/object-list.component.ts index 0f7decadd7..352d7bc393 100644 --- a/src/app/object-list/object-list.component.ts +++ b/src/app/object-list/object-list.component.ts @@ -11,9 +11,8 @@ import { SortDirection, SortOptions } from '../core/cache/models/sort-options.mo import { RemoteData } from '../core/data/remote-data'; import { PageInfo } from '../core/shared/page-info.model'; -import { ListableObject } from '../object-list/listable-object/listable-object.model'; - import { fadeIn } from '../shared/animations/fade'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; import { hasValue } from '../shared/empty.util'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; @@ -83,6 +82,7 @@ export class ObjectListComponent { @Output() sortFieldChange: EventEmitter = new EventEmitter(); data: any = {}; + onPageChange(event) { this.pageChange.emit(event); } diff --git a/src/app/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.ts b/src/app/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.ts index ef968db0b8..2974a87883 100644 --- a/src/app/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.ts +++ b/src/app/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core'; import { listElementFor } from '../../list-element-decorator'; -import { ItemSearchResult } from './item-search-result.model'; import { SearchResultListElementComponent } from '../search-result-list-element.component'; import { Item } from '../../../core/shared/item.model'; +import { ItemSearchResult } from '../../../object-collection/shared/item-search-result.model'; @Component({ selector: 'ds-item-search-result-list-element', diff --git a/src/app/object-list/search-result-list-element/item-search-result/item-search-result.model.ts b/src/app/object-list/search-result-list-element/item-search-result/item-search-result.model.ts deleted file mode 100644 index d9af3539a0..0000000000 --- a/src/app/object-list/search-result-list-element/item-search-result/item-search-result.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SearchResult } from '../../../+search-page/search-result.model'; -import { Item } from '../../../core/shared/item.model'; - -export class ItemSearchResult extends SearchResult { -} diff --git a/src/app/object-list/search-result-list-element/search-result-list-element.component.ts b/src/app/object-list/search-result-list-element/search-result-list-element.component.ts index 4119bc3c2e..ec0afde65d 100644 --- a/src/app/object-list/search-result-list-element/search-result-list-element.component.ts +++ b/src/app/object-list/search-result-list-element/search-result-list-element.component.ts @@ -1,11 +1,11 @@ import { Component, Inject } from '@angular/core'; import { ObjectListElementComponent } from '../object-list-element/object-list-element.component'; -import { ListableObject } from '../listable-object/listable-object.model'; import { SearchResult } from '../../+search-page/search-result.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { Metadatum } from '../../core/shared/metadatum.model'; import { isEmpty, hasNoValue } from '../../shared/empty.util'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; @Component({ selector: 'ds-search-result-list-element', diff --git a/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts index 443b9681d1..2e1184b023 100644 --- a/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts +++ b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts @@ -1,7 +1,7 @@ import { Component, Input, Injector, ReflectiveInjector, OnInit } from '@angular/core'; -import { ListableObject } from '../listable-object/listable-object.model'; import { getListElementFor } from '../list-element-decorator' import { GenericConstructor } from '../../core/shared/generic-constructor'; +import { ListableObject } from '../../object-collection/shared/listable-object.model'; @Component({ selector: 'ds-wrapper-list-element', diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 245d45ea4e..1ebf251e2c 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -15,20 +15,30 @@ import { SafeUrlPipe } from './utils/safe-url-pipe'; import { TruncatePipe } from './utils/truncate.pipe'; import { CollectionListElementComponent } from '../object-list/collection-list-element/collection-list-element.component'; +import { CommunityListElementComponent } from '../object-list/community-list-element/community-list-element.component'; +import { ItemListElementComponent } from '../object-list/item-list-element/item-list-element.component'; +import { ObjectListElementComponent } from '../object-list/object-list-element/object-list-element.component'; +import { SearchResultListElementComponent } from '../object-list/search-result-list-element/search-result-list-element.component'; +import { WrapperListElementComponent } from '../object-list/wrapper-list-element/wrapper-list-element.component'; +import { ObjectListComponent } from '../object-list/object-list.component'; + +import { CollectionGridElementComponent} from '../object-grid/collection-grid-element/collection-grid-element.component' +import { CommunityGridElementComponent} from '../object-grid/community-grid-element/community-grid-element.component' +import { ItemGridElementComponent} from '../object-grid/item-grid-element/item-grid-element.component' +import { ObjectGridElementComponent} from '../object-grid/object-grid-element/object-grid-element.component' +import { WrapperGridElementComponent} from '../object-grid/wrapper-grid-element/wrapper-grid-element.component' +import { ObjectGridComponent } from '../object-grid/object-grid.component'; +import { ObjectCollectionComponent } from '../object-collection/object-collection.component'; import { ComcolPageContentComponent } from './comcol-page-content/comcol-page-content.component'; import { ComcolPageHeaderComponent } from './comcol-page-header/comcol-page-header.component'; import { ComcolPageLogoComponent } from './comcol-page-logo/comcol-page-logo.component'; -import { CommunityListElementComponent } from '../object-list/community-list-element/community-list-element.component'; import { ErrorComponent } from './error/error.component'; import { LoadingComponent } from './loading/loading.component'; -import { ItemListElementComponent } from '../object-list/item-list-element/item-list-element.component'; -import { ObjectListComponent } from '../object-list/object-list.component'; -import { ObjectListElementComponent } from '../object-list/object-list-element/object-list-element.component'; + import { PaginationComponent } from './pagination/pagination.component'; import { ThumbnailComponent } from '../thumbnail/thumbnail.component'; -import { SearchResultListElementComponent } from '../object-list/search-result-list-element/search-result-list-element.component'; import { SearchFormComponent } from './search-form/search-form.component'; -import { WrapperListElementComponent } from '../object-list/wrapper-list-element/wrapper-list-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 { VarDirective } from './utils/var.directive'; @@ -60,6 +70,11 @@ const COMPONENTS = [ LoadingComponent, ObjectListComponent, ObjectListElementComponent, + WrapperListElementComponent, + ObjectGridComponent, + ObjectGridElementComponent, + WrapperGridElementComponent, + ObjectCollectionComponent, PaginationComponent, SearchFormComponent, ThumbnailComponent, @@ -69,10 +84,14 @@ const COMPONENTS = [ const ENTRY_COMPONENTS = [ // put shared entry components (components that are created dynamically) here + ItemListElementComponent, CollectionListElementComponent, CommunityListElementComponent, - ItemListElementComponent, - SearchResultListElementComponent + SearchResultListElementComponent, + ItemGridElementComponent, + CollectionGridElementComponent, + CommunityGridElementComponent, + SearchResultGridElementComponent ]; const DIRECTIVES = [ diff --git a/src/styles/_mixins.scss b/src/styles/_mixins.scss index 73aa27eccc..7d05343152 100644 --- a/src/styles/_mixins.scss +++ b/src/styles/_mixins.scss @@ -2,3 +2,4 @@ @import '../../node_modules/bootstrap/scss/mixins.scss'; /* Custom mixins go here */ + diff --git a/yarn.lock b/yarn.lock index 91b2a787e2..4211b7228a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4804,6 +4804,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-fit-images@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.3.tgz#4089f6d0070a3b5563d3c1ab6f1b28d61331f0ac" + object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"