import React, {ReactNode, useRef, useState} from 'react'; import {useTrans} from '../../i18n/use-trans'; import {Trans} from '../../i18n/trans'; import {Avatar} from '../images/avatar'; import {Tooltip} from '../tooltip/tooltip'; import {IconButton} from '../buttons/icon-button'; import {EditIcon} from '../../icons/material/Edit'; import {message} from '../../i18n/message'; import {Item} from './listbox/item'; import {useController} from 'react-hook-form'; import {useControlledState} from '@react-stately/utils'; import {getInputFieldClassNames} from './input-field/get-input-field-class-names'; import clsx from 'clsx'; import {Skeleton} from '../skeleton/skeleton'; import {useNormalizedModels} from '../../users/queries/use-normalized-models'; import {useNormalizedModel} from '../../users/queries/use-normalized-model'; import {AnimatePresence, m} from 'framer-motion'; import {opacityAnimation} from '../animation/opacity-animation'; import {Select} from '@common/ui/forms/select/select'; import {MessageDescriptor} from '@common/i18n/message-descriptor'; import {BaseFieldProps} from '@common/ui/forms/input-field/base-field-props'; interface NormalizedModelFieldProps { label?: ReactNode; className?: string; background?: BaseFieldProps['background']; value?: string | number; placeholder?: MessageDescriptor; searchPlaceholder?: MessageDescriptor; defaultValue?: string | number; onChange?: (value: string | number) => void; invalid?: boolean; errorMessage?: string; description?: ReactNode; autoFocus?: boolean; queryParams?: Record; endpoint: string; disabled?: boolean; } export function NormalizedModelField({ label, className, background, value, defaultValue = '', placeholder = message('Select item...'), searchPlaceholder = message('Find an item...'), onChange, description, errorMessage, invalid, autoFocus, queryParams, endpoint, disabled, }: NormalizedModelFieldProps) { const inputRef = useRef(null); const [inputValue, setInputValue] = useState(''); const [selectedValue, setSelectedValue] = useControlledState( value, defaultValue, onChange, ); const query = useNormalizedModels(endpoint, { query: inputValue, ...queryParams, }); const {trans} = useTrans(); const fieldClassNames = getInputFieldClassNames({size: 'md'}); if (selectedValue) { return (
{label}
{ setSelectedValue(''); setInputValue(''); requestAnimationFrame(() => { inputRef.current?.focus(); inputRef.current?.click(); }); }} />
{description && !errorMessage && (
{description}
)} {errorMessage && (
{errorMessage}
)}
); } return ( ); } interface SelectedModelPreviewProps { modelId: string | number; selectedValue?: number | string; onEditClick?: () => void; endpoint?: string; disabled?: boolean; queryParams?: NormalizedModelFieldProps['queryParams']; } function SelectedModelPreview({ modelId, onEditClick, endpoint, disabled, queryParams, }: SelectedModelPreviewProps) { const {data, isLoading} = useNormalizedModel( `${endpoint}/${modelId}`, queryParams, ); if (isLoading || !data?.model) { return ; } return ( {data.model.image && }
{data.model.name}
{data.model.description}
}>
); } function LoadingSkeleton() { return (
); } interface FormNormalizedModelFieldProps extends NormalizedModelFieldProps { name: string; } export function FormNormalizedModelField({ name, ...fieldProps }: FormNormalizedModelFieldProps) { const { field: {onChange, value = ''}, fieldState: {invalid, error}, } = useController({ name, }); return ( ); }