From 8101c879e8965e7c54c545a81d7a62ab06d84829 Mon Sep 17 00:00:00 2001 From: Xiangzhe <32761048+xz-dev@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:57:33 +0800 Subject: [PATCH] fix(providers): save compatible provider data URL icons (#10247) --- .../10247-provider-icon-data-url-save.md | 1 + .../modals/EditCompatibleNodeModal.tsx | 23 ++- .../[id]/hooks/useProviderNodeActions.ts | 27 ++-- .../components/AddCompatibleProviderModal.tsx | 32 ++++- src/shared/validation/schemas/provider.ts | 5 +- .../unit/provider-icon-url-validator.test.ts | 89 +++++++++++- tests/unit/provider-node-icon-url.test.ts | 52 +++++++ .../add-compatible-provider-icon-url.test.tsx | 131 +++++++++++++++--- .../ui/edit-compatible-node-icon-url.test.tsx | 94 +++++++++++-- .../ui/use-provider-node-actions.test.tsx | 98 +++++++++++++ 10 files changed, 498 insertions(+), 54 deletions(-) create mode 100644 changelog.d/fixes/10247-provider-icon-data-url-save.md create mode 100644 tests/unit/ui/use-provider-node-actions.test.tsx diff --git a/changelog.d/fixes/10247-provider-icon-data-url-save.md b/changelog.d/fixes/10247-provider-icon-data-url-save.md new file mode 100644 index 0000000000..6ad4538b86 --- /dev/null +++ b/changelog.d/fixes/10247-provider-icon-data-url-save.md @@ -0,0 +1 @@ +- **fix(providers):** compatible/custom providers now save valid Data URL icons and show Add/Edit save failures instead of silently doing nothing ([#10247](https://github.com/diegosouzapw/OmniRoute/pull/10247)) — thanks @xz-dev diff --git a/src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditCompatibleNodeModal.tsx b/src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditCompatibleNodeModal.tsx index 1ba581bf4a..b2c263605c 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditCompatibleNodeModal.tsx +++ b/src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditCompatibleNodeModal.tsx @@ -60,9 +60,10 @@ export default function EditCompatibleNodeModal({ }>(null); const [showAdvanced, setShowAdvanced] = useState(false); const [iconUrlError, setIconUrlError] = useState(null); + const [saveError, setSaveError] = useState(null); useEffect(() => { - if (node) { + if (isOpen && node) { const psd = (node.providerSpecificData || {}) as Record; setFormData({ name: node.name || "", @@ -83,6 +84,8 @@ export default function EditCompatibleNodeModal({ newApiUserId: typeof psd.newApiUserId === "string" ? psd.newApiUserId : "", quotaPerUnit: typeof psd.quotaPerUnit === "number" ? String(psd.quotaPerUnit) : "", }); + setSaveError(null); + setIconUrlError(null); setShowAdvanced( !!( node.chatPath || @@ -91,7 +94,7 @@ export default function EditCompatibleNodeModal({ ) ); } - }, [node, isAnthropic, isCcCompatible]); + }, [isOpen, node, isAnthropic, isCcCompatible]); const apiTypeOptions = [ { value: "chat", label: t("chatCompletions") }, @@ -110,6 +113,7 @@ export default function EditCompatibleNodeModal({ return; } setIconUrlError(null); + setSaveError(null); setSaving(true); try { const payload: any = { @@ -140,6 +144,12 @@ export default function EditCompatibleNodeModal({ } } await onSave(payload); + } catch (error) { + setSaveError( + error instanceof Error && error.message.trim() + ? error.message + : providerText(t, "failedSave", "Failed to save") + ); } finally { setSaving(false); } @@ -359,6 +369,15 @@ export default function EditCompatibleNodeModal({ )} )} + {saveError && ( +
+ {saveError} +
+ )}
)} + {saveError && ( +
+ {saveError} +
+ )}