Skip to content

Commit

Permalink
Add time since last update, and refresh every 5 seconds
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-z committed Jul 15, 2024
1 parent f686645 commit 4686b80
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/healthchecksio.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import useSWR from "swr";
import { groupBy, healthchecksioFetcher, removePrefix, removeSuffix } from "./utils";
import { groupBy, healthchecksioFetcher, removePrefix, removeSuffix, timeSinceShort } from "./utils";
import { STATUS_SYMBOLS } from "./constants";
import { StatusSummary } from "./summary";
import { OptionGroup } from "./option-group";
Expand Down Expand Up @@ -76,7 +76,7 @@ function shortenCheckName(groupKey: typeof GROUP_KEYS[number], groupName: string

export function HealthchecksioStatus({ showInternal, initialGroupKey = "" }: { showInternal?: boolean, initialGroupKey?: string }) {
const [groupKey, setGroupKey] = useState((GROUP_KEYS.includes(initialGroupKey as any) ? initialGroupKey : GROUP_KEYS[0]) as typeof GROUP_KEYS[number]);
const { data: dataRaw, error, isLoading } = useSWR('/api/v3/checks/', healthchecksioFetcher, { refreshInterval: 10000 });
const { data: dataRaw, error, isLoading } = useSWR('/api/v3/checks/', healthchecksioFetcher, { refreshInterval: 5000 });

const checks = (processHCData(dataRaw) || []).filter(check => check.tags_dict.public !== 'False' || showInternal);
const groupedChecks = groupBy(checks, c => c.tags_dict[groupKey]);
Expand All @@ -99,14 +99,15 @@ export function HealthchecksioStatus({ showInternal, initialGroupKey = "" }: { s
selectedClassName="bg-blue-500 text-white"
/>
</div>
<div className="grid px-8 2xl:grid-cols-5 xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 gap-4">
<div className="grid px-8 2xl:grid-cols-4 xl:grid-cols-3 lg:grid-cols-2 sm:grid-cols-2 gap-4">
{Object.entries(groupedChecks).sort().map(([group, checks]) => (
<div key={group} className="border p-4">
<h4 className="text-lg">{group}</h4>
<ul>
{checks.map(check => (
<li key={check.name} className="flex justify-between">
<span>{shortenCheckName(groupKey, group, check.name)}</span>
<span>{shortenCheckName(groupKey, group, check.name)} <span className="text-sm text-gray-500" aria-label="last update time"
title={`Last updated at ${check.last_ping}`}>{timeSinceShort(new Date(check.last_ping))} ago</span></span>
<CheckStatus status={check.status} />
</li>
))}
Expand Down
39 changes: 39 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,43 @@ export function removeSuffix(str: string, suffix: string) {

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

export function timeSince(date: Date): string {
let v: number = Math.floor((new Date().getTime() - date.getTime()) / 1000);

if (v < 60) {
// v is seconds
return v + ' second' + (v === 1 ? '' : 's');
}

v = Math.floor(v / 60); // v is now minutes
if (v < 60) {
return v + ' minute' + (v === 1 ? '' : 's');
}

v = Math.floor(v / 60); // v is now hours
if (v < 24) {
return v + ' hour' + (v === 1 ? '' : 's');
}

v = Math.floor(v / 24); // v is now days
return v + ' day' + (v === 1 ? '' : 's');
}

export function timeSinceShort(date: Date): string {
const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000);
const units: [number, string][] = [
[60, 's'],
[60, 'm'],
[24, 'h'],
[Number.MAX_SAFE_INTEGER, 'd']
];

let value = seconds;
for (const [unit, suffix] of units) {
if (value < unit) return `${value}${suffix}`;
value = Math.floor(value / unit);
}
return `${value}d`;
}

0 comments on commit 4686b80

Please sign in to comment.