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

67 lines
1.8 KiB
TypeScript

import React from "react";
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?: React.ReactElement;
Errored?: React.ReactElement | ((error: unknown) => React.ReactElement);
Empty?: React.ReactElement;
Success: (
data: UseQueryResult<PageableList<T>> & {
data: NonNullable<UseQueryResult<T>["data"]>;
},
) => React.ReactElement;
},
): React.ReactElement;
export function matchQueryStatus<T>(
query: UseQueryResult<PageableList<T>>,
options: {
Loading?: React.ReactElement;
Errored?: React.ReactElement | ((error: unknown) => React.ReactElement);
Success: (data: UseQueryResult<PageableList<T>>) => React.ReactElement;
},
): React.ReactElement;
export function matchQueryStatus<T>(
query: UseQueryResult<PageableList<T>>,
{
Loading,
Errored,
Empty,
Success,
}: {
Loading?: React.ReactElement;
Errored?: React.ReactElement | ((error: unknown) => React.ReactElement);
Empty?: React.ReactElement;
Success: (data: UseQueryResult<PageableList<T>>) => React.ReactElement;
},
): React.ReactElement {
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);
}