DataCard.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import { FC } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { makeStyles } from '@material-ui/core';
  4. import Progress from './Progress';
  5. import { getByteString } from '../../utils/Format';
  6. import { DataProgressProps, DataSectionProps, DataCardProps } from './Types';
  7. const getStyles = makeStyles(() => ({
  8. root: {
  9. backgroundColor: '#F6F6F6',
  10. borderTopRightRadius: '8px',
  11. borderBottomRightRadius: '8px',
  12. height: '100%',
  13. padding: '20px 16px',
  14. boxSizing: 'border-box',
  15. },
  16. title: {
  17. display: 'flex',
  18. justifyContent: 'space-between',
  19. },
  20. content: {
  21. color: '#010E29',
  22. fontSize: '20px',
  23. fontWeight: 600,
  24. lineHeight: '36px',
  25. },
  26. desc: {
  27. color: '#82838E',
  28. fontSize: '14px',
  29. lineHeight: '36px',
  30. marginLeft: "8px",
  31. },
  32. rootName: {
  33. color: '#82838E',
  34. fontSize: '20px',
  35. lineHeight: '24px',
  36. },
  37. childName: {
  38. color: '#06AFF2',
  39. fontSize: '20px',
  40. lineHeight: '24px',
  41. },
  42. ip: {
  43. color: '#010E29',
  44. fontSize: '16px',
  45. lineHeight: '24px',
  46. },
  47. sectionRoot: {
  48. borderSpacing: '0 1px',
  49. display: 'table',
  50. marginTop: '24px',
  51. width: '100%'
  52. },
  53. sectionRow: {
  54. display: 'table-row',
  55. },
  56. sectionHeaderCell: {
  57. display: 'table-cell',
  58. color: '#82838E',
  59. fontSize: '12px',
  60. lineHeight: '24px',
  61. padding: '8px 16px',
  62. textTransform: 'uppercase',
  63. width: '50%',
  64. },
  65. sectionCell: {
  66. backgroundColor: 'white',
  67. color: '#010E29',
  68. display: 'table-cell',
  69. fontSize: '14px',
  70. lineHeight: '24px',
  71. padding: '12px 16px',
  72. textTransform: 'capitalize',
  73. verticalAlign: 'middle',
  74. width: '50%',
  75. },
  76. progressTitle: {
  77. fontSize: '14px',
  78. color: '#010E29',
  79. lineHeight: '24px',
  80. display: 'flex',
  81. justifyContent: 'space-between',
  82. }
  83. }));
  84. const DataSection: FC<DataSectionProps> = (props) => {
  85. const classes = getStyles();
  86. const { titles, contents } = props;
  87. return (
  88. <div className={classes.sectionRoot}>
  89. <div className={classes.sectionRow}>
  90. {titles.map((titleEntry) => <div key={titleEntry} className={classes.sectionHeaderCell}>{titleEntry}</div>)}
  91. </div>
  92. {contents.map((contentEntry) => {
  93. return (
  94. <div key={contentEntry.label} className={classes.sectionRow}>
  95. <div className={classes.sectionCell}>
  96. {contentEntry.label}
  97. </div>
  98. <div className={classes.sectionCell}>
  99. {contentEntry.value}
  100. </div>
  101. </div>)
  102. })}
  103. </div>
  104. );
  105. }
  106. const DataProgress: FC<DataProgressProps> = ({ percent = 0, desc = '' }) => {
  107. const classes = getStyles();
  108. return (
  109. <div>
  110. <div className={classes.progressTitle}>
  111. <span>{`${Number(percent * 100).toFixed(2)}%`}</span>
  112. <span>{desc}</span>
  113. </div>
  114. <Progress percent={percent} color='#06AFF2' />
  115. </div>
  116. )
  117. };
  118. const DataCard: FC<DataCardProps & React.HTMLAttributes<HTMLDivElement>> = (props) => {
  119. const classes = getStyles();
  120. const { t } = useTranslation('systemView');
  121. const { t: commonTrans } = useTranslation();
  122. const capacityTrans: { [key in string]: string } = commonTrans('capacity');
  123. const { node, extend } = props;
  124. const hardwareTitle = [t('hardwareTitle'), t('valueTitle')];
  125. const hardwareContent = [];
  126. const configTitle = [t('configTitle'), t('valueTitle')];
  127. const systemConfig: { label: string; value: any; }[] = [];
  128. const systemTitle = [t('systemTitle'), t('valueTitle')];
  129. const systemContent = [];
  130. const {
  131. created_time: createTime,
  132. updated_time: updateTime,
  133. system_info = {},
  134. hardware_infos: infos = {},
  135. system_configurations,
  136. } = node?.infos || {};
  137. const {
  138. cpu_core_count: cpu = 0,
  139. cpu_core_usage: cpuUsage = 0,
  140. memory = 1,
  141. memory_usage: memoryUsage = 0,
  142. disk = 1,
  143. disk_usage: diskUsage = 0,
  144. } = infos;
  145. if (extend) {
  146. hardwareContent.push({ label: t('thCPUCount'), value: cpu });
  147. hardwareContent.push({
  148. label: t('thCPUUsage'), value: <DataProgress percent={cpuUsage / 100} />
  149. });
  150. hardwareContent.push({
  151. label: t('thMemUsage'), value: <DataProgress percent={memoryUsage / memory} desc={getByteString(memoryUsage, memory, capacityTrans)} />
  152. });
  153. hardwareContent.push({
  154. label: t('thDiskUsage'), value: <DataProgress percent={diskUsage / disk} desc={getByteString(diskUsage, disk, capacityTrans)} />
  155. });
  156. }
  157. if (system_configurations) {
  158. Object.keys(system_configurations).forEach(key => {
  159. systemConfig.push({ label: key, value: system_configurations[key] });
  160. });
  161. }
  162. const {
  163. system_version: version,
  164. deploy_mode: mode = '',
  165. } = system_info;
  166. systemContent.push({ label: t('thVersion'), value: version });
  167. systemContent.push({ label: t('thDeployMode'), value: mode });
  168. systemContent.push({ label: t('thCreateTime'), value: createTime ? new Date(createTime.substring(0, 29)).toLocaleString() : '' });
  169. systemContent.push({ label: t('thUpdateTime'), value: updateTime ? new Date(updateTime.substring(0, 29)).toLocaleString() : '' });
  170. return (
  171. <div className={classes.root}>
  172. <div className={classes.title}>
  173. <div>
  174. <span className={classes.rootName}>Milvus / </span>
  175. <span className={classes.childName}>{node?.infos?.name}</span>
  176. </div>
  177. <div className={classes.ip}>{`${t('thIP')}:${infos?.ip || ''}`}</div>
  178. </div>
  179. {extend && <DataSection titles={hardwareTitle} contents={hardwareContent} />}
  180. <DataSection titles={systemTitle} contents={systemContent} />
  181. {systemConfig.length ?
  182. <DataSection titles={configTitle} contents={systemConfig} />
  183. :
  184. null
  185. }
  186. </div>
  187. );
  188. };
  189. export default DataCard;