feat: add loading state to dashboard page
This commit is contained in:
parent
0cd1a877f1
commit
2cd61c03b9
4 changed files with 20 additions and 12 deletions
|
@ -22,7 +22,7 @@ export const EmptyPage: React.FC<IProps> = ({ title, subtitle, onAction, actionL
|
|||
className={clsx(styles.emptyImage, 'mb-3')}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
height: 'auto',
|
||||
height: '80px',
|
||||
}}
|
||||
/>
|
||||
<p className="empty-title">{title}</p>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Icon } from '@tabler/icons-react';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
interface IProps {
|
||||
|
@ -7,18 +8,19 @@ interface IProps {
|
|||
title: string;
|
||||
subtitle: string;
|
||||
metric: string;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const SystemStat: React.FC<IProps> = ({ icon: IconComponent, progress, title, subtitle, metric }) => (
|
||||
const SystemStat: React.FC<IProps> = ({ icon: IconComponent, progress, title, subtitle, metric, isLoading }) => (
|
||||
<div className="col-sm-6 col-lg-4">
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<div className="d-flex justify-content-between align-items-start">
|
||||
<div className="h2 mb-3 font-weight-bold">{title}</div>
|
||||
<div className={clsx('h2 mb-3 font-weight-bold', { placeholder: isLoading })}>{title}</div>
|
||||
<IconComponent />
|
||||
</div>
|
||||
<div className="h2">{metric}</div>
|
||||
<div className="mb-3 text-muted">{subtitle}</div>
|
||||
<div className={clsx('h2', { 'placeholder col-3': isLoading })}>{metric}</div>
|
||||
<div className={clsx('mb-3 text-muted', { 'placeholder col-11': isLoading })}>{subtitle}</div>
|
||||
<div className="progress progress-sm">
|
||||
<div
|
||||
className="progress-bar bg-primary"
|
||||
|
|
|
@ -4,9 +4,15 @@ import { useTranslations } from 'next-intl';
|
|||
import { SystemRouterOutput } from '../../../../server/routers/system/system.router';
|
||||
import SystemStat from '../components/SystemStat';
|
||||
|
||||
type IProps = { data: SystemRouterOutput['systemInfo'] };
|
||||
type IProps = { data?: SystemRouterOutput['systemInfo']; isLoading: boolean };
|
||||
|
||||
export const DashboardContainer: React.FC<IProps> = ({ data }) => {
|
||||
const defaultData: SystemRouterOutput['systemInfo'] = {
|
||||
cpu: { load: 0 },
|
||||
disk: { available: 0, total: 0, used: 0 },
|
||||
memory: { available: 0, total: 0, used: 0 },
|
||||
};
|
||||
|
||||
export const DashboardContainer: React.FC<IProps> = ({ data = defaultData, isLoading }) => {
|
||||
const { disk, memory, cpu } = data;
|
||||
const t = useTranslations('dashboard');
|
||||
// Convert bytes to GB
|
||||
|
@ -21,9 +27,9 @@ export const DashboardContainer: React.FC<IProps> = ({ data }) => {
|
|||
|
||||
return (
|
||||
<div className="row row-deck row-cards">
|
||||
<SystemStat title={t('cards.disk.title')} metric={`${diskUsed} GB`} subtitle={t('cards.disk.subtitle', { total: diskSize })} icon={IconDatabase} progress={percentUsed} />
|
||||
<SystemStat title={t('cards.cpu.title')} metric={`${cpu.load.toFixed(2)}%`} subtitle={t('cards.cpu.subtitle')} icon={IconCpu} progress={cpu.load} />
|
||||
<SystemStat title={t('cards.memory.title')} metric={`${percentUsedMemory || 0}%`} subtitle={`${memoryTotal} GB`} icon={IconCircuitResistor} progress={percentUsedMemory} />
|
||||
<SystemStat isLoading={isLoading} title={t('cards.disk.title')} metric={`${diskUsed} GB`} subtitle={t('cards.disk.subtitle', { total: diskSize })} icon={IconDatabase} progress={percentUsed} />
|
||||
<SystemStat isLoading={isLoading} title={t('cards.cpu.title')} metric={`${cpu.load.toFixed(2)}%`} subtitle={t('cards.cpu.subtitle')} icon={IconCpu} progress={cpu.load} />
|
||||
<SystemStat isLoading={isLoading} title={t('cards.memory.title')} metric={`${percentUsedMemory || 0}%`} subtitle={`${memoryTotal} GB`} icon={IconCircuitResistor} progress={percentUsedMemory} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,11 +9,11 @@ import { ErrorPage } from '../../../../components/ui/ErrorPage';
|
|||
|
||||
export const DashboardPage: NextPage = () => {
|
||||
const t = useTranslations();
|
||||
const { data, error } = trpc.system.systemInfo.useQuery();
|
||||
const { data, error, isLoading } = trpc.system.systemInfo.useQuery();
|
||||
|
||||
return (
|
||||
<Layout title={t('dashboard.title')}>
|
||||
{data && <DashboardContainer data={data} />}
|
||||
<DashboardContainer data={data} isLoading={isLoading} />
|
||||
{error && <ErrorPage error={t(error.data?.tError.message as MessageKey, { ...error.data?.tError.variables })} />}
|
||||
</Layout>
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue