Added Panel.py

This commit is contained in:
2025-11-29 18:13:46 +01:00
parent 3271aa0d61
commit 659c4e1d4b
8 changed files with 302 additions and 47 deletions

View File

@@ -1,3 +1,4 @@
from myfasthtml.controls.Panel import Panel
from myfasthtml.controls.VisNetwork import VisNetwork
from myfasthtml.core.instances import SingleInstance, InstancesManager
from myfasthtml.core.network_utils import from_parent_child_list
@@ -6,9 +7,14 @@ from myfasthtml.core.network_utils import from_parent_child_list
class InstancesDebugger(SingleInstance):
def __init__(self, parent, _id=None):
super().__init__(parent, _id=_id)
self._panel = Panel(self, _id="-panel")
def render(self):
s_name = InstancesManager.get_session_user_name
nodes, edges = self._get_nodes_and_edges()
vis_network = VisNetwork(self, nodes=nodes, edges=edges, _id="-vis")
return self._panel.set_main(vis_network)
def _get_nodes_and_edges(self):
instances = self._get_instances()
nodes, edges = from_parent_child_list(
instances,
@@ -23,9 +29,7 @@ class InstancesDebugger(SingleInstance):
for node in nodes:
node["shape"] = "box"
vis_network = VisNetwork(self, nodes=nodes, edges=edges, _id="-vis")
# vis_network.add_to_options(physics={"wind": {"x": 0, "y": 1}})
return vis_network
return nodes, edges
def _get_instances(self):
return list(InstancesManager.instances.values())

View File

@@ -123,6 +123,7 @@ class Layout(SingleInstance):
self.header_right = self.Content(self)
self.footer_left = self.Content(self)
self.footer_right = self.Content(self)
self._footer_content = None
def set_footer(self, content):
"""
@@ -141,6 +142,7 @@ class Layout(SingleInstance):
content: FastHTML component(s) or content for the main area
"""
self._main_content = content
return self
def toggle_drawer(self, side: Literal["left", "right"]):
logger.debug(f"Toggle drawer: {side=}, {self._state.left_drawer_open=}")
@@ -233,7 +235,7 @@ class Layout(SingleInstance):
Div: FastHTML Div component for left drawer
"""
resizer = Div(
cls="mf-layout-resizer mf-layout-resizer-right",
cls="mf-resizer mf-resizer-left",
data_command_id=self.commands.update_drawer_width("left").id,
data_side="left"
)
@@ -266,8 +268,9 @@ class Layout(SingleInstance):
Returns:
Div: FastHTML Div component for right drawer
"""
resizer = Div(
cls="mf-layout-resizer mf-layout-resizer-left",
cls="mf-resizer mf-resizer-right",
data_command_id=self.commands.update_drawer_width("right").id,
data_side="right"
)
@@ -311,7 +314,7 @@ class Layout(SingleInstance):
self._mk_main(),
self._mk_right_drawer(),
self._mk_footer(),
Script(f"initLayoutResizer('{self._id}');"),
Script(f"initResizer('{self._id}');"),
id=self._id,
cls="mf-layout",
)

View File

@@ -0,0 +1,102 @@
from dataclasses import dataclass
from typing import Literal
from fasthtml.components import Div
from fasthtml.xtend import Script
from myfasthtml.controls.BaseCommands import BaseCommands
from myfasthtml.core.commands import Command
from myfasthtml.core.instances import MultipleInstance
@dataclass
class PanelConf:
left: bool = False
right: bool = True
class Commands(BaseCommands):
def toggle_side(self, side: Literal["left", "right"]):
return Command("TogglePanelSide", f"Toggle {side} side panel", self._owner.toggle_side, side)
def update_side_width(self, side: Literal["left", "right"]):
"""
Create a command to update panel's side width.
Args:
side: Which panel's side to update ("left" or "right")
Returns:
Command: Command object for updating panel's side width
"""
return Command(
f"UpdatePanelSideWidth_{side}",
f"Update {side} side panel width",
self._owner.update_side_width,
side
)
class Panel(MultipleInstance):
def __init__(self, parent, conf=None, _id=None):
super().__init__(parent, _id=_id)
self.conf = conf or PanelConf()
self.commands = Commands(self)
self._main = None
self._right = None
self._left = None
def update_side_width(self, side, width):
pass
def toggle_side(self, side):
pass
def set_main(self, main):
self._main = main
return self
def set_right(self, right):
self._right = right
return self
def set_left(self, left):
self._left = left
return self
def _mk_right(self):
if not self.conf.right:
return None
resizer = Div(
cls="mf-resizer mf-resizer-right",
data_command_id=self.commands.update_side_width("right").id,
data_side="right"
)
return Div(resizer, self._right, cls="mf-panel-right")
def _mk_left(self):
if not self.conf.left:
return None
resizer = Div(
cls="mf-resizer mf-resizer-left",
data_command_id=self.commands.update_side_width("left").id,
data_side="left"
)
return Div(self._left, resizer, cls="mf-panel-left")
def render(self):
return Div(
self._mk_left(),
Div(self._main, cls="mf-panel-main"),
self._mk_right(),
Script(f"initResizer('{self._id}');"),
cls="mf-panel",
id=self._id,
)
def __ft__(self):
return self.render()