Files
cobble/src/pages/admin/bots/[bot_id]/(hooks)/use-bot-routines.ts
T
tben 5beb5f3de4 Let a conversation's menu show the routines that run in it
The header menu had Tasks but nothing for the schedules whose results
land in that conversation. It now has Schedules, right under Tasks,
opened in a modal that lists only what runs there: a bot's own chat holds
the routines that run nowhere, a workspace only that bot's routines in
it (`routineScopeSql`, tested against SQLite).

The list loads when the modal opens, through
`api/admin/bots/list-routines`, which checks the user chats in that
conversation first, so the page props stay small. `grabCronJobs` gained
an optional `workspace_id`: left out it still means everywhere.

The routines page's row, form and edit modal moved to
`src/components/general/`, and its subtitle to `src/utils/`, since both
the page and the modal use them.
2026-10-23 07:23:15 +01:00

55 lines
1.7 KiB
TypeScript

import fetchApi from "@moduletrace/twui/utils/fetch/fetchApi";
import type { APIResponseObject } from "@moduletrace/bunext/types";
import { useCallback, useEffect, useState } from "react";
import type { CronJobWithNames } from "@/src/types";
type Params = {
bot_id: number;
workspace_id?: number | null;
/**
* Load only once the modal opens, so the conversation's page props stay
* small.
*/
enabled?: boolean;
};
/**
* A conversation's routines: the schedules that run there, a bot's own in
* its chat or the ones that run in the workspace. Loaded on open and
* refreshed after every change, never part of the page props.
*/
export default function useBotRoutines({ bot_id, workspace_id, enabled = true }: Params) {
const [routines, setRoutines] = useState<CronJobWithNames[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string>();
const load = useCallback(async () => {
setLoading(true);
setError(undefined);
const query = new URLSearchParams({ bot_id: String(bot_id) });
if (workspace_id) query.set("workspace_id", String(workspace_id));
const res = await fetchApi<{}, APIResponseObject<CronJobWithNames>>(
`/api/admin/bots/list-routines?${query.toString()}`,
{ method: "GET" },
).catch(() => null);
setLoading(false);
if (!res?.success) {
setError(res?.msg || `Couldn't load the routines.`);
return;
}
setRoutines(res.payload || []);
}, [bot_id, workspace_id]);
useEffect(() => {
if (enabled) load().catch(() => {});
}, [enabled, load]);
return { routines, setRoutines, loading, error, reload: load };
}