Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -447,17 +447,17 @@ <h2 class="text-lg font-extrabold mb-6 flex items-center text-slate-900">
</div>

<!-- Acceptance Criteria -->
<details class="mb-8 border-t border-slate-100 pt-6" open>
<summary class="cursor-pointer text-[10px] font-extrabold text-slate-600 uppercase tracking-widest">Acceptance Criteria</summary>
<p class="text-[11px] text-slate-500 mt-2 mb-3">Required failures produce FAIL; preferred warnings produce CONDITIONAL PASS.</p>
<details class="mb-8 border-t border-slate-100 dark:border-slate-800 pt-6" open>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the required public surfaces

Because this is a Web UI bug fix, the repo checklist requires updating the public-facing files for both bug fixes and Web UI changes; this commit only changes web/index.html, so CHANGELOG.md and web/README.md will omit the shipped contrast fix. Please add the required public-surface updates before landing.

AGENTS.md reference: AGENTS.md:L129-L138

Useful? React with 👍 / 👎.

<summary class="cursor-pointer text-[10px] font-extrabold text-slate-600 dark:text-slate-300 uppercase tracking-widest">Acceptance Criteria</summary>
<p class="text-[11px] text-slate-500 dark:text-slate-400 mt-2 mb-3">Required failures produce FAIL; preferred warnings produce CONDITIONAL PASS.</p>
<div class="space-y-2 text-xs">
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionCaiMode">CAI minimum 0.800</label><select id="criterionCaiMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionGcMode">Overall GC host range</label><select id="criterionGcMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionLocalGcMode">Local GC 30–70% / 60 bp</label><select id="criterionLocalGcMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionTypeIisMode">Type IIS (BsaI/BsmBI/SapI)</label><select id="criterionTypeIisMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="required">Required</option><option value="preferred">Preferred</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionRepeatsMode">Direct repeats</label><select id="criterionRepeatsMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionHomopolymerMode">Homopolymers ≤8 bp</label><select id="criterionHomopolymerMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionMotifsMode">Forbidden motifs</label><select id="criterionMotifsMode" class="criterion-mode rounded-lg border border-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionCaiMode" class="text-slate-700 dark:text-slate-300">CAI minimum 0.800</label><select id="criterionCaiMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionGcMode" class="text-slate-700 dark:text-slate-300">Overall GC host range</label><select id="criterionGcMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionLocalGcMode" class="text-slate-700 dark:text-slate-300">Local GC 30–70% / 60 bp</label><select id="criterionLocalGcMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionTypeIisMode" class="text-slate-700 dark:text-slate-300">Type IIS (BsaI/BsmBI/SapI)</label><select id="criterionTypeIisMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="required">Required</option><option value="preferred">Preferred</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionRepeatsMode" class="text-slate-700 dark:text-slate-300">Direct repeats</label><select id="criterionRepeatsMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionHomopolymerMode" class="text-slate-700 dark:text-slate-300">Homopolymers ≤8 bp</label><select id="criterionHomopolymerMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
<div class="grid grid-cols-[1fr_auto] gap-2 items-center"><label for="criterionMotifsMode" class="text-slate-700 dark:text-slate-300">Forbidden motifs</label><select id="criterionMotifsMode" class="criterion-mode rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 px-2 py-1"><option value="preferred">Preferred</option><option value="required">Required</option><option value="ignored">Ignored</option></select></div>
</div>
</details>

Expand Down
15 changes: 14 additions & 1 deletion web/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,15 @@ function getPrimaryResult(res) {
};
}

// Same wording as the profile-selection cards above (Optimization Settings),
// reused here so the comparison table explains each candidate strategy
// instead of showing a bare name.
const CANDIDATE_DESCRIPTIONS = {
feasibility_best: 'Dynamic-programming candidate with maximum CAI inside the requested GC range when feasible.',
gc_target: 'Profile-engine comparison that prioritizes proximity to the active host GC band.',
high_cai: 'Profile-engine comparison that favors high codon adaptation index.'
};

function renderCandidateComparison(res) {
if (!elements.candidateComparisonContainer || !elements.candidateComparisonBody) return;
if (!Array.isArray(res.candidates) || res.candidates.length === 0) {
Expand All @@ -955,9 +964,13 @@ function renderCandidateComparison(res) {
const isRecommended = candidate.id === recommendedId;
const status = candidate.automated_decision || (candidate.validator_status === 'pass' ? 'PASS' : 'REVIEW');
const aaStatus = candidate.validator_status === 'pass' ? '100%' : 'Review';
const description = CANDIDATE_DESCRIPTIONS[candidate.id];
const nameCell = description
? `${escapeHtml(candidate.label || candidate.id)}<span class="tooltip-container"><span class="info-icon">i</span><span class="tooltip-text">${escapeHtml(description)}</span></span>`
: escapeHtml(candidate.label || candidate.id);
return `
<tr class="${isRecommended ? 'bg-emerald-50 dark:bg-emerald-900/20' : 'bg-white dark:bg-slate-900'}">
<td class="px-3 py-2 font-bold text-slate-800 dark:text-slate-100">${candidate.label || candidate.id}${isRecommended ? ' ★' : ''}</td>
<td class="px-3 py-2 font-bold text-slate-800 dark:text-slate-100">${nameCell}${isRecommended ? ' ★' : ''}</td>
<td class="px-3 py-2">${Number(candidate.cai || 0).toFixed(3)}</td>
<td class="px-3 py-2">${Number(candidate.gc_percent || 0).toFixed(1)}</td>
<td class="px-3 py-2">${Number(candidate.gc_window_min || 0).toFixed(1)}-${Number(candidate.gc_window_max || 0).toFixed(1)}</td>
Expand Down