import React, { useState } from "react"; import { ExternalLink, Check, X, Loader2 } from "lucide-react"; import { Card, CardHeader, CardTitle, CardContent, CardDescription, Button, Input, Label, } from "@/components/ui"; import { initiateOauthCmd, testConfluenceConnectionCmd, testServiceNowConnectionCmd, testAzureDevOpsConnectionCmd, } from "@/lib/tauriCommands"; import { invoke } from "@tauri-apps/api/core"; interface IntegrationConfig { service: string; baseUrl: string; username?: string; projectName?: string; spaceKey?: string; connected: boolean; } export default function Integrations() { const [configs, setConfigs] = useState>({ confluence: { service: "confluence", baseUrl: "", spaceKey: "", connected: false, }, servicenow: { service: "servicenow", baseUrl: "", username: "", connected: false, }, azuredevops: { service: "azuredevops", baseUrl: "", projectName: "", connected: false, }, }); const [loading, setLoading] = useState>({}); const [testResults, setTestResults] = useState>({}); const handleConnect = async (service: string) => { setLoading((prev) => ({ ...prev, [service]: true })); try { const response = await initiateOauthCmd(service); // Open auth URL in default browser using shell plugin await invoke("plugin:shell|open", { path: response.auth_url }); // Mark as connected (optimistic) setConfigs((prev) => ({ ...prev, [service]: { ...prev[service], connected: true }, })); setTestResults((prev) => ({ ...prev, [service]: { success: true, message: "Authentication window opened. Complete the login to continue." }, })); } catch (err) { console.error("Failed to initiate OAuth:", err); setTestResults((prev) => ({ ...prev, [service]: { success: false, message: String(err) }, })); } finally { setLoading((prev) => ({ ...prev, [service]: false })); } }; const handleTestConnection = async (service: string) => { setLoading((prev) => ({ ...prev, [`test-${service}`]: true })); setTestResults((prev) => ({ ...prev, [service]: null })); try { const config = configs[service]; let result; switch (service) { case "confluence": result = await testConfluenceConnectionCmd(config.baseUrl, { space_key: config.spaceKey, }); break; case "servicenow": result = await testServiceNowConnectionCmd(config.baseUrl, { username: config.username, }); break; case "azuredevops": result = await testAzureDevOpsConnectionCmd(config.baseUrl, { project: config.projectName, }); break; default: throw new Error(`Unknown service: ${service}`); } setTestResults((prev) => ({ ...prev, [service]: result })); } catch (err) { setTestResults((prev) => ({ ...prev, [service]: { success: false, message: String(err) }, })); } finally { setLoading((prev) => ({ ...prev, [`test-${service}`]: false })); } }; const updateConfig = (service: string, field: string, value: string) => { setConfigs((prev) => ({ ...prev, [service]: { ...prev[service], [field]: value }, })); }; return (

Integrations

Connect TFTSR with your existing tools and platforms via OAuth2.

{/* Confluence */} Confluence Publish RCA documents to Confluence spaces. Requires OAuth2 authentication with Atlassian.
updateConfig("confluence", "baseUrl", e.target.value)} />
updateConfig("confluence", "spaceKey", e.target.value)} />
{testResults.confluence && (
{testResults.confluence.success ? ( ) : ( )} {testResults.confluence.message}
)}
{/* ServiceNow */} ServiceNow Link incidents and push resolution steps. Uses basic authentication (username + password).
updateConfig("servicenow", "baseUrl", e.target.value)} />
updateConfig("servicenow", "username", e.target.value)} />

ServiceNow credentials are stored securely after first login. OAuth2 not supported.

{testResults.servicenow && (
{testResults.servicenow.success ? ( ) : ( )} {testResults.servicenow.message}
)}
{/* Azure DevOps */} Azure DevOps Create work items and attach RCA documents. Requires OAuth2 authentication with Microsoft.
updateConfig("azuredevops", "baseUrl", e.target.value)} />
updateConfig("azuredevops", "projectName", e.target.value)} />
{testResults.azuredevops && (
{testResults.azuredevops.success ? ( ) : ( )} {testResults.azuredevops.message}
)}

How OAuth2 Authentication Works:

  1. Click "Connect with OAuth2" to open the service's authentication page
  2. Log in with your service credentials in your default browser
  3. Authorize TFTSR to access your account
  4. You'll be automatically redirected back and the connection will be saved
  5. Tokens are encrypted and stored locally in your secure database
); }