import {Fragment, useEffect, useState} from 'react'; import styled from '@emotion/styled'; import {Button} from 'sentry/components/button'; import DateTime from 'sentry/components/dateTime'; import {AutofixChanges} from 'sentry/components/events/autofix/autofixChanges'; import {AutofixRootCause} from 'sentry/components/events/autofix/autofixRootCause'; import { type AutofixData, type AutofixProgressItem, type AutofixStep, AutofixStepType, } from 'sentry/components/events/autofix/types'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Panel from 'sentry/components/panels/panel'; import { IconCheckmark, IconChevron, IconClose, IconCode, IconFatal, IconQuestion, IconSad, } from 'sentry/icons'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import usePrevious from 'sentry/utils/usePrevious'; function StepIcon({step}: {step: AutofixStep}) { if (step.type === AutofixStepType.CHANGES) { return ; } if (step.type === AutofixStepType.ROOT_CAUSE_ANALYSIS) { if (step.causes?.length === 0) { return ; } return step.selection ? ( ) : ( ); } switch (step.status) { case 'PROCESSING': return ; case 'CANCELLED': return ; case 'ERROR': return ; case 'COMPLETED': return ; default: return null; } } function stepShouldBeginExpanded(step: AutofixStep) { if (step.type === AutofixStepType.CHANGES) { return true; } if (step.type === AutofixStepType.ROOT_CAUSE_ANALYSIS) { return step.selection ? false : true; } return step.status !== 'COMPLETED'; } interface StepProps { groupId: string; onRetry: () => void; runId: string; step: AutofixStep; isChild?: boolean; stepNumber?: number; } interface AutofixStepsProps { data: AutofixData; groupId: string; onRetry: () => void; runId: string; } function isProgressLog( item: AutofixProgressItem | AutofixStep ): item is AutofixProgressItem { return 'message' in item && 'timestamp' in item; } function Progress({ progress, groupId, runId, onRetry, }: { groupId: string; onRetry: () => void; progress: AutofixProgressItem | AutofixStep; runId: string; }) { if (isProgressLog(progress)) { return (
{progress.message}
); } return ( ); } export function Step({step, isChild, groupId, runId, onRetry}: StepProps) { const previousStepStatus = usePrevious(step.status); const isActive = step.status !== 'PENDING' && step.status !== 'CANCELLED'; const [isExpanded, setIsExpanded] = useState(() => stepShouldBeginExpanded(step)); useEffect(() => { if ( previousStepStatus && previousStepStatus !== step.status && step.status === 'COMPLETED' ) { setIsExpanded(false); } }, [previousStepStatus, step.status]); const logs: AutofixProgressItem[] = step.progress?.filter(isProgressLog) ?? []; const activeLog = step.completedMessage ?? logs.at(-1)?.message ?? null; const hasContent = Boolean( step.completedMessage || step.progress?.length || step.type !== AutofixStepType.DEFAULT ); const canToggle = Boolean(isActive && hasContent); return ( { if (canToggle) { setIsExpanded(value => !value); } }} > {step.title} {activeLog && !isExpanded && ( {activeLog} )} {canToggle ? (