2023-11-24 17:42:23 +01:00
|
|
|
|
import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
|
|
|
|
|
import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
|
|
|
|
import { MatCheckboxChange } from '@angular/material/checkbox';
|
|
|
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
|
|
|
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,
|
|
|
|
|
DescriptionTemplateField,
|
|
|
|
|
DescriptionTemplateFreeTextData,
|
|
|
|
|
DescriptionTemplateLicenseData,
|
|
|
|
|
DescriptionTemplateOrganizationData,
|
|
|
|
|
DescriptionTemplatePublicationData,
|
|
|
|
|
DescriptionTemplateRadioBoxData,
|
|
|
|
|
DescriptionTemplateRegistryData,
|
|
|
|
|
DescriptionTemplateResearcherAutoCompleteData,
|
|
|
|
|
DescriptionTemplateRichTextAreaData,
|
|
|
|
|
DescriptionTemplateServiceData,
|
|
|
|
|
DescriptionTemplateTagData,
|
|
|
|
|
DescriptionTemplateTaxonomyData,
|
|
|
|
|
DescriptionTemplateTextAreaData,
|
|
|
|
|
DescriptionTemplateUploadData,
|
|
|
|
|
DescriptionTemplateValidationData,
|
|
|
|
|
DescriptionTemplateWordListData
|
|
|
|
|
} from '@app/core/model/description-template/description-template';
|
|
|
|
|
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 { TransitionGroupComponent } from "@app/ui/transition-group/transition-group.component";
|
|
|
|
|
import { BaseComponent } from '@common/base/base.component';
|
|
|
|
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
|
|
|
|
import { Guid } from '@common/types/guid';
|
|
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
|
|
|
import { Subject } from 'rxjs';
|
|
|
|
|
import { debounceTime, delay, map, takeUntil, tap } from 'rxjs/operators';
|
|
|
|
|
import { GENERAL_ANIMATIONS } from '../../animations/animations';
|
|
|
|
|
import { EditorCustomValidators } from '../../custom-validators/editor-custom-validators';
|
2023-12-29 16:04:16 +01:00
|
|
|
|
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel, DescriptionTemplateSectionEditorModel } from '../../description-template-editor.model';
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
|
selector: 'app-description-template-editor-composite-field-component',
|
|
|
|
|
templateUrl: './description-template-editor-composite-field.component.html',
|
|
|
|
|
styleUrls: ['./description-template-editor-composite-field.component.scss'],
|
|
|
|
|
animations: [GENERAL_ANIMATIONS]
|
|
|
|
|
})
|
|
|
|
|
export class DescriptionTemplateEditorCompositeFieldComponent extends BaseComponent implements OnInit, OnChanges {
|
|
|
|
|
|
|
|
|
|
@Input() form: UntypedFormGroup;
|
|
|
|
|
@Input() indexPath: string;
|
|
|
|
|
@Input() viewOnly: boolean;
|
|
|
|
|
|
|
|
|
|
@Input() datasetProfileId?: string;
|
|
|
|
|
|
|
|
|
|
@Input() numbering: string;
|
|
|
|
|
@Input() hasFocus: boolean = false;
|
|
|
|
|
@ViewChild("inputs") inputs: TransitionGroupComponent;
|
|
|
|
|
|
|
|
|
|
showPreview: boolean = true;
|
|
|
|
|
previewDirty: boolean = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
showDescription: boolean = true;
|
|
|
|
|
showAdditionalInfo: boolean = false;
|
|
|
|
|
showExtendedDescription: boolean = false;
|
|
|
|
|
|
|
|
|
|
previewForm: UntypedFormGroup = null;
|
|
|
|
|
// isComposite = false;
|
|
|
|
|
// isMultiplicityEnabled = false;
|
|
|
|
|
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
|
|
|
|
|
|
|
|
|
|
private myCustomValidators: EditorCustomValidators = new EditorCustomValidators();
|
|
|
|
|
|
|
|
|
|
isMultiplicityEnabled = false;
|
|
|
|
|
constructor(
|
|
|
|
|
private dialog: MatDialog,
|
|
|
|
|
private language: TranslateService,
|
|
|
|
|
public enumUtils: EnumUtils,
|
|
|
|
|
public datasetProfileService: DescriptionTemplateService,
|
|
|
|
|
private configurationService: ConfigurationService
|
|
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
|
|
|
// this.setTargetField(null);
|
|
|
|
|
// this.showExtendedDescription = !!this.form.get('extendedDescription').value;
|
|
|
|
|
// this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
|
|
|
|
|
// console.log(this.form.get('fields')['controls'])
|
|
|
|
|
if (changes['form']) {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const multiplicity = this.form.get('multiplicity').value;
|
|
|
|
|
this.isMultiplicityEnabled = multiplicity.min > 0 || multiplicity.max > 0;
|
|
|
|
|
} catch {
|
|
|
|
|
this.isMultiplicityEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get firstField() {
|
|
|
|
|
try {
|
|
|
|
|
return (this.form.get('fields') as UntypedFormArray).at(0);
|
|
|
|
|
} catch {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ngOnInit() {
|
|
|
|
|
//this.addNewField();
|
|
|
|
|
// if (this.form.get('multiplicity')) {
|
|
|
|
|
// if (this.form.get('multiplicity').value.min > 1 || this.form.get('multiplicity').value.max > 1) {
|
|
|
|
|
// this.isMultiplicityEnabled = true;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// this.isComposite = (this.form.get('fields') as FormArray).length > 1;
|
|
|
|
|
|
|
|
|
|
if (this.viewOnly) {
|
|
|
|
|
this.form.get('hasCommentField').disable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SET UP TARGET FIELD
|
|
|
|
|
// if((this.form.get('fields') as FormArray).length>0){
|
|
|
|
|
// //get the first field in list
|
|
|
|
|
// this.targetField = (this.form.get('fields') as FormArray).at(0) as FormGroup;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
this.showExtendedDescription = !!this.form.get('extendedDescription').value;
|
|
|
|
|
this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
|
|
|
|
|
|
|
|
|
|
this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes => {
|
|
|
|
|
// this.previewForm = null;
|
|
|
|
|
this.previewDirty = true;
|
|
|
|
|
this.generatePreviewForm();
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
this.previewSubject$
|
|
|
|
|
.pipe(debounceTime(600))
|
|
|
|
|
.pipe(
|
|
|
|
|
takeUntil(this._destroyed),
|
|
|
|
|
map(model => model.buildForm()),
|
|
|
|
|
map(updatedForm => {
|
|
|
|
|
const previewContainer = document.getElementById('preview_container' + this.form.get('id').value);
|
|
|
|
|
// let clientHeight = -1;
|
|
|
|
|
if (previewContainer) {
|
|
|
|
|
// console.log(previewContainer);
|
|
|
|
|
const clientHeight = previewContainer.clientHeight;
|
|
|
|
|
// console.log(clientHeight);
|
|
|
|
|
|
|
|
|
|
if (clientHeight) {
|
|
|
|
|
previewContainer.style.height = clientHeight.toString() + 'px';
|
|
|
|
|
|
|
|
|
|
// console.log('height:' ,previewContainer.style.height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.showPreview = false;
|
|
|
|
|
this.previewDirty = true;
|
|
|
|
|
this.previewForm = updatedForm;
|
|
|
|
|
return previewContainer;
|
|
|
|
|
}),
|
|
|
|
|
delay(100),
|
|
|
|
|
tap(previewContainer => {
|
|
|
|
|
this.showPreview = true;
|
|
|
|
|
this.previewDirty = false;
|
|
|
|
|
}),
|
|
|
|
|
delay(100)
|
|
|
|
|
)
|
|
|
|
|
.subscribe(previewContainer => {
|
|
|
|
|
|
|
|
|
|
if (previewContainer) {
|
|
|
|
|
previewContainer.style.height = 'auto';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// const updatedForm = model.buildForm();
|
|
|
|
|
// this.reloadPreview(updatedForm)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.generatePreviewForm();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get updatedClass() {
|
|
|
|
|
if (this.previewDirty) return '';
|
|
|
|
|
else return 'updated';
|
|
|
|
|
}
|
|
|
|
|
private reloadPreview(updatedForm: UntypedFormGroup) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
|
|
const previewContainer = document.getElementById('preview_container' + this.form.get('id').value);
|
|
|
|
|
// let clientHeight = -1;
|
|
|
|
|
if (previewContainer) {
|
|
|
|
|
// console.log(previewContainer);
|
|
|
|
|
const clientHeight = previewContainer.clientHeight;
|
|
|
|
|
// console.log(clientHeight);
|
|
|
|
|
|
|
|
|
|
if (clientHeight) {
|
|
|
|
|
previewContainer.style.height = clientHeight.toString() + 'px';
|
|
|
|
|
|
|
|
|
|
// console.log('height:' ,previewContainer.style.height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.showPreview = false;
|
|
|
|
|
this.previewDirty = true;
|
|
|
|
|
this.previewForm = updatedForm;
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.showPreview = true;
|
|
|
|
|
this.previewDirty = false;
|
|
|
|
|
|
|
|
|
|
if (previewContainer) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
if (previewContainer) {
|
|
|
|
|
previewContainer.style.height = 'auto';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-29 16:04:16 +01:00
|
|
|
|
previewSubject$: Subject<DescriptionTemplateSectionEditorModel> = new Subject<DescriptionTemplateSectionEditorModel>();
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
private generatePreviewForm() {
|
|
|
|
|
// const formValue: DescriptionTemplateFieldSet = this.form.getRawValue();
|
|
|
|
|
// const fields: FieldDefinition[] = formValue.fields.map(editorField => this._fieldToFieldDefinition(editorField));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const compositeField: CompositeField = {
|
|
|
|
|
// id: formValue.id,
|
|
|
|
|
// additionalInformation: formValue.additionalInformation,
|
|
|
|
|
// extendedDescription: formValue.extendedDescription,
|
|
|
|
|
// numbering: '',
|
|
|
|
|
// title: formValue.title,
|
|
|
|
|
// ordinal: formValue.ordinal,
|
|
|
|
|
// description: formValue.description,
|
|
|
|
|
// hasCommentField: formValue.hasCommentField,
|
|
|
|
|
// commentFieldValue: '',
|
|
|
|
|
// multiplicity: {
|
|
|
|
|
// max: formValue.multiplicity.max, min: formValue.multiplicity.min,
|
|
|
|
|
// placeholder: formValue.multiplicity.placeholder, tableView: formValue.multiplicity.tableView
|
|
|
|
|
// },
|
|
|
|
|
// multiplicityItems: null,
|
|
|
|
|
// fields: fields.map(editorField => {
|
|
|
|
|
// const model = new DatasetDescriptionFieldEditorModel().fromModel(editorField);
|
|
|
|
|
// if (model.data.fieldType === DescriptionTemplateFieldType.CheckBox) {
|
|
|
|
|
// model.value = model.value ? "true" : "false";//patch
|
|
|
|
|
// }
|
|
|
|
|
// return model;
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const section = new DatasetDescriptionSectionEditorModel();
|
|
|
|
|
// section.title = '';
|
|
|
|
|
// section.numbering = '';
|
|
|
|
|
|
|
|
|
|
// const compositeForm = new DatasetDescriptionCompositeFieldEditorModel().fromModel(compositeField)
|
|
|
|
|
// section.compositeFields = [compositeForm];
|
|
|
|
|
|
|
|
|
|
// this.previewSubject$.next(section);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// private _fieldToFieldDefinition(editorField: Field): FieldDefinition {
|
|
|
|
|
// const field = {
|
|
|
|
|
// id: editorField.id,
|
|
|
|
|
// title: '',
|
|
|
|
|
// page: editorField.page,
|
|
|
|
|
// numbering: '',
|
|
|
|
|
// multiplicity: null,
|
|
|
|
|
// multiplicityItems: null,
|
|
|
|
|
// viewStyle: editorField.viewStyle,
|
|
|
|
|
// defaultValue: editorField.defaultValue,
|
|
|
|
|
// value: null,
|
|
|
|
|
// validations: editorField.validations,
|
|
|
|
|
// } as FieldDefinition;
|
|
|
|
|
|
|
|
|
|
// field.data = editorField.data;
|
|
|
|
|
|
|
|
|
|
// // return new DatasetDescriptionFieldEditorModel().fromModel(field);
|
|
|
|
|
// return field;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
onIsCompositeChange(isComposite: boolean) {
|
|
|
|
|
if (!isComposite && (<UntypedFormArray>this.form.get('fields')).length > 1) {
|
|
|
|
|
for (let i = 0; i < (<UntypedFormArray>this.form.get('fields')).length - 1; i++) {
|
|
|
|
|
(<UntypedFormArray>this.form.get('fields')).removeAt(1);
|
|
|
|
|
}
|
|
|
|
|
(this.form.get('fields') as UntypedFormArray).controls.splice(1);
|
|
|
|
|
}
|
|
|
|
|
if ((<UntypedFormArray>this.form.get('fields')).length === 0) {
|
|
|
|
|
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
|
|
|
|
|
(<UntypedFormArray>this.form.get('fields')).push(field.buildForm());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onIsMultiplicityEnabledChange(isMultiplicityEnabled: MatCheckboxChange) {
|
|
|
|
|
const multiplicity = this.form.get('multiplicity') as UntypedFormGroup;
|
|
|
|
|
|
|
|
|
|
const minControl = multiplicity.get('min');
|
|
|
|
|
const maxControl = multiplicity.get('max');
|
|
|
|
|
const placeholder = multiplicity.get('placeholder');
|
|
|
|
|
const tableView = multiplicity.get('tableView');
|
|
|
|
|
|
|
|
|
|
if (isMultiplicityEnabled.checked) {
|
|
|
|
|
minControl.setValue(0);
|
|
|
|
|
maxControl.setValue(1);
|
|
|
|
|
placeholder.setValue('');
|
|
|
|
|
tableView.setValue(false);
|
|
|
|
|
} else {
|
|
|
|
|
minControl.setValue(0);
|
|
|
|
|
maxControl.setValue(0);
|
|
|
|
|
placeholder.setValue(null);
|
|
|
|
|
tableView.setValue(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.isMultiplicityEnabled = isMultiplicityEnabled.checked;
|
|
|
|
|
minControl.updateValueAndValidity();
|
|
|
|
|
maxControl.updateValueAndValidity();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addNewField() {
|
|
|
|
|
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
|
2023-12-20 08:20:38 +01:00
|
|
|
|
field.id = Guid.create().toString();
|
2023-11-24 17:42:23 +01:00
|
|
|
|
|
|
|
|
|
field.ordinal = (this.form.get('fields') as UntypedFormArray).length;
|
|
|
|
|
|
|
|
|
|
const fieldForm = field.buildForm();
|
|
|
|
|
// fieldForm.setValidators(this.customFieldValidator());
|
|
|
|
|
|
|
|
|
|
// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);
|
|
|
|
|
|
|
|
|
|
(<UntypedFormArray>this.form.get('fields')).push(fieldForm);
|
|
|
|
|
|
|
|
|
|
this.setTargetField(fieldForm);
|
|
|
|
|
fieldForm.updateValueAndValidity();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeleteField(index) {
|
|
|
|
|
|
|
|
|
|
const fieldsForm = <UntypedFormArray>this.form.get('fields');
|
|
|
|
|
fieldsForm.removeAt(index);
|
|
|
|
|
this.inputs.init();
|
|
|
|
|
// calculate ordinals
|
|
|
|
|
fieldsForm.controls.forEach((field, idx) => {
|
|
|
|
|
field.get('ordinal').setValue(idx);
|
|
|
|
|
field.updateValueAndValidity();
|
|
|
|
|
});
|
|
|
|
|
this.form.markAsDirty();//deactivate guard
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getFieldTile(formGroup: UntypedFormGroup, index: number) {
|
|
|
|
|
if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
|
|
|
|
|
return "Field " + (index + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
targetField: UntypedFormGroup;
|
|
|
|
|
validationTypeEnum = ValidationType;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addVisibilityRule(targetField: UntypedFormGroup) {
|
|
|
|
|
const rule: DescriptionTemplateRuleEditorModel = new DescriptionTemplateRuleEditorModel();
|
|
|
|
|
(<UntypedFormArray>targetField.get('visible').get('rules')).push(rule.buildForm());
|
|
|
|
|
}
|
|
|
|
|
toggleRequired(targetField: UntypedFormGroup, event: MatCheckboxChange) {
|
|
|
|
|
|
|
|
|
|
let validationsControl = targetField.get('validations') as UntypedFormControl;
|
|
|
|
|
let validations: Array<ValidationType> = validationsControl.value;
|
|
|
|
|
|
|
|
|
|
if (event.checked) {
|
|
|
|
|
if (!validations.includes(ValidationType.Required)) {//IS ALREADY REQUIRED
|
|
|
|
|
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
|
|
|
|
|
// validationsControl.updateValueAndValidity();
|
|
|
|
|
validations.push(ValidationType.Required);
|
|
|
|
|
// validationsControl.setValue(validations);
|
|
|
|
|
validationsControl.updateValueAndValidity();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
validationsControl.setValue(validations.filter(validator => validator != ValidationType.Required));
|
|
|
|
|
validationsControl.updateValueAndValidity();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if(validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
|
|
|
|
|
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
|
|
|
|
|
// validationsControl.updateValueAndValidity();
|
|
|
|
|
// }else{
|
|
|
|
|
// //SET REQUIRED VALIDATOR
|
|
|
|
|
// console.log('setting required validator');
|
|
|
|
|
// validations.push(ValidationType.Required);
|
|
|
|
|
// validationsControl.setValue(validations);
|
|
|
|
|
// validationsControl.updateValueAndValidity();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
setTargetField(field: AbstractControl) {
|
|
|
|
|
this.targetField = <UntypedFormGroup>field;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deleteTargetField() {
|
|
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
|
restoreFocus: false,
|
|
|
|
|
data: {
|
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
|
|
|
|
isDeleteConfirmation: true
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
dialogRef.afterClosed().subscribe(result => {
|
|
|
|
|
if (result) {
|
|
|
|
|
this._deleteTargetField();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _deleteTargetField() {
|
|
|
|
|
if (!this.targetField) return;
|
|
|
|
|
|
|
|
|
|
let index = -1;
|
|
|
|
|
|
|
|
|
|
const fields = this.form.get('fields') as UntypedFormArray;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < fields.length; i++) {
|
|
|
|
|
let field = fields.at(i);
|
|
|
|
|
if (field.get('id').value === this.targetField.get('id').value) {//index found
|
|
|
|
|
index = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index >= 0) {//target found in fields
|
|
|
|
|
this.DeleteField(index);
|
|
|
|
|
this.targetField = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteField(index: number) {
|
|
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
|
restoreFocus: false,
|
|
|
|
|
data: {
|
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
|
|
|
|
isDeleteConfirmation: true
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
dialogRef.afterClosed().subscribe(result => {
|
|
|
|
|
if (result) {
|
|
|
|
|
this.DeleteField(index);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addNewInput(type: DescriptionTemplateFieldType) {
|
|
|
|
|
|
|
|
|
|
const fieldsArray = this.form.get('fields') as UntypedFormArray;
|
|
|
|
|
|
|
|
|
|
let targetOrdinal = fieldsArray.length;
|
|
|
|
|
try {
|
|
|
|
|
targetOrdinal = fieldsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b)) + 1;
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const field = {
|
2023-12-20 08:20:38 +01:00
|
|
|
|
id: Guid.create().toString(),
|
2023-11-24 17:42:23 +01:00
|
|
|
|
ordinal: targetOrdinal,
|
|
|
|
|
validations: [],
|
|
|
|
|
includeInExport: true
|
|
|
|
|
} as DescriptionTemplateField;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
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.COMBO_BOX: {
|
|
|
|
|
|
|
|
|
|
const firstOption = { label: '', value: '' } as DescriptionTemplateComboBoxOption;
|
|
|
|
|
const data: DescriptionTemplateWordListData = {
|
|
|
|
|
label: '',
|
|
|
|
|
multiList: false,
|
|
|
|
|
options: [firstOption],
|
|
|
|
|
fieldType: DescriptionTemplateFieldType.WORD_LIST
|
|
|
|
|
}
|
|
|
|
|
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.INTERNAL_DMP_ENTRIES_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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(<UntypedFormArray>this.form.get('fields')).push(new DescriptionTemplateFieldEditorModel().fromModel(field).buildForm());
|
|
|
|
|
this.inputs.init();
|
|
|
|
|
// fieldForm.get('viewStyle').get('renderStyle').updateValueAndValidity();
|
|
|
|
|
// fieldForm.get('data').updateValueAndValidity();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// private customFieldValidator(): ValidatorFn{
|
|
|
|
|
// return (control):ValidationErrors | null=>{
|
|
|
|
|
// DescriptionTemplateFieldType
|
|
|
|
|
// switch(control.get('viewStyle').get('renderStyle').value){
|
|
|
|
|
|
|
|
|
|
// case DescriptionTemplateFieldType.TextArea:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.BooleanDecision:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.ComboBox:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.CheckBox:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.FreeText:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.RadioBox:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.DatePicker:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.InternalDmpEntities:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.ExternalDatasets:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.DATA_REPOSITORIES:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Registries:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Services:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Tags:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Researchers:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Organizations:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.DatasetIdentifier:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Currency:
|
|
|
|
|
// return null;
|
|
|
|
|
// case DescriptionTemplateFieldType.Validation:
|
|
|
|
|
// return null;
|
|
|
|
|
// default:
|
|
|
|
|
// return {inputTypeNotValid: true}
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// private _atLeastOneElementListValidator(arrayToCheck): ValidatorFn{
|
|
|
|
|
// return (control: AbstractControl): ValidationErrors | null=>{
|
|
|
|
|
|
|
|
|
|
// const fa = control.get(arrayToCheck) as FormArray;
|
|
|
|
|
|
|
|
|
|
// if(fa.length === 0){
|
|
|
|
|
// return {emptyArray: true};
|
|
|
|
|
// }
|
|
|
|
|
// return null;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
calculateLabelWidth(numbering: string) {
|
|
|
|
|
|
|
|
|
|
const width = numbering.split('.').reduce((acc, item) => item + acc, '').length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { 'width': width + 'em' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get fieldsArray(): UntypedFormArray {
|
|
|
|
|
if (this.form && this.form.get('fields')) {
|
|
|
|
|
return this.form.get('fields') as UntypedFormArray;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
move(index, direction: "up" | "down" = "up") {
|
|
|
|
|
this.inputs.init();
|
|
|
|
|
if (direction === "up" && this.canGoUp(index)) {
|
|
|
|
|
let temp = this.fieldsArray.at(index);
|
|
|
|
|
this.fieldsArray.removeAt(index);
|
|
|
|
|
this.fieldsArray.insert(index - 1, temp);
|
|
|
|
|
} else if (direction === "down" && this.canGoDown(index)) {
|
|
|
|
|
let temp = this.fieldsArray.at(index + 1);
|
|
|
|
|
this.fieldsArray.removeAt(index + 1);
|
|
|
|
|
this.fieldsArray.insert(index, temp);
|
|
|
|
|
}
|
|
|
|
|
this.fieldsArray.controls.forEach((field, index) => {
|
|
|
|
|
field.get('ordinal').setValue(index);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canGoUp(index: number): boolean {
|
|
|
|
|
return index > 0 && !this.viewOnly;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canGoDown(index: number): boolean {
|
|
|
|
|
return index < (this.fieldsArray.length - 1) && !this.viewOnly;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|