Propagate async/await to List.copy(), Swimlane.copy() and callers

Since Card.copy() is now async, all callers in the copy chain need to
be updated to properly await the async operations:

- Make List.copy() async and await card.copy() in loop
- Make Swimlane.copy() async and await list.copy() in loop
- Fix mutateSelectedCards() to support async callbacks and method calls
- Make template copy event handler async in listBody.js

This also fixes the copySelection feature which was passing a callback
to mutateSelectedCards() but the function only supported method names.
This commit is contained in:
Harry Adel 2026-01-31 19:46:22 +02:00
parent 14de981ac3
commit 35715ef2a3
4 changed files with 49 additions and 35 deletions

View file

@ -105,10 +105,15 @@ BlazeComponent.extendComponent({
},
}).register('filterSidebar');
function mutateSelectedCards(mutationName, ...args) {
ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']}).forEach(card => {
card[mutationName](...args);
});
async function mutateSelectedCards(mutationNameOrCallback, ...args) {
const cards = ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']});
for (const card of cards) {
if (typeof mutationNameOrCallback === 'function') {
await mutationNameOrCallback(card);
} else {
await card[mutationNameOrCallback](...args);
}
}
}
BlazeComponent.extendComponent({
@ -441,28 +446,31 @@ Template.copySelectionPopup.events({
const cardId = instance.selectedCardId.get();
const position = instance.position.get();
mutateSelectedCards((card) => {
const newCard = card.copy(boardId, swimlaneId, listId);
if (newCard) {
let sortIndex = 0;
if (cardId) {
const targetCard = ReactiveCache.getCard(cardId);
if (targetCard) {
if (position === 'above') {
sortIndex = targetCard.sort - 0.5;
} else {
sortIndex = targetCard.sort + 0.5;
mutateSelectedCards(async (card) => {
const newCardId = await card.copy(boardId, swimlaneId, listId);
if (newCardId) {
const newCard = ReactiveCache.getCard(newCardId);
if (newCard) {
let sortIndex = 0;
if (cardId) {
const targetCard = ReactiveCache.getCard(cardId);
if (targetCard) {
if (position === 'above') {
sortIndex = targetCard.sort - 0.5;
} else {
sortIndex = targetCard.sort + 0.5;
}
}
} else {
// To end
const board = ReactiveCache.getBoard(boardId);
const cards = board.cards({ swimlaneId, listId }).sort('sort');
if (cards.length > 0) {
sortIndex = cards[cards.length - 1].sort + 1;
}
}
} else {
// To end
const board = ReactiveCache.getBoard(boardId);
const cards = board.cards({ swimlaneId, listId }).sort('sort');
if (cards.length > 0) {
sortIndex = cards[cards.length - 1].sort + 1;
}
newCard.setSort(sortIndex);
}
newCard.setSort(sortIndex);
}
});
EscapeActions.executeUpTo('multiselection');