feat: status + queue updates, filters e UI

- Status renomeados e cores (Em andamento azul, Pausado amarelo)
- Transições automáticas: iniciar=Em andamento, pausar=Pausado
- Fila padrão: Chamados ao criar ticket
- Admin/Empresas: renomeia ‘Slug’ → ‘Apelido’ + mensagens
- Dashboard: últimos tickets priorizam sem responsável (mais antigos)
- Tickets: filtro por responsável + salvar filtro por usuário
- Encerrar ticket: adiciona botão ‘Cancelar’
- Strings atualizadas (PDF, relatórios, badges)
This commit is contained in:
codex-bot 2025-10-20 14:57:22 -03:00
parent e91192a1f6
commit 5535ba81e6
19 changed files with 399 additions and 86 deletions

View file

@ -129,6 +129,14 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
async function handleSubmit(event: React.FormEvent) {
event.preventDefault()
if (!convexUserId) return
// Enforce generous max length for comment plain text
const sanitized = sanitizeEditorHtml(body)
const plain = sanitized.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").trim()
const MAX_COMMENT_CHARS = 20000
if (plain.length > MAX_COMMENT_CHARS) {
toast.error(`Comentário muito longo (máx. ${MAX_COMMENT_CHARS} caracteres)`, { id: "comment" })
return
}
const now = new Date()
const selectedVisibility = canSeeInternalComments ? visibility : "PUBLIC"
const attachments = attachmentsToSend.map((item) => ({ ...item }))
@ -139,7 +147,7 @@ export function TicketComments({ ticket }: TicketCommentsProps) {
id: `temp-${now.getTime()}`,
author: ticket.requester,
visibility: selectedVisibility,
body: sanitizeEditorHtml(body),
body: sanitized,
attachments: attachments.map((attachment) => ({
id: attachment.storageId,
name: attachment.name,