Fixed unit tests

This commit is contained in:
2025-08-22 23:17:01 +02:00
parent 2c5fe004f5
commit b48aaf4621
3 changed files with 19 additions and 68 deletions

View File

@@ -1,4 +1,3 @@
import asyncio
import copy import copy
import logging import logging
from io import BytesIO from io import BytesIO
@@ -211,6 +210,7 @@ class DataGrid(BaseComponent):
self._state.columns = new_columns_states self._state.columns = new_columns_states
self._fast_access = self._init_fast_access(self._df)
self._views.recompute_need_save() self._views.recompute_need_save()
self._db.save_all(self._settings, self._state, self._df if new_column else None) 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(), _mk_keyboard_management(),
Div( Div(
self.mk_table_header(), self.mk_table_header(),
#self.mk_table_body(),
#self.mk_table_body_sse(),
self.mk_table_body_page(), self.mk_table_body_page(),
self.mk_table_footer(), self.mk_table_footer(),
cls="dt2-inner-table"), cls="dt2-inner-table"),
@@ -483,32 +481,11 @@ class DataGrid(BaseComponent):
header_class = "dt2-row dt2-header" + "" if self._settings.header_visible else " hidden" header_class = "dt2-row dt2-header" + "" if self._settings.header_visible else " hidden"
return Div( return Div(
Div(sse_swap="message"),
*[_mk_header(col_def) for col_def in self._state.columns], *[_mk_header(col_def) for col_def in self._state.columns],
cls=header_class, cls=header_class,
id=f"th_{self._id}" 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): def mk_table_body_page(self):
""" """
This function is used to update the table body when the vertical scrollbar reaches the end 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}", 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): def mk_table_footer(self):
return Div( return Div(
*[Div( *[Div(
@@ -560,7 +521,7 @@ class DataGrid(BaseComponent):
else: else:
last_row = None 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)], *[self.mk_body_cell(col_pos, row_index, col_def) for col_pos, col_def in enumerate(self._state.columns)],
cls="dt2-row", cls="dt2-row",
data_row=f"{row_index}", 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 {} **self.commands.get_page(page_index + 1) if row_index == last_row else {}
) for row_index in df.index[start:end]] ) 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 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): def mk_body_cell(self, col_pos, row_index, col_def: DataGridColumnState):
if not col_def.usable: if not col_def.usable:
return None return None
@@ -632,7 +577,6 @@ class DataGrid(BaseComponent):
return tuple(res) return tuple(res)
column_type = col_def.type 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] value = self._fast_access[col_def.col_id][row_index]
if column_type == ColumnType.Bool: 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 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. 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} return {col: df[col].to_numpy() for col in df.columns}
@timed @timed

View File

@@ -7,10 +7,13 @@ attr_map = {
"_id": "id", "_id": "id",
} }
def safe_attr(attr_name): def safe_attr(attr_name):
attr_name = attr_name.replace("hx_", "hx-") attr_name = attr_name.replace("hx_", "hx-")
attr_name = attr_name.replace("data_", "data-")
return attr_map.get(attr_name, attr_name) return attr_map.get(attr_name, attr_name)
def to_html(item): def to_html(item):
if item is None: if item is None:
return "" return ""
@@ -27,14 +30,14 @@ def to_html(item):
class MyFt: class MyFt:
def __init__(self, name, *args, **kwargs): def __init__(self, tag, *args, **kwargs):
self.name = name self.tag = tag
self.children = args self.children = args
self.attrs = kwargs self.attrs = {safe_attr(k): v for k, v in kwargs.items()}
def to_html(self): def to_html(self):
body_items = [to_html(item) for item in self.children] 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)}</div>" return f"<{self.tag} {' '.join(f'{k}="{v}"' for k, v in self.attrs.items())}>{' '.join(body_items)}</div>"
def __ft__(self): def __ft__(self):
return NotStr(self.to_html()) return NotStr(self.to_html())

View File

@@ -642,10 +642,10 @@ def extract_table_values_new(ft, header=True):
# first, get the header # first, get the header
if 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 = {} header_map = {}
res = OrderedDict() res = OrderedDict()
for row in header.children: for row in header_element.children:
col_id = row.attrs["data-col"] col_id = row.attrs["data-col"]
title = row.attrs["data-tooltip"] title = row.attrs["data-tooltip"]
header_map[col_id] = title 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] body = search_elements_by_name(ft, attrs={"class": "dt2-body"}, comparison_method='contains')[0]
for row in body.children: for row in body.children:
for col in row.children: for col in row.children:
col_id = col.attrs["data-col"] if hasattr(col, "attrs"):
cell_value = _get_cell_content_value(col) col_id = col.attrs["data-col"]
res[header_map[col_id]].append(cell_value) cell_value = _get_cell_content_value(col)
res[header_map[col_id]].append(cell_value)
return res return res