Show the policies for each bundle and bitstream within the item

This commit is contained in:
Giuseppe Digilio
2020-03-30 12:57:33 +02:00
parent 18d38ca737
commit 1f26a7b634
3 changed files with 111 additions and 9 deletions

View File

@@ -745,6 +745,8 @@
"item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.",
"item.edit.authorizations.title": "Edit item's Policies",

View File

@@ -1,3 +1,13 @@
<div class="container">
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
<ds-resource-policies [resourceKey]="'item'" [resourceUUID]="(getItemUUID() | async)"></ds-resource-policies>
<ng-container *ngFor="let bundle of (getItemBundles() | async)?.page; trackById">
<ds-resource-policies [resourceKey]="'bundle'"
[resourceUUID]="bundle.id"></ds-resource-policies>
<ng-container *ngFor="let bitstream of (bundleBitstreamsMap.get(bundle.id) | async)?.page; trackById">
<ds-resource-policies [resourceKey]="'bitstream'"
[resourceUUID]="bitstream.id"></ds-resource-policies>
</ng-container>
</ng-container>
</div>

View File

@@ -1,17 +1,24 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { flatMap, map } from 'rxjs/operators';
import { Observable, of as observableOf, Subscription } from 'rxjs';
import { catchError, filter, first, flatMap, map, take } from 'rxjs/operators';
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
import { PaginatedList } from '../../../core/data/paginated-list';
import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
import { RemoteData } from '../../../core/data/remote-data';
import { Item } from '../../../core/shared/item.model';
import { followLink } from '../../../shared/utils/follow-link-config.model';
import { LinkService } from '../../../core/cache/builders/link.service';
import { Bundle } from '../../../core/shared/bundle.model';
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
import { Bitstream } from '../../../core/shared/bitstream.model';
import { FindListOptions } from '../../../core/data/request.models';
interface BundleBitstreamsMapEntry {
id: string;
bitstreams: Observable<PaginatedList<Bitstream>>
}
@Component({
selector: 'ds-item-authorizations',
@@ -20,11 +27,35 @@ import { Bundle } from '../../../core/shared/bundle.model';
/**
* Component that handles the item Authorizations
*/
export class ItemAuthorizationsComponent implements OnInit {
export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
private bundles$: Observable<RemoteData<PaginatedList<Bundle>>>;
public bundleBitstreamsMap: Map<string, Observable<PaginatedList<Bitstream>>> = new Map<string, Observable<PaginatedList<Bitstream>>>();
/**
* The list of bundle for the item
* @type {Observable<PaginatedList<Bundle>>}
*/
private bundles$: Observable<PaginatedList<Bundle>>;
/**
* The target editing item
* @type {Observable<Item>}
*/
private item$: Observable<Item>;
/**
* Array to track all subscriptions and unsubscribe them onDestroy
* @type {Array}
*/
private subs: Subscription[] = [];
/**
* Initialize instance variables
*
* @param {LinkService} linkService
* @param {ResourcePolicyService} resourcePolicyService
* @param {ActivatedRoute} route
*/
constructor(
private linkService: LinkService,
private resourcePolicyService: ResourcePolicyService,
@@ -32,15 +63,74 @@ export class ItemAuthorizationsComponent implements OnInit {
) {
}
/**
* Initialize the component, setting up the bundle and bitstream within the item
*/
ngOnInit(): void {
this.item$ = this.route.data.pipe(
map((data) => data.item),
getFirstSucceededRemoteDataPayload(),
map((item: Item) => this.linkService.resolveLink(item, followLink('bundles')))
map((item: Item) => this.linkService.resolveLink(
item,
followLink('bundles', new FindListOptions(), true, followLink('bitstreams'))
))
) as Observable<Item>;
this.bundles$ = this.item$.pipe(flatMap((item: Item) => item.bundles));
this.bundles$ = this.item$.pipe(
filter((item: Item) => isNotEmpty(item.bundles)),
flatMap((item: Item) => item.bundles),
getFirstSucceededRemoteDataPayload(),
catchError(() => observableOf(new PaginatedList(null, [])))
);
this.subs.push(
this.bundles$.pipe(
take(1),
flatMap((list: PaginatedList<Bundle>) => list.page),
map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) }))
).subscribe((entry: BundleBitstreamsMapEntry) => {
this.bundleBitstreamsMap.set(entry.id, entry.bitstreams)
})
)
}
/**
* Return the item's UUID
*/
getItemUUID(): Observable<string> {
return this.item$.pipe(
map((item: Item) => item.id),
first((UUID: string) => isNotEmpty(UUID))
)
}
/**
* Return all item's bundles
*
* @return an observable that emits all item's bundles
*/
getItemBundles(): Observable<PaginatedList<Bundle>> {
return this.bundles$
}
/**
* Return all bundle's bitstreams
*
* @return an observable that emits all item's bundles
*/
private getBundleBitstreams(bundle: Bundle): Observable<PaginatedList<Bitstream>> {
return bundle.bitstreams.pipe(
getFirstSucceededRemoteDataPayload(),
catchError(() => observableOf(new PaginatedList(null, [])))
)
}
/**
* Unsubscribe from all subscriptions
*/
ngOnDestroy(): void {
this.subs
.filter((subscription) => hasValue(subscription))
.forEach((subscription) => subscription.unsubscribe())
}
}