Add OpenAI block

Also migrate credentials to tRPC

Closes #253
This commit is contained in:
Baptiste Arnaud
2023-03-09 08:46:36 +01:00
parent 97cfdfe79f
commit ff04edf139
86 changed files with 2583 additions and 1055 deletions

View File

@@ -12,21 +12,23 @@ import {
import { ChevronLeftIcon } from '@/components/icons'
import React, { ReactNode } from 'react'
type Props<T> = {
currentItem?: T
onItemSelect: (item: T) => void
items: T[]
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Props<T extends readonly any[]> = {
currentItem: T[number] | undefined
onItemSelect: (item: T[number]) => void
items: T
placeholder?: string
}
export const DropdownList = <T,>({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const DropdownList = <T extends readonly any[]>({
currentItem,
onItemSelect,
items,
placeholder = '',
...props
}: Props<T> & MenuButtonProps) => {
const handleMenuItemClick = (operator: T) => () => {
const handleMenuItemClick = (operator: T[number]) => () => {
onItemSelect(operator)
}
return (

View File

@@ -0,0 +1,27 @@
import { useColorModeValue, HStack, Tag, Text } from '@chakra-ui/react'
import { Variable } from 'models'
export const SetVariableLabel = ({
variableId,
variables,
}: {
variableId: string
variables?: Variable[]
}) => {
const textColor = useColorModeValue('gray.600', 'gray.400')
const variableName = variables?.find(
(variable) => variable.id === variableId
)?.name
if (!variableName) return null
return (
<HStack fontStyle="italic" spacing={1}>
<Text fontSize="sm" color={textColor}>
Set
</Text>
<Tag bg="orange.400" color="white" size="sm">
{variableName}
</Tag>
</HStack>
)
}

View File

@@ -1,4 +1,12 @@
import { Box, Button, Fade, Flex, IconButton, Stack } from '@chakra-ui/react'
import {
Box,
Button,
Fade,
Flex,
IconButton,
SlideFade,
Stack,
} from '@chakra-ui/react'
import { TrashIcon, PlusIcon } from '@/components/icons'
import { createId } from '@paralleldrive/cuid2'
import React, { useState } from 'react'
@@ -7,26 +15,25 @@ type ItemWithId<T> = T & { id: string }
export type TableListItemProps<T> = {
item: T
debounceTimeout?: number
onItemChange: (item: T) => void
}
type Props<T> = {
initialItems: ItemWithId<T>[]
isOrdered?: boolean
addLabel?: string
debounceTimeout?: number
onItemsChange: (items: ItemWithId<T>[]) => void
Item: (props: TableListItemProps<T>) => JSX.Element
ComponentBetweenItems?: (props: unknown) => JSX.Element
onItemsChange: (items: ItemWithId<T>[]) => void
}
export const TableList = <T,>({
initialItems,
onItemsChange,
isOrdered,
addLabel = 'Add',
debounceTimeout,
Item,
ComponentBetweenItems,
onItemsChange,
}: Props<T>) => {
const [items, setItems] = useState(initialItems)
const [showDeleteIndex, setShowDeleteIndex] = useState<number | null>(null)
@@ -38,6 +45,15 @@ export const TableList = <T,>({
onItemsChange([...items, newItem])
}
const insertItem = (itemIndex: number) => () => {
const id = createId()
const newItem = { id } as ItemWithId<T>
const newItems = [...items]
newItems.splice(itemIndex + 1, 0, newItem)
setItems(newItems)
onItemsChange(newItems)
}
const updateItem = (itemIndex: number, updates: Partial<T>) => {
const newItems = items.map((item, idx) =>
idx === itemIndex ? { ...item, ...updates } : item
@@ -62,7 +78,7 @@ export const TableList = <T,>({
const handleMouseLeave = () => setShowDeleteIndex(null)
return (
<Stack spacing="4">
<Stack spacing={0} pt="2">
{items.map((item, itemIndex) => (
<Box key={item.id}>
{itemIndex !== 0 && ComponentBetweenItems && (
@@ -73,35 +89,82 @@ export const TableList = <T,>({
onMouseEnter={handleMouseEnter(itemIndex)}
onMouseLeave={handleMouseLeave}
mt={itemIndex !== 0 && ComponentBetweenItems ? 4 : 0}
justifyContent="center"
pb="4"
>
<Item
item={item}
onItemChange={handleCellChange(itemIndex)}
debounceTimeout={debounceTimeout}
/>
<Fade in={showDeleteIndex === itemIndex}>
<Item item={item} onItemChange={handleCellChange(itemIndex)} />
<Fade
in={showDeleteIndex === itemIndex}
style={{
position: 'absolute',
left: '-15px',
top: '-15px',
}}
unmountOnExit
>
<IconButton
icon={<TrashIcon />}
aria-label="Remove cell"
onClick={deleteItem(itemIndex)}
pos="absolute"
left="-15px"
top="-15px"
size="sm"
shadow="md"
/>
</Fade>
{isOrdered && (
<>
{itemIndex === 0 && (
<SlideFade
offsetY="-5px"
in={showDeleteIndex === itemIndex}
style={{
position: 'absolute',
top: '-15px',
}}
unmountOnExit
>
<IconButton
aria-label={addLabel}
icon={<PlusIcon />}
size="xs"
shadow="md"
colorScheme="blue"
onClick={insertItem(itemIndex - 1)}
/>
</SlideFade>
)}
<SlideFade
offsetY="5px"
in={showDeleteIndex === itemIndex}
style={{
position: 'absolute',
bottom: '5px',
}}
unmountOnExit
>
<IconButton
aria-label={addLabel}
icon={<PlusIcon />}
size="xs"
shadow="md"
colorScheme="blue"
onClick={insertItem(itemIndex)}
/>
</SlideFade>
</>
)}
</Flex>
</Box>
))}
<Button
leftIcon={<PlusIcon />}
onClick={createItem}
flexShrink={0}
colorScheme="blue"
>
{addLabel}
</Button>
{!isOrdered && (
<Button
leftIcon={<PlusIcon />}
onClick={createItem}
flexShrink={0}
colorScheme="blue"
>
{addLabel}
</Button>
)}
</Stack>
)
}

View File

@@ -16,12 +16,12 @@ import { useDebouncedCallback } from 'use-debounce'
import { env } from 'utils'
import { MoreInfoTooltip } from '../MoreInfoTooltip'
type Value<HasVariable> = HasVariable extends undefined | true
type Value<HasVariable> = HasVariable extends true | undefined
? number | VariableString
: number
type Props<HasVariable extends boolean> = {
defaultValue?: Value<HasVariable>
defaultValue: Value<HasVariable> | undefined
debounceTimeout?: number
withVariableButton?: HasVariable
label?: string

View File

@@ -3,6 +3,7 @@ import { injectVariableInText } from '@/features/variables/utils/injectVariableI
import { focusInput } from '@/utils/focusInput'
import {
FormControl,
FormHelperText,
FormLabel,
HStack,
Input as ChakraInput,
@@ -26,6 +27,7 @@ export type TextInputProps = {
onChange: (value: string) => void
debounceTimeout?: number
label?: ReactNode
helperText?: ReactNode
moreInfoTooltip?: string
withVariableButton?: boolean
isRequired?: boolean
@@ -42,6 +44,7 @@ export const TextInput = forwardRef(function TextInput(
defaultValue,
debounceTimeout = 1000,
label,
helperText,
moreInfoTooltip,
withVariableButton = true,
isRequired,
@@ -137,6 +140,7 @@ export const TextInput = forwardRef(function TextInput(
) : (
Input
)}
{helperText && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
)
})