mirror of
https://github.com/labring/FastGPT.git
synced 2026-05-06 01:02:54 +08:00
V4.14.10 dev (#6674)
* feat: model config with brand-new price calculate machanism (#6616) * fix: image read and json error (Agent) (#6502) * fix: 1.image read 2.JSON parsing error * dataset cite and pause * perf: plancall second parse * add test --------- Co-authored-by: archer <545436317@qq.com> * master message * remove invalid code * wip: model config * feat: model config with brand-new price calculate machanism * merge main branch * ajust calculate way * ajust priceTiers resolve procession * perf: price config code * fix: default price * fix: test * fix: comment * fix test --------- Co-authored-by: YeYuheng <57035043+YYH211@users.noreply.github.com> Co-authored-by: archer <545436317@qq.com> * wip: fix modal UI (#6634) * wip: fix modal UI * fix: maxInputToken set * chore: add price unit for non llm models * chore: replace question mark icon with beta tag (#6672) * feat:rerank too long; fix:rerank ui(agent),embedding returns 0 (#6663) * feat:rerank too long; fix:rerank ui(agent),embedding returns 0 * rerank * fix:rerank function * perf: rerank code * fix rerank * perf: model price ui --------- Co-authored-by: archer <545436317@qq.com> * remove llmtype field * revert model init * fix: filed * fix: model select filter * perf: multiple selector render * remove invalid checker * remove invalid i18n * perf: model selector tip * perf: model selector tip * fix cr * limit pnpm version * fix: i18n * fix action * set default mintoken * update i18n * perf: usage push * fix:rerank model ui (#6677) * fix: tier match error * fix: testr --------- Co-authored-by: Ryo <whoeverimf5@gmail.com> Co-authored-by: YeYuheng <57035043+YYH211@users.noreply.github.com>
This commit is contained in:
@@ -16,6 +16,141 @@ import EmptyTip from '../EmptyTip';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '../../common/Icon';
|
||||
|
||||
type RenderListProps = {
|
||||
index: number;
|
||||
list: MultipleSelectProps['list'];
|
||||
cloneValue: (string | undefined)[];
|
||||
setCloneValue: React.Dispatch<React.SetStateAction<(string | undefined)[]>>;
|
||||
onSelect: (val: (string | undefined)[]) => void;
|
||||
onClose: () => void;
|
||||
changeOnEverySelect: boolean;
|
||||
emptyTip?: string;
|
||||
maxH: number;
|
||||
minWidth: string;
|
||||
rowMinWidth: string;
|
||||
MenuRef: React.MutableRefObject<(HTMLDivElement | null)[]>;
|
||||
SelectedItemRef: React.MutableRefObject<(HTMLDivElement | null)[]>;
|
||||
};
|
||||
|
||||
const RenderList = React.memo(function RenderList({
|
||||
index,
|
||||
list,
|
||||
cloneValue,
|
||||
setCloneValue,
|
||||
onSelect,
|
||||
onClose,
|
||||
changeOnEverySelect,
|
||||
emptyTip,
|
||||
maxH,
|
||||
minWidth,
|
||||
rowMinWidth,
|
||||
MenuRef,
|
||||
SelectedItemRef
|
||||
}: RenderListProps) {
|
||||
const { t } = useTranslation();
|
||||
const selectedValue = cloneValue[index];
|
||||
const selectedIndex = list.findIndex((item) => item.value === selectedValue);
|
||||
const children = list[selectedIndex]?.children || [];
|
||||
|
||||
const currentScrollTop = MenuRef.current[index]?.scrollTop;
|
||||
useEffect(() => {
|
||||
if (currentScrollTop !== undefined && MenuRef.current[index]) {
|
||||
MenuRef.current[index]!.scrollTop = currentScrollTop;
|
||||
}
|
||||
}, [currentScrollTop, index, MenuRef]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
ref={(ref) => {
|
||||
MenuRef.current[index] = ref;
|
||||
}}
|
||||
className="nowheel"
|
||||
flex={'1 0 auto'}
|
||||
px={2}
|
||||
borderLeft={index !== 0 ? 'base' : 'none'}
|
||||
minW={index !== 0 ? minWidth : rowMinWidth}
|
||||
maxH={`${maxH}px`}
|
||||
overflowY={'auto'}
|
||||
whiteSpace={'nowrap'}
|
||||
>
|
||||
{list.map((item) => {
|
||||
const hasChildren = item.children && item.children.length > 0;
|
||||
|
||||
return (
|
||||
<Flex
|
||||
key={item.value}
|
||||
ref={(ref) => {
|
||||
if (item.value === selectedValue) {
|
||||
SelectedItemRef.current[index] = ref;
|
||||
}
|
||||
}}
|
||||
py={1.5}
|
||||
_notLast={{ mb: 1 }}
|
||||
cursor={'pointer'}
|
||||
px={1.5}
|
||||
borderRadius={'sm'}
|
||||
_hover={{
|
||||
bg: 'primary.50'
|
||||
}}
|
||||
onClick={() => {
|
||||
const newValue = [...cloneValue];
|
||||
|
||||
if (item.value === selectedValue) {
|
||||
for (let i = index; i < newValue.length; i++) {
|
||||
newValue[i] = undefined;
|
||||
}
|
||||
setCloneValue(newValue);
|
||||
onSelect(newValue);
|
||||
} else {
|
||||
newValue[index] = item.value;
|
||||
setCloneValue(newValue);
|
||||
|
||||
if (changeOnEverySelect || !hasChildren) {
|
||||
onSelect(newValue);
|
||||
}
|
||||
|
||||
if (!hasChildren) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
}}
|
||||
{...(item.value === selectedValue
|
||||
? {
|
||||
bg: 'primary.50',
|
||||
color: 'primary.600'
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{item.label}
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
{list.length === 0 && (
|
||||
<EmptyTip text={emptyTip ?? t('common:no_select_data')} pt={1} pb={3} />
|
||||
)}
|
||||
</Box>
|
||||
{children.length > 0 && (
|
||||
<RenderList
|
||||
list={children}
|
||||
index={index + 1}
|
||||
cloneValue={cloneValue}
|
||||
setCloneValue={setCloneValue}
|
||||
onSelect={onSelect}
|
||||
onClose={onClose}
|
||||
changeOnEverySelect={changeOnEverySelect}
|
||||
emptyTip={emptyTip}
|
||||
maxH={maxH}
|
||||
minWidth={minWidth}
|
||||
rowMinWidth={rowMinWidth}
|
||||
MenuRef={MenuRef}
|
||||
SelectedItemRef={SelectedItemRef}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export const MultipleRowSelect = ({
|
||||
placeholder,
|
||||
label,
|
||||
@@ -30,7 +165,6 @@ export const MultipleRowSelect = ({
|
||||
}: MultipleSelectProps & {
|
||||
rowMinWidth?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const ButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
@@ -53,99 +187,6 @@ export const MultipleRowSelect = ({
|
||||
|
||||
const minWidth = `${MenuRef.current?.[0]?.offsetWidth || 0}px`;
|
||||
|
||||
const RenderList = useCallback(
|
||||
({ index, list }: { index: number; list: MultipleSelectProps['list'] }) => {
|
||||
const selectedValue = cloneValue[index];
|
||||
const selectedIndex = list.findIndex((item) => item.value === selectedValue);
|
||||
const children = list[selectedIndex]?.children || [];
|
||||
|
||||
// Store current scroll position before update
|
||||
const currentScrollTop = MenuRef.current[index]?.scrollTop;
|
||||
// Use useEffect to restore scroll position after render
|
||||
useEffect(() => {
|
||||
if (currentScrollTop !== undefined && MenuRef.current[index]) {
|
||||
MenuRef.current[index]!.scrollTop = currentScrollTop;
|
||||
}
|
||||
}, [currentScrollTop, index]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
ref={(ref) => {
|
||||
MenuRef.current[index] = ref;
|
||||
}}
|
||||
className="nowheel"
|
||||
flex={'1 0 auto'}
|
||||
px={2}
|
||||
borderLeft={index !== 0 ? 'base' : 'none'}
|
||||
minW={index !== 0 ? minWidth : rowMinWidth}
|
||||
maxH={`${maxH}px`}
|
||||
overflowY={'auto'}
|
||||
whiteSpace={'nowrap'}
|
||||
>
|
||||
{list.map((item) => {
|
||||
const hasChildren = item.children && item.children.length > 0;
|
||||
|
||||
return (
|
||||
<Flex
|
||||
key={item.value}
|
||||
ref={(ref) => {
|
||||
if (item.value === selectedValue) {
|
||||
SelectedItemRef.current[index] = ref;
|
||||
}
|
||||
}}
|
||||
py={1.5}
|
||||
_notLast={{ mb: 1 }}
|
||||
cursor={'pointer'}
|
||||
px={1.5}
|
||||
borderRadius={'sm'}
|
||||
_hover={{
|
||||
bg: 'primary.50'
|
||||
}}
|
||||
onClick={() => {
|
||||
const newValue = [...cloneValue];
|
||||
|
||||
if (item.value === selectedValue) {
|
||||
for (let i = index; i < newValue.length; i++) {
|
||||
newValue[i] = undefined;
|
||||
}
|
||||
setCloneValue(newValue);
|
||||
onSelect(newValue);
|
||||
} else {
|
||||
newValue[index] = item.value;
|
||||
setCloneValue(newValue);
|
||||
|
||||
if (changeOnEverySelect || !hasChildren) {
|
||||
onSelect(newValue);
|
||||
}
|
||||
|
||||
if (!hasChildren) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
}}
|
||||
{...(item.value === selectedValue
|
||||
? {
|
||||
bg: 'primary.50',
|
||||
color: 'primary.600'
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{item.label}
|
||||
</Flex>
|
||||
);
|
||||
})}
|
||||
{list.length === 0 && (
|
||||
<EmptyTip text={emptyTip ?? t('common:no_select_data')} pt={1} pb={3} />
|
||||
)}
|
||||
</Box>
|
||||
{children.length > 0 && <RenderList list={children} index={index + 1} />}
|
||||
</>
|
||||
);
|
||||
},
|
||||
[changeOnEverySelect, cloneValue, emptyTip, maxH, minWidth, onClose, onSelect, rowMinWidth, t]
|
||||
);
|
||||
|
||||
const onOpenSelect = useCallback(() => {
|
||||
setCloneValue(Array.isArray(value) ? value : []);
|
||||
onOpen();
|
||||
@@ -221,7 +262,21 @@ export const MultipleRowSelect = ({
|
||||
display={'flex'}
|
||||
userSelect={'none'}
|
||||
>
|
||||
<RenderList list={list} index={0} />
|
||||
<RenderList
|
||||
list={list}
|
||||
index={0}
|
||||
cloneValue={cloneValue}
|
||||
setCloneValue={setCloneValue}
|
||||
onSelect={onSelect}
|
||||
onClose={onClose}
|
||||
changeOnEverySelect={changeOnEverySelect}
|
||||
emptyTip={emptyTip}
|
||||
maxH={maxH}
|
||||
minWidth={minWidth}
|
||||
rowMinWidth={rowMinWidth}
|
||||
MenuRef={MenuRef}
|
||||
SelectedItemRef={SelectedItemRef}
|
||||
/>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</Box>
|
||||
|
||||
@@ -62,6 +62,7 @@ export type SelectProps<T = any> = {
|
||||
onOpenFunc?: () => void;
|
||||
|
||||
tagStyle?: FlexProps;
|
||||
menuBottomSlot?: React.ReactNode;
|
||||
} & Omit<ButtonProps, 'onSelect'>;
|
||||
|
||||
type SelectedItemType<T> = {
|
||||
@@ -91,6 +92,7 @@ const MultipleSelect = <T = any,>({
|
||||
onOpenFunc,
|
||||
|
||||
tagStyle,
|
||||
menuBottomSlot,
|
||||
isLoading,
|
||||
...props
|
||||
}: SelectProps<T>) => {
|
||||
@@ -135,7 +137,7 @@ const MultipleSelect = <T = any,>({
|
||||
if (!isOpen) {
|
||||
setInputValue?.('');
|
||||
}
|
||||
}, [isOpen]);
|
||||
}, [isOpen, setInputValue]);
|
||||
|
||||
const onclickItem = useCallback(
|
||||
(val: T) => {
|
||||
@@ -480,6 +482,15 @@ const MultipleSelect = <T = any,>({
|
||||
|
||||
{ScrollData ? <ScrollData minH={20}>{ListRender}</ScrollData> : ListRender}
|
||||
|
||||
{menuBottomSlot && (
|
||||
<>
|
||||
<MyDivider my={1} />
|
||||
<Box px={1} py={1}>
|
||||
{menuBottomSlot}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isLoading && <MyLoading fixed={false} />}
|
||||
</MenuList>
|
||||
</Menu>
|
||||
|
||||
Reference in New Issue
Block a user