mirror of
https://github.com/SigNoz/signoz.git
synced 2026-09-21 19:00:42 +01:00
Compare commits
1 Commits
fix/ui-tes
...
chore/use-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
175217950c |
@@ -10,3 +10,11 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.errorState {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--spacing-2);
|
||||
padding: var(--spacing-8);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
import { Typography } from '@signozhq/ui/typography';
|
||||
import Spinner from 'components/Spinner';
|
||||
import DashboardContainer from 'pages/DashboardPage/DashboardContainer';
|
||||
|
||||
import { useSeededDashboardV2 } from './hooks/useSeededDashboardV2';
|
||||
import { useSystemDashboard } from './hooks/useSystemDashboard';
|
||||
import styles from './Overview.module.scss';
|
||||
|
||||
function Overview(): JSX.Element {
|
||||
//TODO: this is a temporary solution to get the seeded dashboard. We should fetch this json from the backend.
|
||||
const { dashboard, refetch } = useSeededDashboardV2();
|
||||
const { dashboard, isLoading, isError, error, refetch } = useSystemDashboard();
|
||||
|
||||
return (
|
||||
<div className={styles.overview} data-testid="llm-observability-overview">
|
||||
<DashboardContainer
|
||||
dashboard={dashboard}
|
||||
refetch={refetch}
|
||||
canEditDashboardOverride={false}
|
||||
/>
|
||||
{isLoading && <Spinner tip="Loading dashboard..." />}
|
||||
{!isLoading && (isError || !dashboard) && (
|
||||
<div className={styles.errorState}>
|
||||
<Typography.Title>Failed to load dashboard</Typography.Title>
|
||||
<Typography.Text>{(error as Error | null)?.message}</Typography.Text>
|
||||
</div>
|
||||
)}
|
||||
{!isLoading && !isError && dashboard && (
|
||||
<DashboardContainer
|
||||
dashboard={dashboard}
|
||||
refetch={refetch}
|
||||
canEditDashboardOverride={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { useQueryClient } from 'react-query';
|
||||
|
||||
import { getGetDashboardV2QueryKey } from 'api/generated/services/dashboard';
|
||||
import type {
|
||||
DashboardtypesGettableDashboardV2DTO,
|
||||
GetDashboardV2200,
|
||||
} from 'api/generated/services/sigNoz.schemas';
|
||||
|
||||
import dashboardV2Json from '../json/dashboard.json';
|
||||
|
||||
const dashboard =
|
||||
dashboardV2Json as unknown as DashboardtypesGettableDashboardV2DTO;
|
||||
|
||||
export interface UseSeededDashboardV2Result {
|
||||
dashboard: DashboardtypesGettableDashboardV2DTO;
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
const noop = (): void => {};
|
||||
|
||||
export function useSeededDashboardV2(): UseSeededDashboardV2Result {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const key = getGetDashboardV2QueryKey({ id: dashboard.id });
|
||||
if (queryClient.getQueryData<GetDashboardV2200>(key) === undefined) {
|
||||
queryClient.setQueryData<GetDashboardV2200>(key, {
|
||||
data: dashboard,
|
||||
status: 'success',
|
||||
});
|
||||
}
|
||||
|
||||
return { dashboard, refetch: noop };
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { useCallback, useMemo, useRef } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
|
||||
import {
|
||||
getGetDashboardV2QueryKey,
|
||||
useGetSystemDashboard,
|
||||
} from 'api/generated/services/dashboard';
|
||||
import type { GetSystemDashboardQueryError } from 'api/generated/services/dashboard';
|
||||
import type {
|
||||
DashboardtypesGettableDashboardV2DTO,
|
||||
GetDashboardV2200,
|
||||
} from 'api/generated/services/sigNoz.schemas';
|
||||
|
||||
const SYSTEM_DASHBOARD_NAME = 'ai-o11y-overview';
|
||||
|
||||
const DASHBOARD_ID = 'llm-observability-overview';
|
||||
|
||||
export interface UseSystemDashboardResult {
|
||||
dashboard: DashboardtypesGettableDashboardV2DTO | undefined;
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
error: GetSystemDashboardQueryError | null;
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
export function useSystemDashboard(): UseSystemDashboardResult {
|
||||
const queryClient = useQueryClient();
|
||||
const { data, isLoading, isError, error, refetch } = useGetSystemDashboard(
|
||||
{ name: SYSTEM_DASHBOARD_NAME },
|
||||
{ query: { staleTime: Infinity, refetchOnMount: false } },
|
||||
);
|
||||
|
||||
const dashboard = useMemo(
|
||||
() =>
|
||||
data
|
||||
? ({
|
||||
...data.data,
|
||||
id: DASHBOARD_ID,
|
||||
} as DashboardtypesGettableDashboardV2DTO)
|
||||
: undefined,
|
||||
[data],
|
||||
);
|
||||
|
||||
// Seed during render (not an effect) so the first Panel render already resolves the
|
||||
// dashboard from the cache. Re-seeds only on a new payload, so in-place cache
|
||||
// updates below (optimistic patches) survive re-renders.
|
||||
const seeded = useRef<DashboardtypesGettableDashboardV2DTO>();
|
||||
if (dashboard && seeded.current !== dashboard) {
|
||||
seeded.current = dashboard;
|
||||
queryClient.setQueryData<GetDashboardV2200>(
|
||||
getGetDashboardV2QueryKey({ id: DASHBOARD_ID }),
|
||||
{ data: dashboard, status: 'success' },
|
||||
);
|
||||
}
|
||||
|
||||
const refetchDashboard = useCallback((): void => {
|
||||
void refetch();
|
||||
}, [refetch]);
|
||||
|
||||
return { dashboard, isLoading, isError, error, refetch: refetchDashboard };
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,35 @@ jest.mock('container/LLMObservability/Explorer/Explorer', () => ({
|
||||
default: (): JSX.Element => <div data-testid="llm-observability-explorer" />,
|
||||
}));
|
||||
|
||||
const SYSTEM_DASHBOARD_ENDPOINT = '*/api/v2/dashboards/system/ai-o11y-overview';
|
||||
|
||||
function setupSystemDashboard(): void {
|
||||
server.use(
|
||||
rest.get(SYSTEM_DASHBOARD_ENDPOINT, (_req, res, ctx) =>
|
||||
res(
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
status: 'success',
|
||||
data: {
|
||||
orgId: 'org',
|
||||
locked: true,
|
||||
name: 'signoz---ai-o11y-overview',
|
||||
schemaVersion: 'v6',
|
||||
source: 'system',
|
||||
tags: null,
|
||||
spec: {
|
||||
display: { name: 'AI Observability Overview' },
|
||||
variables: [],
|
||||
panels: {},
|
||||
layouts: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function setupList(items = mockRules): void {
|
||||
server.use(
|
||||
rest.get(LLM_PRICING_ENDPOINT, (_req, res, ctx) =>
|
||||
@@ -41,14 +70,17 @@ describe('LLMObservability (integration)', () => {
|
||||
server.resetHandlers();
|
||||
});
|
||||
|
||||
it('renders the overview panel and the tab bar on the overview route', () => {
|
||||
it('renders the overview panel and the tab bar on the overview route', async () => {
|
||||
setupSystemDashboard();
|
||||
render(<LLMObservability />, undefined, {
|
||||
initialRoute: ROUTES.AI_OBSERVABILITY_OVERVIEW,
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('llm-observability-tabs')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('llm-observability-overview')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('llm-overview-dashboard')).toBeInTheDocument();
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('llm-overview-dashboard')).toBeInTheDocument(),
|
||||
);
|
||||
expect(screen.getByRole('tab', { name: 'Overview' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('tab', { name: 'Explorer' })).toBeInTheDocument();
|
||||
expect(
|
||||
|
||||
Reference in New Issue
Block a user