Files
dspace-angular/src/app/shared/resource-policies/form/resource-policy-form.component.ts
Giuseppe Digilio e1716751d4 Fixed build error
2020-05-20 18:10:17 +02:00

318 lines
10 KiB
TypeScript

import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/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';
import {
RESOURCE_POLICY_FORM_ACTION_TYPE_CONFIG,
RESOURCE_POLICY_FORM_DATE_GROUP_CONFIG,
RESOURCE_POLICY_FORM_DATE_GROUP_LAYOUT,
RESOURCE_POLICY_FORM_DESCRIPTION_CONFIG,
RESOURCE_POLICY_FORM_END_DATE_CONFIG,
RESOURCE_POLICY_FORM_END_DATE_LAYOUT,
RESOURCE_POLICY_FORM_NAME_CONFIG,
RESOURCE_POLICY_FORM_POLICY_TYPE_CONFIG,
RESOURCE_POLICY_FORM_START_DATE_CONFIG,
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 { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
import { hasValue, isEmpty, isNotEmpty } from '../../empty.util';
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,
target: {
type: string,
uuid: string
}
}
@Component({
selector: 'ds-resource-policy-form',
templateUrl: './resource-policy-form.component.html',
})
/**
* Component that show form for adding/editing a resource policy
*/
export class ResourcePolicyFormComponent implements OnInit, OnDestroy {
/**
* If given contains the resource policy to edit
* @type {ResourcePolicy}
*/
@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.
*/
@Output() reset: EventEmitter<any> = new EventEmitter<any>();
/**
* An event fired when form is submitted.
* Event's payload equals to a new ResourcePolicy.
*/
@Output() submit: EventEmitter<ResourcePolicyEvent> = new EventEmitter<ResourcePolicyEvent>();
/**
* The form id
* @type {string}
*/
public formId: string;
/**
* The form model
* @type {DynamicFormControlModel[]}
*/
public formModel: DynamicFormControlModel[];
/**
* The eperson or group that will be grant of the permission
* @type {DSpaceObject}
*/
public resourcePolicyGrant: DSpaceObject;
/**
* The type of the object that will be grant of the permission. It could be 'eperson' or 'group'
* @type {string}
*/
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}
*/
private subs: Subscription[] = [];
/**
* 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,
) {
}
/**
* 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.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()
);
const dsoRD$: Observable<RemoteData<DSpaceObject>> = observableRace(epersonRD$, groupRD$);
this.subs.push(
dsoRD$.pipe(
filter(() => this.isActive),
).subscribe((dsoRD: RemoteData<DSpaceObject>) => {
this.resourcePolicyGrant = dsoRD.payload;
})
)
}
}
/**
* Method to check if the form status is valid or not
*
* @return Observable that emits the form status
*/
isFormValid(): Observable<boolean> {
return this.formService.isValid(this.formId).pipe(
map((isValid: boolean) => isValid && isNotEmpty(this.resourcePolicyGrant))
)
}
/**
* Initialize the form model
*
* @return the form models
*/
private buildResourcePolicyForm(): DynamicFormControlModel[] {
const formModel: DynamicFormControlModel[] = [];
// TODO to be removed when https://jira.lyrasis.org/browse/DS-4477 will be implemented
const policyTypeConf = Object.assign({}, RESOURCE_POLICY_FORM_POLICY_TYPE_CONFIG, {
disabled: isNotEmpty(this.resourcePolicy)
});
// TODO to be removed when https://jira.lyrasis.org/browse/DS-4477 will be implemented
const actionConf = Object.assign({}, RESOURCE_POLICY_FORM_ACTION_TYPE_CONFIG, {
disabled: isNotEmpty(this.resourcePolicy)
});
formModel.push(
new DsDynamicInputModel(RESOURCE_POLICY_FORM_NAME_CONFIG),
new DsDynamicTextAreaModel(RESOURCE_POLICY_FORM_DESCRIPTION_CONFIG),
new DynamicSelectModel(policyTypeConf),
new DynamicSelectModel(actionConf)
);
const startDateModel = new DynamicDatePickerModel(
RESOURCE_POLICY_FORM_START_DATE_CONFIG,
RESOURCE_POLICY_FORM_START_DATE_LAYOUT
);
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, { group: [] });
dateGroupConfig.group.push(startDateModel, endDateModel);
formModel.push(new DynamicFormGroupModel(dateGroupConfig, RESOURCE_POLICY_FORM_DATE_GROUP_LAYOUT));
this.initModelsValue(formModel);
return formModel
}
/**
* Setting up the form models value
*
* @return the form models
*/
initModelsValue(formModel: DynamicFormControlModel[]): DynamicFormControlModel[] {
if (this.resourcePolicy) {
formModel.forEach((model: any) => {
if (model.id === 'date') {
if (hasValue(this.resourcePolicy.startDate)) {
model.get(0).valueUpdates.next(stringToNgbDateStruct(this.resourcePolicy.startDate));
}
if (hasValue(this.resourcePolicy.endDate)) {
model.get(1).valueUpdates.next(stringToNgbDateStruct(this.resourcePolicy.endDate));
}
} else {
if (this.resourcePolicy.hasOwnProperty(model.id) && this.resourcePolicy[model.id]) {
model.valueUpdates.next(this.resourcePolicy[model.id]);
}
}
})
}
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 object name
*/
getResourcePolicyTargetName(): string {
return isNotEmpty(this.resourcePolicyGrant) ? this.dsoNameService.getName(this.resourcePolicyGrant) : '';
}
/**
* Update reference to the eperson or group that will be grant of the permission
*/
updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void {
this.resourcePolicyGrant = object;
this.resourcePolicyGrantType = isEPerson ? 'eperson' : 'group';
}
/**
* Method called on reset
* Emit a new reset Event
*/
onReset(): void {
this.reset.emit();
}
/**
* Method called on submit.
* Emit a new submit Event whether the form is valid
*/
onSubmit(): void {
this.formService.getFormData(this.formId).pipe(take(1))
.subscribe((data) => {
const eventPayload: ResourcePolicyEvent = Object.create({});
eventPayload.object = this.createResourcePolicyByFormData(data);
eventPayload.target = {
type: this.resourcePolicyGrantType,
uuid: this.resourcePolicyGrant.id
};
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) ? 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;
}
/**
* Unsubscribe from all subscriptions
*/
ngOnDestroy(): void {
this.isActive = false;
this.formModel = null;
this.subs
.filter((subscription) => hasValue(subscription))
.forEach((subscription) => subscription.unsubscribe())
}
}