From 18e98938d58d526a4a09c97ca51e00f66dcc621b Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Thu, 23 Jun 2022 15:32:05 +0300 Subject: [PATCH 1/2] WordBuilder.java: #7869 - In exported file fix hidden question title and a. /b. /c for empty answers. a. fix hidden question title when more than 1 multiplicity answers, b. fix hidden question title when no value in the last multiplicity answer, c. Do not show a. / b. / c.... for empty multiplicity answers, d. Do not show a. / b. / c.... when more than 1 multiplicity answers, but only one with value. --- .../utilities/documents/word/WordBuilder.java | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 6ffa49735..a3a47d869 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -285,33 +285,59 @@ public class WordBuilder { for (FieldSet compositeField: compositeFields) { if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) { char c = 'a'; + int multiplicityItems = 0; boolean hasMultiplicityItems = false; int paragraphPos = -1; + int paragraphPosInner = -1; if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) { XWPFParagraph paragraph = addParagraphContent("\t" + page + "." + section + "." + (compositeField.getOrdinal() +1) + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER6, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); paragraphPos = mainDocumentPart.getPosOfParagraph(paragraph); if(compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()){ - addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.HEADER6, numId); +// addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.HEADER6, numId); + XWPFParagraph paragraphInner = addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.TEXT, numId); + paragraphPosInner = mainDocumentPart.getPosOfParagraph(paragraphInner); hasMultiplicityItems = true; + multiplicityItems++; } } hasValue = createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService, hasMultiplicityItems); if(hasValue){ returnedValue = true; + } else if(paragraphPosInner > -1){ + mainDocumentPart.removeBodyElement(paragraphPosInner); + c--; + multiplicityItems--; } if (compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()) { List
list = compositeField.getMultiplicityItems().stream().sorted(Comparator.comparingInt(FieldSet::getOrdinal)).collect(Collectors.toList()); for (FieldSet multiplicityFieldset : list) { + paragraphPosInner = -1; if(!createListing){ c++; - addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.HEADER6, numId); +// addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.HEADER6, numId); + XWPFParagraph paragraphInner = addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.TEXT, numId); + paragraphPosInner = mainDocumentPart.getPosOfParagraph(paragraphInner); hasMultiplicityItems = true; + multiplicityItems++; } - hasValue = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService, hasMultiplicityItems); - if(hasValue){ +// hasValue = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService, hasMultiplicityItems); + boolean hasValueInner = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService, hasMultiplicityItems); +// if(hasValue){ + if(hasValueInner){ + hasValue = true; returnedValue = true; + } else if(paragraphPosInner > -1){ + mainDocumentPart.removeBodyElement(paragraphPosInner); + c--; + multiplicityItems--; + } + } + if(multiplicityItems == 1) { + String text = mainDocumentPart.getLastParagraph().getRuns().get(0).getText(0); + if(text.equals("a. ")) { + mainDocumentPart.getLastParagraph().removeRun(0); } } } @@ -422,6 +448,7 @@ public class WordBuilder { if(hasMultiplicityItems && format != null){ mainDocumentPart.getLastParagraph().createRun().setText(format); hasMultiplicityItems = false; + hasValue = true; } else{ XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId); @@ -461,6 +488,7 @@ public class WordBuilder { } public XWPFParagraph addParagraphContent(Object content, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId) { +// this.indent = 0; if (content != null) { if (content instanceof String && ((String)content).isEmpty()) { return null; From 304a6cfdb3743cf0e0587b1d92ecac21468a287a Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Thu, 23 Jun 2022 15:38:48 +0300 Subject: [PATCH 2/2] Backend: Fix a bug with compareTo of a field throwing an error because ordinal is not exists. FrontEnd: Initialize visibility rules for multiple fields coming from service according to their parents. --- .../user/components/datasetprofile/Field.java | 9 +- .../form-section-inner.component.html | 4 +- .../form-section/form-section.component.html | 8 +- .../form-section/form-section.component.ts | 302 +++++++++--------- .../visibility-rules.service.ts | 5 +- 5 files changed, 167 insertions(+), 161 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java index 4025f619c..8bd186cd4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java @@ -238,7 +238,14 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin @Override public int compareTo(Object o) { - return this.ordinal.compareTo(((Field) o).getOrdinal()); + Field comparedField = (Field) o; + if(this.ordinal != null) { + return this.ordinal.compareTo(comparedField.getOrdinal()); + } else if (comparedField.getOrdinal() != null) { + return comparedField.getOrdinal().compareTo(this.ordinal); + } else { + return 0; + } } @Override diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.html index 2d8594873..e271c4606 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.html @@ -20,8 +20,8 @@
- - {{compositeFieldFormGroup.get('multiplicity').value.placeholder}} diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html index 9a15c0141..58c95a8fb 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html @@ -32,8 +32,8 @@
- - {{compositeFieldFormGroup.get('multiplicity').value.placeholder}} @@ -105,8 +105,8 @@
- - {{fieldsetEntry.form.get('multiplicity').value.placeholder}} diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts index dfb4adefd..860a5676f 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts @@ -1,14 +1,24 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; -import { FormArray, FormGroup } from '@angular/forms'; -import { Rule } from '@app/core/model/dataset-profile-definition/rule'; -import { BaseComponent } from '@common/base/base.component'; -import { takeUntil } from 'rxjs/operators'; -import { DatasetDescriptionCompositeFieldEditorModel } from '../../dataset-description-form.model'; -import { ToCEntry, ToCEntryType } from '../../dataset-description.component'; -import { FormFocusService } from '../../form-focus/form-focus.service'; -import { LinkToScroll } from '../../tableOfContentsMaterial/table-of-contents'; -import { VisibilityRuleSource } from '../../visibility-rules/models/visibility-rule-source'; -import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges +} from '@angular/core'; +import {FormArray, FormGroup} from '@angular/forms'; +import {Rule} from '@app/core/model/dataset-profile-definition/rule'; +import {BaseComponent} from '@common/base/base.component'; +import {takeUntil} from 'rxjs/operators'; +import {DatasetDescriptionCompositeFieldEditorModel} from '../../dataset-description-form.model'; +import {ToCEntry, ToCEntryType} from '../../dataset-description.component'; +import {FormFocusService} from '../../form-focus/form-focus.service'; +import {LinkToScroll} from '../../tableOfContentsMaterial/table-of-contents'; +import {VisibilityRuleSource} from '../../visibility-rules/models/visibility-rule-source'; +import {VisibilityRulesService} from '../../visibility-rules/visibility-rules.service'; @Component({ @@ -47,7 +57,7 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha this.visibilityRulesService.getElementVisibilityMapObservable().pipe(takeUntil(this._destroyed)).subscribe(x => { this.changeDetector.markForCheck(); }); - } + } ngOnInit() { // if (this.section) { @@ -57,6 +67,7 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha if (this.tocentry) {//maybe not needed as well this.form = this.tocentry.form as FormGroup; } + this.initMultipleFieldsVisibility(); } ngOnChanges(changes: SimpleChanges) { @@ -78,6 +89,133 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha // this.visibilityRulesService.triggerVisibilityEvaluation(); // } + setMultipleFieldVisibility(parentCompositeField, compositeField: DatasetDescriptionCompositeFieldEditorModel, idMappings: { old: string, new: string }[]) { + // ** COMPOSITE FIELD IS SHOWN OR HIDDEN FROM ANOTHER ELEMENT + const compositeFieldVisibilityDependencies = this.visibilityRulesService.getVisibilityDependency(parentCompositeField); + if (compositeFieldVisibilityDependencies && compositeFieldVisibilityDependencies.length) { + + compositeFieldVisibilityDependencies.forEach(x => { + const visRule: Rule = { + targetField: compositeField.id, + sourceField: x.sourceControlId, + requiredValue: x.sourceControlValue, + type: '' + } + this.visibilityRulesService.addNewRule(visRule); + }); + } + + // console.log('idMappings ', idMappings); + parentCompositeField.fields.forEach(element => { + // console.log(this.visibilityRulesService.getVisibilityDependency(element.id)); + const dependency = this.visibilityRulesService.getVisibilityDependency(element.id); + if (dependency && dependency.length) { + // * INNER VISIBILITY DEPENDENCIES + // * IF INNER INPUT HIDES ANOTHER INNER INPUT + const innerDependency = parentCompositeField.fields.reduce((innerD, currentElement) => { + const innerDependecies = dependency.filter(d => d.sourceControlId === currentElement.id); + return [...innerD, ...innerDependecies]; + }, []) as VisibilityRuleSource[]; + if (innerDependency.length) { + //Build visibility source + const updatedRules = innerDependency.map(x => { + const newId = idMappings.find(y => y.old === x.sourceControlId); + return {...x, sourceControlId: newId.new}; + }); + // const visRule: VisibilityRule = { + // targetControlId: idMappings.find(x => x.old === element.id).new, + // sourceVisibilityRules: updatedRules + // } + + + const rules = updatedRules.map(x => { + return { + requiredValue: x.sourceControlValue, + sourceField: x.sourceControlId, + targetField: idMappings.find(l => l.old === element.id).new, + type: '' + } as Rule; + }); + + rules.forEach(rule => { + this.visibilityRulesService.addNewRule(rule); + }) + + // this.visibilityRulesService.appendVisibilityRule(visRule); + } + + } + + + // * OUTER DEPENDENCIES + + // * IF INNER INPUT HIDES OUTER INPUTS + const innerIds = idMappings.map(x => x.old) as string[]; + + const outerTargets = this.visibilityRulesService.getVisibilityTargets(element.id).filter(x => !innerIds.includes(x)); + + outerTargets.forEach(target => { + + const outerRules = (this.visibilityRulesService.getVisibilityDependency(target) as VisibilityRuleSource[]).filter(x => x.sourceControlId === element.id); + const updatedRules = outerRules.map(x => { + console.log(idMappings, element); + return {...x, sourceControlId: idMappings.find(y => y.old === element.id).new}; + }); + + // const visRule: VisibilityRule = { + // targetControlId: target, + // sourceVisibilityRules: updatedRules + // } + + + const rules = updatedRules.map(x => { + return { + requiredValue: x.sourceControlValue, + sourceField: x.sourceControlId, + targetField: target, + type: '' + } as Rule; + }) + rules.forEach(rule => { + this.visibilityRulesService.addNewRule(rule); + }) + // this.visibilityRulesService.appendVisibilityRule(visRule); + }); + // * IF INNER INPUT IS HIDDEN BY OUTER INPUT + if (dependency && dependency.length) { + const fieldsThatHideInnerElement = dependency.filter(x => !innerIds.includes(x.sourceControlId)); + if (fieldsThatHideInnerElement.length) { + fieldsThatHideInnerElement.forEach(x => { + const visRule: Rule = { + targetField: idMappings.find(l => l.old === element.id).new, + sourceField: x.sourceControlId, + requiredValue: x.sourceControlValue, + type: '' + } + const shouldBeVisibile = this.visibilityRulesService.checkTargetVisibilityProvidedBySource(x.sourceControlId, element.id); + this.visibilityRulesService.addNewRule(visRule, shouldBeVisibile); + }); + } + } + // console.log(`for ${element.id} targets are`, outerTargets); + }); + } + + initMultipleFieldsVisibility() { + (this.form.get('compositeFields') as FormArray).controls.forEach(control => { + let parentCompositeField = (control as FormGroup).getRawValue(); + if (parentCompositeField.multiplicityItems && parentCompositeField.multiplicityItems.length > 0) { + parentCompositeField.multiplicityItems.forEach(compositeField => { + let idMappings: { old: string, new: string }[] = [{old: parentCompositeField.id, new: compositeField.id}]; + parentCompositeField.fields.forEach((field, index) => { + idMappings.push({ old: field.id, new: compositeField.fields[index].id }); + }); + this.setMultipleFieldVisibility(parentCompositeField, compositeField, idMappings); + }) + } + }); + } + addMultipleField(fieldsetIndex: number) { const compositeFieldToBeCloned = (this.form.get('compositeFields').get('' + fieldsetIndex) as FormGroup).getRawValue(); const multiplicityItemsArray = ((this.form.get('compositeFields').get('' + fieldsetIndex).get('multiplicityItems'))); @@ -93,144 +231,7 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha const idMappings = [] as { old: string, new: string }[]; const compositeField: DatasetDescriptionCompositeFieldEditorModel = new DatasetDescriptionCompositeFieldEditorModel().cloneForMultiplicity(compositeFieldToBeCloned, ordinal, idMappings); - - - - // ** COMPOSITE FIELD IS SHOWN OR HIDDEN FROM ANOTHER ELEMENT - const compositeFieldVisibilityDependencies = this.visibilityRulesService.getVisibilityDependency(compositeFieldToBeCloned); - if (compositeFieldVisibilityDependencies && compositeFieldVisibilityDependencies.length) { - - compositeFieldVisibilityDependencies.forEach(x => { - const visRule: Rule = { - targetField: compositeField.id, - sourceField: x.sourceControlId, - requiredValue: x.sourceControlValue, - type: '' - } - this.visibilityRulesService.addNewRule(visRule); - }); - } - - // console.log('idMappings ', idMappings); - compositeFieldToBeCloned.fields.forEach(element => { - // console.log(this.visibilityRulesService.getVisibilityDependency(element.id)); - const dependency = this.visibilityRulesService.getVisibilityDependency(element.id); - - - - try { - - if (dependency && dependency.length) { - - // * INNER VISIBILITY DEPENDENCIES - // * IF INNER INPUT HIDES ANOTHER INNER INPUT - - const innerDependency = compositeFieldToBeCloned.fields.reduce((innerD, currentElement) => { - - const innerDependecies = dependency.filter(d => d.sourceControlId === currentElement.id); - return [...innerD, ...innerDependecies]; - }, []) as VisibilityRuleSource[]; - - if (innerDependency.length) { - //Build visibility source - const updatedRules = innerDependency.map(x => { - const newId = idMappings.find(y => y.old === x.sourceControlId); - return { ...x, sourceControlId: newId.new }; - }); - // const visRule: VisibilityRule = { - // targetControlId: idMappings.find(x => x.old === element.id).new, - // sourceVisibilityRules: updatedRules - // } - - - const rules = updatedRules.map(x => { - return { - requiredValue: x.sourceControlValue, - sourceField: x.sourceControlId, - targetField: idMappings.find(l => l.old === element.id).new, - type: '' - } as Rule; - }); - - rules.forEach(rule => { - this.visibilityRulesService.addNewRule(rule); - }) - - // this.visibilityRulesService.appendVisibilityRule(visRule); - } - - } - - - // * OUTER DEPENDENCIES - - // * IF INNER INPUT HIDES OUTER INPUTS - const innerIds = idMappings.map(x => x.old) as string[]; - - const outerTargets = this.visibilityRulesService.getVisibilityTargets(element.id).filter(x => !innerIds.includes(x)); - - outerTargets.forEach(target => { - - const outerRules = (this.visibilityRulesService.getVisibilityDependency(target) as VisibilityRuleSource[]).filter(x => x.sourceControlId === element.id); - const updatedRules = outerRules.map(x => { - return { ...x, sourceControlId: idMappings.find(y => y.old === element.id).new }; - }); - - // const visRule: VisibilityRule = { - // targetControlId: target, - // sourceVisibilityRules: updatedRules - // } - - - const rules = updatedRules.map(x => { - return { - requiredValue: x.sourceControlValue, - sourceField: x.sourceControlId, - targetField: target, - type: '' - } as Rule; - }) - - rules.forEach(rule => { - this.visibilityRulesService.addNewRule(rule); - }) - - // this.visibilityRulesService.appendVisibilityRule(visRule); - - }); - - - - - - // * IF INNER INPUT IS HIDDEN BY OUTER INPUT - - if (dependency && dependency.length) { - const fieldsThatHideInnerElement = dependency.filter(x => !innerIds.includes(x.sourceControlId)); - - if (fieldsThatHideInnerElement.length) { - fieldsThatHideInnerElement.forEach(x => { - const visRule: Rule = { - targetField: idMappings.find(l => l.old === element.id).new, - sourceField: x.sourceControlId, - requiredValue: x.sourceControlValue, - type: '' - } - const shouldBeVisibile = this.visibilityRulesService.checkTargetVisibilityProvidedBySource(x.sourceControlId, element.id); - this.visibilityRulesService.addNewRule(visRule, shouldBeVisibile); - }); - } - } - - - // console.log(`for ${element.id} targets are`, outerTargets); - } catch { - console.log('error'); - } - - }); - // console.log(this.visibilityRulesService); - // console.log(this.visibilityRulesService.getVisibilityDependency()); + this.setMultipleFieldVisibility(compositeFieldToBeCloned, compositeField, idMappings); multiplicityItemsArray.push(compositeField.buildForm()); } @@ -264,7 +265,6 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha // } - onAskedToScroll(id: string) { this.panelExpanded = true; this.askedToScroll.emit(id); diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts index 8265bbc7c..40f9bca47 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts @@ -46,7 +46,6 @@ export class VisibilityRulesService { } public updateValueAndVisibility(id: string, value: any) { - console.log('updateValueAndVisibility'); const visibilityRules = this.visibilityRuleContext.rules.filter(item => item.sourceVisibilityRules.filter(source => source.sourceControlId === id).length > 0); if (visibilityRules.length > 0) { visibilityRules.forEach(item => this.evaluateVisibility(item, value, id)); @@ -347,7 +346,7 @@ export class VisibilityRulesService { public addNewRule(rule: Rule, currentVisibility = this.DEFAULTVISIBILITY): void { const targetId = rule.targetField; const sourceId = rule.sourceField; - + console.log(rule); this.visibilityRuleContext.addToVisibilityRulesContext(rule); @@ -368,7 +367,7 @@ export class VisibilityRulesService { /** - * Check what sourceId hides or shows the target field + * Check what sourceId hides or shows the target field * return true if no rule found */ public checkTargetVisibilityProvidedBySource(sourceId: string, targetId: string): boolean {