mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
add docs, rename classes for clarity
This commit is contained in:
@@ -3,24 +3,38 @@ import { NormalizedObject } from '../models/normalized-object.model';
|
|||||||
import { CacheableObject } from '../object-cache.reducer';
|
import { CacheableObject } from '../object-cache.reducer';
|
||||||
import { getRelationships } from './build-decorators';
|
import { getRelationships } from './build-decorators';
|
||||||
import { NormalizedObjectFactory } from '../models/normalized-object-factory';
|
import { NormalizedObjectFactory } from '../models/normalized-object-factory';
|
||||||
import { map, take } from 'rxjs/operators';
|
|
||||||
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||||
import { PaginatedList } from '../../data/paginated-list';
|
|
||||||
|
|
||||||
export function isRestDataObject(halObj: any) {
|
/**
|
||||||
|
* Return true if halObj has a value for `_links.self`
|
||||||
|
*
|
||||||
|
* @param {any} halObj The object to test
|
||||||
|
*/
|
||||||
|
export function isRestDataObject(halObj: any): boolean {
|
||||||
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
|
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRestPaginatedList(halObj: any) {
|
/**
|
||||||
|
* Return true if halObj has a value for `page` and `_embedded`
|
||||||
|
*
|
||||||
|
* @param {any} halObj The object to test
|
||||||
|
*/
|
||||||
|
export function isRestPaginatedList(halObj: any): boolean {
|
||||||
return hasValue(halObj.page) && hasValue(halObj._embedded);
|
return hasValue(halObj.page) && hasValue(halObj._embedded);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPaginatedList(halObj: any) {
|
/**
|
||||||
return hasValue(halObj.page) && hasValue(halObj.pageInfo);
|
* A service to turn domain models in to their normalized
|
||||||
}
|
* counterparts.
|
||||||
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataBuildService {
|
export class NormalizedObjectBuildService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the normalized model that corresponds to the given domain model
|
||||||
|
*
|
||||||
|
* @param {TDomain} domainModel a domain model
|
||||||
|
*/
|
||||||
normalize<TDomain extends CacheableObject, TNormalized extends NormalizedObject>(domainModel: TDomain): TNormalized {
|
normalize<TDomain extends CacheableObject, TNormalized extends NormalizedObject>(domainModel: TDomain): TNormalized {
|
||||||
const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type);
|
const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type);
|
||||||
const relationships = getRelationships(normalizedConstructor) || [];
|
const relationships = getRelationships(normalizedConstructor) || [];
|
10
src/app/core/cache/object-cache.reducer.ts
vendored
10
src/app/core/cache/object-cache.reducer.ts
vendored
@@ -17,8 +17,18 @@ export enum DirtyType {
|
|||||||
Deleted = 'Deleted'
|
Deleted = 'Deleted'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to represent a JsonPatch
|
||||||
|
*/
|
||||||
export interface Patch {
|
export interface Patch {
|
||||||
|
/**
|
||||||
|
* The identifier for this Patch
|
||||||
|
*/
|
||||||
uuid?: string;
|
uuid?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the list of operations this Patch is composed of
|
||||||
|
*/
|
||||||
operations: Operation[];
|
operations: Operation[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -65,8 +65,8 @@ import { BrowseItemsResponseParsingService } from './data/browse-items-response-
|
|||||||
import { DSpaceObjectDataService } from './data/dspace-object-data.service';
|
import { DSpaceObjectDataService } from './data/dspace-object-data.service';
|
||||||
import { CSSVariableService } from '../shared/sass-helper/sass-helper.service';
|
import { CSSVariableService } from '../shared/sass-helper/sass-helper.service';
|
||||||
import { MenuService } from '../shared/menu/menu.service';
|
import { MenuService } from '../shared/menu/menu.service';
|
||||||
import { DataBuildService } from './cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from './cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './data/dso-update-comparator';
|
import { DSOChangeAnalyzer } from './data/dso-change-analyzer.service';
|
||||||
|
|
||||||
const IMPORTS = [
|
const IMPORTS = [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -103,7 +103,7 @@ const PROVIDERS = [
|
|||||||
ObjectCacheService,
|
ObjectCacheService,
|
||||||
PaginationComponentOptions,
|
PaginationComponentOptions,
|
||||||
RegistryService,
|
RegistryService,
|
||||||
DataBuildService,
|
NormalizedObjectBuildService,
|
||||||
RemoteDataBuildService,
|
RemoteDataBuildService,
|
||||||
RequestService,
|
RequestService,
|
||||||
EndpointMapResponseParsingService,
|
EndpointMapResponseParsingService,
|
||||||
@@ -131,7 +131,7 @@ const PROVIDERS = [
|
|||||||
UploaderService,
|
UploaderService,
|
||||||
UUIDService,
|
UUIDService,
|
||||||
DSpaceObjectDataService,
|
DSpaceObjectDataService,
|
||||||
DSOUpdateComparator,
|
DSOChangeAnalyzer,
|
||||||
CSSVariableService,
|
CSSVariableService,
|
||||||
MenuService,
|
MenuService,
|
||||||
// register AuthInterceptor as HttpInterceptor
|
// register AuthInterceptor as HttpInterceptor
|
||||||
|
@@ -8,7 +8,7 @@ import { GenericConstructor } from '../shared/generic-constructor';
|
|||||||
import { PaginatedList } from './paginated-list';
|
import { PaginatedList } from './paginated-list';
|
||||||
import { ResourceType } from '../shared/resource-type';
|
import { ResourceType } from '../shared/resource-type';
|
||||||
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';
|
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';
|
||||||
import { isRestDataObject, isRestPaginatedList } from '../cache/builders/data-build.service';
|
import { isRestDataObject, isRestPaginatedList } from '../cache/builders/normalized-object-build.service';
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
|
|
||||||
export abstract class BaseResponseParsingService {
|
export abstract class BaseResponseParsingService {
|
||||||
|
20
src/app/core/data/change-analyzer.ts
Normal file
20
src/app/core/data/change-analyzer.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||||
|
import { Operation } from 'fast-json-patch/lib/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface to determine what differs between two
|
||||||
|
* NormalizedObjects
|
||||||
|
*/
|
||||||
|
export interface ChangeAnalyzer<TNormalized extends NormalizedObject> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two objects and return their differences as a
|
||||||
|
* JsonPatch Operation Array
|
||||||
|
*
|
||||||
|
* @param {NormalizedObject} object1
|
||||||
|
* The first object to compare
|
||||||
|
* @param {NormalizedObject} object2
|
||||||
|
* The second object to compare
|
||||||
|
*/
|
||||||
|
diff(object1: TNormalized, object2: TNormalized): Operation[];
|
||||||
|
}
|
@@ -11,8 +11,8 @@ import { RequestService } from './request.service';
|
|||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './dso-update-comparator';
|
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
export class CollectionDataService extends ComColDataService<NormalizedCollection, Collection> {
|
||||||
@@ -21,14 +21,14 @@ export class CollectionDataService extends ComColDataService<NormalizedCollectio
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected cds: CommunityDataService,
|
protected cds: CommunityDataService,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator
|
protected comparator: DSOChangeAnalyzer
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@@ -16,8 +16,8 @@ import { RequestEntry } from './request.reducer';
|
|||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './dso-update-comparator';
|
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||||
|
|
||||||
const LINK_NAME = 'test';
|
const LINK_NAME = 'test';
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ class TestService extends ComColDataService<NormalizedTestObject, any> {
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected EnvConfig: GlobalConfig,
|
protected EnvConfig: GlobalConfig,
|
||||||
protected cds: CommunityDataService,
|
protected cds: CommunityDataService,
|
||||||
@@ -38,7 +38,7 @@ class TestService extends ComColDataService<NormalizedTestObject, any> {
|
|||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator,
|
protected comparator: DSOChangeAnalyzer,
|
||||||
protected linkPath: string
|
protected linkPath: string
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
@@ -61,7 +61,7 @@ describe('ComColDataService', () => {
|
|||||||
const notificationsService = {} as NotificationsService;
|
const notificationsService = {} as NotificationsService;
|
||||||
const http = {} as HttpClient;
|
const http = {} as HttpClient;
|
||||||
const comparator = {} as any;
|
const comparator = {} as any;
|
||||||
const dataBuildService = {} as DataBuildService;
|
const dataBuildService = {} as NormalizedObjectBuildService;
|
||||||
|
|
||||||
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
||||||
const options = Object.assign(new FindAllOptions(), {
|
const options = Object.assign(new FindAllOptions(), {
|
||||||
|
@@ -17,8 +17,8 @@ import { Observable } from 'rxjs';
|
|||||||
import { PaginatedList } from './paginated-list';
|
import { PaginatedList } from './paginated-list';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './dso-update-comparator';
|
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
export class CommunityDataService extends ComColDataService<NormalizedCommunity, Community> {
|
||||||
@@ -29,13 +29,13 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator
|
protected comparator: DSOChangeAnalyzer
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,9 @@ import { SortDirection, SortOptions } from '../cache/models/sort-options.model';
|
|||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { Operation } from '../../../../node_modules/fast-json-patch';
|
import { Operation } from '../../../../node_modules/fast-json-patch';
|
||||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||||
import { UpdateComparator } from './update-comparator';
|
import { ChangeAnalyzer } from './change-analyzer';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
|
|
||||||
@@ -27,14 +27,14 @@ class TestService extends DataService<NormalizedTestObject, any> {
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected linkPath: string,
|
protected linkPath: string,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: UpdateComparator<NormalizedTestObject>
|
protected comparator: ChangeAnalyzer<NormalizedTestObject>
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -44,8 +44,8 @@ class TestService extends DataService<NormalizedTestObject, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DummyComparator implements UpdateComparator<NormalizedTestObject> {
|
class DummyChangeAnalyzer implements ChangeAnalyzer<NormalizedTestObject> {
|
||||||
compare(object1: NormalizedTestObject, object2: NormalizedTestObject): Operation[] {
|
diff(object1: NormalizedTestObject, object2: NormalizedTestObject): Operation[] {
|
||||||
return compare((object1 as any).metadata, (object2 as any).metadata);
|
return compare((object1 as any).metadata, (object2 as any).metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,10 +58,10 @@ describe('DataService', () => {
|
|||||||
const rdbService = {} as RemoteDataBuildService;
|
const rdbService = {} as RemoteDataBuildService;
|
||||||
const notificationsService = {} as NotificationsService;
|
const notificationsService = {} as NotificationsService;
|
||||||
const http = {} as HttpClient;
|
const http = {} as HttpClient;
|
||||||
const comparator = new DummyComparator() as any;
|
const comparator = new DummyChangeAnalyzer() as any;
|
||||||
const dataBuildService = {
|
const dataBuildService = {
|
||||||
normalize: (object) => object
|
normalize: (object) => object
|
||||||
} as DataBuildService;
|
} as NormalizedObjectBuildService;
|
||||||
const objectCache = {
|
const objectCache = {
|
||||||
addPatch: () => {
|
addPatch: () => {
|
||||||
/* empty */
|
/* empty */
|
||||||
|
@@ -41,20 +41,20 @@ import { NotificationOptions } from '../../shared/notifications/models/notificat
|
|||||||
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
|
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
|
||||||
import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory';
|
import { NormalizedObjectFactory } from '../cache/models/normalized-object-factory';
|
||||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { UpdateComparator } from './update-comparator';
|
import { ChangeAnalyzer } from './change-analyzer';
|
||||||
|
|
||||||
export abstract class DataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> {
|
export abstract class DataService<TNormalized extends NormalizedObject, TDomain extends CacheableObject> {
|
||||||
protected abstract requestService: RequestService;
|
protected abstract requestService: RequestService;
|
||||||
protected abstract rdbService: RemoteDataBuildService;
|
protected abstract rdbService: RemoteDataBuildService;
|
||||||
protected abstract dataBuildService: DataBuildService;
|
protected abstract dataBuildService: NormalizedObjectBuildService;
|
||||||
protected abstract store: Store<CoreState>;
|
protected abstract store: Store<CoreState>;
|
||||||
protected abstract linkPath: string;
|
protected abstract linkPath: string;
|
||||||
protected abstract halService: HALEndpointService;
|
protected abstract halService: HALEndpointService;
|
||||||
protected abstract objectCache: ObjectCacheService;
|
protected abstract objectCache: ObjectCacheService;
|
||||||
protected abstract notificationsService: NotificationsService;
|
protected abstract notificationsService: NotificationsService;
|
||||||
protected abstract http: HttpClient;
|
protected abstract http: HttpClient;
|
||||||
protected abstract comparator: UpdateComparator<TNormalized>;
|
protected abstract comparator: ChangeAnalyzer<TNormalized>;
|
||||||
|
|
||||||
public abstract getBrowseEndpoint(options: FindAllOptions, linkPath?: string): Observable<string>
|
public abstract getBrowseEndpoint(options: FindAllOptions, linkPath?: string): Observable<string>
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
|||||||
const oldVersion$ = this.objectCache.getBySelfLink(object.self);
|
const oldVersion$ = this.objectCache.getBySelfLink(object.self);
|
||||||
return oldVersion$.pipe(first(), mergeMap((oldVersion: TNormalized) => {
|
return oldVersion$.pipe(first(), mergeMap((oldVersion: TNormalized) => {
|
||||||
const newVersion = this.dataBuildService.normalize<TDomain, TNormalized>(object);
|
const newVersion = this.dataBuildService.normalize<TDomain, TNormalized>(object);
|
||||||
const operations = this.comparator.compare(oldVersion, newVersion);
|
const operations = this.comparator.diff(oldVersion, newVersion);
|
||||||
if (isNotEmpty(operations)) {
|
if (isNotEmpty(operations)) {
|
||||||
this.objectCache.addPatch(object.self, operations);
|
this.objectCache.addPatch(object.self, operations);
|
||||||
}
|
}
|
||||||
@@ -148,6 +148,15 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new DSpaceObject on the server, and store the response
|
||||||
|
* in the object cache
|
||||||
|
*
|
||||||
|
* @param {DSpaceObject} dso
|
||||||
|
* The object to create
|
||||||
|
* @param {string} parentUUID
|
||||||
|
* The UUID of the parent to create the new object under
|
||||||
|
*/
|
||||||
create(dso: TDomain, parentUUID: string): Observable<RemoteData<TDomain>> {
|
create(dso: TDomain, parentUUID: string): Observable<RemoteData<TDomain>> {
|
||||||
const requestId = this.requestService.generateRequestId();
|
const requestId = this.requestService.generateRequestId();
|
||||||
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
|
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
|
||||||
|
26
src/app/core/data/dso-change-analyzer.service.ts
Normal file
26
src/app/core/data/dso-change-analyzer.service.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Operation } from 'fast-json-patch/lib/core';
|
||||||
|
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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to determine what differs between two
|
||||||
|
* DSpaceObjects
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class DSOChangeAnalyzer implements ChangeAnalyzer<NormalizedDSpaceObject> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the metadata of two DSpaceObjects and return the differences as
|
||||||
|
* a JsonPatch Operation Array
|
||||||
|
*
|
||||||
|
* @param {NormalizedDSpaceObject} object1
|
||||||
|
* The first object to compare
|
||||||
|
* @param {NormalizedDSpaceObject} object2
|
||||||
|
* The second object to compare
|
||||||
|
*/
|
||||||
|
diff(object1: NormalizedDSpaceObject, object2: NormalizedDSpaceObject): Operation[] {
|
||||||
|
return compare(object1.metadata, object2.metadata).map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path }));
|
||||||
|
}
|
||||||
|
}
|
@@ -1,12 +0,0 @@
|
|||||||
import { Operation } from 'fast-json-patch/lib/core';
|
|
||||||
import { compare } from 'fast-json-patch';
|
|
||||||
import { UpdateComparator } from './update-comparator';
|
|
||||||
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class DSOUpdateComparator implements UpdateComparator<NormalizedDSpaceObject> {
|
|
||||||
compare(object1: NormalizedDSpaceObject, object2: NormalizedDSpaceObject): Operation[] {
|
|
||||||
return compare(object1.metadata, object2.metadata).map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path }));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,7 +9,7 @@ import { DSpaceObjectDataService } from './dspace-object-data.service';
|
|||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
|
|
||||||
describe('DSpaceObjectDataService', () => {
|
describe('DSpaceObjectDataService', () => {
|
||||||
let scheduler: TestScheduler;
|
let scheduler: TestScheduler;
|
||||||
@@ -46,7 +46,7 @@ describe('DSpaceObjectDataService', () => {
|
|||||||
const notificationsService = {} as NotificationsService;
|
const notificationsService = {} as NotificationsService;
|
||||||
const http = {} as HttpClient;
|
const http = {} as HttpClient;
|
||||||
const comparator = {} as any;
|
const comparator = {} as any;
|
||||||
const dataBuildService = {} as DataBuildService;
|
const dataBuildService = {} as NormalizedObjectBuildService;
|
||||||
|
|
||||||
service = new DSpaceObjectDataService(
|
service = new DSpaceObjectDataService(
|
||||||
requestService,
|
requestService,
|
||||||
|
@@ -13,8 +13,8 @@ import { FindAllOptions } from './request.models';
|
|||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './dso-update-comparator';
|
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> {
|
class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> {
|
||||||
@@ -23,13 +23,13 @@ class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject>
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator) {
|
protected comparator: DSOChangeAnalyzer) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +50,12 @@ export class DSpaceObjectDataService {
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator) {
|
protected comparator: DSOChangeAnalyzer) {
|
||||||
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
|
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@ import { ObjectCacheService } from '../cache/object-cache.service';
|
|||||||
import { FindAllOptions } from './request.models';
|
import { FindAllOptions } from './request.models';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
|
|
||||||
describe('ItemDataService', () => {
|
describe('ItemDataService', () => {
|
||||||
let scheduler: TestScheduler;
|
let scheduler: TestScheduler;
|
||||||
@@ -40,7 +40,7 @@ describe('ItemDataService', () => {
|
|||||||
const notificationsService = {} as NotificationsService;
|
const notificationsService = {} as NotificationsService;
|
||||||
const http = {} as HttpClient;
|
const http = {} as HttpClient;
|
||||||
const comparator = {} as any;
|
const comparator = {} as any;
|
||||||
const dataBuildService = {} as DataBuildService;
|
const dataBuildService = {} as NormalizedObjectBuildService;
|
||||||
|
|
||||||
function initMockBrowseService(isSuccessful: boolean) {
|
function initMockBrowseService(isSuccessful: boolean) {
|
||||||
const obs = isSuccessful ?
|
const obs = isSuccessful ?
|
||||||
|
@@ -18,8 +18,8 @@ import { FindAllOptions } from './request.models';
|
|||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from './dso-update-comparator';
|
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ItemDataService extends DataService<NormalizedItem, Item> {
|
export class ItemDataService extends DataService<NormalizedItem, Item> {
|
||||||
@@ -28,14 +28,14 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
|
|||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected dataBuildService: DataBuildService,
|
protected dataBuildService: NormalizedObjectBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
private bs: BrowseService,
|
private bs: BrowseService,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DSOUpdateComparator) {
|
protected comparator: DSOChangeAnalyzer) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -86,7 +86,17 @@ function completeRequest(state: RequestState, action: RequestCompleteAction): Re
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetResponseTimestamps(state: RequestState, action: ResetResponseTimestampsAction) {
|
/**
|
||||||
|
* Reset the timeAdded property of all responses
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* the current state
|
||||||
|
* @param action
|
||||||
|
* a RequestCompleteAction
|
||||||
|
* @return RequestState
|
||||||
|
* the new state, with the timeAdded property reset
|
||||||
|
*/
|
||||||
|
function resetResponseTimestamps(state: RequestState, action: ResetResponseTimestampsAction): RequestState {
|
||||||
const newState = Object.create(null);
|
const newState = Object.create(null);
|
||||||
Object.keys(state).forEach((key) => {
|
Object.keys(state).forEach((key) => {
|
||||||
newState[key] = Object.assign({}, state[key],
|
newState[key] = Object.assign({}, state[key],
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
|
||||||
import { Operation } from 'fast-json-patch/lib/core';
|
|
||||||
|
|
||||||
export interface UpdateComparator<TNormalized extends NormalizedObject> {
|
|
||||||
compare(object1: TNormalized, object2: TNormalized): Operation[];
|
|
||||||
}
|
|
@@ -79,6 +79,14 @@ export class DSpaceRESTv2Service {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a FormData object from a DSpaceObject
|
||||||
|
*
|
||||||
|
* @param {DSpaceObject} dso
|
||||||
|
* the DSpaceObject
|
||||||
|
* @return {FormData}
|
||||||
|
* the result
|
||||||
|
*/
|
||||||
buildFormData(dso: DSpaceObject): FormData {
|
buildFormData(dso: DSpaceObject): FormData {
|
||||||
const form: FormData = new FormData();
|
const form: FormData = new FormData();
|
||||||
form.append('name', dso.name);
|
form.append('name', dso.name);
|
||||||
|
@@ -35,8 +35,8 @@ import { AuthService } from '../auth/auth.service';
|
|||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { EmptyError } from 'rxjs/internal-compatibility';
|
import { EmptyError } from 'rxjs/internal-compatibility';
|
||||||
import { DataBuildService } from '../cache/builders/data-build.service';
|
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
|
||||||
import { DSOUpdateComparator } from '../data/dso-update-comparator';
|
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
|
||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -119,8 +119,8 @@ describe('MetadataService', () => {
|
|||||||
{ provide: AuthService, useValue: {} },
|
{ provide: AuthService, useValue: {} },
|
||||||
{ provide: NotificationsService, useValue: {} },
|
{ provide: NotificationsService, useValue: {} },
|
||||||
{ provide: HttpClient, useValue: {} },
|
{ provide: HttpClient, useValue: {} },
|
||||||
{ provide: DataBuildService, useValue: {} },
|
{ provide: NormalizedObjectBuildService, useValue: {} },
|
||||||
{ provide: DSOUpdateComparator, useValue: {} },
|
{ provide: DSOChangeAnalyzer, useValue: {} },
|
||||||
Meta,
|
Meta,
|
||||||
Title,
|
Title,
|
||||||
ItemDataService,
|
ItemDataService,
|
||||||
|
@@ -11,6 +11,9 @@ import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
|||||||
import { isNotEmpty } from '../../empty.util';
|
import { isNotEmpty } from '../../empty.util';
|
||||||
import { ResourceType } from '../../../core/shared/resource-type';
|
import { ResourceType } from '../../../core/shared/resource-type';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A form for creating and editing Communities or Collections
|
||||||
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-comcol-form',
|
selector: 'ds-comcol-form',
|
||||||
styleUrls: ['./comcol-form.component.scss'],
|
styleUrls: ['./comcol-form.component.scss'],
|
||||||
|
@@ -31,6 +31,14 @@ export const createTestComponent = <T>(html: string, type: { new(...args: any[])
|
|||||||
return fixture as ComponentFixture<T>;
|
return fixture as ComponentFixture<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows you to spy on a read only property
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* The object to spy on
|
||||||
|
* @param prop
|
||||||
|
* The property to spy on
|
||||||
|
*/
|
||||||
export function spyOnOperator(obj: any, prop: string): any {
|
export function spyOnOperator(obj: any, prop: string): any {
|
||||||
const oldProp = obj[prop];
|
const oldProp = obj[prop];
|
||||||
Object.defineProperty(obj, prop, {
|
Object.defineProperty(obj, prop, {
|
||||||
|
@@ -1,11 +1,30 @@
|
|||||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of seconds between automatic syncs to the
|
||||||
|
* server for requests using a certain HTTP Method
|
||||||
|
*/
|
||||||
type TimePerMethod = {
|
type TimePerMethod = {
|
||||||
[method in RestRequestMethod]: number;
|
[method in RestRequestMethod]: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The config that determines how the automatic syncing
|
||||||
|
* of changed data to the server works
|
||||||
|
*/
|
||||||
export interface AutoSyncConfig {
|
export interface AutoSyncConfig {
|
||||||
|
/**
|
||||||
|
* The number of seconds between automatic syncs to the server
|
||||||
|
*/
|
||||||
defaultTime: number;
|
defaultTime: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Method specific overrides of defaultTime
|
||||||
|
*/
|
||||||
timePerMethod: TimePerMethod;
|
timePerMethod: TimePerMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max number of requests in the buffer before a sync to the server
|
||||||
|
*/
|
||||||
maxBufferSize: number;
|
maxBufferSize: number;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user