move metric list header over

This commit is contained in:
Nate Kelley 2025-03-11 10:24:32 -06:00
parent d0a32dad5d
commit 841ce7aff6
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
10 changed files with 26 additions and 87 deletions

View File

@ -12,8 +12,6 @@ export interface ListMetricsParams {
page_token: number; page_token: number;
/** The number of items to return per page */ /** The number of items to return per page */
page_size: number; page_size: number;
/** Flag to enable admin view with additional permissions and data */
admin_view?: boolean;
/** Filtering options for metrics based on verification status */ /** Filtering options for metrics based on verification status */
status?: VerificationStatus[] | null; status?: VerificationStatus[] | null;
} }

View File

@ -13,6 +13,7 @@ import {
import type { GetMetricParams, ListMetricsParams } from './interfaces'; import type { GetMetricParams, ListMetricsParams } from './interfaces';
import { upgradeMetricToIMetric } from '@/lib/chat'; import { upgradeMetricToIMetric } from '@/lib/chat';
import { queryKeys } from '@/api/query_keys'; import { queryKeys } from '@/api/query_keys';
import { useMemo } from 'react';
export const useGetMetric = (params: GetMetricParams) => { export const useGetMetric = (params: GetMetricParams) => {
const queryFn = useMemoizedFn(async () => { const queryFn = useMemoizedFn(async () => {
@ -40,13 +41,18 @@ export const prefetchGetMetric = async (params: GetMetricParams, queryClientProp
return queryClient; return queryClient;
}; };
export const useGetMetricsList = (params: ListMetricsParams) => { export const useGetMetricsList = (params: Omit<ListMetricsParams, 'page_token' | 'page_size'>) => {
const compiledParams: ListMetricsParams = useMemo(
() => ({ ...params, page_token: 0, page_size: 3000 }),
[params]
);
const queryFn = useMemoizedFn(() => { const queryFn = useMemoizedFn(() => {
return listMetrics(params); return listMetrics(compiledParams);
}); });
const res = useQuery({ const res = useQuery({
...queryKeys.metricsGetList(params), ...queryKeys.metricsGetList(compiledParams),
queryFn queryFn
}); });

View File

@ -1,6 +1,5 @@
import { MetricListContainer } from '@/controllers/MetricListContainer';
import React from 'react'; import React from 'react';
export default function LogsPage() { export default function LogsPage() {
return <MetricListContainer type="logs" />; return <div>THIS SHOULD BE CHATS</div>;
} }

View File

@ -1,5 +1,5 @@
import { MetricListContainer } from '@/controllers/MetricListContainer'; import { MetricListContainer } from '@/controllers/MetricListContainer';
export default function MetricsPage() { export default function MetricsPage() {
return <MetricListContainer type="metrics" />; return <MetricListContainer />;
} }

View File

@ -1 +0,0 @@
export * from './useBusterMetricListByFilter';

View File

@ -1,28 +0,0 @@
'use client';
import React, { useMemo } from 'react';
import { VerificationStatus } from '@/api/asset_interfaces/share';
import { type ListMetricsParams, useGetMetricsList } from '@/api/buster_rest/metrics';
export const useBusterMetricListByFilter = (params: {
filters: VerificationStatus[];
admin_view: boolean;
}) => {
const metricListFilters: ListMetricsParams = useMemo(
() => ({
filters: params.filters,
admin_view: params.admin_view,
page_token: 0,
page_size: 3000
}),
[params.filters.join(','), params.admin_view]
);
const { data: metricList, isFetching, isFetched } = useGetMetricsList(metricListFilters);
return {
metricList,
isFetching,
isFetched
};
};

View File

@ -1,3 +1,2 @@
export * from './BusterMetricsListProvider';
export * from './BusterMetricsIndividualProvider'; export * from './BusterMetricsIndividualProvider';
export * from './BusterMetricProvider'; export * from './BusterMetricProvider';

View File

@ -18,9 +18,8 @@ import { useCreateListByDate } from '@/components/ui/list/useCreateListByDate';
export const MetricItemsContainer: React.FC<{ export const MetricItemsContainer: React.FC<{
metrics: BusterMetricListItem[]; metrics: BusterMetricListItem[];
className?: string; className?: string;
type: 'logs' | 'metrics';
loading: boolean; loading: boolean;
}> = ({ type, metrics = [], className = '', loading }) => { }> = React.memo(({ metrics = [], className = '', loading }) => {
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]); const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
const renderedDates = useRef<Record<string, string>>({}); const renderedDates = useRef<Record<string, string>>({});
const renderedOwners = useRef<Record<string, React.ReactNode>>({}); const renderedOwners = useRef<Record<string, React.ReactNode>>({});
@ -118,7 +117,7 @@ export const MetricItemsContainer: React.FC<{
columns={columns} columns={columns}
onSelectChange={onSelectChange} onSelectChange={onSelectChange}
selectedRowKeys={selectedRowKeys} selectedRowKeys={selectedRowKeys}
emptyState={<EmptyState loading={loading} type={type} />} emptyState={<EmptyState loading={loading} />}
/> />
<MetricSelectedOptionPopup <MetricSelectedOptionPopup
@ -128,27 +127,15 @@ export const MetricItemsContainer: React.FC<{
/> />
</div> </div>
); );
}; });
MetricItemsContainer.displayName = 'MetricItemsContainer';
const EmptyState: React.FC<{ const EmptyState: React.FC<{
loading: boolean; loading: boolean;
type: 'logs' | 'metrics'; }> = React.memo(({ loading }) => {
}> = React.memo(({ loading, type }) => {
if (loading) { if (loading) {
return <></>; return <></>;
} }
if (type === 'logs') {
return (
<ListEmptyStateWithButton
title="You dont have any logs yet."
description="You dont have any logs. As soon as you do, they will start to appear here."
buttonText="New chat"
linkButton={createBusterRoute({ route: BusterRoutes.APP_HOME })}
/>
);
}
return ( return (
<ListEmptyStateWithButton <ListEmptyStateWithButton
title="You dont have any metrics yet." title="You dont have any metrics yet."

View File

@ -1,36 +1,19 @@
'use client'; 'use client';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useMemoizedFn, useMount } from '@/hooks';
import { VerificationStatus } from '@/api/asset_interfaces'; import { VerificationStatus } from '@/api/asset_interfaces';
import { useBusterMetricListByFilter } from '@/context/Metrics';
import { MetricListHeader } from './MetricListHeader'; import { MetricListHeader } from './MetricListHeader';
import { MetricItemsContainer } from './MetricItemsContainer'; import { MetricItemsContainer } from './MetricItemsContainer';
import { AppPageLayout } from '@/components/ui/layouts'; import { AppPageLayout } from '@/components/ui/layouts';
import { useGetMetricsList } from '@/api/buster_rest/metrics';
export const MetricListContainer: React.FC<{ export const MetricListContainer: React.FC<{}> = ({}) => {
type: 'logs' | 'metrics';
}> = ({ type }) => {
const [filters, setFilters] = useState<VerificationStatus[]>([]); const [filters, setFilters] = useState<VerificationStatus[]>([]);
const adminView = type === 'logs'; const { data: metricList, isFetching, isFetched } = useGetMetricsList({ status: filters });
const { metricList, isFetched } = useBusterMetricListByFilter({
filters,
admin_view: adminView
});
const onSetFilters = useMemoizedFn((newFilters: VerificationStatus[]) => {
setFilters(newFilters);
});
useMount(async () => {
onSetFilters([]);
});
return ( return (
<AppPageLayout <AppPageLayout header={<MetricListHeader filters={filters} onSetFilters={setFilters} />}>
header={<MetricListHeader type={type} filters={filters} onSetFilters={onSetFilters} />}>
<MetricItemsContainer <MetricItemsContainer
type={type}
metrics={metricList || []} metrics={metricList || []}
loading={!isFetched} loading={!isFetched}
className="flex-col overflow-hidden" className="flex-col overflow-hidden"

View File

@ -8,24 +8,21 @@ import { useMemoizedFn } from '@/hooks';
import { type SegmentedItem } from '@/components/ui/segmented'; import { type SegmentedItem } from '@/components/ui/segmented';
export const MetricListHeader: React.FC<{ export const MetricListHeader: React.FC<{
type: 'logs' | 'metrics';
filters: VerificationStatus[]; filters: VerificationStatus[];
onSetFilters: (filters: VerificationStatus[]) => void; onSetFilters: (filters: VerificationStatus[]) => void;
}> = ({ type, filters, onSetFilters }) => { }> = React.memo(({ filters, onSetFilters }) => {
const title = type === 'logs' ? 'Logs' : 'Metrics';
const showFilters: boolean = true; const showFilters: boolean = true;
return ( return (
<div className="flex w-full items-center justify-between"> <div className="flex w-full items-center justify-between">
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Text>{title}</Text> <Text>{'Metrics'}</Text>
{showFilters && ( {showFilters && <MetricsFilters filters={filters} onSetFilters={onSetFilters} />}
<MetricsFilters type={type} filters={filters} onSetFilters={onSetFilters} />
)}
</div> </div>
</div> </div>
); );
}; });
MetricListHeader.displayName = 'MetricListHeader';
const options: SegmentedItem<VerificationStatus | 'all'>[] = [ const options: SegmentedItem<VerificationStatus | 'all'>[] = [
{ {
@ -43,10 +40,9 @@ const options: SegmentedItem<VerificationStatus | 'all'>[] = [
]; ];
const MetricsFilters: React.FC<{ const MetricsFilters: React.FC<{
type: 'logs' | 'metrics';
filters: VerificationStatus[]; filters: VerificationStatus[];
onSetFilters: (filters: VerificationStatus[]) => void; onSetFilters: (filters: VerificationStatus[]) => void;
}> = React.memo(({ type, filters, onSetFilters }) => { }> = React.memo(({ filters, onSetFilters }) => {
const selectedOption: SegmentedItem<VerificationStatus | 'all'> | undefined = useMemo(() => { const selectedOption: SegmentedItem<VerificationStatus | 'all'> | undefined = useMemo(() => {
return ( return (
options.find((option) => { options.find((option) => {