2023-11-24 17:42:23 +01:00
|
|
|
|
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 {
|
|
|
|
|
DescriptionTemplateExternalDatasetData,
|
2024-01-31 20:16:39 +01:00
|
|
|
|
DescriptionTemplateLabelAndMultiplicityData,
|
|
|
|
|
DescriptionTemplateLabelData,
|
2023-11-24 17:42:23 +01:00
|
|
|
|
DescriptionTemplateRadioBoxData,
|
2024-02-09 21:46:05 +01:00
|
|
|
|
DescriptionTemplateReferenceTypeData,
|
2024-01-31 20:16:39 +01:00
|
|
|
|
DescriptionTemplateSelectData,
|
|
|
|
|
DescriptionTemplateSelectOption,
|
|
|
|
|
DescriptionTemplateUploadData
|
2023-11-24 17:42:23 +01:00
|
|
|
|
} 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 { BaseComponent } from '@common/base/base.component';
|
|
|
|
|
import { Observable, of } from 'rxjs';
|
|
|
|
|
import { map } from 'rxjs/operators';
|
|
|
|
|
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model';
|
2024-02-05 16:59:11 +01:00
|
|
|
|
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
2024-02-19 14:50:01 +01:00
|
|
|
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
2024-02-20 13:58:16 +01:00
|
|
|
|
import { SemanticsService } from '@app/core/services/semantic/semantics.service';
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
@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;
|
|
|
|
|
validationTypeEnum = ValidationType;
|
|
|
|
|
// isFieldMultiplicityEnabled = false;
|
|
|
|
|
|
|
|
|
|
fieldType: DescriptionTemplateFieldType;
|
|
|
|
|
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
|
|
|
|
|
|
|
|
|
|
@Input() expandView: boolean = true;
|
|
|
|
|
@Input() canBeDeleted: boolean = true;
|
|
|
|
|
|
|
|
|
|
@Output() delete = new EventEmitter<void>();
|
2024-02-05 16:59:11 +01:00
|
|
|
|
@Input() validationErrorModel: ValidationErrorModel;
|
2024-02-08 16:14:25 +01:00
|
|
|
|
@Input() validationRootPath: string;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
public enumUtils: EnumUtils,
|
|
|
|
|
public descriptionTemplateService: DescriptionTemplateService,
|
|
|
|
|
private dialog: MatDialog,
|
2024-02-19 14:50:01 +01:00
|
|
|
|
private configurationService: ConfigurationService,
|
2024-02-20 13:58:16 +01:00
|
|
|
|
private filterService: FilterService,
|
|
|
|
|
public semanticsService: SemanticsService
|
2023-11-24 17:42:23 +01:00
|
|
|
|
) {
|
|
|
|
|
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() {
|
2024-02-05 16:59:11 +01:00
|
|
|
|
const rule: DescriptionTemplateRuleEditorModel = new DescriptionTemplateRuleEditorModel(this.validationErrorModel);
|
|
|
|
|
const ruleArray = this.form.get('visibilityRules') as UntypedFormArray;
|
2024-02-08 16:14:25 +01:00
|
|
|
|
(<UntypedFormArray>this.form.get('visibilityRules')).push(rule.buildForm({rootPath: this.validationRootPath + 'visibilityRules[' + ruleArray.length +'].'}));
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get canApplyVisibility(): boolean {
|
|
|
|
|
|
|
|
|
|
switch (this.fieldType) {
|
|
|
|
|
case DescriptionTemplateFieldType.TEXT_AREA:
|
|
|
|
|
case DescriptionTemplateFieldType.RICH_TEXT_AREA:
|
|
|
|
|
case DescriptionTemplateFieldType.FREE_TEXT:
|
|
|
|
|
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
|
|
|
|
|
case DescriptionTemplateFieldType.RADIO_BOX:
|
2024-01-31 20:16:39 +01:00
|
|
|
|
case DescriptionTemplateFieldType.SELECT:
|
2023-11-24 17:42:23 +01:00
|
|
|
|
case DescriptionTemplateFieldType.CHECK_BOX:
|
|
|
|
|
case DescriptionTemplateFieldType.DATE_PICKER:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onInputTypeChange() {
|
|
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
|
const type = this.fieldType;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
const field: DescriptionTemplateFieldPersist = this.form.getRawValue();
|
2024-05-02 14:57:19 +02:00
|
|
|
|
field.defaultValue = {
|
|
|
|
|
booleanValue: null,
|
|
|
|
|
dateValue: null,
|
|
|
|
|
textListValue: null,
|
|
|
|
|
textValue: null,
|
|
|
|
|
};
|
2023-11-24 17:42:23 +01:00
|
|
|
|
if (!this.canApplyVisibility) {
|
|
|
|
|
field.visibilityRules = [];
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-31 20:16:39 +01:00
|
|
|
|
switch (type) {
|
2024-02-09 21:46:05 +01:00
|
|
|
|
case DescriptionTemplateFieldType.REFERENCE_TYPES: {
|
|
|
|
|
const data: DescriptionTemplateLabelData = {
|
2023-11-24 17:42:23 +01:00
|
|
|
|
label: '',
|
2024-01-31 20:16:39 +01:00
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
2024-05-02 14:57:19 +02:00
|
|
|
|
field.defaultValue = null;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-01-31 20:16:39 +01:00
|
|
|
|
case DescriptionTemplateFieldType.RADIO_BOX: {
|
|
|
|
|
const data: DescriptionTemplateRadioBoxData = {
|
2023-11-24 17:42:23 +01:00
|
|
|
|
label: '',
|
2024-01-31 20:16:39 +01:00
|
|
|
|
options: [],
|
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-01-30 18:27:55 +01:00
|
|
|
|
case DescriptionTemplateFieldType.SELECT: {
|
2024-01-31 20:16:39 +01:00
|
|
|
|
const firstOption = { label: '', value: '' } as DescriptionTemplateSelectOption;
|
2024-01-30 18:27:55 +01:00
|
|
|
|
const data: DescriptionTemplateSelectData = {
|
2023-11-24 17:42:23 +01:00
|
|
|
|
label: '',
|
2024-01-31 20:16:39 +01:00
|
|
|
|
multipleSelect: false,
|
2023-11-24 17:42:23 +01:00
|
|
|
|
options: [firstOption],
|
2024-01-31 20:16:39 +01:00
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-01-31 20:16:39 +01:00
|
|
|
|
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
|
|
|
|
|
case DescriptionTemplateFieldType.CHECK_BOX:
|
|
|
|
|
case DescriptionTemplateFieldType.FREE_TEXT:
|
|
|
|
|
case DescriptionTemplateFieldType.TEXT_AREA:
|
|
|
|
|
case DescriptionTemplateFieldType.RICH_TEXT_AREA:
|
2024-05-02 14:57:19 +02:00
|
|
|
|
case DescriptionTemplateFieldType.DATE_PICKER:{
|
|
|
|
|
const data: DescriptionTemplateLabelData = {
|
|
|
|
|
label: '',
|
|
|
|
|
fieldType: type
|
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-01-31 20:16:39 +01:00
|
|
|
|
case DescriptionTemplateFieldType.TAGS:
|
|
|
|
|
case DescriptionTemplateFieldType.DATASET_IDENTIFIER:
|
|
|
|
|
case DescriptionTemplateFieldType.VALIDATION: {
|
|
|
|
|
const data: DescriptionTemplateLabelData = {
|
2023-11-24 17:42:23 +01:00
|
|
|
|
label: '',
|
2024-01-31 20:16:39 +01:00
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
2024-05-02 14:57:19 +02:00
|
|
|
|
field.defaultValue = null;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-03-05 16:37:01 +01:00
|
|
|
|
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
|
2024-02-09 21:46:05 +01:00
|
|
|
|
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:{
|
2024-01-31 20:16:39 +01:00
|
|
|
|
const data: DescriptionTemplateLabelAndMultiplicityData = {
|
2023-11-24 17:42:23 +01:00
|
|
|
|
label: '',
|
2024-01-31 20:16:39 +01:00
|
|
|
|
multipleSelect: false,
|
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
2024-05-02 14:57:19 +02:00
|
|
|
|
field.defaultValue = null;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case DescriptionTemplateFieldType.UPLOAD: {
|
|
|
|
|
const data: DescriptionTemplateUploadData = {
|
|
|
|
|
label: '',
|
|
|
|
|
types: [],
|
|
|
|
|
maxFileSizeInMB: this.configurationService.maxFileSizeInMB,
|
2024-01-31 20:16:39 +01:00
|
|
|
|
fieldType: type
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|
|
|
|
|
field.data = data;
|
2024-05-02 14:57:19 +02:00
|
|
|
|
field.defaultValue = null;
|
2023-11-24 17:42:23 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 16:59:11 +01:00
|
|
|
|
const form = (new DescriptionTemplateFieldEditorModel(this.validationErrorModel)).fromModel(field)
|
2024-02-08 16:14:25 +01:00
|
|
|
|
.buildForm({rootPath: this.validationRootPath});
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
2024-05-02 14:57:19 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isTextType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.FREE_TEXT ||
|
|
|
|
|
type == DescriptionTemplateFieldType.TEXT_AREA || type == DescriptionTemplateFieldType.RICH_TEXT_AREA ||
|
|
|
|
|
type == DescriptionTemplateFieldType.RADIO_BOX ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isTextListType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.TAGS || type == DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS ||
|
|
|
|
|
type == DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS || type == DescriptionTemplateFieldType.SELECT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isDateType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.DATE_PICKER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isBooleanType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.BOOLEAN_DECISION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isReferenceType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.REFERENCE_TYPES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isExternalIdentifierType(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.VALIDATION || type == DescriptionTemplateFieldType.DATASET_IDENTIFIER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canSetDefaultValue(type: DescriptionTemplateFieldType){
|
|
|
|
|
return type == DescriptionTemplateFieldType.FREE_TEXT ||
|
|
|
|
|
type == DescriptionTemplateFieldType.TEXT_AREA || type == DescriptionTemplateFieldType.RICH_TEXT_AREA ||
|
|
|
|
|
type == DescriptionTemplateFieldType.RADIO_BOX || type == DescriptionTemplateFieldType.SELECT || type == DescriptionTemplateFieldType.DATE_PICKER ||
|
|
|
|
|
type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.BOOLEAN_DECISION;
|
|
|
|
|
}
|
2023-11-24 17:42:23 +01:00
|
|
|
|
}
|