Refactored Properties component to support grouped structures, updated InstancesDebugger and styles, and upgraded myutils to 0.5.0.
This commit is contained in:
@@ -38,7 +38,7 @@ mdurl==0.1.2
|
||||
more-itertools==10.8.0
|
||||
myauth==0.2.1
|
||||
mydbengine==0.1.0
|
||||
myutils==0.4.0
|
||||
myutils==0.5.0
|
||||
nh3==0.3.1
|
||||
numpy==2.3.5
|
||||
oauthlib==3.3.1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
--font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
||||
--spacing: 0.25rem;
|
||||
--text-xs: 0.6875rem;
|
||||
--text-sm: 0.875rem;
|
||||
--text-sm--line-height: calc(1.25 / 0.875);
|
||||
--text-xl: 1.25rem;
|
||||
@@ -11,6 +12,7 @@
|
||||
--radius-md: 0.375rem;
|
||||
--default-font-family: var(--font-sans);
|
||||
--default-mono-font-family: var(--font-mono);
|
||||
--properties-font-size: var(--text-xs);
|
||||
}
|
||||
|
||||
|
||||
@@ -671,4 +673,79 @@
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
border-left: 1px solid var(--color-border-primary);
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
/* *********************************************** */
|
||||
/* ************* Properties Component ************ */
|
||||
/* *********************************************** */
|
||||
|
||||
/* Properties container */
|
||||
.mf-properties {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Group card - using DaisyUI card styling */
|
||||
.mf-properties-group-card {
|
||||
background-color: var(--color-base-100);
|
||||
border: 1px solid color-mix(in oklab, var(--color-base-content) 10%, transparent);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Group header - gradient using DaisyUI primary color */
|
||||
.mf-properties-group-header {
|
||||
background: linear-gradient(135deg, var(--color-primary) 0%, color-mix(in oklab, var(--color-primary) 80%, black) 100%);
|
||||
color: var(--color-primary-content);
|
||||
padding: calc(var(--properties-font-size) * 0.5) calc(var(--properties-font-size) * 0.75);
|
||||
font-weight: 700;
|
||||
font-size: var(--properties-font-size);
|
||||
}
|
||||
|
||||
/* Group content area */
|
||||
.mf-properties-group-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Property row */
|
||||
.mf-properties-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: calc(var(--properties-font-size) * 0.4) calc(var(--properties-font-size) * 0.75);
|
||||
border-bottom: 1px solid color-mix(in oklab, var(--color-base-content) 5%, transparent);
|
||||
transition: background-color 0.15s ease;
|
||||
gap: calc(var(--properties-font-size) * 0.75);
|
||||
}
|
||||
|
||||
.mf-properties-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mf-properties-row:hover {
|
||||
background-color: color-mix(in oklab, var(--color-base-content) 3%, transparent);
|
||||
}
|
||||
|
||||
/* Property key - normal font */
|
||||
.mf-properties-key {
|
||||
font-weight: 600;
|
||||
color: color-mix(in oklab, var(--color-base-content) 70%, transparent);
|
||||
flex: 0 0 40%;
|
||||
font-size: var(--properties-font-size);
|
||||
}
|
||||
|
||||
/* Property value - monospace font */
|
||||
.mf-properties-value {
|
||||
font-family: var(--default-mono-font-family);
|
||||
color: var(--color-base-content);
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-size: var(--properties-font-size);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -21,7 +21,10 @@ class InstancesDebugger(SingleInstance):
|
||||
|
||||
def on_network_event(self, event_data: dict):
|
||||
session, instance_id = event_data["nodes"][0].split("#")
|
||||
properties = {"Id": "_id", "Parent Id": "_parent._id"}
|
||||
properties = {"Main": {"Id": "_id", "Parent Id": "_parent._id"},
|
||||
"State": {"*": "_state"},
|
||||
"Commands": {"*": "commands"},
|
||||
}
|
||||
return self._panel.set_right(Properties(self,
|
||||
InstancesManager.get(session, instance_id),
|
||||
properties,
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
from fasthtml.components import Div
|
||||
from myutils.Expando import Expando
|
||||
from myutils.ProxyObject import ProxyObject
|
||||
|
||||
from myfasthtml.core.instances import MultipleInstance
|
||||
|
||||
|
||||
class Properties(MultipleInstance):
|
||||
def __init__(self, parent, obj=None, properties: dict = None, _id=None):
|
||||
def __init__(self, parent, obj=None, groups: dict = None, _id=None):
|
||||
super().__init__(parent, _id=_id)
|
||||
self.obj = obj
|
||||
self.properties = properties or self._get_default_properties(obj)
|
||||
self.expando = self._create_expando()
|
||||
self.groups = groups
|
||||
self.properties_by_group = self._create_properties_by_group()
|
||||
|
||||
def set_obj(self, obj, properties: list[str] = None):
|
||||
def set_obj(self, obj, groups: dict = None):
|
||||
self.obj = obj
|
||||
self.properties = properties or self._get_default_properties(obj)
|
||||
self.groups = groups
|
||||
self.properties_by_group = self._create_properties_by_group()
|
||||
|
||||
def render(self):
|
||||
return Div(
|
||||
*[Div(k, ":", v) for k, v in self.expando.as_dict().items()],
|
||||
*[
|
||||
Div(
|
||||
Div(group_name if group_name is not None else "", cls="mf-properties-group-header"),
|
||||
Div(
|
||||
*[
|
||||
Div(
|
||||
Div(k, cls="mf-properties-key"),
|
||||
Div(str(v), cls="mf-properties-value", title=str(v)),
|
||||
cls="mf-properties-row"
|
||||
)
|
||||
for k, v in proxy.as_dict().items()
|
||||
],
|
||||
cls="mf-properties-group-content"
|
||||
),
|
||||
cls="mf-properties-group-card"
|
||||
)
|
||||
for group_name, proxy in self.properties_by_group.items()
|
||||
],
|
||||
id=self._id,
|
||||
cls="mf-properties"
|
||||
)
|
||||
|
||||
def _create_expando(self):
|
||||
res = {}
|
||||
for attr_name, mapping in self.properties.items():
|
||||
attrs_path = mapping.split(".")
|
||||
current = self.obj
|
||||
for attr in attrs_path:
|
||||
if hasattr(current, attr):
|
||||
current = getattr(current, attr)
|
||||
else:
|
||||
res[attr_name] = None
|
||||
break
|
||||
res[attr_name] = current
|
||||
def _create_properties_by_group(self):
|
||||
if self.groups is None:
|
||||
return {None: ProxyObject(self.obj, {"*": ""})}
|
||||
|
||||
return Expando(res)
|
||||
|
||||
@staticmethod
|
||||
def _get_default_properties(obj):
|
||||
return {k: k for k, v in dir(obj) if not k.startswith("_")} if obj else {}
|
||||
return {k: ProxyObject(self.obj, v) for k, v in self.groups.items()}
|
||||
|
||||
def __ft__(self):
|
||||
return self.render()
|
||||
|
||||
@@ -176,7 +176,8 @@ class InstancesManager:
|
||||
:param instance_id:
|
||||
:return:
|
||||
"""
|
||||
key = (InstancesManager.get_session_id(session), instance_id)
|
||||
session_id = InstancesManager.get_session_id(session) if isinstance(session, dict) else session
|
||||
key = (session_id, instance_id)
|
||||
return InstancesManager.instances[key]
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user