repos: sidebar actions (sync/edit/remove) + edit modal
ci / gates (push) Successful in 6s
ci / frontend (push) Successful in 35s
ci / rust (push) Successful in 2m43s
ci / e2e (push) Has been skipped
ci / publish (push) Successful in 4m7s

Sidebar:
- Each connection header now has three inline icon buttons: Sync now
  (spins while in flight), Edit (opens the modal), Remove (opens an
  inline confirm strip). Removes cascade repos via ON DELETE CASCADE.
- The connection's last_sync_error surfaces as a red inline banner
  under the header — no more 'error status with nowhere to see why'.
- Sync is POST /api/repos/connections/:id/sync (already existed);
  after either sync or delete the sidebar re-fetches so state stays
  consistent.

Edit modal (RepoConnectionEditModal):
- Loads GET /api/repos/connections/:id, pre-fills owner/base_url/label
- PATCHes only the fields that actually changed; empty string on a
  Some(&str) field sends explicit null so the backend clears it
- Sync-now + Remove reachable from inside the modal too
- Rotating the token is out of scope: the modal says as much and
  points the user at delete + re-create through the wizard (the
  broker doesn't expose an update path, and rotating in place would
  require duplicating the whole broker->store_secret flow here)

Backend:
- GET /api/repos/connections/:id — same ConnectionSummary shape
- PATCH /api/repos/connections/:id — owner/base_url use Option<Option<T>>
  double-nesting so 'omit = leave alone' and 'null = clear' round-trip
  distinctly through serde
- repo_connections::update with COALESCE-per-field so the SQL matches
  the double-Option semantics without an OR-chain per field
This commit is contained in:
Omar Sobh
2026-07-07 17:55:20 -07:00
parent b431d00f1a
commit 637e1bdd69
7 changed files with 795 additions and 4 deletions
@@ -0,0 +1,20 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE repo_connections\n SET owner = CASE WHEN $3 THEN $4 ELSE owner END,\n base_url = CASE WHEN $5 THEN $6 ELSE base_url END,\n label = COALESCE($7, label),\n updated_at = now()\n WHERE id = $1 AND workspace_id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Uuid",
"Bool",
"Text",
"Bool",
"Text",
"Text"
]
},
"nullable": []
},
"hash": "e9e2622dbd52c1d1145fc045adac33ba2eff3dc9341c86a2916a000ccb77ad5b"
}