I can save and load Datagrid content

This commit is contained in:
2026-01-06 18:46:17 +01:00
parent 2f808ed226
commit 70abf21c14
6 changed files with 47 additions and 18 deletions

View File

@@ -37,17 +37,20 @@ markdown-it-py==4.0.0
mdurl==0.1.2 mdurl==0.1.2
more-itertools==10.8.0 more-itertools==10.8.0
myauth==0.2.1 myauth==0.2.1
mydbengine==0.1.0 mydbengine==0.2.1
myutils==0.5.0 -e git+ssh://git@sheerka.synology.me:1010/kodjo/MyFastHtml.git@2f808ed226e98738a1cf476e1f1dda8a1d9118b0#egg=myfasthtml
myutils==0.5.1
nh3==0.3.1 nh3==0.3.1
numpy==2.3.5 numpy==2.3.5
oauthlib==3.3.1 oauthlib==3.3.1
openpyxl==3.1.5 openpyxl==3.1.5
packaging==25.0 packaging==25.0
pandas==2.3.3 pandas==2.3.3
pandas-stubs==2.3.3.251201
passlib==1.7.4 passlib==1.7.4
pipdeptree==2.29.0 pipdeptree==2.29.0
pluggy==1.6.0 pluggy==1.6.0
pyarrow==22.0.0
pyasn1==0.6.1 pyasn1==0.6.1
pycparser==2.23 pycparser==2.23
pydantic==2.12.3 pydantic==2.12.3

View File

@@ -1,6 +1,9 @@
import json
import logging.config import logging.config
import pandas as pd
import yaml import yaml
from dbengine.handlers import BaseRefHandler, handlers
from fasthtml import serve from fasthtml import serve
from fasthtml.components import Div from fasthtml.components import Div
@@ -35,6 +38,23 @@ app, rt = create_app(protect_routes=True,
base_url="http://localhost:5003") base_url="http://localhost:5003")
class DataFrameHandler(BaseRefHandler):
def is_eligible_for(self, obj):
return isinstance(obj, pd.DataFrame)
def tag(self):
return "DataFrame"
def serialize_to_bytes(self, df) -> bytes:
from io import BytesIO
import pickle
return pickle.dumps(df)
def deserialize_from_bytes(self, data: bytes):
import pickle
return pickle.loads(data)
def create_sample_treeview(parent): def create_sample_treeview(parent):
""" """
Create a sample TreeView with a file structure for testing. Create a sample TreeView with a file structure for testing.
@@ -83,7 +103,9 @@ def create_sample_treeview(parent):
@rt("/") @rt("/")
def index(session): def index(session):
session_instance = UniqueInstance(session=session, _id=Ids.UserSession) session_instance = UniqueInstance(session=session,
_id=Ids.UserSession,
on_init=lambda: handlers.register_handler(DataFrameHandler()))
layout = Layout(session_instance, "Testing Layout") layout = Layout(session_instance, "Testing Layout")
layout.footer_left.add("Goodbye World") layout.footer_left.add("Goodbye World")

View File

@@ -12,7 +12,7 @@ from myfasthtml.core.instances import MultipleInstance
class DatagridState(DbObject): class DatagridState(DbObject):
def __init__(self, owner): def __init__(self, owner):
super().__init__(owner) super().__init__(owner, name=f"{owner.get_full_id()}-state")
with self.initializing(): with self.initializing():
self.sidebar_visible: bool = False self.sidebar_visible: bool = False
self.selected_view: str = None self.selected_view: str = None
@@ -25,12 +25,12 @@ class DatagridState(DbObject):
self.filtered: dict = {} self.filtered: dict = {}
self.edition: DatagridEditionState = DatagridEditionState() self.edition: DatagridEditionState = DatagridEditionState()
self.selection: DatagridSelectionState = DatagridSelectionState() self.selection: DatagridSelectionState = DatagridSelectionState()
self.html = None self.ne_data = None
class DatagridSettings(DbObject): class DatagridSettings(DbObject):
def __init__(self, owner): def __init__(self, owner):
super().__init__(owner) super().__init__(owner, name=f"{owner.get_full_id()}-settings")
with self.initializing(): with self.initializing():
self.file_name: Optional[str] = None self.file_name: Optional[str] = None
self.selected_sheet_name: Optional[str] = None self.selected_sheet_name: Optional[str] = None
@@ -52,12 +52,13 @@ class DataGrid(MultipleInstance):
self._state = DatagridState(self) self._state = DatagridState(self)
self.commands = Commands(self) self.commands = Commands(self)
def set_html(self, html): def init_from_dataframe(self, df):
self._state.html = html self._state.ne_data = df
def render(self): def render(self):
html = self._state.ne_data.to_html(index=False) if self._state.ne_data is not None else "Content lost !"
return Div( return Div(
NotStr(self._state.html) if self._state.html else "Content lost !", NotStr(html),
id=self._id id=self._id
) )

View File

@@ -23,7 +23,7 @@ class DocumentDefinition:
document_id: str document_id: str
namespace: str namespace: str
name: str name: str
type: str type: str # table, card,
tab_id: str tab_id: str
datagrid_id: str datagrid_id: str
@@ -32,7 +32,7 @@ class DataGridsState(DbObject):
def __init__(self, owner, name=None): def __init__(self, owner, name=None):
super().__init__(owner, name=name) super().__init__(owner, name=name)
with self.initializing(): with self.initializing():
self.elements: list = [DocumentDefinition] self.elements: list[DocumentDefinition] = []
class Commands(BaseCommands): class Commands(BaseCommands):
@@ -91,9 +91,8 @@ class DataGridsManager(MultipleInstance):
def open_from_excel(self, tab_id, file_upload: FileUpload): def open_from_excel(self, tab_id, file_upload: FileUpload):
excel_content = file_upload.get_content() excel_content = file_upload.get_content()
df = pd.read_excel(excel_content, file_upload.get_sheet_name()) df = pd.read_excel(excel_content, file_upload.get_sheet_name())
html = df.to_html(index=False)
dg = DataGrid(self._tabs_manager) dg = DataGrid(self._tabs_manager)
dg.set_html(html) dg.init_from_dataframe(df)
document = DocumentDefinition( document = DocumentDefinition(
document_id=str(uuid.uuid4()), document_id=str(uuid.uuid4()),
namespace=file_upload.get_file_basename(), namespace=file_upload.get_file_basename(),

View File

@@ -55,13 +55,14 @@ class DbObject:
self._initializing = old_state self._initializing = old_state
def __setattr__(self, name: str, value: str): def __setattr__(self, name: str, value: str):
if name.startswith("_") or name.startswith("ns") or getattr(self, "_initializing", False): if name.startswith("_") or name.startswith("ns_") or getattr(self, "_initializing", False):
super().__setattr__(name, value) super().__setattr__(name, value)
return return
old_value = getattr(self, name, None) if not name.startswith("ne_"):
if old_value == value: old_value = getattr(self, name, None)
return if old_value == value:
return
super().__setattr__(name, value) super().__setattr__(name, value)
self._save_self() self._save_self()

View File

@@ -144,8 +144,11 @@ class UniqueInstance(BaseInstance):
parent: Optional[BaseInstance] = None, parent: Optional[BaseInstance] = None,
session: Optional[dict] = None, session: Optional[dict] = None,
_id: Optional[str] = None, _id: Optional[str] = None,
auto_register: bool = True): auto_register: bool = True,
on_init=None):
super().__init__(parent, session, _id, auto_register) super().__init__(parent, session, _id, auto_register)
if on_init is not None:
on_init()
class MultipleInstance(BaseInstance): class MultipleInstance(BaseInstance):