Skip to content

Commit 32e5818

Browse files
authored
Merge pull request #101 from PathOnAI/Frontend-UI
Frontend UI improve
2 parents 237687e + 4e61b2a commit 32e5818

File tree

9 files changed

+409
-181
lines changed

9 files changed

+409
-181
lines changed

visual-tree-search-app/components/ControlPanel.tsx

Lines changed: 198 additions & 94 deletions
Large diffs are not rendered by default.

visual-tree-search-app/components/Header.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const Header = () => {
88

99
return (
1010
<header className="sticky top-0 z-20 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
11-
<div className="container flex h-14 items-center">
12-
<div className="flex flex-1 items-center justify-center">
11+
<div className="container mx-auto px-4 h-14 relative">
12+
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
1313
<Link href="/" className="flex items-center space-x-2 hover:opacity-80 transition-opacity">
14-
<h1 className="text-lg font-semibold tracking-tight bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent">
14+
<h1 className="text-lg font-semibold tracking-tight bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent whitespace-nowrap">
1515
VisualTreeSearch
1616
</h1>
1717
</Link>
1818
</div>
19-
<div className="flex items-center space-x-2">
19+
<div className="absolute right-0 top-1/2 -translate-y-1/2 pr-4">
2020
<Button
2121
variant="ghost"
2222
size="icon"

visual-tree-search-app/components/Layout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Header from "./Header";
2-
import Footer from "./Footer";
32
import Sidebar from "./Sidebar";
43
import Head from "next/head";
54

@@ -18,14 +17,13 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
1817

1918
<div className="flex min-h-screen bg-gradient-to-b from-background via-background/98 to-background/95 dark:from-slate-950 dark:via-slate-900 dark:to-slate-950">
2019
<Sidebar />
21-
<div className="flex flex-col flex-1 min-w-0 ml-14 lg:ml-56 transition-all duration-300">
20+
<div className="flex flex-col flex-1 min-w-0 transition-all duration-300" style={{ marginLeft: 'var(--sidebar-width, 3.5rem)' }}>
2221
<Header />
23-
<main className="flex-1 p-4 lg:p-6 overflow-auto">
22+
<main className="flex-1 px-4 pt-4 pb-2 lg:px-6 lg:pt-6 lg:pb-3 overflow-auto">
2423
<div className="h-full w-full max-w-full">
2524
{children}
2625
</div>
2726
</main>
28-
<Footer />
2927
</div>
3028
</div>
3129
</>

visual-tree-search-app/components/LiveBrowserView.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { Globe } from 'lucide-react';
23

34
interface LiveBrowserViewProps {
45
liveBrowserUrl: string | null;
@@ -13,9 +14,7 @@ const LiveBrowserView: React.FC<LiveBrowserViewProps> = ({ liveBrowserUrl, width
1314
>
1415
<div className="p-3 border-b border-slate-200 dark:border-slate-700 bg-gradient-to-r from-sky-50 to-white dark:from-slate-900 dark:to-slate-800">
1516
<h2 className="text-lg font-semibold text-sky-950 dark:text-sky-100 flex items-center">
16-
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2 text-cyan-500" viewBox="0 0 20 20" fill="currentColor">
17-
<path fillRule="evenodd" d="M4.083 9h1.946c.089-1.546.383-2.97.837-4.118A6.004 6.004 0 004.083 9zM10 2a8 8 0 100 16 8 8 0 000-16zm0 2c-.076 0-.232.032-.465.262-.238.234-.497.623-.737 1.182-.389.907-.673 2.142-.766 3.556h3.936c-.093-1.414-.377-2.649-.766-3.556-.24-.56-.5-.948-.737-1.182C10.232 4.032 10.076 4 10 4zm3.971 5c-.089-1.546-.383-2.97-.837-4.118A6.004 6.004 0 0115.917 9h-1.946zm-2.003 2H8.032c.093 1.414.377 2.649.766 3.556.24.56.5.948.737 1.182.233.23.389.262.465.262.076 0 .232-.032.465-.262.238-.234.498-.623.737-1.182.389-.907.673-2.142.766-3.556zm1.166 4.118c.454-1.147.748-2.572.837-4.118h1.946a6.004 6.004 0 01-2.783 4.118zm-6.268 0C6.412 13.97 6.118 12.546 6.03 11H4.083a6.004 6.004 0 002.783 4.118z" clipRule="evenodd" />
18-
</svg>
17+
<Globe className="h-4 w-4 mr-1.5 text-primary" />
1918
Live Browser View
2019
</h2>
2120
</div>

visual-tree-search-app/components/MessageLogPanel.tsx

Lines changed: 128 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ interface ParsedMessage {
8989
value?: number;
9090
visits?: number;
9191
};
92+
trajectory?: Array<{
93+
natural_language_description: string;
94+
action: string;
95+
feedback?: string;
96+
}>;
9297
}
9398

9499
interface PathStep {
@@ -112,10 +117,14 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
112117
onSessionIdChange,
113118
variant = 'default'
114119
}) => {
120+
const prevMessagesLengthRef = React.useRef(messages.length);
121+
115122
useEffect(() => {
116-
if (messagesEndRef?.current) {
123+
// Only scroll if new messages were added
124+
if (messages.length > prevMessagesLengthRef.current && messagesEndRef?.current) {
117125
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
118126
}
127+
prevMessagesLengthRef.current = messages.length;
119128
}, [messages, messagesEndRef]);
120129

121130
useEffect(() => {
@@ -133,6 +142,13 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
133142
}, [messages, onSessionIdChange]);
134143

135144
const getCardStyle = (type: string) => {
145+
// Ignore tree update messages
146+
if (type === 'tree_update_node_expansion' ||
147+
type === 'tree_update_node_evaluation' ||
148+
type === 'tree_update_node_children_evaluation') {
149+
return "hidden";
150+
}
151+
136152
switch (type) {
137153
// System Status Messages
138154
case 'reflection_backtracking':
@@ -243,6 +259,13 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
243259
};
244260

245261
const getIcon = (message: ParsedMessage) => {
262+
// Ignore tree update messages
263+
if (message.type === 'tree_update_node_expansion' ||
264+
message.type === 'tree_update_node_evaluation' ||
265+
message.type === 'tree_update_node_children_evaluation') {
266+
return null;
267+
}
268+
246269
switch (message.type) {
247270
case 'reflection_backtracking':
248271
return <Brain className="h-4 w-4 text-blue-500" />;
@@ -358,13 +381,40 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
358381
case 'node_expansion_complete':
359382
return <CheckCircle className="h-4 w-4 text-green-500" />;
360383
case 'evaluation_start':
361-
return <Brain className="h-4 w-4 text-blue-500" />;
384+
return (
385+
<div className="flex items-center gap-2 animate-fadeIn">
386+
<div className="animate-slideIn">
387+
<div className="text-amber-600 dark:text-amber-400">
388+
Starting node evaluation
389+
</div>
390+
<div className="text-xs text-slate-500 dark:text-slate-400">
391+
{message.node_info?.description}
392+
{message.node_info?.action && message.node_info.action !== 'ROOT' && (
393+
<span> | Action: {message.node_info.action}</span>
394+
)}
395+
</div>
396+
</div>
397+
</div>
398+
);
362399
case 'child_evaluated':
363-
return <Star className="h-4 w-4 text-amber-500" />;
400+
return (
401+
<div className="flex items-center gap-2 animate-fadeIn">
402+
<div className="animate-slideIn">
403+
<div className="text-amber-600 dark:text-amber-400">
404+
Child node evaluated
405+
</div>
406+
<div className="text-xs text-slate-500 dark:text-slate-400">
407+
Node ID: {message.node_id} | Score: {message.score?.toFixed(3)}
408+
</div>
409+
</div>
410+
</div>
411+
);
364412
case 'node_evaluation_start':
365-
return <Brain className="h-4 w-4 text-blue-500" />;
413+
return <Brain className="h-4 w-4 text-amber-500" />;
366414
case 'node_evaluation_complete':
367-
return <CheckCircle className="h-4 w-4 text-green-500" />;
415+
return <CheckCircle className="h-4 w-4 text-amber-500" />;
416+
case 'child_evaluated':
417+
return <Star className="h-4 w-4 text-amber-500" />;
368418
default:
369419
return <Info className="h-4 w-4 text-slate-500" />;
370420
}
@@ -499,7 +549,9 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
499549

500550
const formatMessageContent = (message: ParsedMessage) => {
501551
// Ignore tree update messages
502-
if (message.type === 'tree_update_node_expansion' || message.type === 'tree_update_node_evaluation') {
552+
if (message.type === 'tree_update_node_expansion' ||
553+
message.type === 'tree_update_node_evaluation' ||
554+
message.type === 'tree_update_node_children_evaluation') {
503555
return null;
504556
}
505557

@@ -652,7 +704,7 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
652704
{getIcon(message)}
653705
<div className="animate-slideIn">
654706
<div className="text-emerald-600 dark:text-emerald-400">
655-
Search Complete | Score: {message.score}
707+
Search Complete | Score: {message.score?.toFixed(3)}
656708
</div>
657709
{message.path && message.path.length > 0 && (
658710
<div className="mt-1">
@@ -727,7 +779,7 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
727779
{getIcon(message)}
728780
<div className="animate-slideIn">
729781
<div className="text-amber-600 dark:text-amber-400">
730-
Simulation Result | Reward: {message.reward}
782+
Simulation Result | Reward: {message.reward?.toFixed(3)}
731783
</div>
732784
{message.terminal_node_description && (
733785
<div className="text-xs text-slate-500 dark:text-slate-400">
@@ -819,11 +871,66 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
819871
case 'evaluation_start':
820872
return `Starting evaluation of ${message.children_count} children for node ${message.node_id}`;
821873
case 'child_evaluated':
822-
return `Child node ${message.node_id} evaluated with score ${message.score}`;
874+
return `Child node ${message.node_id} evaluated with score ${message.score?.toFixed(3)}`;
823875
case 'node_evaluation_start':
824-
return `Starting evaluation of node ${message.node_id}`;
876+
return (
877+
<div className="flex items-center gap-2 animate-fadeIn">
878+
<div className="animate-slideIn">
879+
<div className="text-amber-600 dark:text-amber-400">
880+
Starting node evaluation
881+
</div>
882+
<div className="text-xs text-slate-500 dark:text-slate-400">
883+
{message.node_info?.description}
884+
{message.node_info?.action && message.node_info.action !== 'ROOT' && (
885+
<span> | Action: {message.node_info.action}</span>
886+
)}
887+
</div>
888+
</div>
889+
</div>
890+
);
825891
case 'node_evaluation_complete':
826-
return `Node ${message.node_id} evaluated with score ${message.score}`;
892+
return (
893+
<div className="flex items-center gap-2 animate-fadeIn">
894+
<div className="animate-slideIn">
895+
<div className="text-amber-600 dark:text-amber-400 font-medium">
896+
Node evaluation complete
897+
</div>
898+
<div className="text-xs text-slate-500 dark:text-slate-400 mt-1">
899+
{message.node_info?.description}
900+
{message.node_info?.action && message.node_info.action !== 'ROOT' && (
901+
<span> | Action: {message.node_info.action}</span>
902+
)}
903+
</div>
904+
<div className="text-xs font-medium text-amber-600 dark:text-amber-400 mt-2">
905+
Score: {message.score?.toFixed(3)}
906+
</div>
907+
{message.trajectory && message.trajectory.length > 0 && (
908+
<div className="mt-2 pl-2 border-l-2 border-amber-200 dark:border-amber-800">
909+
<div className="text-xs font-medium text-amber-600 dark:text-amber-400 mb-1">
910+
Trajectory:
911+
</div>
912+
{message.trajectory.map((step, index) => (
913+
<div
914+
key={index}
915+
className="flex items-start gap-1 text-xs text-slate-500 dark:text-slate-400 animate-fadeIn mb-1.5"
916+
style={{ animationDelay: `${index * 100}ms` }}
917+
>
918+
<ArrowRight className="h-3 w-3 mt-0.5 flex-shrink-0" />
919+
<div className="flex-1">
920+
<div className="font-medium">{step.natural_language_description}</div>
921+
{step.feedback && (
922+
<div className="text-slate-400 italic mt-0.5">
923+
Feedback: {step.feedback}
924+
</div>
925+
)}
926+
</div>
927+
</div>
928+
))}
929+
</div>
930+
)}
931+
</div>
932+
</div>
933+
);
827934

828935
default:
829936
return (
@@ -838,17 +945,22 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
838945
};
839946

840947
return (
841-
<div className={`bg-white dark:bg-slate-800 rounded-lg shadow-md border border-slate-200 dark:border-slate-700 p-2 mt-3 ${variant === 'mcts' ? 'border-cyan-500' : variant === 'lats' ? 'border-purple-500' : ''}`}>
842-
<h2 className="text-base font-semibold mb-1.5 text-sky-950 dark:text-sky-100 flex items-center">
843-
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1.5 text-cyan-500" viewBox="0 0 20 20" fill="currentColor">
844-
<path fillRule="evenodd" d="M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7zM7 9H5v2h2V9zm8 0h-2v2h2V9zM9 9h2v2H9V9z" clipRule="evenodd" />
845-
</svg>
948+
<div className={`bg-white dark:bg-slate-800 rounded-lg shadow-md border border-slate-200 dark:border-slate-700 p-2 ${variant === 'mcts' ? 'border-cyan-500' : variant === 'lats' ? 'border-purple-500' : ''}`}>
949+
<h2 className="text-lg font-semibold text-sky-950 dark:text-sky-100 flex items-center mb-2">
950+
<MessageSquare className="h-4 w-4 mr-1.5 text-primary" />
846951
Message Log {variant !== 'default' ? `(${variant.toUpperCase()})` : ''}
847952
</h2>
848953
<div className="h-[150px] overflow-y-auto border border-slate-200 dark:border-slate-700 rounded-md p-1.5 bg-gradient-to-r from-sky-50 to-white dark:from-slate-900 dark:to-slate-800">
849954
{messages.map((msg, index) => {
850955
const parsedMessage = parseMessage(msg.content);
851956

957+
// Skip tree update messages
958+
if (parsedMessage.type === 'tree_update_node_expansion' ||
959+
parsedMessage.type === 'tree_update_node_evaluation' ||
960+
parsedMessage.type === 'tree_update_node_children_evaluation') {
961+
return null;
962+
}
963+
852964
return (
853965
<div
854966
key={index}

visual-tree-search-app/components/Sidebar.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,22 @@ const Sidebar = () => {
1717
// Only collapse when switching from large to small screen
1818
if (mobile && !isMobile) {
1919
setCollapsed(true);
20+
document.documentElement.style.setProperty('--sidebar-width', '3.5rem');
2021
}
2122
// Auto expand when switching from small to large screen
2223
if (!mobile && isMobile) {
2324
setCollapsed(false);
25+
document.documentElement.style.setProperty('--sidebar-width', '14rem');
2426
}
2527
};
2628

29+
// Set initial sidebar width
30+
document.documentElement.style.setProperty('--sidebar-width', collapsed ? '3.5rem' : '14rem');
31+
2732
checkScreenSize();
2833
window.addEventListener('resize', checkScreenSize);
2934
return () => window.removeEventListener('resize', checkScreenSize);
30-
}, [isMobile]);
35+
}, [isMobile, collapsed]);
3136

3237
const menuItems = [
3338
{
@@ -61,6 +66,7 @@ const Sidebar = () => {
6166

6267
const toggleSidebar = () => {
6368
setCollapsed(!collapsed);
69+
document.documentElement.style.setProperty('--sidebar-width', collapsed ? '3.5rem' : '14rem');
6470
};
6571

6672
return (

visual-tree-search-app/components/TreeVisual.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useEffect, useRef, useState } from 'react';
22
import * as d3 from 'd3';
33
import { useTheme } from 'next-themes';
4+
import { Network } from 'lucide-react';
45

56
interface TreeNode {
67
id: number;
@@ -653,9 +654,7 @@ const TreeVisual: React.FC<TreeVisualProps> = ({
653654
<div className={`${className} bg-white dark:bg-slate-800 rounded-r-lg overflow-hidden`}>
654655
<div className="p-3 border-b border-slate-200 dark:border-slate-700 bg-gradient-to-r from-sky-50 to-white dark:from-slate-900 dark:to-slate-800">
655656
<h2 className="text-lg font-semibold text-sky-950 dark:text-sky-100 flex items-center">
656-
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2 text-cyan-500" viewBox="0 0 20 20" fill="currentColor">
657-
<path d="M7 3a1 1 0 000 2h6a1 1 0 100-2H7zM4 7a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1zM2 11a2 2 0 012-2h12a2 2 0 012 2v4a2 2 0 01-2 2H4a2 2 0 01-2-2v-4z" />
658-
</svg>
657+
<Network className="h-4 w-4 mr-1.5 text-primary" />
659658
{title}
660659
</h2>
661660

0 commit comments

Comments
 (0)