mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-01 20:27:45 +00:00
4.6.9-production (#952)
* move components to web package (#37) * move components * fix * fix: cq connection * fix pagination (#41) * doc * openapi config * fix team share app lose (#42) * fix: ts * doc * doc --------- Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com> Co-authored-by: yst <77910600+yu-and-liu@users.noreply.github.com>
This commit is contained in:
@@ -53,7 +53,6 @@ import type { AdminMarkType } from './SelectMarkCollection';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import Markdown, { CodeClassName } from '@/components/Markdown';
|
||||
import MySelect from '@/components/Select';
|
||||
import MyTooltip from '../MyTooltip';
|
||||
import dynamic from 'next/dynamic';
|
||||
const ResponseTags = dynamic(() => import('./ResponseTags'));
|
||||
@@ -69,6 +68,7 @@ import MessageInput from './MessageInput';
|
||||
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
import ChatBoxDivider from '../core/chat/Divider';
|
||||
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
||||
|
||||
|
@@ -1,125 +0,0 @@
|
||||
import React, { useState, useMemo, useRef } from 'react';
|
||||
import { Box, Card, Flex, useTheme, useOutsideClick, Button } from '@chakra-ui/react';
|
||||
import { addDays, format } from 'date-fns';
|
||||
import { type DateRange, DayPicker } from 'react-day-picker';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import 'react-day-picker/dist/style.css';
|
||||
import zhCN from 'date-fns/locale/zh-CN';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
const DateRangePicker = ({
|
||||
onChange,
|
||||
onSuccess,
|
||||
position = 'bottom',
|
||||
defaultDate = {
|
||||
from: addDays(new Date(), -30),
|
||||
to: new Date()
|
||||
}
|
||||
}: {
|
||||
onChange?: (date: DateRange) => void;
|
||||
onSuccess?: (date: DateRange) => void;
|
||||
position?: 'bottom' | 'top';
|
||||
defaultDate?: DateRange;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const OutRangeRef = useRef(null);
|
||||
const [range, setRange] = useState<DateRange | undefined>(defaultDate);
|
||||
const [showSelected, setShowSelected] = useState(false);
|
||||
|
||||
const formatSelected = useMemo(() => {
|
||||
if (range?.from && range.to) {
|
||||
return `${format(range.from, 'y-MM-dd')} ~ ${format(range.to, 'y-MM-dd')}`;
|
||||
}
|
||||
return `${format(new Date(), 'y-MM-dd')} ~ ${format(new Date(), 'y-MM-dd')}`;
|
||||
}, [range]);
|
||||
|
||||
useOutsideClick({
|
||||
ref: OutRangeRef,
|
||||
handler: () => {
|
||||
setShowSelected(false);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Box position={'relative'} ref={OutRangeRef}>
|
||||
<Flex
|
||||
border={theme.borders.base}
|
||||
px={3}
|
||||
py={1}
|
||||
borderRadius={'sm'}
|
||||
cursor={'pointer'}
|
||||
bg={'myWhite.600'}
|
||||
fontSize={'sm'}
|
||||
onClick={() => setShowSelected(true)}
|
||||
>
|
||||
<Box>{formatSelected}</Box>
|
||||
<MyIcon ml={2} name={'date'} w={'16px'} color={'myGray.600'} />
|
||||
</Flex>
|
||||
{showSelected && (
|
||||
<Card
|
||||
position={'absolute'}
|
||||
zIndex={1}
|
||||
css={{
|
||||
'--rdp-background-color': '#d6e8ff',
|
||||
' --rdp-accent-color': '#0000ff'
|
||||
}}
|
||||
{...(position === 'top'
|
||||
? {
|
||||
bottom: '40px'
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
<DayPicker
|
||||
locale={zhCN}
|
||||
id="test"
|
||||
mode="range"
|
||||
defaultMonth={defaultDate.to}
|
||||
selected={range}
|
||||
disabled={[
|
||||
{ from: new Date(2022, 3, 1), to: addDays(new Date(), -90) },
|
||||
{ from: addDays(new Date(), 1), to: new Date(2099, 1, 1) }
|
||||
]}
|
||||
onSelect={(date) => {
|
||||
if (date?.from === undefined) {
|
||||
date = {
|
||||
from: range?.from,
|
||||
to: range?.from
|
||||
};
|
||||
}
|
||||
if (date?.to === undefined) {
|
||||
date.to = date.from;
|
||||
}
|
||||
setRange(date);
|
||||
onChange && onChange(date);
|
||||
}}
|
||||
footer={
|
||||
<Flex justifyContent={'flex-end'}>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
size={'sm'}
|
||||
mr={2}
|
||||
onClick={() => setShowSelected(false)}
|
||||
>
|
||||
{t('common.Close')}
|
||||
</Button>
|
||||
<Button
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
onSuccess && onSuccess(range || defaultDate);
|
||||
setShowSelected(false);
|
||||
}}
|
||||
>
|
||||
{t('common.Confirm')}
|
||||
</Button>
|
||||
</Flex>
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateRangePicker;
|
||||
export type DateRangeType = DateRange;
|
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { Box, useColorMode, Flex } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { throttle } from 'lodash';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
@@ -1,45 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Spinner, Flex, Box } from '@chakra-ui/react';
|
||||
|
||||
const Loading = ({
|
||||
fixed = true,
|
||||
text = '',
|
||||
bg = 'rgba(255,255,255,0.5)',
|
||||
zIndex = 1000
|
||||
}: {
|
||||
fixed?: boolean;
|
||||
text?: string;
|
||||
bg?: string;
|
||||
zIndex?: number;
|
||||
}) => {
|
||||
return (
|
||||
<Flex
|
||||
position={fixed ? 'fixed' : 'absolute'}
|
||||
zIndex={zIndex}
|
||||
bg={bg}
|
||||
borderRadius={'md'}
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
bottom={0}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
<Spinner
|
||||
thickness="4px"
|
||||
speed="0.65s"
|
||||
emptyColor="myGray.100"
|
||||
color="primary.500"
|
||||
size="xl"
|
||||
/>
|
||||
{text && (
|
||||
<Box mt={2} color="primary.600" fontWeight={'bold'}>
|
||||
{text}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default Loading;
|
@@ -1,10 +1,10 @@
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import MySelect, { type SelectProps } from './index';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { useRouter } from 'next/router';
|
||||
import { AI_POINT_USAGE_CARD_ROUTE } from '@/web/support/wallet/sub/constants';
|
||||
import MySelect, { SelectProps } from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const SelectAiModel = ({ list, ...props }: SelectProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
@@ -1,130 +0,0 @@
|
||||
import React, { useRef, forwardRef, useMemo } from 'react';
|
||||
import {
|
||||
Menu,
|
||||
MenuList,
|
||||
MenuItem,
|
||||
Button,
|
||||
useDisclosure,
|
||||
MenuButton,
|
||||
Box,
|
||||
css
|
||||
} from '@chakra-ui/react';
|
||||
import type { ButtonProps, MenuItemProps } from '@chakra-ui/react';
|
||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||
|
||||
export type SelectProps = ButtonProps & {
|
||||
value?: string;
|
||||
placeholder?: string;
|
||||
list: {
|
||||
alias?: string;
|
||||
label: string | React.ReactNode;
|
||||
value: string;
|
||||
}[];
|
||||
onchange?: (val: any) => void;
|
||||
};
|
||||
|
||||
const MySelect = (
|
||||
{ placeholder, value, width = '100%', list, onchange, ...props }: SelectProps,
|
||||
selectRef: any
|
||||
) => {
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
const menuItemStyles: MenuItemProps = {
|
||||
borderRadius: 'sm',
|
||||
py: 2,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
_hover: {
|
||||
backgroundColor: 'myWhite.600'
|
||||
},
|
||||
_notLast: {
|
||||
mb: 2
|
||||
}
|
||||
};
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const selectItem = useMemo(() => list.find((item) => item.value === value), [list, value]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
css={css({
|
||||
'& div': {
|
||||
width: 'auto !important'
|
||||
}
|
||||
})}
|
||||
>
|
||||
<Menu
|
||||
autoSelect={false}
|
||||
isOpen={isOpen}
|
||||
onOpen={onOpen}
|
||||
onClose={onClose}
|
||||
strategy={'fixed'}
|
||||
matchWidth
|
||||
>
|
||||
<MenuButton
|
||||
as={Button}
|
||||
ref={ref}
|
||||
width={width}
|
||||
px={3}
|
||||
rightIcon={<ChevronDownIcon />}
|
||||
variant={'whitePrimary'}
|
||||
textAlign={'left'}
|
||||
_active={{
|
||||
transform: 'none'
|
||||
}}
|
||||
{...(isOpen
|
||||
? {
|
||||
boxShadow: '0px 0px 4px #A8DBFF',
|
||||
borderColor: 'primary.500'
|
||||
}
|
||||
: {})}
|
||||
{...props}
|
||||
>
|
||||
{selectItem?.alias || selectItem?.label || placeholder}
|
||||
</MenuButton>
|
||||
|
||||
<MenuList
|
||||
minW={(() => {
|
||||
const w = ref.current?.clientWidth;
|
||||
if (w) {
|
||||
return `${w}px !important`;
|
||||
}
|
||||
return Array.isArray(width)
|
||||
? width.map((item) => `${item} !important`)
|
||||
: `${width} !important`;
|
||||
})()}
|
||||
w={'auto'}
|
||||
p={'6px'}
|
||||
border={'1px solid #fff'}
|
||||
boxShadow={
|
||||
'0px 2px 4px rgba(161, 167, 179, 0.25), 0px 0px 1px rgba(121, 141, 159, 0.25);'
|
||||
}
|
||||
zIndex={99}
|
||||
maxH={'40vh'}
|
||||
overflowY={'auto'}
|
||||
>
|
||||
{list.map((item) => (
|
||||
<MenuItem
|
||||
key={item.value}
|
||||
{...menuItemStyles}
|
||||
{...(value === item.value
|
||||
? {
|
||||
color: 'primary.500',
|
||||
bg: 'myWhite.300'
|
||||
}
|
||||
: {})}
|
||||
onClick={() => {
|
||||
if (onchange && value !== item.value) {
|
||||
onchange(item.value);
|
||||
}
|
||||
}}
|
||||
whiteSpace={'pre-wrap'}
|
||||
>
|
||||
{item.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(forwardRef(MySelect));
|
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import Loading from '@/components/Loading';
|
||||
import Loading from '@fastgpt/web/components/common/MyLoading';
|
||||
|
||||
type Props = BoxProps & {
|
||||
isLoading?: boolean;
|
||||
|
@@ -26,9 +26,9 @@ import MyRadio from '@/components/common/MyRadio';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import Tabs from '@/components/Tabs';
|
||||
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
|
||||
export type DatasetParamsProps = {
|
||||
searchMode: `${DatasetSearchModeEnum}`;
|
||||
|
@@ -19,7 +19,7 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
||||
import DatasetSelectContainer, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||
import EmptyTip from '@/components/EmptyTip';
|
||||
|
||||
export const DatasetSelectModal = ({
|
||||
|
@@ -177,7 +177,11 @@ export const FlowProvider = ({
|
||||
({ connect }: { connect: Connection }) => {
|
||||
const source = nodes.find((node) => node.id === connect.source)?.data;
|
||||
const sourceType = (() => {
|
||||
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion) {
|
||||
const type = source?.outputs.find(
|
||||
(output) => output.key === connect.sourceHandle
|
||||
)?.valueType;
|
||||
console.log(type);
|
||||
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion && !type) {
|
||||
return ModuleIOValueTypeEnum.boolean;
|
||||
}
|
||||
if (source?.flowType === FlowNodeTypeEnum.pluginInput) {
|
||||
|
@@ -5,7 +5,7 @@ import { useQuery } from '@tanstack/react-query';
|
||||
import type { SelectAppItemType } from '@fastgpt/global/core/module/type';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||
import { useAppStore } from '@/web/core/app/store/useAppStore';
|
||||
|
||||
const SelectAppModal = ({
|
||||
|
@@ -4,13 +4,13 @@ import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { Box, Button, Flex, ModalBody, useDisclosure, Image } from '@chakra-ui/react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MySelect from '@/components/Select';
|
||||
import { TTSTypeEnum } from '@/constants/app';
|
||||
import type { AppTTSConfigType } from '@fastgpt/global/core/module/type.d';
|
||||
import { useAudioPlay } from '@/web/common/utils/voice';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import MySlider from '@/components/Slider';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const TTSSelect = ({
|
||||
value,
|
||||
|
@@ -19,7 +19,6 @@ import {
|
||||
TableContainer,
|
||||
Button
|
||||
} from '@chakra-ui/react';
|
||||
import MySelect from '@/components/Select';
|
||||
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { onChangeNode, useFlowProviderStore } from '../../../FlowProvider';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -38,6 +37,7 @@ import {
|
||||
import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textarea/PromptEditor/type';
|
||||
import HttpInput from '@fastgpt/web/components/common/Input/HttpInput';
|
||||
import dynamic from 'next/dynamic';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
const OpenApiImportModal = dynamic(() => import('./OpenApiImportModal'));
|
||||
|
||||
enum TabEnum {
|
||||
|
@@ -13,7 +13,6 @@ import { useForm } from 'react-hook-form';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { DYNAMIC_INPUT_KEY, ModuleIOValueTypeEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MySelect from '@/components/Select';
|
||||
import { FlowValueTypeMap } from '@/web/core/modules/constants/dataType';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
} from '@fastgpt/global/core/module/node/constant';
|
||||
import { EditInputFieldMap, EditNodeFieldType } from '@fastgpt/global/core/module/node/type.d';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const FieldEditModal = ({
|
||||
editField = {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import type { RenderInputProps } from '../type';
|
||||
import { onChangeNode } from '../../../../FlowProvider';
|
||||
import MySelect from '@/components/Select';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const SelectRender = ({ item, moduleId }: RenderInputProps) => {
|
||||
return (
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import type { RenderInputProps } from '../type';
|
||||
import { onChangeNode } from '../../../../FlowProvider';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
|
||||
const SelectAiModelRender = ({ item, inputs = [], moduleId }: RenderInputProps) => {
|
||||
const { llmModelList } = useSystemStore();
|
||||
|
@@ -28,7 +28,7 @@ import {
|
||||
} from '@/web/support/openapi/api';
|
||||
import type { EditApiKeyProps } from '@/global/support/openapi/api.d';
|
||||
import { useQuery, useMutation } from '@tanstack/react-query';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||
import dayjs from 'dayjs';
|
||||
import { AddIcon, QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
|
@@ -3,12 +3,12 @@ import MyModal from '@/components/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { ModalCloseButton, ModalBody, Box, ModalFooter, Button } from '@chakra-ui/react';
|
||||
import TagTextarea from '@/components/common/Textarea/TagTextarea';
|
||||
import MySelect from '@/components/Select';
|
||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { postInviteTeamMember } from '@/web/support/user/team/api';
|
||||
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
||||
import type { InviteMemberResponse } from '@fastgpt/global/support/user/team/controller.d';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
|
||||
const InviteModal = ({
|
||||
teamId,
|
||||
|
@@ -38,7 +38,7 @@ import {
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { setToken } from '@/web/support/user/auth';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||
import { FormDataType, defaultForm } from './EditModal';
|
||||
import MyMenu from '@/components/MyMenu';
|
||||
import { useConfirm } from '@/web/common/hooks/useConfirm';
|
||||
|
Reference in New Issue
Block a user