import { useContext, useEffect, useRef, useState } from "react"; import styled, { keyframes } from "styled-components"; import { appear, defaultBorderRadius, secondaryDark, vscBackground, vscBackgroundTransparent, vscForeground, } from "."; import { ChevronDown, ChevronRight, ArrowPath, XMark, MagnifyingGlass, } from "@styled-icons/heroicons-outline"; import { StopCircle } from "@styled-icons/heroicons-solid"; import { HistoryNode } from "../../../schema/HistoryNode"; import HeaderButtonWithText from "./HeaderButtonWithText"; import MarkdownPreview from "@uiw/react-markdown-preview"; import { getMetaKeyLabel, isMetaEquivalentKeyPressed } from "../util"; import { GUIClientContext } from "../App"; interface StepContainerProps { historyNode: HistoryNode; onReverse: () => void; inFuture: boolean; onUserInput: (input: string) => void; onRetry: () => void; onDelete: () => void; open: boolean; onToggleAll: () => void; onToggle: () => void; isFirst: boolean; isLast: boolean; index: number; } // #region styled components const MainDiv = styled.div<{ stepDepth: number; inFuture: boolean }>` opacity: ${(props) => (props.inFuture ? 0.3 : 1)}; animation: ${appear} 0.3s ease-in-out; overflow: hidden; margin-left: 0px; margin-right: 0px; `; const StepContainerDiv = styled.div<{ open: boolean }>` /* background-color: ${(props) => props.open ? vscBackground : secondaryDark}; */ /* border-radius: ${defaultBorderRadius}; */ /* padding: 8px; */ `; const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>` background-color: ${(props) => (props.error ? "#522" : vscBackground)}; display: grid; grid-template-columns: 1fr auto auto; grid-gap: 8px; align-items: center; padding-right: 8px; `; const ContentDiv = styled.div<{ isUserInput: boolean }>` padding: 8px; background-color: ${(props) => props.isUserInput ? secondaryDark : vscBackground}; font-size: 13px; `; const gradient = keyframes` 0% { background-position: 0px 0; } 100% { background-position: 100em 0; } `; const GradientBorder = styled.div<{ borderWidth?: number; borderRadius?: string; borderColor?: string; isFirst: boolean; isLast: boolean; loading: boolean; }>` border-radius: ${(props) => props.borderRadius || "0"}; padding-top: ${(props) => `${(props.borderWidth || 1) / (props.isFirst ? 1 : 2)}px`}; padding-bottom: ${(props) => `${(props.borderWidth || 1) / (props.isLast ? 1 : 2)}px`}; background: ${(props) => props.borderColor ? props.borderColor : `repeating-linear-gradient( 101.79deg, #12887a 0%, #87245c 16%, #e12637 33%, #ffb215 55%, #e12637 67%, #87245c 85%, #12887a 99% )`}; animation: ${(props) => (props.loading ? gradient : "")} 6s linear infinite; background-size: 200% 200%; `; const StyledMarkdownPreview = styled(MarkdownPreview)` pre { background-color: ${secondaryDark}; padding: 1px; border-radius: ${defaultBorderRadius}; border: 0.5px solid white; } code { color: #f78383; word-wrap: break-word; border-radius: ${defaultBorderRadius}; background-color: ${secondaryDark}; } pre > code { background-color: ${secondaryDark}; color: ${vscForeground}; } background-color: ${vscBackground}; font-family: "Lexend", sans-serif; font-size: 13px; padding: 8px; color: ${vscForeground}; `; // #endregion function StepContainer(props: StepContainerProps) { const [isHovered, setIsHovered] = useState(false); const naturalLanguageInputRef = useRef(null); const userInputRef = useRef(null); const isUserInput = props.historyNode.step.name === "UserInputStep"; const client = useContext(GUIClientContext); useEffect(() => { if (userInputRef?.current) { userInputRef.current.focus(); } }, [userInputRef]); useEffect(() => { if (isHovered) { naturalLanguageInputRef.current?.focus(); } }, [isHovered]); return ( { setIsHovered(true); }} onMouseLeave={() => { setIsHovered(false); }} hidden={props.historyNode.step.hide as any} > { if (isMetaEquivalentKeyPressed(e)) { props.onToggleAll(); } else { props.onToggle(); } }} >
{!isUserInput && (props.open ? ( ) : ( ))} {props.historyNode.observation?.title || (props.historyNode.step.name as any)}
{/* { e.stopPropagation(); props.onReverse(); }} > */} <> {(props.historyNode.logs as any)?.length > 0 && ( { e.stopPropagation(); client?.showLogsAtIndex(props.index); }} > )} { e.stopPropagation(); props.onDelete(); }} text={ props.historyNode.active ? `Stop (${getMetaKeyLabel()}⌫)` : "Delete" } > {props.historyNode.active ? ( ) : ( )} {props.historyNode.observation?.error ? ( { e.stopPropagation(); props.onRetry(); }} > ) : ( <> )}
); } export default StepContainer;