diff --git a/main.go b/main.go index 4274b58..6421f96 100644 --- a/main.go +++ b/main.go @@ -801,6 +801,13 @@ func handleListConstraints(db *sql.DB) http.HandlerFunc { Level string `json:"level"` } var overalls []overallEntry + type mismatchEntry struct { + NameA string `json:"name_a"` + NameB string `json:"name_b"` + KindA string `json:"kind_a"` + KindB string `json:"kind_b"` + } + var mismatches []mismatchEntry if role == "admin" { type pairKey struct{ a, b int64 } @@ -865,6 +872,27 @@ func handleListConstraints(db *sql.DB) http.HandlerFunc { constraints[i].Override = &desc } } + overallMap := map[pairKey]overallEntry{} + for _, o := range overalls { + overallMap[pairKey{o.StudentAID, o.StudentBID}] = o + } + for _, o := range overalls { + rev, ok := overallMap[pairKey{o.StudentBID, o.StudentAID}] + if !ok { + continue + } + if isPositive(o.Kind) && !isPositive(rev.Kind) { + mismatches = append(mismatches, mismatchEntry{ + NameA: rev.StudentBName, + NameB: o.StudentBName, + KindA: o.Kind, + KindB: rev.Kind, + }) + } + } + } + if mismatches == nil { + mismatches = []mismatchEntry{} } if overrides == nil { overrides = []overrideEntry{} @@ -874,7 +902,7 @@ func handleListConstraints(db *sql.DB) http.HandlerFunc { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(map[string]any{"constraints": constraints, "overrides": overrides, "overalls": overalls}) + json.NewEncoder(w).Encode(map[string]any{"constraints": constraints, "overrides": overrides, "overalls": overalls, "mismatches": mismatches}) } } diff --git a/static/trip.js b/static/trip.js index 3b17cb7..4b97624 100644 --- a/static/trip.js +++ b/static/trip.js @@ -59,7 +59,6 @@ async function loadStudents() { const kindVariant = { must: 'success', prefer: 'brand', prefer_not: 'warning', must_not: 'danger' }; const kindColor = { must: 'var(--wa-color-success-50)', prefer: 'var(--wa-color-brand-50)', prefer_not: 'var(--wa-color-warning-50)', must_not: 'var(--wa-color-danger-50)' }; const kindOrder = { must: 0, prefer: 1, prefer_not: 2, must_not: 3 }; - const isPositive = kind => kind === 'must' || kind === 'prefer'; const capitalize = s => s.charAt(0).toUpperCase() + s.slice(1); const conflictMap = {}; @@ -82,21 +81,7 @@ async function loadStudents() { } lastOveralls = allOveralls; - const mismatchList = []; - for (const s of students) { - for (const [bId, effA] of Object.entries(allOveralls[s.id])) { - if (!allOveralls[bId] || !allOveralls[bId][s.id]) continue; - const effB = allOveralls[bId][s.id]; - if (isPositive(effA.kind) && !isPositive(effB.kind)) { - mismatchList.push({ - nameA: s.name, - nameB: students.find(x => x.id === parseInt(bId)).name, - kindA: effA.kind, - kindB: effB.kind, - }); - } - } - } + const mismatchList = constraintData.mismatches; const studentName = {}; for (const s of students) studentName[s.id] = s.name; @@ -219,10 +204,10 @@ async function loadStudents() { for (const m of mismatchList) { const div = document.createElement('div'); div.className = 'conflict-row'; - div.appendChild(document.createTextNode(m.nameA + ' \u2192 ' + m.nameB + ': ')); - div.appendChild(kindSpan(m.kindA)); - div.appendChild(document.createTextNode(' but ' + m.nameB + ' \u2192 ' + m.nameA + ': ')); - div.appendChild(kindSpan(m.kindB)); + div.appendChild(document.createTextNode(m.name_a + ' \u2192 ' + m.name_b + ': ')); + div.appendChild(kindSpan(m.kind_a)); + div.appendChild(document.createTextNode(' but ' + m.name_b + ' \u2192 ' + m.name_a + ': ')); + div.appendChild(kindSpan(m.kind_b)); det.appendChild(div); } mismatchesEl.appendChild(det);