fix: dashboard improvements and query speed improvements
This commit is contained in:
@@ -1,18 +1,15 @@
|
||||
import { useEventQueryFilters } from '@/hooks/use-event-query-filters';
|
||||
|
||||
import { useTRPC } from '@/integrations/trpc/react';
|
||||
import { ModalContent, ModalHeader } from '@/modals/Modal/Container';
|
||||
import type { IGetTopGenericInput } from '@openpanel/db';
|
||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { ChevronRightIcon } from 'lucide-react';
|
||||
import { SerieIcon } from '../report-chart/common/serie-icon';
|
||||
import { Button } from '../ui/button';
|
||||
import { ScrollArea } from '../ui/scroll-area';
|
||||
import {
|
||||
OVERVIEW_COLUMNS_NAME,
|
||||
OVERVIEW_COLUMNS_NAME_PLURAL,
|
||||
} from './overview-constants';
|
||||
import { OverviewWidgetTableGeneric } from './overview-widget-table';
|
||||
import { OverviewListModal } from './overview-list-modal';
|
||||
import { useOverviewOptions } from './useOverviewOptions';
|
||||
|
||||
interface OverviewTopGenericModalProps {
|
||||
@@ -24,83 +21,55 @@ export default function OverviewTopGenericModal({
|
||||
projectId,
|
||||
column,
|
||||
}: OverviewTopGenericModalProps) {
|
||||
const [filters, setFilter] = useEventQueryFilters();
|
||||
const [_filters, setFilter] = useEventQueryFilters();
|
||||
const { startDate, endDate, range } = useOverviewOptions();
|
||||
const trpc = useTRPC();
|
||||
const query = useInfiniteQuery(
|
||||
trpc.overview.topGeneric.infiniteQueryOptions(
|
||||
{
|
||||
projectId,
|
||||
filters,
|
||||
startDate,
|
||||
endDate,
|
||||
range,
|
||||
limit: 50,
|
||||
column,
|
||||
},
|
||||
{
|
||||
getNextPageParam: (lastPage, pages) => {
|
||||
if (lastPage.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return pages.length + 1;
|
||||
},
|
||||
},
|
||||
),
|
||||
const query = useQuery(
|
||||
trpc.overview.topGeneric.queryOptions({
|
||||
projectId,
|
||||
filters: _filters,
|
||||
startDate,
|
||||
endDate,
|
||||
range,
|
||||
column,
|
||||
}),
|
||||
);
|
||||
|
||||
const data = query.data?.pages.flat() || [];
|
||||
const isEmpty = !query.hasNextPage && !query.isFetching;
|
||||
|
||||
const columnNamePlural = OVERVIEW_COLUMNS_NAME_PLURAL[column];
|
||||
const columnName = OVERVIEW_COLUMNS_NAME[column];
|
||||
|
||||
return (
|
||||
<ModalContent>
|
||||
<ModalHeader title={`Top ${columnNamePlural}`} />
|
||||
<ScrollArea className="-mx-6 px-2">
|
||||
<OverviewWidgetTableGeneric
|
||||
data={data}
|
||||
column={{
|
||||
name: columnName,
|
||||
render(item) {
|
||||
return (
|
||||
<div className="row items-center gap-2 min-w-0 relative">
|
||||
<SerieIcon name={item.prefix || item.name} />
|
||||
<button
|
||||
type="button"
|
||||
className="truncate"
|
||||
onClick={() => {
|
||||
setFilter(column, item.name);
|
||||
}}
|
||||
>
|
||||
{item.prefix && (
|
||||
<span className="mr-1 row inline-flex items-center gap-1">
|
||||
<span>{item.prefix}</span>
|
||||
<span>
|
||||
<ChevronRightIcon className="size-3" />
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{item.name || 'Not set'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<div className="row center-center p-4 pb-0">
|
||||
<Button
|
||||
variant="outline"
|
||||
className="w-full"
|
||||
onClick={() => query.fetchNextPage()}
|
||||
disabled={isEmpty}
|
||||
<OverviewListModal
|
||||
title={`Top ${columnNamePlural}`}
|
||||
searchPlaceholder={`Search ${columnNamePlural.toLowerCase()}...`}
|
||||
data={query.data ?? []}
|
||||
keyExtractor={(item) => (item.prefix ?? '') + item.name}
|
||||
searchFilter={(item, query) =>
|
||||
item.name?.toLowerCase().includes(query) ||
|
||||
item.prefix?.toLowerCase().includes(query) ||
|
||||
false
|
||||
}
|
||||
columnName={columnName}
|
||||
renderItem={(item) => (
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<SerieIcon name={item.prefix || item.name} />
|
||||
<button
|
||||
type="button"
|
||||
className="truncate hover:underline"
|
||||
onClick={() => {
|
||||
setFilter(column, item.name);
|
||||
}}
|
||||
>
|
||||
Load more
|
||||
</Button>
|
||||
{item.prefix && (
|
||||
<span className="mr-1 inline-flex items-center gap-1">
|
||||
<span>{item.prefix}</span>
|
||||
<ChevronRightIcon className="size-3" />
|
||||
</span>
|
||||
)}
|
||||
{item.name || 'Not set'}
|
||||
</button>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</ModalContent>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user