Skip to content

Commit cd2b176

Browse files
Copilothotlong
andcommitted
fix: address reviewer feedback — dedupe double refresh, use generic MutationEvent<T>
1. types/data.ts: onMutation now uses MutationEvent<T> to preserve record typing 2. ObjectView: skip onMutation subscription when renderListView is provided (avoids double refresh) 3. ListView: skip onMutation subscription when refreshTrigger is provided (avoids double refresh) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> Agent-Logs-Url: https://github.com/objectstack-ai/objectui/sessions/b095f623-c45f-4bc7-8ffd-a5cac05aac07
1 parent d510bbd commit cd2b176

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

packages/plugin-list/src/ListView.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,17 @@ export const ListView = React.forwardRef<ListViewHandle, ListViewProps>(({
416416
}), []);
417417

418418
// --- P2: Auto-subscribe to DataSource mutation events ---
419+
// When an external refreshTrigger is provided, rely on that instead of
420+
// subscribing to dataSource mutations to avoid double refreshes.
419421
React.useEffect(() => {
420-
if (!dataSource?.onMutation || !schema.objectName) return;
422+
if (!dataSource?.onMutation || !schema.objectName || schema.refreshTrigger) return;
421423
const unsub = dataSource.onMutation((event) => {
422424
if (event.resource === schema.objectName) {
423425
setRefreshKey(k => k + 1);
424426
}
425427
});
426428
return unsub;
427-
}, [dataSource, schema.objectName]);
429+
}, [dataSource, schema.objectName, schema.refreshTrigger]);
428430

429431
// Dynamic page size state (wired from pageSizeOptions selector)
430432
const [dynamicPageSize, setDynamicPageSize] = React.useState<number | undefined>(undefined);

packages/plugin-view/src/ObjectView.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,20 @@ export const ObjectView: React.FC<ObjectViewProps> = ({
228228
// When a DataSource implements onMutation(), ObjectView auto-refreshes
229229
// its own data fetch (for non-grid view types like kanban, calendar, etc.)
230230
// whenever a create/update/delete occurs on the same objectName.
231+
//
232+
// ListView-driven configurations already manage refreshKey via
233+
// form success / delete handlers. To avoid double refreshes and
234+
// duplicate find() calls, skip auto-subscription when renderListView is provided.
231235
useEffect(() => {
232236
if (!dataSource?.onMutation || !schema.objectName) return;
237+
if (renderListView) return;
233238
const unsub = dataSource.onMutation((event: any) => {
234239
if (event.resource === schema.objectName) {
235240
setRefreshKey(prev => prev + 1);
236241
}
237242
});
238243
return unsub;
239-
}, [dataSource, schema.objectName]);
244+
}, [dataSource, schema.objectName, renderListView]);
240245

241246
// Data fetching state for non-grid views
242247
const [data, setData] = useState<any[]>([]);

packages/types/src/data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ export interface DataSource<T = any> {
342342
* unsub?.();
343343
* ```
344344
*/
345-
onMutation?(callback: (event: MutationEvent) => void): () => void;
345+
onMutation?(callback: (event: MutationEvent<T>) => void): () => void;
346346
}
347347

348348
/**

0 commit comments

Comments
 (0)