- Added stable slot layout support in various components, enhancing the layout and interaction of nodes. - Updated TypeScript configuration to include new paths for the agent-graph package. - Refactored layout logic in activity lanes and kanban to accommodate stable slot assignments. - Enhanced GraphView and GraphControls to support sidebar visibility toggling and owner slot drop handling. - Introduced new types for layout management in GraphDataPort and related files. - Updated README to include stable slot layout documentation.
115 lines
3.5 KiB
TypeScript
115 lines
3.5 KiB
TypeScript
import React, { act } from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
vi.mock('@radix-ui/react-tooltip', () => ({
|
|
Root: ({ children }: { children: React.ReactNode }) =>
|
|
React.createElement(React.Fragment, null, children),
|
|
Trigger: ({ children }: { children: React.ReactNode }) =>
|
|
React.createElement(React.Fragment, null, children),
|
|
Portal: ({ children }: { children: React.ReactNode }) =>
|
|
React.createElement(React.Fragment, null, children),
|
|
Content: ({ children }: { children: React.ReactNode }) =>
|
|
React.createElement('div', { 'data-testid': 'tooltip-content' }, children),
|
|
Arrow: () => null,
|
|
}));
|
|
|
|
import { GraphControls } from '../../../../packages/agent-graph/src/ui/GraphControls';
|
|
|
|
describe('GraphControls', () => {
|
|
beforeEach(() => {
|
|
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
|
});
|
|
|
|
afterEach(() => {
|
|
document.body.innerHTML = '';
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
it('renders the sidebar toggle before the team and task buttons and triggers the callback', async () => {
|
|
const host = document.createElement('div');
|
|
document.body.appendChild(host);
|
|
const root = createRoot(host);
|
|
const onToggleSidebar = vi.fn();
|
|
|
|
await act(async () => {
|
|
root.render(
|
|
React.createElement(GraphControls, {
|
|
filters: {
|
|
showTasks: true,
|
|
showProcesses: true,
|
|
showEdges: true,
|
|
paused: false,
|
|
},
|
|
onFiltersChange: vi.fn(),
|
|
onZoomIn: vi.fn(),
|
|
onZoomOut: vi.fn(),
|
|
onZoomToFit: vi.fn(),
|
|
onToggleSidebar,
|
|
isSidebarVisible: true,
|
|
onOpenTeamPage: vi.fn(),
|
|
onCreateTask: vi.fn(),
|
|
teamName: 'demo-team',
|
|
})
|
|
);
|
|
await Promise.resolve();
|
|
});
|
|
|
|
const labels = Array.from(host.querySelectorAll('button[aria-label]')).map((button) =>
|
|
button.getAttribute('aria-label')
|
|
);
|
|
|
|
expect(labels.indexOf('Hide sidebar')).toBeGreaterThanOrEqual(0);
|
|
expect(labels.indexOf('Open team page')).toBeGreaterThan(labels.indexOf('Hide sidebar'));
|
|
expect(labels.indexOf('Create task')).toBeGreaterThan(labels.indexOf('Open team page'));
|
|
|
|
const toggleButton = host.querySelector('button[aria-label="Hide sidebar"]');
|
|
expect(toggleButton).not.toBeNull();
|
|
|
|
await act(async () => {
|
|
toggleButton?.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
await Promise.resolve();
|
|
});
|
|
|
|
expect(onToggleSidebar).toHaveBeenCalledTimes(1);
|
|
|
|
await act(async () => {
|
|
root.unmount();
|
|
await Promise.resolve();
|
|
});
|
|
});
|
|
|
|
it('shows the open-sidebar label when the sidebar is hidden', async () => {
|
|
const host = document.createElement('div');
|
|
document.body.appendChild(host);
|
|
const root = createRoot(host);
|
|
|
|
await act(async () => {
|
|
root.render(
|
|
React.createElement(GraphControls, {
|
|
filters: {
|
|
showTasks: true,
|
|
showProcesses: true,
|
|
showEdges: true,
|
|
paused: false,
|
|
},
|
|
onFiltersChange: vi.fn(),
|
|
onZoomIn: vi.fn(),
|
|
onZoomOut: vi.fn(),
|
|
onZoomToFit: vi.fn(),
|
|
onToggleSidebar: vi.fn(),
|
|
isSidebarVisible: false,
|
|
teamName: 'demo-team',
|
|
})
|
|
);
|
|
await Promise.resolve();
|
|
});
|
|
|
|
expect(host.querySelector('button[aria-label="Show sidebar"]')).not.toBeNull();
|
|
|
|
await act(async () => {
|
|
root.unmount();
|
|
await Promise.resolve();
|
|
});
|
|
});
|
|
});
|