Skip to content

Commit

Permalink
TEMP: Should only be done later when DSpace#2339 is merged on main
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrevryghem committed Dec 6, 2023
1 parent 093f591 commit 0794eea
Show file tree
Hide file tree
Showing 24 changed files with 295 additions and 60 deletions.
21 changes: 21 additions & 0 deletions src/app/browse-by/abstract-browse-by-page.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component, Input } from '@angular/core';
import { BrowseByDataType } from './browse-by-switcher/browse-by-decorator';

@Component({
selector: 'ds-abstract-browse-by-page',
template: '',
})
export class AbstractBrowseByPageComponent {

/**
* The {@link BrowseByDataType} of this Component
*/
@Input() browseByType: BrowseByDataType;

/**
* Whether to show the browse by page as a standalone page or not
* This will have an effect on how the component is rendered for accessibility reasons
*/
@Input() showAsStandalonePage: boolean;

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import { Component, Input } from '@angular/core';
import { ThemedComponent } from '../../shared/theme-support/themed.component';
import { BrowseByDatePageComponent } from './browse-by-date-page.component';
import {BrowseByDataType, rendersBrowseBy} from '../browse-by-switcher/browse-by-decorator';
Expand All @@ -15,6 +15,16 @@ import {BrowseByDataType, rendersBrowseBy} from '../browse-by-switcher/browse-by
@rendersBrowseBy(BrowseByDataType.Date)
export class ThemedBrowseByDatePageComponent
extends ThemedComponent<BrowseByDatePageComponent> {

@Input() browseByType: BrowseByDataType;

@Input() showAsStandalonePage: boolean;

inAndOutputNames: (keyof BrowseByDatePageComponent & keyof this)[] = [
'browseByType',
'showAsStandalonePage',
];

protected getComponentName(): string {
return 'BrowseByDatePageComponent';
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<div class="container">
<div [class.container]="showAsStandalonePage">
<section class="comcol-page-browse-section">
<div class="browse-by-metadata w-100">
<ds-browse-by *ngIf="startsWithOptions" class="col-xs-12 w-100"
title="{{'browse.title' | translate:
<ng-container *ngVar="'browse.title' | translate:
{
collection: dsoNameService.getName((parent$ | async)?.payload),
collection: showAsStandalonePage ? dsoNameService.getName((parent$ | async)?.payload) : '',
field: 'browse.metadata.' + browseId | translate,
startsWith: (startsWith)? ('browse.startsWith' | translate: { startsWith: '&quot;' + startsWith + '&quot;' }) : '',
value: (value)? '&quot;' + value + '&quot;': ''
} }}"
parentname="{{dsoNameService.getName((parent$ | async)?.payload)}}"
} as title">
<h1 *ngIf="showAsStandalonePage" [ngClass]="{'sr-only': dsoNameService.getName((parent$ | async)?.payload) }">
{{ title }}
</h1>
<h3 *ngIf="!showAsStandalonePage" [ngClass]="{'sr-only': dsoNameService.getName((parent$ | async)?.payload) }">
{{ title }}
</h3>
</ng-container>
<ds-browse-by *ngIf="startsWithOptions" class="col-xs-12 w-100"
[objects$]="(items$ !== undefined)? items$ : browseEntries$"
[paginationConfig]="(currentPagination$ |async)"
[sortConfig]="(currentSort$ |async)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
import { Component, Inject, OnInit, OnDestroy, Input } from '@angular/core';
import { Component, Inject, OnInit, OnDestroy } from '@angular/core';
import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list.model';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
Expand All @@ -22,6 +22,7 @@ import { Collection } from '../../core/shared/collection.model';
import { Community } from '../../core/shared/community.model';
import { APP_CONFIG, AppConfig } from '../../../config/app-config.interface';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
import { AbstractBrowseByPageComponent } from '../abstract-browse-by-page.component';

export const BBM_PAGINATION_ID = 'bbm';

