mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-30 12:42:22 +00:00
Show status in messages
This commit is contained in:
@@ -36,8 +36,8 @@ function getEventMeta(eventType: AlertEventType): {
|
||||
heading: string;
|
||||
previewText: string;
|
||||
summary: string;
|
||||
statusLabel: string;
|
||||
statusColor: string;
|
||||
statusLabel: string | null;
|
||||
statusColor: string | null;
|
||||
} {
|
||||
switch (eventType) {
|
||||
case "site_online":
|
||||
@@ -63,8 +63,8 @@ function getEventMeta(eventType: AlertEventType): {
|
||||
heading: "Site Status Changed",
|
||||
previewText: "A site in your organization has changed status.",
|
||||
summary: "A site in your organization has changed status.",
|
||||
statusLabel: "Status Changed",
|
||||
statusColor: "#f59e0b"
|
||||
statusLabel: null,
|
||||
statusColor: null
|
||||
};
|
||||
case "health_check_healthy":
|
||||
return {
|
||||
@@ -93,8 +93,8 @@ function getEventMeta(eventType: AlertEventType): {
|
||||
"A health check in your organization has changed status.",
|
||||
summary:
|
||||
"A health check in your organization has changed status.",
|
||||
statusLabel: "Status Changed",
|
||||
statusColor: "#f59e0b"
|
||||
statusLabel: null,
|
||||
statusColor: null
|
||||
};
|
||||
case "resource_healthy":
|
||||
return {
|
||||
@@ -120,8 +120,8 @@ function getEventMeta(eventType: AlertEventType): {
|
||||
previewText:
|
||||
"A resource in your organization has changed status.",
|
||||
summary: "A resource in your organization has changed status.",
|
||||
statusLabel: "Status Changed",
|
||||
statusColor: "#f59e0b"
|
||||
statusLabel: null,
|
||||
statusColor: null
|
||||
};
|
||||
default:
|
||||
return {
|
||||
@@ -135,11 +135,26 @@ function getEventMeta(eventType: AlertEventType): {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveToggleStatus(status: unknown): { label: string; color: string } {
|
||||
switch (String(status).toLowerCase()) {
|
||||
case "online":
|
||||
return { label: "Online", color: "#16a34a" };
|
||||
case "offline":
|
||||
return { label: "Offline", color: "#dc2626" };
|
||||
case "healthy":
|
||||
return { label: "Healthy", color: "#16a34a" };
|
||||
case "unhealthy":
|
||||
return { label: "Unhealthy", color: "#dc2626" };
|
||||
default:
|
||||
return { label: String(status ?? "Unknown"), color: "#f59e0b" };
|
||||
}
|
||||
}
|
||||
|
||||
function formatDataItems(
|
||||
data: Record<string, unknown>
|
||||
): { label: string; value: React.ReactNode }[] {
|
||||
return Object.entries(data)
|
||||
.filter(([key]) => key !== "orgId")
|
||||
.filter(([key]) => key !== "orgId" && key !== "status")
|
||||
.map(([key, value]) => ({
|
||||
label: key
|
||||
.replace(/([A-Z])/g, " $1")
|
||||
@@ -154,16 +169,36 @@ export const AlertNotification = (props: AlertNotificationProps) => {
|
||||
const meta = getEventMeta(eventType);
|
||||
const dataItems = formatDataItems(data);
|
||||
|
||||
const isToggle =
|
||||
eventType === "site_toggle" ||
|
||||
eventType === "health_check_toggle" ||
|
||||
eventType === "resource_toggle";
|
||||
|
||||
const resolvedStatus = isToggle
|
||||
? resolveToggleStatus(data.status)
|
||||
: meta.statusLabel != null
|
||||
? { label: meta.statusLabel, color: meta.statusColor! }
|
||||
: null;
|
||||
|
||||
const allItems: { label: string; value: React.ReactNode }[] = [
|
||||
{ label: "Organization", value: orgId },
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<span style={{ color: meta.statusColor, fontWeight: 600 }}>
|
||||
{meta.statusLabel}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
...(resolvedStatus != null
|
||||
? [
|
||||
{
|
||||
label: "Status",
|
||||
value: (
|
||||
<span
|
||||
style={{
|
||||
color: resolvedStatus.color,
|
||||
fontWeight: 600
|
||||
}}
|
||||
>
|
||||
{resolvedStatus.label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{ label: "Time", value: new Date().toUTCString() },
|
||||
...dataItems
|
||||
];
|
||||
|
||||
@@ -76,6 +76,7 @@ export async function fireHealthCheckHealthyAlert(
|
||||
healthCheckId,
|
||||
data: {
|
||||
healthCheckId,
|
||||
status: "healthy",
|
||||
...(healthCheckName != null ? { healthCheckName } : {}),
|
||||
...extra
|
||||
}
|
||||
@@ -133,6 +134,7 @@ export async function fireHealthCheckUnhealthyAlert(
|
||||
healthCheckId,
|
||||
data: {
|
||||
healthCheckId,
|
||||
status: "unhealthy",
|
||||
...(healthCheckName != null ? { healthCheckName } : {}),
|
||||
...extra
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ export async function fireResourceHealthyAlert(
|
||||
resourceId,
|
||||
data: {
|
||||
resourceId,
|
||||
status: "healthy",
|
||||
...(resourceName != null ? { resourceName } : {}),
|
||||
...extra
|
||||
}
|
||||
@@ -115,6 +116,7 @@ export async function fireResourceUnhealthyAlert(
|
||||
resourceId,
|
||||
data: {
|
||||
resourceId,
|
||||
status: "unhealthy",
|
||||
...(resourceName != null ? { resourceName } : {}),
|
||||
...extra
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ export async function fireSiteOnlineAlert(
|
||||
siteId,
|
||||
data: {
|
||||
siteId,
|
||||
status: "online",
|
||||
...(siteName != null ? { siteName } : {}),
|
||||
...extra
|
||||
}
|
||||
@@ -143,6 +144,7 @@ export async function fireSiteOfflineAlert(
|
||||
siteId,
|
||||
data: {
|
||||
siteId,
|
||||
status: "offline",
|
||||
...(siteName != null ? { siteName } : {}),
|
||||
...extra
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ export async function sendAlertWebhook(
|
||||
const payload = {
|
||||
event: context.eventType,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: deriveStatus(context.eventType, context.data),
|
||||
data: {
|
||||
orgId: context.orgId,
|
||||
...context.data
|
||||
@@ -117,6 +118,38 @@ export async function sendAlertWebhook(
|
||||
throw lastError ?? new Error(`Alert webhook: all ${MAX_RETRIES} attempts failed for "${url}"`);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Status derivation
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function deriveStatus(
|
||||
eventType: AlertContext["eventType"],
|
||||
data: Record<string, unknown>
|
||||
): string {
|
||||
switch (eventType) {
|
||||
case "site_online":
|
||||
return "online";
|
||||
case "site_offline":
|
||||
return "offline";
|
||||
case "site_toggle":
|
||||
return String(data.status ?? "unknown");
|
||||
case "health_check_healthy":
|
||||
case "resource_healthy":
|
||||
return "healthy";
|
||||
case "health_check_unhealthy":
|
||||
case "resource_unhealthy":
|
||||
return "unhealthy";
|
||||
case "health_check_toggle":
|
||||
case "resource_toggle":
|
||||
return String(data.status ?? "unknown");
|
||||
default: {
|
||||
const _exhaustive: never = eventType;
|
||||
void _exhaustive;
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Header construction (mirrors HttpLogDestination.buildHeaders)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user