570b204571
The candidate row is now an intake form, not a button. Confirming asks for a definition of done and refuses without one, takes an optional blocked-on name, and carries the date and the importance through. The blocked-on is a name in the form and a canonical nexus id in the store. promoteCandidate resolves it over the new ipc.ResolveEntity seam and stops the confirmation on an ambiguous or unplaceable name rather than picking. A date set here books a reminder for 09:00 that morning. That is the only unprompted delivery the persona allows, because the owner set the date himself. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SoL7EBdYC5Mhz3DJd49GJy
127 lines
5.8 KiB
HTML
127 lines
5.8 KiB
HTML
{{template "shellTop" "tasks"}}
|
|
<h1>Tasks</h1>
|
|
{{if .Msg}}<div class="msg msg-ok">{{.Msg}}</div>{{end}}
|
|
{{if .Err}}<div class="msg msg-err">{{.Err}}</div>{{end}}
|
|
|
|
<section class=card>
|
|
<h2 class=card-title>add</h2>
|
|
<form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=action value=add>
|
|
<input type=text name=text placeholder="что нужно сделать" size=44 required>
|
|
<input type=date name=due title="due date (optional)">
|
|
<!-- weight 1 is skipped on purpose: the two rungs here are the two words she
|
|
recognises out loud ("важно", "срочно"), so the form and the spoken markers
|
|
mean the same thing. -->
|
|
<select name=weight title="importance (optional)">
|
|
<option value=0>normal</option>
|
|
<option value=2>важно</option>
|
|
<option value=3>срочно</option>
|
|
</select>
|
|
<button class=btn>add</button>
|
|
</form>
|
|
</section>
|
|
|
|
{{if .Stalls}}
|
|
<section class=card>
|
|
<h2 class=card-title>shapes</h2>
|
|
<!-- Counts, and nothing about what they mean (V-512). Whether a task should be
|
|
dropped is his call and Maven does not have an opinion to show here. -->
|
|
<div class=scroll><table>
|
|
<tr><th>count</th><th>shape</th></tr>
|
|
{{range .Stalls}}<tr><td>{{.N}}</td><td>{{.Line}}</td></tr>{{end}}
|
|
</table></div>
|
|
</section>
|
|
{{end}}
|
|
|
|
{{if .Candidates}}
|
|
<section class=card>
|
|
<h2 class=card-title>found, not confirmed <span class=badge>{{len .Candidates}}</span></h2>
|
|
<div class=hint>maven derived these from something she read. nothing counts as your work until you confirm it.</div>
|
|
<div class=hint>confirming asks for a definition of done: what has to be true for this to be finished. a task without one can never leave the board. a date here also books a reminder that morning.</div>
|
|
<div class=scroll><table>
|
|
<tr><th>task</th><th>where from</th><th>captured</th><th>confirm</th><th></th></tr>
|
|
{{range .Candidates}}<tr>
|
|
<td class=text-max>{{.Text}}</td>
|
|
<td class=hint>{{.Source}}{{if .Evidence}} — {{.Evidence}}{{end}}</td>
|
|
<td class=muted>{{.Created}}</td>
|
|
<td><form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=id value="{{.ID}}">
|
|
<input type=hidden name=action value=promote>
|
|
<input type=hidden name=text value="{{.Text}}">
|
|
<input type=text name=done_when placeholder="готово, когда…" size=26 required>
|
|
<!-- A name, not an id. It is resolved against nexus before anything is
|
|
stored, and a name nexus cannot place stops the confirmation. -->
|
|
<input type=text name=blocked_on placeholder="ждёт кого-то" size=14>
|
|
<input type=date name=due value="{{.DueValue}}" title="due date">
|
|
<select name=weight title=importance>
|
|
<option value=0 {{if eq .Weight 0}}selected{{end}}>normal</option>
|
|
<option value=2 {{if eq .Weight 2}}selected{{end}}>важно</option>
|
|
<option value=3 {{if eq .Weight 3}}selected{{end}}>срочно</option>
|
|
</select>
|
|
<button class=btn>confirm</button></form></td>
|
|
<td><form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=id value="{{.ID}}">
|
|
<input type=hidden name=action value=drop>
|
|
<button class="btn btn-muted">drop</button></form></td>
|
|
</tr>{{end}}</table></div>
|
|
</section>
|
|
{{end}}
|
|
|
|
<section class=card>
|
|
<h2 class=card-title>open <span class=badge>{{len .Open}}</span></h2>
|
|
<div class=hint>most pressing first — by the deadlines and the urgency you gave. nothing about a task is guessed; the only signal that is not yours is age, which lifts anything sitting here for weeks.</div>
|
|
{{if .Open}}<div class=scroll><table>
|
|
<tr><th>task</th><th>why</th><th>from</th><th>captured</th><th></th><th></th></tr>
|
|
{{range .Open}}<tr>
|
|
<!-- The text, the date and the importance are editable in place (V-509): a
|
|
dictated task can carry a typo, and a deadline moves. The status is not
|
|
here — that ladder is one-way and has its own two buttons. -->
|
|
<td class=text-max><form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=id value="{{.ID}}">
|
|
<input type=hidden name=action value=edit>
|
|
<input type=text name=text value="{{.Text}}" size=30 required>
|
|
<input type=date name=due value="{{.DueValue}}" title="due date">
|
|
<select name=weight title=importance>
|
|
<!-- Any weight that is not one of the three rungs keeps its own option, or
|
|
saving an unrelated edit would silently reset it to normal. -->
|
|
{{if and (ne .Weight 0) (ne .Weight 2) (ne .Weight 3)}}<option value={{.Weight}} selected>{{.Weight}}</option>{{end}}
|
|
<option value=0 {{if eq .Weight 0}}selected{{end}}>normal</option>
|
|
<option value=2 {{if eq .Weight 2}}selected{{end}}>важно</option>
|
|
<option value=3 {{if eq .Weight 3}}selected{{end}}>срочно</option>
|
|
</select>
|
|
<button class="btn btn-muted">save</button></form></td>
|
|
<td class=hint>{{.Why}}</td>
|
|
<td class=hint>{{.Source}}</td>
|
|
<td class=muted>{{.Created}}</td>
|
|
<td><form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=id value="{{.ID}}">
|
|
<input type=hidden name=action value=done>
|
|
<button class=btn>done</button></form></td>
|
|
<td><form method=post action=/tasks class=inline-form>
|
|
<input type=hidden name=id value="{{.ID}}">
|
|
<input type=hidden name=action value=drop>
|
|
<button class="btn btn-muted">drop</button></form></td>
|
|
</tr>{{end}}</table></div>
|
|
{{else}}<div class=empty>
|
|
<svg class=icon width="20" height="20"><use href="/ethos-icons.svg#i-grid"/></svg>
|
|
<div>no open tasks</div>
|
|
<div class=hint>add one above, or tell maven "добавь в задачи …"</div>
|
|
</div>{{end}}
|
|
</section>
|
|
|
|
{{if .Resolved}}
|
|
<section class=card>
|
|
<h2 class=card-title>resolved <span class=badge>{{len .Resolved}}</span></h2>
|
|
<div class=scroll><table>
|
|
<tr><th>task</th><th>status</th><th>when</th><th>by</th></tr>
|
|
{{range .Resolved}}<tr>
|
|
<td class=text-max>{{.Text}}</td>
|
|
<td><span class="badge {{.Status}}">{{.Status}}</span></td>
|
|
<td class=muted>{{.Resolved}}</td>
|
|
<td class=hint>{{.ResolvedBy}}</td>
|
|
</tr>{{end}}</table></div>
|
|
{{if .ResolvedMore}}<div class=hint>only the {{len .Resolved}} most recent are shown.</div>{{end}}
|
|
</section>
|
|
{{end}}
|
|
{{template "shellBottom"}}
|