mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
fix(ui): keep alert save disabled while a save is in flight
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
5ae1ee088d
commit
f19bd2a6f1
2 changed files with 42 additions and 1 deletions
|
|
@ -613,6 +613,43 @@ describe("Settings", () => {
|
|||
expect(savedSettings).not.toHaveProperty("alert_types");
|
||||
});
|
||||
|
||||
it("should save the reverted alert types when a switch is reverted while a save is in flight", async () => {
|
||||
mockGetCallbacksCall.mockResolvedValue(teamsOnlyCallbacksResponse);
|
||||
const finishSaves: Array<() => void> = [];
|
||||
const pendingSave = () =>
|
||||
new Promise<void>((resolve) => {
|
||||
finishSaves.push(resolve);
|
||||
});
|
||||
vi.mocked(setCallbacksCall).mockImplementationOnce(pendingSave).mockImplementationOnce(pendingSave);
|
||||
|
||||
const user = userEvent.setup();
|
||||
render(<Settings {...defaultProps} />);
|
||||
await user.click(await screen.findByRole("tab", { name: "Alerting Types" }));
|
||||
|
||||
const deprecationWarningsRow = screen.getByRole("row", { name: "Model Deprecation Warnings" });
|
||||
const deprecationWarningsSwitch = within(deprecationWarningsRow).getByRole("switch");
|
||||
const saveButton = screen.getByRole("button", { name: "Save Changes" });
|
||||
await user.click(deprecationWarningsSwitch);
|
||||
await user.click(saveButton);
|
||||
await user.click(deprecationWarningsSwitch);
|
||||
await user.click(saveButton);
|
||||
await act(async () => {
|
||||
finishSaves.forEach((finish) => finish());
|
||||
});
|
||||
await user.click(saveButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(vi.mocked(setCallbacksCall)).toHaveBeenLastCalledWith(
|
||||
"token",
|
||||
expect.objectContaining({
|
||||
general_settings: expect.objectContaining({
|
||||
alert_types: ["llm_exceptions", "spend_reports"],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("should load alert types and webhook values from the Slack callback row", async () => {
|
||||
mockGetCallbacksCall.mockResolvedValue(slackCallbacksResponseWithoutTopLevelAlertTypes);
|
||||
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
const [alertToWebhooks, setAlertToWebhooks] = useState<Record<string, string>>({});
|
||||
const [activeAlerts, setActiveAlerts] = useState<string[]>([]);
|
||||
const [savedAlerts, setSavedAlerts] = useState<string[]>([]);
|
||||
const [isSavingAlerts, setIsSavingAlerts] = useState(false);
|
||||
|
||||
const [showAddCallbacksModal, setShowAddCallbacksModal] = useState(false);
|
||||
const [callbackConfigs, setCallbackConfigs] = useState<any[]>([]);
|
||||
|
|
@ -558,11 +559,14 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
},
|
||||
};
|
||||
|
||||
setIsSavingAlerts(true);
|
||||
try {
|
||||
await setCallbacksCall(accessToken, payload);
|
||||
} catch (error) {
|
||||
toast.fromError(error);
|
||||
return;
|
||||
} finally {
|
||||
setIsSavingAlerts(false);
|
||||
}
|
||||
setSavedAlerts(activeAlerts);
|
||||
toast.success(t("loggingAndAlerts.alertTypes.toasts.saved"));
|
||||
|
|
@ -708,7 +712,7 @@ const Settings: React.FC<SettingsPageProps> = ({ accessToken, userRole, userID,
|
|||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Button size="xs" className="mt-2" onClick={handleSaveAlerts}>
|
||||
<Button size="xs" className="mt-2" onClick={handleSaveAlerts} disabled={isSavingAlerts}>
|
||||
{t("loggingAndAlerts.alertTypes.saveChanges")}
|
||||
</Button>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue