generated from mantinedev/next-pages-template
-
-
Notifications
You must be signed in to change notification settings - Fork 284
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🔀 Merge pull request #277 from MauriceNino/feature/276
Add dash. Integration thanks to @MauriceNino !
- Loading branch information
Showing
7 changed files
with
268 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
import { createStyles, useMantineColorScheme, useMantineTheme } from '@mantine/core'; | ||
import { IconCalendar as CalendarIcon } from '@tabler/icons'; | ||
import axios from 'axios'; | ||
import { useEffect, useState } from 'react'; | ||
import { useConfig } from '../../../tools/state'; | ||
import { serviceItem } from '../../../tools/types'; | ||
import { IModule } from '../modules'; | ||
|
||
const asModule = <T extends IModule>(t: T) => t; | ||
export const DashdotModule = asModule({ | ||
title: 'Dash.', | ||
description: 'A module for displaying the graphs of your running Dash. instance.', | ||
icon: CalendarIcon, | ||
component: DashdotComponent, | ||
options: { | ||
cpuMultiView: { | ||
name: 'CPU Multi-Core View', | ||
value: false, | ||
}, | ||
storageMultiView: { | ||
name: 'Storage Multi-Drive View', | ||
value: false, | ||
}, | ||
useCompactView: { | ||
name: 'Use Compact View', | ||
value: false, | ||
}, | ||
graphs: { | ||
name: 'Graphs', | ||
value: ['CPU', 'RAM', 'Storage', 'Network'], | ||
options: ['CPU', 'RAM', 'Storage', 'Network', 'GPU'], | ||
}, | ||
}, | ||
}); | ||
|
||
const useStyles = createStyles((theme, _params) => ({ | ||
heading: { | ||
marginTop: 0, | ||
marginBottom: 10, | ||
}, | ||
table: { | ||
display: 'table', | ||
}, | ||
tableRow: { | ||
display: 'table-row', | ||
}, | ||
tableLabel: { | ||
display: 'table-cell', | ||
paddingRight: 10, | ||
}, | ||
tableValue: { | ||
display: 'table-cell', | ||
whiteSpace: 'pre-wrap', | ||
paddingBottom: 5, | ||
}, | ||
graphsContainer: { | ||
display: 'flex', | ||
flexDirection: 'row', | ||
flexWrap: 'wrap', | ||
rowGap: 10, | ||
columnGap: 10, | ||
}, | ||
iframe: { | ||
flex: '1 0 auto', | ||
maxWidth: '100%', | ||
height: '140px', | ||
borderRadius: theme.radius.lg, | ||
}, | ||
})); | ||
|
||
const bpsPrettyPrint = (bits?: number) => | ||
!bits | ||
? '-' | ||
: bits > 1000 * 1000 * 1000 | ||
? `${(bits / 1000 / 1000 / 1000).toFixed(1)} Gb/s` | ||
: bits > 1000 * 1000 | ||
? `${(bits / 1000 / 1000).toFixed(1)} Mb/s` | ||
: bits > 1000 | ||
? `${(bits / 1000).toFixed(1)} Kb/s` | ||
: `${bits.toFixed(1)} b/s`; | ||
|
||
const bytePrettyPrint = (byte: number): string => | ||
byte > 1024 * 1024 * 1024 | ||
? `${(byte / 1024 / 1024 / 1024).toFixed(1)} GiB` | ||
: byte > 1024 * 1024 | ||
? `${(byte / 1024 / 1024).toFixed(1)} MiB` | ||
: byte > 1024 | ||
? `${(byte / 1024).toFixed(1)} KiB` | ||
: `${byte.toFixed(1)} B`; | ||
|
||
const useJson = (service: serviceItem | undefined, url: string) => { | ||
const [data, setData] = useState<any | undefined>(); | ||
|
||
const doRequest = async () => { | ||
try { | ||
const resp = await axios.get(url, { baseURL: service?.url }); | ||
|
||
setData(resp.data); | ||
// eslint-disable-next-line no-empty | ||
} catch (e) {} | ||
}; | ||
|
||
useEffect(() => { | ||
if (service?.url) { | ||
doRequest(); | ||
} | ||
}, [service?.url]); | ||
|
||
return data; | ||
}; | ||
|
||
export function DashdotComponent() { | ||
const { config } = useConfig(); | ||
const theme = useMantineTheme(); | ||
const { classes } = useStyles(); | ||
const { colorScheme } = useMantineColorScheme(); | ||
|
||
const dashConfig = config.modules?.[DashdotModule.title] | ||
.options as typeof DashdotModule['options']; | ||
const isCompact = dashConfig?.useCompactView?.value ?? false; | ||
const dashdotService = config.services.filter((service) => service.type === 'Dash.')[0]; | ||
|
||
const enabledGraphs = dashConfig?.graphs?.value ?? ['CPU', 'RAM', 'Storage', 'Network']; | ||
const cpuEnabled = enabledGraphs.includes('CPU'); | ||
const storageEnabled = enabledGraphs.includes('Storage'); | ||
const ramEnabled = enabledGraphs.includes('RAM'); | ||
const networkEnabled = enabledGraphs.includes('Network'); | ||
const gpuEnabled = enabledGraphs.includes('GPU'); | ||
|
||
const info = useJson(dashdotService, '/info'); | ||
const storageLoad = useJson(dashdotService, '/load/storage'); | ||
|
||
const totalUsed = | ||
(storageLoad?.layout as any[])?.reduce((acc, curr) => (curr.load ?? 0) + acc, 0) ?? 0; | ||
const totalSize = | ||
(info?.storage?.layout as any[])?.reduce((acc, curr) => (curr.size ?? 0) + acc, 0) ?? 0; | ||
|
||
const graphs = [ | ||
{ | ||
name: 'CPU', | ||
enabled: cpuEnabled, | ||
params: { | ||
multiView: dashConfig?.cpuMultiView?.value ?? false, | ||
}, | ||
}, | ||
{ | ||
name: 'Storage', | ||
enabled: storageEnabled && !isCompact, | ||
params: { | ||
multiView: dashConfig?.storageMultiView?.value ?? false, | ||
}, | ||
}, | ||
{ | ||
name: 'RAM', | ||
enabled: ramEnabled, | ||
}, | ||
{ | ||
name: 'Network', | ||
enabled: networkEnabled, | ||
spanTwo: true, | ||
}, | ||
{ | ||
name: 'GPU', | ||
enabled: gpuEnabled, | ||
spanTwo: true, | ||
}, | ||
].filter((g) => g.enabled); | ||
|
||
return ( | ||
<div> | ||
<h2 className={classes.heading}>Dash.</h2> | ||
|
||
{!dashdotService ? ( | ||
<p>No dash. service found. Please add one to your Homarr dashboard.</p> | ||
) : !info ? ( | ||
<p>Cannot acquire information from dash. - are you running the latest version?</p> | ||
) : ( | ||
<div className={classes.graphsContainer}> | ||
<div className={classes.table}> | ||
{storageEnabled && isCompact && ( | ||
<div className={classes.tableRow}> | ||
<p className={classes.tableLabel}>Storage:</p> | ||
<p className={classes.tableValue}> | ||
{(totalUsed / (totalSize || 1)).toFixed(1)}%{'\n'} | ||
{bytePrettyPrint(totalUsed)} / {bytePrettyPrint(totalSize)} | ||
</p> | ||
</div> | ||
)} | ||
{networkEnabled && ( | ||
<div className={classes.tableRow}> | ||
<p className={classes.tableLabel}>Network:</p> | ||
<p className={classes.tableValue}> | ||
{bpsPrettyPrint(info?.network?.speedUp)} Up{'\n'} | ||
{bpsPrettyPrint(info?.network?.speedDown)} Down | ||
</p> | ||
</div> | ||
)} | ||
</div> | ||
|
||
{graphs.map((graph) => ( | ||
<iframe | ||
className={classes.iframe} | ||
style={ | ||
isCompact | ||
? { | ||
width: graph.spanTwo ? '100%' : 'calc(50% - 5px)', | ||
} | ||
: undefined | ||
} | ||
key={graph.name} | ||
title={graph.name} | ||
src={`${ | ||
dashdotService.url | ||
}?singleGraphMode=true&graph=${graph.name.toLowerCase()}&theme=${colorScheme}&surface=${(colorScheme === | ||
'dark' | ||
? theme.colors.dark[7] | ||
: theme.colors.gray[0] | ||
).substring(1)}${isCompact ? '&gap=10' : '&gap=5'}&innerRadius=${theme.radius.lg}${ | ||
graph.params | ||
? `&${Object.entries(graph.params) | ||
.map(([key, value]) => `${key}=${value.toString()}`) | ||
.join('&')}` | ||
: '' | ||
}`} | ||
frameBorder="0" | ||
allowTransparency | ||
/> | ||
))} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { DashdotModule } from './DashdotModule'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
export * from './date'; | ||
export * from './calendar'; | ||
export * from './search'; | ||
export * from './dash.'; | ||
export * from './date'; | ||
export * from './downloads'; | ||
export * from './ping'; | ||
export * from './search'; | ||
export * from './weather'; | ||
export * from './downloads'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters