Align report filters and update work session flows
This commit is contained in:
parent
17c1de2272
commit
ff9d95746e
7 changed files with 106 additions and 83 deletions
|
|
@ -483,7 +483,7 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
const hasAssignee = Boolean(currentAssigneeId)
|
||||
const isCurrentResponsible = hasAssignee && convexUserId ? currentAssigneeId === convexUserId : false
|
||||
const isResolved = status === "RESOLVED"
|
||||
const canControlWork = !isResolved && (isAdmin || !hasAssignee || isCurrentResponsible)
|
||||
const canControlWork = !isResolved && isStaff && hasAssignee
|
||||
const canPauseWork = !isResolved && (isAdmin || isCurrentResponsible)
|
||||
const pauseDisabled = !canPauseWork
|
||||
const startDisabled = !canControlWork
|
||||
|
|
@ -491,11 +491,14 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
if (isResolved) {
|
||||
return "Este chamado está encerrado. Reabra o ticket para iniciar um novo atendimento."
|
||||
}
|
||||
if (!isAdmin && hasAssignee && !isCurrentResponsible) {
|
||||
return "Apenas o responsável atual ou um administrador pode iniciar este atendimento."
|
||||
if (!hasAssignee) {
|
||||
return "Defina um responsável antes de iniciar o atendimento."
|
||||
}
|
||||
if (!isStaff) {
|
||||
return "Apenas a equipe interna pode iniciar este atendimento."
|
||||
}
|
||||
return "Não é possível iniciar o atendimento neste momento."
|
||||
}, [isResolved, isAdmin, hasAssignee, isCurrentResponsible])
|
||||
}, [isResolved, hasAssignee, isStaff])
|
||||
|
||||
useEffect(() => {
|
||||
if (!customersInitialized) {
|
||||
|
|
@ -664,11 +667,6 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
setAssigneeSelection(currentAssigneeId)
|
||||
throw new Error("invalid-assignee")
|
||||
} else {
|
||||
if (status === "AWAITING_ATTENDANCE" || workSummary?.activeSession) {
|
||||
toast.error("Pause o atendimento antes de reatribuir o chamado.", { id: "assignee" })
|
||||
setAssigneeSelection(currentAssigneeId)
|
||||
throw new Error("assignee-not-allowed")
|
||||
}
|
||||
const reasonValue = assigneeChangeReason.trim()
|
||||
if (reasonValue.length > 0 && reasonValue.length < 5) {
|
||||
setAssigneeReasonError("Descreva o motivo com pelo menos 5 caracteres ou deixe em branco.")
|
||||
|
|
@ -985,6 +983,10 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
|
||||
const handleStartWork = async (workType: "INTERNAL" | "EXTERNAL") => {
|
||||
if (!convexUserId) return
|
||||
if (!assigneeState?.id) {
|
||||
toast.error("Defina um responsável antes de iniciar o atendimento.")
|
||||
return
|
||||
}
|
||||
toast.dismiss("work")
|
||||
toast.loading("Iniciando atendimento...", { id: "work" })
|
||||
try {
|
||||
|
|
@ -1029,18 +1031,21 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
activeSession: null,
|
||||
perAgentTotals: [],
|
||||
}
|
||||
const actorId = String(convexUserId)
|
||||
const sessionAgentId = assigneeState?.id ? String(assigneeState.id) : ""
|
||||
if (!sessionAgentId) {
|
||||
return base
|
||||
}
|
||||
const existingTotals = base.perAgentTotals ?? []
|
||||
const hasActorEntry = existingTotals.some((item) => item.agentId === actorId)
|
||||
const updatedTotals = hasActorEntry
|
||||
const hasAgentEntry = existingTotals.some((item) => item.agentId === sessionAgentId)
|
||||
const updatedTotals = hasAgentEntry
|
||||
? existingTotals
|
||||
: [
|
||||
...existingTotals,
|
||||
{
|
||||
agentId: actorId,
|
||||
agentName: viewerAgentMeta?.name ?? null,
|
||||
agentEmail: viewerAgentMeta?.email ?? null,
|
||||
avatarUrl: viewerAgentMeta?.avatarUrl ?? null,
|
||||
agentId: sessionAgentId,
|
||||
agentName: assigneeState?.name ?? viewerAgentMeta?.name ?? null,
|
||||
agentEmail: assigneeState?.email ?? viewerAgentMeta?.email ?? null,
|
||||
avatarUrl: assigneeState?.avatarUrl ?? viewerAgentMeta?.avatarUrl ?? null,
|
||||
totalWorkedMs: 0,
|
||||
internalWorkedMs: 0,
|
||||
externalWorkedMs: 0,
|
||||
|
|
@ -1051,7 +1056,7 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
serverNow: typeof resultMeta?.serverNow === "number" ? resultMeta.serverNow : getServerNow(),
|
||||
activeSession: {
|
||||
id: (sessionId as Id<"ticketWorkSessions">) ?? (base.activeSession?.id as Id<"ticketWorkSessions">),
|
||||
agentId: actorId,
|
||||
agentId: sessionAgentId,
|
||||
startedAt: startedAtMs,
|
||||
workType,
|
||||
},
|
||||
|
|
@ -1060,21 +1065,6 @@ export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
|
|||
})
|
||||
|
||||
setStatus("AWAITING_ATTENDANCE")
|
||||
if (viewerAgentMeta) {
|
||||
setAssigneeState((prevAssignee) => {
|
||||
if (prevAssignee && prevAssignee.id === viewerAgentMeta.id) {
|
||||
return prevAssignee
|
||||
}
|
||||
return {
|
||||
id: viewerAgentMeta.id,
|
||||
name: viewerAgentMeta.name ?? prevAssignee?.name ?? "Responsável",
|
||||
email: viewerAgentMeta.email ?? prevAssignee?.email ?? "",
|
||||
avatarUrl: viewerAgentMeta.avatarUrl ?? prevAssignee?.avatarUrl ?? undefined,
|
||||
teams: prevAssignee?.teams ?? [],
|
||||
}
|
||||
})
|
||||
setAssigneeSelection(viewerAgentMeta.id)
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Não foi possível atualizar o atendimento"
|
||||
toast.error(message, { id: "work" })
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ export function TicketsFilters({
|
|||
to={filters.dateTo}
|
||||
onChange={({ from, to }) => setPartial({ dateFrom: from, dateTo: to })}
|
||||
className="w-full min-w-[200px] rounded-2xl border-slate-300 bg-white/95 text-left text-sm font-semibold text-neutral-700 lg:w-auto"
|
||||
align="center"
|
||||
/>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
|
|
@ -253,6 +254,7 @@ export function TicketsFilters({
|
|||
clearLabel="Todas as empresas"
|
||||
triggerClassName={fieldTrigger}
|
||||
prefix={<IconBuilding className="size-4 text-neutral-400" />}
|
||||
align="center"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue