add semantics to dmp blueprint

This commit is contained in:
amentis 2024-02-20 11:37:09 +02:00
parent 61560ec8ad
commit d3659aad24
13 changed files with 70 additions and 22 deletions

View File

@ -5,6 +5,7 @@ import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlAttribute;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@ -24,6 +25,9 @@ public abstract class FieldEntity {
@XmlAttribute(name="description") @XmlAttribute(name="description")
private String description; private String description;
@XmlAttribute(name="semantics")
private List<String> semantics;
@XmlAttribute(name="ordinal") @XmlAttribute(name="ordinal")
private Integer ordinal; private Integer ordinal;
@ -65,6 +69,14 @@ public abstract class FieldEntity {
this.description = description; this.description = description;
} }
public List<String> getSemantics() {
return semantics;
}
public void setSemantics(List<String> semantics) {
this.semantics = semantics;
}
public Integer getOrdinal() { public Integer getOrdinal() {
return ordinal; return ordinal;
} }

View File

@ -51,6 +51,7 @@ public abstract class FieldBuilder<Model extends Field, Entity extends FieldEnti
if (fields.hasField(this.asIndexer(Model._id))) m.setId(d.getId()); if (fields.hasField(this.asIndexer(Model._id))) m.setId(d.getId());
if (fields.hasField(this.asIndexer(Model._category))) m.setCategory(d.getCategory()); if (fields.hasField(this.asIndexer(Model._category))) m.setCategory(d.getCategory());
if (fields.hasField(this.asIndexer(Model._description))) m.setDescription(d.getDescription()); if (fields.hasField(this.asIndexer(Model._description))) m.setDescription(d.getDescription());
if (fields.hasField(this.asIndexer(Model._semantics))) m.setSemantics(d.getSemantics());
if (fields.hasField(this.asIndexer(Model._placeholder))) m.setPlaceholder(d.getPlaceholder()); if (fields.hasField(this.asIndexer(Model._placeholder))) m.setPlaceholder(d.getPlaceholder());
if (fields.hasField(this.asIndexer(Model._ordinal))) m.setOrdinal(d.getOrdinal()); if (fields.hasField(this.asIndexer(Model._ordinal))) m.setOrdinal(d.getOrdinal());
if (fields.hasField(this.asIndexer(Model._required))) m.setRequired(d.isRequired()); if (fields.hasField(this.asIndexer(Model._required))) m.setRequired(d.isRequired());

View File

@ -2,6 +2,7 @@ package eu.eudat.model.dmpblueprintdefinition;
import eu.eudat.commons.enums.DmpBlueprintFieldCategory; import eu.eudat.commons.enums.DmpBlueprintFieldCategory;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public abstract class Field { public abstract class Field {
@ -22,6 +23,9 @@ public abstract class Field {
private String description; private String description;
public final static String _ordinal = "ordinal"; public final static String _ordinal = "ordinal";
private List<String> semantics;
public final static String _semantics = "semantics";
private Integer ordinal; private Integer ordinal;
public final static String _required = "required"; public final static String _required = "required";
@ -67,6 +71,14 @@ public abstract class Field {
this.description = description; this.description = description;
} }
public List<String> getSemantics() {
return semantics;
}
public void setSemantics(List<String> semantics) {
this.semantics = semantics;
}
public Integer getOrdinal() { public Integer getOrdinal() {
return ordinal; return ordinal;
} }

View File

@ -45,6 +45,9 @@ public abstract class FieldPersist {
private String description; private String description;
private List<String> semantics = null;
public final static String _semantics = "semantics";
private Integer ordinal = null; private Integer ordinal = null;
public static final String _ordinal = "ordinal"; public static final String _ordinal = "ordinal";
@ -85,6 +88,14 @@ public abstract class FieldPersist {
this.placeholder = placeholder; this.placeholder = placeholder;
} }
public List<String> getSemantics() {
return semantics;
}
public void setSemantics(List<String> semantics) {
this.semantics = semantics;
}
public String getDescription() { public String getDescription() {
return description; return description;
} }

View File

@ -275,6 +275,7 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
data.setLabel(persist.getLabel()); data.setLabel(persist.getLabel());
data.setPlaceholder(persist.getPlaceholder()); data.setPlaceholder(persist.getPlaceholder());
data.setDescription(persist.getDescription()); data.setDescription(persist.getDescription());
data.setSemantics(persist.getSemantics());
data.setOrdinal(persist.getOrdinal()); data.setOrdinal(persist.getOrdinal());
data.setRequired(persist.getRequired()); data.setRequired(persist.getRequired());

View File

@ -43,6 +43,7 @@ export interface FieldInSection {
label: string; label: string;
placeholder: string; placeholder: string;
description: string; description: string;
semantics: string[];
required: boolean; required: boolean;
ordinal: number; ordinal: number;
} }
@ -101,6 +102,7 @@ export interface FieldInSectionPersist {
label: string; label: string;
placeholder: string; placeholder: string;
description: string; description: string;
semantics: string[];
required: boolean; required: boolean;
ordinal: number; ordinal: number;
} }

