Add a per-row Test button to the Integrations list
The add/edit forms already had "Test connection", backed by existing POST /api/integrations/:id/test (admin-only, pings with the stored config) and POST /api/integrations/test (for a not-yet-saved one) -- but there was no way to re-test an already-configured integration without opening its edit form. Add a "Test" button next to Edit/ Delete on each row, showing an OK/latency or Failed/error badge inline once it returns. Pure frontend wiring to the existing endpoint, no server changes needed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5b6c55383
commit
7564796c39
1 file changed
+28
-1
@@ -29,6 +29,8 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
const [editingIntegration, setEditingIntegration] = useState<IntegrationSummary | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [integrationColors, setIntegrationColors] = useState<Record<string, string>>({});
|
||||
const [testingId, setTestingId] = useState<number | null>(null);
|
||||
const [testResults, setTestResults] = useState<Record<number, { ok: boolean; latencyMs?: number; error?: string }>>({});
|
||||
|
||||
useEffect(() => {
|
||||
api.settings.integrationColors().then((res) => setIntegrationColors(res.integrationColors)).catch(() => {});
|
||||
@@ -52,6 +54,18 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
}
|
||||
}
|
||||
|
||||
async function testIntegration(i: IntegrationSummary) {
|
||||
setTestingId(i.id);
|
||||
try {
|
||||
const result = await api.integrations.testExisting(i.id, {});
|
||||
setTestResults((prev) => ({ ...prev, [i.id]: result }));
|
||||
} catch (err) {
|
||||
setTestResults((prev) => ({ ...prev, [i.id]: { ok: false, error: err instanceof Error ? err.message : String(err) } }));
|
||||
} finally {
|
||||
setTestingId(null);
|
||||
}
|
||||
}
|
||||
|
||||
async function removeIntegration(i: IntegrationSummary) {
|
||||
if (!confirm(`Delete integration "${i.name}"?`)) return;
|
||||
try {
|
||||
@@ -159,7 +173,17 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
</td>
|
||||
{isAdmin && (
|
||||
<td>
|
||||
<div className="btn-list flex-nowrap">
|
||||
<div className="btn-list flex-nowrap align-items-center">
|
||||
<button className="btn btn-sm" onClick={() => testIntegration(i)} disabled={testingId === i.id}>
|
||||
{testingId === i.id ? "Testing…" : "Test"}
|
||||
</button>
|
||||
{testResults[i.id] && testingId !== i.id && (
|
||||
<span className={`badge ${testResults[i.id].ok ? "bg-green-lt text-green" : "bg-red-lt text-red"}`}>
|
||||
{testResults[i.id].ok
|
||||
? `OK${testResults[i.id].latencyMs !== undefined ? ` (${testResults[i.id].latencyMs}ms)` : ""}`
|
||||
: "Failed"}
|
||||
</span>
|
||||
)}
|
||||
<button className="btn btn-sm" onClick={() => setEditingIntegration(i)}>
|
||||
Edit
|
||||
</button>
|
||||
@@ -167,6 +191,9 @@ export default function Integrations({ user }: { user: CurrentUser }) {
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
{testResults[i.id] && !testResults[i.id].ok && testingId !== i.id && (
|
||||
<div className="text-red small mt-1">{testResults[i.id].error}</div>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
|
||||
Reference in new issue
Block a user