Browse Source

fix(autofix): Improve the try again experience (#67025)

Previously, Autofix would flash the old state after triggering a new
run. Now it should work as expected and go straight into the new run
with a blank slate.

Because the overwiteData state was a bit janky I rewrote this hook so
that it sets to the query cache instead.
Malachi Willey 1 year ago
parent
commit
f359d63091
1 changed files with 44 additions and 33 deletions
  1. 44 33
      static/app/components/events/autofix/useAutofix.tsx

+ 44 - 33
static/app/components/events/autofix/useAutofix.tsx

@@ -1,57 +1,68 @@
-import {useCallback, useEffect, useState} from 'react';
+import {useCallback, useState} from 'react';
 
 import type {AutofixData, GroupWithAutofix} from 'sentry/components/events/autofix/types';
 import type {Event} from 'sentry/types';
-import {useApiQuery} from 'sentry/utils/queryClient';
+import {
+  type ApiQueryKey,
+  setApiQueryData,
+  useApiQuery,
+  useQueryClient,
+} from 'sentry/utils/queryClient';
 import useApi from 'sentry/utils/useApi';
 
+type AutofixResponse = {
+  autofix: AutofixData | null;
+};
+
 const POLL_INTERVAL = 2500;
 
+const makeAutofixQueryKey = (groupId: string): ApiQueryKey => [
+  `/issues/${groupId}/ai-autofix/`,
+];
+
+const isPolling = (autofixData?: AutofixData | null) =>
+  autofixData?.status === 'PROCESSING';
+
 export const useAiAutofix = (group: GroupWithAutofix, event: Event) => {
   const api = useApi();
+  const queryClient = useQueryClient();
 
-  const [overwriteData, setOverwriteData] = useState<AutofixData | 'reset' | null>(null);
-  const autofixData =
-    (overwriteData === 'reset' ? null : overwriteData ?? group.metadata?.autofix) ?? null;
-  const isPolling = autofixData?.status === 'PROCESSING';
+  const [isReset, setIsReset] = useState<boolean>(false);
+  const initialAutofixData = group.metadata?.autofix ?? null;
 
   const {
     data: apiData,
     isError,
-    refetch: dataRefetch,
     error,
-  } = useApiQuery<{autofix: AutofixData | null}>([`/issues/${group.id}/ai-autofix/`], {
+  } = useApiQuery<AutofixResponse>(makeAutofixQueryKey(group.id), {
     staleTime: Infinity,
     retry: false,
-    enabled: !autofixData?.status || autofixData.status === 'PROCESSING',
+    initialData: [{autofix: initialAutofixData}, undefined, undefined],
     refetchInterval: data => {
-      if (data?.[0]?.autofix?.status === 'PROCESSING') {
+      if (isPolling(data?.[0]?.autofix)) {
         return POLL_INTERVAL;
       }
       return false;
     },
   });
 
-  useEffect(() => {
-    if (overwriteData !== 'reset' && apiData?.autofix) {
-      setOverwriteData(apiData.autofix);
-    }
-  }, [apiData?.autofix, overwriteData]);
-
   const triggerAutofix = useCallback(
     async (instruction: string) => {
-      setOverwriteData({
-        status: 'PROCESSING',
-        steps: [
-          {
-            id: '1',
-            index: 0,
-            status: 'PROCESSING',
-            title: 'Starting Autofix...',
-            progress: [],
-          },
-        ],
-        created_at: new Date().toISOString(),
+      setIsReset(false);
+      setApiQueryData<AutofixResponse>(queryClient, makeAutofixQueryKey(group.id), {
+        autofix: {
+          status: 'PROCESSING',
+          steps: [
+            {
+              id: '1',
+              index: 0,
+              status: 'PROCESSING',
+              title: 'Starting Autofix...',
+              progress: [],
+            },
+          ],
+          created_at: new Date().toISOString(),
+        },
       });
 
       try {
@@ -65,21 +76,21 @@ export const useAiAutofix = (group: GroupWithAutofix, event: Event) => {
       } catch (e) {
         // Don't need to do anything, error should be in the metadata
       }
-
-      dataRefetch();
     },
-    [api, group.id, event.id, dataRefetch]
+    [queryClient, group.id, api, event.id]
   );
 
   const reset = useCallback(() => {
-    setOverwriteData('reset');
+    setIsReset(true);
   }, []);
 
+  const autofixData = isReset ? null : apiData?.autofix ?? null;
+
   return {
     autofixData,
     error,
     isError,
-    isPolling,
+    isPolling: isPolling(autofixData),
     triggerAutofix,
     reset,
   };