intermediate commit

This commit is contained in:
lotte
2020-02-03 12:58:24 +01:00
parent 28747314e6
commit 360abb78de
12 changed files with 114 additions and 84 deletions

View File

@@ -10,6 +10,7 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { CacheEntry } from './cache-entry';
import { ResourceType } from '../shared/resource-type';
import { applyPatch, Operation } from 'fast-json-patch';
import { NormalizedItem } from './models/normalized-item.model';
export enum DirtyType {
Created = 'Created',
@@ -64,6 +65,7 @@ export class ObjectCacheEntry implements CacheEntry {
patches: Patch[] = [];
isDirty: boolean;
}
/* tslint:enable:max-classes-per-file */
/**
@@ -93,10 +95,14 @@ export function objectCacheReducer(state = initialState, action: ObjectCacheActi
switch (action.type) {
case ObjectCacheActionTypes.ADD: {
if ((action.payload as any).objectToCache instanceof NormalizedItem) {
console.log('ADD', (action.payload as any).objectToCache.self);
}
return addToObjectCache(state, action as AddToObjectCacheAction);
}
case ObjectCacheActionTypes.REMOVE: {
console.log('REMOVE', action.payload);
return removeFromObjectCache(state, action as RemoveFromObjectCacheAction)
}

View File

@@ -9,7 +9,7 @@ import { RestRequestMethod } from '../data/rest-request-method';
/**
* An entry in the ServerSyncBufferState
* href: unique href of an ObjectCacheEntry
* href: unique href of an ServerSyncBufferEntry
* method: RestRequestMethod type
*/
export class ServerSyncBufferEntry {
@@ -48,6 +48,7 @@ export function serverSyncBufferReducer(state = initialState, action: ServerSync
case ServerSyncBufferActionTypes.EMPTY: {
return emptyServerSyncQueue(state, action as EmptySSBAction);
}
default: {
return state;
}
@@ -69,6 +70,7 @@ function addToServerSyncQueue(state: ServerSyncBufferState, action: AddToSSBActi
if (hasNoValue(state.buffer.find((entry) => entry.href === actionEntry.href && entry.method === actionEntry.method))) {
return Object.assign({}, state, { buffer: state.buffer.concat(actionEntry) });
}
return state;
}
/**

View File

@@ -60,7 +60,7 @@ export class RelationshipService extends DataService<Relationship> {
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<Relationship>,
protected appStore: Store<AppState>) {
protected appStore: Store<AppState>,) {
super();
}
@@ -86,11 +86,11 @@ export class RelationshipService extends DataService<Relationship> {
return this.getRelationshipEndpoint(id).pipe(
isNotEmptyOperator(),
take(1),
tap(() => this.removeRelationshipItemsFromCacheByRelationship(id)),
map((endpointURL: string) => new DeleteRequest(this.requestService.generateRequestId(), endpointURL)),
configureRequest(this.requestService),
switchMap((restRequest: RestRequest) => this.requestService.getByUUID(restRequest.uuid)),
getResponseFromEntry(),
tap(() => this.refreshRelationshipItemsInCacheByRelationship(id)),
);
}
@@ -117,8 +117,8 @@ export class RelationshipService extends DataService<Relationship> {
configureRequest(this.requestService),
switchMap((restRequest: RestRequest) => this.requestService.getByUUID(restRequest.uuid)),
getResponseFromEntry(),
tap(() => this.removeRelationshipItemsFromCache(item1)),
tap(() => this.removeRelationshipItemsFromCache(item2))
tap(() => this.refreshRelationshipItemsInCache(item1)),
tap(() => this.refreshRelationshipItemsInCache(item2))
) as Observable<RestResponse>;
}
@@ -126,7 +126,7 @@ export class RelationshipService extends DataService<Relationship> {
* Method to remove two items of a relationship from the cache using the identifier of the relationship
* @param relationshipId The identifier of the relationship
*/
private removeRelationshipItemsFromCacheByRelationship(relationshipId: string) {
private refreshRelationshipItemsInCacheByRelationship(relationshipId: string) {
this.findById(relationshipId).pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
@@ -137,8 +137,8 @@ export class RelationshipService extends DataService<Relationship> {
),
take(1)
).subscribe(([item1, item2]) => {
this.removeRelationshipItemsFromCache(item1);
this.removeRelationshipItemsFromCache(item2);
this.refreshRelationshipItemsInCache(item1);
this.refreshRelationshipItemsInCache(item2);
})
}
@@ -146,17 +146,21 @@ export class RelationshipService extends DataService<Relationship> {
* Method to remove an item that's part of a relationship from the cache
* @param item The item to remove from the cache
*/
private removeRelationshipItemsFromCache(item) {
private refreshRelationshipItemsInCache(item) {
setTimeout(() => {
this.objectCache.remove(item.self);
this.requestService.removeByHrefSubstring(item.uuid);
combineLatest(
this.objectCache.hasBySelfLinkObservable(item.self),
this.requestService.hasByHrefObservable(item.uuid)
this.requestService.hasByHrefObservable(item.self)
).pipe(
filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC),
take(1),
switchMap(() => this.itemService.findByHref(item.self).pipe(take(1)))
).subscribe();
}, 1000)
}
/**
@@ -288,16 +292,17 @@ export class RelationshipService extends DataService<Relationship> {
getSucceededRemoteData(),
isNotEmptyOperator(),
map((relationshipListRD: RemoteData<PaginatedList<Relationship>>) => relationshipListRD.payload.page),
mergeMap((relationships: Relationship[]) => {
switchMap((relationships: Relationship[]) => {
return observableCombineLatest(...relationships.map((relationship: Relationship) => {
return observableCombineLatest(
this.isItemMatchWithItemRD(relationship.leftItem, item2),
this.isItemMatchWithItemRD(relationship.rightItem, item2)
this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.leftItem), item2),
this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.rightItem), item2)
).pipe(
map(([isLeftItem, isRightItem]) => isLeftItem || isRightItem),
map((isMatch) => isMatch ? relationship : undefined)
);
}))
})
)
}),
map((relationships: Relationship[]) => relationships.find(((relationship) => hasValue(relationship))))
)
@@ -357,6 +362,7 @@ export class RelationshipService extends DataService<Relationship> {
* @param nameVariant The name variant to set for the matching relationship
*/
public updateNameVariant(item1: Item, item2: Item, relationshipLabel: string, nameVariant: string): Observable<RemoteData<Relationship>> {
let count = 0
const update$: Observable<RemoteData<Relationship>> = this.getRelationshipByItemsAndLabel(item1, item2, relationshipLabel)
.pipe(
switchMap((relation: Relationship) =>
@@ -378,16 +384,15 @@ export class RelationshipService extends DataService<Relationship> {
}
return this.update(updatedRelationship);
}),
tap((relationshipRD: RemoteData<Relationship>) => {
console.log(relationshipRD);
if (relationshipRD.hasSucceeded && count < 1) {
count++;
this.refreshRelationshipItemsInCache(item1);
this.refreshRelationshipItemsInCache(item2);
}
})
);
update$.pipe(
filter((relationshipRD: RemoteData<Relationship>) => relationshipRD.state === RemoteDataState.RequestPending),
take(1),
).subscribe(() => {
this.removeRelationshipItemsFromCache(item1);
this.removeRelationshipItemsFromCache(item2);
});
return update$
}
@@ -411,7 +416,7 @@ export class RelationshipService extends DataService<Relationship> {
take(1),
).subscribe((relationshipRD: RemoteData<Relationship>) => {
if (relationshipRD.state === RemoteDataState.ResponsePending) {
this.removeRelationshipItemsFromCacheByRelationship(reoRel.relationship.id);
this.refreshRelationshipItemsInCacheByRelationship(reoRel.relationship.id);
}
});

View File

@@ -4,6 +4,7 @@ import { RemoteData } from '../../data/remote-data';
import { ResourceType } from '../resource-type';
import { RelationshipType } from './relationship-type.model';
import { Item } from '../item.model';
import { deserialize } from 'cerialize';
/**
* Describes a Relationship between two Items
@@ -60,4 +61,8 @@ export class Relationship implements CacheableObject {
* The type of Relationship
*/
relationshipType: Observable<RemoteData<RelationshipType>>;
_links: {
[name: string]: string
};
}

View File

@@ -37,7 +37,7 @@
<div *ngIf="isRelationship && context?.index < 1" class="col-auto text-center">
<button class="btn btn-secondary"
type="submit"
type="button"
ngbTooltip="{{'form.lookup-help' | translate}}"
placement="top"
(click)="openLookup(); $event.stopPropagation();">{{'form.lookup' | translate}}
@@ -47,7 +47,7 @@
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
<ng-container *ngIf="relationshipValue$ | async">
<ng-container *ngIf="value?.isVirtual">
<ds-existing-metadata-list-element
[reoRel]="relationshipValue$ | async"
[submissionItem]="item"

View File

@@ -187,7 +187,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
item: Item;
listId: string;
searchConfig: string;
value: MetadataValue;
/**
* List of subscriptions to unsubscribe from
*/
@@ -235,23 +235,23 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
if (this.isRelationship) {
this.listId = 'list-' + this.model.relationship.relationshipType;
this.setItem();
const value = Object.assign(new MetadataValue(), this.model.value);
if (hasValue(value) && value.isVirtual) {
const relationship$ = this.relationshipService.findById(value.virtualValue)
this.value = Object.assign(new MetadataValue(), this.model.value);
if (hasValue(this.value) && this.value.isVirtual) {
const relationship$ = this.relationshipService.findById(this.value.virtualValue)
.pipe(
getAllSucceededRemoteData(),
getRemoteDataPayload());
this.relationshipValue$ = relationship$.pipe(
switchMap((relationship: Relationship) =>
relationship.leftItem.pipe(
tap((t) => console.log(t)),
getSucceededRemoteData(),
getRemoteDataPayload(),
map((leftItem: Item) => {
return new ReorderableRelationship(relationship, leftItem.uuid !== this.item.uuid, this.relationshipService)
}),
)
)
),
startWith(undefined)
);
}
}
@@ -359,7 +359,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
)
)
);
this.subs.push(item$.subscribe((item) => this.item = item));
}
}

