Add task tool result bridge and evidence attachment workflow
This commit is contained in:
@@ -88,8 +88,16 @@
|
||||
</div>
|
||||
{% if task_tool and task_tool.code != 'NONE' %}
|
||||
<div class="md:col-span-2 rounded-2xl border border-violet-200 bg-violet-50 p-4">
|
||||
<div class="flex flex-wrap items-center justify-between gap-3"><div><div class="text-sm font-semibold text-violet-950">ERP Task Tool · {{ task_tool.name }}</div><p class="mt-1 text-xs text-violet-800">{{ task_tool.description }}</p></div>{% if task_tool.launch_url %}<a href="{{ task_tool.launch_url }}{% if task.client_id %}?client_id={{ task.client_id }}{% endif %}" class="rounded-xl bg-violet-700 px-4 py-2 text-sm font-semibold text-white hover:bg-violet-800">Open Tool</a>{% endif %}</div>
|
||||
<p class="mt-2 text-xs text-violet-700">Opening the tool does not automatically mark this task complete. Save the task response/evidence after completing the verification.</p>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-sm font-semibold text-violet-950">ERP Task Tool · {{ task_tool.name }}</div>
|
||||
<p class="mt-1 text-xs text-violet-800">{{ task_tool.description }}</p>
|
||||
</div>
|
||||
{% if task_tool.launch_url %}
|
||||
<button type="submit" formaction="/services/work-tracker/tasks/{{ task.id }}/tool/start" formmethod="post" class="rounded-xl bg-violet-700 px-4 py-2 text-sm font-semibold text-white hover:bg-violet-800">Run Tool</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-violet-700">A Tool Run is created before launch. The linked tool receives the task, client, run and return/result URLs so its generated output can be returned to this task without changing the normal checklist workflow.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if (task.response_type or 'NONE') != 'NONE' or task.response_required or task.evidence_required %}
|
||||
@@ -156,6 +164,72 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if task_tool and task_tool.code != 'NONE' %}
|
||||
<div class="mx-auto mt-6 max-w-3xl rounded-2xl bg-white p-6 shadow-soft">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-slate-900">Tool Output & Evidence</h3>
|
||||
<p class="mt-1 text-sm text-slate-500">Every run is retained against this task. Output returned by the tool is stored with the run and can be downloaded from this task later.</p>
|
||||
</div>
|
||||
<span class="rounded-full bg-violet-100 px-3 py-1 text-xs font-medium text-violet-800">{{ tool_runs|length }} run{% if tool_runs|length != 1 %}s{% endif %}</span>
|
||||
</div>
|
||||
|
||||
{% if request.query_params.get('tool_saved') %}<div class="mt-4 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">Tool result attached to this task.</div>{% endif %}
|
||||
{% if request.query_params.get('tool_error') %}<div class="mt-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800">The tool result could not be saved. Check the selected run and output size.</div>{% endif %}
|
||||
|
||||
<div class="mt-5 space-y-4">
|
||||
{% if tool_runs %}
|
||||
{% for run in tool_runs %}
|
||||
<div class="rounded-2xl border border-slate-200 p-4">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-sm font-semibold text-slate-900">{{ task_tool.name }} · Run #{{ run.id }}</div>
|
||||
<div class="mt-1 text-xs text-slate-500">Started {{ run.started_at_utc }}{% if run.completed_at_utc %} · Completed {{ run.completed_at_utc }}{% endif %}</div>
|
||||
</div>
|
||||
<span class="rounded-full px-3 py-1 text-xs font-medium {% if run.status == 'completed' %}bg-emerald-100 text-emerald-800{% elif run.status == 'completed_with_exceptions' %}bg-amber-100 text-amber-800{% elif run.status == 'failed' %}bg-red-100 text-red-800{% else %}bg-slate-100 text-slate-700{% endif %}">{{ run.status.replace('_',' ').title() }}</span>
|
||||
</div>
|
||||
{% if run.summary %}<p class="mt-3 whitespace-pre-wrap text-sm text-slate-700">{{ run.summary }}</p>{% endif %}
|
||||
<div class="mt-3 flex flex-wrap gap-2 text-xs">
|
||||
{% if run.clean_pass is not none %}<span class="rounded-full bg-slate-100 px-2 py-1 text-slate-700">Clean Pass: {{ 'Yes' if run.clean_pass else 'No' }}</span>{% endif %}
|
||||
{% if run.exception_count is not none %}<span class="rounded-full bg-slate-100 px-2 py-1 text-slate-700">Exceptions: {{ run.exception_count }}</span>{% endif %}
|
||||
{% if run.output_filename %}<a href="/services/work-tracker/tool-runs/{{ run.id }}/output" class="rounded-full bg-indigo-100 px-2 py-1 font-medium text-indigo-800">Download {{ run.output_filename }}</a>{% endif %}
|
||||
</div>
|
||||
|
||||
{% if run.status == 'started' %}
|
||||
<form method="post" enctype="multipart/form-data" action="/services/work-tracker/tool-runs/{{ run.id }}/result" class="mt-4 grid gap-3 rounded-xl bg-slate-50 p-4 md:grid-cols-2">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
<div>
|
||||
<label class="mb-1 block text-xs font-medium text-slate-700">Result Status</label>
|
||||
<select name="status" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="completed">Completed</option><option value="completed_with_exceptions">Completed with Exceptions</option><option value="failed">Failed</option><option value="cancelled">Cancelled</option></select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-xs font-medium text-slate-700">Output File</label>
|
||||
<input type="file" name="output_file" class="w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm">
|
||||
</div>
|
||||
<div class="md:col-span-2">
|
||||
<label class="mb-1 block text-xs font-medium text-slate-700">Result Summary</label>
|
||||
<textarea name="summary" rows="2" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm" placeholder="Tool result / exceptions summary"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-xs font-medium text-slate-700">Clean Pass</label>
|
||||
<select name="clean_pass" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm"><option value="">Not stated</option><option value="true">Yes</option><option value="false">No</option></select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-1 block text-xs font-medium text-slate-700">Exception Count</label>
|
||||
<input type="number" min="0" name="exception_count" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm">
|
||||
</div>
|
||||
<div class="md:col-span-2 flex justify-end"><button class="rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white">Attach Result</button></div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="rounded-xl border border-dashed border-slate-300 px-4 py-6 text-center text-sm text-slate-500">No tool run has been started for this task yet.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if task.is_aqmm_task %}
|
||||
<div class="mx-auto mt-6 max-w-3xl rounded-2xl bg-white p-6 shadow-soft">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
|
||||
Reference in New Issue
Block a user