mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
refactor(ui): colocate the usage view, keeping the shared usage components (#32952)
Split for the usage (UsagePage) segment. Most of the folder is the usage page's own view, but four pieces are reused elsewhere and stay in @/components/UsagePage: TopKeyView (old-usage), KeyModelUsageView and value_formatters (activity_metrics), and the shared types (activity_metrics, chartUtils). The other 21 files move into usage/_components, preserving the folder structure. The external consumers import only the retained files, so they are untouched. The moved files' imports of the retained files become @/components/UsagePage paths, other escaping relative imports are absolutized, and lint suppressions are re-keyed for moved files only. No behavior change.
This commit is contained in:
parent
cb24864a7f
commit
ca877c78c3
23 changed files with 75 additions and 64 deletions
|
|
@ -1502,32 +1502,32 @@
|
|||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/EndpointUsage/components/EndpointUsageBarChart.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageBarChart.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/EndpointUsage/components/EndpointUsageLineChart.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageLineChart.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/EndpointUsage/components/EndpointUsageTable.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/EndpointUsage/components/EndpointUsageTable.tsx": {
|
||||
"no-nested-ternary": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/EntityUsage/EntityUsage.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/EntityUsage/EntityUsage.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/EntityUsage/SpendByProvider.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/EntityUsage/SpendByProvider.tsx": {
|
||||
"no-restricted-imports": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/UsageAIChatPanel.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/UsageAIChatPanel.tsx": {
|
||||
"no-nested-ternary": {
|
||||
"count": 1
|
||||
},
|
||||
|
|
@ -1535,7 +1535,7 @@
|
|||
"count": 1
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/components/UsagePageView.tsx": {
|
||||
"src/app/(dashboard)/usage/_components/components/UsagePageView.tsx": {
|
||||
"no-nested-ternary": {
|
||||
"count": 1
|
||||
},
|
||||
|
|
@ -1549,7 +1549,7 @@
|
|||
"count": 3
|
||||
}
|
||||
},
|
||||
"src/components/UsagePage/hooks/usePaginatedDailyActivity.ts": {
|
||||
"src/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity.ts": {
|
||||
"react-hooks/refs": {
|
||||
"count": 1
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React, { useMemo } from "react";
|
|||
import EndpointUsageBarChart from "./components/EndpointUsageBarChart";
|
||||
import EndpointUsageLineChart from "./components/EndpointUsageLineChart";
|
||||
import EndpointUsageTable from "./components/EndpointUsageTable";
|
||||
import { DailyData, MetricWithMetadata } from "../../types";
|
||||
import { DailyData, MetricWithMetadata } from "@/components/UsagePage/types";
|
||||
|
||||
interface EndpointUsageProps {
|
||||
userSpendData?: {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { BarChart, Card, Title } from "@tremor/react";
|
||||
import { CustomLegend, CustomTooltip } from "@/components/common_components/chartUtils";
|
||||
import { MetricWithMetadata } from "../../../types";
|
||||
import { MetricWithMetadata } from "@/components/UsagePage/types";
|
||||
|
||||
interface EndpointUsageBarChartProps {
|
||||
endpointData?: Record<string, MetricWithMetadata>;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { Card, LineChart, Title } from "@tremor/react";
|
||||
import { useMemo } from "react";
|
||||
import { DailyData } from "../../../types";
|
||||
import { DailyData } from "@/components/UsagePage/types";
|
||||
|
||||
interface EndpointUsageLineChartProps {
|
||||
dailyData?: { results: DailyData[] };
|
||||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import { Table, Progress } from "antd";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
import { MoneyCell } from "@/components/shared/table_cells";
|
||||
import { MetricWithMetadata } from "../../../types";
|
||||
import { MetricWithMetadata } from "@/components/UsagePage/types";
|
||||
|
||||
interface EndpointUsageTableProps {
|
||||
endpointData: Record<string, MetricWithMetadata>;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as networking from "../../../networking";
|
||||
import * as networking from "@/components/networking";
|
||||
import EntityUsage from "./EntityUsage";
|
||||
|
||||
beforeAll(() => {
|
||||
|
|
@ -14,7 +14,7 @@ beforeAll(() => {
|
|||
});
|
||||
|
||||
// Mock the networking module
|
||||
vi.mock("../../../networking", () => ({
|
||||
vi.mock("@/components/networking", () => ({
|
||||
tagDailyActivityCall: vi.fn(),
|
||||
teamDailyActivityCall: vi.fn(),
|
||||
organizationDailyActivityCall: vi.fn(),
|
||||
|
|
@ -24,12 +24,12 @@ vi.mock("../../../networking", () => ({
|
|||
}));
|
||||
|
||||
// Mock the child components to simplify testing
|
||||
vi.mock("../../../activity_metrics", () => ({
|
||||
vi.mock("@/components/activity_metrics", () => ({
|
||||
ActivityMetrics: () => <div>Activity Metrics</div>,
|
||||
processActivityData: () => ({ data: [], metadata: {} }),
|
||||
}));
|
||||
|
||||
vi.mock("./TopKeyView", () => ({
|
||||
vi.mock("@/components/UsagePage/components/EntityUsage/TopKeyView", () => ({
|
||||
default: () => <div>Top Keys</div>,
|
||||
}));
|
||||
|
||||
|
|
@ -37,15 +37,15 @@ vi.mock("./TopModelView", () => ({
|
|||
default: () => <div>Top Models</div>,
|
||||
}));
|
||||
|
||||
vi.mock("../../../EntityUsageExport/EntityUsageExportModal", () => ({
|
||||
vi.mock("@/components/EntityUsageExport/EntityUsageExportModal", () => ({
|
||||
default: () => <div>Entity Usage Export Modal</div>,
|
||||
}));
|
||||
|
||||
vi.mock("../../../EntityUsageExport", () => ({
|
||||
vi.mock("@/components/EntityUsageExport", () => ({
|
||||
UsageExportHeader: () => <div>Usage Export Header</div>,
|
||||
}));
|
||||
|
||||
vi.mock("../../../common_components/team_multi_select", () => ({
|
||||
vi.mock("@/components/common_components/team_multi_select", () => ({
|
||||
default: () => <div>Team Multi Select</div>,
|
||||
}));
|
||||
|
||||
|
|
@ -26,10 +26,10 @@ import {
|
|||
import { ExportOutlined, LoadingOutlined } from "@ant-design/icons";
|
||||
import { Alert, Button } from "antd";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import TeamMultiSelect from "../../../common_components/team_multi_select";
|
||||
import { ActivityMetrics, processActivityData } from "../../../activity_metrics";
|
||||
import { UsageExportHeader } from "../../../EntityUsageExport";
|
||||
import type { EntityType } from "../../../EntityUsageExport/types";
|
||||
import TeamMultiSelect from "@/components/common_components/team_multi_select";
|
||||
import { ActivityMetrics, processActivityData } from "@/components/activity_metrics";
|
||||
import { UsageExportHeader } from "@/components/EntityUsageExport";
|
||||
import type { EntityType } from "@/components/EntityUsageExport/types";
|
||||
import {
|
||||
agentDailyActivityCall,
|
||||
customerDailyActivityCall,
|
||||
|
|
@ -37,13 +37,19 @@ import {
|
|||
tagDailyActivityCall,
|
||||
teamDailyActivityCall,
|
||||
userDailyActivityCall,
|
||||
} from "../../../networking";
|
||||
import { getProviderLogoAndName } from "../../../provider_info_helpers";
|
||||
} from "@/components/networking";
|
||||
import { getProviderLogoAndName } from "@/components/provider_info_helpers";
|
||||
import { usePaginatedDailyActivity } from "../../hooks/usePaginatedDailyActivity";
|
||||
import { BreakdownMetrics, DailyData, EntityMetricWithMetadata, KeyMetricWithMetadata, TagUsage } from "../../types";
|
||||
import { valueFormatterSpend } from "../../utils/value_formatters";
|
||||
import {
|
||||
BreakdownMetrics,
|
||||
DailyData,
|
||||
EntityMetricWithMetadata,
|
||||
KeyMetricWithMetadata,
|
||||
TagUsage,
|
||||
} from "@/components/UsagePage/types";
|
||||
import { valueFormatterSpend } from "@/components/UsagePage/utils/value_formatters";
|
||||
import EndpointUsage from "../EndpointUsage/EndpointUsage";
|
||||
import TopKeyView from "./TopKeyView";
|
||||
import TopKeyView from "@/components/UsagePage/components/EntityUsage/TopKeyView";
|
||||
import TopModelView from "./TopModelView";
|
||||
|
||||
interface EntityMetrics {
|
||||
|
|
@ -2,13 +2,13 @@ import { fireEvent, render, screen } from "@testing-library/react";
|
|||
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||
import SpendByProvider from "./SpendByProvider";
|
||||
|
||||
vi.mock("../../../shared/chart_loader", () => ({
|
||||
vi.mock("@/components/shared/chart_loader", () => ({
|
||||
ChartLoader: ({ isDateChanging }: { isDateChanging: boolean }) => (
|
||||
<div data-testid="chart-loader">{isDateChanging ? "Processing date selection..." : "Loading chart data..."}</div>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock("../../../molecules/models/ProviderLogo", () => ({
|
||||
vi.mock("@/components/molecules/models/ProviderLogo", () => ({
|
||||
ProviderLogo: ({ provider }: { provider: string }) => <div data-testid={`provider-logo-${provider}`}>{provider}</div>,
|
||||
}));
|
||||
|
||||
|
|
@ -17,8 +17,8 @@ import {
|
|||
} from "@tremor/react";
|
||||
import { Tooltip } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { ProviderLogo } from "../../../molecules/models/ProviderLogo";
|
||||
import { ChartLoader } from "../../../shared/chart_loader";
|
||||
import { ProviderLogo } from "@/components/molecules/models/ProviderLogo";
|
||||
import { ChartLoader } from "@/components/shared/chart_loader";
|
||||
|
||||
type ProviderSpendData = {
|
||||
provider: string;
|
||||
|
|
@ -2,8 +2,8 @@ import { BarChart } from "@/components/shared/charts";
|
|||
import { MoneyCell } from "@/components/shared/table_cells";
|
||||
import { Segmented } from "antd";
|
||||
import { useState } from "react";
|
||||
import { formatNumberWithCommas } from "../../../../utils/dataUtils";
|
||||
import { DataTable } from "../../../view_logs/table";
|
||||
import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import { DataTable } from "@/components/view_logs/table";
|
||||
|
||||
type TopModel = {
|
||||
key: string;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { screen } from "@testing-library/react";
|
||||
import { beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { renderWithProviders } from "../../../../tests/test-utils";
|
||||
import { renderWithProviders } from "@/../tests/test-utils";
|
||||
import UsageAIChatPanel from "./UsageAIChatPanel";
|
||||
|
||||
beforeAll(() => {
|
||||
|
|
@ -13,7 +13,7 @@ beforeAll(() => {
|
|||
}
|
||||
});
|
||||
|
||||
vi.mock("../../networking", () => ({
|
||||
vi.mock("@/components/networking", () => ({
|
||||
modelHubCall: vi.fn().mockResolvedValue({
|
||||
data: [{ model_group: "gpt-4" }, { model_group: "claude-3-opus" }],
|
||||
}),
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { Button, Select, Input, Spin } from "antd";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { modelHubCall, usageAiChatStream, UsageAiToolCallEvent } from "../../networking";
|
||||
import { modelHubCall, usageAiChatStream, UsageAiToolCallEvent } from "@/components/networking";
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
|
|
@ -5,9 +5,9 @@ import { useCurrentUser } from "@/app/(dashboard)/hooks/users/useCurrentUser";
|
|||
import { useInfiniteUsers } from "@/app/(dashboard)/hooks/users/useUsers";
|
||||
import { act, fireEvent, screen, waitFor } from "@testing-library/react";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { renderWithProviders } from "../../../../tests/test-utils";
|
||||
import type { Organization } from "../../networking";
|
||||
import * as networking from "../../networking";
|
||||
import { renderWithProviders } from "@/../tests/test-utils";
|
||||
import type { Organization } from "@/components/networking";
|
||||
import * as networking from "@/components/networking";
|
||||
import UsagePage from "./UsagePageView";
|
||||
|
||||
// Polyfill ResizeObserver for test environment
|
||||
|
|
@ -22,23 +22,23 @@ beforeAll(() => {
|
|||
});
|
||||
|
||||
// Mock the networking module
|
||||
vi.mock("../../networking", () => ({
|
||||
vi.mock("@/components/networking", () => ({
|
||||
userDailyActivityCall: vi.fn(),
|
||||
userDailyActivityAggregatedCall: vi.fn(),
|
||||
tagListCall: vi.fn(),
|
||||
}));
|
||||
|
||||
// Mock child components to simplify testing
|
||||
vi.mock("../../activity_metrics", () => ({
|
||||
vi.mock("@/components/activity_metrics", () => ({
|
||||
ActivityMetrics: () => <div>Activity Metrics</div>,
|
||||
processActivityData: () => ({ data: [], metadata: {} }),
|
||||
}));
|
||||
|
||||
vi.mock("../../view_user_spend", () => ({
|
||||
vi.mock("@/components/view_user_spend", () => ({
|
||||
default: () => <div>View User Spend</div>,
|
||||
}));
|
||||
|
||||
vi.mock("./EntityUsage/TopKeyView", () => ({
|
||||
vi.mock("@/components/UsagePage/components/EntityUsage/TopKeyView", () => ({
|
||||
default: () => <div>Top Keys</div>,
|
||||
}));
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ vi.mock("./UsageViewSelect/UsageViewSelect", async () => {
|
|||
return { UsageViewSelect };
|
||||
});
|
||||
|
||||
vi.mock("../../shared/advanced_date_picker", async () => {
|
||||
vi.mock("@/components/shared/advanced_date_picker", async () => {
|
||||
const React = await import("react");
|
||||
const AdvancedDatePicker = () => {
|
||||
return React.createElement("div", { "data-testid": "advanced-date-picker" }, "Date Picker");
|
||||
|
|
@ -89,15 +89,15 @@ vi.mock("../../shared/advanced_date_picker", async () => {
|
|||
return { default: AdvancedDatePicker };
|
||||
});
|
||||
|
||||
vi.mock("../../user_agent_activity", () => ({
|
||||
vi.mock("@/components/user_agent_activity", () => ({
|
||||
default: () => <div>User Agent Activity</div>,
|
||||
}));
|
||||
|
||||
vi.mock("../../cloudzero_export_modal", () => ({
|
||||
vi.mock("@/components/cloudzero_export_modal", () => ({
|
||||
default: () => <div>CloudZero Export Modal</div>,
|
||||
}));
|
||||
|
||||
vi.mock("../../EntityUsageExport", () => ({
|
||||
vi.mock("@/components/EntityUsageExport", () => ({
|
||||
default: () => <div>Entity Usage Export Modal</div>,
|
||||
}));
|
||||
|
||||
|
|
@ -33,24 +33,29 @@ import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
|||
import { useCurrentUser } from "@/app/(dashboard)/hooks/users/useCurrentUser";
|
||||
import { useInfiniteUsers } from "@/app/(dashboard)/hooks/users/useUsers";
|
||||
import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import { all_admin_roles, internalUserRoles } from "../../../utils/roles";
|
||||
import { ActivityMetrics, processActivityData } from "../../activity_metrics";
|
||||
import CloudZeroExportModal from "../../cloudzero_export_modal";
|
||||
import EntityUsageExportModal from "../../EntityUsageExport";
|
||||
import { Team } from "../../key_team_helpers/key_list";
|
||||
import { Organization, tagListCall, userDailyActivityAggregatedCall, userDailyActivityCall } from "../../networking";
|
||||
import AdvancedDatePicker from "../../shared/advanced_date_picker";
|
||||
import { ChartLoader } from "../../shared/chart_loader";
|
||||
import { Tag } from "../../tag_management/types";
|
||||
import UserAgentActivity from "../../user_agent_activity";
|
||||
import ViewUserSpend from "../../view_user_spend";
|
||||
import { all_admin_roles, internalUserRoles } from "@/utils/roles";
|
||||
import { ActivityMetrics, processActivityData } from "@/components/activity_metrics";
|
||||
import CloudZeroExportModal from "@/components/cloudzero_export_modal";
|
||||
import EntityUsageExportModal from "@/components/EntityUsageExport";
|
||||
import { Team } from "@/components/key_team_helpers/key_list";
|
||||
import {
|
||||
Organization,
|
||||
tagListCall,
|
||||
userDailyActivityAggregatedCall,
|
||||
userDailyActivityCall,
|
||||
} from "@/components/networking";
|
||||
import AdvancedDatePicker from "@/components/shared/advanced_date_picker";
|
||||
import { ChartLoader } from "@/components/shared/chart_loader";
|
||||
import { Tag } from "@/components/tag_management/types";
|
||||
import UserAgentActivity from "@/components/user_agent_activity";
|
||||
import ViewUserSpend from "@/components/view_user_spend";
|
||||
import { usePaginatedDailyActivity } from "../hooks/usePaginatedDailyActivity";
|
||||
import { DailyData, KeyMetricWithMetadata, MetricWithMetadata } from "../types";
|
||||
import { valueFormatterSpend } from "../utils/value_formatters";
|
||||
import { DailyData, KeyMetricWithMetadata, MetricWithMetadata } from "@/components/UsagePage/types";
|
||||
import { valueFormatterSpend } from "@/components/UsagePage/utils/value_formatters";
|
||||
import EndpointUsage from "./EndpointUsage/EndpointUsage";
|
||||
import EntityUsage, { EntityList } from "./EntityUsage/EntityUsage";
|
||||
import SpendByProvider from "./EntityUsage/SpendByProvider";
|
||||
import TopKeyView from "./EntityUsage/TopKeyView";
|
||||
import TopKeyView from "@/components/UsagePage/components/EntityUsage/TopKeyView";
|
||||
import UsageAIChatPanel from "./UsageAIChatPanel";
|
||||
import { UsageOption, UsageViewSelect } from "./UsageViewSelect/UsageViewSelect";
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { DailyData } from "../types";
|
||||
import { DailyData } from "@/components/UsagePage/types";
|
||||
|
||||
export interface PaginationProgress {
|
||||
currentPage: number;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import NewUsagePage from "@/components/UsagePage/components/UsagePageView";
|
||||
import NewUsagePage from "./_components/components/UsagePageView";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import { useTeams } from "@/app/(dashboard)/hooks/teams/useTeams";
|
||||
import { useOrganizations } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue