feat(intelligence): strip Memory tab to core view, hide analysis sub-pills (#3397)

This commit is contained in:
Cyrus Gray
2026-06-05 17:45:28 +05:30
committed by GitHub
parent 11fae79346
commit 5d2a4f934f
2 changed files with 57 additions and 64 deletions
@@ -0,0 +1,47 @@
import { screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { renderWithProviders } from '../../test/test-utils';
import type { ToastNotification } from '../../types/intelligence';
import MemorySection from './MemorySection';
const memoryWorkspaceSpy =
vi.fn<(props: { onToast?: (toast: Omit<ToastNotification, 'id'>) => void }) => void>();
vi.mock('./MemoryWorkspace', () => ({
MemoryWorkspace: (props: { onToast?: (toast: Omit<ToastNotification, 'id'>) => void }) => {
memoryWorkspaceSpy(props);
return <div data-testid="memory-workspace" />;
},
}));
describe('<MemorySection />', () => {
it('renders the core MemoryWorkspace directly with no analysis sub-pill bar', () => {
const onToast = vi.fn();
renderWithProviders(<MemorySection onToast={onToast} />);
// Core view is shown.
expect(screen.getByTestId('memory-workspace')).toBeInTheDocument();
// No sub-pill/tab bar (the analysis pills are gone).
for (const label of [
'Diagram',
'Centrality',
'Cohesion',
'Associations',
'Freshness',
'Timeline',
'Paths',
'Namespaces',
]) {
expect(screen.queryByRole('button', { name: label })).not.toBeInTheDocument();
}
});
it('forwards onToast to MemoryWorkspace', () => {
const onToast = vi.fn();
renderWithProviders(<MemorySection onToast={onToast} />);
expect(memoryWorkspaceSpy).toHaveBeenCalledWith(expect.objectContaining({ onToast }));
});
});
@@ -1,76 +1,22 @@
import { useState } from 'react';
import { useT } from '../../lib/i18n/I18nContext';
import type { ToastNotification } from '../../types/intelligence';
import { IS_DEV } from '../../utils/config';
import PillTabBar from '../PillTabBar';
import ConnectionPathTab from './ConnectionPathTab';
import DiagramViewerTab from './DiagramViewerTab';
import EntityAssociationsTab from './EntityAssociationsTab';
import GraphCentralityTab from './GraphCentralityTab';
import GraphCohesionTab from './GraphCohesionTab';
import MemoryFreshnessTab from './MemoryFreshnessTab';
import MemoryTimelineTab from './MemoryTimelineTab';
import { MemoryWorkspace } from './MemoryWorkspace';
import NamespaceOverviewTab from './NamespaceOverviewTab';
/**
* Memory sub-tabs.
* Memory tab body.
*
* All graph/memory-analysis surfaces that previously lived as top-level
* Intelligence tabs are nested here under the "Memory" tab. The first sub-tab
* (`memoryTree`) is the former top-level "Memory" tab (the MemoryWorkspace).
* Renders the core memory experience (`MemoryWorkspace` — sources registry,
* tree-status panel, and summary graph) directly, with no sub-pill/tab bar.
*
* The internal graph/memory-analysis surfaces (Diagram, Centrality, Cohesion,
* Associations, Freshness, Timeline, Paths, Namespaces) are developer/analysis
* views that cluttered the experience and are intentionally no longer reachable
* from this tab. Their components are retained on disk (and still unit-tested)
* so they can be restored behind a dedicated surface later if needed.
*/
type MemorySubTab =
| 'memoryTree'
| 'diagram'
| 'centrality'
| 'cohesion'
| 'associations'
| 'freshness'
| 'timeline'
| 'paths'
| 'namespaces';
interface MemorySectionProps {
onToast: (toast: Omit<ToastNotification, 'id'>) => void;
}
export default function MemorySection({ onToast }: MemorySectionProps) {
const { t } = useT();
const [activeSubTab, setActiveSubTab] = useState<MemorySubTab>('memoryTree');
const allSubTabs: { id: MemorySubTab; label: string; devOnly?: boolean }[] = [
{ id: 'memoryTree', label: t('memory.tab.memoryTree') },
{ id: 'diagram', label: t('memory.tab.diagram'), devOnly: true },
{ id: 'centrality', label: t('memory.tab.centrality'), devOnly: true },
{ id: 'cohesion', label: t('memory.tab.cohesion'), devOnly: true },
{ id: 'associations', label: t('memory.tab.associations'), devOnly: true },
{ id: 'freshness', label: t('memory.tab.freshness'), devOnly: true },
{ id: 'timeline', label: t('memory.tab.timeline'), devOnly: true },
{ id: 'paths', label: t('memory.tab.path'), devOnly: true },
{ id: 'namespaces', label: t('memory.tab.namespaces'), devOnly: true },
];
const subTabs = allSubTabs.filter(tab => !tab.devOnly || IS_DEV);
return (
<div className="space-y-4">
<PillTabBar
items={subTabs.map(tab => ({ label: tab.label, value: tab.id }))}
selected={activeSubTab}
onChange={setActiveSubTab}
containerClassName="flex flex-wrap gap-2 pb-1"
/>
{activeSubTab === 'memoryTree' && <MemoryWorkspace onToast={onToast} />}
{activeSubTab === 'diagram' && <DiagramViewerTab />}
{activeSubTab === 'centrality' && <GraphCentralityTab />}
{activeSubTab === 'cohesion' && <GraphCohesionTab />}
{activeSubTab === 'associations' && <EntityAssociationsTab />}
{activeSubTab === 'freshness' && <MemoryFreshnessTab />}
{activeSubTab === 'timeline' && <MemoryTimelineTab />}
{activeSubTab === 'paths' && <ConnectionPathTab />}
{activeSubTab === 'namespaces' && <NamespaceOverviewTab />}
</div>
);
return <MemoryWorkspace onToast={onToast} />;
}