diff --git a/package.json b/package.json index 9953a712..969847cc 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "lucide-react": "^0.441.0", "next": "14.2.7", "react": "^18", + "react-contenteditable": "^3.3.7", "react-dom": "^18", "react-json-view": "^1.21.3", "react-markdown": "^9.0.1", diff --git a/src/app/api/[..._path]/route.ts b/src/app/api/[..._path]/route.ts index c2f6328a..03950e41 100644 --- a/src/app/api/[..._path]/route.ts +++ b/src/app/api/[..._path]/route.ts @@ -30,7 +30,7 @@ async function handleRequest(req: NextRequest, method: string) { options.body = await req.text(); } - const apiUrl = process.env.LANGGRAPH_API_URL ?? "http://localhost:57515"; + const apiUrl = process.env.LANGGRAPH_API_URL ?? "http://localhost:51356"; const res = await fetch(`${apiUrl}/${path}${queryString}`, options); const headers = new Headers({ diff --git a/src/components/LangSmithLinkToolUI.tsx b/src/components/LangSmithLinkToolUI.tsx index df0fdc1b..fe6bf0f7 100644 --- a/src/components/LangSmithLinkToolUI.tsx +++ b/src/components/LangSmithLinkToolUI.tsx @@ -8,7 +8,6 @@ export const useLangSmithLinkToolUI = () => useAssistantToolUI({ toolName: "langsmith_tool_ui", render: useCallback((input) => { - return ( { const selection = window.getSelection(); @@ -232,37 +233,53 @@ export function ArtifactRenderer(props: ArtifactRendererProps) { return (
-
- props.setSelectedArtifactById(undefined)} - > - - -

{props.artifact.title}

+
+
+ props.setSelectedArtifactById(undefined)} + > + + +

{props.artifact.title}

+
+ {props.artifact.type === "text" ? ( +
+ setIsEditing((v) => !v)} + > + {isEditing ? : } + +
+ ) : null}
-
-
+
{props.artifact.type === "text" ? ( - + ) : null} {props.artifact.type === "code" ? ( diff --git a/src/components/artifacts/CodeRenderer.module.css b/src/components/artifacts/CodeRenderer.module.css index 5ab9abac..97648959 100644 --- a/src/components/artifacts/CodeRenderer.module.css +++ b/src/components/artifacts/CodeRenderer.module.css @@ -1,23 +1,3 @@ -/* .codeMirrorCustom :global(.cm-focused) { - outline: none !important; -} - -.codeMirrorCustom :global(.cm-editor) { - border: none !important; -} - -.codeMirrorCustom :global(.cm-focused) { - outline: none !important; -} - -.codeMirrorCustom :global(.cm-editor) { - border: none !important; -} - -.codeMirrorCustom :global(.cm-gutters) { - border-right: none !important; -} */ - .codeMirrorCustom { height: 100vh !important; overflow: hidden; diff --git a/src/components/artifacts/TextRenderer.module.css b/src/components/artifacts/TextRenderer.module.css new file mode 100644 index 00000000..bcd5e268 --- /dev/null +++ b/src/components/artifacts/TextRenderer.module.css @@ -0,0 +1,35 @@ +.mdEditorCustom { + height: 100% !important; + overflow: hidden; +} + +.mdEditorCustom :global(.w-md-editor) { + height: 100% !important; + border: none !important; +} + +.mdEditorCustom :global(.w-md-editor-content) { + height: 100% !important; +} + +.mdEditorCustom :global(.w-md-editor-text), +.mdEditorCustom :global(.w-md-editor-text-pre), +.mdEditorCustom :global(.w-md-editor-text-input) { + min-height: 100% !important; + height: 100% !important; +} + +.mdEditorCustom :global(.w-md-editor-preview) { + box-shadow: none !important; + border-left: 1px solid #e0e0e0; +} + +.mdEditorCustom :global(.w-md-editor-toolbar) { + border-bottom: none !important; +} + +/* Force full height for text area */ +.fullHeightTextArea :global(.w-md-editor-text-input) { + min-height: 100vh !important; + height: 100% !important; +} diff --git a/src/components/artifacts/TextRenderer.tsx b/src/components/artifacts/TextRenderer.tsx index 5a230b89..6ce1364e 100644 --- a/src/components/artifacts/TextRenderer.tsx +++ b/src/components/artifacts/TextRenderer.tsx @@ -1,39 +1,42 @@ import { Artifact } from "@/types"; import MDEditor from "@uiw/react-md-editor"; -import { useCallback, useEffect, useState } from "react"; +import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react"; -export interface TextRendererProps { - artifact: Artifact; -} +import styles from "./TextRenderer.module.css"; -export function TextRenderer(props: TextRendererProps) { +export function TextRenderer({ + artifact, + isEditing, + setIsEditing, +}: { + artifact: Artifact; + isEditing: boolean; + setIsEditing: Dispatch>; +}) { const [value, setValue] = useState(""); + const hasSetInitial = useRef(false); useEffect(() => { - setValue(props.artifact.content); - }, [props.artifact.content]); - - const handleEdit = useCallback((event: React.FormEvent) => { - const newValue = event.currentTarget.innerText; - setValue(newValue); - }, []); + if (!hasSetInitial.current) { + if (artifact.title === "Quickstart text") { + setIsEditing(true); + } else { + setValue(artifact.content); + } + hasSetInitial.current = true; + } + }, [artifact.content]); return ( -
+
setValue(v || "")} + className={`min-h-full border-none ${styles.mdEditorCustom} ${styles.fullHeightTextArea}`} + height="100%" />
); diff --git a/yarn.lock b/yarn.lock index cddce572..162a318f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4601,7 +4601,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.8.1: +prop-types@^15.7.1, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -4647,6 +4647,14 @@ react-base16-styling@^0.6.0: lodash.flow "^3.3.0" pure-color "^1.2.0" +react-contenteditable@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/react-contenteditable/-/react-contenteditable-3.3.7.tgz#18dd1f281841ba2c2b306e2d28278bc31b7929ed" + integrity sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ== + dependencies: + fast-deep-equal "^3.1.3" + prop-types "^15.7.1" + react-dom@^18: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"