mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-10 23:45:48 +01:00
@@ -50,6 +50,7 @@
|
||||
"prism-react-renderer": "^1.3.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"systeminformation": "^5.11.16",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { Aside as MantineAside, Group } from '@mantine/core';
|
||||
import { WeatherModule, DateModule, CalendarModule, TotalDownloadsModule } from '../modules';
|
||||
import {
|
||||
WeatherModule,
|
||||
DateModule,
|
||||
CalendarModule,
|
||||
TotalDownloadsModule,
|
||||
SystemModule,
|
||||
} from '../modules';
|
||||
import { ModuleWrapper } from '../modules/moduleWrapper';
|
||||
|
||||
export default function Aside(props: any) {
|
||||
@@ -15,11 +21,12 @@ export default function Aside(props: any) {
|
||||
base: 'auto',
|
||||
}}
|
||||
>
|
||||
<Group mt="sm" grow direction="column" style={{ width: 300 }}>
|
||||
<Group my="sm" grow direction="column" style={{ width: 300 }}>
|
||||
<ModuleWrapper module={CalendarModule} />
|
||||
<ModuleWrapper module={TotalDownloadsModule} />
|
||||
<ModuleWrapper module={WeatherModule} />
|
||||
<ModuleWrapper module={DateModule} />
|
||||
<ModuleWrapper module={SystemModule} />
|
||||
</Group>
|
||||
</MantineAside>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
RadarrMediaDisplay,
|
||||
LidarrMediaDisplay,
|
||||
ReadarrMediaDisplay,
|
||||
} from './MediaDisplay';
|
||||
} from '../common';
|
||||
import { serviceItem } from '../../../tools/types';
|
||||
|
||||
export const CalendarModule: IModule = {
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface IMedia {
|
||||
episodeNumber?: number;
|
||||
}
|
||||
|
||||
function MediaDisplay(props: { media: IMedia }) {
|
||||
export function MediaDisplay(props: { media: IMedia }) {
|
||||
const { media }: { media: IMedia } = props;
|
||||
return (
|
||||
<Group position="apart">
|
||||
1
src/components/modules/common/index.ts
Normal file
1
src/components/modules/common/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './MediaDisplay';
|
||||
@@ -4,3 +4,4 @@ export * from './search';
|
||||
export * from './ping';
|
||||
export * from './weather';
|
||||
export * from './downloads';
|
||||
export * from './system';
|
||||
|
||||
64
src/components/modules/system/SystemModule.tsx
Normal file
64
src/components/modules/system/SystemModule.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import {
|
||||
Center,
|
||||
Group,
|
||||
RingProgress,
|
||||
Title,
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import { IconCpu } from '@tabler/icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import si from 'systeminformation';
|
||||
import { useListState } from '@mantine/hooks';
|
||||
import { IModule } from '../modules';
|
||||
|
||||
export const SystemModule: IModule = {
|
||||
title: 'System info',
|
||||
description: 'Show the current CPU usage and memory usage',
|
||||
icon: IconCpu,
|
||||
component: SystemInfo,
|
||||
};
|
||||
|
||||
interface ApiResponse {
|
||||
cpu: si.Systeminformation.CpuData;
|
||||
os: si.Systeminformation.OsData;
|
||||
memory: si.Systeminformation.MemData;
|
||||
load: si.Systeminformation.CurrentLoadData;
|
||||
}
|
||||
|
||||
export default function SystemInfo(args: any) {
|
||||
const [data, setData] = useState<ApiResponse>();
|
||||
|
||||
// Refresh data every second
|
||||
useEffect(() => {
|
||||
setInterval(() => {
|
||||
axios.get('/api/modules/systeminfo').then((res) => setData(res.data));
|
||||
}, 1000);
|
||||
}, [args]);
|
||||
|
||||
// Update data every time data changes
|
||||
const [cpuLoadHistory, cpuLoadHistoryHandlers] =
|
||||
useListState<si.Systeminformation.CurrentLoadData>([]);
|
||||
|
||||
// useEffect(() => {
|
||||
|
||||
// }, [data]);
|
||||
|
||||
const theme = useMantineTheme();
|
||||
const currentLoad = data?.load?.currentLoad ?? 0;
|
||||
|
||||
return (
|
||||
<Center>
|
||||
<Group p="sm" direction="column" align="center">
|
||||
<Title order={3}>Current CPU load</Title>
|
||||
<RingProgress
|
||||
size={150}
|
||||
label={<Center>{`${currentLoad.toFixed(2)}%`}</Center>}
|
||||
thickness={15}
|
||||
roundCaps
|
||||
sections={[{ value: currentLoad ?? 0, color: 'cyan' }]}
|
||||
/>
|
||||
</Group>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
1
src/components/modules/system/index.ts
Normal file
1
src/components/modules/system/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { SystemModule } from './SystemModule';
|
||||
30
src/pages/api/modules/systeminfo.ts
Normal file
30
src/pages/api/modules/systeminfo.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import si from 'systeminformation';
|
||||
|
||||
async function Get(req: NextApiRequest, res: NextApiResponse) {
|
||||
const [osInfo, cpuInfo, memInfo, cpuLoad] = await Promise.all([
|
||||
si.osInfo(),
|
||||
si.cpu(),
|
||||
si.mem(),
|
||||
si.currentLoad(),
|
||||
]);
|
||||
|
||||
const sysinfo = {
|
||||
cpu: cpuInfo,
|
||||
os: osInfo,
|
||||
mem: memInfo,
|
||||
load: cpuLoad,
|
||||
};
|
||||
res.status(200).json(sysinfo);
|
||||
}
|
||||
|
||||
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
// Filter out if the reuqest is a POST or a GET
|
||||
if (req.method === 'GET') {
|
||||
return Get(req, res);
|
||||
}
|
||||
return res.status(405).json({
|
||||
statusCode: 405,
|
||||
message: 'Method not allowed',
|
||||
});
|
||||
};
|
||||
11
yarn.lock
11
yarn.lock
@@ -9444,6 +9444,7 @@ __metadata:
|
||||
react: ^17.0.1
|
||||
react-dom: ^17.0.1
|
||||
require-from-string: ^2.0.2
|
||||
systeminformation: ^5.11.16
|
||||
typescript: 4.6.4
|
||||
uuid: ^8.3.2
|
||||
languageName: unknown
|
||||
@@ -15069,6 +15070,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"systeminformation@npm:^5.11.16":
|
||||
version: 5.11.16
|
||||
resolution: "systeminformation@npm:5.11.16"
|
||||
bin:
|
||||
systeminformation: lib/cli.js
|
||||
checksum: 4e4fb4c9c86c658c7e07a7661ac85a102bfb0a134f76cc5c5e7daf7ba13f9b43895d4ce4d80e55275a3395d254d20a84c53f036f1baececf5b94028ec93242c4
|
||||
conditions: (os=darwin | os=linux | os=win32 | os=freebsd | os=openbsd | os=netbsd | os=sunos | os=android)
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tapable@npm:^1.0.0, tapable@npm:^1.1.3":
|
||||
version: 1.1.3
|
||||
resolution: "tapable@npm:1.1.3"
|
||||
|
||||
Reference in New Issue
Block a user