Browse Source

system view issues

Create / update time have api, but no value
Refine chart click behaviour
Should chose first node in node list view by default
Some data in system configuration is not shown up. Like: min_segment_size_to_enable_index, minio_bucket_name.. each coord should have different configuration.
Logout not working for system view
sutcalag 3 years ago
parent
commit
4642a3e1b9

+ 2 - 1
client/src/i18n/cn/systemView.ts

@@ -2,8 +2,9 @@ const systemViewTrans = {
   diskTitle: 'disk',
   diskTitle: 'disk',
   memoryTitle: 'memory',
   memoryTitle: 'memory',
   qpsTitle: 'qps',
   qpsTitle: 'qps',
-  letencyTitle: 'letency',
+  latencyTitle: 'latency',
   hardwareTitle: 'hardware',
   hardwareTitle: 'hardware',
+  configTitle: 'config',
   valueTitle: 'value',
   valueTitle: 'value',
   systemTitle: 'system',
   systemTitle: 'system',
   thName: 'Node Name',
   thName: 'Node Name',

+ 2 - 1
client/src/i18n/en/systemView.ts

@@ -2,8 +2,9 @@ const systemViewTrans = {
   diskTitle: 'disk',
   diskTitle: 'disk',
   memoryTitle: 'memory',
   memoryTitle: 'memory',
   qpsTitle: 'qps',
   qpsTitle: 'qps',
-  letencyTitle: 'letency',
+  latencyTitle: 'latency',
   hardwareTitle: 'hardware',
   hardwareTitle: 'hardware',
+  configTitle: 'config',
   valueTitle: 'value',
   valueTitle: 'value',
   systemTitle: 'system',
   systemTitle: 'system',
   thName: 'Node Name',
   thName: 'Node Name',

+ 29 - 9
client/src/plugins/system/DataCard.tsx

@@ -137,9 +137,23 @@ const DataCard: FC<DataCardProps & React.HTMLAttributes<HTMLDivElement>> = (prop
   const { t: commonTrans } = useTranslation();
   const { t: commonTrans } = useTranslation();
   const capacityTrans: { [key in string]: string } = commonTrans('capacity');
   const capacityTrans: { [key in string]: string } = commonTrans('capacity');
   const { node, extend } = props;
   const { node, extend } = props;
+
   const hardwareTitle = [t('hardwareTitle'), t('valueTitle')];
   const hardwareTitle = [t('hardwareTitle'), t('valueTitle')];
   const hardwareContent = [];
   const hardwareContent = [];
-  const infos = node?.infos?.hardware_infos || {};
+
+  const configTitle = [t('configTitle'), t('valueTitle')];
+  const systemConfig: { label: string; value: any; }[] = [];
+
+  const systemTitle = [t('systemTitle'), t('valueTitle')];
+  const systemContent = [];
+
+  const {
+    created_time: create,
+    updated_time: update,
+    system_info = {},
+    hardware_infos: infos = {},
+    system_configurations,
+  } = node?.infos || {};
 
 
   const {
   const {
     cpu_core_count: cpu = 0,
     cpu_core_count: cpu = 0,
@@ -163,19 +177,20 @@ const DataCard: FC<DataCardProps & React.HTMLAttributes<HTMLDivElement>> = (prop
     });
     });
   }
   }
 
 
-  const systemTitle = [t('systemTitle'), t('valueTitle')];
-  const systemContent = [];
-  const sysInfos = node?.infos?.system_info || {};
+  if (system_configurations) {
+    Object.keys(system_configurations).forEach(key => {
+      systemConfig.push({ label: key, value: system_configurations[key] });
+    });
+  }
+
   const {
   const {
     system_version: version,
     system_version: version,
     deploy_mode: mode = '',
     deploy_mode: mode = '',
-    created_time: create = '',
-    updated_time: update = '',
-  } = sysInfos;
+  } = system_info;
   systemContent.push({ label: t('thVersion'), value: version });
   systemContent.push({ label: t('thVersion'), value: version });
   systemContent.push({ label: t('thDeployMode'), value: mode });
   systemContent.push({ label: t('thDeployMode'), value: mode });
