Implemented Delete feature in DataGridsManager.py. There is still a bug as DBEngine.delete is not implemented

Improved readability for tests using matcher
This commit is contained in:
2026-02-21 18:31:11 +01:00
parent 730f55d65b
commit d447220eae
12 changed files with 460 additions and 49 deletions

View File

@@ -1022,12 +1022,16 @@ class DataGrid(MultipleInstance):
def delete(self):
"""
remove DBEngine entries
:return:
Remove DBEngine entries for this DataGrid.
Deletes all persistent state associated with this grid:
- State (columns, rows, selection, formatting, etc.)
- Settings (namespace, name, visibility options, etc.)
- DataFrame store (data and fast access structures)
"""
# self._state.delete()
# self._settings.delete()
pass
self._state.delete()
self._settings.delete()
self._df_store.delete()
def __ft__(self):
return self.render()

View File

@@ -73,6 +73,13 @@ class Commands(BaseCommands):
self._owner.select_document,
key="SelectNode")
def delete_grid(self):
return Command("DeleteGrid",
"Delete grid",
self._owner,
self._owner.delete_grid,
key="DeleteNode")
class DataGridsManager(SingleInstance, DatagridMetadataProvider):
@@ -85,6 +92,7 @@ class DataGridsManager(SingleInstance, DatagridMetadataProvider):
self._state = DataGridsState(self)
self._tree = self._mk_tree()
self._tree.bind_command("SelectNode", self.commands.show_document())
self._tree.bind_command("DeleteNode", self.commands.delete_grid(), when="before")
self._tabs_manager = InstancesManager.get_by_type(self._session, TabsManager, None)
self._registry = DataGridsRegistry(parent)
@@ -240,6 +248,55 @@ class DataGridsManager(SingleInstance, DatagridMetadataProvider):
except StopIteration:
# the selected node is not a document (it's a folder)
return None
def delete_grid(self, node_id):
"""
Delete a grid and all its associated resources.
This method is called BEFORE TreeView._delete_node() to ensure we can
access the node's bag to retrieve the document_id.
Args:
node_id: ID of the TreeView node to delete
Returns:
None (TreeView will handle the node removal)
"""
document_id = self._tree.get_bag(node_id)
if document_id is None:
# Node is a folder, not a document - nothing to clean up
return None
try:
# Find the document
document = next(filter(lambda x: x.document_id == document_id, self._state.elements))
# Get the DataGrid instance
dg = DataGrid(self, _id=document.datagrid_id)
# Close the tab
self._tabs_manager.close_tab(document.tab_id)
# Remove from registry
self._registry.remove(document.datagrid_id)
# Clean up DataGrid (delete DBEngine entries)
dg.delete()
# Remove from InstancesManager
InstancesManager.remove(self._session, document.datagrid_id)
# Remove DocumentDefinition from state
self._state.elements = [d for d in self._state.elements if d.document_id != document_id]
self._state.save()
except StopIteration:
# Document not found - already deleted or invalid state
pass
# Note: We do NOT call tree._delete_node() here because TreeView will do it
# automatically after this "before" bound command completes
return None
def create_tab_content(self, tab_id):
"""

View File

@@ -2,18 +2,23 @@ from myfasthtml.core.constants import ColumnType
from myfasthtml.icons.fluent import question20_regular, brain_circuit20_regular, number_symbol20_regular, \
number_row20_regular
from myfasthtml.icons.fluent_p1 import checkbox_checked20_regular, checkbox_unchecked20_regular, \
checkbox_checked20_filled, math_formula16_regular, folder20_regular
checkbox_checked20_filled, math_formula16_regular, folder20_regular, document20_regular
from myfasthtml.icons.fluent_p2 import text_field20_regular, text_bullet_list_square20_regular
from myfasthtml.icons.fluent_p3 import calendar_ltr20_regular
default_icons = {
# default type icons
None: question20_regular,
True: checkbox_checked20_regular,
False: checkbox_unchecked20_regular,
"Brain": brain_circuit20_regular,
"TreeViewFolder" : folder20_regular,
# TreeView icons
"TreeViewFolder": folder20_regular,
"TreeViewFile": document20_regular,
# Datagrid column icons
ColumnType.RowIndex: number_symbol20_regular,
ColumnType.Text: text_field20_regular,
ColumnType.Number: number_row20_regular,

View File

@@ -192,7 +192,7 @@ class TreeView(MultipleInstance):
if self.conf.icons:
self._state.icon_config = self.conf.icons
else:
self._state.icon_config = {"folder": "TreeViewFolder"}
self._state.icon_config = {"folder": "TreeViewFolder", "file": "TreeViewFile"}
def set_icon_config(self, config: dict[str, str]):
"""
@@ -458,8 +458,9 @@ class TreeView(MultipleInstance):
), command=CommandTemplate("TreeView.SaveRename", self.commands.save_rename, args=[node_id]))
else:
label_element = mk.label(
Span(node.label, cls="mf-treenode-label text-sm"),
node.label,
icon=icon,
cls="mf-treenode-label text-sm",
enable_button=False,
command=self.commands.select_node(node_id)
)

View File

@@ -105,7 +105,7 @@ class mk:
kwargs)
icon_part = Span(icon, cls=f"mf-icon-{mk.convert_size(size)} mr-1") if icon else None
text_part = Span(text, cls=f"text-{size} truncate")
return mk.mk(Label(icon_part, text_part, cls=merged_cls, **kwargs), command=command, binding=binding)
return mk.mk(Span(icon_part, text_part, cls=merged_cls, **kwargs), command=command, binding=binding)
@staticmethod
def convert_size(size: str):