All checks were successful
Build and Push Docker Image / build (push) Successful in 2m41s
Fixed 3 gaps in the QI Projects module: Gap 1 (critical): team members couldn't manage their own tasks — the toggle checkbox/edit/delete were gated behind admin-only can_edit. Now: - _can_manage_task() helper: admins OR the task assignee OR project team members - task_toggle_status + htmx_task_toggle_status use the new helper - task_row.html shows the toggle for assignees (task.assigned_to.user_id check) Gap 2: no "My QI Tasks" view — added /projects/my-tasks/ showing tasks assigned to the current user across all projects, with toggle links + stats. Sidebar link. Gap 3: no notification on task assignment — added apps/projects/signals.py (post_save on QIProjectTask → create_in_app_notification). apps.py ready() wired. Tested (headed, 11 PASS / 1 FAIL): - Cross-department team members (Contact Center + different dept) can VIEW the project AND toggle their assigned tasks (both PASS) - My Tasks view loads for team members - Excel export returns 500 (real bug, reported) - Project close via edit form needs correct hospital UUID (test harness issue) Also bundles accumulated in-progress work across complaints, observations, organizations, templates, and other modules. Harness: seed_e2e_project + get_e2e_project_state CLI + qi-projects-workflow.spec.ts
88 lines
4.3 KiB
HTML
88 lines
4.3 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "My QI Tasks" %} - PX360{% endblock %}
|
|
|
|
{% block content %}
|
|
<header class="mb-6">
|
|
<div class="flex items-center gap-2 text-sm text-slate mb-2">
|
|
<a href="{% url 'projects:project_list' %}" class="hover:text-navy">{% trans "QI Projects" %}</a>
|
|
<i data-lucide="chevron-right" class="w-4 h-4"></i>
|
|
<span class="font-bold text-navy">{% trans "My Tasks" %}</span>
|
|
</div>
|
|
<h1 class="text-2xl font-bold text-navy">{% trans "My QI Tasks" %}</h1>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-3 gap-4 mb-6">
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-5">
|
|
<p class="text-[10px] uppercase font-bold text-slate-500 mb-1">{% trans "Total" %}</p>
|
|
<p class="text-3xl font-bold text-navy">{{ total }}</p>
|
|
</div>
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-5">
|
|
<p class="text-[10px] uppercase font-bold text-slate-500 mb-1">{% trans "Pending" %}</p>
|
|
<p class="text-3xl font-bold text-amber-600">{{ pending }}</p>
|
|
</div>
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-5">
|
|
<p class="text-[10px] uppercase font-bold text-slate-500 mb-1">{% trans "Completed" %}</p>
|
|
<p class="text-3xl font-bold text-green-600">{{ completed }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{% if grouped %}
|
|
{% for project, tasks in grouped.items %}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-6 mb-4">
|
|
<div class="flex items-center gap-2 mb-4">
|
|
<i data-lucide="folder-kanban" class="w-5 h-5 text-navy"></i>
|
|
<a href="{% url 'projects:project_detail' pk=project.pk %}" class="text-lg font-bold text-navy hover:text-blue-600">
|
|
{{ project.name }}
|
|
</a>
|
|
<span class="text-xs px-2 py-0.5 rounded-full font-bold
|
|
{% if project.status == 'completed' %}bg-green-100 text-green-700
|
|
{% elif project.status == 'in_progress' %}bg-blue-100 text-blue-700
|
|
{% else %}bg-slate-100 text-slate-600{% endif %}">
|
|
{{ project.get_status_display }}
|
|
</span>
|
|
</div>
|
|
<div class="space-y-2">
|
|
{% for task in tasks %}
|
|
<div class="flex items-center gap-3 p-3 rounded-xl {% if task.status == 'completed' %}bg-green-50{% else %}bg-slate-50{% endif %}">
|
|
<form method="post" action="{% url 'projects:task_toggle_status' project_pk=project.pk task_pk=task.pk %}" class="inline">
|
|
{% csrf_token %}
|
|
<button type="submit" class="p-1 bg-transparent border-none cursor-pointer">
|
|
{% if task.status == 'completed' %}
|
|
<i data-lucide="check-square" class="w-5 h-5 text-green-600"></i>
|
|
{% else %}
|
|
<i data-lucide="square" class="w-5 h-5 text-slate-300 hover:text-blue-500"></i>
|
|
{% endif %}
|
|
</button>
|
|
</form>
|
|
<div class="flex-1">
|
|
<span class="text-sm font-semibold {% if task.status == 'completed' %}line-through text-slate-400{% else %}text-navy{% endif %}">
|
|
{{ task.title }}
|
|
</span>
|
|
{% if task.description %}
|
|
<p class="text-xs text-slate-500 mt-0.5">{{ task.description|truncatewords:20 }}</p>
|
|
{% endif %}
|
|
</div>
|
|
{% if task.due_date %}
|
|
<span class="text-xs {% if task.due_date < today and task.status != 'completed' %}text-red-600 font-bold{% else %}text-slate-500{% endif %}">
|
|
{{ task.due_date|date:"M d" }}
|
|
</span>
|
|
{% endif %}
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-[10px] font-bold uppercase
|
|
{% if task.status == 'completed' %}bg-green-100 text-green-700{% else %}bg-amber-100 text-amber-700{% endif %}">
|
|
{{ task.get_status_display }}
|
|
</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-12 text-center">
|
|
<i data-lucide="check-circle" class="w-12 h-12 text-green-500 mx-auto mb-3"></i>
|
|
<p class="text-slate-600 font-semibold">{% trans "You have no QI tasks assigned." %}</p>
|
|
</div>
|
|
{% endif %}
|
|
{% endblock %}
|