import { FC, useEffect, useState, useRef, useMemo, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { rootContext } from '../../context/Root'; import EmptyCard from '../../components/cards/EmptyCard'; import icons from '../../components/icons/Icons'; import CustomButton from '../../components/customButton/CustomButton'; import MilvusGrid from '../../components/grid/Grid'; import { ToolBarConfig } from '../../components/grid/Types'; import { getQueryStyles } from './Styles'; import Filter from '../../components/advancedSearch'; import { CollectionHttp } from '../../http/Collection'; import { FieldHttp } from '../../http/Field'; import { usePaginationHook } from '../../hooks/Pagination'; import CopyButton from '../../components/advancedSearch/CopyButton'; import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate'; import CustomToolBar from '../../components/grid/ToolBar'; const Query: FC<{ collectionName: string; }> = ({ collectionName }) => { const [fields, setFields] = useState([]); const [expression, setExpression] = useState(''); const [tableLoading, setTableLoading] = useState(); const [queryResult, setQueryResult] = useState(); const [selectedDatas, setSelectedDatas] = useState([]); const [primaryKey, setPrimaryKey] = useState(''); const { setDialog, handleCloseDialog, openSnackBar } = useContext(rootContext); const VectorSearchIcon = icons.vectorSearch; const ResetIcon = icons.refresh; const { t: dialogTrans } = useTranslation('dialog'); const { t: successTrans } = useTranslation('success'); const { t: searchTrans } = useTranslation('search'); const { t: collectionTrans } = useTranslation('collection'); const { t: btnTrans } = useTranslation('btn'); const { t: commonTrans } = useTranslation(); const copyTrans = commonTrans('copy'); const classes = getQueryStyles(); // Format result list const queryResultMemo = useMemo( () => queryResult?.map((resultItem: { [key: string]: any }) => { // Iterate resultItem keys, then format vector(array) items. const tmp = Object.keys(resultItem).reduce( (prev: { [key: string]: any }, item: string) => { if (Array.isArray(resultItem[item])) { const list2Str = `[${resultItem[item]}]`; prev[item] = (
{list2Str}
); } else { prev[item] = resultItem[item]; } return prev; }, {} ); return tmp; }), [queryResult, classes.vectorTableCell, classes.copyBtn, copyTrans.label] ); const { pageSize, handlePageSize, currentPage, handleCurrentPage, total, data: result, order, orderBy, handleGridSort, } = usePaginationHook(queryResultMemo || []); const handlePageChange = (e: any, page: number) => { handleCurrentPage(page); }; const getFields = async (collectionName: string) => { const schemaList = await FieldHttp.getFields(collectionName); const nameList = schemaList.map(v => ({ name: v.name, type: v.data_type.includes('Int') ? 'int' : 'float', })); const primaryKey = schemaList.find(v => v._isPrimaryKey === true)?._fieldName || ''; setPrimaryKey(primaryKey); setFields(nameList); }; // Get fields at first or collection name changed. useEffect(() => { collectionName && getFields(collectionName); }, [collectionName]); const filterRef = useRef(); const handleFilterReset = () => { const currentFilter: any = filterRef.current; currentFilter?.getReset(); setExpression(''); setTableLoading(null); setQueryResult(null); }; const handleFilterSubmit = (expression: string) => { setExpression(expression); setQueryResult(null); }; const handleQuery = async () => { setTableLoading(true); try { const res = await CollectionHttp.queryData(collectionName, { expr: expression, output_fields: fields.map(i => i.name), }); const result = res.data; setQueryResult(result); } catch (err) { setQueryResult([]); } finally { setTableLoading(false); } }; const handleSelectChange = (value: any) => { setSelectedDatas(value); }; const handleDelete = async () => { await CollectionHttp.deleteEntities(collectionName, { expr: `${primaryKey} in [${selectedDatas.map(v => v.id).join(',')}]`, }); handleCloseDialog(); openSnackBar(successTrans('delete', { name: collectionTrans('entites') })); handleQuery(); }; const toolbarConfigs: ToolBarConfig[] = [ { type: 'iconBtn', onClick: () => { setDialog({ open: true, type: 'custom', params: { component: ( ), }, }); }, label: collectionTrans('delete'), icon: 'delete', // tooltip: collectionTrans('deleteTooltip'), disabledTooltip: collectionTrans('deleteTooltip'), disabled: () => selectedDatas.length === 0, }, ]; return (
{`${expression || collectionTrans('exprPlaceHolder')}`}
{btnTrans('reset')} handleQuery()} > {btnTrans('query')}
{tableLoading || queryResult?.length ? ( ({ id: i.name, align: 'left', disablePadding: false, label: i.name, }))} primaryKey={fields.find(i => i.is_primary_key)?.name} openCheckBox={true} isLoading={!!tableLoading} rows={result} rowCount={total} selected={selectedDatas} setSelected={handleSelectChange} page={currentPage} onChangePage={handlePageChange} rowsPerPage={pageSize} setRowsPerPage={handlePageSize} orderBy={orderBy} order={order} handleSort={handleGridSort} /> ) : ( } text={ queryResult?.length === 0 ? searchTrans('empty') : collectionTrans('startTip') } /> )}
); }; export default Query;