Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Diamantis Tziotzios 2024-02-08 09:40:24 +02:00
commit 0c2fb8cbef
25 changed files with 158 additions and 446 deletions

View File

@ -167,10 +167,6 @@ public class FieldSetPersist {
this.spec()
.must(() -> !this.isEmpty(item.getTitle()))
.failOn(FieldSetPersist._title).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldSetPersist._title}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getDescription()))
.failOn(FieldSetPersist._description).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldSetPersist._description}, LocaleContextHolder.getLocale())),
this.refSpec()
.iff(() -> !this.isNull(item.getMultiplicity()))
.on(FieldSetPersist._multiplicity)

View File

@ -151,18 +151,11 @@ public class SectionPersist {
this.spec()
.must(() -> !this.isEmpty(item.getTitle()))
.failOn(SectionPersist._title).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._title}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isEmpty(item.getDescription()))
.failOn(SectionPersist._description).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._description}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getSections()))
.on(SectionPersist._sections)
.over(item.getSections())
.using((itm) -> this.validatorFactory.validator(SectionPersistValidator.class)),
this.spec()
.must(() -> !this.isListNullOrEmpty(item.getFieldSets()))
.failOn(SectionPersist._fieldSets).failWith(messageSource.getMessage("Validation_Required", new Object[]{SectionPersist._fieldSets}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isListNullOrEmpty(item.getFieldSets()))
.on(SectionPersist._fieldSets)

View File

@ -87,9 +87,6 @@ public abstract class BaseFieldDataPersist {
protected List<Specification> getBaseSpecifications(T item) {
List<Specification> specifications = new ArrayList<>();
specifications.addAll(Arrays.asList(
this.spec()
.must(() -> !this.isEmpty(item.getLabel()))
.failOn(BaseFieldDataPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{BaseFieldDataPersist._label}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getFieldType()))
.failOn(BaseFieldDataPersist._fieldType).failWith(messageSource.getMessage("Validation_Required", new Object[]{BaseFieldDataPersist._fieldType}, LocaleContextHolder.getLocale()))

View File

@ -60,11 +60,7 @@ public class ExternalDatasetDataPersist extends BaseFieldDataPersist {
specifications.addAll(Arrays.asList(
this.spec()
.must(() -> !this.isNull(item.getMultipleSelect()))
.failOn(ExternalDatasetDataPersist._multipleSelect).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalDatasetDataPersist._multipleSelect}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getType()))
.failOn(ExternalDatasetDataPersist._type).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalDatasetDataPersist._type}, LocaleContextHolder.getLocale()))
.failOn(ExternalDatasetDataPersist._multipleSelect).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalDatasetDataPersist._multipleSelect}, LocaleContextHolder.getLocale()))
));
return specifications;
}

View File

@ -55,11 +55,8 @@ public class RadioBoxDataPersist extends BaseFieldDataPersist {
this.spec()
.must(() -> !this.isNull(item.getFieldType()))
.failOn(BaseFieldDataPersist._fieldType).failWith(messageSource.getMessage("Validation_Required", new Object[]{BaseFieldDataPersist._fieldType}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getOptions()))
.failOn(RadioBoxDataPersist._options).failWith(messageSource.getMessage("Validation_Required", new Object[]{RadioBoxDataPersist._options}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isNull(item.getOptions()))
.iff(() -> !this.isListNullOrEmpty(item.getOptions()))
.on(RadioBoxDataPersist._options)
.over(item.getOptions())
.using((itm) -> this.validatorFactory.validator(RadioBoxOptionPersist.RadioBoxOptionPersistValidator.class))

View File

@ -68,10 +68,10 @@ public class SelectDataPersist extends BaseFieldDataPersist {
.failOn(SelectDataPersist._multipleSelect).failWith(messageSource.getMessage("Validation_Required", new Object[]{SelectDataPersist._multipleSelect}, LocaleContextHolder.getLocale())),
this.spec()
.must(() -> !this.isNull(item.getOptions()))
.must(() -> !this.isListNullOrEmpty(item.getOptions()))
.failOn(SelectDataPersist._options).failWith(messageSource.getMessage("Validation_Required", new Object[]{SelectDataPersist._options}, LocaleContextHolder.getLocale())),
this.navSpec()
.iff(() -> !this.isNull(item.getOptions()))
.iff(() -> !this.isListNullOrEmpty(item.getOptions()))
.on(SelectDataPersist._options)
.over(item.getOptions())
.using((itm) -> this.validatorFactory.validator(OptionPersist.ComboBoxOptionPersistValidator.class))

View File

@ -87,7 +87,19 @@ public class DescriptionTemplatePersist {
return Arrays.asList(
this.spec()
.must(() -> this.isValidGuid(item.getDescriptionTemplateGroupId()))
.failOn(DescriptionTemplatePersist._descriptionTemplateGroupId).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplatePersist._descriptionTemplateGroupId}, LocaleContextHolder.getLocale()))
.failOn(DescriptionTemplatePersist._descriptionTemplateGroupId).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplatePersist._descriptionTemplateGroupId}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isNull(item.getMinMultiplicity()))
.must(() -> item.getMinMultiplicity() >= 0)
.failOn(DescriptionTemplatePersist._minMultiplicity).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._minMultiplicity}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isNull(item.getMaxMultiplicity()))
.must(() -> item.getMaxMultiplicity() > 0)
.failOn(DescriptionTemplatePersist._maxMultiplicity).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{DescriptionTemplatePersist._maxMultiplicity}, LocaleContextHolder.getLocale())),
this.spec()
.iff(() -> !this.isNull(item.getMaxMultiplicity()))
.must(() -> !this.isNull(item.getMinMultiplicity()) && (item.getMaxMultiplicity() >= item.getMinMultiplicity()))
.failOn(DescriptionTemplatePersist._maxMultiplicity).failWith(messageSource.getMessage("Validation.LowerThanMin", new Object[]{DescriptionTemplatePersist._minMultiplicity}, LocaleContextHolder.getLocale()))
);
}
}

