Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merging recent updates in #386

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.5.1](https://github.com/Zero-True/zero-true/compare/v0.5.0...v0.5.1) (2024-12-09)


### Bug Fixes

* Add style attribute to all relevant components ([#384](https://github.com/Zero-True/zero-true/issues/384)) ([68f42f7](https://github.com/Zero-True/zero-true/commit/68f42f7eb76ef58b9e1263e793b2490a58fd4f9e))

## [0.5.0](https://github.com/Zero-True/zero-true/compare/v0.4.9...v0.5.0) (2024-11-25)


Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license_files = LICENSE
description = A collaborative notebook built for data scientists
long_description = file: README.md
long_description_content_type = text/markdown
version = 0.5.0
version = 0.5.1


[options]
Expand Down
1 change: 1 addition & 0 deletions zt_backend/models/components/autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Autocomplete(ZTComponent):
pre=True,
description="Color of the autocomplete component. Can be custom or standard Material color",
)
style: Optional[str] = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
"update:modelValue",
description="Trigger event for when to run based on the selected value",
Expand Down
27 changes: 19 additions & 8 deletions zt_backend/models/components/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.state.user_state import UserContext


class Button(ZTComponent):
"""Standard button UI component"""

component: str = Field("v-btn", description="Vue component name")
value: bool = Field (False, description="Whether the button has been clicked")
value: bool = Field(False, description="Whether the button has been clicked")
text: str = Field("Click Me", description="Label displayed on the button")
color: str = Field("primary", description="Color of the button")
disabled: bool = Field(False, description="If true, the button is disabled")
outlined: bool = Field(False, description="If true, the button will have an outlined style")
triggerEvent: str = Field("click", description="Trigger event to send code to the backend")
outlined: bool = Field(
False, description="If true, the button will have an outlined style"
)
style: str = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
"click", description="Trigger event to send code to the backend"
)

@validator('value', always=True)
@validator("value", always=True)
def get_label_from_global_state(cls, value, values):
id = values.get('id') # Get the id if it exists in the field values
id = values.get("id") # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
if (
execution_state and id and id in execution_state.component_values
): # Check if id exists in global_state
return execution_state.component_values[
id
] # Return the value associated with id in global_state
except Exception as e:
pass # Handle exception as needed
return (value) # If id doesn't exist in global_state, return the original value
return value # If id doesn't exist in global_state, return the original value
1 change: 1 addition & 0 deletions zt_backend/models/components/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ class Card(ZTComponent):
description="Density of the component",
)
width: Optional[Union[int, str]] = Field("100%", description="Width of the card")
style: Optional[str] = Field("", description="CSS style to apply to the component")
65 changes: 47 additions & 18 deletions zt_backend/models/components/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,70 @@
from pydantic import Field, BaseModel
import numpy as np
from zt_backend.models.components.zt_component import ZTComponent
from typing import List, Dict,Any
from typing import List, Dict, Any


class Header(BaseModel):
"""Header class for the columns of a DataFrame component"""

title: str = Field("", description="Title of the column")
align: str = Field("start", description="Alignment of values in the column")
key: str = Field("name", description="Key of the column, must match the key in the items list")
key: str = Field(
"name", description="Key of the column, must match the key in the items list"
)


class DataFrame(ZTComponent):
"""DataFrame component for displaying tabluar data"""
component: str = Field("v-data-table", description="Vue component name.")
headers: List[Header] = Field([], description="List of column headers for the DataFrame")
items: List[Dict[str, Any]] = Field([], description="List of items to be displayed in the DataFrame")
multi_sort: bool = Field(True, description="Enable or disable multi-sort on the DataFrame")
search: str = Field("", description="Create a text_input component search = zt.text_input(id='search') before to filter the DataFrame items")

component: str = Field("v-data-table", description="Vue component name.")
headers: List[Header] = Field(
[], description="List of column headers for the DataFrame"
)
items: List[Dict[str, Any]] = Field(
[], description="List of items to be displayed in the DataFrame"
)
multi_sort: bool = Field(
True, description="Enable or disable multi-sort on the DataFrame"
)
style: str = Field("", description="CSS style to apply to the component")
search: str = Field(
"",
description="Create a text_input component search = zt.text_input(id='search') before to filter the DataFrame items",
)

