Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Type-check web UI
run: pnpm run type-check:web

- name: Build web UI
run: pnpm run build:web

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/desktop-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Type-check web UI
run: pnpm run type-check:web

- name: Build desktop app
run: ${{ matrix.platform.build_command }}

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Type-check web UI
run: pnpm run type-check:web

- name: Patch nightly version
shell: bash
env:
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
"dev:web": "pnpm --dir src/web-ui dev",
"prebuild": "pnpm run prebuild:web",
"prebuild:web": "pnpm run copy-assets --silent && pnpm run generate-all --silent",
"type-check:web": "pnpm --dir src/web-ui run type-check",
"build": "pnpm run build:web",
"build:web": "pnpm --dir src/web-ui build",
"build:web": "pnpm run type-check:web && pnpm --dir src/web-ui build",
"build:mobile-web": "pnpm --dir src/mobile-web build",
"preview": "pnpm --dir src/web-ui preview",
"desktop:dev": "node scripts/dev.cjs desktop",
Expand Down
4 changes: 3 additions & 1 deletion src/web-ui/src/app/components/NavPanel/MainNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ const MainNav: React.FC<MainNavProps> = ({
const sectionDir = getSectionDepartDir(section.id);
const sectionDepartCls = sectionDir ? ` is-departing-${sectionDir}` : '';

const sectionSceneId = section.sceneId;

return (
<div key={section.id} className={`bitfun-nav-panel__section${sectionDepartCls}`}>
{section.label && (
Expand All @@ -493,7 +495,7 @@ const MainNav: React.FC<MainNavProps> = ({
collapsible={isCollapsible}
isOpen={isSectionOpen}
onToggle={() => toggleSection(section.id)}
onSceneOpen={section.sceneId ? () => openScene(section.sceneId) : undefined}
onSceneOpen={sectionSceneId ? () => openScene(sectionSceneId) : undefined}
actions={section.id === 'workspace' ? (
<div className="bitfun-nav-panel__workspace-action-wrap">
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const NavItem: React.FC<NavItemProps> = ({
.filter(Boolean)
.join(' ')}
onClick={onClick}
title={tooltipContent ?? displayLabel}
>
<span className="bitfun-nav-panel__item-icon" aria-hidden="true">
<Icon size={15} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Tooltip, Modal } from '@/component-library';
import { useI18n } from '@/infrastructure/i18n/hooks/useI18n';
import { useSceneManager } from '../../../hooks/useSceneManager';
import { useNavSceneStore } from '../../../stores/navSceneStore';
import { useSceneStore } from '../../../stores/sceneStore';
import { useToolbarModeContext } from '@/flow_chat/components/toolbar-mode/ToolbarModeContext';
import { useCurrentWorkspace } from '@/infrastructure/contexts/WorkspaceContext';
import { useNotification } from '@/shared/notification-system';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { FlowChatState, Session } from '../../../../../flow_chat/types/flow
import { useSceneStore } from '../../../../stores/sceneStore';
import { useApp } from '../../../../hooks/useApp';
import type { SceneTabId } from '../../../SceneBar/types';
import type { SessionMode } from '../../../../stores/sessionModeStore';
import { useWorkspaceContext } from '@/infrastructure/contexts/WorkspaceContext';
import { createLogger } from '@/shared/utils/logger';
import './SessionsSection.scss';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ const WorkspaceItem: React.FC<WorkspaceItemProps> = ({ workspace, isActive, isSi
workspaceId={workspace.id}
workspacePath={workspace.rootPath}
isActiveWorkspace={isActive}
showCreateActions={false}
/>
</div>

Expand Down
4 changes: 0 additions & 4 deletions src/web-ui/src/app/components/TitleBar/GlobalSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ import { useI18n } from '@/infrastructure/i18n';
import { useWorkspaceContext } from '../../../infrastructure/contexts/WorkspaceContext';
import { useFileSearch } from '@/hooks';
import type { FileSearchResult } from '../../../infrastructure/api/service-api/tauri-commands';
import { createLogger } from '@/shared/utils/logger';
import './GlobalSearch.scss';

const log = createLogger('GlobalSearch');

// Initial result count and load-more batch size
const INITIAL_DISPLAY_COUNT = 50;
const LOAD_MORE_COUNT = 50;
Expand Down
5 changes: 1 addition & 4 deletions src/web-ui/src/app/components/TitleBar/TitleBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ import './TitleBar.scss';

import { Button, WindowControls, Tooltip } from '@/component-library';
import { WorkspaceManager } from '../../../tools/workspace';
import { CurrentSessionTitle, useToolbarModeContext } from '../../../flow_chat';
import { CurrentSessionTitle } from '../../../flow_chat';
import { createConfigCenterTab } from '@/shared/utils/tabUtils';
import { workspaceAPI } from '@/infrastructure/api';
import { NewProjectDialog } from '../NewProjectDialog';
import { AboutDialog } from '../AboutDialog';
import { GlobalSearch } from './GlobalSearch';
import { AgentOrb } from './AgentOrb';
import NotificationButton from './NotificationButton';
import { createLogger } from '@/shared/utils/logger';
Expand Down Expand Up @@ -65,8 +64,6 @@ const TitleBar: React.FC<TitleBarProps> = ({
);
}, []);

const { enableToolbarMode } = useToolbarModeContext();

const lastMouseDownTimeRef = React.useRef<number>(0);

const handleHeaderMouseDown = useCallback((e: React.MouseEvent) => {
Expand Down
13 changes: 8 additions & 5 deletions src/web-ui/src/app/components/panels/BranchSelectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import './BranchSelectModal.scss';

const log = createLogger('BranchSelectModal');

type SelectableBranch = GitBranchType & {
isCurrent?: boolean;
hasWorktree?: boolean;
};

export interface BranchSelectResult {
branch: string;
isNew: boolean;
Expand Down Expand Up @@ -93,7 +98,7 @@ export const BranchSelectModal: React.FC<BranchSelectModalProps> = ({
}
};

const filteredBranches = useMemo(() => {
const filteredBranches = useMemo<SelectableBranch[]>(() => {
let result = branches;

if (searchTerm.trim()) {
Expand All @@ -103,8 +108,8 @@ export const BranchSelectModal: React.FC<BranchSelectModalProps> = ({
);
}

const availableBranches: GitBranchType[] = [];
const unavailableBranches: GitBranchType[] = [];
const availableBranches: SelectableBranch[] = [];
const unavailableBranches: SelectableBranch[] = [];
const existingWorktreeSet = new Set(existingWorktreeBranches);

result.forEach(branch => {
Expand Down Expand Up @@ -217,9 +222,7 @@ export const BranchSelectModal: React.FC<BranchSelectModalProps> = ({
)}

{filteredBranches.map((branch) => {
// @ts-ignore
const isDisabled = branch.isCurrent || branch.hasWorktree;
// @ts-ignore
const hasWorktree = branch.hasWorktree;

return (
Expand Down
6 changes: 2 additions & 4 deletions src/web-ui/src/app/components/panels/FilesPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ const FilesPanel: React.FC<FilesPanelProps> = ({
selectedFile,
expandedFolders,
loading,
silentRefreshing,
error,
loadFileTree,
selectFile,
Expand All @@ -97,13 +96,12 @@ const FilesPanel: React.FC<FilesPanelProps> = ({
enableAutoWatch: true,
enableLazyLoad: true
});

const handleTreeUpdate = useCallback((updatedTree: FileSystemNode[]) => {
log.debug('File tree updated', { nodeCount: updatedTree.length });
setFileTree(updatedTree);
}, [setFileTree]);

const handleNodeExpandLazy = useCallback((path: string, expanded: boolean) => {
const handleNodeExpandLazy = useCallback((path: string) => {
expandFolderLazy(path);
}, [expandFolderLazy]);

Expand Down Expand Up @@ -682,4 +680,4 @@ const FilesPanel: React.FC<FilesPanelProps> = ({
);
};

export default FilesPanel;
export default FilesPanel;
5 changes: 1 addition & 4 deletions src/web-ui/src/app/components/panels/base/FlexiblePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ const FlexiblePanel: React.FC<ExtendedFlexiblePanelProps> = memo(({
if (content?.type !== 'mermaid-editor') return null;

const mermaidData = content.data || {};
const metadata = content.metadata || {};

return {
initialSourceCode: mermaidData.sourceCode || t('flexiblePanel.fallback.mermaidDefaultCode'),
onSave: async (sourceCode: string) => {
Expand Down Expand Up @@ -514,7 +512,7 @@ const FlexiblePanel: React.FC<ExtendedFlexiblePanelProps> = memo(({
onDirtyStateChange(hasChanges);
}
}}
onSave={(savedContent) => {
onSave={() => {
if (onDirtyStateChange) {
onDirtyStateChange(false);
}
Expand Down Expand Up @@ -793,4 +791,3 @@ const FlexiblePanel: React.FC<ExtendedFlexiblePanelProps> = memo(({
FlexiblePanel.displayName = 'FlexiblePanel';

export default FlexiblePanel;

6 changes: 4 additions & 2 deletions src/web-ui/src/app/components/panels/base/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export type PanelContentType =
| 'git-branch-history'
| 'ai-session'
| 'planner'
| 'ui-editor'
| 'ui-relation-graph'
| 'design-tokens'
| 'task-detail'
| 'plan-viewer'
| 'terminal';
Expand Down Expand Up @@ -67,9 +70,8 @@ export interface TabbedFlexiblePanelRef {
export interface PanelContentConfig {
type: PanelContentType;
displayName: string;
icon: React.ComponentType<{ size?: number }>;
icon: React.ComponentType<{ size?: string | number }>;
supportsCopy: boolean;
supportsDownload: boolean;
showHeader: boolean;
}

26 changes: 24 additions & 2 deletions src/web-ui/src/app/components/panels/base/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
GitBranch,
Eye,
Edit3,
Terminal as TerminalIcon,
BookOpen,
Settings,
ClipboardList,
Expand Down Expand Up @@ -125,6 +124,22 @@ export const PANEL_CONTENT_CONFIGS: Record<PanelContentType, PanelContentConfig>
supportsDownload: false,
showHeader: false
},
'git-graph': {
type: 'git-graph',
displayName: 'Git Graph',
icon: GitBranch,
supportsCopy: false,
supportsDownload: false,
showHeader: false
},
'git-branch-history': {
type: 'git-branch-history',
displayName: 'Git Branch History',
icon: GitBranch,
supportsCopy: false,
supportsDownload: false,
showHeader: false
},
'ai-session': {
type: 'ai-session',
displayName: 'AI Session',
Expand Down Expand Up @@ -180,6 +195,14 @@ export const PANEL_CONTENT_CONFIGS: Record<PanelContentType, PanelContentConfig>
supportsCopy: false,
supportsDownload: false,
showHeader: false
},
'terminal': {
type: 'terminal',
displayName: 'Terminal',
icon: Code,
supportsCopy: false,
supportsDownload: false,
showHeader: false
}
};

Expand Down Expand Up @@ -282,4 +305,3 @@ export const generateFileName = (type: PanelContentType, title: string): string
return `${baseName}.txt`;
}
};

Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
* Core component for the right panel, aggregating submodules.
*/

import React, { useEffect, useCallback, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import { EditorArea } from './editor-area';
import { AnchorZone } from './anchor-zone';
import { MissionControl } from './mission-control';
import { EmptyState } from './empty-state';
import { useCanvasStore } from './stores';
import { useTabLifecycle, useKeyboardShortcuts, usePanelTabCoordinator } from './hooks';
import type { AnchorPosition } from './types';
import { createLogger } from '@/shared/utils/logger';
import './ContentCanvas.scss';

const log = createLogger('ContentCanvas');

export interface ContentCanvasProps {
/** Workspace path */
workspacePath?: string;
Expand All @@ -31,20 +27,17 @@ export const ContentCanvas: React.FC<ContentCanvasProps> = ({
workspacePath,
mode = 'agent',
onInteraction,
onBeforeClose,
}) => {
// Store state
const {
primaryGroup,
secondaryGroup,
layout,
isMissionControlOpen,
setAnchorPosition,
setAnchorSize,
closeMissionControl,
openMissionControl,
} = useCanvasStore();

// Initialize hooks
const { handleCloseWithDirtyCheck, handleCloseAllWithDirtyCheck } = useTabLifecycle({ mode });
useKeyboardShortcuts({ enabled: true, handleCloseWithDirtyCheck });
Expand Down Expand Up @@ -137,7 +130,6 @@ export const ContentCanvas: React.FC<ContentCanvasProps> = ({
</div>
);
};

ContentCanvas.displayName = 'ContentCanvas';

export default ContentCanvas;
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export const AnchorZone: React.FC<AnchorZoneProps> = ({
size,
isMaximized = false,
onSizeChange,
onPositionChange,
onClose,
onToggleMaximize,
children,
Expand Down Expand Up @@ -97,10 +96,6 @@ export const AnchorZone: React.FC<AnchorZoneProps> = ({
}, [isCollapsed]);

// Toggle position
const togglePosition = useCallback(() => {
onPositionChange(isBottom ? 'right' : 'bottom');
}, [isBottom, onPositionChange]);

return (
<div
ref={containerRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import type {
DropPosition,
PanelContent,
} from '../types';
import { createLogger } from '@/shared/utils/logger';
import './EditorArea.scss';

const log = createLogger('EditorArea');

export interface EditorAreaProps {
workspacePath?: string;
onOpenMissionControl?: () => void;
Expand Down Expand Up @@ -49,6 +45,7 @@ export const EditorArea: React.FC<EditorAreaProps> = ({
reorderTab,
handleDrop,
setSplitRatio,
setSplitRatio2,
setActiveGroup,
updateTabContent,
setTabDirty,
Expand Down Expand Up @@ -190,7 +187,6 @@ export const EditorArea: React.FC<EditorAreaProps> = ({
}

if (splitMode === 'grid') {
const setSplitRatio2 = (r: number) => useCanvasStore.setState((s) => ({ layout: { ...s.layout, splitRatio2: r } }));
return (
<div ref={containerRef} className="canvas-editor-area is-grid">
<div ref={topRowRef} className="canvas-editor-area__top-row" style={{ flex: `0 0 calc(${splitRatio * 100}% - 2px)` }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import type {
DropPosition,
PanelContent,
SplitMode,
CanvasTab,
} from '../types';
import './EditorGroup.scss';

Expand Down
Loading
Loading