mirror of
https://github.com/markqvist/NomadNet.git
synced 2025-05-18 05:40:26 -04:00
Interface Management initial (2/2)
This commit is contained in:
parent
c415345f59
commit
dfa7adc21e
5 changed files with 1016 additions and 211 deletions
|
@ -279,5 +279,260 @@ class FormMultiList(urwid.Pile, FormField):
|
|||
self.error = "At least one entry is required"
|
||||
break
|
||||
|
||||
self.error_widget.set_text(("error", self.error or ""))
|
||||
return self.error is None
|
||||
|
||||
|
||||
class FormMultiTable(urwid.Pile, FormField):
|
||||
def __init__(self, config_key, fields, validation_types=None, transform=None, **kwargs):
|
||||
self.entries = []
|
||||
self.fields = fields
|
||||
self.error_widget = urwid.Text("")
|
||||
self.error = None
|
||||
self.validation_types = validation_types or []
|
||||
|
||||
header_columns = [('weight', 3, urwid.Text(("list_focus", "Name")))]
|
||||
for field_key, field_config in self.fields.items():
|
||||
header_columns.append(('weight', 2, urwid.Text(("list_focus", field_config.get("label", field_key)))))
|
||||
header_columns.append((4, urwid.Text(("list_focus", ""))))
|
||||
|
||||
self.header_row = urwid.Columns(header_columns)
|
||||
|
||||
first_entry = self.create_entry_row()
|
||||
self.entries.append(first_entry)
|
||||
|
||||
self.add_button = urwid.Button("+ Add ", on_press=self.add_entry)
|
||||
add_button_padded = urwid.Padding(self.add_button, left=2, right=2)
|
||||
|
||||
pile_widgets = [
|
||||
self.header_row,
|
||||
urwid.Divider("-"),
|
||||
first_entry,
|
||||
add_button_padded
|
||||
]
|
||||
|
||||
urwid.Pile.__init__(self, pile_widgets)
|
||||
FormField.__init__(self, config_key, transform)
|
||||
|
||||
def create_entry_row(self, name="", values=None):
|
||||
if values is None:
|
||||
values = {}
|
||||
|
||||
name_edit = urwid.Edit("", name)
|
||||
|
||||
columns = [('weight', 3, name_edit)]
|
||||
|
||||
field_widgets = {}
|
||||
for field_key, field_config in self.fields.items():
|
||||
field_value = values.get(field_key, "")
|
||||
|
||||
if field_config.get("type") == "checkbox":
|
||||
widget = urwid.CheckBox("", state=bool(field_value))
|
||||
elif field_config.get("type") == "dropdown":
|
||||
# TODO: dropdown in MultiTable
|
||||
widget = urwid.Edit("", str(field_value))
|
||||
else:
|
||||
widget = urwid.Edit("", str(field_value))
|
||||
|
||||
field_widgets[field_key] = widget
|
||||
columns.append(('weight', 2, widget))
|
||||
|
||||
remove_button = urwid.Button("×", on_press=lambda button: self.remove_entry(button, entry_row))
|
||||
columns.append((4, remove_button))
|
||||
|
||||
entry_row = urwid.Columns(columns)
|
||||
entry_row.name_edit = name_edit
|
||||
entry_row.field_widgets = field_widgets
|
||||
|
||||
return entry_row
|
||||
|
||||
def remove_entry(self, button, entry_row):
|
||||
if len(self.entries) > 1:
|
||||
self.entries.remove(entry_row)
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def add_entry(self, button):
|
||||
new_entry = self.create_entry_row()
|
||||
self.entries.append(new_entry)
|
||||
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def get_pile_widgets(self):
|
||||
return [
|
||||
self.header_row,
|
||||
urwid.Divider("-")
|
||||
] + self.entries + [
|
||||
urwid.Padding(self.add_button, left=2, right=2)
|
||||
]
|
||||
|
||||
def get_value(self):
|
||||
values = {}
|
||||
for entry in self.entries:
|
||||
name = entry.name_edit.edit_text.strip()
|
||||
if name:
|
||||
subinterface = {}
|
||||
subinterface["interface_enabled"] = True
|
||||
|
||||
for field_key, widget in entry.field_widgets.items():
|
||||
field_config = self.fields.get(field_key, {})
|
||||
|
||||
if hasattr(widget, "get_state"):
|
||||
value = widget.get_state()
|
||||
elif hasattr(widget, "edit_text"):
|
||||
value = widget.edit_text.strip()
|
||||
|
||||
transform = field_config.get("transform")
|
||||
if transform and value:
|
||||
try:
|
||||
value = transform(value)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
value = ""
|
||||
|
||||
if value:
|
||||
subinterface[field_key] = value
|
||||
|
||||
values[name] = subinterface
|
||||
|
||||
return self.transform(values) if self.transform else values
|
||||
|
||||
def set_value(self, value):
|
||||
self.entries = []
|
||||
|
||||
if not value:
|
||||
self.entries.append(self.create_entry_row())
|
||||
else:
|
||||
for name, config in value.items():
|
||||
self.entries.append(self.create_entry_row(name=name, values=config))
|
||||
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def validate(self):
|
||||
values = self.get_value()
|
||||
self.error = None
|
||||
|
||||
for validation in self.validation_types:
|
||||
if validation == "required" and not values:
|
||||
self.error = "At least one subinterface is required"
|
||||
break
|
||||
|
||||
self.error_widget.set_text(("error", self.error or ""))
|
||||
return self.error is None
|
||||
|
||||
|
||||
class FormKeyValuePairs(urwid.Pile, FormField):
|
||||
def __init__(self, config_key, validation_types=None, transform=None, **kwargs):
|
||||
self.entries = []
|
||||
self.error_widget = urwid.Text("")
|
||||
self.error = None
|
||||
self.validation_types = validation_types or []
|
||||
|
||||
header_columns = [
|
||||
('weight', 1, urwid.AttrMap(urwid.Text("Parameter Key"), "multitable_header")),
|
||||
('weight', 1, urwid.AttrMap(urwid.Text("Parameter Value"), "multitable_header")),
|
||||
(4, urwid.AttrMap(urwid.Text("Action"), "multitable_header"))
|
||||
]
|
||||
|
||||
self.header_row = urwid.AttrMap(urwid.Columns(header_columns), "multitable_header")
|
||||
|
||||
first_entry = self.create_entry_row()
|
||||
self.entries.append(first_entry)
|
||||
|
||||
self.add_button = urwid.Button("+ Add Parameter", on_press=self.add_entry)
|
||||
add_button_padded = urwid.Padding(self.add_button, left=2, right=2)
|
||||
|
||||
pile_widgets = [
|
||||
self.header_row,
|
||||
urwid.Divider("-"),
|
||||
first_entry,
|
||||
add_button_padded
|
||||
]
|
||||
|
||||
urwid.Pile.__init__(self, pile_widgets)
|
||||
FormField.__init__(self, config_key, transform)
|
||||
|
||||
def create_entry_row(self, key="", value=""):
|
||||
key_edit = urwid.Edit("", key)
|
||||
value_edit = urwid.Edit("", value)
|
||||
|
||||
remove_button = urwid.Button("×", on_press=lambda button: self.remove_entry(button, entry_row))
|
||||
|
||||
entry_row = urwid.Columns([
|
||||
('weight', 1, key_edit),
|
||||
('weight', 1, value_edit),
|
||||
(4, remove_button)
|
||||
])
|
||||
|
||||
entry_row.key_edit = key_edit
|
||||
entry_row.value_edit = value_edit
|
||||
|
||||
return entry_row
|
||||
|
||||
def remove_entry(self, button, entry_row):
|
||||
if len(self.entries) > 1:
|
||||
self.entries.remove(entry_row)
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def add_entry(self, button):
|
||||
new_entry = self.create_entry_row()
|
||||
self.entries.append(new_entry)
|
||||
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def get_pile_widgets(self):
|
||||
return [
|
||||
self.header_row,
|
||||
urwid.Divider("-")
|
||||
] + self.entries + [
|
||||
urwid.Padding(self.add_button, left=2, right=2)
|
||||
]
|
||||
|
||||
def get_value(self):
|
||||
values = {}
|
||||
for entry in self.entries:
|
||||
key = entry.key_edit.edit_text.strip()
|
||||
value = entry.value_edit.edit_text.strip()
|
||||
|
||||
if key:
|
||||
if value.isdigit():
|
||||
values[key] = int(value)
|
||||
elif value.replace('.', '', 1).isdigit() and value.count('.') <= 1:
|
||||
values[key] = float(value)
|
||||
elif value.lower() == 'true':
|
||||
values[key] = True
|
||||
elif value.lower() == 'false':
|
||||
values[key] = False
|
||||
else:
|
||||
values[key] = value
|
||||
|
||||
return self.transform(values) if self.transform else values
|
||||
|
||||
def set_value(self, value):
|
||||
self.entries = []
|
||||
|
||||
if not value or not isinstance(value, dict):
|
||||
self.entries.append(self.create_entry_row())
|
||||
else:
|
||||
for key, val in value.items():
|
||||
self.entries.append(self.create_entry_row(key=key, value=str(val)))
|
||||
|
||||
self.contents = [(w, self.options()) for w in self.get_pile_widgets()]
|
||||
|
||||
def validate(self):
|
||||
values = self.get_value()
|
||||
self.error = None
|
||||
|
||||
keys = [entry.key_edit.edit_text.strip() for entry in self.entries
|
||||
if entry.key_edit.edit_text.strip()]
|
||||
if len(keys) != len(set(keys)):
|
||||
self.error = "Duplicate keys are not allowed"
|
||||
self.error_widget.set_text(("error", self.error))
|
||||
return False
|
||||
|
||||
for validation in self.validation_types:
|
||||
if validation == "required" and not values:
|
||||
self.error = "Atleast one parameter is required"
|
||||
break
|
||||
|
||||
self.error_widget.set_text(("error", self.error or ""))
|
||||
return self.error is None
|
Loading…
Add table
Add a link
Reference in a new issue