fix: support path bindings in table columns

This commit is contained in:
Admin 2026-09-24 21:47:17 +00:00
parent b108136bab
commit a5e358c7e8
2 changed files with 24 additions and 3 deletions

View File

@ -177,7 +177,7 @@ function renderTable(block, data, theme) {
const allowBreak = block?.style?.allowPageBreak === true
const compact = theme.reportDensity === 'compact' || block?.style?.compact === true
const classes = ['table-wrap', allowBreak ? 'allow-break' : '', compact ? 'compact-table' : ''].filter(Boolean).join(' ')
return `<div class="${classes}"><table><thead><tr>${columns.map(c => `<th>${escapeHtml(c.label)}</th>`).join('')}</tr></thead><tbody>${rows.map(row => `<tr>${columns.map(c => `<td>${escapeHtml(getPath(row, c.key))}</td>`).join('')}</tr>`).join('')}</tbody></table></div>`
return `<div class="${classes}"><table><thead><tr>${columns.map(c => `<th>${escapeHtml(c.label)}</th>`).join('')}</tr></thead><tbody>${rows.map(row => `<tr>${columns.map(c => `<td>${escapeHtml(getPath(row, c.key ?? c.path))}</td>`).join('')}</tr>`).join('')}</tbody></table></div>`
}
function blockHtml(block, data, theme) {
@ -259,7 +259,7 @@ function emailTable(block, data, theme) {
const cellStyle = `padding:${cellPadding}px;border-bottom:1px solid ${theme.borderColor};color:${theme.textColor};text-align:left;vertical-align:top;`
return `<mj-table padding="0" font-size="${Math.max(10, theme.baseFontSize - 2)}px" line-height="${theme.lineHeight}">
<tr>${columns.map(column => `<th style="${headerStyle}">${escapeHtml(column.label)}</th>`).join('')}</tr>
${rows.map(row => `<tr>${columns.map(column => `<td style="${cellStyle}">${escapeHtml(getPath(row, column.key))}</td>`).join('')}</tr>`).join('')}
${rows.map(row => `<tr>${columns.map(column => `<td style="${cellStyle}">${escapeHtml(getPath(row, column.key ?? column.path))}</td>`).join('')}</tr>`).join('')}
</mj-table>`
}
@ -337,7 +337,7 @@ function emailBlockText(block, data) {
const columns = Array.isArray(p.columns) ? p.columns : []
if (!Array.isArray(rows) || !columns.length) return ''
const header = columns.map(column => textValue(column.label)).join(' | ')
const body = rows.map(row => columns.map(column => textValue(getPath(row, column.key))).join(' | ')).join('\n')
const body = rows.map(row => columns.map(column => textValue(getPath(row, column.key ?? column.path))).join(' | ')).join('\n')
return [header, body].filter(Boolean).join('\n')
}
case 'spacer':

View File

@ -285,3 +285,24 @@ test('email spacer renders safely', () => {
}, {})
assert.match(html, /height:32px/)
})
test('tables accept path as well as key for column bindings', () => {
const template = {
blocks: [{
type: 'table',
props: {
rowsPath: 'areas',
columns: [
{ label: 'Area', path: 'area' },
{ label: 'Actual', path: 'actual' }
]
}
}]
}
const data = { areas: [{ area: 'Packing', actual: '6.7 TPH' }] }
const html = renderReportHtml(template, data)
assert.match(html, />Packing</)
assert.match(html, />6\.7 TPH</)
assert.doesNotMatch(html, /\[object Object\]/)
})