Add bot schedules (routines), open Activity, add Help and a Desktop computer view

Bots create, list, update and delete schedules (cron_jobs, Bun.cron in UTC);
a per-minute cron queues due runs as tasks. Routines, Activity (super admins)
and Help get their own rail aside. Help covers familiar problems, starting
with signing in to Google through Cookie-Editor over the new Desktop (noVNC)
view.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 10:52:32 +01:00
co-authored by Claude Opus 5.5
parent f24c0d7e82
commit c44048dbab
62 changed files with 1904 additions and 78 deletions
+10 -2
View File
@@ -3,7 +3,9 @@ import Stack from "@moduletrace/twui/layout/Stack";
import { AppContext } from "@/src/pages/__root";
import useLiveBots from "@/src/hooks/use-live-bots";
import useLiveWorkspaces from "../(hooks)/use-live-workspaces";
import { RailPages } from "@/src/dict/rail-pages-dict";
import RailHeader from "../(partials)/rail-header";
import RailPagesList from "../(partials)/rail-pages-list";
import RailCrewList from "../(partials)/rail-crew-list";
import RailSettingsList from "../(partials)/rail-settings-list";
import RailUserRow from "../(partials)/rail-user-row";
@@ -13,13 +15,17 @@ import RailWorkspaceList from "../(partials)/rail-workspace-list";
* Left rail: wordmark and Add, then the crew (pinned coordinator first,
* the latest bots, the workspaces). Inside a workspace it lists that
* workspace's crew instead; on `/admin/settings/*` a back link and the
* settings sub pages. Collapses to a 64px icon rail below 1024px.
* settings sub pages, and on routines, activity and help a back link and
* those pages (`RailPages`). Collapses to a 64px icon rail below 1024px.
*/
export default function BotsRail() {
const { pageProps } = useContext(AppContext);
const pathname = pageProps?.url?.pathname;
const is_settings_page = Boolean(pathname?.startsWith("/admin/settings"));
const is_rail_page = RailPages.some(
(page) => pathname == page.url || Boolean(pathname?.startsWith(`${page.url}/`)),
);
const workspace = pageProps?.workspace;
const in_workspace = Boolean(workspace?.id && pathname?.startsWith("/admin/workspaces/"));
@@ -39,10 +45,12 @@ export default function BotsRail() {
className="w-16 lg:w-[260px] shrink-0 h-full gap-0! items-stretch border-0 border-r border-solid border-hairline"
aria-label={is_settings_page ? "Settings" : in_workspace ? workspace?.name || "Workspace" : "Bots"}
>
<RailHeader show_add={!is_settings_page} />
<RailHeader show_add={!is_settings_page && !is_rail_page} />
<Stack className="grow min-h-0 overflow-y-auto gap-0! items-stretch px-2 lg:px-3 pt-1 pb-3">
{is_settings_page ? (
<RailSettingsList pathname={pathname} />
) : is_rail_page ? (
<RailPagesList pathname={pathname} />
) : in_workspace && live_workspace ? (
<RailWorkspaceList
workspace={live_workspace}