feat: implement automatic SysPulse detection and Report View overhead toggle

This commit is contained in:
2026-02-22 22:20:04 +01:00
parent 214a24be9d
commit ab4b2af800
2 changed files with 64 additions and 22 deletions

View File

@@ -20,6 +20,7 @@ interface ProcessStats {
memory: number;
status: string;
user_id?: string;
is_syspulse: boolean;
}
interface SystemStats {
@@ -52,6 +53,7 @@ interface AggregatedProcess {
instance_count: number;
warnings: string[];
history: ProcessHistoryPoint[];
is_syspulse: boolean;
}
interface ProfilingReport {
@@ -77,7 +79,6 @@ function App() {
try {
const isRecording = stats?.is_recording ?? false;
const data = await invoke<SystemStats>('get_system_stats', {
excludeSelf: true,
minimal: isRecording || view === 'report'
});
setStats(data);
@@ -289,7 +290,10 @@ function App() {
{stats.processes.map((proc) => (
<div key={proc.pid} className="grid grid-cols-[1fr_100px_100px_120px_80px] gap-4 px-4 py-4 border-b border-surface1/20 group hover:bg-surface1/20 transition-all rounded-xl">
<div className="font-black text-text truncate text-sm flex items-center gap-3" title={proc.name}>
<div className="w-2 h-2 rounded-full bg-surface2 group-hover:bg-blue transition-colors" />
<div className={cn(
"w-2 h-2 rounded-full transition-colors",
proc.is_syspulse ? "bg-mauve" : "bg-surface2 group-hover:bg-blue"
)} />
{proc.name}
</div>
<div className="font-mono text-overlay2 text-xs text-right self-center">{proc.pid}</div>
@@ -321,6 +325,7 @@ function ReportView({ report, onBack }: { report: ProfilingReport, onBack: () =>
const [sortField, setSortField] = useState<SortField>('avg_cpu');
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
const [selectedProcess, setSelectedProcess] = useState<AggregatedProcess | null>(null);
const [hideProfiler, setHideProfiler] = useState(true);
const handleSort = (field: SortField) => {
if (sortField === field) {
@@ -332,20 +337,22 @@ function ReportView({ report, onBack }: { report: ProfilingReport, onBack: () =>
};
const sortedProcesses = useMemo(() => {
return [...report.aggregated_processes].sort((a, b) => {
const valA = a[sortField as keyof AggregatedProcess];
const valB = b[sortField as keyof AggregatedProcess];
if (typeof valA === 'string' && typeof valB === 'string') {
return sortOrder === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA);
}
const numA = (valA as number) ?? 0;
const numB = (valB as number) ?? 0;
return sortOrder === 'asc' ? numA - numB : numB - numA;
});
}, [report, sortField, sortOrder]);
return [...report.aggregated_processes]
.filter(p => !hideProfiler || !p.is_syspulse)
.sort((a, b) => {
const valA = a[sortField as keyof AggregatedProcess];
const valB = b[sortField as keyof AggregatedProcess];
if (typeof valA === 'string' && typeof valB === 'string') {
return sortOrder === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA);
}
const numA = (valA as number) ?? 0;
const numB = (valB as number) ?? 0;
return sortOrder === 'asc' ? numA - numB : numB - numA;
});
}, [report, sortField, sortOrder, hideProfiler]);
const saveReport = async () => {
try {
@@ -366,6 +373,17 @@ function ReportView({ report, onBack }: { report: ProfilingReport, onBack: () =>
<span className="font-black tracking-tighter uppercase italic text-xl">Profiling Report</span>
</div>
<div className="flex gap-4 px-4">
<button
onClick={() => setHideProfiler(!hideProfiler)}
className={cn(
"flex items-center gap-2 px-4 py-1.5 border rounded-xl text-xs font-black transition-all uppercase tracking-widest",
hideProfiler
? "bg-blue/10 border-blue/30 text-blue hover:bg-blue/20"
: "bg-surface1/50 border-surface2 text-subtext0 hover:text-text"
)}
>
<Shield size={14} /> {hideProfiler ? "SHOW PROFILER" : "HIDE PROFILER"}
</button>
<button
onClick={saveReport}
className="flex items-center gap-2 px-4 py-1.5 bg-surface1/50 hover:bg-surface1 border border-surface2 rounded-xl text-xs font-black transition-all text-text uppercase tracking-widest"