Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 39 additions & 18 deletions apps/frontend/src/pages/[type]/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -1658,25 +1658,29 @@ const patchProjectMutation = useMutation({
},

onMutate: async ({ projectId, data }) => {
// Cancel outgoing refetches
await queryClient.cancelQueries({ queryKey: ['project', 'v2', projectId] })
// Cancel outgoing refetches for both slug-based and ID-based cache keys
// The query may be keyed by slug (routeProjectId) but we also have the actual UUID (projectId)
await queryClient.cancelQueries({ queryKey: ['project', 'v2', routeProjectId.value] })
if (routeProjectId.value !== projectId) {
await queryClient.cancelQueries({ queryKey: ['project', 'v2', projectId] })
}

// Snapshot previous value
const previousProject = queryClient.getQueryData(['project', 'v2', projectId])
// Snapshot previous value from the active query (uses route param as key)
const previousProject = queryClient.getQueryData(['project', 'v2', routeProjectId.value])

// Optimistic update
queryClient.setQueryData(['project', 'v2', projectId], (old) => {
// Optimistic update on the active query key
queryClient.setQueryData(['project', 'v2', routeProjectId.value], (old) => {
if (!old) return old
return { ...old, ...data }
})

return { previousProject }
},

onError: (err, { projectId }, context) => {
// Rollback on error
onError: (err, _variables, context) => {
// Rollback on error using the active query key
if (context?.previousProject) {
queryClient.setQueryData(['project', 'v2', projectId], context.previousProject)
queryClient.setQueryData(['project', 'v2', routeProjectId.value], context.previousProject)
}
addNotification({
title: formatMessage(commonMessages.errorNotificationTitle),
Expand All @@ -1687,8 +1691,11 @@ const patchProjectMutation = useMutation({
},

onSettled: async (_data, _error, { projectId }) => {
// Always refetch to ensure consistency
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', projectId] })
// Invalidate both slug-based and ID-based cache keys to ensure consistency
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', routeProjectId.value] })
if (routeProjectId.value !== projectId) {
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', projectId] })
}
await queryClient.invalidateQueries({ queryKey: ['project', 'v3', projectId] })
},
})
Expand All @@ -1703,21 +1710,28 @@ const patchStatusMutation = useMutation({
},

onMutate: async ({ projectId, status }) => {
await queryClient.cancelQueries({ queryKey: ['project', 'v2', projectId] })
const previousProject = queryClient.getQueryData(['project', 'v2', projectId])
// Cancel outgoing refetches for both slug-based and ID-based cache keys
await queryClient.cancelQueries({ queryKey: ['project', 'v2', routeProjectId.value] })
if (routeProjectId.value !== projectId) {
await queryClient.cancelQueries({ queryKey: ['project', 'v2', projectId] })
}

// Optimistic update
queryClient.setQueryData(['project', 'v2', projectId], (old) => {
// Snapshot previous value from the active query (uses route param as key)
const previousProject = queryClient.getQueryData(['project', 'v2', routeProjectId.value])

// Optimistic update on the active query key
queryClient.setQueryData(['project', 'v2', routeProjectId.value], (old) => {
if (!old) return old
return { ...old, status }
})

return { previousProject }
},

onError: (err, { projectId }, context) => {
onError: (err, _variables, context) => {
// Rollback on error using the active query key
if (context?.previousProject) {
queryClient.setQueryData(['project', 'v2', projectId], context.previousProject)
queryClient.setQueryData(['project', 'v2', routeProjectId.value], context.previousProject)
}
addNotification({
title: formatMessage(commonMessages.errorNotificationTitle),
Expand All @@ -1727,7 +1741,11 @@ const patchStatusMutation = useMutation({
},

onSettled: async (_data, _error, { projectId }) => {
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', projectId] })
// Invalidate both slug-based and ID-based cache keys to ensure consistency
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', routeProjectId.value] })
if (routeProjectId.value !== projectId) {
await queryClient.invalidateQueries({ queryKey: ['project', 'v2', projectId] })
}
},
})

Expand Down Expand Up @@ -1902,6 +1920,9 @@ watch(downloadModal, (modal) => {
})

async function setProcessing() {
// Guard against multiple submissions while mutation is pending
if (patchStatusMutation.isPending.value) return

startLoading()
patchStatusMutation.mutate(
{ projectId: project.value.id, status: 'processing' },
Expand Down
Loading
Loading