feat: implement new grid creation with inline rename in DataGridsManager

- Add new_grid() method to create empty DataGrid under selected folder/leaf parent
  - Generate unique sheet names (Sheet1, Sheet2, ...) with _generate_unique_sheet_name()
  - Auto-select and open new node in edit mode for immediate renaming
  - Fix TreeView to cancel edit mode when selecting any node
  - Wire "New grid" icon to new_grid() instead of clear_tree()
  - Add 14 unit tests covering new_grid() scenarios and TreeView behavior
This commit is contained in:
2026-02-20 21:50:47 +01:00
parent 8f3b2e795e
commit 40a90c7ff5
4 changed files with 368 additions and 10 deletions

View File

@@ -184,10 +184,10 @@ class TreeView(MultipleInstance):
self._state = TreeViewState(self)
self.conf = conf or TreeViewConf()
self.commands = Commands(self)
if items:
self._state.items = items
if self.conf.icons:
self._state.icon_config = self.conf.icons
@@ -350,6 +350,7 @@ class TreeView(MultipleInstance):
def _save_rename(self, node_id: str, node_label: str):
"""Save renamed node with new label."""
logger.debug(f"_save_rename {node_id=}, {node_label=}")
if node_id not in self._state.items:
raise ValueError(f"Node {node_id} does not exist")
@@ -393,7 +394,9 @@ class TreeView(MultipleInstance):
"""Select a node."""
if node_id not in self._state.items:
raise ValueError(f"Node {node_id} does not exist")
# Cancel edit mode when selecting
self._state.editing = None
self._state.selected = node_id
return self
@@ -401,11 +404,11 @@ class TreeView(MultipleInstance):
"""Render action buttons for a node (visible on hover)."""
is_leaf = len(self._state.items[node_id].children) == 0
conf = self.conf
add_visible = conf.add_leaf if is_leaf else conf.add_node
edit_visible = conf.edit_leaf if is_leaf else conf.edit_node
add_visible = conf.add_leaf if is_leaf else conf.add_node
edit_visible = conf.edit_leaf if is_leaf else conf.edit_node
delete_visible = conf.delete_leaf if is_leaf else conf.delete_node
buttons = []
if add_visible:
buttons.append(mk.icon(add_circle20_regular, command=self.commands.add_child(node_id)))
@@ -413,7 +416,7 @@ class TreeView(MultipleInstance):
buttons.append(mk.icon(edit20_regular, command=self.commands.start_rename(node_id)))
if delete_visible:
buttons.append(mk.icon(delete20_regular, command=self.commands.delete_node(node_id)))
return Div(*buttons, cls="mf-treenode-actions")
def _render_node(self, node_id: str, level: int = 0):