feat: update application status tracking and rename pipeline metrics in dashboard UI

This commit is contained in:
2026-08-15 00:07:11 -07:00
parent 286278c1ec
commit 86a092ecd3
4 changed files with 22 additions and 15 deletions
+11 -5
View File
@@ -68,10 +68,16 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
return return
} }
qualifiedCount := 0 toReviewCount := 0
inPipelineCount := 0
for _, j := range jobs { for _, j := range jobs {
if j.Analysis != nil && j.Analysis.IsQualified { if j.App != nil && j.App.Status != "OPTED_OUT" {
qualifiedCount++ inPipelineCount++
} else if j.App == nil || j.App.Status != "OPTED_OUT" {
if j.Analysis != nil && (j.Analysis.IsQualified || j.Analysis.Status == "PENDING") {
toReviewCount++
}
} }
} }
@@ -81,9 +87,9 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
Applications: apps, Applications: apps,
ActiveTab: "triage", ActiveTab: "triage",
LLMProvider: s.cfg.LLMProvider, LLMProvider: s.cfg.LLMProvider,
QualifiedJobsCount: qualifiedCount, ToReviewCount: toReviewCount,
TotalIngestedCount: len(jobs), TotalIngestedCount: len(jobs),
ActiveApplications: len(apps), InPipelineCount: inPipelineCount,
} }
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
+1
View File
@@ -113,6 +113,7 @@ const applyTableHTML = `{{ define "applyTable" }}
<!-- Change Status --> <!-- Change Status -->
<td class="px-4 py-3 text-right"> <td class="px-4 py-3 text-right">
<select hx-patch="/applications/{{ .App.ID }}/status" <select hx-patch="/applications/{{ .App.ID }}/status"
name="status"
hx-target="#apply-container" hx-target="#apply-container"
hx-swap="innerHTML" hx-swap="innerHTML"
class="px-2 py-1 bg-slate-900 border border-slate-700 rounded-lg text-slate-200 text-[10px] focus:outline-none focus:border-indigo-500"> class="px-2 py-1 bg-slate-900 border border-slate-700 rounded-lg text-slate-200 text-[10px] focus:outline-none focus:border-indigo-500">
+8 -8
View File
@@ -68,17 +68,17 @@ const mainLayoutHTML = `{{ define "page" }}<!DOCTYPE html>
<div class="hidden md:flex items-center space-x-6 text-xs"> <div class="hidden md:flex items-center space-x-6 text-xs">
<div class="flex items-center space-x-1.5"> <div class="flex items-center space-x-1.5">
<span class="w-2 h-2 rounded-full bg-emerald-400"></span> <span class="w-2 h-2 rounded-full bg-emerald-400"></span>
<span class="text-slate-400">Qualified:</span> <span class="text-slate-400">To Review:</span>
<span class="font-bold text-emerald-400">{{ .QualifiedJobsCount }}</span> <span class="font-bold text-emerald-400">{{ .ToReviewCount }}</span>
</div> </div>
<div class="flex items-center space-x-1.5"> <div class="flex items-center space-x-1.5">
<span class="text-slate-400">Ingested:</span> <span class="text-slate-400">In Pipeline:</span>
<span class="font-bold text-violet-400">{{ .InPipelineCount }}</span>
</div>
<div class="flex items-center space-x-1.5">
<span class="text-slate-400">Total Ingested:</span>
<span class="font-bold text-white">{{ .TotalIngestedCount }}</span> <span class="font-bold text-white">{{ .TotalIngestedCount }}</span>
</div> </div>
<div class="flex items-center space-x-1.5">
<span class="text-slate-400">Applied:</span>
<span class="font-bold text-violet-400">{{ .ActiveApplications }}</span>
</div>
<div class="flex items-center space-x-1.5 px-2 py-1 rounded-md bg-slate-900/60 border border-slate-800"> <div class="flex items-center space-x-1.5 px-2 py-1 rounded-md bg-slate-900/60 border border-slate-800">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span> <span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
<span class="text-slate-400">LLM:</span> <span class="text-slate-400">LLM:</span>
@@ -302,7 +302,7 @@ const mainLayoutHTML = `{{ define "page" }}<!DOCTYPE html>
const textMatch = !text || rowText.includes(text); const textMatch = !text || rowText.includes(text);
let qualMatch; let qualMatch;
switch (qual) { switch (qual) {
case 'default': qualMatch = rowApp !== 'opted-out' && (rowQual === 'qualified' || rowQual === 'pending'); break; case 'default': qualMatch = rowApp !== 'opted-out' && rowApp !== 'pipeline' && (rowQual === 'qualified' || rowQual === 'pending'); break;
case 'not-qualified': qualMatch = rowApp !== 'opted-out' && rowQual === 'not-qualified'; break; case 'not-qualified': qualMatch = rowApp !== 'opted-out' && rowQual === 'not-qualified'; break;
case 'saved': qualMatch = rowApp === 'pipeline'; break; case 'saved': qualMatch = rowApp === 'pipeline'; break;
case 'all': qualMatch = rowApp !== 'opted-out'; break; case 'all': qualMatch = rowApp !== 'opted-out'; break;
+2 -2
View File
@@ -70,9 +70,9 @@ type PageData struct {
Applications []db.JobWithAnalysis Applications []db.JobWithAnalysis
ActiveTab string ActiveTab string
LLMProvider string LLMProvider string
QualifiedJobsCount int ToReviewCount int
TotalIngestedCount int TotalIngestedCount int
ActiveApplications int InPipelineCount int
} }
var rootTemplate *template.Template var rootTemplate *template.Template