mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
V4.6.9-first commit (#899)
* perf: insert mongo dataset data session * perf: dataset data index * remove delay * rename bill schema * rename bill record * perf: bill table * perf: prompt * perf: sub plan * change the usage count * feat: usage bill * publish usages * doc * 新增团队聊天功能 (#20) * perf: doc * feat 添加标签部分 feat 信息团队标签配置 feat 新增团队同步管理 feat team分享页面 feat 完成team分享页面 feat 实现模糊搜索 style 格式化 fix 修复迷糊匹配 style 样式修改 fix 团队标签功能修复 * fix 修复鉴权功能 * merge 合并代码 * fix 修复引用错误 * fix 修复pr问题 * fix 修复ts格式问题 --------- Co-authored-by: archer <545436317@qq.com> Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com> * update extra plan * fix: ts * format * perf: bill field * feat: standard plan * fix: ts * feat 个人账号页面修改 (#22) * feat 添加标签部分 feat 信息团队标签配置 feat 新增团队同步管理 feat team分享页面 feat 完成team分享页面 feat 实现模糊搜索 style 格式化 fix 修复迷糊匹配 style 样式修改 fix 团队标签功能修复 * fix 修复鉴权功能 * merge 合并代码 * fix 修复引用错误 * fix 修复pr问题 * fix 修复ts格式问题 * feat 修改个人账号页 --------- Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com> * sub plan page (#23) * fix chunk index; error page text * feat: dataset process Integral prediction * feat: stand plan field * feat: sub plan limit * perf: index * query extension * perf: share link push app name * perf: plan point unit * perf: get sub plan * perf: account page * feat 新增套餐详情弹窗代码 (#24) * merge 合并代码 * fix 新增套餐详情弹框 * fix 修复pr问题 * feat: change http node input to prompt editor (#21) * feat: change http node input to prompt editor * fix * split PromptEditor to HttpInput * Team plans (#25) * perf: pay check * perf: team plan test * plan limit check * replace sensitive text * perf: fix some null * collection null check * perf: plans modal * perf: http module * pacakge (#26) * individuation page and pay modal amount (#27) * feat: individuation page * team chat config * pay modal * plan count and replace invalid chars (#29) * fix: user oneapi * fix: training queue * fix: qa queue * perf: remove space chars * replace invalid chars * change httpinput dropdown menu (#28) * perf: http * reseet free plan * perf: plan code to packages * remove llm config to package * perf: code * perf: faq * fix: get team plan --------- Co-authored-by: yst <77910600+yu-and-liu@users.noreply.github.com> Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com> Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
@@ -45,10 +45,19 @@ const options = {
|
||||
tabSize: 2
|
||||
};
|
||||
|
||||
const JSONEditor = ({ defaultValue, value, onChange, resize, variables = [], ...props }: Props) => {
|
||||
const JSONEditor = ({
|
||||
defaultValue,
|
||||
value,
|
||||
onChange,
|
||||
resize,
|
||||
variables = [],
|
||||
placeholder,
|
||||
...props
|
||||
}: Props) => {
|
||||
const { toast } = useToast();
|
||||
const { t } = useTranslation();
|
||||
const [height, setHeight] = useState(props.height || 100);
|
||||
const [placeholderDisplay, setPlaceholderDisplay] = useState('block');
|
||||
const initialY = useRef(0);
|
||||
const completionRegisterRef = useRef<any>();
|
||||
const monaco = useMonaco();
|
||||
@@ -217,6 +226,7 @@ const JSONEditor = ({ defaultValue, value, onChange, resize, variables = [], ...
|
||||
borderColor={'myGray.200'}
|
||||
py={2}
|
||||
height={'auto'}
|
||||
position={'relative'}
|
||||
{...props}
|
||||
>
|
||||
<Editor
|
||||
@@ -227,11 +237,36 @@ const JSONEditor = ({ defaultValue, value, onChange, resize, variables = [], ...
|
||||
beforeMount={beforeMount}
|
||||
defaultValue={defaultValue}
|
||||
value={value}
|
||||
onChange={(e) => onChange?.(e || '')}
|
||||
onChange={(e) => {
|
||||
onChange?.(e || '');
|
||||
if (!e) {
|
||||
setPlaceholderDisplay('block');
|
||||
} else {
|
||||
setPlaceholderDisplay('none');
|
||||
}
|
||||
}}
|
||||
wrapperProps={{
|
||||
onBlur
|
||||
}}
|
||||
onMount={() => {
|
||||
if (!value) {
|
||||
setPlaceholderDisplay('block');
|
||||
} else {
|
||||
setPlaceholderDisplay('none');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
className="monaco-placeholder"
|
||||
position={'absolute'}
|
||||
top={2}
|
||||
left={4}
|
||||
fontSize={'xs'}
|
||||
color={'myGray.500'}
|
||||
display={placeholderDisplay}
|
||||
>
|
||||
{placeholder}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
@@ -37,6 +37,7 @@ export default function Editor({
|
||||
onChange?: (editorState: EditorState) => void;
|
||||
onBlur?: (editor: LexicalEditor) => void;
|
||||
value?: string;
|
||||
currentValue?: string;
|
||||
placeholder?: string;
|
||||
}) {
|
||||
const [key, setKey] = useState(getNanoid(6));
|
||||
@@ -75,7 +76,7 @@ export default function Editor({
|
||||
useEffect(() => {
|
||||
if (focus) return;
|
||||
setKey(getNanoid(6));
|
||||
}, [value, variables, focus]);
|
||||
}, [value, variables.length]);
|
||||
|
||||
return (
|
||||
<Box position={'relative'} width={'full'} h={`${height}px`} cursor={'text'}>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Button, ModalBody, ModalFooter, useDisclosure } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { editorStateToText } from './utils';
|
||||
import Editor from './Editor';
|
||||
import MyModal from '../../MyModal';
|
||||
|
@@ -0,0 +1,89 @@
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { EditorVariablePickerType } from '../../type';
|
||||
import MyIcon from '../../../../Icon';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
|
||||
export default function DropDownMenu({
|
||||
variables,
|
||||
setDropdownValue
|
||||
}: {
|
||||
variables: EditorVariablePickerType[];
|
||||
setDropdownValue?: (value: string) => void;
|
||||
}) {
|
||||
const [highlightedIndex, setHighlightedIndex] = React.useState(0);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(event: any) => {
|
||||
if (event.keyCode === 38) {
|
||||
setHighlightedIndex((prevIndex) => Math.max(prevIndex - 1, 0));
|
||||
} else if (event.keyCode === 40) {
|
||||
setHighlightedIndex((prevIndex) => Math.min(prevIndex + 1, variables.length - 1));
|
||||
} else if (event.keyCode === 13 && variables[highlightedIndex]?.key) {
|
||||
setDropdownValue?.(variables[highlightedIndex].key);
|
||||
}
|
||||
},
|
||||
[highlightedIndex, variables]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [handleKeyDown]);
|
||||
|
||||
return variables.length ? (
|
||||
<Box
|
||||
bg={'white'}
|
||||
boxShadow={'lg'}
|
||||
borderWidth={'1px'}
|
||||
borderColor={'borderColor.base'}
|
||||
p={2}
|
||||
borderRadius={'md'}
|
||||
position={'fixed'}
|
||||
w={'auto'}
|
||||
zIndex={99999}
|
||||
>
|
||||
{variables.map((item, index) => (
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
as={'li'}
|
||||
key={item.key}
|
||||
px={4}
|
||||
py={2}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
maxH={'300px'}
|
||||
overflow={'auto'}
|
||||
_notLast={{
|
||||
mb: 2
|
||||
}}
|
||||
{...(highlightedIndex === index
|
||||
? {
|
||||
bg: 'primary.50',
|
||||
color: 'primary.600'
|
||||
}
|
||||
: {
|
||||
bg: 'white',
|
||||
color: 'myGray.600'
|
||||
})}
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
setDropdownValue?.(item.key);
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
setHighlightedIndex(index);
|
||||
}}
|
||||
>
|
||||
<MyIcon name={(item.icon as any) || 'core/modules/variable'} w={'14px'} />
|
||||
<Box ml={2} fontSize={'sm'}>
|
||||
{item.key}
|
||||
{item.key !== item.label && `(${item.label})`}
|
||||
</Box>
|
||||
</Flex>
|
||||
))}
|
||||
</Box>
|
||||
) : null;
|
||||
}
|
@@ -7,18 +7,16 @@ export default function OnBlurPlugin({ onBlur }: { onBlur?: (editor: LexicalEdit
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
useEffect(() => {
|
||||
return mergeRegister(
|
||||
editor.registerCommand(
|
||||
BLUR_COMMAND,
|
||||
() => {
|
||||
if (onBlur) onBlur(editor);
|
||||
return editor.registerCommand(
|
||||
BLUR_COMMAND,
|
||||
() => {
|
||||
onBlur?.(editor);
|
||||
|
||||
return true;
|
||||
},
|
||||
COMMAND_PRIORITY_EDITOR
|
||||
)
|
||||
return true;
|
||||
},
|
||||
COMMAND_PRIORITY_EDITOR
|
||||
);
|
||||
}, [editor, onBlur]);
|
||||
}, [editor]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@@ -0,0 +1,25 @@
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import { $createParagraphNode, $createTextNode, RootNode } from 'lexical';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const newlinesRegex = /[\n\r]/g;
|
||||
|
||||
export function SingleLinePlugin(): null {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
useEffect(() => {
|
||||
return editor.registerNodeTransform(RootNode, (rootNode: RootNode) => {
|
||||
const textContent = rootNode.getTextContent();
|
||||
|
||||
if (newlinesRegex.test(textContent)) {
|
||||
const newText = textContent.replace(newlinesRegex, '');
|
||||
const paragraph = $createParagraphNode();
|
||||
paragraph.append($createTextNode(newText));
|
||||
rootNode.clear().append(paragraph);
|
||||
rootNode.selectEnd();
|
||||
}
|
||||
});
|
||||
}, [editor]);
|
||||
|
||||
return null;
|
||||
}
|
@@ -2,9 +2,8 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
|
||||
import { LexicalTypeaheadMenuPlugin } from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
||||
import { $createTextNode, $getSelection, $isRangeSelection, TextNode } from 'lexical';
|
||||
import * as React from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { VariableInputEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '../../../../Icon';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
@@ -24,42 +23,6 @@ export default function VariablePickerPlugin({
|
||||
minLength: 0
|
||||
});
|
||||
|
||||
const VariableTypeList = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: t('core.module.variable.input type'),
|
||||
icon: 'core/app/variable/input',
|
||||
value: VariableInputEnum.input
|
||||
},
|
||||
{
|
||||
title: t('core.module.variable.textarea type'),
|
||||
icon: 'core/app/variable/textarea',
|
||||
value: VariableInputEnum.textarea
|
||||
},
|
||||
{
|
||||
title: t('core.module.variable.select type'),
|
||||
icon: 'core/app/variable/select',
|
||||
value: VariableInputEnum.select
|
||||
}
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
// const options: Array<any> = useMemo(() => {
|
||||
// // const newVariableOption = {
|
||||
// // label: t('common.Add New') + "变量",
|
||||
// // key: 'new_variable',
|
||||
// // icon: 'core/modules/variable'
|
||||
// // };
|
||||
// return [
|
||||
// ...variables.map((item) => ({
|
||||
// ...item,
|
||||
// icon: VariableTypeList.find((type) => type.value === item.type)?.icon
|
||||
// }))
|
||||
// // newVariableOption
|
||||
// ];
|
||||
// }, [VariableTypeList, t, variables]);
|
||||
|
||||
const onSelectOption = useCallback(
|
||||
(selectedOption: any, nodeToRemove: TextNode | null, closeMenu: () => void) => {
|
||||
editor.update(() => {
|
||||
|
Reference in New Issue
Block a user