import { Typography, Tooltip, Box } from '@mui/material'; import { useContext } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import AttuGrid from '@/components/grid/Grid'; import { ColDefinitionsType } from '@/components/grid/Types'; import { useTranslation } from 'react-i18next'; import Icons from '@/components/icons/Icons'; import { formatFieldType, formatNumber, findKeyValue } from '@/utils'; import { dataContext, rootContext, systemContext } from '@/context'; import IndexTypeElement from './IndexTypeElement'; import { getLabelDisplayedRows } from '@/pages/search/Utils'; import StatusAction from '@/pages/databases/collections/StatusAction'; import CustomToolTip from '@/components/customToolTip/CustomToolTip'; import { Wrapper, InfoWrapper, Card, InfoRow, InfoLabel, InfoValue, ActionWrapper, StyledChip, DataTypeChip, NameWrapper, ParamWrapper, GridWrapper, } from './StyledComponents'; import LoadCollectionDialog from '@/pages/dialogs/LoadCollectionDialog'; import RenameCollectionDialog from '@/pages/dialogs/RenameCollectionDialog'; import EditMmapDialog from '@/pages/dialogs/EditMmapDialog'; import DropCollectionDialog from '@/pages/dialogs/DropCollectionDialog'; import CopyButton from '@/components/advancedSearch/CopyButton'; import RefreshButton from '@/components/customButton/RefreshButton'; import { CollectionService } from '@/http'; import type { FieldObject } from '@server/types'; const Overview = () => { const { fetchCollection, collections, loading, database } = useContext(dataContext); const { data } = useContext(systemContext); const { setDialog } = useContext(rootContext); const { collectionName = '' } = useParams<{ collectionName: string }>(); const navigate = useNavigate(); const { t: collectionTrans } = useTranslation('collection'); const { t: indexTrans } = useTranslation('index'); const { t: btnTrans } = useTranslation('btn'); const { t: commonTrans } = useTranslation(); const consistencyTooltipsMap: Record = { Strong: collectionTrans('consistencyStrongTooltip'), Bounded: collectionTrans('consistencyBoundedTooltip'), Session: collectionTrans('consistencySessionTooltip'), Eventually: collectionTrans('consistencyEventuallyTooltip'), }; // get collection const collection = collections.find( c => c.collection_name === collectionName ); // fetch collection if not loaded if (collection && !collection.schema) { fetchCollection(collectionName); } // get fields const fields = collection?.schema?.fields || []; const colDefinitions: ColDefinitionsType[] = [ { id: 'name', align: 'left', disablePadding: true, formatter(f: FieldObject) { return ( {f.name} {f.name === '$meta' && ( )} {f.is_primary_key && ( theme.palette.secondary.light, fontWeight: 600, fontSize: '12px', height: '20px', '& .MuiChip-label': { px: 1, }, border: theme => `1px solid ${theme.palette.secondary.main}`, }} /> )} {f.is_partition_key && ( )} {findKeyValue(f.type_params, 'enable_match') && ( )} {findKeyValue(f.type_params, 'enable_analyzer') === 'true' && ( { const textToCopy = findKeyValue( f.type_params, 'analyzer_params' ); navigator.clipboard.writeText(textToCopy as string); }} /> )} {(findKeyValue(f.type_params, 'mmap.enabled') === 'true' || isCollectionMmapEnabled) && ( { setDialog({ open: true, type: 'custom', params: { component: ( { fetchCollection(collectionName); }} /> ), }, }); }} /> )} {f.function && ( { const textToCopy = JSON.stringify(f.function); navigator.clipboard.writeText(textToCopy as string); }} /> )} ); }, label: collectionTrans('fieldName'), sortBy: 'name', }, { id: 'data_type', align: 'left', disablePadding: false, formatter(f) { return ( ); }, label: collectionTrans('fieldType'), }, { id: 'nullable', align: 'left', disablePadding: false, label: collectionTrans('nullable'), formatter(f) { return ( {f.nullable ? ( ) : ( )} ); }, }, { id: 'default_value', align: 'left', disablePadding: false, label: collectionTrans('defaultValue'), formatter(f) { return ( {f.default_value || '--'} ); }, }, { id: 'name', align: 'left', disablePadding: true, label: indexTrans('indexName'), formatter(f) { return {f.index?.index_name}; }, }, { id: 'name', align: 'left', disablePadding: true, label: indexTrans('type'), notSort: true, formatter(f) { return ( { await fetchCollection(collectionName); }} /> ); }, }, { id: 'name', align: 'left', disablePadding: false, label: indexTrans('param'), notSort: true, formatter(f) { return ( {f.index ? ( {f.index.indexParameterPairs.length > 0 ? ( f.index.indexParameterPairs.map((p: any) => p.value ? (
{`${p.key}:`} {p.value}
) : ( '' ) ) ) : ( <>-- )}
) : ( <>-- )}
); }, }, { id: 'description', align: 'left', disablePadding: false, label: indexTrans('desc'), formatter(f) { return {f.description || '--'}; }, }, ]; // only show create index element when there is only one vector field let CreateIndexElement = null; if ( collection && collection.schema && collection.schema.vectorFields.length === 1 ) { CreateIndexElement = ( { await fetchCollection(collectionName); }} /> ); } // enable modify replica if there are more than one query node const enableModifyReplica = data && data.queryNodes && data.queryNodes.length > 1; // if is autoID enabled const isAutoIDEnabled = collection?.schema?.fields.some( f => f.autoID === true ); // check if collection is mmap enabled const isCollectionMmapEnabled = collection?.properties?.some((p: any) => { return p.key === 'mmap.enabled' && p.value === 'true'; }); // get loading state label return ( {collection && ( {collectionTrans('name')} {collection.collection_name} { setDialog({ open: true, type: 'custom', params: { component: ( { await fetchCollection(newName); navigate( `/databases/${database}/${newName}/schema` ); }} /> ), }, }); }} tooltip={btnTrans('rename')} icon={} /> { const res = await CollectionService.describeCollectionUnformatted( collection.collection_name ); const json = JSON.stringify(res, null, 2); const blob = new Blob([json], { type: 'application/json', }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${collection.collection_name}.json`; a.click(); }} tooltip={btnTrans('downloadSchema')} icon={} /> { setDialog({ open: true, type: 'custom', params: { component: ( { navigate(`/databases/${database}`); }} /> ), }, }); }} tooltip={btnTrans('drop')} icon={} /> { await fetchCollection(collectionName); }} icon={} /> {collectionTrans('description')} {collection?.description || '--'} {collectionTrans('createdTime')} {new Date(collection.createdTime).toLocaleString()} {collectionTrans('status')} {collectionTrans('replica')} {collection.loaded ? collection.replicas?.length : '...'} {collection.loaded && enableModifyReplica && ( { setDialog({ open: true, type: 'custom', params: { component: ( ), }, }); }} icon={} /> )} {collection.loaded ? ( collectionTrans('count') ) : ( <> {collectionTrans('rowCount')} )} {formatNumber(Number(collection?.rowCount || '0'))} {collectionTrans('features')} {isAutoIDEnabled && ( )} { setDialog({ open: true, type: 'custom', params: { component: ( { fetchCollection(collectionName); }} /> ), }, }); }} deleteIcon={ } /> )} 1 ? 'fields' : 'field'}`) )} /> ); }; export default Overview;