DatabaseCard.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import { FC, useContext } from 'react';
  2. import { Theme, Typography, useTheme } from '@mui/material';
  3. import { useNavigate } from 'react-router-dom';
  4. import { useTranslation } from 'react-i18next';
  5. import { MilvusService } from '@/http';
  6. import icons from '@/components/icons/Icons';
  7. import CustomButton from '@/components/customButton/CustomButton';
  8. import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
  9. import { rootContext, authContext } from '@/context';
  10. import { DatabaseObject } from '@server/types';
  11. import CreateDatabaseDialog from '../dialogs/CreateDatabaseDialog';
  12. import CustomToolTip from '@/components/customToolTip/CustomToolTip';
  13. import { CREATE_DB } from './Home';
  14. import { makeStyles } from '@mui/styles';
  15. const useStyles = makeStyles((theme: Theme) => ({
  16. wrapper: {
  17. position: 'relative',
  18. display: `flex`,
  19. flexDirection: `column`,
  20. gap: theme.spacing(1),
  21. backgroundColor: theme.palette.background.paper,
  22. color: theme.palette.text.primary,
  23. padding: theme.spacing(2),
  24. border: `1px solid ${theme.palette.divider}`,
  25. minWidth: '168px',
  26. minHeight: '168px',
  27. cursor: 'pointer',
  28. borderRadius: 8,
  29. '&:hover': {
  30. boxShadow: '0px 0px 4px 0px #00000029',
  31. borderColor: theme.palette.primary.main,
  32. },
  33. '&.active': {
  34. boxShadow: '0px 0px 4px 0px #00000029',
  35. borderColor: theme.palette.primary.main,
  36. },
  37. },
  38. dbTitle: {
  39. fontSize: '20px',
  40. lineHeight: '24px',
  41. fontWeight: 'bold',
  42. marginBottom: theme.spacing(1),
  43. '& svg': {
  44. verticalAlign: '-3px',
  45. },
  46. maxWidth: '168px',
  47. wordBreak: 'break-all',
  48. },
  49. label: {
  50. fontSize: '12px',
  51. lineHeight: '16px',
  52. color: theme.palette.text.secondary,
  53. },
  54. value: {
  55. fontSize: '24px',
  56. lineHeight: '28px',
  57. fontWeight: 'bold',
  58. marginBottom: theme.spacing(1),
  59. },
  60. delIcon: {
  61. color: theme.palette.text.primary,
  62. cursor: 'pointer',
  63. position: 'absolute',
  64. right: 4,
  65. top: 4,
  66. minWidth: 0,
  67. minHeight: 0,
  68. padding: theme.spacing(0),
  69. '& svg': {
  70. width: 15,
  71. },
  72. },
  73. // create db
  74. create: {
  75. border: `1px dashed ${theme.palette.primary.main}`,
  76. justifyContent: 'center',
  77. alignItems: 'center',
  78. color: theme.palette.text.primary,
  79. },
  80. }));
  81. export interface DatabaseCardProps {
  82. wrapperClass?: string;
  83. database: DatabaseObject;
  84. setDatabase: (database: string) => void;
  85. dropDatabase: (params: { db_name: string }) => Promise<void>;
  86. isActive?: boolean;
  87. }
  88. const DatabaseCard: FC<DatabaseCardProps> = ({
  89. database = { name: '', collections: [], createdTime: 0 },
  90. wrapperClass = '',
  91. setDatabase,
  92. dropDatabase,
  93. isActive = false,
  94. }) => {
  95. // context
  96. const { isManaged } = useContext(authContext);
  97. const { setDialog, openSnackBar, handleCloseDialog } =
  98. useContext(rootContext);
  99. // i18n
  100. const { t: homeTrans } = useTranslation('home');
  101. const { t: successTrans } = useTranslation('success');
  102. const { t: dbTrans } = useTranslation('database');
  103. const { t: btnTrans } = useTranslation('btn');
  104. const { t: dialogTrans } = useTranslation('dialog');
  105. const navigate = useNavigate();
  106. const classes = useStyles();
  107. const theme = useTheme();
  108. const DbIcon = icons.database;
  109. const DeleteIcon = icons.delete;
  110. const PlusIcon = icons.add;
  111. const ZillizIcon = icons.zilliz;
  112. const onClick = async () => {
  113. // use database
  114. await MilvusService.useDatabase({ database: database.name });
  115. // set database
  116. setDatabase(database.name);
  117. // navigate to database detail page
  118. const targetPath = `/databases/${database.name}`;
  119. navigate(targetPath);
  120. };
  121. const handleDelete = async () => {
  122. await dropDatabase({ db_name: database.name });
  123. openSnackBar(successTrans('delete', { name: dbTrans('database') }));
  124. // use database
  125. await MilvusService.useDatabase({ database: 'default' });
  126. handleCloseDialog();
  127. };
  128. // empty database => create new database
  129. if (database.name === CREATE_DB.name) {
  130. return (
  131. <section
  132. className={`${wrapperClass} ${classes.wrapper} ${classes.create}`}
  133. onClick={() => {
  134. setDialog({
  135. open: true,
  136. type: 'custom',
  137. params: {
  138. component: <CreateDatabaseDialog />,
  139. },
  140. });
  141. }}
  142. >
  143. <PlusIcon />
  144. <Typography variant="h6">{dbTrans('createTitle')}</Typography>
  145. </section>
  146. );
  147. }
  148. return (
  149. <section className={`${wrapperClass}`}>
  150. <section
  151. className={`${classes.wrapper} ${isActive ? 'active' : ''}`}
  152. onClick={onClick}
  153. >
  154. <>
  155. {isManaged ? <ZillizIcon /> : <DbIcon />}
  156. <Typography variant="h3" className={classes.dbTitle}>
  157. {database.name}
  158. </Typography>
  159. </>
  160. <div>
  161. <div key={database.name}>
  162. <Typography className={classes.label}>
  163. {homeTrans('all')}
  164. </Typography>
  165. <Typography
  166. className={classes.value}
  167. style={{ color: theme.palette.primary.main }}
  168. >
  169. {database.collections.length}
  170. </Typography>
  171. {database.createdTime !== -1 && (
  172. <>
  173. <Typography className={classes.label}>
  174. {homeTrans('createdTime')}
  175. </Typography>
  176. <Typography className={classes.label}>
  177. {new Date(database.createdTime / 1000000).toLocaleString()}
  178. </Typography>
  179. </>
  180. )}
  181. </div>
  182. {database.name !== 'default' && (
  183. <CustomButton
  184. className={classes.delIcon}
  185. onClick={(event: any) => {
  186. event.stopPropagation();
  187. setDialog({
  188. open: true,
  189. type: 'custom',
  190. params: {
  191. component: (
  192. <DeleteTemplate
  193. label={btnTrans('drop')}
  194. title={dialogTrans('deleteTitle', {
  195. type: dbTrans('database'),
  196. })}
  197. text={dbTrans('deleteWarning')}
  198. handleDelete={handleDelete}
  199. compare={database.name}
  200. />
  201. ),
  202. },
  203. });
  204. }}
  205. >
  206. <CustomToolTip
  207. title={`${btnTrans('drop')} ${dbTrans('database')}`}
  208. >
  209. <DeleteIcon />
  210. </CustomToolTip>
  211. </CustomButton>
  212. )}
  213. </div>
  214. </section>
  215. </section>
  216. );
  217. };
  218. export default DatabaseCard;