View File

@ -198,4 +198,18 @@ export class DescriptionTemplateService {
if (like) { lookup.like = this.filterService.transformLike(like); } if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup; return lookup;
} }
// Semantics Autocomplete
semanticsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup()).pipe(map(x => x)),
filterFn: (searchQuery: string, data?: any) => this.searchSemantics(this.buildSemanticsAutocompleteLookup(searchQuery)).pipe(map(x => x)),
displayFn: (item) => item,
titleFn: (item) => item,
}
private buildSemanticsAutocompleteLookup(like?: string ): DescriptionTemplateSemanticsLookup {
const lookup: DescriptionTemplateSemanticsLookup = new DescriptionTemplateSemanticsLookup();
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
} }

View File

@ -136,7 +136,7 @@
<mat-form-field class="col-6"> <mat-form-field class="col-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}</mat-label> <mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}</mat-label>
<app-multiple-auto-complete placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}" [hidePlaceholder]="true" required='false' [separatorKeysCodes]="separatorKeysCodes" [formControl]="this.form.get('schematics')" [configuration]="semanticsAutoCompleteConfiguration"> <app-multiple-auto-complete placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}" [hidePlaceholder]="true" required='false' [separatorKeysCodes]="separatorKeysCodes" [formControl]="this.form.get('schematics')" [configuration]="descriptionTemplateService.semanticsAutoCompleteConfiguration">
</app-multiple-auto-complete> </app-multiple-auto-complete>
<mat-error *ngIf="form.get('schematics').hasError('backendError')">{{form.get('schematics').getError('backendError').message}}</mat-error> <mat-error *ngIf="form.get('schematics').hasError('backendError')">{{form.get('schematics').getError('backendError').message}}</mat-error>
</mat-form-field> </mat-form-field>

View File

