Redesigned overview page.

This commit is contained in:
Mike Cao 2025-08-21 03:01:37 -07:00
parent 5d1f2a6f2d
commit f7ca583410
12 changed files with 257 additions and 96 deletions

View file

@ -1,5 +1,5 @@
import { ReactNode, useMemo, useState } from 'react';
import { Button, Column, Icon, Row, SearchField, Text, Grid } from '@umami/react-zen';
import { Button, Column, Icon, Row, SearchField, Text } from '@umami/react-zen';
import { LinkButton } from '@/components/common/LinkButton';
import { LoadingPanel } from '@/components/common/LoadingPanel';
import {
@ -114,11 +114,18 @@ export function MetricsTable({
}, [data, dataFilter, search, limit, formatValue, type]);
const downloadData = isExpanded ? data : filteredData;
const hasActions = data && (allowSearch || allowDownload || onClose || children);
return (
<LoadingPanel data={data} isFetching={isFetching} isLoading={isLoading} error={error}>
<Grid rows="40px 1fr" height="100%" overflow="hidden" gap>
<Row alignItems="center">
<LoadingPanel
data={data}
isFetching={isFetching}
isLoading={isLoading}
error={error}
height="100%"
>
{hasActions && (
<Row alignItems="center" paddingBottom="3">
{allowSearch && <SearchField value={search} onSearch={setSearch} delay={300} />}
<Row justifyContent="flex-end" flexGrow={1} gap>
{children}
@ -132,25 +139,32 @@ export function MetricsTable({
)}
</Row>
</Row>
<Column overflowY="auto" minHeight="0" height="100%" paddingRight="3" overflow="hidden">
{data &&
(isExpanded ? (
<ListExpandedTable {...(props as ListExpandedTableProps)} data={data} />
) : (
<ListTable {...(props as ListTableProps)} data={filteredData} />
))}
{showMore && limit && (
<Row justifyContent="center">
<LinkButton href={updateParams({ view: type })} variant="quiet">
<Icon size="sm">
<Maximize />
</Icon>
<Text>{formatMessage(labels.more)}</Text>
</LinkButton>
</Row>
)}
</Column>
</Grid>
)}
<Column
overflowY="auto"
minHeight="0"
height="100%"
paddingRight="3"
overflow="hidden"
flexGrow={1}
>
{data &&
(isExpanded ? (
<ListExpandedTable {...(props as ListExpandedTableProps)} data={data} />
) : (
<ListTable {...(props as ListTableProps)} data={filteredData} />
))}
</Column>
{showMore && limit && (
<Row justifyContent="center">
<LinkButton href={updateParams({ view: type })} variant="quiet">
<Icon size="sm">
<Maximize />
</Icon>
<Text>{formatMessage(labels.more)}</Text>
</LinkButton>
</Row>
)}
</LoadingPanel>
);
}

View file

@ -7,15 +7,12 @@ import { useContext } from 'react';
import { MetricsTable, MetricsTableProps } from './MetricsTable';
export interface PagesTableProps extends MetricsTableProps {
type: string;
allowFilter?: boolean;
}
export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
const {
router,
updateParams,
query: { view = 'path' },
} = useNavigation();
export function PagesTable({ type, allowFilter, ...props }: PagesTableProps) {
const { router, updateParams } = useNavigation();
const { formatMessage, labels } = useMessages();
const { domain } = useContext(WebsiteContext);
@ -45,11 +42,11 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
const renderLink = ({ x }) => {
return (
<FilterLink
id={view === 'entry' || view === 'exit' ? 'path' : view}
id={type === 'entry' || type === 'exit' ? 'path' : type}
value={x}
label={!x && formatMessage(labels.none)}
externalUrl={
view !== 'title'
type !== 'title'
? `${domain.startsWith('http') ? domain : `https://${domain}`}${x}`
: null
}
@ -61,12 +58,12 @@ export function PagesTable({ allowFilter, ...props }: PagesTableProps) {
<MetricsTable
{...props}
title={formatMessage(labels.pages)}
type={view}
type={type}
metric={formatMessage(labels.visitors)}
dataFilter={emptyFilter}
renderLabel={renderLink}
>
{allowFilter && <FilterButtons items={buttons} value={view} onChange={handleChange} />}
{allowFilter && <FilterButtons items={buttons} value={type} onChange={handleChange} />}
</MetricsTable>
);
}

View file

@ -16,7 +16,7 @@ const filters = {
export function QueryParametersTable({
allowFilter,
...props
}: { allowFilter: boolean } & MetricsTableProps) {
}: { allowFilter?: boolean } & MetricsTableProps) {
const [filter, setFilter] = useState(FILTER_COMBINED);
const { formatMessage, labels } = useMessages();