mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #1801 from GauravD2t/main
Displaying Recent Submissions on the homepage
This commit is contained in:
@@ -258,3 +258,10 @@ mediaViewer:
|
|||||||
info:
|
info:
|
||||||
enableEndUserAgreement: true
|
enableEndUserAgreement: true
|
||||||
enablePrivacyStatement: true
|
enablePrivacyStatement: true
|
||||||
|
# Home Page
|
||||||
|
homePage:
|
||||||
|
recentSubmissions:
|
||||||
|
# The number of item showing in recent submission components
|
||||||
|
pageSize: 5
|
||||||
|
# Sort record of recent submission
|
||||||
|
sortField: 'dc.date.accessioned'
|
||||||
|
@@ -5,4 +5,5 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
<ds-search-form [inPlaceSearch]="false" [searchPlaceholder]="'home.search-form.placeholder' | translate"></ds-search-form>
|
<ds-search-form [inPlaceSearch]="false" [searchPlaceholder]="'home.search-form.placeholder' | translate"></ds-search-form>
|
||||||
<ds-top-level-community-list></ds-top-level-community-list>
|
<ds-top-level-community-list></ds-top-level-community-list>
|
||||||
|
<ds-recent-item-list *ngIf="recentSubmissionspageSize>0"></ds-recent-item-list>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -3,7 +3,7 @@ import { map } from 'rxjs/operators';
|
|||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Site } from '../core/shared/site.model';
|
import { Site } from '../core/shared/site.model';
|
||||||
|
import { environment } from '../../environments/environment';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-home-page',
|
selector: 'ds-home-page',
|
||||||
styleUrls: ['./home-page.component.scss'],
|
styleUrls: ['./home-page.component.scss'],
|
||||||
@@ -12,10 +12,11 @@ import { Site } from '../core/shared/site.model';
|
|||||||
export class HomePageComponent implements OnInit {
|
export class HomePageComponent implements OnInit {
|
||||||
|
|
||||||
site$: Observable<Site>;
|
site$: Observable<Site>;
|
||||||
|
recentSubmissionspageSize: number;
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
) {
|
) {
|
||||||
|
this.recentSubmissionspageSize = environment.homePage.recentSubmissions.pageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@@ -9,13 +9,14 @@ import { TopLevelCommunityListComponent } from './top-level-community-list/top-l
|
|||||||
import { StatisticsModule } from '../statistics/statistics.module';
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
import { ThemedHomeNewsComponent } from './home-news/themed-home-news.component';
|
import { ThemedHomeNewsComponent } from './home-news/themed-home-news.component';
|
||||||
import { ThemedHomePageComponent } from './themed-home-page.component';
|
import { ThemedHomePageComponent } from './themed-home-page.component';
|
||||||
|
import { RecentItemListComponent } from './recent-item-list/recent-item-list.component';
|
||||||
const DECLARATIONS = [
|
const DECLARATIONS = [
|
||||||
HomePageComponent,
|
HomePageComponent,
|
||||||
ThemedHomePageComponent,
|
ThemedHomePageComponent,
|
||||||
TopLevelCommunityListComponent,
|
TopLevelCommunityListComponent,
|
||||||
ThemedHomeNewsComponent,
|
ThemedHomeNewsComponent,
|
||||||
HomeNewsComponent,
|
HomeNewsComponent,
|
||||||
|
RecentItemListComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@@ -0,0 +1,15 @@
|
|||||||
|
<ng-container *ngVar="(itemRD$ | async) as itemRD">
|
||||||
|
<div class="mt-4" *ngIf="itemRD?.hasSucceeded && itemRD?.payload?.page.length > 0" @fadeIn>
|
||||||
|
<div class="d-flex flex-row border-bottom mb-4 pb-4 ng-tns-c416-2"></div>
|
||||||
|
<h2> {{'home.recent-submissions.head' | translate}}</h2>
|
||||||
|
<div class="my-4" *ngFor="let item of itemRD?.payload?.page">
|
||||||
|
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode" class="pb-4">
|
||||||
|
</ds-listable-object-component-loader>
|
||||||
|
</div>
|
||||||
|
<button (click)="onLoadMore()" class="btn btn-primary search-button mt-4 float-left ng-tns-c290-40">Load
|
||||||
|
more...</button>
|
||||||
|
</div>
|
||||||
|
<ds-error *ngIf="itemRD?.hasFailed" message="{{'error.recent-submissions' | translate}}"></ds-error>
|
||||||
|
<ds-loading *ngIf="!itemRD || itemRD.isLoading" message="{{'loading.recent-submissions' | translate}}">
|
||||||
|
</ds-loading>
|
||||||
|
</ng-container>
|
@@ -0,0 +1,66 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { SearchService } from 'src/app/core/shared/search/search.service';
|
||||||
|
import { createSuccessfulRemoteDataObject } from 'src/app/shared/remote-data.utils';
|
||||||
|
import { SearchServiceStub } from 'src/app/shared/testing/search-service.stub';
|
||||||
|
import { createPaginatedList } from 'src/app/shared/testing/utils.test';
|
||||||
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
|
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
|
||||||
|
import { RecentItemListComponent } from './recent-item-list.component';
|
||||||
|
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||||
|
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
|
||||||
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
|
import { ViewMode } from 'src/app/core/shared/view-mode.model';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
describe('RecentItemListComponent', () => {
|
||||||
|
let component: RecentItemListComponent;
|
||||||
|
let fixture: ComponentFixture<RecentItemListComponent>;
|
||||||
|
const emptyList = createSuccessfulRemoteDataObject(createPaginatedList([]));
|
||||||
|
let paginationService;
|
||||||
|
const searchServiceStub = Object.assign(new SearchServiceStub(), {
|
||||||
|
search: () => observableOf(emptyList),
|
||||||
|
/* eslint-disable no-empty,@typescript-eslint/no-empty-function */
|
||||||
|
clearDiscoveryRequests: () => {}
|
||||||
|
/* eslint-enable no-empty,@typescript-eslint/no-empty-function */
|
||||||
|
});
|
||||||
|
paginationService = new PaginationServiceStub();
|
||||||
|
const mockSearchOptions = observableOf(new PaginatedSearchOptions({
|
||||||
|
pagination: Object.assign(new PaginationComponentOptions(), {
|
||||||
|
id: 'search-page-configuration',
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1
|
||||||
|
}),
|
||||||
|
sort: new SortOptions('dc.date.accessioned', SortDirection.DESC),
|
||||||
|
}));
|
||||||
|
const searchConfigServiceStub = {
|
||||||
|
paginatedSearchOptions: mockSearchOptions
|
||||||
|
};
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ RecentItemListComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: SearchService, useValue: searchServiceStub },
|
||||||
|
{ provide: PaginationService, useValue: paginationService },
|
||||||
|
{ provide: SearchConfigurationService, useValue: searchConfigServiceStub },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RecentItemListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the navigate method on the Router with view mode list parameter as a parameter when setViewMode is called', () => {
|
||||||
|
component.onLoadMore();
|
||||||
|
expect(paginationService.updateRouteWithUrl).toHaveBeenCalledWith(undefined, ['search'], Object({ sortField: 'dc.date.accessioned', sortDirection: 'DESC', page: 1 }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,72 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||||
|
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
|
||||||
|
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||||
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
|
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||||
|
import { Item } from '../../core/shared/item.model';
|
||||||
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
|
import { SearchService } from '../../core/shared/search/search.service';
|
||||||
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
|
import { environment } from '../../../environments/environment';
|
||||||
|
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||||
|
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||||
|
import {
|
||||||
|
toDSpaceObjectListRD
|
||||||
|
} from '../../core/shared/operators';
|
||||||
|
import {
|
||||||
|
Observable,
|
||||||
|
} from 'rxjs';
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-recent-item-list',
|
||||||
|
templateUrl: './recent-item-list.component.html',
|
||||||
|
styleUrls: ['./recent-item-list.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
animations: [
|
||||||
|
fadeIn,
|
||||||
|
fadeInOut
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class RecentItemListComponent implements OnInit {
|
||||||
|
itemRD$: Observable<RemoteData<PaginatedList<Item>>>;
|
||||||
|
paginationConfig: PaginationComponentOptions;
|
||||||
|
sortConfig: SortOptions;
|
||||||
|
/**
|
||||||
|
* The view-mode we're currently on
|
||||||
|
* @type {ViewMode}
|
||||||
|
*/
|
||||||
|
viewMode = ViewMode.ListElement;
|
||||||
|
constructor(private searchService: SearchService,
|
||||||
|
private paginationService: PaginationService,
|
||||||
|
public searchConfigurationService: SearchConfigurationService
|
||||||
|
) {
|
||||||
|
|
||||||
|
this.paginationConfig = Object.assign(new PaginationComponentOptions(), {
|
||||||
|
id: 'hp',
|
||||||
|
pageSize: environment.homePage.recentSubmissions.pageSize,
|
||||||
|
currentPage: 1,
|
||||||
|
maxSize: 1
|
||||||
|
});
|
||||||
|
this.sortConfig = new SortOptions(environment.homePage.recentSubmissions.sortField, SortDirection.DESC);
|
||||||
|
}
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.itemRD$ = this.searchService.search(
|
||||||
|
new PaginatedSearchOptions({
|
||||||
|
pagination: this.paginationConfig,
|
||||||
|
sort: this.sortConfig,
|
||||||
|
}),
|
||||||
|
).pipe(toDSpaceObjectListRD()) as Observable<RemoteData<PaginatedList<Item>>>;
|
||||||
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.paginationService.clearPagination(this.paginationConfig.id);
|
||||||
|
}
|
||||||
|
onLoadMore(): void {
|
||||||
|
this.paginationService.updateRouteWithUrl(this.searchConfigurationService.paginationID, ['search'], {
|
||||||
|
sortField: environment.homePage.recentSubmissions.sortField,
|
||||||
|
sortDirection: 'DESC' as SortDirection,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -4763,5 +4763,6 @@
|
|||||||
"person.orcid.registry.queue": "ORCID Registry Queue",
|
"person.orcid.registry.queue": "ORCID Registry Queue",
|
||||||
|
|
||||||
"person.orcid.registry.auth": "ORCID Authorizations",
|
"person.orcid.registry.auth": "ORCID Authorizations",
|
||||||
|
"home.recent-submissions.head": "Recent Submissions",
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ import { BrowseByConfig } from './browse-by-config.interface';
|
|||||||
import { BundleConfig } from './bundle-config.interface';
|
import { BundleConfig } from './bundle-config.interface';
|
||||||
import { ActuatorsConfig } from './actuators.config';
|
import { ActuatorsConfig } from './actuators.config';
|
||||||
import { InfoConfig } from './info-config.interface';
|
import { InfoConfig } from './info-config.interface';
|
||||||
|
import { HomeConfig } from './homepage-config.interface';
|
||||||
interface AppConfig extends Config {
|
interface AppConfig extends Config {
|
||||||
ui: UIServerConfig;
|
ui: UIServerConfig;
|
||||||
rest: ServerConfig;
|
rest: ServerConfig;
|
||||||
@@ -38,6 +38,7 @@ interface AppConfig extends Config {
|
|||||||
bundle: BundleConfig;
|
bundle: BundleConfig;
|
||||||
actuators: ActuatorsConfig
|
actuators: ActuatorsConfig
|
||||||
info: InfoConfig;
|
info: InfoConfig;
|
||||||
|
homePage: HomeConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,7 +17,7 @@ import { UIServerConfig } from './ui-server-config.interface';
|
|||||||
import { BundleConfig } from './bundle-config.interface';
|
import { BundleConfig } from './bundle-config.interface';
|
||||||
import { ActuatorsConfig } from './actuators.config';
|
import { ActuatorsConfig } from './actuators.config';
|
||||||
import { InfoConfig } from './info-config.interface';
|
import { InfoConfig } from './info-config.interface';
|
||||||
|
import { HomeConfig } from './homepage-config.interface';
|
||||||
export class DefaultAppConfig implements AppConfig {
|
export class DefaultAppConfig implements AppConfig {
|
||||||
production = false;
|
production = false;
|
||||||
|
|
||||||
@@ -338,4 +338,13 @@ export class DefaultAppConfig implements AppConfig {
|
|||||||
enableEndUserAgreement: true,
|
enableEndUserAgreement: true,
|
||||||
enablePrivacyStatement: true
|
enablePrivacyStatement: true
|
||||||
};
|
};
|
||||||
|
// Home Pages
|
||||||
|
homePage: HomeConfig = {
|
||||||
|
recentSubmissions: {
|
||||||
|
//The number of item showing in recent submission components
|
||||||
|
pageSize: 5,
|
||||||
|
//sort record of recent submission
|
||||||
|
sortField: 'dc.date.accessioned',
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
20
src/config/homepage-config.interface.ts
Normal file
20
src/config/homepage-config.interface.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { Config } from './config.interface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config that determines how the dropdown list of years are created for browse-by-date components
|
||||||
|
*/
|
||||||
|
export interface HomeConfig extends Config {
|
||||||
|
recentSubmissions: {
|
||||||
|
/**
|
||||||
|
* The number of item showing in recent submission components
|
||||||
|
*/
|
||||||
|
pageSize: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sort record of recent submission
|
||||||
|
*/
|
||||||
|
sortField: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -247,5 +247,13 @@ export const environment: BuildConfig = {
|
|||||||
info: {
|
info: {
|
||||||
enableEndUserAgreement: true,
|
enableEndUserAgreement: true,
|
||||||
enablePrivacyStatement: true,
|
enablePrivacyStatement: true,
|
||||||
|
},
|
||||||
|
//Home Page
|
||||||
|
homePage: {
|
||||||
|
recentSubmissions: {
|
||||||
|
pageSize: 5,
|
||||||
|
//sort record of recent submission
|
||||||
|
sortField: 'dc.date.accessioned',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user