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:
Archer
2024-03-08 13:33:45 +08:00
committed by GitHub
parent 46d9a6461f
commit 4d66e0f828
61 changed files with 290 additions and 141 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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';

View File

@@ -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;

View File

@@ -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();

View File

@@ -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));

View File

@@ -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;

View File

@@ -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}`;

View File

@@ -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 = ({

View File

@@ -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) {

View File

@@ -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 = ({

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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 = {

View File

@@ -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 (

View File

@@ -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();

View File

@@ -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';

View File

@@ -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,

View File

@@ -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';