c0b9cf12f7
Co-authored-by: Cursor <cursoragent@cursor.com>
117 lines
10 KiB
HTML
117 lines
10 KiB
HTML
{% load i18n %}
|
||
<div class="page-content"{% if form_open %} data-task-form-open="1"{% endif %}>
|
||
|
||
<!-- Заголовок -->
|
||
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:1.25rem; gap:0.75rem;">
|
||
<div>
|
||
<h1 style="font-size:1.25rem; font-weight:500; color:var(--color-foreground);">{% trans "Мои задачи" %}</h1>
|
||
<p style="font-size:0.875rem; color:var(--color-muted-foreground); margin-top:0.25rem;">{% trans "Задачи, созданные вами или назначенные вам" %}</p>
|
||
</div>
|
||
<button type="button" class="btn btn-primary" style="white-space:nowrap;" onclick="taskCreateOpen()">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>
|
||
</svg>
|
||
{% trans "Новая задача" %}
|
||
</button>
|
||
</div>
|
||
|
||
{{ department_tree|json_script:"department-tree-data" }}
|
||
{% include "partials/task-create-modal.html" %}
|
||
|
||
<!-- Таби -->
|
||
<div style="display:flex; gap:0.25rem; margin-bottom:1rem; background:var(--color-muted); border-radius:var(--radius); padding:0.25rem; width:fit-content;">
|
||
{% with base="display:inline-flex; align-items:center; gap:0.375rem; padding:0.375rem 0.75rem; border-radius:calc(var(--radius) - 2px); font-size:0.8125rem; font-weight:500; text-decoration:none; cursor:pointer;" %}
|
||
<a href="/tasks/" hx-get="/tasks/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader"
|
||
style="{{ base }} {% if not active_status %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
|
||
{% trans "Все" %} <span style="background:{% if not active_status %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.all }}</span>
|
||
</a>
|
||
<a href="/tasks/?status=pending" hx-get="/tasks/?status=pending" hx-target="#main-content" hx-push-url="/tasks/?status=pending" hx-indicator="#loader"
|
||
style="{{ base }} {% if active_status == 'pending' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
|
||
{% trans "Ожидает" %} <span style="background:{% if active_status == 'pending' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.pending }}</span>
|
||
</a>
|
||
<a href="/tasks/?status=in_progress" hx-get="/tasks/?status=in_progress" hx-target="#main-content" hx-push-url="/tasks/?status=in_progress" hx-indicator="#loader"
|
||
style="{{ base }} {% if active_status == 'in_progress' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
|
||
{% trans "В работе" %} <span style="background:{% if active_status == 'in_progress' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.in_progress }}</span>
|
||
</a>
|
||
<a href="/tasks/?status=done" hx-get="/tasks/?status=done" hx-target="#main-content" hx-push-url="/tasks/?status=done" hx-indicator="#loader"
|
||
style="{{ base }} {% if active_status == 'done' %}background:var(--color-primary); color:var(--color-primary-foreground);{% else %}background:transparent; color:var(--color-muted-foreground);{% endif %}">
|
||
{% trans "Выполнено" %} <span style="background:{% if active_status == 'done' %}rgba(255,255,255,0.25){% else %}var(--color-border){% endif %}; border-radius:999px; padding:0 0.375rem; font-size:0.6875rem; line-height:1.6;">{{ counts.done }}</span>
|
||
</a>
|
||
{% endwith %}
|
||
</div>
|
||
|
||
<!-- Список задач -->
|
||
<div style="background:var(--color-card); border-radius:0.75rem; border:1px solid var(--color-border); box-shadow:0 1px 2px rgb(0 0 0/0.05); overflow:hidden;">
|
||
|
||
{% for task in tasks %}
|
||
<div class="task-row li-hover" style="{% if not forloop.last %}border-bottom:1px solid var(--color-border);{% endif %} {% if task.status == 'done' %}background:var(--color-muted);{% endif %}">
|
||
<form hx-post="/tasks/{{ task.pk }}/toggle/" hx-target="#main-content" hx-indicator="#loader" style="margin:0; display:flex;">
|
||
{% csrf_token %}
|
||
<input type="checkbox" {% if task.status == 'done' %}checked{% endif %}
|
||
onchange="htmx.trigger(this.form, 'submit')"
|
||
style="width:1rem; height:1rem; flex-shrink:0; accent-color:var(--color-primary); cursor:pointer; margin-top:2px;">
|
||
</form>
|
||
<div style="flex:1; min-width:0; cursor:pointer;"
|
||
hx-get="/tasks/{{ task.pk }}/" hx-target="#main-content" hx-push-url="/tasks/{{ task.pk }}/" hx-indicator="#loader">
|
||
<div style="font-size:0.875rem; font-weight:500; color:{% if task.status == 'done' %}var(--color-muted-foreground); text-decoration:line-through;{% else %}var(--color-card-foreground);{% endif %}">{{ task.title }}</div>
|
||
<div style="font-size:0.75rem; color:var(--color-muted-foreground); margin-top:0.0625rem;">
|
||
{% if task.description %}{{ task.description|truncatechars:90 }}{% endif %}
|
||
{% if task.display_people %}
|
||
<span style="opacity:0.8;">
|
||
→
|
||
{% for a in task.display_people %}{{ a.get_full_name }}{% if not forloop.last %}, {% endif %}{% endfor %}
|
||
</span>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
<div class="task-meta">
|
||
{% if task.status == 'done' %}
|
||
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(152 55% 35%);">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>{% trans "Выполнено" %}
|
||
</span>
|
||
{% elif task.status == 'in_progress' %}
|
||
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(152 55% 35%);">
|
||
<span style="width:6px; height:6px; border-radius:50%; background:hsl(152 55% 45%); flex-shrink:0;"></span>{% trans "В работе" %}
|
||
</span>
|
||
{% elif task.status == 'cancelled' %}
|
||
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:var(--color-muted-foreground);">
|
||
<span style="width:6px; height:6px; border-radius:50%; background:var(--color-muted-foreground); flex-shrink:0;"></span>{% trans "Отменено" %}
|
||
</span>
|
||
{% else %}
|
||
<span style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:hsl(38 70% 35%);">
|
||
<span style="width:6px; height:6px; border-radius:50%; background:hsl(38 92% 50%); flex-shrink:0;"></span>{% trans "Ожидает" %}
|
||
</span>
|
||
{% endif %}
|
||
{% if task.due_date %}
|
||
<span class="task-date" style="display:inline-flex; align-items:center; gap:0.25rem; font-size:0.75rem; color:{% if task.is_overdue %}var(--color-destructive); font-weight:600;{% else %}var(--color-muted-foreground);{% endif %}">
|
||
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>{{ task.due_date|date:"d.m.Y" }}
|
||
</span>
|
||
{% endif %}
|
||
<span class="badge {{ task.priority_badge }}">{{ task.get_priority_display }}</span>
|
||
{% if task.can_edit %}
|
||
<a hx-get="/tasks/{{ task.pk }}/edit/" hx-target="#main-content" hx-push-url="/tasks/{{ task.pk }}/edit/" hx-indicator="#loader"
|
||
class="btn btn-ghost btn-icon" title="{% trans 'Редактировать' %}" style="padding:0.25rem; color:var(--color-muted-foreground); margin-left:auto; cursor:pointer;">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
|
||
</a>
|
||
{% endif %}
|
||
{% if task.can_delete %}
|
||
<form hx-post="/tasks/{{ task.pk }}/delete/" hx-target="#main-content" hx-push-url="/tasks/" hx-indicator="#loader"
|
||
hx-confirm="{% trans 'Удалить задачу' %} «{{ task.title }}»?" style="margin:0; display:flex;">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-ghost btn-icon" title="{% trans 'Удалить' %}" style="padding:0.25rem; color:var(--color-muted-foreground);">
|
||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
|
||
</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% empty %}
|
||
<div style="padding:2.5rem; text-align:center; color:var(--color-muted-foreground); font-size:0.875rem;">
|
||
{% if active_status %}{% trans "Задач с таким статусом нет" %}{% else %}{% trans "Задач пока нет — создайте первую" %}{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
|
||
</div>
|
||
|
||
</div>
|