-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConnectionSwitcher.tsx
More file actions
107 lines (96 loc) · 3.49 KB
/
Copy pathConnectionSwitcher.tsx
File metadata and controls
107 lines (96 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { useState, useRef, useEffect } from "react";
import { ChevronDown, Plus, Upload, Download, Wifi, WifiOff, Loader } from "lucide-react";
import type { Connection } from "../types";
import { useApp } from "../contexts/AppContext";
import * as api from "../utils/api";
interface ConnectionSwitcherProps {
onAddNew: () => void;
onImport: () => void;
}
export function ConnectionSwitcher({ onAddNew, onImport }: ConnectionSwitcherProps) {
const { data, activeConnection, connectionStatus, switchConnection } = useApp();
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const getStatusIcon = () => {
switch (connectionStatus) {
case "connected":
return <Wifi size={14} className="status-icon connected" />;
case "connecting":
return <Loader size={14} className="status-icon connecting" />;
case "error":
return <WifiOff size={14} className="status-icon error" />;
default:
return <WifiOff size={14} className="status-icon disconnected" />;
}
};
const handleSelect = async (id: string) => {
setIsOpen(false);
if (id !== activeConnection?.id) {
await switchConnection(id);
}
};
const handleAddNew = () => {
setIsOpen(false);
onAddNew();
};
const handleImport = () => {
setIsOpen(false);
onImport();
};
const handleExport = async (e: React.MouseEvent, conn: Connection) => {
e.stopPropagation();
setIsOpen(false);
await api.exportConnection(conn);
};
if (!activeConnection) return null;
return (
<div className="connection-switcher" ref={dropdownRef}>
<button className="connection-switcher-button" onClick={() => setIsOpen(!isOpen)}>
{getStatusIcon()}
<span className="connection-name">{activeConnection.name}</span>
<ChevronDown size={16} className={`chevron ${isOpen ? "open" : ""}`} />
</button>
{isOpen && (
<div className="connection-dropdown">
{data.connections.map((conn) => (
<div
key={conn.id}
className={`connection-option ${conn.id === activeConnection.id ? "active" : ""}`}
onClick={() => handleSelect(conn.id)}
>
<div className="connection-option-info">
<span className="connection-option-name">{conn.name}</span>
<span className="connection-option-broker">{conn.broker_url}</span>
</div>
<button
className="connection-export-btn"
onClick={(e) => handleExport(e, conn)}
title="Export connection"
>
<Upload size={14} />
</button>
</div>
))}
<div className="connection-dropdown-divider" />
<button className="connection-option add-new" onClick={handleAddNew}>
<Plus size={16} />
<span>Add Connection</span>
</button>
<button className="connection-option add-new" onClick={handleImport}>
<Download size={16} />
<span>Import Connection</span>
</button>
</div>
)}
</div>
);
}