CreateForm.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import { makeStyles, Theme, Typography } from '@material-ui/core';
  2. import { useMemo } from 'react';
  3. import { useTranslation } from 'react-i18next';
  4. import { ITextfieldConfig } from '@/components/customInput/Types';
  5. import CustomInput from '@/components/customInput/CustomInput';
  6. import CustomSelector from '@/components/customSelector/CustomSelector';
  7. import { Option } from '@/components/customSelector/Types';
  8. import { m_OPTIONS } from '@/consts';
  9. import { FormHelperType } from '../../types/Common';
  10. const useStyles = makeStyles((theme: Theme) => ({
  11. wrapper: {
  12. maxWidth: '480px',
  13. },
  14. select: {
  15. width: '100%',
  16. marginBottom: theme.spacing(2),
  17. },
  18. paramTitle: {
  19. margin: theme.spacing(2, 0),
  20. color: theme.palette.attuGrey.dark,
  21. lineHeight: '20px',
  22. fontSize: '14px',
  23. },
  24. }));
  25. const CreateForm = (
  26. props: FormHelperType & {
  27. metricOptions: Option[];
  28. indexOptions: Option[];
  29. indexParams: string[];
  30. indexTypeChange?: (type: string) => void;
  31. }
  32. ) => {
  33. const classes = useStyles();
  34. const {
  35. updateForm,
  36. formValue,
  37. checkIsValid,
  38. validation,
  39. indexParams,
  40. indexTypeChange,
  41. indexOptions,
  42. metricOptions,
  43. } = props;
  44. const { t: commonTrans } = useTranslation();
  45. const { t: indexTrans } = useTranslation('index');
  46. const { t: warningTrans } = useTranslation('warning');
  47. const paramsConfig: ITextfieldConfig[] = useMemo(() => {
  48. const result = [];
  49. const generateNumberConfig = (
  50. label: string,
  51. key: string,
  52. min: number,
  53. max: number
  54. ) => {
  55. const config: ITextfieldConfig = {
  56. label,
  57. key,
  58. onChange: value => {
  59. updateForm(key, value);
  60. },
  61. variant: 'filled',
  62. fullWidth: true,
  63. type: 'number',
  64. value: formValue[key],
  65. validations: [
  66. {
  67. rule: 'require',
  68. errorText: warningTrans('required', { name: label }),
  69. },
  70. {
  71. rule: 'range',
  72. errorText: warningTrans('range', { min, max }),
  73. extraParam: {
  74. min,
  75. max,
  76. type: 'number',
  77. },
  78. },
  79. ],
  80. };
  81. return config;
  82. };
  83. const nlist = generateNumberConfig('nlist', 'nlist', 1, 65536);
  84. const nbits = generateNumberConfig('nbits', 'nbits', 1, 16);
  85. const nTrees = generateNumberConfig('nTrees', 'n_trees', 1, 1024);
  86. const M = generateNumberConfig('M', 'M', 4, 64);
  87. const efConstruction = generateNumberConfig(
  88. 'Ef Construction',
  89. 'efConstruction',
  90. 8,
  91. 512
  92. );
  93. const outDegree = generateNumberConfig('out_degree', 'out_degree', 5, 300);
  94. const candidatePoolSize = generateNumberConfig(
  95. 'candidate_pool_size',
  96. 'candidate_pool_size',
  97. 50,
  98. 1000
  99. );
  100. const searchLength = generateNumberConfig(
  101. 'search_length',
  102. 'search_length',
  103. 10,
  104. 300
  105. );
  106. const knng = generateNumberConfig('knng', 'knng', 5, 300);
  107. if (indexParams.includes('nlist')) {
  108. result.push(nlist);
  109. }
  110. if (indexParams.includes('nbits')) {
  111. result.push(nbits);
  112. }
  113. if (indexParams.includes('M')) {
  114. result.push(M);
  115. }
  116. if (indexParams.includes('efConstruction')) {
  117. result.push(efConstruction);
  118. }
  119. if (indexParams.includes('n_trees')) {
  120. result.push(nTrees);
  121. }
  122. if (indexParams.includes('out_degree')) {
  123. result.push(outDegree);
  124. }
  125. if (indexParams.includes('candidate_pool_size')) {
  126. result.push(candidatePoolSize);
  127. }
  128. if (indexParams.includes('search_length')) {
  129. result.push(searchLength);
  130. }
  131. if (indexParams.includes('knng')) {
  132. result.push(knng);
  133. }
  134. return result;
  135. }, [updateForm, warningTrans, indexParams, formValue]);
  136. const indexNameConfig: ITextfieldConfig = {
  137. label: 'Index Name',
  138. key: 'index_name',
  139. onChange: (value: string) => updateForm('index_name', value),
  140. variant: 'filled',
  141. placeholder: 'Index name',
  142. fullWidth: true,
  143. validations: [
  144. {
  145. rule: 'require',
  146. errorText: warningTrans('required', {
  147. name: 'Index Name',
  148. }),
  149. },
  150. ],
  151. defaultValue: '',
  152. };
  153. return (
  154. <div className={classes.wrapper}>
  155. <CustomInput
  156. type="text"
  157. textConfig={indexNameConfig}
  158. checkValid={checkIsValid}
  159. validInfo={validation}
  160. />
  161. <CustomSelector
  162. label={indexTrans('type')}
  163. value={formValue.index_type}
  164. options={indexOptions}
  165. onChange={(e: { target: { value: unknown } }) => {
  166. const type = e.target.value;
  167. updateForm('index_type', type as string);
  168. // reset metric type value
  169. updateForm('metric_type', 'L2');
  170. indexTypeChange && indexTypeChange(type as string);
  171. }}
  172. variant="filled"
  173. wrapperClass={classes.select}
  174. />
  175. {metricOptions.length ? (
  176. <Typography className={classes.paramTitle}>
  177. {commonTrans('param')}
  178. </Typography>
  179. ) : null}
  180. {metricOptions.length ? (
  181. <CustomSelector
  182. label={indexTrans('metric')}
  183. value={formValue.metric_type}
  184. options={metricOptions}
  185. onChange={(e: { target: { value: unknown } }) => {
  186. const type = e.target.value;
  187. updateForm('metric_type', type as string);
  188. }}
  189. variant="filled"
  190. wrapperClass={classes.select}
  191. />
  192. ) : null}
  193. {indexParams.includes('m') && (
  194. <CustomSelector
  195. label="m"
  196. value={Number(formValue.m)}
  197. options={m_OPTIONS}
  198. onChange={(e: { target: { value: unknown } }) =>
  199. updateForm('m', e.target.value as string)
  200. }
  201. variant="filled"
  202. wrapperClass={classes.select}
  203. />
  204. )}
  205. {paramsConfig.length
  206. ? paramsConfig.map(v => (
  207. <CustomInput
  208. type="text"
  209. textConfig={v}
  210. checkValid={checkIsValid}
  211. validInfo={validation}
  212. key={v.label}
  213. />
  214. ))
  215. : null}
  216. </div>
  217. );
  218. };
  219. export default CreateForm;