Restructure Tasks as a master-detail board, like the Directory outreach board
Each task arrival (a full week's sheet, or sometimes a single one-off task) is now its own card in a left-hand list; selecting one shows its full detail on the right, reusing the same .ab-card/.ab-outreach-list/.ab-outreach-detail styling as the Directory tab for visual consistency. Also drops the placeholder narrative text under Notes and Reports.
This commit is contained in:
1 parent
10deb08700
commit
798d35f4c9
1 file changed
+87
-42
+87
-42
@@ -848,57 +848,19 @@
|
||||
|
||||
<div id="tab-tasks" class="tab-content">
|
||||
<h2 style="margin: 0 0 6px; font-size: 1.3rem; font-weight: 800; color: #1b3a5c;">Weekly Tasks</h2>
|
||||
<p class="narrative">Peter's weekly task sheet (~/Downloads/Mckinley_Weekly_Task_Plan_*.xlsx) — a new one arrives about once a week; each week gets its own card below, newest first. [Placeholder — add a new card each week rather than overwriting the last one.]</p>
|
||||
<p class="narrative">Peter's task assignments — usually a full week's sheet (~/Downloads/Mckinley_Weekly_Task_Plan_*.xlsx), sometimes just a single one-off task. Each arrival gets its own card on the left, newest first; select one to see its full detail. [Placeholder — add a new entry to TASKS_DATA each time Peter sends one.]</p>
|
||||
|
||||
<div class="card">
|
||||
<h3>Week of 17–21 Aug 2026</h3>
|
||||
<table class="crm-detail-table">
|
||||
<thead>
|
||||
<tr><th>Subtask</th><th>Ask</th><th>KPI</th><th>Status</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>PE companies</td>
|
||||
<td>Search LinkedIn for employees of power electronics companies from Peter's market research</td>
|
||||
<td>>10 people</td>
|
||||
<td>Still open</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SPIE attendees</td>
|
||||
<td>Check whether employees of those same PE companies attend SPIE O&P 2026</td>
|
||||
<td>>10</td>
|
||||
<td>Still open, blocked on PE companies task above</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Message draft</td>
|
||||
<td>Design first-contact info material to send</td>
|
||||
<td>>2</td>
|
||||
<td>Done</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPP for CRM</td>
|
||||
<td>Define CRM requirements, stay solution-unbiased</td>
|
||||
<td>—</td>
|
||||
<td>Done</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LinkedIn Posts</td>
|
||||
<td>Continue posts per the Canva whiteboard</td>
|
||||
<td>4 posts</td>
|
||||
<td>Ongoing</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="ab-outreach" style="display: flex;">
|
||||
<div class="ab-outreach-list" id="tasks-list"></div>
|
||||
<div class="ab-outreach-detail" id="tasks-detail"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Notes</h2>
|
||||
<p class="narrative">[Placeholder — quick notes go here.]</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Reports</h2>
|
||||
<p class="narrative">Mckinley's own reports to Peter on completed weekly tasks — not related to the LinkedIn Analytics End of Month Report. [Placeholder — add each report here once written.]</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6264,6 +6226,89 @@
|
||||
document.getElementById("ab-view-board-btn").click();
|
||||
document.querySelector(".ab-filter-chip[data-source=\"Outreach\"]").click();
|
||||
|
||||
/* ---- Tasks: Peter's weekly (sometimes single-task) assignments, master-detail like the
|
||||
Directory outreach board -- a list of arrivals on the left, full detail on the right.
|
||||
Reuses .ab-card/.ab-outreach-list/.ab-outreach-detail styling for visual consistency. */
|
||||
var TASKS_DATA = [
|
||||
{
|
||||
id: "week-2026-08-17",
|
||||
label: "Week of 17–21 Aug 2026",
|
||||
subtasks: [
|
||||
{ subtask: "PE companies", ask: "Search LinkedIn for employees of power electronics companies from Peter's market research", kpi: ">10 people", status: "Still open" },
|
||||
{ subtask: "SPIE attendees", ask: "Check whether employees of those same PE companies attend SPIE O&P 2026", kpi: ">10", status: "Still open, blocked on PE companies task above" },
|
||||
{ subtask: "Message draft", ask: "Design first-contact info material to send", kpi: ">2", status: "Done" },
|
||||
{ subtask: "IPP for CRM", ask: "Define CRM requirements, stay solution-unbiased", kpi: "—", status: "Done" },
|
||||
{ subtask: "LinkedIn Posts", ask: "Continue posts per the Canva whiteboard", kpi: "4 posts", status: "Ongoing" }
|
||||
]
|
||||
}
|
||||
];
|
||||
var tasksSelectedId = null;
|
||||
|
||||
function tasksEsc(s) {
|
||||
return String(s == null ? "" : s).replace(/[&<>"]/g, function (c) {
|
||||
return { "&": "&", "<": "<", ">": ">", "\"": """ }[c];
|
||||
});
|
||||
}
|
||||
|
||||
function renderTasksBoard() {
|
||||
var sorted = TASKS_DATA; // newest-first order is authored order for now
|
||||
if (!tasksSelectedId || !sorted.some(function (t) { return t.id === tasksSelectedId; })) {
|
||||
tasksSelectedId = sorted.length ? sorted[0].id : null;
|
||||
}
|
||||
|
||||
var list = document.getElementById("tasks-list");
|
||||
list.innerHTML = "";
|
||||
sorted.forEach(function (entry) {
|
||||
list.appendChild(buildTaskSidebarCard(entry, entry.id === tasksSelectedId));
|
||||
});
|
||||
|
||||
var detail = document.getElementById("tasks-detail");
|
||||
var selected = sorted.filter(function (t) { return t.id === tasksSelectedId; })[0];
|
||||
detail.innerHTML = selected ? buildTaskDetail(selected) : "<div class=\"ab-outreach-empty\">No tasks yet.</div>";
|
||||
}
|
||||
|
||||
function buildTaskSidebarCard(entry, isSelected) {
|
||||
var card = document.createElement("div");
|
||||
card.className = "ab-card" + (isSelected ? " selected" : "");
|
||||
card.dataset.id = entry.id;
|
||||
|
||||
var openCount = entry.subtasks.filter(function (s) { return s.status.indexOf("Done") !== 0; }).length;
|
||||
var summary = entry.subtasks.length === 1
|
||||
? entry.subtasks[0].status
|
||||
: (openCount === 0 ? "All done" : openCount + " still open");
|
||||
|
||||
card.innerHTML =
|
||||
"<div class=\"ab-card-top\">" +
|
||||
"<div class=\"ab-card-company\">" + tasksEsc(entry.label) + "</div>" +
|
||||
"<span class=\"ab-source-chip boss\">" + tasksEsc(summary) + "</span>" +
|
||||
"</div>" +
|
||||
"<div class=\"ab-card-name\">" + entry.subtasks.length + (entry.subtasks.length === 1 ? " task" : " subtasks") + "</div>";
|
||||
|
||||
card.addEventListener("click", function () {
|
||||
tasksSelectedId = entry.id;
|
||||
renderTasksBoard();
|
||||
});
|
||||
return card;
|
||||
}
|
||||
|
||||
function buildTaskDetail(entry) {
|
||||
var rows = entry.subtasks.map(function (s) {
|
||||
return "<tr><td>" + tasksEsc(s.subtask) + "</td><td>" + tasksEsc(s.ask) + "</td><td>" + tasksEsc(s.kpi) + "</td><td>" + tasksEsc(s.status) + "</td></tr>";
|
||||
}).join("");
|
||||
|
||||
return (
|
||||
"<div class=\"card\">" +
|
||||
"<h3>" + tasksEsc(entry.label) + "</h3>" +
|
||||
"<table class=\"crm-detail-table\">" +
|
||||
"<thead><tr><th>Subtask</th><th>Ask</th><th>KPI</th><th>Status</th></tr></thead>" +
|
||||
"<tbody>" + rows + "</tbody>" +
|
||||
"</table>" +
|
||||
"</div>"
|
||||
);
|
||||
}
|
||||
|
||||
renderTasksBoard();
|
||||
|
||||
/* ---- Opportunities module loader ----
|
||||
Fetches its markup, injects it into the empty tab container, then loads its
|
||||
script as a normal <script src> (so it runs only once the DOM it needs exists). */
|
||||
|
||||
Reference in new issue
Block a user