-  systemContent.push({ label: t('thCreateTime'), value: create });
-  systemContent.push({ label: t('thUpdateTime'), value: update });
+  systemContent.push({ label: t('thCreateTime'), value: create ? new Date(create.substr(0, 37)).toLocaleString() : '' });
+  systemContent.push({ label: t('thUpdateTime'), value: update ? new Date(update.substr(0, 37)).toLocaleString() : '' });
 
 
   return (
   return (
     <div className={classes.root}>
     <div className={classes.root}>
@@ -188,6 +203,11 @@ const DataCard: FC<DataCardProps & React.HTMLAttributes<HTMLDivElement>> = (prop
       </div>
       </div>
       {extend && <DataSection titles={hardwareTitle} contents={hardwareContent} />}
       {extend && <DataSection titles={hardwareTitle} contents={hardwareContent} />}
       <DataSection titles={systemTitle} contents={systemContent} />
       <DataSection titles={systemTitle} contents={systemContent} />
+      {systemConfig.length ?
+        <DataSection titles={configTitle} contents={systemConfig} />
+        :
+        null
+      }
     </div>
     </div>
   );
   );
 };
 };

+ 10 - 1
client/src/plugins/system/NodeListView.tsx

@@ -21,7 +21,6 @@ const getStyles = makeStyles((theme: Theme) => ({
       `"a a"
       `"a a"
        "b ."
        "b ."
        "b d"`,
        "b d"`,
-    height: 'calc(100% - 28px)',
   },
   },
   cardContainer: {
   cardContainer: {
     display: 'grid',
     display: 'grid',
@@ -124,6 +123,16 @@ const NodeListView: FC<NodeListViewProps> = (props) => {
     }
     }
   }, [selectedCord, childNodes, capacityTrans]);
   }, [selectedCord, childNodes, capacityTrans]);
 
 
