def test_szng004_on_focus(test, props, data_fn): app = dash.Dash(__name__) baseProps1 = get_props(data_fn=data_fn) baseProps2 = get_props(data_fn=data_fn) baseProps1.update(dict(**props, id="table1")) baseProps2.update(dict(**props, id="table2")) app.layout = Div( [ DataTable(**baseProps1), DataTable(**baseProps2), ] ) test.start_server(app) table2 = test.table("table2") for i in range(len(baseProps1.get("columns"))): table2.cell(0, i).click() t1 = test.driver.find_element_by_css_selector("#table1") t2 = test.driver.find_element_by_css_selector("#table2") cells_are_same_width(t1, t1) cells_are_same_width(t1, t2) assert test.get_log_errors() == []
def get_app(): app = dash.Dash(__name__) app.layout = html.Div([ DataTable( id="table", data=df[0:250], columns=[{ "name": i, "id": i, "hideable": i == "Complaint ID" } for i in rawDf.columns], editable=True, sort_action="native", include_headers_on_copy_paste=True, ), DataTable( id="table2", data=df[0:10], columns=[{ "name": i, "id": i, "deletable": True } for i in rawDf.columns], editable=True, sort_action="native", include_headers_on_copy_paste=True, ), ]) @app.callback( Output("table", "data"), [Input("table", "data_timestamp")], [State("table", "data"), State("table", "data_previous")], ) # pylint: disable=unused-argument def update_data(timestamp, current, previous): # pylint: enable=unused-argument if timestamp is None or current is None or previous is None: raise PreventUpdate modified = False if len(current) == len(previous): for (i, datum) in enumerate(current): previous_datum = previous[i] if datum["Unnamed: 0"] != previous_datum["Unnamed: 0"]: datum["Complaint ID"] = "MODIFIED" modified = True if modified: return current else: raise PreventUpdate return app
def test_szng002_percentages_result_in_same_widths(test): _fixed_columns = [dict(headers=True, data=1), dict(headers=True)] _fixed_rows = [dict(headers=True, data=1), dict(headers=True)] _merge_duplicate_headers = [True, False] variations = [] i = 0 for fixed_columns in _fixed_columns: for fixed_rows in _fixed_rows: for merge_duplicate_headers in _merge_duplicate_headers: variations.append({ **base_props, "fixed_columns": fixed_columns, "fixed_rows": fixed_rows, "merge_duplicate_headers": merge_duplicate_headers, "id": "table{}".format(i), }) i = i + 1 tables = [DataTable(**variation) for variation in variations] app = dash.Dash(__name__) app.layout = Div(tables) test.start_server(app) cells_are_same_width(test, "#table0", "#table0") for i in range(1, len(variations)): cells_are_same_width(test, "#table0", "#table{}".format(i)) assert test.get_log_errors() == []
def test_scrol002_edit_navigate(test, fixed_rows, fixed_columns, ops): props = {**base_props, **fixed_rows, **fixed_columns, **ops} app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") assert target.is_ready() fixed_width = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;" ) scroll_by(test, 200) # alignment is ok after editing a cell target.cell(0, 3).click() test.send_keys("abc" + Keys.ENTER) wait.until(lambda: target.cell(1, 3).is_selected(), 3) wait.until(lambda: -get_margin(test) == fixed_width + get_scroll(test), 3) # alignment is ok after navigating test.send_keys(Keys.ARROW_DOWN) test.send_keys(Keys.ARROW_RIGHT) wait.until(lambda: target.cell(2, 4).is_selected(), 3) wait.until(lambda: -get_margin(test) == fixed_width + get_scroll(test), 3) assert test.get_log_errors() == []
def test_ttip001_displays_aligned_tooltip(test, fixed_rows, fixed_columns, ops): props = { **base_props, **fixed_rows, **fixed_columns, **ops, **dict(tooltip_data=tooltip_data_text), } app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") cell = target.cell(0, 0) tooltip = target.tooltip target.is_ready() cell.move_to() assert tooltip.exists() assert tooltip.get_text() == ";; 1-1" assert_aligned(cell.get(), tooltip.get()) mid = math.ceil(len(columns) / 2) cell = target.cell(0, mid) cell.move_to() assert_aligned(cell.get(), tooltip.get()) cell = target.cell(0, len(columns) - 1) cell.move_to() assert_aligned(cell.get(), tooltip.get()) assert test.get_log_errors() == []
def update_calendar_live(n) -> DataTable: """ """ df = get_calender_df( HeimdallrSettings().google_calendar_id, HeimdallrSettings()._credentials_base_path, num_entries=ALL_CONSTANTS.TABLE_PAGE_SIZE, ) return DataTable( id="calender-table-0", columns=[{ "name": i, "id": i } for i in df.columns], data=df.to_dict("records"), page_size=ALL_CONSTANTS.TABLE_PAGE_SIZE, style_as_list_view=True, style_data_conditional=[ { "if": { "column_id": "start", "filter_query": "{start} > 3.9" }, "backgroundColor": "green", "color": "white", }, ], # TODO: MAKE GRADIENT TO ORANGE FOR WHEN NEARING START, and GREEN WHEN IN PROGRESS )
def update_table(n) -> Div: """ """ MQTT_CLIENT.loop() compute_machines = [] if GPU_STATS: df = to_overall_gpu_process_df(copy.deepcopy(GPU_STATS)) else: df = DataFrame(["No data"], columns=("data", )) compute_machines.append( DataTable( id="gpu-table-0", columns=[{ "name": i, "id": i } for i in df.columns], data=df.to_dict("records"), page_size=ALL_CONSTANTS.TABLE_PAGE_SIZE, # style_as_list_view=True, style_data_conditional=[{ "if": { "row_index": "odd" }, "backgroundColor": "rgb(248, 248, 248)" }], style_header={ "backgroundColor": "rgb(230, 230, 230)", "fontWeight": "bold", }, )) return Div(compute_machines)
def get_app(): app = dash.Dash(__name__) columns = [{"name": i, "id": i} for i in ["a", "b"]] data = [dict(a=1, b=2), dict(a=11, b=22)] app.layout = Div( [ Button(id="clear-table", children=["Clear table"]), DataTable(id="table", columns=columns, data=data), ] ) @app.callback( [Output("table", "data"), Output("table", "columns")], [Input("clear-table", "n_clicks")], ) def clear_table(n_clicks): if n_clicks is None: raise PreventUpdate nonlocal columns, data return (data, columns) if n_clicks % 2 == 0 else (None, None) return app
def get_app2(): app = dash.Dash(__name__) app.layout = html.Div([ html.Button("i=20", id="button", n_clicks=0), DataTable( id="table", page_size=5, columns=[{ "name": "i", "id": "i" }, { "name": "square", "id": "square" }], data=[{ "i": i, "square": i**2 } for i in range(50 + 1)], page_current=5, ), dcc.Graph(), ]) @app.callback(Output("table", "data"), Input("button", "n_clicks")) def update_table_data(n): return ([{ "i": i, "square": i**2 } for i in range(20 + 1)] if n > 0 else dash.no_update) return app
def test_scrol001_fixed_alignment(test, fixed_rows, fixed_columns, ops): props = {**base_props, **fixed_rows, **fixed_columns, **ops} app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") assert target.is_ready() fixed_width = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;" ) assert -get_margin(test) == pytest.approx(fixed_width, abs=1) scroll_by(test, 200) wait.until( lambda: -get_margin(test) == pytest.approx(fixed_width + 200, abs=1), 3) scroll_by(test, -200) wait.until(lambda: -get_margin(test) == pytest.approx(fixed_width, abs=1), 3) assert test.get_log_errors() == []
def szng003_on_prop_change_impl( test, fixed_columns, fixed_rows, merge_duplicate_headers, callback_props ): props = {**base_props, **fixed_columns, **fixed_rows, **merge_duplicate_headers} table = DataTable(**props, id="table") app = dash.Dash(__name__) app.layout = Div([Button(id="btn", children=["Update"]), table]) @app.callback( [Output("table", key) for key in callback_props.keys()], [Input("btn", "n_clicks")], prevent_initial_call=True, ) def callback(n_clicks): return [callback_props.get(key) for key in callback_props.keys()] test.start_server(app) target = test.driver.find_element_by_css_selector("#table") cells_are_same_width(target, target) test.driver.find_element_by_css_selector("#btn").click() cells_are_same_width(target, target) assert test.get_log_errors() == []
def get_app(props=dict(), special=False, clear=False): app = dash.Dash(__name__) baseProps = get_props(rows=200) if special: for c in baseProps.get("columns"): if c["id"] == "bbb": c["id"] = "b+bb" elif c["id"] == "ccc": c["id"] = "c cc" elif c["id"] == "ddd": c["id"] = "d:dd" elif c["id"] == "eee": c["id"] = "e-ee" elif c["id"] == "fff": c["id"] = "f_ff" elif c["id"] == "ggg": c["id"] = "g.gg" for i in range(len(baseProps["data"])): d = baseProps["data"][i] d["b+bb"] = d["bbb"] d["c cc"] = d["ccc"] d["d:dd"] = d["ddd"] d["e-ee"] = d["eee"] d["f_ff"] = d["fff"] d["g.gg"] = d["ggg"] baseProps.update(dict(filter_action="native")) baseProps.update(props) if clear: app.layout = Div([ DataTable(**baseProps), Button(id="btn", children=["Clear filters"]) ]) @app.callback(Output("table", "filter_query"), Input("btn", "n_clicks")) def get_filter(n_clicks): return "" else: app.layout = DataTable(**baseProps) return app
def get_app(props, data_fn=generate_mock_data): app = dash.Dash(__name__) baseProps = get_props(data_fn=data_fn) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(props=dict()): app = dash.Dash(__name__) baseProps = get_props() baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(props=dict()): app = dash.Dash(__name__) baseProps = get_props() baseProps.update( dict(columns=[dict(c, hideable="last") for c in baseProps["columns"]])) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(props=dict()): app = dash.Dash(__name__) baseProps = dict( columns=[dict(name=i, id=i, selectable=True) for i in rawDf.columns], data=df, editable=True, filter_action="native", fixed_columns={"headers": True}, fixed_rows={"headers": True}, page_action="native", row_deletable=True, row_selectable=True, sort_action="native", ) baseProps.update(props) app.layout = Div([DataTable(**baseProps), DataTable(**baseProps)]) return app
def load_table(filetype, payload): df = ( pd.read_csv(io.StringIO(base64.b64decode(payload).decode("utf-8"))) if filetype == "csv" else pd.read_excel(io.BytesIO(base64.b64decode(payload))) ) return html.Div( DataTable( data=df.to_dict("records"), columns=[{"id": i} for i in ["city", "country"]], ) )
def get_app( props=dict(), data_fn=generate_markdown_mock_data, assets_folder=None): app = (dash.Dash(__name__) if assets_folder is None else dash.Dash( __name__, assets_folder=assets_folder)) baseProps = get_props(data_fn=data_fn) baseProps.update(dict(filter_action="native", sort_action="native")) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(props=dict(), data_fn=generate_mock_data): app = dash.Dash(__name__) baseProps = get_props(data_fn=data_fn) for c in baseProps.get("columns"): c.update(dict(on_change=dict(action="coerce", failure="reject"))) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(editable): app = dash.Dash(__name__) baseProps = get_props() baseProps.update(dict(editable=editable)) if editable: for c in baseProps["columns"]: c["editable"] = not c["id"] in ["bbb", "eee", "fff"] app.layout = DataTable(**baseProps) return app
def get_sigle_row_app(props=dict()): app = dash.Dash(__name__) baseProps = get_props() baseProps.update( dict(columns=[ dict(c, hideable=True, name=c["id"]) for c in baseProps["columns"] ])) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def test_tbst024_row_selectable_filter_action(test): app = dash.Dash(__name__) app.layout = DataTable( id="test-table", row_selectable="single", filter_action="native", ) test.start_server(app) test.wait_for_element("#test-table") assert test.get_log_errors() == []
def test_ddvi001_fixed_table(dash_duo): app = Dash(__name__) app.layout = Div([ Dropdown( id="dropdown", options=[ { "label": "New York City", "value": "NYC" }, { "label": "Montreal", "value": "MTL" }, { "label": "San Francisco", "value": "SF" }, ], value="NYC", ), DataTable( id="table", columns=[{ "name": x, "id": x, "selectable": True } for x in ["a", "b", "c"]], editable=True, row_deletable=True, fixed_rows=dict(headers=True), fixed_columns=dict(headers=True), data=[{ "a": "a" + str(x), "b": "b" + str(x), "c": "c" + str(x) } for x in range(0, 20)], ), ]) dash_duo.start_server(app) dash_duo.find_element("#dropdown").click() dash_duo.wait_for_element("#dropdown .Select-menu-outer") dash_duo.percy_snapshot( "dcc.Dropdown dropdown overlaps table fixed rows/columns") assert dash_duo.get_logs() == []
def test_upft001_test_upload_with_different_file_types(filetype, dash_dcc): filepath = os.path.join( os.path.dirname(__file__), "upload-assets", f"upft001.{filetype}", ) app = Dash(__name__) app.layout = html.Div( [ html.Div(filepath, id="waitfor"), html.Div( id="upload-div", children=dcc.Upload( id="upload", children=html.Div(["Drag and Drop or ", html.A("Select a File")]), style={ "width": "100%", "height": "60px", "lineHeight": "60px", "borderWidth": "1px", "borderStyle": "dashed", "borderRadius": "5px", "textAlign": "center", }, ), ), html.Div(id="output"), html.Div(DataTable(data=[{}]), style={"display": "none"}), ] ) @app.callback(Output("output", "children"), [Input("upload", "contents")]) def update_output(contents): if contents is not None: return load_data_by_type(filetype, contents) dash_dcc.start_server(app) upload_div = dash_dcc.wait_for_element("#upload-div input[type=file]") upload_div.send_keys(filepath) dash_dcc.wait_for_text_to_equal("#raw-title", "Raw Content") dash_dcc.percy_snapshot("Core" + filepath) assert dash_dcc.get_logs() == []
def get_app(props=dict()): app = dash.Dash(__name__) baseProps = get_props() for i in range(len(baseProps["data"])): datum = baseProps["data"][i] if datum["eee"] % 2 == 0: datum.pop("eee") elif datum["eee"] % 10 == 5: datum["eee"] = "xx-{}-xx".format(datum["eee"]) for c in baseProps["columns"]: if c["id"] == "rows": c.update(dict(format=dict(specifier=".^5"))) elif c["id"] == "ccc": c.update( dict(format=dict( locale=dict(seperate_4digits=False), prefix=1000, specifier=".3f", ))) elif c["id"] == "ddd": c.update( dict( format=dict( locale=dict(symbol=["eq. $", ""], seperate_4digits=False), nully=0, specifier="$,.2f", ), on_change=dict(action="coerce", failure="default"), validation=dict(allow_nully=True), )) elif c["id"] == "eee": c.update( dict( format=dict(nully="N/A", specifier=""), on_change=dict(action="coerce", failure="default"), )) baseProps.update(dict(filter_action="native")) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def get_app(markdown_options): app = dash.Dash(__name__) props = dict( id="table", columns=[dict(name="a", id="a", type="text", presentation="markdown")], data=[dict(a="<h1>html h1 heading</h1>")], ) if markdown_options is not None: props["markdown_options"] = markdown_options app.layout = DataTable(**props) return app
def test_navg005_unselectable_cells(test, cell_selectable): app = dash.Dash(__name__) app.layout = DataTable( id="table", columns=[dict(id="a", name="a"), dict(id="b", name="b")], data=[dict(a=0, b=0), dict(a=1, b=2)], cell_selectable=cell_selectable, ) test.start_server(app) target = test.table("table") target.cell(0, "a").click() assert target.cell(0, "a").is_selected() == cell_selectable assert test.get_log_errors() == []
def get_app(): app = dash.Dash(__name__) app.layout = DataTable( id="table", data=df[0:250], columns=[ { "id": "Complaint ID", "name": "Complaint ID", "presentation": "markdown" }, { "id": "Product", "name": "Product", "presentation": "markdown" }, { "id": "Sub-product", "name": "Sub-product" }, { "id": "Issue", "name": "Issue", "presentation": "markdown" }, { "id": "Sub-issue", "name": "Sub-issue" }, { "id": "State", "name": "State", "presentation": "markdown" }, { "id": "ZIP", "name": "ZIP" }, ], editable=True, sort_action="native", include_headers_on_copy_paste=True, ) return app
def get_app_and_locks(): app = dash.Dash(__name__) app.layout = html.Div([ dcc.Input(id="input"), html.Button(["Blocking"], id="blocking"), html.Button(["Non Blocking"], id="non-blocking"), DataTable( id="table", columns=[{ "name": i, "id": i } for i in rawDf.columns], data=df, editable=True, filter_action="native", fixed_columns={"headers": True}, fixed_rows={"headers": True}, page_action="native", row_deletable=True, row_selectable=True, sort_action="native", ), ]) blocking_lock = Lock() non_blocking_lock = Lock() @app.callback(Output("table", "style_cell_conditional"), [Input("non-blocking", "n_clicks")]) def non_blocking_callback(clicks): if clicks is None: raise PreventUpdate with non_blocking_lock: return [] @app.callback(Output("table", "data"), [Input("blocking", "n_clicks")]) def blocking_callback(clicks): if clicks is None: raise PreventUpdate with blocking_lock: return df return app, blocking_lock, non_blocking_lock
def get_app(): app = dash.Dash(__name__) app.layout = html.Div( [ DataTable( id="table", columns=[{"name": i, "id": i} for i in rawDf.columns], data=df, editable=True, filter_action="native", fixed_columns={"headers": True}, fixed_rows={"headers": True}, page_action="native", page_size=10, row_deletable=True, row_selectable=True, sort_action="native", style_cell=dict(width=100, min_width=100, max_width=100), ), html.Div(id="props_container", children=["Nothing yet"]), ] ) @app.callback( Output("props_container", "children"), [Input("table", prop) for prop in props] ) def show_props(*args): # return 'Something yet!' # print('show props') return html.Table( [ html.Tr( [ html.Td(prop), html.Td( json.dumps(val) if val is not None else "None", id=prop ), ] ) for prop, val in zip(props, args) ] ) return app