Add chat widget improvements and chat history component

Widget improvements:
- Pulsating badge with unread message count on floating button
- Clickable ticket reference link in chat header
- ExternalLink icon on hover

Desktop (Raven) improvements:
- Track previous unread count for new message detection
- Send native Windows notifications for new messages
- Focus chat window when new messages arrive

Chat history:
- New query getTicketChatHistory for fetching chat sessions and messages
- New component TicketChatHistory displaying chat sessions
- Sessions can be expanded/collapsed to view messages
- Pagination support for long conversations
- Added to both dashboard and portal ticket views

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-07 03:20:22 -03:00
parent b194d77d57
commit d766de4fda
6 changed files with 453 additions and 9 deletions

View file

@ -29,6 +29,7 @@ import {
FileText,
Image as ImageIcon,
Download,
ExternalLink,
} from "lucide-react"
const MAX_MESSAGE_LENGTH = 4000
@ -444,10 +445,16 @@ export function ChatWidget() {
)}
</div>
{activeSession && (
<p className="text-xs text-slate-500">
#{activeSession.ticketRef}
{machineHostname && ` - ${machineHostname}`}
</p>
<a
href={`/dashboard/tickets/${activeTicketId}`}
target="_blank"
rel="noopener noreferrer"
className="group flex items-center gap-1 text-xs text-slate-500 hover:text-primary transition-colors"
>
<span>#{activeSession.ticketRef}</span>
{machineHostname && <span> - {machineHostname}</span>}
<ExternalLink className="size-3 opacity-0 group-hover:opacity-100 transition-opacity" />
</a>
)}
</div>
</div>
@ -725,9 +732,15 @@ export function ChatWidget() {
>
<MessageCircle className="size-6" />
{totalUnread > 0 && (
<span className="absolute -right-1 -top-1 flex size-6 items-center justify-center rounded-full bg-red-500 text-xs font-bold">
{totalUnread}
</span>
<>
{/* Anel pulsante externo */}
<span className="absolute -right-1 -top-1 flex size-6 items-center justify-center">
<span className="absolute inline-flex size-full animate-ping rounded-full bg-red-400 opacity-75" />
<span className="relative flex size-6 items-center justify-center rounded-full bg-red-500 text-xs font-bold text-white">
{totalUnread > 99 ? "99+" : totalUnread}
</span>
</span>
</>
)}
</button>
)}