balibabu commited on
Commit
d684338
·
1 Parent(s): 294440e

fix: Add Task Executor to system panel #2061 (#2070)

Browse files

### What problem does this PR solve?

fix: Add Task Executor to system panel #2061

### Type of change


- [x] New Feature (non-breaking change which adds functionality)

web/src/components/line-chart/index.tsx CHANGED
@@ -10,44 +10,6 @@ import {
10
  } from 'recharts';
11
  import { CategoricalChartProps } from 'recharts/types/chart/generateCategoricalChart';
12
 
13
- const data = [
14
- {
15
- name: 'Page A',
16
- uv: 4000,
17
- pv: 2400,
18
- },
19
- {
20
- name: 'Page B',
21
- uv: 3000,
22
- pv: 1398,
23
- },
24
- {
25
- name: 'Page C',
26
- uv: 2000,
27
- pv: 9800,
28
- },
29
- {
30
- name: 'Page D',
31
- uv: 2780,
32
- pv: 3908,
33
- },
34
- {
35
- name: 'Page E',
36
- uv: 1890,
37
- pv: 4800,
38
- },
39
- {
40
- name: 'Page F',
41
- uv: 2390,
42
- pv: 3800,
43
- },
44
- {
45
- name: 'Page G',
46
- uv: 3490,
47
- pv: 4300,
48
- },
49
- ];
50
-
51
  interface IProps extends CategoricalChartProps {
52
  data?: Array<{ xAxis: string; yAxis: number }>;
53
  showLegend?: boolean;
 
10
  } from 'recharts';
11
  import { CategoricalChartProps } from 'recharts/types/chart/generateCategoricalChart';
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  interface IProps extends CategoricalChartProps {
14
  data?: Array<{ xAxis: string; yAxis: number }>;
15
  showLegend?: boolean;
web/src/hooks/user-setting-hooks.ts CHANGED
@@ -1,7 +1,7 @@
1
  import { LanguageTranslationMap } from '@/constants/common';
2
  import { ResponseGetType } from '@/interfaces/database/base';
3
  import { ITenantInfo } from '@/interfaces/database/knowledge';
4
- import { ISystemStatus, IUserInfo } from '@/interfaces/database/userSetting';
5
  import userService from '@/services/user-service';
6
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
7
  import { message } from 'antd';
 
1
  import { LanguageTranslationMap } from '@/constants/common';
2
  import { ResponseGetType } from '@/interfaces/database/base';
3
  import { ITenantInfo } from '@/interfaces/database/knowledge';
4
+ import { ISystemStatus, IUserInfo } from '@/interfaces/database/user-setting';
5
  import userService from '@/services/user-service';
6
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
7
  import { message } from 'antd';
web/src/interfaces/database/{userSetting.ts → user-setting.ts} RENAMED
@@ -20,11 +20,17 @@ export interface IUserInfo {
20
  update_time: number;
21
  }
22
 
 
 
23
  export interface ISystemStatus {
24
  es: Es;
25
  minio: Minio;
26
  mysql: Minio;
27
  redis: Redis;
 
 
 
 
28
  }
29
 
30
  interface Redis {
 
20
  update_time: number;
21
  }
22
 
23
+ export type TaskExecutorElapsed = Record<string, number[]>;
24
+
25
  export interface ISystemStatus {
26
  es: Es;
27
  minio: Minio;
28
  mysql: Minio;
29
  redis: Redis;
30
+ task_executor: {
31
+ status: string;
32
+ elapsed: TaskExecutorElapsed;
33
+ };
34
  }
35
 
36
  interface Redis {
web/src/pages/user-setting/setting-system/index.less CHANGED
@@ -18,3 +18,16 @@
18
  color: red;
19
  }
20
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  color: red;
19
  }
20
  }
