Fixed transform issue and added reset

This commit is contained in:
2026-02-22 19:06:40 +01:00
parent 3715954222
commit b5abb59332
3 changed files with 98 additions and 49 deletions

View File

@@ -69,7 +69,7 @@ class Commands(BaseCommands):
"UpdateViewState",
"Update view transform and layout mode",
self._owner,
self._owner._handle_update_view_state
self._owner.handle_update_view_state
).htmx(target=f"#{self._id}", swap='none')
def apply_filter(self):
@@ -81,9 +81,21 @@ class Commands(BaseCommands):
"ApplyFilter",
"Apply filter to graph",
self._owner,
self._owner._handle_apply_filter,
self._owner.handle_apply_filter,
key="#{id}-apply-filter",
).htmx(target=f"#{self._id}")
def reset_view(self):
"""Reset the view transform to default values.
This command can be used to fix stuck/frozen canvas by resetting zoom/pan state.
"""
return Command(
"ResetTransform",
"Reset view transform",
self._owner,
self._owner.handle_reset_view
).htmx(target=f"#{self._id}")
class HierarchicalCanvasGraph(MultipleInstance):
@@ -135,64 +147,81 @@ class HierarchicalCanvasGraph(MultipleInstance):
"""
return self._state
def get_selected_id(self) -> Optional[str]:
"""Get the currently selected node ID.
Returns:
str or None: The selected node ID, or None if no selection
"""
return self._state.ns_selected_id
# def get_selected_id(self) -> Optional[str]:
# """Get the currently selected node ID.
#
# Returns:
# str or None: The selected node ID, or None if no selection
# """
# return self._state.ns_selected_id
#
# def set_collapsed(self, node_ids: set):
# """Set the collapsed state of nodes.
#
# Args:
# node_ids: Set of node IDs to mark as collapsed
# """
# self._state.collapsed = list(node_ids)
# logger.debug(f"set_collapsed: {len(node_ids)} nodes collapsed")
#
# def toggle_node(self, node_id: str):
# """Toggle the collapsed state of a node.
#
# Args:
# node_id: The ID of the node to toggle
#
# Returns:
# self: For chaining
# """
# collapsed_set = set(self._state.collapsed)
# if node_id in collapsed_set:
# collapsed_set.remove(node_id)
# logger.debug(f"toggle_node: expanded {node_id}")
# else:
# collapsed_set.add(node_id)
# logger.debug(f"toggle_node: collapsed {node_id}")
#
# self._state.collapsed = list(collapsed_set)
# return self
def set_collapsed(self, node_ids: set):
"""Set the collapsed state of nodes.
Args:
node_ids: Set of node IDs to mark as collapsed
"""
self._state.collapsed = list(node_ids)
logger.debug(f"set_collapsed: {len(node_ids)} nodes collapsed")
def toggle_node(self, node_id: str):
"""Toggle the collapsed state of a node.
Args:
node_id: The ID of the node to toggle
Returns:
self: For chaining
"""
collapsed_set = set(self._state.collapsed)
if node_id in collapsed_set:
collapsed_set.remove(node_id)
logger.debug(f"toggle_node: expanded {node_id}")
else:
collapsed_set.add(node_id)
logger.debug(f"toggle_node: collapsed {node_id}")
self._state.collapsed = list(collapsed_set)
return self
def _handle_update_view_state(self, transform=None, layout_mode=None):
def handle_update_view_state(self, transform: Optional[dict] = None, layout_mode: Optional[str] = None):
"""Internal handler to update view state from client.
Args:
transform: Optional dict with zoom/pan transform state
transform: Optional dict with zoom/pan transform state (received as JSON string)
layout_mode: Optional string with layout orientation
Returns:
str: Empty string (no UI update needed)
"""
if transform is not None:
# Parse JSON string to dict (sent as JSON.stringify() from JS)
if isinstance(transform, str):
try:
transform = json.loads(transform)
except (json.JSONDecodeError, TypeError) as e:
logger.error(f"Failed to parse transform JSON: {e}")
return ""
self._state.transform = transform
logger.debug(f"Transform updated: {self._state.transform}")
if layout_mode is not None:
self._state.layout_mode = layout_mode
logger.debug(f"Layout mode updated: {self._state.layout_mode}")
return ""
def _handle_apply_filter(self, query_param="text", value=None):
def handle_reset_view(self):
"""Internal handler to reset view transform to default values.
Returns:
self: For HTMX to render the updated graph with reset transform
"""
self._state.transform = {"x": 0, "y": 0, "scale": 1}
self._state.collapsed = []
logger.debug("Transform and collapsed state reset to defaults")
return self
def handle_apply_filter(self, query_param="text", value=None):
"""Internal handler to apply filter and re-render the graph.
Args: