Fixed tab recreation logic and improved error handling

This commit is contained in:
2026-01-10 21:18:23 +01:00
parent 5201858b79
commit 47848bb2fd
3 changed files with 64 additions and 11 deletions

View File

@@ -117,6 +117,29 @@ class DataGridsManager(MultipleInstance):
# the selected node is not a document (it's a folder)
return None
def create_tab_content(self, tab_id):
"""
Recreate the content for a tab managed by this DataGridsManager.
Called by TabsManager when the content is not in cache (e.g., after restart).
Args:
tab_id: ID of the tab to recreate content for
Returns:
The recreated component (Panel with DataGrid)
"""
# Find the document associated with this tab
document = next((d for d in self._state.elements if d.tab_id == tab_id), None)
if document is None:
raise ValueError(f"No document found for tab {tab_id}")
# Recreate the DataGrid with its saved state
dg = DataGrid(self._tabs_manager, _id=document.datagrid_id)
# Wrap in Panel
return Panel(self).set_main(dg)
def clear_tree(self):
self._state.elements = []
self._tree.clear()

View File

@@ -120,15 +120,36 @@ class TabsManager(MultipleInstance):
if tab_config["component"] is None:
return Div("Tab content does not support serialization.")
# 1. Try to get existing component instance
res = InstancesManager.get(self._session, tab_config["component"][1], None)
if res is not None:
logger.debug(f"Component {tab_config['component'][1]} already exists")
return res
# 2. Get or create parent
if tab_config["component_parent"] is None:
logger.error(f"No parent defined for tab {tab_id}")
return Div("Failed to retrieve tab content.")
parent = InstancesManager.get(self._session, tab_config["component_parent"][1], None)
if parent is None:
logger.error(f"Parent {tab_config['component_parent'][1]} not found for tab {tab_id}")
return Div("Parent component not available")
# 3. If parent supports create_tab_content, use it
if hasattr(parent, 'create_tab_content'):
try:
logger.debug(f"Component not created yet. Need to manually create it.")
return InstancesManager.dynamic_get(self._session, tab_config["component_parent"], tab_config["component"])
logger.debug(f"Asking parent {tab_config['component_parent'][1]} to create tab content for {tab_id}")
content = parent.create_tab_content(tab_id)
# Store in cache
self._state.ns_tabs_content[tab_id] = content
return content
except Exception as e:
logger.error(f"Error while retrieving tab content: {e}")
logger.error(f"Error while parent creating tab content: {e}")
return Div("Failed to retrieve tab content.")
else:
# Parent doesn't support create_tab_content, fallback to error
logger.error(f"Parent {tab_config['component_parent'][1]} doesn't support create_tab_content")
return Div("Failed to retrieve tab content.")
def _get_or_create_tab_content(self, tab_id):

View File

@@ -210,15 +210,24 @@ class InstancesManager:
@staticmethod
def dynamic_get(session, component_parent: tuple, component: tuple):
parent_type, parent_id = component_parent
component_type, component_id = component
# 1. Check if component already exists
existing = InstancesManager.get(session, component_id, None)
if existing is not None:
logger.debug(f"Component {component_id} already exists, returning existing instance")
return existing
# 2. Component doesn't exist, create it
parent_type, parent_id = component_parent
# parent should always exist
parent = InstancesManager.get(session, parent_id)
real_component_type = snake_to_pascal(component_type.removeprefix("mf-"))
component_full_type = f"myfasthtml.controls.{real_component_type}.{real_component_type}"
cls = get_class(component_full_type)
logger.debug(f"Creating new component {component_id} of type {real_component_type}")
return cls(parent, _id=component_id)
@staticmethod