mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-15 22:13:02 +00:00
Merge remote-tracking branch 'upstream/main' into fix-ngonchanges-not-working-for-themed-components_contribute-main
# Conflicts: # src/app/shared/object-list/metadata-representation-list-element/metadata-representation-list-element.component.ts # src/app/shared/object-list/metadata-representation-list-element/plain-text/plain-text-metadata-list-element.component.html # src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.ts # src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.ts # src/app/shared/shared.module.ts # src/app/shared/theme-support/themed.component.ts # src/themes/custom/lazy-theme.module.ts
This commit is contained in:
@@ -8,13 +8,16 @@ import {
|
||||
OnDestroy,
|
||||
ComponentFactoryResolver,
|
||||
ChangeDetectorRef,
|
||||
OnChanges
|
||||
OnChanges,
|
||||
HostBinding,
|
||||
ElementRef,
|
||||
} from '@angular/core';
|
||||
import { hasNoValue, hasValue, isNotEmpty } from '../empty.util';
|
||||
import { combineLatest, from as fromPromise, Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import { combineLatest, from as fromPromise, Observable, of as observableOf, Subscription, BehaviorSubject } from 'rxjs';
|
||||
import { ThemeService } from './theme.service';
|
||||
import { catchError, switchMap, map } from 'rxjs/operators';
|
||||
import { catchError, switchMap, map, tap } from 'rxjs/operators';
|
||||
import { GenericConstructor } from '../../core/shared/generic-constructor';
|
||||
import { BASE_THEME_NAME } from './theme.constants';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-themed',
|
||||
@@ -23,18 +26,30 @@ import { GenericConstructor } from '../../core/shared/generic-constructor';
|
||||
})
|
||||
export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges {
|
||||
@ViewChild('vcr', { read: ViewContainerRef }) vcr: ViewContainerRef;
|
||||
@ViewChild('content') themedElementContent: ElementRef;
|
||||
protected compRef: ComponentRef<T>;
|
||||
|
||||
/**
|
||||
* A reference to the themed component. Will start as undefined and emit every time the themed
|
||||
* component is rendered
|
||||
*/
|
||||
public compRef$: BehaviorSubject<ComponentRef<T>> = new BehaviorSubject(undefined);
|
||||
|
||||
protected lazyLoadObs: Observable<any>;
|
||||
protected lazyLoadSub: Subscription;
|
||||
protected themeSub: Subscription;
|
||||
|
||||
protected inAndOutputNames: (keyof T & keyof this)[] = [];
|
||||
|
||||
/**
|
||||
* A data attribute on the ThemedComponent to indicate which theme the rendered component came from.
|
||||
*/
|
||||
@HostBinding('attr.data-used-theme') usedTheme: string;
|
||||
|
||||
constructor(
|
||||
protected resolver: ComponentFactoryResolver,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
protected themeService: ThemeService
|
||||
protected themeService: ThemeService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -94,6 +109,7 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
|
||||
} 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()];
|
||||
})
|
||||
@@ -105,13 +121,15 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
|
||||
|
||||
this.lazyLoadSub = this.lazyLoadObs.subscribe(([simpleChanges, constructor]: [SimpleChanges, GenericConstructor<T>]) => {
|
||||
const factory = this.resolver.resolveComponentFactory(constructor);
|
||||
this.compRef = this.vcr.createComponent(factory);
|
||||
this.compRef = this.vcr.createComponent(factory, undefined, undefined, [this.themedElementContent.nativeElement.childNodes]);
|
||||
if (hasValue(simpleChanges)) {
|
||||
this.ngOnChanges(simpleChanges);
|
||||
} else {
|
||||
this.connectInputsAndOutputs();
|
||||
}
|
||||
this.compRef$.next(this.compRef);
|
||||
this.cdr.markForCheck();
|
||||
this.themedElementContent.nativeElement.remove();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,7 +145,7 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
|
||||
|
||||
protected connectInputsAndOutputs(): void {
|
||||
if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
|
||||
this.inAndOutputNames.forEach((name: any) => {
|
||||
this.inAndOutputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => {
|
||||
this.compRef.instance[name] = this[name];
|
||||
});
|
||||
}
|
||||
@@ -144,6 +162,7 @@ export abstract class ThemedComponent<T> implements OnInit, OnDestroy, OnChanges
|
||||
private resolveThemedComponent(themeName?: string, checkedThemeNames: string[] = []): Observable<any> {
|
||||
if (isNotEmpty(themeName)) {
|
||||
return fromPromise(this.importThemedComponent(themeName)).pipe(
|
||||
tap(() => this.usedTheme = themeName),
|
||||
catchError(() => {
|
||||
// Try the next ancestor theme instead
|
||||
const nextTheme = this.themeService.getThemeConfigFor(themeName)?.extends;
|
||||
|
Reference in New Issue
Block a user