Skip to content

Commit

Permalink
Merge pull request #279 from maxfordham/275-display_bn_shownull-behav…
Browse files Browse the repository at this point in the history
…ing-like-a-class-var

🐛 Resolve bn_shownull display issue
  • Loading branch information
ollyhensby authored Feb 12, 2024
2 parents 568e712 + 7f1546c commit 07f10d2
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 71 deletions.
45 changes: 8 additions & 37 deletions src/ipyautoui/autoform.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# +

"""layout attributes of a form box
"""
# %run _dev_maplocal_params.py
Expand All @@ -9,34 +7,19 @@
import typing as ty

from IPython.display import display, clear_output
from ipyautoui.constants import BUTTON_WIDTH_MIN
from ipyautoui.nullable import Nullable
from ipyautoui.constants import KWARGS_SHOWNULL, KWARGS_SHOWRAW, SHOWNULL_ICON_SHOW, SHOWNULL_ICON_HIDE
from ipyautoui.custom.buttonbars import SaveButtonBar
from ipyautoui.custom.title_description import TitleDescription
from ipyautoui._utils import display_python_string, show_hide_widget
from ipyautoui.nullable import Nullable

def make_bold(s: str) -> str:
return f"<big><b>{s}</b></big>"


# -

SHOWNULL_ICON_SHOW = "plus"
SHOWNULL_ICON_HIDE = "minus"
KWARGS_SHOWNULL = dict(
icon=SHOWNULL_ICON_SHOW,
layout=w.Layout(width=BUTTON_WIDTH_MIN, display=""),
tooltip="show null form fields",
style={"font_weight": "bold"})
KWARGS_SHOWRAW = dict(icon="code",
layout=w.Layout(width=BUTTON_WIDTH_MIN, display="None"),
tooltip="show raw data",
style={"font_weight": "bold"},
)


class ShowNull(tr.HasTraits):
display_bn_shownull = tr.Bool(default_value=True)
display_bn_shownull = tr.Bool(default_value=True)

@tr.observe("display_bn_shownull")
def _observe_display_bn_shownull(self, change):
Expand All @@ -63,20 +46,13 @@ def bn_shownull(self):
def bn_shownull(self, value):
self._bn_shownull = value

def show_hide_bn_nullable(self): # work with AutoObject only
is_nullable = [True for v in self.di_widgets.values() if isinstance(v, Nullable)]
if len(is_nullable) > 0:
if self.display_bn_shownull:
show_hide_widget(self.bn_shownull, self.display_bn_shownull)
# NOTE: don't think should be required but it appeared to be saving the
# state of the button.layout.display between objects otherwise ...
# ... not sure... but this seems to fix it
else:
self.display_bn_shownull = True
def show_hide_bn_nullable(self):
"""Set display of show null button based on if any nullable widgets are found."""
if self.check_for_nullables(): # check_for_nullables is defined in AutoObject
self.display_bn_shownull = True
else:
self.display_bn_shownull = False




if __name__ == "__main__":
sn = ShowNull()
Expand Down Expand Up @@ -247,11 +223,6 @@ class AutoObjectFormLayout(ShowRaw, ShowNull, WrapSaveButtonBar):


# +





def demo_autoobject_form(title="test", description="a description of the title"):
"""for docs and testing only..."""
from ipyautoui.custom.buttonbars import SaveButtonBar
Expand Down
21 changes: 12 additions & 9 deletions src/ipyautoui/autoobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,18 @@

import logging
import pathlib
import functools
import ipywidgets as w
from IPython.display import display
import pandas as pd # TODO: pandas is a heavy dep. if only used for pd.isnull... ?
import traitlets as tr
import typing as ty
import json
from IPython.display import display
from jsonref import replace_refs
import ipyautoui.automapschema as aumap
from ipyautoui._utils import obj_from_importstr
from ipyautoui.nullable import Nullable
from ipyautoui.autobox import AutoBox
from ipyautoui.autoform import AutoObjectFormLayout
from jsonref import replace_refs
from pydantic import BaseModel
from ipyautoui.watch_validate import WatchValidate
from ipyautoui.custom.title_description import TitleDescription
import contextlib
import pandas as pd # TODO: pandas is a heavy dep. if only used for pd.isnull... ?

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -438,6 +433,14 @@ def di_widgets_value(self): # used to set _value
get_value = lambda v: v._value if "_value" in v.traits() else v.value
return {k: get_value(v) for k, v in self.di_widgets.items()}

