mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
refactor: simplify arrow function syntax and improve readability in dashboard components
This commit is contained in:
@@ -205,8 +205,9 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
}
|
||||
|
||||
serviceExceptionCounts.sort(
|
||||
(a: ServiceExceptionSummary, b: ServiceExceptionSummary) =>
|
||||
b.unresolvedCount - a.unresolvedCount,
|
||||
(a: ServiceExceptionSummary, b: ServiceExceptionSummary) => {
|
||||
return b.unresolvedCount - a.unresolvedCount;
|
||||
},
|
||||
);
|
||||
|
||||
setServiceSummaries(serviceExceptionCounts);
|
||||
@@ -506,9 +507,9 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
const barWidth: number =
|
||||
((exception.occuranceCount || 0) / maxOccurrences) * 100;
|
||||
|
||||
const isNewToday: boolean = !!(
|
||||
const isNewToday: boolean = Boolean(
|
||||
exception.firstSeenAt &&
|
||||
new Date(exception.firstSeenAt) > oneDayAgo
|
||||
new Date(exception.firstSeenAt) > oneDayAgo,
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -524,10 +525,7 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
] as Route,
|
||||
)
|
||||
.toString()
|
||||
.replace(
|
||||
/\/?$/,
|
||||
`/${exception.fingerprint}`,
|
||||
),
|
||||
.replace(/\/?$/, `/${exception.fingerprint}`),
|
||||
)
|
||||
: RouteUtil.populateRouteParams(
|
||||
RouteMap[
|
||||
@@ -582,9 +580,7 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
</div>
|
||||
<div className="text-right flex-shrink-0">
|
||||
<p className="text-sm font-bold text-gray-900">
|
||||
{(
|
||||
exception.occuranceCount || 0
|
||||
).toLocaleString()}
|
||||
{(exception.occuranceCount || 0).toLocaleString()}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">hits</p>
|
||||
</div>
|
||||
@@ -619,48 +615,46 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
</div>
|
||||
<div className="rounded-xl border border-gray-200 bg-white overflow-hidden">
|
||||
<div className="divide-y divide-gray-50">
|
||||
{serviceSummaries.map(
|
||||
(summary: ServiceExceptionSummary) => {
|
||||
const barWidth: number =
|
||||
(summary.unresolvedCount / maxServiceBugs) * 100;
|
||||
{serviceSummaries.map((summary: ServiceExceptionSummary) => {
|
||||
const barWidth: number =
|
||||
(summary.unresolvedCount / maxServiceBugs) * 100;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={summary.service.id?.toString()}
|
||||
className="px-4 py-3"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<TelemetryServiceElement
|
||||
telemetryService={summary.service}
|
||||
/>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="text-right">
|
||||
<span className="text-sm font-bold text-red-600">
|
||||
{summary.unresolvedCount}
|
||||
</span>
|
||||
<span className="text-xs text-gray-400 ml-1">
|
||||
bugs
|
||||
</span>
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
key={summary.service.id?.toString()}
|
||||
className="px-4 py-3"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<TelemetryServiceElement
|
||||
telemetryService={summary.service}
|
||||
/>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="text-right">
|
||||
<span className="text-sm font-bold text-red-600">
|
||||
{summary.unresolvedCount}
|
||||
</span>
|
||||
<span className="text-xs text-gray-400 ml-1">
|
||||
bugs
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 h-1.5 bg-gray-100 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full bg-red-400"
|
||||
style={{
|
||||
width: `${Math.max(barWidth, 3)}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs text-gray-400 flex-shrink-0">
|
||||
{summary.totalOccurrences.toLocaleString()} hits
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
)}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 h-1.5 bg-gray-100 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full bg-red-400"
|
||||
style={{
|
||||
width: `${Math.max(barWidth, 3)}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs text-gray-400 flex-shrink-0">
|
||||
{summary.totalOccurrences.toLocaleString()} hits
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -679,58 +673,54 @@ const ExceptionsDashboard: FunctionComponent = (): ReactElement => {
|
||||
<div className="divide-y divide-gray-50">
|
||||
{recentExceptions
|
||||
.slice(0, 5)
|
||||
.map(
|
||||
(exception: TelemetryException, index: number) => {
|
||||
return (
|
||||
<AppLink
|
||||
key={
|
||||
exception.id?.toString() || index.toString()
|
||||
}
|
||||
className="block px-4 py-3 hover:bg-gray-50 transition-colors"
|
||||
to={
|
||||
exception.fingerprint
|
||||
? new Route(
|
||||
RouteUtil.populateRouteParams(
|
||||
RouteMap[
|
||||
PageMap.EXCEPTIONS_VIEW_ROOT
|
||||
] as Route,
|
||||
)
|
||||
.toString()
|
||||
.replace(
|
||||
/\/?$/,
|
||||
`/${exception.fingerprint}`,
|
||||
),
|
||||
)
|
||||
: RouteUtil.populateRouteParams(
|
||||
.map((exception: TelemetryException, index: number) => {
|
||||
return (
|
||||
<AppLink
|
||||
key={exception.id?.toString() || index.toString()}
|
||||
className="block px-4 py-3 hover:bg-gray-50 transition-colors"
|
||||
to={
|
||||
exception.fingerprint
|
||||
? new Route(
|
||||
RouteUtil.populateRouteParams(
|
||||
RouteMap[
|
||||
PageMap.EXCEPTIONS_UNRESOLVED
|
||||
PageMap.EXCEPTIONS_VIEW_ROOT
|
||||
] as Route,
|
||||
)
|
||||
}
|
||||
>
|
||||
<p className="text-sm text-gray-900 truncate font-medium">
|
||||
{exception.message ||
|
||||
exception.exceptionType ||
|
||||
"Unknown"}
|
||||
</p>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
{exception.service && (
|
||||
<span className="text-xs text-gray-500">
|
||||
{exception.service.name?.toString()}
|
||||
</span>
|
||||
)}
|
||||
{exception.lastSeenAt && (
|
||||
<span className="text-xs text-gray-400">
|
||||
{OneUptimeDate.fromNow(
|
||||
new Date(exception.lastSeenAt),
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</AppLink>
|
||||
);
|
||||
},
|
||||
)}
|
||||
.toString()
|
||||
.replace(
|
||||
/\/?$/,
|
||||
`/${exception.fingerprint}`,
|
||||
),
|
||||
)
|
||||
: RouteUtil.populateRouteParams(
|
||||
RouteMap[
|
||||
PageMap.EXCEPTIONS_UNRESOLVED
|
||||
] as Route,
|
||||
)
|
||||
}
|
||||
>
|
||||
<p className="text-sm text-gray-900 truncate font-medium">
|
||||
{exception.message ||
|
||||
exception.exceptionType ||
|
||||
"Unknown"}
|
||||
</p>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
{exception.service && (
|
||||
<span className="text-xs text-gray-500">
|
||||
{exception.service.name?.toString()}
|
||||
</span>
|
||||
)}
|
||||
{exception.lastSeenAt && (
|
||||
<span className="text-xs text-gray-400">
|
||||
{OneUptimeDate.fromNow(
|
||||
new Date(exception.lastSeenAt),
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</AppLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -50,9 +50,7 @@ const MetricsDashboard: FunctionComponent = (): ReactElement => {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
const categorizeMetric: (name: string) => string = (
|
||||
name: string,
|
||||
): string => {
|
||||
const categorizeMetric: (name: string) => string = (name: string): string => {
|
||||
const lower: string = name.toLowerCase();
|
||||
if (
|
||||
lower.includes("cpu") ||
|
||||
@@ -370,9 +368,7 @@ const MetricsDashboard: FunctionComponent = (): ReactElement => {
|
||||
|
||||
<div className="rounded-xl border border-gray-200 bg-white p-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-medium text-gray-500">
|
||||
Avg per Service
|
||||
</p>
|
||||
<p className="text-sm font-medium text-gray-500">Avg per Service</p>
|
||||
<div className="h-9 w-9 rounded-lg bg-blue-50 flex items-center justify-center">
|
||||
<svg
|
||||
className="h-4.5 w-4.5 text-blue-600"
|
||||
@@ -399,9 +395,7 @@ const MetricsDashboard: FunctionComponent = (): ReactElement => {
|
||||
|
||||
<div className="rounded-xl border border-gray-200 bg-white p-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm font-medium text-gray-500">
|
||||
No Metrics
|
||||
</p>
|
||||
<p className="text-sm font-medium text-gray-500">No Metrics</p>
|
||||
<div
|
||||
className={`h-9 w-9 rounded-lg flex items-center justify-center ${servicesWithNoMetrics > 0 ? "bg-amber-50" : "bg-gray-50"}`}
|
||||
>
|
||||
@@ -454,9 +448,7 @@ const MetricsDashboard: FunctionComponent = (): ReactElement => {
|
||||
{cat.count}
|
||||
</span>
|
||||
<span className={`text-sm ${cat.color}`}>{cat.name}</span>
|
||||
<span
|
||||
className={`text-xs ${cat.color} opacity-60`}
|
||||
>
|
||||
<span className={`text-xs ${cat.color} opacity-60`}>
|
||||
{pct}%
|
||||
</span>
|
||||
</div>
|
||||
@@ -467,9 +459,7 @@ const MetricsDashboard: FunctionComponent = (): ReactElement => {
|
||||
<div className="flex h-2 rounded-full overflow-hidden mt-3">
|
||||
{metricCategories.map((cat: MetricCategory) => {
|
||||
const pct: number =
|
||||
totalMetricCount > 0
|
||||
? (cat.count / totalMetricCount) * 100
|
||||
: 0;
|
||||
totalMetricCount > 0 ? (cat.count / totalMetricCount) * 100 : 0;
|
||||
const barColorMap: Record<string, string> = {
|
||||
System: "bg-blue-400",
|
||||
Request: "bg-purple-400",
|
||||
|
||||
@@ -165,10 +165,7 @@ const ProfilesDashboard: FunctionComponent = (): ReactElement => {
|
||||
}
|
||||
|
||||
// Track global type stats
|
||||
typeCountMap.set(
|
||||
profileType,
|
||||
(typeCountMap.get(profileType) || 0) + 1,
|
||||
);
|
||||
typeCountMap.set(profileType, (typeCountMap.get(profileType) || 0) + 1);
|
||||
}
|
||||
|
||||
setTotalSampleCount(totalSamples);
|
||||
@@ -185,20 +182,23 @@ const ProfilesDashboard: FunctionComponent = (): ReactElement => {
|
||||
badgeColor: ProfileUtil.getProfileTypeBadgeColor(type),
|
||||
};
|
||||
})
|
||||
.sort(
|
||||
(a: ProfileTypeStats, b: ProfileTypeStats) => b.count - a.count,
|
||||
);
|
||||
.sort((a: ProfileTypeStats, b: ProfileTypeStats) => {
|
||||
return b.count - a.count;
|
||||
});
|
||||
|
||||
setProfileTypeStats(typeStats);
|
||||
|
||||
// Only show services that have profiles
|
||||
const summariesWithData: Array<ServiceProfileSummary> = Array.from(
|
||||
summaryMap.values(),
|
||||
).filter((s: ServiceProfileSummary) => s.profileCount > 0);
|
||||
).filter((s: ServiceProfileSummary) => {
|
||||
return s.profileCount > 0;
|
||||
});
|
||||
|
||||
summariesWithData.sort(
|
||||
(a: ServiceProfileSummary, b: ServiceProfileSummary) =>
|
||||
b.profileCount - a.profileCount,
|
||||
(a: ServiceProfileSummary, b: ServiceProfileSummary) => {
|
||||
return b.profileCount - a.profileCount;
|
||||
},
|
||||
);
|
||||
|
||||
setServiceSummaries(summariesWithData);
|
||||
@@ -289,7 +289,9 @@ const ProfilesDashboard: FunctionComponent = (): ReactElement => {
|
||||
}
|
||||
|
||||
const maxProfiles: number = Math.max(
|
||||
...serviceSummaries.map((s: ServiceProfileSummary) => s.profileCount),
|
||||
...serviceSummaries.map((s: ServiceProfileSummary) => {
|
||||
return s.profileCount;
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -64,9 +64,9 @@ const getPercentile: (arr: Array<number>, p: number) => number = (
|
||||
if (arr.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
const sorted: Array<number> = [...arr].sort(
|
||||
(a: number, b: number) => a - b,
|
||||
);
|
||||
const sorted: Array<number> = [...arr].sort((a: number, b: number) => {
|
||||
return a - b;
|
||||
});
|
||||
const idx: number = Math.ceil((p / 100) * sorted.length) - 1;
|
||||
return sorted[Math.max(0, idx)] || 0;
|
||||
};
|
||||
@@ -197,8 +197,7 @@ const TracesDashboard: FunctionComponent = (): ReactElement => {
|
||||
}
|
||||
|
||||
if (span.statusCode === SpanStatus.Error) {
|
||||
const errorSet: Set<string> =
|
||||
serviceErrorTraceIds.get(serviceId)!;
|
||||
const errorSet: Set<string> = serviceErrorTraceIds.get(serviceId)!;
|
||||
if (!errorSet.has(traceId)) {
|
||||
errorSet.add(traceId);
|
||||
summary.errorTraces += 1;
|
||||
@@ -254,7 +253,9 @@ const TracesDashboard: FunctionComponent = (): ReactElement => {
|
||||
const summariesWithData: Array<ServiceTraceSummary> = Array.from(
|
||||
summaryMap.values(),
|
||||
)
|
||||
.filter((s: ServiceTraceSummary) => s.totalTraces > 0)
|
||||
.filter((s: ServiceTraceSummary) => {
|
||||
return s.totalTraces > 0;
|
||||
})
|
||||
.map((s: ServiceTraceSummary) => {
|
||||
return {
|
||||
...s,
|
||||
@@ -290,9 +291,9 @@ const TracesDashboard: FunctionComponent = (): ReactElement => {
|
||||
setRecentErrorTraces(errorTraces.slice(0, 8));
|
||||
|
||||
const slowTraces: Array<RecentTrace> = [...allTraces]
|
||||
.sort(
|
||||
(a: RecentTrace, b: RecentTrace) => b.durationNano - a.durationNano,
|
||||
)
|
||||
.sort((a: RecentTrace, b: RecentTrace) => {
|
||||
return b.durationNano - a.durationNano;
|
||||
})
|
||||
.slice(0, 8);
|
||||
setRecentSlowTraces(slowTraces);
|
||||
} catch (err) {
|
||||
@@ -309,9 +310,9 @@ const TracesDashboard: FunctionComponent = (): ReactElement => {
|
||||
const getServiceName: (serviceId: string) => string = (
|
||||
serviceId: string,
|
||||
): string => {
|
||||
const service: Service | undefined = services.find(
|
||||
(s: Service) => s.id?.toString() === serviceId,
|
||||
);
|
||||
const service: Service | undefined = services.find((s: Service) => {
|
||||
return s.id?.toString() === serviceId;
|
||||
});
|
||||
return service?.name?.toString() || "Unknown";
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user