Skip to content

Commit 8d13873

Browse files
committed
feat(gui): prefix undo stack entries with device name
When a firewall/cluster/host is affected, undo stack descriptions now start with the device name (e.g. "fw1: Move Interface eth0") for consistent, scannable undo history. Adds a prefix parameter to move_object, set_object_folder and make_subinterface.
1 parent 2b792b7 commit 8d13873

2 files changed

Lines changed: 28 additions & 8 deletions

File tree

src/firewallfabrik/gui/object_tree.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,12 +1060,18 @@ def _on_items_dropped(self, dest_item, entries):
10601060

10611061
any_changed = False
10621062
last_id = None
1063+
dest_prefix = self._get_device_prefix(dest_item)
10631064
for entry in entries:
10641065
model_cls = MODEL_MAP.get(entry.get('type'))
10651066
if model_cls is None:
10661067
continue
10671068
obj_id = uuid.UUID(entry['id'])
1068-
if self._ops.set_object_folder(obj_id, model_cls, target_folder):
1069+
if self._ops.set_object_folder(
1070+
obj_id,
1071+
model_cls,
1072+
target_folder,
1073+
prefix=dest_prefix,
1074+
):
10691075
any_changed = True
10701076
last_id = obj_id
10711077

@@ -1308,7 +1314,12 @@ def _ctx_make_subinterface(self, item, target_iface_id):
13081314
obj_id = item.data(0, Qt.ItemDataRole.UserRole)
13091315
if not obj_id:
13101316
return
1311-
if self._ops.make_subinterface(uuid.UUID(obj_id), uuid.UUID(target_iface_id)):
1317+
prefix = self._get_device_prefix(item)
1318+
if self._ops.make_subinterface(
1319+
uuid.UUID(obj_id),
1320+
uuid.UUID(target_iface_id),
1321+
prefix=prefix,
1322+
):
13121323
self.tree_changed.emit('', '')
13131324

13141325
# -- Duplicate --
@@ -1420,7 +1431,13 @@ def _ctx_move(self, item, target_lib_id):
14201431
model_cls = MODEL_MAP.get(obj_type)
14211432
if model_cls is None:
14221433
return
1423-
if self._ops.move_object(uuid.UUID(obj_id), model_cls, target_lib_id):
1434+
prefix = self._get_device_prefix(item)
1435+
if self._ops.move_object(
1436+
uuid.UUID(obj_id),
1437+
model_cls,
1438+
target_lib_id,
1439+
prefix=prefix,
1440+
):
14241441
self.tree_changed.emit(obj_id, obj_type)
14251442
QTimer.singleShot(0, lambda: self.select_object(uuid.UUID(obj_id)))
14261443

@@ -1514,6 +1531,7 @@ def _ctx_paste(self, item):
15141531
model_cls,
15151532
target_lib_id,
15161533
folder=target_folder,
1534+
prefix=prefix,
15171535
target_group_id=target_group_id,
15181536
):
15191537
last_id = cb_id

src/firewallfabrik/gui/object_tree_ops.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ def move_object(
498498
target_lib_id,
499499
*,
500500
folder=None,
501+
prefix='',
501502
target_group_id=None,
502503
):
503504
"""Move *obj_id* to *target_lib_id*. Returns True on success.
@@ -548,7 +549,7 @@ def move_object(
548549
iface.library_id = target_lib_id
549550

550551
session.commit()
551-
self._db_manager.save_state(f'Move {obj_type} {obj_name}')
552+
self._db_manager.save_state(f'{prefix}Move {obj_type} {obj_name}')
552553
except Exception:
553554
session.rollback()
554555
raise
@@ -769,7 +770,7 @@ def create_host_with_interfaces(
769770
# Folder move (drag & drop / cut-paste)
770771
# ------------------------------------------------------------------
771772

772-
def set_object_folder(self, obj_id, model_cls, folder):
773+
def set_object_folder(self, obj_id, model_cls, folder, *, prefix=''):
773774
"""Set or clear ``data.folder`` on an existing object.
774775
775776
*folder* is the target subfolder path (e.g. ``'A/B'``) or an
@@ -796,7 +797,8 @@ def set_object_folder(self, obj_id, model_cls, folder):
796797
obj.data = data
797798
session.commit()
798799
self._db_manager.save_state(
799-
f'Move {getattr(obj, "type", type(obj).__name__)} {obj.name} to folder'
800+
f'{prefix}Move {getattr(obj, "type", type(obj).__name__)}'
801+
f' {obj.name} to folder'
800802
)
801803
except Exception:
802804
session.rollback()
@@ -1113,7 +1115,7 @@ def remove_keyword(self, obj_ids_with_types, keyword):
11131115
# Make subinterface
11141116
# ------------------------------------------------------------------
11151117

1116-
def make_subinterface(self, iface_id, target_parent_iface_id):
1118+
def make_subinterface(self, iface_id, target_parent_iface_id, *, prefix=''):
11171119
"""Reparent an interface under another interface. Returns True on success."""
11181120
if self._db_manager is None:
11191121
return False
@@ -1125,7 +1127,7 @@ def make_subinterface(self, iface_id, target_parent_iface_id):
11251127
iface.parent_interface_id = target_parent_iface_id
11261128
iface_name = iface.name
11271129
session.commit()
1128-
self._db_manager.save_state(f'Make subinterface {iface_name}')
1130+
self._db_manager.save_state(f'{prefix}Make subinterface {iface_name}')
11291131
except Exception:
11301132
session.rollback()
11311133
raise

0 commit comments

Comments
 (0)