- Convert to 7 entity types: task, note, project, list item, contact, decision, weblink - Each conversion has a dedicated form page with pre-filled fields and context selectors - Multi-line paste creates batch with shared import_batch_id and undo button - 3-tab filtering: Inbox (unprocessed), Processed (with conversion links), All - Context pre-fill: optional area/project selectors on capture form - Processed items show type badge and link to converted entity - Sidebar badge count for unprocessed items already working Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
111 lines
5.5 KiB
HTML
111 lines
5.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
<div class="page-header">
|
|
<h1 class="page-title">Capture<span class="page-count">{{ items|length }}</span></h1>
|
|
</div>
|
|
|
|
<!-- Quick capture input -->
|
|
<div class="card mb-4">
|
|
<form action="/capture/add" method="post">
|
|
<label class="form-label mb-2">Quick Capture (one item per line)</label>
|
|
<textarea name="raw_text" class="form-textarea" rows="3" placeholder="Type or paste items here... Each line becomes a separate capture item" required></textarea>
|
|
<details class="mt-2">
|
|
<summary class="text-sm text-muted" style="cursor:pointer">Context (optional)</summary>
|
|
<div class="form-grid mt-2" style="grid-template-columns:1fr 1fr">
|
|
<div class="form-group">
|
|
<label class="form-label">Project</label>
|
|
<select name="project_id" class="form-select">
|
|
<option value="">None</option>
|
|
{% for d in sidebar.domain_tree %}
|
|
<optgroup label="{{ d.name }}">
|
|
{% for a in d.areas %}{% for p in a.projects %}
|
|
<option value="{{ p.id }}">{{ p.name }}</option>
|
|
{% endfor %}{% endfor %}
|
|
{% for p in d.standalone_projects %}
|
|
<option value="{{ p.id }}">{{ p.name }}</option>
|
|
{% endfor %}
|
|
</optgroup>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Area</label>
|
|
<select name="area_id" class="form-select">
|
|
<option value="">None</option>
|
|
{% for d in sidebar.domain_tree %}
|
|
{% for a in d.areas %}
|
|
<option value="{{ a.id }}">{{ d.name }} / {{ a.name }}</option>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
<div class="mt-2"><button type="submit" class="btn btn-primary">Capture</button></div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Filter tabs -->
|
|
<div class="tab-strip mb-3">
|
|
<a href="/capture?show=inbox" class="tab-item {{ 'active' if show == 'inbox' or show not in ('processed', 'all') }}">Inbox</a>
|
|
<a href="/capture?show=processed" class="tab-item {{ 'active' if show == 'processed' }}">Processed</a>
|
|
<a href="/capture?show=all" class="tab-item {{ 'active' if show == 'all' }}">All</a>
|
|
</div>
|
|
|
|
{% if items %}
|
|
{% for item in items %}
|
|
|
|
{# Batch header #}
|
|
{% if item._batch_first and item.import_batch_id %}
|
|
<div class="flex items-center justify-between mb-2 mt-3" style="padding:6px 12px;background:var(--surface2);border-radius:var(--radius-sm)">
|
|
<span class="text-xs text-muted">Batch · {{ batches[item.import_batch_id|string] }} items</span>
|
|
<form action="/capture/batch/{{ item.import_batch_id }}/undo" method="post" style="display:inline" data-confirm="Delete all items in this batch?">
|
|
<button class="btn btn-ghost btn-xs" style="color:var(--red)">Undo batch</button>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="capture-item {{ 'completed' if item.processed }}">
|
|
<div class="capture-text {{ 'text-muted' if item.processed }}" style="{{ 'text-decoration:line-through' if item.processed }}">{{ item.raw_text }}</div>
|
|
|
|
{% if item.processed %}
|
|
<div class="capture-actions">
|
|
{% if item.converted_to_type and item.converted_to_type != 'dismissed' %}
|
|
<span class="row-tag">{{ item.converted_to_type|replace('_', ' ') }}</span>
|
|
{% if item.converted_to_id %}
|
|
{% if item.converted_to_type == 'list_item' and item.list_id %}
|
|
<a href="/lists/{{ item.list_id }}" class="btn btn-ghost btn-xs">View →</a>
|
|
{% elif item.converted_to_type == 'weblink' %}
|
|
<a href="/weblinks" class="btn btn-ghost btn-xs">View →</a>
|
|
{% elif item.converted_to_type in ('task', 'note', 'project', 'contact', 'decision') %}
|
|
<a href="/{{ item.converted_to_type }}s/{{ item.converted_to_id }}" class="btn btn-ghost btn-xs">View →</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% elif item.converted_to_type == 'dismissed' %}
|
|
<span class="row-tag" style="color:var(--muted)">dismissed</span>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<div class="capture-actions">
|
|
<select onchange="if(this.value) window.location.href=this.value" class="filter-select" style="font-size:0.75rem;padding:3px 6px">
|
|
<option value="">Convert...</option>
|
|
{% for key, label in convert_types.items() %}
|
|
<option value="/capture/{{ item.id }}/convert/{{ key }}">{{ label }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<form action="/capture/{{ item.id }}/dismiss" method="post" style="display:inline"><button class="btn btn-ghost btn-xs">Dismiss</button></form>
|
|
<form action="/capture/{{ item.id }}/delete" method="post" style="display:inline"><button class="btn btn-ghost btn-xs" style="color:var(--red)">×</button></form>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon">📥</div>
|
|
<div class="empty-state-text">
|
|
{% if show == 'processed' %}No processed items{% elif show == 'all' %}No capture items{% else %}Inbox is empty{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|