move tagstore to ngrx

This commit is contained in:
Art Lowel
2021-07-01 11:36:12 +02:00
parent 03e2e30510
commit c86f163cb7
4 changed files with 100 additions and 28 deletions

View File

@@ -13,6 +13,7 @@ import {
BitstreamFormatRegistryState BitstreamFormatRegistryState
} from '../+admin/admin-registries/bitstream-formats/bitstream-format.reducers'; } from '../+admin/admin-registries/bitstream-formats/bitstream-format.reducers';
import { historyReducer, HistoryState } from './history/history.reducer'; import { historyReducer, HistoryState } from './history/history.reducer';
import { metaTagReducer, MetaTagState } from './metadata/meta-tag.reducer';
export interface CoreState { export interface CoreState {
'bitstreamFormats': BitstreamFormatRegistryState; 'bitstreamFormats': BitstreamFormatRegistryState;
@@ -24,6 +25,7 @@ export interface CoreState {
'index': MetaIndexState; 'index': MetaIndexState;
'auth': AuthState; 'auth': AuthState;
'json/patch': JsonPatchOperationsState; 'json/patch': JsonPatchOperationsState;
'metaTag': MetaTagState;
'route': RouteState; 'route': RouteState;
} }
@@ -37,5 +39,6 @@ export const coreReducers: ActionReducerMap<CoreState> = {
'index': indexReducer, 'index': indexReducer,
'auth': authReducer, 'auth': authReducer,
'json/patch': jsonPatchOperationsReducer, 'json/patch': jsonPatchOperationsReducer,
'metaTag': metaTagReducer,
'route': routeReducer 'route': routeReducer
}; };

View File

@@ -0,0 +1,24 @@
import { type } from '../../shared/ngrx/type';
import { Action } from '@ngrx/store';
import { MetaDefinition } from '@angular/platform-browser';
// tslint:disable:max-classes-per-file
export const MetaTagTypes = {
ADD: type('dspace/meta-tag/ADD'),
CLEAR: type('dspace/meta-tag/CLEAR')
};
export class AddMetaTagAction implements Action {
type = MetaTagTypes.ADD;
payload: string;
constructor(property: string) {
this.payload = property;
}
}
export class ClearMetaTagAction implements Action {
type = MetaTagTypes.CLEAR;
}
export type MetaTagAction = AddMetaTagAction | ClearMetaTagAction;

View File

@@ -0,0 +1,38 @@
import {
MetaTagAction,
MetaTagTypes,
AddMetaTagAction,
ClearMetaTagAction,
} from './meta-tag.actions';
export interface MetaTagState {
tagsInUse: string[];
}
const initialstate: MetaTagState = {
tagsInUse: []
};
export const metaTagReducer = (state: MetaTagState = initialstate, action: MetaTagAction): MetaTagState => {
switch (action.type) {
case MetaTagTypes.ADD: {
return addMetaTag(state, action as AddMetaTagAction);
}
case MetaTagTypes.CLEAR: {
return clearMetaTags(state, action as ClearMetaTagAction);
}
default: {
return state;
}
}
};
const addMetaTag = (state: MetaTagState, action: AddMetaTagAction): MetaTagState => {
return {
tagsInUse: [...state.tagsInUse, action.payload]
};
};
const clearMetaTags = (state: MetaTagState, action: ClearMetaTagAction): MetaTagState => {
return Object.assign({}, initialstate);
};

View File

@@ -30,12 +30,33 @@ import { Bundle } from '../shared/bundle.model';
import { PaginatedList } from '../data/paginated-list.model'; import { PaginatedList } from '../data/paginated-list.model';
import { URLCombiner } from '../url-combiner/url-combiner'; import { URLCombiner } from '../url-combiner/url-combiner';
import { HardRedirectService } from '../services/hard-redirect.service'; import { HardRedirectService } from '../services/hard-redirect.service';
import { MetaTagState } from './meta-tag.reducer';
import { Store, createSelector, select, MemoizedSelector } from '@ngrx/store';
import { AddMetaTagAction, ClearMetaTagAction } from './meta-tag.actions';
import { coreSelector } from '../core.selectors';
import { CoreState } from '../core.reducers';
import { ObjectCacheEntry, ObjectCacheState } from '../cache/object-cache.reducer';
/**
* The base selector function to select the metaTag section in the store
*/
const metaTagSelector = createSelector(
coreSelector,
(state: CoreState) => state.metaTag
);
/**
* Selector function to select the tags in use from the MetaTagState
*/
const tagsInUseSelector =
createSelector(
metaTagSelector,
(state: MetaTagState) => state.tagsInUse,
);
@Injectable() @Injectable()
export class MetadataService { export class MetadataService {
private tagStore: Map<string, MetaDefinition[]>;
private currentObject: BehaviorSubject<DSpaceObject> = new BehaviorSubject<DSpaceObject>(undefined); private currentObject: BehaviorSubject<DSpaceObject> = new BehaviorSubject<DSpaceObject>(undefined);
/** /**
@@ -63,11 +84,9 @@ export class MetadataService {
private bitstreamDataService: BitstreamDataService, private bitstreamDataService: BitstreamDataService,
private bitstreamFormatDataService: BitstreamFormatDataService, private bitstreamFormatDataService: BitstreamFormatDataService,
private rootService: RootDataService, private rootService: RootDataService,
private store: Store<MetaTagState>,
private hardRedirectService: HardRedirectService, private hardRedirectService: HardRedirectService,
) { ) {
// TODO: determine what open graph meta tags are needed and whether
// the differ per route. potentially add image based on DSpaceObject
this.tagStore = new Map<string, MetaDefinition[]>();
} }
public listenForRouteChange(): void { public listenForRouteChange(): void {
@@ -442,7 +461,7 @@ export class MetadataService {
if (content) { if (content) {
const tag = { property, content } as MetaDefinition; const tag = { property, content } as MetaDefinition;
this.meta.addTag(tag); this.meta.addTag(tag);
this.storeTag(property, tag); this.storeTag(property);
} }
} }
@@ -452,33 +471,21 @@ export class MetadataService {
} }
} }
private storeTag(key: string, tag: MetaDefinition): void { private storeTag(key: string): void {
const tags: MetaDefinition[] = this.getTags(key); this.store.dispatch(new AddMetaTagAction(key));
tags.push(tag);
this.setTags(key, tags);
}
private getTags(key: string): MetaDefinition[] {
let tags: MetaDefinition[] = this.tagStore.get(key);
if (tags === undefined) {
tags = [];
}
return tags;
}
private setTags(key: string, tags: MetaDefinition[]): void {
this.tagStore.set(key, tags);
} }
public clearMetaTags() { public clearMetaTags() {
this.tagStore.forEach((tags: MetaDefinition[], property: string) => { this.store.pipe(
select(tagsInUseSelector),
take(1)
).subscribe((tagsInUse: string[]) => {
for (const property of tagsInUse) {
this.meta.removeTag('property=\'' + property + '\''); this.meta.removeTag('property=\'' + property + '\'');
}
this.store.dispatch(new ClearMetaTagAction());
}); });
this.tagStore.clear();
} }
public getTagStore(): Map<string, MetaDefinition[]> {
return this.tagStore;
}
} }