intermediate bug commit

This commit is contained in:
lotte
2018-09-26 15:31:26 +02:00
parent bae69aef97
commit 8c05ed86ef
9 changed files with 69 additions and 27 deletions

View File

@@ -24,7 +24,7 @@ module.exports = {
autoSync: { autoSync: {
defaultTime: 0, defaultTime: 0,
maxBufferSize: 100, maxBufferSize: 100,
timePerMethod: {'Patch': 30} //time in seconds timePerMethod: {'PATCH': 3} //time in seconds
} }
}, },
// Form settings // Form settings

View File

@@ -24,9 +24,25 @@
[content]="communityPayload.copyrightText" [content]="communityPayload.copyrightText"
[hasInnerHtml]="true"> [hasInnerHtml]="true">
</ds-comcol-page-content> </ds-comcol-page-content>
<ds-community-page-sub-collection-list [community]="communityPayload"></ds-community-page-sub-collection-list> <form (submit)="patchIt()">
<div class="row">
<div class="form-group col col-sm-4">
<label for="newname">Change Name</label>
<div class="input-group mb-3">
<input type="email" class="form-control" id="newname" name="newname"
placeholder="Enter a collection name" [(ngModel)]="newname">
<div class="input-group-append">
<button class="btn btn-danger" type="submit">Patch!</button>
</div>
</div>
</div>
</div>
</form>
<ds-community-page-sub-collection-list
[community]="communityPayload"></ds-community-page-sub-collection-list>
</div> </div>
</div> </div>
<ds-error *ngIf="communityRD?.hasFailed" message="{{'error.community' | translate}}"></ds-error> <ds-error *ngIf="communityRD?.hasFailed" message="{{'error.community' | translate}}"></ds-error>
<ds-loading *ngIf="communityRD?.isLoading" message="{{'loading.community' | translate}}"></ds-loading> <ds-loading *ngIf="communityRD?.isLoading"
message="{{'loading.community' | translate}}"></ds-loading>
</div> </div>

View File

@@ -1,4 +1,4 @@
import {mergeMap, filter, map} from 'rxjs/operators'; import { mergeMap, filter, map, first, tap } from 'rxjs/operators';
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@@ -24,6 +24,9 @@ import { hasValue } from '../shared/empty.util';
export class CommunityPageComponent implements OnInit, OnDestroy { export class CommunityPageComponent implements OnInit, OnDestroy {
communityRD$: Observable<RemoteData<Community>>; communityRD$: Observable<RemoteData<Community>>;
logoRD$: Observable<RemoteData<Bitstream>>; logoRD$: Observable<RemoteData<Bitstream>>;
href: string;
newname: string;
private subs: Subscription[] = []; private subs: Subscription[] = [];
constructor( constructor(
@@ -40,10 +43,20 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
map((rd: RemoteData<Community>) => rd.payload), map((rd: RemoteData<Community>) => rd.payload),
filter((community: Community) => hasValue(community)), filter((community: Community) => hasValue(community)),
mergeMap((community: Community) => community.logo)); mergeMap((community: Community) => community.logo));
this.communityRD$.pipe(first()).subscribe((crd) => {
this.href = crd.payload.self;
this.newname = crd.payload.name;
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe()); this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
} }
patchIt(): void {
console.log('patching it!', this.href, this.newname);
this.communityDataService.patch(this.href, [{ op: 'replace', path: '/name', value: this.newname }]);
}
} }

View File

@@ -1,6 +1,4 @@
import { animate, state, style, transition, trigger } from '@angular/animations'; import { Component, OnInit } from '@angular/core';
import { Component, HostBinding, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { FilterType } from '../../../search-service/filter-type.model'; import { FilterType } from '../../../search-service/filter-type.model';
import { import {
facetLoad, facetLoad,

View File

@@ -182,8 +182,10 @@ function addPatchObjectCache(state: ObjectCacheState, action: AddPatchObjectCach
const newState = Object.assign({}, state); const newState = Object.assign({}, state);
if (hasValue(newState[uuid])) { if (hasValue(newState[uuid])) {
const patches = newState[uuid].patches; const patches = newState[uuid].patches;
newState[uuid].patches = [...patches, {operations} as Patch]; newState[uuid] = Object.assign({}, newState[uuid], {
newState[uuid].isDirty = true; patches: [...patches, { operations } as Patch],
isDirty: true
});
} }
return newState; return newState;
} }
@@ -203,7 +205,7 @@ function applyPatchObjectCache(state: ObjectCacheState, action: ApplyPatchObject
const newState = Object.assign({}, state); const newState = Object.assign({}, state);
if (hasValue(newState[uuid])) { if (hasValue(newState[uuid])) {
// flatten two dimensional array // flatten two dimensional array
const flatPatch: Operation[] = [].concat(...newState[uuid].patches); const flatPatch: Operation[] = [].concat(...newState[uuid].patches.map((patch) => patch.operations));
const newData = applyPatch( newState[uuid].data, flatPatch); const newData = applyPatch( newState[uuid].data, flatPatch);
newState[uuid].data = newData.newDocument; newState[uuid].data = newData.newDocument;
newState[uuid].patches = []; newState[uuid].patches = [];

View File

@@ -91,7 +91,7 @@ export class ObjectCacheService {
getBySelfLink<T extends NormalizedObject>(selfLink: string): Observable<T> { getBySelfLink<T extends NormalizedObject>(selfLink: string): Observable<T> {
return this.getEntry(selfLink).pipe( return this.getEntry(selfLink).pipe(
map((entry: ObjectCacheEntry) => { map((entry: ObjectCacheEntry) => {
const flatPatch: Operation[] = [].concat(...entry.patches); const flatPatch: Operation[] = [].concat(...entry.patches.map((patch) => patch.operations));
const patchedData = applyPatch(entry.data, flatPatch).newDocument; const patchedData = applyPatch(entry.data, flatPatch).newDocument;
return Object.assign({}, entry, { data: patchedData }); return Object.assign({}, entry, { data: patchedData });
} }

View File

@@ -31,7 +31,7 @@ export class AddToSSBAction implements Action {
* the unique href of the cached object entry that should be updated * the unique href of the cached object entry that should be updated
*/ */
constructor(href: string, method: RestRequestMethod) { constructor(href: string, method: RestRequestMethod) {
this.payload = { href, method: undefined }; this.payload = { href, method: method };
} }
} }

View File

@@ -1,4 +1,4 @@
import { delay, exhaustMap, first, map, switchMap, tap } from 'rxjs/operators'; import { delay, exhaustMap, first, map, startWith, switchMap, tap } from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects'; import { Actions, Effect, ofType } from '@ngrx/effects';
import { import {
@@ -9,17 +9,17 @@ import {
} from './server-sync-buffer.actions'; } from './server-sync-buffer.actions';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { CoreState } from '../core.reducers'; import { coreSelector, CoreState } from '../core.reducers';
import { Action, select, Store } from '@ngrx/store'; import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer'; import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer';
import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs'; import { of as observableOf, combineLatest as observableCombineLatest, empty as observableEmpty } from 'rxjs';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { PutRequest } from '../data/request.models'; import { PutRequest } from '../data/request.models';
import { ObjectCacheService } from './object-cache.service'; import { ObjectCacheService } from './object-cache.service';
import { ApplyPatchObjectCacheAction } from './object-cache.actions'; import { ApplyPatchObjectCacheAction } from './object-cache.actions';
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { hasValue } from '../../shared/empty.util'; import { hasValue, isNotEmpty, isNotUndefined } from '../../shared/empty.util';
import { Observable } from 'rxjs/internal/Observable'; import { Observable } from 'rxjs/internal/Observable';
import { RestRequestMethod } from '../data/rest-request-method'; import { RestRequestMethod } from '../data/rest-request-method';
@@ -29,9 +29,8 @@ export class ServerSyncBufferEffects {
.pipe( .pipe(
ofType(ServerSyncBufferActionTypes.ADD), ofType(ServerSyncBufferActionTypes.ADD),
exhaustMap((action: AddToSSBAction) => { exhaustMap((action: AddToSSBAction) => {
// const autoSyncConfig = this.EnvConfig.cache.autoSync; const autoSyncConfig = this.EnvConfig.cache.autoSync;
// const timeoutInSeconds = autoSyncConfig.timePerMethod[action.type] || autoSyncConfig.defaultTime; const timeoutInSeconds = autoSyncConfig.timePerMethod[action.payload.method] || autoSyncConfig.defaultTime;
const timeoutInSeconds = 0;
return observableOf(new CommitSSBAction(action.payload.method)).pipe(delay(timeoutInSeconds * 1000)) return observableOf(new CommitSSBAction(action.payload.method)).pipe(delay(timeoutInSeconds * 1000))
}) })
); );
@@ -41,7 +40,7 @@ export class ServerSyncBufferEffects {
ofType(ServerSyncBufferActionTypes.COMMIT), ofType(ServerSyncBufferActionTypes.COMMIT),
switchMap((action: CommitSSBAction) => { switchMap((action: CommitSSBAction) => {
return this.store.pipe( return this.store.pipe(
select(serverSyncBufferSelector), select(serverSyncBufferSelector()),
map((bufferState: ServerSyncBufferState) => { map((bufferState: ServerSyncBufferState) => {
const actions: Array<Observable<Action>> = bufferState.buffer const actions: Array<Observable<Action>> = bufferState.buffer
.filter((entry: ServerSyncBufferEntry) => { .filter((entry: ServerSyncBufferEntry) => {
@@ -54,29 +53,41 @@ export class ServerSyncBufferEffects {
}) })
.map((entry: ServerSyncBufferEntry) => { .map((entry: ServerSyncBufferEntry) => {
if (entry.method === RestRequestMethod.PATCH) { if (entry.method === RestRequestMethod.PATCH) {
console.log(this.applyPatch(entry.href));
return this.applyPatch(entry.href); return this.applyPatch(entry.href);
} else { } else {
/* TODO other request stuff */ /* TODO other request stuff */
} }
}); });
console.log(actions);
/* Add extra action to array, to make sure the ServerSyncBuffer is emptied afterwards */ /* Add extra action to array, to make sure the ServerSyncBuffer is emptied afterwards */
return observableCombineLatest(actions).pipe( if (isNotEmpty(actions) && isNotUndefined(actions[0])) {
map((array) => array.push(new EmptySSBAction(action.payload))) return observableCombineLatest(...actions).pipe(
map((array) => {
console.log(array);
return array.push(new EmptySSBAction(action.payload));
})
); );
} else {
return { type:'NO_ACTION' };
}
}) })
) )
}) })
); );
private applyPatch(href: string): Observable<Action> { private applyPatch(href: string): Observable<Action> {
const patchObject = this.objectCache.getBySelfLink(href); const patchObject = this.objectCache.getBySelfLink(href);
return patchObject.pipe( const test = patchObject.pipe(
map((object) => { map((object) => {
const serializedObject = new DSpaceRESTv2Serializer(object.constructor as GenericConstructor<{}>).serialize(object); const serializedObject = new DSpaceRESTv2Serializer(object.constructor as GenericConstructor<{}>).serialize(object);
this.requestService.configure(new PutRequest(this.requestService.generateRequestId(), href, serializedObject)); this.requestService.configure(new PutRequest(this.requestService.generateRequestId(), href, serializedObject));
console.log(new ApplyPatchObjectCacheAction(href));
return new ApplyPatchObjectCacheAction(href) return new ApplyPatchObjectCacheAction(href)
}) })
) )
return test;
} }
constructor(private actions$: Actions, constructor(private actions$: Actions,
@@ -88,4 +99,6 @@ export class ServerSyncBufferEffects {
} }
} }
export const serverSyncBufferSelector = (state: CoreState) => state['cache/syncbuffer']; export function serverSyncBufferSelector(): MemoizedSelector<CoreState, ServerSyncBufferState> {
return createSelector(coreSelector, (state: CoreState) => state['cache/syncbuffer']);
}

View File

@@ -4,5 +4,5 @@ import { AutoSyncConfig } from './auto-sync-config.interface';
export interface CacheConfig extends Config { export interface CacheConfig extends Config {
msToLive: number, msToLive: number,
control: string, control: string,
// autoSync: AutoSyncConfig autoSync: AutoSyncConfig
} }