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