06/22 Fix Low impact items
This commit is contained in:
@@ -65,6 +65,44 @@ struct ExecuteInspectionView: View {
|
||||
|
||||
private var formSchema: [[String: Any]] { template?.formSchema ?? [] }
|
||||
|
||||
/// Live score computed directly from `formValues` (in-memory SwiftUI state)
|
||||
/// so it updates as the inspector fills in each field — without waiting for
|
||||
/// `saveDraft()` to flush to SwiftData and `computeScore()` to run.
|
||||
/// Returns nil when the schema has no scoreable fields.
|
||||
private var liveScore: Double? {
|
||||
let scoreable = formSchema.filter {
|
||||
["rating", "checkbox", "radio", "pass_fail"].contains($0["type"] as? String ?? "")
|
||||
}
|
||||
guard !scoreable.isEmpty else { return nil }
|
||||
|
||||
var total = 0; var earned = 0
|
||||
for field in scoreable {
|
||||
let fid: String
|
||||
if let s = field["id"] as? String { fid = s }
|
||||
else if let n = field["id"] as? Int { fid = String(n) }
|
||||
else { continue }
|
||||
guard let ftype = field["type"] as? String else { continue }
|
||||
let val = formValues[fid] ?? ""
|
||||
|
||||
switch ftype {
|
||||
case "rating":
|
||||
if let v = Int(val), v > 0 { earned += v; total += field["max"] as? Int ?? 5 }
|
||||
case "checkbox":
|
||||
total += 1; if val == "true" { earned += 1 }
|
||||
case "radio":
|
||||
total += 1
|
||||
if ["pass","yes","ok","good","acceptable","compliant"].contains(val.lowercased()) { earned += 1 }
|
||||
case "pass_fail":
|
||||
guard !val.isEmpty else { continue }
|
||||
total += 1
|
||||
if ["pass","yes","ok","good","acceptable","compliant"].contains(val.lowercased()) { earned += 1 }
|
||||
default: break
|
||||
}
|
||||
}
|
||||
guard total > 0 else { return nil }
|
||||
return (Double(earned) / Double(total) * 100).rounded(toPlaces: 2)
|
||||
}
|
||||
|
||||
// ── Body ──────────────────────────────────────────────────────────────
|
||||
|
||||
var body: some View {
|
||||
@@ -83,7 +121,25 @@ struct ExecuteInspectionView: View {
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
ConnectivityBadge()
|
||||
HStack(spacing: 10) {
|
||||
// Live score — updates on every field change via formValues binding.
|
||||
// Only shown when the schema has at least one scoreable field.
|
||||
if let score = liveScore {
|
||||
let color: Color = score >= 80 ? .green : score >= 60 ? .orange : .red
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: "chart.bar.fill")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(color)
|
||||
Text(String(format: "%.0f%%", score))
|
||||
.font(.system(size: 13, weight: .semibold, design: .rounded))
|
||||
.foregroundStyle(color)
|
||||
}
|
||||
.padding(.horizontal, 8).padding(.vertical, 4)
|
||||
.background(color.opacity(0.12))
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
ConnectivityBadge()
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
|
||||
Reference in New Issue
Block a user