浏览代码

feat: prompt editor support auto height by content height and fix some bugs (#3712)

Joel 1 年之前
父节点
当前提交
f92130338b

+ 2 - 1
web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx

@@ -218,13 +218,14 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
               !isInWorkflow && 'px-10 pt-6 pb-8',
               isInWorkflow && 'p-4')}>
               <div className='flex items-center justify-between h-8'>
-                <div className={cn('font-semibold text-gray-900', isInWorkflow && 'text-[13px]')}>
+                <div className={cn('font-semibold text-gray-900 shrink-0', isInWorkflow && 'text-[13px]')}>
                   {t('common.modelProvider.model').toLocaleUpperCase()}
                 </div>
                 <ModelSelector
                   defaultModel={(provider || modelId) ? { provider, model: modelId } : undefined}
                   modelList={activeTextGenerationModelList}
                   onSelect={handleChangeModel}
+                  triggerClassName='max-w-[295px]'
                 />
               </div>
               {

+ 2 - 2
web/app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger.tsx

@@ -47,7 +47,7 @@ const Trigger: FC<TriggerProps> = ({
         'relative flex items-center px-2 h-8 rounded-lg  cursor-pointer',
         !isInWorkflow && 'border hover:border-[1.5px]',
         !isInWorkflow && (disabled ? 'border-[#F79009] bg-[#FFFAEB]' : 'border-[#444CE7] bg-primary-50'),
-        isInWorkflow && 'bg-gray-100 border border-gray-100  hover:border-gray-200',
+        isInWorkflow && 'pr-[30px] bg-gray-100 border border-gray-100  hover:border-gray-200',
       )}
     >
       {
@@ -103,7 +103,7 @@ const Trigger: FC<TriggerProps> = ({
             </TooltipPlus>
           )
           : (
-            <SlidersH className={cn(!isInWorkflow ? 'text-indigo-600' : 'text-gray-500', 'w-4 h-4')} />
+            <SlidersH className={cn(!isInWorkflow ? 'text-indigo-600' : 'text-gray-500', 'shrink-0 w-4 h-4')} />
           )
       }
       {isInWorkflow && (<ChevronDown className='absolute top-[9px] right-2 w-3.5 h-3.5 text-gray-500' />)}

+ 5 - 2
web/app/components/workflow/nodes/_base/components/editor/base.tsx

@@ -16,6 +16,7 @@ type Props = {
   minHeight?: number
   value: string
   isFocus: boolean
+  isInNode?: boolean
 }
 
 const Base: FC<Props> = ({
@@ -26,14 +27,16 @@ const Base: FC<Props> = ({
   minHeight = 120,
   value,
   isFocus,
+  isInNode,
 }) => {
   const ref = useRef<HTMLDivElement>(null)
   const {
     wrapClassName,
+    wrapStyle,
     isExpand,
     setIsExpand,
     editorExpandHeight,
-  } = useToggleExpend({ ref, hasFooter: false })
+  } = useToggleExpend({ ref, hasFooter: false, isInNode })
 
   const editorContentMinHeight = minHeight - 28
   const [editorContentHeight, setEditorContentHeight] = useState(editorContentMinHeight)
@@ -45,7 +48,7 @@ const Base: FC<Props> = ({
   }, [value])
 
   return (
-    <div className={cn(wrapClassName)}>
+    <div className={cn(wrapClassName)} style={wrapStyle}>
       <div ref={ref} className={cn(className, isExpand && 'h-full', '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-2'>
           <div className='text-xs font-semibold text-gray-700'>{title}</div>

+ 3 - 0
web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx

@@ -18,6 +18,7 @@ type Props = {
   readOnly?: boolean
   isJSONStringifyBeauty?: boolean
   height?: number
+  isInNode?: boolean
 }
 
 const languageMap = {
@@ -35,6 +36,7 @@ const CodeEditor: FC<Props> = ({
   readOnly,
   isJSONStringifyBeauty,
   height,
+  isInNode,
 }) => {
   const [isFocus, setIsFocus] = React.useState(false)
 
@@ -90,6 +92,7 @@ const CodeEditor: FC<Props> = ({
         headerRight={headerRight}
         isFocus={isFocus && !readOnly}
         minHeight={height || 200}
+        isInNode={isInNode}
       >
         <>
           {/* https://www.npmjs.com/package/@monaco-editor/react */}

+ 3 - 0
web/app/components/workflow/nodes/_base/components/editor/text-editor.tsx

@@ -13,6 +13,7 @@ type Props = {
   onBlur?: () => void
   placeholder?: string
   readonly?: boolean
+  isInNode?: boolean
 }
 
 const TextEditor: FC<Props> = ({
@@ -24,6 +25,7 @@ const TextEditor: FC<Props> = ({
   onBlur,
   placeholder,
   readonly,
+  isInNode,
 }) => {
   const [isFocus, {
     setTrue: setIsFocus,
@@ -43,6 +45,7 @@ const TextEditor: FC<Props> = ({
         headerRight={headerRight}
         isFocus={isFocus}
         minHeight={minHeight}
+        isInNode={isInNode}
       >
         <textarea
           value={value}

+ 19 - 32
web/app/components/workflow/nodes/_base/components/prompt/editor.tsx

@@ -12,14 +12,14 @@ import {
 } from '../../../../types'
 import ToggleExpandBtn from '@/app/components/workflow/nodes/_base/components/toggle-expand-btn'
 import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend'
-import PromptEditorHeightResizeWrap from '@/app/components/app/configuration/config-prompt/prompt-editor-height-resize-wrap'
 import PromptEditor from '@/app/components/base/prompt-editor'
 import { Clipboard, ClipboardCheck } from '@/app/components/base/icons/src/vender/line/files'
 import s from '@/app/components/app/configuration/config-prompt/style.module.css'
 import { Trash03 } from '@/app/components/base/icons/src/vender/line/general'
-import TooltipPlus from '@/app/components/base/tooltip-plus'
 import { useEventEmitterContextContext } from '@/context/event-emitter'
 import { PROMPT_EDITOR_INSERT_QUICKLY } from '@/app/components/base/prompt-editor/plugins/update-block'
+import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
+import TooltipPlus from '@/app/components/base/tooltip-plus'
 
 type Props = {
   instanceId?: string
@@ -66,12 +66,11 @@ const Editor: FC<Props> = ({
   const ref = useRef<HTMLDivElement>(null)
   const {
     wrapClassName,
+    wrapStyle,
     isExpand,
     setIsExpand,
     editorExpandHeight,
-  } = useToggleExpend({ ref })
-  const minHeight = 98
-  const [editorHeight, setEditorHeight] = React.useState(minHeight)
+  } = useToggleExpend({ ref, isInNode: true })
   const [isCopied, setIsCopied] = React.useState(false)
   const handleCopy = useCallback(() => {
     copy(value)
@@ -103,7 +102,7 @@ const Editor: FC<Props> = ({
   }
 
   return (
-    <div className={cn(wrapClassName)}>
+    <div className={cn(wrapClassName)} style={wrapStyle}>
       <div ref={ref} className={cn(isFocus ? s.gradientBorder : 'bg-gray-100', isExpand && 'h-full', '!rounded-[9px] p-0.5')}>
         <div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg')}>
           <div className='pt-1 pl-3 pr-2 flex justify-between h-6 items-center'>
@@ -113,6 +112,13 @@ const Editor: FC<Props> = ({
               <div className='w-px h-3 ml-2 mr-2 bg-gray-200'></div>
               {/* Operations */}
               <div className='flex items-center space-x-2'>
+                {!readOnly && (
+                  <TooltipPlus
+                    popupContent={`${t('workflow.common.insertVarTip')}`}
+                  >
+                    <Variable02 className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={handleInsertVariable} />
+                  </TooltipPlus>
+                )}
                 {showRemove && (
                   <Trash03 className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={onRemove} />
                 )}
@@ -129,32 +135,12 @@ const Editor: FC<Props> = ({
 
             </div>
           </div>
-          <PromptEditorHeightResizeWrap
-            className={cn(isExpand && 'h-0 grow', 'px-3 min-h-[102px] overflow-y-auto text-sm text-gray-700')}
-            height={isExpand ? editorExpandHeight : editorHeight}
-            minHeight={minHeight}
-            onHeightChange={setEditorHeight}
-            footer={(
-              <div className='pl-3 pb-2 flex'>
-                {(isFocus || isShowInsertToolTip)
-                  ? (
-                    <TooltipPlus
-                      popupContent={`${t('workflow.common.insertVarTip')}`}
-                    >
-                      <div
-                        className="h-[18px] leading-[18px] px-1 rounded-md bg-gray-100 text-xs text-gray-500"
-                        onClick={handleInsertVariable}
-                      >{'{x} '}{t('workflow.nodes.common.insertVarTip')}</div>
-                    </TooltipPlus>)
-                  : <div className='h-[18px]'></div>}
-              </div>
-            )}
-            hideResize={isExpand}
-          >
-            <>
+
+          {/* Min: 80 Max: 560. Header: 24 */}
+          <div className={cn('pb-2', isExpand && 'flex flex-col grow')}>
+            <div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'px-3 min-h-[56px]  overflow-y-auto')}>
               <PromptEditor
                 instanceId={instanceId}
-                className={cn('min-h-[84px]')}
                 compact
                 style={isExpand ? { height: editorExpandHeight - 5 } : {}}
                 value={value}
@@ -199,8 +185,9 @@ const Editor: FC<Props> = ({
               />
               {/* to patch Editor not support dynamic change editable status */}
               {readOnly && <div className='absolute inset-0 z-10'></div>}
-            </>
-          </PromptEditorHeightResizeWrap>
+            </div>
+          </div>
+
         </div>
       </div>
     </div>

+ 13 - 2
web/app/components/workflow/nodes/_base/hooks/use-toggle-expend.ts

@@ -3,20 +3,31 @@ import { useEffect, useState } from 'react'
 type Params = {
   ref: React.RefObject<HTMLDivElement>
   hasFooter?: boolean
+  isInNode?: boolean
 }
 
-const useToggleExpend = ({ ref, hasFooter = true }: Params) => {
+const useToggleExpend = ({ ref, hasFooter = true, isInNode }: Params) => {
   const [isExpand, setIsExpand] = useState(false)
   const [wrapHeight, setWrapHeight] = useState(ref.current?.clientHeight)
   const editorExpandHeight = isExpand ? wrapHeight! - (hasFooter ? 56 : 29) : 0
   useEffect(() => {
     setWrapHeight(ref.current?.clientHeight)
+  // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [isExpand])
 
-  const wrapClassName = isExpand && 'absolute z-10 left-4 right-6 top-[52px] bottom-0 pb-4 bg-white'
+  const wrapClassName = (() => {
+    if (!isExpand)
+      return ''
 
+    if (isInNode)
+      return 'fixed z-10  right-[9px] top-[166px] bottom-[8px] w-[419px] p-4 bg-white rounded-xl'
+
+    return 'absolute z-10 left-4 right-6 top-[52px] bottom-0 pb-4 bg-white'
+  })()
+  const wrapStyle = isExpand ? { boxShadow: '0px 0px 12px -4px rgba(16, 24, 40, 0.05), 0px -3px 6px -2px rgba(16, 24, 40, 0.03)' } : {}
   return {
     wrapClassName,
+    wrapStyle,
     editorExpandHeight,
     isExpand,
     setIsExpand,

+ 1 - 0
web/app/components/workflow/nodes/code/panel.tsx

@@ -80,6 +80,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
         </Field>
         <Split />
         <CodeEditor
+          isInNode
           readOnly={readOnly}
           title={
             <TypeSelector

+ 1 - 0
web/app/components/workflow/nodes/http/components/key-value/bulk-edit/index.tsx

@@ -37,6 +37,7 @@ const BulkEdit: FC<Props> = ({
   return (
     <div>
       <TextEditor
+        isInNode
         title={<div className='uppercase'>{t(`${i18nPrefix}.bulkEdit`)}</div>}
         value={tempValue}
         onChange={handleChange}

+ 1 - 0
web/app/components/workflow/nodes/question-classifier/components/advanced-setting.tsx

@@ -29,6 +29,7 @@ const AdvancedSetting: FC<Props> = ({
   return (
     <>
       <TextEditor
+        isInNode
         title={t(`${i18nPrefix}.instruction`)!}
         value={instruction}
         onChange={onInstructionChange}

+ 1 - 0
web/app/components/workflow/nodes/question-classifier/components/class-item.tsx

@@ -31,6 +31,7 @@ const ClassItem: FC<Props> = ({
 
   return (
     <TextEditor
+      isInNode
       title={<div>
         <div className='w-[200px]'>
           <div

+ 1 - 0
web/app/components/workflow/nodes/template-transform/panel.tsx

@@ -62,6 +62,7 @@ const Panel: FC<NodePanelProps<TemplateTransformNodeType>> = ({
         </Field>
         <Split />
         <CodeEditor
+          isInNode
           readOnly={readOnly}
           language={CodeLanguage.python3}
           title={