Merge branch 'dmp-refactoring' of code-repo.d4science.org:MaDgiK-CITE/argos into dmp-refactoring
This commit is contained in:
commit
ea6ea25116
|
@ -219,8 +219,7 @@ public class DescriptionPersist {
|
|||
.must(() -> !this.isNull(item.getProperties()))
|
||||
.failOn(DescriptionPersist._properties).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionPersist._properties}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> item.getStatus() == DescriptionStatus.Finalized)
|
||||
.must(() -> this.isDescriptionTemplateMultiplicityValid(finalDmpBlueprintEntity, item.getDmpId(), item.getDescriptionTemplateId()))
|
||||
.must(() -> this.isDescriptionTemplateMaxMultiplicityValid(finalDmpBlueprintEntity, item.getDmpId(), item.getDmpDescriptionTemplateId(), this.isValidGuid(item.getId())))
|
||||
.failOn(DescriptionPersist._descriptionTemplateId).failWith(messageSource.getMessage("Validation.InvalidDescriptionTemplateMultiplicity", new Object[]{DescriptionPersist._descriptionTemplateId}, LocaleContextHolder.getLocale()))
|
||||
// this.refSpec()
|
||||
// .iff(() -> !this.isNull(item.getProperties()))
|
||||
|
@ -235,26 +234,28 @@ public class DescriptionPersist {
|
|||
);
|
||||
}
|
||||
|
||||
private boolean isDescriptionTemplateMultiplicityValid(DmpBlueprintEntity dmpBlueprintEntity, UUID dmpId, UUID descriptionTemplateId){
|
||||
private boolean isDescriptionTemplateMaxMultiplicityValid(DmpBlueprintEntity dmpBlueprintEntity, UUID dmpId, UUID dmpDescriptionTemplateId, Boolean isUpdate){
|
||||
eu.eudat.commons.types.dmpblueprint.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(eu.eudat.commons.types.dmpblueprint.DefinitionEntity.class, dmpBlueprintEntity.getDefinition());
|
||||
if (definition == null || this.isListNullOrEmpty(definition.getSections())) return true;
|
||||
|
||||
DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(dmpDescriptionTemplateId).isActive(IsActive.Active).dmpIds(dmpId).first();
|
||||
if (dmpDescriptionTemplateEntity == null) return true;
|
||||
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).dmpIds(dmpId).dmpDescriptionTemplateIds(dmpDescriptionTemplateId).isActive(IsActive.Active).collect();
|
||||
|
||||
for (SectionEntity section: definition.getSections()) {
|
||||
if (section.getHasTemplates() && !this.isListNullOrEmpty(section.getDescriptionTemplates())){
|
||||
int descriptionsCount = 0;
|
||||
if (dmpDescriptionTemplateEntity.getSectionId().equals(section.getId()) && section.getHasTemplates() && !this.isListNullOrEmpty(section.getDescriptionTemplates())){
|
||||
int descriptionsCount;
|
||||
if (isUpdate) descriptionsCount = -1;
|
||||
else descriptionsCount = 0;
|
||||
|
||||
for (eu.eudat.commons.types.dmpblueprint.DescriptionTemplateEntity sectionDescriptionTemplate: section.getDescriptionTemplates()) {
|
||||
if (sectionDescriptionTemplate.getMaxMultiplicity() == null && sectionDescriptionTemplate.getMinMultiplicity() == null ) continue;
|
||||
|
||||
DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery = this.queryFactory.query(DmpDescriptionTemplateQuery.class).isActive(IsActive.Active).dmpIds(dmpId).sectionIds(section.getId());
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).dmpIds(dmpId).dmpDescriptionTemplateSubQuery(dmpDescriptionTemplateQuery).isActive(IsActive.Active).collect();
|
||||
if (this.isListNullOrEmpty(descriptionEntities)) continue;
|
||||
|
||||
if (sectionDescriptionTemplate.getDescriptionTemplateGroupId().equals(dmpDescriptionTemplateEntity.getDescriptionTemplateGroupId())){
|
||||
for (DescriptionEntity description: descriptionEntities){
|
||||
if (description.getDescriptionTemplateId().equals(descriptionTemplateId)) descriptionsCount++;
|
||||
if (description.getDmpDescriptionTemplateId().equals(dmpDescriptionTemplateEntity.getId())) descriptionsCount++;
|
||||
}
|
||||
if (sectionDescriptionTemplate.getMinMultiplicity() != null && sectionDescriptionTemplate.getMinMultiplicity() >= descriptionsCount) return false;
|
||||
if (sectionDescriptionTemplate.getMaxMultiplicity() != null && sectionDescriptionTemplate.getMaxMultiplicity() <= descriptionsCount) return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
|||
private final UserScope userScope;
|
||||
private final AuthorizationService authService;
|
||||
private final QueryUtilsService queryUtilsService;
|
||||
|
||||
private Collection<UUID> dmpDescriptionTemplateIds;
|
||||
public DescriptionQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) {
|
||||
this.userScope = userScope;
|
||||
this.authService = authService;
|
||||
|
@ -110,7 +112,20 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public DescriptionQuery dmpDescriptionTemplateIds(UUID value) {
|
||||
this.dmpDescriptionTemplateIds = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescriptionQuery dmpDescriptionTemplateIds(UUID... value) {
|
||||
this.dmpDescriptionTemplateIds = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescriptionQuery dmpDescriptionTemplateIds(Collection<UUID> values) {
|
||||
this.dmpDescriptionTemplateIds = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DescriptionQuery finalizedAfter(Instant value) {
|
||||
this.finalizedAfter = value;
|
||||
|
@ -287,6 +302,12 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
|
|||
QueryContext<DmpEntity, UUID> subQuery = this.applySubQuery(this.dmpQuery, queryContext, UUID.class, dmpEntityRoot -> dmpEntityRoot.get(DmpEntity._id));
|
||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpId)).value(subQuery.Query));
|
||||
}
|
||||
if (this.dmpDescriptionTemplateIds != null) {
|
||||
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpDescriptionTemplateId));
|
||||
for (UUID item : this.dmpDescriptionTemplateIds)
|
||||
inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
if (!predicates.isEmpty()) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
|
|
|
@ -358,7 +358,9 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService {
|
|||
eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition());
|
||||
|
||||
Description description = new Description();
|
||||
description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, descriptionTemplateEntity));
|
||||
FieldSet descriptionTemplateFields = fieldSet.extractPrefixed(this.conventionService.asPrefix(Description._descriptionTemplate));
|
||||
|
||||
description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(descriptionTemplateFields, descriptionTemplateEntity));
|
||||
return mapPrefilledEntityToDescription(description, descriptionTemplateDefinition, prefillingSourceDefinition, prefillingSourceEntity.getLabel(), externalData.getResults().getFirst());//TODO
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,8 @@ export class DmpBlueprintService {
|
|||
lookup.project = {
|
||||
fields: [
|
||||
nameof<DmpBlueprint>(x => x.id),
|
||||
nameof<DmpBlueprint>(x => x.label)
|
||||
nameof<DmpBlueprint>(x => x.label),
|
||||
nameof<DmpBlueprint>(x => x.version)
|
||||
]
|
||||
};
|
||||
lookup.order = { items: [nameof<DmpBlueprint>(x => x.label)] };
|
||||
|
|
|
@ -283,6 +283,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
|||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.formGroup.get('status').setValue(DescriptionTemplateStatus.Finalized);
|
||||
if(this.isNewVersion) this.isNewVersion = false;
|
||||
this.persistEntity();
|
||||
}});
|
||||
}
|
||||
|
|
|
@ -550,6 +550,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
|
|||
finalize() {
|
||||
if (this.checkValidity()) {
|
||||
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);
|
||||
if(this.isNewVersion) this.isNewVersion = false;
|
||||
this.formSubmit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati
|
|||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
||||
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-editor-component',
|
||||
|
@ -55,24 +58,6 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
isNew = true;
|
||||
isDeleted = false;
|
||||
item: Description;
|
||||
// showInactiveDetails = false;
|
||||
// selectedSystemFields: Array<DescriptionSystemFieldType> = [];
|
||||
// DescriptionSectionFieldCategory = DescriptionSectionFieldCategory;
|
||||
// DescriptionSystemFieldType = DescriptionSystemFieldType;
|
||||
// public DescriptionSystemFieldTypeEnum = this.enumUtils.getEnumValues<DescriptionSystemFieldType>(DescriptionSystemFieldType);
|
||||
// DescriptionExtraFieldDataType = DescriptionExtraFieldDataType;
|
||||
// public DescriptionExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<DescriptionExtraFieldDataType>(DescriptionExtraFieldDataType);
|
||||
|
||||
// blueprintsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
// filterFn: this.filterDescriptionTempaltes.bind(this),
|
||||
// initialItems: (excludedItems: any[]) => this.filterDescriptionTempaltes('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
// displayFn: (item: DatasetProfileModel) => item.label,
|
||||
// titleFn: (item: DatasetProfileModel) => item.label,
|
||||
// subtitleFn: (item: DatasetProfileModel) => item.description,
|
||||
// popupItemActionIcon: 'visibility'
|
||||
// };
|
||||
|
||||
// hasChanges = false;
|
||||
fieldsetIdWithFocus: string;
|
||||
|
||||
viewOnly = false;
|
||||
|
@ -211,10 +196,14 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
},
|
||||
panelClass: 'custom-modalbox'
|
||||
});
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
dialogRef.afterClosed().subscribe((result: Description) => {
|
||||
if (result) {
|
||||
result.dmp = this.item.dmp;
|
||||
result.dmpDescriptionTemplate = this.item.dmpDescriptionTemplate;
|
||||
|
||||
const sectionId = this.item.dmpDescriptionTemplate.sectionId;
|
||||
result.dmpDescriptionTemplate = this.item.dmp.dmpDescriptionTemplates.find(x => x.sectionId == sectionId && x.descriptionTemplateGroupId == result.descriptionTemplate.groupId);
|
||||
|
||||
this.prepareForm(result);
|
||||
// this.descriptionModel = this.descriptionModel.fromModel(result);
|
||||
// this.descriptionModel.dmp = data;
|
||||
|
@ -551,6 +540,13 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
try {
|
||||
this.editorModel = data ? new DescriptionEditorModel().fromModel(data, data.descriptionTemplate) : new DescriptionEditorModel();
|
||||
this.item = data;
|
||||
if (data && data.dmpDescriptionTemplate?.sectionId && data.dmp?.blueprint?.definition?.sections?.length > 0 && data.dmp?.descriptions?.length > 0){
|
||||
const section = data.dmp?.blueprint?.definition?.sections.find(x => x.id == data.dmpDescriptionTemplate?.sectionId);
|
||||
if(section.hasTemplates) {
|
||||
const notAvailableDescriptionTemplates = this.calculateMultiplicityRejectedDmpDescriptionTemplates(section, data.dmp.descriptions.filter(x => x.isActive == IsActive.Active));
|
||||
this.item.dmp.dmpDescriptionTemplates = data.dmp.dmpDescriptionTemplates.filter(x => !notAvailableDescriptionTemplates.map(y => y.id).includes(x.id) )
|
||||
}
|
||||
}
|
||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||
this.buildForm();
|
||||
} catch (error) {
|
||||
|
@ -588,6 +584,26 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
|
||||
}
|
||||
|
||||
calculateMultiplicityRejectedDmpDescriptionTemplates(section: DmpBlueprintDefinitionSection, descriptions: Description[]) : DmpDescriptionTemplate[]{
|
||||
if (section.descriptionTemplates?.length > 0){
|
||||
descriptions = descriptions?.filter(x => x?.dmpDescriptionTemplate?.sectionId === section.id) || [];
|
||||
|
||||
let rejectedDmpDescriptionTemplates: DmpDescriptionTemplate[] = [];
|
||||
section.descriptionTemplates.forEach(sectionDescriptionTemplate => {
|
||||
if (sectionDescriptionTemplate.maxMultiplicity != null){
|
||||
const commonDescriptions = descriptions.filter(x => x.dmpDescriptionTemplate.descriptionTemplateGroupId == sectionDescriptionTemplate.descriptionTemplateGroupId);
|
||||
|
||||
if (commonDescriptions && commonDescriptions.length >= sectionDescriptionTemplate.maxMultiplicity) {
|
||||
rejectedDmpDescriptionTemplates = commonDescriptions.map(x => x.dmpDescriptionTemplate);
|
||||
}
|
||||
}
|
||||
})
|
||||
return rejectedDmpDescriptionTemplates;
|
||||
} else{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
refreshData(): void {
|
||||
this.getItem(this.editorModel.id, (data: Description) => this.prepareForm(data));
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||
|
@ -165,6 +165,13 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.currentDescriptionTemplate), nameof<DescriptionTemplate>(x => x.version)].join('.'),
|
||||
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@ import { TranslateService } from "@ngx-translate/core";
|
|||
import { UUID } from "crypto";
|
||||
import { Observable } from "rxjs";
|
||||
import { map, takeUntil } from "rxjs/operators";
|
||||
import { DescriptionEditorResolver } from "../description-editor.resolver";
|
||||
import { nameof } from "ts-simple-nameof";
|
||||
import { Description } from "@app/core/model/description/description";
|
||||
import { IsActive } from "@app/core/common/enum/is-active.enum";
|
||||
|
||||
@Component({
|
||||
selector: 'prefill-description-component',
|
||||
|
@ -47,7 +51,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
|
|||
|
||||
this.dmp = data.dmp;
|
||||
this.dmpSectionId = data.dmpSectionId;
|
||||
this.availableDescriptionTemplates = this.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.dmpSectionId).map(x => x.currentDescriptionTemplate);
|
||||
this.availableDescriptionTemplates = this.dmp.dmpDescriptionTemplates.filter(x => x.sectionId == this.dmpSectionId && x.isActive == IsActive.Active).map(x => x.currentDescriptionTemplate);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -212,7 +216,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
|
|||
// }
|
||||
const formData = this.formService.getValue(this.prefillForm.value) as DescriptionProfilingRequest;
|
||||
|
||||
this.prefillingSourceService.generate(formData, DescriptionTemplateEditorResolver.lookupFields())
|
||||
this.prefillingSourceService.generate(formData, DescriptionEditorResolver.descriptionTemplateLookupFields(nameof<Description>(x => x.descriptionTemplate)))
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(description => {
|
||||
if (description) {
|
||||
this.closeDialog(description);
|
||||
|
|
|
@ -96,11 +96,17 @@
|
|||
</li>
|
||||
</ol>
|
||||
<ul *ngIf="item.id && section.hasTemplates && canEditSection(section.id) && !formGroup.disabled" class="add-description-option">
|
||||
<li>
|
||||
<li *ngIf="canAddDescription(section)">
|
||||
<a class="add-description-action" [routerLink]="['/descriptions/edit/' + item.id + '/' + section.id]">
|
||||
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="!canAddDescription(section)">
|
||||
<a [ngClass]="{'drag-handle-disabled': true}" class="add-description-action">
|
||||
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
||||
</a>
|
||||
<small class="text-danger">{{'DMP-EDITOR.DESCRIPTION-TEMPLATES-MAX-MULTIPLICITY'| translate}}</small>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
||||
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprint, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { Dmp, DmpPersist } from '@app/core/model/dmp/dmp';
|
||||
import { LanguageInfo } from '@app/core/model/language-info';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
|
@ -88,6 +88,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
|
||||
displayFn: (item: DmpBlueprint) => item.label,
|
||||
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' '+ item.version,
|
||||
titleFn: (item: DmpBlueprint) => item.label,
|
||||
valueAssign: (item: DmpBlueprint) => item.id,
|
||||
};
|
||||
|
@ -446,6 +447,32 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
});
|
||||
}
|
||||
|
||||
canAddDescription(section: DmpBlueprintDefinitionSection ): boolean{
|
||||
if(section.hasTemplates){
|
||||
if (section.descriptionTemplates?.length > 0){
|
||||
const descriptions = this.descriptionsInSection(section.id)
|
||||
|
||||
let multiplicityValidResults :boolean[] = [];
|
||||
section.descriptionTemplates.forEach(sectionDescriptionTemplate => {
|
||||
if (sectionDescriptionTemplate.maxMultiplicity != null){
|
||||
const count = descriptions.filter(x => x.dmpDescriptionTemplate.descriptionTemplateGroupId == sectionDescriptionTemplate.descriptionTemplateGroupId).length || 0;
|
||||
if (count >= sectionDescriptionTemplate.maxMultiplicity) multiplicityValidResults.push(false);
|
||||
else multiplicityValidResults.push(true);
|
||||
}else{
|
||||
multiplicityValidResults.push(true);
|
||||
}
|
||||
})
|
||||
|
||||
if(multiplicityValidResults.includes(true)) return true
|
||||
else return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Description Template
|
||||
|
|
|
@ -61,6 +61,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
|||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
|
||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.id)].join('.'),
|
||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||
|
||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
|
||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
|
||||
|
@ -104,6 +105,8 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
|||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
|
||||
(prefix ? prefix + '.' : '') + [nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</div>
|
||||
<div class="col-12 title-form">
|
||||
<mat-form-field class="w-100">
|
||||
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('blueprintId')" placeholder="{{'DMP-NEW-VERSION-DIALOG.FIELDS.BLUEPRINT-PLACEHOLDER' | translate}}" [configuration]="dmpBlueprintService.singleAutocompleteConfiguration">
|
||||
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('blueprintId')" placeholder="{{'DMP-NEW-VERSION-DIALOG.FIELDS.BLUEPRINT-PLACEHOLDER' | translate}}" [configuration]="singleAutocompleteBlueprintConfiguration">
|
||||
</app-single-auto-complete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
|
|
@ -6,10 +6,13 @@ import { DmpService } from '@app/core/services/dmp/dmp.service';
|
|||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
|
||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-new-version-dialog',
|
||||
|
@ -22,6 +25,16 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
|
|||
editorModel: DmpNewVersionDialogEditorModel;
|
||||
formGroup: UntypedFormGroup;
|
||||
|
||||
singleAutocompleteBlueprintConfiguration: SingleAutoCompleteConfiguration = {
|
||||
initialItems: (data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
getSelectedItem: (selectedItem: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
|
||||
displayFn: (item: DmpBlueprint) => item.label,
|
||||
subtitleFn: (item: DmpBlueprint) => this.language.instant('DMP-EDITOR.FIELDS.DMP-BLUEPRINT-VERSION') + ' '+ item.version,
|
||||
titleFn: (item: DmpBlueprint) => item.label,
|
||||
valueAssign: (item: DmpBlueprint) => item.id,
|
||||
};
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<NewVersionDmpDialogComponent>,
|
||||
private dmpService: DmpService,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<div class="container-fluid">
|
||||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">
|
||||
|
@ -41,3 +42,4 @@
|
|||
<div class="col-auto"><button mat-button color="primary" [disabled]="!isFormValid" (click)="send()" type="button">Save</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,31 @@
|
|||
<div class="profile">
|
||||
<div class="container-fluid">
|
||||
<div *ngIf="user | async as userProfile; else loading" class="user-profile">
|
||||
<div class="col user-profile-title">{{'USER-DIALOG.USER-PROFILE' | translate}}</div>
|
||||
<div class="row user-profile-title">
|
||||
<div class="col mb-2">
|
||||
{{'USER-DIALOG.USER-PROFILE' | translate}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="tenantFormGroup" class="col-auto mr-5">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Tenant</mat-label>
|
||||
<mat-select placeholder="Tenant" [formControl]="this.tenantFormGroup.get('tenantCode')">
|
||||
<ng-container *ngFor="let tenant of tenants | async">
|
||||
<mat-option [value]="tenant">{{ tenant }}</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12 col-lg-auto mt-1">
|
||||
<button mat-mini-fab (click)="switchTenant()">
|
||||
<mat-icon class="mat-mini-fab-icon">refresh</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row profile-content" [formGroup]="formGroup">
|
||||
<div class="col">
|
||||
<div class="row mb-4">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||
import { FormBuilder, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type';
|
||||
|
@ -22,12 +22,16 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati
|
|||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import * as moment from 'moment-timezone';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Observable, from, of } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { AddAccountDialogComponent } from './add-account/add-account-dialog.component';
|
||||
import { UserProfileEditorModel } from './user-profile-editor.model';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { PrincipalService } from '@app/core/services/http/principal.service';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-profile',
|
||||
|
@ -51,6 +55,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
errorMessages = [];
|
||||
nestedCount = [];
|
||||
nestedIndex = 0;
|
||||
tenants: Observable<Array<string>>;
|
||||
|
||||
organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterOrganisations.bind(this),
|
||||
|
@ -61,6 +66,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
};
|
||||
|
||||
formGroup: UntypedFormGroup;
|
||||
tenantFormGroup: UntypedFormGroup;
|
||||
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private route: ActivatedRoute,
|
||||
|
@ -75,7 +82,10 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
private dialog: MatDialog,
|
||||
public enumUtils: EnumUtils,
|
||||
private httpClient: HttpClient,
|
||||
private matomoService: MatomoService
|
||||
private matomoService: MatomoService,
|
||||
private formBuilder: UntypedFormBuilder,
|
||||
private keycloakService: KeycloakService,
|
||||
private principalService: PrincipalService
|
||||
) {
|
||||
super();
|
||||
this.languages = this.languageService.getAvailableLanguagesCodes();
|
||||
|
@ -100,6 +110,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.tenantFormGroup = this.formBuilder.group({
|
||||
tenantCode: [this.authService.selectedTenant(), [Validators.required]]
|
||||
});
|
||||
this.matomoService.trackPageView('User Profile');
|
||||
this.route.params
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
|
@ -149,6 +162,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } });
|
||||
// this.initializeDisabledFormGroup();
|
||||
|
||||
this.tenants = this.loadUserTenants();
|
||||
this.unlock();
|
||||
return result;
|
||||
}));
|
||||
|
@ -407,4 +422,29 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
}
|
||||
}
|
||||
|
||||
// Switch Tenant
|
||||
loadUserTenants(): Observable<Array<string>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.TenantHeaderInterceptor]
|
||||
};
|
||||
return this.principalService.myTenants({ params: params });
|
||||
}
|
||||
|
||||
switchTenant(): void {
|
||||
if (this.tenantFormGroup.valid === false) return;
|
||||
|
||||
const selectedTenant = this.tenantFormGroup.get('tenantCode').value;
|
||||
this.formSubmit(selectedTenant);
|
||||
this.loadUser();
|
||||
}
|
||||
|
||||
formSubmit(selectedTenant: string): void {
|
||||
this.authService.selectedTenant(selectedTenant);
|
||||
}
|
||||
|
||||
loadUser(): void {
|
||||
const returnUrl = '/profile';
|
||||
this.authService.prepareAuthRequest(from(this.keycloakService.getToken()), {}).pipe(takeUntil(this._destroyed)).subscribe(() => this.authService.onAuthenticateSuccess(returnUrl), (error) => this.authService.onAuthenticateError(error));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,10 @@
|
|||
},
|
||||
"CRITERIA": {
|
||||
"LIKE": "Search..."
|
||||
},
|
||||
"START-NEW-DMP-DIALOG": {
|
||||
"UPLOAD-FILE": "Upoad File",
|
||||
"REPLACE-FILE": "Replace File"
|
||||
}
|
||||
},
|
||||
"HYBRID-LISTING": {
|
||||
|
@ -1291,6 +1295,7 @@
|
|||
"LOCKED": "Locked",
|
||||
"DESCRIPTION": "Description",
|
||||
"NO-TEMPLATE-MESSAGE": "If you can't find a template or if you want to create a personalized template for your institution, research community or training needs, please contact us.",
|
||||
"DESCRIPTION-TEMPLATES-MAX-MULTIPLICITY": "Description Templates has reached the maximun multiplicity",
|
||||
"FIELDS": {
|
||||
"TITLE": "Title of Plan",
|
||||
"DESCRIPTION": "Description",
|
||||
|
@ -1304,7 +1309,8 @@
|
|||
"EMAIL": "Email",
|
||||
"USER": "User",
|
||||
"USER-ROLE": "Role",
|
||||
"SECTION": "Specific DMP Section"
|
||||
"SECTION": "Specific DMP Section",
|
||||
"DMP-BLUEPRINT-VERSION": "Version"
|
||||
},
|
||||
"ACTIONS": {
|
||||
"DISCARD": "Discard",
|
||||
|
|
Loading…
Reference in New Issue