Skip to content

Commit

Permalink
feat(view): show error widget when static data cant be loaded
Browse files Browse the repository at this point in the history
  • Loading branch information
MauriceNino committed Jun 10, 2022
1 parent 6d201aa commit 89d9fcc
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 20 deletions.
1 change: 0 additions & 1 deletion apps/api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const lst = (item: string): any[] => item.split(',');

export const CONFIG: Config = {
port: numNull(penv('PORT')) ?? 3001,
enable_tilt: penv('ENABLE_TILT') === 'true',
widget_list: lst(penv('WIDGET_LIST') ?? 'os,cpu,storage,ram,network'),

disable_host: penv('DISABLE_HOST') === 'true',
Expand Down
10 changes: 5 additions & 5 deletions apps/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@ if (environment.production) {
});
}

// Send general system information
app.get('/system-info', async (_, res) => {
res.send(getStaticServerInfo());
});

// Launch the server
server.listen(CONFIG.port, async () => {
console.log('listening on *:' + CONFIG.port);
Expand All @@ -44,6 +39,11 @@ server.listen(CONFIG.port, async () => {
await loadStaticServerInfo();
const obs = getDynamicServerInfo();

// Send general system information
app.get('/system-info', async (_, res) => {
res.send(getStaticServerInfo());
});

// Send current system status
io.on('connection', socket => {
const cpuSub = obs.cpu.subscribe(cpu => {
Expand Down
11 changes: 10 additions & 1 deletion apps/view/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const GlobalStyle = createGlobalStyle`
#root {
overflow-x: hidden;
width: 100%;
min-height: 100%;
min-height: 100vh;
background: ${({ theme }) =>
theme.dark ? getDarkGradient(theme) : getLightGradient(theme)};
Expand All @@ -74,6 +74,15 @@ const GlobalStyle = createGlobalStyle`
.ant-switch-checked {
background: var(--ant-primary-color);
}
.ant-btn {
background: ${({ theme }) => theme.colors.background};
border: none;
&:hover, &:focus, &:active {
background: var(--ant-primary-color);
}
}
`;

export const App: FC = () => {
Expand Down
18 changes: 13 additions & 5 deletions apps/view/src/api/os-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ServerInfo } from '@dash/common';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { environment } from '../environments/environment';

export type HttpResponse<T> = {
Expand All @@ -9,13 +9,17 @@ export type HttpResponse<T> = {
error?: any;
};

export const useServerInfo = () => {
export const useServerInfo = (): [
HttpResponse<ServerInfo>,
() => Promise<void>
] => {
const [serverInfo, setServerInfo] = useState<HttpResponse<ServerInfo>>({
loading: true,
});

useEffect(() => {
axios
const loadStaticData = useCallback(async () => {
setServerInfo({ loading: true });
await axios
.get<ServerInfo>(`${environment.backendUrl}/system-info`)
.then(result =>
setServerInfo({
Expand All @@ -31,5 +35,9 @@ export const useServerInfo = () => {
);
}, []);

return serverInfo;
useEffect(() => {
loadStaticData();
}, [loadStaticData]);

return [serverInfo, loadStaticData];
};
13 changes: 9 additions & 4 deletions apps/view/src/components/chart-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useIsMobile } from '../services/mobile';
type ContainerProps = {
mobile: boolean;
edges: [boolean, boolean, boolean, boolean];
loading: boolean;
};
const Container = styled.div<ContainerProps>`
position: relative;
Expand All @@ -27,11 +28,14 @@ const Container = styled.div<ContainerProps>`
> div {
overflow: hidden;
${({ edges: [top, right, bottom, left], loading }) =>
!loading &&
`
position: absolute;
border-radius: ${({ edges: [top, right, bottom, left] }) =>
`${top ? '25px' : '10px'} ${right ? '25px' : '10px'} ${
bottom ? '25px' : '10px'
} ${left ? '25px' : '10px'}`};
border-radius: ${`${top ? '25px' : '10px'} ${right ? '25px' : '10px'} ${
bottom ? '25px' : '10px'
} ${left ? '25px' : '10px'}`};
`}
}
&:before {
Expand Down Expand Up @@ -73,6 +77,7 @@ export const ChartContainer = motion(
ref={ref}
mobile={isMobile}
edges={props.edges ?? [true, true, true, true]}
loading={!props.contentLoaded}
>
{props.contentLoaded ? (
<>
Expand Down
60 changes: 57 additions & 3 deletions apps/view/src/components/main-widget-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GlassPane } from '../components/glass-pane';
import { environment } from '../environments/environment';
import { useIsMobile } from '../services/mobile';
import { CpuWidget } from '../widgets/cpu';
import { ErrorWidget } from '../widgets/error';
import { NetworkWidget } from '../widgets/network';
import { RamWidget } from '../widgets/ram';
import { ServerWidget } from '../widgets/server';
Expand Down Expand Up @@ -44,10 +45,25 @@ const FlexContainer = styled(motion.div)<{ mobile: boolean }>`
row-gap: ${({ mobile }) => (mobile ? '40px' : '70px')};
`;

const ErrorContainer = styled(motion.div)<{ mobile: boolean }>`
width: ${({ mobile }) => (mobile ? 'calc(100vw - 50px)' : '92vw')};
min-height: ${({ mobile }) => (mobile ? 'calc(100vh - 50px)' : '86vh')};
margin: ${({ mobile }) => (mobile ? '50px' : '7vh')} auto
${({ mobile }) => (mobile ? '50px' : '7vh')} auto;
display: flex;
flex-flow: row wrap;
column-gap: 40px;
row-gap: ${({ mobile }) => (mobile ? '40px' : '70px')};
justify-content: center;
align-items: center;
`;

export const MainWidgetContainer: FC = () => {
const isMobile = useIsMobile();

const serverInfo = useServerInfo();
const [serverInfo, reloadServerInfo] = useServerInfo();
const osData = serverInfo.data?.os;
const cpuData = serverInfo.data?.cpu;
const ramData = serverInfo.data?.ram;
Expand Down Expand Up @@ -103,8 +119,47 @@ export const MainWidgetContainer: FC = () => {
socket.on('storage-load', data => {
setStorageLoad(data);
});
}, []);

return () => {
socket.close();
};
}, [serverInfo.data]);

const errors = [
{
condition: !!serverInfo.error,
text: 'Error loading the static data!',
},
{
condition: !config,
text: 'Invalid or incomplete static data loaded!',
},
{
condition: serverInfo.loading,
text: 'Loading static data...',
},
];
const error = errors.find(e => e.condition);

if (error) {
return (
<ErrorContainer
variants={containerVariants}
initial='initial'
animate='animate'
exit='exit'
mobile={isMobile}
>
<ErrorWidget
errorText={error.text}
onReload={reloadServerInfo}
loading={serverInfo.loading}
/>
</ErrorContainer>
);
}

// Can never happen
if (!config) {
return null;
}
Expand Down Expand Up @@ -164,7 +219,6 @@ export const MainWidgetContainer: FC = () => {
layoutId={`widget_${widget}`}
grow={currentConfig.grow}
minWidth={currentConfig.minWidth}
enableTilt={config?.enable_tilt}
>
<currentConfig.Widget
// @ts-ignore
Expand Down
88 changes: 88 additions & 0 deletions apps/view/src/widgets/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {
faExclamationTriangle,
faRotateRight,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Button } from 'antd';
import { Variants } from 'framer-motion';
import { FC } from 'react';
import { SwapSpinner } from 'react-spinners-kit';
import styled, { useTheme } from 'styled-components';
import { GlassPane } from '../components/glass-pane';
import { ThemedText } from '../components/text';

const itemVariants: Variants = {
initial: {
opacity: 0,
scale: 0.9,
},
animate: {
opacity: 1,
scale: 1,
},
};

const Content = styled.div`
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 50px;
padding: 30px;
`;

const ReloadButton = styled(Button)`
position: absolute;
top: 30px;
right: 30px;
height: 45px;
width: 45px;
> svg {
font-size: 22px;
}
`;

type ErrorWidgetProps = {
errorText: string;
onReload: () => void;
loading: boolean;
};
export const ErrorWidget: FC<ErrorWidgetProps> = ({
errorText,
onReload,
loading,
}) => {
const theme = useTheme();

return (
<GlassPane variants={itemVariants} grow={0} minWidth={500}>
<Content>
{loading ? (
<SwapSpinner size={100} color={theme.colors.primary} loading={true} />
) : (
<>
<FontAwesomeIcon
icon={faExclamationTriangle}
color={theme.colors.text}
size='5x'
/>
<ThemedText>{errorText}</ThemedText>
{onReload && (
<ReloadButton
shape='circle'
icon={
<FontAwesomeIcon
icon={faRotateRight}
color={theme.colors.text}
/>
}
onClick={onReload}
/>
)}
</>
)}
</Content>
</GlassPane>
);
};
1 change: 0 additions & 1 deletion libs/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export type HardwareInfo = {
export type Config = {
// General
port: number;
enable_tilt: boolean;
widget_list: ('os' | 'cpu' | 'storage' | 'ram' | 'network')[];

// OS Widget
Expand Down

0 comments on commit 89d9fcc

Please sign in to comment.