Skip to content

Commit

Permalink
Merge pull request #3886 from tdonohue/port_3709_to_main
Browse files Browse the repository at this point in the history
[Port main] Exclude search and browse from Angular SSR (#3709)
  • Loading branch information
tdonohue authored Jan 23, 2025
2 parents cb8a7cd + 17ecc59 commit 63c9874
Show file tree
Hide file tree
Showing 38 changed files with 641 additions and 51 deletions.
14 changes: 14 additions & 0 deletions config/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ ssr:
inlineCriticalCss: false
# Path prefixes to enable SSR for. By default these are limited to paths of primary DSpace objects.
paths: [ '/home', '/items/', '/entities/', '/collections/', '/communities/', '/bitstream/', '/bitstreams/', '/handle/' ]
# Whether to enable rendering of Search component on SSR.
# If set to true the component will be included in the HTML returned from the server side rendering.
# If set to false the component will not be included in the HTML returned from the server side rendering.
enableSearchComponent: false,
# Whether to enable rendering of Browse component on SSR.
# If set to true the component will be included in the HTML returned from the server side rendering.
# If set to false the component will not be included in the HTML returned from the server side rendering.
enableBrowseComponent: false,

# The REST API server settings
# NOTE: these settings define which (publicly available) REST API to use. They are usually
Expand Down Expand Up @@ -450,6 +458,12 @@ search:
enabled: false
# List of filters to enable in "Advanced Search" dropdown
filter: [ 'title', 'author', 'subject', 'entityType' ]
#
# Number used to render n UI elements called loading skeletons that act as placeholders.
# These elements indicate that some content will be loaded in their stead.
# Since we don't know how many filters will be loaded before we receive a response from the server we use this parameter for the skeletons count.
# e.g. If we set 5 then 5 loading skeletons will be visualized before the actual filters are retrieved.
defaultFiltersCount: 5


# Notify metrics
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"ng2-nouislider": "^2.0.0",
"ngx-infinite-scroll": "^16.0.0",
"ngx-pagination": "6.0.3",
"ngx-skeleton-loader": "^9.0.0",
"ngx-ui-switch": "^14.1.0",
"nouislider": "^15.7.1",
"orejime": "^2.3.1",
Expand Down
34 changes: 34 additions & 0 deletions src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { CommonModule } from '@angular/common';
import {
ChangeDetectorRef,
NO_ERRORS_SCHEMA,
PLATFORM_ID,
} from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import {
Expand All @@ -26,6 +29,7 @@ import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-
import { SortDirection } from '../../core/cache/models/sort-options.model';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { PaginationService } from '../../core/pagination/pagination.service';
import { BrowseEntry } from '../../core/shared/browse-entry.model';
import { Community } from '../../core/shared/community.model';
import { Item } from '../../core/shared/item.model';
import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component';
Expand Down Expand Up @@ -123,6 +127,7 @@ describe('BrowseByDateComponent', () => {
{ provide: ChangeDetectorRef, useValue: mockCdRef },
{ provide: Store, useValue: {} },
{ provide: APP_CONFIG, useValue: environment },
{ provide: PLATFORM_ID, useValue: 'browser' },
],
schemas: [NO_ERRORS_SCHEMA],
})
Expand Down Expand Up @@ -172,4 +177,33 @@ describe('BrowseByDateComponent', () => {
//expect(comp.startsWithOptions[0]).toEqual(new Date().getUTCFullYear());
expect(comp.startsWithOptions[0]).toEqual(1960);
});

describe('when rendered in SSR', () => {
beforeEach(() => {
comp.platformId = 'server';
spyOn((comp as any).browseService, 'getBrowseItemsFor');
});

it('should not call getBrowseItemsFor on init', (done) => {
comp.ngOnInit();
expect((comp as any).browseService.getBrowseItemsFor).not.toHaveBeenCalled();
comp.loading$.subscribe((res) => {
expect(res).toBeFalsy();
done();
});
});
});

describe('when rendered in CSR', () => {
beforeEach(() => {
comp.platformId = 'browser';
spyOn((comp as any).browseService, 'getBrowseItemsFor').and.returnValue(createSuccessfulRemoteDataObject$(new BrowseEntry()));
});

it('should call getBrowseItemsFor on init', fakeAsync(() => {
comp.ngOnInit();
tick(100);
expect((comp as any).browseService.getBrowseItemsFor).toHaveBeenCalled();
}));
});
});
11 changes: 10 additions & 1 deletion src/app/browse-by/browse-by-date/browse-by-date.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {
AsyncPipe,
isPlatformServer,
NgIf,
} from '@angular/common';
import {
ChangeDetectorRef,
Component,
Inject,
OnInit,
PLATFORM_ID,
} from '@angular/core';
import {
ActivatedRoute,
Expand All @@ -17,6 +19,7 @@ import { TranslateModule } from '@ngx-translate/core';
import {
combineLatest as observableCombineLatest,
Observable,
of as observableOf,
} from 'rxjs';
import {
map,
Expand All @@ -28,6 +31,7 @@ import {
APP_CONFIG,
AppConfig,
} from '../../../config/app-config.interface';
import { environment } from '../../../environments/environment';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BrowseService } from '../../core/browse/browse.service';
import {
Expand Down Expand Up @@ -99,11 +103,16 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
@Inject(APP_CONFIG) public appConfig: AppConfig,
public dsoNameService: DSONameService,
protected cdRef: ChangeDetectorRef,
@Inject(PLATFORM_ID) public platformId: any,
) {
super(route, browseService, dsoService, paginationService, router, appConfig, dsoNameService);
super(route, browseService, dsoService, paginationService, router, appConfig, dsoNameService, platformId);
}

ngOnInit(): void {
if (!this.renderOnServerSide && !environment.ssr.enableBrowseComponent && isPlatformServer(this.platformId)) {
this.loading$ = observableOf(false);
return;
}
const sortConfig = new SortOptions('default', SortDirection.ASC);
this.startsWithType = StartsWithType.date;
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="comcol-page-browse-section">
<section class="comcol-page-browse-section" *ngIf="(!ssrRenderingDisabled)">
<div class="browse-by-metadata w-100">
<ds-browse-by *ngIf="(loading$ | async) !== true" class="col-xs-12 w-100"
title="{{'browse.title' | translate:{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
NO_ERRORS_SCHEMA,
PLATFORM_ID,
} from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
Expand Down Expand Up @@ -147,6 +152,7 @@ describe('BrowseByMetadataComponent', () => {
{ provide: ThemeService, useValue: getMockThemeService() },
{ provide: SelectableListService, useValue: {} },
{ provide: HostWindowService, useValue: {} },
{ provide: PLATFORM_ID, useValue: 'browser' },
],
schemas: [NO_ERRORS_SCHEMA],
})
Expand Down Expand Up @@ -259,6 +265,35 @@ describe('BrowseByMetadataComponent', () => {
expect(result.fetchThumbnail).toBeTrue();
});
});

