feat: focus priority, focus links, task list assignment, lists drag-and-drop, URL display fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 22:19:15 +00:00
parent 931abf2abd
commit 2e919d458b
12 changed files with 291 additions and 19 deletions

View File

@@ -94,7 +94,14 @@
<label for="li-{{ li.id }}"></label>
</div>
</form>
<span style="flex:1;font-size:0.82rem;{{ 'text-decoration:line-through;' if li.completed }}">{{ li.content }}</span>
<span class="cl-display-{{ li.id }}" style="flex:1;font-size:0.82rem;{{ 'text-decoration:line-through;' if li.completed }}">{{ li.content }}</span>
<form class="cl-edit-{{ li.id }}" action="/focus/{{ item.id }}/list-item/{{ li.id }}/edit" method="post" style="display:none;flex:1;gap:4px;align-items:center;">
<input type="text" name="content" value="{{ li.content }}" class="form-input" style="flex:1;padding:2px 6px;font-size:0.82rem;" required>
<button type="submit" class="btn btn-primary btn-xs">Save</button>
<button type="button" class="btn btn-ghost btn-xs cl-edit-cancel" data-id="{{ li.id }}">Cancel</button>
</form>
<button type="button" class="btn btn-ghost btn-xs cl-copy-btn" data-text="{{ li.content|e }}" title="Copy" style="color:var(--muted);padding:0 3px;">&#128203;</button>
<button type="button" class="btn btn-ghost btn-xs cl-edit-btn" data-id="{{ li.id }}" title="Edit" style="color:var(--muted);padding:0 3px;">&#9998;</button>
<form action="/focus/{{ item.id }}/list-item/{{ li.id }}/delete" method="post" style="display:inline">
<button class="btn btn-ghost btn-xs" style="color:var(--red);padding:0 4px;" title="Remove">&times;</button>
</form>
@@ -110,6 +117,53 @@
</div>
<!-- Links -->
<div class="card mt-4">
<div class="card-header">
<h2 class="card-title">Links</h2>
</div>
<form action="/focus/{{ item.id }}/links/add" method="post" class="flex gap-2 items-end" style="padding: 12px; border-bottom: 1px solid var(--border);">
<div class="form-group" style="flex:2; margin:0;">
<label class="form-label">Link</label>
<select name="link_id" class="form-select" required>
<option value="">Select link...</option>
{% for l in all_links %}
<option value="{{ l.id }}">{{ l.label }} — {{ l.url[:40] }}{% if l.url|length > 40 %}...{% endif %}</option>
{% endfor %}
</select>
</div>
<div class="form-group" style="flex:1; margin:0;">
<label class="form-label">Role</label>
<input type="text" name="role" class="form-input" list="link-roles" placeholder="e.g. reference, docs...">
<datalist id="link-roles">
<option value="website">
<option value="documentation">
<option value="reference">
<option value="repository">
<option value="social">
<option value="resource">
</datalist>
</div>
<button type="submit" class="btn btn-primary btn-sm">Add</button>
<a href="/links/create?focus_id={{ item.id }}" class="btn btn-ghost btn-sm">+ New Link</a>
</form>
{% for l in linked_links %}
<div class="list-row">
<span class="row-title"><a href="{{ l.url }}" target="_blank">{{ l.label }}</a></span>
<span class="row-meta" style="min-width:0;overflow:hidden;text-overflow:ellipsis;">{{ l.url }}</span>
{% if l.role %}<span class="row-tag">{{ l.role }}</span>{% endif %}
<div class="row-actions">
<a href="/links/{{ l.id }}/edit" class="btn btn-ghost btn-xs">Edit</a>
<form action="/focus/{{ item.id }}/links/{{ l.id }}/remove" method="post" style="display:inline">
<button class="btn btn-ghost btn-xs">Unlink</button>
</form>
</div>
</div>
{% else %}
<div class="text-sm text-muted" style="padding: 12px;">No links</div>
{% endfor %}
</div>
<script>
(function() {
var container = document.getElementById('focus-checklist');
@@ -169,5 +223,36 @@
});
});
})();
// Copy list item text
document.querySelectorAll('.cl-copy-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
var text = btn.getAttribute('data-text');
navigator.clipboard.writeText(text).then(function() {
var orig = btn.innerHTML;
btn.innerHTML = '&#10003;';
btn.style.color = 'var(--green)';
setTimeout(function() { btn.innerHTML = orig; btn.style.color = 'var(--muted)'; }, 1200);
});
});
});
// Edit list item inline
document.querySelectorAll('.cl-edit-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
var id = btn.dataset.id;
document.querySelector('.cl-display-' + id).style.display = 'none';
var form = document.querySelector('.cl-edit-' + id);
form.style.display = 'flex';
form.querySelector('input').focus();
});
});
document.querySelectorAll('.cl-edit-cancel').forEach(function(btn) {
btn.addEventListener('click', function() {
var id = btn.dataset.id;
document.querySelector('.cl-display-' + id).style.display = '';
document.querySelector('.cl-edit-' + id).style.display = 'none';
});
});
</script>
{% endblock %}