Expand All @@ -36,7 +37,7 @@ export const BBM_PAGINATION_ID = 'bbm';
* or multiple metadata fields. An example would be 'author' for
* 'dc.contributor.*'
*/
export class BrowseByMetadataPageComponent implements OnInit, OnDestroy {
export class BrowseByMetadataPageComponent extends AbstractBrowseByPageComponent implements OnInit, OnDestroy {

/**
* The list of browse-entries to display
Expand Down Expand Up @@ -130,7 +131,7 @@ export class BrowseByMetadataPageComponent implements OnInit, OnDestroy {
@Inject(APP_CONFIG) public appConfig: AppConfig,
public dsoNameService: DSONameService,
) {

super();
this.fetchThumbnails = this.appConfig.browseBy.showThumbnails;
this.paginationConfig = Object.assign(new PaginationComponentOptions(), {
id: BBM_PAGINATION_ID,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import { Component, Input } from '@angular/core';
import { ThemedComponent } from '../../shared/theme-support/themed.component';
import { BrowseByMetadataPageComponent } from './browse-by-metadata-page.component';
import {BrowseByDataType, rendersBrowseBy} from '../browse-by-switcher/browse-by-decorator';
Expand All @@ -15,6 +15,16 @@ import {BrowseByDataType, rendersBrowseBy} from '../browse-by-switcher/browse-by
@rendersBrowseBy(BrowseByDataType.Metadata)
export class ThemedBrowseByMetadataPageComponent
extends ThemedComponent<BrowseByMetadataPageComponent> {

@Input() browseByType: BrowseByDataType;

@Input() showAsStandalonePage: boolean;

inAndOutputNames: (keyof BrowseByMetadataPageComponent & keyof this)[] = [
'browseByType',
'showAsStandalonePage',
];

protected getComponentName(): string {
return 'BrowseByMetadataPageComponent';
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ds-themed-browse-by-switcher [browseByType]="browseByDataType$ | async"
[showAsStandalonePage]="true">
</ds-themed-browse-by-switcher>
Empty file.
24 changes: 24 additions & 0 deletions src/app/browse-by/browse-by-page/browse-by-page.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowseByPageComponent } from './browse-by-page.component';

describe('BrowseByPageComponent', () => {
let component: BrowseByPageComponent;
let fixture: ComponentFixture<BrowseByPageComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
BrowseByPageComponent,
],
})
.compileComponents();

fixture = TestBed.createComponent(BrowseByPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
27 changes: 27 additions & 0 deletions src/app/browse-by/browse-by-page/browse-by-page.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Data } from '@angular/router';
import { map } from 'rxjs/operators';
import { BrowseByDataType } from '../browse-by-switcher/browse-by-decorator';
import { Observable } from 'rxjs';

@Component({
selector: 'ds-browse-by-page',
templateUrl: './browse-by-page.component.html',
styleUrls: ['./browse-by-page.component.scss'],
})
export class BrowseByPageComponent implements OnInit {

browseByDataType$: Observable<BrowseByDataType>;

constructor(
protected route: ActivatedRoute,
) {
}

ngOnInit(): void {
this.browseByDataType$ = this.route.data.pipe(
map((data: Data) => data?.browseDefinition),
);
}

}
4 changes: 2 additions & 2 deletions src/app/browse-by/browse-by-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { NgModule } from '@angular/core';
import { BrowseByGuard } from './browse-by-guard';
import { BrowseByDSOBreadcrumbResolver } from './browse-by-dso-breadcrumb.resolver';
import { BrowseByI18nBreadcrumbResolver } from './browse-by-i18n-breadcrumb.resolver';
import { ThemedBrowseBySwitcherComponent } from './browse-by-switcher/themed-browse-by-switcher.component';
import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { BrowseByPageComponent } from './browse-by-page/browse-by-page.component';

@NgModule({
imports: [
Expand All @@ -18,7 +18,7 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
children: [
{
path: ':id',
component: ThemedBrowseBySwitcherComponent,
component: BrowseByPageComponent,
canActivate: [BrowseByGuard],
resolve: { breadcrumb: BrowseByI18nBreadcrumbResolver },
data: { title: 'browse.title.page', breadcrumbKey: 'browse.metadata' }
Expand Down
17 changes: 7 additions & 10 deletions src/app/browse-by/browse-by-switcher/browse-by-decorator.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { hasNoValue } from '../../shared/empty.util';
import { InjectionToken } from '@angular/core';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import {
DEFAULT_THEME,
resolveTheme
} from '../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { DEFAULT_THEME, resolveTheme } from '../../shared/object-collection/shared/listable-object/listable-object.decorator';
import { AbstractBrowseByPageComponent } from '../abstract-browse-by-page.component';

export enum BrowseByDataType {
Title = 'title',
Expand All @@ -15,19 +12,19 @@ export enum BrowseByDataType {

export const DEFAULT_BROWSE_BY_TYPE = BrowseByDataType.Metadata;

export const BROWSE_BY_COMPONENT_FACTORY = new InjectionToken<(browseByType, theme) => GenericConstructor<any>>('getComponentByBrowseByType', {
export const BROWSE_BY_COMPONENT_FACTORY = new InjectionToken<(browseByType: BrowseByDataType, theme: string) => AbstractBrowseByPageComponent>('getComponentByBrowseByType', {
providedIn: 'root',
factory: () => getComponentByBrowseByType
});

const map = new Map();
const map: Map<BrowseByDataType, Map<string, AbstractBrowseByPageComponent>> = new Map();

/**
* Decorator used for rendering Browse-By pages by type
* @param browseByType The type of page
* @param theme The optional theme for the component
*/
export function rendersBrowseBy(browseByType: string, theme = DEFAULT_THEME) {
export function rendersBrowseBy(browseByType: BrowseByDataType, theme = DEFAULT_THEME) {
return function decorator(component: any) {
if (hasNoValue(map.get(browseByType))) {
map.set(browseByType, new Map());
Expand All @@ -45,8 +42,8 @@ export function rendersBrowseBy(browseByType: string, theme = DEFAULT_THEME) {
* @param browseByType The type of page
* @param theme the theme to match
*/
export function getComponentByBrowseByType(browseByType, theme) {
let themeMap = map.get(browseByType);
export function getComponentByBrowseByType(browseByType: BrowseByDataType, theme: string): AbstractBrowseByPageComponent {
let themeMap: Map<string, AbstractBrowseByPageComponent> = map.get(browseByType);
if (hasNoValue(themeMap)) {
themeMap = map.get(DEFAULT_BROWSE_BY_TYPE);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<ng-container *ngComponentOutlet="browseByComponent | async"></ng-container>
<ng-template dsDynamicComponentLoader></ng-template>
Original file line number Diff line number Diff line change
@@ -1,38 +1,103 @@
import { Component, Inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BROWSE_BY_COMPONENT_FACTORY } from './browse-by-decorator';
import { Component, OnInit, Input, ComponentRef, ViewChild, SimpleChanges, ViewContainerRef, OnChanges, Inject } from '@angular/core';
import { Subscription } from 'rxjs';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { ThemeService } from '../../shared/theme-support/theme.service';
import { AbstractBrowseByPageComponent } from '../abstract-browse-by-page.component';
import { DynamicComponentLoaderDirective } from './dynamic-component-loader-directive';
import { hasValue, isNotEmpty, hasNoValue } from '../../shared/empty.util';
import { BROWSE_BY_COMPONENT_FACTORY, BrowseByDataType } from './browse-by-decorator';

@Component({
selector: 'ds-browse-by-switcher',
templateUrl: './browse-by-switcher.component.html'
})
/**
* Component for determining what Browse-By component to use depending on the metadata (browse ID) provided
*
* TODO should extend AbstractComponentLoaderComponent once PR https://github.com/DSpace/dspace-angular/pull/2339 is
* merged.
*/
export class BrowseBySwitcherComponent implements OnInit {
export class BrowseBySwitcherComponent implements OnInit, OnChanges {

@Input() browseByType: BrowseByDataType;

@Input() showAsStandalonePage = true;

/**
* Directive to determine where the dynamic child component is located
*/
@ViewChild(DynamicComponentLoaderDirective, { static: true }) componentDirective: DynamicComponentLoaderDirective;

/**
* Resolved browse-by component
* The reference to the dynamic component
*/
browseByComponent: Observable<any>;
protected compRef: ComponentRef<AbstractBrowseByPageComponent>;

public constructor(protected route: ActivatedRoute,
protected themeService: ThemeService,
@Inject(BROWSE_BY_COMPONENT_FACTORY) private getComponentByBrowseByType: (browseByType, theme) => GenericConstructor<any>) {
subs: Subscription[] = [];

inputNames: (keyof this)[] = [
'browseByType',
'showAsStandalonePage',
];

public constructor(
protected themeService: ThemeService,
@Inject(BROWSE_BY_COMPONENT_FACTORY) private getComponentByBrowseByType: (browseByType: string, theme: string) => GenericConstructor<AbstractBrowseByPageComponent>,
) {
}

/**
* Fetch the correct browse-by component by using the relevant config from the route data
*/
ngOnInit(): void {
this.browseByComponent = this.route.data.pipe(
map((data: { browseDefinition: BrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.getRenderType(), this.themeService.getThemeName()))
this.instantiateComponent();
}

ngOnChanges(changes: SimpleChanges): void {
if (hasNoValue(this.compRef)) {
// sometimes the component has not been initialized yet, so it first needs to be initialized
// before being called again
this.instantiateComponent(changes);
} else {
// if an input or output has changed
if (this.inputNames.some((name: any) => hasValue(changes[name]))) {
this.connectInputs();
}
}
}

public instantiateComponent(changes?: SimpleChanges): void {
const component: GenericConstructor<AbstractBrowseByPageComponent> = this.getComponent();

const viewContainerRef: ViewContainerRef = this.componentDirective.viewContainerRef;
viewContainerRef.clear();

this.compRef = viewContainerRef.createComponent(
component, {
index: 0,
injector: undefined,
},
);

if (hasValue(changes)) {
this.ngOnChanges(changes);
} else {
this.connectInputs();
}
}

public getComponent(): GenericConstructor<AbstractBrowseByPageComponent> {
return this.getComponentByBrowseByType(this.browseByType, this.themeService.getThemeName());
}


protected connectInputs(): void {
if (isNotEmpty(this.inputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
this.inputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => {
this.compRef.setInput(name, this[name]);
});
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Directive, ViewContainerRef } from '@angular/core';

/**
* Directive used as a hook to know where to inject the dynamic loaded component
* TODO should be removed once https://github.com/DSpace/dspace-angular/pull/2339 is merged
*/
@Directive({
selector: '[dsDynamicComponentLoader]'
})
export class DynamicComponentLoaderDirective {

constructor(
public viewContainerRef: ViewContainerRef,
) {
}

}
Loading

0 comments on commit 0794eea

Please sign in to comment.