| @@ -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> | |||
| { | |||
| @@ -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' />)} | |||
| @@ -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> | |||
| @@ -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 */} | |||
| @@ -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} | |||
| @@ -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> | |||
| @@ -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, | |||
| @@ -80,6 +80,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({ | |||
| </Field> | |||
| <Split /> | |||
| <CodeEditor | |||
| isInNode | |||
| readOnly={readOnly} | |||
| title={ | |||
| <TypeSelector | |||
| @@ -37,6 +37,7 @@ const BulkEdit: FC<Props> = ({ | |||
| return ( | |||
| <div> | |||
| <TextEditor | |||
| isInNode | |||
| title={<div className='uppercase'>{t(`${i18nPrefix}.bulkEdit`)}</div>} | |||
| value={tempValue} | |||
| onChange={handleChange} | |||
| @@ -29,6 +29,7 @@ const AdvancedSetting: FC<Props> = ({ | |||
| return ( | |||
| <> | |||
| <TextEditor | |||
| isInNode | |||
| title={t(`${i18nPrefix}.instruction`)!} | |||
| value={instruction} | |||
| onChange={onInstructionChange} | |||
| @@ -31,6 +31,7 @@ const ClassItem: FC<Props> = ({ | |||
| return ( | |||
| <TextEditor | |||
| isInNode | |||
| title={<div> | |||
| <div className='w-[200px]'> | |||
| <div | |||
| @@ -62,6 +62,7 @@ const Panel: FC<NodePanelProps<TemplateTransformNodeType>> = ({ | |||
| </Field> | |||
| <Split /> | |||
| <CodeEditor | |||
| isInNode | |||
| readOnly={readOnly} | |||
| language={CodeLanguage.python3} | |||
| title={ | |||