mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 23:02:10 +03:00
feat: add "Clear All Models" button on provider detail page
Adds a button next to the Auto-Sync toggle to clear all custom models for a provider. Extends DELETE /api/provider-models to support ?all=true parameter for bulk deletion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1542,6 +1542,29 @@ export default function ProviderDetailPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const [clearingModels, setClearingModels] = useState(false);
|
||||
const handleClearAllModels = async () => {
|
||||
if (clearingModels) return;
|
||||
if (!confirm(t("clearAllModelsConfirm"))) return;
|
||||
setClearingModels(true);
|
||||
try {
|
||||
const res = await fetch(
|
||||
`/api/provider-models?provider=${encodeURIComponent(providerStorageAlias)}&all=true`,
|
||||
{ method: "DELETE" }
|
||||
);
|
||||
if (res.ok) {
|
||||
await fetchProviderModelMeta();
|
||||
notify.success(t("clearAllModelsSuccess"));
|
||||
} else {
|
||||
notify.error(t("clearAllModelsFailed"));
|
||||
}
|
||||
} catch {
|
||||
notify.error(t("clearAllModelsFailed"));
|
||||
} finally {
|
||||
setClearingModels(false);
|
||||
}
|
||||
};
|
||||
|
||||
const customMap = useMemo(() => buildCompatMap(modelMeta.customModels), [modelMeta.customModels]);
|
||||
const overrideMap = useMemo(
|
||||
() => buildCompatMap(modelMeta.modelCompatOverrides),
|
||||
@@ -1650,10 +1673,25 @@ export default function ProviderDetailPage() {
|
||||
</button>
|
||||
);
|
||||
|
||||
const clearAllButton = modelMeta.customModels.length > 0 && (
|
||||
<button
|
||||
onClick={handleClearAllModels}
|
||||
disabled={clearingModels}
|
||||
className="flex items-center gap-1.5 px-2.5 py-1 rounded-lg border border-red-300 dark:border-red-800 bg-transparent cursor-pointer text-[12px] text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title={t("clearAllModels")}
|
||||
>
|
||||
<span className="material-symbols-outlined text-[16px]">delete_sweep</span>
|
||||
<span>{t("clearAllModels")}</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
if (isCompatible) {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-4">{autoSyncToggle}</div>
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
{autoSyncToggle}
|
||||
{clearAllButton}
|
||||
</div>
|
||||
<CompatibleModelsSection
|
||||
providerStorageAlias={providerStorageAlias}
|
||||
providerDisplayAlias={providerDisplayAlias}
|
||||
@@ -1691,6 +1729,7 @@ export default function ProviderDetailPage() {
|
||||
{importingModels ? t("importingModels") : t("importFromModels")}
|
||||
</Button>
|
||||
{autoSyncToggle}
|
||||
{clearAllButton}
|
||||
{!canImportModels && (
|
||||
<span className="text-xs text-text-muted">{t("addConnectionToImport")}</span>
|
||||
)}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
getAllCustomModels,
|
||||
addCustomModel,
|
||||
removeCustomModel,
|
||||
replaceCustomModels,
|
||||
updateCustomModel,
|
||||
getModelCompatOverrides,
|
||||
mergeModelCompatOverride,
|
||||
@@ -242,11 +243,30 @@ export async function DELETE(request) {
|
||||
const provider = searchParams.get("provider");
|
||||
const modelId = searchParams.get("model");
|
||||
|
||||
if (!provider || !modelId) {
|
||||
if (!provider) {
|
||||
return Response.json(
|
||||
{
|
||||
error: {
|
||||
message: "provider and model query params are required",
|
||||
message: "provider query param is required",
|
||||
type: "validation_error",
|
||||
},
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// DELETE /api/provider-models?provider=<id>&all=true — clear all models
|
||||
const all = searchParams.get("all");
|
||||
if (all === "true") {
|
||||
await replaceCustomModels(provider, []);
|
||||
return Response.json({ cleared: true });
|
||||
}
|
||||
|
||||
if (!modelId) {
|
||||
return Response.json(
|
||||
{
|
||||
error: {
|
||||
message: "model query param is required (or use all=true)",
|
||||
type: "validation_error",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1383,6 +1383,10 @@
|
||||
"autoSyncEnabled": "Auto-sync enabled — models will refresh periodically",
|
||||
"autoSyncDisabled": "Auto-sync disabled",
|
||||
"autoSyncToggleFailed": "Failed to toggle auto-sync",
|
||||
"clearAllModels": "Clear All Models",
|
||||
"clearAllModelsConfirm": "Are you sure you want to remove all models for this provider? This cannot be undone.",
|
||||
"clearAllModelsSuccess": "All models cleared",
|
||||
"clearAllModelsFailed": "Failed to clear models",
|
||||
"addConnectionToImport": "Add a connection to enable importing.",
|
||||
"noModelsConfigured": "No models configured",
|
||||
"connectionCount": "{count} connection(s)",
|
||||
|
||||
@@ -1383,6 +1383,10 @@
|
||||
"autoSyncEnabled": "已启用自动同步 — 模型列表将定期刷新",
|
||||
"autoSyncDisabled": "已禁用自动同步",
|
||||
"autoSyncToggleFailed": "切换自动同步失败",
|
||||
"clearAllModels": "清除所有模型",
|
||||
"clearAllModelsConfirm": "确定要删除此提供商的所有模型吗?此操作不可撤销。",
|
||||
"clearAllModelsSuccess": "已清除所有模型",
|
||||
"clearAllModelsFailed": "清除模型失败",
|
||||
"addConnectionToImport": "添加连接以启用导入。",
|
||||
"noModelsConfigured": "尚未配置模型",
|
||||
"connectionCount": "{count} 连接",
|
||||
|
||||
Reference in New Issue
Block a user