Skip to content

Commit 0c48758

Browse files
authored
Merge pull request #870 from objectstack-ai/copilot/fix-grouping-functionality
2 parents 0dd913f + 2542e23 commit 0c48758

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

ROADMAP.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,18 @@ The `FlowDesigner` is a canvas-based flow editor that bridges the gap between th
10211021

10221022
---
10231023

1024+
## 🐛 Bug Fixes
1025+
1026+
### ListView Grouping Config Not Taking Effect (February 2026)
1027+
1028+
**Root Cause:** `viewComponentSchema` `useMemo` in `ListView.tsx` was missing `groupingConfig`, `rowColorConfig`, and `navigation.handleClick` in its dependency array. When users toggled grouping fields via the toolbar popover, the state changed but the memoized schema was not recomputed, so the child grid/kanban/gallery never received the updated grouping config.
1029+
1030+
**Fix:** Added `groupingConfig`, `rowColorConfig`, and `navigation.handleClick` to the `useMemo` dependency array at line 856 of `ListView.tsx`.
1031+
1032+
**Tests:** Added integration test in `ListViewGroupingPropagation.test.tsx` that verifies toggling a group field via the toolbar immediately updates the rendered schema. All 117 ListView tests pass.
1033+
1034+
---
1035+
10241036
## ⚠️ Risk Management
10251037

10261038
| Risk | Mitigation |

packages/plugin-list/src/ListView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ export const ListView: React.FC<ListViewProps> = ({
853853
default:
854854
return baseProps;
855855
}
856-
}, [currentView, schema, currentSort, effectiveFields]);
856+
}, [currentView, schema, currentSort, effectiveFields, groupingConfig, rowColorConfig, navigation.handleClick]);
857857

858858
const hasFilters = currentFilters.conditions && currentFilters.conditions.length > 0;
859859

packages/plugin-list/src/__tests__/ListViewGroupingPropagation.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,52 @@ describe('ListView grouping config propagation', () => {
184184
expect(capturedSchema.grouping).toEqual(groupingConfig);
185185
});
186186

187+
it('updates grid schema when user toggles grouping via toolbar', async () => {
188+
render(
189+
<ListView
190+
schema={{
191+
type: 'list-view',
192+
objectName: 'products',
193+
viewType: 'grid',
194+
fields: ['name', 'category'],
195+
data: testData,
196+
}}
197+
/>,
198+
);
199+
200+
// Initially no grouping
201+
expect(capturedSchema).toBeDefined();
202+
expect(capturedSchema.type).toBe('object-grid');
203+
expect(capturedSchema.grouping).toBeUndefined();
204+
205+
// Open Group popover
206+
const groupButton = screen.getByRole('button', { name: /group/i });
207+
fireEvent.click(groupButton);
208+
209+
// Select the 'category' field checkbox in the group field list
210+
const fieldList = screen.getByTestId('group-field-list');
211+
const checkboxes = fieldList.querySelectorAll('input[type="checkbox"]');
212+
// Find the checkbox for 'category'
213+
const categoryCheckbox = Array.from(checkboxes).find(cb => {
214+
const label = cb.closest('label');
215+
return label?.textContent?.includes('category');
216+
});
217+
expect(categoryCheckbox).toBeDefined();
218+
fireEvent.click(categoryCheckbox!);
219+
220+
// Schema should now include grouping config
221+
expect(capturedSchema.grouping).toBeDefined();
222+
expect(capturedSchema.grouping.fields).toEqual(
223+
expect.arrayContaining([
224+
expect.objectContaining({ field: 'category' }),
225+
]),
226+
);
227+
228+
// Toggle off — click the checkbox again
229+
fireEvent.click(categoryCheckbox!);
230+
expect(capturedSchema.grouping).toBeUndefined();
231+
});
232+
187233
it('does not pass grouping when no grouping config exists', () => {
188234
render(
189235
<ListView

0 commit comments

Comments
 (0)