Skip to content

Commit e10422c

Browse files
configuration viewer
1 parent 3402a8e commit e10422c

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

src/holoviz_mcp/apps/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Here for technical reasons."""
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""An app to view the holoviz-mcp configuration using Panel and Panel Material UI best practices.
2+
3+
- Uses parameter-driven architecture for reactivity and maintainability
4+
- Uses a Panel template for layout and branding
5+
- Uses only Panel Material UI components for UI widgets
6+
- Separates config loading logic from UI logic
7+
- Responsive and modern design
8+
"""
9+
10+
import json
11+
12+
import panel as pn
13+
import panel_material_ui as pmui
14+
import param
15+
16+
from holoviz_mcp.config.loader import HoloVizMCPConfig
17+
from holoviz_mcp.config.loader import get_config
18+
from holoviz_mcp.config.loader import get_config_loader
19+
20+
pn.extension("jsoneditor")
21+
22+
23+
class ConfigViewer(param.Parameterized):
24+
"""
25+
A Panel Material UI app for viewing holoviz-mcp configuration.
26+
27+
Features:
28+
- Parameter-driven reactivity
29+
- Modern, responsive UI using Panel Material UI
30+
- Separation of config loading and UI logic
31+
- Supports dark and light themes
32+
"""
33+
34+
config_source = param.Selector(objects=["Combined", "Default", "User"], default="Combined", doc="Which configuration to show")
35+
dark_theme = param.Boolean(default=False, doc="Use dark theme for the JSON editor", allow_refs=True)
36+
37+
def __init__(self, **params):
38+
"""
39+
Initialize the ConfigViewer.
40+
41+
Loads environment config and config loader.
42+
"""
43+
super().__init__(**params)
44+
self._env_config = HoloVizMCPConfig.from_environment()
45+
self._loader = get_config_loader()
46+
47+
@param.depends("config_source")
48+
def _config_json(self):
49+
"""Get the selected configuration as a JSON string."""
50+
if self.config_source == "Combined":
51+
return get_config().model_dump_json(indent=2)
52+
elif self.config_source == "Default":
53+
default_config_file = self._env_config.default_dir / "config.yaml"
54+
default_config = self._loader._load_yaml_file(default_config_file)
55+
return json.dumps(default_config, indent=2)
56+
elif self.config_source == "User":
57+
user_config_file = self._env_config.user_dir / "config.yaml"
58+
user_config = self._loader._load_yaml_file(user_config_file)
59+
return json.dumps(user_config, indent=2)
60+
return json.dumps({"error": "Unknown config source"}, indent=2)
61+
62+
@param.depends("dark_theme")
63+
def _theme(self):
64+
"""Get the theme for the JSON editor ('dark' or 'light')."""
65+
return "dark" if self.dark_theme else "light"
66+
67+
def view(self):
68+
"""Get the main view for the configuration viewer app."""
69+
selector = pmui.RadioButtonGroup.from_param(
70+
self.param.config_source,
71+
color="primary",
72+
orientation="horizontal",
73+
sx={"mb": 2},
74+
)
75+
json_pane = pn.pane.JSON(
76+
self._config_json,
77+
name="holoviz-mcp config",
78+
theme=self._theme,
79+
sizing_mode="stretch_width",
80+
)
81+
card = pmui.Paper(
82+
pmui.Column(
83+
pmui.Typography(
84+
"HoloViz MCP Configuration Viewer",
85+
variant="h5",
86+
sx={"fontWeight": 700, "mb": 2},
87+
),
88+
selector,
89+
json_pane,
90+
),
91+
elevation=3,
92+
sx={"maxWidth": "900px", "margin": "auto", "padding": "32px"},
93+
)
94+
return pmui.Container(card)
95+
96+
def _update_source(self, selector):
97+
"""Update the config source from the selector widget."""
98+
self.config_source = selector.value
99+
100+
@classmethod
101+
def create_app(cls):
102+
"""Create and return the Panel Material UI app page."""
103+
viewer = cls()
104+
page = pmui.Page(
105+
title="HoloViz MCP Configuration Viewer",
106+
main=[viewer.view()],
107+
)
108+
viewer.dark_theme = page.param.dark_theme
109+
return page
110+
111+
112+
if __name__ == "__main__":
113+
ConfigViewer.create_app().show(port=5007, open=True, dev=True)
114+
elif pn.state.served:
115+
ConfigViewer.create_app().servable()

0 commit comments

Comments
 (0)