69110: Failure notification on create and edit eperson

This commit is contained in:
Marie Verdonck
2020-03-13 17:28:37 +01:00
parent a261034f9d
commit 1853d1bda2
4 changed files with 97 additions and 23 deletions

View File

@@ -220,6 +220,8 @@
"admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"",
"admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.",
"admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"",
"admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"",

View File

@@ -10,6 +10,8 @@ import { TranslateService } from '@ngx-translate/core';
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
import { Subscription } from 'rxjs/internal/Subscription';
import { take } from 'rxjs/operators';
import { RestResponse } from '../../../../core/cache/response.models';
import { PaginatedList } from '../../../../core/data/paginated-list';
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
import { EPerson } from '../../../../core/eperson/models/eperson.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
@@ -231,14 +233,18 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
* @param values
*/
createNewEPerson(values) {
this.subs.push(this.epersonService.create(Object.assign(new EPerson(), values), null)
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload())
.subscribe((newEPerson: EPerson) => {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: newEPerson.name }));
this.submitForm.emit(newEPerson);
}));
const ePersonToCreate = Object.assign(new EPerson(), values);
const response = this.epersonService.tryToCreate(ePersonToCreate);
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: ePersonToCreate.name }));
this.submitForm.emit(ePersonToCreate);
} else {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure', { name: ePersonToCreate.name }));
}
});
this.showNotificationIfEmailInUse(ePersonToCreate);
}
/**
@@ -247,7 +253,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
* @param values
*/
editEPerson(ePerson: EPerson, values) {
this.epersonService.updateEPerson(Object.assign(new EPerson(), {
const editedEperson = Object.assign(new EPerson(), {
id: ePerson.id,
metadata: {
'eperson.firstname': [
@@ -266,14 +272,35 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
requireCertificate: (hasValue(values.requireCertificate) ? values.requireCertificate : ePerson.requireCertificate),
selfRegistered: false,
_links: ePerson._links,
}))
.pipe(
getSucceededRemoteData(),
getRemoteDataPayload())
.subscribe((updatedEPerson: EPerson) => {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: updatedEPerson.name }));
this.submitForm.emit(updatedEPerson);
});
});
const response = this.epersonService.updateEPerson(editedEperson);
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
if (restResponse.isSuccessful) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: editedEperson.name }));
this.submitForm.emit(editedEperson);
} else {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure', { name: editedEperson.name }));
}
});
this.showNotificationIfEmailInUse(editedEperson);
}
private showNotificationIfEmailInUse(ePersonToCreate: EPerson) {
// Relevant message for email in use
// TODO: should be changed to email scope, but byEmail currently not in backend
this.subs.push(this.epersonService.searchByScope(null, ePersonToCreate.email, {
currentPage: 1,
elementsPerPage: 0
}).pipe(getSucceededRemoteData(), getRemoteDataPayload())
.subscribe((list: PaginatedList<EPerson>) => {
if (list.totalElements > 0) {
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure.emailInUse', {
name: ePersonToCreate.name,
email: ePersonToCreate.email
}));
}
}));
}
/**

View File

@@ -409,6 +409,48 @@ export abstract class DataService<T extends CacheableObject> {
)
}
/**
* Create a new DSpaceObject on the server, and store the response
* in the object cache, returns observable of the response to determine success
*
* @param {DSpaceObject} dso
* The object to create
*/
tryToCreate(dso: T): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
isNotEmptyOperator(),
distinctUntilChanged(),
);
const serializedDso = new DSpaceSerializer(getClassForType((dso as any).type)).serialize(dso);
const request$ = endpoint$.pipe(
take(1),
map((endpoint: string) => new CreateRequest(requestId, endpoint, JSON.stringify(serializedDso)))
);
// Execute the post request
request$.pipe(
configureRequest(this.requestService)
).subscribe();
return this.fetchResponse(requestId);
}
/**
* Gets the restResponse from the requestService
* @param requestId
*/
protected fetchResponse(requestId: string): Observable<RestResponse> {
return this.requestService.getByUUID(requestId).pipe(
getResponseFromEntry(),
map((response: RestResponse) => {
return response;
})
);
}
/**
* Delete an existing DSpace Object on the server
* @param dsoID The DSpace Object' id to be removed

View File

@@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { createSelector, select, Store } from '@ngrx/store';
import { Operation } from 'fast-json-patch/lib/core';
import { Observable } from 'rxjs';
import { filter, mergeMap, take } from 'rxjs/operators';
import { filter, map, take } from 'rxjs/operators';
import {
EPeopleRegistryCancelEPersonAction,
EPeopleRegistryEditEPersonAction
@@ -17,6 +17,7 @@ import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { SearchParam } from '../cache/models/search-param.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RestResponse } from '../cache/response.models';
import { DataService } from '../data/data.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
import { PaginatedList } from '../data/paginated-list';
@@ -136,18 +137,20 @@ export class EPersonDataService extends DataService<EPerson> {
* The patch is derived from the differences between the given object and its version in the object cache
* @param {DSpaceObject} ePerson The given object
*/
public updateEPerson(ePerson: EPerson): Observable<RemoteData<EPerson>> {
public updateEPerson(ePerson: EPerson): Observable<RestResponse> {
const requestId = this.requestService.generateRequestId();
const oldVersion$ = this.findByHref(ePerson._links.self.href);
return oldVersion$.pipe(
oldVersion$.pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
mergeMap((oldEPerson: EPerson) => {
map((oldEPerson: EPerson) => {
const operations = this.generateOperations(oldEPerson, ePerson);
const patchRequest = new PatchRequest(this.requestService.generateRequestId(), ePerson._links.self.href, operations);
const patchRequest = new PatchRequest(requestId, ePerson._links.self.href, operations);
this.requestService.configure(patchRequest);
return this.findByHref(ePerson._links.self.href);
}),
);
return this.fetchResponse(requestId);
}
/**