Refactor: Remove obsolete TDD coverage analysis, test concept enhancement, context gathering, and task generation commands

- Deleted the following command files:
  - tdd-coverage-analysis.md
  - test-concept-enhanced.md
  - test-context-gather.md
  - test-task-generate.md

Enhancement: Update FloatingPanel component styles

- Adjusted FloatingPanel backdrop styles for improved layout
- Modified height calculation to utilize full viewport height below the toolbar
This commit is contained in:
catlog22
2026-02-14 23:09:10 +08:00
parent b7bd433263
commit 3a9a66aa3b
15 changed files with 49 additions and 6345 deletions

View File

@@ -3,7 +3,7 @@
// ========================================
// Manages allotment-based split panes for CLI viewer
import { useCallback, useMemo } from 'react';
import { useCallback, useMemo, useRef, useEffect } from 'react';
import { Allotment } from 'allotment';
import 'allotment/dist/style.css';
import { cn } from '@/lib/utils';
@@ -105,14 +105,46 @@ function LayoutGroupRenderer({ group, minSize, onSizeChange }: LayoutGroupRender
export function LayoutContainer({ className }: LayoutContainerProps) {
const layout = useViewerLayout();
const panes = useViewerPanes();
const setLayout = useViewerStore((state) => state.setLayout);
// Use ref to track if we're currently updating to prevent infinite loops
const isUpdatingRef = useRef(false);
// Track previous sizes to avoid unnecessary updates
const prevSizesRef = useRef<number[] | undefined>(layout.sizes);
// Update prevSizesRef when layout.sizes changes from external sources
useEffect(() => {
if (!isUpdatingRef.current) {
prevSizesRef.current = layout.sizes;
}
}, [layout.sizes]);
// Stable callback with no dependencies - prevents Allotment onChange infinite loop
const handleSizeChange = useCallback(
(sizes: number[]) => {
// Update the root layout with new sizes
setLayout({ ...layout, sizes });
// Skip if sizes haven't actually changed (compare by value)
if (
prevSizesRef.current &&
sizes.length === prevSizesRef.current.length &&
sizes.every((s, i) => Math.abs(s - prevSizesRef.current![i]) < 0.1)
) {
return;
}
// Use functional update to avoid dependency on layout
isUpdatingRef.current = true;
prevSizesRef.current = sizes;
useViewerStore.getState().setLayout((prev) => ({
...prev,
sizes,
}));
// Reset updating flag after a microtask
queueMicrotask(() => {
isUpdatingRef.current = false;
});
},
[layout, setLayout]
[] // No dependencies - uses getState() and refs to prevent infinite loops
);
// Render based on layout type

View File

@@ -53,10 +53,10 @@ export function FloatingPanel({
{/* Backdrop */}
<div
className={cn(
'fixed inset-0 z-40 transition-opacity duration-200',
'fixed z-40 transition-opacity duration-200',
isOpen ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'
)}
style={{ top: '40px' }} // Below toolbar
style={{ top: '40px', bottom: 0, left: 0, right: 0 }}
onClick={handleBackdropClick}
>
<div className="absolute inset-0 bg-black/20" />
@@ -76,7 +76,7 @@ export function FloatingPanel({
)}
style={{
top: '40px', // Below toolbar
height: 'calc(100vh - 56px - 40px)', // Subtract both app header and toolbar
height: 'calc(100vh - 40px)', // Full height below toolbar
width: `${width}px`,
}}
>

View File

@@ -73,7 +73,7 @@ export interface ViewerState {
nextTabIdCounter: number;
// Actions
setLayout: (newLayout: AllotmentLayout) => void;
setLayout: (newLayout: AllotmentLayout | ((prev: AllotmentLayout) => AllotmentLayout)) => void;
addPane: (parentPaneId?: PaneId, direction?: 'horizontal' | 'vertical') => PaneId;
removePane: (paneId: PaneId) => void;
addTab: (paneId: PaneId, executionId: CliExecutionId, title: string) => TabId;
@@ -373,8 +373,14 @@ export const useViewerStore = create<ViewerState>()(
// ========== Layout Actions ==========
setLayout: (newLayout: AllotmentLayout) => {
set({ layout: newLayout }, false, 'viewer/setLayout');
setLayout: (newLayout: AllotmentLayout | ((prev: AllotmentLayout) => AllotmentLayout)) => {
if (typeof newLayout === 'function') {
const currentLayout = get().layout;
const result = newLayout(currentLayout);
set({ layout: result }, false, 'viewer/setLayout');
} else {
set({ layout: newLayout }, false, 'viewer/setLayout');
}
},
addPane: (parentPaneId?: PaneId, direction: 'horizontal' | 'vertical' = 'horizontal') => {