mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Intermediate commit
This commit is contained in:
@@ -1675,9 +1675,21 @@
|
|||||||
|
|
||||||
"resource-policies.add.for.item": "Add a new Item policy",
|
"resource-policies.add.for.item": "Add a new Item policy",
|
||||||
|
|
||||||
"resource-policies.create.modal.head": "Create new resource policy",
|
"resource-policies.create.page.heading": "Create new resource policy for ",
|
||||||
|
|
||||||
"resource-policies.edit.modal.head": "Edit resource policy",
|
"resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.",
|
||||||
|
|
||||||
|
"resource-policies.create.page.success.content": "Operation successful",
|
||||||
|
|
||||||
|
"resource-policies.create.page.title": "Create new resource policy",
|
||||||
|
|
||||||
|
"resource-policies.edit.page.heading": "Edit resource policy ",
|
||||||
|
|
||||||
|
"resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.",
|
||||||
|
|
||||||
|
"resource-policies.edit.page.success.content": "Operation successful",
|
||||||
|
|
||||||
|
"resource-policies.edit.page.title": "Edit resource policy",
|
||||||
|
|
||||||
"resource-policies.form.action-type.label": "Select the action type",
|
"resource-policies.form.action-type.label": "Select the action type",
|
||||||
|
|
||||||
@@ -1721,9 +1733,11 @@
|
|||||||
|
|
||||||
"resource-policies.table.headers.group": "Group",
|
"resource-policies.table.headers.group": "Group",
|
||||||
|
|
||||||
|
"resource-policies.table.headers.id": "ID",
|
||||||
|
|
||||||
"resource-policies.table.headers.name": "Name",
|
"resource-policies.table.headers.name": "Name",
|
||||||
|
|
||||||
"resource-policies.table.headers.id": "ID",
|
"resource-policies.table.headers.policyType": "type",
|
||||||
|
|
||||||
"resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream",
|
"resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream",
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@ import { ItemMoveComponent } from './item-move/item-move.component';
|
|||||||
import { VirtualMetadataComponent } from './virtual-metadata/virtual-metadata.component';
|
import { VirtualMetadataComponent } from './virtual-metadata/virtual-metadata.component';
|
||||||
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
|
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
|
||||||
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
||||||
|
import { ResourcePolicyEditComponent } from '../../shared/resource-policies/edit/resource-policy-edit.component';
|
||||||
|
import { ResourcePolicyCreateComponent } from '../../shared/resource-policies/create/resource-policy-create.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module that contains all components related to the Edit Item page administrator functionality
|
* Module that contains all components related to the Edit Item page administrator functionality
|
||||||
@@ -56,7 +58,9 @@ import { ItemAuthorizationsComponent } from './item-authorizations/item-authoriz
|
|||||||
ItemCollectionMapperComponent,
|
ItemCollectionMapperComponent,
|
||||||
ItemMoveComponent,
|
ItemMoveComponent,
|
||||||
VirtualMetadataComponent,
|
VirtualMetadataComponent,
|
||||||
ItemAuthorizationsComponent
|
ItemAuthorizationsComponent,
|
||||||
|
ResourcePolicyEditComponent,
|
||||||
|
ResourcePolicyCreateComponent,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class EditItemPageModule {
|
export class EditItemPageModule {
|
||||||
|
@@ -15,8 +15,10 @@ import { ItemRelationshipsComponent } from './item-relationships/item-relationsh
|
|||||||
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
|
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
|
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
|
||||||
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
|
||||||
import { ResourcePolicyEditComponent } from '../../shared/resource-policies/edit/resource-policy-edit.component';
|
import { ResourcePolicyTargetResolver } from '../../shared/resource-policies/resolvers/resource-policy-target.resolver';
|
||||||
|
import { ResourcePolicyResolver } from '../../shared/resource-policies/resolvers/resource-policy.resolver';
|
||||||
import { ResourcePolicyCreateComponent } from '../../shared/resource-policies/create/resource-policy-create.component';
|
import { ResourcePolicyCreateComponent } from '../../shared/resource-policies/create/resource-policy-create.component';
|
||||||
|
import { ResourcePolicyEditComponent } from '../../shared/resource-policies/edit/resource-policy-edit.component';
|
||||||
|
|
||||||
export const ITEM_EDIT_WITHDRAW_PATH = 'withdraw';
|
export const ITEM_EDIT_WITHDRAW_PATH = 'withdraw';
|
||||||
export const ITEM_EDIT_REINSTATE_PATH = 'reinstate';
|
export const ITEM_EDIT_REINSTATE_PATH = 'reinstate';
|
||||||
@@ -118,19 +120,27 @@ export const ITEM_EDIT_AUTHORIZATIONS_PATH = 'authorizations';
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ITEM_EDIT_AUTHORIZATIONS_PATH,
|
path: ITEM_EDIT_AUTHORIZATIONS_PATH,
|
||||||
data: { title: 'item.edit.authorizations.title' },
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: ':dso/create',
|
path: 'create',
|
||||||
|
resolve: {
|
||||||
|
resourcePolicyTarget: ResourcePolicyTargetResolver
|
||||||
|
},
|
||||||
component: ResourcePolicyCreateComponent,
|
component: ResourcePolicyCreateComponent,
|
||||||
|
data: { title: 'resource-policies.create.page.title' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':dso/:policy/edit',
|
path: 'edit',
|
||||||
|
resolve: {
|
||||||
|
resourcePolicy: ResourcePolicyResolver
|
||||||
|
},
|
||||||
component: ResourcePolicyEditComponent,
|
component: ResourcePolicyEditComponent,
|
||||||
|
data: { title: 'resource-policies.edit.page.title' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: ItemAuthorizationsComponent
|
component: ItemAuthorizationsComponent,
|
||||||
|
data: { title: 'item.edit.authorizations.title' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -138,7 +148,10 @@ export const ITEM_EDIT_AUTHORIZATIONS_PATH = 'authorizations';
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
providers: []
|
providers: [
|
||||||
|
ResourcePolicyResolver,
|
||||||
|
ResourcePolicyTargetResolver
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class EditItemPageRoutingModule {
|
export class EditItemPageRoutingModule {
|
||||||
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
|
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
|
||||||
<ds-resource-policies [resourceKey]="'item'" [resourceUUID]="(getItemUUID() | async)"></ds-resource-policies>
|
<ds-resource-policies [resourceType]="'item'" [resourceUUID]="(getItemUUID() | async)"></ds-resource-policies>
|
||||||
<ng-container *ngFor="let bundle of (getItemBundles() | async)?.page; trackById">
|
<ng-container *ngFor="let bundle of (getItemBundles() | async)?.page; trackById">
|
||||||
<ds-resource-policies [resourceKey]="'bundle'"
|
<ds-resource-policies [resourceType]="'bundle'"
|
||||||
[resourceUUID]="bundle.id"></ds-resource-policies>
|
[resourceUUID]="bundle.id"></ds-resource-policies>
|
||||||
<ng-container *ngFor="let bitstream of (bundleBitstreamsMap.get(bundle.id) | async)?.page; trackById">
|
<ng-container *ngFor="let bitstream of (bundleBitstreamsMap.get(bundle.id) | async)?.page; trackById">
|
||||||
<ds-resource-policies [resourceKey]="'bitstream'"
|
<ds-resource-policies [resourceType]="'bitstream'"
|
||||||
[resourceUUID]="bitstream.id"></ds-resource-policies>
|
[resourceUUID]="bitstream.id"></ds-resource-policies>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -170,18 +170,6 @@ describe('ResourcePolicyService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('delete', () => {
|
describe('delete', () => {
|
||||||
beforeEach(async(() => {
|
|
||||||
scheduler = getTestScheduler();
|
|
||||||
responseCacheEntry.completed = true;
|
|
||||||
requestService = jasmine.createSpyObj('requestService', {
|
|
||||||
configure: {},
|
|
||||||
getByHref: observableOf(responseCacheEntry),
|
|
||||||
getByUUID: hot('a', { a: responseCacheEntry }),
|
|
||||||
generateRequestId: 'request-id',
|
|
||||||
removeByHrefSubstring: {}
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should proxy the call to dataservice.create', () => {
|
it('should proxy the call to dataservice.create', () => {
|
||||||
scheduler.schedule(() => service.delete(resourcePolicyId));
|
scheduler.schedule(() => service.delete(resourcePolicyId));
|
||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
@@ -190,6 +178,15 @@ describe('ResourcePolicyService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('update', () => {
|
||||||
|
it('should proxy the call to dataservice.update', () => {
|
||||||
|
scheduler.schedule(() => service.update(resourcePolicy));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.update).toHaveBeenCalledWith(resourcePolicy);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('findById', () => {
|
describe('findById', () => {
|
||||||
it('should proxy the call to dataservice.findById', () => {
|
it('should proxy the call to dataservice.findById', () => {
|
||||||
scheduler.schedule(() => service.findById(resourcePolicyId));
|
scheduler.schedule(() => service.findById(resourcePolicyId));
|
||||||
|
@@ -103,6 +103,15 @@ export class ResourcePolicyService {
|
|||||||
return this.dataService.delete(resourcePolicyID);
|
return this.dataService.delete(resourcePolicyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new patch to the object cache
|
||||||
|
* The patch is derived from the differences between the given object and its version in the object cache
|
||||||
|
* @param {ResourcePolicy} object The given object
|
||||||
|
*/
|
||||||
|
update(object: ResourcePolicy): Observable<RemoteData<ResourcePolicy>> {
|
||||||
|
return this.dataService.update(object);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an observable of {@link RemoteData} of a {@link ResourcePolicy}, based on an href, with a list of {@link FollowLinkConfig},
|
* Returns an observable of {@link RemoteData} of a {@link ResourcePolicy}, based on an href, with a list of {@link FollowLinkConfig},
|
||||||
* to automatically resolve {@link HALLink}s of the {@link ResourcePolicy}
|
* to automatically resolve {@link HALLink}s of the {@link ResourcePolicy}
|
||||||
|
@@ -67,6 +67,10 @@ export const getSucceededRemoteData = () =>
|
|||||||
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
|
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
|
||||||
source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded));
|
source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded));
|
||||||
|
|
||||||
|
export const getSucceededRemoteWithNotEmptyData = () =>
|
||||||
|
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
|
||||||
|
source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded && isNotEmpty(rd.payload)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the first successful remotely retrieved object
|
* Get the first successful remotely retrieved object
|
||||||
*
|
*
|
||||||
@@ -84,6 +88,23 @@ export const getFirstSucceededRemoteDataPayload = () =>
|
|||||||
getRemoteDataPayload()
|
getRemoteDataPayload()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first successful remotely retrieved object with not empty payload
|
||||||
|
*
|
||||||
|
* You usually don't want to use this, it is a code smell.
|
||||||
|
* Work with the RemoteData object instead, that way you can
|
||||||
|
* handle loading and errors correctly.
|
||||||
|
*
|
||||||
|
* These operators were created as a first step in refactoring
|
||||||
|
* out all the instances where this is used incorrectly.
|
||||||
|
*/
|
||||||
|
export const getFirstSucceededRemoteDataWithNotEmptyPayload = () =>
|
||||||
|
<T>(source: Observable<RemoteData<T>>): Observable<T> =>
|
||||||
|
source.pipe(
|
||||||
|
getSucceededRemoteWithNotEmptyData(),
|
||||||
|
getRemoteDataPayload()
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the all successful remotely retrieved objects
|
* Get the all successful remotely retrieved objects
|
||||||
*
|
*
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h4 class="mb-3">{{'resource-policies.create.modal.head' | translate}}</h4>
|
<h4 class="mb-3">{{'resource-policies.edit.page.heading' | translate}} {{targetResourceName}}</h4>
|
||||||
|
|
||||||
<ds-resource-policy-form (reset)="redirectToPreviousPage()"
|
<ds-resource-policy-form (reset)="redirectToAuthorizationsPage()"
|
||||||
(submit)="createResourcePolicy($event)"></ds-resource-policy-form>
|
(submit)="createResourcePolicy($event)"></ds-resource-policy-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,32 +1,69 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
import { take } from 'rxjs/operators';
|
import { first, map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ResourcePolicyEvent } from '../form/resource-policy-form';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { RouteService } from '../../../core/services/route.service';
|
|
||||||
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||||
|
import { NotificationsService } from '../../notifications/notifications.service';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||||
|
import { ResourcePolicyEvent } from '../form/resource-policy-form';
|
||||||
|
import { ITEM_EDIT_AUTHORIZATIONS_PATH } from '../../../+item-page/edit-item-page/edit-item-page.routing.module';
|
||||||
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-resource-policy-create',
|
selector: 'ds-resource-policy-create',
|
||||||
templateUrl: './resource-policy-create.component.html'
|
templateUrl: './resource-policy-create.component.html'
|
||||||
})
|
})
|
||||||
export class ResourcePolicyCreateComponent {
|
export class ResourcePolicyCreateComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The uuid of the resource target of the policy
|
||||||
|
*/
|
||||||
|
private targetResourceUUID: string;
|
||||||
|
|
||||||
|
public targetResourceName: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected resourcePolicy: ResourcePolicyService,
|
private dsoNameService: DSONameService,
|
||||||
protected router: Router,
|
private notificationsService: NotificationsService,
|
||||||
protected routeService: RouteService) {
|
private resourcePolicyService: ResourcePolicyService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.route.data.pipe(
|
||||||
|
map((data) => data),
|
||||||
|
take(1)
|
||||||
|
).subscribe((data: any) => {
|
||||||
|
this.targetResourceUUID = (data.resourcePolicyTarget as RemoteData<DSpaceObject>).payload.id;
|
||||||
|
this.targetResourceName = this.dsoNameService.getName((data.resourcePolicyTarget as RemoteData<DSpaceObject>).payload);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
redirectToAuthorizationsPage() {
|
||||||
|
this.router.navigate([`../../${ITEM_EDIT_AUTHORIZATIONS_PATH}`], { relativeTo: this.route });
|
||||||
}
|
}
|
||||||
|
|
||||||
createResourcePolicy(event: ResourcePolicyEvent) {
|
createResourcePolicy(event: ResourcePolicyEvent) {
|
||||||
|
let response$;
|
||||||
|
if (event.target.type === 'eperson') {
|
||||||
|
response$ = this.resourcePolicyService.create(event.object, this.targetResourceUUID, event.target.uuid);
|
||||||
|
} else {
|
||||||
|
response$ = this.resourcePolicyService.create(event.object, this.targetResourceUUID, null, event.target.uuid);
|
||||||
|
}
|
||||||
|
response$.pipe(
|
||||||
|
first((response: RemoteData<ResourcePolicy>) => !response.isResponsePending)
|
||||||
|
).subscribe((responseRD: RemoteData<ResourcePolicy>) => {
|
||||||
|
if (responseRD.hasSucceeded) {
|
||||||
|
this.notificationsService.success(null, 'resource-policies.create.page.success.content');
|
||||||
|
this.redirectToAuthorizationsPage();
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, 'resource-policies.create.page.failure.content');
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectToPreviousPage() {
|
|
||||||
this.routeService.getPreviousUrl().pipe(take(1))
|
|
||||||
.subscribe((url) => {
|
|
||||||
this.router.navigateByUrl(url);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h4 class="mb-3">{{'resource-policies.edit.modal.head' | translate}}</h4>
|
<h4 class="mb-3">{{'resource-policies.edit.page.heading' | translate}} {{resourcePolicy.id}}</h4>
|
||||||
|
|
||||||
<ds-resource-policy-form></ds-resource-policy-form>
|
<ds-resource-policy-form [resourcePolicy]="resourcePolicy"
|
||||||
|
(reset)="redirectToAuthorizationsPage()"
|
||||||
|
(submit)="updateResourcePolicy($event)"></ds-resource-policy-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,9 +1,60 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { first, map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||||
|
import { NotificationsService } from '../../notifications/notifications.service';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||||
|
import { ResourcePolicyEvent } from '../form/resource-policy-form';
|
||||||
|
import { ITEM_EDIT_AUTHORIZATIONS_PATH } from '../../../+item-page/edit-item-page/edit-item-page.routing.module';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-resource-policy-edit',
|
selector: 'ds-resource-policy-edit',
|
||||||
templateUrl: './resource-policy-edit.component.html'
|
templateUrl: './resource-policy-edit.component.html'
|
||||||
})
|
})
|
||||||
export class ResourcePolicyEditComponent {
|
export class ResourcePolicyEditComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource policy object to edit
|
||||||
|
*/
|
||||||
|
public resourcePolicy: ResourcePolicy;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
private resourcePolicyService: ResourcePolicyService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.route.data.pipe(
|
||||||
|
map((data) => data),
|
||||||
|
take(1)
|
||||||
|
).subscribe((data: any) => {
|
||||||
|
this.resourcePolicy = (data.resourcePolicy as RemoteData<ResourcePolicy>).payload;
|
||||||
|
console.log(data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
redirectToAuthorizationsPage() {
|
||||||
|
this.router.navigate([`../../${ITEM_EDIT_AUTHORIZATIONS_PATH}`], { relativeTo: this.route });
|
||||||
|
}
|
||||||
|
|
||||||
|
updateResourcePolicy(event: ResourcePolicyEvent) {
|
||||||
|
const updatedObject = Object.assign({}, event.object, {
|
||||||
|
_links: this.resourcePolicy._links
|
||||||
|
});
|
||||||
|
this.resourcePolicyService.update(updatedObject).pipe(
|
||||||
|
first((response: RemoteData<ResourcePolicy>) => !response.isResponsePending)
|
||||||
|
).subscribe((responseRD: RemoteData<ResourcePolicy>) => {
|
||||||
|
if (responseRD.hasSucceeded) {
|
||||||
|
this.notificationsService.success(null, 'resource-policies.edit.page.success.content');
|
||||||
|
this.redirectToAuthorizationsPage();
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(null, 'resource-policies.edit.page.failure.content');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, take } from 'rxjs/operators';
|
||||||
@@ -7,13 +7,15 @@ import { uniqueId } from 'lodash'
|
|||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||||
import { EPersonDataService } from '../../../../core/eperson/eperson-data.service';
|
|
||||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
|
||||||
import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model';
|
||||||
import { DataService } from '../../../../core/data/data.service';
|
import { DataService } from '../../../../core/data/data.service';
|
||||||
import { hasValue, isNotEmpty } from '../../../empty.util';
|
import { hasValue, isNotEmpty } from '../../../empty.util';
|
||||||
import { FindListOptions } from '../../../../core/data/request.models';
|
import { FindListOptions } from '../../../../core/data/request.models';
|
||||||
import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service';
|
||||||
|
import { getDataServiceFor } from '../../../../core/cache/builders/build-decorators';
|
||||||
|
import { EPERSON } from '../../../../core/eperson/models/eperson.resource-type';
|
||||||
|
import { GROUP } from '../../../../core/eperson/models/group.resource-type';
|
||||||
|
import { ResourceType } from '../../../../core/shared/resource-type';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-eperson-group-list',
|
selector: 'ds-eperson-group-list',
|
||||||
@@ -69,9 +71,13 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
private subs: Subscription[] = [];
|
private subs: Subscription[] = [];
|
||||||
|
|
||||||
constructor(public dsoNameService: DSONameService,
|
constructor(public dsoNameService: DSONameService, private parentInjector: Injector) {
|
||||||
private epersonService: EPersonDataService,
|
const resourceType: ResourceType = (this.isListOfEPerson) ? EPERSON : GROUP;
|
||||||
private groupsService: GroupDataService) {
|
const provider = getDataServiceFor(resourceType);
|
||||||
|
this.dataService = Injector.create({
|
||||||
|
providers: [],
|
||||||
|
parent: this.parentInjector
|
||||||
|
}).get(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,7 +86,6 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.paginationOptions.id = uniqueId('eperson-group-list-pagination');
|
this.paginationOptions.id = uniqueId('eperson-group-list-pagination');
|
||||||
this.paginationOptions.pageSize = 5;
|
this.paginationOptions.pageSize = 5;
|
||||||
this.dataService = (this.isListOfEPerson) ? this.epersonService : this.groupsService;
|
|
||||||
|
|
||||||
if (this.initSelected) {
|
if (this.initSelected) {
|
||||||
this.entrySelectedId.next(this.initSelected);
|
this.entrySelectedId.next(this.initSelected);
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<label for="ResourcePolicyObject">{{'resource-policies.form.eperson-group-list.label' | translate}}</label>
|
<label for="ResourcePolicyObject">{{'resource-policies.form.eperson-group-list.label' | translate}}</label>
|
||||||
<input id="ResourcePolicyObject" class="form-control mb-3" type="text" readonly [value]="getResourcePolicyTargetName()">
|
<input id="ResourcePolicyObject" class="form-control mb-3" type="text" readonly [value]="getResourcePolicyTargetName()">
|
||||||
<ngb-tabset type="pills">
|
<ngb-tabset *ngIf="canSetGrant()" type="pills">
|
||||||
<ngb-tab [title]="'resource-policies.form.eperson-group-list.tab.eperson' | translate">
|
<ngb-tab [title]="'resource-policies.form.eperson-group-list.tab.eperson' | translate">
|
||||||
<ng-template ngbTabContent>
|
<ng-template ngbTabContent>
|
||||||
<ds-eperson-group-list (select)="updateObjectSelected($event, true)"></ds-eperson-group-list>
|
<ds-eperson-group-list (select)="updateObjectSelected($event, true)"></ds-eperson-group-list>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
|
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
|
||||||
|
|
||||||
@@ -22,8 +22,11 @@ import { DsDynamicTextAreaModel } from '../../form/builder/ds-dynamic-form-ui/mo
|
|||||||
import { DynamicDsDatePickerModel } from '../../form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.model';
|
import { DynamicDsDatePickerModel } from '../../form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.model';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||||
import { hasValue, isNotEmpty } from '../../empty.util';
|
import { hasValue, isEmpty, isNotEmpty } from '../../empty.util';
|
||||||
import { FormService } from '../../form/form.service';
|
import { FormService } from '../../form/form.service';
|
||||||
|
import { RESOURCE_POLICY } from '../../../core/resource-policy/models/resource-policy.resource-type';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { Subscription } from 'rxjs/internal/Subscription';
|
||||||
|
|
||||||
export interface ResourcePolicyEvent {
|
export interface ResourcePolicyEvent {
|
||||||
object: ResourcePolicy,
|
object: ResourcePolicy,
|
||||||
@@ -40,10 +43,10 @@ export interface ResourcePolicyEvent {
|
|||||||
/**
|
/**
|
||||||
* Component that show form for adding/editing a resource policy
|
* Component that show form for adding/editing a resource policy
|
||||||
*/
|
*/
|
||||||
export class ResourcePolicyFormComponent implements OnInit {
|
export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resource policy to edit
|
* If given contains the resource policy to edit
|
||||||
* @type {ResourcePolicy}
|
* @type {ResourcePolicy}
|
||||||
*/
|
*/
|
||||||
@Input() resourcePolicy: ResourcePolicy;
|
@Input() resourcePolicy: ResourcePolicy;
|
||||||
@@ -76,13 +79,19 @@ export class ResourcePolicyFormComponent implements OnInit {
|
|||||||
* The eperson or group that will be grant of the permission
|
* The eperson or group that will be grant of the permission
|
||||||
* @type {DSpaceObject}
|
* @type {DSpaceObject}
|
||||||
*/
|
*/
|
||||||
public resourcePolicyTarget: DSpaceObject;
|
public resourcePolicyGrant: DSpaceObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the object that will be grant of the permission. It could be 'eperson' or 'group'
|
* The type of the object that will be grant of the permission. It could be 'eperson' or 'group'
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
public resourcePolicyTargetType: string;
|
public resourcePolicyGrantType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||||
|
* @type {Array}
|
||||||
|
*/
|
||||||
|
private subs: Subscription[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables
|
* Initialize instance variables
|
||||||
@@ -102,6 +111,14 @@ export class ResourcePolicyFormComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.formId = this.formService.getUniqueId('resource-policy-form');
|
this.formId = this.formService.getUniqueId('resource-policy-form');
|
||||||
this.formModel = this.buildResourcePolicyForm();
|
this.formModel = this.buildResourcePolicyForm();
|
||||||
|
|
||||||
|
if (!this.canSetGrant()) {
|
||||||
|
this.subs.push(observableCombineLatest([this.resourcePolicy.eperson, this.resourcePolicy.group])
|
||||||
|
.subscribe(([epersonRD, groupRD]: [RemoteData<DSpaceObject>, RemoteData<DSpaceObject>]) => {
|
||||||
|
this.resourcePolicyGrant = epersonRD.payload || groupRD.payload;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +128,7 @@ export class ResourcePolicyFormComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
isFormValid(): Observable<boolean> {
|
isFormValid(): Observable<boolean> {
|
||||||
return this.formService.isValid(this.formId).pipe(
|
return this.formService.isValid(this.formId).pipe(
|
||||||
map((isValid: boolean) => isValid && isNotEmpty(this.resourcePolicyTarget))
|
map((isValid: boolean) => isValid && isNotEmpty(this.resourcePolicyGrant))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,21 +188,31 @@ export class ResourcePolicyFormComponent implements OnInit {
|
|||||||
return formModel;
|
return formModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a boolean representing If is possible to set policy grant
|
||||||
|
*
|
||||||
|
* @return true if is possible, false otherwise
|
||||||
|
*/
|
||||||
|
canSetGrant(): boolean {
|
||||||
|
return isEmpty(this.resourcePolicy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the name of the eperson or group that will be grant of the permission
|
* Return the name of the eperson or group that will be grant of the permission
|
||||||
*
|
*
|
||||||
* @return the object name
|
* @return the object name
|
||||||
*/
|
*/
|
||||||
getResourcePolicyTargetName(): string {
|
getResourcePolicyTargetName(): string {
|
||||||
return isNotEmpty(this.resourcePolicyTarget) ? this.dsoNameService.getName(this.resourcePolicyTarget) : '';
|
console.log(this.resourcePolicy);
|
||||||
|
return isNotEmpty(this.resourcePolicyGrant) ? this.dsoNameService.getName(this.resourcePolicyGrant) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update reference to the eperson or group that will be grant of the permission
|
* Update reference to the eperson or group that will be grant of the permission
|
||||||
*/
|
*/
|
||||||
updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void {
|
updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void {
|
||||||
this.resourcePolicyTarget = object;
|
this.resourcePolicyGrant = object;
|
||||||
this.resourcePolicyTargetType = isEPerson ? 'eperson' : 'group';
|
this.resourcePolicyGrantType = isEPerson ? 'eperson' : 'group';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,17 +231,40 @@ export class ResourcePolicyFormComponent implements OnInit {
|
|||||||
this.formService.getFormData(this.formId)
|
this.formService.getFormData(this.formId)
|
||||||
.subscribe((data) => {
|
.subscribe((data) => {
|
||||||
const eventPayload: ResourcePolicyEvent = Object.create({});
|
const eventPayload: ResourcePolicyEvent = Object.create({});
|
||||||
const resourcePolicy = new ResourcePolicy();
|
eventPayload.object = this.createResourcePolicyByFormData(data);
|
||||||
resourcePolicy.name = data.name;
|
console.log('resourcePolicyTarget', this.resourcePolicyGrant.type.value);
|
||||||
resourcePolicy.description = data.description;
|
eventPayload.target = {
|
||||||
resourcePolicy.policyType = data.policyType;
|
type: this.resourcePolicyGrantType,
|
||||||
resourcePolicy.action = data.action;
|
uuid: this.resourcePolicyGrant.id
|
||||||
resourcePolicy.startDate = (data.date) ? data.date.start : undefined;
|
};
|
||||||
resourcePolicy.endDate = (data.date) ? data.date.end : undefined;
|
|
||||||
eventPayload.object = resourcePolicy;
|
|
||||||
eventPayload.target.type = this.resourcePolicyTargetType;
|
|
||||||
eventPayload.target.uuid = this.resourcePolicyTarget.id;
|
|
||||||
this.submit.emit(eventPayload);
|
this.submit.emit(eventPayload);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create e new ResourcePolicy by form data
|
||||||
|
*
|
||||||
|
* @return the new ResourcePolicy object
|
||||||
|
*/
|
||||||
|
createResourcePolicyByFormData(data): ResourcePolicy {
|
||||||
|
const resourcePolicy = new ResourcePolicy();
|
||||||
|
resourcePolicy.name = (data.name) ? data.name[0].value : null;
|
||||||
|
resourcePolicy.description = (data.description) ? data.description[0].value : null;
|
||||||
|
resourcePolicy.policyType = (data.policyType) ? data.policyType[0].value : null;
|
||||||
|
resourcePolicy.action = (data.action) ? data.action[0].value : null;
|
||||||
|
resourcePolicy.startDate = (data.date && data.date.start) ? data.date.start[0].value : null;
|
||||||
|
resourcePolicy.endDate = (data.date && data.date.end) ? data.date.end[0].value : null;
|
||||||
|
resourcePolicy.type = RESOURCE_POLICY;
|
||||||
|
|
||||||
|
return resourcePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribe from all subscriptions
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subs
|
||||||
|
.filter((subscription) => hasValue(subscription))
|
||||||
|
.forEach((subscription) => subscription.unsubscribe())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable, Injector } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { find } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { getDataServiceFor } from '../../../core/cache/builders/build-decorators';
|
||||||
|
import { ResourceType } from '../../../core/shared/resource-type';
|
||||||
|
import { DataService } from '../../../core/data/data.service';
|
||||||
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
|
import { hasValue, isEmpty } from '../../empty.util';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a resolver that requests a specific item before the route is activated
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ResourcePolicyTargetResolver implements Resolve<RemoteData<DSpaceObject>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data service used to make request.
|
||||||
|
*/
|
||||||
|
private dataService: DataService<DSpaceObject>;
|
||||||
|
|
||||||
|
constructor(private parentInjector: Injector, private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for resolving an item based on the parameters in the current route
|
||||||
|
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
|
||||||
|
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
|
||||||
|
* @returns Observable<<RemoteData<Item>> Emits the found item based on the parameters in the current route,
|
||||||
|
* or an error if something went wrong
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<DSpaceObject>> {
|
||||||
|
const targetType = route.queryParamMap.get('targetType');
|
||||||
|
const policyTargetId = route.queryParamMap.get('policyTargetId');
|
||||||
|
|
||||||
|
if (isEmpty(targetType) || isEmpty(policyTargetId)) {
|
||||||
|
this.router.navigateByUrl('/404', { skipLocationChange: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = getDataServiceFor(new ResourceType(targetType));
|
||||||
|
this.dataService = Injector.create({
|
||||||
|
providers: [],
|
||||||
|
parent: this.parentInjector
|
||||||
|
}).get(provider);
|
||||||
|
|
||||||
|
return this.dataService.findById(policyTargetId).pipe(
|
||||||
|
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { find } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { hasValue, isEmpty } from '../../empty.util';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||||
|
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||||
|
import { followLink } from '../../utils/follow-link-config.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a resolver that requests a specific item before the route is activated
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ResourcePolicyResolver implements Resolve<RemoteData<ResourcePolicy>> {
|
||||||
|
|
||||||
|
constructor(private resourcePolicyService: ResourcePolicyService, private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for resolving an item based on the parameters in the current route
|
||||||
|
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
|
||||||
|
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
|
||||||
|
* @returns Observable<<RemoteData<Item>> Emits the found item based on the parameters in the current route,
|
||||||
|
* or an error if something went wrong
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<ResourcePolicy>> {
|
||||||
|
const policyId = route.queryParamMap.get('policyId');
|
||||||
|
|
||||||
|
if (isEmpty(policyId)) {
|
||||||
|
this.router.navigateByUrl('/404', { skipLocationChange: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.resourcePolicyService.findById(policyId, followLink('eperson'), followLink('group')).pipe(
|
||||||
|
find((RD) => hasValue(RD.error) || RD.hasSucceeded),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -4,9 +4,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th colspan="7">
|
<th colspan="7">
|
||||||
<p class="d-flex justify-content-between align-items-center m-0">
|
<p class="d-flex justify-content-between align-items-center m-0">
|
||||||
{{ 'resource-policies.table.headers.title.for.' + resourceKey | translate }} {{resourceUUID}}
|
{{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} {{resourceUUID}}
|
||||||
<button class="btn btn-outline-primary float-right" (click)="createResourcePolicy()">
|
<button class="btn btn-outline-primary float-right" (click)="createResourcePolicy()">
|
||||||
{{'resource-policies.add.for.' + resourceKey | translate}}
|
{{'resource-policies.add.for.' + resourceType | translate}}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</th>
|
</th>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
<tr class="text-center">
|
<tr class="text-center">
|
||||||
<th>{{'resource-policies.table.headers.id' | translate}}</th>
|
<th>{{'resource-policies.table.headers.id' | translate}}</th>
|
||||||
<th>{{'resource-policies.table.headers.name' | translate}}</th>
|
<th>{{'resource-policies.table.headers.name' | translate}}</th>
|
||||||
|
<th>{{'resource-policies.table.headers.policyType' | translate}}</th>
|
||||||
<th>{{'resource-policies.table.headers.action' | translate}}</th>
|
<th>{{'resource-policies.table.headers.action' | translate}}</th>
|
||||||
<th>{{'resource-policies.table.headers.eperson' | translate}}</th>
|
<th>{{'resource-policies.table.headers.eperson' | translate}}</th>
|
||||||
<th>{{'resource-policies.table.headers.group' | translate}}</th>
|
<th>{{'resource-policies.table.headers.group' | translate}}</th>
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</th>
|
</th>
|
||||||
<td>{{policy.name}}</td>
|
<td>{{policy.name}}</td>
|
||||||
|
<td>{{policy.policyType}}</td>
|
||||||
<td>{{policy.action}}</td>
|
<td>{{policy.action}}</td>
|
||||||
<td *ngIf="(hasEPerson(policy) | async)">
|
<td *ngIf="(hasEPerson(policy) | async)">
|
||||||
{{getEPersonName(policy) | async}}
|
{{getEPersonName(policy) | async}}
|
||||||
|
@@ -1,12 +1,16 @@
|
|||||||
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { filter, map, startWith, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ResourcePolicyService } from '../../core/resource-policy/resource-policy.service';
|
import { ResourcePolicyService } from '../../core/resource-policy/resource-policy.service';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { getFirstSucceededRemoteDataPayload, getSucceededRemoteData } from '../../core/shared/operators';
|
import {
|
||||||
|
getFirstSucceededRemoteDataPayload,
|
||||||
|
getFirstSucceededRemoteDataWithNotEmptyPayload,
|
||||||
|
getSucceededRemoteData
|
||||||
|
} from '../../core/shared/operators';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
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';
|
||||||
@@ -15,6 +19,8 @@ import { GroupDataService } from '../../core/eperson/group-data.service';
|
|||||||
import { hasValue, isNotEmpty } from '../empty.util';
|
import { hasValue, isNotEmpty } from '../empty.util';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
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 { followLink } from '../utils/follow-link-config.model';
|
||||||
|
import { RequestService } from '../../core/data/request.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-resource-policies',
|
selector: 'ds-resource-policies',
|
||||||
@@ -36,13 +42,20 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* The resource type (e.g. 'item', 'bundle' etc) used as key to build automatically translation label
|
* The resource type (e.g. 'item', 'bundle' etc) used as key to build automatically translation label
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
@Input() public resourceKey: string;
|
@Input() public resourceType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if component is active
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
private isActive: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of policies for given resource
|
* The list of policies for given resource
|
||||||
* @type {Observable<RemoteData<PaginatedList<ResourcePolicy>>>}
|
* @type {Observable<RemoteData<PaginatedList<ResourcePolicy>>>}
|
||||||
*/
|
*/
|
||||||
private resourcePolicies$: Observable<RemoteData<PaginatedList<ResourcePolicy>>>;
|
private resourcePolicies$: BehaviorSubject<RemoteData<PaginatedList<ResourcePolicy>>> =
|
||||||
|
new BehaviorSubject<RemoteData<PaginatedList<ResourcePolicy>>>({} as any);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||||
@@ -57,6 +70,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @param {DSONameService} dsoNameService
|
* @param {DSONameService} dsoNameService
|
||||||
* @param {EPersonDataService} ePersonService
|
* @param {EPersonDataService} ePersonService
|
||||||
* @param {GroupDataService} groupService
|
* @param {GroupDataService} groupService
|
||||||
|
* @param {RequestService} requestService
|
||||||
* @param {ResourcePolicyService} resourcePolicyService
|
* @param {ResourcePolicyService} resourcePolicyService
|
||||||
* @param {ActivatedRoute} route
|
* @param {ActivatedRoute} route
|
||||||
* @param {Router} router
|
* @param {Router} router
|
||||||
@@ -66,6 +80,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
private dsoNameService: DSONameService,
|
private dsoNameService: DSONameService,
|
||||||
private ePersonService: EPersonDataService,
|
private ePersonService: EPersonDataService,
|
||||||
private groupService: GroupDataService,
|
private groupService: GroupDataService,
|
||||||
|
private requestService: RequestService,
|
||||||
private resourcePolicyService: ResourcePolicyService,
|
private resourcePolicyService: ResourcePolicyService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router
|
private router: Router
|
||||||
@@ -76,9 +91,16 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* Initialize the component, setting up the resource's policies
|
* Initialize the component, setting up the resource's policies
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.resourcePolicies$ = this.resourcePolicyService.searchByResource(this.resourceUUID).pipe(
|
this.isActive = true;
|
||||||
getSucceededRemoteData()
|
this.requestService.removeByHrefSubstring(this.resourceUUID);
|
||||||
);
|
this.resourcePolicyService.searchByResource(this.resourceUUID, null,
|
||||||
|
followLink('eperson'), followLink('group')).pipe(
|
||||||
|
filter(() => this.isActive),
|
||||||
|
getSucceededRemoteData(),
|
||||||
|
take(1)
|
||||||
|
).subscribe((result) => {
|
||||||
|
this.resourcePolicies$.next(result);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +108,13 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* Redirect to resource policy creation page
|
* Redirect to resource policy creation page
|
||||||
*/
|
*/
|
||||||
createResourcePolicy(): void {
|
createResourcePolicy(): void {
|
||||||
this.router.navigate([`../${this.resourceUUID}/create`], { relativeTo: this.route })
|
this.router.navigate([`../create`], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: {
|
||||||
|
policyTargetId: this.resourceUUID,
|
||||||
|
targetType: this.resourceType
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +123,12 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @param policy The resource policy
|
* @param policy The resource policy
|
||||||
*/
|
*/
|
||||||
editResourcePolicy(policy: ResourcePolicy): void {
|
editResourcePolicy(policy: ResourcePolicy): void {
|
||||||
this.router.navigate([`../${this.resourceUUID}/${policy.id}/edit`], { relativeTo: this.route })
|
this.router.navigate([`../edit`], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: {
|
||||||
|
policyId: policy.id
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,9 +137,11 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @param policy The resource policy
|
* @param policy The resource policy
|
||||||
*/
|
*/
|
||||||
getEPersonName(policy: ResourcePolicy): Observable<string> {
|
getEPersonName(policy: ResourcePolicy): Observable<string> {
|
||||||
return this.ePersonService.findByHref(policy._links.eperson.href).pipe(
|
return policy.eperson.pipe(
|
||||||
getFirstSucceededRemoteDataPayload(),
|
filter(() => this.isActive),
|
||||||
map((eperson: EPerson) => this.dsoNameService.getName(eperson))
|
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||||
|
map((eperson: EPerson) => this.dsoNameService.getName(eperson)),
|
||||||
|
startWith('')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,9 +151,11 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @param policy The resource policy
|
* @param policy The resource policy
|
||||||
*/
|
*/
|
||||||
getGroupName(policy: ResourcePolicy): Observable<string> {
|
getGroupName(policy: ResourcePolicy): Observable<string> {
|
||||||
return this.groupService.findByHref(policy._links.group.href).pipe(
|
return policy.group.pipe(
|
||||||
getFirstSucceededRemoteDataPayload(),
|
filter(() => this.isActive),
|
||||||
map((group: Group) => this.dsoNameService.getName(group))
|
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||||
|
map((group: Group) => this.dsoNameService.getName(group)),
|
||||||
|
startWith('')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +165,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @return an observable that emits all resource's policies
|
* @return an observable that emits all resource's policies
|
||||||
*/
|
*/
|
||||||
getResourcePolicies(): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
getResourcePolicies(): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
||||||
return this.resourcePolicies$;
|
return this.resourcePolicies$.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,7 +175,8 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @return an observable that emits true when the policy is linked to a ePerson, false otherwise
|
* @return an observable that emits true when the policy is linked to a ePerson, false otherwise
|
||||||
*/
|
*/
|
||||||
hasEPerson(policy): Observable<boolean> {
|
hasEPerson(policy): Observable<boolean> {
|
||||||
return this.ePersonService.findByHref(policy._links.eperson.href).pipe(
|
return policy.eperson.pipe(
|
||||||
|
filter(() => this.isActive),
|
||||||
getFirstSucceededRemoteDataPayload(),
|
getFirstSucceededRemoteDataPayload(),
|
||||||
map((eperson: EPerson) => isNotEmpty(eperson))
|
map((eperson: EPerson) => isNotEmpty(eperson))
|
||||||
)
|
)
|
||||||
@@ -151,7 +189,8 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* @return an observable that emits true when the policy is linked to a group, false otherwise
|
* @return an observable that emits true when the policy is linked to a group, false otherwise
|
||||||
*/
|
*/
|
||||||
hasGroup(policy): Observable<boolean> {
|
hasGroup(policy): Observable<boolean> {
|
||||||
return this.groupService.findByHref(policy._links.group.href).pipe(
|
return policy.group.pipe(
|
||||||
|
filter(() => this.isActive),
|
||||||
getFirstSucceededRemoteDataPayload(),
|
getFirstSucceededRemoteDataPayload(),
|
||||||
map((group: Group) => isNotEmpty(group))
|
map((group: Group) => isNotEmpty(group))
|
||||||
)
|
)
|
||||||
@@ -164,7 +203,8 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
redirectToGroupEditPage(policy: ResourcePolicy): void {
|
redirectToGroupEditPage(policy: ResourcePolicy): void {
|
||||||
this.subs.push(
|
this.subs.push(
|
||||||
this.groupService.findByHref(policy._links.group.href).pipe(
|
policy.group.pipe(
|
||||||
|
filter(() => this.isActive),
|
||||||
getFirstSucceededRemoteDataPayload(),
|
getFirstSucceededRemoteDataPayload(),
|
||||||
map((group: Group) => group.id)
|
map((group: Group) => group.id)
|
||||||
).subscribe((groupUUID) => this.router.navigate(['groups', groupUUID, 'edit']))
|
).subscribe((groupUUID) => this.router.navigate(['groups', groupUUID, 'edit']))
|
||||||
@@ -175,6 +215,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
|||||||
* Unsubscribe from all subscriptions
|
* Unsubscribe from all subscriptions
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
this.isActive = false;
|
||||||
this.subs
|
this.subs
|
||||||
.filter((subscription) => hasValue(subscription))
|
.filter((subscription) => hasValue(subscription))
|
||||||
.forEach((subscription) => subscription.unsubscribe())
|
.forEach((subscription) => subscription.unsubscribe())
|
||||||
|
@@ -189,9 +189,9 @@ import { ItemVersionsNoticeComponent } from './item/item-versions/notice/item-ve
|
|||||||
import { ResourcePoliciesComponent } from './resource-policies/resource-policies.component';
|
import { ResourcePoliciesComponent } from './resource-policies/resource-policies.component';
|
||||||
import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive';
|
import { NgForTrackByIdDirective } from './ng-for-track-by-id.directive';
|
||||||
import { ResourcePolicyFormComponent } from './resource-policies/form/resource-policy-form';
|
import { ResourcePolicyFormComponent } from './resource-policies/form/resource-policy-form';
|
||||||
import { ResourcePolicyCreateComponent } from './resource-policies/create/resource-policy-create.component';
|
|
||||||
import { ResourcePolicyEditComponent } from './resource-policies/edit/resource-policy-edit.component';
|
|
||||||
import { EpersonGroupListComponent } from './resource-policies/form/eperson-group-list/eperson-group-list.component';
|
import { EpersonGroupListComponent } from './resource-policies/form/eperson-group-list/eperson-group-list.component';
|
||||||
|
import { ResourcePolicyTargetResolver } from './resource-policies/resolvers/resource-policy-target.resolver';
|
||||||
|
import { ResourcePolicyResolver } from './resource-policies/resolvers/resource-policy.resolver';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||||
@@ -366,8 +366,6 @@ const COMPONENTS = [
|
|||||||
ItemVersionsNoticeComponent,
|
ItemVersionsNoticeComponent,
|
||||||
ResourcePoliciesComponent,
|
ResourcePoliciesComponent,
|
||||||
ResourcePolicyFormComponent,
|
ResourcePolicyFormComponent,
|
||||||
ResourcePolicyCreateComponent,
|
|
||||||
ResourcePolicyEditComponent,
|
|
||||||
EpersonGroupListComponent
|
EpersonGroupListComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -435,9 +433,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
LogInPasswordComponent,
|
LogInPasswordComponent,
|
||||||
LogInShibbolethComponent,
|
LogInShibbolethComponent,
|
||||||
ItemVersionsComponent,
|
ItemVersionsComponent,
|
||||||
ItemVersionsNoticeComponent,
|
ItemVersionsNoticeComponent
|
||||||
ResourcePolicyCreateComponent,
|
|
||||||
ResourcePolicyEditComponent
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const SHARED_ITEM_PAGE_COMPONENTS = [
|
const SHARED_ITEM_PAGE_COMPONENTS = [
|
||||||
@@ -452,7 +448,9 @@ const PROVIDERS = [
|
|||||||
{
|
{
|
||||||
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
||||||
useValue: dsDynamicFormControlMapFn
|
useValue: dsDynamicFormControlMapFn
|
||||||
}
|
},
|
||||||
|
ResourcePolicyResolver,
|
||||||
|
ResourcePolicyTargetResolver
|
||||||
];
|
];
|
||||||
|
|
||||||
const DIRECTIVES = [
|
const DIRECTIVES = [
|
||||||
|
Reference in New Issue
Block a user