fix: introduced clientId for lists, to avoid duplicate list after server sync
PR Checks / lint-and-test (pull_request) Successful in 1m28s

This commit is contained in:
2026-09-14 13:30:17 +02:00
parent e0a8377bec
commit 8f3ece17ac
3 changed files with 15 additions and 3 deletions
+6
View File
@@ -11,6 +11,12 @@ import type {
export interface LocalList extends List { export interface LocalList extends List {
pendingSync?: boolean pendingSync?: boolean
// Stable identity for this list on this client, independent of `id`.
// `id` starts out as a client-generated placeholder and gets swapped for
// the server-assigned one once "createList" syncs (see remapListId) -
// clientId never changes, so UI code that needs a stable key across that
// swap (e.g. <TransitionGroup>'s :key) can use it instead of `id`.
clientId?: string
} }
export interface LocalListItem extends ListItem { export interface LocalListItem extends ListItem {
+8 -2
View File
@@ -147,8 +147,10 @@ export const useListsStore = defineStore('lists', () => {
async function createList(name: string): Promise<LocalList> { async function createList(name: string): Promise<LocalList> {
const now = new Date().toISOString() const now = new Date().toISOString()
const id = generateId()
const localList: LocalList = { const localList: LocalList = {
id: generateId(), id,
clientId: id,
name, name,
created_at: now, created_at: now,
modified_at: now, modified_at: now,
@@ -538,7 +540,11 @@ export const useListsStore = defineStore('lists', () => {
for (const serverList of serverLists) { for (const serverList of serverLists) {
const existingList = localById.get(serverList.id) const existingList = localById.get(serverList.id)
if (!existingList || !existingList.pendingSync) { if (!existingList || !existingList.pendingSync) {
toPut.push({ ...serverList, pendingSync: false }) toPut.push({
...serverList,
pendingSync: false,
clientId: existingList?.clientId ?? serverList.id,
})
} }
} }
if (toPut.length > 0) { if (toPut.length > 0) {
+1 -1
View File
@@ -110,7 +110,7 @@ async function handleCreateList() {
<TransitionGroup v-if="displayedLists.length > 0" tag="ul" name="list-reorder" class="lists"> <TransitionGroup v-if="displayedLists.length > 0" tag="ul" name="list-reorder" class="lists">
<li <li
v-for="list in displayedLists" v-for="list in displayedLists"
:key="list.id" :key="list.clientId ?? list.id"
:ref="(el) => setItemRef(list.id, el as Element | null)" :ref="(el) => setItemRef(list.id, el as Element | null)"
class="list-row" class="list-row"
:class="{ 'no-transition': isPointerActive && draggingId === list.id }" :class="{ 'no-transition': isPointerActive && draggingId === list.id }"