feat(observation): surface Action/RCA/QI decision tree and Inform Reporter step

After the department responds, PX decides what to do next. The post-response
banner now presents the choice inline instead of only in the actions toolbar:
- Create Action (minor / isolated) — or 'Action exists' badge if already converted
- Start RCA (serious / pattern)
- QI Project (systemic trend) — admins only
- Resolve (no action needed)

Non-admin viewers still see the simple Resolve form.

The resolved-state banner now shows whether the reporter has been informed
(response_sent_at) and surfaces an 'Inform Reporter' button that opens the
existing observation_respond modal — closing the loop with the patient who
reported the observation. Both changes use existing endpoints; this is pure
UI surfacing at the moment of decision.
This commit is contained in:
ismail 2026-07-20 22:06:29 +03:00
parent 185cc67c10
commit 93f4fc6342

View File

@ -124,22 +124,89 @@
{% endif %}
</div>
{% elif observation.department_responded_at and observation.status not in 'resolved,closed' %}
<div class="bg-green-50 rounded-2xl border border-green-200 p-4 mb-6 flex items-center justify-between gap-4">
<div class="flex items-center gap-3">
<div class="bg-green-50 rounded-2xl border border-green-200 p-4 mb-6">
<div class="flex items-center gap-3 mb-3">
<div class="w-9 h-9 rounded-full bg-green-100 flex items-center justify-center shrink-0"><i data-lucide="check-circle-2" class="w-4 h-4 text-green-600"></i></div>
<div><p class="text-sm font-bold text-navy">{% trans "Department has responded" %}</p><p class="text-xs text-slate">{% trans "Review the response and resolve this observation." %}</p></div>
<div class="flex-1">
<p class="text-sm font-bold text-navy">{% trans "Department has responded" %}</p>
<p class="text-xs text-slate">{% trans "Decide what to do next, then resolve and inform the reporter." %}</p>
</div>
</div>
{% if can_convert %}
<form method="post" action="{% url 'observations:observation_change_status' observation.id %}" class="inline shrink-0" onsubmit="return confirm('{% trans "Mark this observation as resolved?" %}')">
<div class="grid grid-cols-2 md:grid-cols-4 gap-2">
{% if not observation.action_id %}
<a href="{% url 'observations:observation_convert_to_action' observation.id %}"
class="p-3 border-green-200 bg-white rounded-xl hover:bg-green-100 flex flex-col items-center gap-1 group transition text-center">
<i data-lucide="arrow-right-circle" class="w-5 h-5 text-green-600"></i>
<span class="text-[10px] font-bold text-green-700 uppercase leading-tight">{% trans "Create Action" %}</span>
<span class="text-[9px] text-slate">{% trans "Minor / isolated" %}</span>
</a>
{% else %}
<div class="p-3 border-green-200 bg-green-100 rounded-xl flex flex-col items-center gap-1 text-center">
<i data-lucide="check" class="w-5 h-5 text-green-600"></i>
<span class="text-[10px] font-bold text-green-700 uppercase leading-tight">{% trans "Action exists" %}</span>
</div>
{% endif %}
<a href="{% url 'rca:rca_create' %}?related_model=observation&related_id={{ observation.pk }}"
class="p-3 border-purple-200 bg-white rounded-xl hover:bg-purple-50 flex flex-col items-center gap-1 group transition text-center">
<i data-lucide="search" class="w-5 h-5 text-purple-600"></i>
<span class="text-[10px] font-bold text-purple-700 uppercase leading-tight">{% trans "Start RCA" %}</span>
<span class="text-[9px] text-slate">{% trans "Serious / pattern" %}</span>
</a>
{% if can_admin %}
<a href="{% url 'projects:project_create' %}?related_model=observation&related_id={{ observation.pk }}"
class="p-3 border-teal-200 bg-white rounded-xl hover:bg-teal-50 flex flex-col items-center gap-1 group transition text-center">
<i data-lucide="folder-plus" class="w-5 h-5 text-teal-600"></i>
<span class="text-[10px] font-bold text-teal-700 uppercase leading-tight">{% trans "QI Project" %}</span>
<span class="text-[9px] text-slate">{% trans "Systemic trend" %}</span>
</a>
{% endif %}
<form method="post" action="{% url 'observations:observation_change_status' observation.id %}"
class="contents" onsubmit="return confirm('{% trans "Mark this observation as resolved?" %}')">
{% csrf_token %}
<input type="hidden" name="status" value="resolved">
<button type="submit"
class="p-3 border-navy bg-navy text-white rounded-xl hover:bg-blue flex flex-col items-center gap-1 transition text-center">
<i data-lucide="check-circle" class="w-5 h-5"></i>
<span class="text-[10px] font-bold uppercase leading-tight">{% trans "Resolve" %}</span>
<span class="text-[9px] text-blue-200">{% trans "No action needed" %}</span>
</button>
</form>
</div>
{% else %}
{# Non-admin viewers see only the simple resolve form #}
<form method="post" action="{% url 'observations:observation_change_status' observation.id %}"
class="inline" onsubmit="return confirm('{% trans "Mark this observation as resolved?" %}')">
{% csrf_token %}<input type="hidden" name="status" value="resolved">
<button type="submit" class="px-4 py-2 bg-green-600 text-white rounded-lg font-bold text-sm hover:bg-green-700 transition whitespace-nowrap">{% trans "Resolve" %}</button>
<button type="submit" class="px-4 py-2 bg-green-600 text-white rounded-lg font-bold text-sm hover:bg-green-700 transition whitespace-nowrap">
{% trans "Resolve" %}
</button>
</form>
{% endif %}
</div>
{% elif observation.status in 'resolved,closed' %}
<div class="bg-slate-50 rounded-2xl border border-slate-200 p-4 mb-6 flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-slate-200 flex items-center justify-center shrink-0"><i data-lucide="check-circle-2" class="w-4 h-4 text-slate-600"></i></div>
<div><p class="text-sm font-bold text-navy">{% trans "This observation is resolved" %}</p></div>
<div class="bg-slate-50 rounded-2xl border border-slate-200 p-4 mb-6 flex items-center justify-between gap-4">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-slate-200 flex items-center justify-center shrink-0"><i data-lucide="check-circle-2" class="w-4 h-4 text-slate-600"></i></div>
<div>
<p class="text-sm font-bold text-navy">{% trans "This observation is resolved" %}</p>
{% if observation.response_sent_at %}
<p class="text-xs text-slate">{% trans "Reporter informed on" %} {{ observation.response_sent_at|date:"M d, Y H:i" }}</p>
{% else %}
<p class="text-xs text-slate">{% trans "Reporter has not yet been informed." %}</p>
{% endif %}
</div>
</div>
{% if can_convert and not observation.response_sent_at and observation.status == 'resolved' %}
<button type="button" onclick="document.getElementById('respondModal').style.display='flex'"
class="px-4 py-2 bg-navy text-white rounded-lg font-bold text-sm hover:bg-blue transition whitespace-nowrap inline-flex items-center gap-2">
<i data-lucide="mail" class="w-4 h-4"></i>
{% trans "Inform Reporter" %}
</button>
{% endif %}
</div>
{% endif %}