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:
@@ -1812,6 +1812,12 @@
|
||||
|
||||
"resource-policies.create.page.title": "Create new resource policy",
|
||||
|
||||
"resource-policies.delete.btn": "Delete selected resource policies",
|
||||
|
||||
"resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.",
|
||||
|
||||
"resource-policies.delete.success.content": "Operation successful",
|
||||
|
||||
"resource-policies.edit.page.heading": "Edit resource policy ",
|
||||
|
||||
"resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.",
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div class="container">
|
||||
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
|
||||
<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); trackById">
|
||||
<ds-resource-policies [resourceType]="'bundle'"
|
||||
[resourceUUID]="bundle.id"></ds-resource-policies>
|
||||
<ng-container *ngFor="let bitstream of (bundleBitstreamsMap.get(bundle.id) | async)?.page; trackById">
|
||||
|
@@ -1,12 +1,15 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { Observable, of as observableOf, Subscription } from 'rxjs';
|
||||
import { BehaviorSubject, 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 {
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload
|
||||
} from '../../../core/shared/operators';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
import { LinkService } from '../../../core/cache/builders/link.service';
|
||||
@@ -15,6 +18,9 @@ import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { FindListOptions } from '../../../core/data/request.models';
|
||||
|
||||
/**
|
||||
* Interface for a bundle's bitstream map entry
|
||||
*/
|
||||
interface BundleBitstreamsMapEntry {
|
||||
id: string;
|
||||
bitstreams: Observable<PaginatedList<Bitstream>>
|
||||
@@ -35,7 +41,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
* The list of bundle for the item
|
||||
* @type {Observable<PaginatedList<Bundle>>}
|
||||
*/
|
||||
private bundles$: Observable<PaginatedList<Bundle>>;
|
||||
private bundles$: BehaviorSubject<Bundle[]> = new BehaviorSubject<Bundle[]>([]);
|
||||
|
||||
/**
|
||||
* The target editing item
|
||||
@@ -69,22 +75,28 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
ngOnInit(): void {
|
||||
this.item$ = this.route.data.pipe(
|
||||
map((data) => data.item),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
map((item: Item) => this.linkService.resolveLink(
|
||||
item,
|
||||
followLink('bundles', new FindListOptions(), true, followLink('bitstreams'))
|
||||
))
|
||||
) as Observable<Item>;
|
||||
|
||||
this.bundles$ = this.item$.pipe(
|
||||
const bundles$: Observable<PaginatedList<Bundle>> = this.item$.pipe(
|
||||
filter((item: Item) => isNotEmpty(item.bundles)),
|
||||
flatMap((item: Item) => item.bundles),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
catchError(() => observableOf(new PaginatedList(null, [])))
|
||||
);
|
||||
|
||||
this.subs.push(
|
||||
this.bundles$.pipe(
|
||||
bundles$.pipe(
|
||||
take(1),
|
||||
map((list: PaginatedList<Bundle>) => list.page)
|
||||
).subscribe((bundles: Bundle[]) => {
|
||||
this.bundles$.next(bundles);
|
||||
}),
|
||||
bundles$.pipe(
|
||||
take(1),
|
||||
flatMap((list: PaginatedList<Bundle>) => list.page),
|
||||
map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) }))
|
||||
@@ -109,8 +121,8 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
||||
*
|
||||
* @return an observable that emits all item's bundles
|
||||
*/
|
||||
getItemBundles(): Observable<PaginatedList<Bundle>> {
|
||||
return this.bundles$
|
||||
getItemBundles(): Observable<Bundle[]> {
|
||||
return this.bundles$.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -7,6 +7,7 @@ import { Item } from '../core/shared/item.model';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
import { find } from 'rxjs/operators';
|
||||
import { followLink } from '../shared/utils/follow-link-config.model';
|
||||
import { FindListOptions } from '../core/data/request.models';
|
||||
|
||||
/**
|
||||
* This class represents a resolver that requests a specific item before the route is activated
|
||||
@@ -26,7 +27,7 @@ export class ItemPageResolver implements Resolve<RemoteData<Item>> {
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Item>> {
|
||||
return this.itemService.findById(route.params.id,
|
||||
followLink('owningCollection'),
|
||||
followLink('bundles'),
|
||||
followLink('bundles', new FindListOptions(), true, followLink('bitstreams')),
|
||||
followLink('relationships'),
|
||||
followLink('version', undefined, true, followLink('versionhistory')),
|
||||
).pipe(
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<div class="container">
|
||||
<h4 class="mb-3">{{'resource-policies.edit.page.heading' | translate}} {{targetResourceName}}</h4>
|
||||
<h4 class="mb-3">{{'resource-policies.create.page.heading' | translate}} {{targetResourceName}}</h4>
|
||||
|
||||
<ds-resource-policy-form (reset)="redirectToAuthorizationsPage()"
|
||||
<ds-resource-policy-form [isProcessing]="isProcessing()"
|
||||
(reset)="redirectToAuthorizationsPage()"
|
||||
(submit)="createResourcePolicy($event)"></ds-resource-policy-form>
|
||||
</div>
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { first, map, take } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||
@@ -18,19 +20,29 @@ import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||
})
|
||||
export class ResourcePolicyCreateComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* The name of the resource target of the policy
|
||||
*/
|
||||
public targetResourceName: string;
|
||||
|
||||
/**
|
||||
* A boolean representing if a submission creation operation is pending
|
||||
* @type {BehaviorSubject<boolean>}
|
||||
*/
|
||||
private processing$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
/**
|
||||
* The uuid of the resource target of the policy
|
||||
*/
|
||||
private targetResourceUUID: string;
|
||||
|
||||
public targetResourceName: string;
|
||||
|
||||
constructor(
|
||||
private dsoNameService: DSONameService,
|
||||
private notificationsService: NotificationsService,
|
||||
private resourcePolicyService: ResourcePolicyService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router) {
|
||||
private router: Router,
|
||||
private translate: TranslateService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -43,11 +55,16 @@ export class ResourcePolicyCreateComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
redirectToAuthorizationsPage() {
|
||||
isProcessing(): Observable<boolean> {
|
||||
return this.processing$.asObservable();
|
||||
}
|
||||
|
||||
redirectToAuthorizationsPage(): void {
|
||||
this.router.navigate([`../../${ITEM_EDIT_AUTHORIZATIONS_PATH}`], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
createResourcePolicy(event: ResourcePolicyEvent) {
|
||||
createResourcePolicy(event: ResourcePolicyEvent): void {
|
||||
this.processing$.next(true);
|
||||
let response$;
|
||||
if (event.target.type === 'eperson') {
|
||||
response$ = this.resourcePolicyService.create(event.object, this.targetResourceUUID, event.target.uuid);
|
||||
@@ -57,11 +74,12 @@ export class ResourcePolicyCreateComponent implements OnInit {
|
||||
response$.pipe(
|
||||
first((response: RemoteData<ResourcePolicy>) => !response.isResponsePending)
|
||||
).subscribe((responseRD: RemoteData<ResourcePolicy>) => {
|
||||
this.processing$.next(false);
|
||||
if (responseRD.hasSucceeded) {
|
||||
this.notificationsService.success(null, 'resource-policies.create.page.success.content');
|
||||
this.notificationsService.success(null, this.translate.get('resource-policies.create.page.success.content'));
|
||||
this.redirectToAuthorizationsPage();
|
||||
} else {
|
||||
this.notificationsService.error(null, 'resource-policies.create.page.failure.content');
|
||||
this.notificationsService.success(null, this.translate.get('resource-policies.create.page.failure.content'));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
<h4 class="mb-3">{{'resource-policies.edit.page.heading' | translate}} {{resourcePolicy.id}}</h4>
|
||||
|
||||
<ds-resource-policy-form [resourcePolicy]="resourcePolicy"
|
||||
[isProcessing]="isProcessing()"
|
||||
(reset)="redirectToAuthorizationsPage()"
|
||||
(submit)="updateResourcePolicy($event)"></ds-resource-policy-form>
|
||||
</div>
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { first, map, take } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||
import { NotificationsService } from '../../notifications/notifications.service';
|
||||
@@ -9,6 +11,7 @@ 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 { RESOURCE_POLICY } from '../../../core/resource-policy/models/resource-policy.resource-type';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-resource-policy-edit',
|
||||
@@ -21,11 +24,18 @@ export class ResourcePolicyEditComponent implements OnInit {
|
||||
*/
|
||||
public resourcePolicy: ResourcePolicy;
|
||||
|
||||
/**
|
||||
* A boolean representing if a submission editing operation is pending
|
||||
* @type {BehaviorSubject<boolean>}
|
||||
*/
|
||||
private processing$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
constructor(
|
||||
private notificationsService: NotificationsService,
|
||||
private resourcePolicyService: ResourcePolicyService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router) {
|
||||
private router: Router,
|
||||
private translate: TranslateService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -34,26 +44,33 @@ export class ResourcePolicyEditComponent implements OnInit {
|
||||
take(1)
|
||||
).subscribe((data: any) => {
|
||||
this.resourcePolicy = (data.resourcePolicy as RemoteData<ResourcePolicy>).payload;
|
||||
console.log(data)
|
||||
});
|
||||
}
|
||||
|
||||
isProcessing(): Observable<boolean> {
|
||||
return this.processing$.asObservable();
|
||||
}
|
||||
|
||||
redirectToAuthorizationsPage() {
|
||||
this.router.navigate([`../../${ITEM_EDIT_AUTHORIZATIONS_PATH}`], { relativeTo: this.route });
|
||||
}
|
||||
|
||||
updateResourcePolicy(event: ResourcePolicyEvent) {
|
||||
this.processing$.next(true);
|
||||
const updatedObject = Object.assign({}, event.object, {
|
||||
id: this.resourcePolicy.id,
|
||||
type: RESOURCE_POLICY.value,
|
||||
_links: this.resourcePolicy._links
|
||||
});
|
||||
this.resourcePolicyService.update(updatedObject).pipe(
|
||||
first((response: RemoteData<ResourcePolicy>) => !response.isResponsePending)
|
||||
).subscribe((responseRD: RemoteData<ResourcePolicy>) => {
|
||||
this.processing$.next(false);
|
||||
if (responseRD.hasSucceeded) {
|
||||
this.notificationsService.success(null, 'resource-policies.edit.page.success.content');
|
||||
this.notificationsService.success(null, this.translate.get('resource-policies.edit.page.success.content'));
|
||||
this.redirectToAuthorizationsPage();
|
||||
} else {
|
||||
this.notificationsService.error(null, 'resource-policies.edit.page.failure.content');
|
||||
this.notificationsService.error(null, this.translate.get('resource-policies.edit.page.failure.content'));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -151,6 +151,7 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
||||
* Unsubscribe from all subscriptions
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.list$ = null;
|
||||
this.subs
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe())
|
||||
|
@@ -27,11 +27,19 @@
|
||||
<div class="col text-right">
|
||||
<button type="reset"
|
||||
class="btn btn-default"
|
||||
[disabled]="(isProcessing | async)"
|
||||
(click)="onReset()">{{'form.cancel' | translate}}</button>
|
||||
<button type="button"
|
||||
class="btn btn-primary"
|
||||
[disabled]="!(isFormValid() | async)"
|
||||
(click)="onSubmit()">{{'form.submit' | translate}}</button>
|
||||
[disabled]="!(isFormValid() | async) || (isProcessing | async)"
|
||||
(click)="onSubmit()">
|
||||
<span *ngIf="(isProcessing | async)">
|
||||
<i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}
|
||||
</span>
|
||||
<span *ngIf="!(isProcessing | async)">
|
||||
{{'form.submit' | translate}}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
DynamicDateControlModelConfig,
|
||||
DynamicDatePickerModelConfig,
|
||||
DynamicFormControlLayout,
|
||||
DynamicFormGroupModelConfig,
|
||||
DynamicFormOptionConfig,
|
||||
@@ -118,9 +118,12 @@ export const RESOURCE_POLICY_FORM_DATE_GROUP_LAYOUT: DynamicFormControlLayout =
|
||||
}
|
||||
};
|
||||
|
||||
export const RESOURCE_POLICY_FORM_START_DATE_CONFIG: DynamicDateControlModelConfig = {
|
||||
export const RESOURCE_POLICY_FORM_START_DATE_CONFIG: DynamicDatePickerModelConfig = {
|
||||
id: 'start',
|
||||
label: 'resource-policies.form.date.start.label',
|
||||
placeholder: 'resource-policies.form.date.start.label',
|
||||
inline: false,
|
||||
toggleIcon: 'far fa-calendar-alt'
|
||||
};
|
||||
|
||||
export const RESOURCE_POLICY_FORM_START_DATE_LAYOUT: DynamicFormControlLayout = {
|
||||
@@ -133,9 +136,12 @@ export const RESOURCE_POLICY_FORM_START_DATE_LAYOUT: DynamicFormControlLayout =
|
||||
}
|
||||
};
|
||||
|
||||
export const RESOURCE_POLICY_FORM_END_DATE_CONFIG: DynamicDateControlModelConfig = {
|
||||
export const RESOURCE_POLICY_FORM_END_DATE_CONFIG: DynamicDatePickerModelConfig = {
|
||||
id: 'end',
|
||||
label: 'resource-policies.form.date.end.label'
|
||||
label: 'resource-policies.form.date.end.label',
|
||||
placeholder: 'resource-policies.form.date.end.label',
|
||||
inline: false,
|
||||
toggleIcon: 'far fa-calendar-alt'
|
||||
};
|
||||
export const RESOURCE_POLICY_FORM_END_DATE_LAYOUT: DynamicFormControlLayout = {
|
||||
element: {
|
||||
|
@@ -1,8 +1,13 @@
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
|
||||
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { DynamicFormControlModel, DynamicFormGroupModel, DynamicSelectModel } from '@ng-dynamic-forms/core';
|
||||
import { Observable, of as observableOf, race as observableRace } from 'rxjs';
|
||||
import { filter, map, take } from 'rxjs/operators';
|
||||
import {
|
||||
DynamicDatePickerModel,
|
||||
DynamicFormControlModel,
|
||||
DynamicFormGroupModel,
|
||||
DynamicSelectModel
|
||||
} from '@ng-dynamic-forms/core';
|
||||
|
||||
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||
import { DsDynamicInputModel } from '../../form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model';
|
||||
@@ -19,7 +24,6 @@ import {
|
||||
RESOURCE_POLICY_FORM_START_DATE_LAYOUT
|
||||
} from './resource-policy-form.model';
|
||||
import { DsDynamicTextAreaModel } from '../../form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.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 { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../../empty.util';
|
||||
@@ -27,6 +31,11 @@ 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';
|
||||
import { dateToISOFormat, stringToNgbDateStruct } from '../../date.util';
|
||||
import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
|
||||
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { RequestService } from '../../../core/data/request.service';
|
||||
|
||||
export interface ResourcePolicyEvent {
|
||||
object: ResourcePolicy,
|
||||
@@ -51,6 +60,12 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
@Input() resourcePolicy: ResourcePolicy;
|
||||
|
||||
/**
|
||||
* A boolean representing if form submit operation is processing
|
||||
* @type {boolean}
|
||||
*/
|
||||
@Input() isProcessing: Observable<boolean> = observableOf(false);
|
||||
|
||||
/**
|
||||
* An event fired when form is canceled.
|
||||
* Event's payload is empty.
|
||||
@@ -87,6 +102,12 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
public resourcePolicyGrantType: string;
|
||||
|
||||
/**
|
||||
* A boolean representing if component is active
|
||||
* @type {boolean}
|
||||
*/
|
||||
private isActive: boolean;
|
||||
|
||||
/**
|
||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||
* @type {Array}
|
||||
@@ -97,11 +118,17 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
* Initialize instance variables
|
||||
*
|
||||
* @param {DSONameService} dsoNameService
|
||||
* @param {EPersonDataService} ePersonService
|
||||
* @param {FormService} formService
|
||||
* @param {GroupDataService} groupService
|
||||
* @param {RequestService} requestService
|
||||
*/
|
||||
constructor(
|
||||
private dsoNameService: DSONameService,
|
||||
private ePersonService: EPersonDataService,
|
||||
private formService: FormService,
|
||||
private groupService: GroupDataService,
|
||||
private requestService: RequestService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -109,13 +136,24 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
* Initialize the component, setting up the form model
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.isActive = true;
|
||||
this.formId = this.formService.getUniqueId('resource-policy-form');
|
||||
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;
|
||||
this.requestService.removeByHrefSubstring(this.resourcePolicy._links.eperson.href);
|
||||
this.requestService.removeByHrefSubstring(this.resourcePolicy._links.group.href);
|
||||
const epersonRD$ = this.ePersonService.findByHref(this.resourcePolicy._links.eperson.href).pipe(
|
||||
getSucceededRemoteData()
|
||||
);
|
||||
const groupRD$ = this.groupService.findByHref(this.resourcePolicy._links.group.href).pipe(
|
||||
getSucceededRemoteData()
|
||||
);
|
||||
this.subs.push(
|
||||
observableRace(epersonRD$, groupRD$).pipe(
|
||||
filter(() => this.isActive),
|
||||
).subscribe((dsoRD: RemoteData<DSpaceObject>) => {
|
||||
this.resourcePolicyGrant = dsoRD.payload;
|
||||
})
|
||||
)
|
||||
}
|
||||
@@ -146,15 +184,15 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
new DynamicSelectModel(RESOURCE_POLICY_FORM_ACTION_TYPE_CONFIG)
|
||||
);
|
||||
|
||||
const startDateModel = new DynamicDsDatePickerModel(
|
||||
const startDateModel = new DynamicDatePickerModel(
|
||||
RESOURCE_POLICY_FORM_START_DATE_CONFIG,
|
||||
RESOURCE_POLICY_FORM_START_DATE_LAYOUT
|
||||
);
|
||||
const endDateModel = new DynamicDsDatePickerModel(
|
||||
const endDateModel = new DynamicDatePickerModel(
|
||||
RESOURCE_POLICY_FORM_END_DATE_CONFIG,
|
||||
RESOURCE_POLICY_FORM_END_DATE_LAYOUT
|
||||
);
|
||||
const dateGroupConfig = Object.assign({}, RESOURCE_POLICY_FORM_DATE_GROUP_CONFIG);
|
||||
const dateGroupConfig = Object.assign({}, RESOURCE_POLICY_FORM_DATE_GROUP_CONFIG, { group: [] });
|
||||
dateGroupConfig.group.push(startDateModel, endDateModel);
|
||||
formModel.push(new DynamicFormGroupModel(dateGroupConfig, RESOURCE_POLICY_FORM_DATE_GROUP_LAYOUT));
|
||||
|
||||
@@ -172,10 +210,10 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
formModel.forEach((model: any) => {
|
||||
if (model.id === 'date') {
|
||||
if (hasValue(this.resourcePolicy.startDate)) {
|
||||
model.get(0).valueUpdates.next(this.resourcePolicy.startDate);
|
||||
model.get(0).valueUpdates.next(stringToNgbDateStruct(this.resourcePolicy.startDate));
|
||||
}
|
||||
if (hasValue(this.resourcePolicy.endDate)) {
|
||||
model.get(1).valueUpdates.next(this.resourcePolicy.startDate);
|
||||
model.get(1).valueUpdates.next(stringToNgbDateStruct(this.resourcePolicy.endDate));
|
||||
}
|
||||
} else {
|
||||
if (this.resourcePolicy.hasOwnProperty(model.id) && this.resourcePolicy[model.id]) {
|
||||
@@ -203,7 +241,6 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
* @return the object name
|
||||
*/
|
||||
getResourcePolicyTargetName(): string {
|
||||
console.log(this.resourcePolicy);
|
||||
return isNotEmpty(this.resourcePolicyGrant) ? this.dsoNameService.getName(this.resourcePolicyGrant) : '';
|
||||
}
|
||||
|
||||
@@ -228,11 +265,10 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
* Emit a new submit Event whether the form is valid
|
||||
*/
|
||||
onSubmit(): void {
|
||||
this.formService.getFormData(this.formId)
|
||||
this.formService.getFormData(this.formId).pipe(take(1))
|
||||
.subscribe((data) => {
|
||||
const eventPayload: ResourcePolicyEvent = Object.create({});
|
||||
eventPayload.object = this.createResourcePolicyByFormData(data);
|
||||
console.log('resourcePolicyTarget', this.resourcePolicyGrant.type.value);
|
||||
eventPayload.target = {
|
||||
type: this.resourcePolicyGrantType,
|
||||
uuid: this.resourcePolicyGrant.id
|
||||
@@ -252,8 +288,8 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
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.startDate = (data.date && data.date.start) ? dateToISOFormat(data.date.start[0].value) : null;
|
||||
resourcePolicy.endDate = (data.date && data.date.end) ? dateToISOFormat(data.date.end[0].value) : null;
|
||||
resourcePolicy.type = RESOURCE_POLICY;
|
||||
|
||||
return resourcePolicy;
|
||||
@@ -263,6 +299,8 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
|
||||
* Unsubscribe from all subscriptions
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.isActive = false;
|
||||
this.formModel = null;
|
||||
this.subs
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe())
|
||||
|
@@ -1,17 +1,40 @@
|
||||
<div *ngIf="(getResourcePolicies() | async)?.hasSucceeded">
|
||||
<div *ngIf="(getResourcePolicies() | async)?.length > 0">
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="7">
|
||||
<p class="d-flex justify-content-between align-items-center m-0">
|
||||
<th colspan="9">
|
||||
<div class="d-flex justify-content-between align-items-center m-0">
|
||||
{{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} {{resourceUUID}}
|
||||
<button class="btn btn-outline-primary float-right" (click)="createResourcePolicy()">
|
||||
{{'resource-policies.add.for.' + resourceType | translate}}
|
||||
</button>
|
||||
</p>
|
||||
<div>
|
||||
<button class="btn btn-outline-primary float-right ml-1"
|
||||
[disabled]="(!(canDelete() | async)) || (isProcessingDelete() | async)"
|
||||
(click)="deleteSelectedResourcePolicies()">
|
||||
<span *ngIf="(isProcessingDelete() | async)">
|
||||
<i class='fas fa-circle-notch fa-spin'></i> {{'submission.workflow.tasks.generic.processing' | translate}}
|
||||
</span>
|
||||
<span *ngIf="!(isProcessingDelete() | async)">
|
||||
{{'resource-policies.delete.btn' | translate}}
|
||||
</span>
|
||||
</button>
|
||||
<button class="btn btn-outline-primary float-right"
|
||||
[disabled]="(isProcessingDelete() | async)"
|
||||
(click)="redirectToResourcePolicyCreatePage()">
|
||||
{{'resource-policies.add.for.' + resourceType | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
<tr class="text-center">
|
||||
<th>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
class="custom-control-input"
|
||||
[id]="'selectAll_' + resourceUUID"
|
||||
(change)="selectAllCheckbox($event)">
|
||||
<label class="custom-control-label" [for]="'selectAll_' + resourceUUID"></label>
|
||||
</div>
|
||||
</th>
|
||||
<th>{{'resource-policies.table.headers.id' | translate}}</th>
|
||||
<th>{{'resource-policies.table.headers.name' | translate}}</th>
|
||||
<th>{{'resource-policies.table.headers.policyType' | translate}}</th>
|
||||
@@ -23,29 +46,39 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let policy of (getResourcePolicies() | async)?.payload?.page; trackById">
|
||||
<tr *ngFor="let entry of (getResourcePolicies() | async); trackById">
|
||||
<td class="text-center">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
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">
|
||||
{{policy.id}}
|
||||
<button class="btn btn-link pt-0 pb-0" (click)="editResourcePolicy(policy)">
|
||||
{{entry.id}}
|
||||
<button class="btn btn-link pt-0 pb-0" (click)="redirectToResourcePolicyEditPage(entry.policy)">
|
||||
{{'resource-policies.table.headers.edit' | translate}}
|
||||
</button>
|
||||
</th>
|
||||
<td>{{policy.name}}</td>
|
||||
<td>{{policy.policyType}}</td>
|
||||
<td>{{policy.action}}</td>
|
||||
<td *ngIf="(hasEPerson(policy) | async)">
|
||||
{{getEPersonName(policy) | async}}
|
||||
<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(policy) | async)"></td>
|
||||
<td *ngIf="(hasGroup(policy) | async)">
|
||||
{{getGroupName(policy) | async}}
|
||||
<button class="btn btn-link pt-0 pb-0" (click)="redirectToGroupEditPage(policy)">
|
||||
<td *ngIf="!(hasEPerson(entry.policy) | async)"></td>
|
||||
<td *ngIf="(hasGroup(entry.policy) | async)">
|
||||
{{getGroupName(entry.policy) | async}}
|
||||
<button class="btn btn-link pt-0 pb-0" (click)="redirectToGroupEditPage(entry.policy)">
|
||||
{{'resource-policies.table.headers.edit' | translate}}
|
||||
</button>
|
||||
</td>
|
||||
<td *ngIf="!(hasGroup(policy) | async)"></td>
|
||||
<td>{{policy.startDate}}</td>
|
||||
<td>{{policy.endDate}}</td>
|
||||
<td *ngIf="!(hasGroup(entry.policy) | async)"></td>
|
||||
<td>{{formatDate(entry.policy.startDate)}}</td>
|
||||
<td>{{formatDate(entry.policy.endDate)}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@@ -1,26 +1,32 @@
|
||||
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
|
||||
import { filter, map, startWith, take } from 'rxjs/operators';
|
||||
import { BehaviorSubject, from as observableFrom, Observable, Subscription } from 'rxjs';
|
||||
import { concatMap, distinctUntilChanged, filter, map, reduce, scan, startWith, take } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { ResourcePolicyService } from '../../core/resource-policy/resource-policy.service';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import {
|
||||
getFirstSucceededRemoteDataPayload,
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload,
|
||||
getSucceededRemoteData
|
||||
} from '../../core/shared/operators';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { ResourcePolicy } from '../../core/resource-policy/models/resource-policy.model';
|
||||
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 { hasValue, 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 { followLink } from '../utils/follow-link-config.model';
|
||||
import { RequestService } from '../../core/data/request.service';
|
||||
import { NotificationsService } from '../notifications/notifications.service';
|
||||
import { dateToString, stringToNgbDateStruct } from '../date.util';
|
||||
|
||||
interface ResourcePolicyCheckboxEntry {
|
||||
id: string;
|
||||
policy: ResourcePolicy;
|
||||
checked: boolean
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ds-resource-policies',
|
||||
@@ -51,11 +57,17 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
private isActive: boolean;
|
||||
|
||||
/**
|
||||
* The list of policies for given resource
|
||||
* @type {Observable<RemoteData<PaginatedList<ResourcePolicy>>>}
|
||||
* A boolean representing if a submission delete operation is pending
|
||||
* @type {BehaviorSubject<boolean>}
|
||||
*/
|
||||
private resourcePolicies$: BehaviorSubject<RemoteData<PaginatedList<ResourcePolicy>>> =
|
||||
new BehaviorSubject<RemoteData<PaginatedList<ResourcePolicy>>>({} as any);
|
||||
private processingDelete$ = new BehaviorSubject<boolean>(false);
|
||||
|
||||
/**
|
||||
* The list of policies for given resource
|
||||
* @type {BehaviorSubject<ResourcePolicyCheckboxEntry[]>}
|
||||
*/
|
||||
private resourcePoliciesEntries$: BehaviorSubject<ResourcePolicyCheckboxEntry[]> =
|
||||
new BehaviorSubject<ResourcePolicyCheckboxEntry[]>([]);
|
||||
|
||||
/**
|
||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||
@@ -70,20 +82,24 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
* @param {DSONameService} dsoNameService
|
||||
* @param {EPersonDataService} ePersonService
|
||||
* @param {GroupDataService} groupService
|
||||
* @param {NotificationsService} notificationsService
|
||||
* @param {RequestService} requestService
|
||||
* @param {ResourcePolicyService} resourcePolicyService
|
||||
* @param {ActivatedRoute} route
|
||||
* @param {Router} router
|
||||
* @param {TranslateService} translate
|
||||
*/
|
||||
constructor(
|
||||
private cdr: ChangeDetectorRef,
|
||||
private dsoNameService: DSONameService,
|
||||
private ePersonService: EPersonDataService,
|
||||
private groupService: GroupDataService,
|
||||
private notificationsService: NotificationsService,
|
||||
private requestService: RequestService,
|
||||
private resourcePolicyService: ResourcePolicyService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private translate: TranslateService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -92,22 +108,144 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.isActive = true;
|
||||
this.initResourcePolicyLIst();
|
||||
}
|
||||
|
||||
canDelete(): Observable<boolean> {
|
||||
return observableFrom(this.resourcePoliciesEntries$.value).pipe(
|
||||
filter((entry: ResourcePolicyCheckboxEntry) => entry.checked),
|
||||
reduce((acc: any, value: any) => [...acc, ...value], []),
|
||||
map((entries: ResourcePolicyCheckboxEntry[]) => isNotEmpty(entries)),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
}
|
||||
|
||||
deleteSelectedResourcePolicies(): void {
|
||||
this.processingDelete$.next(true);
|
||||
const policiesToDelete: ResourcePolicyCheckboxEntry[] = this.resourcePoliciesEntries$.value
|
||||
.filter((entry: ResourcePolicyCheckboxEntry) => entry.checked);
|
||||
observableFrom(policiesToDelete).pipe(
|
||||
concatMap((entry: ResourcePolicyCheckboxEntry) => this.resourcePolicyService.delete(entry.policy.id)),
|
||||
scan((acc: any, value: any) => [...acc, ...value], []),
|
||||
filter((results: boolean[]) => results.length === policiesToDelete.length),
|
||||
take(1),
|
||||
).subscribe((results: boolean[]) => {
|
||||
const failureResults = results.filter((result: boolean) => !result);
|
||||
if (isEmpty(failureResults)) {
|
||||
this.notificationsService.success(null, this.translate.get('resource-policies.delete.success.content'));
|
||||
} else {
|
||||
this.notificationsService.error(null, this.translate.get('resource-policies.delete.failure.content'));
|
||||
}
|
||||
this.initResourcePolicyLIst();
|
||||
this.processingDelete$.next(false);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(
|
||||
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(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
map((group: Group) => this.dsoNameService.getName(group)),
|
||||
startWith('')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all resource's policies
|
||||
*
|
||||
* @return an observable that emits all resource's policies
|
||||
*/
|
||||
getResourcePolicies(): Observable<ResourcePolicyCheckboxEntry[]> {
|
||||
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(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((eperson: EPerson) => isNotEmpty(eperson))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((group: Group) => isNotEmpty(group))
|
||||
)
|
||||
}
|
||||
|
||||
initResourcePolicyLIst() {
|
||||
// TODO to be reviewed when https://github.com/DSpace/dspace-angular/issues/644 will be resolved
|
||||
this.requestService.removeByHrefSubstring(this.resourceUUID);
|
||||
this.resourcePolicyService.searchByResource(this.resourceUUID, null,
|
||||
followLink('eperson'), followLink('group')).pipe(
|
||||
this.resourcePolicyService.searchByResource(this.resourceUUID).pipe(
|
||||
filter(() => this.isActive),
|
||||
getSucceededRemoteData(),
|
||||
take(1)
|
||||
).subscribe((result) => {
|
||||
this.resourcePolicies$.next(result);
|
||||
const entries = result.payload.page.map((policy: ResourcePolicy) => ({
|
||||
id: policy.id,
|
||||
policy: policy,
|
||||
checked: false
|
||||
}));
|
||||
this.resourcePoliciesEntries$.next(entries);
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
isProcessingDelete(): Observable<boolean> {
|
||||
return this.processingDelete$.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to resource policy creation page
|
||||
*/
|
||||
createResourcePolicy(): void {
|
||||
redirectToResourcePolicyCreatePage(): void {
|
||||
this.router.navigate([`../create`], {
|
||||
relativeTo: this.route,
|
||||
queryParams: {
|
||||
@@ -122,7 +260,7 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
*
|
||||
* @param policy The resource policy
|
||||
*/
|
||||
editResourcePolicy(policy: ResourcePolicy): void {
|
||||
redirectToResourcePolicyEditPage(policy: ResourcePolicy): void {
|
||||
this.router.navigate([`../edit`], {
|
||||
relativeTo: this.route,
|
||||
queryParams: {
|
||||
@@ -131,79 +269,15 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ePerson's name which the given policy is linked to
|
||||
*
|
||||
* @param policy The resource policy
|
||||
*/
|
||||
getEPersonName(policy: ResourcePolicy): Observable<string> {
|
||||
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> {
|
||||
return policy.group.pipe(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataWithNotEmptyPayload(),
|
||||
map((group: Group) => this.dsoNameService.getName(group)),
|
||||
startWith('')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all resource's policies
|
||||
*
|
||||
* @return an observable that emits all resource's policies
|
||||
*/
|
||||
getResourcePolicies(): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
||||
return this.resourcePolicies$.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> {
|
||||
return policy.eperson.pipe(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((eperson: EPerson) => isNotEmpty(eperson))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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> {
|
||||
return policy.group.pipe(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((group: Group) => isNotEmpty(group))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to group edit page
|
||||
*
|
||||
* @param policy The resource policy
|
||||
*/
|
||||
redirectToGroupEditPage(policy: ResourcePolicy): void {
|
||||
this.requestService.removeByHrefSubstring(policy._links.group.href);
|
||||
this.subs.push(
|
||||
policy.group.pipe(
|
||||
this.groupService.findByHref(policy._links.group.href).pipe(
|
||||
filter(() => this.isActive),
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((group: Group) => group.id)
|
||||
@@ -211,6 +285,21 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Select/unselect all checkbox in the list
|
||||
*/
|
||||
selectAllCheckbox(event: any): void {
|
||||
const checked = event.target.checked;
|
||||
this.resourcePoliciesEntries$.value.forEach((entry: ResourcePolicyCheckboxEntry) => entry.checked = checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select/unselect checkbox
|
||||
*/
|
||||
selectCheckbox(policyEntry: ResourcePolicyCheckboxEntry, checked: boolean) {
|
||||
policyEntry.checked = checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from all subscriptions
|
||||
*/
|
||||
@@ -220,4 +309,5 @@ export class ResourcePoliciesComponent implements OnInit, OnDestroy {
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe())
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user