import logging from datetime import datetime import arcticdb as adb import pandas as pd from nicegui import APIRouter, app, ui from aggridx import aggridx from annotations import PGroup from state import grids, lib OPTIONS = { ":getRowId": "(params) => params.data.index", # set row ID to index column "context": {"pgroup": None}, "defaultColDef": { "filter": True, "editable": True, "sortable": True, "resizable": True }, "pagination": True, "paginationAutoPageSize": True, "theme": "balham" } log = logging.getLogger(__name__) router = APIRouter() @router.page("/tables/{pgroup}") def table(pgroup: PGroup): pgroups = app.storage.user.get("pgroups", []) if pgroup in pgroups: table_show(pgroup) else: table_deny(pgroup) def table_show(pgroup): # with ui.left_drawer(value=False) as ld: # dark = ui.dark_mode(value=True) # ui.switch("dark mode").bind_value(dark) # with ui.page_sticky(position="left", x_offset=-12.5): # def cb(): # ld.toggle() # btn.icon = "sym_o_left_panel_close" if ld.value else "sym_o_left_panel_open" # btn = ui.button(icon="sym_o_left_panel_open", on_click=cb).props("flat dense") try: df = lib.read(pgroup).data except adb.exceptions.NoSuchVersionException: df = pd.DataFrame() df = df.reset_index() options = OPTIONS.copy() options["context"]["pgroup"] = pgroup grid = aggridx.from_pandas(df, options=options) grid.classes("h-[calc(100vh-2rem)]") # full height minus padding grid.on("cellValueChanged", update_adb) grid.on("cellValueChanged", update_grids) grids[pgroup].add(grid) def table_deny(pgroup): username = app.storage.user.get("username", "unknown user") log.error(f'access to pgroup {pgroup} denied for user "{username}"') with ui.column().classes("absolute-center items-center gap-8"): ui.icon("sym_o_front_hand", size="xl") ui.label(f"access to {pgroup} denied").classes("text-2xl") def update_adb(evt): if evt.args.get("source") != "edit": # ignore event if it was no direct edit return pgroup = evt.args["context"]["pgroup"] row_id = evt.args["rowId"] col_id = evt.args["colId"] new_val = evt.args["newValue"] index = datetime.fromisoformat(row_id) # nicegui converts datetime to str df = lib.read(pgroup, date_range=[index]).data df.at[index, col_id] = new_val lib.update(pgroup, df) def update_grids(evt): sender = evt.sender pgroup = evt.args["context"]["pgroup"] row_index = evt.args["rowIndex"] row_id = evt.args["rowId"] col_id = evt.args["colId"] new_val = evt.args["newValue"] for grid in grids[pgroup]: grid.set_cell_server(row_index, col_id, new_val) if grid == sender: # the sender is already up-to-date continue grid.set_cell_client(row_id, col_id, new_val)