summaryrefslogtreecommitdiff
path: root/extension/react-app/src/components/StepContainer.tsx
diff options
context:
space:
mode:
authorNate Sesti <33237525+sestinj@users.noreply.github.com>2023-09-23 13:06:00 -0700
committerGitHub <noreply@github.com>2023-09-23 13:06:00 -0700
commite976d60974a7837967d03807605cbf2e7b4f3f9a (patch)
tree5ecb19062abb162832530dd953e9d2801026c23c /extension/react-app/src/components/StepContainer.tsx
parent470711d25b44d1a545c57bc17d40d5e1fd402216 (diff)
downloadsncontinue-e976d60974a7837967d03807605cbf2e7b4f3f9a.tar.gz
sncontinue-e976d60974a7837967d03807605cbf2e7b4f3f9a.tar.bz2
sncontinue-e976d60974a7837967d03807605cbf2e7b4f3f9a.zip
UI Redesign and fixing many details (#496)
* feat: :lipstick: start of major design upgrade * feat: :lipstick: model selection page * feat: :lipstick: use shortcut to add highlighted code as ctx * feat: :lipstick: better display of errors * feat: :lipstick: ui for learning keyboard shortcuts, more details * refactor: :construction: testing slash commands ui * Truncate continue.log * refactor: :construction: refactoring client_session, ui, more * feat: :bug: layout fixes * refactor: :lipstick: ui to enter OpenAI Key * refactor: :truck: rename MaybeProxyOpenAI -> OpenAIFreeTrial * starting help center * removing old shortcut docs * fix: :bug: fix model setting logic to avoid overwrites * feat: :lipstick: tutorial and model descriptions * refactor: :truck: rename unused -> saved * refactor: :truck: rename model roles * feat: :lipstick: edit indicator * refactor: :lipstick: move +, folder icons * feat: :lipstick: tab to clear all context * fix: :bug: context providers ui fixes * fix: :bug: fix lag when stopping step * fix: :bug: don't override system message for models * fix: :bug: fix continue button cursor * feat: :lipstick: title bar * fix: :bug: updates to code highlighting logic and more * fix: :bug: fix renaming of summarize model role * feat: :lipstick: help page and better session title * feat: :lipstick: more help page / ui improvements * feat: :lipstick: set session title * fix: :bug: small fixes for changing sessions * fix: :bug: perfecting the highlighting code and ctx interactions * style: :lipstick: sticky headers for scroll, ollama warming * fix: :bug: fix toggle bug --------- Co-authored-by: Ty Dunn <ty@tydunn.com>
Diffstat (limited to 'extension/react-app/src/components/StepContainer.tsx')
-rw-r--r--extension/react-app/src/components/StepContainer.tsx241
1 files changed, 50 insertions, 191 deletions
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index a05aefb0..61529227 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -1,18 +1,9 @@
-import { useContext, useEffect, useRef, useState } from "react";
-import styled, { keyframes } from "styled-components";
-import { secondaryDark, vscBackground } from ".";
-import {
- ChevronDownIcon,
- ChevronRightIcon,
- ArrowPathIcon,
- XMarkIcon,
- MagnifyingGlassIcon,
- StopCircleIcon,
-} from "@heroicons/react/24/outline";
+import { useEffect, useRef, useState } from "react";
+import styled from "styled-components";
+import { defaultBorderRadius, secondaryDark, vscBackground } from ".";
+import { ArrowPathIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { HistoryNode } from "../../../schema/HistoryNode";
import HeaderButtonWithText from "./HeaderButtonWithText";
-import { getMetaKeyLabel, isMetaEquivalentKeyPressed } from "../util";
-import { GUIClientContext } from "../App";
import StyledMarkdownPreview from "./StyledMarkdownPreview";
interface StepContainerProps {
@@ -23,11 +14,10 @@ interface StepContainerProps {
onRetry: () => void;
onDelete: () => void;
open: boolean;
- onToggleAll: () => void;
- onToggle: () => void;
isFirst: boolean;
isLast: boolean;
index: number;
+ noUserInputParent: boolean;
}
// #region styled components
@@ -35,74 +25,30 @@ interface StepContainerProps {
const MainDiv = styled.div<{
stepDepth: number;
inFuture: boolean;
-}>`
- opacity: ${(props) => (props.inFuture ? 0.3 : 1)};
- overflow: hidden;
- margin-left: 0px;
- margin-right: 0px;
-`;
+}>``;
-const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>`
- background-color: ${(props) => (props.error ? "#522" : vscBackground)};
- display: grid;
- grid-template-columns: 1fr auto auto;
+const ButtonsDiv = styled.div`
+ display: flex;
+ gap: 2px;
align-items: center;
- padding-right: 8px;
-`;
+ background-color: ${vscBackground};
+ box-shadow: 1px 1px 10px ${vscBackground};
+ border-radius: ${defaultBorderRadius};
-const LeftHeaderSubDiv = styled.div`
- margin: 8px;
- display: grid;
- grid-template-columns: auto 1fr;
- align-items: center;
- grid-gap: 2px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ height: 0;
`;
const ContentDiv = styled.div<{ isUserInput: boolean }>`
- padding-left: 4px;
- padding-right: 2px;
+ padding: 2px;
+ padding-right: 0px;
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,
- #1BBE84 0%,
- #331BBE 16%,
- #BE1B55 33%,
- #A6BE1B 55%,
- #BE1B55 67%,
- #331BBE 85%,
- #1BBE84 99%
- )`};
- animation: ${(props) => (props.loading ? gradient : "")} 6s linear infinite;
- background-size: 200% 200%;
+ border-radius: ${defaultBorderRadius};
+ overflow: hidden;
`;
// #endregion
@@ -112,7 +58,6 @@ function StepContainer(props: StepContainerProps) {
const naturalLanguageInputRef = useRef<HTMLTextAreaElement>(null);
const userInputRef = useRef<HTMLInputElement>(null);
const isUserInput = props.historyNode.step.name === "UserInputStep";
- const client = useContext(GUIClientContext);
useEffect(() => {
if (userInputRef?.current) {
@@ -139,91 +84,11 @@ function StepContainer(props: StepContainerProps) {
hidden={props.historyNode.step.hide as any}
>
<div>
- <GradientBorder
- loading={props.historyNode.active as boolean}
- isFirst={props.isFirst}
- isLast={props.isLast}
- borderColor={
- props.historyNode.observation?.error
- ? "#f005"
- : props.historyNode.active
- ? undefined
- : "transparent"
- }
- className="overflow-hidden cursor-pointer"
- onClick={(e) => {
- if (isMetaEquivalentKeyPressed(e)) {
- props.onToggleAll();
- } else {
- props.onToggle();
- }
- }}
- >
- <HeaderDiv
- loading={(props.historyNode.active as boolean) || false}
- error={props.historyNode.observation?.error ? true : false}
- >
- <LeftHeaderSubDiv
- style={
- props.historyNode.observation?.error ? { color: "white" } : {}
- }
- >
- {!isUserInput &&
- (props.open ? (
- <ChevronDownIcon width="1.4em" height="1.4em" />
- ) : (
- <ChevronRightIcon width="1.4em" height="1.4em" />
- ))}
- {props.historyNode.observation?.title ||
- (props.historyNode.step.name as any)}
- </LeftHeaderSubDiv>
- {/* <HeaderButton
- onClick={(e) => {
- e.stopPropagation();
- props.onReverse();
- }}
- >
- <Backward size="1.6em" onClick={props.onReverse}></Backward>
- </HeaderButton> */}
- {(isHovered || (props.historyNode.active as boolean)) && (
- <div className="flex gap-2 items-center">
- {(props.historyNode.logs as any)?.length > 0 && (
- <HeaderButtonWithText
- text="Logs"
- onClick={(e) => {
- e.stopPropagation();
- client?.showLogsAtIndex(props.index);
- }}
- >
- <MagnifyingGlassIcon width="1.4em" height="1.4em" />
- </HeaderButtonWithText>
- )}
- <HeaderButtonWithText
- onClick={(e) => {
- e.stopPropagation();
- props.onDelete();
- }}
- text={
- props.historyNode.active
- ? `Stop (${getMetaKeyLabel()}⌫)`
- : "Delete"
- }
- >
- {props.historyNode.active ? (
- <StopCircleIcon
- width="1.4em"
- height="1.4em"
- onClick={props.onDelete}
- />
- ) : (
- <XMarkIcon
- width="1.4em"
- height="1.4em"
- onClick={props.onDelete}
- />
- )}
- </HeaderButtonWithText>
- {props.historyNode.observation?.error ? (
+ {isHovered &&
+ (props.historyNode.observation?.error || props.noUserInputParent) && (
+ <ButtonsDiv>
+ {props.historyNode.observation?.error &&
+ ((
<HeaderButtonWithText
text="Retry"
onClick={(e) => {
@@ -237,39 +102,33 @@ function StepContainer(props: StepContainerProps) {
onClick={props.onRetry}
/>
</HeaderButtonWithText>
- ) : (
- <></>
- )}
- </div>
- )}
- </HeaderDiv>
- </GradientBorder>
- <ContentDiv hidden={!props.open} isUserInput={isUserInput}>
- {props.open && false && (
- <>
- <pre className="overflow-x-scroll">
- Step Details:
- <br />
- {JSON.stringify(props.historyNode.step, null, 2)}
- </pre>
- </>
- )}
+ ) as any)}
- {props.historyNode.observation?.error ? (
- <details>
- <summary>View Traceback</summary>
- <pre className="overflow-x-scroll">
- {props.historyNode.observation.error as string}
- </pre>
- </details>
- ) : (
- <StyledMarkdownPreview
- source={props.historyNode.step.description || ""}
- wrapperElement={{
- "data-color-mode": "dark",
- }}
- />
+ {props.noUserInputParent && (
+ <HeaderButtonWithText
+ text="Delete"
+ onClick={(e) => {
+ e.stopPropagation();
+ props.onDelete();
+ }}
+ >
+ <XMarkIcon
+ width="1.4em"
+ height="1.4em"
+ onClick={props.onRetry}
+ />
+ </HeaderButtonWithText>
+ )}
+ </ButtonsDiv>
)}
+
+ <ContentDiv hidden={!props.open} isUserInput={isUserInput}>
+ <StyledMarkdownPreview
+ source={props.historyNode.step.description || ""}
+ wrapperElement={{
+ "data-color-mode": "dark",
+ }}
+ />
</ContentDiv>
</div>
</MainDiv>