From f34c19717db0d3c2138defdc848f04dff5b9262a Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Wed, 15 May 2019 10:51:36 +0200 Subject: [PATCH 01/14] fix an issue where the state of an aggregated RD would be wrong when some of the RDs it's based on were still pending --- .../builders/remote-data-build.service.ts | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index c0b359e7ea..c98621928c 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { combineLatest as observableCombineLatest, Observable, of as observableOf, race as observableRace } from 'rxjs'; -import { distinctUntilChanged, flatMap, map, startWith, switchMap } from 'rxjs/operators'; +import { distinctUntilChanged, flatMap, map, startWith, switchMap, tap } from 'rxjs/operators'; import { hasValue, hasValueOperator, isEmpty, isNotEmpty, isNotUndefined } from '../../../shared/empty.util'; import { PaginatedList } from '../../data/paginated-list'; @@ -205,17 +205,29 @@ export class RemoteDataBuildService { return observableCombineLatest(...input).pipe( map((arr) => { + // The request of an aggregate RD should be pending if at least one + // of the RDs it's based on is still in the state RequestPending const requestPending: boolean = arr .map((d: RemoteData) => d.isRequestPending) - .every((b: boolean) => b === true); + .find((b: boolean) => b === true); - const responsePending: boolean = arr + // The response of an aggregate RD should be pending if no requests + // are still pending and at least one of the RDs it's based + // on is still in the state ResponsePending + const responsePending: boolean = !requestPending && arr .map((d: RemoteData) => d.isResponsePending) - .every((b: boolean) => b === true); + .find((b: boolean) => b === true); - const isSuccessful: boolean = arr - .map((d: RemoteData) => d.hasSucceeded) - .every((b: boolean) => b === true); + + let isSuccessful: boolean = undefined; + // isSuccessful should be undefined until all responses have come in. + // We can't know its state beforehand. We also can't say it's false + // because that would imply a request failed. + if (!(requestPending || responsePending)) { + isSuccessful = arr + .map((d: RemoteData) => d.hasSucceeded) + .every((b: boolean) => b === true); + } const errorMessage: string = arr .map((d: RemoteData) => d.error) From c216e35a23709ff55acccad18c9c84934549fae4 Mon Sep 17 00:00:00 2001 From: lotte Date: Wed, 15 May 2019 15:34:46 +0200 Subject: [PATCH 02/14] added search link fixes --- .../collection-page.component.ts | 80 ++++++++----------- src/app/+home-page/home-page.component.html | 2 +- .../my-dspace-page.component.html | 10 ++- .../my-dspace-page.component.ts | 14 +++- .../search-authority-filter.component.html | 4 +- .../search-authority-filter.component.ts | 1 - .../search-boolean-filter.component.html | 4 +- .../search-facet-option.component.ts | 12 ++- .../search-facet-range-option.component.ts | 12 ++- .../search-facet-selected-option.component.ts | 12 ++- .../search-facet-filter-wrapper.component.ts | 10 ++- .../search-facet-filter.component.ts | 22 ++++- .../search-filter.component.html | 2 +- .../search-filter/search-filter.component.ts | 5 ++ .../search-filter/search-filter.service.ts | 1 + .../search-hierarchy-filter.component.html | 4 +- .../search-range-filter.component.html | 2 +- .../search-range-filter.component.ts | 7 +- .../search-text-filter.component.html | 4 +- .../search-filters.component.html | 2 +- .../search-filters.component.ts | 14 +++- .../search-labels/search-labels.component.ts | 14 +++- .../+search-page/search-page.component.html | 9 ++- src/app/+search-page/search-page.component.ts | 10 ++- .../search-service/search.service.ts | 4 +- .../search-settings.component.ts | 33 +++++++- .../search-sidebar.component.html | 4 +- .../search-sidebar.component.ts | 6 ++ .../search-form/search-form.component.spec.ts | 7 ++ .../search-form/search-form.component.ts | 38 +++++++-- .../view-mode-switch.component.ts | 28 ++++++- 31 files changed, 271 insertions(+), 106 deletions(-) diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index a2cec6b553..3433729902 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { Observable, Subscription } from 'rxjs'; -import { filter, flatMap, map, take } from 'rxjs/operators'; +import { filter, flatMap, map, switchMap, take } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { SearchService } from '../+search-page/search-service/search.service'; import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; @@ -15,7 +15,11 @@ import { Bitstream } from '../core/shared/bitstream.model'; import { Collection } from '../core/shared/collection.model'; import { DSpaceObjectType } from '../core/shared/dspace-object-type.model'; import { Item } from '../core/shared/item.model'; -import { getSucceededRemoteData, toDSpaceObjectListRD } from '../core/shared/operators'; +import { + getSucceededRemoteData, + redirectToPageNotFoundOn404, + toDSpaceObjectListRD +} from '../core/shared/operators'; import { fadeIn, fadeInOut } from '../shared/animations/fade'; import { hasValue, isNotEmpty } from '../shared/empty.util'; @@ -31,22 +35,19 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp fadeInOut ] }) -export class CollectionPageComponent implements OnInit, OnDestroy { +export class CollectionPageComponent implements OnInit { collectionRD$: Observable>; itemRD$: Observable>>; logoRD$: Observable>; paginationConfig: PaginationComponentOptions; sortConfig: SortOptions; - private subs: Subscription[] = []; - private collectionId: string; - private currentPage: number; - private pageSize: number; constructor( private collectionDataService: CollectionDataService, private searchService: SearchService, private metadata: MetadataService, - private route: ActivatedRoute + private route: ActivatedRoute, + private router: Router ) { this.paginationConfig = new PaginationComponentOptions(); this.paginationConfig.id = 'collection-page-pagination'; @@ -57,7 +58,8 @@ export class CollectionPageComponent implements OnInit, OnDestroy { ngOnInit(): void { this.collectionRD$ = this.route.data.pipe( - map((data) => data.collection), + map((data) => data.collection as RemoteData), + redirectToPageNotFoundOn404(this.router), take(1) ); this.logoRD$ = this.collectionRD$.pipe( @@ -65,42 +67,26 @@ export class CollectionPageComponent implements OnInit, OnDestroy { filter((collection: Collection) => hasValue(collection)), flatMap((collection: Collection) => collection.logo) ); - this.subs.push( - this.route.queryParams.subscribe((params) => { - this.metadata.processRemoteData(this.collectionRD$); - const page = +params.page || this.paginationConfig.currentPage; - const pageSize = +params.pageSize || this.paginationConfig.pageSize; - - this.collectionRD$.subscribe((rd: RemoteData) => { - this.collectionId = rd.payload.id; - this.updatePage(page, pageSize); - }); - }) - ); + this.route.queryParams.pipe(take(1)).subscribe((params) => { + this.metadata.processRemoteData(this.collectionRD$); + this.onPaginationChange(params) + }) } - updatePage(currentPage: number, pageSize: number) { - this.itemRD$ = this.searchService.search( - new PaginatedSearchOptions({ - scope: this.collectionId, - pagination: { - currentPage, - pageSize - } as PaginationComponentOptions, - sort: this.sortConfig, - dsoType: DSpaceObjectType.ITEM - })).pipe( - toDSpaceObjectListRD(), + updatePage() { + this.itemRD$ = this.collectionRD$.pipe( getSucceededRemoteData(), - take(1), - ) as Observable>>; - - this.currentPage = currentPage; - this.pageSize = pageSize; - } - - ngOnDestroy(): void { - this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe()); + map((rd) => rd.payload.id), + switchMap((id: string) => { + return this.searchService.search( + new PaginatedSearchOptions({ + scope: id, + pagination: this.paginationConfig, + sort: this.sortConfig, + dsoType: DSpaceObjectType.ITEM + })).pipe(toDSpaceObjectListRD()) as Observable>>; + }) + ) } isNotEmpty(object: any) { @@ -108,8 +94,10 @@ export class CollectionPageComponent implements OnInit, OnDestroy { } onPaginationChange(event) { - if (this.currentPage !== event.page || this.pageSize !== event.pageSize) { - this.updatePage(event.page, event.pageSize); - } + this.paginationConfig.currentPage = +event.page || this.paginationConfig.currentPage; + this.paginationConfig.pageSize = +event.pageSize || this.paginationConfig.pageSize; + this.sortConfig.direction = event.sortDirection || this.sortConfig.direction; + this.sortConfig.field = event.sortField || this.sortConfig.field; + this.updatePage(); } } diff --git a/src/app/+home-page/home-page.component.html b/src/app/+home-page/home-page.component.html index 6a3e20ca9d..39ba479033 100644 --- a/src/app/+home-page/home-page.component.html +++ b/src/app/+home-page/home-page.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/app/+my-dspace-page/my-dspace-page.component.html b/src/app/+my-dspace-page/my-dspace-page.component.html index 79fad17b26..744bc4803d 100644 --- a/src/app/+my-dspace-page/my-dspace-page.component.html +++ b/src/app/+my-dspace-page/my-dspace-page.component.html @@ -12,9 +12,10 @@ [query]="(searchOptions$ | async)?.query" [scope]="(searchOptions$ | async)?.scope" [currentUrl]="getSearchLink()" - [scopes]="(scopeListRD$ | async)"> + [scopes]="(scopeListRD$ | async)" + [inPlaceSearch]="inPlaceSearch"> - +
+ [ngClass]="{'active': !(isSidebarCollapsed() | async)}" + [inPlaceSearch]="inPlaceSearch">
- +
diff --git a/src/app/+search-page/search-sidebar/search-sidebar.component.ts b/src/app/+search-page/search-sidebar/search-sidebar.component.ts index 9abcf71dcb..9ee0a74942 100644 --- a/src/app/+search-page/search-sidebar/search-sidebar.component.ts +++ b/src/app/+search-page/search-sidebar/search-sidebar.component.ts @@ -34,8 +34,14 @@ export class SearchSidebarComponent { */ @Input() viewModeList; + /** + * True when the search component should show results on the current page + */ + @Input() inPlaceSearch; + /** * Emits event when the user clicks a button to open or close the sidebar */ @Output() toggleSidebar = new EventEmitter(); + } diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index b164abee1f..a60aeb8054 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -8,6 +8,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { Community } from '../../core/shared/community.model'; import { TranslateModule } from '@ngx-translate/core'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; +import { SearchService } from '../../+search-page/search-service/search.service'; describe('SearchFormComponent', () => { let comp: SearchFormComponent; @@ -18,6 +19,12 @@ describe('SearchFormComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [FormsModule, RouterTestingModule, TranslateModule.forRoot()], + providers: [ + { + provide: SearchService, + useValue: {} + } + ], declarations: [SearchFormComponent] }).compileComponents(); })); diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts index ea96bd8114..410c78c1d5 100644 --- a/src/app/shared/search-form/search-form.component.ts +++ b/src/app/shared/search-form/search-form.component.ts @@ -4,6 +4,7 @@ import { Router } from '@angular/router'; import { hasValue, isNotEmpty } from '../empty.util'; import { QueryParamsHandling } from '@angular/router/src/config'; import { MYDSPACE_ROUTE } from '../../+my-dspace-page/my-dspace-page.component'; +import { SearchService } from '../../+search-page/search-service/search.service'; /** * This component renders a simple item page. @@ -26,6 +27,11 @@ export class SearchFormComponent { */ @Input() query: string; + /** + * True when the search component should show results on the current page + */ + @Input() inPlaceSearch; + /** * The currently selected scope object's UUID */ @@ -39,7 +45,7 @@ export class SearchFormComponent { */ @Input() scopes: DSpaceObject[]; - constructor(private router: Router) { + constructor(private router: Router, private searchService: SearchService) { } /** @@ -63,14 +69,10 @@ export class SearchFormComponent { * @param data Updated parameters */ updateSearch(data: any) { - const newUrl = hasValue(this.currentUrl) ? this.currentUrl : '/search'; - let handling: QueryParamsHandling = '' ; - if (this.currentUrl === '/search' || this.currentUrl === MYDSPACE_ROUTE) { - handling = 'merge'; - } - this.router.navigate([newUrl], { + + this.router.navigate(this.getSearchLinkParts(), { queryParams: Object.assign({}, { page: 1 }, data), - queryParamsHandling: handling + queryParamsHandling: 'merge' }); } @@ -81,4 +83,24 @@ export class SearchFormComponent { return isNotEmpty(object); } + + /** + * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true + */ + public getSearchLink(): string { + if (this.inPlaceSearch) { + return './'; + } + return this.searchService.getSearchLink(); + } + + /** + * @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces + */ + public getSearchLinkParts(): string[] { + if (this.inPlaceSearch) { + return []; + } + return this.getSearchLink().split('/'); + } } diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.ts b/src/app/shared/view-mode-switch/view-mode-switch.component.ts index b011fce6a0..dc355c6409 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.ts +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.ts @@ -17,6 +17,11 @@ import { isEmpty } from '../empty.util'; export class ViewModeSwitchComponent implements OnInit, OnDestroy { @Input() viewModeList: ViewMode[]; + /** + * True when the search component should show results on the current page + */ + @Input() inPlaceSearch; + currentMode: ViewMode = ViewMode.List; viewModeEnum = ViewMode; private sub: Subscription; @@ -35,7 +40,7 @@ export class ViewModeSwitchComponent implements OnInit, OnDestroy { } switchViewTo(viewMode: ViewMode) { - this.searchService.setViewMode(viewMode); + this.searchService.setViewMode(viewMode, this.getSearchLinkParts()); } ngOnDestroy() { @@ -47,4 +52,25 @@ export class ViewModeSwitchComponent implements OnInit, OnDestroy { isToShow(viewMode: ViewMode) { return this.viewModeList && this.viewModeList.includes(viewMode); } + + /** + * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true + */ + public getSearchLink(): string { + if (this.inPlaceSearch) { + return './'; + } + return this.searchService.getSearchLink(); + } + + /** + * @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces + */ + public getSearchLinkParts(): string[] { + if (this.searchService) { + return []; + } + return this.getSearchLink().split('/'); + } + } From 2852ef0364202c2cae5ce957d3e8820d43635d93 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 16 May 2019 09:33:55 +0200 Subject: [PATCH 03/14] fix test issues, rewrite recent submissions using switchmap --- .../collection-page.component.ts | 66 ++++++++++++------- .../search-facet-filter.component.spec.ts | 5 +- .../search-range-filter.component.spec.ts | 6 +- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index 3433729902..1e18eb8115 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -1,7 +1,7 @@ -import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { Observable, Subscription } from 'rxjs'; -import { filter, flatMap, map, switchMap, take } from 'rxjs/operators'; +import { BehaviorSubject, of as observableOf, Observable, Subject } from 'rxjs'; +import { filter, flatMap, map, switchMap, take, tap } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { SearchService } from '../+search-page/search-service/search.service'; import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; @@ -22,7 +22,7 @@ import { } from '../core/shared/operators'; import { fadeIn, fadeInOut } from '../shared/animations/fade'; -import { hasValue, isNotEmpty } from '../shared/empty.util'; +import { hasNoValue, hasValue, isNotEmpty } from '../shared/empty.util'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; @Component({ @@ -41,6 +41,10 @@ export class CollectionPageComponent implements OnInit { logoRD$: Observable>; paginationConfig: PaginationComponentOptions; sortConfig: SortOptions; + private paginationChanges$: Subject<{ + paginationConfig: PaginationComponentOptions, + sortConfig: SortOptions + }>; constructor( private collectionDataService: CollectionDataService, @@ -67,37 +71,49 @@ export class CollectionPageComponent implements OnInit { filter((collection: Collection) => hasValue(collection)), flatMap((collection: Collection) => collection.logo) ); + + this.paginationChanges$ = new BehaviorSubject({ + paginationConfig: this.paginationConfig, + sortConfig: this.sortConfig + }); + + this.itemRD$ = this.paginationChanges$.pipe( + tap((dto) => console.log('dto', dto)), + switchMap((dto) => this.collectionRD$.pipe( + getSucceededRemoteData(), + map((rd) => rd.payload.id), + switchMap((id: string) => { + return this.searchService.search( + new PaginatedSearchOptions({ + scope: id, + pagination: dto.paginationConfig, + sort: dto.sortConfig, + dsoType: DSpaceObjectType.ITEM + })).pipe(toDSpaceObjectListRD()) as Observable>> + }) + ) + ) + ); + this.route.queryParams.pipe(take(1)).subscribe((params) => { this.metadata.processRemoteData(this.collectionRD$); this.onPaginationChange(params) }) } - updatePage() { - this.itemRD$ = this.collectionRD$.pipe( - getSucceededRemoteData(), - map((rd) => rd.payload.id), - switchMap((id: string) => { - return this.searchService.search( - new PaginatedSearchOptions({ - scope: id, - pagination: this.paginationConfig, - sort: this.sortConfig, - dsoType: DSpaceObjectType.ITEM - })).pipe(toDSpaceObjectListRD()) as Observable>>; - }) - ) - } - isNotEmpty(object: any) { return isNotEmpty(object); } onPaginationChange(event) { - this.paginationConfig.currentPage = +event.page || this.paginationConfig.currentPage; - this.paginationConfig.pageSize = +event.pageSize || this.paginationConfig.pageSize; - this.sortConfig.direction = event.sortDirection || this.sortConfig.direction; - this.sortConfig.field = event.sortField || this.sortConfig.field; - this.updatePage(); + this.paginationConfig.currentPage = +event.page || this.paginationConfig.currentPage; + this.paginationConfig.pageSize = +event.pageSize || this.paginationConfig.pageSize; + this.sortConfig.direction = event.sortDirection || this.sortConfig.direction; + this.sortConfig.field = event.sortField || this.sortConfig.field; + + this.paginationChanges$.next({ + paginationConfig: this.paginationConfig, + sortConfig: this.sortConfig + }); } } diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts index adb2919653..457d8d3031 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { FILTER_CONFIG, SearchFilterService } from '../search-filter.service'; +import { FILTER_CONFIG, IN_PLACE_SEARCH, SearchFilterService } from '../search-filter.service'; import { SearchFilterConfig } from '../../../search-service/search-filter-config.model'; import { FilterType } from '../../../search-service/filter-type.model'; import { FacetValue } from '../../../search-service/facet-value.model'; @@ -71,6 +71,7 @@ describe('SearchFacetFilterComponent', () => { { provide: FILTER_CONFIG, useValue: new SearchFilterConfig() }, { provide: RemoteDataBuildService, useValue: {aggregate: () => observableOf({})} }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, + { provide: IN_PLACE_SEARCH, useValue: false }, { provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => observableOf(selectedValues), @@ -178,7 +179,7 @@ describe('SearchFacetFilterComponent', () => { }); it('should call navigate on the router with the right searchlink and parameters', () => { - expect(router.navigate).toHaveBeenCalledWith([searchUrl], { + expect(router.navigate).toHaveBeenCalledWith(searchUrl.split('/'), { queryParams: { [mockFilterConfig.paramName]: [...selectedValues, testValue] }, queryParamsHandling: 'merge' }); diff --git a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts index 4fc3222600..119f3f92a9 100644 --- a/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-range-filter/search-range-filter.component.spec.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { FILTER_CONFIG, SearchFilterService } from '../search-filter.service'; +import { FILTER_CONFIG, IN_PLACE_SEARCH, SearchFilterService } from '../search-filter.service'; import { SearchFilterConfig } from '../../../search-service/search-filter-config.model'; import { FilterType } from '../../../search-service/filter-type.model'; import { FacetValue } from '../../../search-service/facet-value.model'; @@ -18,7 +18,6 @@ import { PageInfo } from '../../../../core/shared/page-info.model'; import { SearchRangeFilterComponent } from './search-range-filter.component'; import { RouteService } from '../../../../shared/services/route.service'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; -import { SearchConfigurationService } from '../../../search-service/search-configuration.service'; import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub'; @@ -79,6 +78,7 @@ describe('SearchRangeFilterComponent', () => { { provide: RemoteDataBuildService, useValue: {aggregate: () => observableOf({})} }, { provide: RouteService, useValue: {getQueryParameterValue: () => observableOf({})} }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, + { provide: IN_PLACE_SEARCH, useValue: false }, { provide: SearchFilterService, useValue: { getSelectedValuesForFilter: () => selectedValues, @@ -119,7 +119,7 @@ describe('SearchRangeFilterComponent', () => { }); it('should call navigate on the router with the right searchlink and parameters', () => { - expect(router.navigate).toHaveBeenCalledWith([searchUrl], { + expect(router.navigate).toHaveBeenCalledWith(searchUrl.split('/'), { queryParams: { [mockFilterConfig.paramName + minSuffix]: [1900], [mockFilterConfig.paramName + maxSuffix]: [1950] From 3afa288c58db3a943607dd6fd051b04fb04661fc Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 16 May 2019 10:20:35 +0200 Subject: [PATCH 04/14] fixed loading issue --- src/app/+collection-page/collection-page.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index 1e18eb8115..87647f2808 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject, of as observableOf, Observable, Subject } from 'rxjs'; -import { filter, flatMap, map, switchMap, take, tap } from 'rxjs/operators'; +import { filter, flatMap, map, startWith, switchMap, take, tap } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { SearchService } from '../+search-page/search-service/search.service'; import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; @@ -78,7 +78,6 @@ export class CollectionPageComponent implements OnInit { }); this.itemRD$ = this.paginationChanges$.pipe( - tap((dto) => console.log('dto', dto)), switchMap((dto) => this.collectionRD$.pipe( getSucceededRemoteData(), map((rd) => rd.payload.id), @@ -90,7 +89,8 @@ export class CollectionPageComponent implements OnInit { sort: dto.sortConfig, dsoType: DSpaceObjectType.ITEM })).pipe(toDSpaceObjectListRD()) as Observable>> - }) + }), + startWith(undefined) // Make sure switching page shows loading component ) ) ); From fa5c80b7e112c7a9e68b75fbf3612eca17d2dc83 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 16 May 2019 11:16:24 +0200 Subject: [PATCH 05/14] double the webpack heap space --- package.json | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1f75da6c8b..7dde8491f0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "engines": { "node": ">=8.0.0" }, + "config": { + "wp_cmd": "node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js" + }, "scripts": { "global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup", "clean:coverage": "rimraf coverage", @@ -23,9 +26,9 @@ "prebuild": "yarn run clean:dist", "prebuild:aot": "yarn run prebuild", "prebuild:prod": "yarn run prebuild", - "build": "webpack --progress --mode development", - "build:aot": "webpack --env.aot --env.server --mode development && webpack --env.aot --env.client --mode development", - "build:prod": "webpack --env.aot --env.server --mode production && webpack --env.aot --env.client --mode production", + "build": "$npm_package_config_wp_cmd --progress --mode development", + "build:aot": "$npm_package_config_wp_cmd --env.aot --env.server --mode development && $npm_package_config_wp_cmd --env.aot --env.client --mode development", + "build:prod": "$npm_package_config_wp_cmd --env.aot --env.server --mode production && $npm_package_config_wp_cmd --env.aot --env.client --mode production", "postbuild:prod": "yarn run rollup", "rollup": "rollup -c rollup.config.js", "prestart": "yarn run build:prod", @@ -40,9 +43,9 @@ "server": "node dist/server.js", "server:watch": "nodemon dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js", - "webpack:watch": "webpack -w --mode development", - "watch": "yarn run build && npm-run-all -p webpack:watch server:watch", - "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug", + "webpack:watch": "$npm_package_config_wp_cmd -w --mode development", + "watch": "yarn run build && npm-run-all -p $npm_package_config_wp_cmd:watch server:watch", + "watch:debug": "yarn run build && npm-run-all -p $npm_package_config_wp_cmd:watch server:watch:debug", "predebug": "yarn run build", "predebug:server": "yarn run build", "debug": "node --debug-brk dist/server.js", From 5254308b8b8073b472aa774f1997a0228115a0a3 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Thu, 16 May 2019 11:38:10 +0200 Subject: [PATCH 06/14] fix reference webpack:watch to script --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7dde8491f0..3c52ca700b 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "server:watch": "nodemon dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js", "webpack:watch": "$npm_package_config_wp_cmd -w --mode development", - "watch": "yarn run build && npm-run-all -p $npm_package_config_wp_cmd:watch server:watch", - "watch:debug": "yarn run build && npm-run-all -p $npm_package_config_wp_cmd:watch server:watch:debug", + "watch": "yarn run build && npm-run-all -p webpack:watch server:watch", + "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug", "predebug": "yarn run build", "predebug:server": "yarn run build", "debug": "node --debug-brk dist/server.js", From 487ee9f75668c4cca13bd6f28c10ca42a7ff4400 Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 16 May 2019 13:43:07 +0200 Subject: [PATCH 07/14] small fixes for search --- src/app/+collection-page/collection-page.component.ts | 4 ++-- src/app/+search-page/search-service/search.service.ts | 5 +---- .../search-settings/search-settings.component.ts | 2 -- src/app/core/cache/builders/remote-data-build.service.ts | 3 +-- src/app/shared/search-form/search-form.component.ts | 2 -- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index 87647f2808..41afbf2115 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -90,14 +90,14 @@ export class CollectionPageComponent implements OnInit { dsoType: DSpaceObjectType.ITEM })).pipe(toDSpaceObjectListRD()) as Observable>> }), - startWith(undefined) // Make sure switching page shows loading component + startWith(undefined) // Make sure switching pages shows loading component ) ) ); this.route.queryParams.pipe(take(1)).subscribe((params) => { this.metadata.processRemoteData(this.collectionRD$); - this.onPaginationChange(params) + this.onPaginationChange(params); }) } diff --git a/src/app/+search-page/search-service/search.service.ts b/src/app/+search-page/search-service/search.service.ts index 52be0417a8..598657a1b2 100644 --- a/src/app/+search-page/search-service/search.service.ts +++ b/src/app/+search-page/search-service/search.service.ts @@ -354,10 +354,7 @@ export class SearchService implements OnDestroy { * @returns {string} The base path to the search page */ getSearchLink(): string { - const urlTree = this.router.parseUrl(this.router.url); - const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET]; - const searchLink: any = '/' + g.toString(); - return (searchLink !== '/search' && searchLink !== '/mydspace') ? '/search' : searchLink; + return '/search'; } /** diff --git a/src/app/+search-page/search-settings/search-settings.component.ts b/src/app/+search-page/search-settings/search-settings.component.ts index 78a1823ab4..aac861c64f 100644 --- a/src/app/+search-page/search-settings/search-settings.component.ts +++ b/src/app/+search-page/search-settings/search-settings.component.ts @@ -79,7 +79,6 @@ export class SearchSettingsComponent implements OnInit { this.router.navigate(this.getSearchLinkParts(), navigationExtras); } - /** * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true */ @@ -99,5 +98,4 @@ export class SearchSettingsComponent implements OnInit { } return this.getSearchLink().split('/'); } - } diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index c98621928c..563dce23d1 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -218,8 +218,7 @@ export class RemoteDataBuildService { .map((d: RemoteData) => d.isResponsePending) .find((b: boolean) => b === true); - - let isSuccessful: boolean = undefined; + let isSuccessful: boolean; // isSuccessful should be undefined until all responses have come in. // We can't know its state beforehand. We also can't say it's false // because that would imply a request failed. diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts index 410c78c1d5..10c3a3ede7 100644 --- a/src/app/shared/search-form/search-form.component.ts +++ b/src/app/shared/search-form/search-form.component.ts @@ -69,7 +69,6 @@ export class SearchFormComponent { * @param data Updated parameters */ updateSearch(data: any) { - this.router.navigate(this.getSearchLinkParts(), { queryParams: Object.assign({}, { page: 1 }, data), queryParamsHandling: 'merge' @@ -83,7 +82,6 @@ export class SearchFormComponent { return isNotEmpty(object); } - /** * @returns {string} The base path to the search page, or the current page when inPlaceSearch is true */ From cbde7fc679a17bb21e7f04c04aeaa9a3ed0316fd Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 16 May 2019 16:44:38 +0200 Subject: [PATCH 08/14] facet fix --- .../search-facet-selected-option.component.ts | 1 + .../search-facet-filter.component.ts | 33 ++++++++++++------- .../search-filter/search-filter.service.ts | 3 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts index 78dde92c2b..f01e1ade96 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.ts @@ -62,6 +62,7 @@ export class SearchFacetSelectedOptionComponent implements OnInit, OnDestroy { ngOnInit(): void { this.sub = observableCombineLatest(this.selectedValues$, this.searchConfigService.searchOptions) .subscribe(([selectedValues, searchOptions]) => { + console.log(selectedValues); this.updateRemoveParams(selectedValues) }); } diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index b502fb6830..263344fbc3 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -6,7 +6,7 @@ import { Subject, Subscription } from 'rxjs'; -import { switchMap, distinctUntilChanged, map, take, flatMap } from 'rxjs/operators'; +import { switchMap, distinctUntilChanged, map, take, flatMap, tap } from 'rxjs/operators'; import { animate, state, style, transition, trigger } from '@angular/animations'; import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @@ -117,14 +117,6 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { }) ); - this.selectedValues$ = observableCombineLatest( - this.filterService.getSelectedValuesForFilter(this.filterConfig), - facetValues$.pipe(flatMap((facetValues) => facetValues.values))).pipe( - map(([selectedValues, facetValues]) => { - return facetValues.payload.page.filter((facetValue) => selectedValues.includes(this.getFacetValue(facetValue))) - }) - ); - let filterValues = []; this.subs.push(facetValues$.subscribe((facetOutcome) => { const newValues$ = facetOutcome.values; @@ -140,9 +132,24 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { filterValues = [...filterValues, newValues$]; - this.subs.push(this.rdbs.aggregate(filterValues).subscribe((rd: RemoteData>>) => { + this.subs.push(this.rdbs.aggregate(filterValues).pipe( + tap((rd: RemoteData>>) => { + this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig).pipe( + map((selectedValues) => { + return selectedValues.map((value: string) => { + const fValue = [].concat(...rd.payload.map((page) => page.page)).find((facetValue: FacetValue) => facetValue.value === value) + if (hasValue(fValue)) { + return fValue; + } + return Object.assign(new FacetValue(), { label: value, value: value }); + }); + }) + ); + }) + ).subscribe((rd: RemoteData>>) => { this.animationState = 'ready'; this.filterValues$.next(rd); + })); this.subs.push(newValues$.pipe(take(1)).subscribe((rd) => { this.isLastPage$.next(hasNoValue(rd.payload.next)) @@ -224,10 +231,12 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { if (isNotEmpty(data)) { this.router.navigate(this.getSearchLinkParts(), { queryParams: - { [this.filterConfig.paramName]: [ + { + [this.filterConfig.paramName]: [ ...selectedValues.map((facet) => this.getFacetValue(facet)), data - ] }, + ] + }, queryParamsHandling: 'merge' }); this.filter = ''; diff --git a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts index 9c9ca6e1b1..4b12417084 100644 --- a/src/app/+search-page/search-filters/search-filter/search-filter.service.ts +++ b/src/app/+search-page/search-filters/search-filter/search-filter.service.ts @@ -21,6 +21,8 @@ import { SearchOptions } from '../../search-options.model'; import { PaginatedSearchOptions } from '../../paginated-search-options.model'; import { SearchFixedFilterService } from './search-fixed-filter.service'; import { Params } from '@angular/router'; +import * as postcss from 'postcss'; +import prefix = postcss.vendor.prefix; // const spy = create(); const filterStateSelector = (state: SearchFiltersState) => state.searchFilter; @@ -142,7 +144,6 @@ export class SearchFilterService { const prefixValues$ = this.routeService.getQueryParamsWithPrefix(filterConfig.paramName + '.').pipe( map((params: Params) => [].concat(...Object.values(params))), ); - return observableCombineLatest(values$, prefixValues$).pipe( map(([values, prefixValues]) => { if (isNotEmpty(values)) { From 0bdb0ba2b76f500312af217a1888a09e34f602e9 Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 16 May 2019 17:11:13 +0200 Subject: [PATCH 09/14] fixed test and search facet issue for mydspace --- .../my-dspace-page.component.html | 3 ++- .../search-facet-selected-option.component.ts | 1 - .../search-facet-filter.component.spec.ts | 16 ++++++++++++---- .../search-facet-filter.component.ts | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/app/+my-dspace-page/my-dspace-page.component.html b/src/app/+my-dspace-page/my-dspace-page.component.html index 744bc4803d..4c691028fc 100644 --- a/src/app/+my-dspace-page/my-dspace-page.component.html +++ b/src/app/+my-dspace-page/my-dspace-page.component.html @@ -6,7 +6,8 @@ id="search-sidebar" [configurationList]="(configurationList$ | async)" [resultCount]="(resultsRD$ | async)?.payload.totalElements" - [viewModeList]="viewModeList"> + [viewModeList]="viewModeList" + [inPlaceSearch]="inPlaceSearch">
{ - console.log(selectedValues); this.updateRemoveParams(selectedValues) }); } diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts index 457d8d3031..5d8b51de96 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.spec.ts @@ -19,6 +19,7 @@ import { SearchFacetFilterComponent } from './search-facet-filter.component'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub'; import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component'; +import { tap } from 'rxjs/operators'; describe('SearchFacetFilterComponent', () => { let comp: SearchFacetFilterComponent; @@ -69,7 +70,7 @@ describe('SearchFacetFilterComponent', () => { { provide: SearchService, useValue: new SearchServiceStub(searchLink) }, { provide: Router, useValue: new RouterStub() }, { provide: FILTER_CONFIG, useValue: new SearchFilterConfig() }, - { provide: RemoteDataBuildService, useValue: {aggregate: () => observableOf({})} }, + { provide: RemoteDataBuildService, useValue: { aggregate: () => observableOf({}) } }, { provide: SEARCH_CONFIG_SERVICE, useValue: new SearchConfigurationServiceStub() }, { provide: IN_PLACE_SEARCH, useValue: false }, { @@ -173,7 +174,14 @@ describe('SearchFacetFilterComponent', () => { const searchUrl = '/search/path'; const testValue = 'test'; const data = testValue; + beforeEach(() => { + comp.selectedValues$ = observableOf(selectedValues.map((value) => + Object.assign(new FacetValue(), { + label: value, + value: value + }))); + fixture.detectChanges(); spyOn(comp, 'getSearchLink').and.returnValue(searchUrl); comp.onSubmit(data); }); @@ -193,9 +201,9 @@ describe('SearchFacetFilterComponent', () => { }); it('should call showFirstPageOnly and empty the filter', () => { - expect(comp.animationState).toEqual('loading'); - expect((comp as any).collapseNextUpdate).toBeTruthy(); - expect(comp.filter).toEqual(''); + expect(comp.animationState).toEqual('loading'); + expect((comp as any).collapseNextUpdate).toBeTruthy(); + expect(comp.filter).toEqual(''); }); }); diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 263344fbc3..772240eb0b 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -137,7 +137,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy { this.selectedValues$ = this.filterService.getSelectedValuesForFilter(this.filterConfig).pipe( map((selectedValues) => { return selectedValues.map((value: string) => { - const fValue = [].concat(...rd.payload.map((page) => page.page)).find((facetValue: FacetValue) => facetValue.value === value) + const fValue = [].concat(...rd.payload.map((page) => page.page)).find((facetValue: FacetValue) => facetValue.value === value); if (hasValue(fValue)) { return fValue; } From 9b03c02f294b8222675d6785ad79bfb6aeb0309b Mon Sep 17 00:00:00 2001 From: lotte Date: Fri, 17 May 2019 09:44:12 +0200 Subject: [PATCH 10/14] disabled statistics link --- src/app/navbar/navbar.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts index 008a86599d..48b316af4b 100644 --- a/src/app/navbar/navbar.component.ts +++ b/src/app/navbar/navbar.component.ts @@ -115,7 +115,7 @@ export class NavbarComponent extends MenuComponent implements OnInit { model: { type: MenuItemType.LINK, text: 'menu.section.statistics', - link: '#' + link: '' } as LinkMenuItemModel, index: 2 }, From d16335ddb187642f6a624ca156f7a76ab2410001 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 17 May 2019 10:21:37 +0200 Subject: [PATCH 11/14] update requirement versions in docs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8f2320dbf3..cb2f41130f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [h Quick start ----------- -**Ensure you're running [Node](https://nodejs.org) >= `v8.0.x`, [npm](https://www.npmjs.com/) >= `v3.x` and [yarn](https://yarnpkg.com) >= `v0.20.x`** +**Ensure you're running [Node](https://nodejs.org) >= `v8.0.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) >= `v1.x`** ```bash # clone the repo @@ -65,7 +65,7 @@ Requirements ------------ - [Node.js](https://nodejs.org), [npm](https://www.npmjs.com/), and [yarn](https://yarnpkg.com) -- Ensure you're running node >= `v5.x`, npm >= `v3.x` and yarn >= `v0.20.x` +- Ensure you're running node >= `v8.x`, npm >= `v5.x` and yarn >= `v1.x` If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS. From 8aaff69d97b1667d806e702d9d0a918d51838de8 Mon Sep 17 00:00:00 2001 From: lotte Date: Fri, 17 May 2019 11:43:54 +0200 Subject: [PATCH 12/14] fixed issue with thumbnails not showing --- .../+item-page/simple/item-page.component.ts | 11 +---------- src/app/thumbnail/thumbnail.component.html | 4 ++-- src/app/thumbnail/thumbnail.component.ts | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/app/+item-page/simple/item-page.component.ts b/src/app/+item-page/simple/item-page.component.ts index e4d96e3bc4..89d5977583 100644 --- a/src/app/+item-page/simple/item-page.component.ts +++ b/src/app/+item-page/simple/item-page.component.ts @@ -1,5 +1,5 @@ -import { mergeMap, filter, map, take } from 'rxjs/operators'; +import { mergeMap, filter, map, take, tap } from 'rxjs/operators'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; @@ -41,11 +41,6 @@ export class ItemPageComponent implements OnInit { */ itemRD$: Observable>; - /** - * The item's thumbnail - */ - thumbnail$: Observable; - /** * The view-mode we're currently on */ @@ -64,9 +59,5 @@ export class ItemPageComponent implements OnInit { redirectToPageNotFoundOn404(this.router) ); this.metadataService.processRemoteData(this.itemRD$); - this.thumbnail$ = this.itemRD$.pipe( - map((rd: RemoteData) => rd.payload), - filter((item: Item) => hasValue(item)), - mergeMap((item: Item) => item.getThumbnail())); } } diff --git a/src/app/thumbnail/thumbnail.component.html b/src/app/thumbnail/thumbnail.component.html index 781b3ce524..87fd0251f5 100644 --- a/src/app/thumbnail/thumbnail.component.html +++ b/src/app/thumbnail/thumbnail.component.html @@ -1,4 +1,4 @@
- - +
+ diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts index 5e2b713b31..7ebf01e283 100644 --- a/src/app/thumbnail/thumbnail.component.ts +++ b/src/app/thumbnail/thumbnail.component.ts @@ -1,5 +1,6 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { Bitstream } from '../core/shared/bitstream.model'; +import { hasValue } from '../shared/empty.util'; /** * This component renders a given Bitstream as a thumbnail. @@ -12,19 +13,27 @@ import { Bitstream } from '../core/shared/bitstream.model'; styleUrls: ['./thumbnail.component.scss'], templateUrl: './thumbnail.component.html' }) -export class ThumbnailComponent { +export class ThumbnailComponent implements OnInit { @Input() thumbnail: Bitstream; - data: any = {}; - /** * The default 'holder.js' image */ @Input() defaultImage? = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2293%22%20height%3D%22120%22%20viewBox%3D%220%200%2093%20120%22%20preserveAspectRatio%3D%22none%22%3E%3C!--%0ASource%20URL%3A%20holder.js%2F93x120%3Ftext%3DNo%20Thumbnail%0ACreated%20with%20Holder.js%202.8.2.%0ALearn%20more%20at%20http%3A%2F%2Fholderjs.com%0A(c)%202012-2015%20Ivan%20Malopinsky%20-%20http%3A%2F%2Fimsky.co%0A--%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%3C!%5BCDATA%5B%23holder_1543e460b05%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%5D%5D%3E%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1543e460b05%22%3E%3Crect%20width%3D%2293%22%20height%3D%22120%22%20fill%3D%22%23EEEEEE%22%2F%3E%3Cg%3E%3Ctext%20x%3D%2235.6171875%22%20y%3D%2257%22%3ENo%3C%2Ftext%3E%3Ctext%20x%3D%2210.8125%22%20y%3D%2272%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'; + src: string; errorHandler(event) { event.currentTarget.src = this.defaultImage; } + ngOnInit(): void { + if (hasValue(this.thumbnail) && this.thumbnail.content) { + this.src = this.thumbnail.content; + } + else { + this.src = this.defaultImage + } + } + } From 151ac0114f2f34869c8a2b29e4791abc74001287 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 17 May 2019 13:28:10 +0200 Subject: [PATCH 13/14] replace npm variable with dedicated script to run webpack with a larger heapspace. The variables didn't work cross-platform --- package.json | 11 ++++------- webpack/run-webpack.js | 13 +++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 webpack/run-webpack.js diff --git a/package.json b/package.json index 3c52ca700b..cc687ea269 100644 --- a/package.json +++ b/package.json @@ -10,9 +10,6 @@ "engines": { "node": ">=8.0.0" }, - "config": { - "wp_cmd": "node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js" - }, "scripts": { "global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup", "clean:coverage": "rimraf coverage", @@ -26,9 +23,9 @@ "prebuild": "yarn run clean:dist", "prebuild:aot": "yarn run prebuild", "prebuild:prod": "yarn run prebuild", - "build": "$npm_package_config_wp_cmd --progress --mode development", - "build:aot": "$npm_package_config_wp_cmd --env.aot --env.server --mode development && $npm_package_config_wp_cmd --env.aot --env.client --mode development", - "build:prod": "$npm_package_config_wp_cmd --env.aot --env.server --mode production && $npm_package_config_wp_cmd --env.aot --env.client --mode production", + "build": "node ./webpack/run-webpack.js --progress --mode development", + "build:aot": "node ./webpack/run-webpack.js --env.aot --env.server --mode development && node ./webpack/run-webpack.js --env.aot --env.client --mode development", + "build:prod": "node ./webpack/run-webpack.js --env.aot --env.server --mode production && node ./webpack/run-webpack.js --env.aot --env.client --mode production", "postbuild:prod": "yarn run rollup", "rollup": "rollup -c rollup.config.js", "prestart": "yarn run build:prod", @@ -43,7 +40,7 @@ "server": "node dist/server.js", "server:watch": "nodemon dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js", - "webpack:watch": "$npm_package_config_wp_cmd -w --mode development", + "webpack:watch": "node ./webpack/run-webpack.js -w --mode development", "watch": "yarn run build && npm-run-all -p webpack:watch server:watch", "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug", "predebug": "yarn run build", diff --git a/webpack/run-webpack.js b/webpack/run-webpack.js new file mode 100644 index 0000000000..93f17b4619 --- /dev/null +++ b/webpack/run-webpack.js @@ -0,0 +1,13 @@ +const path = require('path'); +const child_process = require('child_process'); + +const heapSize = 4096; +const webpackPath = path.join('node_modules', 'webpack', 'bin', 'webpack.js'); + +const params = [ + '--max_old_space_size=' + heapSize, + webpackPath, + ...process.argv.slice(2) +]; + +child_process.spawn('node', params, { stdio:'inherit' }); From 081c5d09523f501c44f64669c5b980905680234e Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 17 May 2019 14:36:22 +0200 Subject: [PATCH 14/14] fix lint error --- src/app/thumbnail/thumbnail.component.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts index 7ebf01e283..9700e01821 100644 --- a/src/app/thumbnail/thumbnail.component.ts +++ b/src/app/thumbnail/thumbnail.component.ts @@ -30,8 +30,7 @@ export class ThumbnailComponent implements OnInit { ngOnInit(): void { if (hasValue(this.thumbnail) && this.thumbnail.content) { this.src = this.thumbnail.content; - } - else { + } else { this.src = this.defaultImage } }