21
+
22
+ .taskBarTooltip {
23
+ font-size: 16px;
24
+ }
25
+
26
+ .taskBar {
27
+ width: '100%';
28
+ height: 200px;
29
+ }
30
+
31
+ .taskBarTitle {
32
+ font-size: 16px;
33
+ }
web/src/pages/user-setting/setting-system/index.tsx CHANGED
@@ -1,6 +1,9 @@
1
  import SvgIcon from '@/components/svg-icon';
2
  import { useFetchSystemStatus } from '@/hooks/user-setting-hooks';
3
- import { ISystemStatus, Minio } from '@/interfaces/database/userSetting';
 
 
 
4
  import { Badge, Card, Flex, Spin, Typography } from 'antd';
5
  import classNames from 'classnames';
6
  import lowerCase from 'lodash/lowerCase';
@@ -9,6 +12,7 @@ import { useEffect } from 'react';
9
 
10
  import { toFixed } from '@/utils/common-util';
11
  import styles from './index.less';
 
12
 
13
  const { Text } = Typography;
14
 
@@ -23,6 +27,7 @@ const TitleMap = {
23
  minio: 'MinIO Object Storage',
24
  redis: 'Redis',
25
  mysql: 'Mysql',
 
26
  };
27
 
28
  const SystemInfo = () => {
@@ -48,7 +53,11 @@ const SystemInfo = () => {
48
  type="inner"
49
  title={
50
  <Flex align="center" gap={10}>
51
- <SvgIcon name={key} width={26}></SvgIcon>
 
 
 
 
52
  <span className={styles.title}>
53
  {TitleMap[key as keyof typeof TitleMap]}
54
  </span>
@@ -60,28 +69,34 @@ const SystemInfo = () => {
60
  }
61
  key={key}
62
  >
63
- {Object.keys(info)
64
- .filter((x) => x !== 'status')
65
- .map((x) => {
66
- return (
67
- <Flex
68
- key={x}
69
- align="center"
70
- gap={16}
71
- className={styles.text}
72
- >
73
- <b>{upperFirst(lowerCase(x))}:</b>
74
- <Text
75
- className={classNames({
76
- [styles.error]: x === 'error',
77
- })}
78
  >
79
- {toFixed(info[x as keyof Minio]) as any}
80
- {x === 'elapsed' && ' ms'}
81
- </Text>
82
- </Flex>
83
- );
84
- })}
 
 
 
 
 
 
 
85
  </Card>
86
  );
87
  })}
 
1
  import SvgIcon from '@/components/svg-icon';
2
  import { useFetchSystemStatus } from '@/hooks/user-setting-hooks';
3
+ import {
4
+ ISystemStatus,
5
+ TaskExecutorElapsed,
6
+ } from '@/interfaces/database/user-setting';
7
  import { Badge, Card, Flex, Spin, Typography } from 'antd';
8
  import classNames from 'classnames';
9
  import lowerCase from 'lodash/lowerCase';
 
12
 
13
  import { toFixed } from '@/utils/common-util';
14
  import styles from './index.less';
15
+ import TaskBarChat from './task-bar-chat';
16
 
17
  const { Text } = Typography;
18
 
 
27
  minio: 'MinIO Object Storage',
28
  redis: 'Redis',
29
  mysql: 'Mysql',
30
+ task_executor: 'Task Executor',
31
  };
32
 
33
  const SystemInfo = () => {
 
53
  type="inner"
54
  title={
55
  <Flex align="center" gap={10}>
56
+ {key === 'task_executor' ? (
57
+ <img src="/logo.svg" alt="" width={26} />
58
+ ) : (
59
+ <SvgIcon name={key} width={26}></SvgIcon>
60
+ )}
61
  <span className={styles.title}>
62
  {TitleMap[key as keyof typeof TitleMap]}
63
  </span>
 
69
  }
70
  key={key}
71
  >
72
+ {key === 'task_executor' ? (
73
+ <TaskBarChat
74
+ data={info.elapsed as TaskExecutorElapsed}
75
+ ></TaskBarChat>
76
+ ) : (
77
+ Object.keys(info)
78
+ .filter((x) => x !== 'status')
79
+ .map((x) => {
80
+ return (
81
+ <Flex
82
+ key={x}
83
+ align="center"
84
+ gap={16}
85
+ className={styles.text}
 
86
  >
87
+ <b>{upperFirst(lowerCase(x))}:</b>
88
+ <Text
89
+ className={classNames({
90
+ [styles.error]: x === 'error',
91
+ })}
92
+ >
93
+ {toFixed((info as Record<string, any>)[x]) as any}
94
+ {x === 'elapsed' && ' ms'}
95
+ </Text>
96
+ </Flex>
97
+ );
98
+ })
99
+ )}
100
  </Card>
101
  );
