show already completed tasks

This commit is contained in:
2026-02-10 20:02:16 +01:00
parent 9ef70e0436
commit 9a0adbf05c
7 changed files with 604 additions and 375 deletions

View File

@@ -10,12 +10,15 @@
<!-- Filters -->
<div style="border-bottom: 1px solid var(--border-dim); margin-bottom: 2rem; padding-bottom: 0.5rem; display: flex; gap: 20px;">
<div class="filter-tab active" id="filter-all" onclick="setFilter('all')" style="cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--text-primary);">
All Tasks
<div class="filter-tab active" id="filter-open" onclick="setFilter('open')" style="cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--text-primary);">
Open
</div>
<div class="filter-tab" id="filter-today" onclick="setFilter('today')" style="cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--text-secondary);">
Due Today
</div>
<div class="filter-tab" id="filter-completed" onclick="setFilter('completed')" style="cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--text-secondary);">
Completed
</div>
</div>
<!-- Grouped Lists -->
@@ -41,11 +44,34 @@
{% if act_tasks %}
<ul style="list-style: none; padding: 0; margin-top: 0;">
{% for task in act_tasks %}
{% include 'task_row_partial' %}
<!-- Inline Task Row -->
<li class="task-item-row"
data-due-date="{{ task.due_date.strftime('%Y-%m-%d') if task.due_date else '' }}"
data-status="{{ task.status }}"
style="padding: 8px 0; border-bottom: 1px solid var(--border-dim); display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px; overflow: hidden;">
<a href="{{ url_for('task_detail', task_id=task._id) }}" style="text-decoration: none; color: var(--text-primary); font-weight: 500; {% if task.status == 'completed' %}text-decoration: line-through; color: var(--text-secondary);{% endif %}">
{{ task.name }}
</a>
{% if task.due_date %}
<span style="font-size: 0.75rem; color: var(--text-secondary); background: var(--bg-input); padding: 2px 6px; border-radius: 4px;">
{{ task.due_date.strftime('%d. %b %H:%M') }}
</span>
{% endif %}
</div>
<div style="display: flex; gap: 10px;">
<form action="{{ url_for('toggle_timer', activity_id=task.activity_id) }}" method="POST" style="margin: 0;">
<input type="hidden" name="note" value="{{ task.name }}">
<button type="submit" title="Start Timer" style="background: none; border: 1px solid var(--border-dim); cursor: pointer; border-radius: 4px; padding: 2px 6px; color: var(--text-secondary); font-size: 0.8rem;">
</button>
</form>
</div>
</li>
{% endfor %}
</ul>
{% else %}
<div style="padding-left: 20px; color: var(--text-secondary); font-size: 0.85rem; margin-bottom: 1rem;">No open tasks</div>
{% endif %}
</div>
{% endfor %}
@@ -67,7 +93,27 @@
</div>
<ul style="list-style: none; padding: 0; margin-top: 0;">
{% for task in no_act_tasks %}
{% include 'task_row_partial' %}
<!-- Inline Task Row -->
<li class="task-item-row"
data-due-date="{{ task.due_date.strftime('%Y-%m-%d') if task.due_date else '' }}"
data-status="{{ task.status }}"
style="padding: 8px 0; border-bottom: 1px solid var(--border-dim); display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10px; overflow: hidden;">
<a href="{{ url_for('task_detail', task_id=task._id) }}" style="text-decoration: none; color: var(--text-primary); font-weight: 500; {% if task.status == 'completed' %}text-decoration: line-through; color: var(--text-secondary);{% endif %}">
{{ task.name }}
</a>
{% if task.due_date %}
<span style="font-size: 0.75rem; color: var(--text-secondary); background: var(--bg-input); padding: 2px 6px; border-radius: 4px;">
{{ task.due_date.strftime('%d. %b %H:%M') }}
</span>
{% endif %}
</div>
<div style="display: flex; gap: 10px;">
<!-- No start button usually here if no activity linked -->
</div>
</li>
{% endfor %}
</ul>
</div>
@@ -97,8 +143,8 @@
</div>
<!-- Modal for New Task -->
<div id="taskModal" style="display:none; position: fixed; top:0; left:0; width:100%; height:100%; background: rgba(0,0,0,0.4); z-index: 2000; justify-content: center; align-items: center;">
<div class="card" style="width: 90%; max-width: 450px; box-shadow: 0 10px 25px rgba(0,0,0,0.1);">
<div id="taskModal" class="modal-backdrop">
<div class="modal-card">
<h3 style="margin-bottom: 1.5rem;">Create New Task</h3>
<form action="{{ url_for('create_task') }}" method="POST">
<label>Task Name</label>
@@ -112,14 +158,10 @@
{% endfor %}
</select>
<div style="display: flex; gap: 1rem;">
<div style="flex: 1;">
<label>Due Date</label>
<input type="datetime-local" name="due_date">
</div>
</div>
<label>Due Date</label>
<input type="datetime-local" name="due_date">
<div style="margin-bottom: 1.5rem; display: flex; align-items: start; gap: 10px;">
<div style="margin-bottom: 1.5rem; display: flex; align-items: start; gap: 10px; margin-top: 1.5rem;">
<input type="checkbox" id="is_template" name="is_template" value="1" style="width: auto; margin-top: 4px;">
<label for="is_template" style="margin-top: 0; text-transform: none; font-weight: 400; line-height: 1.4;">
<strong>Save as Template?</strong><br>
@@ -127,23 +169,15 @@
</label>
</div>
<div style="display: flex; justify-content: flex-end; gap: 10px;">
<button type="button" class="btn" style="background: white; color: var(--text-primary); border: 1px solid var(--border-dim);" onclick="closeTaskModal()">Cancel</button>
<div style="display: flex; justify-content: flex-end; gap: 10px; margin-top: 2rem;">
<button type="button" class="btn" style="background: transparent; color: var(--text-secondary); border: 1px solid var(--border-dim);" onclick="closeTaskModal()">Cancel</button>
<button type="submit" class="btn">Create Task</button>
</div>
</form>
</div>
</div>
<!-- Inline macro for task rows to avoid duplication -->
{% set today_str = now_date_str %} <!-- Assuming passed or calculated in JS. Let's use JS for 'Today' logic -->
<!-- We define the snippet inline via standard HTML inside loops above, but effectively we want this structure: -->
<!--
Used a macro or include approach? Jinja 'include' with local context is tricky inside loops for simple snippets.
I'll create the row logic directly in the loops above, but here is the block for reference.
-->
<!-- Scripts removed dead macros -->
<script>
function openTaskModal(activityId) {
const modal = document.getElementById('taskModal');
@@ -156,12 +190,12 @@
select.value = "";
}
modal.style.display = 'flex';
modal.classList.add('show');
nameInput.focus();
}
function closeTaskModal() {
document.getElementById('taskModal').style.display = 'none';
document.getElementById('taskModal').classList.remove('show');
}
// Close on backdrop click
@@ -171,74 +205,39 @@
// Filtering Logic
function setFilter(type) {
document.querySelectorAll('.filter-tab').forEach(el => el.style.color = 'var(--text-secondary)');
document.querySelectorAll('.filter-tab').forEach(el => {
el.style.color = 'var(--text-secondary)';
el.classList.remove('active');
});
document.getElementById('filter-' + type).style.color = 'var(--text-primary)';
document.getElementById('filter-' + type).classList.add('active');
const taskItems = document.querySelectorAll('.task-item-row');
const today = new Date().toISOString().split('T')[0];
taskItems.forEach(item => {
if (type === 'all') {
item.style.display = 'flex';
const status = item.getAttribute('data-status');
const dateStr = item.getAttribute('data-due-date');
let show = false;
if (type === 'open') {
if (status !== 'completed') show = true;
} else if (type === 'today') {
const dateStr = item.getAttribute('data-due-date');
// Simple check if date string starts with today's YYYY-MM-DD
if (dateStr && dateStr.startsWith(today)) {
item.style.display = 'flex';
} else {
item.style.display = 'none';
}
// Open tasks due today
if (status !== 'completed' && dateStr && dateStr.startsWith(today)) show = true;
} else if (type === 'completed') {
if (status === 'completed') show = true;
}
item.style.display = show ? 'flex' : 'none';
});
// Hide groups that become empty? Optional.
// Removed the group hiding logic block here to ensure Activity headers always stay visible
}
// Initialize filter
setFilter('open');
</script>
<!-- Inline Task Row Template Helper -->
{% macro task_row_partial() %}
<!-- This technically needs to be a separate file or defined as a macro at top of file.
Since I can't easily create a partial file in this response format without explicit request,
Reference: this is the HTML used inside the loops above. -->
{% endmacro %}
{% endblock %}
{% macro task_row_partial() %}
<!-- NOTE: This is a hack to define the row content for the loops above.
Normally you'd copy-paste this inside the loops or use a real macro.
Since I can't put macros inside blocks in standard Jinja without issues,
I will copy paste this HTML into the loops in the final file version. -->
{% endmacro %}
<!--
REAL TEMPLATE CONTENT FOR INCLUSION IN LOOPS:
-->
{% block task_row_content %}
<!-- ... THIS IS USED INSIDE THE LOOPS ... -->
<li class="task-item-row" data-due-date="{{ task.due_date.strftime('%Y-%m-%d') if task.due_date else '' }}"
style="padding: 8px 0; border-bottom: 1px solid var(--border-dim); display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; alignItems: center; gap: 10px; overflow: hidden;">
<a href="{{ url_for('task_detail', task_id=task._id) }}" style="text-decoration: none; color: var(--text-primary); font-weight: 500;">
{{ task.name }}
</a>
{% if task.due_date %}
<span style="font-size: 0.75rem; color: {% if task.due_date < now %}var(--danger-color){% else %}var(--text-secondary){% endif %}; background: var(--bg-input); padding: 2px 6px; border-radius: 4px;">
{{ task.due_date.strftime('%d. %b %H:%M') }}
</span>
{% endif %}
</div>
<div style="display: flex; gap: 10px;">
{% if task.activity_id %}
<form action="{{ url_for('toggle_timer', activity_id=task.activity_id) }}" method="POST" style="margin: 0;">
<input type="hidden" name="note" value="{{ task.name }}">
<button type="submit" title="Start Timer" style="background: none; border: 1px solid var(--border-dim); cursor: pointer; border-radius: 4px; padding: 2px 6px; color: var(--text-secondary); font-size: 0.8rem;">
</button>
</form>
{% endif %}
</div>
</li>
{% endblock %}