Files
frontend/apps/cm/src/shared/lib/match-query-status.ts
T

66 lines
1.6 KiB
TypeScript

import { type UseQueryResult } from "@tanstack/react-query";
import type { PageableList } from "../model";
/**
* Match the state of a query to a set of components.
*
* Useful for rendering different UI based on the state of a query.
*/
export function matchQueryStatus<T>(
query: UseQueryResult<PageableList<T>>,
options: {
Loading?: JSX.Element;
Errored?: JSX.Element | ((error: unknown) => JSX.Element);
Empty?: JSX.Element;
Success: (
data: UseQueryResult<PageableList<T>> & {
data: NonNullable<UseQueryResult<T>["data"]>;
},
) => JSX.Element;
},
): JSX.Element;
export function matchQueryStatus<T>(
query: UseQueryResult<PageableList<T>>,
options: {
Loading?: JSX.Element;
Errored?: JSX.Element | ((error: unknown) => JSX.Element);
Success: (data: UseQueryResult<PageableList<T>>) => JSX.Element;
},
): JSX.Element;
export function matchQueryStatus<T>(
query: UseQueryResult<PageableList<T>>,
{
Loading,
Errored,
Empty,
Success,
}: {
Loading?: JSX.Element;
Errored?: JSX.Element | ((error: unknown) => JSX.Element);
Empty?: JSX.Element;
Success: (data: UseQueryResult<PageableList<T>>) => JSX.Element;
},
): JSX.Element {
if (query.isLoading && Loading) {
return Loading;
}
if (query.isError && Errored) {
if (typeof Errored === "function") {
return Errored(query.error);
}
return Errored;
}
const isEmpty =
query.data?.content === undefined ||
query.data?.content === null ||
(Array.isArray(query.data?.content) && query.data?.content.length === 0);
if (isEmpty && Empty) {
return Empty;
}
return Success(query);
}