From 87dabdc9a5115c55cdb2b6e4e9d9f6f826b8cc2b Mon Sep 17 00:00:00 2001 From: "d.svitak" Date: Fri, 13 Feb 2026 08:57:21 +0100 Subject: [PATCH 1/2] added missing flowToNextPage flag to Area, included into import/export, updated mapping logic --- .../example/common/mapping/AreasExport.groovy | 2 + .../example/common/mapping/AreasImport.groovy | 12 ++-- .../migration/example/example/Import.groovy | 5 +- .../src/test/groovy/AreasExportTest.groovy | 22 +++---- .../src/test/groovy/AreasImportTest.groovy | 53 ++++++++++------- .../api/dto/migrationmodel/Mapping.kt | 5 +- .../builder/documentcontent/AreaBuilder.kt | 9 +++ .../migrationmodel/documentcontent/Area.kt | 6 +- .../api/repository/MappingRepository.kt | 2 +- .../migrationmodel/DocumentContentEntity.kt | 2 +- .../migrationmodel/MappingEntity.kt | 57 ++++++++++--------- .../DesignerDocumentObjectBuilder.kt | 1 + .../migrationmodel/MappingEntityTest.kt | 54 +++++++++++++----- 13 files changed, 146 insertions(+), 84 deletions(-) diff --git a/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasExport.groovy b/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasExport.groovy index 3a29b6e5..ccbca381 100644 --- a/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasExport.groovy +++ b/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasExport.groovy @@ -43,6 +43,7 @@ static void run(Migration migration, Path path) { Mapping.displayHeader("pageId", false), Mapping.displayHeader("pageName", true), Mapping.displayHeader("interactiveFlowName", false), + Mapping.displayHeader("flowToNextPage", false), Mapping.displayHeader("x", true), Mapping.displayHeader("y", true), Mapping.displayHeader("width", true), @@ -85,6 +86,7 @@ static String buildArea(Migration migration, Number idx, Area area, DocumentObje builder.append(Csv.serialize(page.id) + ",") builder.append(Csv.serialize(page.name) + ",") builder.append(Csv.serialize(area.interactiveFlowName) + ",") + builder.append(Csv.serialize(area.flowToNextPage) + ",") builder.append(Csv.serialize(area.position.x) + ",") builder.append(Csv.serialize(area.position.y) + ",") builder.append(Csv.serialize(area.position.width) + ",") diff --git a/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasImport.groovy b/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasImport.groovy index bf34cc15..e756eca9 100644 --- a/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasImport.groovy +++ b/migration-examples/src/main/groovy/com/quadient/migration/example/common/mapping/AreasImport.groovy @@ -27,7 +27,6 @@ static void run(Migration migration, Path path) { def columnNames = Csv.parseColumnNames(fileLines.removeFirst()).collect { Mapping.normalizeHeader(it) } DocumentObject currentPage = null - def areas = null MappingItem.Area mapping = null int areaIndex = 0 for (line in fileLines) { @@ -37,7 +36,8 @@ static void run(Migration migration, Path path) { if (currentPage?.id != pageId) { if (currentPage != null) { - migration.mappingRepository.upsert(pageId, mapping) + migration.mappingRepository.upsert(currentPage.id, mapping) + migration.mappingRepository.applyAreaMapping(currentPage.id) } def pageModel = migration.documentObjectRepository.find(pageId) @@ -45,16 +45,16 @@ static void run(Migration migration, Path path) { throw new IllegalStateException("Page '${pageId}' not found.") } - areas = pageModel.content.findAll { it instanceof Area } as List mapping = migration.mappingRepository.getAreaMapping(pageId) currentPage = pageModel areaIndex = 0 } def interactiveFlowName = Csv.deserialize(values.get("interactiveFlowName"), String.class) - if (interactiveFlowName != mapping.areas.get(areaIndex) && areas[areaIndex].interactiveFlowName != interactiveFlowName) { - mapping.areas[areaIndex] = interactiveFlowName - } + mapping.areas[areaIndex] = interactiveFlowName + + def flowToNextPage = Csv.deserialize(values.get("flowToNextPage"), Boolean.class) + mapping.flowToNextPage[areaIndex] = flowToNextPage ?: false areaIndex++ } diff --git a/migration-examples/src/main/groovy/com/quadient/migration/example/example/Import.groovy b/migration-examples/src/main/groovy/com/quadient/migration/example/example/Import.groovy index f6a69244..691a857c 100644 --- a/migration-examples/src/main/groovy/com/quadient/migration/example/example/Import.groovy +++ b/migration-examples/src/main/groovy/com/quadient/migration/example/example/Import.groovy @@ -403,8 +403,9 @@ def page = new DocumentObjectBuilder("page1", DocumentObjectType.Page) it.width(contentWidth) it.height(Size.ofCentimeters(2)) } - .documentObjectRef(signature.id) - .attachmentRef(exampleAttachment.id) + .documentObjectRef(signature.id) + .attachmentRef(exampleAttachment.id) + .flowToNextPage(true) } .variableStructureRef(variableStructure.id) .build() diff --git a/migration-examples/src/test/groovy/AreasExportTest.groovy b/migration-examples/src/test/groovy/AreasExportTest.groovy index 769a8b8c..a769e685 100644 --- a/migration-examples/src/test/groovy/AreasExportTest.groovy +++ b/migration-examples/src/test/groovy/AreasExportTest.groovy @@ -31,29 +31,29 @@ class AreasExportTest { @Test void export() { Path mappingFile = Paths.get(dir.path, "testProject.csv") - when(migration.mappingRepository.getAreaMapping(any())).thenReturn(new MappingItem.Area(null, [:])) + when(migration.mappingRepository.getAreaMapping(any())).thenReturn(new MappingItem.Area(null, [:], [:])) when((migration.documentObjectRepository as DocumentObjectRepository).list(any())).thenReturn([ new DocumentObject("empty tmpl", null, [], new CustomFieldMap([:]), DocumentObjectType.Template, [], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), - new DocumentObject("unreferenced page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), + new DocumentObject("unreferenced page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow", true)], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), new DocumentObject("full tmpl", null, [], new CustomFieldMap([:]), DocumentObjectType.Template, [new DocumentObjectRef("full page")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), - new DocumentObject("full page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow2"), createArea("test flow3"), createArea(null), createArea("test flow5")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), + new DocumentObject("full page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow2"), createArea("test flow3", true), createArea(null), createArea("test flow5")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null), ]) AreasExport.run(migration, mappingFile) def expected = """\ - templateId (read-only),templateName (read-only),pageId,pageName (read-only),interactiveFlowName,x (read-only),y (read-only),width (read-only),height (read-only),contentPreview (read-only) - full tmpl,,full page,,test flow2,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,test flow3,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,test flow5,0.0mm,0.0mm,0.0mm,0.0mm, - ,,unreferenced page,,test flow,0.0mm,0.0mm,0.0mm,0.0mm, + templateId (read-only),templateName (read-only),pageId,pageName (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),contentPreview (read-only) + full tmpl,,full page,,test flow2,false,0.0mm,0.0mm,0.0mm,0.0mm, + full tmpl,,full page,,test flow3,true,0.0mm,0.0mm,0.0mm,0.0mm, + full tmpl,,full page,,,false,0.0mm,0.0mm,0.0mm,0.0mm, + full tmpl,,full page,,test flow5,false,0.0mm,0.0mm,0.0mm,0.0mm, + ,,unreferenced page,,test flow,true,0.0mm,0.0mm,0.0mm,0.0mm, """.stripIndent() Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n")) } - static Area createArea(String flowName) { - return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName) + static Area createArea(String flowName, Boolean flowToNextPage = false) { + return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName, flowToNextPage) } static SkipOptions emptySkipOptions() { diff --git a/migration-examples/src/test/groovy/AreasImportTest.groovy b/migration-examples/src/test/groovy/AreasImportTest.groovy index 7579b46e..575bd48c 100644 --- a/migration-examples/src/test/groovy/AreasImportTest.groovy +++ b/migration-examples/src/test/groovy/AreasImportTest.groovy @@ -12,14 +12,12 @@ import org.junit.jupiter.api.io.TempDir import java.nio.file.Path import java.nio.file.Paths -import static org.mockito.ArgumentMatchers.any import static org.mockito.Mockito.verify import static org.mockito.Mockito.when -import static org.mockito.Mockito.times class AreasImportTest { @TempDir - java.io.File dir + File dir Migration migration @@ -31,33 +29,48 @@ class AreasImportTest { @Test void importTest() { Path mappingFile = Paths.get(dir.path, "testProject.csv") - when(migration.mappingRepository.getAreaMapping(any())).thenReturn(new MappingItem.Area(null, [:])) - givenPageExists("full page", ["test flow2", "test flow3", null, "test flow5"]) - givenPageExists("unreferenced page", ["test flow"]) + + when(migration.mappingRepository.getAreaMapping("page1")).thenReturn(new MappingItem.Area(null, [:], [:])) + when(migration.mappingRepository.getAreaMapping("page2")).thenReturn(new MappingItem.Area(null, [:], [:])) + when(migration.mappingRepository.getAreaMapping("page3")).thenReturn(new MappingItem.Area(null, [:], [:])) + + givenPageExists("page1", ["flow1", "flow2", "flow3"], [false, false, false]) + givenPageExists("page2", ["flowA", "flowB"], [false, false]) + givenPageExists("page3", [null, "beta", null, "delta"]) + def input = """\ - templateId,templateName,pageId,pageName,interactiveFlowName,x,y,width,height,contentPreview - ,,unreferenced page,,test flow,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,test flow2,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,test flow3,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,new flow name,0.0mm,0.0mm,0.0mm,0.0mm, - full tmpl,,full page,,new test flow5,0.0mm,0.0mm,0.0mm,0.0mm, + templateId,templateName,pageId,pageName,interactiveFlowName,flowToNextPage,x,y,width,height,contentPreview + ,,page1,,flow1,false,0.0mm,0.0mm,0.0mm,0.0mm, + ,,page1,,new flow2,false,0.0mm,0.0mm,0.0mm,0.0mm, + ,,page1,,flow3,true,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl2,,page2,,flowA,true,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl2,,page2,,modified flowB,false,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl3,,page3,,new alpha,false,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl3,,page3,,beta,true,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl3,,page3,,new gamma,false,0.0mm,0.0mm,0.0mm,0.0mm, + tmpl3,,page3,,modified delta,true,0.0mm,0.0mm,0.0mm,0.0mm, """.stripIndent() mappingFile.toFile().write(input) AreasImport.run(migration, mappingFile) - verify(migration.mappingRepository, times(2)) - .upsert("full page", new MappingItem.Area(null, [2: "new flow name", 3: "new test flow5"])) - verify(migration.mappingRepository).applyAreaMapping("full page") + verify(migration.mappingRepository).upsert("page1", new MappingItem.Area(null, [0: "flow1", 1: "new flow2", 2: "flow3"], [0: false, 1: false, 2: true])) + verify(migration.mappingRepository).applyAreaMapping("page1") + verify(migration.mappingRepository).upsert("page2", new MappingItem.Area(null, [0: "flowA", 1: "modified flowB"], [0: true, 1: false])) + verify(migration.mappingRepository).applyAreaMapping("page2") + verify(migration.mappingRepository).upsert("page3", new MappingItem.Area(null, [0: "new alpha", 1: "beta", 2: "new gamma", 3: "modified delta"], [0: false, 1: true, 2: false, 3: true])) + verify(migration.mappingRepository).applyAreaMapping("page3") } - static Area createArea(String flowName) { - return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName) + static Area createArea(String flowName, boolean flowToNextPage) { + return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName, flowToNextPage) } - void givenPageExists(String pageId, List flowNames) { - def content = flowNames.collect { flowName -> createArea(flowName) } + void givenPageExists(String pageId, List flowNames, List flowToNextPageValues = null) { + def values = flowToNextPageValues ?: flowNames.collect { false } + def content = [flowNames, values].transpose() + .collect { String flowName, Boolean flowToNextPage -> createArea(flowName, flowToNextPage) } when(migration.documentObjectRepository.find(pageId)) - .thenReturn(new DocumentObject(pageId, null, [], new CustomFieldMap([:]), DocumentObjectType.Page, content, false, null, null, null, null, null, null, null, [:], new SkipOptions(false, null, null), null)) + .thenReturn(new DocumentObject(pageId, null, [], new CustomFieldMap([:]), DocumentObjectType.Page, content, false, null, null, null, null, null, null, null, [:], new SkipOptions(false, null, null), null)) } } \ No newline at end of file diff --git a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/Mapping.kt b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/Mapping.kt index cac9928c..ca3e9538 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/Mapping.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/Mapping.kt @@ -22,6 +22,7 @@ sealed class MappingItem { data class Area( override var name: String?, var areas: MutableMap, + var flowToNextPage: MutableMap = mutableMapOf(), ) : MappingItem() data class Image( @@ -102,7 +103,9 @@ sealed class MappingItem { ) } - is MappingItem.Area -> MappingItemEntity.Area( name = this.name, areas = this.areas) + is MappingItem.Area -> MappingItemEntity.Area( + name = this.name, areas = this.areas, flowToNextPage = this.flowToNextPage + ) is MappingItem.Image -> { MappingItemEntity.Image( diff --git a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/builder/documentcontent/AreaBuilder.kt b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/builder/documentcontent/AreaBuilder.kt index e959e090..42d7471a 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/builder/documentcontent/AreaBuilder.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/builder/documentcontent/AreaBuilder.kt @@ -10,6 +10,7 @@ class AreaBuilder : DocumentContentBuilderBase { override val content = mutableListOf() private var position: Position? = null private var interactiveFlowName: String? = null + private var flowToNextPage: Boolean = false /** * Sets the position of the flow area. @@ -36,6 +37,13 @@ class AreaBuilder : DocumentContentBuilderBase { */ fun interactiveFlowName(interactiveFlowName: String) = apply { this.interactiveFlowName = interactiveFlowName } + /** + * Set whether the flow area should flow to the next page. + * @param flowToNextPage Whether the flow area should flow to the next page. Default is false. + * @return The [AreaBuilder] instance for method chaining. + */ + fun flowToNextPage(flowToNextPage: Boolean) = apply { this.flowToNextPage = flowToNextPage } + /** * Builds the [Area] instance. * @return The constructed [Area] instance. @@ -45,6 +53,7 @@ class AreaBuilder : DocumentContentBuilderBase { content = content, position = position, interactiveFlowName = interactiveFlowName, + flowToNextPage = flowToNextPage, ) } } \ No newline at end of file diff --git a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/documentcontent/Area.kt b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/documentcontent/Area.kt index 72305db8..180e2d10 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/documentcontent/Area.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/api/dto/migrationmodel/documentcontent/Area.kt @@ -3,7 +3,7 @@ package com.quadient.migration.api.dto.migrationmodel import com.quadient.migration.persistence.migrationmodel.AreaEntity import com.quadient.migration.shared.Position -data class Area(var content: List, var position: Position?, var interactiveFlowName: String?) : +data class Area(var content: List, var position: Position?, var interactiveFlowName: String?, var flowToNextPage: Boolean = false) : DocumentContent, RefValidatable { override fun collectRefs(): List { return content.flatMap { @@ -16,9 +16,9 @@ data class Area(var content: List, var position: Position?, var companion object { fun fromDb(entity: AreaEntity): Area = Area( - entity.content.map { DocumentContent.fromDbContent(it) }, entity.position, entity.interactiveFlowName + entity.content.map { DocumentContent.fromDbContent(it) }, entity.position, entity.interactiveFlowName, entity.flowToNextPage ) } - fun toDb() = AreaEntity(content.toDb(), position, interactiveFlowName) + fun toDb() = AreaEntity(content.toDb(), position, interactiveFlowName, flowToNextPage) } \ No newline at end of file diff --git a/migration-library/src/main/kotlin/com/quadient/migration/api/repository/MappingRepository.kt b/migration-library/src/main/kotlin/com/quadient/migration/api/repository/MappingRepository.kt index e171dfdd..1cca2ad4 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/api/repository/MappingRepository.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/api/repository/MappingRepository.kt @@ -68,7 +68,7 @@ class MappingRepository( fun getAreaMapping(id: String): MappingItem.Area { return (internalRepository.find(id) ?: MappingItemEntity.Area( - name = null, areas = mutableMapOf() + name = null, areas = mutableMapOf(), flowToNextPage = mutableMapOf() )).toDto() as MappingItem.Area } diff --git a/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/DocumentContentEntity.kt b/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/DocumentContentEntity.kt index 05dcc2b3..4c9692f3 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/DocumentContentEntity.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/DocumentContentEntity.kt @@ -45,5 +45,5 @@ data class ParagraphEntity( @Serializable data class AreaEntity( - val content: List, val position: Position?, val interactiveFlowName: String? + val content: List, val position: Position?, val interactiveFlowName: String?, val flowToNextPage: Boolean = false ) : DocumentContentEntity diff --git a/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntity.kt b/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntity.kt index 222805d8..88199617 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntity.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntity.kt @@ -10,14 +10,14 @@ import org.jetbrains.exposed.v1.core.dao.id.CompositeID import org.jetbrains.exposed.v1.core.dao.id.EntityID import org.jetbrains.exposed.v1.dao.CompositeEntity import org.jetbrains.exposed.v1.dao.CompositeEntityClass -import com.quadient.migration.api.dto.migrationmodel.DocumentObject as DocumentObjectDto -import com.quadient.migration.api.dto.migrationmodel.Image as ImageDto -import com.quadient.migration.api.dto.migrationmodel.Attachment as AttachmentDto -import com.quadient.migration.api.dto.migrationmodel.ParagraphStyle as ParagraphStyleDto -import com.quadient.migration.api.dto.migrationmodel.TextStyle as TextStyleDto -import com.quadient.migration.api.dto.migrationmodel.Variable as VariableDto -import com.quadient.migration.api.dto.migrationmodel.VariableStructure as VariableStructureDto -import com.quadient.migration.api.dto.migrationmodel.Area as AreaDto +import com.quadient.migration.api.dto.migrationmodel.DocumentObject as DocumentObjectModel +import com.quadient.migration.api.dto.migrationmodel.Image as ImageModel +import com.quadient.migration.api.dto.migrationmodel.Attachment as AttachmentModel +import com.quadient.migration.api.dto.migrationmodel.ParagraphStyle as ParagraphStyleModel +import com.quadient.migration.api.dto.migrationmodel.TextStyle as TextStyleModel +import com.quadient.migration.api.dto.migrationmodel.Variable as VariableModel +import com.quadient.migration.api.dto.migrationmodel.VariableStructure as VariableStructureModel +import com.quadient.migration.api.dto.migrationmodel.Area as AreaModel class MappingEntity(id: EntityID) : CompositeEntity(id) { companion object : CompositeEntityClass(MappingTable) @@ -49,7 +49,7 @@ sealed class MappingItemEntity { var skip: SkipOptions? = null, ) : MappingItemEntity() { - fun apply(item: DocumentObjectDto): DocumentObjectDto { + fun apply(item: DocumentObjectModel): DocumentObjectModel { return item.copy( name = name, internal = internal ?: false, @@ -64,26 +64,31 @@ sealed class MappingItemEntity { @Serializable data class Area( - override val name: String?, val areas: MutableMap + override val name: String?, + val areas: MutableMap, + val flowToNextPage: MutableMap = mutableMapOf() ) : MappingItemEntity() { - fun apply(item: DocumentObjectDto): DocumentObjectDto { - if (areas.isEmpty()) { + fun apply(item: DocumentObjectModel): DocumentObjectModel { + if (areas.isEmpty() && flowToNextPage.isEmpty()) { return item } - val objectAreas = item.content.filter { it is AreaDto } - - if (objectAreas.size == areas.size) { - for ((idx, obj) in objectAreas.withIndex()) { - (obj as AreaDto).interactiveFlowName = areas[idx] + var areaIndex = 0 + val updatedContent = item.content.map { contentItem -> + if (contentItem is AreaModel) { + val idx = areaIndex++ + contentItem.copy( + interactiveFlowName = if (areas.containsKey(idx)) areas[idx] else contentItem.interactiveFlowName, + flowToNextPage = if (flowToNextPage.containsKey(idx)) (flowToNextPage[idx] ?: false) else false + ) + } else { + contentItem } } - - return item.copy(content = item.content) + return item.copy(content = updatedContent) } } - @Serializable data class Image( override val name: String?, @@ -94,7 +99,7 @@ sealed class MappingItemEntity { val alternateText: String? = null, val targetAttachmentId: String? = null, ) : MappingItemEntity() { - fun apply(item: ImageDto): ImageDto { + fun apply(item: ImageModel): ImageModel { return item.copy( name = name, targetFolder = targetFolder, @@ -116,7 +121,7 @@ sealed class MappingItemEntity { var skip: SkipOptions? = null, val targetImageId: String? = null, ) : MappingItemEntity() { - fun apply(item: AttachmentDto): AttachmentDto { + fun apply(item: AttachmentModel): AttachmentModel { return item.copy( name = name, targetFolder = targetFolder, @@ -151,7 +156,7 @@ sealed class MappingItemEntity { var pdfTaggingRule: ParagraphPdfTaggingRule? ) : Definition - fun apply(item: ParagraphStyleDto): ParagraphStyleDto { + fun apply(item: ParagraphStyleModel): ParagraphStyleModel { return when (definition) { is Ref -> { item.copy( @@ -220,7 +225,7 @@ sealed class MappingItemEntity { override val name: String?, val dataType: DataType?, ) : MappingItemEntity() { - fun apply(variable: VariableDto): VariableDto { + fun apply(variable: VariableModel): VariableModel { return variable.copy( name = name, dataType = dataType ?: variable.dataType, ) @@ -233,7 +238,7 @@ sealed class MappingItemEntity { val mappings: MutableMap?, val languageVariable: VariableEntityRef?, ) : MappingItemEntity() { - fun apply(item: VariableStructureDto): VariableStructureDto { + fun apply(item: VariableStructureModel): VariableStructureModel { return item.copy( name = name, structure = mappings ?: mutableMapOf(), @@ -263,7 +268,7 @@ sealed class MappingItemEntity { var interspacing: Size? ) : Definition - fun apply(item: TextStyleDto): TextStyleDto { + fun apply(item: TextStyleModel): TextStyleModel { return when (definition) { is Ref -> { item.copy( diff --git a/migration-library/src/main/kotlin/com/quadient/migration/service/inspirebuilder/DesignerDocumentObjectBuilder.kt b/migration-library/src/main/kotlin/com/quadient/migration/service/inspirebuilder/DesignerDocumentObjectBuilder.kt index 3d55309f..1ec998f5 100644 --- a/migration-library/src/main/kotlin/com/quadient/migration/service/inspirebuilder/DesignerDocumentObjectBuilder.kt +++ b/migration-library/src/main/kotlin/com/quadient/migration/service/inspirebuilder/DesignerDocumentObjectBuilder.kt @@ -349,6 +349,7 @@ class DesignerDocumentObjectBuilder( page.addFlowArea().setPosX(position.x.toMeters()).setPosY(position.y.toMeters()) .setWidth(position.width.toMeters()).setHeight(position.height.toMeters()).setFlow(sectionAreaFlow) + .setFlowToNextPage(areaModel.flowToNextPage) } } diff --git a/migration-library/src/test/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntityTest.kt b/migration-library/src/test/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntityTest.kt index 2a7f30ba..be4c5bed 100644 --- a/migration-library/src/test/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntityTest.kt +++ b/migration-library/src/test/kotlin/com/quadient/migration/persistence/migrationmodel/MappingEntityTest.kt @@ -1,15 +1,13 @@ package com.quadient.migration.persistence.migrationmodel import com.quadient.migration.api.dto.migrationmodel.Area -import com.quadient.migration.api.dto.migrationmodel.DocumentContent -import com.quadient.migration.api.dto.migrationmodel.DocumentObject -import com.quadient.migration.api.dto.migrationmodel.Image import com.quadient.migration.api.dto.migrationmodel.ParagraphStyleDefinition import com.quadient.migration.api.dto.migrationmodel.ParagraphStyleRef import com.quadient.migration.api.dto.migrationmodel.StringValue import com.quadient.migration.api.dto.migrationmodel.TextStyleDefinition import com.quadient.migration.api.dto.migrationmodel.TextStyleRef import com.quadient.migration.api.dto.migrationmodel.VariableStructureRef +import com.quadient.migration.api.dto.migrationmodel.builder.documentcontent.AreaBuilder import com.quadient.migration.shared.Alignment import com.quadient.migration.shared.Color import com.quadient.migration.shared.DataType @@ -117,15 +115,17 @@ class MappingEntityTest { @Test fun `maps interactiveFlowName`() { val mapping = MappingItemEntity.Area( - name = null, areas = mutableMapOf(0 to "AddedFirstAreaName", 1 to null, 2 to "AddedLastAreaName") + name = null, + areas = mutableMapOf(0 to "AddedFirstAreaName", 1 to null, 2 to "AddedLastAreaName"), + flowToNextPage = mutableMapOf(0 to false, 1 to false, 2 to true) ) val dto = aBlockDto( "doc1", content = listOf( - Area(emptyList(), null, null), + Area(emptyList(), null, null, true), aParagraph(content = listOf(aText(content = listOf(StringValue("Default paragraph content"))))), - Area(emptyList(), null, "MiddleAreaFlow"), + Area(emptyList(), null, "MiddleAreaFlow", false), aParagraph(content = listOf(aText(content = listOf(StringValue("Another paragraph content"))))), - Area(emptyList(), null, null), + Area(emptyList(), null, null, false), ) ) @@ -133,12 +133,40 @@ class MappingEntityTest { result.content.shouldBeEqualTo( listOf( - Area(emptyList(), null, "AddedFirstAreaName"), + Area(emptyList(), null, "AddedFirstAreaName", false), aParagraph(content = listOf(aText(content = listOf(StringValue("Default paragraph content"))))), - Area(emptyList(), null, null), + Area(emptyList(), null, null, false), aParagraph(content = listOf(aText(content = listOf(StringValue("Another paragraph content"))))), - Area(emptyList(), null, "AddedLastAreaName"), - )) + Area(emptyList(), null, "AddedLastAreaName", true), + ) + ) + } + + @Test + fun `flowToNextPage are mapped correctly when are missing entirely from the mapping`() { + val mapping = MappingItemEntity.Area( + name = null, + areas = mutableMapOf(0 to "FirstArea", 1 to "SecondAreaModified"), + ) + val block = aBlockDto( + "doc1", content = listOf( + AreaBuilder().interactiveFlowName("FirstArea").build(), + AreaBuilder().interactiveFlowName("SecondArea").build(), + AreaBuilder().build(), + AreaBuilder().interactiveFlowName("FourthArea").build(), + ) + ) + + val result = mapping.apply(block) + + result.content.shouldBeEqualTo( + listOf( + AreaBuilder().interactiveFlowName("FirstArea").flowToNextPage(false).build(), + AreaBuilder().interactiveFlowName("SecondAreaModified").flowToNextPage(false).build(), + AreaBuilder().flowToNextPage(false).build(), + AreaBuilder().interactiveFlowName("FourthArea").flowToNextPage(false).build(), + ) + ) } } @@ -278,7 +306,7 @@ class MappingEntityTest { val result = mapping.apply(dto) val resultDef = result.definition - if (resultDef !is ParagraphStyleDefinition ) { + if (resultDef !is ParagraphStyleDefinition) { throw AssertionError("Expected ParagraphStyleDefinition, got ${resultDef::class.simpleName}") } @@ -317,7 +345,7 @@ class MappingEntityTest { val result = mapping.apply(dto) val resultDef = result.definition - if (resultDef !is ParagraphStyleDefinition ) { + if (resultDef !is ParagraphStyleDefinition) { throw AssertionError("Expected ParagraphStyleDefinition, got ${resultDef::class.simpleName}") } From d846ff14c2f3dc3258c0052dde1ebbbb4a439153 Mon Sep 17 00:00:00 2001 From: "d.svitak" Date: Fri, 13 Feb 2026 09:21:17 +0100 Subject: [PATCH 2/2] changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f0e0d44..28a365ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) - Added azureAI sample files - Introduced attachment table that allows to work with static files. Export/import, path config and other support included +- Areas have flowToNextPage property (false by default) available in Area builder and import/export scripts. ### Changed