Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
- Added base template model, builder and database table. Document objects and display rules can reference them by id
- Layout index.html able to export suggested base template setup to layout csv file. Importing it creates base templates,
links templates and pages to them and assigns areas to created base template areas via interactive flow names.
- Introducing index into the layout mappings to be resistant to sorting and other potential discrepancies

### Changed

Expand Down
14 changes: 11 additions & 3 deletions migration-examples/layout/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,10 @@
const w = parseSizeMm(col(row, 'width'));
const h = parseSizeMm(col(row, 'height'));
if (x == null || y == null || w == null || h == null) return null;
const areaIndex = Number(col(row, 'areaIndex').trim());
if (Number.isNaN(areaIndex)) {
throw new Error(`Row ${lineIndices[idx] + 1} is missing a valid areaIndex value.`);
}
return {
area: {
x, y, w, h,
Expand All @@ -783,8 +787,10 @@
contentPreview: col(row, 'contentPreview') || '',
},
lineIndex: lineIndices[idx],
areaIndex,
};
}).filter(a => a != null);
rawAreasWithLine.sort((a, b) => a.areaIndex - b.areaIndex);
const rawAreas = /** @type {{x:number,y:number,w:number,h:number,flowToNextPage:boolean,interactiveFlowName:string,contentPreview:string}[]} */ (
rawAreasWithLine.map(a => a.area)
);
Expand Down Expand Up @@ -949,6 +955,7 @@
baseRows.push([
baseTemplateId, baseTemplateName, basePageId, basePageName,
pageWidthMm, pageHeightMm,
String(areaGroupIndex),
flowName, String(flowToNextPage),
`${draft.position.x}mm`, `${draft.position.y}mm`, `${draft.position.w}mm`, `${draft.position.h}mm`,
"Base", "", "",
Expand Down Expand Up @@ -1020,9 +1027,10 @@
baseRows.forEach(baseRow => {
const byLogicalName = {
templateId: baseRow[0], templateName: baseRow[1], pageId: baseRow[2], pageName: baseRow[3],
pageWidth: baseRow[4], pageHeight: baseRow[5], interactiveFlowName: baseRow[6], flowToNextPage: baseRow[7],
x: baseRow[8], y: baseRow[9], width: baseRow[10], height: baseRow[11],
type: baseRow[12], targetId: baseRow[13], contentPreview: baseRow[14],
pageWidth: baseRow[4], pageHeight: baseRow[5], areaIndex: baseRow[6],
interactiveFlowName: baseRow[7], flowToNextPage: baseRow[8],
x: baseRow[9], y: baseRow[10], width: baseRow[11], height: baseRow[12],
type: baseRow[13], targetId: baseRow[14], contentPreview: baseRow[15],
};
const row = headers.map(h => byLogicalName[normalizeHeaderName(h)] ?? "");
rows.push(row);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static void run(Migration migration, Path path) {
Mapping.displayHeader("pageName", true),
Mapping.displayHeader("pageWidth", true),
Mapping.displayHeader("pageHeight", true),
Mapping.displayHeader("areaIndex", true),
Mapping.displayHeader("interactiveFlowName", false),
Mapping.displayHeader("flowToNextPage", false),
Mapping.displayHeader("x", true),
Expand Down Expand Up @@ -91,8 +92,8 @@ static void run(Migration migration, Path path) {
baseTemplates.each { baseTemplate ->
baseTemplate.pages.eachWithIndex { page, pageIdx ->
def pageId = "page-${pageIdx + 1}"
page.areas.each { area ->
writer.writeLine(buildBaseTemplateArea(baseTemplate, pageId, page, area))
page.areas.eachWithIndex { area, areaIdx ->
writer.writeLine(buildBaseTemplateArea(baseTemplate, pageId, page, area, areaIdx))
}
}
}
Expand All @@ -109,6 +110,7 @@ static String buildArea(Migration migration, Number idx, Area area, DocumentObje
def pageOptions = page?.options instanceof PageOptions ? page.options as PageOptions : null
builder.append(Csv.serialize(pageOptions?.width) + ",")
builder.append(Csv.serialize(pageOptions?.height) + ",")
builder.append(Csv.serialize(idx) + ",")
builder.append(Csv.serialize(area.interactiveFlowName) + ",")
builder.append(Csv.serialize(area.flowToNextPage) + ",")
builder.append(Csv.serialize(area.position.x) + ",")
Expand All @@ -124,14 +126,15 @@ static String buildArea(Migration migration, Number idx, Area area, DocumentObje
return builder.toString()
}

static String buildBaseTemplateArea(BaseTemplate baseTemplate, String pageId, BaseTemplatePage page, BaseTemplateArea area) {
static String buildBaseTemplateArea(BaseTemplate baseTemplate, String pageId, BaseTemplatePage page, BaseTemplateArea area, Number idx) {
def builder = new StringBuilder()
builder.append(Csv.serialize(baseTemplate.id) + ",")
builder.append(Csv.serialize(baseTemplate.name) + ",")
builder.append(Csv.serialize(pageId) + ",")
builder.append(Csv.serialize(page.name) + ",")
builder.append(Csv.serialize(page.pageWidth) + ",")
builder.append(Csv.serialize(page.pageHeight) + ",")
builder.append(Csv.serialize(idx) + ",")
builder.append(Csv.serialize(area.interactiveFlowName) + ",")
builder.append(Csv.serialize(area.flowToNextPage) + ",")
builder.append(Csv.serialize(area.position?.x) + ",")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package com.quadient.migration.example.common.mapping

import com.quadient.migration.api.Migration
import com.quadient.migration.api.dto.migrationmodel.BaseTemplateLocation
import com.quadient.migration.api.dto.migrationmodel.DocumentObject
import com.quadient.migration.api.dto.migrationmodel.builder.BaseTemplateBuilder
import com.quadient.migration.api.dto.migrationmodel.MappingItem
import com.quadient.migration.example.common.util.Csv
Expand All @@ -36,13 +35,10 @@ static void run(Migration migration, Path path) {
def fileLines = path.toFile().readLines()
def columnNames = Csv.parseColumnNames(fileLines.removeFirst()).collect { Mapping.normalizeHeader(it) }

def areaMappings = new HashMap<String, MappingItem>()
def areaMappings = new HashMap<String, MappingItem.Area>()
def docObjectsToTargetIds = new LinkedHashMap<String, String>()
def baseTemplateDrafts = new LinkedHashMap<String, BaseTemplateDraft>()

DocumentObject currentDocumentObject = null
MappingItem.Area areaMapping = null
int areaIndex = 0
for (line in fileLines) {
def values = Csv.getCells(line, columnNames)

Expand All @@ -56,19 +52,16 @@ static void run(Migration migration, Path path) {
def templateId = Csv.deserialize(values.get("templateId"), String.class)
def documentObjectId = pageId ?: templateId

if (currentDocumentObject?.id != documentObjectId) {
if (currentDocumentObject != null) {
areaMappings[currentDocumentObject.id] = areaMapping
}

def documentObjectModel = migration.documentObjectRepository.find(documentObjectId)
if (!documentObjectModel) {
def areaMapping = areaMappings.computeIfAbsent(documentObjectId) {
if (!migration.documentObjectRepository.find(documentObjectId)) {
throw new IllegalStateException("Document object '${documentObjectId}' not found.")
}
migration.mappingRepository.getAreaMapping(documentObjectId)
}

areaMapping = migration.mappingRepository.getAreaMapping(documentObjectId)
currentDocumentObject = documentObjectModel
areaIndex = 0
def areaIndex = Csv.deserialize(values.get("areaIndex"), Integer.class)
if (areaIndex == null) {
throw new IllegalStateException("Row for document object '${documentObjectId}' is missing an areaIndex value.")
}

def interactiveFlowName = Csv.deserialize(values.get("interactiveFlowName"), String.class)
Expand All @@ -86,12 +79,6 @@ static void run(Migration migration, Path path) {
docObjectsToTargetIds[templateId] = targetId
}
}

areaIndex++
}

if (currentDocumentObject != null) {
areaMappings[currentDocumentObject.id] = areaMapping
}

Mapping.upsertBatched(migration.mappingRepository, areaMappings, "area mappings", log)
Expand All @@ -113,25 +100,28 @@ private static void assignAreaToBaseTemplateDraft(Map<String, BaseTemplateDraft>
baseTemplateDraft.name = Csv.deserialize(values.get("templateName"), String.class)
}

def page = baseTemplateDraft.pages.computeIfAbsent(pageGroupId) {
new BaseTemplateBuilder.Page()
.name(Csv.deserialize(values.get("pageName"), String.class))
.pageWidth(Csv.deserialize(values.get("pageWidth"), Size.class))
.pageHeight(Csv.deserialize(values.get("pageHeight"), Size.class))
def pageDraft = baseTemplateDraft.pages.computeIfAbsent(pageGroupId) {
new BaseTemplatePageDraft(name: Csv.deserialize(values.get("pageName"), String.class),
pageWidth: Csv.deserialize(values.get("pageWidth"), Size.class),
pageHeight: Csv.deserialize(values.get("pageHeight"), Size.class))
}

def interactiveFlowName = Csv.deserialize(values.get("interactiveFlowName"), String.class)
if (!interactiveFlowName) {
throw new IllegalStateException("Rows of type 'Base' must specify an interactiveFlowName for the consolidated area.")
}
def areaIndex = Csv.deserialize(values.get("areaIndex"), Integer.class)
if (areaIndex == null) {
throw new IllegalStateException("Rows of type 'Base' must specify an areaIndex identifying the area's position.")
}
def x = Csv.deserialize(values.get("x"), Size.class)
def y = Csv.deserialize(values.get("y"), Size.class)
def width = Csv.deserialize(values.get("width"), Size.class)
def height = Csv.deserialize(values.get("height"), Size.class)
def position = (x != null && y != null && width != null && height != null) ? new Position(x, y, width, height) : null
def flowToNextPage = Csv.deserialize(values.get("flowToNextPage"), Boolean.class) ?: false

page.addArea(interactiveFlowName)
pageDraft.areasByIndex[areaIndex] = new BaseTemplateBuilder.Area(interactiveFlowName)
.position(position)
.flowToNextPage(flowToNextPage)
}
Expand Down Expand Up @@ -171,7 +161,14 @@ private static void applyBaseTemplateDraftMappings(Migration migration, Map<Stri
def mapping = migration.mappingRepository.getBaseTemplateMapping(baseTemplateId)
mapping.name = draft.name ?: existing?.name
mapping.targetFolder = existing?.targetFolder
mapping.pages = draft.pages.values().collect { it.build() } as List<BaseTemplatePage>
mapping.pages = draft.pages.values().collect { pageDraft ->
new BaseTemplateBuilder.Page()
.name(pageDraft.name)
.pageWidth(pageDraft.pageWidth)
.pageHeight(pageDraft.pageHeight)
.addAreas(pageDraft.areasByIndex.values() as List)
.build()
} as List<BaseTemplatePage>

mappings[baseTemplateId] = mapping
}
Expand All @@ -182,5 +179,12 @@ private static void applyBaseTemplateDraftMappings(Migration migration, Map<Stri

class BaseTemplateDraft {
String name
Map<String, BaseTemplateBuilder.Page> pages = new LinkedHashMap<>()
Map<String, BaseTemplatePageDraft> pages = new LinkedHashMap<>()
}

class BaseTemplatePageDraft {
String name
Size pageWidth
Size pageHeight
Map<Integer, BaseTemplateBuilder.Area> areasByIndex = new TreeMap<>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ static <T> T deserialize(String value, Class<T> cls) {
return (trimmed.isEmpty() ? null : trimmed) as T
}
case IcmPath: return IcmPath.from(value) as T
case Integer:
case int:
return value.trim().toInteger() as T
case Color: return Color.fromHex(value) as T
case Size: return Size.fromString(value) as T
case BaseTemplateLocation: {
Expand Down
36 changes: 18 additions & 18 deletions migration-examples/src/test/groovy/LayoutExportTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ class LayoutExportTest {
LayoutExport.run(migration, mappingFile)

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
full tmpl,,full page,,,,test flow2,false,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,test flow3,true,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,,false,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,test flow5,false,0mm,0mm,0mm,0mm,Standard,,
,,unreferenced page,,,,test flow,true,0mm,0mm,0mm,0mm,Standard,,
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),areaIndex (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
full tmpl,,full page,,,,0,test flow2,false,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,1,test flow3,true,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,2,,false,0mm,0mm,0mm,0mm,Standard,,
full tmpl,,full page,,,,3,test flow5,false,0mm,0mm,0mm,0mm,Standard,,
,,unreferenced page,,,,0,test flow,true,0mm,0mm,0mm,0mm,Standard,,
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand All @@ -71,10 +71,10 @@ class LayoutExportTest {
LayoutExport.run(migration, mappingFile)

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
tmpl with areas,,,,,,Address Content,false,0mm,0mm,0mm,0mm,Standard,,
tmpl with areas,,,,,,,true,0mm,0mm,0mm,0mm,Standard,,
tmpl with areas,,,,,,Footer,false,0mm,0mm,0mm,0mm,Standard,,
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),areaIndex (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
tmpl with areas,,,,,,0,Address Content,false,0mm,0mm,0mm,0mm,Standard,,
tmpl with areas,,,,,,1,,true,0mm,0mm,0mm,0mm,Standard,,
tmpl with areas,,,,,,2,Footer,false,0mm,0mm,0mm,0mm,Standard,,
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand All @@ -97,8 +97,8 @@ class LayoutExportTest {
LayoutExport.run(migration, mappingFile)

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
tmpl with base,,page with own base,,,,test flow,false,0mm,0mm,0mm,0mm,Standard,\$G1,
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),areaIndex (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
tmpl with base,,page with own base,,,,0,test flow,false,0mm,0mm,0mm,0mm,Standard,\$G1,
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand All @@ -123,10 +123,10 @@ class LayoutExportTest {
LayoutExport.run(migration, mappingFile)

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
bt-1,Base template 1,page-1,Page 1,210mm,297mm,address,false,1cm,1cm,190mm,20mm,Base,,
bt-1,Base template 1,page-1,Page 1,210mm,297mm,Area 2,true,1cm,30mm,190mm,50mm,Base,,
bt-1,Base template 1,page-2,Page 2,210mm,99mm,Area 1,false,0mm,0mm,210mm,99mm,Base,,
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),areaIndex (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
bt-1,Base template 1,page-1,Page 1,210mm,297mm,0,address,false,1cm,1cm,190mm,20mm,Base,,
bt-1,Base template 1,page-1,Page 1,210mm,297mm,1,Area 2,true,1cm,30mm,190mm,50mm,Base,,
bt-1,Base template 1,page-2,Page 2,210mm,99mm,0,Area 1,false,0mm,0mm,210mm,99mm,Base,,
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand Down Expand Up @@ -154,8 +154,8 @@ class LayoutExportTest {
LayoutExport.run(migration, mappingFile)

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
,,page with preview,,,,test flow,false,0mm,0mm,0mm,0mm,Standard,,docRef: Block One;imageRef: Image One;docRef: Block Two;(+2 more)
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),areaIndex (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),type,targetId,contentPreview (read-only)
,,page with preview,,,,0,test flow,false,0mm,0mm,0mm,0mm,Standard,,docRef: Block One;imageRef: Image One;docRef: Block Two;(+2 more)
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand Down
Loading
Loading