describe('when rendered in SSR', () => {
beforeEach(() => {
comp.ssrRenderingDisabled = true;
spyOn((comp as any).browseService, 'getBrowseEntriesFor').and.returnValue(createSuccessfulRemoteDataObject$(null));
});

it('should not call getBrowseEntriesFor on init', (done) => {
comp.ngOnInit();
expect((comp as any).browseService.getBrowseEntriesFor).not.toHaveBeenCalled();
comp.loading$.subscribe((res) => {
expect(res).toBeFalsy();
done();
});
});
});

describe('when rendered in CSR', () => {
beforeEach(() => {
comp.ssrRenderingDisabled = false;
spyOn((comp as any).browseService, 'getBrowseEntriesFor').and.returnValue(createSuccessfulRemoteDataObject$(new BrowseEntry()));
});

it('should call getBrowseEntriesFor on init', fakeAsync(() => {
comp.ngOnInit();
tick(100);
expect((comp as any).browseService.getBrowseEntriesFor).toHaveBeenCalled();
}));
});
});

export function toRemoteData(objects: any[]): Observable<RemoteData<PaginatedList<any>>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AsyncPipe,
isPlatformServer,
NgIf,
} from '@angular/common';
import {
Expand All @@ -9,6 +10,7 @@ import {
OnChanges,
OnDestroy,
OnInit,
PLATFORM_ID,
} from '@angular/core';
import {
ActivatedRoute,
Expand All @@ -33,6 +35,7 @@ import {
APP_CONFIG,
AppConfig,
} from '../../../config/app-config.interface';
import { environment } from '../../../environments/environment';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { BrowseService } from '../../core/browse/browse.service';
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
Expand Down Expand Up @@ -114,6 +117,11 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
*/
@Input() displayTitle = true;

/**
* Defines whether to fetch search results during SSR execution
*/
@Input() renderOnServerSide: boolean;

scope$: BehaviorSubject<string> = new BehaviorSubject(undefined);

/**
Expand Down Expand Up @@ -194,6 +202,10 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
* Observable determining if the loading animation needs to be shown
*/
loading$ = observableOf(true);
/**
* Whether this component should be rendered or not in SSR
*/
ssrRenderingDisabled = false;

public constructor(protected route: ActivatedRoute,
protected browseService: BrowseService,
Expand All @@ -202,18 +214,23 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
protected router: Router,
@Inject(APP_CONFIG) public appConfig: AppConfig,
public dsoNameService: DSONameService,
@Inject(PLATFORM_ID) public platformId: any,
) {
this.fetchThumbnails = this.appConfig.browseBy.showThumbnails;
this.paginationConfig = Object.assign(new PaginationComponentOptions(), {
id: BBM_PAGINATION_ID,
currentPage: 1,
pageSize: this.appConfig.browseBy.pageSize,
});
this.ssrRenderingDisabled = !this.renderOnServerSide && !environment.ssr.enableBrowseComponent && isPlatformServer(this.platformId);
}


ngOnInit(): void {

if (this.ssrRenderingDisabled) {
this.loading$ = observableOf(false);
return;
}
const sortConfig = new SortOptions('default', SortDirection.ASC);
this.updatePage(getBrowseSearchOptions(this.defaultBrowseId, this.paginationConfig, sortConfig));
this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
Expand Down Expand Up @@ -336,7 +353,6 @@ export class BrowseByMetadataComponent implements OnInit, OnChanges, OnDestroy {
this.paginationService.clearPagination(this.paginationConfig.id);
}


}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ComponentFixture,
fakeAsync,
TestBed,
tick,
waitForAsync,
} from '@angular/core/testing';
import {
Expand All @@ -23,6 +25,7 @@ import { BrowseService } from '../../core/browse/browse.service';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { ItemDataService } from '../../core/data/item-data.service';
import { PaginationService } from '../../core/pagination/pagination.service';
import { BrowseEntry } from '../../core/shared/browse-entry.model';
import { Community } from '../../core/shared/community.model';
import { Item } from '../../core/shared/item.model';
import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component';
Expand Down Expand Up @@ -81,6 +84,7 @@ describe('BrowseByTitleComponent', () => {

const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {
params: observableOf({}),
queryParams: observableOf({}),
data: observableOf({ metadata: 'title' }),
});

Expand Down Expand Up @@ -127,4 +131,35 @@ describe('BrowseByTitleComponent', () => {
expect(result.payload.page).toEqual(mockItems);
});
});

describe('when rendered in SSR', () => {
beforeEach(() => {
comp.platformId = 'server';
spyOn((comp as any).browseService, 'getBrowseItemsFor');
fixture.detectChanges();
});

it('should not call getBrowseItemsFor on init', (done) => {
comp.ngOnInit();
expect((comp as any).browseService.getBrowseItemsFor).not.toHaveBeenCalled();
comp.loading$.subscribe((res) => {
expect(res).toBeFalsy();
done();
});
});
});

describe('when rendered in CSR', () => {
beforeEach(() => {
comp.platformId = 'browser';
fixture.detectChanges();
spyOn((comp as any).browseService, 'getBrowseItemsFor').and.returnValue(createSuccessfulRemoteDataObject$(new BrowseEntry()));
});

it('should call getBrowseItemsFor on init', fakeAsync(() => {
comp.ngOnInit();
tick(100);
expect((comp as any).browseService.getBrowseItemsFor).toHaveBeenCalled();
}));
});
});
Loading

0 comments on commit 63c9874

Please sign in to comment.