Archer a9cdece341
4.8.6 merge (#1943)
* Dataset collection forbid (#1885)

* perf: tool call support same id

* feat: collection forbid

* feat: collection forbid

* Inheritance Permission for apps (#1897)

* feat: app schema define

chore: references of authapp

* feat: authApp method inheritance

* feat: create and update api

* feat: update

* feat: inheritance Permission controller for app.

* feat: abstract version of inheritPermission

* feat: ancestorId for apps

* chore: update app

* fix: inheritPermission abstract version

* feat: update folder defaultPermission

* feat: app update api

* chore: inheritance frontend

* chore: app list api

* feat: update defaultPermission in app deatil

* feat: backend api finished

* feat: app inheritance permission fe

* fix: app update defaultpermission causes collaborator miss

* fix: ts error

* chore: adjust the codes

* chore: i18n

chore: i18n

* chore: fe adjust and i18n

* chore: adjust the code

* feat: resume api;
chore: rewrite update api and inheritPermission methods

* chore: something

* chore: fe code adjusting

* feat: frontend adjusting

* chore: fe code adjusting

* chore: adjusting the code

* perf: fe loading

* format

* Inheritance fix (#1908)

* fix: SlideCard

* fix: authapp did not return parent app for inheritance app

* fix: fe adjusting

* feat: fe adjusing

* perf: inherit per ux

* doc

* fix: ts errors (#1916)

* perf: inherit permission

* fix: permission inherit

* Workflow type (#1938)

* perf: workflow type

tmp workflow

perf: workflow type

feat: custom field config

* perf: dynamic input

* perf: node classify

* perf: node classify

* perf: node classify

* perf: node classify

* fix: workflow custom input

* feat: text editor and customFeedback move to basic nodes

* feat: community system plugin

* fix: ts

* feat: exprEval plugin

* perf: workflow type

* perf: plugin important

* fix: default templates

* perf: markdown hr css

* lock

* perf: fetch url

* perf: new plugin version

* fix: chat histories update

* fix: collection paths invalid

* perf: app card ui

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
2024-07-04 17:42:09 +08:00

156 lines
3.8 KiB
TypeScript

import React, { useRef, forwardRef, useMemo } from 'react';
import {
Menu,
MenuList,
MenuItem,
Button,
useDisclosure,
MenuButton,
Box,
css,
Flex
} from '@chakra-ui/react';
import type { ButtonProps, MenuItemProps } from '@chakra-ui/react';
import { ChevronDownIcon } from '@chakra-ui/icons';
import { useLoading } from '../../../hooks/useLoading';
import MyIcon from '../Icon';
export type SelectProps<T = any> = ButtonProps & {
value?: T;
placeholder?: string;
list: {
alias?: string;
label: string | React.ReactNode;
description?: string;
value: T;
}[];
isLoading?: boolean;
onchange?: (val: T) => void;
};
const MySelect = <T = any,>({
placeholder,
value,
width = '100%',
list = [],
onchange,
isLoading = false,
...props
}: SelectProps<T>) => {
const ref = useRef<HTMLButtonElement>(null);
const { Loading } = useLoading();
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}
>
<Flex alignItems={'center'}>
{isLoading && <MyIcon mr={2} name={'common/loading'} w={'16px'} />}
{selectItem?.alias || selectItem?.label || placeholder}
</Flex>
</MenuButton>
<MenuList
className={props.className}
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'}
px={'6px'}
py={'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, i) => (
<MenuItem
key={i}
{...menuItemStyles}
{...(value === item.value
? {
color: 'primary.600',
bg: 'myGray.100'
}
: {
color: 'myGray.900'
})}
onClick={() => {
if (onchange && value !== item.value) {
onchange(item.value);
}
}}
whiteSpace={'pre-wrap'}
fontSize={'sm'}
display={'block'}
>
<Box>{item.label}</Box>
{item.description && (
<Box color={'myGray.500'} fontSize={'xs'}>
{item.description}
</Box>
)}
</MenuItem>
))}
</MenuList>
</Menu>
</Box>
);
};
export default MySelect;