Refactored tables.

This commit is contained in:
Mike Cao 2025-08-23 01:12:37 -07:00
parent 600a3d28c3
commit c8fe93dd9d
56 changed files with 643 additions and 1038 deletions

View file

@ -1,54 +1,47 @@
import { ReactNode } from 'react';
import classNames from 'classnames';
import { HTMLAttributes, ReactNode, useState } from 'react';
import Link from 'next/link';
import { Icon } from '@umami/react-zen';
import { Icon, Row } from '@umami/react-zen';
import { useMessages, useNavigation } from '@/components/hooks';
import { ExternalLink } from '@/components/icons';
import styles from './FilterLink.module.css';
export interface FilterLinkProps {
id: string;
export interface FilterLinkProps extends HTMLAttributes<HTMLDivElement> {
type: string;
value: string;
label?: string;
icon?: ReactNode;
externalUrl?: string;
className?: string;
children?: ReactNode;
}
export function FilterLink({
id,
value,
label,
externalUrl,
children,
className,
}: FilterLinkProps) {
export function FilterLink({ type, value, label, externalUrl, icon }: FilterLinkProps) {
const [showLink, setShowLink] = useState(false);
const { formatMessage, labels } = useMessages();
const { updateParams, query } = useNavigation();
const active = query[id] !== undefined;
const selected = query[id] === value;
const active = query[type] !== undefined;
const selected = query[type] === value;
return (
<div
className={classNames(styles.row, className, {
[styles.inactive]: active && !selected,
[styles.active]: active && selected,
})}
<Row
alignItems="center"
gap
fontWeight={active && selected ? 'bold' : undefined}
color={active && !selected ? 'muted' : undefined}
onMouseOver={() => setShowLink(true)}
onMouseOut={() => setShowLink(false)}
>
{children}
{icon}
{!value && `(${label || formatMessage(labels.unknown)})`}
{value && (
<Link href={updateParams({ [id]: `eq.${value}` })} className={styles.label} replace>
<Link href={updateParams({ [type]: `eq.${value}` })} replace>
{label || value}
</Link>
)}
{externalUrl && (
<a className={styles.link} href={externalUrl} target="_blank" rel="noreferrer noopener">
<Icon className={styles.icon}>
{externalUrl && showLink && (
<a href={externalUrl} target="_blank" rel="noreferrer noopener">
<Icon color="muted">
<ExternalLink />
</Icon>
</a>
)}
</div>
</Row>
);
}

View file

@ -30,7 +30,7 @@ export function LoadingPanel({
return (
<>
{/* Show loading spinner only if no data exists */}
{(isLoading || isFetching) && !data && (
{(isLoading || isFetching) && (
<Column position="relative" height="100%" {...props}>
<Loading icon={loadingIcon} position="page" />
</Column>

View file

@ -28,7 +28,11 @@ export function PageHeader({
>
<Column>
<Row alignItems="center" gap="3">
{icon && <Icon size="md">{icon}</Icon>}
{icon && (
<Icon size="md" color="muted">
{icon}
</Icon>
)}
{title && <Heading size="4">{title}</Heading>}
</Row>
{description && <Text color="muted">{description}</Text>}