-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[editor] ErrorBoundary Renderer for PromptInput #799
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { ActionIcon, Tooltip } from "@mantine/core"; | ||
import { IconBraces, IconBracesOff } from "@tabler/icons-react"; | ||
|
||
type Props = { | ||
isRawJSON: boolean; | ||
setIsRawJSON: (value: boolean) => void; | ||
}; | ||
|
||
export default function JSONEditorToggleButton({ | ||
isRawJSON, | ||
setIsRawJSON, | ||
}: Props) { | ||
return ( | ||
<Tooltip label="Toggle JSON editor" withArrow> | ||
<ActionIcon onClick={() => setIsRawJSON(!isRawJSON)}> | ||
{isRawJSON ? <IconBracesOff size="1rem" /> : <IconBraces size="1rem" />} | ||
</ActionIcon> | ||
</Tooltip> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,27 +3,63 @@ import { memo, useState } from "react"; | |
import { PromptInputSchema } from "../../../utils/promptUtils"; | ||
import PromptInputSchemaRenderer from "./schema_renderer/PromptInputSchemaRenderer"; | ||
import PromptInputConfigRenderer from "./PromptInputConfigRenderer"; | ||
import { ActionIcon, Flex, Tooltip } from "@mantine/core"; | ||
import { IconBraces, IconBracesOff } from "@tabler/icons-react"; | ||
import { Flex } from "@mantine/core"; | ||
import PromptInputJSONRenderer from "./PromptInputJSONRenderer"; | ||
import { ErrorBoundary, useErrorBoundary } from "react-error-boundary"; | ||
import { Text } from "@mantine/core"; | ||
import JSONRenderer from "../../JSONRenderer"; | ||
import JSONEditorToggleButton from "../../JSONEditorToggleButton"; | ||
|
||
type Props = { | ||
input: PromptInput; | ||
schema?: PromptInputSchema; | ||
onChangeInput: (value: PromptInput) => void; | ||
}; | ||
|
||
type ErrorFallbackProps = { | ||
input: PromptInput; | ||
toggleJSONEditor: () => void; | ||
}; | ||
|
||
function InputErrorFallback({ input, toggleJSONEditor }: ErrorFallbackProps) { | ||
const { resetBoundary: clearRenderError } = useErrorBoundary(); | ||
return ( | ||
<Flex direction="column"> | ||
<Text color="red" size="sm"> | ||
Invalid input format for model. Toggle JSON editor to update | ||
</Text> | ||
<JSONRenderer content={input} /> | ||
<Flex justify="flex-end"> | ||
<JSONEditorToggleButton | ||
isRawJSON={false} | ||
setIsRawJSON={() => { | ||
clearRenderError(); | ||
toggleJSONEditor(); | ||
}} | ||
/> | ||
</Flex> | ||
</Flex> | ||
); | ||
} | ||
|
||
export default memo(function PromptInputRenderer({ | ||
input, | ||
schema, | ||
onChangeInput, | ||
}: Props) { | ||
const [isRawJSON, setIsRawJSON] = useState(false); | ||
return ( | ||
const rawJSONToggleButton = ( | ||
<Flex justify="flex-end"> | ||
<JSONEditorToggleButton | ||
isRawJSON={isRawJSON} | ||
setIsRawJSON={setIsRawJSON} | ||
/> | ||
</Flex> | ||
); | ||
|
||
const nonJSONRenderer = ( | ||
<> | ||
{isRawJSON ? ( | ||
<PromptInputJSONRenderer input={input} onChangeInput={onChangeInput} /> | ||
) : schema ? ( | ||
{schema ? ( | ||
<PromptInputSchemaRenderer | ||
input={input} | ||
schema={schema} | ||
|
@@ -35,17 +71,34 @@ export default memo(function PromptInputRenderer({ | |
onChangeInput={onChangeInput} | ||
/> | ||
)} | ||
<Flex justify="flex-end"> | ||
<Tooltip label="Toggle JSON editor" withArrow> | ||
<ActionIcon onClick={() => setIsRawJSON((curr) => !curr)}> | ||
{isRawJSON ? ( | ||
<IconBracesOff size="1rem" /> | ||
) : ( | ||
<IconBraces size="1rem" /> | ||
)} | ||
</ActionIcon> | ||
</Tooltip> | ||
</Flex> | ||
{rawJSONToggleButton} | ||
</> | ||
); | ||
|
||
return ( | ||
<> | ||
{isRawJSON ? ( | ||
<> | ||
<PromptInputJSONRenderer | ||
input={input} | ||
onChangeInput={onChangeInput} | ||
/> | ||
{rawJSONToggleButton} | ||
</> | ||
) : ( | ||
<ErrorBoundary | ||
fallbackRender={() => ( | ||
<InputErrorFallback | ||
input={input} | ||
// Fallback is only shown when an error occurs in non-JSON renderer | ||
// so toggle must be to JSON editor | ||
toggleJSONEditor={() => setIsRawJSON(true)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is confusing because it only gets called during the Can we rename this to make ti more intuitive, or leave a comment in code explaining what's happening There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's implicitly assuming that the current state of
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll leave a comment in the code.
|
||
/> | ||
)} | ||
> | ||
{nonJSONRenderer} | ||
</ErrorBoundary> | ||
)} | ||
</> | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: delete
resetBoundary
since we don't use itThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do use it -- this just renames it to
clearRenderError
since I foundresetBoundary
to be a bit unclear