Main process — worker thread for team data: - New team-data-worker thread handles getTeamData and findLogsForTask, isolating heavy file I/O (scanning 300+ subagent JSONL files) from Electron's main event loop. getTeamData dropped from ~2000ms on the main thread to ~110ms via the worker. - Worker-side dedup and 10s result cache for findLogsForTask prevents redundant scans when the same task is queried multiple times. - Discovery cache TTL raised from 5s to 30s — avoids re-scanning the entire project directory on every call. - Message cap at 200 in TeamDataService to keep IPC payloads under 1MB (was sending 2200+ messages / ~3MB, stalling Chromium IPC serialization). - IPC handlers fall back to main-thread execution if the worker is unavailable (graceful degradation). Renderer — useShallow and memoization (55 files): - Added useShallow to store selectors across 55 renderer files. Batched individual useStore() calls (e.g. 17 calls in ExtensionStoreView, 10 in ConnectionSection) into single useShallow selectors, cutting unnecessary re-render checks on every store update. - MemberLogsTab: three 5-second polling intervals now pause when the parent tab is hidden (display:none). Previously 5 hidden tabs × 3 intervals = 15 polling timers firing continuously. - KanbanColumn wrapped in React.memo to skip re-renders when props haven't changed. - MemberList: memoized activeMembers/removedMembers/colorMap; replaced O(n×m) per-member task scan with a pre-computed reviewer map. - Bounded timer Maps in store initialization to prevent unbounded growth of debounce/throttle tracking maps during long sessions.
27 lines
841 B
TypeScript
27 lines
841 B
TypeScript
/**
|
|
* PaneContainer - Horizontal flex container that renders panes side by side.
|
|
* DndContext is owned by TabbedLayout (parent) for cross-component tab DnD.
|
|
*/
|
|
|
|
import { Fragment } from 'react';
|
|
|
|
import { useStore } from '@renderer/store';
|
|
import { useShallow } from 'zustand/react/shallow';
|
|
|
|
import { PaneResizeHandle } from './PaneResizeHandle';
|
|
import { PaneView } from './PaneView';
|
|
|
|
export const PaneContainer = (): React.JSX.Element => {
|
|
const panes = useStore(useShallow((s) => s.paneLayout.panes));
|
|
|
|
return (
|
|
<div id="pane-container" className="flex flex-1 overflow-hidden">
|
|
{panes.map((pane, i) => (
|
|
<Fragment key={pane.id}>
|
|
{i > 0 && <PaneResizeHandle leftPaneId={panes[i - 1].id} rightPaneId={pane.id} />}
|
|
<PaneView paneId={pane.id} />
|
|
</Fragment>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|