mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[CST-5674] Edit policy target; modal content; test
This commit is contained in:
@@ -19,6 +19,8 @@ import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils
|
|||||||
import { RestResponse } from '../cache/response.models';
|
import { RestResponse } from '../cache/response.models';
|
||||||
import { RequestEntry } from '../data/request-entry.model';
|
import { RequestEntry } from '../data/request-entry.model';
|
||||||
import { FindListOptions } from '../data/find-list-options.model';
|
import { FindListOptions } from '../data/find-list-options.model';
|
||||||
|
import { EPersonDataService } from '../eperson/eperson-data.service';
|
||||||
|
import { GroupDataService } from '../eperson/group-data.service';
|
||||||
|
|
||||||
describe('ResourcePolicyService', () => {
|
describe('ResourcePolicyService', () => {
|
||||||
let scheduler: TestScheduler;
|
let scheduler: TestScheduler;
|
||||||
@@ -28,6 +30,8 @@ describe('ResourcePolicyService', () => {
|
|||||||
let objectCache: ObjectCacheService;
|
let objectCache: ObjectCacheService;
|
||||||
let halService: HALEndpointService;
|
let halService: HALEndpointService;
|
||||||
let responseCacheEntry: RequestEntry;
|
let responseCacheEntry: RequestEntry;
|
||||||
|
let ePersonService: EPersonDataService;
|
||||||
|
let groupService: GroupDataService;
|
||||||
|
|
||||||
const resourcePolicy: any = {
|
const resourcePolicy: any = {
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -129,7 +133,9 @@ describe('ResourcePolicyService', () => {
|
|||||||
halService,
|
halService,
|
||||||
notificationsService,
|
notificationsService,
|
||||||
http,
|
http,
|
||||||
comparator
|
comparator,
|
||||||
|
ePersonService,
|
||||||
|
groupService
|
||||||
);
|
);
|
||||||
|
|
||||||
spyOn((service as any).dataService, 'create').and.callThrough();
|
spyOn((service as any).dataService, 'create').and.callThrough();
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable max-classes-per-file */
|
/* eslint-disable max-classes-per-file */
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@@ -23,11 +23,19 @@ import { PaginatedList } from '../data/paginated-list.model';
|
|||||||
import { ActionType } from './models/action-type.model';
|
import { ActionType } from './models/action-type.model';
|
||||||
import { RequestParam } from '../cache/models/request-param.model';
|
import { RequestParam } from '../cache/models/request-param.model';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { isNotEmpty } from '../../shared/empty.util';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { NoContent } from '../shared/NoContent.model';
|
import { NoContent } from '../shared/NoContent.model';
|
||||||
import { getFirstCompletedRemoteData } from '../shared/operators';
|
import { getFirstCompletedRemoteData } from '../shared/operators';
|
||||||
import { CoreState } from '../core-state.model';
|
import { CoreState } from '../core-state.model';
|
||||||
import { FindListOptions } from '../data/find-list-options.model';
|
import { FindListOptions } from '../data/find-list-options.model';
|
||||||
|
import { HttpOptions } from '../dspace-rest/dspace-rest.service';
|
||||||
|
import { PostRequest } from '../data/request.models';
|
||||||
|
import { GenericConstructor } from '../shared/generic-constructor';
|
||||||
|
import { ResponseParsingService } from '../data/parsing.service';
|
||||||
|
import { StatusCodeOnlyResponseParsingService } from '../data/status-code-only-response-parsing.service';
|
||||||
|
import { HALLink } from '../shared/hal-link.model';
|
||||||
|
import { EPersonDataService } from '../eperson/eperson-data.service';
|
||||||
|
import { GroupDataService } from '../eperson/group-data.service';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +52,8 @@ class DataServiceImpl extends DataService<ResourcePolicy> {
|
|||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: ChangeAnalyzer<ResourcePolicy>) {
|
protected comparator: ChangeAnalyzer<ResourcePolicy>,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +77,10 @@ export class ResourcePolicyService {
|
|||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DefaultChangeAnalyzer<ResourcePolicy>) {
|
protected comparator: DefaultChangeAnalyzer<ResourcePolicy>,
|
||||||
|
protected ePersonService: EPersonDataService,
|
||||||
|
protected groupService: GroupDataService,
|
||||||
|
) {
|
||||||
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
|
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,4 +233,39 @@ export class ResourcePolicyService {
|
|||||||
return this.dataService.searchBy(this.searchByResourceMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
return this.dataService.searchBy(this.searchByResourceMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the target of the resource policy
|
||||||
|
* @param resourcePolicyHref the link to the resource policy
|
||||||
|
* @param uuid the UUID of the target to which the permission is being granted
|
||||||
|
* @param type the type of the target (eperson or group) to which the permission is being granted
|
||||||
|
*/
|
||||||
|
updateTarget(resourcePolicyHref: string, uuid: string, type: string): Observable<RemoteData<any>> {
|
||||||
|
|
||||||
|
const targetService = type === 'eperson' ? this.ePersonService : this.groupService;
|
||||||
|
|
||||||
|
const ep$ = targetService.getBrowseEndpoint().pipe(
|
||||||
|
take(1),
|
||||||
|
map((endpoint: string) =>`${endpoint}/${uuid}`),
|
||||||
|
);
|
||||||
|
|
||||||
|
const options: HttpOptions = Object.create({});
|
||||||
|
let headers = new HttpHeaders();
|
||||||
|
headers = headers.append('Content-Type', 'text/uri-list');
|
||||||
|
options.headers = headers;
|
||||||
|
|
||||||
|
const requestId = this.requestService.generateRequestId();
|
||||||
|
|
||||||
|
return ep$.pipe(switchMap((ep) => {
|
||||||
|
const request = new PostRequest(requestId, resourcePolicyHref, ep, options);
|
||||||
|
Object.assign(request, {
|
||||||
|
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
||||||
|
return StatusCodeOnlyResponseParsingService;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.requestService.send(request);
|
||||||
|
return this.rdbService.buildFromRequestUUID(requestId);
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable, of, combineLatest as observableCombineLatest, } from 'rxjs';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, take } from 'rxjs/operators';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
@@ -88,16 +88,29 @@ export class ResourcePolicyEditComponent implements OnInit {
|
|||||||
type: RESOURCE_POLICY.value,
|
type: RESOURCE_POLICY.value,
|
||||||
_links: this.resourcePolicy._links
|
_links: this.resourcePolicy._links
|
||||||
});
|
});
|
||||||
this.resourcePolicyService.update(updatedObject).pipe(
|
|
||||||
|
const updateTargetSucceeded$ = event.updateTarget ? this.resourcePolicyService.updateTarget(
|
||||||
|
this.resourcePolicy._links.self.href, event.target.uuid, event.target.type
|
||||||
|
).pipe(
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
).subscribe((responseRD: RemoteData<ResourcePolicy>) => {
|
map((responseRD) => responseRD && responseRD.hasSucceeded)
|
||||||
this.processing$.next(false);
|
) : of(true);
|
||||||
if (responseRD && responseRD.hasSucceeded) {
|
|
||||||
this.notificationsService.success(null, this.translate.get('resource-policies.edit.page.success.content'));
|
const updateResourcePolicySucceeded$ = this.resourcePolicyService.update(updatedObject).pipe(
|
||||||
this.redirectToAuthorizationsPage();
|
getFirstCompletedRemoteData(),
|
||||||
} else {
|
map((responseRD) => responseRD && responseRD.hasSucceeded)
|
||||||
this.notificationsService.error(null, this.translate.get('resource-policies.edit.page.failure.content'));
|
);
|
||||||
|
|
||||||
|
observableCombineLatest([updateTargetSucceeded$, updateResourcePolicySucceeded$]).subscribe(
|
||||||
|
([updateTargetSucceeded, updateResourcePolicySucceeded]) => {
|
||||||
|
this.processing$.next(false);
|
||||||
|
if (updateTargetSucceeded && updateResourcePolicySucceeded) {
|
||||||
|
this.notificationsService.success(null, this.translate.get('resource-policies.edit.page.success.content'));
|
||||||
|
this.redirectToAuthorizationsPage();
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, this.translate.get('resource-policies.edit.page.failure.content'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,15 +55,24 @@
|
|||||||
|
|
||||||
<ng-template #content let-modal>
|
<ng-template #content let-modal>
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title" id="modal-basic-title">TITLE</h4>
|
<h4 class="modal-title" id="modal-basic-title">{{ 'resource-policies.form.eperson-group-list.modal.header' | translate }}</h4>
|
||||||
<button type="button" class="close" aria-label="Close" (click)="modal.close()">
|
<button type="button" class="close" aria-label="Close" (click)="modal.close()">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
TEXT
|
<div class="d-flex flex-row">
|
||||||
|
<div class="mr-3">
|
||||||
|
<i class="fas fa-info-circle fa-2x text-info"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p [innerHTML]="(navActiveId === 'eperson' ? 'resource-policies.form.eperson-group-list.modal.text1.toGroup' :
|
||||||
|
'resource-policies.form.eperson-group-list.modal.text1.toEPerson') | translate" class="font-weight-bold"></p>
|
||||||
|
<p [innerHTML]="'resource-policies.form.eperson-group-list.modal.text2' | translate"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline-dark" (click)="modal.close()">Ok</button>
|
<button type="button" class="btn btn-secondary" (click)="modal.close()">{{ 'resource-policies.form.eperson-group-list.modal.close' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@@ -222,6 +222,8 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
|
|
||||||
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
||||||
testComp = testFixture.componentInstance;
|
testComp = testFixture.componentInstance;
|
||||||
|
testComp.resourcePolicy = resourcePolicy;
|
||||||
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -242,6 +244,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
fixture = TestBed.createComponent(ResourcePolicyFormComponent);
|
fixture = TestBed.createComponent(ResourcePolicyFormComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
compAsAny = fixture.componentInstance;
|
compAsAny = fixture.componentInstance;
|
||||||
|
compAsAny.resourcePolicy = resourcePolicy;
|
||||||
comp.isProcessing = observableOf(false);
|
comp.isProcessing = observableOf(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -261,7 +264,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
expect(compAsAny.buildResourcePolicyForm).toHaveBeenCalled();
|
expect(compAsAny.buildResourcePolicyForm).toHaveBeenCalled();
|
||||||
expect(compAsAny.initModelsValue).toHaveBeenCalled();
|
expect(compAsAny.initModelsValue).toHaveBeenCalled();
|
||||||
expect(compAsAny.formModel.length).toBe(5);
|
expect(compAsAny.formModel.length).toBe(5);
|
||||||
expect(compAsAny.subs.length).toBe(0);
|
expect(compAsAny.subs.length).toBe(1);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -279,7 +282,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
expect(compAsAny.reset.emit).toHaveBeenCalled();
|
expect(compAsAny.reset.emit).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update resource policy grant object properly', () => {
|
it('should update resource policy grant object properly', () => {
|
||||||
comp.updateObjectSelected(EPersonMock, true);
|
comp.updateObjectSelected(EPersonMock, true);
|
||||||
|
|
||||||
expect(comp.resourcePolicyGrant).toEqual(EPersonMock);
|
expect(comp.resourcePolicyGrant).toEqual(EPersonMock);
|
||||||
@@ -301,6 +304,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
compAsAny = fixture.componentInstance;
|
compAsAny = fixture.componentInstance;
|
||||||
comp.resourcePolicy = resourcePolicy;
|
comp.resourcePolicy = resourcePolicy;
|
||||||
|
compAsAny.resourcePolicy = resourcePolicy;
|
||||||
comp.isProcessing = observableOf(false);
|
comp.isProcessing = observableOf(false);
|
||||||
compAsAny.ePersonService.findByHref.and.returnValue(
|
compAsAny.ePersonService.findByHref.and.returnValue(
|
||||||
observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100))
|
observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100))
|
||||||
@@ -343,8 +347,8 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not can set grant', () => {
|
it('should be being edited', () => {
|
||||||
expect(comp.isBeingEdited()).toBeFalsy();
|
expect(comp.isBeingEdited()).toBeTrue();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have a target name', () => {
|
it('should have a target name', () => {
|
||||||
@@ -398,6 +402,7 @@ describe('ResourcePolicyFormComponent test suite', () => {
|
|||||||
type: 'group',
|
type: 'group',
|
||||||
uuid: GroupMock.id
|
uuid: GroupMock.id
|
||||||
};
|
};
|
||||||
|
eventPayload.updateTarget = false;
|
||||||
|
|
||||||
scheduler = getTestScheduler();
|
scheduler = getTestScheduler();
|
||||||
scheduler.schedule(() => comp.onSubmit());
|
scheduler.schedule(() => comp.onSubmit());
|
||||||
|
@@ -49,6 +49,7 @@ export interface ResourcePolicyEvent {
|
|||||||
type: string,
|
type: string,
|
||||||
uuid: string
|
uuid: string
|
||||||
};
|
};
|
||||||
|
updateTarget: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -130,6 +131,8 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
navActiveId: string;
|
navActiveId: string;
|
||||||
|
|
||||||
|
resourcePolicyTargetUpdated = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables
|
* Initialize instance variables
|
||||||
*
|
*
|
||||||
@@ -278,6 +281,7 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
|||||||
* Update reference to the eperson or group that will be granted the permission
|
* Update reference to the eperson or group that will be granted the permission
|
||||||
*/
|
*/
|
||||||
updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void {
|
updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void {
|
||||||
|
this.resourcePolicyTargetUpdated = true;
|
||||||
this.resourcePolicyGrant = object;
|
this.resourcePolicyGrant = object;
|
||||||
this.resourcePolicyGrantType = isEPerson ? 'eperson' : 'group';
|
this.resourcePolicyGrantType = isEPerson ? 'eperson' : 'group';
|
||||||
this.resourcePolicyTargetName$.next(this.getResourcePolicyTargetName());
|
this.resourcePolicyTargetName$.next(this.getResourcePolicyTargetName());
|
||||||
@@ -304,6 +308,7 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
|||||||
type: this.resourcePolicyGrantType,
|
type: this.resourcePolicyGrantType,
|
||||||
uuid: this.resourcePolicyGrant.id
|
uuid: this.resourcePolicyGrant.id
|
||||||
};
|
};
|
||||||
|
eventPayload.updateTarget = this.resourcePolicyTargetUpdated;
|
||||||
this.submit.emit(eventPayload);
|
this.submit.emit(eventPayload);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -3136,6 +3136,16 @@
|
|||||||
|
|
||||||
"resource-policies.form.eperson-group-list.table.headers.name": "Name",
|
"resource-policies.form.eperson-group-list.table.headers.name": "Name",
|
||||||
|
|
||||||
|
"resource-policies.form.eperson-group-list.modal.header": "Cannot change type",
|
||||||
|
|
||||||
|
"resource-policies.form.eperson-group-list.modal.text1.toGroup": "It is not possible to replace an ePerson with a group.",
|
||||||
|
|
||||||
|
"resource-policies.form.eperson-group-list.modal.text1.toEPerson": "It is not possible to replace a group with an ePerson.",
|
||||||
|
|
||||||
|
"resource-policies.form.eperson-group-list.modal.text2": "Delete the current resource policy and create a new one with the desired type.",
|
||||||
|
|
||||||
|
"resource-policies.form.eperson-group-list.modal.close": "Ok",
|
||||||
|
|
||||||
"resource-policies.form.date.end.label": "End Date",
|
"resource-policies.form.date.end.label": "End Date",
|
||||||
|
|
||||||
"resource-policies.form.date.start.label": "Start Date",
|
"resource-policies.form.date.start.label": "Start Date",
|
||||||
|
Reference in New Issue
Block a user