argos/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor...

468 lines
14 KiB
TypeScript

import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroupDirective, NgForm, UntypedFormArray, UntypedFormControl, UntypedFormGroup, } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { ValidationType } from '@app/core/common/enum/validation-type';
import {
DescriptionTemplateAutoCompleteData,
DescriptionTemplateBooleanDecisionData,
DescriptionTemplateCheckBoxData,
DescriptionTemplateComboBoxOption,
DescriptionTemplateCurrencyData,
DescriptionTemplateDataRepositoryData,
DescriptionTemplateDatasetIdentifierData,
DescriptionTemplateDatePickerData,
DescriptionTemplateDmpAutoCompleteData,
DescriptionTemplateExternalDatasetData,
DescriptionTemplateFreeTextData,
DescriptionTemplateLicenseData,
DescriptionTemplateOrganizationData,
DescriptionTemplatePublicationData,
DescriptionTemplateRadioBoxData,
DescriptionTemplateRegistryData,
DescriptionTemplateResearcherAutoCompleteData,
DescriptionTemplateRichTextAreaData,
DescriptionTemplateServiceData,
DescriptionTemplateTagData,
DescriptionTemplateTaxonomyData,
DescriptionTemplateTextAreaData,
DescriptionTemplateUploadData,
DescriptionTemplateValidationData,
DescriptionTemplateSelectData
} from '@app/core/model/description-template/description-template';
import { DescriptionTemplateFieldPersist } from '@app/core/model/description-template/description-template-persist';
import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model';
@Component({
selector: 'app-description-template-editor-field-component',
templateUrl: './description-template-editor-field.component.html',
styleUrls: ['./description-template-editor-field.component.scss']
})
export class DescriptionTemplateEditorFieldComponent extends BaseComponent implements OnInit, ErrorStateMatcher {
@Input() viewOnly: boolean;
@Input() form: UntypedFormGroup;
@Input() showOrdinal = true;
@Input() indexPath: string;
validationTypeEnum = ValidationType;
// isFieldMultiplicityEnabled = false;
fieldType: DescriptionTemplateFieldType;
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
@Input() expandView: boolean = true;
@Input() canBeDeleted: boolean = true;
@Output() delete = new EventEmitter<void>();
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
semanticsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterSemantics.bind(this),
initialItems: (excludedItems: any[]) => this.filterSemantics('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x !== resultItem)))),
displayFn: (item) => item,
titleFn: (item) => item
}
filterSemantics(value: string): Observable<String[]> {
// return this.descriptionTemplateService.searchSemantics(value);
return of([]);
}
constructor(
public enumUtils: EnumUtils,
public descriptionTemplateService: DescriptionTemplateService,
private dialog: MatDialog,
private configurationService: ConfigurationService
) {
super();
}
isErrorState(control: UntypedFormControl, form: FormGroupDirective | NgForm): boolean {
if (this.form.get('data').untouched) return false;
return this.form.get('data').invalid;
}
ngOnInit() {
const fieldType = this.form.get('data').get('fieldType').value;
if (fieldType) {
this.fieldType = fieldType;
if (this.fieldType !== DescriptionTemplateFieldType.FREE_TEXT) {
this.setValidator(ValidationType.URL, false);
}
}
}
addNewRule() {
const rule: DescriptionTemplateRuleEditorModel = new DescriptionTemplateRuleEditorModel();
(<UntypedFormArray>this.form.get('visibilityRules')).push(rule.buildForm());
}
get canApplyVisibility(): boolean {
switch (this.fieldType) {
case DescriptionTemplateFieldType.TEXT_AREA:
case DescriptionTemplateFieldType.RICH_TEXT_AREA:
case DescriptionTemplateFieldType.UPLOAD:
case DescriptionTemplateFieldType.FREE_TEXT:
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
case DescriptionTemplateFieldType.RADIO_BOX:
case DescriptionTemplateFieldType.COMBO_BOX:
case DescriptionTemplateFieldType.CHECK_BOX:
case DescriptionTemplateFieldType.DATE_PICKER:
return true;
}
return false;
}
onInputTypeChange() {
const x = this.fieldType;
const field: DescriptionTemplateFieldPersist = this.form.getRawValue();
field.defaultValue = undefined;
if (!this.canApplyVisibility) {
field.visibilityRules = [];
}
switch (x) {
case DescriptionTemplateFieldType.BOOLEAN_DECISION: {
const data: DescriptionTemplateBooleanDecisionData = {
label: '',
fieldType: DescriptionTemplateFieldType.BOOLEAN_DECISION,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CHECK_BOX: {
const data: DescriptionTemplateCheckBoxData = {
label: '',
fieldType: DescriptionTemplateFieldType.CHECK_BOX,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.SELECT: {
const firstOption = { label: '', value: '' } as DescriptionTemplateComboBoxOption;
const data: DescriptionTemplateSelectData = {
label: '',
multiList: false,
options: [firstOption],
fieldType: DescriptionTemplateFieldType.SELECT
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.AUTO_COMPLETE: {
const data: DescriptionTemplateAutoCompleteData = {
autoCompleteSingleDataList: [],
multiAutoComplete: false,
label: '',
fieldType: DescriptionTemplateFieldType.AUTO_COMPLETE
}
field.data = data;
break;
} case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES: {
const data: DescriptionTemplateDmpAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DMPS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.FREE_TEXT: {
const data: DescriptionTemplateFreeTextData = {
label: '',
fieldType: DescriptionTemplateFieldType.FREE_TEXT
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RADIO_BOX: {
const data: DescriptionTemplateRadioBoxData = {
label: '',
options: [],
fieldType: DescriptionTemplateFieldType.RADIO_BOX
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TEXT_AREA: {
const data: DescriptionTemplateTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RICH_TEXT_AREA: {
const data: DescriptionTemplateRichTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.RICH_TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.UPLOAD: {
const data: DescriptionTemplateUploadData = {
label: '',
types: [],
maxFileSizeInMB: this.configurationService.maxFileSizeInMB,
fieldType: DescriptionTemplateFieldType.UPLOAD
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATE_PICKER: {
const data: DescriptionTemplateDatePickerData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATE_PICKER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.EXTERNAL_DATASETS: {
const data: DescriptionTemplateExternalDatasetData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.EXTERNAL_DATASETS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATA_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUB_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.JOURNAL_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAXONOMIES: {
const data: DescriptionTemplateTaxonomyData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.TAXONOMIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.LICENSES: {
const data: DescriptionTemplateLicenseData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.LICENSES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUBLICATIONS: {
const data: DescriptionTemplatePublicationData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.PUBLICATIONS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.REGISTRIES: {
const data: DescriptionTemplateRegistryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.REGISTRIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.SERVICES: {
const data: DescriptionTemplateServiceData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.SERVICES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAGS: {
const data: DescriptionTemplateTagData = {
label: '',
fieldType: DescriptionTemplateFieldType.TAGS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RESEARCHERS: {
const data: DescriptionTemplateResearcherAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.RESEARCHERS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.ORGANIZATIONS: {
const data: DescriptionTemplateOrganizationData = {
// autoCompleteSingleDataList: [], //TODO maybe remove
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.ORGANIZATIONS
};
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATASET_IDENTIFIER: {
const data: DescriptionTemplateDatasetIdentifierData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATASET_IDENTIFIER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CURRENCY: {
const data: DescriptionTemplateCurrencyData = {
label: '',
fieldType: DescriptionTemplateFieldType.CURRENCY
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.VALIDATION: {
const data: DescriptionTemplateValidationData = {
label: '',
fieldType: DescriptionTemplateFieldType.VALIDATION
}
field.data = data;
break;
}
}
const form = (new DescriptionTemplateFieldEditorModel).fromModel(field).buildForm();
const fields = this.form.parent as UntypedFormArray;
let index = -1;
fields.controls.forEach((control, i) => {
if (this.form.get('id').value === control.get('id').value) {
index = i
}
});
if (index >= 0) {
fields.removeAt(index);
fields.insert(index, form);
this.form = form;
}
// setTimeout(() => { //TODO
// this.showPreview = true;
// });
}
toggleRequired(event: MatSlideToggleChange) {
this.setValidator(ValidationType.Required, event.checked);
}
toggleURL(event: MatSlideToggleChange) {
this.setValidator(ValidationType.URL, event.checked);
}
private setValidator(validationType: ValidationType, add: boolean) {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
if (add) {
if (!validations.includes(validationType)) {
validations.push(validationType);
validationsControl.updateValueAndValidity();
}
} else {
validationsControl.setValue(validations.filter(validator => validator != validationType));
validationsControl.updateValueAndValidity();
}
this.form.markAsDirty();//deactivate guard
}
get isRequired() {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
return validations.includes(ValidationType.Required);
}
get isURL() {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
return validations.includes(ValidationType.URL);
}
onDelete() {
this.delete.emit();
}
}