mirror of
https://github.com/umami-software/umami.git
synced 2026-02-08 22:57:12 +01:00
Unified loading states.
This commit is contained in:
parent
7b5591a3ce
commit
da8c7e99c5
52 changed files with 506 additions and 364 deletions
|
|
@ -1,32 +1,59 @@
|
|||
import { ReactNode } from 'react';
|
||||
import { Spinner, Dots, Column, type ColumnProps } from '@umami/react-zen';
|
||||
import { Loading, Column, type ColumnProps } from '@umami/react-zen';
|
||||
import { ErrorMessage } from '@/components/common/ErrorMessage';
|
||||
import { Empty } from '@/components/common/Empty';
|
||||
|
||||
export interface LoadingPanelProps extends ColumnProps {
|
||||
data?: any;
|
||||
error?: Error;
|
||||
isEmpty?: boolean;
|
||||
isLoading?: boolean;
|
||||
isFetching?: boolean;
|
||||
loadingIcon?: 'dots' | 'spinner';
|
||||
renderEmpty?: () => ReactNode;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function LoadingPanel({
|
||||
data,
|
||||
error,
|
||||
isEmpty,
|
||||
isFetched,
|
||||
isLoading,
|
||||
isFetching,
|
||||
loadingIcon = 'dots',
|
||||
renderEmpty = () => <Empty />,
|
||||
children,
|
||||
...props
|
||||
}: {
|
||||
error?: Error;
|
||||
isEmpty?: boolean;
|
||||
isFetched?: boolean;
|
||||
isLoading?: boolean;
|
||||
loadingIcon?: 'dots' | 'spinner';
|
||||
renderEmpty?: () => ReactNode;
|
||||
children: ReactNode;
|
||||
} & ColumnProps) {
|
||||
}: LoadingPanelProps) {
|
||||
const empty = isEmpty ?? checkEmpty(data);
|
||||
|
||||
return (
|
||||
<Column {...props}>
|
||||
{isLoading && !isFetched && (loadingIcon === 'dots' ? <Dots /> : <Spinner />)}
|
||||
<Column position="relative" flexGrow={1} {...props}>
|
||||
{/* Show loading spinner only if no data exists */}
|
||||
{(isLoading || isFetching) && !data && <Loading icon={loadingIcon} position="page" />}
|
||||
|
||||
{/* Show error */}
|
||||
{error && <ErrorMessage />}
|
||||
{!error && !isLoading && isEmpty && renderEmpty()}
|
||||
{!error && !isLoading && !isEmpty && children}
|
||||
|
||||
{/* Show empty state (once loaded) */}
|
||||
{!error && !isLoading && !isFetching && empty && renderEmpty()}
|
||||
|
||||
{/* Show main content when data exists */}
|
||||
{!error && !empty && children}
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
function checkEmpty(data: any) {
|
||||
if (!data) return false;
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
return data.length <= 0;
|
||||
}
|
||||
|
||||
if (typeof data === 'object') {
|
||||
return Object.keys(data).length <= 0;
|
||||
}
|
||||
|
||||
return !!data;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue