Fix Cora filter, speed up Overview, add inbox path link

Remove status gate from Cora filter — LB Method is the discriminator,
not status. Derive Overview stats and Cora section from /tasks data
directly (no slow /tasks/link-building fetch). Add click-to-copy
Z:\cora-inbox path next to Cora header. Show due dates in This Month.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cora-start
PeninsulaInd 2026-02-20 11:51:29 -06:00
parent f67f1b9124
commit 01ba657b35
2 changed files with 35 additions and 37 deletions

View File

@ -184,11 +184,17 @@ async def get_link_building_tasks():
# -- Build focused groups --
# need_cora: status "to do" AND LB Method = "Cora Backlinks"
need_cora = [
# Split active vs closed
closed_statuses = {"complete", "closed", "done"}
active_lb = [
t for t in lb_tasks
if t["status"] == "to do"
and t["custom_fields"].get("LB Method") == "Cora Backlinks"
if not any(kw in t["status"] for kw in closed_statuses)
]
# need_cora: open LB tasks where LB Method = "Cora Backlinks"
need_cora = [
t for t in active_lb
if t["custom_fields"].get("LB Method") == "Cora Backlinks"
]
# recently_completed: closed/complete tasks with date_done in last 7 days
@ -215,13 +221,6 @@ async def get_link_building_tasks():
kv = t.get("kv_state")
if kv is None or kv.get("state", "") in early_states:
in_progress_not_started.append(t)
# Group by company (exclude closed from the active list for the grid)
closed_statuses = {"complete", "closed", "done"}
active_lb = [
t for t in lb_tasks
if not any(kw in t["status"] for kw in closed_statuses)
]
by_company: dict[str, list] = {}
for task in active_lb:
company = task["custom_fields"].get("Customer") or "Unassigned"

View File

@ -151,6 +151,7 @@
<div class="section section--tight">
<div class="section__header">
<h2 class="section__title"><span class="icon">&#128203;</span> Cora Reports Needed</h2>
<span onclick="navigator.clipboard.writeText('Z:\\cora-inbox');this.textContent='Copied!';setTimeout(()=>this.textContent='Z:\\cora-inbox',1500)" style="font-size:0.75rem;color:var(--gold-light);cursor:pointer;margin-left:0.5rem;" title="Click to copy path">Z:\cora-inbox</span>
<span class="section__badge"><a href="#" class="section__link" data-tab="linkbuilding">View LB</a></span>
</div>
<div class="task-table-wrap task-table-wrap--compact" id="overview-cora">
@ -350,39 +351,35 @@ function updateGreeting() {
// --- Overview Tab ---
async function loadOverview() {
const [tasks, lb, pr, agents, health] = await Promise.all([
const [tasks, agents, health] = await Promise.all([
fetchJSON('/tasks'),
fetchJSON('/tasks/link-building'),
fetchJSON('/tasks/press-releases'),
fetchJSON('/agents'),
fetchJSON('/system/health'),
]);
// Cache for other tabs
_cache.tasks = tasks;
_cache.lb = lb;
_cache.pr = pr;
_cache.agents = agents;
_cache.health = health;
// Stats
if (tasks) {
// Stats — derive LB/PR counts from tasks data
if (tasks && tasks.tasks) {
document.getElementById('stat-total').textContent = tasks.count || 0;
document.getElementById('stat-total-detail').textContent = `ClickUp tasks`;
}
if (lb) {
document.getElementById('stat-lb').textContent = lb.total || 0;
document.getElementById('stat-lb-detail').textContent =
`${lb.companies ? lb.companies.length : 0} companies`;
document.getElementById('badge-lb').textContent = lb.total || 0;
}
if (pr) {
document.getElementById('stat-pr').textContent = pr.total || 0;
document.getElementById('stat-pr-detail').textContent =
`${pr.companies ? pr.companies.length : 0} companies`;
document.getElementById('badge-pr').textContent = pr.total || 0;
}
if (tasks && tasks.tasks) {
const lbTasks = tasks.tasks.filter(t => t.task_type === 'Link Building');
const prTasks = tasks.tasks.filter(t => t.task_type === 'Press Release');
document.getElementById('stat-lb').textContent = lbTasks.length;
const lbCompanies = new Set(lbTasks.map(t => t.custom_fields?.Customer || 'Unassigned'));
document.getElementById('stat-lb-detail').textContent = `${lbCompanies.size} companies`;
document.getElementById('badge-lb').textContent = lbTasks.length;
document.getElementById('stat-pr').textContent = prTasks.length;
const prCompanies = new Set(prTasks.map(t => t.custom_fields?.Customer || 'Unassigned'));
document.getElementById('stat-pr-detail').textContent = `${prCompanies.size} companies`;
document.getElementById('badge-pr').textContent = prTasks.length;
const companies = new Set(tasks.tasks.map(t => t.custom_fields?.Customer || 'Unassigned'));
document.getElementById('stat-companies').textContent = companies.size;
const names = [...companies].filter(c => c !== 'Unassigned').slice(0, 4).join(', ');
@ -443,12 +440,14 @@ async function loadOverview() {
}
}
document.getElementById('this-month-count').textContent = thisMonth.length;
renderOverviewTable('overview-this-month', thisMonth, false);
}
renderOverviewTable('overview-this-month', thisMonth, true);
// -- Cora Reports Needed --
if (lb && lb.need_cora) {
renderOverviewTable('overview-cora', lb.need_cora, false);
// -- Cora Reports Needed: LB tasks with LB Method = Cora Backlinks --
const needCora = openTasks.filter(t =>
t.task_type === 'Link Building'
&& t.custom_fields?.['LB Method'] === 'Cora Backlinks'
);
renderOverviewTable('overview-cora', needCora, false);
}
// Health inline