View File

@@ -1,6 +1,11 @@
<div *ngIf="metadataRepresentation" class="d-flex">
<div class="d-flex">
<span class="mr-auto text-contents">
<ng-container *ngIf="!metadataRepresentation">
<ds-loading [showMessage]="false"></ds-loading>
</ng-container>
<ng-container *ngIf="metadataRepresentation">
<ds-metadata-representation-loader [mdRepresentation]="metadataRepresentation"></ds-metadata-representation-loader>
</ng-container>
</span>
<button type="button" class="btn btn-secondary"
(click)="removeSelection()">

View File

@@ -32,6 +32,7 @@ export class AddRelationshipAction implements Action {
* @param item1 The first item in the relationship
* @param item2 The second item in the relationship
* @param relationshipType The label of the relationshipType
* @param submissionId The current submissionId
* @param nameVariant The nameVariant of the relationshipType
*/
constructor(
@@ -62,6 +63,7 @@ export class UpdateRelationshipAction implements Action {
* @param item1 The first item in the relationship
* @param item2 The second item in the relationship
* @param relationshipType The label of the relationshipType
* @param submissionId The current submissionId
* @param nameVariant The nameVariant of the relationshipType
*/
constructor(
@@ -94,6 +96,7 @@ export class RemoveRelationshipAction implements Action {
* @param item1 The first item in the relationship
* @param item2 The second item in the relationship
* @param relationshipType The label of the relationshipType
* @param submissionId The current submissionId
*/
constructor(
item1: Item,

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { debounceTime, filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
import { debounceTime, filter, map, mergeMap, switchMap, take, tap } from 'rxjs/operators';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { RelationshipService } from '../../../../../core/data/relationship.service';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../core/shared/operators';
@@ -17,9 +17,10 @@ import { SubmissionState } from '../../../../../submission/submission.reducers';
import { Store } from '@ngrx/store';
import { ObjectCacheService } from '../../../../../core/cache/object-cache.service';
import { RequestService } from '../../../../../core/data/request.service';
import { ServerSyncBufferActionTypes } from '../../../../../core/cache/server-sync-buffer.actions';
const DEBOUNCE_TIME = 5000;
let updateAfterPatchSubmissionId: string;
/**
* NGRX effects for RelationshipEffects
*/
@@ -68,7 +69,6 @@ export class RelationshipEffects {
} else {
this.removeRelationship(item1, item2, relationshipType, submissionId);
}
}
delete this.debounceMap[identifier];
delete this.initialActionMap[identifier];
@@ -91,19 +91,31 @@ export class RelationshipEffects {
.pipe(
ofType(RelationshipActionTypes.UPDATE_RELATIONSHIP),
map((action: UpdateRelationshipAction) => {
const { item1, item2, relationshipType, nameVariant } = action.payload;
const { item1, item2, relationshipType, submissionId, nameVariant } = action.payload;
const identifier: string = this.createIdentifier(item1, item2, relationshipType);
const inProgress = hasValue(this.debounceMap[identifier]);
if (inProgress) {
this.nameVariantUpdates[identifier] = nameVariant;
} else {
this.relationshipService.updateNameVariant(item1, item2, relationshipType, nameVariant)
.subscribe();
this.relationshipService.updateNameVariant(item1, item2, relationshipType, nameVariant).pipe(take(1))
.subscribe(() => {
updateAfterPatchSubmissionId = submissionId;
});
}
}
)
);
@Effect() commitServerSyncBuffer = this.actions$
.pipe(
ofType(ServerSyncBufferActionTypes.COMMIT),
filter(() => hasValue(updateAfterPatchSubmissionId)),
tap(() => console.log('id', updateAfterPatchSubmissionId)),
refreshWorkspaceItemInCache('bla' + updateAfterPatchSubmissionId, this.submissionObjectService, this.objectCache, this.requestService),
tap(() => console.log('id nog s', updateAfterPatchSubmissionId)),
map((submissionObject) => new SaveSubmissionSectionFormSuccessAction(updateAfterPatchSubmissionId, [submissionObject], false))
);
constructor(private actions$: Actions,
private relationshipService: RelationshipService,
private relationshipTypeService: RelationshipTypeService,
@@ -133,7 +145,7 @@ export class RelationshipEffects {
}
),
take(1),
this.removeWorkspaceItemFromCache(submissionId)
refreshWorkspaceItemInCache(submissionId, this.submissionObjectService, this.objectCache, this.requestService)
).subscribe((submissionObject: SubmissionObject) => this.store.dispatch(new SaveSubmissionSectionFormSuccessAction(submissionId, [submissionObject], false)));
}
@@ -143,25 +155,26 @@ export class RelationshipEffects {
hasValueOperator(),
mergeMap((relationship: Relationship) => this.relationshipService.deleteRelationship(relationship.id)),
take(1),
this.removeWorkspaceItemFromCache(submissionId)
refreshWorkspaceItemInCache(submissionId, this.submissionObjectService, this.objectCache, this.requestService)
).subscribe((submissionObject: SubmissionObject) => this.store.dispatch(new SaveSubmissionSectionFormSuccessAction(submissionId, [submissionObject], false)));
}
}
removeWorkspaceItemFromCache = (submissionId) =>
const refreshWorkspaceItemInCache = (submissionId, submissionObjectService, objectCache, requestService) =>
<T>(source: Observable<T>): Observable<SubmissionObject> =>
source.pipe(
switchMap(() => this.submissionObjectService.getHrefByID(submissionId).pipe(take(1))),
tap(() => console.log(submissionId)),
switchMap(() => submissionObjectService.getHrefByID(submissionId).pipe(take(1))),
switchMap((href: string) => {
this.objectCache.remove(href);
this.requestService.removeByHrefSubstring(submissionId);
objectCache.remove(href);
requestService.removeByHrefSubstring(submissionId);
return combineLatest(
this.objectCache.hasBySelfLinkObservable(href),
this.requestService.hasByHrefObservable(href)
objectCache.hasBySelfLinkObservable(href),
requestService.hasByHrefObservable(href)
).pipe(
filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC),
take(1),
switchMap(() => this.submissionObjectService.findById(submissionId).pipe(getSucceededRemoteData(), getRemoteDataPayload()) as Observable<SubmissionObject>)
switchMap(() => submissionObjectService.findById(submissionId).pipe(getSucceededRemoteData(), getRemoteDataPayload()) as Observable<SubmissionObject>)
)
}
));
}

View File

@@ -295,7 +295,7 @@ export class FormComponent implements OnDestroy, OnInit {
removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void {
console.log(arrayContext, index);
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray;
this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove'));
this.removeArrayItem.emit(this.getEvent($event, arrayContext, index - 1, 'remove'));
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
this.formService.changeForm(this.formId, this.formModel);
}

View File

@@ -259,10 +259,6 @@ export class SubmissionSectionformComponent extends SectionModelComponent {
if (isNotEmpty(sectionData) && !isEqual(sectionData, this.sectionData.data)) {
this.sectionData.data = sectionData;
if (this.hasMetadataEnrichment(sectionData)) {
const msg = this.translate.instant(
'submission.sections.general.metadata-extracted',
{ sectionId: this.sectionData.id });
this.notificationsService.info(null, msg, null, true);
this.isUpdating = true;
this.formModel = null;
this.cdr.detectChanges();

View File

@@ -321,10 +321,6 @@ export class SectionsService {
take(1),
filter(([available, enabled]: [boolean, boolean]) => available))
.subscribe(([available, enabled]: [boolean, boolean]) => {
if (!enabled) {
const msg = this.translate.instant('submission.sections.general.metadata-extracted-new-section', {sectionId});
this.notificationsService.info(null, msg, null, true);
}
this.store.dispatch(new UpdateSectionDataAction(submissionId, sectionId, data, errors));
});
}