Skip to content

Commit 645024d

Browse files
authored
Merge pull request DSpace#2339 from alexandrevryghem/generify-component-loaders_contribute-main
Created abstract component loader class
2 parents cb7c2c9 + 4602cdd commit 645024d

69 files changed

Lines changed: 693 additions & 797 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<ng-template dsListableObject>
1+
<ng-template dsDynamicComponentLoader>
22
</ng-template>
33
<div #badges>
44
<ng-content></ng-content>

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.ts

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ComponentFactoryResolver, ElementRef, OnInit, ViewChild } from '@angular/core';
1+
import { Component, ComponentRef, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
22
import { Item } from '../../../../../core/shared/item.model';
33
import { ViewMode } from '../../../../../core/shared/view-mode.model';
44
import {
@@ -11,9 +11,10 @@ import { SearchResultGridElementComponent } from '../../../../../shared/object-g
1111
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
1212
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
1313
import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
14-
import { ListableObjectDirective } from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive';
14+
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
1515
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
1616
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
17+
import { hasValue } from '../../../../../shared/empty.util';
1718

1819
@listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.AdminSearch)
1920
@Component({
@@ -24,17 +25,18 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service
2425
/**
2526
* The component for displaying a list element for an item search result on the admin search page
2627
*/
27-
export class ItemAdminSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> implements OnInit {
28-
@ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective;
28+
export class ItemAdminSearchResultGridElementComponent extends SearchResultGridElementComponent<ItemSearchResult, Item> implements OnDestroy, OnInit {
29+
@ViewChild(DynamicComponentLoaderDirective, { static: true }) dynamicComponentLoaderDirective: DynamicComponentLoaderDirective;
2930
@ViewChild('badges', { static: true }) badges: ElementRef;
3031
@ViewChild('buttons', { static: true }) buttons: ElementRef;
3132

33+
protected compRef: ComponentRef<Component>;
34+
3235
constructor(
3336
public dsoNameService: DSONameService,
3437
protected truncatableService: TruncatableService,
3538
protected bitstreamDataService: BitstreamDataService,
3639
private themeService: ThemeService,
37-
private componentFactoryResolver: ComponentFactoryResolver,
3840
) {
3941
super(dsoNameService, truncatableService, bitstreamDataService);
4042
}
@@ -44,23 +46,32 @@ export class ItemAdminSearchResultGridElementComponent extends SearchResultGridE
4446
*/
4547
ngOnInit(): void {
4648
super.ngOnInit();
47-
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponent());
49+
const component: GenericConstructor<Component> = this.getComponent();
4850

49-
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
51+
const viewContainerRef = this.dynamicComponentLoaderDirective.viewContainerRef;
5052
viewContainerRef.clear();
5153

52-
const componentRef = viewContainerRef.createComponent(
53-
componentFactory,
54-
0,
55-
undefined,
56-
[
57-
[this.badges.nativeElement],
58-
[this.buttons.nativeElement]
59-
]);
60-
(componentRef.instance as any).object = this.object;
61-
(componentRef.instance as any).index = this.index;
62-
(componentRef.instance as any).linkType = this.linkType;
63-
(componentRef.instance as any).listID = this.listID;
54+
this.compRef = viewContainerRef.createComponent(
55+
component, {
56+
index: 0,
57+
injector: undefined,
58+
projectableNodes: [
59+
[this.badges.nativeElement],
60+
[this.buttons.nativeElement],
61+
],
62+
},
63+
);
64+
this.compRef.setInput('object',this.object);
65+
this.compRef.setInput('index', this.index);
66+
this.compRef.setInput('linkType', this.linkType);
67+
this.compRef.setInput('listID', this.listID);
68+
}
69+
70+
ngOnDestroy(): void {
71+
if (hasValue(this.compRef)) {
72+
this.compRef.destroy();
73+
this.compRef = undefined;
74+
}
6475
}
6576

6677
/**

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-search-result-admin-workflow-grid-element.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<ng-template dsListableObject>
1+
<ng-template dsDynamicComponentLoader>
22
</ng-template>
33
<div #badges class="position-absolute ml-1">
44
<div class="workflow-badge">

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-search-result-admin-workflow-grid-element.component.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import {
1818
ItemGridElementComponent
1919
} from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
2020
import {
21-
ListableObjectDirective
22-
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive';
21+
DynamicComponentLoaderDirective
22+
} from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
2323
import {
2424
WorkflowItemSearchResult
2525
} from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
@@ -38,7 +38,7 @@ describe('WorkflowItemSearchResultAdminWorkflowGridElementComponent', () => {
3838
let itemRD$;
3939
let linkService;
4040
let object;
41-
let themeService;
41+
let themeService: ThemeService;
4242

4343
function init() {
4444
itemRD$ = createSuccessfulRemoteDataObject$(new Item());
@@ -55,7 +55,11 @@ describe('WorkflowItemSearchResultAdminWorkflowGridElementComponent', () => {
5555
init();
5656
TestBed.configureTestingModule(
5757
{
58-
declarations: [WorkflowItemSearchResultAdminWorkflowGridElementComponent, ItemGridElementComponent, ListableObjectDirective],
58+
declarations: [
59+
WorkflowItemSearchResultAdminWorkflowGridElementComponent,
60+
ItemGridElementComponent,
61+
DynamicComponentLoaderDirective,
62+
],
5963
imports: [
6064
NoopAnimationsModule,
6165
TranslateModule.forRoot(),

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-search-result-admin-workflow-grid-element.component.ts

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ComponentFactoryResolver, ElementRef, ViewChild } from '@angular/core';
1+
import { Component, ElementRef, ViewChild, ComponentRef, OnDestroy, OnInit } from '@angular/core';
22
import { Item } from '../../../../../core/shared/item.model';
33
import { ViewMode } from '../../../../../core/shared/view-mode.model';
44
import {
@@ -10,7 +10,7 @@ import { SearchResultGridElementComponent } from '../../../../../shared/object-g
1010
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
1111
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
1212
import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
13-
import { ListableObjectDirective } from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive';
13+
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
1414
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
1515
import { Observable } from 'rxjs';
1616
import { LinkService } from '../../../../../core/cache/builders/link.service';
@@ -24,6 +24,7 @@ import { take } from 'rxjs/operators';
2424
import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
2525
import { ThemeService } from '../../../../../shared/theme-support/theme.service';
2626
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
27+
import { hasValue } from '../../../../../shared/empty.util';
2728

2829
@listableObjectComponent(WorkflowItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch)
2930
@Component({
@@ -34,11 +35,11 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service
3435
/**
3536
* The component for displaying a grid element for an workflow item on the admin workflow search page
3637
*/
37-
export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkflowItemSearchResult, WorkflowItem> {
38+
export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkflowItemSearchResult, WorkflowItem> implements OnDestroy, OnInit {
3839
/**
3940
* Directive used to render the dynamic component in
4041
*/
41-
@ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective;
42+
@ViewChild(DynamicComponentLoaderDirective, { static: true }) dynamicComponentLoaderDirective: DynamicComponentLoaderDirective;
4243

4344
/**
4445
* The html child that contains the badges html
@@ -55,9 +56,10 @@ export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends S
5556
*/
5657
public item$: Observable<Item>;
5758

59+
protected compRef: ComponentRef<Component>;
60+
5861
constructor(
5962
public dsoNameService: DSONameService,
60-
private componentFactoryResolver: ComponentFactoryResolver,
6163
private linkService: LinkService,
6264
protected truncatableService: TruncatableService,
6365
private themeService: ThemeService,
@@ -75,26 +77,34 @@ export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends S
7577
this.dso = this.linkService.resolveLink(this.dso, followLink('item'));
7678
this.item$ = (this.dso.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload());
7779
this.item$.pipe(take(1)).subscribe((item: Item) => {
78-
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponent(item));
80+
const component: GenericConstructor<Component> = this.getComponent(item);
7981

80-
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
81-
viewContainerRef.clear();
82+
const viewContainerRef = this.dynamicComponentLoaderDirective.viewContainerRef;
83+
viewContainerRef.clear();
8284

83-
const componentRef = viewContainerRef.createComponent(
84-
componentFactory,
85-
0,
86-
undefined,
87-
[
85+
this.compRef = viewContainerRef.createComponent(
86+
component, {
87+
index: 0,
88+
injector: undefined,
89+
projectableNodes: [
8890
[this.badges.nativeElement],
89-
[this.buttons.nativeElement]
90-
]);
91-
(componentRef.instance as any).object = item;
92-
(componentRef.instance as any).index = this.index;
93-
(componentRef.instance as any).linkType = this.linkType;
94-
(componentRef.instance as any).listID = this.listID;
95-
componentRef.changeDetectorRef.detectChanges();
96-
}
97-
);
91+
[this.buttons.nativeElement],
92+
],
93+
},
94+
);
95+
this.compRef.setInput('object', item);
96+
this.compRef.setInput('index', this.index);
97+
this.compRef.setInput('linkType', this.linkType);
98+
this.compRef.setInput('listID', this.listID);
99+
this.compRef.changeDetectorRef.detectChanges();
100+
});
101+
}
102+
103+
ngOnDestroy(): void {
104+
if (hasValue(this.compRef)) {
105+
this.compRef.destroy();
106+
this.compRef = undefined;
107+
}
98108
}
99109

100110
/**

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workspace-item/workspace-item-search-result-admin-workflow-grid-element.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<ng-template dsListableObject>
1+
<ng-template dsDynamicComponentLoader>
22
</ng-template>
33
<div #badges class="position-absolute ml-1">
44
<div class="workflow-badge">

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workspace-item/workspace-item-search-result-admin-workflow-grid-element.component.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import {
2020
ItemGridElementComponent
2121
} from '../../../../../shared/object-grid/item-grid-element/item-types/item/item-grid-element.component';
2222
import {
23-
ListableObjectDirective
24-
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive';
23+
DynamicComponentLoaderDirective
24+
} from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
2525
import {
2626
WorkflowItemSearchResult
2727
} from '../../../../../shared/object-collection/shared/workflow-item-search-result.model';
@@ -45,7 +45,7 @@ describe('WorkspaceItemSearchResultAdminWorkflowGridElementComponent', () => {
4545
let itemRD$;
4646
let linkService;
4747
let object;
48-
let themeService;
48+
let themeService: ThemeService;
4949
let supervisionOrderDataService;
5050

5151
function init() {
@@ -67,7 +67,11 @@ describe('WorkspaceItemSearchResultAdminWorkflowGridElementComponent', () => {
6767
init();
6868
TestBed.configureTestingModule(
6969
{
70-
declarations: [WorkspaceItemSearchResultAdminWorkflowGridElementComponent, ItemGridElementComponent, ListableObjectDirective],
70+
declarations: [
71+
WorkspaceItemSearchResultAdminWorkflowGridElementComponent,
72+
ItemGridElementComponent,
73+
DynamicComponentLoaderDirective,
74+
],
7175
imports: [
7276
NoopAnimationsModule,
7377
TranslateModule.forRoot(),

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workspace-item/workspace-item-search-result-admin-workflow-grid-element.component.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ComponentFactoryResolver, ElementRef, ViewChild, OnInit } from '@angular/core';
1+
import { Component, ElementRef, ViewChild, OnInit, OnDestroy, ComponentRef } from '@angular/core';
22

33
import { BehaviorSubject, Observable } from 'rxjs';
44
import { map, mergeMap, take, tap } from 'rxjs/operators';
@@ -16,9 +16,7 @@ import {
1616
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
1717
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
1818
import { GenericConstructor } from '../../../../../core/shared/generic-constructor';
19-
import {
20-
ListableObjectDirective
21-
} from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive';
19+
import { DynamicComponentLoaderDirective } from '../../../../../shared/abstract-component-loader/dynamic-component-loader.directive';
2220
import { WorkspaceItem } from '../../../../../core/submission/models/workspaceitem.model';
2321
import { LinkService } from '../../../../../core/cache/builders/link.service';
2422
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
@@ -37,6 +35,7 @@ import { SupervisionOrder } from '../../../../../core/supervision-order/models/s
3735
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
3836
import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service';
3937
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
38+
import { hasValue } from '../../../../../shared/empty.util';
4039

4140
@listableObjectComponent(WorkspaceItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch)
4241
@Component({
@@ -47,7 +46,7 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service
4746
/**
4847
* The component for displaying a grid element for an workflow item on the admin workflow search page
4948
*/
50-
export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkspaceItemSearchResult, WorkspaceItem> implements OnInit {
49+
export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkspaceItemSearchResult, WorkspaceItem> implements OnDestroy, OnInit {
5150

5251
/**
5352
* The item linked to the workspace item
@@ -67,7 +66,7 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
6766
/**
6867
* Directive used to render the dynamic component in
6968
*/
70-
@ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective;
69+
@ViewChild(DynamicComponentLoaderDirective, { static: true }) dynamicComponentLoaderDirective: DynamicComponentLoaderDirective;
7170

7271
/**
7372
* The html child that contains the badges html
@@ -79,9 +78,13 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
7978
*/
8079
@ViewChild('buttons', { static: true }) buttons: ElementRef;
8180

81+
/**
82+
* The reference to the dynamic component
83+
*/
84+
protected compRef: ComponentRef<Component>;
85+
8286
constructor(
8387
public dsoNameService: DSONameService,
84-
private componentFactoryResolver: ComponentFactoryResolver,
8588
private linkService: LinkService,
8689
protected truncatableService: TruncatableService,
8790
private themeService: ThemeService,
@@ -100,24 +103,24 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
100103
this.dso = this.linkService.resolveLink(this.dso, followLink('item'));
101104
this.item$ = (this.dso.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload());
102105
this.item$.pipe(take(1)).subscribe((item: Item) => {
103-
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponent(item));
106+
const component: GenericConstructor<Component> = this.getComponent(item);
104107

105-
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
108+
const viewContainerRef = this.dynamicComponentLoaderDirective.viewContainerRef;
106109
viewContainerRef.clear();
107110

108-
const componentRef = viewContainerRef.createComponent(
109-
componentFactory,
110-
0,
111-
undefined,
112-
[
111+
this.compRef = viewContainerRef.createComponent(
112+
component, {
113+
index: 0,
114+
projectableNodes: [
113115
[this.badges.nativeElement],
114116
[this.buttons.nativeElement]
115-
]);
116-
(componentRef.instance as any).object = item;
117-
(componentRef.instance as any).index = this.index;
118-
(componentRef.instance as any).linkType = this.linkType;
119-
(componentRef.instance as any).listID = this.listID;
120-
componentRef.changeDetectorRef.detectChanges();
117+
],
118+
});
119+
this.compRef.setInput('object', item);
120+
this.compRef.setInput('index', this.index);
121+
this.compRef.setInput('linkType', this.linkType);
122+
this.compRef.setInput('listID', this.listID);
123+
this.compRef.changeDetectorRef.detectChanges();
121124
}
122125
);
123126

@@ -130,6 +133,13 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
130133
});
131134
}
132135

136+
ngOnDestroy(): void {
137+
if (hasValue(this.compRef)) {
138+
this.compRef.destroy();
139+
this.compRef = undefined;
140+
}
141+
}
142+
133143
/**
134144
* Fetch the component depending on the item's entity type, view mode and context
135145
* @returns {GenericConstructor<Component>}

0 commit comments

Comments
 (0)