Refactor filter handling for queries.

This commit is contained in:
Mike Cao 2025-07-02 01:44:12 -07:00
parent 5b300f1ff5
commit ee6c68d27c
107 changed files with 731 additions and 835 deletions

View file

@ -3,7 +3,6 @@ import { LoadingPanel } from '@/components/common/LoadingPanel';
import { PageviewsChart } from '@/components/metrics/PageviewsChart';
import { useWebsitePageviewsQuery } from '@/components/hooks/queries/useWebsitePageviewsQuery';
import { useDateRange } from '@/components/hooks';
import { Panel } from '@/components/common/Panel';
export function WebsiteChart({
websiteId,
@ -48,16 +47,14 @@ export function WebsiteChart({
}, [data, startDate, endDate, unit]);
return (
<Panel height="520px">
<LoadingPanel data={data} isFetching={isFetching} isLoading={isLoading} error={error}>
<PageviewsChart
key={value}
data={chartData}
minDate={startDate}
maxDate={endDate}
unit={unit}
/>
</LoadingPanel>
</Panel>
<LoadingPanel data={data} isFetching={isFetching} isLoading={isLoading} error={error}>
<PageviewsChart
key={value}
data={chartData}
minDate={startDate}
maxDate={endDate}
unit={unit}
/>
</LoadingPanel>
);
}

View file

@ -1,6 +1,7 @@
'use client';
import { Column } from '@umami/react-zen';
import { useNavigation } from '@/components/hooks';
import { Panel } from '@/components/common/Panel';
import { WebsiteChart } from './WebsiteChart';
import { WebsiteExpandedView } from './WebsiteExpandedView';
import { WebsiteMetricsBar } from './WebsiteMetricsBar';
@ -16,8 +17,10 @@ export function WebsiteDetailsPage({ websiteId }: { websiteId: string }) {
return (
<Column gap>
<WebsiteControls websiteId={websiteId} allowCompare={true} />
<WebsiteMetricsBar websiteId={websiteId} showFilter={true} showChange={true} />
<WebsiteChart websiteId={websiteId} compareMode={compare} />
<WebsiteMetricsBar websiteId={websiteId} showChange={true} />
<Panel>
<WebsiteChart websiteId={websiteId} compareMode={compare} />
</Panel>
{!view && !compare && <WebsiteTableView websiteId={websiteId} />}
{view && !compare && <WebsiteExpandedView websiteId={websiteId} />}
{compare && <WebsiteCompareTables websiteId={websiteId} />}

View file

@ -11,13 +11,12 @@ import {
import { Fragment } from 'react';
import { More, Share, Edit } from '@/components/icons';
import { useMessages, useNavigation } from '@/components/hooks';
import { InputItem } from '@/lib/types';
export function WebsiteMenu({ websiteId }: { websiteId: string }) {
const { formatMessage, labels } = useMessages();
const { router, updateParams, renderUrl } = useNavigation();
const menuItems: InputItem[] = [
const menuItems = [
{ id: 'share', label: formatMessage(labels.share), icon: <Share /> },
{ id: 'edit', label: formatMessage(labels.edit), icon: <Edit />, seperator: true },
];

View file

@ -3,26 +3,18 @@ import { MetricCard } from '@/components/metrics/MetricCard';
import { MetricsBar } from '@/components/metrics/MetricsBar';
import { formatShortTime, formatLongNumber } from '@/lib/format';
import { useWebsiteStatsQuery } from '@/components/hooks/queries/useWebsiteStatsQuery';
import { useWebsites } from '@/store/websites';
import { LoadingPanel } from '@/components/common/LoadingPanel';
export function WebsiteMetricsBar({
websiteId,
showChange = false,
compareMode = false,
}: {
websiteId: string;
showChange?: boolean;
compareMode?: boolean;
showFilter?: boolean;
}) {
const { dateRange } = useDateRange(websiteId);
const { formatMessage, labels } = useMessages();
const dateCompare = useWebsites(state => state[websiteId]?.dateCompare);
const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(
websiteId,
compareMode && dateCompare,
);
const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(websiteId);
const isAllTime = dateRange.value === 'all';
const { pageviews, visitors, visits, bounces, totaltime, previous } = data || {};
@ -87,8 +79,7 @@ export function WebsiteMetricsBar({
change={change}
formatValue={formatValue}
reverseColors={reverseColors}
showChange={!isAllTime && (compareMode || showChange)}
showPrevious={!isAllTime && compareMode}
showChange={!isAllTime}
/>
);
})}

View file

@ -9,7 +9,7 @@ import { LoadingPanel } from '@/components/common/LoadingPanel';
import { Panel } from '@/components/common/Panel';
export function GoalsPage({ websiteId }: { websiteId: string }) {
const { result, query } = useReportsQuery({ websiteId, type: 'goal' });
const { data, isLoading, error } = useReportsQuery({ websiteId, type: 'goal' });
const {
dateRange: { startDate, endDate },
} = useDateRange(websiteId);
@ -20,14 +20,16 @@ export function GoalsPage({ websiteId }: { websiteId: string }) {
<SectionHeader>
<GoalAddButton websiteId={websiteId} />
</SectionHeader>
<LoadingPanel data={result?.data} isLoading={query?.isLoading} error={query?.error}>
<Grid columns="1fr 1fr" gap>
{result?.data?.map((report: any) => (
<Panel key={report.id}>
<Goal {...report} startDate={startDate} endDate={endDate} />
</Panel>
))}
</Grid>
<LoadingPanel data={data} isLoading={isLoading} error={error}>
{data && (
<Grid columns="1fr 1fr" gap>
{data['data'].map((report: any) => (
<Panel key={report.id}>
<Goal {...report} startDate={startDate} endDate={endDate} />
</Panel>
))}
</Grid>
)}
</LoadingPanel>
</Column>
);

View file

@ -73,7 +73,7 @@ export function UTM({ websiteId, startDate, endDate }: UTMProps) {
);
}
function toArray(data: { [key: string]: number } = {}) {
function toArray(data: Record<string, number> = {}) {
return Object.keys(data)
.map(key => {
return { name: key, value: data[key] };

View file

@ -14,7 +14,7 @@ export function SessionsDataTable({
const queryResult = useWebsiteSessionsQuery(websiteId);
return (
<DataGrid queryResult={queryResult} allowSearch={true} renderEmpty={() => children}>
<DataGrid queryResult={queryResult} renderEmpty={() => children} allowPaging>
{({ data }) => <SessionsTable data={data} showDomain={!websiteId} />}
</DataGrid>
);

View file

@ -1,12 +1,12 @@
import { ReactNode } from 'react';
import { Icon, TextField, Column, Row, Label, Text } from '@umami/react-zen';
import { useFormat, useLocale, useMessages, useRegionNames, useTimezone } from '@/components/hooks';
import { useFormat, useLocale, useMessages, useRegionNames } from '@/components/hooks';
import { TypeIcon } from '@/components/common/TypeIcon';
import { Location, KeyRound, Calendar } from '@/components/icons';
import { DateDistance } from '@/components/common/DateDistance';
export function SessionInfo({ data }) {
const { locale } = useLocale();
const { formatTimezoneDate } = useTimezone();
const { formatMessage, labels } = useMessages();
const { formatValue } = useFormat();
const { getRegionName } = useRegionNames(locale);
@ -22,11 +22,11 @@ export function SessionInfo({ data }) {
</Info>
<Info label={formatMessage(labels.lastSeen)} icon={<Calendar />}>
{formatTimezoneDate(data?.lastAt, 'PPPPpp')}
<DateDistance date={new Date(data.lastAt)} />
</Info>
<Info label={formatMessage(labels.firstSeen)} icon={<Calendar />}>
{formatTimezoneDate(data?.firstAt, 'PPPPpp')}
<DateDistance date={new Date(data.firstAt)} />
</Info>
<Info