From b48aaf46218dfbc120c0e268ede7829eea99e1ad Mon Sep 17 00:00:00 2001 From: Kodjo Sossouvi Date: Fri, 22 Aug 2025 23:17:01 +0200 Subject: [PATCH] Fixed unit tests --- .../datagrid_new/components/DataGrid.py | 65 ++----------------- src/core/fasthtml_helper.py | 11 ++-- tests/helpers.py | 11 ++-- 3 files changed, 19 insertions(+), 68 deletions(-) diff --git a/src/components/datagrid_new/components/DataGrid.py b/src/components/datagrid_new/components/DataGrid.py index dbdc222..57d267c 100644 --- a/src/components/datagrid_new/components/DataGrid.py +++ b/src/components/datagrid_new/components/DataGrid.py @@ -1,4 +1,3 @@ -import asyncio import copy import logging from io import BytesIO @@ -211,6 +210,7 @@ class DataGrid(BaseComponent): self._state.columns = new_columns_states + self._fast_access = self._init_fast_access(self._df) self._views.recompute_need_save() self._db.save_all(self._settings, self._state, self._df if new_column else None) @@ -446,8 +446,6 @@ class DataGrid(BaseComponent): _mk_keyboard_management(), Div( self.mk_table_header(), - #self.mk_table_body(), - #self.mk_table_body_sse(), self.mk_table_body_page(), self.mk_table_footer(), cls="dt2-inner-table"), @@ -483,32 +481,11 @@ class DataGrid(BaseComponent): header_class = "dt2-row dt2-header" + "" if self._settings.header_visible else " hidden" return Div( - Div(sse_swap="message"), *[_mk_header(col_def) for col_def in self._state.columns], cls=header_class, id=f"th_{self._id}" ) - def mk_table_body_sse(self): - """ - This function is used to create a sse update - Unfortunately, the sse does not update the correct element - tb_{self._id} is not updated - Plus UI refreshment issues - """ - max_height = self._compute_body_max_height() - - return Div( - hx_ext="sse", - sse_connect=f"{ROUTE_ROOT}{Routes.YieldRow}?_id={self._id}", - sse_close='close', - sse_swap="message", - hx_swap="beforeend", - cls="dt2-body", - style=f"max-height:{max_height}px;", - id=f"tb_{self._id}", - ) - def mk_table_body_page(self): """ This function is used to update the table body when the vertical scrollbar reaches the end @@ -523,22 +500,6 @@ class DataGrid(BaseComponent): id=f"tb_{self._id}", ) - def mk_table_body(self): - df = self._get_filtered_df() - max_height = self._compute_body_max_height() - - return Div( - *[Div( - *[self.mk_body_cell(col_pos, row_index, col_def) for col_pos, col_def in enumerate(self._state.columns)], - cls="dt2-row", - data_row=f"{row_index}", - id=f"tr_{self._id}-{row_index}", - ) for row_index in df.index], - cls="dt2-body", - style=f"max-height:{max_height}px;", - id=f"tb_{self._id}" - ) - def mk_table_footer(self): return Div( *[Div( @@ -560,7 +521,7 @@ class DataGrid(BaseComponent): else: last_row = None - rows = [Div( + rows = [Div( *[self.mk_body_cell(col_pos, row_index, col_def) for col_pos, col_def in enumerate(self._state.columns)], cls="dt2-row", data_row=f"{row_index}", @@ -568,26 +529,10 @@ class DataGrid(BaseComponent): **self.commands.get_page(page_index + 1) if row_index == last_row else {} ) for row_index in df.index[start:end]] - rows.append(Script(f"manageScrollbars('{self._id}', false);"),) + rows.append(Script(f"manageScrollbars('{self._id}', false);"), ) return rows - async def mk_body_content_sse(self): - df = self._get_filtered_df() - for i, row_index in enumerate(df.index): - yield sse_message(Div( - *[self.mk_body_cell(col_pos, row_index, col_def) for col_pos, col_def in enumerate(self._state.columns)], - cls="dt2-row", - data_row=f"{row_index}", - id=f"tr_{self._id}-{row_index}", - )) - if i % 50 == 0: - await asyncio.sleep(0.01) - logger.debug(f"yielding row {i}") - - logger.debug(f"yielding close event") - yield f"event: close\ndata: \n\n" - def mk_body_cell(self, col_pos, row_index, col_def: DataGridColumnState): if not col_def.usable: return None @@ -632,7 +577,6 @@ class DataGrid(BaseComponent): return tuple(res) column_type = col_def.type - # value = self._df.iloc[row_index, col_def.col_index] value = self._fast_access[col_def.col_id][row_index] if column_type == ColumnType.Bool: @@ -922,6 +866,9 @@ class DataGrid(BaseComponent): dict: A dictionary where the keys are the column names of the input DataFrame and the values are the corresponding column values as NumPy arrays. """ + if df is None: + return {} + return {col: df[col].to_numpy() for col in df.columns} @timed diff --git a/src/core/fasthtml_helper.py b/src/core/fasthtml_helper.py index e9bc874..016f8a2 100644 --- a/src/core/fasthtml_helper.py +++ b/src/core/fasthtml_helper.py @@ -7,10 +7,13 @@ attr_map = { "_id": "id", } + def safe_attr(attr_name): attr_name = attr_name.replace("hx_", "hx-") + attr_name = attr_name.replace("data_", "data-") return attr_map.get(attr_name, attr_name) + def to_html(item): if item is None: return "" @@ -27,14 +30,14 @@ def to_html(item): class MyFt: - def __init__(self, name, *args, **kwargs): - self.name = name + def __init__(self, tag, *args, **kwargs): + self.tag = tag self.children = args - self.attrs = kwargs + self.attrs = {safe_attr(k): v for k, v in kwargs.items()} def to_html(self): body_items = [to_html(item) for item in self.children] - return f"<{self.name} {' '.join(f'{safe_attr(k)}="{v}"' for k, v in self.attrs.items())}>{' '.join(body_items)}" + return f"<{self.tag} {' '.join(f'{k}="{v}"' for k, v in self.attrs.items())}>{' '.join(body_items)}" def __ft__(self): return NotStr(self.to_html()) diff --git a/tests/helpers.py b/tests/helpers.py index 9bb5791..4bae796 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -642,10 +642,10 @@ def extract_table_values_new(ft, header=True): # first, get the header if header: - header = search_elements_by_name(ft, attrs={"class": "dt2-header"}, comparison_method='contains')[0] + header_element = search_elements_by_name(ft, attrs={"class": "dt2-header"}, comparison_method='contains')[0] header_map = {} res = OrderedDict() - for row in header.children: + for row in header_element.children: col_id = row.attrs["data-col"] title = row.attrs["data-tooltip"] header_map[col_id] = title @@ -654,9 +654,10 @@ def extract_table_values_new(ft, header=True): body = search_elements_by_name(ft, attrs={"class": "dt2-body"}, comparison_method='contains')[0] for row in body.children: for col in row.children: - col_id = col.attrs["data-col"] - cell_value = _get_cell_content_value(col) - res[header_map[col_id]].append(cell_value) + if hasattr(col, "attrs"): + col_id = col.attrs["data-col"] + cell_value = _get_cell_content_value(col) + res[header_map[col_id]].append(cell_value) return res