View File

@ -36,6 +36,7 @@ public class ReferenceQuery extends QueryBase<ReferenceEntity> {
private Collection<ReferenceType> referenceTypes;
private Collection<String> references;
private Collection<String> sources;
private Collection<UUID> excludedIds;
@ -111,6 +112,21 @@ public class ReferenceQuery extends QueryBase<ReferenceEntity> {
return this;
}
public ReferenceQuery sources(String value) {
this.sources = List.of(value);
return this;
}
public ReferenceQuery sources(String... value) {
this.sources = Arrays.asList(value);
return this;
}
public ReferenceQuery sources(Collection<String> values) {
this.sources = values;
return this;
}
public ReferenceQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
@ -177,7 +193,7 @@ public class ReferenceQuery extends QueryBase<ReferenceEntity> {
@Override
protected Boolean isFalseQuery() {
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.referenceTypes) || this.isEmpty(this.referenceSourceTypes)|| this.isFalseQuery(this.dmpReferenceQuery);
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.sources) ||this.isEmpty(this.excludedIds) || this.isEmpty(this.referenceTypes) || this.isEmpty(this.referenceSourceTypes)|| this.isFalseQuery(this.dmpReferenceQuery);
}
@Override
@ -219,6 +235,12 @@ public class ReferenceQuery extends QueryBase<ReferenceEntity> {
inClause.value(item);
predicates.add(inClause);
}
if (this.sources != null) {
CriteriaBuilder.In<String> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceEntity._source));
for (String item : this.sources)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceEntity._id));
for (UUID item : this.excludedIds)

View File

@ -21,6 +21,8 @@ public class DmpBlueprintLookup extends Lookup {
private List<UUID> excludedIds;
private List<UUID> groupIds;
public String getLike() {
return like;
}
@ -37,6 +39,14 @@ public class DmpBlueprintLookup extends Lookup {
this.isActive = isActive;
}
public List<DmpBlueprintStatus> getStatuses() {
return statuses;
}
public void setStatuses(List<DmpBlueprintStatus> statuses) {
this.statuses = statuses;
}
public List<UUID> getIds() {
return ids;
}
@ -49,25 +59,32 @@ public class DmpBlueprintLookup extends Lookup {
return excludedIds;
}
public void setExcludedIds(List<UUID> excludeIds) {
this.excludedIds = excludeIds;
public void setExcludedIds(List<UUID> excludedIds) {
this.excludedIds = excludedIds;
}
public List<DmpBlueprintStatus> getStatuses() {
return statuses;
public List<UUID> getGroupIds() {
return groupIds;
}
public void setStatuses(List<DmpBlueprintStatus> statuses) {
this.statuses = statuses;
public void setGroupIds(List<UUID> groupIds) {
this.groupIds = groupIds;
}
public DmpBlueprintQuery enrich(QueryFactory queryFactory) {
DmpBlueprintQuery query = queryFactory.query(DmpBlueprintQuery.class);
if (this.like != null) query.like(this.like);
if (this.isActive != null) query.isActive(this.isActive);
if (this.statuses != null) query.statuses(this.statuses);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.like != null)
query.like(this.like);
if (this.isActive != null)
query.isActive(this.isActive);
if (this.statuses != null)
query.statuses(this.statuses);
if (this.ids != null)
query.ids(this.ids);
if (this.excludedIds != null)
query.excludedIds(this.excludedIds);
if (this.groupIds != null)
query.groupIds(this.groupIds);
this.enrichCommon(query);

View File

@ -512,12 +512,13 @@ public class DescriptionServiceImpl implements DescriptionService {
referenceEntity = this.entityManager.find(ReferenceEntity.class, referencePersist.getId());
if (referenceEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{referencePersist.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale()));
} else {
referenceEntity = this.queryFactory.query(ReferenceQuery.class).sourceTypes(referencePersist.getSourceType()).references(referencePersist.getReference()).first();
referenceEntity = this.queryFactory.query(ReferenceQuery.class).sourceTypes(referencePersist.getSourceType()).sources(referencePersist.getSource()).isActive(IsActive.Active).references(referencePersist.getReference()).first();
if (referenceEntity == null){
referenceEntity = new ReferenceEntity();
referenceEntity.setId(UUID.randomUUID());
referenceEntity.setIsActive(IsActive.Active);
referenceEntity.setCreatedAt(Instant.now());
referenceEntity.setType(referencePersist.getType());
referenceEntity.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(referencePersist.getDefinition())));
referenceEntity.setUpdatedAt(Instant.now());

View File

@ -647,12 +647,13 @@ public class DmpServiceImpl implements DmpService {
referenceEntity = this.entityManager.find(ReferenceEntity.class, referencePersist.getId());
if (referenceEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{referencePersist.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale()));
} else {
referenceEntity = this.queryFactory.query(ReferenceQuery.class).sourceTypes(referencePersist.getSourceType()).references(referencePersist.getReference()).first();
referenceEntity = this.queryFactory.query(ReferenceQuery.class).sourceTypes(referencePersist.getSourceType()).sources(referencePersist.getSource()).isActive(IsActive.Active).references(referencePersist.getReference()).first();
if (referenceEntity == null){
referenceEntity = new ReferenceEntity();
referenceEntity.setId(UUID.randomUUID());
referenceEntity.setIsActive(IsActive.Active);
referenceEntity.setCreatedAt(Instant.now());
referenceEntity.setType(referencePersist.getType());
referenceEntity.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(referencePersist.getDefinition())));
referenceEntity.setUpdatedAt(Instant.now());

View File

@ -407,7 +407,7 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
DmpBlueprintEntity data = new DmpBlueprintEntity();
data.setId(UUID.randomUUID());
data.setLabel(model.getLabel());
data.setStatus(model.getStatus());
data.setStatus(DmpBlueprintStatus.Draft);
data.setDefinition(this.xmlHandlingService.toXml(this.buildDefinitionEntity(model.getDefinition())));
data.setGroupId(oldDmpBlueprintEntity.getGroupId());
data.setVersion((short) (oldDmpBlueprintEntity.getVersion() + 1));

View File

@ -11,6 +11,7 @@ export interface DmpBlueprint extends BaseEntity {
definition: DmpBlueprintDefinition;
status: DmpBlueprintStatus;
version: number;
groupId: Guid;
}
export interface DmpBlueprintDefinition {

View File

@ -9,6 +9,7 @@ export class DmpBlueprintLookup extends Lookup implements DmpBlueprintFilter {
like: string;
isActive: IsActive[];
statuses: DmpBlueprintStatus[];
groupIds: Guid[];
constructor() {
super();

View File

@ -1,15 +1,17 @@
<div class="row" *ngIf="form.get('data')">
<div class="col-12">
<h5 style="font-weight: bold; display: inline-block; margin-right: 2em;">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-TITLE'
<h5 style="font-weight: bold; display: inline-block; margin-right: 2em;">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-TITLE'
| translate}}</h5>
<ng-container *ngIf="form.get('data').errors?.emptyArray && form.get('data').touched">
<mat-icon class="text-danger translateY-3">warning_amber</mat-icon>
<small class="text-danger">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-RADIO-AT-LEAST-ONE-REQUIRED'| translate}}</small>
<small class="text-danger">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-RADIO-AT-LEAST-ONE-REQUIRED'| translate}}</small>
</ng-container>
<mat-error *ngIf="form.get('data').get('options').dirty && form.get('data').get('options').hasError('required')">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-RADIO-AT-LEAST-ONE-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="form.get('data').get('options').hasError('backendError')">{{form.get('data').get('options').getError('backendError').message}}</mat-error>
</div>
<!-- <mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-PLACEHOLDER' | translate}}</mat-label>
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field> -->
@ -17,14 +19,16 @@
<div class="col-12">
<div *ngFor="let option of form.get('data').get('options')['controls'] index as i" class="row">
<mat-form-field class="col">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="option.get('label')">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="option.get('label')" required="true">
<mat-error *ngIf="option.get('label').hasError('backendError')">{{option.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="option.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-VALUE' | translate}}</mat-label>
<input matInput type="string" [formControl]="option.get('value')">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-VALUE' | translate}}</mat-label>
<input matInput type="string" [formControl]="option.get('value')" required="true">
<mat-error *ngIf="option.get('value').hasError('backendError')">{{option.get('value').getError('backendError').message}}</mat-error>
<mat-error *ngIf="option.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<button mat-icon-button class="col-auto" (click)="deleteRow(i)" type="button"
[disabled]="this.form.disabled">

View File

@ -9,7 +9,7 @@
</ng-container>
</div>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multipleSelect')">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-SELECT' | translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-WORDLIST' | translate}}
<mat-error *ngIf="form.get('data').get('multipleSelect').hasError('backendError')">{{form.get('data').get('multipleSelect').getError('backendError').message}}</mat-error>
</mat-checkbox>
@ -36,6 +36,8 @@
</button>
</div>
</div>
<mat-error *ngIf="form.get('data').get('options').dirty && form.get('data').get('options').hasError('required')">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-RADIO-AT-LEAST-ONE-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="form.get('data').get('options').hasError('backendError')">{{form.get('data').get('options').getError('backendError').message}}</mat-error>
<div class="col-auto"><button mat-icon-button (click)="addNewRow()">
<mat-icon>add</mat-icon>
</button></div>

View File

@ -65,7 +65,7 @@
[hasFocus]="fieldset.get('id').value === selectedFieldSetId"
[datasetProfileId]="datasetProfileId"
[validationErrorModel]="validationErrorModel"
[rootPath]="rootPath">
[rootPath]="rootPath + 'fieldSets[' + i + '].'">
</app-description-template-editor-composite-field-component>
</mat-card-content>
</mat-card>

View File

@ -616,6 +616,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
section.ordinal = sectionsArray.length;
}
//store rootPath for next levels/components
this.rootPath = 'definition.pages['+ pageIndex +'].sections[' + sectionsArray.length + '].';
sectionsArray.push(section.buildForm({ rootPath: 'definition.pages['+ pageIndex +'].sections[' + sectionsArray.length + '].' }));
// this.form.updateValueAndValidity();
@ -634,21 +638,24 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
sectionIndexes.forEach(index => {
parentSectionRootPath = parentSectionRootPath + 'sections[' + index +'].'
});
sectionsArray = parent.form.get('sections') as UntypedFormArray;
//adding page parent MAYBE NOT NEEDED
try {
const maxOrdinal = sectionsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b));
section.ordinal = maxOrdinal + 1;
} catch {
section.ordinal = sectionsArray.length;
}
//store rootPath for next levels/components
this.rootPath = 'definition.pages['+ pageIndex +'].'+ parentSectionRootPath;
sectionsArray.push(section.buildForm({ rootPath: 'definition.pages['+ pageIndex +'].' + parentSectionRootPath + 'sections[' + sectionsArray.length + '].' }));
// (child.form.parent as FormArray).push(section.buildForm());
}
sectionsArray = parent.form.get('sections') as UntypedFormArray;
//adding page parent MAYBE NOT NEEDED
try {
const maxOrdinal = sectionsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b));
section.ordinal = maxOrdinal + 1;
} catch {
section.ordinal = sectionsArray.length;
}
sectionsArray.push(section.buildForm({ rootPath: 'definition.pages['+ pageIndex +'].' + parentSectionRootPath + 'sections[' + sectionsArray.length + '].' }));
// (child.form.parent as FormArray).push(section.buildForm());
} else {
console.error('Section can only be child of a page or another section');
}
@ -687,8 +694,6 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
field.ordinal = 0;//first filed in the fields list
const fieldSetsArray = parent.form.get('fieldSets') as UntypedFormArray
//store rootPath for next levels/components
this.rootPath = 'definition.pages['+ pageIndex +'].'+ parentSectionRootPath+ 'fieldSets[' + fieldSetsArray.length + '].';
const fieldForm = field.buildForm({ rootPath: this.rootPath+ 'fields[' + 0 + '].'});
//give fieldset id and ordinal

