From 3262f2961329e49459d54441fe632316b094ac62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Brand=C3=A9ho?= Date: Fri, 27 Oct 2023 18:38:25 +0200 Subject: [PATCH] fix editable column and theme casting (#2051) --- .../web/utils/helpers/dataeditor.js | 12 +-- reflex/components/__init__.py | 1 + reflex/components/datadisplay/__init__.py | 2 +- reflex/components/datadisplay/dataeditor.py | 77 ++++++++++--------- reflex/components/datadisplay/dataeditor.pyi | 72 ++++++++--------- 5 files changed, 87 insertions(+), 77 deletions(-) diff --git a/reflex/.templates/web/utils/helpers/dataeditor.js b/reflex/.templates/web/utils/helpers/dataeditor.js index 9d7fc0748..bd8ce89b1 100644 --- a/reflex/.templates/web/utils/helpers/dataeditor.js +++ b/reflex/.templates/web/utils/helpers/dataeditor.js @@ -19,6 +19,7 @@ export function locateCell(row, column) { } export function formatCell(value, column) { + const editable = column.editable || true switch (column.type) { case "int": case "float": @@ -26,8 +27,8 @@ export function formatCell(value, column) { kind: GridCellKind.Number, data: value, displayData: value + "", - readonly: false, - allowOverlay: false + readonly: !editable, + allowOverlay: editable, } case "datetime": // value = moment format? @@ -36,15 +37,14 @@ export function formatCell(value, column) { kind: GridCellKind.Text, data: value, displayData: value, - readonly: false, - allowOverlay: true + readonly: !editable, + allowOverlay: editable, } case "bool": return { kind: GridCellKind.Boolean, data: value, - readonly: false, - // allowOverlay: true + readonly: !editable, } default: return { diff --git a/reflex/components/__init__.py b/reflex/components/__init__.py index 9d01c92fe..4ad0a999f 100644 --- a/reflex/components/__init__.py +++ b/reflex/components/__init__.py @@ -33,6 +33,7 @@ code_block = CodeBlock.create connection_banner = ConnectionBanner.create connection_modal = ConnectionModal.create data_editor = DataEditor.create +data_editor_theme = DataEditorTheme data_table = DataTable.create divider = Divider.create list = List.create diff --git a/reflex/components/datadisplay/__init__.py b/reflex/components/datadisplay/__init__.py index 88bea861b..3bf3cf8a4 100644 --- a/reflex/components/datadisplay/__init__.py +++ b/reflex/components/datadisplay/__init__.py @@ -2,7 +2,7 @@ from .badge import Badge from .code import Code, CodeBlock -from .dataeditor import DataEditor +from .dataeditor import DataEditor, DataEditorTheme from .datatable import DataTable from .divider import Divider from .keyboard_key import KeyboardKey diff --git a/reflex/components/datadisplay/dataeditor.py b/reflex/components/datadisplay/dataeditor.py index 8936b12de..6f4fc8c48 100644 --- a/reflex/components/datadisplay/dataeditor.py +++ b/reflex/components/datadisplay/dataeditor.py @@ -2,7 +2,7 @@ from __future__ import annotations from enum import Enum -from typing import Any, Callable, Dict, List, Optional +from typing import Any, Callable, Dict, List, Optional, Union from reflex.base import Base from reflex.components.component import Component, NoSSRComponent @@ -68,38 +68,38 @@ class GridColumnIcons(Enum): class DataEditorTheme(Base): """The theme for the DataEditor component.""" - accentColor: Optional[str] = None - accentFg: Optional[str] = None - accentLight: Optional[str] = None - baseFontStyle: Optional[str] = None - bgBubble: Optional[str] = None - bgBubbleSelected: Optional[str] = None - bgCell: Optional[str] = None - bgCellMedium: Optional[str] = None - bgHeader: Optional[str] = None - bgHeaderHasFocus: Optional[str] = None - bgHeaderHovered: Optional[str] = None - bgIconHeader: Optional[str] = None - bgSearchResult: Optional[str] = None - borderColor: Optional[str] = None - cellHorizontalPadding: Optional[int] = None - cellVerticalPadding: Optional[int] = None - drilldownBorder: Optional[str] = None - editorFontSize: Optional[str] = None - fgIconHeader: Optional[str] = None - fontFamily: Optional[str] = None - headerBottomBorderColor: Optional[str] = None - headerFontStyle: Optional[str] = None - horizontalBorderColor: Optional[str] = None - lineHeight: Optional[int] = None - linkColor: Optional[str] = None - textBubble: Optional[str] = None - textDark: Optional[str] = None - textGroupHeader: Optional[str] = None - textHeader: Optional[str] = None - textHeaderSelected: Optional[str] = None - textLight: Optional[str] = None - textMedium: Optional[str] = None + accent_color: Optional[str] = None + accent_fg: Optional[str] = None + accent_light: Optional[str] = None + base_font_style: Optional[str] = None + bg_bubble: Optional[str] = None + bg_bubble_selected: Optional[str] = None + bg_cell: Optional[str] = None + bg_cell_medium: Optional[str] = None + bg_header: Optional[str] = None + bg_header_has_focus: Optional[str] = None + bg_header_hovered: Optional[str] = None + bg_icon_header: Optional[str] = None + bg_search_result: Optional[str] = None + border_color: Optional[str] = None + cell_horizontal_padding: Optional[int] = None + cell_vertical_padding: Optional[int] = None + drilldown_border: Optional[str] = None + editor_font_size: Optional[str] = None + fg_icon_header: Optional[str] = None + font_family: Optional[str] = None + header_bottom_border_color: Optional[str] = None + header_font_style: Optional[str] = None + horizontal_border_color: Optional[str] = None + line_height: Optional[int] = None + link_color: Optional[str] = None + text_bubble: Optional[str] = None + text_dark: Optional[str] = None + text_group_header: Optional[str] = None + text_header: Optional[str] = None + text_header_selected: Optional[str] = None + text_light: Optional[str] = None + text_medium: Optional[str] = None class DataEditor(NoSSRComponent): @@ -198,7 +198,7 @@ class DataEditor(NoSSRComponent): scroll_offset_y: Var[int] # global theme - theme: Var[DataEditorTheme] + theme: Var[Union[DataEditorTheme, Dict]] def _get_imports(self): return imports.merge_imports( @@ -317,6 +317,11 @@ class DataEditor(NoSSRComponent): format.format_data_editor_column(col) for col in columns ] + if "theme" in props: + theme = props.get("theme") + if isinstance(theme, Dict): + props["theme"] = DataEditorTheme(**theme) + # Allow by default to select a region of cells in the grid. props.setdefault("getCellForSelection", True) @@ -405,4 +410,6 @@ def serialize_dataeditortheme(theme: DataEditorTheme): Returns: The serialized theme. """ - return format.json_dumps({k: v for k, v in theme.__dict__.items() if v is not None}) + return format.json_dumps( + {format.to_camel_case(k): v for k, v in theme.__dict__.items() if v is not None} + ) diff --git a/reflex/components/datadisplay/dataeditor.pyi b/reflex/components/datadisplay/dataeditor.pyi index 65be921e1..756215e80 100644 --- a/reflex/components/datadisplay/dataeditor.pyi +++ b/reflex/components/datadisplay/dataeditor.pyi @@ -3,12 +3,12 @@ # This file was generated by `scripts/pyi_generator.py`! # ------------------------------------------------------ -from typing import Any, Dict, Optional, overload, Literal, Union, List +from typing import Dict, Union, Literal, overload, List, Any, Optional from reflex.vars import Var, BaseVar, ComputedVar from reflex.event import EventChain, EventHandler, EventSpec from reflex.style import Style from enum import Enum -from typing import Any, Callable, Dict, List, Optional +from typing import Any, Callable, Dict, List, Optional, Union from reflex.base import Base from reflex.components.component import Component, NoSSRComponent from reflex.components.literals import LiteralRowMarker @@ -19,38 +19,38 @@ from reflex.vars import ImportVar, Var, get_unique_variable_name class GridColumnIcons(Enum): ... class DataEditorTheme(Base): - accentColor: Optional[str] - accentFg: Optional[str] - accentLight: Optional[str] - baseFontStyle: Optional[str] - bgBubble: Optional[str] - bgBubbleSelected: Optional[str] - bgCell: Optional[str] - bgCellMedium: Optional[str] - bgHeader: Optional[str] - bgHeaderHasFocus: Optional[str] - bgHeaderHovered: Optional[str] - bgIconHeader: Optional[str] - bgSearchResult: Optional[str] - borderColor: Optional[str] - cellHorizontalPadding: Optional[int] - cellVerticalPadding: Optional[int] - drilldownBorder: Optional[str] - editorFontSize: Optional[str] - fgIconHeader: Optional[str] - fontFamily: Optional[str] - headerBottomBorderColor: Optional[str] - headerFontStyle: Optional[str] - horizontalBorderColor: Optional[str] - lineHeight: Optional[int] - linkColor: Optional[str] - textBubble: Optional[str] - textDark: Optional[str] - textGroupHeader: Optional[str] - textHeader: Optional[str] - textHeaderSelected: Optional[str] - textLight: Optional[str] - textMedium: Optional[str] + accent_color: Optional[str] + accent_fg: Optional[str] + accent_light: Optional[str] + base_font_style: Optional[str] + bg_bubble: Optional[str] + bg_bubble_selected: Optional[str] + bg_cell: Optional[str] + bg_cell_medium: Optional[str] + bg_header: Optional[str] + bg_header_has_focus: Optional[str] + bg_header_hovered: Optional[str] + bg_icon_header: Optional[str] + bg_search_result: Optional[str] + border_color: Optional[str] + cell_horizontal_padding: Optional[int] + cell_vertical_padding: Optional[int] + drilldown_border: Optional[str] + editor_font_size: Optional[str] + fg_icon_header: Optional[str] + font_family: Optional[str] + header_bottom_border_color: Optional[str] + header_font_style: Optional[str] + horizontal_border_color: Optional[str] + line_height: Optional[int] + link_color: Optional[str] + text_bubble: Optional[str] + text_dark: Optional[str] + text_group_header: Optional[str] + text_header: Optional[str] + text_header_selected: Optional[str] + text_light: Optional[str] + text_medium: Optional[str] class DataEditor(NoSSRComponent): def get_event_triggers(self) -> Dict[str, Callable]: ... @@ -94,7 +94,9 @@ class DataEditor(NoSSRComponent): overscroll_y: Optional[Union[Var[int], int]] = None, scroll_offset_x: Optional[Union[Var[int], int]] = None, scroll_offset_y: Optional[Union[Var[int], int]] = None, - theme: Optional[Union[Var[DataEditorTheme], DataEditorTheme]] = None, + theme: Optional[ + Union[Var[Union[DataEditorTheme, Dict]], Union[DataEditorTheme, Dict]] + ] = None, style: Optional[Style] = None, key: Optional[Any] = None, id: Optional[Any] = None,