mirror of
https://github.com/natankeddem/bale.git
synced 2026-04-23 06:50:41 +00:00
155 lines
6.8 KiB
Python
155 lines
6.8 KiB
Python
from nicegui import ui
|
|
from snapper import elements as el
|
|
from snapper.tabs import Tab
|
|
from snapper.interfaces import ssh
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Drawer(object):
|
|
def __init__(self, main_column, on_click, hide_content) -> None:
|
|
self._on_click = on_click
|
|
self._hide_content = hide_content
|
|
self._main_column = main_column
|
|
self._header_row = None
|
|
self._table = None
|
|
self._name = ""
|
|
self._hostname = ""
|
|
self._username = ""
|
|
self._password = ""
|
|
self._buttons = {}
|
|
self._selection_mode = None
|
|
|
|
def build(self):
|
|
with ui.left_drawer(top_corner=True, bordered=True).props("width=200").classes("q-pt-sm q-pb-xs"):
|
|
with el.WColumn():
|
|
self._header_row = el.WRow().classes("justify-between")
|
|
self._header_row.tailwind().height("12")
|
|
with self._header_row:
|
|
with ui.row():
|
|
el.IButton(icon="add", on_click=self._display_host_dialog)
|
|
self._buttons["remove"] = el.IButton(icon="remove", on_click=lambda: self._modify_host("remove"))
|
|
self._buttons["edit"] = el.IButton(icon="edit", on_click=lambda: self._modify_host("edit"))
|
|
ui.label(text="HOSTS").classes("text-secondary")
|
|
self._table = (
|
|
ui.table(
|
|
[
|
|
{
|
|
"name": "name",
|
|
"label": "Name",
|
|
"field": "name",
|
|
"required": True,
|
|
"align": "center",
|
|
"sortable": True,
|
|
}
|
|
],
|
|
[],
|
|
row_key="name",
|
|
pagination={"rowsPerPage": 0, "sortBy": "name"},
|
|
on_select=lambda e: self._selected(e),
|
|
)
|
|
.on("rowClick", self._clicked, [[], ["name"], None])
|
|
.props("hide-header hide-pagination hide-selected-banner dense flat bordered binary-state-sort")
|
|
.classes("w-full text-secondary")
|
|
)
|
|
self._table.visible = False
|
|
for name in ssh.get_hosts("data"):
|
|
self._add_host_to_table(name)
|
|
|
|
def _add_host_to_table(self, name):
|
|
if len(name) > 0:
|
|
for row in self._table.rows:
|
|
if name == row["name"]:
|
|
return
|
|
self._table.add_rows({"name": name})
|
|
self._table.visible = True
|
|
Tab.register_connection(name)
|
|
|
|
async def _display_host_dialog(self, name=""):
|
|
save = None
|
|
|
|
async def send_key():
|
|
s = ssh.Ssh(
|
|
"data", host=host_input.value, hostname=hostname_input.value, username=username_input.value, password=password_input.value
|
|
)
|
|
result = await s.send_key()
|
|
if result.stdout.strip() != "":
|
|
el.notify(result.stdout.strip(), multi_line=True, type="positive")
|
|
if result.stderr.strip() != "":
|
|
el.notify(result.stderr.strip(), multi_line=True, type="negative")
|
|
|
|
with ui.dialog() as host_dialog, el.Card():
|
|
with el.DBody(height="[90vh]"):
|
|
with el.WColumn():
|
|
host_input = el.DInput(label="Host", value=" ")
|
|
hostname_input = el.DInput(label="Hostname", value=" ")
|
|
username_input = el.DInput(label="Username", value=" ")
|
|
save_em = el.ErrorAggregator(host_input, hostname_input, username_input)
|
|
with el.Card() as c:
|
|
c.tailwind.width("full")
|
|
password_input = el.DInput(label="Password", value=" ").props("type=password")
|
|
send_em = el.ErrorAggregator(hostname_input, username_input, password_input)
|
|
el.DButton("SEND KEY", on_click=send_key).bind_enabled_from(send_em, "no_errors").tailwind.width("full")
|
|
with el.Card() as c:
|
|
c.tailwind.width("full")
|
|
with ui.scroll_area() as s:
|
|
s.tailwind.height("[200px]")
|
|
public_key = await ssh.get_public_key("data")
|
|
ui.label(public_key).classes("text-secondary break-all")
|
|
el.DButton("SAVE", on_click=lambda: host_dialog.submit("save")).bind_enabled_from(save_em, "no_errors")
|
|
host_input.value = name
|
|
if name != "":
|
|
s = ssh.Ssh(path="data", host=name)
|
|
hostname_input.value = s.hostname
|
|
username_input.value = s.username
|
|
|
|
result = await host_dialog
|
|
if result == "save":
|
|
if name != "" and name != host_input.value:
|
|
for row in self._table.rows:
|
|
if name == row["name"]:
|
|
self._table.remove_rows(row)
|
|
ssh.Ssh(path="data", host=host_input.value, hostname=hostname_input.value, username=username_input.value)
|
|
self._add_host_to_table(host_input.value)
|
|
|
|
def _modify_host(self, mode):
|
|
self._hide_content()
|
|
self._selection_mode = mode
|
|
if mode is None:
|
|
self._table._props["selected"] = []
|
|
self._table.props("selection=none")
|
|
for icon, button in self._buttons.items():
|
|
button.props(f"icon={icon}")
|
|
elif self._buttons[mode]._props["icon"] == "close":
|
|
self._selection_mode = None
|
|
self._table._props["selected"] = []
|
|
self._table.props("selection=none")
|
|
for icon, button in self._buttons.items():
|
|
button.props(f"icon={icon}")
|
|
else:
|
|
self._table.props("selection=single")
|
|
for icon, button in self._buttons.items():
|
|
if mode == icon:
|
|
button.props("icon=close")
|
|
else:
|
|
button.props(f"icon={icon}")
|
|
|
|
async def _selected(self, e):
|
|
self._hide_content()
|
|
if self._selection_mode == "edit":
|
|
if len(e.selection) > 0:
|
|
await self._display_host_dialog(name=e.selection[0]["name"])
|
|
if self._selection_mode == "remove":
|
|
if len(e.selection) > 0:
|
|
for row in e.selection:
|
|
ssh.Ssh(path="data", host=row["name"]).remove()
|
|
self._table.remove_rows(row)
|
|
self._modify_host(None)
|
|
|
|
async def _clicked(self, e):
|
|
if "name" in e.args[1]:
|
|
host = e.args[1]["name"]
|
|
if self._on_click is not None:
|
|
await self._on_click(host)
|