usePlaybookAop.ts2.3 KBView on GitHub 'use client';
import { useQuery } from '@tanstack/react-query';
import { useTRPC } from '@/providers/query-provider';
import type {
ConversationFieldDefs,
CustomFieldDefs,
} from '@/modules/aop/components/TriggerConfigEditor';
import type { CrmFieldEnumOption } from '@/modules/crm/types';
/**
* A `status` enum option as stored on the AOP — carries the stage colour + icon.
* Same shape as every other CRM enum option, so the shared `getEnum*` helpers accept it.
*/
export type StageOption = CrmFieldEnumOption;
/**
* Loads the backing AOP's field definitions for a playbook surface. Both the
* stage header (icon + colour from `status` options) and the trigger editor
* (field-change pickers) read from here. Keyed by `aopId`, so multiple stage /
* trigger nodes in one document share a single cached request. Returns empty
* definitions until an `aopId` is known (e.g. the legacy slug surface).
*
* `ownerUserId` is the AOP's owner, threaded from whoever mounted the document.
* It is a parameter and not an ambient read of the member picker on purpose:
* these node views also render inside the `/brain` document editor, which mounts
* no picker and can be showing anyone's document. An ambient read there would
* filter an admin's OWN playbook by whichever teammate they had selected, match
* nothing, and empty the stage pickers and field editors of a document that is
* working fine.
*/
export function usePlaybookAop(aopId?: string | null, ownerUserId?: string | null) {
const trpc = useTRPC();
const { data } = useQuery({
...trpc.aop.getAopById.queryOptions({
id: aopId ?? '',
targetUserId: ownerUserId ?? undefined,
}),
enabled: !!aopId,
staleTime: 5 * 60 * 1000,
});
const aop = data?.aop as
| {
name?: string | null;
conversationFieldDefinitions?: ConversationFieldDefs | null;
customFieldDefinitions?: CustomFieldDefs | null;
}
| undefined;
const aopName = aop?.name ?? null;
const conversationFieldDefs = (aop?.conversationFieldDefinitions ?? {}) as ConversationFieldDefs;
const customFieldDefs = (aop?.customFieldDefinitions ?? {}) as CustomFieldDefs;
const statusOptions = (conversationFieldDefs.status?.options ?? []) as StageOption[];
return { aopName, conversationFieldDefs, customFieldDefs, statusOptions };
}