Add the Input Interface task submission form to Tasks/Progress
New "Add a Task" card above the master-detail board: track dropdown (8
real tracks + new Unassigned/Needs Triage fallback), submitter dropdown
(Peter/Mckinley), and a task text field. Submit is disabled until all
three are filled. Posts to the Input Interface session's local Flask
backend (localhost:8507/submit-task, POST {trackId, submitter, taskText}),
which owns writing the new subtask into TASKS_DATA on disk. On success,
this page's own in-memory TASKS_DATA is patched immediately too, so the
board reflects the new task without a reload, form clears and shows
"Added to {label}". On error, shows the message inline and leaves the
form filled in.
Also adds the "Unassigned / Needs Triage" track itself (empty, pale
red/orange tint to stand out, positioned first in TASKS_DATA) as the
catch-all destination for submissions that don't fit an existing track.
Source values from that backend ("Input Interface (Peter)" / "Input
Interface (Mckinley)") needed no rendering changes on this end -- source
was already displayed as a plain string everywhere, never switched on for
styling.
This commit is contained in:
1 parent
ab7f8368ae
commit
7c0c169cf0
1 file changed
+105
-1
+105
-1
@@ -724,6 +724,7 @@
|
||||
.ab-card:hover { border-color: #2d6a9f; }
|
||||
.ab-card-weekly { background: #fffbe6; }
|
||||
.ab-card-progress-log { background: #eefbf1; }
|
||||
.ab-card-unassigned { background: #fdecea; border-color: #e2a29b; }
|
||||
|
||||
.pl-cal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
||||
.pl-cal-label { font-size: 1.05rem; font-weight: 800; color: #1b3a5c; }
|
||||
@@ -889,6 +890,40 @@
|
||||
</div>
|
||||
|
||||
<div id="tab-tasks" class="tab-content">
|
||||
<div class="card" style="margin-bottom: 20px;">
|
||||
<h2>Add a Task</h2>
|
||||
<div style="display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end;">
|
||||
<label style="flex:1; min-width:200px;">Track
|
||||
<select id="ti-track">
|
||||
<option value="">Select a track…</option>
|
||||
<option value="open-items-linkedin">LinkedIn</option>
|
||||
<option value="open-items-outreach">Outreach</option>
|
||||
<option value="open-items-department-dash">Department Dash</option>
|
||||
<option value="open-items-demographics">Demographics</option>
|
||||
<option value="open-items-mail-merge">Mail Merge Interface</option>
|
||||
<option value="open-items-crm-research">CRM Research</option>
|
||||
<option value="open-items-opportunities">Opportunities / Conference Scout</option>
|
||||
<option value="open-items-market-intelligence">Market Intelligence / Prospect Scout</option>
|
||||
<option value="open-items-unassigned">Unassigned / Needs Triage</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="min-width:160px;">Submitted by
|
||||
<select id="ti-submitter">
|
||||
<option value="">Select…</option>
|
||||
<option value="Peter">Peter</option>
|
||||
<option value="Mckinley">Mckinley</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<label style="display:block; margin-top:12px;">Task
|
||||
<textarea id="ti-text" maxlength="2000" rows="3" style="width:100%; font-family:inherit; font-size:0.95rem; padding:8px 10px; border:1px solid #d3dbe4; border-radius:6px;" placeholder="Describe the task…"></textarea>
|
||||
</label>
|
||||
<div style="margin-top:12px; display:flex; align-items:center; gap:12px;">
|
||||
<button type="button" id="ti-submit" disabled>Add Task</button>
|
||||
<span id="ti-status" style="font-size:0.85rem;"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
@@ -6369,6 +6404,13 @@
|
||||
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: "open-items-unassigned",
|
||||
label: "Unassigned / Needs Triage",
|
||||
subtasks: [],
|
||||
notes: [],
|
||||
reports: []
|
||||
},
|
||||
{
|
||||
id: "open-items-linkedin",
|
||||
label: "LinkedIn",
|
||||
@@ -6570,7 +6612,8 @@
|
||||
|
||||
function buildTaskSidebarCard(entry, isSelected) {
|
||||
var card = document.createElement("div");
|
||||
card.className = "ab-card" + (isSelected ? " selected" : "");
|
||||
var unassignedClass = entry.id === "open-items-unassigned" ? " ab-card-unassigned" : "";
|
||||
card.className = "ab-card" + unassignedClass + (isSelected ? " selected" : "");
|
||||
card.dataset.id = entry.id;
|
||||
|
||||
// Three buckets, not two: "Still open" (actionable), "Ongoing" (standing/recurring,
|
||||
@@ -6658,6 +6701,67 @@
|
||||
|
||||
renderTasksBoard();
|
||||
|
||||
/* ---- Input Interface: local-only task submission form, posts to a small Flask
|
||||
backend (port 8507, owned by the Input Interface session) that writes the new
|
||||
subtask directly into TASKS_DATA in index.html on disk. This page's own
|
||||
in-memory TASKS_DATA is patched immediately on success too, so the board
|
||||
reflects the new task without needing a reload. */
|
||||
(function () {
|
||||
var trackEl = document.getElementById("ti-track");
|
||||
var submitterEl = document.getElementById("ti-submitter");
|
||||
var textEl = document.getElementById("ti-text");
|
||||
var submitBtn = document.getElementById("ti-submit");
|
||||
var statusEl = document.getElementById("ti-status");
|
||||
|
||||
function updateSubmitEnabled() {
|
||||
submitBtn.disabled = !(trackEl.value && submitterEl.value && textEl.value.trim());
|
||||
}
|
||||
trackEl.addEventListener("change", updateSubmitEnabled);
|
||||
submitterEl.addEventListener("change", updateSubmitEnabled);
|
||||
textEl.addEventListener("input", updateSubmitEnabled);
|
||||
|
||||
submitBtn.addEventListener("click", function () {
|
||||
submitBtn.disabled = true;
|
||||
statusEl.textContent = "Adding…";
|
||||
statusEl.style.color = "#6b7a8d";
|
||||
|
||||
var trackId = trackEl.value;
|
||||
var trackLabel = trackEl.options[trackEl.selectedIndex].text;
|
||||
|
||||
fetch("http://localhost:8507/submit-task", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ trackId: trackId, submitter: submitterEl.value, taskText: textEl.value.trim() })
|
||||
})
|
||||
.then(function (r) { return r.json().then(function (data) { return { ok: r.ok, data: data }; }); })
|
||||
.then(function (result) {
|
||||
if (!result.ok) {
|
||||
statusEl.textContent = (result.data && result.data.error) || "Something went wrong.";
|
||||
statusEl.style.color = "#b3261e";
|
||||
updateSubmitEnabled();
|
||||
return;
|
||||
}
|
||||
var track = TASKS_DATA.filter(function (t) { return t.id === trackId; })[0];
|
||||
if (track && result.data.subtask && result.data.subtask.subtask) {
|
||||
track.subtasks.push(result.data.subtask);
|
||||
}
|
||||
trackEl.value = "";
|
||||
submitterEl.value = "";
|
||||
textEl.value = "";
|
||||
statusEl.textContent = "Added to " + trackLabel + ".";
|
||||
statusEl.style.color = "#1a8a60";
|
||||
updateSubmitEnabled();
|
||||
tasksSelectedId = trackId;
|
||||
renderTasksBoard();
|
||||
})
|
||||
.catch(function () {
|
||||
statusEl.textContent = "Couldn't reach the task input backend (localhost:8507) — is it running?";
|
||||
statusEl.style.color = "#b3261e";
|
||||
updateSubmitEnabled();
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
/* ---- Progress Log: a normal entry in the same sidebar list as Weekly Tasks and the
|
||||
track cards, not a separate section. Its detail view is a calendar (not a list)
|
||||
-- still computed from the exact same TASKS_DATA/WEEKLY_TASKS_DATA notes+reports,
|
||||
|
||||
Reference in new issue
Block a user