diff --git a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts index 38b9a87582..f2a8fc45f1 100644 --- a/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts +++ b/ui/litellm-dashboard/e2e_tests/fixtures/migratedPages.ts @@ -10,16 +10,18 @@ * * Keep this in lockstep with MIGRATED_PAGES in src/utils/migratedPages.ts. * Pending (add as each PR lands): the leaf-pages batch - * (budgets, caching, cost-tracking, guardrails, guardrails-monitor, logs, - * mcp-servers, memory, policies, prompts, search-tools, skills, - * tag-management, tool-policies, transform-request, ui-theme, vector-stores, - * workflows). + * (caching, cost-tracking, guardrails, logs, mcp-servers, memory, + * policies, prompts, search-tools, skills, tag-management, tool-policies, + * transform-request, ui-theme, vector-stores). */ export const MIGRATED_E2E_PAGES: Record = { api_ref: "api-reference", "llm-playground": "playground", projects: "projects", "access-groups": "access-groups", + budgets: "budgets", + workflows: "workflows", + "guardrails-monitor": "guardrails-monitor", }; export const MIGRATED_E2E_SEGMENTS: string[] = [...new Set(Object.values(MIGRATED_E2E_PAGES))]; diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json index 8f865915e4..9f7c2e5c38 100644 --- a/ui/litellm-dashboard/eslint-suppressions.json +++ b/ui/litellm-dashboard/eslint-suppressions.json @@ -419,22 +419,22 @@ "count": 1 } }, - "src/components/GuardrailsMonitor/EvaluationSettingsModal.tsx": { + "src/app/(dashboard)/guardrails-monitor/components/EvaluationSettingsModal.tsx": { "react-hooks/set-state-in-effect": { "count": 1 } }, - "src/components/GuardrailsMonitor/GuardrailsMonitorView.tsx": { + "src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/GuardrailsMonitor/ScoreChart.test.tsx": { + "src/app/(dashboard)/guardrails-monitor/components/ScoreChart.test.tsx": { "react/display-name": { "count": 1 } }, - "src/components/GuardrailsMonitor/ScoreChart.tsx": { + "src/app/(dashboard)/guardrails-monitor/components/ScoreChart.tsx": { "no-restricted-imports": { "count": 1 } @@ -798,22 +798,22 @@ "count": 1 } }, - "src/components/budgets/budget_modal.tsx": { + "src/app/(dashboard)/budgets/components/budget_modal.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/budgets/budget_panel.test.tsx": { + "src/app/(dashboard)/budgets/components/budget_panel.test.tsx": { "unused-imports/no-unused-imports": { "count": 2 } }, - "src/components/budgets/budget_panel.tsx": { + "src/app/(dashboard)/budgets/components/budget_panel.tsx": { "no-restricted-imports": { "count": 1 } }, - "src/components/budgets/edit_budget_modal.tsx": { + "src/app/(dashboard)/budgets/components/edit_budget_modal.tsx": { "no-restricted-imports": { "count": 1 } @@ -2163,7 +2163,7 @@ "count": 1 } }, - "src/components/workflow_runs/index.tsx": { + "src/app/(dashboard)/workflows/WorkflowRuns.tsx": { "no-restricted-syntax": { "count": 3 }, diff --git a/ui/litellm-dashboard/src/components/budgets/budget_modal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_modal.tsx similarity index 97% rename from ui/litellm-dashboard/src/components/budgets/budget_modal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_modal.tsx index b5ad8aaff3..b4658aa999 100644 --- a/ui/litellm-dashboard/src/components/budgets/budget_modal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_modal.tsx @@ -2,7 +2,7 @@ import React from "react"; import { TextInput, Accordion, AccordionHeader, AccordionBody } from "@tremor/react"; import { Button as Button2, Modal, Form, InputNumber, Select } from "antd"; import { useCreateBudget } from "@/app/(dashboard)/hooks/budgets/useBudgets"; -import NotificationsManager from "../molecules/notifications_manager"; +import NotificationsManager from "@/components/molecules/notifications_manager"; interface BudgetModalProps { isModalVisible: boolean; diff --git a/ui/litellm-dashboard/src/components/budgets/budget_panel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/budgets/budget_panel.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.test.tsx diff --git a/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx similarity index 93% rename from ui/litellm-dashboard/src/components/budgets/budget_panel.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx index 744fac64a1..0e601645c2 100644 --- a/ui/litellm-dashboard/src/components/budgets/budget_panel.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/budget_panel.tsx @@ -21,10 +21,10 @@ import { } from "@tremor/react"; import React, { useState } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; -import DeleteResourceModal from "../common_components/DeleteResourceModal"; -import TableIconActionButton from "../common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; -import NotificationsManager from "../molecules/notifications_manager"; -import { useBudgets, useDeleteBudget } from "@/app/(dashboard)/hooks/budgets/useBudgets"; +import DeleteResourceModal from "@/components/common_components/DeleteResourceModal"; +import TableIconActionButton from "@/components/common_components/IconActionButton/TableIconActionButtons/TableIconActionButton"; +import NotificationsManager from "@/components/molecules/notifications_manager"; +import { useBudgets, useDeleteBudget, budgetItem } from "@/app/(dashboard)/hooks/budgets/useBudgets"; import BudgetModal from "./budget_modal"; import EditBudgetModal from "./edit_budget_modal"; import { CREATE_END_USER_CURL_COMMAND, CHAT_COMPLETIONS_CURL_COMMAND, OPENAI_SDK_PYTHON_CODE } from "./constants"; @@ -35,14 +35,6 @@ interface BudgetSettingsPageProps { accessToken: string | null; } -export interface budgetItem { - budget_id: string; - max_budget: number | null; - rpm_limit: number | null; - tpm_limit: number | null; - updated_at: string; -} - const BudgetPanel: React.FC = ({ accessToken }) => { const [isCreateModelVisible, setIsCreateModelVisible] = useState(false); const [isEditModalVisible, setIsEditModalVisible] = useState(false); diff --git a/ui/litellm-dashboard/src/components/budgets/constants.ts b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/constants.ts similarity index 100% rename from ui/litellm-dashboard/src/components/budgets/constants.ts rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/components/constants.ts diff --git a/ui/litellm-dashboard/src/components/budgets/edit_budget_modal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/edit_budget_modal.tsx similarity index 95% rename from ui/litellm-dashboard/src/components/budgets/edit_budget_modal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/budgets/components/edit_budget_modal.tsx index 8b95a8366f..98a6996948 100644 --- a/ui/litellm-dashboard/src/components/budgets/edit_budget_modal.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/components/edit_budget_modal.tsx @@ -2,8 +2,8 @@ import React, { useEffect } from "react"; import { TextInput, Accordion, AccordionHeader, AccordionBody } from "@tremor/react"; import { Button as Button2, Modal, Form, InputNumber, Select } from "antd"; import { useUpdateBudget } from "@/app/(dashboard)/hooks/budgets/useBudgets"; -import { budgetItem } from "./budget_panel"; -import NotificationsManager from "../molecules/notifications_manager"; +import { budgetItem } from "@/app/(dashboard)/hooks/budgets/useBudgets"; +import NotificationsManager from "@/components/molecules/notifications_manager"; interface EditBudgetModalProps { isModalVisible: boolean; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx new file mode 100644 index 0000000000..547699411e --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/budgets/page.tsx @@ -0,0 +1,9 @@ +"use client"; + +import BudgetPanel from "./components/budget_panel"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; + +export default function Budgets() { + const { accessToken } = useAuthorized(); + return ; +} diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/EvaluationSettingsModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/EvaluationSettingsModal.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/EvaluationSettingsModal.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/EvaluationSettingsModal.tsx diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailConfig.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailConfig.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailConfig.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailConfig.test.tsx diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailConfig.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailConfig.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailConfig.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailConfig.tsx diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailDetail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailDetail.tsx similarity index 97% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailDetail.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailDetail.tsx index 2d0d5710f8..1d959ccca9 100644 --- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailDetail.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailDetail.tsx @@ -4,9 +4,9 @@ import { Button, Col, Row, Spin, Tabs } from "antd"; import React, { useMemo, useState } from "react"; import { getGuardrailsUsageDetail, getGuardrailsUsageLogs } from "@/components/networking"; import { EvaluationSettingsModal } from "./EvaluationSettingsModal"; -import { LogViewer } from "./LogViewer"; -import { MetricCard } from "./MetricCard"; -import type { LogEntry } from "./mockData"; +import { LogViewer } from "@/components/GuardrailsMonitor/LogViewer"; +import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard"; +import type { LogEntry } from "@/components/GuardrailsMonitor/mockData"; interface GuardrailDetailProps { guardrailId: string; diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsMonitorView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.test.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsMonitorView.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.test.tsx diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsMonitorView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsMonitorView.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsMonitorView.tsx diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsOverview.tsx similarity index 98% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsOverview.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsOverview.tsx index 076ab13496..519c5e1789 100644 --- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/GuardrailsOverview.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/GuardrailsOverview.tsx @@ -4,9 +4,9 @@ import { Button, Card, Col, Row, Spin, Table, Typography } from "antd"; import type { ColumnsType } from "antd/es/table"; import React, { useMemo, useState } from "react"; import { getGuardrailsUsageOverview } from "@/components/networking"; -import { type PerformanceRow } from "./mockData"; +import { type PerformanceRow } from "@/components/GuardrailsMonitor/mockData"; import { EvaluationSettingsModal } from "./EvaluationSettingsModal"; -import { MetricCard } from "./MetricCard"; +import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard"; import { ScoreChart } from "./ScoreChart"; interface GuardrailsOverviewProps { diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/ScoreChart.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/ScoreChart.test.tsx similarity index 96% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/ScoreChart.test.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/ScoreChart.test.tsx index 934d4ea394..3a36eb9621 100644 --- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/ScoreChart.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/ScoreChart.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { describe, it, expect, vi } from "vitest"; import { screen } from "@testing-library/react"; -import { renderWithProviders } from "../../../tests/test-utils"; +import { renderWithProviders } from "../../../../../tests/test-utils"; import { ScoreChart } from "./ScoreChart"; vi.mock("@tremor/react", async (importOriginal) => { diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/ScoreChart.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/ScoreChart.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/GuardrailsMonitor/ScoreChart.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/components/ScoreChart.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.tsx new file mode 100644 index 0000000000..388ed168f1 --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.tsx @@ -0,0 +1,9 @@ +"use client"; + +import GuardrailsMonitorView from "./components/GuardrailsMonitorView"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; + +export default function GuardrailsMonitor() { + const { accessToken } = useAuthorized(); + return ; +} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/budgets/useBudgets.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/budgets/useBudgets.ts index 99c170b679..0d8d94f236 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/budgets/useBudgets.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/budgets/useBudgets.ts @@ -2,7 +2,14 @@ import { useQuery, useMutation, useQueryClient, UseQueryResult } from "@tanstack import { createQueryKeys } from "../common/queryKeysFactory"; import { getBudgetList, budgetCreateCall, budgetUpdateCall, budgetDeleteCall } from "@/components/networking"; import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; -import { budgetItem } from "@/components/budgets/budget_panel"; + +export interface budgetItem { + budget_id: string; + max_budget: number | null; + rpm_limit: number | null; + tpm_limit: number | null; + updated_at: string; +} export const budgetKeys = createQueryKeys("budgets"); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/page.tsx index f0dddec39a..0bf79f492f 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/page.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/page.tsx @@ -3,7 +3,6 @@ import ModelsAndEndpointsView from "@/app/(dashboard)/models-and-endpoints/ModelsAndEndpointsView"; import AdminPanel from "@/components/AdminPanel"; import AgentsPanel from "@/components/agents"; -import BudgetPanel from "@/components/budgets/budget_panel"; import CacheDashboard from "@/components/cache_dashboard"; import ClaudeCodePluginsPanel from "@/components/claude_code_plugins"; import { teamListCall as v2TeamListCall } from "@/app/(dashboard)/hooks/teams/useTeams"; @@ -12,7 +11,6 @@ import useProxySettings from "@/app/(dashboard)/hooks/proxySettings/useProxySett import LoadingScreen from "@/components/common_components/LoadingScreen"; import { CostTrackingSettings } from "@/components/CostTrackingSettings"; import GeneralSettings from "@/components/general_settings"; -import GuardrailsMonitorView from "@/components/GuardrailsMonitor/GuardrailsMonitorView"; import GuardrailsPanel from "@/components/guardrails"; import PoliciesPanel from "@/components/policies"; import { Team } from "@/components/key_team_helpers/key_list"; @@ -37,7 +35,6 @@ import UserDashboard from "@/components/user_dashboard"; import VectorStoreManagement from "@/components/vector_store_management"; import ToolPoliciesView from "@/components/ToolPoliciesView"; import { MemoryView } from "@/components/MemoryView"; -import WorkflowRuns from "@/components/workflow_runs"; import SpendLogsTable from "@/components/view_logs"; import ViewUserDashboard from "@/components/view_users"; import { useAuth } from "@/contexts/AuthContext"; @@ -385,8 +382,6 @@ function CreateKeyPageContent() { ) : page == "logging-and-alerts" ? ( - ) : page == "budgets" ? ( - ) : page == "guardrails" ? ( ) : page == "policies" ? ( @@ -450,12 +445,8 @@ function CreateKeyPageContent() { ) : page == "tool-policies" ? ( - ) : page == "workflows" ? ( - ) : page == "memory" ? ( - ) : page == "guardrails-monitor" ? ( - ) : page == "new_usage" ? ( ) : ( diff --git a/ui/litellm-dashboard/src/components/workflow_runs/index.tsx b/ui/litellm-dashboard/src/app/(dashboard)/workflows/WorkflowRuns.tsx similarity index 100% rename from ui/litellm-dashboard/src/components/workflow_runs/index.tsx rename to ui/litellm-dashboard/src/app/(dashboard)/workflows/WorkflowRuns.tsx diff --git a/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.tsx b/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.tsx new file mode 100644 index 0000000000..4b3d88f44f --- /dev/null +++ b/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.tsx @@ -0,0 +1,9 @@ +"use client"; + +import WorkflowRuns from "./WorkflowRuns"; +import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized"; + +export default function Workflows() { + const { accessToken } = useAuthorized(); + return ; +} diff --git a/ui/litellm-dashboard/src/utils/migratedPages.test.ts b/ui/litellm-dashboard/src/utils/migratedPages.test.ts index b8d7af55fe..e837cd33b3 100644 --- a/ui/litellm-dashboard/src/utils/migratedPages.test.ts +++ b/ui/litellm-dashboard/src/utils/migratedPages.test.ts @@ -55,6 +55,15 @@ describe("migratedHref / legacyPageHref", () => { expect(MIGRATED_PAGES.projects).toBe("projects"); expect(MIGRATED_PAGES["access-groups"]).toBe("access-groups"); }); + + it("maps the budgets, workflows, and guardrails-monitor sidebar ids to their routes", async () => { + vi.doMock("@/components/networking", () => ({ serverRootPath: "/" })); + const { MIGRATED_PAGES } = await import("./migratedPages"); + + expect(MIGRATED_PAGES.budgets).toBe("budgets"); + expect(MIGRATED_PAGES.workflows).toBe("workflows"); + expect(MIGRATED_PAGES["guardrails-monitor"]).toBe("guardrails-monitor"); + }); }); describe("dev server (NODE_ENV=development)", () => { diff --git a/ui/litellm-dashboard/src/utils/migratedPages.ts b/ui/litellm-dashboard/src/utils/migratedPages.ts index b0a570d059..1ab854f582 100644 --- a/ui/litellm-dashboard/src/utils/migratedPages.ts +++ b/ui/litellm-dashboard/src/utils/migratedPages.ts @@ -15,6 +15,9 @@ export const MIGRATED_PAGES: Record = { "llm-playground": "playground", projects: "projects", "access-groups": "access-groups", + budgets: "budgets", + workflows: "workflows", + "guardrails-monitor": "guardrails-monitor", }; function uiBase(): string {