144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
import gi
|
|
gi.require_version('Gtk', '3.0')
|
|
from gi.repository import Gtk
|
|
from .host_item import HostItem
|
|
from models import VPNType
|
|
|
|
|
|
class ActiveLocationCard:
|
|
def __init__(self, location, customer_name, callbacks):
|
|
self.location = location
|
|
self.customer_name = customer_name
|
|
self.callbacks = callbacks
|
|
self.widget = self._create_widget()
|
|
|
|
def _create_widget(self):
|
|
# Clean card layout - just a box with proper spacing
|
|
location_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
|
|
|
|
# Location header with controls
|
|
header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
|
|
location_vbox.pack_start(header_box, False, False, 0)
|
|
|
|
# Location info
|
|
info_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
|
|
header_box.pack_start(info_vbox, True, True, 0)
|
|
|
|
# Location name with VPN type
|
|
location_label = Gtk.Label()
|
|
location_label.set_markup(f"<b>📍 {self.location.name}</b>")
|
|
location_label.set_halign(Gtk.Align.START)
|
|
info_vbox.pack_start(location_label, False, False, 0)
|
|
|
|
# VPN type
|
|
vpn_icons = {
|
|
VPNType.OPENVPN: "🔒",
|
|
VPNType.WIREGUARD: "⚡",
|
|
VPNType.IPSEC: "🛡️"
|
|
}
|
|
vpn_icon = vpn_icons.get(self.location.vpn_type, "🔑")
|
|
|
|
type_label = Gtk.Label()
|
|
type_label.set_markup(f"<small>{vpn_icon} {self.location.vpn_type.value} VPN</small>")
|
|
type_label.set_halign(Gtk.Align.START)
|
|
info_vbox.pack_start(type_label, False, False, 0)
|
|
|
|
# Status and controls
|
|
controls_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
|
|
header_box.pack_end(controls_box, False, False, 0)
|
|
|
|
# Status
|
|
status_text = "● Connected" if self.location.connected else "○ Disconnected"
|
|
status_color = "#4caf50" if self.location.connected else "#999"
|
|
status_label = Gtk.Label()
|
|
status_label.set_markup(f"<small><span color='{status_color}'>{status_text}</span></small>")
|
|
controls_box.pack_start(status_label, False, False, 0)
|
|
|
|
# Connect/Disconnect button
|
|
btn_text = "Disconnect" if self.location.connected else "Connect"
|
|
connect_btn = Gtk.Button(label=btn_text)
|
|
if self.location.connected:
|
|
connect_btn.get_style_context().add_class("destructive-action")
|
|
else:
|
|
connect_btn.get_style_context().add_class("suggested-action")
|
|
connect_btn.connect("clicked", self._on_connect_clicked)
|
|
controls_box.pack_start(connect_btn, False, False, 0)
|
|
|
|
# X button to deactivate (close button style)
|
|
close_btn = Gtk.Button(label="✕")
|
|
close_btn.set_tooltip_text("Deactivate location")
|
|
close_btn.get_style_context().add_class("circular")
|
|
close_btn.connect("clicked", self._on_deactivate_clicked)
|
|
controls_box.pack_start(close_btn, False, False, 0)
|
|
|
|
# Hosts section if available
|
|
if self.location.hosts:
|
|
hosts_label = Gtk.Label()
|
|
hosts_label.set_markup("<b>Infrastructure</b>")
|
|
hosts_label.set_halign(Gtk.Align.START)
|
|
hosts_label.set_margin_top(8)
|
|
location_vbox.pack_start(hosts_label, False, False, 0)
|
|
|
|
# Hosts box with indent
|
|
hosts_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
|
|
hosts_box.set_margin_start(16)
|
|
location_vbox.pack_start(hosts_box, False, False, 0)
|
|
|
|
for host in self.location.hosts:
|
|
host_item = HostItem(host, self.callbacks['open_service'])
|
|
hosts_box.pack_start(host_item.widget, False, False, 0)
|
|
|
|
return location_vbox
|
|
|
|
def _on_connect_clicked(self, button):
|
|
self.callbacks['toggle_connection'](self.location)
|
|
|
|
def _on_deactivate_clicked(self, button):
|
|
self.callbacks['deactivate_location'](self.location, self.customer_name)
|
|
|
|
|
|
class InactiveLocationCard:
|
|
def __init__(self, location, customer_name, callbacks):
|
|
self.location = location
|
|
self.customer_name = customer_name
|
|
self.callbacks = callbacks
|
|
self.widget = self._create_widget()
|
|
|
|
def _create_widget(self):
|
|
# Clean horizontal layout
|
|
location_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
|
|
|
|
# Location info
|
|
info_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
|
|
location_hbox.pack_start(info_vbox, True, True, 0)
|
|
|
|
# Location name
|
|
location_label = Gtk.Label()
|
|
location_label.set_markup(f"<b>📍 {self.location.name}</b>")
|
|
location_label.set_halign(Gtk.Align.START)
|
|
info_vbox.pack_start(location_label, False, False, 0)
|
|
|
|
# VPN type and host count
|
|
vpn_icons = {
|
|
VPNType.OPENVPN: "🔒",
|
|
VPNType.WIREGUARD: "⚡",
|
|
VPNType.IPSEC: "🛡️"
|
|
}
|
|
vpn_icon = vpn_icons.get(self.location.vpn_type, "🔑")
|
|
host_count = len(self.location.hosts)
|
|
|
|
details_label = Gtk.Label()
|
|
details_label.set_markup(f"<small>{vpn_icon} {self.location.vpn_type.value} VPN • {host_count} hosts</small>")
|
|
details_label.set_halign(Gtk.Align.START)
|
|
info_vbox.pack_start(details_label, False, False, 0)
|
|
|
|
# Activate button
|
|
activate_btn = Gtk.Button(label="Set Active")
|
|
activate_btn.get_style_context().add_class("suggested-action")
|
|
activate_btn.connect("clicked", self._on_activate_clicked)
|
|
location_hbox.pack_end(activate_btn, False, False, 0)
|
|
|
|
return location_hbox
|
|
|
|
def _on_activate_clicked(self, button):
|
|
self.callbacks['set_location_active'](self.location, self.customer_name) |