diff --git a/src/components/board/Stack.vue b/src/components/board/Stack.vue index 7300a40b0..04802b9f2 100644 --- a/src/components/board/Stack.vue +++ b/src/components/board/Stack.vue @@ -251,12 +251,12 @@ export default { if (addedIndex !== null && removedIndex === null) { // move card to new stack card.stackId = stackId - card.order = addedIndex + card.order = this.getUnfilteredOrder(addedIndex, card.id) console.debug('move card to stack', card.stackId, card.order) await this.$store.dispatch('reorderCard', card) } if (addedIndex !== null && removedIndex !== null) { - card.order = addedIndex + card.order = this.getUnfilteredOrder(addedIndex, card.id) console.debug('move card in stack', card.stackId, card.order) await this.$store.dispatch('reorderCard', card) } @@ -267,6 +267,39 @@ export default { return this.cardsByStack[index] } }, + getUnfilteredOrder(filteredAddedIndex, cardId) { + // Convert a drop index from the filtered view to the correct + // order among all active (non-archived, unfiltered) cards in + // the stack so that reordering works correctly when filters + // are active. + const allCards = this.$store.getters.activeCardsByStack(this.stack.id) + .filter(c => c.id !== cardId) + const filteredCards = this.cardsByStack.filter(c => c.id !== cardId) + + if (filteredCards.length === 0 || allCards.length === 0) { + return filteredAddedIndex + } + + if (filteredAddedIndex <= 0) { + // Dropped before the first visible card + const firstVisible = filteredCards[0] + const idx = allCards.findIndex(c => c.id === firstVisible.id) + return idx !== -1 ? idx : filteredAddedIndex + } + + if (filteredAddedIndex >= filteredCards.length) { + // Dropped after the last visible card + const lastVisible = filteredCards[filteredCards.length - 1] + const idx = allCards.findIndex(c => c.id === lastVisible.id) + return idx !== -1 ? idx + 1 : filteredAddedIndex + } + + // Dropped between two visible cards — place after the + // preceding visible card in the unfiltered list + const prevVisible = filteredCards[filteredAddedIndex - 1] + const idx = allCards.findIndex(c => c.id === prevVisible.id) + return idx !== -1 ? idx + 1 : filteredAddedIndex + }, deleteStack(stack) { this.$store.dispatch('deleteStack', stack) showUndo(t('deck', 'List deleted'), () => this.$store.dispatch('stackUndoDelete', stack)) diff --git a/src/store/card.js b/src/store/card.js index e9d0098a9..0ad27ade5 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -184,6 +184,11 @@ export default function cardModuleFactory() { }) .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) }, + activeCardsByStack: (state) => (id) => { + return state.cards + .filter((card) => card.stackId === id && !card.archived) + .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) + }, cardById: state => (id) => { return state.cards.find((card) => card.id === id) }, @@ -299,10 +304,12 @@ export default function cardModuleFactory() { }, async reorderCard({ commit, getters }, card) { let i = 0 + let found = false const newCards = [] - for (const c of getters.cardsByStack(card.stackId)) { + for (const c of getters.activeCardsByStack(card.stackId)) { if (c.id === card.id) { newCards.push(card) + found = true } if (i === card.order) { i++ @@ -311,7 +318,9 @@ export default function cardModuleFactory() { newCards.push({ ...c, order: i++ }) } } - newCards.push(card) + if (!found) { + newCards.push(card) + } await commit('updateCardsReorder', newCards) apiClient.reorderCard(card).then((cards) => {