diff --git a/src/app/+collection-page/collection-page.component.html b/src/app/+collection-page/collection-page.component.html index a233163070..90ae0cdf4c 100644 --- a/src/app/+collection-page/collection-page.component.html +++ b/src/app/+collection-page/collection-page.component.html @@ -33,6 +33,20 @@ [content]="collection.license" [title]="'collection.page.license'"> +
+
+
+ +
+ +
+ +
+
+
+
+
diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index 59cf83777f..95aa8ddc4a 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -15,7 +15,7 @@ import { Item } from '../core/shared/item.model'; import { fadeIn, fadeInOut } from '../shared/animations/fade'; import { hasValue, isNotEmpty } from '../shared/empty.util'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; -import { filter, flatMap, map } from 'rxjs/operators'; +import { filter, first, flatMap, map } from 'rxjs/operators'; import { SearchService } from '../+search-page/search-service/search.service'; import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model'; import { toDSpaceObjectListRD } from '../core/shared/operators'; @@ -39,6 +39,8 @@ export class CollectionPageComponent implements OnInit, OnDestroy { sortConfig: SortOptions; private subs: Subscription[] = []; private collectionId: string; + href: string; + newname: string; constructor( private collectionDataService: CollectionDataService, @@ -77,6 +79,10 @@ export class CollectionPageComponent implements OnInit, OnDestroy { }); }) ); + this.collectionRD$.pipe(first()).subscribe((crd) => { + this.href = crd.payload.self; + this.newname = crd.payload.name; + }); } updatePage(searchOptions) { @@ -109,4 +115,9 @@ export class CollectionPageComponent implements OnInit, OnDestroy { } }) } + + patchIt(): void { + console.log('patching it!', this.href, this.newname); + this.collectionDataService.patch(this.href, [{ op: 'replace', path: '/name', value: this.newname }]); + } } diff --git a/src/app/+community-page/community-page.component.html b/src/app/+community-page/community-page.component.html index ce86171370..1bf322a688 100644 --- a/src/app/+community-page/community-page.component.html +++ b/src/app/+community-page/community-page.component.html @@ -24,20 +24,6 @@ [content]="communityPayload.copyrightText" [hasInnerHtml]="true"> -
-
-
- -
- -
- -
-
-
-
-
diff --git a/src/app/+community-page/community-page.component.ts b/src/app/+community-page/community-page.component.ts index 5a36209c28..ce260aefc0 100644 --- a/src/app/+community-page/community-page.component.ts +++ b/src/app/+community-page/community-page.component.ts @@ -24,8 +24,7 @@ import { hasValue } from '../shared/empty.util'; export class CommunityPageComponent implements OnInit, OnDestroy { communityRD$: Observable>; logoRD$: Observable>; - href: string; - newname: string; + private subs: Subscription[] = []; @@ -44,19 +43,13 @@ export class CommunityPageComponent implements OnInit, OnDestroy { filter((community: Community) => hasValue(community)), mergeMap((community: Community) => community.logo)); - this.communityRD$.pipe(first()).subscribe((crd) => { - this.href = crd.payload.self; - this.newname = crd.payload.name; - }); + } ngOnDestroy(): void { 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 }]); - } + } diff --git a/src/app/core/auth/auth-response-parsing.service.spec.ts b/src/app/core/auth/auth-response-parsing.service.spec.ts index f6dd87e99a..4622d885c1 100644 --- a/src/app/core/auth/auth-response-parsing.service.spec.ts +++ b/src/app/core/auth/auth-response-parsing.service.spec.ts @@ -8,13 +8,13 @@ import { CoreState } from '../core.reducers'; import { AuthStatus } from './models/auth-status.model'; import { AuthResponseParsingService } from './auth-response-parsing.service'; import { AuthGetRequest, AuthPostRequest } from '../data/request.models'; -import { getMockStore } from '../../shared/mocks/mock-store'; +// import { getMockStore } from '../../shared/mocks/mock-store'; describe('AuthResponseParsingService', () => { let service: AuthResponseParsingService; const EnvConfig = {cache: {msToLive: 1000}} as GlobalConfig; - const store = getMockStore() as Store; + const store = {} as Store; const objectCacheService = new ObjectCacheService(store); beforeEach(() => { diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index ec65e3a060..42178d721d 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -17,7 +17,6 @@ import { REQUEST } from '@nguniversal/express-engine/tokens'; import { RouterReducerState } from '@ngrx/router-store'; import { select, Store } from '@ngrx/store'; import { CookieAttributes } from 'js-cookie'; -import { Observable } from 'rxjs/Observable'; import { EPerson } from '../eperson/models/eperson.model'; import { AuthRequestService } from './auth-request.service'; diff --git a/src/app/core/auth/models/auth-status.model.ts b/src/app/core/auth/models/auth-status.model.ts index b8ccf9ed6d..4cb4bd530e 100644 --- a/src/app/core/auth/models/auth-status.model.ts +++ b/src/app/core/auth/models/auth-status.model.ts @@ -2,7 +2,7 @@ import { AuthError } from './auth-error.model'; import { AuthTokenInfo } from './auth-token-info.model'; import { EPerson } from '../../eperson/models/eperson.model'; import { RemoteData } from '../../data/remote-data'; -import { Observable } from 'rxjs/Observable'; +import { Observable } from 'rxjs/internal/Observable'; export class AuthStatus { diff --git a/src/app/core/cache/object-cache.reducer.ts b/src/app/core/cache/object-cache.reducer.ts index f856b57892..4424bb2142 100644 --- a/src/app/core/cache/object-cache.reducer.ts +++ b/src/app/core/cache/object-cache.reducer.ts @@ -21,6 +21,7 @@ export interface Patch { uuid?: string; operations: Operation[]; } + /**conca * An interface to represent objects that can be cached * @@ -119,7 +120,7 @@ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheActio timeAdded: action.payload.timeAdded, msToLive: action.payload.msToLive, requestHref: action.payload.requestHref, - isDirty: false, + isDirty: (hasValue(existing) ? isNotEmpty(existing.patches) : false), patches: (hasValue(existing) ? existing.patches : []) } }); @@ -206,9 +207,8 @@ function applyPatchObjectCache(state: ObjectCacheState, action: ApplyPatchObject if (hasValue(newState[uuid])) { // flatten two dimensional array const flatPatch: Operation[] = [].concat(...newState[uuid].patches.map((patch) => patch.operations)); - const newData = applyPatch( newState[uuid].data, flatPatch); - newState[uuid].data = newData.newDocument; - newState[uuid].patches = []; + const newData = applyPatch(newState[uuid].data, flatPatch, undefined, false); + newState[uuid] = Object.assign({}, newState[uuid], { data: newData.newDocument, patches: [] }); } return newState; } diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index f60b2de684..909a160068 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -1,6 +1,6 @@ import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; -import { distinctUntilChanged, filter, first, map, mergeMap } from 'rxjs/operators'; +import { distinctUntilChanged, filter, first, map, mergeMap, } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { MemoizedSelector, select, Store } from '@ngrx/store'; import { IndexName } from '../index/index.reducer'; @@ -18,9 +18,10 @@ import { coreSelector, CoreState } from '../core.reducers'; import { pathSelector } from '../shared/selectors'; import { NormalizedObjectFactory } from './models/normalized-object-factory'; import { NormalizedObject } from './models/normalized-object.model'; -import { applyPatch, Operation } from 'fast-json-patch'; +import { applyPatch, applyReducer, Operation } from 'fast-json-patch'; import { AddToSSBAction } from './server-sync-buffer.actions'; import { RestRequestMethod } from '../data/rest-request-method'; +import { ReplaceOperation } from 'fast-json-patch/lib/core'; function selfLinkFromUuidSelector(uuid: string): MemoizedSelector { return pathSelector(coreSelector, 'index', IndexName.OBJECT, uuid); @@ -92,7 +93,7 @@ export class ObjectCacheService { return this.getEntry(selfLink).pipe( map((entry: ObjectCacheEntry) => { const flatPatch: Operation[] = [].concat(...entry.patches.map((patch) => patch.operations)); - const patchedData = applyPatch(entry.data, flatPatch).newDocument; + const patchedData = applyPatch(entry.data, flatPatch, undefined, false).newDocument; return Object.assign({}, entry, { data: patchedData }); } ), @@ -114,7 +115,7 @@ export class ObjectCacheService { getRequestHrefBySelfLink(selfLink: string): Observable { return this.getEntry(selfLink).pipe( map((entry: ObjectCacheEntry) => entry.requestHref), - distinctUntilChanged(),); + distinctUntilChanged()); } getRequestHrefByUUID(uuid: string): Observable { @@ -211,7 +212,6 @@ export class ObjectCacheService { } - /** * Add operations to the existing list of operations for an ObjectCacheEntry * Makes sure the ServerSyncBuffer for this ObjectCacheEntry is updated diff --git a/src/app/core/cache/server-sync-buffer.effects.ts b/src/app/core/cache/server-sync-buffer.effects.ts index 1211740ffe..d5988cb839 100644 --- a/src/app/core/cache/server-sync-buffer.effects.ts +++ b/src/app/core/cache/server-sync-buffer.effects.ts @@ -1,4 +1,4 @@ -import { delay, exhaustMap, first, map, startWith, switchMap, tap } from 'rxjs/operators'; +import { delay, exhaustMap, first, map, switchMap } from 'rxjs/operators'; import { Inject, Injectable } from '@angular/core'; import { Actions, Effect, ofType } from '@ngrx/effects'; import { @@ -12,7 +12,7 @@ import { GlobalConfig } from '../../../config/global-config.interface'; import { coreSelector, CoreState } from '../core.reducers'; import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer'; -import { of as observableOf, combineLatest as observableCombineLatest, empty as observableEmpty } from 'rxjs'; +import { combineLatest as observableCombineLatest, of as observableOf } from 'rxjs'; import { RequestService } from '../data/request.service'; import { PutRequest } from '../data/request.models'; import { ObjectCacheService } from './object-cache.service'; @@ -41,7 +41,7 @@ export class ServerSyncBufferEffects { switchMap((action: CommitSSBAction) => { return this.store.pipe( select(serverSyncBufferSelector()), - map((bufferState: ServerSyncBufferState) => { + switchMap((bufferState: ServerSyncBufferState) => { const actions: Array> = bufferState.buffer .filter((entry: ServerSyncBufferEntry) => { /* If there's a request method, filter @@ -53,41 +53,37 @@ export class ServerSyncBufferEffects { }) .map((entry: ServerSyncBufferEntry) => { if (entry.method === RestRequestMethod.PATCH) { - console.log(this.applyPatch(entry.href)); return this.applyPatch(entry.href); } else { /* TODO other request stuff */ } }); - console.log(actions); + /* Add extra action to array, to make sure the ServerSyncBuffer is emptied afterwards */ if (isNotEmpty(actions) && isNotUndefined(actions[0])) { return observableCombineLatest(...actions).pipe( - map((array) => { - console.log(array); - return array.push(new EmptySSBAction(action.payload)); - }) - ); + switchMap((array) => [...array, new EmptySSBAction(action.payload)]) + ); } else { - return { type:'NO_ACTION' }; + return observableOf({ type: 'NO_ACTION' }); } }) ) }) ); - private applyPatch(href: string): Observable { - const patchObject = this.objectCache.getBySelfLink(href); - const test = patchObject.pipe( + const patchObject = this.objectCache.getBySelfLink(href).pipe(first()); + + return patchObject.pipe( map((object) => { const serializedObject = new DSpaceRESTv2Serializer(object.constructor as GenericConstructor<{}>).serialize(object); + this.requestService.configure(new PutRequest(this.requestService.generateRequestId(), href, serializedObject)); - console.log(new ApplyPatchObjectCacheAction(href)); + return new ApplyPatchObjectCacheAction(href) }) ) - return test; } constructor(private actions$: Actions, diff --git a/src/app/shared/mocks/mock-remote-data-build.service.ts b/src/app/shared/mocks/mock-remote-data-build.service.ts index 7308051c85..33d273e1ef 100644 --- a/src/app/shared/mocks/mock-remote-data-build.service.ts +++ b/src/app/shared/mocks/mock-remote-data-build.service.ts @@ -1,11 +1,10 @@ -import { Observable } from 'rxjs'; -import { map, take } from 'rxjs/operators'; +import { Observable, of as observableOf } from 'rxjs'; +import { map } from 'rxjs/operators'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer'; import { RemoteData } from '../../core/data/remote-data'; import { RequestEntry } from '../../core/data/request.reducer'; import { hasValue } from '../empty.util'; -import { NormalizedObject } from '../../core/cache/models/normalized-object.model'; export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observable>): RemoteDataBuildService { return { @@ -19,7 +18,7 @@ export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observab } as RemoteData))) } }, - buildSingle: (href$: string | Observable) => Observable.of(new RemoteData(false, false, true, undefined, {})) + buildSingle: (href$: string | Observable) => observableOf(new RemoteData(false, false, true, undefined, {})) } as RemoteDataBuildService; } diff --git a/src/app/shared/mocks/mock-store.ts b/src/app/shared/mocks/mock-store.ts index 7a6ca772f2..e69de29bb2 100644 --- a/src/app/shared/mocks/mock-store.ts +++ b/src/app/shared/mocks/mock-store.ts @@ -1,4 +0,0 @@ -import { Store } from '@ngrx/store'; -import { of as observableOf } from 'rxjs'; - - diff --git a/src/app/shared/services/route.service.ts b/src/app/shared/services/route.service.ts index d72367c977..9dd9a0f164 100644 --- a/src/app/shared/services/route.service.ts +++ b/src/app/shared/services/route.service.ts @@ -52,6 +52,6 @@ export class RouteService { }); return params; }), - distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),); + distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))); } } diff --git a/src/app/shared/testing/auth-request-service-stub.ts b/src/app/shared/testing/auth-request-service-stub.ts index a7ff7dcd53..ae58fd27fa 100644 --- a/src/app/shared/testing/auth-request-service-stub.ts +++ b/src/app/shared/testing/auth-request-service-stub.ts @@ -27,7 +27,7 @@ export class AuthRequestServiceStub { if (this.validateToken(token)) { authStatusStub.authenticated = true; authStatusStub.token = this.mockTokenInfo; - authStatusStub.eperson = Observable.of(new RemoteData(false, false, true, undefined, this.mockUser)); + authStatusStub.eperson = observableOf(new RemoteData(false, false, true, undefined, this.mockUser)); } else { authStatusStub.authenticated = false; } @@ -46,7 +46,7 @@ export class AuthRequestServiceStub { if (this.validateToken(token)) { authStatusStub.authenticated = true; authStatusStub.token = this.mockTokenInfo; - authStatusStub.eperson = Observable.of(new RemoteData(false, false, true, undefined, this.mockUser)); + authStatusStub.eperson = observableOf(new RemoteData(false, false, true, undefined, this.mockUser)); } else { authStatusStub.authenticated = false; }