agent-drawer.html
99 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<!-- Agent Drawer -->
<div id="agent-drawer" class="fixed top-0 right-0 h-full w-full sm:w-[400px] z-[60] translate-x-full transition-all duration-200 ease-out">
<div class="flex flex-col h-full bg-white border-l border-slate-200 shadow-xl">
<!-- Header -->
<div class="flex items-center justify-between px-4 py-3 border-b border-slate-100">
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.455 2.456L21.75 6l-1.036.259a3.375 3.375 0 00-2.455 2.456z" /></svg>
<h3 class="text-sm font-semibold text-slate-700">Agent</h3>
</div>
<div class="flex items-center gap-1">
<div class="dropdown dropdown-end">
<div tabindex="0" role="button" class="inline-flex items-center justify-center w-7 h-7 rounded-md text-slate-400 hover:bg-slate-100" title="History">
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
</div>
<div tabindex="0" class="dropdown-content menu bg-white rounded-lg z-[1] w-52 p-1.5 shadow-lg border border-slate-200 max-h-64 overflow-y-auto">
<button class="btn btn-ghost btn-xs w-full mb-1 text-indigo-600" hx-post="/agent/conversations/new" hx-target="body">New Chat</button>
{{range $conv := dashboard.Conversations}}
<a class="block rounded px-2.5 py-1.5 text-xs text-slate-500 hover:bg-slate-50 hover:text-slate-700 truncate cursor-pointer"
hx-get="/agent/conversations/{{$conv.ID}}" hx-target="#drawer-messages" hx-swap="innerHTML">
{{$conv.Title}}
</a>
{{end}}
</div>
</div>
<button class="inline-flex items-center justify-center w-7 h-7 rounded-md text-slate-400 hover:bg-slate-100" onclick="document.body.classList.remove('has-drawer')" title="Close">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
</button>
</div>
</div>
{{if not dashboard.HasAgent}}
<div class="flex-1 flex items-center justify-center p-6">
<div class="text-center">
<div class="inline-flex items-center justify-center w-12 h-12 rounded-xl bg-amber-50 mb-3">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" /></svg>
</div>
<p class="text-sm text-slate-600 mb-1 font-medium">Sign in to Claude</p>
<p class="text-xs text-slate-400">Run <code class="text-[11px] bg-slate-100 px-1.5 py-0.5 rounded font-mono">claude</code> in the IDE terminal</p>
</div>
</div>
{{else}}
<div id="drawer-messages" class="flex-1 overflow-y-auto px-4 py-4 space-y-3">
<div class="text-center py-12">
<p class="text-slate-400 text-xs">Ask the agent to manage infrastructure</p>
</div>
</div>
<div id="drawer-loading" class="hidden px-4 pb-2">
<div class="flex items-center gap-2 px-3 py-2">
<span class="loading loading-dots loading-xs text-indigo-400"></span>
<span class="text-xs text-slate-400">Thinking...</span>
</div>
</div>
<div class="border-t border-slate-100 p-3">
<form id="drawer-chat-form" hx-post="/agent/chat" hx-target="#drawer-messages" hx-swap="beforeend" class="flex gap-2">
<input type="hidden" name="conversation_id" id="drawer-conversation-id" value="" />
<textarea name="message" id="agent-input"
class="textarea textarea-bordered textarea-sm flex-1 min-h-[40px] max-h-24 resize-none text-sm"
placeholder="Ask anything..."
rows="1"
onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();this.form.requestSubmit()}"
required></textarea>
<button type="submit" class="btn btn-primary btn-sm self-end">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" /></svg>
</button>
</form>
</div>
{{end}}
</div>
</div>
<script>
document.addEventListener('htmx:beforeRequest', function(e) {
if (e.detail.elt.id === 'drawer-chat-form') {
var input = document.getElementById('agent-input');
var msg = input.value.trim();
if (msg) {
var messagesDiv = document.getElementById('drawer-messages');
var placeholder = messagesDiv.querySelector('.text-center');
if (placeholder) placeholder.remove();
messagesDiv.insertAdjacentHTML('beforeend',
'<div class="flex justify-end"><div class="max-w-[80%] rounded-xl rounded-br-sm px-3 py-2 bg-indigo-50 text-sm text-slate-700">' +
msg.replace(/</g, '<').replace(/>/g, '>') +
'</div></div>');
document.getElementById('drawer-loading').classList.remove('hidden');
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
}
});
document.addEventListener('htmx:afterRequest', function(e) {
if (e.detail.elt.id === 'drawer-chat-form') {
document.getElementById('drawer-loading').classList.add('hidden');
document.getElementById('agent-input').value = '';
var messagesDiv = document.getElementById('drawer-messages');
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
});
</script>