Commit d3dfadbd authored by Joel's avatar Joel

feat: add code editor

parent e474e02a
...@@ -32,8 +32,8 @@ const allMockData = { ...@@ -32,8 +32,8 @@ const allMockData = {
[BlockEnum.End]: EndNodeMock, [BlockEnum.End]: EndNodeMock,
} }
const nodes = [ const nodes = [
BlockEnum.Start/* 1 */, BlockEnum.QuestionClassifier/* 5 */, BlockEnum.DirectAnswer/* 2 */, BlockEnum.LLM/* 3 */, BlockEnum.KnowledgeRetrieval/* 4 */, BlockEnum.Code/* 7 */, BlockEnum.Start/* 1 */, BlockEnum.QuestionClassifier/* 5 */, BlockEnum.DirectAnswer/* 2 */, BlockEnum.LLM/* 3 */, BlockEnum.KnowledgeRetrieval/* 4 */,
BlockEnum.IfElse/* 6 */, BlockEnum.Code/* 7 */, BlockEnum.TemplateTransform/* 8 */, BlockEnum.HttpRequest/* 9 */, BlockEnum.Tool/* 10 */, BlockEnum.IfElse/* 6 */, BlockEnum.TemplateTransform/* 8 */, BlockEnum.HttpRequest/* 9 */, BlockEnum.Tool/* 10 */,
BlockEnum.VariableAssigner/* 11 */, BlockEnum.End/* 12 */, BlockEnum.VariableAssigner/* 11 */, BlockEnum.End/* 12 */,
].map((item, i) => { ].map((item, i) => {
const payload = allMockData[item] const payload = allMockData[item]
...@@ -78,7 +78,6 @@ const Page: FC = () => { ...@@ -78,7 +78,6 @@ const Page: FC = () => {
<Workflow <Workflow
nodes={initialNodes} nodes={initialNodes}
edges={initialEdges} edges={initialEdges}
selectedNodeId='1'
/> />
</div> </div>
) )
......
...@@ -40,7 +40,7 @@ const Base: FC<Props> = ({ ...@@ -40,7 +40,7 @@ const Base: FC<Props> = ({
}, [isExpanded]) }, [isExpanded])
return ( return (
<div className={cn(className, 'rounded-lg border', isFocus ? 'bg-white border-gray-200' : 'bg-gray-100 border-gray-100')}> <div className={cn(className, 'rounded-lg border', isFocus ? 'bg-white border-gray-200' : 'bg-gray-100 border-gray-100 overflow-hidden')}>
<div className='flex justify-between items-center h-7 pt-1 pl-3 pr-1'> <div className='flex justify-between items-center h-7 pt-1 pl-3 pr-1'>
<div className='text-xs font-semibold text-gray-700'>{title}</div> <div className='text-xs font-semibold text-gray-700'>{title}</div>
<div className='flex items-center'> <div className='flex items-center'>
......
'use client' 'use client'
import type { FC } from 'react' import type { FC } from 'react'
import Editor from '@monaco-editor/react'
import React from 'react' import React from 'react'
import Base from './base' import Base from './base'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
type Props = { type Props = {
value: string value: string
onChange: (value: string) => void onChange: (value: string) => void
title: JSX.Element title: JSX.Element
language?: string language: CodeLanguage
headerRight?: JSX.Element headerRight?: JSX.Element
} }
...@@ -16,9 +18,13 @@ const CodeEditor: FC<Props> = ({ ...@@ -16,9 +18,13 @@ const CodeEditor: FC<Props> = ({
onChange, onChange,
title, title,
headerRight, headerRight,
language,
}) => { }) => {
const [isFocus, setIsFocus] = React.useState(false) const [isFocus, setIsFocus] = React.useState(false)
const handleEditorChange = (value: string | undefined) => {
onChange(value || '')
}
return ( return (
<div> <div>
<Base <Base
...@@ -26,15 +32,24 @@ const CodeEditor: FC<Props> = ({ ...@@ -26,15 +32,24 @@ const CodeEditor: FC<Props> = ({
value={value} value={value}
headerRight={headerRight} headerRight={headerRight}
isFocus={isFocus} isFocus={isFocus}
minHeight={86} minHeight={200}
> >
<textarea {/* https://www.npmjs.com/package/@monaco-editor/react */}
<Editor
className='h-full'
defaultLanguage={language === CodeLanguage.javascript ? 'javascript' : 'python'}
value={value} value={value}
onChange={e => onChange(e.target.value)} onChange={handleEditorChange}
onFocus={() => setIsFocus(true)} // https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOptions.html
onBlur={() => setIsFocus(false)} options={{
className='w-full h-full p-3 resize-none bg-transparent' quickSuggestions: false,
minimap: { enabled: false },
// lineNumbers: (num) => {
// return <div>{num}</div>
// }
}}
/> />
</Base> </Base>
</div> </div>
) )
......
...@@ -57,6 +57,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({ ...@@ -57,6 +57,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
/> />
</Field> </Field>
<Split /> <Split />
{inputs.code_language}
<CodeEditor <CodeEditor
title={ title={
<TypeSelector <TypeSelector
...@@ -65,6 +66,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({ ...@@ -65,6 +66,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
onChange={handleCodeLanguageChange} onChange={handleCodeLanguageChange}
/> />
} }
language={inputs.code_language}
value={inputs.code} value={inputs.code}
onChange={handleCodeChange} onChange={handleCodeChange}
/> />
......
...@@ -17,14 +17,14 @@ const useConfig = (id: string, payload: CodeNodeType) => { ...@@ -17,14 +17,14 @@ const useConfig = (id: string, payload: CodeNodeType) => {
draft.code = code draft.code = code
}) })
setInputs(newInputs) setInputs(newInputs)
}, [setInputs]) }, [inputs, setInputs])
const handleCodeLanguageChange = useCallback((codeLanguage: CodeLanguage) => { const handleCodeLanguageChange = useCallback((codeLanguage: CodeLanguage) => {
const newInputs = produce(inputs, (draft) => { const newInputs = produce(inputs, (draft) => {
draft.code_language = codeLanguage draft.code_language = codeLanguage
}) })
setInputs(newInputs) setInputs(newInputs)
}, [setInputs]) }, [inputs, setInputs])
const { handleVarListChange: handleOutputVarListChange, handleAddVariable: handleAddOutputVariable } = useOutputVarList<CodeNodeType>({ const { handleVarListChange: handleOutputVarListChange, handleAddVariable: handleAddOutputVariable } = useOutputVarList<CodeNodeType>({
inputs, inputs,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
"@lexical/react": "^0.12.2", "@lexical/react": "^0.12.2",
"@mdx-js/loader": "^2.3.0", "@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "^2.3.0", "@mdx-js/react": "^2.3.0",
"@monaco-editor/react": "^4.6.0",
"@next/mdx": "^14.0.4", "@next/mdx": "^14.0.4",
"@sentry/react": "^7.54.0", "@sentry/react": "^7.54.0",
"@sentry/utils": "^7.54.0", "@sentry/utils": "^7.54.0",
......
...@@ -490,6 +490,20 @@ ...@@ -490,6 +490,20 @@
resolved "https://registry.npmjs.org/@miragejs/pretender-node-polyfill/-/pretender-node-polyfill-0.1.2.tgz" resolved "https://registry.npmjs.org/@miragejs/pretender-node-polyfill/-/pretender-node-polyfill-0.1.2.tgz"
integrity sha512-M/BexG/p05C5lFfMunxo/QcgIJnMT2vDVCd00wNqK2ImZONIlEETZwWJu1QtLxtmYlSHlCFl3JNzp0tLe7OJ5g== integrity sha512-M/BexG/p05C5lFfMunxo/QcgIJnMT2vDVCd00wNqK2ImZONIlEETZwWJu1QtLxtmYlSHlCFl3JNzp0tLe7OJ5g==
"@monaco-editor/loader@^1.4.0":
version "1.4.0"
resolved "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz"
integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==
dependencies:
state-local "^1.0.6"
"@monaco-editor/react@^4.6.0":
version "4.6.0"
resolved "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz"
integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==
dependencies:
"@monaco-editor/loader" "^1.4.0"
"@next/env@14.1.0": "@next/env@14.1.0":
version "14.1.0" version "14.1.0"
resolved "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz" resolved "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz"
...@@ -5343,6 +5357,11 @@ miragejs@^0.1.47: ...@@ -5343,6 +5357,11 @@ miragejs@^0.1.47:
lodash.values "^4.3.0" lodash.values "^4.3.0"
pretender "^3.4.7" pretender "^3.4.7"
"monaco-editor@>= 0.21.0 < 1", "monaco-editor@>= 0.25.0 < 1":
version "0.46.0"
resolved "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.46.0.tgz"
integrity sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ==
mri@^1.1.0: mri@^1.1.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz"
...@@ -5957,7 +5976,7 @@ react-18-input-autosize@^3.0.0: ...@@ -5957,7 +5976,7 @@ react-18-input-autosize@^3.0.0:
dependencies: dependencies:
prop-types "^15.5.8" prop-types "^15.5.8"
react-dom@*, "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", "react-dom@^16 || ^17 || ^18", react-dom@^18.2.0, react-dom@>=16.0.0, react-dom@>=16.14.0, react-dom@>=16.8.0, react-dom@>=16.9.0, react-dom@>=17, react-dom@>=17.x: react-dom@*, "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", "react-dom@^16 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0, react-dom@>=16.0.0, react-dom@>=16.14.0, react-dom@>=16.8.0, react-dom@>=16.9.0, react-dom@>=17, react-dom@>=17.x:
version "18.2.0" version "18.2.0"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
...@@ -6676,6 +6695,11 @@ spdx-license-ids@^3.0.0: ...@@ -6676,6 +6695,11 @@ spdx-license-ids@^3.0.0:
resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz"
integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==
state-local@^1.0.6:
version "1.0.7"
resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz"
integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==
stop-iteration-iterator@^1.0.0: stop-iteration-iterator@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment