Files
cc-switch/src
allen_xln 85f0be9e1d feat(provider-form): soften validation with "save anyway" prompt (#2307)
* feat(provider-form): soften business-rule validation with "save anyway" prompt

Refactor handleSubmit so empty-field / missing-item validations (provider
name, endpoint, API key, opencode model, template variables, provider key
required) no longer hard-reject with toast.error. Instead they are collected
into an issues list and presented via a ConfirmDialog; the user can cancel
or choose "Save anyway" to proceed.

Integrity constraints stay as hard rejections:
- providerKey regex / duplicate (would corrupt other providers)
- Copilot / Codex OAuth not authenticated (no token, cannot establish)
- omo Other Fields JSON not an object / parse failure

This aligns the frontend with the backend's existing "relaxed save / strict
switch" split (see gemini_config.rs: validate_gemini_settings vs
validate_gemini_settings_strict) and unblocks legitimate configs such as
AWS Bedrock, Vertex AI, and custom Gemini base URLs that the UI previously
refused to save.

Refs: #2196, #1204

* fix(provider-form): address review feedback on soft-validation

P1: move empty providerKey back to hard rejection for OpenCode / OpenClaw /
Hermes. Since providerKey is the primary identity for these apps and the
mutations layer throws "Provider key is required" when absent, letting users
click "save anyway" would surface a generic error toast instead of a
precise, actionable one. Treat empty providerKey as an integrity constraint
alongside regex / duplicate checks.

P2: give the soft-confirm submit path its own submitting state. The
confirm-dialog path bypassed react-hook-form's isSubmitting lifecycle, so
slow or failing saves left the outer submit button responsive and could
spawn unhandled rejections. Now the confirm handler awaits performSubmit
inside try/catch/finally, uses an isConfirmSubmitting flag to gate both
confirm and cancel clicks, and folds the flag into the outer disabled
state and onSubmittingChange callback.

Refs: #2307 review comments

* chore(clippy): use push for single char '…' in truncate_body

Clippy 1.95 added single_char_add_str which flagged the push_str("…")
in truncate_body. Rebased onto latest upstream/main and applied the
suggested fix so the Backend Checks clippy job passes.

Unrelated to this PR's core changes; bundled in so the PR is mergeable
without waiting for a separate upstream fix.

---------

Co-authored-by: Allen <allen@AllenMacBook-M4-Pro.local>
2026-04-25 09:28:28 +08:00
..