Skip to content

Commit 5a43f6a

Browse files
Claudehotlong
andauthored
refactor(studio): replace setTimeout hack with proper state invalidation
- Remove setTimeout hack in ObjectExplorer component - Add refreshTrigger state pattern for data table refresh - ObjectDataTable now re-fetches when refreshTrigger changes - Eliminates race conditions from tab-switching hack - Part of Phase 1.5: Data Refresh Fix task Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/6c441201-fefb-4ec4-90de-2d3cd9f043db Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 89c0f97 commit 5a43f6a

2 files changed

Lines changed: 8 additions & 8 deletions

File tree

apps/studio/src/components/ObjectDataTable.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
interface ObjectDataTableProps {
2222
objectApiName: string;
2323
onEdit: (record: any) => void;
24+
refreshTrigger?: number;
2425
}
2526

2627
function CellValue({ value, type }: { value: any; type: string }) {
@@ -78,7 +79,7 @@ function TableSkeleton({ cols }: { cols: number }) {
7879
);
7980
}
8081

81-
export function ObjectDataTable({ objectApiName, onEdit }: ObjectDataTableProps) {
82+
export function ObjectDataTable({ objectApiName, onEdit, refreshTrigger = 0 }: ObjectDataTableProps) {
8283
const client = useClient();
8384
const [def, setDef] = useState<any>(null);
8485
const [records, setRecords] = useState<any[]>([]);
@@ -136,7 +137,7 @@ export function ObjectDataTable({ objectApiName, onEdit }: ObjectDataTableProps)
136137
}
137138
loadData();
138139
return () => { mounted = false; };
139-
}, [client, objectApiName, page]);
140+
}, [client, objectApiName, page, refreshTrigger]);
140141

141142
async function handleDelete(id: string) {
142143
if (!confirm('Are you sure you want to delete this record?')) return;

apps/studio/src/components/ObjectExplorer.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export function ObjectExplorer({ objectApiName }: ObjectExplorerProps) {
1818
const [activeTab, setActiveTab] = useState<ObjectTab>('schema');
1919
const [editingRecord, setEditingRecord] = useState<any>(null);
2020
const [showForm, setShowForm] = useState(false);
21+
// Refresh trigger: increment this to force data table to refetch
22+
const [refreshTrigger, setRefreshTrigger] = useState(0);
2123

2224
function handleEdit(record: any) {
2325
setEditingRecord(record);
@@ -27,11 +29,8 @@ export function ObjectExplorer({ objectApiName }: ObjectExplorerProps) {
2729
function handleFormSuccess() {
2830
setShowForm(false);
2931
setEditingRecord(null);
30-
// Force data tab re-fetch by toggling activeTab
31-
if (activeTab === 'data') {
32-
setActiveTab('schema');
33-
setTimeout(() => setActiveTab('data'), 0);
34-
}
32+
// Trigger data table refresh by incrementing the refresh counter
33+
setRefreshTrigger(prev => prev + 1);
3534
}
3635

3736
const tabs: { id: ObjectTab; label: string; icon: React.ElementType }[] = [
@@ -78,7 +77,7 @@ export function ObjectExplorer({ objectApiName }: ObjectExplorerProps) {
7877
<ObjectSchemaInspector objectApiName={objectApiName} />
7978
)}
8079
{activeTab === 'data' && (
81-
<ObjectDataTable objectApiName={objectApiName} onEdit={handleEdit} />
80+
<ObjectDataTable objectApiName={objectApiName} onEdit={handleEdit} refreshTrigger={refreshTrigger} />
8281
)}
8382
{activeTab === 'api' && (
8483
<ObjectApiConsole objectApiName={objectApiName} />

0 commit comments

Comments
 (0)