From 45473bfd14718cf78421d4efa5d24d0ff163c851 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:32:18 +0000 Subject: [PATCH 1/3] Initial plan From 92377100b8d943cc8b94300786fa60ff692f46dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:40:08 +0000 Subject: [PATCH 2/3] Fix plugin-list tests to match updated component implementation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- .../src/__tests__/ListView.test.tsx | 26 +++++----- .../__tests__/ListViewPersistence.test.tsx | 48 ++++++++++++------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/packages/plugin-list/src/__tests__/ListView.test.tsx b/packages/plugin-list/src/__tests__/ListView.test.tsx index 9813c0ed8..d6d4efe73 100644 --- a/packages/plugin-list/src/__tests__/ListView.test.tsx +++ b/packages/plugin-list/src/__tests__/ListView.test.tsx @@ -75,7 +75,7 @@ describe('ListView', () => { }; renderWithProvider(); - const searchInput = screen.getByPlaceholderText(/search/i); + const searchInput = screen.getByPlaceholderText(/find/i); expect(searchInput).toBeInTheDocument(); }); @@ -89,7 +89,7 @@ describe('ListView', () => { }; renderWithProvider(); - const searchInput = screen.getByPlaceholderText(/search/i); + const searchInput = screen.getByPlaceholderText(/find/i); fireEvent.change(searchInput, { target: { value: 'test' } }); expect(onSearchChange).toHaveBeenCalledWith('test'); @@ -101,22 +101,24 @@ describe('ListView', () => { objectName: 'contacts', viewType: 'grid', fields: ['name', 'email'], + options: { + kanban: { + groupField: 'status', + }, + }, }; renderWithProvider(); - // Find list view button and click it - // Using getAllByRole because there might be multiple buttons - const buttons = screen.getAllByRole('radio'); // ToggleGroup usually uses radio role if type="single" - // However, if it's implemented as buttons using ToggleGroup which is roving tabindex... - // Let's try finding by aria-label which ViewSwitcher sets - const listButton = screen.getByLabelText('List'); - - fireEvent.click(listButton); + // Find kanban view button and click it + // ViewSwitcher uses buttons with aria-label + const kanbanButton = screen.getByLabelText('Kanban'); + + fireEvent.click(kanbanButton); // localStorage should be set with new view const storageKey = 'listview-contacts-view'; - expect(localStorageMock.getItem(storageKey)).toBe('list'); + expect(localStorageMock.getItem(storageKey)).toBe('kanban'); }); it('should call onViewChange when view is changed', () => { @@ -194,7 +196,7 @@ describe('ListView', () => { }; renderWithProvider(); - const searchInput = screen.getByPlaceholderText(/search/i) as HTMLInputElement; + const searchInput = screen.getByPlaceholderText(/find/i) as HTMLInputElement; // Type in search fireEvent.change(searchInput, { target: { value: 'test' } }); diff --git a/packages/plugin-list/src/__tests__/ListViewPersistence.test.tsx b/packages/plugin-list/src/__tests__/ListViewPersistence.test.tsx index ee9a72598..e786a16cc 100644 --- a/packages/plugin-list/src/__tests__/ListViewPersistence.test.tsx +++ b/packages/plugin-list/src/__tests__/ListViewPersistence.test.tsx @@ -49,17 +49,22 @@ describe('ListView Persistence', () => { id: 'my-custom-view', objectName: 'tasks', viewType: 'grid', // Start with grid + options: { + kanban: { + groupField: 'status', + }, + }, }; renderWithProvider(); - // Simulate changing to list view - const listButton = screen.getByLabelText('List'); - fireEvent.click(listButton); + // Simulate changing to kanban view + const kanbanButton = screen.getByLabelText('Kanban'); + fireEvent.click(kanbanButton); // Check scoped storage key const expectedKey = 'listview-tasks-my-custom-view-view'; - expect(localStorageMock.getItem(expectedKey)).toBe('list'); + expect(localStorageMock.getItem(expectedKey)).toBe('kanban'); // Check fallback key is NOT set expect(localStorageMock.getItem('listview-tasks-view')).toBeNull(); @@ -69,44 +74,53 @@ describe('ListView Persistence', () => { // Setup: View A (Global/Default) prefers Grid localStorageMock.setItem('listview-tasks-view', 'grid'); - // Setup: View B (Special) prefers List - // We define View B with valid options for Kanban to force it to render the button just in case, - // but we will test switching between Grid/List. + // Setup: View B (Special) prefers Kanban + // We define View B with valid options for Kanban to force it to render the button const viewB_Schema: ListViewSchema = { type: 'list-view', id: 'special-view', objectName: 'tasks', - viewType: 'list' // Default to List + viewType: 'kanban', // Default to Kanban + options: { + kanban: { + groupField: 'status', + }, + }, }; renderWithProvider(); - // Should use the schema default 'list' (since no storage exists for THIS view id) + // Should use the schema default 'kanban' (since no storage exists for THIS view id) // It should NOT use 'grid' from the global/default view. - const listButton = screen.getByLabelText('List'); - expect(listButton.getAttribute('data-state')).toBe('on'); + const kanbanButton = screen.getByLabelText('Kanban'); + expect(kanbanButton.getAttribute('data-state')).toBe('on'); const gridButton = screen.getByLabelText('Grid'); expect(gridButton.getAttribute('data-state')).toBe('off'); }); it('should switch correctly when storage has a value for THIS view', () => { - // Setup: This specific view was previously set to 'list' - localStorageMock.setItem('listview-tasks-my-board-view', 'list'); + // Setup: This specific view was previously set to 'kanban' + localStorageMock.setItem('listview-tasks-my-board-view', 'kanban'); const schema: ListViewSchema = { type: 'list-view', id: 'my-board', objectName: 'tasks', - viewType: 'grid' // Default in schema is grid + viewType: 'grid', // Default in schema is grid + options: { + kanban: { + groupField: 'status', + }, + }, }; renderWithProvider(); - // Should respect storage ('list') over schema ('grid') - const listButton = screen.getByLabelText('List'); - expect(listButton.getAttribute('data-state')).toBe('on'); + // Should respect storage ('kanban') over schema ('grid') + const kanbanButton = screen.getByLabelText('Kanban'); + expect(kanbanButton.getAttribute('data-state')).toBe('on'); }); }); From e28dd11ffa414452b72fd782e670f9ed6d08c398 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:45:55 +0000 Subject: [PATCH 3/3] Fix all test timeouts and add chartComponents export Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/plugin-aggrid/src/index.test.ts | 2 +- packages/plugin-charts/src/index.tsx | 6 ++++++ packages/plugin-kanban/src/index.test.ts | 2 +- packages/plugin-markdown/src/index.test.ts | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/plugin-aggrid/src/index.test.ts b/packages/plugin-aggrid/src/index.test.ts index 7f0c9650b..2bf1ca1af 100644 --- a/packages/plugin-aggrid/src/index.test.ts +++ b/packages/plugin-aggrid/src/index.test.ts @@ -13,7 +13,7 @@ describe('Plugin AgGrid', () => { // Import all renderers to register them beforeAll(async () => { await import('./index'); - }); + }, 15000); // Increase timeout to 15 seconds for async import describe('aggrid component', () => { it('should be registered in ComponentRegistry', () => { diff --git a/packages/plugin-charts/src/index.tsx b/packages/plugin-charts/src/index.tsx index 0a95230c1..ce52b42b6 100644 --- a/packages/plugin-charts/src/index.tsx +++ b/packages/plugin-charts/src/index.tsx @@ -15,6 +15,12 @@ export type { BarChartSchema } from './types'; export { ChartBarRenderer, ChartRenderer }; export { ObjectChart } from './ObjectChart'; +// Standard Export Protocol - for manual integration +export const chartComponents = { + 'bar-chart': ChartBarRenderer, + 'chart': ChartRenderer, +}; + // Register the component with the ComponentRegistry ComponentRegistry.register( 'bar-chart', diff --git a/packages/plugin-kanban/src/index.test.ts b/packages/plugin-kanban/src/index.test.ts index 4331b9fdf..1ff314956 100644 --- a/packages/plugin-kanban/src/index.test.ts +++ b/packages/plugin-kanban/src/index.test.ts @@ -13,7 +13,7 @@ describe('Plugin Kanban', () => { // Import all renderers to register them beforeAll(async () => { await import('./index'); - }); + }, 15000); // Increase timeout to 15 seconds for async import describe('kanban component', () => { it('should be registered in ComponentRegistry', () => { diff --git a/packages/plugin-markdown/src/index.test.ts b/packages/plugin-markdown/src/index.test.ts index 9aed82feb..70b0ae970 100644 --- a/packages/plugin-markdown/src/index.test.ts +++ b/packages/plugin-markdown/src/index.test.ts @@ -13,7 +13,7 @@ describe('Plugin Markdown', () => { // Import all renderers to register them beforeAll(async () => { await import('./index'); - }); + }, 15000); // Increase timeout to 15 seconds for async import describe('markdown component', () => { it('should be registered in ComponentRegistry', () => {