Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ describe('ResourceContent table view handoff', () => {
})
}

it('hands off a restored view the table is mounted with', () => {
// The table can only honour `initialViewId` while its views query already
// lists that id. Reopening a chat against a cached list from before the
// agent's write would otherwise strand the restored view.
render({ type: 'table', id: 'table-1', title: 'Invoices', viewId: 'view-restored' })

expect(useTableViewPinStore.getState().pins['table-1']?.viewId).toBe('view-restored')
})

it('does not pin a table opened without a saved view', () => {
render({ type: 'table', id: 'table-1', title: 'Invoices' })

expect(useTableViewPinStore.getState().pins['table-1']).toBeUndefined()
})

it('hands off a saved view that arrives after the embedded table mounts', () => {
const table: MothershipResource = {
type: 'table',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,7 @@ export const ResourceContent = memo(function ResourceContent({
visible = true,
onBrowserOverlayControllerChange,
}: ResourceContentProps) {
const observedTableViewRef = useRef(
resource.type === 'table' ? { tableId: resource.id, viewId: resource.viewId } : null
)
const observedTableViewRef = useRef<{ tableId: string; viewId?: string } | null>(null)

useEffect(() => {
const previous = observedTableViewRef.current
Expand All @@ -192,8 +190,13 @@ export const ResourceContent = memo(function ResourceContent({
return
}
/**
* `initialViewId` owns the first table adoption. If refreshed chat data
* supplies it later, use the same one-shot handoff as live stream events.
* Pinned on mount as well as on later changes. `initialViewId` alone is not
* enough: the table honours it only while its views query already carries
* that id, and a cached list from before the agent wrote the view resolves
* it to nothing. Adoption then settles on the default and never revisits
* the id, so the restored view is lost until the tab is reopened. The pin
* waits for the refetch instead, and costs nothing when adoption already
* applied the same view — the table consumes it without touching the URL.
*/
useTableViewPinStore.getState().pin(next.tableId, next.viewId)
}, [resource.id, resource.type, resource.viewId])
Expand Down
Loading