+  useEffect(() => {
+    const timeoutID = window.setTimeout(() => {
+      const el = document.querySelectorAll<HTMLElement>(".MuiDataGrid-row")[0];
+      if (el instanceof HTMLElement) {
+        el.click();
+      }
+    }, 300);
+    return () => window.clearTimeout(timeoutID);
+  }, [childNodes]);
+
   return (
   return (
     <div className={classes.root}>
     <div className={classes.root}>
       <button className={classes.childCloseBtn} onClick={() => setCord(null)}>
       <button className={classes.childCloseBtn} onClick={() => setCord(null)}>

+ 9 - 7
client/src/plugins/system/SystemView.tsx

@@ -17,7 +17,7 @@ const getStyles = makeStyles((theme: Theme) => ({
     fontFamily: 'Roboto',
     fontFamily: 'Roboto',
     margin: '14px 40px',
     margin: '14px 40px',
     position: 'relative',
     position: 'relative',
-    height: 'calc(100vh - 80px)',
+    height: 'fit-content',
     display: 'flex',
     display: 'flex',
     flexDirection: 'column',
     flexDirection: 'column',
   },
   },
@@ -48,10 +48,11 @@ const getStyles = makeStyles((theme: Theme) => ({
   },
   },
   showChildView: {
   showChildView: {
     top: 0,
     top: 0,
-    maxHeight: 'auto',
+    minHeight: '100%',
+    height: 'fit-content',
   },
   },
   hideChildView: {
   hideChildView: {
-    top: '1000px',
+    top: '1500px',
     maxHeight: 0,
     maxHeight: 0,
   },
   },
   childCloseBtn: {
   childCloseBtn: {
@@ -68,7 +69,7 @@ const parseJson = (jsonData: any) => {
 
 
   const system = {
   const system = {
     // qps: Math.random() * 1000,
     // qps: Math.random() * 1000,
-    letency: Math.random() * 1000,
+    latency: Math.random() * 1000,
     disk: 0,
     disk: 0,
     diskUsage: 0,
     diskUsage: 0,
     memory: 0,
     memory: 0,
@@ -94,7 +95,6 @@ const parseJson = (jsonData: any) => {
   return { nodes, childNodes, system };
   return { nodes, childNodes, system };
 }
 }
 
 
-
 const SystemView: any = () => {
 const SystemView: any = () => {
   useNavigationHook(ALL_ROUTER_TYPES.SYSTEM);
   useNavigationHook(ALL_ROUTER_TYPES.SYSTEM);
   const { t } = useTranslation('systemView');
   const { t } = useTranslation('systemView');
@@ -123,16 +123,18 @@ const SystemView: any = () => {
   }, []);
   }, []);
 
 
   let qps = system?.qps || 0;
   let qps = system?.qps || 0;
-  const letency = system?.letency || 0;
+  const latency = system?.latency || 0;
   const childView = useRef<HTMLInputElement>(null);
   const childView = useRef<HTMLInputElement>(null);
 
 
+
+
   return (
   return (
     <div className={classes.root}>
     <div className={classes.root}>
       <div className={clsx(classes.cardContainer, selectedCord && classes.transparent)}>
       <div className={clsx(classes.cardContainer, selectedCord && classes.transparent)}>
         <ProgressCard title={t('diskTitle')} usage={system.diskUsage} total={system.disk} />
         <ProgressCard title={t('diskTitle')} usage={system.diskUsage} total={system.disk} />
         <ProgressCard title={t('memoryTitle')} usage={system.memoryUsage} total={system.memory} />
         <ProgressCard title={t('memoryTitle')} usage={system.memoryUsage} total={system.memory} />
         <LineChartCard title={t('qpsTitle')} value={qps} />
         <LineChartCard title={t('qpsTitle')} value={qps} />
-        <LineChartCard title={t('letencyTitle')} value={letency} />
+        <LineChartCard title={t('latencyTitle')} value={latency} />
       </div>
       </div>
       <div className={classes.contentContainer}>
       <div className={classes.contentContainer}>
         <Topo nodes={nodes} setNode={setNode} setCord={setCord} />
         <Topo nodes={nodes} setNode={setNode} setCord={setCord} />

+ 25 - 11
client/src/plugins/system/Topology.tsx

@@ -25,14 +25,13 @@ const getStyles = makeStyles((theme: Theme) => ({
       transition: 'all .25s',
       transition: 'all .25s',
     },
     },
 
 
-    '&:hover, &:focus': {
+    '&:hover, &.selectedNode': {
       transform: 'scale(1.1)',
       transform: 'scale(1.1)',
       filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))',
       filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))',
-    },
-
-    '&:focus': {
       outline: 'none',
       outline: 'none',
+    },
 
 
+    '&.selectedNode': {
       '& circle': {
       '& circle': {
         fill: '#06AFF2',
         fill: '#06AFF2',
         stroke: '#06AFF2',
         stroke: '#06AFF2',
@@ -57,14 +56,13 @@ const getStyles = makeStyles((theme: Theme) => ({
       transition: 'all .25s',
       transition: 'all .25s',
     },
     },
 
 
-    '&:hover, &:focus': {
+    '&:hover, &.selectedNode': {
       transform: 'scale(1.1)',
       transform: 'scale(1.1)',
       filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))',
       filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))',
-    },
-
-    '&:focus': {
       outline: 'none',
       outline: 'none',
+    },
 
 
+    '&.selectedNode': {
       '& svg path': {
       '& svg path': {
         fill: 'white',
         fill: 'white',
       },
       },
@@ -113,6 +111,20 @@ const capitalize = (s: string) => {
   return s.charAt(0).toUpperCase() + s.slice(1);
   return s.charAt(0).toUpperCase() + s.slice(1);
 }
 }
 
 
+const setSelected = (el: any) => {
+  const nodes = document.querySelectorAll<HTMLElement>('.selectedNode');
+  nodes.forEach(n => n.classList.remove('selectedNode'));
+
+  function getGParent(e: any): any {
+    if (e.tagName === 'g') {
+      return e;
+    } else {
+      return getGParent(e.parentElement);
+    }
+  }
+  getGParent(el).classList.add('selectedNode');
+}
+
 const Topo = (props: any) => {
 const Topo = (props: any) => {
   const classes = getStyles();
   const classes = getStyles();
   const { nodes, setNode, setCord } = props;
   const { nodes, setNode, setCord } = props;
@@ -221,8 +233,9 @@ const Topo = (props: any) => {
               <g key={`${node?.infos?.name}`}>
               <g key={`${node?.infos?.name}`}>
                 <line x1={`${WIDTH / 2}`} y1={`${HEIGHT / 2}`} x2={nodeCenterX} y2={nodeCenterY} stroke="#06AFF2" />
                 <line x1={`${WIDTH / 2}`} y1={`${HEIGHT / 2}`} x2={nodeCenterX} y2={nodeCenterY} stroke="#06AFF2" />
                 {connectedLength && (<line x1={nodeCenterX} y1={nodeCenterY} x2={childNodeCenterX} y2={childNodeCenterY} stroke="#06AFF2" />)}
                 {connectedLength && (<line x1={nodeCenterX} y1={nodeCenterY} x2={childNodeCenterX} y2={childNodeCenterY} stroke="#06AFF2" />)}
-                <g className={classes.childNode} tabIndex={0} onClick={() => {
+                <g className={classes.childNode} tabIndex={0} onClick={e => {
                   setNode(node);
                   setNode(node);
+                  setSelected(e.target);
                 }}
                 }}
                 >
                 >
                   <circle cx={nodeCenterX} cy={nodeCenterY} r={R2} fill="white" stroke="#06AFF2" />
                   <circle cx={nodeCenterX} cy={nodeCenterY} r={R2} fill="white" stroke="#06AFF2" />
@@ -255,9 +268,10 @@ const Topo = (props: any) => {
           }
           }
           return null;
           return null;
         })}
         })}
-        <g id="center" className={classes.rootNode} tabIndex={0} onClick={() => {
+        <g id="center" className={classes.rootNode} tabIndex={0} onClick={e => {
           setNode(centerNode);
           setNode(centerNode);
-        }} >
+          setSelected(e.target);
+        }}>
           <circle cx={`${WIDTH / 2}`} cy={`${HEIGHT / 2}`} r={R1} fill="white" stroke="#06AFF2" />
           <circle cx={`${WIDTH / 2}`} cy={`${HEIGHT / 2}`} r={R1} fill="white" stroke="#06AFF2" />
           <text fontFamily="Roboto" textAnchor="middle" alignmentBaseline="middle" fill="#06AFF2" fontWeight="700" fontSize="24" x={`${WIDTH / 2}`} y={`${HEIGHT / 2}`}>Milvus</text>
           <text fontFamily="Roboto" textAnchor="middle" alignmentBaseline="middle" fill="#06AFF2" fontWeight="700" fontSize="24" x={`${WIDTH / 2}`} y={`${HEIGHT / 2}`}>Milvus</text>
         </g>
         </g>

+ 3 - 0
client/src/plugins/system/Types.ts

@@ -5,6 +5,9 @@ export interface Node {
     hardware_infos: any,
     hardware_infos: any,
     system_info: any,
     system_info: any,
     name: string,
     name: string,
+    created_time: string,
+    updated_time: string,
+    system_configurations: any,
   },
   },
   connected: {
   connected: {
     connected_identifier: number,
     connected_identifier: number,

+ 1 - 0
client/src/plugins/system/config.json

@@ -3,6 +3,7 @@
   "version": "0.1.0",
   "version": "0.1.0",
   "client": {
   "client": {
     "path": "system",
     "path": "system",
+    "auth": true,
     "entry": "SystemView.tsx",
     "entry": "SystemView.tsx",
     "label": "System View",
     "label": "System View",
     "iconName": "navSystem"
     "iconName": "navSystem"