Header.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { FC, useContext } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import {
  4. makeStyles,
  5. Theme,
  6. createStyles,
  7. Typography,
  8. Tooltip,
  9. } from '@material-ui/core';
  10. import { useNavigate } from 'react-router-dom';
  11. import { navContext, dataContext, authContext } from '@/context';
  12. import { MilvusService } from '@/http';
  13. import CustomSelector from '@/components/customSelector/CustomSelector';
  14. import StatusIcon, { LoadingType } from '@/components/status/StatusIcon';
  15. import icons from '../icons/Icons';
  16. const useStyles = makeStyles((theme: Theme) =>
  17. createStyles({
  18. header: {
  19. display: 'flex',
  20. alignItems: 'center',
  21. color: theme.palette.common.black,
  22. paddingRight: theme.spacing(1),
  23. backgroundColor: '#fff',
  24. borderBottom: '1px solid #e0e0e0',
  25. minHeight: 56,
  26. },
  27. contentWrapper: {
  28. display: 'flex',
  29. justifyContent: 'space-between',
  30. alignItems: 'center',
  31. paddingLeft: theme.spacing(1.5),
  32. flex: 1,
  33. },
  34. navigation: {
  35. display: 'flex',
  36. alignItems: 'center',
  37. },
  38. icon: {
  39. color: theme.palette.primary.main,
  40. cursor: 'pointer',
  41. marginRight: theme.spacing(1),
  42. width: '20px',
  43. },
  44. addressWrapper: {
  45. display: 'flex',
  46. alignItems: 'center',
  47. '& .text': {
  48. marginRight: theme.spacing(2),
  49. '& .address': {
  50. fontSize: '14px',
  51. lineHeight: '20px',
  52. color: '#545454',
  53. },
  54. '& .status': {
  55. fontSize: '12px',
  56. lineHeight: '16px',
  57. color: '#1ba954',
  58. },
  59. },
  60. },
  61. database: {
  62. width: theme.spacing(16),
  63. marginRight: theme.spacing(2),
  64. },
  65. })
  66. );
  67. const Header: FC = () => {
  68. const classes = useStyles();
  69. const { navInfo } = useContext(navContext);
  70. const { database, databases, setDatabase, loading } = useContext(dataContext);
  71. const { authReq, logout } = useContext(authContext);
  72. const { address, username } = authReq;
  73. const navigate = useNavigate();
  74. const { t: commonTrans } = useTranslation();
  75. const statusTrans = commonTrans('status');
  76. const { t: dbTrans } = useTranslation('database');
  77. const BackIcon = icons.back;
  78. const LogoutIcon = icons.logout;
  79. const Avatar = icons.avatar;
  80. const handleBack = (path: string) => {
  81. navigate(path);
  82. };
  83. const handleLogout = async () => {
  84. logout();
  85. };
  86. const useDatabase = async (database: string) => {
  87. await MilvusService.useDatabase({ database });
  88. };
  89. const dbOptions = databases.map(d => ({ value: d.name, label: d.name }));
  90. const isLoadingDb = dbOptions.length === 0;
  91. return (
  92. <header className={classes.header}>
  93. <div className={classes.contentWrapper}>
  94. <div className={classes.navigation}>
  95. {navInfo.backPath !== '' && (
  96. <BackIcon
  97. classes={{ root: classes.icon }}
  98. onClick={() => handleBack(navInfo.backPath)}
  99. />
  100. )}
  101. {navInfo.showDatabaseSelector &&
  102. (!isLoadingDb ? (
  103. <CustomSelector
  104. label={dbTrans('database')}
  105. value={database}
  106. onChange={async (e: { target: { value: unknown } }) => {
  107. const database = e.target.value as string;
  108. await useDatabase(database);
  109. setDatabase(database);
  110. // if url contains databases, go to the database page
  111. if (window.location.hash.includes('databases')) {
  112. navigate(`/databases/${database}`);
  113. }
  114. }}
  115. options={dbOptions}
  116. variant="filled"
  117. wrapperClass={classes.database}
  118. disabled={loading}
  119. />
  120. ) : (
  121. <StatusIcon type={LoadingType.CREATING} />
  122. ))}
  123. <Typography variant="h5" color="textPrimary">
  124. {navInfo.navTitle}
  125. </Typography>
  126. {navInfo.extra}
  127. </div>
  128. <div className={classes.addressWrapper}>
  129. <div className="text">
  130. <Typography className="address">{address}</Typography>
  131. <Typography className="status">{statusTrans.running}</Typography>
  132. </div>
  133. {username && (
  134. <Tooltip title={username}>
  135. <div>
  136. <Avatar classes={{ root: classes.icon }} />
  137. </div>
  138. </Tooltip>
  139. )}
  140. <Tooltip title={''}>
  141. <div>
  142. <LogoutIcon
  143. classes={{ root: classes.icon }}
  144. onClick={handleLogout}
  145. />
  146. </div>
  147. </Tooltip>
  148. </div>
  149. </div>
  150. </header>
  151. );
  152. };
  153. export default Header;