feat: 增加tailchat 网络菜单

pull/70/head
moonrailgun 2 years ago
parent 7cdb5220c5
commit 11514175e6

@ -907,6 +907,8 @@ importers:
'@types/morgan': ^1.9.4
'@types/react': ^18.0.25
'@types/react-dom': ^18.0.8
ahooks: ^3.7.4
axios: ^1.2.2
body-parser: ^1.20.1
compression: ^1.7.4
cross-env: ^7.0.3
@ -937,6 +939,8 @@ importers:
'@remix-run/react': 1.9.0_biqbaboplfbrettd7655fr4n2y
'@typegoose/typegoose': 9.3.1
'@types/md5': 2.3.2
ahooks: 3.7.4_react@18.2.0
axios: 1.2.2
body-parser: 1.20.1
compression: 1.7.4
express: 4.18.2
@ -15384,6 +15388,16 @@ packages:
- debug
dev: false
/axios/1.2.2:
resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==}
dependencies:
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: false
/b-tween/0.3.3:
resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==}
dev: false
@ -30899,7 +30913,6 @@ packages:
/proxy-from-env/1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: true
/prr/1.0.1:
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}

@ -1,10 +1,9 @@
import {
Admin,
Resource,
ListGuesser,
fetchUtils,
EditGuesser,
ShowGuesser,
CustomRoutes,
} from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
import { authProvider, authStorageKey } from './authProvider';
@ -19,6 +18,9 @@ import GroupIcon from '@mui/icons-material/Group';
import AttachFileIcon from '@mui/icons-material/AttachFile';
import { theme } from './theme';
import { Dashboard } from './dashboard';
import { Route } from 'react-router-dom';
import { TailchatNetwork } from './network';
import { TailchatLayout } from './layout';
const httpClient: typeof fetchUtils.fetchJson = (url, options = {}) => {
try {
@ -47,6 +49,7 @@ export const App = () => (
basename="/admin"
theme={theme}
dashboard={Dashboard}
layout={TailchatLayout}
disableTelemetry={true}
authProvider={authProvider}
dataProvider={dataProvider}
@ -80,5 +83,9 @@ export const App = () => (
list={FileList}
show={ShowGuesser}
/>
<CustomRoutes>
<Route path="/network" element={<TailchatNetwork />} />
</CustomRoutes>
</Admin>
);

@ -0,0 +1,17 @@
import React from 'react';
import { Chip, Grid } from '@mui/material';
export const ChipItems: React.FC<{
items: string[];
}> = React.memo((props) => {
return (
<Grid container spacing={1}>
{props.items.map((item) => (
<Grid key={item} item>
<Chip label={item} />
</Grid>
))}
</Grid>
);
});
ChipItems.displayName = 'ChipItems';

@ -0,0 +1,29 @@
import React from 'react';
import {
Menu,
MenuProps,
ResourceMenuItem,
useResourceDefinitions,
} from 'react-admin';
import FilterDramaIcon from '@mui/icons-material/FilterDrama';
export const TailchatMenu: React.FC<MenuProps> = React.memo((props) => {
const resources = useResourceDefinitions();
return (
<Menu {...props}>
<Menu.DashboardItem />
{...Object.keys(resources)
.filter((name) => resources[name].hasList)
.map((name) => <ResourceMenuItem key={name} name={name} />)}
<Menu.Item
to="/admin/network"
primaryText="Tailchat 网络"
leftIcon={<FilterDramaIcon />}
/>
</Menu>
);
});
TailchatMenu.displayName = 'TailchatMenu';

@ -0,0 +1,8 @@
import React from 'react';
import { LayoutComponent } from 'react-admin';
import { Layout } from 'react-admin';
import { TailchatMenu } from './Menu';
export const TailchatLayout: LayoutComponent = (props) => (
<Layout {...props} menu={TailchatMenu} />
);

@ -0,0 +1,96 @@
import React from 'react';
import { request } from '../request';
import { useRequest } from 'ahooks';
import {
CircularProgress,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Typography,
Box,
} from '@mui/material';
import _uniq from 'lodash/uniq';
import { ChipItems } from '../components/ChipItems';
/**
* Tailchat
*/
export const TailchatNetwork: React.FC = React.memo(() => {
const { data, loading } = useRequest(async () => {
const { data } = await request('/network/all');
return data;
});
if (loading) {
return <CircularProgress />;
}
return (
<Box
sx={{
paddingTop: 2,
paddingBottom: 2,
maxWidth: '100vw',
}}
>
<Typography variant="h6" gutterBottom>
</Typography>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell></TableCell>
<TableCell>CPU</TableCell>
<TableCell>IP</TableCell>
<TableCell>SDK</TableCell>
</TableRow>
</TableHead>
<TableBody>
{(data.nodes ?? []).map((row) => (
<TableRow
key={row.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.id}
{row.local && <span> (*)</span>}
</TableCell>
<TableCell>{row.hostname}</TableCell>
<TableCell>{row.cpu}%</TableCell>
<TableCell>
<ChipItems items={row.ipList ?? []} />
</TableCell>
<TableCell>{row.client.version}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Typography variant="h6" gutterBottom>
</Typography>
<Box flexWrap="wrap" overflow="hidden">
<ChipItems items={_uniq<string>(data.services ?? [])} />
</Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Box flexWrap="wrap" overflow="hidden">
<ChipItems items={_uniq<string>(data.actions ?? [])} />
</Box>
<Typography variant="h6" gutterBottom>
</Typography>
<Box flexWrap="wrap" overflow="hidden">
<ChipItems items={_uniq<string>(data.events ?? [])} />
</Box>
</Box>
);
});
TailchatNetwork.displayName = 'TailchatNetwork';

@ -0,0 +1,29 @@
import axios from 'axios';
import { authStorageKey } from './authProvider';
import _set from 'lodash/set';
/**
*
*/
function createRequest() {
const ins = axios.create({
baseURL: '/admin/api',
});
ins.interceptors.request.use(async (val) => {
try {
const { token } = JSON.parse(
window.localStorage.getItem(authStorageKey) ?? '{}'
);
_set(val, ['headers', 'Authorization'], `Bearer ${token}`);
return val;
} catch (err) {
throw err;
}
});
return ins;
}
export const request = createRequest();

@ -39,7 +39,6 @@ export const UserList: React.FC = () => (
<DateField source="createdAt" label="创建时间" />
<PostListActionToolbar>
<ShowButton />
<EditButton />
</PostListActionToolbar>
</Datagrid>
</List>

@ -18,6 +18,8 @@
"@remix-run/react": "^1.9.0",
"@typegoose/typegoose": "9.3.1",
"@types/md5": "^2.3.2",
"ahooks": "^3.7.4",
"axios": "^1.2.2",
"body-parser": "^1.20.1",
"compression": "^1.7.4",
"express": "^4.18.2",

Loading…
Cancel
Save