Split partner review board panels and add back button

This commit is contained in:
A R R R Associates
2026-08-14 14:56:53 +05:30
parent 74586d60ed
commit 9b3ea9a1c7
2 changed files with 184 additions and 110 deletions
@@ -19,6 +19,7 @@
</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="/partner/reviews" class="rounded-2xl border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50">← Back to Review Board</a>
<a href="{{ workspace.documents_href }}" class="rounded-2xl bg-emerald-600 px-4 py-2 text-sm font-semibold text-white">Final Documents / UDIN</a>
<a href="/partner/dashboard?tab=review" class="rounded-2xl border border-slate-300 px-4 py-2 text-sm font-semibold text-slate-700">Close Workspace</a>
</div>
@@ -2,86 +2,7 @@
{% block content %}
{% include "modules/partners/templates/partners/_partner_tabs.html" %}
<div class="space-y-6">
<div class="flex flex-col gap-3 rounded-3xl border border-slate-200 bg-white p-5 shadow-soft lg:flex-row lg:items-center lg:justify-between">
<div>
<h2 class="text-xl font-semibold">Partner Review Board</h2>
<p class="text-sm text-slate-500">Engagement-level review queue. Task-level review, rework and history remain available inside each engagement.</p>
</div>
<form method="get" class="flex gap-2">
<input name="q" value="{{ q or '' }}" placeholder="Search client, task or service" class="w-72 rounded-xl border border-slate-300 px-3 py-2 text-sm">
<button class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Search</button>
</form>
</div>
{# Build engagement-level counts without changing the existing backend payload. #}
{% set metrics = namespace(pending_review=[], clarification_required=[], rework_sent=[], approved=[], completed=[]) %}
{% for column in payload.columns %}
{% for task in column.tasks %}
{% if task.subscription_id %}
{% if column.code == 'pending_review' and task.subscription_id not in metrics.pending_review %}
{% set _ = metrics.pending_review.append(task.subscription_id) %}
{% elif column.code == 'clarification_required' and task.subscription_id not in metrics.clarification_required %}
{% set _ = metrics.clarification_required.append(task.subscription_id) %}
{% elif column.code == 'rework_sent' and task.subscription_id not in metrics.rework_sent %}
{% set _ = metrics.rework_sent.append(task.subscription_id) %}
{% elif column.code == 'approved' and task.subscription_id not in metrics.approved %}
{% set _ = metrics.approved.append(task.subscription_id) %}
{% elif column.code == 'completed' and task.subscription_id not in metrics.completed %}
{% set _ = metrics.completed.append(task.subscription_id) %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Pending Review</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.pending_review|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements with completed work awaiting review</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Clarification Required</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.clarification_required|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements with blocked tasks</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Rework Sent</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.rework_sent|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements containing rework items</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">In Progress</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.approved|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements currently moving with the team</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Completed</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.completed|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements containing closed tasks</div>
</div>
</div>
<section class="overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-soft">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200">
<thead class="bg-slate-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Client / Engagement</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Status</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Task Progress</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Review Items</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Assigned Team</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Priority / Target</th>
<th class="px-4 py-3 text-right text-xs font-semibold uppercase tracking-wide text-slate-500">Action</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% set board = namespace(seen=[]) %}
{% for column in payload.columns %}
{% for task in column.tasks %}
{% if task.subscription_id and task.subscription_id not in board.seen %}
{% set _ = board.seen.append(task.subscription_id) %}
{% macro engagement_row(task, column, payload) %}
{% set stats = namespace(total=0, completed=0, blocked=0, review=0, rework=0, overdue=false, assignees=[]) %}
{% for stat_column in payload.columns %}
{% for item in stat_column.tasks %}
@@ -160,19 +81,171 @@
<a href="/partner/reviews/engagements/{{ task.subscription_id }}" class="inline-flex rounded-xl border border-slate-300 px-3 py-2 text-xs font-semibold text-slate-700 hover:bg-slate-50">Open Review</a>
</td>
</tr>
{% endmacro %}
{% macro panel(title, subtitle, ids, payload, tone) %}
<section class="overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-soft">
<div class="flex flex-col gap-2 border-b border-slate-200 px-5 py-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<h3 class="text-base font-semibold text-slate-900">{{ title }}</h3>
<p class="mt-1 text-xs text-slate-500">{{ subtitle }}</p>
</div>
{% if tone == 'review' %}
<span class="w-fit rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold text-amber-700">{{ ids|length }} engagement{{ '' if ids|length == 1 else 's' }}</span>
{% elif tone == 'progress' %}
<span class="w-fit rounded-full bg-blue-100 px-3 py-1 text-xs font-semibold text-blue-700">{{ ids|length }} engagement{{ '' if ids|length == 1 else 's' }}</span>
{% else %}
<span class="w-fit rounded-full bg-emerald-100 px-3 py-1 text-xs font-semibold text-emerald-700">{{ ids|length }} engagement{{ '' if ids|length == 1 else 's' }}</span>
{% endif %}
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200">
<thead class="bg-slate-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Client / Engagement</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Status</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Task Progress</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Review Items</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Assigned Team</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">Priority / Target</th>
<th class="px-4 py-3 text-right text-xs font-semibold uppercase tracking-wide text-slate-500">Action</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100">
{% set rendered = namespace(seen=[]) %}
{% for column in payload.columns %}
{% for task in column.tasks %}
{% if task.subscription_id and task.subscription_id in ids and task.subscription_id not in rendered.seen %}
{% set _ = rendered.seen.append(task.subscription_id) %}
{{ engagement_row(task, column, payload) }}
{% endif %}
{% endfor %}
{% endfor %}
{% if board.seen|length == 0 %}
{% if rendered.seen|length == 0 %}
<tr>
<td colspan="7" class="px-6 py-12 text-center text-sm text-slate-500">No engagement review items found.</td>
<td colspan="7" class="px-6 py-10 text-center text-sm text-slate-500">No engagements in this section.</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</section>
</section>
{% endmacro %}
<div class="space-y-6">
<div class="flex flex-col gap-3 rounded-3xl border border-slate-200 bg-white p-5 shadow-soft lg:flex-row lg:items-center lg:justify-between">
<div>
<h2 class="text-xl font-semibold">Partner Review Board</h2>
<p class="text-sm text-slate-500">Engagement-level review queue. Task-level review, rework and history remain available inside each engagement.</p>
</div>
<form method="get" class="flex gap-2">
<input name="q" value="{{ q or '' }}" placeholder="Search client, task or service" class="w-72 rounded-xl border border-slate-300 px-3 py-2 text-sm">
<button class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white">Search</button>
</form>
</div>
{% set metrics = namespace(pending_review=[], clarification_required=[], rework_sent=[], approved=[], completed=[]) %}
{% for column in payload.columns %}
{% for task in column.tasks %}
{% if task.subscription_id %}
{% if column.code == 'pending_review' and task.subscription_id not in metrics.pending_review %}
{% set _ = metrics.pending_review.append(task.subscription_id) %}
{% elif column.code == 'clarification_required' and task.subscription_id not in metrics.clarification_required %}
{% set _ = metrics.clarification_required.append(task.subscription_id) %}
{% elif column.code == 'rework_sent' and task.subscription_id not in metrics.rework_sent %}
{% set _ = metrics.rework_sent.append(task.subscription_id) %}
{% elif column.code == 'approved' and task.subscription_id not in metrics.approved %}
{% set _ = metrics.approved.append(task.subscription_id) %}
{% elif column.code == 'completed' and task.subscription_id not in metrics.completed %}
{% set _ = metrics.completed.append(task.subscription_id) %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Pending Review</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.pending_review|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements with completed work awaiting review</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Clarification Required</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.clarification_required|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements with blocked tasks</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Rework Sent</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.rework_sent|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements containing rework items</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">In Progress</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.approved|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements currently moving with the team</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="text-xs font-semibold uppercase tracking-wide text-slate-500">Completed</div>
<div class="mt-1 text-2xl font-semibold text-slate-900">{{ metrics.completed|length }}</div>
<div class="mt-1 text-xs text-slate-500">Engagements containing closed tasks</div>
</div>
</div>
{# Each engagement appears in exactly one panel: review first, then in progress, then completed. #}
{% set groups = namespace(review=[], progress=[], completed=[]) %}
{% for column in payload.columns %}
{% if column.code in ['pending_review', 'clarification_required', 'rework_sent'] %}
{% for task in column.tasks %}
{% if task.subscription_id and task.subscription_id not in groups.review %}
{% set _ = groups.review.append(task.subscription_id) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% for column in payload.columns %}
{% if column.code == 'approved' %}
{% for task in column.tasks %}
{% if task.subscription_id and task.subscription_id not in groups.review and task.subscription_id not in groups.progress %}
{% set _ = groups.progress.append(task.subscription_id) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% for column in payload.columns %}
{% if column.code == 'completed' %}
{% for task in column.tasks %}
{% if task.subscription_id and task.subscription_id not in groups.review and task.subscription_id not in groups.progress and task.subscription_id not in groups.completed %}
{% set _ = groups.completed.append(task.subscription_id) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{{ panel(
'Review Required',
'Pending review, clarification-required and rework engagements are shown first.',
groups.review,
payload,
'review'
) }}
{{ panel(
'In Progress',
'Engagements currently moving with the team and not presently waiting in the review queue.',
groups.progress,
payload,
'progress'
) }}
{{ panel(
'Completed',
'Completed engagement rows remain available separately for review history and reference.',
groups.completed,
payload,
'completed'
) }}
<div class="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-3 text-xs text-slate-500">
Review remains task-level inside the engagement. This board only groups the existing task records into one engagement row for easier partner navigation.