feat(documents): add title section movement helpers
This commit is contained in:
41
frontend/utils/documentTitleSections.js
Normal file
41
frontend/utils/documentTitleSections.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const titleLevel = row => Math.min(Math.max(Number(row.titleLevel) || 1, 1), 3)
|
||||
|
||||
// A section includes every row up to the next title at the same or a higher level.
|
||||
const sectionEnd = (rows, start) => {
|
||||
const level = titleLevel(rows[start])
|
||||
let end = start + 1
|
||||
while (end < rows.length && (rows[end].mode !== 'title' || titleLevel(rows[end]) > level)) end += 1
|
||||
return end
|
||||
}
|
||||
|
||||
export const getTitleSectionMove = (rows, rowId, direction) => {
|
||||
if (!['up', 'down'].includes(direction)) return null
|
||||
const start = rows.findIndex(row => row.id === rowId)
|
||||
if (start < 0 || rows[start].mode !== 'title') return null
|
||||
|
||||
const level = titleLevel(rows[start])
|
||||
const end = sectionEnd(rows, start)
|
||||
if (direction === 'down') {
|
||||
// A title at a higher level ends the parent section: never cross it.
|
||||
if (end === rows.length || titleLevel(rows[end]) !== level) return null
|
||||
return { start, end, target: sectionEnd(rows, end) }
|
||||
}
|
||||
|
||||
for (let previous = start - 1; previous >= 0; previous -= 1) {
|
||||
if (rows[previous].mode !== 'title' || titleLevel(rows[previous]) > level) continue
|
||||
if (titleLevel(rows[previous]) < level) return null
|
||||
return { start, end, target: previous }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const moveTitleSection = (rows, rowId, direction) => {
|
||||
const move = getTitleSectionMove(rows, rowId, direction)
|
||||
if (!move) return rows
|
||||
|
||||
const { start, end, target } = move
|
||||
const result = rows.slice()
|
||||
const section = result.splice(start, end - start)
|
||||
result.splice(target > start ? target - section.length : target, 0, ...section)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user