Merge branch 'w2p-89676_feature-selective-export_contribute-7.2' into w2p-91272_Add-themed-components-to-upstream-branch

This commit is contained in:
Alexandre Vryghem
2022-05-15 19:14:27 +02:00
10 changed files with 124 additions and 14 deletions

View File

@@ -1,6 +1,10 @@
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';
export enum BrowseByDataType {
Title = 'title',
@@ -10,7 +14,7 @@ export enum BrowseByDataType {
export const DEFAULT_BROWSE_BY_TYPE = BrowseByDataType.Metadata;
export const BROWSE_BY_COMPONENT_FACTORY = new InjectionToken<(browseByType) => GenericConstructor<any>>('getComponentByBrowseByType', {
export const BROWSE_BY_COMPONENT_FACTORY = new InjectionToken<(browseByType, theme) => GenericConstructor<any>>('getComponentByBrowseByType', {
providedIn: 'root',
factory: () => getComponentByBrowseByType
});
@@ -20,13 +24,17 @@ const map = 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: BrowseByDataType) {
export function rendersBrowseBy(browseByType: BrowseByDataType, theme = DEFAULT_THEME) {
return function decorator(component: any) {
if (hasNoValue(map.get(browseByType))) {
map.set(browseByType, component);
map.set(browseByType, new Map());
}
if (hasNoValue(map.get(browseByType).get(theme))) {
map.get(browseByType).set(theme, component);
} else {
throw new Error(`There can't be more than one component to render Browse-By of type "${browseByType}"`);
throw new Error(`There can't be more than one component to render Browse-By of type "${browseByType}" and theme "${theme}"`);
}
};
}
@@ -34,11 +42,16 @@ export function rendersBrowseBy(browseByType: BrowseByDataType) {
/**
* Get the component used for rendering a Browse-By page by type
* @param browseByType The type of page
* @param theme the theme to match
*/
export function getComponentByBrowseByType(browseByType) {
const comp = map.get(browseByType);
export function getComponentByBrowseByType(browseByType, theme) {
let themeMap = map.get(browseByType);
if (hasNoValue(themeMap)) {
themeMap = map.get(DEFAULT_BROWSE_BY_TYPE);
}
const comp = resolveTheme(themeMap, theme);
if (hasNoValue(comp)) {
map.get(DEFAULT_BROWSE_BY_TYPE);
return themeMap.get(DEFAULT_THEME);
}
return comp;
}

View File

@@ -4,7 +4,8 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { BROWSE_BY_COMPONENT_FACTORY, BrowseByDataType } from './browse-by-decorator';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { BehaviorSubject, of as observableOf } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { ThemeService } from '../../shared/theme-support/theme.service';
describe('BrowseBySwitcherComponent', () => {
let comp: BrowseBySwitcherComponent;
@@ -44,11 +45,20 @@ describe('BrowseBySwitcherComponent', () => {
data
};
let themeService: ThemeService;
let themeName: string;
beforeEach(waitForAsync(() => {
themeName = 'dspace';
themeService = jasmine.createSpyObj('themeService', {
getThemeName: themeName,
});
TestBed.configureTestingModule({
declarations: [BrowseBySwitcherComponent],
providers: [
{ provide: ActivatedRoute, useValue: activatedRouteStub },
{ provide: ThemeService, useValue: themeService },
{ provide: BROWSE_BY_COMPONENT_FACTORY, useValue: jasmine.createSpy('getComponentByBrowseByType').and.returnValue(null) }
],
schemas: [NO_ERRORS_SCHEMA]
@@ -68,7 +78,7 @@ describe('BrowseBySwitcherComponent', () => {
});
it(`should call getComponentByBrowseByType with type "${type.dataType}"`, () => {
expect((comp as any).getComponentByBrowseByType).toHaveBeenCalledWith(type.dataType);
expect((comp as any).getComponentByBrowseByType).toHaveBeenCalledWith(type.dataType, themeName);
});
});
});

View File

@@ -5,6 +5,7 @@ import { map } from 'rxjs/operators';
import { BROWSE_BY_COMPONENT_FACTORY } from './browse-by-decorator';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { BrowseDefinition } from '../../core/shared/browse-definition.model';
import { ThemeService } from '../../shared/theme-support/theme.service';
@Component({
selector: 'ds-browse-by-switcher',
@@ -21,7 +22,8 @@ export class BrowseBySwitcherComponent implements OnInit {
browseByComponent: Observable<any>;
public constructor(protected route: ActivatedRoute,
@Inject(BROWSE_BY_COMPONENT_FACTORY) private getComponentByBrowseByType: (browseByType) => GenericConstructor<any>) {
protected themeService: ThemeService,
@Inject(BROWSE_BY_COMPONENT_FACTORY) private getComponentByBrowseByType: (browseByType, theme) => GenericConstructor<any>) {
}
/**
@@ -29,7 +31,7 @@ export class BrowseBySwitcherComponent implements OnInit {
*/
ngOnInit(): void {
this.browseByComponent = this.route.data.pipe(
map((data: { browseDefinition: BrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.dataType))
map((data: { browseDefinition: BrowseDefinition }) => this.getComponentByBrowseByType(data.browseDefinition.dataType, this.themeService.getThemeName()))
);
}

View File

@@ -0,0 +1,64 @@
import { ThemedComponent } from '../../theme-support/themed.component';
import { SearchResultsComponent, SelectionConfig } from './search-results.component';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { CollectionElementLinkType } from '../../object-collection/collection-element-link.type';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list.model';
import { SearchResult } from '../models/search-result.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { PaginatedSearchOptions } from '../models/paginated-search-options.model';
import { SortOptions } from '../../../core/cache/models/sort-options.model';
import { ViewMode } from '../../../core/shared/view-mode.model';
import { Context } from '../../../core/shared/context.model';
import { ListableObject } from '../../object-collection/shared/listable-object.model';
/**
* Themed wrapper for SearchResultsComponent
*/
@Component({
selector: 'ds-themed-search-results',
styleUrls: [],
templateUrl: '../../theme-support/themed.component.html',
})
export class ThemedSearchResultsComponent extends ThemedComponent<SearchResultsComponent> {
protected inAndOutputNames: (keyof SearchResultsComponent & keyof this)[] = ['linkType', 'searchResults', 'searchConfig', 'sortConfig', 'viewMode', 'configuration', 'disableHeader', 'selectable', 'context', 'hidePaginationDetail', 'selectionConfig', 'deselectObject', 'selectObject'];
@Input() linkType: CollectionElementLinkType;
@Input() searchResults: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>;
@Input() searchConfig: PaginatedSearchOptions;
@Input() sortConfig: SortOptions;
@Input() viewMode: ViewMode;
@Input() configuration: string;
@Input() disableHeader = false;
@Input() selectable = false;
@Input() context: Context;
@Input() hidePaginationDetail = false;
@Input() selectionConfig: SelectionConfig = null;
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
@Output() selectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
protected getComponentName(): string {
return 'SearchResultsComponent';
}
protected importThemedComponent(themeName: string): Promise<any> {
return import(`../../../../themes/${themeName}/app/shared/search/search-results/search-results.component`);
}
protected importUnthemedComponent(): Promise<any> {
return import('./search-results.component');
}
}

View File

@@ -29,7 +29,7 @@
| translate}}
</button>
</div>
<ds-search-results [searchResults]="resultsRD$ | async"
<ds-themed-search-results [searchResults]="resultsRD$ | async"
[searchConfig]="searchOptions$ | async"
[configuration]="(currentConfiguration$ | async)"
[disableHeader]="!searchEnabled"
@@ -38,7 +38,7 @@
[selectable]="selectable"
[selectionConfig]="selectionConfig"
(deselectObject)="deselectObject.emit($event)"
(selectObject)="selectObject.emit($event)"></ds-search-results>
(selectObject)="selectObject.emit($event)"></ds-themed-search-results>
</div>
</div>
</ng-template>

View File

@@ -29,6 +29,7 @@ import { SharedModule } from '../shared.module';
import { SearchResultsComponent } from './search-results/search-results.component';
import { SearchComponent } from './search.component';
import { ThemedSearchComponent } from './themed-search.component';
import { ThemedSearchResultsComponent } from './search-results/themed-search-results.component';
const COMPONENTS = [
SearchComponent,
@@ -52,7 +53,8 @@ const COMPONENTS = [
SearchAuthorityFilterComponent,
SearchSwitchConfigurationComponent,
ConfigurationSearchPageComponent,
ThemedConfigurationSearchPageComponent
ThemedConfigurationSearchPageComponent,
ThemedSearchResultsComponent,
];
const ENTRY_COMPONENTS = [

View File

@@ -0,0 +1,17 @@
import { SearchResultsComponent as BaseComponent } from '../../../../../../app/shared/search/search-results/search-results.component';
import { Component } from '@angular/core';
import { fadeIn, fadeInOut } from '../../../../../../app/shared/animations/fade';
@Component({
selector: 'ds-search-results',
// templateUrl: './search-results.component.html',
templateUrl: '../../../../../../app/shared/search/search-results/search-results.component.html',
// styleUrls: ['./search-results.component.scss'],
animations: [
fadeIn,
fadeInOut
]
})
export class SearchResultsComponent extends BaseComponent {
}

View File

@@ -94,6 +94,7 @@ import {
EditItemTemplatePageComponent
} from './app/collection-page/edit-item-template-page/edit-item-template-page.component';
import { LoadingComponent } from './app/shared/loading/loading.component';
import { SearchResultsComponent } from './app/shared/search/search-results/search-results.component';
const DECLARATIONS = [
FileSectionComponent,
@@ -143,6 +144,7 @@ const DECLARATIONS = [
ItemMetadataComponent,
EditItemTemplatePageComponent,
LoadingComponent,
SearchResultsComponent,
];
@NgModule({