import { QueryObserverLoadingErrorResult, QueryObserverLoadingResult, QueryObserverRefetchErrorResult, QueryObserverSuccessResult, UseQueryResult, } from "@tanstack/react-query"; import { ReactNode } from "react"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { TRPCClientErrorLike } from "@calcom/trpc/client"; import { trpc } from "@calcom/trpc/react"; import type { inferHandlerInput, inferProcedureInput, inferProcedureOutput, ProcedureRecord, } from "@calcom/trpc/server"; import type { AppRouter } from "@calcom/trpc/server/routers/_app"; import { Alert } from "@calcom/ui/Alert"; import Loader from "@calcom/ui/Loader"; import type { UseTRPCQueryOptions } from "@trpc/react/shared"; type ErrorLike = { message: string; }; type JSXElementOrNull = JSX.Element | null; interface QueryCellOptionsBase { query: UseQueryResult; customLoader?: ReactNode; error?: ( query: QueryObserverLoadingErrorResult | QueryObserverRefetchErrorResult ) => JSXElementOrNull; loading?: (query: QueryObserverLoadingResult | null) => JSXElementOrNull; } interface QueryCellOptionsNoEmpty extends QueryCellOptionsBase { success: (query: QueryObserverSuccessResult) => JSXElementOrNull; } interface QueryCellOptionsWithEmpty extends QueryCellOptionsBase { success: (query: QueryObserverSuccessResult, TError>) => JSXElementOrNull; /** * If there's no data (`null`, `undefined`, or `[]`), render this component */ empty: (query: QueryObserverSuccessResult) => JSXElementOrNull; } export function QueryCell( opts: QueryCellOptionsWithEmpty ): JSXElementOrNull; export function QueryCell( opts: QueryCellOptionsNoEmpty ): JSXElementOrNull; /** @deprecated Use `trpc.useQuery` instead. */ export function QueryCell( opts: QueryCellOptionsNoEmpty | QueryCellOptionsWithEmpty ) { const { query } = opts; const { isLocaleReady } = useLocale(); const StatusLoader = opts.customLoader || ; // Fixes edge case where this can return null form query cell if (query.status === "loading" || !isLocaleReady) { return opts.loading?.(query.status === "loading" ? query : null) ?? StatusLoader; } if (query.status === "success") { if ("empty" in opts && (query.data == null || (Array.isArray(query.data) && query.data.length === 0))) { return opts.empty(query); } return opts.success(query as any); } if (query.status === "error") { return ( opts.error?.(query) ?? ( ) ); } // impossible state return null; } type inferProcedures = { [TPath in keyof TObj]: { input: inferProcedureInput; output: inferProcedureOutput; }; }; type TQueryValues = inferProcedures; type TQueries = AppRouter["_def"]["queries"]; type TError = TRPCClientErrorLike; const withQuery = ( pathAndInput: [path: TPath, ...args: inferHandlerInput], params?: UseTRPCQueryOptions< TPath, TQueryValues[TPath]["input"], TQueryValues[TPath]["output"], TQueryValues[TPath]["output"], TError > ) => { return function WithQuery( opts: Omit< Partial> & QueryCellOptionsNoEmpty, "query" > ) { const query = trpc.useQuery(pathAndInput, params); return ; }; }; export { withQuery };