mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-11 12:03:03 +00:00
[Task 72956] applied feedback to the deletion of epersons
This commit is contained in:
@@ -25,6 +25,9 @@ import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock
|
|||||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
|
||||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
||||||
|
import { UUIDService } from '../../../core/shared/uuid.service';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
describe('EPeopleRegistryComponent', () => {
|
describe('EPeopleRegistryComponent', () => {
|
||||||
let component: EPeopleRegistryComponent;
|
let component: EPeopleRegistryComponent;
|
||||||
@@ -35,6 +38,7 @@ describe('EPeopleRegistryComponent', () => {
|
|||||||
let mockEPeople;
|
let mockEPeople;
|
||||||
let ePersonDataServiceStub: any;
|
let ePersonDataServiceStub: any;
|
||||||
let authorizationService: AuthorizationDataService;
|
let authorizationService: AuthorizationDataService;
|
||||||
|
let modalService;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
mockEPeople = [EPersonMock, EPersonMock2];
|
mockEPeople = [EPersonMock, EPersonMock2];
|
||||||
@@ -104,6 +108,9 @@ describe('EPeopleRegistryComponent', () => {
|
|||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
|
||||||
{ provide: FormBuilderService, useValue: builderService },
|
{ provide: FormBuilderService, useValue: builderService },
|
||||||
{ provide: AuthorizationDataService, useValue: authorizationService },
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
{ provide: ObjectCacheService, useValue: {} },
|
||||||
|
{ provide: UUIDService, useValue: {} },
|
||||||
|
{ provide: Store, useValue: {} },
|
||||||
{ provide: Router, useValue: new RouterStub() },
|
{ provide: Router, useValue: new RouterStub() },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
@@ -113,6 +120,8 @@ describe('EPeopleRegistryComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(EPeopleRegistryComponent);
|
fixture = TestBed.createComponent(EPeopleRegistryComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
modalService = (component as any).modalService;
|
||||||
|
spyOn(modalService, 'open').and.returnValue(Object.assign({ componentInstance: Object.assign({ response: observableOf(true) }) }));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -17,6 +17,9 @@ import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
|||||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
|
import { ConfirmationModalComponent } from '../../../shared/confirmation-modal/confirmation-modal.component';
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { RequestService } from '../../../core/data/request.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-epeople-registry',
|
selector: 'ds-epeople-registry',
|
||||||
@@ -71,7 +74,9 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private authorizationService: AuthorizationDataService,
|
private authorizationService: AuthorizationDataService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private router: Router) {
|
private router: Router,
|
||||||
|
private modalService: NgbModal,
|
||||||
|
public requestService: RequestService) {
|
||||||
this.currentSearchQuery = '';
|
this.currentSearchQuery = '';
|
||||||
this.currentSearchScope = 'metadata';
|
this.currentSearchScope = 'metadata';
|
||||||
this.searchForm = this.formBuilder.group(({
|
this.searchForm = this.formBuilder.group(({
|
||||||
@@ -81,6 +86,13 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.initialisePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will initialise the page
|
||||||
|
*/
|
||||||
|
initialisePage() {
|
||||||
this.isEPersonFormShown = false;
|
this.isEPersonFormShown = false;
|
||||||
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
|
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
|
||||||
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
||||||
@@ -190,10 +202,20 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
* Deletes EPerson, show notification on success/failure & updates EPeople list
|
* Deletes EPerson, show notification on success/failure & updates EPeople list
|
||||||
*/
|
*/
|
||||||
deleteEPerson(ePerson: EPerson) {
|
deleteEPerson(ePerson: EPerson) {
|
||||||
|
if (hasValue(ePerson.id)) {
|
||||||
|
const modalRef = this.modalService.open(ConfirmationModalComponent);
|
||||||
|
modalRef.componentInstance.dso = ePerson;
|
||||||
|
modalRef.componentInstance.headerLabel = 'confirmation-modal.delete-eperson.header';
|
||||||
|
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
||||||
|
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
||||||
|
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
||||||
|
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||||
|
if (confirm) {
|
||||||
if (hasValue(ePerson.id)) {
|
if (hasValue(ePerson.id)) {
|
||||||
this.epersonService.deleteEPerson(ePerson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
this.epersonService.deleteEPerson(ePerson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||||
if (restResponse.isSuccessful) {
|
if (restResponse.isSuccessful) {
|
||||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: ePerson.name }));
|
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: ePerson.name }));
|
||||||
|
this.reset();
|
||||||
this.forceUpdateEPeople();
|
this.forceUpdateEPeople();
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + ePerson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.statusText);
|
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + ePerson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.statusText);
|
||||||
@@ -201,6 +223,8 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
this.epersonService.cancelEditEPerson();
|
this.epersonService.cancelEditEPerson();
|
||||||
this.isEPersonFormShown = false;
|
this.isEPersonFormShown = false;
|
||||||
})
|
})
|
||||||
|
}}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,4 +254,16 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
this.search({ query: '' });
|
this.search({ query: '' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will ensure that the page gets reset and that the cache is cleared
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
this.ePeopleDto$.pipe(take(1)).subscribe((epersons: PaginatedList<EpersonDtoModel>) => {
|
||||||
|
epersons.page.forEach((eperson: EpersonDtoModel) => {
|
||||||
|
this.requestService.removeByHrefSubstring(eperson.eperson.self);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this.initialisePage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,11 +2,11 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { EventEmitter, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, inject, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, inject, TestBed, tick } from '@angular/core/testing';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { BrowserModule, By } from '@angular/platform-browser';
|
import { BrowserModule, By } from '@angular/platform-browser';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal, NgbModule, NgbModalModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
|
||||||
@@ -286,16 +286,19 @@ describe('EPersonFormComponent', () => {
|
|||||||
|
|
||||||
let ePersonId;
|
let ePersonId;
|
||||||
let eperson: EPerson;
|
let eperson: EPerson;
|
||||||
|
let modalService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(authService, 'impersonate').and.callThrough();
|
spyOn(authService, 'impersonate').and.callThrough();
|
||||||
ePersonId = 'testEPersonId';
|
ePersonId = 'testEPersonId';
|
||||||
eperson = Object.assign(new EPerson(), {
|
eperson = EPersonMock;
|
||||||
id: ePersonId
|
|
||||||
});
|
|
||||||
component.epersonInitial = eperson;
|
component.epersonInitial = eperson;
|
||||||
component.canDelete$ = observableOf(true);
|
component.canDelete$ = observableOf(true);
|
||||||
spyOn(component.epersonService, 'getActiveEPerson').and.returnValue(observableOf(eperson));
|
spyOn(component.epersonService, 'getActiveEPerson').and.returnValue(observableOf(eperson));
|
||||||
|
modalService = (component as any).modalService;
|
||||||
|
spyOn(modalService, 'open').and.returnValue(Object.assign({ componentInstance: Object.assign({ response: observableOf(true) }) }));
|
||||||
|
fixture.detectChanges()
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it ('the delete button should be active if the eperson can be deleted', () => {
|
it ('the delete button should be active if the eperson can be deleted', () => {
|
||||||
@@ -312,6 +315,7 @@ describe('EPersonFormComponent', () => {
|
|||||||
|
|
||||||
it ('should call the epersonFormComponent delete when clicked on the button' , () => {
|
it ('should call the epersonFormComponent delete when clicked on the button' , () => {
|
||||||
spyOn(component, 'delete').and.stub();
|
spyOn(component, 'delete').and.stub();
|
||||||
|
spyOn(component.epersonService, 'deleteEPerson').and.returnValue(observableOf(new RestResponse(true, 204, 'No Content')));
|
||||||
const deleteButton = fixture.debugElement.query(By.css('.delete-button'));
|
const deleteButton = fixture.debugElement.query(By.css('.delete-button'));
|
||||||
deleteButton.triggerEventHandler('click', null);
|
deleteButton.triggerEventHandler('click', null);
|
||||||
expect(component.delete).toHaveBeenCalled();
|
expect(component.delete).toHaveBeenCalled();
|
||||||
|
@@ -7,7 +7,7 @@ import {
|
|||||||
DynamicInputModel
|
DynamicInputModel
|
||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Subscription, combineLatest, of } from 'rxjs';
|
import { Subscription, combineLatest, of, of as observableOf } from 'rxjs';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { switchMap, take } from 'rxjs/operators';
|
import { switchMap, take } from 'rxjs/operators';
|
||||||
import { RestResponse } from '../../../../core/cache/response.models';
|
import { RestResponse } from '../../../../core/cache/response.models';
|
||||||
@@ -25,6 +25,9 @@ import { PaginationComponentOptions } from '../../../../shared/pagination/pagina
|
|||||||
import { AuthService } from '../../../../core/auth/auth.service';
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||||
import { FeatureID } from '../../../../core/data/feature-authorization/feature-id';
|
import { FeatureID } from '../../../../core/data/feature-authorization/feature-id';
|
||||||
|
import { ConfirmationModalComponent } from '../../../../shared/confirmation-modal/confirmation-modal.component';
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { RequestService } from '../../../../core/data/request.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-eperson-form',
|
selector: 'ds-eperson-form',
|
||||||
@@ -159,7 +162,9 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private authorizationService: AuthorizationDataService) {
|
private authorizationService: AuthorizationDataService,
|
||||||
|
private modalService: NgbModal,
|
||||||
|
public requestService: RequestService) {
|
||||||
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
||||||
this.epersonInitial = eperson;
|
this.epersonInitial = eperson;
|
||||||
if (hasValue(eperson)) {
|
if (hasValue(eperson)) {
|
||||||
@@ -169,6 +174,13 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.initialisePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will initialise the page
|
||||||
|
*/
|
||||||
|
initialisePage() {
|
||||||
combineLatest(
|
combineLatest(
|
||||||
this.translateService.get(`${this.messagePrefix}.firstName`),
|
this.translateService.get(`${this.messagePrefix}.firstName`),
|
||||||
this.translateService.get(`${this.messagePrefix}.lastName`),
|
this.translateService.get(`${this.messagePrefix}.lastName`),
|
||||||
@@ -413,18 +425,27 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
delete() {
|
delete() {
|
||||||
this.epersonService.getActiveEPerson().pipe(take(1)).subscribe((eperson: EPerson) => {
|
this.epersonService.getActiveEPerson().pipe(take(1)).subscribe((eperson: EPerson) => {
|
||||||
|
const modalRef = this.modalService.open(ConfirmationModalComponent);
|
||||||
|
modalRef.componentInstance.dso = eperson;
|
||||||
|
modalRef.componentInstance.headerLabel = 'confirmation-modal.delete-eperson.header';
|
||||||
|
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
||||||
|
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
||||||
|
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
||||||
|
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||||
|
if (confirm) {
|
||||||
if (hasValue(eperson.id)) {
|
if (hasValue(eperson.id)) {
|
||||||
this.epersonService.deleteEPerson(eperson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
this.epersonService.deleteEPerson(eperson).pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||||
if (restResponse.isSuccessful) {
|
if (restResponse.isSuccessful) {
|
||||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: eperson.name }));
|
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: eperson.name }));
|
||||||
|
this.reset();
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + eperson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.statusText);
|
this.notificationsService.error('Error occured when trying to delete EPerson with id: ' + eperson.id + ' with code: ' + restResponse.statusCode + ' and message: ' + restResponse.statusText);
|
||||||
}
|
}
|
||||||
this.cancelForm.emit();
|
this.cancelForm.emit();
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
)
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -442,4 +463,14 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
this.onCancel();
|
this.onCancel();
|
||||||
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
|
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will ensure that the page gets reset and that the cache is cleared
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
this.epersonService.getActiveEPerson().pipe(take(1)).subscribe((eperson: EPerson) => {
|
||||||
|
this.requestService.removeByHrefSubstring(eperson.self);
|
||||||
|
});
|
||||||
|
this.initialisePage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -258,6 +258,10 @@
|
|||||||
|
|
||||||
"admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"",
|
"admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"",
|
||||||
|
|
||||||
"admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:",
|
"admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:",
|
||||||
|
|
||||||
"admin.access-control.epeople.form.table.id": "ID",
|
"admin.access-control.epeople.form.table.id": "ID",
|
||||||
@@ -1003,6 +1007,13 @@
|
|||||||
|
|
||||||
"confirmation-modal.export-metadata.confirm": "Export",
|
"confirmation-modal.export-metadata.confirm": "Export",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-eperson.cancel": "Cancel",
|
||||||
|
|
||||||
|
"confirmation-modal.delete-eperson.confirm": "Delete",
|
||||||
|
|
||||||
|
|
||||||
"error.bitstream": "Error fetching bitstream",
|
"error.bitstream": "Error fetching bitstream",
|
||||||
|
Reference in New Issue
Block a user