From ee7b4cc2563dbf273f9129b3e4e8f70f7d3386a2 Mon Sep 17 00:00:00 2001 From: PeninsulaInd Date: Fri, 20 Feb 2026 20:55:07 -0600 Subject: [PATCH] Add Cora Reports to Run queue as first section on Link Building tab Filters out automation-touched tasks (error, automation underway, complete, closed, done, internal review) and sorts by due date. Renders with 10-at-a-time pagination and responsive mobile layout. Co-Authored-By: Claude Opus 4.6 --- cheddahbot/api.py | 7 ++++ dashboard/index.html | 79 ++++++++++++++++++++++++++++++++++++++++++++ dashboard/styles.css | 4 +++ 3 files changed, 90 insertions(+) diff --git a/cheddahbot/api.py b/cheddahbot/api.py index f26ddd4..0718aa2 100644 --- a/cheddahbot/api.py +++ b/cheddahbot/api.py @@ -192,10 +192,17 @@ async def get_link_building_tasks(): ] # need_cora: open LB tasks where LB Method = "Cora Backlinks" + # Exclude tasks that automation already touched + automation_touched = { + "error", "automation underway", "complete", + "closed", "done", "internal review", + } need_cora = [ t for t in active_lb if t["custom_fields"].get("LB Method") == "Cora Backlinks" + and t["status"] not in automation_touched ] + need_cora.sort(key=lambda t: int(t.get("due_date") or "9999999999999")) # recently_completed: closed/complete tasks with date_done in last 7 days seven_days_ago_ms = (time.time() - 7 * 86400) * 1000 diff --git a/dashboard/index.html b/dashboard/index.html index 9eb3f39..29c334b 100644 --- a/dashboard/index.html +++ b/dashboard/index.html @@ -178,6 +178,17 @@
+ +
+
+

📋 Cora Reports to Run

+ - +
+
+

Loading...

+
+
+
@@ -523,6 +534,69 @@ function renderRecentTable(containerId, tasks) { container.innerHTML = html; } +function renderCoraQueue(containerId, tasks) { + const container = document.getElementById(containerId); + if (!tasks || tasks.length === 0) { + container.innerHTML = '

No Cora reports queued.

'; + return; + } + + const PAGE_SIZE = 10; + let showAll = false; + + function render() { + const visible = showAll ? tasks : tasks.slice(0, PAGE_SIZE); + let html = ` + + + + + + + `; + + visible.forEach((t, i) => { + const company = t.custom_fields?.Customer || 'Unassigned'; + const keyword = t.custom_fields?.Keyword || ''; + const link = t.url ? `${esc(t.name)}` : esc(t.name); + let dueStr = '-'; + if (t.due_date) { + const d = new Date(parseInt(t.due_date, 10)); + dueStr = d.toLocaleDateString('en-US', {month:'short', day:'numeric'}); + } + html += ` + + + + + + `; + }); + + html += '
#TaskKeywordCompanyDue Date
${i + 1}${link}${esc(keyword)}${esc(company)}${esc(dueStr)}
'; + + if (tasks.length > PAGE_SIZE) { + const remaining = tasks.length - PAGE_SIZE; + const label = showAll ? 'Show less' : `Show more (${remaining} remaining)`; + html += `
+ +
`; + } + + container.innerHTML = html; + + const btn = document.getElementById('cora-toggle-btn'); + if (btn) { + btn.addEventListener('click', () => { + showAll = !showAll; + render(); + }); + } + } + + render(); +} + function renderOverviewTable(containerId, tasks, showDueDate) { const container = document.getElementById(containerId); if (!tasks || tasks.length === 0) { @@ -644,6 +718,11 @@ async function loadLinkBuilding() { `; document.getElementById('lb-stats').innerHTML = statsHtml; + // Cora Reports to Run + const coraQueue = data.need_cora || []; + document.getElementById('lb-cora-count').textContent = coraQueue.length; + renderCoraQueue('lb-cora-table', coraQueue); + // Recently Completed const recent = data.recently_completed || []; document.getElementById('lb-recent-count').textContent = recent.length; diff --git a/dashboard/styles.css b/dashboard/styles.css index eebd0c4..ebcb975 100644 --- a/dashboard/styles.css +++ b/dashboard/styles.css @@ -1014,6 +1014,10 @@ body { min-width: 700px; } + .cora-hide-mobile { + display: none; + } + .page-header__greeting { font-size: 1.35rem; }