mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-06 08:16:43 +00:00
fix(ui): stamp the tag list with the range it answers
Changing the date range left the previous range's tags in state until the new request landed, so the filter either offered tags that range no longer has or, when the old range was empty, stated "no tags" about a range nobody had measured yet. Stamp the fetched list with its range key and select it during render, the same way the request tiles above already guard against a superseded range. Clearing in the effect would be a render too late.
This commit is contained in:
parent
13b5c80c90
commit
beed32eb60
2 changed files with 48 additions and 5 deletions
|
|
@ -610,6 +610,42 @@ describe("UsagePage", () => {
|
|||
expect(screen.getByTestId("entity-usage")).toHaveAttribute("data-entity-list", "[]");
|
||||
});
|
||||
|
||||
it("should drop the previous range's tags as soon as the range changes", async () => {
|
||||
mockTagListCall.mockResolvedValue({ "old-range-tag": { name: "old-range-tag" } } as never);
|
||||
|
||||
renderWithProviders(<UsagePage {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.change(screen.getByTestId("usage-view-select"), { target: { value: "tag" } });
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("entity-usage")).toHaveAttribute(
|
||||
"data-entity-list",
|
||||
JSON.stringify([{ label: "old-range-tag", value: "old-range-tag" }]),
|
||||
);
|
||||
});
|
||||
|
||||
let resolveNewRange: (tags: Record<string, unknown>) => void = () => {};
|
||||
mockTagListCall.mockReturnValue(
|
||||
new Promise((resolve) => {
|
||||
resolveNewRange = resolve;
|
||||
}) as ReturnType<typeof networking.tagListCall>,
|
||||
);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByTestId("pick-a-different-range"));
|
||||
});
|
||||
|
||||
expect(screen.getByTestId("entity-usage")).toHaveAttribute("data-entity-list", "null");
|
||||
|
||||
await act(async () => {
|
||||
resolveNewRange({});
|
||||
});
|
||||
|
||||
expect(screen.getByTestId("entity-usage")).toHaveAttribute("data-entity-list", "[]");
|
||||
});
|
||||
|
||||
it("should show tag usage selector option for internal users", async () => {
|
||||
mockUseAuthorized.mockReturnValue({
|
||||
isLoading: false,
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
to: initialToDate,
|
||||
});
|
||||
|
||||
const [allTags, setAllTags] = useState<EntityList[] | null>(null);
|
||||
const [fetchedTags, setFetchedTags] = useState<FetchedForRange<EntityList[]> | null>(null);
|
||||
const { data: customers = [] } = useCustomers();
|
||||
const { data: agentsResponse } = useAgents();
|
||||
const { data: currentUser } = useCurrentUser();
|
||||
|
|
@ -138,6 +138,12 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
const startTime = useMemo(() => (dateValue.from ? new Date(dateValue.from) : null), [dateValue.from]);
|
||||
const endTime = useMemo(() => (dateValue.to ? new Date(dateValue.to) : null), [dateValue.to]);
|
||||
|
||||
// Stamped and selected during render like the request tiles below: the tag
|
||||
// filter reads "no tags" from an empty list, so a list left over from the
|
||||
// previous range would state that about a range nobody has measured yet.
|
||||
const currentTagRangeKey = fetchedRangeKey(startTime, endTime);
|
||||
const allTags = selectForRange(fetchedTags, currentTagRangeKey);
|
||||
|
||||
useEffect(() => {
|
||||
if (!accessToken) return;
|
||||
let cancelled = false;
|
||||
|
|
@ -145,12 +151,13 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
try {
|
||||
const tags = await tagListCall(accessToken, startTime, endTime);
|
||||
if (cancelled) return;
|
||||
setAllTags(
|
||||
Object.values(tags).map((tag: Tag) => ({
|
||||
setFetchedTags({
|
||||
rangeKey: currentTagRangeKey,
|
||||
value: Object.values(tags).map((tag: Tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.name,
|
||||
})),
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
if (!cancelled) {
|
||||
console.error("Failed to fetch tag list", e);
|
||||
|
|
@ -160,7 +167,7 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [accessToken, startTime, endTime]);
|
||||
}, [accessToken, startTime, endTime, currentTagRangeKey]);
|
||||
|
||||
// Everything the request tiles read is stamped with the range it answers and
|
||||
// selected during render, rather than cleared in an effect. An effect runs
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue