From a1e3c83e46ab240258724b3ef3508c03aa60546c Mon Sep 17 00:00:00 2001 From: William Welling Date: Tue, 8 Jul 2025 16:10:51 -0500 Subject: [PATCH 1/2] Restore non-customized image gallery theme components This customization required non standard custom components with custom selectors. Therefore, this restoration is likely broken in itself without the customizations. --- .../collection-page.component.html | 153 ++++++-------- .../collection-page.component.scss | 0 .../collection-page.component.ts | 35 +++- .../community-list.component.ts | 22 +- .../community-page.component.html | 120 +++++------ .../community-page.component.scss | 0 .../community-page.component.ts | 189 +++++++++--------- .../item/item-grid-element.component.html | 8 - .../item/item-grid-element.component.scss | 0 .../item/item-grid-element.component.ts | 9 +- ...-search-result-grid-element.component.html | 104 +++++----- ...-search-result-grid-element.component.scss | 14 -- ...em-search-result-grid-element.component.ts | 21 +- .../image-gallery/eager-theme.module.ts | 30 +-- 14 files changed, 347 insertions(+), 358 deletions(-) create mode 100644 src/themes/image-gallery/app/collection-page/collection-page.component.scss create mode 100644 src/themes/image-gallery/app/community-page/community-page.component.scss create mode 100644 src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.scss diff --git a/src/themes/image-gallery/app/collection-page/collection-page.component.html b/src/themes/image-gallery/app/collection-page/collection-page.component.html index 9e74912aa24..407adeec926 100644 --- a/src/themes/image-gallery/app/collection-page/collection-page.component.html +++ b/src/themes/image-gallery/app/collection-page/collection-page.component.html @@ -1,97 +1,70 @@
-
-
-
- -
-
- - - - - - + + + + @if (logoRD$) { + - --> - - - - - - - - - - - - - -
- -
-
+ } + + + + + + + + + + + +
+
- - - - -
- - -

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

- - - -
- - - -
+ + +
-
- - - -
+ @if (collection.copyrightText) { +
+ + + +
+ } +
+ }
-
- - + } + @if (collectionRD?.hasFailed) { + + } + @if (collectionRD?.isLoading) { + + } diff --git a/src/themes/image-gallery/app/collection-page/collection-page.component.scss b/src/themes/image-gallery/app/collection-page/collection-page.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/image-gallery/app/collection-page/collection-page.component.ts b/src/themes/image-gallery/app/collection-page/collection-page.component.ts index b8cc428b7ea..2cfeeb81c1a 100644 --- a/src/themes/image-gallery/app/collection-page/collection-page.component.ts +++ b/src/themes/image-gallery/app/collection-page/collection-page.component.ts @@ -1,18 +1,45 @@ +import { AsyncPipe } from '@angular/common'; import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; import { CollectionPageComponent as BaseComponent } from '../../../../app/collection-page/collection-page.component'; import { fadeIn, fadeInOut } from '../../../../app/shared/animations/fade'; +import { ThemedComcolPageBrowseByComponent } from '../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; +import { ThemedComcolPageContentComponent } from '../../../../app/shared/comcol/comcol-page-content/themed-comcol-page-content.component'; +import { ThemedComcolPageHandleComponent } from '../../../../app/shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; +import { ComcolPageHeaderComponent } from '../../../../app/shared/comcol/comcol-page-header/comcol-page-header.component'; +import { ComcolPageLogoComponent } from '../../../../app/shared/comcol/comcol-page-logo/comcol-page-logo.component'; +import { DsoEditMenuComponent } from '../../../../app/shared/dso-page/dso-edit-menu/dso-edit-menu.component'; +import { ErrorComponent } from '../../../../app/shared/error/error.component'; +import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component'; +import { VarDirective } from '../../../../app/shared/utils/var.directive'; @Component({ selector: 'ds-collection-page', - templateUrl: './collection-page.component.html', + // styleUrls: ['../../../../app/collection-page/collection-page.component.scss'], + styleUrls: ['./collection-page.component.scss'], // templateUrl: '../../../../app/collection-page/collection-page.component.html', - // styleUrls: ['./collection-page.component.scss'], - styleUrls: ['../../../../app/collection-page/collection-page.component.scss'], + templateUrl: './collection-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, animations: [ fadeIn, fadeInOut - ] + ], + imports: [ + AsyncPipe, + ComcolPageHeaderComponent, + ComcolPageLogoComponent, + DsoEditMenuComponent, + ErrorComponent, + RouterOutlet, + ThemedComcolPageBrowseByComponent, + ThemedComcolPageContentComponent, + ThemedComcolPageHandleComponent, + ThemedLoadingComponent, + TranslateModule, + VarDirective, + ], + standalone: true, }) /** * This component represents a detail page for a single collection diff --git a/src/themes/image-gallery/app/community-list-page/community-list/community-list.component.ts b/src/themes/image-gallery/app/community-list-page/community-list/community-list.component.ts index 9c927075e0d..723f5616496 100644 --- a/src/themes/image-gallery/app/community-list-page/community-list/community-list.component.ts +++ b/src/themes/image-gallery/app/community-list-page/community-list/community-list.component.ts @@ -1,4 +1,11 @@ +import { CdkTreeModule } from '@angular/cdk/tree'; +import { AsyncPipe } from '@angular/common'; import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component'; +import { TruncatablePartComponent } from '../../../../../app/shared/truncatable/truncatable-part/truncatable-part.component'; +import { TruncatableComponent } from '../../../../../app/shared/truncatable/truncatable.component'; import { CommunityListComponent as BaseComponent } from '../../../../tamu/app/community-list-page/community-list/community-list.component'; /** @@ -10,9 +17,20 @@ import { CommunityListComponent as BaseComponent } from '../../../../tamu/app/co */ @Component({ selector: 'ds-community-list', + styleUrls: ['../../../../../app/community-list-page/community-list/community-list.component.scss'], // styleUrls: ['./community-list.component.scss'], - // templateUrl: './community-list.component.html' - templateUrl: '../../../../../app/community-list-page/community-list/community-list.component.html' + templateUrl: '../../../../../app/community-list-page/community-list/community-list.component.html', + // templateUrl: './community-list.component.html', + standalone: true, + imports: [ + AsyncPipe, + CdkTreeModule, + RouterLink, + ThemedLoadingComponent, + TranslateModule, + TruncatableComponent, + TruncatablePartComponent, + ], }) export class CommunityListComponent extends BaseComponent { diff --git a/src/themes/image-gallery/app/community-page/community-page.component.html b/src/themes/image-gallery/app/community-page/community-page.component.html index 9ee75f41178..bf72a1a5f62 100644 --- a/src/themes/image-gallery/app/community-page/community-page.component.html +++ b/src/themes/image-gallery/app/community-page/community-page.component.html @@ -1,78 +1,52 @@
-
-
- -
-
- - - - - - - - - - - - - - - - - -
- -
-
- - - - - - - - - - - - -
-

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

- - + @if (communityRD?.hasSucceeded) { +
+ @if (communityRD?.payload; as communityPayload) { +
+
+
+ + + + @if (logoRD$) { + + + } + + + + + + + + + +
+
- - - - - - -
-
- - - -
+
+ + + + +
+ @if (communityPayload.copyrightText) { +
+ + + +
+ } +
+ }
-
+ } - - + @if (communityRD?.hasFailed) { + + } + @if (communityRD?.isLoading) { + + } diff --git a/src/themes/image-gallery/app/community-page/community-page.component.scss b/src/themes/image-gallery/app/community-page/community-page.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/image-gallery/app/community-page/community-page.component.ts b/src/themes/image-gallery/app/community-page/community-page.component.ts index d14c3d07dff..a425af7a3fb 100644 --- a/src/themes/image-gallery/app/community-page/community-page.component.ts +++ b/src/themes/image-gallery/app/community-page/community-page.component.ts @@ -1,111 +1,114 @@ -import { ChangeDetectionStrategy, Component, Inject, OnDestroy } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; -import { BehaviorSubject, Observable, Subject, combineLatest as observableCombineLatest } from 'rxjs'; -import { map, startWith, switchMap } from 'rxjs/operators'; -import { CommunityPageComponent as BaseComponent } from '../../../../app/community-page/community-page.component'; -import { AuthService } from '../../../../app/core/auth/auth.service'; -import { DSONameService } from '../../../../app/core/breadcrumbs/dso-name.service'; -import { BROWSE_LINKS_TO_FOLLOW } from '../../../../app/core/browse/browse.service'; -import { SortDirection, SortOptions } from '../../../../app/core/cache/models/sort-options.model'; -import { CommunityDataService } from '../../../../app/core/data/community-data.service'; -import { AuthorizationDataService } from '../../../../app/core/data/feature-authorization/authorization-data.service'; -import { PaginatedList } from '../../../../app/core/data/paginated-list.model'; -import { RemoteData } from '../../../../app/core/data/remote-data'; -import { MetadataService } from '../../../../app/core/metadata/metadata.service'; -import { PaginationService } from '../../../../app/core/pagination/pagination.service'; -import { DSpaceObjectType } from '../../../../app/core/shared/dspace-object-type.model'; -import { Item } from '../../../../app/core/shared/item.model'; -import { getFirstSucceededRemoteData, toDSpaceObjectListRD } from '../../../../app/core/shared/operators'; -import { SearchService } from '../../../../app/core/shared/search/search.service'; -import { fadeInOut } from '../../../../app/shared/animations/fade'; -import { PaginationComponentOptions } from '../../../../app/shared/pagination/pagination-component-options.model'; -import { PaginatedSearchOptions } from '../../../../app/shared/search/models/paginated-search-options.model'; -import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; +import { AsyncPipe } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + OnInit, +} from '@angular/core'; +import { + ActivatedRoute, + Router, + RouterModule, + RouterOutlet, +} from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { + filter, + map, + mergeMap, +} from 'rxjs/operators'; +import { getCommunityPageRoute } from 'src/app/community-page/community-page-routing-paths'; +import { AuthService } from 'src/app/core/auth/auth.service'; +import { DSONameService } from 'src/app/core/breadcrumbs/dso-name.service'; +import { AuthorizationDataService } from 'src/app/core/data/feature-authorization/authorization-data.service'; +import { FeatureID } from 'src/app/core/data/feature-authorization/feature-id'; +import { RemoteData } from 'src/app/core/data/remote-data'; +import { redirectOn4xx } from 'src/app/core/shared/authorized.operators'; +import { Bitstream } from 'src/app/core/shared/bitstream.model'; +import { Community } from 'src/app/core/shared/community.model'; +import { getAllSucceededRemoteDataPayload } from 'src/app/core/shared/operators'; +import { fadeInOut } from 'src/app/shared/animations/fade'; +import { ThemedComcolPageBrowseByComponent } from 'src/app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; +import { ThemedComcolPageContentComponent } from 'src/app/shared/comcol/comcol-page-content/themed-comcol-page-content.component'; +import { ThemedComcolPageHandleComponent } from 'src/app/shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; +import { ComcolPageHeaderComponent } from 'src/app/shared/comcol/comcol-page-header/comcol-page-header.component'; +import { ComcolPageLogoComponent } from 'src/app/shared/comcol/comcol-page-logo/comcol-page-logo.component'; +import { DsoEditMenuComponent } from 'src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component'; +import { hasValue } from 'src/app/shared/empty.util'; +import { ErrorComponent } from 'src/app/shared/error/error.component'; +import { ThemedLoadingComponent } from 'src/app/shared/loading/themed-loading.component'; +import { VarDirective } from 'src/app/shared/utils/var.directive'; @Component({ - selector: 'ds-community-page', + selector: 'ds-base-community-page', + styleUrls: ['./community-page.component.scss'], templateUrl: './community-page.component.html', - // templateUrl: '../../../../app/community-page/community-page.component.html', - // styleUrls: ['./community-page.component.scss'], - styleUrls: ['../../../../app/community-page/community-page.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - animations: [fadeInOut] + animations: [fadeInOut], + imports: [ + AsyncPipe, + ComcolPageHeaderComponent, + ComcolPageLogoComponent, + DsoEditMenuComponent, + ErrorComponent, + RouterModule, + RouterOutlet, + ThemedComcolPageBrowseByComponent, + ThemedComcolPageContentComponent, + ThemedComcolPageHandleComponent, + ThemedLoadingComponent, + TranslateModule, + VarDirective, + ], + standalone: true, }) /** * This component represents a detail page for a single community */ -export class CommunityPageComponent extends BaseComponent implements OnDestroy { - itemRD$: Observable>>; - paginationConfig: PaginationComponentOptions; - sortConfig: SortOptions; - private paginationChanges$: Subject<{ - paginationConfig: PaginationComponentOptions, - sortConfig: SortOptions - }>; +export class CommunityPageComponent implements OnInit { + /** + * The community displayed on this page + */ + communityRD$: Observable>; + + /** + * Whether the current user is a Community admin + */ + isCommunityAdmin$: Observable; + + /** + * The logo of this community + */ + logoRD$: Observable>; + + /** + * Route to the community page + */ + communityPageRoute$: Observable; constructor( - private searchService: SearchService, - private paginationService: PaginationService, - communityDataService: CommunityDataService, - metadata: MetadataService, - route: ActivatedRoute, - router: Router, - authService: AuthService, - authorizationDataService: AuthorizationDataService, - dsoNameService: DSONameService, - @Inject(APP_CONFIG) public appConfig: AppConfig, + private route: ActivatedRoute, + private router: Router, + private authService: AuthService, + private authorizationDataService: AuthorizationDataService, + public dsoNameService: DSONameService, ) { - super( - communityDataService, - metadata, - route, - router, - authService, - authorizationDataService, - dsoNameService - ); - this.paginationConfig = Object.assign(new PaginationComponentOptions(), { - id: 'cp', - currentPage: 1, - pageSize: this.appConfig.browseBy.pageSize, - }); - this.sortConfig = new SortOptions('dc.date.accessioned', SortDirection.DESC); } ngOnInit(): void { - super.ngOnInit(); - - this.paginationChanges$ = new BehaviorSubject({ - paginationConfig: this.paginationConfig, - sortConfig: this.sortConfig - }); - - const currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); - const currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, this.sortConfig); - - this.itemRD$ = observableCombineLatest([currentPagination$, currentSort$]).pipe( - switchMap(([currentPagination, currentSort]) => this.communityRD$.pipe( - getFirstSucceededRemoteData(), - map((rd) => rd.payload.id), - switchMap((id: string) => { - return this.searchService.search( - new PaginatedSearchOptions({ - scope: id, - pagination: currentPagination, - sort: currentSort, - dsoTypes: [DSpaceObjectType.ITEM] - }), null, true, true, ...BROWSE_LINKS_TO_FOLLOW) - .pipe(toDSpaceObjectListRD()) as Observable>>; - }), - startWith(undefined) // Make sure switching pages shows loading component - ) - ) + this.communityRD$ = this.route.data.pipe( + map((data) => data.dso as RemoteData), + redirectOn4xx(this.router, this.authService), ); + this.logoRD$ = this.communityRD$.pipe( + map((rd: RemoteData) => rd.payload), + filter((community: Community) => hasValue(community)), + mergeMap((community: Community) => community.logo)); + this.communityPageRoute$ = this.communityRD$.pipe( + getAllSucceededRemoteDataPayload(), + map((community) => getCommunityPageRoute(community.id)), + ); + this.isCommunityAdmin$ = this.authorizationDataService.isAuthorized(FeatureID.IsCommunityAdmin); } - - ngOnDestroy(): void { - this.paginationService.clearPagination(this.paginationConfig.id); - } - } diff --git a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html index e068bc42e8b..434c4b5b5c2 100644 --- a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html +++ b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html @@ -1,12 +1,4 @@ - - - - - - - diff --git a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.scss b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts index 1a4a942af75..f369af1339a 100644 --- a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts +++ b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts @@ -5,14 +5,19 @@ import { ViewMode } from '../../../../../../../../app/core/shared/view-mode.mode import { focusShadow } from '../../../../../../../../app/shared/animations/focus'; import { listableObjectComponent } from '../../../../../../../../app/shared/object-collection/shared/listable-object/listable-object.decorator'; import { ItemGridElementComponent as BaseComponent } from '../../../../../../../../app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component'; +import { ItemSearchResultGridElementComponent } from '../../../../../../../../app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; @listableObjectComponent('Publication', ViewMode.GridElement, Context.Any, 'image-gallery') @listableObjectComponent(Item, ViewMode.GridElement, Context.Any, 'image-gallery') @Component({ selector: 'ds-item-grid-element', - styleUrls: ['../../../../../../../../app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.scss'], + styleUrls: ['./item-grid-element.component.scss'], templateUrl: './item-grid-element.component.html', - animations: [focusShadow] + animations: [focusShadow], + standalone: true, + imports: [ + ItemSearchResultGridElementComponent, + ], }) /** * The component for displaying a grid element for an item of the type Publication diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html index f37f5467ca6..6acfa839f09 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html @@ -1,50 +1,60 @@ -
-
- -
- -
- - -
+
+
+ +
+ @if (linkType !== linkTypes.None) { +
+
+ + +
- -
- - -
+ } + @if (linkType === linkTypes.None) { + +
+ + +
-
- -

- {{firstMetadataValue('dc.date.created')}} - - -
- + } +
+ @if (showLabel) { + + } + + +

+
+ @if (dso.hasMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])) { + +

+ @if (dso.hasMetadata('dc.date.issued')) { + {{firstMetadataValue('dc.date.issued')}} + } + @for (author of allMetadataValues(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); track author) { + , + + + } +

+
+ } + @if (dso.hasMetadata('dc.description.abstract')) { + +

+ +

+
+ } +
+ @if (linkType !== linkTypes.None) { + + }
+ +
diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss index eff43255daa..e69de29bb2d 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss @@ -1,14 +0,0 @@ -:host { - .card { - background-color: #E8E8E8; - } - - ::ng-deep { - div.card div.thumbnail { - margin: 15px 15px 0px 15px; - } - div.card div.thumbnail > .thumbnail-content { - object-fit: contain; - } - } -} diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts index 98b8c2b0181..79235362f9f 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts @@ -1,18 +1,35 @@ +import { AsyncPipe } from '@angular/common'; import { Component } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; import { Context } from '../../../../../../../../app/core/shared/context.model'; import { ViewMode } from '../../../../../../../../app/core/shared/view-mode.model'; import { focusShadow } from '../../../../../../../../app/shared/animations/focus'; +import { ThemedBadgesComponent } from '../../../../../../../../app/shared/object-collection/shared/badges/themed-badges.component'; import { ItemSearchResult } from '../../../../../../../../app/shared/object-collection/shared/item-search-result.model'; import { listableObjectComponent } from '../../../../../../../../app/shared/object-collection/shared/listable-object/listable-object.decorator'; import { ItemSearchResultGridElementComponent as BaseComponent } from '../../../../../../../../app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; +import { TruncatablePartComponent } from '../../../../../../../../app/shared/truncatable/truncatable-part/truncatable-part.component'; +import { TruncatableComponent } from '../../../../../../../../app/shared/truncatable/truncatable.component'; +import { ThemedThumbnailComponent } from '../../../../../../../../app/thumbnail/themed-thumbnail.component'; @listableObjectComponent('PublicationSearchResult', ViewMode.GridElement, Context.Any, 'image-gallery') @listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.Any, 'image-gallery') @Component({ - selector: 'ds-item-search-result-grid-element-custom', + selector: 'ds-item-search-result-grid-element', styleUrls: ['./item-search-result-grid-element.component.scss'], templateUrl: './item-search-result-grid-element.component.html', - animations: [focusShadow] + animations: [focusShadow], + standalone: true, + imports: [ + AsyncPipe, + RouterLink, + ThemedBadgesComponent, + ThemedThumbnailComponent, + TranslateModule, + TruncatableComponent, + TruncatablePartComponent, + ], }) /** * The component for displaying a grid element for an item search result of the type Publication diff --git a/src/themes/image-gallery/eager-theme.module.ts b/src/themes/image-gallery/eager-theme.module.ts index 17c3bdc2953..f505c9aff0b 100644 --- a/src/themes/image-gallery/eager-theme.module.ts +++ b/src/themes/image-gallery/eager-theme.module.ts @@ -1,15 +1,8 @@ import { CdkTreeModule } from '@angular/cdk/tree'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { CommunityPageModule } from '../../app/community-page/community-page.module'; -import { NavbarModule } from '../../app/navbar/navbar.module'; + import { RootModule } from '../../app/root.module'; -import { SharedBrowseByModule } from '../../app/shared/browse-by/shared-browse-by.module'; -import { ComcolModule } from '../../app/shared/comcol/comcol.module'; -import { DsoPageModule } from '../../app/shared/dso-page/dso-page.module'; -import { ResultsBackButtonModule } from '../../app/shared/results-back-button/results-back-button.module'; -import { SharedModule } from '../../app/shared/shared.module'; -import { StatisticsModule } from '../../app/statistics/statistics.module'; import { CollectionPageComponent } from './app/collection-page/collection-page.component'; import { CommunityListComponent } from './app/community-list-page/community-list/community-list.component'; import { CommunityPageComponent } from './app/community-page/community-page.component'; @@ -20,35 +13,26 @@ import { ItemSearchResultGridElementComponent } from './app/shared/object-grid/s * Add components that use a custom decorator to ENTRY_COMPONENTS as well as DECLARATIONS. * This will ensure that decorator gets picked up when the app loads */ -const ENTRY_COMPONENTS = [ - CollectionPageComponent, - CommunityPageComponent, -]; +const ENTRY_COMPONENTS = []; const DECLARATIONS = [ ...ENTRY_COMPONENTS, + CollectionPageComponent, CommunityListComponent, + CommunityPageComponent, ItemGridElementComponent, ItemSearchResultGridElementComponent, ]; @NgModule({ imports: [ + CdkTreeModule, CommonModule, - SharedModule, - SharedBrowseByModule, - ResultsBackButtonModule, RootModule, - NavbarModule, - ComcolModule, - DsoPageModule, - StatisticsModule, - CommunityPageModule, - CdkTreeModule, + ...DECLARATIONS, ], - declarations: DECLARATIONS, providers: [ - ...ENTRY_COMPONENTS.map((component) => ({ provide: component })) + ...ENTRY_COMPONENTS.map((component) => ({ provide: component })), ], }) /** From 3e7f51063cade89b0a85ce13cebc7e32246c0ded Mon Sep 17 00:00:00 2001 From: William Welling Date: Wed, 9 Jul 2025 10:55:10 -0500 Subject: [PATCH 2/2] Wrap text on logo, add community list and recent submission grid to community and collection pages --- .../collection-page.component.html | 39 ++++- .../collection-page.component.ts | 103 +++++++++++- .../community-page.component.html | 37 ++++- .../community-page.component.ts | 154 +++++++++++------- .../item/item-grid-element.component.html | 9 + .../item/item-grid-element.component.ts | 2 +- ...-search-result-grid-element.component.html | 8 + ...-search-result-grid-element.component.scss | 14 ++ ...em-search-result-grid-element.component.ts | 2 +- 9 files changed, 303 insertions(+), 65 deletions(-) diff --git a/src/themes/image-gallery/app/collection-page/collection-page.component.html b/src/themes/image-gallery/app/collection-page/collection-page.component.html index 407adeec926..9d0c8666d98 100644 --- a/src/themes/image-gallery/app/collection-page/collection-page.component.html +++ b/src/themes/image-gallery/app/collection-page/collection-page.component.html @@ -13,10 +13,16 @@ @if (logoRD$) { - + + + } + + + + + + + + @if (itemRD?.hasSucceeded) { +
+

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

+ + +
+ } + @if (itemRD?.hasFailed) { + + } + @if (!itemRD || itemRD.isLoading) { + + } + @if (!itemRD?.isLoading && itemRD?.payload?.page.length === 0) { + + } +
+ + @if (collection.copyrightText) { diff --git a/src/themes/image-gallery/app/collection-page/collection-page.component.ts b/src/themes/image-gallery/app/collection-page/collection-page.component.ts index 2cfeeb81c1a..513cc3d2bb2 100644 --- a/src/themes/image-gallery/app/collection-page/collection-page.component.ts +++ b/src/themes/image-gallery/app/collection-page/collection-page.component.ts @@ -1,8 +1,26 @@ import { AsyncPipe } from '@angular/common'; -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; +import { + ChangeDetectionStrategy, + Component, + Inject, + OnDestroy +} from '@angular/core'; +import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; +import { BehaviorSubject, combineLatest, map, Observable, startWith, Subject, switchMap } from 'rxjs'; import { CollectionPageComponent as BaseComponent } from '../../../../app/collection-page/collection-page.component'; +import { AuthService } from '../../../../app/core/auth/auth.service'; +import { DSONameService } from '../../../../app/core/breadcrumbs/dso-name.service'; +import { getBrowseLinksToFollow } from '../../../../app/core/browse/browse.service'; +import { SortDirection, SortOptions } from '../../../../app/core/cache/models/sort-options.model'; +import { AuthorizationDataService } from '../../../../app/core/data/feature-authorization/authorization-data.service'; +import { PaginatedList } from '../../../../app/core/data/paginated-list.model'; +import { RemoteData } from '../../../../app/core/data/remote-data'; +import { PaginationService } from '../../../../app/core/pagination/pagination.service'; +import { DSpaceObjectType } from '../../../../app/core/shared/dspace-object-type.model'; +import { Item } from '../../../../app/core/shared/item.model'; +import { getFirstSucceededRemoteData, toDSpaceObjectListRD } from '../../../../app/core/shared/operators'; +import { SearchService } from '../../../../app/core/shared/search/search.service'; import { fadeIn, fadeInOut } from '../../../../app/shared/animations/fade'; import { ThemedComcolPageBrowseByComponent } from '../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; import { ThemedComcolPageContentComponent } from '../../../../app/shared/comcol/comcol-page-content/themed-comcol-page-content.component'; @@ -12,7 +30,12 @@ import { ComcolPageLogoComponent } from '../../../../app/shared/comcol/comcol-pa import { DsoEditMenuComponent } from '../../../../app/shared/dso-page/dso-edit-menu/dso-edit-menu.component'; import { ErrorComponent } from '../../../../app/shared/error/error.component'; import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component'; +import { ObjectGridComponent } from '../../../../app/shared/object-grid/object-grid.component'; +import { PaginationComponentOptions } from '../../../../app/shared/pagination/pagination-component-options.model'; +import { PaginatedSearchOptions } from '../../../../app/shared/search/models/paginated-search-options.model'; import { VarDirective } from '../../../../app/shared/utils/var.directive'; +import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; +import { CommunityListComponent } from '../community-list-page/community-list/community-list.component'; @Component({ selector: 'ds-collection-page', @@ -29,8 +52,10 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; AsyncPipe, ComcolPageHeaderComponent, ComcolPageLogoComponent, + CommunityListComponent, DsoEditMenuComponent, ErrorComponent, + ObjectGridComponent, RouterOutlet, ThemedComcolPageBrowseByComponent, ThemedComcolPageContentComponent, @@ -44,6 +69,78 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; /** * This component represents a detail page for a single collection */ -export class CollectionPageComponent extends BaseComponent { +export class CollectionPageComponent extends BaseComponent implements OnDestroy { + itemRD$: Observable>>; + + paginationConfig: PaginationComponentOptions; + + sortConfig: SortOptions; + + private paginationChanges$: Subject<{ + paginationConfig: PaginationComponentOptions, + sortConfig: SortOptions + }>; + + constructor( + private readonly searchService: SearchService, + private readonly paginationService: PaginationService, + route: ActivatedRoute, + router: Router, + authService: AuthService, + authorizationDataService: AuthorizationDataService, + public dsoNameService: DSONameService, + @Inject(APP_CONFIG) public appConfig: AppConfig, + ) { + super( + route, + router, + authService, + authorizationDataService, + dsoNameService + ); + + this.paginationConfig = Object.assign(new PaginationComponentOptions(), { + id: 'cp', + currentPage: 1, + pageSize: this.appConfig.browseBy.pageSize, + }); + + this.sortConfig = new SortOptions('dc.date.accessioned', SortDirection.DESC); + } + + ngOnInit(): void { + super.ngOnInit(); + + this.paginationChanges$ = new BehaviorSubject({ + paginationConfig: this.paginationConfig, + sortConfig: this.sortConfig + }); + + const currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); + const currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, this.sortConfig); + + this.itemRD$ = combineLatest([currentPagination$, currentSort$]).pipe( + switchMap(([currentPagination, currentSort]) => this.collectionRD$.pipe( + getFirstSucceededRemoteData(), + map((rd) => rd.payload.id), + switchMap((id: string) => { + return this.searchService.search( + new PaginatedSearchOptions({ + scope: id, + pagination: currentPagination, + sort: currentSort, + dsoTypes: [DSpaceObjectType.ITEM] + }), null, true, true, ...getBrowseLinksToFollow()) + .pipe(toDSpaceObjectListRD()) as Observable>>; + }), + startWith(undefined) // Make sure switching pages shows loading component + ) + ) + ); + } + + ngOnDestroy(): void { + this.paginationService.clearPagination(this.paginationConfig.id); + } } diff --git a/src/themes/image-gallery/app/community-page/community-page.component.html b/src/themes/image-gallery/app/community-page/community-page.component.html index bf72a1a5f62..ab80b0428bd 100644 --- a/src/themes/image-gallery/app/community-page/community-page.component.html +++ b/src/themes/image-gallery/app/community-page/community-page.component.html @@ -9,8 +9,12 @@ @if (logoRD$) { - + + + + } @@ -29,6 +33,37 @@ + + + + + + + + @if (itemRD?.hasSucceeded) { +
+

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

+ + +
+ } + @if (itemRD?.hasFailed) { + + } + @if (!itemRD || itemRD.isLoading) { + + } + @if (!itemRD?.isLoading && itemRD?.payload?.page.length === 0) { + + } +
+ + @if (communityPayload.copyrightText) { diff --git a/src/themes/image-gallery/app/community-page/community-page.component.ts b/src/themes/image-gallery/app/community-page/community-page.component.ts index a425af7a3fb..ece1cb13119 100644 --- a/src/themes/image-gallery/app/community-page/community-page.component.ts +++ b/src/themes/image-gallery/app/community-page/community-page.component.ts @@ -2,7 +2,8 @@ import { AsyncPipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, - OnInit, + Inject, + OnDestroy } from '@angular/core'; import { ActivatedRoute, @@ -11,33 +12,40 @@ import { RouterOutlet, } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs'; import { - filter, map, - mergeMap, + startWith, + switchMap } from 'rxjs/operators'; -import { getCommunityPageRoute } from 'src/app/community-page/community-page-routing-paths'; -import { AuthService } from 'src/app/core/auth/auth.service'; -import { DSONameService } from 'src/app/core/breadcrumbs/dso-name.service'; -import { AuthorizationDataService } from 'src/app/core/data/feature-authorization/authorization-data.service'; -import { FeatureID } from 'src/app/core/data/feature-authorization/feature-id'; -import { RemoteData } from 'src/app/core/data/remote-data'; -import { redirectOn4xx } from 'src/app/core/shared/authorized.operators'; -import { Bitstream } from 'src/app/core/shared/bitstream.model'; -import { Community } from 'src/app/core/shared/community.model'; -import { getAllSucceededRemoteDataPayload } from 'src/app/core/shared/operators'; -import { fadeInOut } from 'src/app/shared/animations/fade'; -import { ThemedComcolPageBrowseByComponent } from 'src/app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; -import { ThemedComcolPageContentComponent } from 'src/app/shared/comcol/comcol-page-content/themed-comcol-page-content.component'; -import { ThemedComcolPageHandleComponent } from 'src/app/shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; -import { ComcolPageHeaderComponent } from 'src/app/shared/comcol/comcol-page-header/comcol-page-header.component'; -import { ComcolPageLogoComponent } from 'src/app/shared/comcol/comcol-page-logo/comcol-page-logo.component'; -import { DsoEditMenuComponent } from 'src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component'; -import { hasValue } from 'src/app/shared/empty.util'; -import { ErrorComponent } from 'src/app/shared/error/error.component'; -import { ThemedLoadingComponent } from 'src/app/shared/loading/themed-loading.component'; -import { VarDirective } from 'src/app/shared/utils/var.directive'; +import { CommunityPageComponent as BaseComponent } from '../../../../app/community-page/community-page.component'; +import { AuthService } from '../../../../app/core/auth/auth.service'; +import { DSONameService } from '../../../../app/core/breadcrumbs/dso-name.service'; +import { getBrowseLinksToFollow } from '../../../../app/core/browse/browse.service'; +import { SortDirection, SortOptions } from '../../../../app/core/cache/models/sort-options.model'; +import { AuthorizationDataService } from '../../../../app/core/data/feature-authorization/authorization-data.service'; +import { PaginatedList } from '../../../../app/core/data/paginated-list.model'; +import { RemoteData } from '../../../../app/core/data/remote-data'; +import { PaginationService } from '../../../../app/core/pagination/pagination.service'; +import { DSpaceObjectType } from '../../../../app/core/shared/dspace-object-type.model'; +import { Item } from '../../../../app/core/shared/item.model'; +import { getFirstSucceededRemoteData, toDSpaceObjectListRD } from '../../../../app/core/shared/operators'; +import { SearchService } from '../../../../app/core/shared/search/search.service'; +import { fadeInOut } from '../../../../app/shared/animations/fade'; +import { ThemedComcolPageBrowseByComponent } from '../../../../app/shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component'; +import { ThemedComcolPageContentComponent } from '../../../../app/shared/comcol/comcol-page-content/themed-comcol-page-content.component'; +import { ThemedComcolPageHandleComponent } from '../../../../app/shared/comcol/comcol-page-handle/themed-comcol-page-handle.component'; +import { ComcolPageHeaderComponent } from '../../../../app/shared/comcol/comcol-page-header/comcol-page-header.component'; +import { ComcolPageLogoComponent } from '../../../../app/shared/comcol/comcol-page-logo/comcol-page-logo.component'; +import { DsoEditMenuComponent } from '../../../../app/shared/dso-page/dso-edit-menu/dso-edit-menu.component'; +import { ErrorComponent } from '../../../../app/shared/error/error.component'; +import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component'; +import { ObjectGridComponent } from '../../../../app/shared/object-grid/object-grid.component'; +import { PaginationComponentOptions } from '../../../../app/shared/pagination/pagination-component-options.model'; +import { PaginatedSearchOptions } from '../../../../app/shared/search/models/paginated-search-options.model'; +import { VarDirective } from '../../../../app/shared/utils/var.directive'; +import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface'; +import { CommunityListComponent } from '../community-list-page/community-list/community-list.component'; @Component({ selector: 'ds-base-community-page', @@ -49,8 +57,10 @@ import { VarDirective } from 'src/app/shared/utils/var.directive'; AsyncPipe, ComcolPageHeaderComponent, ComcolPageLogoComponent, + CommunityListComponent, DsoEditMenuComponent, ErrorComponent, + ObjectGridComponent, RouterModule, RouterOutlet, ThemedComcolPageBrowseByComponent, @@ -65,50 +75,78 @@ import { VarDirective } from 'src/app/shared/utils/var.directive'; /** * This component represents a detail page for a single community */ -export class CommunityPageComponent implements OnInit { - /** - * The community displayed on this page - */ - communityRD$: Observable>; +export class CommunityPageComponent extends BaseComponent implements OnDestroy { - /** - * Whether the current user is a Community admin - */ - isCommunityAdmin$: Observable; + itemRD$: Observable>>; - /** - * The logo of this community - */ - logoRD$: Observable>; + paginationConfig: PaginationComponentOptions; - /** - * Route to the community page - */ - communityPageRoute$: Observable; + sortConfig: SortOptions; + + private paginationChanges$: Subject<{ + paginationConfig: PaginationComponentOptions, + sortConfig: SortOptions + }>; constructor( - private route: ActivatedRoute, - private router: Router, - private authService: AuthService, - private authorizationDataService: AuthorizationDataService, + private readonly searchService: SearchService, + private readonly paginationService: PaginationService, + route: ActivatedRoute, + router: Router, + authService: AuthService, + authorizationDataService: AuthorizationDataService, public dsoNameService: DSONameService, + @Inject(APP_CONFIG) public appConfig: AppConfig, ) { + super( + route, + router, + authService, + authorizationDataService, + dsoNameService + ); + + this.paginationConfig = Object.assign(new PaginationComponentOptions(), { + id: 'cp', + currentPage: 1, + pageSize: this.appConfig.browseBy.pageSize, + }); + this.sortConfig = new SortOptions('dc.date.accessioned', SortDirection.DESC); } ngOnInit(): void { - this.communityRD$ = this.route.data.pipe( - map((data) => data.dso as RemoteData), - redirectOn4xx(this.router, this.authService), - ); - this.logoRD$ = this.communityRD$.pipe( - map((rd: RemoteData) => rd.payload), - filter((community: Community) => hasValue(community)), - mergeMap((community: Community) => community.logo)); - this.communityPageRoute$ = this.communityRD$.pipe( - getAllSucceededRemoteDataPayload(), - map((community) => getCommunityPageRoute(community.id)), + super.ngOnInit(); + + this.paginationChanges$ = new BehaviorSubject({ + paginationConfig: this.paginationConfig, + sortConfig: this.sortConfig + }); + + const currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig); + const currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, this.sortConfig); + + this.itemRD$ = combineLatest([currentPagination$, currentSort$]).pipe( + switchMap(([currentPagination, currentSort]) => this.communityRD$.pipe( + getFirstSucceededRemoteData(), + map((rd) => rd.payload.id), + switchMap((id: string) => { + return this.searchService.search( + new PaginatedSearchOptions({ + scope: id, + pagination: currentPagination, + sort: currentSort, + dsoTypes: [DSpaceObjectType.ITEM] + }), null, true, true, ...getBrowseLinksToFollow()) + .pipe(toDSpaceObjectListRD()) as Observable>>; + }), + startWith(undefined) // Make sure switching pages shows loading component + ) + ) ); - this.isCommunityAdmin$ = this.authorizationDataService.isAuthorized(FeatureID.IsCommunityAdmin); + } + + ngOnDestroy(): void { + this.paginationService.clearPagination(this.paginationConfig.id); } } diff --git a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html index 434c4b5b5c2..c6c2b02d402 100644 --- a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html +++ b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.html @@ -1,4 +1,13 @@ + + + + + + + + diff --git a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts index f369af1339a..33f92fa0723 100644 --- a/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts +++ b/src/themes/image-gallery/app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component.ts @@ -5,7 +5,7 @@ import { ViewMode } from '../../../../../../../../app/core/shared/view-mode.mode import { focusShadow } from '../../../../../../../../app/shared/animations/focus'; import { listableObjectComponent } from '../../../../../../../../app/shared/object-collection/shared/listable-object/listable-object.decorator'; import { ItemGridElementComponent as BaseComponent } from '../../../../../../../../app/shared/object-grid/item-grid-element/item-types/item/item-grid-element.component'; -import { ItemSearchResultGridElementComponent } from '../../../../../../../../app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; +import { ItemSearchResultGridElementComponent } from '../../../search-result-grid-element/item-search-result/item/item-search-result-grid-element.component'; @listableObjectComponent('Publication', ViewMode.GridElement, Context.Any, 'image-gallery') @listableObjectComponent(Item, ViewMode.GridElement, Context.Any, 'image-gallery') diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html index 6acfa839f09..009b44e5e3d 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html @@ -20,6 +20,12 @@ }
+ +

+ @if (dso.hasMetadata('dc.date.created')) { + {{firstMetadataValue('dc.date.created')}} + } + +
diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss index e69de29bb2d..eff43255daa 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.scss @@ -0,0 +1,14 @@ +:host { + .card { + background-color: #E8E8E8; + } + + ::ng-deep { + div.card div.thumbnail { + margin: 15px 15px 0px 15px; + } + div.card div.thumbnail > .thumbnail-content { + object-fit: contain; + } + } +} diff --git a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts index 79235362f9f..24e5881c1e9 100644 --- a/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts +++ b/src/themes/image-gallery/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.ts @@ -16,7 +16,7 @@ import { ThemedThumbnailComponent } from '../../../../../../../../app/thumbnail/ @listableObjectComponent('PublicationSearchResult', ViewMode.GridElement, Context.Any, 'image-gallery') @listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.Any, 'image-gallery') @Component({ - selector: 'ds-item-search-result-grid-element', + selector: 'ds-item-search-result-grid-element-custom', styleUrls: ['./item-search-result-grid-element.component.scss'], templateUrl: './item-search-result-grid-element.component.html', animations: [focusShadow],