Skip to content

Commit

Permalink
feat: add Proxmox Uptime View (#2092)
Browse files Browse the repository at this point in the history
* feat: add Proxmox Uptime View

* fix: Proxmox Uptime

* fix: Proxmox Uptime

* fix: add env.example, make formattedUptime a constant

* fix: Uptime

* fix: Implement dayjs

* fix: removed unused import

* fix: Uptime
  • Loading branch information
JasonLeeB06 authored Aug 1, 2024
1 parent 68ff84c commit c042c24
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 21 deletions.
2 changes: 1 addition & 1 deletion public/locales/en/modules/health-monitoring.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
},
"info": {
"uptime": "Uptime",
"uptimeFormat": "{{days}} days, {{hours}} hours",
"uptimeFormat": "{{days}} days, {{hours}} hours, {{minutes}} minutes",
"updates": "Updates Available",
"reboot": "Reboot"
},
Expand Down
20 changes: 14 additions & 6 deletions src/widgets/health-monitoring/HealthMonitoringTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
IconInfoSquare,
IconStatusChange,
} from '@tabler/icons-react';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import { useTranslation } from 'next-i18next';
import { useConfigContext } from '~/config/provider';
import { api } from '~/utils/api';
Expand All @@ -18,6 +20,8 @@ import HealthMonitoringFileSystem from './HealthMonitoringFileSystem';
import HealthMonitoringMemory from './HealthMonitoringMemory';
import { ClusterStatusTile } from './cluster/HealthMonitoringClusterTile';

dayjs.extend(duration);

const defaultViewStates = ['none', 'node', 'vm', 'lxc', 'storage'] as const;
type DefaultViewState = (typeof defaultViewStates)[number];

Expand Down Expand Up @@ -186,12 +190,6 @@ function HealthMonitoringWidgetTile({ widget }: HealthMonitoringWidgetProps) {
const SystemStatusTile = ({ data, properties }: { data: any; properties: any }) => {
const { t } = useTranslation('modules/health-monitoring');

const formatUptime = (uptime: number) => {
const days = Math.floor(uptime / (60 * 60 * 24));
const remainingHours = Math.floor((uptime % (60 * 60 * 24)) / 3600);
return t('info.uptimeFormat', { days: days, hours: remainingHours})
};

return (
<Stack>
<Card>
Expand Down Expand Up @@ -268,3 +266,13 @@ const useStatusQuery = (node: string, ignoreCerts: boolean) => {
};

export default definition;

export const formatUptime = (uptime: number) => {
const { t } = useTranslation('modules/health-monitoring');
const time = dayjs.duration(uptime, 's');
return t('info.uptimeFormat', {
days: Math.floor(time.asDays()),
hours: time.hours(),
minutes: time.minutes(),
});
};
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { Accordion, Center, Flex, Group, RingProgress, Stack, Text } from '@mantine/core';
import { Accordion, Card, Center, Flex, Group, RingProgress, Stack, Text } from '@mantine/core';
import {
IconBrain,
IconCpu,
IconCube,
IconDatabase,
IconDeviceLaptop,
IconInfoSquare,
IconServer,
} from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { ResourceData, ResourceSummary } from '~/widgets/health-monitoring/cluster/types';
import { ResourceData } from '~/widgets/health-monitoring/cluster/types';

import { formatUptime } from '../HealthMonitoringTile';
import { ResourceType } from './HealthMonitoringClusterResourceRow';

export const ClusterStatusTile = ({
data,
properties,
}: {
data: ResourceSummary;
properties: any;
}) => {
export const ClusterStatusTile = ({ data, properties }: { data: any; properties: any }) => {
const { t } = useTranslation('modules/health-monitoring');

const running = (total: number, current: ResourceData) => {
Expand Down Expand Up @@ -46,12 +42,26 @@ export const ClusterStatusTile = ({
(sum: number, item: ResourceData) => (item.running ? item.cpu * item.maxCpu + sum : sum),
0
);
const uptime = data.nodes.reduce(
(sum: number, { uptime }: ResourceData) => (sum > uptime ? sum : uptime),
0
);

const cpuPercent = (usedCpu / maxCpu) * 100;
const memPercent = (usedMem / maxMem) * 100;

return (
<Stack h="100%">
<Card>
<Group position="center">
<IconInfoSquare size={40} />
<Text fz="lg" tt="uppercase" fw={700} c="dimmed" align="center">
{t('info.uptime')}:
<br />
{formatUptime(uptime)}
</Text>
</Group>
</Card>
<SummaryHeader cpu={cpuPercent} memory={memPercent} include={properties.summary} />
<Accordion
variant="contained"
Expand Down Expand Up @@ -123,9 +133,8 @@ interface SummaryHeaderProps {

const SummaryHeader = ({ cpu, memory, include }: SummaryHeaderProps) => {
const { t } = useTranslation('modules/health-monitoring');
if (!include) {
return null;
}
if (!include) return null;

return (
<Center>
<Group noWrap>
Expand All @@ -142,7 +151,7 @@ const SummaryHeader = ({ cpu, memory, include }: SummaryHeaderProps) => {
sections={[{ value: cpu, color: cpu > 75 ? 'orange' : 'green' }]}
/>
<Stack align="center" justify="center" spacing={0}>
<Text>{t('cluster.summary.cpu')}</Text>
<Text weight={500}>{t('cluster.summary.cpu')}</Text>
<Text>{cpu.toFixed(1)}%</Text>
</Stack>
</Flex>
Expand All @@ -159,7 +168,7 @@ const SummaryHeader = ({ cpu, memory, include }: SummaryHeaderProps) => {
sections={[{ value: memory, color: memory > 75 ? 'orange' : 'green' }]}
/>
<Stack align="center" justify="center" spacing={0}>
<Text>{t('cluster.summary.ram')}</Text>
<Text weight={500}>{t('cluster.summary.ram')}</Text>
<Text>{memory.toFixed(1)}%</Text>
</Stack>
</Flex>
Expand Down

0 comments on commit c042c24

Please sign in to comment.