mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Added item services.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { EffectsModule } from "@ngrx/effects";
|
||||
import { CollectionDataEffects } from "./data-services/collection/collection-data.effects";
|
||||
import { ItemDataEffects } from "./data-services/item/item-data.effects";
|
||||
|
||||
export const coreEffects = [
|
||||
EffectsModule.run(CollectionDataEffects)
|
||||
EffectsModule.run(CollectionDataEffects),
|
||||
EffectsModule.run(ItemDataEffects)
|
||||
];
|
||||
|
@@ -5,6 +5,7 @@ import { isNotEmpty } from "../shared/empty.util";
|
||||
import { DSpaceRESTv2Service } from "./dspace-rest-v2/dspace-rest-v2.service";
|
||||
import { CollectionDataService } from "./data-services/collection/collection-data.service";
|
||||
import { CacheService } from "./data-services/cache/cache.service";
|
||||
import { ItemDataService } from "./data-services/item/item-data.service";
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
@@ -19,6 +20,7 @@ const EXPORTS = [
|
||||
|
||||
const PROVIDERS = [
|
||||
CollectionDataService,
|
||||
ItemDataService,
|
||||
DSpaceRESTv2Service,
|
||||
CacheService
|
||||
];
|
||||
|
@@ -4,14 +4,17 @@ import {
|
||||
collectionDataReducer
|
||||
} from "./data-services/collection/collection-data.reducer";
|
||||
import { CacheState, cacheReducer } from "./data-services/cache/cache.reducer";
|
||||
import { ItemDataState, itemDataReducer } from "./data-services/item/item-data.reducer";
|
||||
|
||||
export interface CoreState {
|
||||
collectionData: CollectionDataState,
|
||||
itemData: ItemDataState,
|
||||
cache: CacheState
|
||||
}
|
||||
|
||||
export const reducers = {
|
||||
collectionData: collectionDataReducer,
|
||||
itemData: itemDataReducer,
|
||||
cache: cacheReducer
|
||||
};
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Actions, Effect, toPayload } from "@ngrx/effects";
|
||||
import { Actions, Effect } from "@ngrx/effects";
|
||||
import { Collection } from "../../shared/collection.model";
|
||||
import { Observable } from "rxjs";
|
||||
import {
|
||||
|
@@ -15,8 +15,8 @@ export class CollectionDataService {
|
||||
private cache: CacheService
|
||||
) { }
|
||||
|
||||
findAll(scope?: Collection): Observable<Collection[]> {
|
||||
this.store.dispatch(new CollectionFindMultipleRequestAction(scope));
|
||||
findAll(scopeID?: string): Observable<Collection[]> {
|
||||
this.store.dispatch(new CollectionFindMultipleRequestAction(scopeID));
|
||||
//get an observable of the IDs from the collectionData store
|
||||
return this.store.select<Array<string>>('core', 'collectionData', 'findMultiple', 'collectionsIDs')
|
||||
.flatMap((collectionIds: Array<string>) => {
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Action } from "@ngrx/store";
|
||||
import { type } from "../../../shared/ngrx/type";
|
||||
import { Collection } from "../../shared/collection.model";
|
||||
import { PaginationOptions } from "../../shared/pagination-options.model";
|
||||
import { SortOptions } from "../../shared/sort-options.model";
|
||||
|
||||
@@ -13,18 +12,18 @@ export const CollectionFindMultipleActionTypes = {
|
||||
export class CollectionFindMultipleRequestAction implements Action {
|
||||
type = CollectionFindMultipleActionTypes.FIND_MULTI_REQUEST;
|
||||
payload: {
|
||||
scope: Collection,
|
||||
scopeID: string,
|
||||
paginationOptions: PaginationOptions,
|
||||
sortOptions: SortOptions
|
||||
};
|
||||
|
||||
constructor(
|
||||
scope?: Collection,
|
||||
scopeID?: string,
|
||||
paginationOptions: PaginationOptions = new PaginationOptions(),
|
||||
sortOptions: SortOptions = new SortOptions()
|
||||
) {
|
||||
this.payload = {
|
||||
scope,
|
||||
scopeID,
|
||||
paginationOptions,
|
||||
sortOptions
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { Collection } from "../../shared/collection.model";
|
||||
import { PaginationOptions } from "../../shared/pagination-options.model";
|
||||
import { SortOptions } from "../../shared/sort-options.model";
|
||||
import {
|
||||
@@ -7,7 +6,7 @@ import {
|
||||
} from "./collection-find-multiple.actions";
|
||||
|
||||
export interface CollectionFindMultipleState {
|
||||
scope: Collection;
|
||||
scopeID: string;
|
||||
collectionsIDs: Array<String>;
|
||||
isLoading: boolean;
|
||||
errorMessage: string;
|
||||
@@ -16,7 +15,7 @@ export interface CollectionFindMultipleState {
|
||||
}
|
||||
|
||||
const initialState: CollectionFindMultipleState = {
|
||||
scope: undefined,
|
||||
scopeID: undefined,
|
||||
collectionsIDs: [],
|
||||
isLoading: false,
|
||||
errorMessage: undefined,
|
||||
@@ -29,7 +28,7 @@ export const findMultipleReducer = (state = initialState, action: CollectionFind
|
||||
|
||||
case CollectionFindMultipleActionTypes.FIND_MULTI_REQUEST: {
|
||||
return Object.assign({}, state, {
|
||||
scope: action.payload.scope,
|
||||
scopeID: action.payload.scopeID,
|
||||
collectionsIDs: [],
|
||||
isLoading: true,
|
||||
errorMessage: undefined,
|
||||
|
66
src/app/core/data-services/item/item-data.effects.ts
Normal file
66
src/app/core/data-services/item/item-data.effects.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Actions, Effect } from "@ngrx/effects";
|
||||
import { Item } from "../../shared/item.model";
|
||||
import { Observable } from "rxjs";
|
||||
import {
|
||||
ItemFindMultipleActionTypes,
|
||||
ItemFindMultipleSuccessAction,
|
||||
ItemFindMultipleErrorAction
|
||||
} from "./item-find-multiple.actions";
|
||||
import {
|
||||
ItemFindSingleActionTypes,
|
||||
ItemFindByIdSuccessAction,
|
||||
ItemFindByIdErrorAction
|
||||
} from "./item-find-single.actions";
|
||||
import { DSpaceRESTV2Response } from "../../dspace-rest-v2/dspace-rest-v2-response.model";
|
||||
import { DSpaceRESTv2Serializer } from "../../dspace-rest-v2/dspace-rest-v2.serializer";
|
||||
import { DSpaceRESTv2Service } from "../../dspace-rest-v2/dspace-rest-v2.service";
|
||||
import { CacheService } from "../cache/cache.service";
|
||||
import { GlobalConfig } from "../../../../config";
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataEffects {
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private restApi: DSpaceRESTv2Service,
|
||||
private cache: CacheService
|
||||
) {}
|
||||
|
||||
// TODO, results of a findall aren't retrieved from cache for now,
|
||||
// because currently the cache is more of an object store. We need to move
|
||||
// more towards memoization for things like this.
|
||||
@Effect() findAll$ = this.actions$
|
||||
.ofType(ItemFindMultipleActionTypes.FIND_MULTI_REQUEST)
|
||||
.switchMap(() => {
|
||||
return this.restApi.get('/items')
|
||||
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Item).deserializeArray(data))
|
||||
.do((items: Item[]) => {
|
||||
items.forEach((item) => {
|
||||
this.cache.add(item, GlobalConfig.cache.msToLive);
|
||||
});
|
||||
})
|
||||
.map((items: Array<Item>) => items.map(item => item.id))
|
||||
.map((ids: Array<string>) => new ItemFindMultipleSuccessAction(ids))
|
||||
.catch((errorMsg: string) => Observable.of(new ItemFindMultipleErrorAction(errorMsg)));
|
||||
});
|
||||
|
||||
@Effect() findById$ = this.actions$
|
||||
.ofType(ItemFindSingleActionTypes.FIND_BY_ID_REQUEST)
|
||||
.switchMap(action => {
|
||||
if (this.cache.has(action.payload)) {
|
||||
return this.cache.get<Item>(action.payload)
|
||||
.map(item => new ItemFindByIdSuccessAction(item.id));
|
||||
}
|
||||
else {
|
||||
return this.restApi.get(`/items/${action.payload}`)
|
||||
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Item).deserialize(data))
|
||||
.do((item: Item) => {
|
||||
this.cache.add(item, GlobalConfig.cache.msToLive);
|
||||
})
|
||||
.map((item: Item) => new ItemFindByIdSuccessAction(item.id))
|
||||
.catch((errorMsg: string) => Observable.of(new ItemFindByIdErrorAction(errorMsg)));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
17
src/app/core/data-services/item/item-data.reducer.ts
Normal file
17
src/app/core/data-services/item/item-data.reducer.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { combineReducers } from "@ngrx/store";
|
||||
import { ItemFindMultipleState, findMultipleReducer } from "./item-find-multiple.reducer";
|
||||
import { ItemFindSingleState, findSingleReducer } from "./item-find-single.reducer";
|
||||
|
||||
export interface ItemDataState {
|
||||
findMultiple: ItemFindMultipleState,
|
||||
findSingle: ItemFindSingleState
|
||||
}
|
||||
|
||||
const reducers = {
|
||||
findMultiple: findMultipleReducer,
|
||||
findSingle: findSingleReducer
|
||||
};
|
||||
|
||||
export function itemDataReducer(state: any, action: any) {
|
||||
return combineReducers(reducers)(state, action);
|
||||
}
|
33
src/app/core/data-services/item/item-data.service.ts
Normal file
33
src/app/core/data-services/item/item-data.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { ItemDataState } from "./item-data.reducer";
|
||||
import { Store } from "@ngrx/store";
|
||||
import { Item } from "../../shared/item.model";
|
||||
import { ItemFindMultipleRequestAction } from "./item-find-multiple.actions";
|
||||
import { ItemFindByIdRequestAction } from "./item-find-single.actions";
|
||||
import { CacheService } from "../cache/cache.service";
|
||||
import 'rxjs/add/observable/forkJoin';
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataService {
|
||||
constructor(
|
||||
private store: Store<ItemDataState>,
|
||||
private cache: CacheService
|
||||
) { }
|
||||
|
||||
findAll(scopeID?: string): Observable<Item[]> {
|
||||
this.store.dispatch(new ItemFindMultipleRequestAction(scopeID));
|
||||
//get an observable of the IDs from the itemData store
|
||||
return this.store.select<Array<string>>('core', 'itemData', 'findMultiple', 'itemsIDs')
|
||||
.flatMap((itemIds: Array<string>) => {
|
||||
// use those IDs to fetch the actual item objects from the cache
|
||||
return this.cache.getList<Item>(itemIds);
|
||||
});
|
||||
}
|
||||
|
||||
findById(id: string): Observable<Item> {
|
||||
this.store.dispatch(new ItemFindByIdRequestAction(id));
|
||||
return this.cache.get<Item>(id);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
import { Action } from "@ngrx/store";
|
||||
import { type } from "../../../shared/ngrx/type";
|
||||
import { PaginationOptions } from "../../shared/pagination-options.model";
|
||||
import { SortOptions } from "../../shared/sort-options.model";
|
||||
|
||||
export const ItemFindMultipleActionTypes = {
|
||||
FIND_MULTI_REQUEST: type('dspace/core/data/item/FIND_MULTI_REQUEST'),
|
||||
FIND_MULTI_SUCCESS: type('dspace/core/data/item/FIND_MULTI_SUCCESS'),
|
||||
FIND_MULTI_ERROR: type('dspace/core/data/item/FIND_MULTI_ERROR')
|
||||
};
|
||||
|
||||
export class ItemFindMultipleRequestAction implements Action {
|
||||
type = ItemFindMultipleActionTypes.FIND_MULTI_REQUEST;
|
||||
payload: {
|
||||
scopeID: string,
|
||||
paginationOptions: PaginationOptions,
|
||||
sortOptions: SortOptions
|
||||
};
|
||||
|
||||
constructor(
|
||||
scopeID?: string,
|
||||
paginationOptions: PaginationOptions = new PaginationOptions(),
|
||||
sortOptions: SortOptions = new SortOptions()
|
||||
) {
|
||||
this.payload = {
|
||||
scopeID,
|
||||
paginationOptions,
|
||||
sortOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ItemFindMultipleSuccessAction implements Action {
|
||||
type = ItemFindMultipleActionTypes.FIND_MULTI_SUCCESS;
|
||||
payload: Array<string>;
|
||||
|
||||
constructor(itemIDs: Array<string>) {
|
||||
this.payload = itemIDs;
|
||||
}
|
||||
}
|
||||
|
||||
export class ItemFindMultipleErrorAction implements Action {
|
||||
type = ItemFindMultipleActionTypes.FIND_MULTI_ERROR;
|
||||
payload: string;
|
||||
|
||||
constructor(errorMessage: string) {
|
||||
this.payload = errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
export type ItemFindMultipleAction
|
||||
= ItemFindMultipleRequestAction
|
||||
| ItemFindMultipleSuccessAction
|
||||
| ItemFindMultipleErrorAction;
|
@@ -0,0 +1,59 @@
|
||||
import { PaginationOptions } from "../../shared/pagination-options.model";
|
||||
import { SortOptions } from "../../shared/sort-options.model";
|
||||
import {
|
||||
ItemFindMultipleAction,
|
||||
ItemFindMultipleActionTypes
|
||||
} from "./item-find-multiple.actions";
|
||||
|
||||
export interface ItemFindMultipleState {
|
||||
scopeID: string;
|
||||
itemsIDs: Array<String>;
|
||||
isLoading: boolean;
|
||||
errorMessage: string;
|
||||
paginationOptions: PaginationOptions;
|
||||
sortOptions: SortOptions;
|
||||
}
|
||||
|
||||
const initialState: ItemFindMultipleState = {
|
||||
scopeID: undefined,
|
||||
itemsIDs: [],
|
||||
isLoading: false,
|
||||
errorMessage: undefined,
|
||||
paginationOptions: undefined,
|
||||
sortOptions: undefined
|
||||
};
|
||||
|
||||
export const findMultipleReducer = (state = initialState, action: ItemFindMultipleAction): ItemFindMultipleState => {
|
||||
switch (action.type) {
|
||||
|
||||
case ItemFindMultipleActionTypes.FIND_MULTI_REQUEST: {
|
||||
return Object.assign({}, state, {
|
||||
scopeID: action.payload.scopeID,
|
||||
itemsIDs: [],
|
||||
isLoading: true,
|
||||
errorMessage: undefined,
|
||||
paginationOptions: action.payload.paginationOptions,
|
||||
sortOptions: action.payload.sortOptions
|
||||
});
|
||||
}
|
||||
|
||||
case ItemFindMultipleActionTypes.FIND_MULTI_SUCCESS: {
|
||||
return Object.assign({}, state, {
|
||||
isLoading: false,
|
||||
itemsIDs: action.payload,
|
||||
errorMessage: undefined
|
||||
});
|
||||
}
|
||||
|
||||
case ItemFindMultipleActionTypes.FIND_MULTI_ERROR: {
|
||||
return Object.assign({}, state, {
|
||||
isLoading: false,
|
||||
errorMessage: action.payload
|
||||
});
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
};
|
42
src/app/core/data-services/item/item-find-single.actions.ts
Normal file
42
src/app/core/data-services/item/item-find-single.actions.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Action } from "@ngrx/store";
|
||||
import { type } from "../../../shared/ngrx/type";
|
||||
import { Item } from "../../shared/item.model";
|
||||
|
||||
export const ItemFindSingleActionTypes = {
|
||||
FIND_BY_ID_REQUEST: type('dspace/core/data/item/FIND_BY_ID_REQUEST'),
|
||||
FIND_BY_ID_SUCCESS: type('dspace/core/data/item/FIND_BY_ID_SUCCESS'),
|
||||
FIND_BY_ID_ERROR: type('dspace/core/data/item/FIND_BY_ID_ERROR')
|
||||
};
|
||||
|
||||
export class ItemFindByIdRequestAction implements Action {
|
||||
type = ItemFindSingleActionTypes.FIND_BY_ID_REQUEST;
|
||||
payload: string;
|
||||
|
||||
constructor(id: string) {
|
||||
this.payload = id;
|
||||
}
|
||||
}
|
||||
|
||||
export class ItemFindByIdSuccessAction implements Action {
|
||||
type = ItemFindSingleActionTypes.FIND_BY_ID_SUCCESS;
|
||||
payload: string;
|
||||
|
||||
constructor(itemID: string) {
|
||||
this.payload = itemID;
|
||||
}
|
||||
}
|
||||
|
||||
export class ItemFindByIdErrorAction implements Action {
|
||||
type = ItemFindSingleActionTypes.FIND_BY_ID_ERROR;
|
||||
payload: string;
|
||||
|
||||
constructor(errorMessage: string) {
|
||||
this.payload = errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
export type ItemFindSingleAction
|
||||
= ItemFindByIdRequestAction
|
||||
| ItemFindByIdSuccessAction
|
||||
| ItemFindByIdErrorAction;
|
||||
|
48
src/app/core/data-services/item/item-find-single.reducer.ts
Normal file
48
src/app/core/data-services/item/item-find-single.reducer.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Item } from "../../shared/item.model";
|
||||
import {
|
||||
ItemFindSingleAction,
|
||||
ItemFindSingleActionTypes
|
||||
} from "./item-find-single.actions";
|
||||
|
||||
export interface ItemFindSingleState {
|
||||
isLoading: boolean;
|
||||
errorMessage: string;
|
||||
itemID: string;
|
||||
}
|
||||
|
||||
const initialState: ItemFindSingleState = {
|
||||
isLoading: false,
|
||||
errorMessage: undefined,
|
||||
itemID: undefined
|
||||
};
|
||||
|
||||
export const findSingleReducer = (state = initialState, action: ItemFindSingleAction): ItemFindSingleState => {
|
||||
switch (action.type) {
|
||||
|
||||
case ItemFindSingleActionTypes.FIND_BY_ID_REQUEST: {
|
||||
return Object.assign({}, state, {
|
||||
isLoading: true,
|
||||
errorMessage: undefined,
|
||||
itemID: action.payload
|
||||
});
|
||||
}
|
||||
|
||||
case ItemFindSingleActionTypes.FIND_BY_ID_SUCCESS: {
|
||||
return Object.assign({}, state, {
|
||||
isLoading: false,
|
||||
errorMessage: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
case ItemFindSingleActionTypes.FIND_BY_ID_ERROR: {
|
||||
return Object.assign({}, state, {
|
||||
isLoading: false,
|
||||
errorMessage: action.payload
|
||||
});
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user