468 lines
14 KiB
TypeScript
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();
|
|
}
|
|
}
|