diff --git a/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html b/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
index 7a9481f2f1..886c8f31c0 100644
--- a/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
+++ b/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
@@ -3,13 +3,27 @@
(keydown.arrowdown)="shiftFocusDown($event)"
(keydown.arrowup)="shiftFocusUp($event)" (keydown.esc)="close()"
(dsClickOutside)="close();">
-
-
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/src/app/shared/input-suggestions/input-suggestions.component.ts b/src/app/shared/input-suggestions/input-suggestions.component.ts
index c48dcfb831..7b5c9f34f2 100644
--- a/src/app/shared/input-suggestions/input-suggestions.component.ts
+++ b/src/app/shared/input-suggestions/input-suggestions.component.ts
@@ -53,6 +53,11 @@ export class InputSuggestionsComponent implements ControlValueAccessor, OnChange
*/
@Input() valid = true;
+ /**
+ * Label for the input field. Used for screen readers.
+ */
+ @Input() label? = '';
+
/**
* Output for when the form is submitted
*/
diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.spec.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.spec.ts
index 3442b044a2..458272c606 100644
--- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.spec.ts
+++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.spec.ts
@@ -1,5 +1,5 @@
-import { waitForAsync, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
-import { ChangeDetectionStrategy, ComponentFactoryResolver, NO_ERRORS_SCHEMA } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
+import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { ListableObjectComponentLoaderComponent } from './listable-object-component-loader.component';
import { ListableObject } from '../listable-object.model';
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
@@ -117,17 +117,33 @@ describe('ListableObjectComponentLoaderComponent', () => {
});
describe('When a reloadedObject is emitted', () => {
+ let listableComponent;
+ let reloadedObject: any;
- it('should re-instantiate the listable component ', fakeAsync(() => {
+ beforeEach(() => {
+ spyOn((comp as any), 'connectInputsAndOutputs').and.returnValue(null);
+ spyOn((comp as any).contentChange, 'emit').and.returnValue(null);
- spyOn((comp as any), 'instantiateComponent').and.returnValue(null);
+ listableComponent = fixture.debugElement.query(By.css('ds-item-list-element')).componentInstance;
+ reloadedObject = 'object';
+ });
+
+ it('should pass it on connectInputsAndOutputs', fakeAsync(() => {
+ expect((comp as any).connectInputsAndOutputs).not.toHaveBeenCalled();
- const listableComponent = fixture.debugElement.query(By.css('ds-item-list-element')).componentInstance;
- const reloadedObject: any = 'object';
(listableComponent as any).reloadedObject.emit(reloadedObject);
tick();
- expect((comp as any).instantiateComponent).toHaveBeenCalledWith(reloadedObject);
+ expect((comp as any).connectInputsAndOutputs).toHaveBeenCalled();
+ }));
+
+ it('should re-emit it as a contentChange', fakeAsync(() => {
+ expect((comp as any).contentChange.emit).not.toHaveBeenCalled();
+
+ (listableComponent as any).reloadedObject.emit(reloadedObject);
+ tick();
+
+ expect((comp as any).contentChange.emit).toHaveBeenCalledWith(reloadedObject);
}));
});
diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts
index 30ad91c1e2..4c6206cb43 100644
--- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts
+++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts
@@ -3,10 +3,14 @@ import {
ComponentFactoryResolver,
ElementRef,
Input,
- OnDestroy, OnInit,
- Output, ViewChild
-,
- EventEmitter
+ OnDestroy,
+ OnInit,
+ Output,
+ ViewChild,
+ EventEmitter,
+ SimpleChanges,
+ OnChanges,
+ ComponentRef
} from '@angular/core';
import { ListableObject } from '../listable-object.model';
import { ViewMode } from '../../../../core/shared/view-mode.model';
@@ -15,7 +19,7 @@ import { getListableObjectComponent } from './listable-object.decorator';
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
import { ListableObjectDirective } from './listable-object.directive';
import { CollectionElementLinkType } from '../../collection-element-link.type';
-import { hasValue } from '../../../empty.util';
+import { hasValue, isNotEmpty } from '../../../empty.util';
import { Subscription } from 'rxjs/internal/Subscription';
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
import { take } from 'rxjs/operators';
@@ -29,7 +33,7 @@ import { ThemeService } from '../../../theme-support/theme.service';
/**
* Component for determining what component to use depending on the item's entity type (dspace.entity.type)
*/
-export class ListableObjectComponentLoaderComponent implements OnInit, OnDestroy {
+export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges, OnDestroy {
/**
* The item or metadata to determine the component for
*/
@@ -107,6 +111,25 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnDestroy
*/
protected subs: Subscription[] = [];
+ /**
+ * The reference to the dynamic component
+ */
+ protected compRef: ComponentRef
;
+
+ /**
+ * The list of input and output names for the dynamic component
+ */
+ protected inAndOutputNames: string[] = [
+ 'object',
+ 'index',
+ 'linkType',
+ 'listID',
+ 'showLabel',
+ 'context',
+ 'viewMode',
+ 'value',
+ ];
+
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private themeService: ThemeService
@@ -120,6 +143,15 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnDestroy
this.instantiateComponent(this.object);
}
+ /**
+ * Whenever the inputs change, update the inputs of the dynamic component
+ */
+ ngOnChanges(changes: SimpleChanges): void {
+ if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
+ this.connectInputsAndOutputs();
+ }
+ }
+
ngOnDestroy() {
this.subs
.filter((subscription) => hasValue(subscription))
@@ -137,28 +169,22 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnDestroy
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
viewContainerRef.clear();
- const componentRef = viewContainerRef.createComponent(
+ this.compRef = viewContainerRef.createComponent(
componentFactory,
0,
undefined,
[
[this.badges.nativeElement],
]);
- (componentRef.instance as any).object = object;
- (componentRef.instance as any).index = this.index;
- (componentRef.instance as any).linkType = this.linkType;
- (componentRef.instance as any).listID = this.listID;
- (componentRef.instance as any).showLabel = this.showLabel;
- (componentRef.instance as any).context = this.context;
- (componentRef.instance as any).viewMode = this.viewMode;
- (componentRef.instance as any).value = this.value;
- if ((componentRef.instance as any).reloadedObject) {
- (componentRef.instance as any).reloadedObject.pipe(take(1)).subscribe((reloadedObject: DSpaceObject) => {
+ this.connectInputsAndOutputs();
+
+ if ((this.compRef.instance as any).reloadedObject) {
+ (this.compRef.instance as any).reloadedObject.pipe(take(1)).subscribe((reloadedObject: DSpaceObject) => {
if (reloadedObject) {
- componentRef.destroy();
+ this.compRef.destroy();
this.object = reloadedObject;
- this.instantiateComponent(reloadedObject);
+ this.connectInputsAndOutputs();
this.contentChange.emit(reloadedObject);
}
});
@@ -187,4 +213,17 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnDestroy
context: Context): GenericConstructor {
return getListableObjectComponent(renderTypes, viewMode, context, this.themeService.getThemeName());
}
+
+ /**
+ * Connect the in and outputs of this component to the dynamic component,
+ * to ensure they're in sync
+ */
+ protected connectInputsAndOutputs(): void {
+ if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
+ this.inAndOutputNames.forEach((name: any) => {
+ this.compRef.instance[name] = this[name];
+ });
+ }
+ }
+
}
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component.ts
index b729307443..74411d2341 100644
--- a/src/app/shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component.ts
+++ b/src/app/shared/object-detail/my-dspace-result-detail-element/claimed-task-search-result/claimed-task-search-result-detail-element.component.ts
@@ -49,8 +49,8 @@ export class ClaimedTaskSearchResultDetailElementComponent extends SearchResultD
*/
ngOnInit() {
super.ngOnInit();
- this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
- followLink('item', null, true, true, true, followLink('bundles')),
+ this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
+ followLink('item', {}, followLink('bundles')),
followLink('submitter')
), followLink('action'));
this.workflowitemRD$ = this.dso.workflowitem as Observable>;
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html
index e4d2526eb2..61e2955deb 100644
--- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html
+++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.html
@@ -10,7 +10,7 @@
-
+
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts
index 2b38b58598..07acf3ea75 100644
--- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts
+++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts
@@ -126,13 +126,6 @@ describe('ItemDetailPreviewComponent', () => {
}));
- it('should get item thumbnail', (done) => {
- component.getThumbnail().subscribe((thumbnail) => {
- expect(thumbnail).toBeDefined();
- done();
- });
- });
-
it('should get item bitstreams', (done) => {
component.getFiles().subscribe((bitstreams) => {
expect(bitstreams).toBeDefined();
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts
index a4dc0a1d3d..92c1afcb59 100644
--- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts
+++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.ts
@@ -5,10 +5,7 @@ import { first } from 'rxjs/operators';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
import { Item } from '../../../../core/shared/item.model';
-import {
- getFirstSucceededRemoteDataPayload,
- getFirstSucceededRemoteListPayload
-} from '../../../../core/shared/operators';
+import { getFirstSucceededRemoteListPayload } from '../../../../core/shared/operators';
import { MyDspaceItemStatusType } from '../../../object-collection/shared/mydspace-item-status/my-dspace-item-status-type';
import { fadeInOut } from '../../../animations/fade';
import { Bitstream } from '../../../../core/shared/bitstream.model';
@@ -57,11 +54,6 @@ export class ItemDetailPreviewComponent {
*/
public separator = ', ';
- /**
- * The item's thumbnail
- */
- public thumbnail$: Observable;
-
/**
* Initialize instance variables
*
@@ -86,13 +78,6 @@ export class ItemDetailPreviewComponent {
});
}
- // TODO refactor this method to return RemoteData, and the template to deal with loading and errors
- public getThumbnail(): Observable {
- return this.bitstreamDataService.getThumbnailFor(this.item).pipe(
- getFirstSucceededRemoteDataPayload()
- );
- }
-
// TODO refactor this method to return RemoteData, and the template to deal with loading and errors
public getFiles(): Observable {
return this.bitstreamDataService
diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component.ts
index a8b2514ffb..df27abd42e 100644
--- a/src/app/shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component.ts
+++ b/src/app/shared/object-detail/my-dspace-result-detail-element/pool-search-result/pool-search-result-detail-element.component.ts
@@ -48,8 +48,8 @@ export class PoolSearchResultDetailElementComponent extends SearchResultDetailEl
*/
ngOnInit() {
super.ngOnInit();
- this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
- followLink('item', null, true, true, true, followLink('bundles')),
+ this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
+ followLink('item', {}, followLink('bundles')),
followLink('submitter')
), followLink('action'));
this.workflowitemRD$ = this.dso.workflowitem as Observable>;
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 bc16853721..d2454b28e6 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
@@ -6,13 +6,13 @@
-
+
-
+
@@ -43,4 +43,3 @@
-
diff --git a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts
index 7436d2922e..da1f0ea11b 100644
--- a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts
+++ b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts
@@ -3,13 +3,11 @@ import { Observable } from 'rxjs';
import { SearchResult } from '../../search/search-result.model';
import { BitstreamDataService } from '../../../core/data/bitstream-data.service';
-import { Bitstream } from '../../../core/shared/bitstream.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { Metadata } from '../../../core/shared/metadata.utils';
import { hasValue } from '../../empty.util';
import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component';
import { TruncatableService } from '../../truncatable/truncatable.service';
-import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
@Component({
selector: 'ds-search-result-grid-element',
@@ -66,11 +64,4 @@ export class SearchResultGridElementComponent
, K exten
private isCollapsed(): Observable {
return this.truncatableService.isCollapsed(this.dso.id);
}
-
- // TODO refactor to return RemoteData, and thumbnail template to deal with loading
- getThumbnail(): Observable {
- return this.bitstreamDataService.getThumbnailFor(this.dso as any).pipe(
- getFirstSucceededRemoteDataPayload()
- );
- }
}
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component.ts
index 5571782ce2..eaf407d787 100644
--- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component.ts
+++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-approved-search-result/claimed-approved-search-result-list-element.component.ts
@@ -55,10 +55,7 @@ export class ClaimedApprovedSearchResultListElementComponent extends SearchResul
super.ngOnInit();
this.linkService.resolveLinks(this.dso,
followLink('workflowitem',
- null,
- true,
- false,
- true,
+ { useCachedVersionIfAvailable: false },
followLink('item'),
followLink('submitter')
),
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component.ts
index 630aa699a7..0b9a925dbf 100644
--- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component.ts
+++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-search-result/claimed-declined-search-result-list-element.component.ts
@@ -56,10 +56,7 @@ export class ClaimedDeclinedSearchResultListElementComponent extends SearchResul
super.ngOnInit();
this.linkService.resolveLinks(this.dso,
followLink('workflowitem',
- null,
- true,
- false,
- true,
+ { useCachedVersionIfAvailable: false },
followLink('item'),
followLink('submitter')
),
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 dae3272889..2cf8f9a231 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
@@ -50,7 +50,7 @@ export class ClaimedSearchResultListElementComponent extends SearchResultListEle
*/
ngOnInit() {
super.ngOnInit();
- this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
+ this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
followLink('item'), followLink('submitter')
), followLink('action'));
this.workflowitemRD$ = this.dso.workflowitem as Observable>;
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 fe4fa715ee..e9d64db572 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
@@ -60,7 +60,7 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
*/
ngOnInit() {
super.ngOnInit();
- this.linkService.resolveLinks(this.dso, followLink('workflowitem', null, true, true, true,
+ this.linkService.resolveLinks(this.dso, followLink('workflowitem', {},
followLink('item'), followLink('submitter')
), followLink('action'));
this.workflowitemRD$ = this.dso.workflowitem as Observable>;
diff --git a/src/app/shared/search/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html
index 5e6bcfaf8b..44aed494e3 100644
--- a/src/app/shared/search/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html
+++ b/src/app/shared/search/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html
@@ -8,15 +8,18 @@
diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.html b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.html
index cf4876e34f..e2e57e7370 100644
--- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.html
+++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.html
@@ -1,10 +1,13 @@