mirror of
https://github.com/aljazceru/hummingbot-dashboard.git
synced 2026-02-20 04:26:49 +01:00
(feat) add ui components
This commit is contained in:
0
ui_components/__init__.py
Normal file
0
ui_components/__init__.py
Normal file
34
ui_components/bot_performance_card.py
Normal file
34
ui_components/bot_performance_card.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from streamlit_elements import mui
|
||||
from ui_components.dashboard import Dashboard
|
||||
|
||||
|
||||
class BotPerformanceCard(Dashboard.Item):
|
||||
DEFAULT_CONTENT = (
|
||||
"This impressive paella is a perfect party dish and a fun meal to cook "
|
||||
"together with your guests. Add 1 cup of frozen peas along with the mussels, "
|
||||
"if you like."
|
||||
)
|
||||
|
||||
def __init__(self, board, x, y, w, h, **item_props):
|
||||
super().__init__(board, x, y, w, h, isResizable=False, **item_props)
|
||||
|
||||
def __call__(self, bot_config: dict):
|
||||
with mui.Card(key=self._key,
|
||||
sx={"display": "flex", "flexDirection": "column", "borderRadius": 3, "overflow": "hidden"},
|
||||
elevation=2):
|
||||
color = "green" if bot_config["is_running"] else "red"
|
||||
mui.CardHeader(
|
||||
title=bot_config["bot_name"],
|
||||
subheader=f"Running since {bot_config['start_date']}",
|
||||
avatar=mui.Avatar("🤖", sx={"bgcolor": color}),
|
||||
className=self._draggable_class,
|
||||
)
|
||||
|
||||
with mui.CardContent(sx={"flex": 1}):
|
||||
mui.Typography(bot_config["balances"])
|
||||
mui.Typography(bot_config["trades"])
|
||||
mui.Typography(bot_config["pnl"])
|
||||
|
||||
with mui.CardActions(disableSpacing=True):
|
||||
mui.IconButton(mui.icon.Stop)
|
||||
mui.IconButton(mui.icon.Share)
|
||||
34
ui_components/card.py
Normal file
34
ui_components/card.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from streamlit_elements import mui
|
||||
from ui_components.dashboard import Dashboard
|
||||
|
||||
|
||||
class Card(Dashboard.Item):
|
||||
|
||||
DEFAULT_CONTENT = (
|
||||
"This impressive paella is a perfect party dish and a fun meal to cook "
|
||||
"together with your guests. Add 1 cup of frozen peas along with the mussels, "
|
||||
"if you like."
|
||||
)
|
||||
|
||||
def __call__(self, content):
|
||||
with mui.Card(key=self._key, sx={"display": "flex", "flexDirection": "column", "borderRadius": 3, "overflow": "hidden"}, elevation=1):
|
||||
mui.CardHeader(
|
||||
title="Shrimp and Chorizo Paella",
|
||||
subheader="September 14, 2016",
|
||||
avatar=mui.Avatar("R", sx={"bgcolor": "red"}),
|
||||
action=mui.IconButton(mui.icon.MoreVert),
|
||||
className=self._draggable_class,
|
||||
)
|
||||
mui.CardMedia(
|
||||
component="img",
|
||||
height=194,
|
||||
image="https://mui.com/static/images/cards/paella.jpg",
|
||||
alt="Paella dish",
|
||||
)
|
||||
|
||||
with mui.CardContent(sx={"flex": 1}):
|
||||
mui.Typography(content)
|
||||
|
||||
with mui.CardActions(disableSpacing=True):
|
||||
mui.IconButton(mui.icon.Favorite)
|
||||
mui.IconButton(mui.icon.Share)
|
||||
60
ui_components/dashboard.py
Normal file
60
ui_components/dashboard.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from uuid import uuid4
|
||||
from abc import ABC, abstractmethod
|
||||
from streamlit_elements import dashboard, mui
|
||||
from contextlib import contextmanager
|
||||
|
||||
|
||||
class Dashboard:
|
||||
|
||||
DRAGGABLE_CLASS = "draggable"
|
||||
|
||||
def __init__(self):
|
||||
self._layout = []
|
||||
|
||||
def _register(self, item):
|
||||
self._layout.append(item)
|
||||
|
||||
@contextmanager
|
||||
def __call__(self, **props):
|
||||
# Draggable classname query selector.
|
||||
props["draggableHandle"] = f".{Dashboard.DRAGGABLE_CLASS}"
|
||||
|
||||
with dashboard.Grid(self._layout, **props):
|
||||
yield
|
||||
|
||||
class Item(ABC):
|
||||
|
||||
def __init__(self, board, x, y, w, h, **item_props):
|
||||
self._key = str(uuid4())
|
||||
self._draggable_class = Dashboard.DRAGGABLE_CLASS
|
||||
self._dark_mode = True
|
||||
board._register(dashboard.Item(self._key, x, y, w, h, **item_props))
|
||||
|
||||
def _switch_theme(self):
|
||||
self._dark_mode = not self._dark_mode
|
||||
|
||||
@contextmanager
|
||||
def title_bar(self, padding="5px 15px 5px 15px", dark_switcher=True):
|
||||
with mui.Stack(
|
||||
className=self._draggable_class,
|
||||
alignItems="center",
|
||||
direction="row",
|
||||
spacing=1,
|
||||
sx={
|
||||
"padding": padding,
|
||||
"borderBottom": 1,
|
||||
"borderColor": "divider",
|
||||
},
|
||||
):
|
||||
yield
|
||||
|
||||
if dark_switcher:
|
||||
if self._dark_mode:
|
||||
mui.IconButton(mui.icon.DarkMode, onClick=self._switch_theme)
|
||||
else:
|
||||
mui.IconButton(mui.icon.LightMode, sx={"color": "#ffc107"}, onClick=self._switch_theme)
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self):
|
||||
"""Show elements."""
|
||||
raise NotImplementedError
|
||||
51
ui_components/datagrid.py
Normal file
51
ui_components/datagrid.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import json
|
||||
|
||||
from streamlit_elements import mui
|
||||
from .dashboard import Dashboard
|
||||
|
||||
|
||||
class DataGrid(Dashboard.Item):
|
||||
DEFAULT_COLUMNS = [
|
||||
{"field": 'id', "headerName": 'ID', "width": 90},
|
||||
{"field": 'firstName', "headerName": 'First name', "width": 150, "editable": True, },
|
||||
{"field": 'lastName', "headerName": 'Last name', "width": 150, "editable": True, },
|
||||
{"field": 'age', "headerName": 'Age', "type": 'number', "width": 110, "editable": True, },
|
||||
]
|
||||
DEFAULT_ROWS = [
|
||||
{"id": 1, "lastName": 'Snow', "firstName": 'Jon', "age": 35},
|
||||
{"id": 2, "lastName": 'Lannister', "firstName": 'Cersei', "age": 42},
|
||||
{"id": 3, "lastName": 'Lannister', "firstName": 'Jaime', "age": 45},
|
||||
{"id": 4, "lastName": 'Stark', "firstName": 'Arya', "age": 16},
|
||||
{"id": 5, "lastName": 'Targaryen', "firstName": 'Daenerys', "age": None},
|
||||
{"id": 6, "lastName": 'Melisandre', "firstName": None, "age": 150},
|
||||
{"id": 7, "lastName": 'Clifford', "firstName": 'Ferrara', "age": 44},
|
||||
{"id": 8, "lastName": 'Frances', "firstName": 'Rossini', "age": 36},
|
||||
{"id": 9, "lastName": 'Roxie', "firstName": 'Harvey', "age": 65},
|
||||
]
|
||||
|
||||
def _handle_edit(self, params):
|
||||
print(params)
|
||||
|
||||
def __call__(self, json_data):
|
||||
try:
|
||||
data = json.loads(json_data)
|
||||
except json.JSONDecodeError:
|
||||
data = self.DEFAULT_ROWS
|
||||
|
||||
with mui.Paper(key=self._key,
|
||||
sx={"display": "flex", "flexDirection": "column", "borderRadius": 3, "overflow": "hidden"},
|
||||
elevation=1):
|
||||
with self.title_bar(padding="10px 15px 10px 15px", dark_switcher=False):
|
||||
mui.icon.ViewCompact()
|
||||
mui.Typography("Data grid")
|
||||
|
||||
with mui.Box(sx={"flex": 1, "minHeight": 0}):
|
||||
mui.DataGrid(
|
||||
columns=self.DEFAULT_COLUMNS,
|
||||
rows=data,
|
||||
pageSize=5,
|
||||
rowsPerPageOptions=[5],
|
||||
checkboxSelection=True,
|
||||
disableSelectionOnClick=True,
|
||||
onCellEditCommit=self._handle_edit,
|
||||
)
|
||||
Reference in New Issue
Block a user