diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
index 48fb01200b..3d6e251238 100644
--- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
+++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
@@ -5,14 +5,14 @@
diff --git a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.html b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.html
index 8d3afea273..e2f55ce10c 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.html
+++ b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.html
@@ -1,9 +1,9 @@
diff --git a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts
index 32919d9758..3527b9fddd 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.spec.ts
@@ -30,7 +30,7 @@ describe('BrowseLinkMetadataListElementComponent', () => {
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(BrowseLinkMetadataListElementComponent);
comp = fixture.componentInstance;
- comp.metadataRepresentation = mockMetadataRepresentation;
+ comp.mdRepresentation = mockMetadataRepresentation;
fixture.detectChanges();
}));
@@ -46,7 +46,7 @@ describe('BrowseLinkMetadataListElementComponent', () => {
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(BrowseLinkMetadataListElementComponent);
comp = fixture.componentInstance;
- comp.metadataRepresentation = mockMetadataRepresentationWithUrl;
+ comp.mdRepresentation = mockMetadataRepresentationWithUrl;
fixture.detectChanges();
}));
diff --git a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.ts
index 0eb0ce05b0..51907b5641 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/browse-link/browse-link-metadata-list-element.component.ts
@@ -20,9 +20,9 @@ export class BrowseLinkMetadataListElementComponent extends MetadataRepresentati
* expects 'startsWith' (eg browse by date) or 'value' (eg browse by title)
*/
getQueryParams() {
- let queryParams = {startsWith: this.metadataRepresentation.getValue()};
- if (this.metadataRepresentation.browseDefinition.metadataBrowse) {
- return {value: this.metadataRepresentation.getValue()};
+ let queryParams = {startsWith: this.mdRepresentation.getValue()};
+ if (this.mdRepresentation.browseDefinition.metadataBrowse) {
+ return {value: this.mdRepresentation.getValue()};
}
return queryParams;
}
diff --git a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.html b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.html
index 91219c7189..904ea95c20 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.html
+++ b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.html
@@ -1 +1 @@
-
+
diff --git a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts
index 6e48ba3a6f..99052b6b14 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-list-element.component.spec.ts
@@ -23,7 +23,7 @@ describe('ItemMetadataListElementComponent', () => {
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(ItemMetadataListElementComponent);
comp = fixture.componentInstance;
- comp.metadataRepresentation = mockItemMetadataRepresentation;
+ comp.mdRepresentation = mockItemMetadataRepresentation;
fixture.detectChanges();
}));
diff --git a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts
index 967b09986d..c4a6903129 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component.ts
@@ -1,5 +1,5 @@
import { MetadataRepresentationListElementComponent } from '../metadata-representation-list-element.component';
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, Input } from '@angular/core';
import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model';
import { getItemPageRoute } from '../../../../item-page/item-page-routing-paths';
@@ -11,7 +11,7 @@ import { getItemPageRoute } from '../../../../item-page/item-page-routing-paths'
* An abstract class for displaying a single ItemMetadataRepresentation
*/
export class ItemMetadataRepresentationListElementComponent extends MetadataRepresentationListElementComponent implements OnInit {
- metadataRepresentation: ItemMetadataRepresentation;
+ @Input() mdRepresentation: ItemMetadataRepresentation;
/**
* Route to the item's page
@@ -19,6 +19,6 @@ export class ItemMetadataRepresentationListElementComponent extends MetadataRepr
itemPageRoute: string;
ngOnInit(): void {
- this.itemPageRoute = getItemPageRoute(this.metadataRepresentation);
+ this.itemPageRoute = getItemPageRoute(this.mdRepresentation);
}
}
diff --git a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts
index f0cc150b3e..dc8febe84a 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.spec.ts
@@ -36,7 +36,7 @@ describe('MetadataRepresentationListElementComponent', () => {
describe('when the value is not a URL', () => {
beforeEach(() => {
- comp.metadataRepresentation = mockMetadataRepresentation;
+ comp.mdRepresentation = mockMetadataRepresentation;
});
it('isLink correctly detects a non-URL string as false', () => {
waitForAsync(() => {
@@ -47,7 +47,7 @@ describe('MetadataRepresentationListElementComponent', () => {
describe('when the value is a URL', () => {
beforeEach(() => {
- comp.metadataRepresentation = mockMetadataRepresentationUrl;
+ comp.mdRepresentation = mockMetadataRepresentationUrl;
});
it('isLink correctly detects a URL string as true', () => {
waitForAsync(() => {
diff --git a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts
index b69f6b37dc..d8f8621ca6 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts
@@ -1,5 +1,6 @@
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
import { MetadataRepresentation } from '../../../core/shared/metadata-representation/metadata-representation.model';
+import { Context } from '../../../core/shared/context.model';
@Component({
selector: 'ds-metadata-representation-list-element',
@@ -9,10 +10,15 @@ import { MetadataRepresentation } from '../../../core/shared/metadata-representa
* An abstract class for displaying a single MetadataRepresentation
*/
export class MetadataRepresentationListElementComponent {
+ /**
+ * The optional context
+ */
+ @Input() context: Context;
+
/**
* The metadata representation of this component
*/
- metadataRepresentation: MetadataRepresentation;
+ @Input() mdRepresentation: MetadataRepresentation;
/**
* Returns true if this component's value matches a basic regex "Is this an HTTP URL" test
@@ -20,7 +26,7 @@ export class MetadataRepresentationListElementComponent {
isLink(): boolean {
// Match any string that begins with http:// or https://
const linkPattern = new RegExp(/^https?\/\/.*/);
- return linkPattern.test(this.metadataRepresentation.getValue());
+ return linkPattern.test(this.mdRepresentation.getValue());
}
}
diff --git a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html
index 7b611a7d1f..7d416e9f3e 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html
+++ b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html
@@ -1,17 +1,17 @@
diff --git a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.spec.ts b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.spec.ts
index cfb812a475..91d7db3562 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.spec.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.spec.ts
@@ -29,7 +29,7 @@ describe('PlainTextMetadataListElementComponent', () => {
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(PlainTextMetadataListElementComponent);
comp = fixture.componentInstance;
- comp.metadataRepresentation = mockMetadataRepresentation;
+ comp.mdRepresentation = mockMetadataRepresentation;
fixture.detectChanges();
}));
diff --git a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.ts b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.ts
index 2d21a7afe8..4ff16e949a 100644
--- a/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.ts
+++ b/src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.ts
@@ -20,9 +20,9 @@ export class PlainTextMetadataListElementComponent extends MetadataRepresentatio
* expects 'startsWith' (eg browse by date) or 'value' (eg browse by title)
*/
getQueryParams() {
- let queryParams = {startsWith: this.metadataRepresentation.getValue()};
- if (this.metadataRepresentation.browseDefinition.metadataBrowse) {
- return {value: this.metadataRepresentation.getValue()};
+ let queryParams = {startsWith: this.mdRepresentation.getValue()};
+ if (this.mdRepresentation.browseDefinition.metadataBrowse) {
+ return {value: this.mdRepresentation.getValue()};
}
return queryParams;
}
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts
index 18c03d71c4..f92ad28973 100644
--- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts
+++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts
@@ -19,7 +19,7 @@ import { ObjectCacheService } from '../../../../core/cache/object-cache.service'
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
import { Item } from '../../../../core/shared/item.model';
import { mergeMap, tap } from 'rxjs/operators';
-import { isNotEmpty } from '../../../empty.util';
+import { isNotEmpty, hasValue } from '../../../empty.util';
import { Context } from '../../../../core/shared/context.model';
@Component({
@@ -99,7 +99,9 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
ngOnDestroy() {
// This ensures the object is removed from cache, when action is performed on task
- this.objectCache.remove(this.dso._links.workflowitem.href);
+ if (hasValue(this.dso)) {
+ this.objectCache.remove(this.dso._links.workflowitem.href);
+ }
}
}
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts
index b3b3bd2b5a..c69ef05380 100644
--- a/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts
+++ b/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts
@@ -20,7 +20,7 @@ import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interfac
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
import { Item } from '../../../../core/shared/item.model';
-import { isNotEmpty } from '../../../empty.util';
+import { isNotEmpty, hasValue } from '../../../empty.util';
import { Context } from '../../../../core/shared/context.model';
/**
@@ -109,6 +109,8 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
ngOnDestroy() {
// This ensures the object is removed from cache, when action is performed on task
- this.objectCache.remove(this.dso._links.workflowitem.href);
+ if (hasValue(this.dso)) {
+ this.objectCache.remove(this.dso._links.workflowitem.href);
+ }
}
}
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index 54d3cb2e66..5245f244c4 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -50,6 +50,7 @@ import { ErrorComponent } from './error/error.component';
import { LoadingComponent } from './loading/loading.component';
import { PaginationComponent } from './pagination/pagination.component';
import { ThumbnailComponent } from '../thumbnail/thumbnail.component';
+import { ThemedThumbnailComponent } from '../thumbnail/themed-thumbnail.component';
import { SearchFormComponent } from './search-form/search-form.component';
import { ThemedSearchFormComponent } from './search-form/themed-search-form.component';
import {
@@ -348,6 +349,7 @@ const COMPONENTS = [
PageWithSidebarComponent,
SidebarDropdownComponent,
ThumbnailComponent,
+ ThemedThumbnailComponent,
MyDSpaceStatusBadgeComponent,
ThemedMyDSpaceStatusBadgeComponent,
ViewModeSwitchComponent,
diff --git a/src/app/shared/theme-support/themed.component.ts b/src/app/shared/theme-support/themed.component.ts
index 07e868c512..6b0727ccdd 100644
--- a/src/app/shared/theme-support/themed.component.ts
+++ b/src/app/shared/theme-support/themed.component.ts
@@ -12,8 +12,8 @@ import {
HostBinding,
ElementRef,
} from '@angular/core';
-import { hasValue, isNotEmpty } from '../empty.util';
-import { from as fromPromise, Observable, of as observableOf, Subscription, BehaviorSubject } from 'rxjs';
+import { hasNoValue, hasValue, isNotEmpty } from '../empty.util';
+import { combineLatest, from as fromPromise, Observable, of as observableOf, Subscription, BehaviorSubject } from 'rxjs';
import { ThemeService } from './theme.service';
import { catchError, switchMap, map, tap } from 'rxjs/operators';
import { GenericConstructor } from '../../core/shared/generic-constructor';
@@ -35,6 +35,7 @@ export abstract class ThemedComponent
implements OnInit, OnDestroy, OnChanges
*/
public compRef$: BehaviorSubject> = new BehaviorSubject(undefined);
+ protected lazyLoadObs: Observable;
protected lazyLoadSub: Subscription;
protected themeSub: Subscription;
@@ -58,20 +59,24 @@ export abstract class ThemedComponent implements OnInit, OnDestroy, OnChanges
protected abstract importUnthemedComponent(): Promise;
ngOnChanges(changes: SimpleChanges): void {
- // if an input or output has changed
- if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
- this.connectInputsAndOutputs();
- if (this.compRef?.instance && 'ngOnChanges' in this.compRef.instance) {
- (this.compRef.instance as any).ngOnChanges(changes);
+ if (hasNoValue(this.compRef)) {
+ // sometimes the component has not been initialized yet, so it first needs to be initialized
+ // before being called again
+ this.initComponentInstance(changes);
+ } else {
+ // if an input or output has changed
+ if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
+ this.connectInputsAndOutputs();
+ if (this.compRef?.instance && 'ngOnChanges' in this.compRef.instance) {
+ (this.compRef.instance as any).ngOnChanges(changes);
+ }
}
}
}
ngOnInit(): void {
this.destroyComponentInstance();
- this.themeSub = this.themeService.getThemeName$().subscribe(() => {
- this.renderComponentInstance();
- });
+ this.initComponentInstance();
}
ngOnDestroy(): void {
@@ -79,33 +84,49 @@ export abstract class ThemedComponent implements OnInit, OnDestroy, OnChanges
this.destroyComponentInstance();
}
- protected renderComponentInstance(): void {
- this.destroyComponentInstance();
+ initComponentInstance(changes?: SimpleChanges) {
+ this.themeSub = this.themeService?.getThemeName$().subscribe(() => {
+ this.renderComponentInstance(changes);
+ });
+ }
+ protected renderComponentInstance(changes?: SimpleChanges): void {
if (hasValue(this.lazyLoadSub)) {
this.lazyLoadSub.unsubscribe();
}
- this.lazyLoadSub = this.resolveThemedComponent(this.themeService.getThemeName()).pipe(
- switchMap((themedFile: any) => {
- if (hasValue(themedFile) && hasValue(themedFile[this.getComponentName()])) {
- // if the file is not null, and exports a component with the specified name,
- // return that component
- return [themedFile[this.getComponentName()]];
- } else {
- // otherwise import and return the default component
- return fromPromise(this.importUnthemedComponent()).pipe(
+ if (hasNoValue(this.lazyLoadObs)) {
+ this.destroyComponentInstance();
+
+ this.lazyLoadObs = combineLatest([
+ observableOf(changes),
+ this.resolveThemedComponent(this.themeService.getThemeName()).pipe(
+ switchMap((themedFile: any) => {
+ if (hasValue(themedFile) && hasValue(themedFile[this.getComponentName()])) {
+ // if the file is not null, and exports a component with the specified name,
+ // return that component
+ return [themedFile[this.getComponentName()]];
+ } else {
+ // otherwise import and return the default component
+ return fromPromise(this.importUnthemedComponent()).pipe(
tap(() => this.usedTheme = BASE_THEME_NAME),
- map((unthemedFile: any) => {
- return unthemedFile[this.getComponentName()];
- })
- );
- }
- }),
- ).subscribe((constructor: GenericConstructor) => {
+ map((unthemedFile: any) => {
+ return unthemedFile[this.getComponentName()];
+ })
+ );
+ }
+ })),
+ ]);
+ }
+
+ this.lazyLoadSub = this.lazyLoadObs.subscribe(([simpleChanges, constructor]: [SimpleChanges, GenericConstructor]) => {
const factory = this.resolver.resolveComponentFactory(constructor);
this.compRef = this.vcr.createComponent(factory, undefined, undefined, [this.themedElementContent.nativeElement.childNodes]);
- this.connectInputsAndOutputs();
+ if (hasValue(simpleChanges)) {
+ this.ngOnChanges(simpleChanges);
+ } else {
+ this.connectInputsAndOutputs();
+ }
this.compRef$.next(this.compRef);
this.cdr.markForCheck();
this.themedElementContent.nativeElement.remove();
diff --git a/src/app/submission/sections/upload/file/section-upload-file.component.html b/src/app/submission/sections/upload/file/section-upload-file.component.html
index 9bf4eb1bcb..8999853d72 100644
--- a/src/app/submission/sections/upload/file/section-upload-file.component.html
+++ b/src/app/submission/sections/upload/file/section-upload-file.component.html
@@ -1,8 +1,8 @@
-
-
+
+
diff --git a/src/app/thumbnail/themed-thumbnail.component.ts b/src/app/thumbnail/themed-thumbnail.component.ts
new file mode 100644
index 0000000000..2a8d809104
--- /dev/null
+++ b/src/app/thumbnail/themed-thumbnail.component.ts
@@ -0,0 +1,44 @@
+import { ThemedComponent } from '../shared/theme-support/themed.component';
+import { Component, Input } from '@angular/core';
+import { ThumbnailComponent } from './thumbnail.component';
+import { Bitstream } from '../core/shared/bitstream.model';
+import { RemoteData } from '../core/data/remote-data';
+
+@Component({
+ selector: 'ds-themed-thumbnail',
+ styleUrls: [],
+ templateUrl: '../shared/theme-support/themed.component.html',
+})
+export class ThemedThumbnailComponent extends ThemedComponent
{
+
+ @Input() thumbnail: Bitstream | RemoteData;
+
+ @Input() defaultImage?: string | null;
+
+ @Input() alt?: string;
+
+ @Input() placeholder?: string;
+
+ @Input() limitWidth?: boolean;
+
+ protected inAndOutputNames: (keyof ThumbnailComponent & keyof this)[] = [
+ 'thumbnail',
+ 'defaultImage',
+ 'alt',
+ 'placeholder',
+ 'limitWidth',
+ ];
+
+ protected getComponentName(): string {
+ return 'ThumbnailComponent';
+ }
+
+ protected importThemedComponent(themeName: string): Promise {
+ return import(`../../themes/${themeName}/app/thumbnail/thumbnail.component`);
+ }
+
+ protected importUnthemedComponent(): Promise {
+ return import('./thumbnail.component');
+ }
+
+}
diff --git a/src/app/thumbnail/thumbnail.component.spec.ts b/src/app/thumbnail/thumbnail.component.spec.ts
index 29aebe03fc..ebecb5e075 100644
--- a/src/app/thumbnail/thumbnail.component.spec.ts
+++ b/src/app/thumbnail/thumbnail.component.spec.ts
@@ -134,7 +134,7 @@ describe('ThumbnailComponent', () => {
const img = fixture.debugElement.query(By.css('img.thumbnail-content'));
img.nativeNode.onerror = null;
- comp.ngOnChanges();
+ comp.ngOnChanges({});
setSrcSpy = spyOn(comp, 'setSrc').and.callThrough();
});
@@ -261,14 +261,14 @@ describe('ThumbnailComponent', () => {
describe('if content can be loaded', () => {
it('should display an image', () => {
- comp.ngOnChanges();
+ comp.ngOnChanges({});
fixture.detectChanges();
const image: HTMLElement = fixture.debugElement.query(By.css('img')).nativeElement;
expect(image.getAttribute('src')).toBe(thumbnail._links.content.href);
});
it('should include the alt text', () => {
- comp.ngOnChanges();
+ comp.ngOnChanges({});
fixture.detectChanges();
const image: HTMLElement = fixture.debugElement.query(By.css('img')).nativeElement;
expect(image.getAttribute('alt')).toBe('TRANSLATED ' + comp.alt);
@@ -301,14 +301,14 @@ describe('ThumbnailComponent', () => {
describe('if content can be loaded', () => {
it('should display an image', () => {
- comp.ngOnChanges();
+ comp.ngOnChanges({});
fixture.detectChanges();
const image: HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute('src')).toBe(thumbnail._links.content.href);
});
it('should display the alt text', () => {
- comp.ngOnChanges();
+ comp.ngOnChanges({});
fixture.detectChanges();
const image: HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute('alt')).toBe('TRANSLATED ' + comp.alt);
@@ -327,7 +327,7 @@ describe('ThumbnailComponent', () => {
it('should show the default image', () => {
comp.defaultImage = 'default/image.jpg';
- comp.ngOnChanges();
+ comp.ngOnChanges({});
expect(comp.src$.getValue()).toBe('default/image.jpg');
});
});
diff --git a/src/app/thumbnail/thumbnail.component.ts b/src/app/thumbnail/thumbnail.component.ts
index 5a7557def1..7f6531cc5e 100644
--- a/src/app/thumbnail/thumbnail.component.ts
+++ b/src/app/thumbnail/thumbnail.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnChanges } from '@angular/core';
+import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { Bitstream } from '../core/shared/bitstream.model';
import { hasNoValue, hasValue } from '../shared/empty.util';
import { RemoteData } from '../core/data/remote-data';
@@ -70,8 +70,9 @@ export class ThumbnailComponent implements OnChanges {
* Resolve the thumbnail.
* Use a default image if no actual image is available.
*/
- ngOnChanges(): void {
+ ngOnChanges(changes: SimpleChanges): void {
if (hasNoValue(this.thumbnail)) {
+ this.setSrc(this.defaultImage);
return;
}
diff --git a/src/themes/custom/app/thumbnail/thumbnail.component.html b/src/themes/custom/app/thumbnail/thumbnail.component.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/themes/custom/app/thumbnail/thumbnail.component.scss b/src/themes/custom/app/thumbnail/thumbnail.component.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/themes/custom/app/thumbnail/thumbnail.component.ts b/src/themes/custom/app/thumbnail/thumbnail.component.ts
new file mode 100644
index 0000000000..406183c8e7
--- /dev/null
+++ b/src/themes/custom/app/thumbnail/thumbnail.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { ThumbnailComponent as BaseComponent } from '../../../../app/thumbnail/thumbnail.component';
+
+@Component({
+ selector: 'ds-thumbnail',
+ // styleUrls: ['./thumbnail.component.scss'],
+ styleUrls: ['../../../../app/thumbnail/thumbnail.component.scss'],
+ // templateUrl: './thumbnail.component.html',
+ templateUrl: '../../../../app/thumbnail/thumbnail.component.html',
+})
+export class ThumbnailComponent extends BaseComponent {
+}
diff --git a/src/themes/custom/lazy-theme.module.ts b/src/themes/custom/lazy-theme.module.ts
index f57f6fb11a..adf3a888c1 100644
--- a/src/themes/custom/lazy-theme.module.ts
+++ b/src/themes/custom/lazy-theme.module.ts
@@ -140,6 +140,7 @@ import {
} from './app/item-page/media-viewer/media-viewer-video/media-viewer-video.component';
import { NgxGalleryModule } from '@kolkov/ngx-gallery';
import { WorkspaceItemsDeletePageComponent } from './app/workspace-items-delete-page/workspace-items-delete/workspace-items-delete.component';
+import { ThumbnailComponent } from './app/thumbnail/thumbnail.component';
const DECLARATIONS = [
FileSectionComponent,
@@ -215,6 +216,7 @@ const DECLARATIONS = [
MediaViewerImageComponent,
MediaViewerVideoComponent,
WorkspaceItemsDeletePageComponent,
+ ThumbnailComponent,
];
@NgModule({