diff --git a/_frontend/src/components/Widget.jsx b/_frontend/src/components/Widgets.jsx
similarity index 87%
rename from _frontend/src/components/Widget.jsx
rename to _frontend/src/components/Widgets.jsx
index 1df9f8f..5b0a5f9 100644
--- a/_frontend/src/components/Widget.jsx
+++ b/_frontend/src/components/Widgets.jsx
@@ -1,3 +1,4 @@
+import { APIButton } from './widgets/ApiStatus.jsx'
import { DiskUsage } from './widgets/DiskUsage.jsx'
import { MessageWidget } from './widgets/MessageWidget.jsx'
import { PieChartWidget } from './widgets/PieChartWidget.jsx'
@@ -8,6 +9,7 @@ const WidgetTypes = {
message: MessageWidget,
'script-status': ScriptStatus,
'disk-usage': DiskUsage,
+ 'api-button': APIButton,
}
export const Widget = ({ type, value }) => {
diff --git a/_frontend/src/components/charts/PieChart.jsx b/_frontend/src/components/charts/PieChart.jsx
index 5b2d4d9..c4f9073 100644
--- a/_frontend/src/components/charts/PieChart.jsx
+++ b/_frontend/src/components/charts/PieChart.jsx
@@ -1,7 +1,11 @@
-import { useEffect, useRef } from 'preact/hooks'
+import { useEffect, useRef, useState } from 'preact/hooks'
import { hashCode } from '../../util.jsx'
+let pieChartPiecesSeed = 934635493
+
export const PieChart = ({ parts, labels, total }) => {
+ const [seed] = useState(() => pieChartPiecesSeed++)
+
parts = parts || [1]
labels = labels || parts
@@ -47,8 +51,8 @@ export const PieChart = ({ parts, labels, total }) => {
g.stroke()
let acc = 0
- for (const [angle, label] of anglesAndLabel) {
- g.fillStyle = `hsl(${((hashCode(label) % 0xff) * 360) / 0xff}, 80%, 65%)`
+ anglesAndLabel.forEach(([angle, label], i) => {
+ g.fillStyle = `hsl(${((hashCode(`${i} ${seed}`) % 0xff) * 360) / 0xff}, 80%, 65%)`
g.beginPath()
g.moveTo(0, 0)
g.arc(0, 0, width * 0.5 * 0.8, acc - 0.5 * Math.PI, acc + angle - 0.5 * Math.PI)
@@ -69,9 +73,9 @@ export const PieChart = ({ parts, labels, total }) => {
)
acc += angle
- }
+ })
}
- }, [canvasRef, parts])
+ }, [canvasRef, parts, labels])
return
}
diff --git a/_frontend/src/components/widgets/ApiStatus.jsx b/_frontend/src/components/widgets/ApiStatus.jsx
new file mode 100644
index 0000000..d7b502a
--- /dev/null
+++ b/_frontend/src/components/widgets/ApiStatus.jsx
@@ -0,0 +1,32 @@
+import { ToastMessage, useToasts } from '../Toasts.jsx'
+
+export const APIButton = ({ title, url }) => {
+ const [showToast] = useToasts()
+
+ const fetchAPI = async () => {
+ try {
+ const res = await fetch(url)
+ const status = await res.text()
+
+ if (!res.ok) {
+ showToast(