Spaces:
Sleeping
Sleeping
fix(sidepanel): add CRITICAL severity filter/cards, description, proper severity ordering
Browse files- extension/sidepanel.js +23 -7
extension/sidepanel.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
| 1 |
/**
|
| 2 |
-
* ClauseGuard — Side Panel
|
|
|
|
|
|
|
|
|
|
| 3 |
*/
|
| 4 |
|
| 5 |
const DESCS = {
|
|
@@ -13,8 +16,12 @@ const DESCS = {
|
|
| 13 |
"Arbitration": "You waive your right to sue in court.",
|
| 14 |
};
|
| 15 |
|
|
|
|
|
|
|
|
|
|
| 16 |
// SVG icons for severity
|
| 17 |
const SEV_ICONS = {
|
|
|
|
| 18 |
HIGH: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
|
| 19 |
MEDIUM: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>',
|
| 20 |
LOW: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
|
|
@@ -51,10 +58,20 @@ async function loadResults() {
|
|
| 51 |
pf.style.width = `${results.risk_score}%`;
|
| 52 |
pf.style.background = results.risk_score >= 60 ? "#ef4444" : results.risk_score >= 30 ? "#f59e0b" : "#22c55e";
|
| 53 |
|
| 54 |
-
//
|
| 55 |
-
const counts = { HIGH: 0, MEDIUM: 0, LOW: 0 };
|
| 56 |
const flagged = results.results.filter(r => r.categories?.length > 0);
|
| 57 |
-
flagged.forEach(r => r.categories.forEach(c => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
document.getElementById("fc-high").textContent = counts.HIGH;
|
| 59 |
document.getElementById("fc-med").textContent = counts.MEDIUM;
|
| 60 |
document.getElementById("fc-low").textContent = counts.LOW;
|
|
@@ -74,11 +91,10 @@ function renderClauses() {
|
|
| 74 |
|
| 75 |
list.innerHTML = filtered.map((clause, i) => {
|
| 76 |
const maxSev = clause.categories.reduce((m, c) => {
|
| 77 |
-
|
| 78 |
-
return (o[c.severity] || 0) > (o[m] || 0) ? c.severity : m;
|
| 79 |
}, "LOW");
|
| 80 |
|
| 81 |
-
const tagMap = { HIGH: "tag-high", MEDIUM: "tag-medium", LOW: "tag-low" };
|
| 82 |
|
| 83 |
const tags = clause.categories.map(c =>
|
| 84 |
`<span class="tag ${tagMap[c.severity] || "tag-medium"}">${SEV_ICONS[c.severity] || ""} ${c.name}</span>`
|
|
|
|
| 1 |
/**
|
| 2 |
+
* ClauseGuard — Side Panel v4.3
|
| 3 |
+
*
|
| 4 |
+
* FIXED v4.3: Added CRITICAL severity support (filter, cards, icons, descriptions).
|
| 5 |
+
* FIXED v4.3: Severity ordering now uses numeric mapping consistently.
|
| 6 |
*/
|
| 7 |
|
| 8 |
const DESCS = {
|
|
|
|
| 16 |
"Arbitration": "You waive your right to sue in court.",
|
| 17 |
};
|
| 18 |
|
| 19 |
+
// Severity numeric ordering (higher = more severe)
|
| 20 |
+
const SEV_ORDER = { CRITICAL: 4, HIGH: 3, MEDIUM: 2, LOW: 1 };
|
| 21 |
+
|
| 22 |
// SVG icons for severity
|
| 23 |
const SEV_ICONS = {
|
| 24 |
+
CRITICAL: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
|
| 25 |
HIGH: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
|
| 26 |
MEDIUM: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>',
|
| 27 |
LOW: '<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
|
|
|
|
| 58 |
pf.style.width = `${results.risk_score}%`;
|
| 59 |
pf.style.background = results.risk_score >= 60 ? "#ef4444" : results.risk_score >= 30 ? "#f59e0b" : "#22c55e";
|
| 60 |
|
| 61 |
+
// FIX v4.3: Count CRITICAL severity too
|
| 62 |
+
const counts = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };
|
| 63 |
const flagged = results.results.filter(r => r.categories?.length > 0);
|
| 64 |
+
flagged.forEach(r => r.categories.forEach(c => {
|
| 65 |
+
if (counts[c.severity] !== undefined) counts[c.severity]++;
|
| 66 |
+
else counts.MEDIUM++; // Default unknown to MEDIUM
|
| 67 |
+
}));
|
| 68 |
+
|
| 69 |
+
// Show CRITICAL count in the filter if any exist
|
| 70 |
+
const fcCrit = document.getElementById("fc-crit");
|
| 71 |
+
const critFilter = document.getElementById("filter-critical");
|
| 72 |
+
if (fcCrit) fcCrit.textContent = counts.CRITICAL;
|
| 73 |
+
if (critFilter) critFilter.style.display = counts.CRITICAL > 0 ? "flex" : "none";
|
| 74 |
+
|
| 75 |
document.getElementById("fc-high").textContent = counts.HIGH;
|
| 76 |
document.getElementById("fc-med").textContent = counts.MEDIUM;
|
| 77 |
document.getElementById("fc-low").textContent = counts.LOW;
|
|
|
|
| 91 |
|
| 92 |
list.innerHTML = filtered.map((clause, i) => {
|
| 93 |
const maxSev = clause.categories.reduce((m, c) => {
|
| 94 |
+
return (SEV_ORDER[c.severity] || 0) > (SEV_ORDER[m] || 0) ? c.severity : m;
|
|
|
|
| 95 |
}, "LOW");
|
| 96 |
|
| 97 |
+
const tagMap = { CRITICAL: "tag-critical", HIGH: "tag-high", MEDIUM: "tag-medium", LOW: "tag-low" };
|
| 98 |
|
| 99 |
const tags = clause.categories.map(c =>
|
| 100 |
`<span class="tag ${tagMap[c.severity] || "tag-medium"}">${SEV_ICONS[c.severity] || ""} ${c.name}</span>`
|