mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Created separate pages for edit & create EPersons
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
||||||
import { getAccessControlModuleRoute } from '../app-routing-paths';
|
import { getAccessControlModuleRoute } from '../app-routing-paths';
|
||||||
|
|
||||||
|
export const EPERSON_PATH = 'epeople';
|
||||||
|
|
||||||
|
export function getEPersonsRoute(): string {
|
||||||
|
return new URLCombiner(getAccessControlModuleRoute(), EPERSON_PATH).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEPersonEditRoute(id: string): string {
|
||||||
|
return new URLCombiner(getEPersonsRoute(), id).toString();
|
||||||
|
}
|
||||||
|
|
||||||
export const GROUP_EDIT_PATH = 'groups';
|
export const GROUP_EDIT_PATH = 'groups';
|
||||||
|
|
||||||
export function getGroupsRoute() {
|
export function getGroupsRoute() {
|
||||||
|
@@ -3,7 +3,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
import { EPeopleRegistryComponent } from './epeople-registry/epeople-registry.component';
|
import { EPeopleRegistryComponent } from './epeople-registry/epeople-registry.component';
|
||||||
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
|
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
|
||||||
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
|
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
|
||||||
import { GROUP_EDIT_PATH } from './access-control-routing-paths';
|
import { EPERSON_PATH, GROUP_EDIT_PATH } from './access-control-routing-paths';
|
||||||
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
import { GroupPageGuard } from './group-registry/group-page.guard';
|
import { GroupPageGuard } from './group-registry/group-page.guard';
|
||||||
import {
|
import {
|
||||||
@@ -13,12 +13,14 @@ import {
|
|||||||
SiteAdministratorGuard
|
SiteAdministratorGuard
|
||||||
} from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
|
} from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
|
||||||
import { BulkAccessComponent } from './bulk-access/bulk-access.component';
|
import { BulkAccessComponent } from './bulk-access/bulk-access.component';
|
||||||
|
import { EPersonFormComponent } from './epeople-registry/eperson-form/eperson-form.component';
|
||||||
|
import { EPersonResolver } from './epeople-registry/eperson-resolver.service';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forChild([
|
RouterModule.forChild([
|
||||||
{
|
{
|
||||||
path: 'epeople',
|
path: EPERSON_PATH,
|
||||||
component: EPeopleRegistryComponent,
|
component: EPeopleRegistryComponent,
|
||||||
resolve: {
|
resolve: {
|
||||||
breadcrumb: I18nBreadcrumbResolver
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
@@ -26,6 +28,25 @@ import { BulkAccessComponent } from './bulk-access/bulk-access.component';
|
|||||||
data: { title: 'admin.access-control.epeople.title', breadcrumbKey: 'admin.access-control.epeople' },
|
data: { title: 'admin.access-control.epeople.title', breadcrumbKey: 'admin.access-control.epeople' },
|
||||||
canActivate: [SiteAdministratorGuard]
|
canActivate: [SiteAdministratorGuard]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: `${EPERSON_PATH}/create`,
|
||||||
|
component: EPersonFormComponent,
|
||||||
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver,
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.epeople.add.title', breadcrumbKey: 'admin.access-control.epeople.add' },
|
||||||
|
canActivate: [SiteAdministratorGuard],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `${EPERSON_PATH}/:id`,
|
||||||
|
component: EPersonFormComponent,
|
||||||
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver,
|
||||||
|
ePerson: EPersonResolver,
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.epeople.edit.title', breadcrumbKey: 'admin.access-control.epeople.edit' },
|
||||||
|
canActivate: [SiteAdministratorGuard],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: GROUP_EDIT_PATH,
|
path: GROUP_EDIT_PATH,
|
||||||
component: GroupsRegistryComponent,
|
component: GroupsRegistryComponent,
|
||||||
|
@@ -4,19 +4,15 @@
|
|||||||
<div class="d-flex justify-content-between border-bottom mb-3">
|
<div class="d-flex justify-content-between border-bottom mb-3">
|
||||||
<h2 id="header" class="pb-2">{{labelPrefix + 'head' | translate}}</h2>
|
<h2 id="header" class="pb-2">{{labelPrefix + 'head' | translate}}</h2>
|
||||||
|
|
||||||
<div *ngIf="!isEPersonFormShown">
|
<div>
|
||||||
<button class="mr-auto btn btn-success addEPerson-button"
|
<button class="mr-auto btn btn-success addEPerson-button"
|
||||||
(click)="isEPersonFormShown = true">
|
[routerLink]="'create'">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
<span class="d-none d-sm-inline ml-1">{{labelPrefix + 'button.add' | translate}}</span>
|
<span class="d-none d-sm-inline ml-1">{{labelPrefix + 'button.add' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ds-eperson-form *ngIf="isEPersonFormShown" (submitForm)="reset()"
|
|
||||||
(cancelForm)="isEPersonFormShown = false"></ds-eperson-form>
|
|
||||||
|
|
||||||
<div *ngIf="!isEPersonFormShown">
|
|
||||||
<h3 id="search" class="border-bottom pb-2">{{labelPrefix + 'search.head' | translate}}
|
<h3 id="search" class="border-bottom pb-2">{{labelPrefix + 'search.head' | translate}}
|
||||||
|
|
||||||
</h3>
|
</h3>
|
||||||
@@ -72,7 +68,7 @@
|
|||||||
<td>{{epersonDto.eperson.email}}</td>
|
<td>{{epersonDto.eperson.email}}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group edit-field">
|
<div class="btn-group edit-field">
|
||||||
<button (click)="toggleEditEPerson(epersonDto.eperson)"
|
<button [routerLink]="getEditEPeoplePage(epersonDto.eperson.id)"
|
||||||
class="btn btn-outline-primary btn-sm access-control-editEPersonButton"
|
class="btn btn-outline-primary btn-sm access-control-editEPersonButton"
|
||||||
title="{{labelPrefix + 'table.edit.buttons.edit' | translate: { name: dsoNameService.getName(epersonDto.eperson) } }}">
|
title="{{labelPrefix + 'table.edit.buttons.edit' | translate: { name: dsoNameService.getName(epersonDto.eperson) } }}">
|
||||||
<i class="fas fa-edit fa-fw"></i>
|
<i class="fas fa-edit fa-fw"></i>
|
||||||
@@ -97,4 +93,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
@@ -203,36 +203,6 @@ describe('EPeopleRegistryComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('toggleEditEPerson', () => {
|
|
||||||
describe('when you click on first edit eperson button', () => {
|
|
||||||
beforeEach(fakeAsync(() => {
|
|
||||||
const editButtons = fixture.debugElement.queryAll(By.css('.access-control-editEPersonButton'));
|
|
||||||
editButtons[0].triggerEventHandler('click', {
|
|
||||||
preventDefault: () => {/**/
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tick();
|
|
||||||
fixture.detectChanges();
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('editEPerson form is toggled', () => {
|
|
||||||
const ePeopleIds = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
|
|
||||||
ePersonDataServiceStub.getActiveEPerson().subscribe((activeEPerson: EPerson) => {
|
|
||||||
if (ePeopleIds[0] && activeEPerson === ePeopleIds[0].nativeElement.textContent) {
|
|
||||||
expect(component.isEPersonFormShown).toEqual(false);
|
|
||||||
} else {
|
|
||||||
expect(component.isEPersonFormShown).toEqual(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('EPerson search section is hidden', () => {
|
|
||||||
expect(fixture.debugElement.query(By.css('#search'))).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('deleteEPerson', () => {
|
describe('deleteEPerson', () => {
|
||||||
describe('when you click on first delete eperson button', () => {
|
describe('when you click on first delete eperson button', () => {
|
||||||
let ePeopleIdsFoundBeforeDelete;
|
let ePeopleIdsFoundBeforeDelete;
|
||||||
|
@@ -22,6 +22,7 @@ import { PageInfo } from '../../core/shared/page-info.model';
|
|||||||
import { NoContent } from '../../core/shared/NoContent.model';
|
import { NoContent } from '../../core/shared/NoContent.model';
|
||||||
import { PaginationService } from '../../core/pagination/pagination.service';
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { getEPersonEditRoute, getEPersonsRoute } from '../access-control-routing-paths';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-epeople-registry',
|
selector: 'ds-epeople-registry',
|
||||||
@@ -64,11 +65,6 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
currentPage: 1
|
currentPage: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not to show the EPerson form
|
|
||||||
*/
|
|
||||||
isEPersonFormShown: boolean;
|
|
||||||
|
|
||||||
// The search form
|
// The search form
|
||||||
searchForm;
|
searchForm;
|
||||||
|
|
||||||
@@ -114,17 +110,11 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
initialisePage() {
|
initialisePage() {
|
||||||
this.searching$.next(true);
|
this.searching$.next(true);
|
||||||
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) => {
|
|
||||||
if (eperson != null && eperson.id) {
|
|
||||||
this.isEPersonFormShown = true;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
this.subs.push(this.ePeople$.pipe(
|
this.subs.push(this.ePeople$.pipe(
|
||||||
switchMap((epeople: PaginatedList<EPerson>) => {
|
switchMap((epeople: PaginatedList<EPerson>) => {
|
||||||
if (epeople.pageInfo.totalElements > 0) {
|
if (epeople.pageInfo.totalElements > 0) {
|
||||||
return combineLatest([...epeople.page.map((eperson: EPerson) => {
|
return combineLatest(epeople.page.map((eperson: EPerson) => {
|
||||||
return this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(eperson) ? eperson.self : undefined).pipe(
|
return this.authorizationService.isAuthorized(FeatureID.CanDelete, hasValue(eperson) ? eperson.self : undefined).pipe(
|
||||||
map((authorized) => {
|
map((authorized) => {
|
||||||
const epersonDtoModel: EpersonDtoModel = new EpersonDtoModel();
|
const epersonDtoModel: EpersonDtoModel = new EpersonDtoModel();
|
||||||
@@ -133,7 +123,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
return epersonDtoModel;
|
return epersonDtoModel;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
})]).pipe(map((dtos: EpersonDtoModel[]) => {
|
})).pipe(map((dtos: EpersonDtoModel[]) => {
|
||||||
return buildPaginatedList(epeople.pageInfo, dtos);
|
return buildPaginatedList(epeople.pageInfo, dtos);
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
@@ -160,14 +150,14 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
const query: string = data.query;
|
const query: string = data.query;
|
||||||
const scope: string = data.scope;
|
const scope: string = data.scope;
|
||||||
if (query != null && this.currentSearchQuery !== query) {
|
if (query != null && this.currentSearchQuery !== query) {
|
||||||
this.router.navigate([this.epersonService.getEPeoplePageRouterLink()], {
|
void this.router.navigate([getEPersonsRoute()], {
|
||||||
queryParamsHandling: 'merge'
|
queryParamsHandling: 'merge'
|
||||||
});
|
});
|
||||||
this.currentSearchQuery = query;
|
this.currentSearchQuery = query;
|
||||||
this.paginationService.resetPage(this.config.id);
|
this.paginationService.resetPage(this.config.id);
|
||||||
}
|
}
|
||||||
if (scope != null && this.currentSearchScope !== scope) {
|
if (scope != null && this.currentSearchScope !== scope) {
|
||||||
this.router.navigate([this.epersonService.getEPeoplePageRouterLink()], {
|
void this.router.navigate([getEPersonsRoute()], {
|
||||||
queryParamsHandling: 'merge'
|
queryParamsHandling: 'merge'
|
||||||
});
|
});
|
||||||
this.currentSearchScope = scope;
|
this.currentSearchScope = scope;
|
||||||
@@ -205,23 +195,6 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
return this.epersonService.getActiveEPerson();
|
return this.epersonService.getActiveEPerson();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Start editing the selected EPerson
|
|
||||||
* @param ePerson
|
|
||||||
*/
|
|
||||||
toggleEditEPerson(ePerson: EPerson) {
|
|
||||||
this.getActiveEPerson().pipe(take(1)).subscribe((activeEPerson: EPerson) => {
|
|
||||||
if (ePerson === activeEPerson) {
|
|
||||||
this.epersonService.cancelEditEPerson();
|
|
||||||
this.isEPersonFormShown = false;
|
|
||||||
} else {
|
|
||||||
this.epersonService.editEPerson(ePerson);
|
|
||||||
this.isEPersonFormShown = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.scrollToTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes EPerson, show notification on success/failure & updates EPeople list
|
* Deletes EPerson, show notification on success/failure & updates EPeople list
|
||||||
*/
|
*/
|
||||||
@@ -264,16 +237,6 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
|
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToTop() {
|
|
||||||
(function smoothscroll() {
|
|
||||||
const currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
|
|
||||||
if (currentScroll > 0) {
|
|
||||||
window.requestAnimationFrame(smoothscroll);
|
|
||||||
window.scrollTo(0, currentScroll - (currentScroll / 8));
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset all input-fields to be empty and search all search
|
* Reset all input-fields to be empty and search all search
|
||||||
*/
|
*/
|
||||||
@@ -284,20 +247,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
this.search({query: ''});
|
this.search({query: ''});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getEditEPeoplePage(id: string): string {
|
||||||
* This method will set everything to stale, which will cause the lists on this page to update.
|
return getEPersonEditRoute(id);
|
||||||
*/
|
|
||||||
reset(): void {
|
|
||||||
this.epersonService.getBrowseEndpoint().pipe(
|
|
||||||
take(1),
|
|
||||||
switchMap((href: string) => {
|
|
||||||
return this.requestService.setStaleByHrefSubstring(href).pipe(
|
|
||||||
take(1),
|
|
||||||
);
|
|
||||||
})
|
|
||||||
).subscribe(()=>{
|
|
||||||
this.epersonService.cancelEditEPerson();
|
|
||||||
this.isEPersonFormShown = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
<div *ngIf="epersonService.getActiveEPerson() | async; then editheader; else createHeader"></div>
|
<div class="container">
|
||||||
|
<div class="group-form row">
|
||||||
|
<div class="col-12">
|
||||||
|
|
||||||
|
<div *ngIf="epersonService.getActiveEPerson() | async; then editHeader; else createHeader"></div>
|
||||||
|
|
||||||
<ng-template #createHeader>
|
<ng-template #createHeader>
|
||||||
<h4>{{messagePrefix + '.create' | translate}}</h4>
|
<h2 class="border-bottom pb-2">{{messagePrefix + '.create' | translate}}</h2>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #editheader>
|
<ng-template #editHeader>
|
||||||
<h4>{{messagePrefix + '.edit' | translate}}</h4>
|
<h2 class="border-bottom pb-2">{{messagePrefix + '.edit' | translate}}</h2>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ds-form [formId]="formId"
|
<ds-form [formId]="formId"
|
||||||
@@ -16,8 +20,9 @@
|
|||||||
[submitLabel]="submitLabel"
|
[submitLabel]="submitLabel"
|
||||||
(submitForm)="onSubmit()">
|
(submitForm)="onSubmit()">
|
||||||
<div before class="btn-group">
|
<div before class="btn-group">
|
||||||
<button (click)="onCancel()"
|
<button (click)="onCancel()" class="btn btn-outline-secondary">
|
||||||
class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button>
|
<i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="displayResetPassword" between class="btn-group">
|
<div *ngIf="displayResetPassword" between class="btn-group">
|
||||||
<button class="btn btn-primary" [disabled]="!(canReset$ | async)" (click)="resetPassword()">
|
<button class="btn btn-primary" [disabled]="!(canReset$ | async)" (click)="resetPassword()">
|
||||||
@@ -25,7 +30,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div between class="btn-group ml-1">
|
<div between class="btn-group ml-1">
|
||||||
<button *ngIf="!isImpersonated" class="btn btn-primary" [ngClass]="{'d-none' : !(canImpersonate$ | async)}" (click)="impersonate()">
|
<button *ngIf="!isImpersonated" class="btn btn-primary" [ngClass]="{'d-none' : !(canImpersonate$ | async)}"
|
||||||
|
(click)="impersonate()">
|
||||||
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}}
|
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="isImpersonated" class="btn btn-primary" (click)="stopImpersonating()">
|
<button *ngIf="isImpersonated" class="btn btn-primary" (click)="stopImpersonating()">
|
||||||
@@ -87,3 +93,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@@ -31,6 +31,10 @@ import { PaginationServiceStub } from '../../../shared/testing/pagination-servic
|
|||||||
import { FindListOptions } from '../../../core/data/find-list-options.model';
|
import { FindListOptions } from '../../../core/data/find-list-options.model';
|
||||||
import { ValidateEmailNotTaken } from './validators/email-taken.validator';
|
import { ValidateEmailNotTaken } from './validators/email-taken.validator';
|
||||||
import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service';
|
import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service';
|
||||||
|
import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||||
|
import { ActivatedRouteStub } from '../../../shared/testing/active-router.stub';
|
||||||
|
|
||||||
describe('EPersonFormComponent', () => {
|
describe('EPersonFormComponent', () => {
|
||||||
let component: EPersonFormComponent;
|
let component: EPersonFormComponent;
|
||||||
@@ -43,6 +47,8 @@ describe('EPersonFormComponent', () => {
|
|||||||
let authorizationService: AuthorizationDataService;
|
let authorizationService: AuthorizationDataService;
|
||||||
let groupsDataService: GroupDataService;
|
let groupsDataService: GroupDataService;
|
||||||
let epersonRegistrationService: EpersonRegistrationService;
|
let epersonRegistrationService: EpersonRegistrationService;
|
||||||
|
let route: ActivatedRouteStub;
|
||||||
|
let router: RouterStub;
|
||||||
|
|
||||||
let paginationService;
|
let paginationService;
|
||||||
|
|
||||||
@@ -106,6 +112,9 @@ describe('EPersonFormComponent', () => {
|
|||||||
},
|
},
|
||||||
getEPersonByEmail(email): Observable<RemoteData<EPerson>> {
|
getEPersonByEmail(email): Observable<RemoteData<EPerson>> {
|
||||||
return createSuccessfulRemoteDataObject$(null);
|
return createSuccessfulRemoteDataObject$(null);
|
||||||
|
},
|
||||||
|
findById(_id: string, _useCachedVersionIfAvailable = true, _reRequestOnStale = true, ..._linksToFollow: FollowLinkConfig<EPerson>[]): Observable<RemoteData<EPerson>> {
|
||||||
|
return createSuccessfulRemoteDataObject$(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
builderService = Object.assign(getMockFormBuilderService(),{
|
builderService = Object.assign(getMockFormBuilderService(),{
|
||||||
@@ -182,6 +191,8 @@ describe('EPersonFormComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
paginationService = new PaginationServiceStub();
|
paginationService = new PaginationServiceStub();
|
||||||
|
route = new ActivatedRouteStub();
|
||||||
|
router = new RouterStub();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
|
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
@@ -202,6 +213,8 @@ describe('EPersonFormComponent', () => {
|
|||||||
{ provide: PaginationService, useValue: paginationService },
|
{ provide: PaginationService, useValue: paginationService },
|
||||||
{ provide: RequestService, useValue: jasmine.createSpyObj('requestService', ['removeByHrefSubstring'])},
|
{ provide: RequestService, useValue: jasmine.createSpyObj('requestService', ['removeByHrefSubstring'])},
|
||||||
{ provide: EpersonRegistrationService, useValue: epersonRegistrationService },
|
{ provide: EpersonRegistrationService, useValue: epersonRegistrationService },
|
||||||
|
{ provide: ActivatedRoute, useValue: route },
|
||||||
|
{ provide: Router, useValue: router },
|
||||||
EPeopleRegistryComponent
|
EPeopleRegistryComponent
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
@@ -263,24 +276,18 @@ describe('EPersonFormComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
describe('firstName, lastName and email should be required', () => {
|
describe('firstName, lastName and email should be required', () => {
|
||||||
it('form should be invalid because the firstName is required', waitForAsync(() => {
|
it('form should be invalid because the firstName is required', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.firstName.valid).toBeFalse();
|
expect(component.formGroup.controls.firstName.valid).toBeFalse();
|
||||||
expect(component.formGroup.controls.firstName.errors.required).toBeTrue();
|
expect(component.formGroup.controls.firstName.errors.required).toBeTrue();
|
||||||
});
|
});
|
||||||
}));
|
it('form should be invalid because the lastName is required', () => {
|
||||||
it('form should be invalid because the lastName is required', waitForAsync(() => {
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.lastName.valid).toBeFalse();
|
expect(component.formGroup.controls.lastName.valid).toBeFalse();
|
||||||
expect(component.formGroup.controls.lastName.errors.required).toBeTrue();
|
expect(component.formGroup.controls.lastName.errors.required).toBeTrue();
|
||||||
});
|
});
|
||||||
}));
|
it('form should be invalid because the email is required', () => {
|
||||||
it('form should be invalid because the email is required', waitForAsync(() => {
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.email.valid).toBeFalse();
|
expect(component.formGroup.controls.email.valid).toBeFalse();
|
||||||
expect(component.formGroup.controls.email.errors.required).toBeTrue();
|
expect(component.formGroup.controls.email.errors.required).toBeTrue();
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('after inserting information firstName,lastName and email not required', () => {
|
describe('after inserting information firstName,lastName and email not required', () => {
|
||||||
@@ -290,24 +297,18 @@ describe('EPersonFormComponent', () => {
|
|||||||
component.formGroup.controls.email.setValue('test@test.com');
|
component.formGroup.controls.email.setValue('test@test.com');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
it('firstName should be valid because the firstName is set', waitForAsync(() => {
|
it('firstName should be valid because the firstName is set', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.firstName.valid).toBeTrue();
|
expect(component.formGroup.controls.firstName.valid).toBeTrue();
|
||||||
expect(component.formGroup.controls.firstName.errors).toBeNull();
|
expect(component.formGroup.controls.firstName.errors).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
it('lastName should be valid because the lastName is set', () => {
|
||||||
it('lastName should be valid because the lastName is set', waitForAsync(() => {
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.lastName.valid).toBeTrue();
|
expect(component.formGroup.controls.lastName.valid).toBeTrue();
|
||||||
expect(component.formGroup.controls.lastName.errors).toBeNull();
|
expect(component.formGroup.controls.lastName.errors).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
it('email should be valid because the email is set', () => {
|
||||||
it('email should be valid because the email is set', waitForAsync(() => {
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.email.valid).toBeTrue();
|
expect(component.formGroup.controls.email.valid).toBeTrue();
|
||||||
expect(component.formGroup.controls.email.errors).toBeNull();
|
expect(component.formGroup.controls.email.errors).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -316,12 +317,10 @@ describe('EPersonFormComponent', () => {
|
|||||||
component.formGroup.controls.email.setValue('test@test');
|
component.formGroup.controls.email.setValue('test@test');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
it('email should not be valid because the email pattern', waitForAsync(() => {
|
it('email should not be valid because the email pattern', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.email.valid).toBeFalse();
|
expect(component.formGroup.controls.email.valid).toBeFalse();
|
||||||
expect(component.formGroup.controls.email.errors.pattern).toBeTruthy();
|
expect(component.formGroup.controls.email.errors.pattern).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('after already utilized email', () => {
|
describe('after already utilized email', () => {
|
||||||
@@ -336,12 +335,10 @@ describe('EPersonFormComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('email should not be valid because email is already taken', waitForAsync(() => {
|
it('email should not be valid because email is already taken', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.formGroup.controls.email.valid).toBeFalse();
|
expect(component.formGroup.controls.email.valid).toBeFalse();
|
||||||
expect(component.formGroup.controls.email.errors.emailTaken).toBeTruthy();
|
expect(component.formGroup.controls.email.errors.emailTaken).toBeTruthy();
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -393,11 +390,9 @@ describe('EPersonFormComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit a new eperson using the correct values', waitForAsync(() => {
|
it('should emit a new eperson using the correct values', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.submitForm.emit).toHaveBeenCalledWith(expected);
|
expect(component.submitForm.emit).toHaveBeenCalledWith(expected);
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with an active eperson', () => {
|
describe('with an active eperson', () => {
|
||||||
@@ -428,11 +423,9 @@ describe('EPersonFormComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit the existing eperson using the correct values', waitForAsync(() => {
|
it('should emit the existing eperson using the correct values', () => {
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(component.submitForm.emit).toHaveBeenCalledWith(expectedWithId);
|
expect(component.submitForm.emit).toHaveBeenCalledWith(expectedWithId);
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -38,6 +38,8 @@ import { Registration } from '../../../core/shared/registration.model';
|
|||||||
import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service';
|
import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service';
|
||||||
import { TYPE_REQUEST_FORGOT } from '../../../register-email-form/register-email-form.component';
|
import { TYPE_REQUEST_FORGOT } from '../../../register-email-form/register-email-form.component';
|
||||||
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { getEPersonsRoute } from '../../access-control-routing-paths';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-eperson-form',
|
selector: 'ds-eperson-form',
|
||||||
@@ -194,6 +196,8 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
public requestService: RequestService,
|
public requestService: RequestService,
|
||||||
private epersonRegistrationService: EpersonRegistrationService,
|
private epersonRegistrationService: EpersonRegistrationService,
|
||||||
public dsoNameService: DSONameService,
|
public dsoNameService: DSONameService,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected router: Router,
|
||||||
) {
|
) {
|
||||||
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
||||||
this.epersonInitial = eperson;
|
this.epersonInitial = eperson;
|
||||||
@@ -213,7 +217,9 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
* This method will initialise the page
|
* This method will initialise the page
|
||||||
*/
|
*/
|
||||||
initialisePage() {
|
initialisePage() {
|
||||||
|
this.subs.push(this.epersonService.findById(this.route.snapshot.params.id).subscribe((ePersonRD: RemoteData<EPerson>) => {
|
||||||
|
this.epersonService.editEPerson(ePersonRD.payload);
|
||||||
|
}));
|
||||||
observableCombineLatest([
|
observableCombineLatest([
|
||||||
this.translateService.get(`${this.messagePrefix}.firstName`),
|
this.translateService.get(`${this.messagePrefix}.firstName`),
|
||||||
this.translateService.get(`${this.messagePrefix}.lastName`),
|
this.translateService.get(`${this.messagePrefix}.lastName`),
|
||||||
@@ -339,6 +345,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
onCancel() {
|
onCancel() {
|
||||||
this.epersonService.cancelEditEPerson();
|
this.epersonService.cancelEditEPerson();
|
||||||
this.cancelForm.emit();
|
this.cancelForm.emit();
|
||||||
|
void this.router.navigate([getEPersonsRoute()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,6 +397,8 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
if (rd.hasSucceeded) {
|
if (rd.hasSucceeded) {
|
||||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: this.dsoNameService.getName(ePersonToCreate) }));
|
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.created.success', { name: this.dsoNameService.getName(ePersonToCreate) }));
|
||||||
this.submitForm.emit(ePersonToCreate);
|
this.submitForm.emit(ePersonToCreate);
|
||||||
|
this.epersonService.clearEPersonRequests();
|
||||||
|
void this.router.navigateByUrl(getEPersonsRoute());
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure', { name: this.dsoNameService.getName(ePersonToCreate) }));
|
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.created.failure', { name: this.dsoNameService.getName(ePersonToCreate) }));
|
||||||
this.cancelForm.emit();
|
this.cancelForm.emit();
|
||||||
@@ -429,6 +438,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
if (rd.hasSucceeded) {
|
if (rd.hasSucceeded) {
|
||||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: this.dsoNameService.getName(editedEperson) }));
|
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.edited.success', { name: this.dsoNameService.getName(editedEperson) }));
|
||||||
this.submitForm.emit(editedEperson);
|
this.submitForm.emit(editedEperson);
|
||||||
|
void this.router.navigateByUrl(getEPersonsRoute());
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.edited.failure', { name: this.dsoNameService.getName(editedEperson) }));
|
this.notificationsService.error(this.translateService.get(this.labelPrefix + 'notification.edited.failure', { name: this.dsoNameService.getName(editedEperson) }));
|
||||||
this.cancelForm.emit();
|
this.cancelForm.emit();
|
||||||
@@ -495,6 +505,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
).subscribe(({ restResponse, eperson }: { restResponse: RemoteData<NoContent> | null, eperson: EPerson }) => {
|
).subscribe(({ restResponse, eperson }: { restResponse: RemoteData<NoContent> | null, eperson: EPerson }) => {
|
||||||
if (restResponse?.hasSucceeded) {
|
if (restResponse?.hasSucceeded) {
|
||||||
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: this.dsoNameService.getName(eperson) }));
|
this.notificationsService.success(this.translateService.get(this.labelPrefix + 'notification.deleted.success', { name: this.dsoNameService.getName(eperson) }));
|
||||||
|
void this.router.navigate([getEPersonsRoute()]);
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.error(`Error occurred when trying to delete EPerson with id: ${eperson?.id} with code: ${restResponse?.statusCode} and message: ${restResponse?.errorMessage}`);
|
this.notificationsService.error(`Error occurred when trying to delete EPerson with id: ${eperson?.id} with code: ${restResponse?.statusCode} and message: ${restResponse?.errorMessage}`);
|
||||||
}
|
}
|
||||||
@@ -541,16 +552,6 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for the given ePerson if there is already an ePerson in the system with that email
|
* Checks for the given ePerson if there is already an ePerson in the system with that email
|
||||||
* and shows notification if this is the case
|
* and shows notification if this is the case
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
|
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||||
|
import { ResolvedAction } from '../../core/resolving/resolver.actions';
|
||||||
|
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
|
|
||||||
|
export const EPERSON_EDIT_FOLLOW_LINKS: FollowLinkConfig<EPerson>[] = [
|
||||||
|
followLink('groups'),
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a resolver that requests a specific {@link EPerson} before the route is activated
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class EPersonResolver implements Resolve<RemoteData<EPerson>> {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected ePersonService: EPersonDataService,
|
||||||
|
protected store: Store<any>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for resolving a {@link EPerson} based on the parameters in the current route
|
||||||
|
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
|
||||||
|
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
|
||||||
|
* @returns `Observable<<RemoteData<EPerson>>` Emits the found {@link EPerson} based on the parameters in the current
|
||||||
|
* route, or an error if something went wrong
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<EPerson>> {
|
||||||
|
const ePersonRD$: Observable<RemoteData<EPerson>> = this.ePersonService.findById(route.params.id,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
...EPERSON_EDIT_FOLLOW_LINKS,
|
||||||
|
).pipe(
|
||||||
|
getFirstCompletedRemoteData(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ePersonRD$.subscribe((ePersonRD: RemoteData<EPerson>) => {
|
||||||
|
this.store.dispatch(new ResolvedAction(state.url, ePersonRD.payload));
|
||||||
|
});
|
||||||
|
|
||||||
|
return ePersonRD$;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -248,6 +248,14 @@
|
|||||||
|
|
||||||
"admin.access-control.epeople.title": "EPeople",
|
"admin.access-control.epeople.title": "EPeople",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.edit.breadcrumbs": "New EPerson",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.edit.title": "New EPerson",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.add.breadcrumbs": "Add EPerson",
|
||||||
|
|
||||||
|
"admin.access-control.epeople.add.title": "Add EPerson",
|
||||||
|
|
||||||
"admin.access-control.epeople.head": "EPeople",
|
"admin.access-control.epeople.head": "EPeople",
|
||||||
|
|
||||||
"admin.access-control.epeople.search.head": "Search",
|
"admin.access-control.epeople.search.head": "Search",
|
||||||
|
Reference in New Issue
Block a user