From 223d18673c0daafec3b728f9874a5982c7ee3fd3 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal <47861399+roaga@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:30:17 -0400 Subject: [PATCH] feat(autofix): Add clean error handling, keyboard support in message box (#77873) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - You can use the return key in the message box to send the message now - Cleanly displays errors and step retries - Small copy change Screenshot 2024-09-20 at 1 47 37 PM --- .../events/autofix/autofixInsightCards.tsx | 1 - .../events/autofix/autofixMessageBox.tsx | 73 ++++++++++--------- .../events/autofix/autofixSteps.tsx | 25 +++++++ 3 files changed, 63 insertions(+), 36 deletions(-) diff --git a/static/app/components/events/autofix/autofixInsightCards.tsx b/static/app/components/events/autofix/autofixInsightCards.tsx index e4a3158afac678..65d191d17a223a 100644 --- a/static/app/components/events/autofix/autofixInsightCards.tsx +++ b/static/app/components/events/autofix/autofixInsightCards.tsx @@ -261,7 +261,6 @@ function AutofixInsightCards({ ) ) : !hasStepAbove && !hasStepBelow ? ( -

Nothing yet...

Autofix will share important conclusions here as it discovers them, building a line of reasoning up to the root cause. diff --git a/static/app/components/events/autofix/autofixMessageBox.tsx b/static/app/components/events/autofix/autofixMessageBox.tsx index 7649c539587b2e..30ea803310c99a 100644 --- a/static/app/components/events/autofix/autofixMessageBox.tsx +++ b/static/app/components/events/autofix/autofixMessageBox.tsx @@ -1,4 +1,4 @@ -import {Fragment, useState} from 'react'; +import {type FormEvent, Fragment, useState} from 'react'; import styled from '@emotion/styled'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; @@ -112,7 +112,8 @@ function AutofixMessageBox({ const [message, setMessage] = useState(''); const {mutate: send} = useSendMessage({groupId, runId}); - const handleSend = () => { + const handleSend = (e: FormEvent) => { + e.preventDefault(); if (message.trim() !== '' || allowEmptyMessage) { if (onSend != null) { onSend(message); @@ -157,39 +158,41 @@ function AutofixMessageBox({

{message.length > 0 ? notEmptyInfoText : emptyInfoText}

- - {!responseRequired ? ( - - setMessage(e.target.value)} - placeholder={inputPlaceholder} - disabled={isDisabled} - /> - - - ) : ( - - setMessage(e.target.value)} - placeholder={'Please answer to continue...'} - disabled={isDisabled} - /> - - - )} - +
+ + {!responseRequired ? ( + + setMessage(e.target.value)} + placeholder={inputPlaceholder} + disabled={isDisabled} + /> + + + ) : ( + + setMessage(e.target.value)} + placeholder={'Please answer to continue...'} + /> + + + )} + +
); } diff --git a/static/app/components/events/autofix/autofixSteps.tsx b/static/app/components/events/autofix/autofixSteps.tsx index bb066bcdc7b925..d2f91ac2aae450 100644 --- a/static/app/components/events/autofix/autofixSteps.tsx +++ b/static/app/components/events/autofix/autofixSteps.tsx @@ -16,6 +16,7 @@ import { type AutofixStep, AutofixStepType, } from 'sentry/components/events/autofix/types'; +import {space} from 'sentry/styles/space'; import testableTransition from 'sentry/utils/testableTransition'; const animationProps: AnimationProps = { @@ -26,6 +27,7 @@ const animationProps: AnimationProps = { }; interface StepProps { groupId: string; + hasErroredStepBefore: boolean; hasStepAbove: boolean; hasStepBelow: boolean; onRetry: () => void; @@ -64,6 +66,7 @@ export function Step({ repos, hasStepBelow, hasStepAbove, + hasErroredStepBefore, }: StepProps) { const isActive = step.status !== 'PENDING' && step.status !== 'CANCELLED'; @@ -93,6 +96,13 @@ export function Step({ {step.type === AutofixStepType.CHANGES && ( )} + {hasErroredStepBefore && hasStepBelow && ( + + Autofix encountered an error. +
+ Restarting step from scratch... +
+ )} @@ -162,6 +172,12 @@ export function AutofixSteps({data, groupId, runId, onRetry}: AutofixStepsProps) lastStep.type === AutofixStepType.CHANGES && lastStep.status === 'COMPLETED'; const disabled = areCodeChangesShowing ? true : false; + const previousStep = steps.length > 2 ? steps[steps.length - 2] : null; + const previousStepErrored = + previousStep !== null && + previousStep?.type === lastStep.type && + previousStep.status === 'ERROR'; + const scrollToMatchingStep = () => { const matchingStepIndex = steps.findIndex(step => step.type === lastStep.type); if (matchingStepIndex !== -1 && stepsRef.current[matchingStepIndex]) { @@ -182,6 +198,7 @@ export function AutofixSteps({data, groupId, runId, onRetry}: AutofixStepsProps) runId={runId} onRetry={onRetry} repos={repos} + hasErroredStepBefore={previousStepErrored} /> ))} @@ -221,6 +238,14 @@ export function AutofixSteps({data, groupId, runId, onRetry}: AutofixStepsProps) ); } +const StepMessage = styled('div')` + overflow: hidden; + padding: ${space(2)}; + color: ${p => p.theme.subText}; + justify-content: center; + text-align: center; +`; + const StepsContainer = styled('div')` margin-bottom: 13em; `;