From a5339c43aeb327cbb2d15436a32af19d56bdad48 Mon Sep 17 00:00:00 2001 From: SUN <350916525@qq.com> Date: Sat, 9 Mar 2024 23:35:29 +0800 Subject: [PATCH] complete topic page style --- eventmesh-dashboard-view/package-lock.json | 59 ++++++++++ eventmesh-dashboard-view/package.json | 2 + eventmesh-dashboard-view/src/App.css | 0 eventmesh-dashboard-view/src/App.tsx | 5 +- .../src/assets/icons/index.ts | 3 +- .../src/routes/topic/Topic.tsx | 35 +----- .../topic/{ => stats}/AbnormalTopicCount.tsx | 0 .../src/routes/topic/stats/Stats.tsx | 110 ++++++++++++++++++ .../src/routes/topic/stats/StatsChart.tsx | 79 +++++++++++++ .../routes/topic/{ => stats}/TopicCount.tsx | 2 +- .../src/routes/topic/topic-list/TopicList.tsx | 90 ++++++++++++++ eventmesh-dashboard-view/src/utils/chart.ts | 28 +++++ 12 files changed, 379 insertions(+), 34 deletions(-) delete mode 100644 eventmesh-dashboard-view/src/App.css rename eventmesh-dashboard-view/src/routes/topic/{ => stats}/AbnormalTopicCount.tsx (100%) create mode 100644 eventmesh-dashboard-view/src/routes/topic/stats/Stats.tsx create mode 100644 eventmesh-dashboard-view/src/routes/topic/stats/StatsChart.tsx rename eventmesh-dashboard-view/src/routes/topic/{ => stats}/TopicCount.tsx (96%) create mode 100644 eventmesh-dashboard-view/src/routes/topic/topic-list/TopicList.tsx create mode 100644 eventmesh-dashboard-view/src/utils/chart.ts diff --git a/eventmesh-dashboard-view/package-lock.json b/eventmesh-dashboard-view/package-lock.json index c6ae3064..836cb6e8 100644 --- a/eventmesh-dashboard-view/package-lock.json +++ b/eventmesh-dashboard-view/package-lock.json @@ -12,6 +12,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.15.12", + "@mui/x-data-grid": "^6.19.6", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -19,6 +20,7 @@ "@types/node": "^16.18.86", "@types/react": "^18.2.63", "@types/react-dom": "^18.2.20", + "echarts": "^5.5.0", "localforage": "^1.10.0", "match-sorter": "^6.3.4", "react": "^18.2.0", @@ -3698,6 +3700,31 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/@mui/x-data-grid": { + "version": "6.19.6", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.19.6.tgz", + "integrity": "sha512-jpZkX1Gnlo87gKcD10mKMY8YoAzUD8Cv3/IvedH3FINDKO3hnraMeOciKDeUk0tYSj8RUDB02kpTHCM8ojLVBA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/utils": "^5.14.16", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -7533,6 +7560,20 @@ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, + "node_modules/echarts": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.5.0.tgz", + "integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.5.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -15737,6 +15778,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -18851,6 +18897,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zrender": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.5.0.tgz", + "integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" } } } diff --git a/eventmesh-dashboard-view/package.json b/eventmesh-dashboard-view/package.json index 9a28db5c..791cadc7 100644 --- a/eventmesh-dashboard-view/package.json +++ b/eventmesh-dashboard-view/package.json @@ -7,6 +7,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.12", "@mui/material": "^5.15.12", + "@mui/x-data-grid": "^6.19.6", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -14,6 +15,7 @@ "@types/node": "^16.18.86", "@types/react": "^18.2.63", "@types/react-dom": "^18.2.20", + "echarts": "^5.5.0", "localforage": "^1.10.0", "match-sorter": "^6.3.4", "react": "^18.2.0", diff --git a/eventmesh-dashboard-view/src/App.css b/eventmesh-dashboard-view/src/App.css deleted file mode 100644 index e69de29b..00000000 diff --git a/eventmesh-dashboard-view/src/App.tsx b/eventmesh-dashboard-view/src/App.tsx index bb8add63..b3a6fd07 100644 --- a/eventmesh-dashboard-view/src/App.tsx +++ b/eventmesh-dashboard-view/src/App.tsx @@ -1,6 +1,5 @@ import React from 'react' import { createTheme, ThemeProvider, CssBaseline } from '@mui/material' -import './App.css' import AppRoutes from './routes/Routes' function App() { @@ -8,10 +7,12 @@ function App() { () => createTheme({ palette: { - // mode: prefersDarkMode ? 'dark' : 'light', primary: { main: '#1f95fc' } + }, + typography: { + fontSize: 14 } }), [] diff --git a/eventmesh-dashboard-view/src/assets/icons/index.ts b/eventmesh-dashboard-view/src/assets/icons/index.ts index ecf08a63..8d501f86 100644 --- a/eventmesh-dashboard-view/src/assets/icons/index.ts +++ b/eventmesh-dashboard-view/src/assets/icons/index.ts @@ -1,6 +1,7 @@ import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined'; import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined'; import FoundationIcon from '@mui/icons-material/Foundation'; +import RefreshIcon from '@mui/icons-material/Refresh'; import { ReactComponent as EventMeshLogoIcon } from './eventmesh-logo.svg'; import { ReactComponent as EventMeshTopicIcon } from './eventmesh-topic.svg'; @@ -20,7 +21,7 @@ export const Icons = { HomeOutlined: HomeOutlinedIcon, AddCircleOutlineOutlined: AddCircleOutlineOutlinedIcon, Foundation: FoundationIcon, - + Refresh: RefreshIcon, EventMeshLogo: EventMeshLogoIcon, EventMeshTopic: EventMeshTopicIcon, diff --git a/eventmesh-dashboard-view/src/routes/topic/Topic.tsx b/eventmesh-dashboard-view/src/routes/topic/Topic.tsx index cce861e5..55665337 100644 --- a/eventmesh-dashboard-view/src/routes/topic/Topic.tsx +++ b/eventmesh-dashboard-view/src/routes/topic/Topic.tsx @@ -1,8 +1,8 @@ -import React, { forwardRef } from 'react' +import React, { forwardRef, useState } from 'react' import { Box, BoxProps, Paper, Stack } from '@mui/material' import Page from '../../components/Page' -import TopicCount from './TopicCount' -import AbnormalTopicCount from './AbnormalTopicCount' +import Stats from './stats/Stats' +import TopicList from './topic-list/TopicList' interface TopicProps extends BoxProps {} @@ -10,33 +10,8 @@ const Topic = forwardRef(({ ...props }, ref) => { return ( - - - - - - - - Filter - Refresh - - - Topic Stats - Message Stats - Average Message Stats - - - - - - Search - Add - - List - + + ) diff --git a/eventmesh-dashboard-view/src/routes/topic/AbnormalTopicCount.tsx b/eventmesh-dashboard-view/src/routes/topic/stats/AbnormalTopicCount.tsx similarity index 100% rename from eventmesh-dashboard-view/src/routes/topic/AbnormalTopicCount.tsx rename to eventmesh-dashboard-view/src/routes/topic/stats/AbnormalTopicCount.tsx diff --git a/eventmesh-dashboard-view/src/routes/topic/stats/Stats.tsx b/eventmesh-dashboard-view/src/routes/topic/stats/Stats.tsx new file mode 100644 index 00000000..ad0e316e --- /dev/null +++ b/eventmesh-dashboard-view/src/routes/topic/stats/Stats.tsx @@ -0,0 +1,110 @@ +import React, { forwardRef, useState } from 'react' +import { + Stack, + StackProps, + Box, + Select, + MenuItem, + Paper, + Grid +} from '@mui/material' +import TopicCount from './TopicCount' +import AbnormalTopicCount from './AbnormalTopicCount' +import { Icons } from '../../../assets/icons' +import StatsChart from './StatsChart' + +enum TimeOptionEnum { + LatestHour = 'LATEST_HOUR' +} +type StatsParams = { + time?: TimeOptionEnum + runtimeId?: string +} + +const TimeOptions = [{ value: TimeOptionEnum.LatestHour, label: '最新一小时' }] + +interface StatsProps extends StackProps {} + +const Stats = forwardRef(({ ...props }, ref) => { + const [statsParams, setStatsParams] = useState({ + runtimeId: '' + }) + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +}) + +Stats.displayName = 'Stats' +export default Stats diff --git a/eventmesh-dashboard-view/src/routes/topic/stats/StatsChart.tsx b/eventmesh-dashboard-view/src/routes/topic/stats/StatsChart.tsx new file mode 100644 index 00000000..fb89be2b --- /dev/null +++ b/eventmesh-dashboard-view/src/routes/topic/stats/StatsChart.tsx @@ -0,0 +1,79 @@ +import React, { forwardRef, useRef, useEffect } from 'react' +import { Box, BoxProps } from '@mui/material' +import echarts from '../../../utils/chart' + +interface StatsChartProps extends BoxProps {} + +const StatsChart = forwardRef( + ({ ...props }, ref) => { + const chartElemRef = useRef(null) + const chartInsRef = useRef(null) + + useEffect(() => { + if (!chartInsRef.current) { + const chartIns = echarts.init(chartElemRef.current) + const chartOptions = getChartOptions() + chartIns.setOption(chartOptions) + chartInsRef.current = chartIns + } + }, []) + + return + } +) + +StatsChart.displayName = 'StatsChart' +export default StatsChart + +const getChartOptions = () => { + return { + grid: { + top: 10, + left: 40, + right: 10, + bottom: 20 + }, + xAxis: { + type: 'category', + splitLine: { + show: true, + lineStyle: { + type: 'dashed' + } + }, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + }, + yAxis: { + type: 'value', + splitLine: { + show: true, + lineStyle: { + type: 'dashed' + } + } + }, + series: [ + { + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + showSymbol: false, + lineStyle: { + width: 0 + }, + areaStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(92, 216, 244)' + }, + { + offset: 1, + color: 'rgb(115, 189, 255)' + } + ]) + } + } + ] + } +} diff --git a/eventmesh-dashboard-view/src/routes/topic/TopicCount.tsx b/eventmesh-dashboard-view/src/routes/topic/stats/TopicCount.tsx similarity index 96% rename from eventmesh-dashboard-view/src/routes/topic/TopicCount.tsx rename to eventmesh-dashboard-view/src/routes/topic/stats/TopicCount.tsx index 22c7b66e..f3dc06ee 100644 --- a/eventmesh-dashboard-view/src/routes/topic/TopicCount.tsx +++ b/eventmesh-dashboard-view/src/routes/topic/stats/TopicCount.tsx @@ -1,6 +1,6 @@ import React, { forwardRef } from 'react' import { Paper, PaperProps, Stack, Typography } from '@mui/material' -import { Icons } from '../../assets/icons' +import { Icons } from '../../../assets/icons' interface TopicCountProps extends PaperProps {} diff --git a/eventmesh-dashboard-view/src/routes/topic/topic-list/TopicList.tsx b/eventmesh-dashboard-view/src/routes/topic/topic-list/TopicList.tsx new file mode 100644 index 00000000..77f8e363 --- /dev/null +++ b/eventmesh-dashboard-view/src/routes/topic/topic-list/TopicList.tsx @@ -0,0 +1,90 @@ +import React, { forwardRef } from 'react' +import { Stack, StackProps, TextField, Paper, Button } from '@mui/material' +import { DataGrid, GridColDef, GridRowsProp } from '@mui/x-data-grid' +import { grey } from '@mui/material/colors' + +interface TopicListProps extends StackProps {} + +const TopicList = forwardRef( + ({ ...props }, ref) => { + return ( + + + + + + + + + + + ) + } +) + +TopicList.displayName = 'TopicList' +export default TopicList + +const rows: GridRowsProp = [ + { + id: 1, + topicName: 'Topicname A0012', + topicStatus: 'NORMAL', + topicDesc: 'Topicname A0012 is for service A' + }, + { + id: 2, + topicName: 'Topicname C23', + topicStatus: 'ABNORMAL', + topicDesc: 'This is for service B' + }, + { + id: 3, + topicName: 'Topicname 40012', + topicStatus: 'ABNORMAL', + topicDesc: + 'Topic description. This could be too long to display completely in the cell' + } +] + +const columns: GridColDef[] = [ + { field: 'topicName', headerName: 'Topic 名称', width: 240 }, + { field: 'topicStatus', headerName: '健康状态', width: 150 }, + { field: 'topicDesc', headerName: '描述', flex: 1 }, + { + field: 'actions', + headerName: '操作', + headerAlign: 'center', + width: 240, + align: 'center', + renderCell: () => { + return ( + + + + + ) + } + } +] diff --git a/eventmesh-dashboard-view/src/utils/chart.ts b/eventmesh-dashboard-view/src/utils/chart.ts new file mode 100644 index 00000000..f0cff8b0 --- /dev/null +++ b/eventmesh-dashboard-view/src/utils/chart.ts @@ -0,0 +1,28 @@ +import * as echarts from 'echarts/core' + +import { LineChart } from 'echarts/charts' +import { + PolarComponent, + TitleComponent, + TooltipComponent, + GridComponent, + MarkAreaComponent, + MarkLineComponent, + ToolboxComponent +} from 'echarts/components' +import { CanvasRenderer } from 'echarts/renderers' + +echarts.use([ + LineChart, + PolarComponent, + TitleComponent, + GridComponent, + TitleComponent, + TooltipComponent, + MarkLineComponent, + MarkAreaComponent, + ToolboxComponent, + CanvasRenderer +]) + +export default echarts \ No newline at end of file