feat(desktop): simplify provider cards in Settings → API 服务 (re-open)#117
feat(desktop): simplify provider cards in Settings → API 服务 (re-open)#117
Conversation
Collapse each provider card to one header row (label, masked key, optional base URL). The "Active" badge or a compact "set active" button sits on the right; the model selector is hidden on non-active providers and rendered as a click-to-edit chip on the active card. Per-row actions (Test connection, Re-enter key, Delete) move into a ··· overflow menu, and the duplicated dashed "Add provider" button at the bottom of the list is removed. Signed-off-by: hqhq1025 <1506751656@qq.com>
… failure Codex flagged two Major issues in #116: - handleTestConnection awaited testActive() without try/catch, leaking bridge errors as unhandled promise rejections. - Model chip optimistically set new value before save completed; on save failure the UI showed an unsaved model. Now save() returns boolean and handleChange rolls back primary to its previous value when save fails. Signed-off-by: hqhq1025 <1506751656@qq.com>
There was a problem hiding this comment.
Findings
-
[Major] Silent bridge fallback violates the no-silent-fallback constraint — both new code paths return early when
window.codesignis unavailable, with no surfaced error (apps/desktop/src/renderer/src/components/Settings.tsx:657,apps/desktop/src/renderer/src/components/Settings.tsx:768). This can fail user actions without UI feedback.
Suggested fix:if (!window.codesign) { pushToast({ variant: 'error', title: t('settings.providers.toast.connectionFailed'), description: t('settings.common.unknownError'), }); return; }
-
[Major] Optimistic model rollback can revert to stale value on overlapping saves —
handleChangecapturesprevper call and rolls back on failure (apps/desktop/src/renderer/src/components/Settings.tsx:786). If two saves overlap, a late failure from an earlier selection can overwrite a later successful change.
Suggested fix:const saveSeq = useRef(0); function handleChange(v: string) { const prev = primary; const seq = ++saveSeq.current; setPrimary(v); setEditing(false); void save(v).then((ok) => { if (!ok && seq === saveSeq.current) setPrimary(prev); }); }
Summary
- Review mode: initial
- 2 issues found in modified lines (silent fallback + stale rollback race).
docs/VISION.mdanddocs/PRINCIPLES.mdwere Not found in repo/docs in this workspace, so principle checks were done against availableCLAUDE.mdconstraints plus the diffed files.- Residual risk: no test updates for new overflow-menu actions and optimistic rollback behavior.
Testing
- Not run (automation)
open-codesign Bot
| : 'border-[var(--color-border)] bg-[var(--color-surface)]'; | ||
|
|
||
| async function handleTestConnection() { | ||
| if (!window.codesign) return; |
There was a problem hiding this comment.
if (!window.codesign) return; silently drops the action. Project constraints require surfaced errors/no silent fallback. Please toast or throw with context here.
| if (saveTimeout.current !== null) clearTimeout(saveTimeout.current); | ||
| saveTimeout.current = setTimeout(() => void save(v), 400); | ||
| setEditing(false); | ||
| void save(v).then((ok) => { |
There was a problem hiding this comment.
Rollback is race-prone across overlapping saves: a late failure from an earlier change can reset a newer successful selection. Please gate rollback with a request sequence/id (or cancel stale requests).
Reopen of #116 after #113 squash-merge auto-closed it. Rebased onto current main; first commit (the one duplicated by #113's squash) was dropped via rebase --skip. The 2 fixes from codex re-review are included.
Summary
Test plan
🤖 Generated with Claude Code