feat: add Slack-like channel and DM messaging UX

- Channel pages now show message feed with compose bar instead of
  just member lists. Messages display with agent avatars, names,
  and timestamps. Collapsible info panel shows channel details.
- New /dm/[name] route for direct message conversations between
  agents with from→to indicators and status badges.
- Sidebar DM links now navigate to /dm/{name} instead of agent
  edit forms.
- Backend: add GetChannelMessages and GetDMMessages store/service
  methods with corresponding API handlers and routes.
- Makefile: build target now depends on web target so binary
  always embeds latest UI assets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Algis Dumbris
2026-03-14 06:46:07 +02:00
co-authored by Claude Opus 4.6
parent cad0138337
commit f5ae132ef4
13 changed files with 704 additions and 110 deletions
+11 -3
View File
@@ -62,7 +62,7 @@ export const messages = {
return request<{ messages: any[]; total: number }>('GET', `/api/messages${q ? '?' + q : ''}`);
},
get: (id: number) => request<any>('GET', `/api/messages/${id}`),
send: (body: { from?: string; to: string; body: string; priority?: number; subject?: string; channel_id?: number }) =>
send: (body: { from?: string; to?: string; body: string; priority?: number; subject?: string; channel_id?: number }) =>
request<any>('POST', '/api/messages', body),
markDone: (id: number) => request<{ status: string }>('POST', `/api/messages/${id}/done`),
search: (q: string, limit?: number) => {
@@ -86,7 +86,11 @@ export const agents = {
request<{ agent: any; api_key: string }>('POST', '/api/agents', body),
delete: (name: string) => request<{ status: string }>('DELETE', `/api/agents/${encodeURIComponent(name)}`),
revokeKey: (name: string) =>
request<{ agent: any; api_key: string }>('POST', `/api/agents/${encodeURIComponent(name)}/revoke-key`)
request<{ agent: any; api_key: string }>('POST', `/api/agents/${encodeURIComponent(name)}/revoke-key`),
messages: (name: string, limit?: number) => {
const qs = limit ? `?limit=${limit}` : '';
return request<{ messages: any[]; total: number }>('GET', `/api/agents/${encodeURIComponent(name)}/messages${qs}`);
}
};
// Channels
@@ -98,7 +102,11 @@ export const channels = {
join: (name: string, agent?: string) =>
request<{ status: string }>('POST', `/api/channels/${encodeURIComponent(name)}/join`, agent ? { agent } : {}),
leave: (name: string, agent?: string) =>
request<{ status: string }>('POST', `/api/channels/${encodeURIComponent(name)}/leave`, agent ? { agent } : {})
request<{ status: string }>('POST', `/api/channels/${encodeURIComponent(name)}/leave`, agent ? { agent } : {}),
messages: (name: string, limit?: number) => {
const qs = limit ? `?limit=${limit}` : '';
return request<{ messages: any[]; total: number }>('GET', `/api/channels/${encodeURIComponent(name)}/messages${qs}`);
}
};
// API Keys