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', () => {