From 7071e3ba43b39201b63be59ec3774bf78855b1e8 Mon Sep 17 00:00:00 2001 From: Theo <36564257+theoholl@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:37:12 +0000 Subject: [PATCH 1/2] Fix reordering filtered lists Signed-off-by: Theo <36564257+theoholl@users.noreply.github.com> --- src/components/board/Stack.vue | 33 +++++++++++++++++++++++++++++++-- src/store/card.js | 7 ++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/components/board/Stack.vue b/src/components/board/Stack.vue index 7300a40b0..811f96925 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,35 @@ export default { return this.cardsByStack[index] } }, + getUnfilteredOrder(filteredAddedIndex, cardId) { + // Convert a drop index from the filtered view to the correct + // order among all (unfiltered) cards in the stack so that + // reordering works correctly when filters are active. + const allCards = this.$store.getters.allCardsByStack(this.stack.id) + .filter(c => !c.archived && 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] + return allCards.findIndex(c => c.id === firstVisible.id) + } + + if (filteredAddedIndex >= filteredCards.length) { + // Dropped after the last visible card + const lastVisible = filteredCards[filteredCards.length - 1] + return allCards.findIndex(c => c.id === lastVisible.id) + 1 + } + + // Dropped between two visible cards — place after the + // preceding visible card in the unfiltered list + const prevVisible = filteredCards[filteredAddedIndex - 1] + return allCards.findIndex(c => c.id === prevVisible.id) + 1 + }, 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..23239055d 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) }, + allCardsByStack: (state) => (id) => { + return state.cards + .filter((card) => card.stackId === id) + .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) + }, cardById: state => (id) => { return state.cards.find((card) => card.id === id) }, @@ -300,7 +305,7 @@ export default function cardModuleFactory() { async reorderCard({ commit, getters }, card) { let i = 0 const newCards = [] - for (const c of getters.cardsByStack(card.stackId)) { + for (const c of getters.allCardsByStack(card.stackId)) { if (c.id === card.id) { newCards.push(card) } From f0ff642bf6ec529c1609f8b630ace63595a040b0 Mon Sep 17 00:00:00 2001 From: Theo <36564257+theoholl@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:07:18 +0000 Subject: [PATCH 2/2] Exclude archived cards from reordering Signed-off-by: Theo <36564257+theoholl@users.noreply.github.com> --- src/components/board/Stack.vue | 18 +++++++++++------- src/store/card.js | 12 ++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/components/board/Stack.vue b/src/components/board/Stack.vue index 811f96925..04802b9f2 100644 --- a/src/components/board/Stack.vue +++ b/src/components/board/Stack.vue @@ -269,10 +269,11 @@ export default { }, getUnfilteredOrder(filteredAddedIndex, cardId) { // Convert a drop index from the filtered view to the correct - // order among all (unfiltered) cards in the stack so that - // reordering works correctly when filters are active. - const allCards = this.$store.getters.allCardsByStack(this.stack.id) - .filter(c => !c.archived && c.id !== cardId) + // 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) { @@ -282,19 +283,22 @@ export default { if (filteredAddedIndex <= 0) { // Dropped before the first visible card const firstVisible = filteredCards[0] - return allCards.findIndex(c => c.id === firstVisible.id) + 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] - return allCards.findIndex(c => c.id === lastVisible.id) + 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] - return allCards.findIndex(c => c.id === prevVisible.id) + 1 + const idx = allCards.findIndex(c => c.id === prevVisible.id) + return idx !== -1 ? idx + 1 : filteredAddedIndex }, deleteStack(stack) { this.$store.dispatch('deleteStack', stack) diff --git a/src/store/card.js b/src/store/card.js index 23239055d..0ad27ade5 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -184,9 +184,9 @@ export default function cardModuleFactory() { }) .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) }, - allCardsByStack: (state) => (id) => { + activeCardsByStack: (state) => (id) => { return state.cards - .filter((card) => card.stackId === id) + .filter((card) => card.stackId === id && !card.archived) .sort((a, b) => a.order - b.order || a.createdAt - b.createdAt) }, cardById: state => (id) => { @@ -304,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.allCardsByStack(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++ @@ -316,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) => {