def check_for_nullables(self) -> bool:
"""Search through widgets and as soon as a Nullable widget is found, return True.
Else, return False."""
for v in self.di_widgets.values():
if isinstance(v, Nullable):
return True
return False


class AutoObjectForm(AutoObject, AutoObjectFormLayout):
def __init__(self, **kwargs):
Expand All @@ -452,7 +455,7 @@ def __init__(self, **kwargs):
self.vbx_showraw,
]
self.show_hide_bn_nullable()

def display_ui(self): # NOTE: this overwritten this in AutoObjectForm
self.vbx_widget.layout.display = ""

Expand Down
34 changes: 10 additions & 24 deletions src/ipyautoui/autoui.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,25 @@
# %load_ext lab_black

import pathlib
from IPython.display import display
from pydantic import BaseModel, ValidationError
import json
import logging
import functools
import traitlets as tr
import typing as ty
from ipyautoui.autoform import AutoObjectFormLayout, ShowRaw
from ipyautoui.custom import SaveButtonBar # removing makes circular import error
import json
import logging
from ipyautoui.automapschema import map_widget, widgetcaller, _init_model_schema
import ipywidgets as w
from pydantic import BaseModel
from ipyautoui.automapschema import pydantic_validate
from IPython.display import clear_output
from ipyautoui.automapschema import (
map_widget,
widgetcaller,
_init_model_schema,
get_widgets_map,
get_containers_map,
)
from pydantic import BaseModel, ValidationError
from IPython.display import display

from ipyautoui.custom import SaveButtonBar # removing makes circular import error
from ipyautoui.autobox import AutoBox
from ipyautoui.autoform import TitleDescription, WrapSaveButtonBar, ShowRaw, ShowNull
from ipyautoui.autoform import AutoObjectFormLayout, TitleDescription, WrapSaveButtonBar, ShowRaw, ShowNull
from ipyautoui.custom.editgrid import EditGrid
from ipyautoui.automapschema import get_widgets_map, get_containers_map, map_widget, widgetcaller, _init_model_schema, pydantic_validate

logger = logging.getLogger(__name__)


# +
import functools


def wrapped_partial(func, *args, **kwargs):
# http://louistiao.me/posts/adding-__name__-and-__doc__-attributes-to-functoolspartial-objects/
partial_func = functools.partial(func, *args, **kwargs)
Expand Down Expand Up @@ -217,9 +205,6 @@ def create_autodisplay_map(
return {ext: AutoRenderer}





def get_autoui(schema: ty.Union[ty.Type[BaseModel], dict], **kwargs):
model, schema = _init_model_schema(schema)
schema = {**schema, **kwargs}
Expand Down Expand Up @@ -258,6 +243,7 @@ def _set_children(self):
self.vbx_widget,
self.vbx_showraw,
]
self.show_hide_bn_nullable()

if model is not None:
return wrapped_partial(
Expand Down
13 changes: 13 additions & 0 deletions src/ipyautoui/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,19 @@
layout={"width": BUTTON_WIDTH_MIN},
)

SHOWNULL_ICON_SHOW = "plus"
SHOWNULL_ICON_HIDE = "minus"
KWARGS_SHOWNULL = frozenmap(
icon=SHOWNULL_ICON_SHOW,
layout=dict(width=BUTTON_WIDTH_MIN, display=""),
tooltip="show null form fields",
style={"font_weight": "bold"})
KWARGS_SHOWRAW = frozenmap(icon="code",
layout=dict(width=BUTTON_WIDTH_MIN, display="None"),
tooltip="show raw data",
style={"font_weight": "bold"},
)


KWARGS_DATAGRID_DEFAULT = frozenmap(
header_renderer=TextRenderer(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_autoobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class NoNullables(BaseModel):
a: str = Field(default="Test", description="This test is important")
b: str = Field(default="Test1", description="This test is important too")

ui = AutoObjectForm.from_pydantic_model(NoNullables)
ui = AutoObjectForm.from_pydantic_model(NoNullables)
assert ui.display_bn_shownull == False
assert ui.bn_shownull.layout.display == "None"

Expand Down

0 comments on commit 07f10d2

Please sign in to comment.