Group all indented lines into item.
This commit is contained in:
parent
9f22e30f82
commit
8ebac3d97d
1 changed files with 71 additions and 33 deletions
104
index.html
104
index.html
|
|
@ -726,7 +726,7 @@
|
||||||
<pre>curl -O <a href="https://mccormick.cx/apps/kanban-todo/kbtd">https://mccormick.cx/apps/kanban-todo/kbtd</a>
|
<pre>curl -O <a href="https://mccormick.cx/apps/kanban-todo/kbtd">https://mccormick.cx/apps/kanban-todo/kbtd</a>
|
||||||
chmod 755 kbtd
|
chmod 755 kbtd
|
||||||
|
|
||||||
# If self-hosting, set KBTD_URL to your URL:
|
# If self-hosting, set KBTD_URL to point at your URL:
|
||||||
# export KBTD_URL="<span class="current-url">https://mccormick.cx/apps/kanban-todo/kbtd</span>"
|
# export KBTD_URL="<span class="current-url">https://mccormick.cx/apps/kanban-todo/kbtd</span>"
|
||||||
|
|
||||||
# Then launch with:
|
# Then launch with:
|
||||||
|
|
@ -1032,6 +1032,7 @@ chmod 755 kbtd
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
|
const trimmed = line.trim();
|
||||||
|
|
||||||
if (line.startsWith('# ')) {
|
if (line.startsWith('# ')) {
|
||||||
finishCard();
|
finishCard();
|
||||||
|
|
@ -1052,19 +1053,25 @@ chmod 755 kbtd
|
||||||
};
|
};
|
||||||
currentSection.columns.push(currentColumn);
|
currentSection.columns.push(currentColumn);
|
||||||
}
|
}
|
||||||
else if ((line.trim().startsWith('- [ ]') || line.trim().startsWith('- [x]')) && currentColumn) {
|
else if ((trimmed.startsWith('- [ ]') || trimmed.startsWith('- [x]')) && currentColumn) {
|
||||||
finishCard();
|
const isIndented = line.startsWith(' ') || line.startsWith('\t');
|
||||||
const isCompleted = line.trim().startsWith('- [x]');
|
|
||||||
const textStart = line.indexOf(']') + 2;
|
|
||||||
const text = line.substring(textStart).trim();
|
|
||||||
|
|
||||||
currentCard = {
|
if (isIndented && currentCard) {
|
||||||
text: text,
|
currentCard.nestedLines.push(line);
|
||||||
completed: isCompleted,
|
} else {
|
||||||
lineNumber: i,
|
finishCard();
|
||||||
originalLine: line,
|
const isCompleted = trimmed.startsWith('- [x]');
|
||||||
nestedLines: []
|
const textStart = line.indexOf(']') + 2;
|
||||||
};
|
const text = line.substring(textStart).trim();
|
||||||
|
|
||||||
|
currentCard = {
|
||||||
|
text: text,
|
||||||
|
completed: isCompleted,
|
||||||
|
lineNumber: i,
|
||||||
|
originalLine: line,
|
||||||
|
nestedLines: []
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (currentCard) {
|
if (currentCard) {
|
||||||
|
|
@ -1121,6 +1128,20 @@ chmod 755 kbtd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findCardByLineNumber(lineNumber) {
|
||||||
|
const section = state.sections[state.currentSectionIndex];
|
||||||
|
for (let colIndex = 0; colIndex < section.columns.length; colIndex++) {
|
||||||
|
const column = section.columns[colIndex];
|
||||||
|
for (let cardIndex = 0; cardIndex < column.cards.length; cardIndex++) {
|
||||||
|
const card = column.cards[cardIndex];
|
||||||
|
if (card.lineNumber === lineNumber) {
|
||||||
|
return { card, colIndex, cardIndex };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
async function moveLineInFile(fromLine, toLine, targetColumnIndex, insertPosition) {
|
async function moveLineInFile(fromLine, toLine, targetColumnIndex, insertPosition) {
|
||||||
console.log('moveLineInFile: from line', fromLine, 'to line', toLine, 'targetColumnIndex:', targetColumnIndex, 'insertPosition:', insertPosition);
|
console.log('moveLineInFile: from line', fromLine, 'to line', toLine, 'targetColumnIndex:', targetColumnIndex, 'insertPosition:', insertPosition);
|
||||||
await modifyFileLines(lines => {
|
await modifyFileLines(lines => {
|
||||||
|
|
@ -1129,11 +1150,19 @@ chmod 755 kbtd
|
||||||
const targetColumnIsEmpty = targetColumn.cards.length === 0;
|
const targetColumnIsEmpty = targetColumn.cards.length === 0;
|
||||||
const isInsertingAtBottom = insertPosition === targetColumn.cards.length;
|
const isInsertingAtBottom = insertPosition === targetColumn.cards.length;
|
||||||
|
|
||||||
|
const cardInfo = findCardByLineNumber(fromLine);
|
||||||
|
if (!cardInfo) {
|
||||||
|
console.error('Could not find card with line number', fromLine);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedLineCount = cardInfo.card.nestedLines.length;
|
||||||
|
console.log('Card has', nestedLineCount, 'nested lines');
|
||||||
console.log('Before move, source line', fromLine, '=', lines[fromLine]);
|
console.log('Before move, source line', fromLine, '=', lines[fromLine]);
|
||||||
console.log('Target column is empty:', targetColumnIsEmpty);
|
console.log('Target column is empty:', targetColumnIsEmpty);
|
||||||
console.log('Inserting at bottom:', isInsertingAtBottom);
|
console.log('Inserting at bottom:', isInsertingAtBottom);
|
||||||
|
|
||||||
const [movedLine] = lines.splice(fromLine, 1);
|
const movedLines = lines.splice(fromLine, 1 + nestedLineCount);
|
||||||
|
|
||||||
let actualInsertLine;
|
let actualInsertLine;
|
||||||
|
|
||||||
|
|
@ -1142,12 +1171,12 @@ chmod 755 kbtd
|
||||||
actualInsertLine = targetColumn.headerLineNumber + 1;
|
actualInsertLine = targetColumn.headerLineNumber + 1;
|
||||||
|
|
||||||
if (actualInsertLine < lines.length && lines[actualInsertLine].trim() === '') {
|
if (actualInsertLine < lines.length && lines[actualInsertLine].trim() === '') {
|
||||||
lines.splice(actualInsertLine, 0, movedLine);
|
lines.splice(actualInsertLine, 0, ...movedLines);
|
||||||
} else {
|
} else {
|
||||||
lines.splice(actualInsertLine, 0, '', movedLine);
|
lines.splice(actualInsertLine, 0, '', ...movedLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
const afterLine = actualInsertLine + (lines[actualInsertLine].trim() === '' ? 2 : 1);
|
const afterLine = actualInsertLine + (lines[actualInsertLine].trim() === '' ? 1 + movedLines.length : movedLines.length);
|
||||||
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
||||||
lines.splice(afterLine, 0, '');
|
lines.splice(afterLine, 0, '');
|
||||||
}
|
}
|
||||||
|
|
@ -1160,7 +1189,7 @@ chmod 755 kbtd
|
||||||
actualInsertLine++;
|
actualInsertLine++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.splice(actualInsertLine, 0, movedLine);
|
lines.splice(actualInsertLine, 0, ...movedLines);
|
||||||
} else {
|
} else {
|
||||||
console.log('Inserting at position', insertPosition);
|
console.log('Inserting at position', insertPosition);
|
||||||
const cardBefore = targetColumn.cards[insertPosition - 1];
|
const cardBefore = targetColumn.cards[insertPosition - 1];
|
||||||
|
|
@ -1170,20 +1199,20 @@ chmod 755 kbtd
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromLine < actualInsertLine) {
|
if (fromLine < actualInsertLine) {
|
||||||
actualInsertLine--;
|
actualInsertLine -= (1 + nestedLineCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actualInsertLine > 0 && lines[actualInsertLine - 1].trim() === '') {
|
if (actualInsertLine > 0 && lines[actualInsertLine - 1].trim() === '') {
|
||||||
console.log('Line before target is blank, replacing it');
|
console.log('Line before target is blank, replacing it');
|
||||||
lines[actualInsertLine - 1] = movedLine;
|
lines.splice(actualInsertLine - 1, 1, ...movedLines);
|
||||||
} else {
|
} else {
|
||||||
console.log('Inserting at target position');
|
console.log('Inserting at target position');
|
||||||
lines.splice(actualInsertLine, 0, movedLine);
|
lines.splice(actualInsertLine, 0, ...movedLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInsertingAtBottom) {
|
if (isInsertingAtBottom) {
|
||||||
const movedLineIndex = lines[actualInsertLine - 1] === movedLine ? actualInsertLine - 1 : actualInsertLine;
|
const movedLineIndex = lines[actualInsertLine - 1] === movedLines[0] ? actualInsertLine - 1 : actualInsertLine;
|
||||||
const afterLine = movedLineIndex + 1;
|
const afterLine = movedLineIndex + movedLines.length;
|
||||||
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
||||||
console.log('Inserting at bottom - ensuring blank line after moved item at line', afterLine);
|
console.log('Inserting at bottom - ensuring blank line after moved item at line', afterLine);
|
||||||
lines.splice(afterLine, 0, '');
|
lines.splice(afterLine, 0, '');
|
||||||
|
|
@ -1193,7 +1222,7 @@ chmod 755 kbtd
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('After move, lines around target:');
|
console.log('After move, lines around target:');
|
||||||
for (let i = Math.max(0, actualInsertLine - 2); i <= Math.min(lines.length - 1, actualInsertLine + 2); i++) {
|
for (let i = Math.max(0, actualInsertLine - 2); i <= Math.min(lines.length - 1, actualInsertLine + movedLines.length + 2); i++) {
|
||||||
console.log(` line ${i}: "${lines[i]}"`);
|
console.log(` line ${i}: "${lines[i]}"`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -1202,7 +1231,16 @@ chmod 755 kbtd
|
||||||
async function moveLineBetweenSections(fromLine, targetSectionIndex, targetColumnIndex) {
|
async function moveLineBetweenSections(fromLine, targetSectionIndex, targetColumnIndex) {
|
||||||
console.log('moveLineBetweenSections: from line', fromLine, 'to section', targetSectionIndex, 'column', targetColumnIndex);
|
console.log('moveLineBetweenSections: from line', fromLine, 'to section', targetSectionIndex, 'column', targetColumnIndex);
|
||||||
await modifyFileLines(lines => {
|
await modifyFileLines(lines => {
|
||||||
const [movedLine] = lines.splice(fromLine, 1);
|
const cardInfo = findCardByLineNumber(fromLine);
|
||||||
|
if (!cardInfo) {
|
||||||
|
console.error('Could not find card with line number', fromLine);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedLineCount = cardInfo.card.nestedLines.length;
|
||||||
|
console.log('Card has', nestedLineCount, 'nested lines');
|
||||||
|
|
||||||
|
const movedLines = lines.splice(fromLine, 1 + nestedLineCount);
|
||||||
|
|
||||||
const targetSection = state.sections[targetSectionIndex];
|
const targetSection = state.sections[targetSectionIndex];
|
||||||
const targetColumn = targetSection.columns[targetColumnIndex];
|
const targetColumn = targetSection.columns[targetColumnIndex];
|
||||||
|
|
@ -1212,16 +1250,16 @@ chmod 755 kbtd
|
||||||
insertLine = targetColumn.headerLineNumber + 1;
|
insertLine = targetColumn.headerLineNumber + 1;
|
||||||
|
|
||||||
if (fromLine < insertLine) {
|
if (fromLine < insertLine) {
|
||||||
insertLine--;
|
insertLine -= (1 + nestedLineCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insertLine < lines.length && lines[insertLine].trim() === '') {
|
if (insertLine < lines.length && lines[insertLine].trim() === '') {
|
||||||
lines.splice(insertLine, 0, movedLine);
|
lines.splice(insertLine, 0, ...movedLines);
|
||||||
} else {
|
} else {
|
||||||
lines.splice(insertLine, 0, '', movedLine);
|
lines.splice(insertLine, 0, '', ...movedLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
const afterLine = insertLine + (lines[insertLine].trim() === '' ? 2 : 1);
|
const afterLine = insertLine + (lines[insertLine].trim() === '' ? 1 + movedLines.length : movedLines.length);
|
||||||
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
||||||
lines.splice(afterLine, 0, '');
|
lines.splice(afterLine, 0, '');
|
||||||
}
|
}
|
||||||
|
|
@ -1233,18 +1271,18 @@ chmod 755 kbtd
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromLine < insertLine) {
|
if (fromLine < insertLine) {
|
||||||
insertLine--;
|
insertLine -= (1 + nestedLineCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.splice(insertLine, 0, movedLine);
|
lines.splice(insertLine, 0, ...movedLines);
|
||||||
|
|
||||||
const afterLine = insertLine + 1;
|
const afterLine = insertLine + movedLines.length;
|
||||||
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
if (afterLine >= lines.length || lines[afterLine].trim() !== '') {
|
||||||
lines.splice(afterLine, 0, '');
|
lines.splice(afterLine, 0, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Moved line to position', insertLine);
|
console.log('Moved lines to position', insertLine);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue