feat: Refactor AppShell and Header components, enhance memory management UI, and align API endpoints

- Removed defaultCollapsed prop from AppShell and set sidebar to be collapsed by default.
- Updated Header component to remove mobile menu toggle and added a history entry button.
- Refactored ExplorationsSection to streamline data extraction and improve UI rendering.
- Added new messages for GitHub sync success and error handling in issues.
- Implemented View Memory Dialog for better memory content viewing and editing.
- Enhanced FlowToolbar to auto-create flows and improved save functionality.
- Conducted a frontend audit for API endpoint alignment with backend implementations.
This commit is contained in:
catlog22
2026-02-07 23:15:50 +08:00
parent 82ed5054f5
commit 80ae4baea8
13 changed files with 418 additions and 195 deletions

View File

@@ -17,8 +17,6 @@ import { useWorkflowStore } from '@/stores/workflowStore';
import { useWebSocketNotifications, useWebSocket } from '@/hooks';
export interface AppShellProps {
/** Initial sidebar collapsed state */
defaultCollapsed?: boolean;
/** Callback for refresh action */
onRefresh?: () => void;
/** Whether refresh is in progress */
@@ -31,7 +29,6 @@ export interface AppShellProps {
const SIDEBAR_COLLAPSED_KEY = 'ccw-sidebar-collapsed';
export function AppShell({
defaultCollapsed = false,
onRefresh,
isRefreshing = false,
children,
@@ -74,13 +71,14 @@ export function AppShell({
setWorkspaceInitialized(true);
}, [isWorkspaceInitialized, projectPath, location.search, switchWorkspace]);
// Sidebar collapse state (persisted)
// Sidebar collapse state default to collapsed (hidden)
const [sidebarCollapsed, setSidebarCollapsed] = useState(() => {
if (typeof window !== 'undefined') {
const stored = localStorage.getItem(SIDEBAR_COLLAPSED_KEY);
return stored ? JSON.parse(stored) : defaultCollapsed;
// Default to collapsed (true) if no persisted value
return stored !== null ? JSON.parse(stored) : true;
}
return defaultCollapsed;
return true;
});
// Mobile sidebar open state
@@ -117,16 +115,14 @@ export function AppShell({
localStorage.setItem(SIDEBAR_COLLAPSED_KEY, JSON.stringify(sidebarCollapsed));
}, [sidebarCollapsed]);
// Close mobile sidebar on route change or resize
// Close mobile sidebar on resize
useEffect(() => {
const handleResize = () => {
if (window.innerWidth >= 768) {
setMobileOpen(false);
}
};
window.addEventListener('resize', handleResize);
// Cleanup: Remove event listener on unmount to prevent memory leak
return () => window.removeEventListener('resize', handleResize);
}, []);
@@ -174,7 +170,7 @@ export function AppShell({
{/* Main layout - sidebar + content */}
<div className="flex flex-1 overflow-hidden">
{/* Sidebar */}
{/* Sidebar - collapsed by default */}
<Sidebar
collapsed={sidebarCollapsed}
onCollapsedChange={handleCollapsedChange}
@@ -186,7 +182,6 @@ export function AppShell({
<MainContent
className={cn(
'transition-all duration-300',
// Add left margin on desktop to account for fixed sidebar
sidebarCollapsed ? 'md:ml-16' : 'md:ml-64'
)}
>

View File

@@ -8,7 +8,6 @@ import { Link } from 'react-router-dom';
import { useIntl } from 'react-intl';
import {
Workflow,
Menu,
Moon,
Sun,
RefreshCw,
@@ -17,6 +16,7 @@ import {
LogOut,
Terminal,
Bell,
Clock,
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/Button';
@@ -27,8 +27,6 @@ import { useCliStreamStore, selectActiveExecutionCount } from '@/stores/cliStrea
import { useNotificationStore } from '@/stores';
export interface HeaderProps {
/** Callback to toggle mobile sidebar */
onMenuClick?: () => void;
/** Callback for refresh action */
onRefresh?: () => void;
/** Whether refresh is in progress */
@@ -38,7 +36,6 @@ export interface HeaderProps {
}
export function Header({
onMenuClick,
onRefresh,
isRefreshing = false,
onCliMonitorClick,
@@ -65,19 +62,8 @@ export function Header({
className="flex items-center justify-between px-4 md:px-5 h-14 bg-card border-b border-border sticky top-0 z-50 shadow-sm"
role="banner"
>
{/* Left side - Menu button (mobile) and Logo */}
{/* Left side - Logo */}
<div className="flex items-center gap-3">
{/* Mobile menu toggle */}
<Button
variant="ghost"
size="icon"
className="md:hidden"
onClick={onMenuClick}
aria-label={formatMessage({ id: 'common.aria.toggleNavigation' })}
>
<Menu className="w-5 h-5" />
</Button>
{/* Logo / Brand */}
<Link
to="/"
@@ -91,6 +77,19 @@ export function Header({
{/* Right side - Actions */}
<div className="flex items-center gap-2">
{/* History entry */}
<Button
variant="ghost"
size="sm"
asChild
className="gap-2"
>
<Link to="/history">
<Clock className="h-4 w-4" />
<span className="hidden sm:inline">{formatMessage({ id: 'navigation.main.history' })}</span>
</Link>
</Button>
{/* CLI Monitor button */}
<Button
variant="ghost"