فهرست منبع

fix(local-presets): optimistic remove on delete

      The Slicer -> Local Profiles page kept showing a just-deleted row for
      the ~hundreds of ms it took invalidateQueries to refetch. A quick
      re-click on the same row opened a second delete-confirm modal that
      resolved to a 404 from the backend.

      Add an optimistic queryClient.setQueryData filter in deleteMutation's
      onSuccess so the row disappears the instant the DELETE returns 200.
      Existing invalidateQueries calls stay in place to reconcile any drift.

      Found while reproducing #1713 (verifying maziggy's setup against the
      reporter's). Unrelated to that investigation but caught here.
maziggy 2 ماه پیش
والد
کامیت
0eed98657f
2فایلهای تغییر یافته به همراه16 افزوده شده و 2 حذف شده
  1. 0 0
      CHANGELOG.md
  2. 16 2
      frontend/src/components/LocalProfilesView.tsx

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
CHANGELOG.md


+ 16 - 2
frontend/src/components/LocalProfilesView.tsx

@@ -15,7 +15,7 @@ import {
   AlertCircle,
   AlertCircle,
 } from 'lucide-react';
 } from 'lucide-react';
 import { api } from '../api/client';
 import { api } from '../api/client';
-import type { LocalPreset } from '../api/client';
+import type { LocalPreset, LocalPresetsResponse } from '../api/client';
 import { Card, CardContent } from './Card';
 import { Card, CardContent } from './Card';
 import { Button } from './Button';
 import { Button } from './Button';
 import { useToast } from '../contexts/ToastContext';
 import { useToast } from '../contexts/ToastContext';
@@ -276,7 +276,21 @@ export function LocalProfilesView() {
 
 
   const deleteMutation = useMutation({
   const deleteMutation = useMutation({
     mutationFn: (id: number) => api.deleteLocalPreset(id),
     mutationFn: (id: number) => api.deleteLocalPreset(id),
-    onSuccess: () => {
+    onSuccess: (_, id) => {
+      // Optimistically drop the row from the cached list so the rendered table
+      // updates the instant the DELETE returns. Without this the row stays
+      // visible until invalidateQueries' background refetch completes, and a
+      // quick re-click on the same row opens a second delete-confirm modal
+      // that resolves to a 404 (server already deleted it). The cache holds a
+      // grouped response (filament / printer / process), not a flat list.
+      queryClient.setQueryData<LocalPresetsResponse>(['localPresets'], (old) => {
+        if (!old) return old;
+        return {
+          filament: old.filament.filter((p) => p.id !== id),
+          printer: old.printer.filter((p) => p.id !== id),
+          process: old.process.filter((p) => p.id !== id),
+        };
+      });
       queryClient.invalidateQueries({ queryKey: ['localPresets'] });
       queryClient.invalidateQueries({ queryKey: ['localPresets'] });
       // Match the import path: the SliceModal's `slicerPresets` query needs
       // Match the import path: the SliceModal's `slicerPresets` query needs
       // to be invalidated too, otherwise the deleted preset keeps appearing
       // to be invalidated too, otherwise the deleted preset keeps appearing

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است