mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 07:23:03 +00:00
got rid of TNormalized everywhere
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
import { Operation } from 'fast-json-patch/lib/core';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
|
||||
/**
|
||||
* An interface to determine what differs between two
|
||||
* NormalizedObjects
|
||||
*/
|
||||
export interface ChangeAnalyzer<TNormalized extends NormalizedObject> {
|
||||
export interface ChangeAnalyzer<T extends CacheableObject> {
|
||||
|
||||
/**
|
||||
* Compare two objects and return their differences as a
|
||||
@@ -16,5 +17,5 @@ export interface ChangeAnalyzer<TNormalized extends NormalizedObject> {
|
||||
* @param {NormalizedObject} object2
|
||||
* The second object to compare
|
||||
*/
|
||||
diff(object1: TNormalized, object2: TNormalized): Operation[];
|
||||
diff(object1: T | NormalizedObject<T>, object2: T | NormalizedObject<T>): Operation[];
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
|
||||
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||
|
||||
@Injectable()
|
||||
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
||||
export class CollectionDataService extends ComColDataService<Collection> {
|
||||
protected linkPath = 'collections';
|
||||
|
||||
constructor(
|
||||
@@ -28,7 +28,7 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer
|
||||
protected comparator: DSOChangeAnalyzer<Collection>
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
@@ -18,14 +18,16 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { Community } from '../shared/community.model';
|
||||
|
||||
const LINK_NAME = 'test';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
class NormalizedTestObject extends NormalizedObject {
|
||||
class NormalizedTestObject extends NormalizedObject<Item> {
|
||||
}
|
||||
|
||||
class TestService extends ComColDataService<NormalizedTestObject, any> {
|
||||
class TestService extends ComColDataService<any> {
|
||||
|
||||
constructor(
|
||||
protected requestService: RequestService,
|
||||
@@ -38,7 +40,7 @@ class TestService extends ComColDataService<NormalizedTestObject, any> {
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer,
|
||||
protected comparator: DSOChangeAnalyzer<Community>,
|
||||
protected linkPath: string
|
||||
) {
|
||||
super();
|
||||
|
@@ -1,28 +1,17 @@
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
first,
|
||||
map,
|
||||
mergeMap,
|
||||
share,
|
||||
take,
|
||||
tap
|
||||
} from 'rxjs/operators';
|
||||
import { distinctUntilChanged, filter, map, mergeMap, share, take, tap } from 'rxjs/operators';
|
||||
import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { NormalizedCommunity } from '../cache/models/normalized-community.model';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { CommunityDataService } from './community-data.service';
|
||||
|
||||
import { DataService } from './data.service';
|
||||
import { FindAllOptions, FindByIDRequest } from './request.models';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { RequestEntry } from './request.reducer';
|
||||
import { getResponseFromEntry } from '../shared/operators';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
|
||||
export abstract class ComColDataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> extends DataService<TNormalized, TDomain> {
|
||||
export abstract class ComColDataService<T extends CacheableObject> extends DataService<T> {
|
||||
protected abstract cds: CommunityDataService;
|
||||
protected abstract objectCache: ObjectCacheService;
|
||||
protected abstract halService: HALEndpointService;
|
||||
|
@@ -21,7 +21,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
|
||||
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||
|
||||
@Injectable()
|
||||
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
||||
export class CommunityDataService extends ComColDataService<Community> {
|
||||
protected linkPath = 'communities';
|
||||
protected topLinkPath = 'communities/search/top';
|
||||
protected cds = this;
|
||||
@@ -35,7 +35,7 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer
|
||||
protected comparator: DSOChangeAnalyzer<Community>
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -54,6 +54,6 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
|
||||
this.requestService.configure(request);
|
||||
});
|
||||
|
||||
return this.rdbService.buildList<NormalizedCommunity, Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
|
||||
return this.rdbService.buildList<Community>(hrefObs) as Observable<RemoteData<PaginatedList<Community>>>;
|
||||
}
|
||||
}
|
||||
|
@@ -16,14 +16,15 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { Item } from '../shared/item.model';
|
||||
|
||||
const endpoint = 'https://rest.api/core';
|
||||
|
||||
// tslint:disable:max-classes-per-file
|
||||
class NormalizedTestObject extends NormalizedObject {
|
||||
class NormalizedTestObject extends NormalizedObject<Item> {
|
||||
}
|
||||
|
||||
class TestService extends DataService<NormalizedTestObject, any> {
|
||||
class TestService extends DataService<any> {
|
||||
constructor(
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
|
@@ -42,7 +42,7 @@ import { RequestEntry } from './request.reducer';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { ChangeAnalyzer } from './change-analyzer';
|
||||
|
||||
export abstract class DataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> {
|
||||
export abstract class DataService<T extends CacheableObject> {
|
||||
protected abstract requestService: RequestService;
|
||||
protected abstract rdbService: RemoteDataBuildService;
|
||||
protected abstract dataBuildService: NormalizedObjectBuildService;
|
||||
@@ -52,7 +52,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
protected abstract objectCache: ObjectCacheService;
|
||||
protected abstract notificationsService: NotificationsService;
|
||||
protected abstract http: HttpClient;
|
||||
protected abstract comparator: ChangeAnalyzer<TNormalized>;
|
||||
protected abstract comparator: ChangeAnalyzer<T>;
|
||||
|
||||
public abstract getBrowseEndpoint(options: FindAllOptions, linkPath?: string): Observable<string>
|
||||
|
||||
@@ -81,7 +81,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
}
|
||||
}
|
||||
|
||||
findAll(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<TDomain>>> {
|
||||
findAll(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<T>>> {
|
||||
const hrefObs = this.getFindAllHref(options);
|
||||
|
||||
hrefObs.pipe(
|
||||
@@ -92,7 +92,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
this.requestService.configure(request);
|
||||
});
|
||||
|
||||
return this.rdbService.buildList<TNormalized, TDomain>(hrefObs) as Observable<RemoteData<PaginatedList<TDomain>>>;
|
||||
return this.rdbService.buildList<T>(hrefObs) as Observable<RemoteData<PaginatedList<T>>>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
return `${endpoint}/${resourceID}`;
|
||||
}
|
||||
|
||||
findById(id: string): Observable<RemoteData<TDomain>> {
|
||||
findById(id: string): Observable<RemoteData<T>> {
|
||||
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
map((endpoint: string) => this.getIDHref(endpoint, id)));
|
||||
|
||||
@@ -115,12 +115,12 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
this.requestService.configure(request);
|
||||
});
|
||||
|
||||
return this.rdbService.buildSingle<TNormalized, TDomain>(hrefObs);
|
||||
return this.rdbService.buildSingle<T>(hrefObs);
|
||||
}
|
||||
|
||||
findByHref(href: string): Observable<RemoteData<TDomain>> {
|
||||
findByHref(href: string): Observable<RemoteData<T>> {
|
||||
this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href));
|
||||
return this.rdbService.buildSingle<TNormalized, TDomain>(href);
|
||||
return this.rdbService.buildSingle<T>(href);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,11 +137,10 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
* The patch is derived from the differences between the given object and its version in the object cache
|
||||
* @param {DSpaceObject} object The given object
|
||||
*/
|
||||
update(object: TDomain): Observable<RemoteData<TDomain>> {
|
||||
update(object: T): Observable<RemoteData<T>> {
|
||||
const oldVersion$ = this.objectCache.getBySelfLink(object.self);
|
||||
return oldVersion$.pipe(take(1), mergeMap((oldVersion: TNormalized) => {
|
||||
const newVersion = this.dataBuildService.normalize<TDomain, TNormalized>(object);
|
||||
const operations = this.comparator.diff(oldVersion, newVersion);
|
||||
return oldVersion$.pipe(take(1), mergeMap((oldVersion: T) => {
|
||||
const operations = this.comparator.diff(oldVersion, object);
|
||||
if (isNotEmpty(operations)) {
|
||||
this.objectCache.addPatch(object.self, operations);
|
||||
}
|
||||
@@ -160,7 +159,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
* @param {string} parentUUID
|
||||
* The UUID of the parent to create the new object under
|
||||
*/
|
||||
create(dso: TDomain, parentUUID: string): Observable<RemoteData<TDomain>> {
|
||||
create(dso: T, parentUUID: string): Observable<RemoteData<T>> {
|
||||
const requestId = this.requestService.generateRequestId();
|
||||
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
isNotEmptyOperator(),
|
||||
@@ -168,7 +167,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
map((endpoint: string) => parentUUID ? `${endpoint}?parentCommunity=${parentUUID}` : endpoint)
|
||||
);
|
||||
|
||||
const normalizedObject: TNormalized = this.dataBuildService.normalize<TDomain, TNormalized>(dso);
|
||||
const normalizedObject: NormalizedObject<T> = this.dataBuildService.normalize<T>(dso);
|
||||
const serializedDso = new DSpaceRESTv2Serializer(NormalizedObjectFactory.getConstructor(dso.type)).serialize(normalizedObject);
|
||||
|
||||
const request$ = endpoint$.pipe(
|
||||
@@ -209,7 +208,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
||||
* @param dso The DSpace Object to be removed
|
||||
* Return an observable that emits true when the deletion was successful, false when it failed
|
||||
*/
|
||||
delete(dso: TDomain): Observable<boolean> {
|
||||
delete(dso: T): Observable<boolean> {
|
||||
const requestId = this.requestService.generateRequestId();
|
||||
|
||||
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
|
||||
|
@@ -3,13 +3,14 @@ import { compare } from 'fast-json-patch';
|
||||
import { ChangeAnalyzer } from './change-analyzer';
|
||||
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
|
||||
/**
|
||||
* A class to determine what differs between two
|
||||
* DSpaceObjects
|
||||
*/
|
||||
@Injectable()
|
||||
export class DSOChangeAnalyzer implements ChangeAnalyzer<NormalizedDSpaceObject> {
|
||||
export class DSOChangeAnalyzer<T extends DSpaceObject> implements ChangeAnalyzer<T> {
|
||||
|
||||
/**
|
||||
* Compare the metadata of two DSpaceObjects and return the differences as
|
||||
@@ -20,7 +21,7 @@ export class DSOChangeAnalyzer implements ChangeAnalyzer<NormalizedDSpaceObject>
|
||||
* @param {NormalizedDSpaceObject} object2
|
||||
* The second object to compare
|
||||
*/
|
||||
diff(object1: NormalizedDSpaceObject, object2: NormalizedDSpaceObject): Operation[] {
|
||||
diff(object1: T | NormalizedDSpaceObject<T>, object2: T | NormalizedDSpaceObject<T>): Operation[] {
|
||||
return compare(object1.metadata, object2.metadata).map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path }));
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ import { RestRequest } from './request.models';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
import { BaseResponseParsingService } from './base-response-parsing.service';
|
||||
import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
|
||||
@Injectable()
|
||||
export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||
@@ -28,7 +29,7 @@ export class DSOResponseParsingService extends BaseResponseParsingService implem
|
||||
}
|
||||
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
const processRequestDTO = this.process<NormalizedObject, ResourceType>(data.payload, request.uuid);
|
||||
const processRequestDTO = this.process<NormalizedObject<DSpaceObject>, ResourceType>(data.payload, request.uuid);
|
||||
let objectList = processRequestDTO;
|
||||
|
||||
if (hasNoValue(processRequestDTO)) {
|
||||
|
@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
@@ -17,7 +16,7 @@ import { NormalizedObjectBuildService } from '../cache/builders/normalized-objec
|
||||
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> {
|
||||
class DataServiceImpl extends DataService<DSpaceObject> {
|
||||
protected linkPath = 'dso';
|
||||
|
||||
constructor(
|
||||
@@ -29,7 +28,7 @@ class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject>
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer) {
|
||||
protected comparator: DSOChangeAnalyzer<DSpaceObject>) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -55,7 +54,7 @@ export class DSpaceObjectDataService {
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer) {
|
||||
protected comparator: DSOChangeAnalyzer<DSpaceObject>) {
|
||||
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,10 @@
|
||||
|
||||
import {distinctUntilChanged, map, filter} from 'rxjs/operators';
|
||||
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { BrowseService } from '../browse/browse.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { NormalizedItem } from '../cache/models/normalized-item.model';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
@@ -24,7 +22,7 @@ import { configureRequest, getRequestFromRequestHref } from '../shared/operators
|
||||
import { RequestEntry } from './request.reducer';
|
||||
|
||||
@Injectable()
|
||||
export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||
export class ItemDataService extends DataService<Item> {
|
||||
protected linkPath = 'items';
|
||||
|
||||
constructor(
|
||||
@@ -37,7 +35,7 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||
protected halService: HALEndpointService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected http: HttpClient,
|
||||
protected comparator: DSOChangeAnalyzer) {
|
||||
protected comparator: DSOChangeAnalyzer<Item>) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@@ -8,17 +8,16 @@ import { CoreState } from '../core.reducers';
|
||||
import { DataService } from './data.service';
|
||||
import { RequestService } from './request.service';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { FindAllOptions, GetRequest, RestRequest } from './request.models';
|
||||
import { FindAllOptions } from './request.models';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { MetadataSchema } from '../metadata/metadataschema.model';
|
||||
import { NormalizedMetadataSchema } from '../metadata/normalized-metadata-schema.model';
|
||||
import { ChangeAnalyzer } from './change-analyzer';
|
||||
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
|
||||
@Injectable()
|
||||
export class MetadataSchemaDataService extends DataService<NormalizedMetadataSchema, MetadataSchema> {
|
||||
export class MetadataSchemaDataService extends DataService<MetadataSchema> {
|
||||
protected linkPath = 'metadataschemas';
|
||||
|
||||
constructor(
|
||||
@@ -28,7 +27,7 @@ export class MetadataSchemaDataService extends DataService<NormalizedMetadataSch
|
||||
private bs: BrowseService,
|
||||
protected halService: HALEndpointService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
protected comparator: ChangeAnalyzer<NormalizedMetadataSchema>,
|
||||
protected comparator: ChangeAnalyzer<MetadataSchema>,
|
||||
protected dataBuildService: NormalizedObjectBuildService,
|
||||
protected http: HttpClient,
|
||||
protected notificationsService: NotificationsService) {
|
||||
@@ -45,5 +44,4 @@ export class MetadataSchemaDataService extends DataService<NormalizedMetadataSch
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -8,68 +8,92 @@ export const ObjectUpdatesActionTypes = {
|
||||
DISCARD: type('dspace/core/object-updates/DISCARD'),
|
||||
REINSTATE: type('dspace/core/object-updates/REINSTATE'),
|
||||
REMOVE: type('dspace/core/object-updates/REMOVE'),
|
||||
REMOVE_SINGLE: type('dspace/core/object-updates/REMOVE_SINGLE')
|
||||
REMOVE_SINGLE: type('dspace/core/object-updates/REMOVE_SINGLE'),
|
||||
REPLACE: type('dspace/core/object-updates/REPLACE')
|
||||
};
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
export class AddToObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.ADD;
|
||||
|
||||
export class ReplaceObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.REPLACE;
|
||||
payload: {
|
||||
url: string,
|
||||
operation: Operation,
|
||||
fieldID: string
|
||||
operations: Operation[],
|
||||
lastModified: number
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string,
|
||||
operation: Operation,
|
||||
fieldID: string
|
||||
operations: Operation[],
|
||||
lastModified: number
|
||||
) {
|
||||
this.payload = { url, operation, fieldID };
|
||||
this.payload = { url, operations, lastModified };
|
||||
}
|
||||
}
|
||||
|
||||
export class AddToObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.ADD;
|
||||
payload: {
|
||||
url: string,
|
||||
operation: Operation
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string,
|
||||
operation: Operation) {
|
||||
this.payload = { url, operation };
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplyObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.APPLY;
|
||||
payload: string;
|
||||
payload: {
|
||||
url: string
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string
|
||||
) {
|
||||
this.payload = url;
|
||||
this.payload.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
export class DiscardObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.DISCARD;
|
||||
payload: string;
|
||||
payload: {
|
||||
url: string
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string
|
||||
) {
|
||||
this.payload = url;
|
||||
this.payload.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
export class ReinstateObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.REINSTATE;
|
||||
payload: string;
|
||||
payload: {
|
||||
url: string
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string
|
||||
) {
|
||||
this.payload = url;
|
||||
this.payload.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
export class RemoveObjectUpdatesAction implements Action {
|
||||
type = ObjectUpdatesActionTypes.REMOVE;
|
||||
payload: string;
|
||||
payload: {
|
||||
url: string
|
||||
};
|
||||
|
||||
constructor(
|
||||
url: string
|
||||
) {
|
||||
this.payload = url;
|
||||
this.payload.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +111,7 @@ export class RemoveSingleObjectUpdateAction implements Action {
|
||||
this.payload = { url, fieldID };
|
||||
}
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
@@ -98,4 +123,5 @@ export type ObjectUpdatesAction
|
||||
| DiscardObjectUpdatesAction
|
||||
| ReinstateObjectUpdatesAction
|
||||
| RemoveObjectUpdatesAction
|
||||
| RemoveSingleObjectUpdateAction;
|
||||
| RemoveSingleObjectUpdateAction
|
||||
| ReplaceObjectUpdatesAction;
|
||||
|
@@ -6,17 +6,13 @@ import {
|
||||
ObjectUpdatesActionTypes,
|
||||
ReinstateObjectUpdatesAction,
|
||||
RemoveObjectUpdatesAction,
|
||||
RemoveSingleObjectUpdateAction
|
||||
RemoveSingleObjectUpdateAction, ReplaceObjectUpdatesAction
|
||||
} from './object-updates.actions';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
|
||||
export interface ObjectUpdates {
|
||||
[id: string]: Operation[]
|
||||
}
|
||||
|
||||
export interface ObjectUpdatesEntry {
|
||||
updates: ObjectUpdates;
|
||||
updates: Operation[];
|
||||
lastServerUpdate: number;
|
||||
lastModified: number;
|
||||
discarded: boolean;
|
||||
@@ -30,70 +26,96 @@ export interface ObjectUpdatesState {
|
||||
const initialState = Object.create(null);
|
||||
|
||||
export function objectUpdatesReducer(state = initialState, action: ObjectUpdatesAction): ObjectUpdatesState {
|
||||
let newState = state;
|
||||
switch (action.type) {
|
||||
case ObjectUpdatesActionTypes.REPLACE: {
|
||||
newState = replaceObjectUpdates(state, action as ReplaceObjectUpdatesAction);
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.ADD: {
|
||||
return addToObjectUpdates(state, action as AddToObjectUpdatesAction);
|
||||
newState = addToObjectUpdates(state, action as AddToObjectUpdatesAction);
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.APPLY: {
|
||||
/* For now do nothing, handle in effect */
|
||||
// return applyObjectUpdates(state, action as ApplyObjectUpdatesAction);
|
||||
return state;
|
||||
newState = state;
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.DISCARD: {
|
||||
return discardObjectUpdates(state, action as DiscardObjectUpdatesAction);
|
||||
newState = discardObjectUpdates(state, action as DiscardObjectUpdatesAction);
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.REINSTATE: {
|
||||
return reinstateObjectUpdates(state, action as ReinstateObjectUpdatesAction);
|
||||
newState = reinstateObjectUpdates(state, action as ReinstateObjectUpdatesAction);
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.REMOVE: {
|
||||
return removeObjectUpdates(state, action as RemoveObjectUpdatesAction);
|
||||
newState = removeObjectUpdates(state, action as RemoveObjectUpdatesAction);
|
||||
break;
|
||||
}
|
||||
case ObjectUpdatesActionTypes.REMOVE_SINGLE: {
|
||||
return removeSingleObjectUpdates(state, action as RemoveSingleObjectUpdateAction);
|
||||
newState = removeSingleObjectUpdates(state, action as RemoveSingleObjectUpdateAction);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return setLastModified(newState, action.payload.url);
|
||||
}
|
||||
|
||||
function replaceObjectUpdates(state: any, action: ReplaceObjectUpdatesAction) {
|
||||
const key: string = action.payload.url;
|
||||
const operations: Operation[] = action.payload.operations;
|
||||
const newUpdateEntry = Object.assign({}, state[key] || {}, { updates: operations });
|
||||
return Object.assign({}, state, { [key]: newUpdateEntry });
|
||||
}
|
||||
|
||||
function addToObjectUpdates(state: any, action: AddToObjectUpdatesAction) {
|
||||
const key: string = action.payload.url;
|
||||
const operation: Operation = action.payload.operation;
|
||||
const keyState = state[key] || {
|
||||
updates: {},
|
||||
lastServerUpdate: 0,
|
||||
lastModified: new Date(),
|
||||
discarded: false
|
||||
};
|
||||
const objectUpdates: Operation[] = keyState.updates[action.payload.fieldID] || [];
|
||||
const newUpdates = [...objectUpdates, action.payload.operation];
|
||||
const newKeyState = Object.assign(state[key], { updates: newUpdates });
|
||||
return Object.assign(state, newKeyState);
|
||||
const objectUpdates: Operation[] = keyState.updates || [];
|
||||
const newUpdates = [...objectUpdates, operation];
|
||||
const newKeyState = Object.assign({}, state[key], { updates: newUpdates });
|
||||
return Object.assign({}, state, newKeyState);
|
||||
}
|
||||
|
||||
function discardObjectUpdates(state: any, action: DiscardObjectUpdatesAction) {
|
||||
const key: string = action.payload;
|
||||
const key: string = action.payload.url;
|
||||
const keyState = state[key];
|
||||
if (hasValue(keyState)) {
|
||||
const newKeyState = Object.assign(keyState, { discarded: true });
|
||||
return Object.assign(state, newKeyState);
|
||||
const newKeyState = Object.assign({}, keyState, { discarded: true });
|
||||
return Object.assign({}, state, newKeyState);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function reinstateObjectUpdates(state: any, action: ReinstateObjectUpdatesAction) {
|
||||
const key: string = action.payload;
|
||||
const key: string = action.payload.url;
|
||||
const keyState = state[key];
|
||||
if (hasValue(keyState)) {
|
||||
const newKeyState = Object.assign(keyState, { discarded: false });
|
||||
return Object.assign(state, newKeyState);
|
||||
const newKeyState = Object.assign({}, keyState, { discarded: false });
|
||||
return Object.assign({}, state, newKeyState);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function removeObjectUpdates(state: any, action: RemoveObjectUpdatesAction) {
|
||||
const key: string = action.payload;
|
||||
const keyState = state[key];
|
||||
const newState = Object.assign(state);
|
||||
const key: string = action.payload.url;
|
||||
return removeObjectUpdatesByURL(state, key);
|
||||
}
|
||||
|
||||
function removeObjectUpdatesByURL(state: any, url: string) {
|
||||
const keyState = state[url];
|
||||
const newState = Object.assign({}, state);
|
||||
if (hasValue(keyState)) {
|
||||
delete newState[key];
|
||||
delete newState[url];
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
@@ -102,11 +124,16 @@ function removeSingleObjectUpdates(state: any, action: RemoveSingleObjectUpdateA
|
||||
const key: string = action.payload.url;
|
||||
let newKeyState = state[key];
|
||||
if (hasValue(newKeyState)) {
|
||||
const newUpdates: Operation[] = Object.assign(newKeyState.updates);
|
||||
const newUpdates: Operation[] = Object.assign({}, newKeyState.updates);
|
||||
if (hasValue(newUpdates[action.payload.fieldID])) {
|
||||
delete newUpdates[action.payload.fieldID];
|
||||
}
|
||||
newKeyState = Object.assign(state[key], { updates: newUpdates });
|
||||
newKeyState = Object.assign({}, state[key], { updates: newUpdates });
|
||||
}
|
||||
return Object.assign(state, newKeyState);
|
||||
return Object.assign({}, state, newKeyState);
|
||||
}
|
||||
|
||||
function setLastModified(state: any, url: string) {
|
||||
const newKeyState = Object.assign({}, state[url] || {}, { lastModified: Date.now() });
|
||||
return Object.assign({}, state, newKeyState);
|
||||
}
|
||||
|
Reference in New Issue
Block a user