View File

@ -60,8 +60,8 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `users[${index}].`
}), context.getValidation('users')
)
})
), context.getValidation('users').validators
),
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators]
});
@ -1233,8 +1233,9 @@ export class DescriptionTemplateExternalSelectDataEditorModel extends Descriptio
(this.sources ?? []).map(
(item, index) => item.buildForm({
rootPath: `${rootPath}sources[${index}].`
}), context.getValidation('sources')
)));
})
), context.getValidation('sources').validators
));
return formGroup;
}
@ -1583,8 +1584,9 @@ export class DescriptionTemplateRadioBoxDataEditorModel extends DescriptionTempl
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `${rootPath}options[${index}].`
}), context.getValidation('options')
)));
})
), context.getValidation('options').validators
));
return formGroup;
}
@ -1729,8 +1731,9 @@ export class DescriptionTemplateSelectDataEditorModel extends DescriptionTemplat
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `${rootPath}options[${index}].`
}), context.getValidation('options')
)));
})
), context.getValidation('options').validators
));
return formGroup;
}

View File

@ -14,6 +14,14 @@ const routes: Routes = [
component: DmpBlueprintListingComponent,
canActivate: [AuthGuard]
},
{
path: 'versions/:groupid',
component: DmpBlueprintListingComponent,
canActivate: [AuthGuard],
data: {
mode: 'versions-listing'
}
},
{
path: 'new',
canActivate: [AuthGuard],
@ -45,7 +53,6 @@ const routes: Routes = [
},
action: 'clone'
}
},
{
path: 'new-version/:newversionid',
@ -64,7 +71,6 @@ const routes: Routes = [
},
action: 'new-version'
}
},
{
path: ':id',

View File

@ -84,7 +84,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
}
protected get canFinalize(): boolean {
return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint);
return !this.isNewVersion && !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint);
}
protected get canCreateNewVersion(): boolean {
@ -128,7 +128,9 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
this.matomoService.trackPageView('Admin: DMP Blueprints');
super.ngOnInit();
this.initModelFlags(this.route.snapshot.data['action']);
this.route.data.subscribe(d => this.initModelFlags(d['action']));
this.route.data.subscribe(d => {
this.initModelFlags(d['action']);
});
}
private initModelFlags(action: string): void {
@ -171,9 +173,13 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDmpBlueprint));
this.selectedSystemFields = this.selectedSystemFieldDisabled();
this.dmpBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
if (this.editorModel.status == DmpBlueprintStatus.Finalized || this.isDeleted) {
if (this.isFinalized || this.isDeleted) {
this.formGroup.disable();
}
const action = this.route.snapshot.data['action'];
if (action && action == 'new-version') {
this.formGroup.enable();
}
}
refreshData(id?: Guid): void {
@ -213,9 +219,9 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
formSubmit(): void {
this.formService.touchAllFormFields(this.formGroup);
// if (!this.isFormValid()) {
// return;
// }
if (!this.isFormValid()) {
return;
}
this.persistEntity();
}
@ -461,240 +467,6 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates').markAsDirty();
}
//
//
// Autocomplete configuration
//
//
// onRemoveDescritionTemplate(event, sectionIndex: number) {
// const descriptionTemplateFormArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
// const foundIndex = descriptionTemplateFormArray.controls.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id);
// if (foundIndex !== -1) {
// descriptionTemplateFormArray.removeAt(foundIndex);
// DmpBlueprintEditorModel.reApplySectionValidators(
// {
// formGroup: this.formGroup,
// validationErrorModel: this.editorModel.validationErrorModel
// }
// )
// this.formGroup.get('definition').get('sections').markAsDirty();
// }
// }
// onSelectDescritionTemplate(item, sectionIndex) {
// ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray)
// .push(this.editorModel.createChildDescriptionTemplate(item, sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length));
// }
// ngAfterViewInit() {
// this.route.params
// .pipe(takeUntil(this._destroyed))
// .subscribe((params: Params) => {
// this.dmpBlueprintId = params['id'];
// const cloneId = params['cloneid'];
// if (this.dmpBlueprintId != null) {
// this.isNew = false;
// this.dmpBlueprintService.getSingleBlueprint(this.dmpBlueprintId).pipe(map(data => data as any))
// .pipe(takeUntil(this._destroyed))
// .subscribe(data => {
// this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data);
// this.formGroup = this.dmpBlueprintEditor.buildForm();
// this.buildSystemFields();
// this.fillDescriptionTemplatesInMultAutocomplete();
// if (this.dmpBlueprintEditor.status == DmpBlueprintStatus.Finalized) {
// this.formGroup.disable();
// this.viewOnly = true
// }
// // this.breadCrumbs = observableOf([{
// // parentComponentName: 'DmpBlueprintListingComponent',
// // label: this.language.instant('NAV-BAR.TEMPLATE'),
// // url: '/dmp-blueprints/' + this.dmpBlueprintId
// // }]);
// });
// } else if (cloneId != null) {
// this.isClone = true;
// this.dmpBlueprintService.clone(cloneId).pipe(map(data => data as any), takeUntil(this._destroyed))
// .subscribe(
// data => {
// this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data);
// this.dmpBlueprintEditor.id = null;
// this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft;
// this.formGroup = this.dmpBlueprintEditor.buildForm();
// this.buildSystemFields();
// this.fillDescriptionTemplatesInMultAutocomplete();
// },
// error => this.onCallbackError(error)
// );
// } else {
// this.dmpBlueprintEditorModel = new DmpBlueprintEditorModel();
// this.dmpBlueprintEditor = new DmpBlueprintEditor();
// setTimeout(() => {
// // this.formGroup = this.dmpBlueprintModel.buildForm();
// // this.addField();
// this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft;
// this.formGroup = this.dmpBlueprintEditor.buildForm();
// });
// // this.breadCrumbs = observableOf([{
// // parentComponentName: 'DmpBlueprintListingComponent',
// // label: this.language.instant('NAV-BAR.TEMPLATE'),
// // url: '/dmp-blueprints/' + this.dmpBlueprintId
// // }]);
// }
// });
// }
// buildSystemFields() {
// const sections = this.sectionsArray().controls.length;
// for (let i = 0; i < sections; i++) {
// let systemFieldsInSection = new Array();
// this.fieldsArray(i).controls.forEach((field) => {
// if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == DmpBlueprintSectionFieldCategory.SYSTEM)) {
// systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type);
// }
// })
// this.systemFieldListPerSection.push(systemFieldsInSection);
// }
// }
// fillDescriptionTemplatesInMultAutocomplete() {
// const sections = this.sectionsArray().controls.length;
// for (let i = 0; i < sections; i++) {
// let descriptionTemplatesInSection = new Array<DatasetProfileModel>();
// this.descriptionTemplatesArray(i).controls.forEach((template) => {
// descriptionTemplatesInSection.push({ id: template.value.descriptionTemplateId, label: template.value.label, description: "" });
// })
// this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection);
// }
// }
// checkForProfiles(event, sectionIndex: number) {
// if (event.checked === false) {
// this.descriptionTemplatesPerSection[sectionIndex] = new Array<DatasetProfileModel>();
// this.descriptionTemplatesArray(sectionIndex).clear();
// }
// }
// sectionsArray(): UntypedFormArray {
// //return this.dmpBlueprintsFormGroup.get('sections') as FormArray;
// return this.formGroup.get('definition').get('sections') as UntypedFormArray;
// }
// fieldsArray(sectionIndex: number): UntypedFormArray {
// return this.sectionsArray().at(sectionIndex).get('fields') as UntypedFormArray;
// }
// removeField(sectionIndex: number, fieldIndex: number): void {
// this.fieldsArray(sectionIndex).removeAt(fieldIndex);
// }
// systemFieldsArray(sectionIndex: number): UntypedFormArray {
// return this.sectionsArray().at(sectionIndex).get('systemFields') as UntypedFormArray;
// }
// initSystemField(systemField?: SystemFieldType): UntypedFormGroup {
// return this.fb.group({
// id: this.fb.control(Guid.create().toString()),
// type: this.fb.control(systemField),
// label: this.fb.control(''),
// placeholder: this.fb.control(''),
// description: this.fb.control(''),
// required: this.fb.control(true),
// ordinal: this.fb.control('')
// });
// }
// addSystemField(sectionIndex: number, systemField?: SystemFieldType): void {
// this.addField(sectionIndex, FieldCategory.SYSTEM, systemField);
// }
// transfromEnumToString(type: SystemFieldType): string {
// return this.fieldList.find(f => f.type == type).label;
// }
// selectedFieldType(type: SystemFieldType, sectionIndex: number): void {
// let index = this.systemFieldListPerSection[sectionIndex].indexOf(type);
// if (index == -1) {
// this.systemFieldListPerSection[sectionIndex].push(type);
// this.addSystemField(sectionIndex, type);
// }
// else {
// this.systemFieldListPerSection[sectionIndex].splice(index, 1);
// this.removeSystemField(sectionIndex, type);
// }
// }
// descriptionTemplatesArray(sectionIndex: number): UntypedFormArray {
// return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as UntypedFormArray;
// }
// addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void {
// this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({
// label: this.fb.control(descriptionTemplate.value)
// }));
// }
// removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void {
// this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex);
// }
// extraFieldsArray(sectionIndex: number): UntypedFormArray {
// return this.sectionsArray().at(sectionIndex).get('extraFields') as UntypedFormArray;
// }
// getExtraFieldTypes(): Number[] {
// let keys: string[] = Object.keys(ExtraFieldType);
// keys = keys.slice(0, keys.length / 2);
// const values: Number[] = keys.map(Number);
// return values;
// }
// getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string {
// switch (extraFieldType) {
// case ExtraFieldType.TEXT: return 'Text';
// case ExtraFieldType.RICH_TEXT: return 'Rich Text';
// case ExtraFieldType.DATE: return 'Date';
// case ExtraFieldType.NUMBER: return 'Number';
// }
// }
// moveItemInFormArray(formArray: UntypedFormArray, fromIndex: number, toIndex: number): void {
// const dir = toIndex > fromIndex ? 1 : -1;
// const item = formArray.at(fromIndex);
// for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) {
// const current = formArray.at(i + dir);
// formArray.setControl(i, current);
// }
// formArray.setControl(toIndex, item);
// }
// // clearForm(): void{
// // this.dmpBlueprintsFormGroup.reset();
// // }
onPreviewDescriptionTemplate(event: DescriptionTemplate, sectionId: Guid) {
const dialogRef = this.dialog.open(DescriptionTemplatePreviewDialogComponent, {
@ -749,15 +521,6 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
return true;
}
// formSubmit(): void {
// if (this.checkValidity())
// this.onSubmit();
// }
// public isFormValid() {
// return this.formGroup.valid;
// }
hasTitle(): boolean {
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === DmpBlueprintSectionFieldCategory.SYSTEM || field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM) && field.systemFieldType === DmpBlueprintSystemFieldType.TEXT));
@ -787,119 +550,10 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
}
// onSubmit(): void {
// this.dmpBlueprintService.createBlueprint(this.formGroup.value)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => this.onCallbackSuccess(),
// error => this.onCallbackError(error)
// );
// }
// onCallbackSuccess(): void {
// this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
// this.router.navigate(['/dmp-blueprints']);
// }
// onCallbackError(errorResponse: any) {
// this.setErrorModel(errorResponse.error);
// this.formService.validateAllFormFields(this.formGroup);
// }
// public setErrorModel(validationErrorModel: ValidationErrorModel) {
// Object.keys(validationErrorModel).forEach(item => {
// (<any>this.dmpBlueprintEditor.validationErrorModel)[item] = (<any>validationErrorModel)[item];
// });
// }
public cancel(): void {
this.router.navigate(['/dmp-blueprints']);
}
// // addField() {
// // (<FormArray>this.formGroup.get('definition').get('fields')).push(new DmpBlueprintFieldEditorModel().buildForm());
// // }
// // removeField(index: number) {
// // (<FormArray>this.formGroup.get('definition').get('fields')).controls.splice(index, 1);
// // }
// getDmpBlueprintFieldDataTypeValues(): Number[] {
// let keys: string[] = Object.keys(DmpBlueprintFieldDataType);
// keys = keys.slice(0, keys.length / 2);
// const values: Number[] = keys.map(Number);
// return values;
// }
// getDmpBlueprintFieldDataTypeWithLanguage(fieldType: DmpBlueprintFieldDataType): string {
// let result = '';
// this.language.get(this.enumUtils.toDmpBlueprintExtraFieldDataTypeString(fieldType))
// .pipe(takeUntil(this._destroyed))
// .subscribe((value: string) => {
// result = value;
// });
// return result;
// }
// getDmpBlueprintFieldTypeValues(): Number[] {
// let keys: string[] = Object.keys(DmpBlueprintType);
// keys = keys.slice(0, keys.length / 2);
// const values: Number[] = keys.map(Number);
// return values;
// }
// getDmpBlueprintFieldTypeWithLanguage(blueprintType: DmpBlueprintType): string {
// let result = '';
// this.language.get(this.enumUtils.toDmpBlueprintTypeString(blueprintType))
// .pipe(takeUntil(this._destroyed))
// .subscribe((value: string) => {
// result = value;
// });
// return result;
// }
// delete() {
// this.dialog.open(ConfirmationDialogComponent, {
// data: {
// isDeleteConfirmation: true,
// confirmButton: this.language.instant('DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
// cancelButton: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
// message: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
// }
// })
// .afterClosed()
// .subscribe(
// confirmed => {
// if (confirmed) {
// if (this.formGroup.get('status').value == DmpBlueprintStatus.Draft) {
// // this.formGroup.get('status').setValue(DmpBlueprintStatus.Deleted);
// this.dmpBlueprintService.createBlueprint(this.formGroup.value)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => this.onCallbackSuccess(),
// error => this.onCallbackError(error)
// );
// }
// else {
// // this.dmpBlueprintService.delete(this.dmpBlueprintId)
// // .pipe(takeUntil(this._destroyed))
// // .subscribe(
// // complete => this.onCallbackSuccess(),
// // error => {
// // if (error.error.statusCode == 674) {
// // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error);
// // } else {
// // this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
// // }
// // }
// // );
// }
// }
// }
// )
// }
finalize() {
if (this.checkValidity()) {
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);

View File

@ -23,7 +23,7 @@
</div>
</div>
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns" [count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size" [defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event)" (pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)" (columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns" [count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size" [defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event, '/dmp-blueprints')" (pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)" (columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
<app-dmp-blueprint-listing-filters hybrid-listing-filters [(filter)]="lookup" (filterChange)="filterChanged($event)" />
@ -90,16 +90,20 @@
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item [routerLink]="['./' + row.id]">
<button mat-menu-item [routerLink]="['/dmp-blueprints/', row.id]">
<mat-icon>edit</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.EDIT' | translate}}
</button>
<button mat-menu-item [routerLink]="['./new-version/' + row.id]">
<button mat-menu-item [routerLink]="['/dmp-blueprints/new-version' , row.id]">
<mat-icon>queue</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item [routerLink]="['./clone/' + row.id]">
<button mat-menu-item [routerLink]="['/dmp-blueprints/clone' , row.id]">
<mat-icon>content_copy</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.CLONE' | translate}}
</button>
<button mat-menu-item (click)="export(row.id)" [routerLink]="['./' + row.id]">
<button mat-menu-item [routerLink]="['/dmp-blueprints/versions' , row.groupId]">
<mat-icon>library_books</mat-icon>
{{'DMP-BLUEPRINT-LISTING.ACTIONS.VIEW-VERSIONS' | translate}}
</button>
<button mat-menu-item (click)="export(row.id)" [routerLink]="['/dmp-blueprints/', row.id]">
<mat-icon>download</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.DOWNLOAD-XML' | translate}}
</button>
<button mat-menu-item (click)="delete(row.id)">

View File

@ -40,6 +40,7 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
userSettingsKey = { key: 'DmpBlueprintListingUserSettings' };
propertiesAvailableForOrder: ColumnDefinition[];
dmpBlueprintStatuses = DmpBlueprintStatus;
mode;
@ViewChild('dmpBlueprintStatus', { static: true }) dmpBlueprintStatus?: TemplateRef<any>;
@ViewChild('actions', { static: true }) actions?: TemplateRef<any>;
@ -50,6 +51,7 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
nameof<DmpBlueprint>(x => x.label),
nameof<DmpBlueprint>(x => x.status),
nameof<DmpBlueprint>(x => x.version),
nameof<DmpBlueprint>(x => x.groupId),
nameof<DmpBlueprint>(x => x.updatedAt),
nameof<DmpBlueprint>(x => x.createdAt),
nameof<DmpBlueprint>(x => x.hash),
@ -76,6 +78,7 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
// Lookup setup
// Default lookup values are defined in the user settings class.
this.mode = this.route.snapshot?.data['mode'];
this.lookup = this.initializeLookup();
}
@ -90,6 +93,7 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
lookup.isActive = [IsActive.Active];
lookup.order = { items: [this.toDescSortField(nameof<DmpBlueprint>(x => x.createdAt))] };
if (this.mode && this.mode == 'versions-listing') lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))]
this.updateOrderUiFields(lookup.order);
lookup.project = {

View File

@ -1,10 +1,5 @@
<mat-form-field class="w-100" *ngIf="multipleAutoCompleteSearchConfiguration">
<ng-container *ngIf="label">
<mat-label>{{label}}</mat-label>
</ng-container>
<ng-container *ngIf="!label">
<mat-label>{{'REFERENCE-FIELD.PLACEHOLDER' | translate}} {{enumUtils.toReferenceTypeString(referenceType)}}</mat-label>
</ng-container>
<mat-label>{{label ?? enumUtils.toReferenceTypeString(referenceType)}}</mat-label>
<app-multiple-auto-complete placeholder = "{{ placeholder ?? enumUtils.toReferenceTypeString(referenceType)}}" [formControl]="form" [configuration]="multipleAutoCompleteSearchConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="form.hasError('backendError')">{{form.getError('backendError').message}}</mat-error>

View File

@ -1923,7 +1923,8 @@
"EDIT": "Edit",
"CLONE": "Clone",
"NEW-VERSION": "New Version",
"DOWNLOAD-XML": "Download XML"
"DOWNLOAD-XML": "Download XML",
"VIEW-VERSIONS": "All Dmp Blueprint Versions"
},
"IMPORT": {
"UPLOAD-XML": "Import",