@ -20,13 +20,11 @@ import { DescriptionTemplateFieldPersist } from '@app/core/model/description-tem
import { ConfigurationService } from "@app/core/services/configuration/configuration.service"; import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.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 { BaseComponent } from '@common/base/base.component';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model'; import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { DescriptionTemplateSemanticsLookup } from '@app/core/query/description-template-semantics.lookup';
import { FilterService } from '@common/modules/text-filter/filter-service'; import { FilterService } from '@common/modules/text-filter/filter-service';
@Component({ @Component({
@ -52,24 +50,6 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple
readonly separatorKeysCodes: number[] = [ENTER, COMMA]; readonly separatorKeysCodes: number[] = [ENTER, COMMA];
semanticsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.descriptionTemplateService.searchSemantics(this.buildAutocompleteLookup()).pipe(map(x => x)),
filterFn: (searchQuery: string, data?: any) => this.descriptionTemplateService.searchSemantics(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x)),
displayFn: (item) => item,
titleFn: (item) => item,
}
// filterSemantics(value: string): Observable<String[]> {
// // return this.descriptionTemplateService.searchSemantics(value);
// return of([]);
// }
private buildAutocompleteLookup(like?: string ): DescriptionTemplateSemanticsLookup {
const lookup: DescriptionTemplateSemanticsLookup = new DescriptionTemplateSemanticsLookup();
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
constructor( constructor(
public enumUtils: EnumUtils, public enumUtils: EnumUtils,
public descriptionTemplateService: DescriptionTemplateService, public descriptionTemplateService: DescriptionTemplateService,

View File

@ -160,6 +160,15 @@
<mat-error *ngIf="field.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="col" *ngIf="field.get('category').value != null">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.SEMANTICS' | translate}}</mat-label>
<app-multiple-auto-complete placeholder="{{'DMP-BLUEPRINT-EDITOR.FIELDS.SEMANTICS' | translate}}" [hidePlaceholder]="true" required='false' [separatorKeysCodes]="separatorKeysCodes" [formControl]="field.get('semantics')" [configuration]="descriptionTemplateService.semanticsAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="field.get('semantics').hasError('backendError')">{{field.get('semantics').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('semantics').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-auto" *ngIf="field.get('category').value != null"> <div class="col-auto" *ngIf="field.get('category').value != null">
<mat-checkbox [disabled]="field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.Title || field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.Description" [formControl]="field.get('required')"><span>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-REQUIRED' | translate}}</span></mat-checkbox> <mat-checkbox [disabled]="field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.Title || field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.Description" [formControl]="field.get('required')"><span>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-REQUIRED' | translate}}</span></mat-checkbox>
<mat-error *ngIf="field.get('required').hasError('backendError')">{{field.get('required').getError('backendError').message}}</mat-error> <mat-error *ngIf="field.get('required').hasError('backendError')">{{field.get('required').getError('backendError').message}}</mat-error>

View File

@ -297,6 +297,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
public label: string; public label: string;
public placeholder: string; public placeholder: string;
public description: string; public description: string;
public semantics: string[];
public required: boolean = false; public required: boolean = false;
public ordinal: number; public ordinal: number;
public dataType: DmpBlueprintExtraFieldDataType; public dataType: DmpBlueprintExtraFieldDataType;
@ -315,6 +316,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
this.label = item.label; this.label = item.label;
this.placeholder = item.placeholder; this.placeholder = item.placeholder;
this.description = item.description; this.description = item.description;
this.semantics = item.semantics;
this.required = item.required; this.required = item.required;
this.ordinal = item.ordinal; this.ordinal = item.ordinal;
@ -350,6 +352,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
placeholder: [{ value: this.placeholder, disabled: disabled }, context.getValidation('placeholder').validators], placeholder: [{ value: this.placeholder, disabled: disabled }, context.getValidation('placeholder').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
required: [{ value: this.required, disabled: disabled }, context.getValidation('required').validators], required: [{ value: this.required, disabled: disabled }, context.getValidation('required').validators],
semantics: [{ value: this.semantics, disabled: disabled }, context.getValidation('semantics').validators],
ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators],
dataType: [{ value: this.dataType, disabled: disabled }, context.getValidation('dataType').validators], dataType: [{ value: this.dataType, disabled: disabled }, context.getValidation('dataType').validators],
systemFieldType: [{ value: this.systemFieldType, disabled: disabled }, context.getValidation('systemFieldType').validators], systemFieldType: [{ value: this.systemFieldType, disabled: disabled }, context.getValidation('systemFieldType').validators],
@ -372,6 +375,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
baseValidationArray.push({ key: 'label-extra', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); baseValidationArray.push({ key: 'label-extra', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
baseValidationArray.push({ key: 'placeholder', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}placeholder`)] }); baseValidationArray.push({ key: 'placeholder', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}placeholder`)] });
baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}description`)] }); baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}description`)] });
baseValidationArray.push({ key: 'semantics', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}semantics`)] });
baseValidationArray.push({ key: 'required', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}required`)] }); baseValidationArray.push({ key: 'required', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}required`)] });
baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] });
baseValidationArray.push({ key: 'dataType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dataType`)] }); baseValidationArray.push({ key: 'dataType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dataType`)] });
@ -394,7 +398,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
validationErrorModel validationErrorModel
}); });
['id', 'category', 'dataType', 'systemFieldType', 'referenceTypeId', 'label', 'placeholder', 'description', 'required', 'ordinal'].forEach(keyField => { ['id', 'category', 'dataType', 'systemFieldType', 'referenceTypeId', 'label', 'placeholder', 'description', 'semantics', 'required', 'ordinal'].forEach(keyField => {
const control = formGroup?.get(keyField); const control = formGroup?.get(keyField);
control?.clearValidators(); control?.clearValidators();
if (keyField == 'label') { if (keyField == 'label') {

View File

@ -34,6 +34,7 @@ export class DmpBlueprintEditorResolver extends BaseEditorResolver {
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.semantics)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<SystemFieldInSection>(x => x.systemFieldType)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<SystemFieldInSection>(x => x.systemFieldType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<ExtraFieldInSection>(x => x.dataType)].join('.'), [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<ExtraFieldInSection>(x => x.dataType)].join('.'),

View File

@ -1609,6 +1609,7 @@
"DATA-TYPE": "Data Type", "DATA-TYPE": "Data Type",
"CATEGORY": "Field Type", "CATEGORY": "Field Type",
"FIELD-REQUIRED": "Required", "FIELD-REQUIRED": "Required",
"SEMANTICS": "Semantics",
"DESCRIPTION-TEMPLATES": "Description Templates", "DESCRIPTION-TEMPLATES": "Description Templates",
"DESCRIPTION-TEMPLATE": "Description Template", "DESCRIPTION-TEMPLATE": "Description Template",
"DESCRIPTION-TEMPLATE-LABEL": "Label", "DESCRIPTION-TEMPLATE-LABEL": "Label",