diff --git a/packages/desktop-client/src/components/transactions/TransactionList.jsx b/packages/desktop-client/src/components/transactions/TransactionList.jsx index 137cc61bc5ffc2222e4ee0697886919836659c2b..9b3eb7895fb7293cc8206b3f9b027365965e2372 100644 --- a/packages/desktop-client/src/components/transactions/TransactionList.jsx +++ b/packages/desktop-client/src/components/transactions/TransactionList.jsx @@ -192,7 +192,7 @@ export function TransactionList({ onApplyFilter({ field: 'notes', op: 'matches', - value: `(^|\\s|\\w|#)${escapeRegExp(tag)}($|\\s|#)`, + value: `(^|\\s|\\w)${escapeRegExp(tag)}($|\\s|#)`, type: 'string', }); }); diff --git a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx index b5a445ea904ae52f9cf26a6561b07bee138e0c69..c421da17e5c154b7c272081e97779fbdbadd2333 100644 --- a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx +++ b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx @@ -2494,6 +2494,7 @@ function notesTagFormatter(notes, onNotesTagClick) { {words.map((word, i, arr) => { const separator = arr.length - 1 === i ? '' : ' '; if (word.includes('#') && word.length > 1) { + let lastEmptyTag = -1; // Treat tags in a single word as separate tags. // #tag1#tag2 => (#tag1)(#tag2) // not-a-tag#tag2#tag3 => not-a-tag(#tag2)(#tag3) @@ -2503,9 +2504,15 @@ function notesTagFormatter(notes, onNotesTagClick) { } if (!tag) { + lastEmptyTag = ti; return '#'; } + if (lastEmptyTag === ti - 1) { + return `${tag} `; + } + lastEmptyTag = -1; + const validTag = `#${tag}`; return ( <span key={`${validTag}${ti}`}> diff --git a/packages/loot-core/src/server/accounts/sync.ts b/packages/loot-core/src/server/accounts/sync.ts index b83c5ddd6df555ba65b30573bfe0cf5499ea610f..cf2e25197dc8cc4b9ee894c337a367d6a7fcc988 100644 --- a/packages/loot-core/src/server/accounts/sync.ts +++ b/packages/loot-core/src/server/accounts/sync.ts @@ -272,6 +272,10 @@ async function normalizeBankSyncTransactions(transactions, acctId) { trans.cleared = Boolean(trans.booked); + const notes = + trans.remittanceInformationUnstructured || + (trans.remittanceInformationUnstructuredArray || []).join(', '); + normalized.push({ payee_name: trans.payeeName, trans: { @@ -279,9 +283,7 @@ async function normalizeBankSyncTransactions(transactions, acctId) { payee: trans.payee, account: trans.account, date: trans.date, - notes: - trans.remittanceInformationUnstructured || - (trans.remittanceInformationUnstructuredArray || []).join(', '), + notes: notes.trim().replace('#', '##'), imported_id: trans.transactionId, imported_payee: trans.imported_payee, cleared: trans.cleared, diff --git a/upcoming-release-notes/3246.md b/upcoming-release-notes/3246.md new file mode 100644 index 0000000000000000000000000000000000000000..6a03af438ff0c371b0f1129829f9ac2cdb35e9d0 --- /dev/null +++ b/upcoming-release-notes/3246.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [psybers] +--- + +Allow escaping tags with double ##.