@classmethod
def from_dataframe(cls, df: pd.DataFrame, id: str, multi_sort: bool = True, search: str = ""):
def from_dataframe(
cls, df: pd.DataFrame, id: str, multi_sort: bool = True, search: str = ""
):
"""Create a DataFrame component from a pandas DataFrame"""
df = df.replace({np.nan:None}).replace({np.inf:None}).replace({-np.inf:None})
df = df.replace({np.nan: None}).replace({np.inf: None}).replace({-np.inf: None})
if search:
search = search.lower()
df = df[df.astype(str).apply(lambda x: x.str.lower().str.contains(search)).any(axis=1)]
df = df[
df.astype(str)
.apply(lambda x: x.str.lower().str.contains(search))
.any(axis=1)
]
headers = [{"title": col, "key": col} for col in df.columns]
items = df.to_dict(orient='records')
return cls(id=id, headers=headers, items=items, multi_sort=multi_sort, search=search)

items = df.to_dict(orient="records")
return cls(
id=id, headers=headers, items=items, multi_sort=multi_sort, search=search
)


def dataframe(df: pd.DataFrame, id: str, multi_sort: bool = True, search: str = ""):
"""Create a ZT DataFrame component from a pandas DataFrame"""
df = df.replace({np.nan:None}).replace({np.inf:None}).replace({-np.inf:None})
df = df.replace({np.nan: None}).replace({np.inf: None}).replace({-np.inf: None})
if search:
search = search.lower()
df = df[df.astype(str).apply(lambda x: x.str.lower().str.contains(search)).any(axis=1)]
headers = [{"title": col, "key": col} for col in df.columns]
items = df.to_dict(orient='records')
return DataFrame(id=id, headers=headers, items=items, multi_sort=multi_sort, search=search)
df = df[
df.astype(str)
.apply(lambda x: x.str.lower().str.contains(search))
.any(axis=1)
]
headers = [{"title": col, "key": col} for col in df.columns]
items = df.to_dict(orient="records")
return DataFrame(
id=id, headers=headers, items=items, multi_sort=multi_sort, search=search
)
16 changes: 11 additions & 5 deletions zt_backend/models/components/file_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.state.user_state import UserContext


class FileInput(ZTComponent):
"""File input component allowing users to upload files."""

Expand Down Expand Up @@ -37,14 +38,19 @@ class FileInput(ZTComponent):
counter: Optional[bool] = Field(
False, description="If true, shows a file count indicator"
)
style: str = Field("", description="CSS style to apply to the component")

@validator('value', always=True) #TODO: debug and replace with field validator
@validator("value", always=True) # TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values
id = values["id"] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
if (
execution_state and id and id in execution_state.component_values
): # Check if id exists in global_state
return execution_state.component_values[
id
] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value
Expand All @@ -70,4 +76,4 @@ def get_files(self):
for file_name, file_content in self.value.items():
files.append(BytesIO(base64.b64decode(file_content)))

return files
return files
1 change: 1 addition & 0 deletions zt_backend/models/components/iframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class iFrame(ZTComponent):
height: Union[int, str] = Field("100%", description="Height of the iframe")
frameborder: int = Field(0, description="Frame border of the iframe")
scrolling: str = Field("auto", description="Scrolling of the iframe")
style: str = Field("", description="CSS style to apply to the component")
allowtransparency: bool = Field(
False, description="Allow transparency of the iframe"
)
1 change: 1 addition & 0 deletions zt_backend/models/components/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Image(ZTComponent):
component: str = Field("v-img", description="Vue component name")
src: str = Field(..., description="Source URL or Path of the image")
alt: str = Field("", description="Alternative text for the image")
style: str = Field("", description="CSS style to apply to the component")
width: Union[int, str] = Field("100%", description="Width of the image")
height: Union[int, str] = Field("100%", description="Height of the image")

Expand Down
15 changes: 11 additions & 4 deletions zt_backend/models/components/matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,19 @@ class Matplotlib(ZTComponent):
component: str = Field("v-img", description="Vue component name")
src: str = Field(..., description="Source URL of the image of the graph")
alt: str = Field("", description="Alternative text for the graph image")
style: str = Field("", description="CSS style to apply to the component")
width: Union[int, str] = Field("100%", description="Width of the graph")
height: Union[int, str] = Field("100%", description="Height of the graph")

@classmethod
def from_matplotlib(
cls, id: str, figure: plt.Figure, alt="", width=200, height=200
cls,
id: str,
figure: plt.Figure,
alt="",
style="",
width=200,
height=200,
):
"""Create a Matplotlib component from a matplotlib figure"""
plt.style.use("dark_background")
Expand All @@ -26,15 +33,15 @@ def from_matplotlib(
buffer.seek(0)
base64_data = base64.b64encode(buffer.read()).decode()
src = f"data:image/png;base64,{base64_data}"
return cls(id=id, src=src, alt=alt, width=width, height=height)
return cls(id=id, src=src, alt=alt, style=style, width=width, height=height)


def matplotlib(id: str, figure: plt.Figure, alt="", width=200, height=200):
def matplotlib(id: str, figure: plt.Figure, alt="", style="", width=200, height=200):
"""Create a Matplotlib component from a matplotlib figure"""
plt.style.use("dark_background")
buffer = BytesIO()
figure.savefig(buffer, format="png")
buffer.seek(0)
base64_data = base64.b64encode(buffer.read()).decode()
src = f"data:image/png;base64,{base64_data}"
return Matplotlib(id=id, src=src, alt=alt, width=width, height=height)
return Matplotlib(id=id, src=src, alt=alt, style=style, width=width, height=height)
1 change: 1 addition & 0 deletions zt_backend/models/components/number_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class NumberInput(ZTComponent):
step: Optional[Union[int, float]] = Field(
1, description="The number to increment or decrement by"
)
style: Optional[str] = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
None, description="Trigger event to send code to the backend"
)
Expand Down
54 changes: 35 additions & 19 deletions zt_backend/models/components/range_slider.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
from typing import List, Optional,Union
from typing import List, Optional, Union
from pydantic import Field, field_validator, validator
from zt_backend.models.components.zt_component import ZTComponent
from zt_backend.models.components.validations import validate_color
from zt_backend.models.state.user_state import UserContext


class RangeSlider(ZTComponent):
"""A slider component that allows a user to select a range of values"""

component: str = Field("v-range-slider", description="Vue component name")
value: List[Union[int,float]] = Field([0, 100], description="Current value range of the slider")
min: Union[int,float] = Field(0, description="Minimum value of the slider")
max: Union[int,float] = Field(100, description="Maximum value of the slider")
step: Union[int,float] = Field(1, gt=0, description="Step increment of the slider")
thumb_label: str = Field('always', description="Displays the thumb label")
value: List[Union[int, float]] = Field(
[0, 100], description="Current value range of the slider"
)
min: Union[int, float] = Field(0, description="Minimum value of the slider")
max: Union[int, float] = Field(100, description="Maximum value of the slider")
step: Union[int, float] = Field(1, gt=0, description="Step increment of the slider")
thumb_label: str = Field("always", description="Displays the thumb label")
thumb_size: int = Field(0, description="Size of the thumb")
tick_labels: bool = Field(False, description="Displays the tick labels")
ticks: list = Field([], description="Displays the ticks")
color: str = Field('primary', pre=True, description="Color of the range slider. Can be custom or standard Material color")
size: str = Field('large', description="Size of the slider")
label: Optional[str] = Field(None,description= 'A label for your slider')
rounded: bool = Field(True, description="Determines if the slider has rounded edges")
triggerEvent: str = Field('end',description="Trigger event for when to trigger a run")

@field_validator('color')
color: str = Field(
"primary",
pre=True,
description="Color of the range slider. Can be custom or standard Material color",
)
size: str = Field("large", description="Size of the slider")
label: Optional[str] = Field(None, description="A label for your slider")
rounded: bool = Field(
True, description="Determines if the slider has rounded edges"
)
style: Optional[str] = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
"end", description="Trigger event for when to trigger a run"
)

@field_validator("color")
def validate_color(cls, color):
return validate_color(color)
@validator('value', always=True) #TODO: debug and replace with field validator

@validator("value", always=True) # TODO: debug and replace with field validator
def get_value_from_global_state(cls, value, values):
id = values['id'] # Get the id if it exists in the field values
id = values["id"] # Get the id if it exists in the field values
execution_state = UserContext.get_state()
try:
if execution_state and id and id in execution_state.component_values: # Check if id exists in global_state
return execution_state.component_values[id] # Return the value associated with id in global_state
if (
execution_state and id and id in execution_state.component_values
): # Check if id exists in global_state
return execution_state.component_values[
id
] # Return the value associated with id in global_state
except Exception as e:
e
return value # If id doesn't exist in global_state, return the original value

1 change: 1 addition & 0 deletions zt_backend/models/components/rating.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Rating(ZTComponent):
None, description="Array of labels to display next to each item"
)
ripple: bool = Field(False, description="Applies the v-ripple directive")
style: Optional[str] = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
"update:modelValue", description="Trigger event for when to run the rating"
)
Expand Down
1 change: 1 addition & 0 deletions zt_backend/models/components/selectbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SelectBox(ZTComponent):
pre=True,
description="Color of the range slider. Can be custom or standard Material color",
)
style: Optional[str] = Field("", description="CSS style to apply to the component")
triggerEvent: str = Field(
"update:modelValue", description="Trigger event for when to trigger a run"
)
Expand Down
Loading
Loading