mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
94207: Extract RP entries into a separate component
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
<td class="text-center">
|
||||||
|
<div class="custom-control custom-checkbox">
|
||||||
|
<input type="checkbox"
|
||||||
|
class="custom-control-input"
|
||||||
|
[id]="entry.id"
|
||||||
|
[ngModel]="entry.checked"
|
||||||
|
(ngModelChange)="this.toggleCheckbox.emit($event);">
|
||||||
|
<label class="custom-control-label" [for]="entry.id"></label>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<th scope="row">
|
||||||
|
{{entry.id}}
|
||||||
|
</th>
|
||||||
|
<td>{{entry.policy.name}}</td>
|
||||||
|
<td>{{entry.policy.policyType}}</td>
|
||||||
|
<td>{{entry.policy.action}}</td>
|
||||||
|
<td>
|
||||||
|
{{ epersonName$ | async }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ groupName$ | async }}
|
||||||
|
</td>
|
||||||
|
<td>{{formatDate(entry.policy.startDate)}}</td>
|
||||||
|
<td>{{formatDate(entry.policy.endDate)}}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
|
||||||
|
<div class="btn-group edit-field">
|
||||||
|
<button class="btn btn-outline-primary btn-sm"
|
||||||
|
[title]="'resource-policies.table.headers.edit.policy' | translate"
|
||||||
|
(click)="redirectToResourcePolicyEditPage()">
|
||||||
|
<i class="fas fa-edit fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
<button *ngIf="(groupName$ | async) !== undefined" class="btn btn-outline-primary btn-sm"
|
||||||
|
[title]="'resource-policies.table.headers.edit.group' | translate"
|
||||||
|
(click)="redirectToGroupEditPage()">
|
||||||
|
<i class="fas fa-users fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
@@ -0,0 +1,222 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { createSuccessfulRemoteDataObject } from '../../remote-data.utils';
|
||||||
|
import { GroupMock } from '../../testing/group-mock';
|
||||||
|
import { PolicyType } from '../../../core/resource-policy/models/policy-type.model';
|
||||||
|
import { ActionType } from '../../../core/resource-policy/models/action-type.model';
|
||||||
|
import { EPersonMock } from '../../testing/eperson.mock';
|
||||||
|
import { ResourcePolicyEntryComponent } from './resource-policy-entry.component';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||||
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { RouterStub } from '../../testing/router.stub';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { cold } from 'jasmine-marbles';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import createSpyObj = jasmine.createSpyObj;
|
||||||
|
|
||||||
|
const groupRP: any = {
|
||||||
|
id: '1',
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
policyType: PolicyType.TYPE_SUBMISSION,
|
||||||
|
action: ActionType.READ,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
type: 'resourcepolicy',
|
||||||
|
uuid: 'resource-policy-1',
|
||||||
|
_links: {
|
||||||
|
eperson: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1/eperson'
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1/group'
|
||||||
|
},
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
eperson: observableOf(createSuccessfulRemoteDataObject(undefined)),
|
||||||
|
group: observableOf(createSuccessfulRemoteDataObject(GroupMock))
|
||||||
|
};
|
||||||
|
|
||||||
|
const epersonRP: any = {
|
||||||
|
id: '1',
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
policyType: PolicyType.TYPE_SUBMISSION,
|
||||||
|
action: ActionType.READ,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
type: 'resourcepolicy',
|
||||||
|
uuid: 'resource-policy-1',
|
||||||
|
_links: {
|
||||||
|
eperson: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1/eperson'
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1/group'
|
||||||
|
},
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
eperson: observableOf(createSuccessfulRemoteDataObject(EPersonMock)),
|
||||||
|
group: observableOf(createSuccessfulRemoteDataObject(undefined))
|
||||||
|
};
|
||||||
|
|
||||||
|
const item = Object.assign(new Item(), {
|
||||||
|
uuid: 'itemUUID',
|
||||||
|
id: 'itemUUID',
|
||||||
|
_links: {
|
||||||
|
self: { href: 'item-selflink' }
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ResourcePolicyEntryComponent', () => {
|
||||||
|
let fixture: ComponentFixture<ResourcePolicyEntryComponent>;
|
||||||
|
let comp: ResourcePolicyEntryComponent;
|
||||||
|
let compAsAny: any;
|
||||||
|
|
||||||
|
let dsoNameService;
|
||||||
|
let groupService;
|
||||||
|
let routeStub;
|
||||||
|
let routerStub;
|
||||||
|
|
||||||
|
it('should pass', () => {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
dsoNameService = createSpyObj('dsoNameMock', {
|
||||||
|
getName: 'NAME'
|
||||||
|
});
|
||||||
|
groupService = jasmine.createSpyObj('groupService', {
|
||||||
|
findByHref: jasmine.createSpy('findByHref'),
|
||||||
|
});
|
||||||
|
routeStub = {
|
||||||
|
data: observableOf({
|
||||||
|
item: createSuccessfulRemoteDataObject(item)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
routerStub = Object.assign(new RouterStub(), {
|
||||||
|
url: `url/edit`
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
TranslateModule.forRoot()
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ResourcePolicyEntryComponent,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
|
{ provide: Router, useValue: routerStub },
|
||||||
|
{ provide: GroupDataService, useValue: groupService },
|
||||||
|
{ provide: DSONameService, useValue: dsoNameService }
|
||||||
|
],
|
||||||
|
// schemas: [
|
||||||
|
// NO_ERRORS_SCHEMA
|
||||||
|
// ]
|
||||||
|
}).compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ResourcePolicyEntryComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
compAsAny = comp;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('target DSO is an EPerson', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.entry = {
|
||||||
|
id: 'test',
|
||||||
|
policy: epersonRP,
|
||||||
|
checked: false,
|
||||||
|
};
|
||||||
|
comp.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a valid epersonName$', () => {
|
||||||
|
expect(compAsAny.epersonName$).toBeObservable(cold('(n|)', { u: undefined, n: 'NAME' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have an undefined groupName$', () => {
|
||||||
|
expect(compAsAny.groupName$).toBeObservable(cold('(u|)', { u: undefined, n: 'NAME' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('target DSO is a Group ', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.entry = {
|
||||||
|
id: 'test',
|
||||||
|
policy: groupRP,
|
||||||
|
checked: false,
|
||||||
|
};
|
||||||
|
comp.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a valid groupName$', () => {
|
||||||
|
expect(compAsAny.groupName$).toBeObservable(cold('(n|)', { u: undefined, n: 'NAME' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have an undefined epersonName$', () => {
|
||||||
|
expect(compAsAny.epersonName$).toBeObservable(cold('(u|)', { u: undefined, n: 'NAME' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.entry = {
|
||||||
|
id: 'test',
|
||||||
|
policy: groupRP,
|
||||||
|
checked: false,
|
||||||
|
};
|
||||||
|
comp.ngOnInit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format date properly', () => {
|
||||||
|
expect(comp.formatDate('2020-04-14T12:00:00Z')).toBe('2020-04-14');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to ResourcePolicy edit page', () => {
|
||||||
|
|
||||||
|
comp.redirectToResourcePolicyEditPage();
|
||||||
|
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to Group edit page', () => {
|
||||||
|
compAsAny.groupService.findByHref.and.returnValue(observableOf(createSuccessfulRemoteDataObject(GroupMock)));
|
||||||
|
|
||||||
|
comp.redirectToGroupEditPage();
|
||||||
|
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit new state when checkbox is toggled', () => {
|
||||||
|
spyOn(comp.toggleCheckbox, 'emit');
|
||||||
|
|
||||||
|
const checkbox = fixture.debugElement.query(By.css('input[type="checkbox"]'));
|
||||||
|
|
||||||
|
comp.entry.checked = false;
|
||||||
|
checkbox.triggerEventHandler('ngModelChange', true);
|
||||||
|
expect(comp.toggleCheckbox.emit).toHaveBeenCalledWith(true);
|
||||||
|
|
||||||
|
comp.entry.checked = true;
|
||||||
|
checkbox.triggerEventHandler('ngModelChange', false);
|
||||||
|
expect(comp.toggleCheckbox.emit).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||||
|
import { hasValue, isNotEmpty } from '../../empty.util';
|
||||||
|
import { dateToString, stringToNgbDateStruct } from '../../date.util';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { getAllSucceededRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||||
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { Group } from '../../../core/eperson/models/group.model';
|
||||||
|
import { ACCESS_CONTROL_MODULE_PATH } from '../../../app-routing-paths';
|
||||||
|
import { GROUP_EDIT_PATH } from '../../../access-control/access-control-routing-paths';
|
||||||
|
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||||
|
|
||||||
|
export interface ResourcePolicyCheckboxEntry {
|
||||||
|
id: string;
|
||||||
|
policy: ResourcePolicy;
|
||||||
|
checked: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
/* eslint-disable @angular-eslint/component-selector */
|
||||||
|
selector: 'tr[ds-resource-policy-entry]',
|
||||||
|
templateUrl: './resource-policy-entry.component.html',
|
||||||
|
})
|
||||||
|
export class ResourcePolicyEntryComponent implements OnInit {
|
||||||
|
@Input()
|
||||||
|
entry: ResourcePolicyCheckboxEntry;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
public toggleCheckbox: EventEmitter<boolean> = new EventEmitter();
|
||||||
|
|
||||||
|
epersonName$: Observable<string>;
|
||||||
|
groupName$: Observable<string>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected dsoNameService: DSONameService,
|
||||||
|
protected groupService: GroupDataService,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected router: Router,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.epersonName$ = this.getName$(this.entry.policy.eperson);
|
||||||
|
this.groupName$ = this.getName$(this.entry.policy.group);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getName$(dso$: Observable<RemoteData<DSpaceObject>>): Observable<string> {
|
||||||
|
return dso$.pipe(
|
||||||
|
getAllSucceededRemoteData(),
|
||||||
|
map((rd: RemoteData<DSpaceObject>) => {
|
||||||
|
if (hasValue(rd?.payload)) {
|
||||||
|
return this.dsoNameService.getName(rd.payload);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a date in simplified format (YYYY-MM-DD).
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* @return a string with formatted date
|
||||||
|
*/
|
||||||
|
formatDate(date: string): string {
|
||||||
|
return isNotEmpty(date) ? dateToString(stringToNgbDateStruct(date)) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to resource policy editing page
|
||||||
|
*/
|
||||||
|
redirectToResourcePolicyEditPage(): void {
|
||||||
|
this.router.navigate([`./edit`], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: {
|
||||||
|
policyId: this.entry.policy.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to group edit page
|
||||||
|
*/
|
||||||
|
redirectToGroupEditPage(): void {
|
||||||
|
this.groupService.findByHref(this.entry.policy._links.group.href, false).pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
|
map((group: Group) => group.id),
|
||||||
|
).subscribe((groupUUID) => {
|
||||||
|
this.router.navigate([ACCESS_CONTROL_MODULE_PATH, GROUP_EDIT_PATH, groupUUID]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -57,49 +57,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody *ngIf="(getResourcePolicies() | async)?.length > 0">
|
<tbody *ngIf="(getResourcePolicies() | async)?.length > 0">
|
||||||
<tr *ngFor="let entry of (getResourcePolicies() | async); trackById">
|
<tr ds-resource-policy-entry *ngFor="let entry of (getResourcePolicies() | async)"
|
||||||
<td class="text-center">
|
[entry]="entry"
|
||||||
<div class="custom-control custom-checkbox">
|
(toggleCheckbox)="selectCheckbox(entry, $event)"
|
||||||
<input type="checkbox"
|
></tr>
|
||||||
class="custom-control-input"
|
|
||||||
[id]="entry.id"
|
|
||||||
[ngModel]="entry.checked"
|
|
||||||
(ngModelChange)="selectCheckbox(entry, $event)">
|
|
||||||
<label class="custom-control-label" [for]="entry.id"></label>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<th scope="row">
|
|
||||||
{{entry.id}}
|
|
||||||
</th>
|
|
||||||
<td>{{entry.policy.name}}</td>
|
|
||||||
<td>{{entry.policy.policyType}}</td>
|
|
||||||
<td>{{entry.policy.action}}</td>
|
|
||||||
<td *ngIf="(hasEPerson(entry.policy) | async)">
|
|
||||||
{{getEPersonName(entry.policy) | async}}
|
|
||||||
</td>
|
|
||||||
<td *ngIf="!(hasEPerson(entry.policy) | async)"></td>
|
|
||||||
<td *ngIf="(hasGroup(entry.policy) | async)">
|
|
||||||
{{getGroupName(entry.policy) | async}}
|
|
||||||
</td>
|
|
||||||
<td *ngIf="!(hasGroup(entry.policy) | async)"></td>
|
|
||||||
<td>{{formatDate(entry.policy.startDate)}}</td>
|
|
||||||
<td>{{formatDate(entry.policy.endDate)}}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
|
|
||||||
<div class="btn-group edit-field">
|
|
||||||
<button class="btn btn-outline-primary btn-sm"
|
|
||||||
[title]="'resource-policies.table.headers.edit.policy' | translate"
|
|
||||||
(click)="redirectToResourcePolicyEditPage(entry.policy)">
|
|
||||||
<i class="fas fa-edit fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
<button *ngIf="(hasGroup(entry.policy) | async)" class="btn btn-outline-primary btn-sm"
|
|
||||||
[title]="'resource-policies.table.headers.edit.group' | translate"
|
|
||||||
(click)="redirectToGroupEditPage(entry.policy)">
|
|
||||||
<i class="fas fa-users fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -33,6 +33,8 @@ import { PolicyType } from '../../core/resource-policy/models/policy-type.model'
|
|||||||
import { ActionType } from '../../core/resource-policy/models/action-type.model';
|
import { ActionType } from '../../core/resource-policy/models/action-type.model';
|
||||||
import { EPersonMock } from '../testing/eperson.mock';
|
import { EPersonMock } from '../testing/eperson.mock';
|
||||||
import { GroupMock } from '../testing/group-mock';
|
import { GroupMock } from '../testing/group-mock';
|
||||||
|
import { ResourcePolicyEntryComponent } from './entry/resource-policy-entry.component';
|
||||||
|
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
||||||
|
|
||||||
describe('ResourcePoliciesComponent test suite', () => {
|
describe('ResourcePoliciesComponent test suite', () => {
|
||||||
let comp: ResourcePoliciesComponent;
|
let comp: ResourcePoliciesComponent;
|
||||||
@@ -188,6 +190,10 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
const paginatedList = buildPaginatedList(pageInfo, array);
|
const paginatedList = buildPaginatedList(pageInfo, array);
|
||||||
const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList);
|
const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList);
|
||||||
|
|
||||||
|
const dsoNameService = jasmine.createSpyObj('dsoNameMock', {
|
||||||
|
getName: 'NAME'
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -198,6 +204,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
ResourcePoliciesComponent,
|
ResourcePoliciesComponent,
|
||||||
|
ResourcePolicyEntryComponent,
|
||||||
TestComponent
|
TestComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -209,6 +216,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
{ provide: ResourcePolicyService, useValue: resourcePolicyService },
|
{ provide: ResourcePolicyService, useValue: resourcePolicyService },
|
||||||
{ provide: RequestService, useValue: getMockRequestService() },
|
{ provide: RequestService, useValue: getMockRequestService() },
|
||||||
{ provide: Router, useValue: routerStub },
|
{ provide: Router, useValue: routerStub },
|
||||||
|
{ provide: DSONameService, useValue: dsoNameService },
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
ResourcePoliciesComponent
|
ResourcePoliciesComponent
|
||||||
], schemas: [
|
], schemas: [
|
||||||
@@ -260,10 +268,10 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should init component properly', () => {
|
it('should init component properly', () => {
|
||||||
spyOn(comp, 'initResourcePolicyLIst');
|
spyOn(comp, 'initResourcePolicyList');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(compAsAny.isActive).toBeTruthy();
|
expect(compAsAny.isActive).toBeTruthy();
|
||||||
expect(comp.initResourcePolicyLIst).toHaveBeenCalled();
|
expect(comp.initResourcePolicyList).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init resource policies list properly', () => {
|
it('should init resource policies list properly', () => {
|
||||||
@@ -274,7 +282,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
scheduler = getTestScheduler();
|
scheduler = getTestScheduler();
|
||||||
scheduler.schedule(() => comp.initResourcePolicyLIst());
|
scheduler.schedule(() => comp.initResourcePolicyList());
|
||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
|
|
||||||
expect(compAsAny.resourcePoliciesEntries$.value).toEqual(expected);
|
expect(compAsAny.resourcePoliciesEntries$.value).toEqual(expected);
|
||||||
@@ -291,7 +299,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
const initResourcePolicyEntries = getInitEntries();
|
const initResourcePolicyEntries = getInitEntries();
|
||||||
compAsAny.resourcePoliciesEntries$.next(initResourcePolicyEntries);
|
compAsAny.resourcePoliciesEntries$.next(initResourcePolicyEntries);
|
||||||
resourcePolicyService.searchByResource.and.returnValue(observableOf({}));
|
resourcePolicyService.searchByResource.and.returnValue(observableOf({}));
|
||||||
spyOn(comp, 'initResourcePolicyLIst').and.callFake(() => ({}));
|
spyOn(comp, 'initResourcePolicyList').and.callFake(() => ({}));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -361,7 +369,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
|
|
||||||
expect(notificationsServiceStub.success).toHaveBeenCalled();
|
expect(notificationsServiceStub.success).toHaveBeenCalled();
|
||||||
expect(comp.initResourcePolicyLIst).toHaveBeenCalled();
|
expect(comp.initResourcePolicyList).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should notify error when delete is not successful', () => {
|
it('should notify error when delete is not successful', () => {
|
||||||
@@ -372,7 +380,7 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
|
|
||||||
expect(notificationsServiceStub.error).toHaveBeenCalled();
|
expect(notificationsServiceStub.error).toHaveBeenCalled();
|
||||||
expect(comp.initResourcePolicyLIst).toHaveBeenCalled();
|
expect(comp.initResourcePolicyList).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -384,68 +392,6 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasEPerson', () => {
|
|
||||||
it('should true when policy is link to the eperson', () => {
|
|
||||||
|
|
||||||
expect(comp.hasEPerson(anotherResourcePolicy)).toBeObservable(cold('(ab|)', {
|
|
||||||
a: false,
|
|
||||||
b: true
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should false when policy is not link to the eperson', () => {
|
|
||||||
|
|
||||||
expect(comp.hasEPerson(resourcePolicy)).toBeObservable(cold('(aa|)', {
|
|
||||||
a: false
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasGroup', () => {
|
|
||||||
it('should true when policy is link to the group', () => {
|
|
||||||
|
|
||||||
expect(comp.hasGroup(resourcePolicy)).toBeObservable(cold('(ab|)', {
|
|
||||||
a: false,
|
|
||||||
b: true
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should false when policy is not link to the group', () => {
|
|
||||||
|
|
||||||
expect(comp.hasGroup(anotherResourcePolicy)).toBeObservable(cold('(aa|)', {
|
|
||||||
a: false
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getEPersonName', () => {
|
|
||||||
it('should return the eperson name', () => {
|
|
||||||
|
|
||||||
expect(comp.getEPersonName(anotherResourcePolicy)).toBeObservable(cold('(ab|)', {
|
|
||||||
a: '',
|
|
||||||
b: 'User Test'
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getGroupName', () => {
|
|
||||||
it('should return the group name', () => {
|
|
||||||
|
|
||||||
expect(comp.getGroupName(resourcePolicy)).toBeObservable(cold('(ab|)', {
|
|
||||||
a: '',
|
|
||||||
b: 'testgroupname'
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should format date properly', () => {
|
|
||||||
expect(comp.formatDate('2020-04-14T12:00:00Z')).toBe('2020-04-14');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should select All Checkbox', () => {
|
it('should select All Checkbox', () => {
|
||||||
spyOn(comp, 'selectAllCheckbox').and.callThrough();
|
spyOn(comp, 'selectAllCheckbox').and.callThrough();
|
||||||
const checkbox = fixture.debugElement.query(By.css('table > thead > tr:nth-child(2) input'));
|
const checkbox = fixture.debugElement.query(By.css('table > thead > tr:nth-child(2) input'));
|
||||||
@@ -469,19 +415,6 @@ describe('ResourcePoliciesComponent test suite', () => {
|
|||||||
comp.redirectToResourcePolicyCreatePage();
|
comp.redirectToResourcePolicyCreatePage();
|
||||||
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should redirect to resource policy edit page', () => {
|
|
||||||
|
|
||||||
comp.redirectToResourcePolicyEditPage(resourcePolicy);
|
|
||||||
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should redirect to resource policy edit page', () => {
|
|
||||||
compAsAny.groupService.findByHref.and.returnValue(observableOf(createSuccessfulRemoteDataObject(GroupMock)));
|
|
||||||
|
|
||||||
comp.redirectToGroupEditPage(resourcePolicy);
|
|
||||||
expect(compAsAny.router.navigate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -2,48 +2,25 @@ import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular
|
|||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
import { BehaviorSubject, from as observableFrom, Observable, Subscription } from 'rxjs';
|
import { BehaviorSubject, from as observableFrom, Observable, Subscription } from 'rxjs';
|
||||||
import {
|
import { concatMap, distinctUntilChanged, filter, map, reduce, scan, take } from 'rxjs/operators';
|
||||||
concatMap,
|
|
||||||
distinctUntilChanged,
|
|
||||||
filter,
|
|
||||||
map,
|
|
||||||
reduce,
|
|
||||||
scan,
|
|
||||||
startWith,
|
|
||||||
take
|
|
||||||
} from 'rxjs/operators';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { ResourcePolicyService } from '../../core/resource-policy/resource-policy.service';
|
import { ResourcePolicyService } from '../../core/resource-policy/resource-policy.service';
|
||||||
import {
|
import { getAllSucceededRemoteData } from '../../core/shared/operators';
|
||||||
getFirstSucceededRemoteDataPayload,
|
|
||||||
getFirstSucceededRemoteDataWithNotEmptyPayload,
|
|
||||||
getAllSucceededRemoteData
|
|
||||||
} from '../../core/shared/operators';
|
|
||||||
import { ResourcePolicy } from '../../core/resource-policy/models/resource-policy.model';
|
import { ResourcePolicy } from '../../core/resource-policy/models/resource-policy.model';
|
||||||
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
||||||
import { Group } from '../../core/eperson/models/group.model';
|
|
||||||
import { GroupDataService } from '../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../core/eperson/group-data.service';
|
||||||
import { hasValue, isEmpty, isNotEmpty } from '../empty.util';
|
import { hasValue, isEmpty, isNotEmpty } from '../empty.util';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
|
||||||
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||||
import { RequestService } from '../../core/data/request.service';
|
import { RequestService } from '../../core/data/request.service';
|
||||||
import { NotificationsService } from '../notifications/notifications.service';
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
import { dateToString, stringToNgbDateStruct } from '../date.util';
|
|
||||||
import { followLink } from '../utils/follow-link-config.model';
|
import { followLink } from '../utils/follow-link-config.model';
|
||||||
import { ACCESS_CONTROL_MODULE_PATH } from '../../app-routing-paths';
|
import { ResourcePolicyCheckboxEntry } from './entry/resource-policy-entry.component';
|
||||||
import { GROUP_EDIT_PATH } from '../../access-control/access-control-routing-paths';
|
|
||||||
|
|
||||||
interface ResourcePolicyCheckboxEntry {
|
|
||||||
id: string;
|
|
||||||
policy: ResourcePolicy;
|
|
||||||
checked: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-resource-policies',
|
selector: 'ds-resource-policies',
|
||||||
styleUrls: ['./resource-policies.component.scss'],
|
styleUrls: ['./resource-policies.component.scss'],
|
||||||
templateUrl: './resource-policies.component.html'
|
templateUrl: './resource-policies.component.html',
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* Component that shows the policies for given resource
|
* Component that shows the policies for given resource
|
||||||
@@ -126,7 +103,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.isActive = true;
|
this.isActive = true;
|
||||||
this.initResourcePolicyLIst();
|
this.initResourcePolicyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,48 +145,6 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a date in simplified format (YYYY-MM-DD).
|
|
||||||
*
|
|
||||||
* @param date
|
|
||||||
* @return a string with formatted date
|
|
||||||
*/
|
|
||||||
formatDate(date: string): string {
|
|
||||||
return isNotEmpty(date) ? dateToString(stringToNgbDateStruct(date)) : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the ePerson's name which the given policy is linked to
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
*/
|
|
||||||
getEPersonName(policy: ResourcePolicy): Observable<string> {
|
|
||||||
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
|
|
||||||
// return this.ePersonService.findByHref(policy._links.eperson.href).pipe(
|
|
||||||
return policy.eperson.pipe(
|
|
||||||
filter(() => this.isActive),
|
|
||||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
|
||||||
map((eperson: EPerson) => this.dsoNameService.getName(eperson)),
|
|
||||||
startWith('')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the group's name which the given policy is linked to
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
*/
|
|
||||||
getGroupName(policy: ResourcePolicy): Observable<string> {
|
|
||||||
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
|
|
||||||
// return this.groupService.findByHref(policy._links.group.href).pipe(
|
|
||||||
return policy.group.pipe(
|
|
||||||
filter(() => this.isActive),
|
|
||||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
|
||||||
map((group: Group) => this.dsoNameService.getName(group)),
|
|
||||||
startWith('')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all resource's policies
|
* Return all resource's policies
|
||||||
*
|
*
|
||||||
@@ -219,46 +154,14 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
return this.resourcePoliciesEntries$.asObservable();
|
return this.resourcePoliciesEntries$.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether the given policy is linked to a ePerson
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
* @return an observable that emits true when the policy is linked to a ePerson, false otherwise
|
|
||||||
*/
|
|
||||||
hasEPerson(policy): Observable<boolean> {
|
|
||||||
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
|
|
||||||
// return this.ePersonService.findByHref(policy._links.eperson.href).pipe(
|
|
||||||
return policy.eperson.pipe(
|
|
||||||
filter(() => this.isActive),
|
|
||||||
getFirstSucceededRemoteDataPayload(),
|
|
||||||
map((eperson: EPerson) => isNotEmpty(eperson)),
|
|
||||||
startWith(false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether the given policy is linked to a group
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
* @return an observable that emits true when the policy is linked to a group, false otherwise
|
|
||||||
*/
|
|
||||||
hasGroup(policy): Observable<boolean> {
|
|
||||||
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
|
|
||||||
// return this.groupService.findByHref(policy._links.group.href).pipe(
|
|
||||||
return policy.group.pipe(
|
|
||||||
filter(() => this.isActive),
|
|
||||||
getFirstSucceededRemoteDataPayload(),
|
|
||||||
map((group: Group) => isNotEmpty(group)),
|
|
||||||
startWith(false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the resource's policies list
|
* Initialize the resource's policies list
|
||||||
*/
|
*/
|
||||||
initResourcePolicyLIst() {
|
initResourcePolicyList() {
|
||||||
this.subs.push(this.resourcePolicyService.searchByResource(this.resourceUUID, null, false, true,
|
this.subs.push(this.resourcePolicyService.searchByResource(
|
||||||
followLink('eperson'), followLink('group')).pipe(
|
this.resourceUUID, null, false, true,
|
||||||
|
followLink('eperson'), followLink('group')
|
||||||
|
).pipe(
|
||||||
filter(() => this.isActive),
|
filter(() => this.isActive),
|
||||||
getAllSucceededRemoteData()
|
getAllSucceededRemoteData()
|
||||||
).subscribe((result) => {
|
).subscribe((result) => {
|
||||||
@@ -295,37 +198,6 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to resource policy editing page
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
*/
|
|
||||||
redirectToResourcePolicyEditPage(policy: ResourcePolicy): void {
|
|
||||||
this.router.navigate([`./edit`], {
|
|
||||||
relativeTo: this.route,
|
|
||||||
queryParams: {
|
|
||||||
policyId: policy.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to group edit page
|
|
||||||
*
|
|
||||||
* @param policy The resource policy
|
|
||||||
*/
|
|
||||||
redirectToGroupEditPage(policy: ResourcePolicy): void {
|
|
||||||
this.subs.push(
|
|
||||||
this.groupService.findByHref(policy._links.group.href, false).pipe(
|
|
||||||
filter(() => this.isActive),
|
|
||||||
getFirstSucceededRemoteDataPayload(),
|
|
||||||
map((group: Group) => group.id)
|
|
||||||
).subscribe((groupUUID) => {
|
|
||||||
this.router.navigate([ACCESS_CONTROL_MODULE_PATH, GROUP_EDIT_PATH, groupUUID]);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select/unselect all checkbox in the list
|
* Select/unselect all checkbox in the list
|
||||||
*/
|
*/
|
||||||
|
@@ -15,9 +15,11 @@ import { GroupSearchBoxComponent } from './form/eperson-group-list/group-search-
|
|||||||
import { EpersonSearchBoxComponent } from './form/eperson-group-list/eperson-search-box/eperson-search-box.component';
|
import { EpersonSearchBoxComponent } from './form/eperson-group-list/eperson-search-box/eperson-search-box.component';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { SharedModule } from '../shared.module';
|
import { SharedModule } from '../shared.module';
|
||||||
|
import { ResourcePolicyEntryComponent } from './entry/resource-policy-entry.component';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
ResourcePoliciesComponent,
|
ResourcePoliciesComponent,
|
||||||
|
ResourcePolicyEntryComponent,
|
||||||
ResourcePolicyFormComponent,
|
ResourcePolicyFormComponent,
|
||||||
ResourcePolicyEditComponent,
|
ResourcePolicyEditComponent,
|
||||||
ResourcePolicyCreateComponent,
|
ResourcePolicyCreateComponent,
|
||||||
|
Reference in New Issue
Block a user