Files
calendar/packages/features/ee/workflows/hooks/useAgentsData.ts
T
aa48e72c12 feat: inbound calls in cal ai (#23890)
* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types

* feat: add inbound calls

* chore: formatting

* chore

* feat: finish inbound call

* chore: formatting

* fix: update bug

* fix: types

* refactor: Agent Configuration Sheet (#23930)

* refactor: agent configuration sheet

* chore: use default phone numbre

* refactor: improvements

* refactor: improvements

* fix: types

* fix: feedback

* chore:

* fix: feedback

* fix: prompt

* fix: review

* fix: review

* refactor: class

* refactor: class

* refactor: rename

* Update apps/web/public/static/locales/en/common.json

* Update apps/web/public/static/locales/en/common.json

* chore: update set value

* fix: remove index

* fix: type error

* fix: update tetss

* fix: use logger

* refactor: don't use static

* fix: type

* fix: schema

* refactor:

---------

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2025-10-09 11:40:37 +01:00

108 lines
3.0 KiB
TypeScript

import { useMemo } from "react";
import type { UseFormReturn } from "react-hook-form";
import { useWatch } from "react-hook-form";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { FormValues } from "../pages/workflow";
type AgentData = RouterOutputs["viewer"]["aiVoiceAgent"]["get"];
interface AgentQuery {
data: AgentData | undefined;
isPending: boolean;
isLoading: boolean;
error: Error | null;
}
interface UseAgentsDataReturn {
outboundAgentQueries: AgentQuery[];
inboundAgentQueries: AgentQuery[];
}
const emptyQuery: AgentQuery = { data: undefined, isPending: false, isLoading: false, error: null };
/**
* Custom hook to fetch and manage agent data for workflow steps.
*
* @param form - React Hook Form instance for workflow form values
* @returns Object containing outbound and inbound agent queries with proper typing
*/
export function useAgentsData(form: UseFormReturn<FormValues>): UseAgentsDataReturn {
const watchedSteps = useWatch({
control: form.control,
name: "steps",
});
const allAgentIds = useMemo(() => {
const outboundAgentIds = (watchedSteps || []).map((step) => step?.agentId || null);
const inboundAgentIds = (watchedSteps || []).map((step) => step?.inboundAgentId || null);
return { outboundAgentIds, inboundAgentIds };
}, [watchedSteps]);
const uniqueAgentIds = useMemo((): string[] => {
const allIds = [...allAgentIds.outboundAgentIds, ...allAgentIds.inboundAgentIds];
const validIds: string[] = [];
for (const id of allIds) {
if (id && typeof id === "string") {
validIds.push(id);
}
}
return Array.from(new Set(validIds));
}, [allAgentIds]);
const uniqueAgentQueries = trpc.useQueries((t) =>
uniqueAgentIds.map((agentId) => {
return t.viewer.aiVoiceAgent.get(
{ id: agentId },
{
enabled: true,
staleTime: 5 * 60 * 1000,
}
);
})
);
const agentDataMap = useMemo(() => {
const map = new Map<string, AgentQuery>();
uniqueAgentIds.forEach((agentId, index) => {
const query = uniqueAgentQueries[index];
if (query) {
map.set(agentId, {
data: query.data,
isPending: query.isPending,
isLoading: query.isLoading,
error: query.error,
});
}
});
return map;
}, [uniqueAgentIds, uniqueAgentQueries]);
const outboundAgentQueries = useMemo((): AgentQuery[] => {
return allAgentIds.outboundAgentIds.map((agentId) => {
if (!agentId) {
return emptyQuery;
}
return agentDataMap.get(agentId) || emptyQuery;
});
}, [allAgentIds.outboundAgentIds, agentDataMap]);
const inboundAgentQueries = useMemo((): AgentQuery[] => {
return allAgentIds.inboundAgentIds.map((agentId) => {
if (!agentId) {
return emptyQuery;
}
return agentDataMap.get(agentId) || emptyQuery;
});
}, [allAgentIds.inboundAgentIds, agentDataMap]);
return {
outboundAgentQueries,
inboundAgentQueries,
};
}