4.8 preview (#1288)

* Revert "lafAccount add pat & re request when token invalid (#76)" (#77)

This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be.

* perf: workflow ux

* system config

* Newflow (#89)

* docs: Add doc for Xinference (#1266)

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>

* Revert "lafAccount add pat & re request when token invalid (#76)" (#77)

This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be.

* perf: workflow ux

* system config

* Revert "lafAccount add pat & re request when token invalid (#76)" (#77)

This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be.

* Revert "lafAccount add pat & re request when token invalid (#76)" (#77)

This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be.

* Revert "lafAccount add pat & re request when token invalid (#76)" (#77)

This reverts commit 83d85dfe37adcaef4833385ea52ee79fd84720be.

* rename code

* move code

* update flow

* input type selector

* perf: workflow runtime

* feat: node adapt newflow

* feat: adapt plugin

* feat: 360 connection

* check workflow

* perf: flow 性能

* change plugin input type (#81)

* change plugin input type

* plugin label mode

* perf: nodecard

* debug

* perf: debug ui

* connection ui

* change workflow ui (#82)

* feat: workflow debug

* adapt openAPI for new workflow (#83)

* adapt openAPI for new workflow

* i18n

* perf: plugin debug

* plugin input ui

* delete

* perf: global variable select

* fix rebase

* perf: workflow performance

* feat: input render type icon

* input icon

* adapt flow (#84)

* adapt newflow

* temp

* temp

* fix

* feat: app schedule trigger

* feat: app schedule trigger

* perf: schedule ui

* feat: ioslatevm run js code

* perf: workflow varialbe table ui

* feat: adapt simple mode

* feat: adapt input params

* output

* feat: adapt tamplate

* fix: ts

* add if-else module (#86)

* perf: worker

* if else node

* perf: tiktoken worker

* fix: ts

* perf: tiktoken

* fix if-else node (#87)

* fix if-else node

* type

* fix

* perf: audio render

* perf: Parallel worker

* log

* perf: if else node

* adapt plugin

* prompt

* perf: reference ui

* reference ui

* handle ux

* template ui and plugin tool

* adapt v1 workflow

* adapt v1 workflow completions

* perf: time variables

* feat: workflow keyboard shortcuts

* adapt v1 workflow

* update workflow example doc (#88)

* fix: simple mode select tool

---------

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
Co-authored-by: Carson Yang <yangchuansheng33@gmail.com>
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>

* doc

* perf: extract node

* extra node field

* update plugin version

* doc

* variable

* change doc & fix prompt editor (#90)

* fold workflow code

* value type label

---------

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
Co-authored-by: Carson Yang <yangchuansheng33@gmail.com>
Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
This commit is contained in:
Archer
2024-04-25 17:51:20 +08:00
committed by GitHub
parent b08d81f887
commit 439c819ff1
505 changed files with 23570 additions and 18215 deletions

View File

@@ -0,0 +1,135 @@
import React, { useRef, useCallback, useState } from 'react';
import { Button, useDisclosure, Box, Flex, useOutsideClick } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons';
import { MultipleSelectProps } from './type';
import EmptyTip from '../EmptyTip';
import { useTranslation } from 'next-i18next';
const MultipleRowSelect = ({
placeholder,
label,
value = [],
list,
emptyTip,
maxH = 300,
onSelect,
styles
}: MultipleSelectProps) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null);
const { isOpen, onOpen, onClose } = useDisclosure();
const [cloneValue, setCloneValue] = useState(value);
useOutsideClick({
ref: ref,
handler: onClose
});
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 || [];
const hasChildren = list.some((item) => item.children && item.children?.length > 0);
return (
<>
<Box
flex={'1 0 auto'}
// width={0}
px={2}
borderLeft={index !== 0 ? 'base' : 'none'}
maxH={`${maxH}px`}
overflowY={'auto'}
whiteSpace={'nowrap'}
>
{list.map((item) => (
<Flex
key={item.value}
py={2}
cursor={'pointer'}
px={2}
borderRadius={'md'}
_hover={{
bg: 'primary.50',
color: 'primary.600'
}}
{...(item.value === selectedValue
? {
color: 'primary.600'
}
: {
onClick: () => {
const newValue = [...cloneValue];
newValue[index] = item.value;
setCloneValue(newValue);
if (!hasChildren) {
onSelect(newValue);
onClose();
}
}
})}
>
{item.label}
</Flex>
))}
{list.length === 0 && (
<EmptyTip text={emptyTip ?? t('common.MultipleRowSelect.No data')} pt={1} pb={3} />
)}
</Box>
{children.length > 0 && <RenderList list={children} index={index + 1} />}
</>
);
},
[cloneValue]
);
const onOpenSelect = useCallback(() => {
setCloneValue(value);
onOpen();
}, [value, onOpen]);
return (
<Box ref={ref} position={'relative'}>
<Button
justifyContent={'space-between'}
width={'100%'}
rightIcon={<ChevronDownIcon />}
variant={'whiteFlow'}
_active={{
transform: 'none'
}}
{...(isOpen
? {
boxShadow: '0px 0px 4px #A8DBFF',
borderColor: 'primary.500'
}
: {})}
{...styles}
onClick={() => (isOpen ? onClose() : onOpenSelect())}
>
<Box>{label ?? placeholder}</Box>
</Button>
{isOpen && (
<Box
position={'absolute'}
top={'45px'}
py={2}
bg={'white'}
border={'1px solid #fff'}
boxShadow={'5'}
borderRadius={'md'}
zIndex={1}
minW={'100%'}
w={'max-content'}
>
<Flex>
<RenderList list={list} index={0} />
</Flex>
</Box>
)}
</Box>
);
};
export default React.memo(MultipleRowSelect);

View File

@@ -0,0 +1,131 @@
import { Box, Flex, useDisclosure, useOutsideClick } from '@chakra-ui/react';
import React, { useRef } from 'react';
import { useTranslation } from 'next-i18next';
import FillTag from '../Tag/index';
import MyIcon from '../Icon';
export type SelectProps = {
value?: string[];
placeholder?: string;
list: {
icon?: string;
alias?: string;
label: string | React.ReactNode;
value: string;
}[];
maxH?: number;
onSelect: (val: any[]) => void;
};
const MultipleSelect = ({
value = [],
placeholder,
list = [],
maxH = 400,
onSelect
}: SelectProps) => {
const { t } = useTranslation();
const ref = useRef<HTMLDivElement>(null);
const { isOpen, onOpen, onClose } = useDisclosure();
useOutsideClick({
ref: ref,
handler: onClose
});
return (
<Box ref={ref} position={'relative'}>
<Flex
alignItems={'center'}
flexWrap={'wrap'}
border={'base'}
py={2}
px={3}
borderRadius={'md'}
cursor={'pointer'}
gap={3}
onClick={() => (isOpen ? onClose() : onOpen())}
>
{value.map((item) => {
const listItem = list.find((i) => i.value === item);
if (!listItem) return null;
return (
<FillTag colorSchema="blue" p={2} cursor={'default'}>
{listItem.alias || listItem.label}
<MyIcon
name={'common/closeLight'}
ml={1}
w="14px"
cursor={'pointer'}
onClick={(e) => {
e.stopPropagation();
onSelect(value.filter((i) => i !== item));
}}
/>
</FillTag>
);
})}
{value.length === 0 && placeholder && (
<Box color={'myGray.500'} fontSize={'sm'}>
{placeholder}
</Box>
)}
</Flex>
{isOpen && (
<Box
px={3}
py={2}
bg={'white'}
borderRadius={'md'}
whiteSpace={'nowrap'}
maxH={`${maxH}px`}
overflowY={'auto'}
boxShadow={'2'}
position={'absolute'}
top={'110%'}
border={'base'}
w={'100%'}
zIndex={100}
>
{list.map((item) => {
const selected = value.includes(item.value);
return (
<Flex
alignItems={'center'}
_notLast={{ mb: 1 }}
py={2}
px={3}
borderRadius={'md'}
cursor={'pointer'}
_hover={{
bg: 'primary.50'
}}
{...(selected
? {
color: 'primary.600',
onClick: (e) => {
e.stopPropagation();
onSelect(value.filter((i) => i !== item.value));
}
}
: {
onClick: (e) => {
e.stopPropagation();
onSelect([...value, item.value]);
}
})}
>
{item.icon && <MyIcon name={item.icon as any} w={'14px'} mr={1} />}
<Box>{item.label}</Box>
</Flex>
);
})}
</Box>
)}
</Box>
);
};
export default React.memo(MultipleSelect);

View File

@@ -0,0 +1,24 @@
import React, { useRef } from 'react';
import { timezoneList } from '@fastgpt/global/common/time/timezone';
import { Select } from '@chakra-ui/react';
const TimezoneSelect = ({ value, onChange }: { value?: string; onChange: (e: string) => void }) => {
const timezones = useRef(timezoneList());
return (
<Select
value={value}
onChange={(e) => {
onChange(e.target.value);
}}
>
{timezones.current.map((item) => (
<option key={item.value} value={item.value}>
{item.name}
</option>
))}
</Select>
);
};
export default React.memo(TimezoneSelect);

View File

@@ -28,7 +28,15 @@ export type SelectProps = ButtonProps & {
};
const MySelect = (
{ placeholder, value, width = '100%', list, onchange, isLoading = false, ...props }: SelectProps,
{
placeholder,
value,
width = '100%',
list = [],
onchange,
isLoading = false,
...props
}: SelectProps,
selectRef: any
) => {
const ref = useRef<HTMLButtonElement>(null);

View File

@@ -0,0 +1,16 @@
type ListItemType = {
alias?: string;
label: string | React.ReactNode;
value: any;
children?: ListItemType[];
};
export type MultipleSelectProps<T = any> = {
label?: string | React.ReactNode;
value: any[];
placeholder?: string;
list: ListItemType[];
emptyTip?: string;
maxH?: number;
onSelect: (val: any[]) => void;
styles?: ButtonProps;
};