DatabaseCard.tsx 6.6 KB

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