mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-17 04:34:25 +00:00
fix(ui): drop deprecation banners from kept features and make the rest permanent (#46314)
* fix(ui): drop deprecation banners from kept features and make the rest permanent * test(ui): pin deprecation banner copy, dismissal and kept-feature absence * fix(ui): point deprecation banner at the discussion instead of asking for feedback * test(ui): drop copy-pinning and removed-banner absence tests * refactor(ui): build the deprecation banner on the shadcn Alert primitive
This commit is contained in:
parent
29202d2b50
commit
bdc0893c28
8 changed files with 25 additions and 97 deletions
|
|
@ -14,7 +14,6 @@ import {
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
|
||||
import { DeprecationBanner } from "@/components/DeprecationBanner";
|
||||
import { toast } from "@/lib/toast";
|
||||
import {
|
||||
getGeneralSettingsCall,
|
||||
|
|
@ -317,7 +316,6 @@ const MCPNetworkSettings: React.FC<MCPNetworkSettingsProps> = ({ accessToken })
|
|||
|
||||
return (
|
||||
<div className="space-y-6 p-4">
|
||||
<DeprecationBanner featureName="MCP Network Settings and the internal-network-only flag" />
|
||||
<div>
|
||||
<p className="text-lg font-semibold">Private IP Ranges</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
|
|
|
|||
|
|
@ -49,10 +49,4 @@ describe("Memory page access by role", () => {
|
|||
await waitFor(() => expect(requestedUrls().filter((url) => url.includes("/v1/memory"))).toEqual([]));
|
||||
},
|
||||
);
|
||||
|
||||
it("hides the deprecation banner along with the page body for a denied role", () => {
|
||||
renderAs("Internal User");
|
||||
|
||||
expect(screen.queryByText(/draft deprecation list/i)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { MemoryView } from "./_components/MemoryView";
|
||||
import { DeprecationBanner } from "@/components/DeprecationBanner";
|
||||
import { AdminOnlyNotice } from "@/components/shared/AdminOnlyNotice";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import useCan from "@/app/(dashboard)/hooks/useCan";
|
||||
|
|
@ -14,10 +13,5 @@ export default function Memory() {
|
|||
return <AdminOnlyNotice pageTitle="Memory" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<DeprecationBanner featureName="Memory" />
|
||||
<MemoryView accessToken={accessToken} userID={userId} userRole={userRole} />
|
||||
</>
|
||||
);
|
||||
return <MemoryView accessToken={accessToken} userID={userId} userRole={userRole} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import CompareUI from "@/app/(dashboard)/playground/components/compareUI/Compare
|
|||
import ComplianceUI from "@/app/(dashboard)/playground/components/complianceUI/ComplianceUI";
|
||||
import SystemOneUI from "@/app/(dashboard)/playground/components/systemOneUI/SystemOneUI";
|
||||
import BetaBadge from "@/components/BetaBadge";
|
||||
import { DeprecationBanner } from "@/components/DeprecationBanner";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
import { fetchProxySettings } from "@/utils/proxyUtils";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
|
|
@ -100,7 +99,6 @@ export default function PlaygroundPage() {
|
|||
<SystemOneUI accessToken={accessToken} disabledPersonalKeyCreation={disabledPersonalKeyCreation} />
|
||||
</TabsContent>
|
||||
<TabsContent value="agent-builder" className="mt-0 h-full data-hidden:hidden" keepMounted>
|
||||
<DeprecationBanner featureName="The Playground's Agent Builder" />
|
||||
<AgentBuilderView
|
||||
accessToken={accessToken}
|
||||
token={token}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import PromptsPanel from "./_components";
|
||||
import { DeprecationBanner } from "@/components/DeprecationBanner";
|
||||
import useAuthorized from "@/app/(dashboard)/hooks/useAuthorized";
|
||||
|
||||
export default function Prompts() {
|
||||
const { accessToken, userRole } = useAuthorized();
|
||||
return (
|
||||
<>
|
||||
<DeprecationBanner featureName="Prompt Management" />
|
||||
<PromptsPanel accessToken={accessToken} userRole={userRole} />
|
||||
</>
|
||||
);
|
||||
return <PromptsPanel accessToken={accessToken} userRole={userRole} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ describe("Workflows page access by role", () => {
|
|||
},
|
||||
);
|
||||
|
||||
it("hides the deprecation banner along with the page body for a denied role", () => {
|
||||
renderAs("Internal User");
|
||||
it("shows an admin the deprecation notice", () => {
|
||||
renderAs("Admin");
|
||||
|
||||
expect(screen.queryByText(/draft deprecation list/i)).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("alert")).toHaveTextContent("Workflows");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,44 +1,20 @@
|
|||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { DeprecationBanner } from "./DeprecationBanner";
|
||||
|
||||
describe("DeprecationBanner", () => {
|
||||
it("names the deprecated feature in the heading and the body", () => {
|
||||
render(<DeprecationBanner featureName="Memory" />);
|
||||
it("names the deprecated feature", () => {
|
||||
render(<DeprecationBanner featureName="Workflows" />);
|
||||
|
||||
expect(screen.getByText("Memory is on a draft deprecation list")).toBeInTheDocument();
|
||||
expect(screen.getByText(/Memory is one of several experimental features/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("states the target removal date and that the list is not final", () => {
|
||||
render(<DeprecationBanner featureName="Memory" />);
|
||||
|
||||
expect(screen.getByText(/as early as September 1, 2026/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/This list is a draft and is not final/)).toBeInTheDocument();
|
||||
expect(screen.getByRole("alert")).toHaveTextContent("Workflows");
|
||||
});
|
||||
|
||||
it("links to the deprecation discussion in a new tab without leaking the opener", () => {
|
||||
render(<DeprecationBanner featureName="Memory" />);
|
||||
render(<DeprecationBanner featureName="Workflows" />);
|
||||
|
||||
const link = screen.getByRole("link", { name: "deprecation discussion" });
|
||||
expect(link).toHaveAttribute("href", "https://github.com/BerriAI/litellm/discussions/32090");
|
||||
expect(link).toHaveAttribute("target", "_blank");
|
||||
expect(link).toHaveAttribute("rel", "noopener noreferrer");
|
||||
});
|
||||
|
||||
it("exposes a named close control", () => {
|
||||
render(<DeprecationBanner featureName="Memory" />);
|
||||
|
||||
expect(screen.getByRole("button", { name: /close/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("hides the banner once the close control is used", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<DeprecationBanner featureName="Memory" />);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /close/i }));
|
||||
|
||||
expect(screen.queryByText("Memory is on a draft deprecation list")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,52 +1,26 @@
|
|||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
import Link from "next/link";
|
||||
import { Info, X } from "lucide-react";
|
||||
import { Info } from "lucide-react";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
|
||||
const DEPRECATION_DISCUSSION_URL = "https://github.com/BerriAI/litellm/discussions/32090";
|
||||
const DEPRECATION_TARGET_DATE = "September 1, 2026";
|
||||
|
||||
interface DeprecationBannerProps {
|
||||
featureName: string;
|
||||
}
|
||||
|
||||
export const DeprecationBanner: React.FC<DeprecationBannerProps> = ({ featureName }) => {
|
||||
const [isClosed, setIsClosed] = useState(false);
|
||||
|
||||
if (isClosed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="alert"
|
||||
className="mb-4 flex items-start gap-3 rounded-lg border border-border bg-muted/50 px-4 py-3 text-sm"
|
||||
>
|
||||
<Info className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="font-medium">{`${featureName} is on a draft deprecation list`}</p>
|
||||
<p className="mt-1 break-words text-muted-foreground">
|
||||
{`${featureName} is one of several experimental features we're considering removing, potentially as early as ${DEPRECATION_TARGET_DATE}. This list is a draft and is not final. If you rely on this feature, please share feedback on the `}
|
||||
<Link
|
||||
href={DEPRECATION_DISCUSSION_URL}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="underline underline-offset-4"
|
||||
>
|
||||
deprecation discussion
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Close"
|
||||
onClick={() => setIsClosed(true)}
|
||||
className="shrink-0 rounded-md p-0.5 text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
<X className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const DeprecationBanner: React.FC<DeprecationBannerProps> = ({ featureName }) => (
|
||||
<Alert className="mb-4">
|
||||
<Info />
|
||||
<AlertTitle>{`${featureName} is deprecated`}</AlertTitle>
|
||||
<AlertDescription>
|
||||
{`${featureName} will be removed in the near future. See the `}
|
||||
<Link href={DEPRECATION_DISCUSSION_URL} target="_blank" rel="noopener noreferrer">
|
||||
deprecation discussion
|
||||
</Link>
|
||||
{" for details."}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue