kpi-dashboard / templates /admin /tasks.html
Admin
Initial HF deploy
04477e7
Raw
History Blame
10.1 kB
{% extends "base.html" %}
{% block title %}Задачи{% endblock %}
{% block page_title %}Задачи{% endblock %}
{% block content %}
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<h2 style="margin:0;font-size:15px;font-weight:600;color:#fff;">Задачи</h2>
{% if current_user.role in ('admin', 'senior_expert') %}
<a href="{{ url_for('admin.create_task') }}" class="btn-apple">
<i class="bi bi-plus-lg"></i> Новая задача
</a>
{% endif %}
</div>
{% macro task_table(tasks, show_assigner=False) %}
<div class="d-card" style="border-radius:20px;background:rgba(6,11,40,0.6);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,0.05);overflow:hidden;">
<div class="d-card-body" style="padding: 0;">
{% if tasks %}
<div class="table-responsive">
<table class="d-table-card">
<thead>
<tr>
<th style="padding-left: 16px;color:#A0A5B5;">Задача</th>
{% if show_assigner %}<th style="color:#A0A5B5;">От кого</th>{% endif %}
<th style="color:#A0A5B5;">{% if show_assigner %}Кому{% else %}Назначена{% endif %}</th>
<th style="color:#A0A5B5;">Приоритет</th>
<th style="color:#A0A5B5;">Статус</th>
<th style="color:#A0A5B5;">Срок</th>
<th style="text-align:right;padding-right:16px;color:#A0A5B5;">Действия</th>
</tr>
</thead>
<tbody>
{% for t in tasks %}
<tr>
<td style="padding-left: 16px; font-weight: 500;">
{{ t.title }}
{% if t.rework_comment %}
<i class="bi bi-arrow-counterclockwise" style="color: #d97706; margin-left: 6px;" title="Отправлено на доработку"></i>
{% endif %}
</td>
{% if show_assigner %}<td>{{ t.assigner.full_name if t.assigner else '—' }}</td>{% endif %}
<td>{% if show_assigner %}{{ t.assignee.full_name }}{% else %}{{ t.assigner.full_name if t.assigner else '—' }}{% endif %}</td>
<td>
<span style="font-size:10px;font-weight:600;padding:1px 8px;border-radius:999px;{% if t.priority == 'high' %}background:rgba(220,38,38,0.1);color:#dc2626;{% elif t.priority == 'medium' %}background:rgba(217,119,6,0.1);color:#d97706;{% else %}background:rgba(37,99,235,0.1);color:#2563eb;{% endif %}">
{{ {'high': 'Высокий', 'medium': 'Средний', 'low': 'Низкий'}.get(t.priority, t.priority) }}
</span>
</td>
<td>
<span style="font-size:10px;font-weight:600;padding:1px 8px;border-radius:999px;{% if t.status == 'completed' %}background:rgba(22,163,74,0.1);color:#16a34a;{% elif t.status == 'in_progress' %}background:rgba(37,99,235,0.1);color:#2563eb;{% elif t.status == 'cancelled' %}background:rgba(100,116,139,0.1);color:#A0A5B5;{% else %}background:rgba(217,119,6,0.1);color:#d97706;{% endif %}">
{{ {'pending': 'Ожидает', 'in_progress': 'В работе', 'completed': 'Готово', 'cancelled': 'Отменено'}.get(t.status, t.status) }}
</span>
</td>
<td>{{ t.due_date.strftime('%d.%m.%Y') if t.due_date else '—' }}</td>
<td style="text-align: right; padding-right: 16px;">
<div style="display: inline-flex; gap: 4px; align-items: center;">
{% if t.assigned_to == current_user.id or current_user.role == 'admin' %}
<a href="{{ url_for('admin.update_task_status', task_id=t.id, status='in_progress') }}" class="btn-apple-outline btn-apple-sm" title="В работе" style="color: #2563eb; border-color: #2563eb;">🔄</a>
<a href="{{ url_for('admin.update_task_status', task_id=t.id, status='completed') }}" class="btn-apple-outline btn-apple-sm" title="Готово" style="color: #16a34a; border-color: #16a34a;"></a>
{% endif %}
{% if t.assigned_by == current_user.id or current_user.role == 'admin' %}
<button type="button" class="btn-apple-outline btn-apple-sm rework-btn" title="На доработку" style="color: #d97706; border-color: #d97706;" data-task-id="{{ t.id }}" data-task-title="{{ t.title }}"></button>
<a href="{{ url_for('admin.edit_task', task_id=t.id) }}" class="btn-apple-outline btn-apple-sm" title="Редактировать"><i class="bi bi-pencil"></i></a>
{% endif %}
{% if current_user.role == 'admin' %}
<a href="{{ url_for('admin.delete_task', task_id=t.id) }}" class="btn-apple-outline btn-apple-sm" title="Удалить" style="color:#ef4444;border-color:#ef4444;" onclick="return confirm('Удалить задачу?')"><svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M2 4h12M5 4V2.5A1.5 1.5 0 016.5 1h3A1.5 1.5 0 0111 2.5V4M3 4v9.5A1.5 1.5 0 004.5 15h7a1.5 1.5 0 001.5-1.5V4"/></svg></a>
{% endif %}
<span style="font-size: 0.75rem; color: #999; max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="{{ t.description or '' }}">
{% if t.description %}<i class="bi bi-chat-dots" style="margin-left: 4px;"></i>{% endif %}
</span>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div style="text-align: center; padding: 40px 0;">
<i class="bi bi-clipboard-check" style="font-size:2.5rem;color:#A0A5B5;"></i>
<p style="color:#A0A5B5;margin-top:8px;">Нет задач</p>
</div>
{% endif %}
</div>
</div>
{% endmacro %}
{% if current_user.role == 'admin' %}
{{ task_table(tasks=assigned_tasks, show_assigner=False) }}
{% else %}
{% if assigned_tasks %}
<h3 style="font-size:14px;font-weight:600;margin-bottom:12px;color:#fff;">Мои задачи</h3>
{{ task_table(tasks=assigned_tasks, show_assigner=True) }}
{% endif %}
{% if created_tasks %}
<h3 style="font-size:14px;font-weight:600;margin:24px 0 12px;color:#fff;">Я назначил</h3>
{{ task_table(tasks=created_tasks, show_assigner=False) }}
{% endif %}
{% if not assigned_tasks and not created_tasks %}
<div class="d-card" style="border-radius:20px;background:rgba(6,11,40,0.6);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,0.05);">
<div class="d-card-body" style="text-align:center;padding:40px 0;">
<i class="bi bi-clipboard-check" style="font-size:2.5rem;color:#A0A5B5;"></i>
<p style="color:#A0A5B5;margin-top:8px;">Нет задач</p>
</div>
</div>
{% endif %}
{% endif %}
<div id="reworkModal" class="modal-overlay" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:1000;align-items:center;justify-content:center;">
<div style="max-width:450px;width:90%;border-radius:20px;background:rgba(6,11,40,0.95);backdrop-filter:blur(20px);border:1px solid rgba(255,255,255,0.1);overflow:hidden;">
<div style="display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border-bottom:1px solid rgba(255,255,255,0.05);">
<h5 style="margin:0;font-size:15px;font-weight:600;color:#fff;">Отправить на доработку</h5>
<button type="button" style="background:none;border:none;font-size:20px;color:#A0A5B5;cursor:pointer;" onclick="closeReworkModal()">&times;</button>
</div>
<form id="reworkForm" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div style="padding:16px;">
<p style="margin:0 0 8px;font-size:13px;color:#A0A5B5;" id="reworkTaskTitle"></p>
<textarea name="rework_comment" class="form-control form-control-sm" rows="3" placeholder="Что нужно исправить?" required style="background:rgba(6,11,40,0.6);border-color:rgba(255,255,255,0.1);color:#fff;border-radius:12px;"></textarea>
</div>
<div style="display:flex;gap:8px;justify-content:flex-end;padding:12px 16px;border-top:1px solid rgba(255,255,255,0.05);">
<button type="button" class="btn-apple-outline" onclick="closeReworkModal()" style="border-radius:12px;">Отмена</button>
<button type="submit" class="btn-apple" style="background:#d97706;border-radius:12px;">Отправить</button>
</div>
</form>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
document.querySelectorAll('.rework-btn').forEach(btn => {
btn.addEventListener('click', function() {
const taskId = this.dataset.taskId;
const taskTitle = this.dataset.taskTitle;
document.getElementById('reworkTaskTitle').textContent = taskTitle;
document.getElementById('reworkForm').action = '/admin/tasks/rework/' + taskId;
document.getElementById('reworkModal').style.display = 'flex';
});
});
function closeReworkModal() {
document.getElementById('reworkModal').style.display = 'none';
}
</script>
{% endblock %}