Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/add themes #120

Merged
merged 4 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ Pachtop is built with what I'd like to call the **"VRRTT"** stack (Vite, Rust, R
- **SysInfo** is a Rust crate that provides system information. This crate is used to get information about the system's CPU, memory, disks, network, and processes. This is what Pachtop uses to get the system metrics on different operating systems.

# Features & Roadmap

- [x] Themes & Color Schemes
- [x] Aggregate CPU usage & per-core CPU usage metrics
- [x] Memory Usage
- [x] Network Usage
- [x] System Information
- [x] Processes
- [x] Disk Usage
- [x] Persistent metrics over time
- [ ] Persistent metrics over time
- [ ] Battery Usage?
- [ ] GPU Usage?

Expand Down
4 changes: 3 additions & 1 deletion src/components/area-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import * as Highcharts from "highcharts/highstock";
import HighchartsReact from "highcharts-react-official";
import { Dispatch, SetStateAction, useEffect, useRef } from "react";
import { useState } from "react";
import { useViewportSize } from "@mantine/hooks";
import { useColorScheme, useViewportSize } from "@mantine/hooks";
import { useMantineTheme } from "@mantine/core";

export interface InitialAreaChatStateInput {
title: {
Expand All @@ -23,6 +24,7 @@ export interface InitialAreaChatStateInput {
export const useAreaChartState = (
opts: InitialAreaChatStateInput
): [Highcharts.Options, Dispatch<SetStateAction<Highcharts.Options>>] => {
const theme = useMantineTheme();
const [chartOptions, setChartOptions] = useState<Highcharts.Options>({
title: {
text: opts.title.text,
Expand Down
5 changes: 3 additions & 2 deletions src/components/page-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { Stack, Title } from "@mantine/core";
interface PageWrapperProps {
name: string;
children: React.ReactNode;
height?: number | string;
}

const PageWrapper: React.FC<PageWrapperProps> = ({ children, name }) => {
const PageWrapper: React.FC<PageWrapperProps> = ({ children, name, height }) => {
return (
<Stack spacing="lg">
<Stack spacing="lg" h={height}>
<Title order={2}>{name}</Title>
{children}
</Stack>
Expand Down
6 changes: 5 additions & 1 deletion src/features/metrics/components/disks/disk.stats-ring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import formatOverallStats from "@/features/metrics/utils/format-overall-stats";
import React from "react";

import { IconCpu2 } from "@tabler/icons-react";
import { useMantineTheme } from "@mantine/core";

const DiskStatsRing: React.FC = ({}) => {
const { disks } = useServerEventsContext();
const { other } = useMantineTheme();

const disk = disks[0];

Expand All @@ -18,7 +20,9 @@ const DiskStatsRing: React.FC = ({}) => {
const stats = React.useMemo(() => formatOverallStats(used, available), [used, available]);
const label = `Disk ${disk?.data?.at(-1)?.name}`;

return <StatsRing color="grape" Icon={IconCpu2} stats={stats} label={label} progress={progress} />;
return (
<StatsRing color={other.charts.statsRing.disk} Icon={IconCpu2} stats={stats} label={label} progress={progress} />
);
};

export default DiskStatsRing;
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import Card from "@/components/card";
import AreaChart, { useAreaChartState } from "@/components/area-chart";
import useServerEventsContext from "@/hooks/useServerEventsContext";
import { useEffect } from "react";
import { useMantineTheme } from "@mantine/core";

// TODO: Remove Luxon and ChartJS
// TODO: Make timestamp work automatically
// TODO: fix time

const GlobalCpuAreaChart: React.FC = ({}) => {
const { globalCpu } = useServerEventsContext();
const { other } = useMantineTheme();
const [chartOptions, setChartOptions] = useAreaChartState({
title: {
text: "CPU Usage",
Expand All @@ -34,13 +36,7 @@ const GlobalCpuAreaChart: React.FC = ({}) => {
name: "CPU Usage",
type: "area",
data: globalCpu.map((cpu) => [cpu.timestamp, cpu.usage]),
color: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, "rgba(255, 99, 132, 1)"],
[1, "rgba(255, 99, 132, 0.45)"],
],
},
color: other.charts.area.globalCpu.color,
},
],
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import fromNumberToPercentageString from "@/features/metrics/utils/from-number-t
import React from "react";

import { IconCpu } from "@tabler/icons-react";
import { useMantineTheme } from "@mantine/core";

const GlobalCpuStatsRing: React.FC = ({}) => {
const { globalCpu } = useServerEventsContext();
const { other } = useMantineTheme();

const progress = globalCpu.at(-1)?.usage || 0;
const stats = React.useMemo(() => fromNumberToPercentageString(progress), [progress]);

return <StatsRing color="blue" Icon={IconCpu} stats={stats} label="CPU" progress={progress} />;
return <StatsRing color={other.charts.statsRing.cpu} Icon={IconCpu} stats={stats} label="CPU" progress={progress} />;
};

export default GlobalCpuStatsRing;
10 changes: 3 additions & 7 deletions src/features/metrics/components/memory/memory.area-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import formatBytes from "@/features/metrics/utils/format-bytes";
import AreaChart, { useAreaChartState } from "@/components/area-chart";
import useServerEventsContext from "@/hooks/useServerEventsContext";
import { useEffect } from "react";
import { useMantineTheme } from "@mantine/core";

const MemoryAreaChart: React.FC = ({}) => {
const { memory } = useServerEventsContext();
const { other } = useMantineTheme();
const [chartOptions, setChartOptions] = useAreaChartState({
title: {
text: "Ram Usage",
Expand All @@ -31,13 +33,7 @@ const MemoryAreaChart: React.FC = ({}) => {
name: "RAM Usage",
type: "area",
data: memory.map((mem) => [mem.timestamp, mem.used]),
color: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, "rgba(10, 167, 147, 1)"],
[1, "rgba(10, 167, 147, 0.45)"],
],
},
color: other.charts.area.memory.color,
},
],
});
Expand Down
6 changes: 5 additions & 1 deletion src/features/metrics/components/memory/memory.stats-ring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import formatOverallStats from "@/features/metrics/utils/format-overall-stats";
import React from "react";

import { IconCpu2 } from "@tabler/icons-react";
import { useMantineTheme } from "@mantine/core";

const MemoryStatsRing: React.FC = ({}) => {
const { memory } = useServerEventsContext();
const { other } = useMantineTheme();

const available = memory?.at(-1)?.total || 0;
const used = memory?.at(-1)?.used || 0;
const progress = memory?.at(-1)?.usedPercentage || 0;

const stats = React.useMemo(() => formatOverallStats(used, available), [used, available]);

return <StatsRing color="cyan" Icon={IconCpu2} stats={stats} label="Memory" progress={progress} />;
return (
<StatsRing color={other.charts.statsRing.memory} Icon={IconCpu2} stats={stats} label="Memory" progress={progress} />
);
};

export default MemoryStatsRing;
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import AreaChart, { useAreaChartState } from "@/components/area-chart";
import useServerEventsContext from "@/hooks/useServerEventsContext";
import { useEffect, useState } from "react";
import { SeriesOptionsType } from "highcharts";
import { useMantineTheme } from "@mantine/core";

// TODO: Remove Luxon and ChartJS
// TODO: Make timestamp work automatically
// TODO: fix time

const NetworksAreaChart: React.FC = ({}) => {
const { networks } = useServerEventsContext();
const { other } = useMantineTheme();
const [chartOptions, setChartOptions] = useAreaChartState({
title: {
text: "Network Received",
Expand Down Expand Up @@ -40,12 +42,11 @@ const NetworksAreaChart: React.FC = ({}) => {
name: `${network.id}`,
type: "area",
data: network.data.map((net) => [net.timestamp, net.received]),
color: other.charts.area.networkReceived.color,
})),
});
}, [JSON.stringify(networks)]);



return (
<Card style={{ height: "450px" }}>
<AreaChart options={chartOptions} />
Expand Down
10 changes: 3 additions & 7 deletions src/features/metrics/components/swap/swap.area-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import formatBytes from "@/features/metrics/utils/format-bytes";
import AreaChart, { useAreaChartState } from "@/components/area-chart";
import useServerEventsContext from "@/hooks/useServerEventsContext";
import { useEffect } from "react";
import { useMantineTheme } from "@mantine/core";

const SwapAreaChart: React.FC = ({}) => {
const { swap } = useServerEventsContext();
const { other } = useMantineTheme();
const [chartOptions, setChartOptions] = useAreaChartState({
title: {
text: "Swap Memory Usage",
Expand All @@ -31,13 +33,7 @@ const SwapAreaChart: React.FC = ({}) => {
name: "Swap Usage",
type: "area",
data: swap.map((swap) => [swap.timestamp, swap.used]),
color: {
linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
stops: [
[0, "rgba(53, 162, 235, 0.45)"],
[1, "rgba(53, 162, 235)"],
],
},
color: other.charts.area.swap.color,
},
],
});
Expand Down
6 changes: 5 additions & 1 deletion src/features/metrics/components/swap/swap.stats-ring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import formatOverallStats from "@/features/metrics/utils/format-overall-stats";
import React from "react";

import { IconCpu2 } from "@tabler/icons-react";
import { useMantineTheme } from "@mantine/core";

const SwapStatsRing: React.FC = ({}) => {
const { swap } = useServerEventsContext();
const { other } = useMantineTheme();

const available = swap?.at(-1)?.total || 0;
const used = swap?.at(-1)?.used || 0;
const progress = swap?.at(-1)?.usedPercentage || 0;

const stats = React.useMemo(() => formatOverallStats(used, available), [used, available]);

return <StatsRing color="red" Icon={IconCpu2} stats={stats} label="Swap" progress={progress} />;
return (
<StatsRing color={other.charts.statsRing.swap} Icon={IconCpu2} stats={stats} label="Swap" progress={progress} />
);
};

export default SwapStatsRing;
27 changes: 15 additions & 12 deletions src/features/settings/pages/settings.page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
import React from "react";
import AutoStartSettingsView from "@/features/settings/views/autostart.view";
import GeneralSettingsView from "@/features/settings/views/general.view";
import AboutView from "@/features/settings/views/about.view";
import PageWrapper from "@/components/page-wrapper";
import Card from "@/components/card";

import { Icon24Hours, IconGitBranch } from "@tabler/icons-react";
import { IconGitBranch, IconSettings2 } from "@tabler/icons-react";
import { Center, Grid, NavLink } from "@mantine/core";
import { useState } from "react";

const settings = [
{ icon: Icon24Hours, label: "Auto Start", view: <AutoStartSettingsView /> },
{
icon: IconGitBranch,
label: "About",
view: <AboutView />,
},
{ icon: IconSettings2, label: "General", view: <GeneralSettingsView /> },

// TODO: FIX responsiveness
// {
// icon: IconGitBranch,
// label: "About",
// view: <AboutView />,
// },
];

const SettingsPage = () => {
const [active, setActive] = useState(0);

const items = settings.map((item, index) => (
<React.Fragment key={item.label}>
<Grid.Col span={4}>
<Grid.Col span={3}>
<NavLink
key={item.label}
active={index === active}
Expand All @@ -37,10 +40,10 @@ const SettingsPage = () => {
));

return (
<PageWrapper name="Settings">
<PageWrapper name="Settings" height={"94vh"}>
<Center>
<Card>
<Grid style={{ width: "45rem" }}>{items}</Grid>
<Card style={{ height: "85vh" }}>
<Grid style={{ width: "50rem" }}>{items}</Grid>
</Card>
</Center>
</PageWrapper>
Expand Down
36 changes: 0 additions & 36 deletions src/features/settings/views/autostart.view.tsx

This file was deleted.

Loading
Loading