Show I1 inline panels below checklist task rows

This commit is contained in:
A R R R Associates
2026-08-08 13:04:25 +05:30
parent 6b3d9fc730
commit e071f7e79c
@@ -175,7 +175,7 @@
<details class="relative"> <details class="relative">
<summary class="list-none cursor-pointer rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-bold text-amber-700 hover:bg-amber-100">! Blocked</summary> <summary class="list-none cursor-pointer rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-bold text-amber-700 hover:bg-amber-100">! Blocked</summary>
<form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/quick-action" class="absolute right-0 z-20 mt-2 w-80 rounded-xl border border-amber-200 bg-white p-3 shadow-xl"> <form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/quick-action" class="absolute right-0 z-30 mt-2 w-80 rounded-xl border border-amber-200 bg-white p-3 shadow-xl">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="hidden" name="action" value="blocked"> <input type="hidden" name="action" value="blocked">
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Reason</label> <label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Reason</label>
@@ -189,7 +189,7 @@
<details class="relative"> <details class="relative">
<summary class="list-none cursor-pointer rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm font-bold text-red-700 hover:bg-red-100">✕ N/A</summary> <summary class="list-none cursor-pointer rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm font-bold text-red-700 hover:bg-red-100">✕ N/A</summary>
<form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/quick-action" class="absolute right-0 z-20 mt-2 w-80 rounded-xl border border-red-200 bg-white p-3 shadow-xl"> <form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/quick-action" class="absolute right-0 z-30 mt-2 w-80 rounded-xl border border-red-200 bg-white p-3 shadow-xl">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="hidden" name="action" value="na"> <input type="hidden" name="action" value="na">
<label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Short reason</label> <label class="mb-1 block text-xs font-semibold uppercase tracking-wide text-slate-500">Short reason</label>
@@ -202,9 +202,31 @@
<span class="rounded-xl bg-slate-100 px-3 py-2 text-sm font-semibold text-slate-500">🔒 Locked</span> <span class="rounded-xl bg-slate-100 px-3 py-2 text-sm font-semibold text-slate-500">🔒 Locked</span>
{% endif %} {% endif %}
<details class="group w-full lg:w-auto"> <button type="button"
<summary class="list-none cursor-pointer rounded-xl border border-violet-200 bg-violet-50 px-3 py-2 text-center text-sm font-semibold text-violet-700 hover:bg-violet-100">Documents{% if task.i1_documents %} · {{ task.i1_documents|length }}{% endif %}</summary> data-i1-panel-trigger="documents"
<div class="mt-3 rounded-2xl border border-violet-200 bg-white p-4 lg:min-w-[620px]"> data-i1-task-id="{{ task.id }}"
class="rounded-xl border border-violet-200 bg-violet-50 px-3 py-2 text-sm font-semibold text-violet-700 hover:bg-violet-100">
Documents{% if task.i1_documents %} · {{ task.i1_documents|length }}{% endif %}
</button>
<button type="button"
data-i1-panel-trigger="messages"
data-i1-task-id="{{ task.id }}"
class="rounded-xl border border-sky-200 bg-sky-50 px-3 py-2 text-sm font-semibold text-sky-700 hover:bg-sky-100">
Message / Clarification{% if task.i1_communications %} · {{ task.i1_communications|length }}{% endif %}
</button>
<button type="button"
data-i1-panel-trigger="details"
data-i1-task-id="{{ task.id }}"
class="rounded-xl border border-slate-300 bg-white px-3 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50">
Details
</button>
</div>
</div>
<div class="mt-3 space-y-3" data-i1-panels-for-task="{{ task.id }}">
<div data-i1-panel="documents" class="hidden w-full rounded-2xl border border-violet-200 bg-violet-50/40 p-4">
<div class="flex flex-wrap items-start justify-between gap-3"> <div class="flex flex-wrap items-start justify-between gap-3">
<div> <div>
<h5 class="font-semibold text-slate-900">Task Documents</h5> <h5 class="font-semibold text-slate-900">Task Documents</h5>
@@ -214,7 +236,7 @@
</div> </div>
{% if task.i1_documents %} {% if task.i1_documents %}
<div class="mt-3 divide-y divide-slate-100 rounded-xl border border-slate-200"> <div class="mt-3 divide-y divide-slate-100 rounded-xl border border-slate-200 bg-white">
{% for doc in task.i1_documents[:5] %} {% for doc in task.i1_documents[:5] %}
{% set latest = doc.versions[0] if doc.versions else none %} {% set latest = doc.versions[0] if doc.versions else none %}
<div class="flex flex-wrap items-center justify-between gap-2 px-3 py-2 text-sm"> <div class="flex flex-wrap items-center justify-between gap-2 px-3 py-2 text-sm">
@@ -227,7 +249,7 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="mt-3 rounded-xl border border-dashed border-slate-300 px-4 py-3 text-sm text-slate-500">No document attached yet.</div> <div class="mt-3 rounded-xl border border-dashed border-slate-300 bg-white px-4 py-3 text-sm text-slate-500">No document attached yet.</div>
{% endif %} {% endif %}
<form method="post" action="/documents/tasks/{{ task.id }}/upload" enctype="multipart/form-data" class="mt-3 flex flex-col gap-2 sm:flex-row sm:items-end"> <form method="post" action="/documents/tasks/{{ task.id }}/upload" enctype="multipart/form-data" class="mt-3 flex flex-col gap-2 sm:flex-row sm:items-end">
@@ -241,11 +263,8 @@
<button type="submit" class="rounded-lg bg-violet-600 px-4 py-2 text-sm font-semibold text-white hover:bg-violet-700">Upload</button> <button type="submit" class="rounded-lg bg-violet-600 px-4 py-2 text-sm font-semibold text-white hover:bg-violet-700">Upload</button>
</form> </form>
</div> </div>
</details>
<details class="group w-full lg:w-auto"> <div data-i1-panel="messages" class="hidden w-full rounded-2xl border border-sky-200 bg-sky-50/40 p-4">
<summary class="list-none cursor-pointer rounded-xl border border-sky-200 bg-sky-50 px-3 py-2 text-center text-sm font-semibold text-sky-700 hover:bg-sky-100">Message / Clarification{% if task.i1_communications %} · {{ task.i1_communications|length }}{% endif %}</summary>
<div class="mt-3 rounded-2xl border border-sky-200 bg-white p-4 lg:min-w-[620px]">
<div class="flex flex-wrap items-start justify-between gap-3"> <div class="flex flex-wrap items-start justify-between gap-3">
<div> <div>
<h5 class="font-semibold text-slate-900">Messages / Clarifications</h5> <h5 class="font-semibold text-slate-900">Messages / Clarifications</h5>
@@ -255,7 +274,7 @@
</div> </div>
{% if task.i1_communications %} {% if task.i1_communications %}
<div class="mt-3 max-h-52 divide-y divide-slate-100 overflow-y-auto rounded-xl border border-slate-200"> <div class="mt-3 max-h-52 divide-y divide-slate-100 overflow-y-auto rounded-xl border border-slate-200 bg-white">
{% for item in task.i1_communications[:5] %} {% for item in task.i1_communications[:5] %}
<div class="px-3 py-2"> <div class="px-3 py-2">
<div class="flex flex-wrap items-center justify-between gap-2 text-[11px] text-slate-500"> <div class="flex flex-wrap items-center justify-between gap-2 text-[11px] text-slate-500">
@@ -268,27 +287,26 @@
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="mt-3 rounded-xl border border-dashed border-slate-300 px-4 py-3 text-sm text-slate-500">No message or clarification yet.</div> <div class="mt-3 rounded-xl border border-dashed border-slate-300 bg-white px-4 py-3 text-sm text-slate-500">No message or clarification yet.</div>
{% endif %} {% endif %}
<form method="post" action="/employee/work/tasks/{{ task.id }}/communication" class="mt-3 grid gap-2 sm:grid-cols-2"> <form method="post" action="/employee/work/tasks/{{ task.id }}/communication" class="mt-3 grid gap-2 sm:grid-cols-2">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="hidden" name="return_to" value="/employee/work/engagements/{{ board.engagement_id }}?task_id={{ task.id }}#task-{{ task.id }}"> <input type="hidden" name="return_to" value="/employee/work/engagements/{{ board.engagement_id }}?task_id={{ task.id }}#task-{{ task.id }}">
<select name="comment_type" class="rounded-lg border border-slate-300 px-3 py-2 text-sm"> <select name="comment_type" class="rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm">
{% for code, label in board.communication_types %}<option value="{{ code }}">{{ label }}</option>{% endfor %} {% for code, label in board.communication_types %}<option value="{{ code }}">{{ label }}</option>{% endfor %}
</select> </select>
<select name="visibility" class="rounded-lg border border-slate-300 px-3 py-2 text-sm"> <select name="visibility" class="rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm">
{% for code, label in board.communication_visibilities %}<option value="{{ code }}">{{ label }}</option>{% endfor %} {% for code, label in board.communication_visibilities %}<option value="{{ code }}">{{ label }}</option>{% endfor %}
</select> </select>
<textarea name="message" rows="2" required class="sm:col-span-2 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm" placeholder="Type message or clarification"></textarea> <textarea name="message" rows="2" required class="sm:col-span-2 w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm" placeholder="Type message or clarification"></textarea>
<div class="sm:col-span-2 flex justify-end"><button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-semibold text-white hover:bg-sky-700">Send</button></div> <div class="sm:col-span-2 flex justify-end">
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-semibold text-white hover:bg-sky-700">Send</button>
</div>
</form> </form>
</div> </div>
</details>
<details class="group w-full lg:w-auto"> <div data-i1-panel="details" class="hidden w-full rounded-2xl border border-slate-200 bg-slate-50 p-4">
<summary class="list-none cursor-pointer rounded-xl border border-slate-300 bg-white px-3 py-2 text-center text-sm font-semibold text-slate-700 hover:bg-slate-50">Details</summary>
<div class="mt-3 rounded-2xl border border-slate-200 bg-slate-50 p-4 lg:min-w-[720px]">
<form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/save" class="space-y-4"> <form method="post" action="/employee/work/engagements/{{ board.engagement_id }}/tasks/{{ task.id }}/save" class="space-y-4">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input type="hidden" name="status" value="{{ task.status or 'pending' }}"> <input type="hidden" name="status" value="{{ task.status or 'pending' }}">
@@ -326,13 +344,12 @@
<input type="text" name="remarks" value="{{ task.remarks or '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm" placeholder="Optional"> <input type="text" name="remarks" value="{{ task.remarks or '' }}" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm" placeholder="Optional">
</div> </div>
<div class="flex flex-wrap items-center justify-between gap-2"> <div class="flex justify-end">
<div class="text-xs text-slate-500">Documents and messages can be added directly from this checklist row.</div>
<button type="submit" class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Save Details</button> <button type="submit" class="rounded-lg bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Save Details</button>
</div> </div>
</form> </form>
</div> </div>
</details> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -367,4 +384,30 @@
</dl> </dl>
</section> </section>
</div> </div>
<script>
document.addEventListener("click", function (event) {
const trigger = event.target.closest("[data-i1-panel-trigger]");
if (!trigger) return;
const taskId = trigger.getAttribute("data-i1-task-id");
const panelName = trigger.getAttribute("data-i1-panel-trigger");
const container = document.querySelector('[data-i1-panels-for-task="' + taskId + '"]');
if (!container) return;
const requested = container.querySelector('[data-i1-panel="' + panelName + '"]');
if (!requested) return;
const wasOpen = !requested.classList.contains("hidden");
container.querySelectorAll("[data-i1-panel]").forEach(function (panel) {
panel.classList.add("hidden");
});
if (!wasOpen) {
requested.classList.remove("hidden");
requested.scrollIntoView({ behavior: "smooth", block: "nearest" });
}
});
</script>
{% endblock %} {% endblock %}