102
  })}
web/src/pages/user-setting/setting-system/task-bar-chat.tsx ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { TaskExecutorElapsed } from '@/interfaces/database/user-setting';
2
+ import { Divider, Flex } from 'antd';
3
+ import { max } from 'lodash';
4
+ import {
5
+ Bar,
6
+ BarChart,
7
+ CartesianGrid,
8
+ ResponsiveContainer,
9
+ Tooltip,
10
+ } from 'recharts';
11
+
12
+ import styles from './index.less';
13
+
14
+ interface IProps {
15
+ data: TaskExecutorElapsed;
16
+ }
17
+
18
+ const getColor = (value: number) => {
19
+ if (value > 120) {
20
+ return 'red';
21
+ } else if (value <= 120 && value > 50) {
22
+ return '#faad14';
23
+ }
24
+ return '#52c41a';
25
+ };
26
+
27
+ const getMaxLength = (data: TaskExecutorElapsed) => {
28
+ const lengths = Object.keys(data).reduce<number[]>((pre, cur) => {
29
+ pre.push(data[cur].length);
30
+ return pre;
31
+ }, []);
32
+ return max(lengths) ?? 0;
33
+ };
34
+
35
+ const fillEmptyElementByMaxLength = (list: any[], maxLength: number) => {
36
+ if (list.length === maxLength) {
37
+ return list;
38
+ }
39
+ return list.concat(
40
+ new Array(maxLength - list.length).fill({
41
+ value: 0,
42
+ actualValue: 0,
43
+ fill: getColor(0),
44
+ }),
45
+ );
46
+ };
47
+
48
+ const CustomTooltip = ({ active, payload }: any) => {
49
+ if (active && payload && payload.length) {
50
+ return (
51
+ <div className="custom-tooltip">
52
+ <p
53
+ className={styles.taskBarTooltip}
54
+ >{`${payload[0].payload.actualValue}`}</p>
55
+ </div>
56
+ );
57
+ }
58
+
59
+ return null;
60
+ };
61
+
62
+ const TaskBarChat = ({ data }: IProps) => {
63
+ const maxLength = getMaxLength(data);
64
+ return (
65
+ <Flex gap="middle" vertical>
66
+ {Object.keys(data).map((key) => {
67
+ const list = data[key].map((x) => ({
68
+ value: x > 120 ? 120 : x,
69
+ actualValue: x,
70
+ fill: getColor(x),
71
+ }));
72
+ const nextList = fillEmptyElementByMaxLength(list, maxLength);
73
+ return (
74
+ <Flex key={key} className={styles.taskBar} vertical>
75
+ <b className={styles.taskBarTitle}>ID: {key}</b>
76
+ <ResponsiveContainer>
77
+ <BarChart data={nextList} barSize={20}>
78
+ <CartesianGrid strokeDasharray="3 3" />
79
+ <Tooltip content={<CustomTooltip></CustomTooltip>} />
80
+ <Bar dataKey="value" />
81
+ </BarChart>
82
+ </ResponsiveContainer>
83
+ <Divider></Divider>
84
+ </Flex>
85
+ );
86
+ })}
87
+ </Flex>
88
+ );
89
+ };
90
+
91
+ export default TaskBarChat;