mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
94322: Fix theme matching using handles
This commit is contained in:
@@ -15,10 +15,11 @@ import { RESOURCE_POLICY } from '../resource-policy/models/resource-policy.resou
|
||||
import { COMMUNITY } from './community.resource-type';
|
||||
import { Community } from './community.model';
|
||||
import { ChildHALResource } from './child-hal-resource.model';
|
||||
import { HandleObject } from './handle-object.model';
|
||||
|
||||
@typedObject
|
||||
@inheritSerialization(DSpaceObject)
|
||||
export class Collection extends DSpaceObject implements ChildHALResource {
|
||||
export class Collection extends DSpaceObject implements ChildHALResource, HandleObject {
|
||||
static type = COLLECTION;
|
||||
|
||||
/**
|
||||
|
@@ -11,10 +11,11 @@ import { COMMUNITY } from './community.resource-type';
|
||||
import { DSpaceObject } from './dspace-object.model';
|
||||
import { HALLink } from './hal-link.model';
|
||||
import { ChildHALResource } from './child-hal-resource.model';
|
||||
import { HandleObject } from './handle-object.model';
|
||||
|
||||
@typedObject
|
||||
@inheritSerialization(DSpaceObject)
|
||||
export class Community extends DSpaceObject implements ChildHALResource {
|
||||
export class Community extends DSpaceObject implements ChildHALResource, HandleObject {
|
||||
static type = COMMUNITY;
|
||||
|
||||
/**
|
||||
|
8
src/app/core/shared/handle-object.model.ts
Normal file
8
src/app/core/shared/handle-object.model.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Interface representing an object in DSpace that contains a handle
|
||||
*/
|
||||
export interface HandleObject {
|
||||
|
||||
handle: string;
|
||||
|
||||
}
|
@@ -23,13 +23,14 @@ import { BITSTREAM } from './bitstream.resource-type';
|
||||
import { Bitstream } from './bitstream.model';
|
||||
import { ACCESS_STATUS } from 'src/app/shared/object-list/access-status-badge/access-status.resource-type';
|
||||
import { AccessStatusObject } from 'src/app/shared/object-list/access-status-badge/access-status.model';
|
||||
import { HandleObject } from './handle-object.model';
|
||||
|
||||
/**
|
||||
* Class representing a DSpace Item
|
||||
*/
|
||||
@typedObject
|
||||
@inheritSerialization(DSpaceObject)
|
||||
export class Item extends DSpaceObject implements ChildHALResource {
|
||||
export class Item extends DSpaceObject implements ChildHALResource, HandleObject {
|
||||
static type = ITEM;
|
||||
|
||||
/**
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { Injectable, Inject, Injector } from '@angular/core';
|
||||
import { Store, createFeatureSelector, createSelector, select } from '@ngrx/store';
|
||||
import { EMPTY, Observable, of as observableOf } from 'rxjs';
|
||||
import { ThemeState } from './theme.reducer';
|
||||
@@ -46,10 +46,11 @@ export class ThemeService {
|
||||
private store: Store<ThemeState>,
|
||||
private linkService: LinkService,
|
||||
private dSpaceObjectDataService: DSpaceObjectDataService,
|
||||
protected injector: Injector,
|
||||
@Inject(GET_THEME_CONFIG_FOR_FACTORY) private gtcf: (str) => ThemeConfig
|
||||
) {
|
||||
// Create objects from the theme configs in the environment file
|
||||
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig));
|
||||
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig, injector));
|
||||
this.hasDynamicTheme = environment.themes.some((themeConfig: any) =>
|
||||
hasValue(themeConfig.regex) ||
|
||||
hasValue(themeConfig.handle) ||
|
||||
|
@@ -8,6 +8,7 @@ import { Collection } from '../app/core/shared/collection.model';
|
||||
import { Item } from '../app/core/shared/item.model';
|
||||
import { ITEM } from '../app/core/shared/item.resource-type';
|
||||
import { getItemModuleRoute } from '../app/item-page/item-page-routing-paths';
|
||||
import { HandleService } from '../app/shared/handle.service';
|
||||
|
||||
describe('Theme Models', () => {
|
||||
let theme: Theme;
|
||||
@@ -67,24 +68,40 @@ describe('Theme Models', () => {
|
||||
});
|
||||
|
||||
describe('HandleTheme', () => {
|
||||
let handleService;
|
||||
beforeEach(() => {
|
||||
handleService = new HandleService();
|
||||
});
|
||||
it('should return true when the DSO\'s handle matches the theme\'s handle', () => {
|
||||
theme = new HandleTheme({
|
||||
name: 'matching-handle',
|
||||
handle: '1234/5678',
|
||||
});
|
||||
const dso = Object.assign(new Item(), {
|
||||
}, handleService);
|
||||
const matchingDso = Object.assign(new Item(), {
|
||||
type: ITEM.value,
|
||||
uuid: 'item-uuid',
|
||||
handle: '1234/5678',
|
||||
}, handleService);
|
||||
expect(theme.matches('', matchingDso)).toEqual(true);
|
||||
});
|
||||
it('should return false when the DSO\'s handle contains the theme\'s handle as a subpart', () => {
|
||||
theme = new HandleTheme({
|
||||
name: 'matching-handle',
|
||||
handle: '1234/5678',
|
||||
}, handleService);
|
||||
const dso = Object.assign(new Item(), {
|
||||
type: ITEM.value,
|
||||
uuid: 'item-uuid',
|
||||
handle: '1234/567891011',
|
||||
});
|
||||
expect(theme.matches('', dso)).toEqual(true);
|
||||
expect(theme.matches('', dso)).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return false when the handles don\'t match', () => {
|
||||
theme = new HandleTheme({
|
||||
name: 'no-matching-handle',
|
||||
handle: '1234/5678',
|
||||
});
|
||||
}, handleService);
|
||||
const dso = Object.assign(new Item(), {
|
||||
type: ITEM.value,
|
||||
uuid: 'item-uuid',
|
||||
|
@@ -3,6 +3,9 @@ import { Config } from './config.interface';
|
||||
import { hasValue, hasNoValue, isNotEmpty } from '../app/shared/empty.util';
|
||||
import { DSpaceObject } from '../app/core/shared/dspace-object.model';
|
||||
import { getDSORoute } from '../app/app-routing-paths';
|
||||
import { HandleObject } from '../app/core/shared/handle-object.model';
|
||||
import { Injector } from '@angular/core';
|
||||
import { HandleService } from '../app/shared/handle.service';
|
||||
|
||||
export interface NamedThemeConfig extends Config {
|
||||
name: string;
|
||||
@@ -82,12 +85,20 @@ export class RegExTheme extends Theme {
|
||||
}
|
||||
|
||||
export class HandleTheme extends Theme {
|
||||
constructor(public config: HandleThemeConfig) {
|
||||
|
||||
private normalizedHandle;
|
||||
|
||||
constructor(public config: HandleThemeConfig,
|
||||
protected handleService: HandleService
|
||||
) {
|
||||
super(config);
|
||||
this.normalizedHandle = this.handleService.normalizeHandle(this.config.handle);
|
||||
|
||||
}
|
||||
|
||||
matches(url: string, dso: any): boolean {
|
||||
return hasValue(dso) && hasValue(dso.handle) && dso.handle.includes(this.config.handle);
|
||||
matches<T extends DSpaceObject & HandleObject>(url: string, dso: T): boolean {
|
||||
return hasValue(dso) && hasValue(dso.handle)
|
||||
&& this.handleService.normalizeHandle(dso.handle) === this.normalizedHandle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,11 +112,11 @@ export class UUIDTheme extends Theme {
|
||||
}
|
||||
}
|
||||
|
||||
export const themeFactory = (config: ThemeConfig): Theme => {
|
||||
export const themeFactory = (config: ThemeConfig, injector: Injector): Theme => {
|
||||
if (hasValue((config as RegExThemeConfig).regex)) {
|
||||
return new RegExTheme(config as RegExThemeConfig);
|
||||
} else if (hasValue((config as HandleThemeConfig).handle)) {
|
||||
return new HandleTheme(config as HandleThemeConfig);
|
||||
return new HandleTheme(config as HandleThemeConfig, injector.get(HandleService));
|
||||
} else if (hasValue((config as UUIDThemeConfig).uuid)) {
|
||||
return new UUIDTheme(config as UUIDThemeConfig);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user