import { makeStyles, Theme, TextField, IconButton } from '@material-ui/core'; import { FC, Fragment, ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; import CustomButton from '../../components/customButton/CustomButton'; import CustomSelector from '../../components/customSelector/CustomSelector'; import icons from '../../components/icons/Icons'; import { generateId } from '../../utils/Common'; import { getCreateFieldType } from '../../utils/Format'; import { ALL_OPTIONS, AUTO_ID_OPTIONS, VECTOR_FIELDS_OPTIONS, } from './Constants'; import { CreateFieldsProps, CreateFieldType, DataTypeEnum, Field, } from './Types'; const useStyles = makeStyles((theme: Theme) => ({ rowWrapper: { display: 'flex', flexWrap: 'nowrap', alignItems: 'center', gap: '10px', width: '100%', '& .dimension': { maxWidth: '160px', }, }, input: { fontSize: '14px', }, primaryInput: { maxWidth: '160px', }, select: { width: '160px', }, descInput: { minWidth: '270px', flexGrow: 1, }, btnTxt: { textTransform: 'uppercase', }, iconBtn: { padding: 0, width: '20px', height: '20px', }, mb3: { marginBottom: theme.spacing(3), }, mb2: { marginBottom: theme.spacing(2), }, })); const CreateFields: FC = ({ fields, setFields, // @TODO validation setfieldsAllValid, setAutoID, autoID, }) => { const { t } = useTranslation('collection'); const classes = useStyles(); const primaryInt64Value = 'INT64 (Primary key)'; const AddIcon = icons.add; const RemoveIcon = icons.remove; const getSelector = ( type: 'all' | 'vector', label: string, value: number, onChange: (value: DataTypeEnum) => void ) => ( ) => { onChange(e.target.value as DataTypeEnum); }} value={value} variant="filled" label={label} classes={{ root: classes.select }} /> ); const getInput = ( label: string, value: string | number, handleChange: (value: string) => void, className = '', inputClassName = '', isReadOnly = false ) => ( ) => { handleChange(e.target.value as string); }} variant="filled" className={className} InputProps={{ classes: { input: inputClassName, }, }} disabled={isReadOnly} /> ); const changeFields = ( id: string, key: string, value: string | DataTypeEnum ) => { const newFields = fields.map(f => { if (f.id !== id) { return f; } return { ...f, [key]: value, }; }); setFields(newFields); }; const handleAddNewField = () => { const newDefaultItem: Field = { name: '', type: DataTypeEnum.Int16, isPrimaryKey: false, desc: '', isDefault: false, id: generateId(), }; setFields([...fields, newDefaultItem]); }; const handleRemoveField = (field: Field) => { const newFields = fields.filter(f => f.id !== field.id); setFields(newFields); }; const generatePrimaryKeyRow = ( field: Field, autoID: boolean ): ReactElement => { return (
{getInput( t('fieldType'), primaryInt64Value, () => {}, classes.primaryInput, classes.input, true )} {getInput(t('fieldName'), field.name, (value: string) => changeFields(field.id, 'name', value) )} ) => { const autoId = e.target.value === 'true'; setAutoID(autoId); }} variant="filled" classes={{ root: classes.select }} /> {getInput( t('description'), field.desc, (value: string) => changeFields(field.id, 'desc', value), classes.descInput )}
); }; const generateDefaultVectorRow = (field: Field): ReactElement => { return ( <>
{getSelector( 'vector', t('fieldType'), field.type, (value: DataTypeEnum) => changeFields(field.id, 'type', value) )} {getInput(t('fieldName'), field.name, (value: string) => changeFields(field.id, 'name', value) )} {getInput( t('dimension'), field.dimension as number, (value: string) => changeFields(field.id, 'dimension', value), 'dimension' )} {getInput( t('description'), field.desc, (value: string) => changeFields(field.id, 'desc', value), classes.descInput )}
{t('newBtn')} ); }; const generateNumberRow = (field: Field): ReactElement => { return (
handleRemoveField(field)} classes={{ root: classes.iconBtn }} aria-label="delete" > {getInput(t('fieldName'), field.name, (value: string) => changeFields(field.id, 'name', value) )} {getSelector('all', t('fieldType'), field.type, (value: DataTypeEnum) => changeFields(field.id, 'type', value) )} {getInput( t('description'), field.desc, (value: string) => changeFields(field.id, 'desc', value), classes.descInput )}
); }; const generateVectorRow = (field: Field) => { return (
{getInput(t('fieldName'), field.name, (value: string) => changeFields(field.id, 'name', value) )} {getSelector('all', t('fieldType'), field.type, (value: DataTypeEnum) => changeFields(field.id, 'type', value) )} {getInput( t('dimension'), field.dimension as number, (value: string) => changeFields(field.id, 'dimension', value), 'dimension' )} {getInput( t('description'), field.desc, (value: string) => changeFields(field.id, 'desc', value), classes.descInput )}
); }; const generateFieldRow = (field: Field, autoID: boolean) => { const createType: CreateFieldType = getCreateFieldType(field); switch (createType) { case 'primaryKey': { return generatePrimaryKeyRow(field, autoID); } case 'defaultVector': { return generateDefaultVectorRow(field); } case 'vector': { return generateVectorRow(field); } // use number as default createType default: { return generateNumberRow(field); } } }; return ( <> {fields.map((field, index) => ( {generateFieldRow(field, autoID)} ))} ); }; export default CreateFields;