Make a workspace page a dashboard and drop its coordinator from the rail

The workspace rail now lists only the bots attached to the workspace, with the back link returning to the workspace page from a bot's conversation. /admin/workspaces/<id> becomes a read-only dashboard (picture, context, latest activity, bots, computers) that links into the editable settings page.
This commit is contained in:
2026-10-19 13:40:59 +01:00
parent 7b1ccfeb62
commit e5747effa8
16 changed files with 425 additions and 63 deletions
@@ -0,0 +1,40 @@
import BunSQLite from "@moduletrace/bun-sqlite";
import { AppData } from "@/src/data/app-data";
import type { WorkspaceActivityItem } from "@/src/types";
type Params = {
user_id: number | string;
workspace_id: number | string;
};
/**
* The user's latest conversations in a workspace, most recent first, each
* with the bot it's with, its message count and latest message. Empty
* sessions are left out unless active.
*/
export default async function grabWorkspaceActivity({
user_id,
workspace_id,
}: Params): Promise<WorkspaceActivityItem[]> {
const res = await BunSQLite.sql<WorkspaceActivityItem>({
sql: `SELECT s.*,
b.name AS bot_name,
b.image_media_id AS bot_image_media_id,
b.hue AS bot_hue,
b.face AS bot_face,
(SELECT COUNT(*) FROM bot_messages m WHERE m.session_id = s.id) AS message_count,
(SELECT m.text FROM bot_messages m WHERE m.session_id = s.id ORDER BY m.created_at DESC, m.id DESC LIMIT 1) AS last_message_text
FROM bot_sessions s
JOIN bots b ON b.id = s.bot_id
WHERE s.workspace_id = ? AND s.user_id = ?
AND (s.status = 'active' OR EXISTS (SELECT 1 FROM bot_messages m WHERE m.session_id = s.id))
AND (b.kind = 'coordinator' OR EXISTS (
SELECT 1 FROM workspace_bots wb WHERE wb.workspace_id = s.workspace_id AND wb.bot_id = s.bot_id
))
ORDER BY COALESCE(s.last_activity_at, s.created_at) DESC, s.id DESC
LIMIT ?`,
values: [workspace_id, user_id, AppData.WorkspaceActivityItems],
});
return res.payload || [];
}