Improved command management to reduce the number of instances
This commit is contained in:
@@ -57,7 +57,7 @@ class DataGrid(MultipleInstance):
|
||||
|
||||
def render(self):
|
||||
return Div(
|
||||
NotStr(self._state.html),
|
||||
NotStr(self._state.html) if self._state.html else "Content lost !",
|
||||
id=self._id
|
||||
)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
|
||||
import pandas as pd
|
||||
@@ -10,7 +11,7 @@ from myfasthtml.controls.Panel import Panel
|
||||
from myfasthtml.controls.TabsManager import TabsManager
|
||||
from myfasthtml.controls.TreeView import TreeView, TreeNode
|
||||
from myfasthtml.controls.helpers import mk
|
||||
from myfasthtml.core.commands import Command, LambdaCommand
|
||||
from myfasthtml.core.commands import Command
|
||||
from myfasthtml.core.dbmanager import DbObject
|
||||
from myfasthtml.core.instances import MultipleInstance, InstancesManager
|
||||
from myfasthtml.icons.fluent_p1 import table_add20_regular
|
||||
@@ -19,6 +20,7 @@ from myfasthtml.icons.fluent_p3 import folder_open20_regular
|
||||
|
||||
@dataclass
|
||||
class DocumentDefinition:
|
||||
document_id: str
|
||||
namespace: str
|
||||
name: str
|
||||
type: str
|
||||
@@ -30,7 +32,7 @@ class DataGridsState(DbObject):
|
||||
def __init__(self, owner, name=None):
|
||||
super().__init__(owner, name=name)
|
||||
with self.initializing():
|
||||
self.elements: list = []
|
||||
self.elements: list = [DocumentDefinition]
|
||||
|
||||
|
||||
class Commands(BaseCommands):
|
||||
@@ -61,7 +63,11 @@ class Commands(BaseCommands):
|
||||
self._owner.clear_tree).htmx(target=f"#{self._owner._tree.get_id()}")
|
||||
|
||||
def show_document(self):
|
||||
return LambdaCommand(self._owner, lambda: print("show_document"))
|
||||
return Command("ShowDocument",
|
||||
"Show document",
|
||||
self._owner,
|
||||
self._owner.select_document,
|
||||
key="SelectNode")
|
||||
|
||||
|
||||
class DataGridsManager(MultipleInstance):
|
||||
@@ -89,18 +95,29 @@ class DataGridsManager(MultipleInstance):
|
||||
dg = DataGrid(self._tabs_manager)
|
||||
dg.set_html(html)
|
||||
document = DocumentDefinition(
|
||||
document_id=str(uuid.uuid4()),
|
||||
namespace=file_upload.get_file_basename(),
|
||||
name=file_upload.get_sheet_name(),
|
||||
type="excel",
|
||||
tab_id=tab_id,
|
||||
datagrid_id=dg.get_id()
|
||||
)
|
||||
self._state.elements = self._state.elements + [document]
|
||||
self._state.elements = self._state.elements + [document] # do not use append() other it won't be saved
|
||||
parent_id = self._tree.ensure_path(document.namespace)
|
||||
tree_node = TreeNode(label=document.name, type="excel", parent=parent_id)
|
||||
self._tree.add_node(tree_node, parent_id=parent_id)
|
||||
return self._mk_tree(), self._tabs_manager.change_tab_content(tab_id, document.name, Panel(self).set_main(dg))
|
||||
|
||||
def select_document(self, node_id):
|
||||
document_id = self._tree.get_bag(node_id)
|
||||
try:
|
||||
document = next(filter(lambda x: x.document_id == document_id, self._state.elements))
|
||||
dg = DataGrid(self._tabs_manager, _id=document.datagrid_id)
|
||||
return self._tabs_manager.show_or_create_tab(document.tab_id, document.name, dg)
|
||||
except StopIteration:
|
||||
# the selected node is not a document (it's a folder)
|
||||
return None
|
||||
|
||||
def clear_tree(self):
|
||||
self._state.elements = []
|
||||
self._tree.clear()
|
||||
@@ -117,7 +134,11 @@ class DataGridsManager(MultipleInstance):
|
||||
tree = TreeView(self, _id="-treeview")
|
||||
for element in self._state.elements:
|
||||
parent_id = tree.ensure_path(element.namespace)
|
||||
tree.add_node(TreeNode(label=element.name, type=element.type, parent=parent_id, id=element.datagrid_id))
|
||||
tree.add_node(TreeNode(id=element.document_id,
|
||||
label=element.name,
|
||||
type=element.type,
|
||||
parent=parent_id,
|
||||
bag=element.document_id))
|
||||
return tree
|
||||
|
||||
def render(self):
|
||||
|
||||
@@ -40,7 +40,7 @@ class PanelIds:
|
||||
|
||||
@dataclass
|
||||
class PanelConf:
|
||||
left: bool = True
|
||||
left: bool = False
|
||||
right: bool = True
|
||||
|
||||
|
||||
|
||||
@@ -58,29 +58,34 @@ class TabsManagerState(DbObject):
|
||||
|
||||
class Commands(BaseCommands):
|
||||
def show_tab(self, tab_id):
|
||||
return Command(f"{self._prefix}ShowTab",
|
||||
return Command(f"ShowTab",
|
||||
"Activate or show a specific tab",
|
||||
self._owner,
|
||||
self._owner.show_tab,
|
||||
args=[tab_id,
|
||||
True,
|
||||
False]).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
False],
|
||||
key=f"{self._owner.get_full_id()}-ShowTab-{tab_id}",
|
||||
).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
|
||||
def close_tab(self, tab_id):
|
||||
return Command(f"{self._prefix}CloseTab",
|
||||
return Command(f"CloseTab",
|
||||
"Close a specific tab",
|
||||
self._owner,
|
||||
self._owner.close_tab,
|
||||
args=[tab_id]).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
kwargs={"tab_id": tab_id},
|
||||
).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
|
||||
def add_tab(self, label: str, component: Any, auto_increment=False):
|
||||
return Command(f"{self._prefix}AddTab",
|
||||
return Command(f"AddTab",
|
||||
"Add a new tab",
|
||||
self._owner,
|
||||
self._owner.on_new_tab,
|
||||
args=[label,
|
||||
component,
|
||||
auto_increment]).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
auto_increment],
|
||||
key="#{id-name-args}",
|
||||
).htmx(target=f"#{self._id}-controller", swap="outerHTML")
|
||||
|
||||
|
||||
class TabsManager(MultipleInstance):
|
||||
@@ -148,6 +153,13 @@ class TabsManager(MultipleInstance):
|
||||
tab_id = self.create_tab(label, component)
|
||||
return self.show_tab(tab_id, oob=False)
|
||||
|
||||
def show_or_create_tab(self, tab_id, label, component, activate=True):
|
||||
logger.debug(f"show_or_create_tab {tab_id=}, {label=}, {component=}, {activate=}")
|
||||
if tab_id not in self._state.tabs:
|
||||
self._add_or_update_tab(tab_id, label, component, activate)
|
||||
|
||||
return self.show_tab(tab_id, activate=activate, oob=True)
|
||||
|
||||
def create_tab(self, label: str, component: Any, activate: bool = True) -> str:
|
||||
"""
|
||||
Add a new tab or update an existing one with the same component type, ID and label.
|
||||
|
||||
@@ -267,6 +267,12 @@ class TreeView(MultipleInstance):
|
||||
self._state.update(state)
|
||||
return self
|
||||
|
||||
def get_bag(self, node_id: str):
|
||||
try:
|
||||
return self._state.items[node_id].bag
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def _toggle_node(self, node_id: str):
|
||||
"""Toggle expand/collapse state of a node."""
|
||||
if node_id in self._state.opened:
|
||||
|
||||
Reference in New Issue
Block a user