Import ClientFlow production v4928.1.5.132.4
This commit is contained in:
@@ -8,6 +8,7 @@ from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from urllib.parse import quote
|
||||
|
||||
import app.admin_dashboard as legacy
|
||||
from app.admin_dashboard import * # noqa: F401,F403
|
||||
@@ -23,6 +24,10 @@ from app.admin_ui.view_models.operations import (
|
||||
operation_card_title,
|
||||
operation_primary_label,
|
||||
operation_status_chip,
|
||||
operation_due_label,
|
||||
operation_priority_reason,
|
||||
operation_queue_label,
|
||||
operation_value,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
@@ -40,7 +45,7 @@ def _operation_card_class(item: dict) -> str:
|
||||
return card_class
|
||||
|
||||
|
||||
def _render_work_item(item: dict) -> str:
|
||||
def _render_work_item(item: dict, return_to: str = "/operations?scope=all") -> str:
|
||||
high = is_high_priority(item)
|
||||
blocked = is_blocked(item)
|
||||
title = operation_card_title(item)
|
||||
@@ -67,8 +72,21 @@ def _render_work_item(item: dict) -> str:
|
||||
priority_chip = "cf-chip-orange"
|
||||
if status_text == "sem oportunidade comercial":
|
||||
priority_chip = "cf-chip-gray"
|
||||
elif status_text == "associação por confirmar":
|
||||
priority_chip = "cf-chip-purple"
|
||||
elif status_text == "validação obrigatória":
|
||||
priority_chip = "cf-chip-orange"
|
||||
status_chip_html = "" if status_text == "normal" else f'<span class="cf-chip {priority_chip}">{esc(status_text)}</span>'
|
||||
primary = operation_primary_label(item)
|
||||
due_label = operation_due_label(item)
|
||||
queue_text = operation_queue_label(item)
|
||||
value = operation_value(item)
|
||||
value_html = money_html(value) if value > 0 else "Valor por definir"
|
||||
priority_reason = operation_priority_reason(item)
|
||||
primary_href = str(item.get('href') or '#')
|
||||
if primary_href.startswith('/tasks/') and return_to:
|
||||
sep = '&' if '?' in primary_href else '?'
|
||||
primary_href = f"{primary_href}{sep}return_to={quote(return_to, safe='')}"
|
||||
# v4.8.9: details are intentionally not rendered in Operations cards.
|
||||
# Technical metadata remains available in task/opportunity/admin pages, while
|
||||
# the work queue keeps only decision-making information.
|
||||
@@ -83,14 +101,21 @@ def _render_work_item(item: dict) -> str:
|
||||
{status_chip_html}
|
||||
</div>
|
||||
</div>
|
||||
<div class="cf-work-meta d-flex flex-wrap gap-2 small text-secondary mb-2">
|
||||
<span class="badge text-bg-light border">{esc(queue_text)}</span>
|
||||
<span>{esc(due_label)}</span>
|
||||
<span>·</span>
|
||||
<span>{value_html}</span>
|
||||
</div>
|
||||
<div class="cf-work-next compact">
|
||||
<span>Próxima ação</span>
|
||||
<strong>{esc(primary)}</strong>
|
||||
<div class="small text-secondary mt-1 text-break">{esc(detail)}</div>
|
||||
<div class="small mt-2"><strong>Motivo da prioridade:</strong> {esc(priority_reason)}</div>
|
||||
</div>
|
||||
{blockers_html}
|
||||
<div class="cf-work-actions">
|
||||
<a class="btn btn-sm btn-primary cf-work-primary-action" href="{esc(item.get('href') or '#')}">{esc(primary)}</a>
|
||||
<a class="btn btn-sm btn-primary cf-work-primary-action" href="{esc(primary_href)}">{esc(primary)}</a>
|
||||
<div class="cf-work-secondary-actions">
|
||||
{chatwoot_button}
|
||||
{opportunity_button}
|
||||
@@ -99,15 +124,17 @@ def _render_work_item(item: dict) -> str:
|
||||
</article>
|
||||
"""
|
||||
|
||||
def _render_work_group(label: str, items: list[dict]) -> str:
|
||||
def _render_work_group(label: str, items: list[dict], return_to: str = "/operations?scope=all") -> str:
|
||||
if not items:
|
||||
return ""
|
||||
cards = "".join(_render_work_item(item) for item in items)
|
||||
cards = "".join(_render_work_item(item, return_to=return_to) for item in items)
|
||||
return f'<div class="cf-work-section-title">{esc(label)}</div><section class="cf-work-section">{cards}</section>'
|
||||
|
||||
|
||||
def render_operations_work_items(model: dict) -> str:
|
||||
queue_html = _render_work_group("Prioridade alta", model.get("high_items") or []) + _render_work_group("Normal", model.get("normal_items") or [])
|
||||
scope = str(model.get("scope") or "all").strip() or "all"
|
||||
return_to = f"/operations?scope={quote(scope, safe='')}"
|
||||
queue_html = _render_work_group("Prioridade alta", model.get("high_items") or [], return_to=return_to) + _render_work_group("Normal", model.get("normal_items") or [], return_to=return_to)
|
||||
if not queue_html:
|
||||
queue_html = '<div class="cf-work-empty"><strong>Sem trabalho pendente neste filtro.</strong><div class="small mt-1">Quando houver ações humanas ou bloqueios concretos, aparecem aqui.</div></div>'
|
||||
return f'''
|
||||
|
||||
Reference in New Issue
Block a user