Skip to content

Commit 7daaa33

Browse files
authored
Fix instance disk row menu closing on instance state change (#2453)
* fix instance disk row menu closing on instance state change * make it a little cleaner * comment
1 parent 5561f28 commit 7daaa33

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

app/pages/project/instances/instance/tabs/StorageTab.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
useApiQueryClient,
1919
usePrefetchedApiQuery,
2020
type Disk,
21+
type InstanceState,
2122
} from '@oxide/api'
2223
import { Storage24Icon } from '@oxide/design-system/icons/react'
2324

@@ -60,7 +61,15 @@ StorageTab.loader = async ({ params }: LoaderFunctionArgs) => {
6061
return null
6162
}
6263

63-
const colHelper = createColumnHelper<Disk>()
64+
// Bit of a hack: by putting the instance state in the row data, we can avoid
65+
// remaking the row actions callback whenever the instance state changes, which
66+
// causes the whole table to get re-rendered, which jarringly closes any open
67+
// row actions menus
68+
type InstanceDisk = Disk & {
69+
instanceState: InstanceState
70+
}
71+
72+
const colHelper = createColumnHelper<InstanceDisk>()
6473
const staticCols = [
6574
colHelper.accessor('name', { header: 'Disk' }),
6675
colHelper.accessor('size', Columns.size),
@@ -112,7 +121,7 @@ export function StorageTab() {
112121
const { data: instance } = usePrefetchedApiQuery('instanceView', instancePathQuery)
113122

114123
const makeActions = useCallback(
115-
(disk: Disk): MenuAction[] => [
124+
(disk: InstanceDisk): MenuAction[] => [
116125
{
117126
label: 'Snapshot',
118127
disabled: !diskCan.snapshot(disk) && (
@@ -135,7 +144,7 @@ export function StorageTab() {
135144
// don't bother checking disk state: assume that if it is showing up
136145
// in this list, it can be detached
137146
label: 'Detach',
138-
disabled: !instanceCan.detachDisk({ runState: instance.runState }) && (
147+
disabled: !instanceCan.detachDisk({ runState: disk.instanceState }) && (
139148
<>
140149
Instance must be <span className="text-default">stopped</span> before disk can
141150
be detached
@@ -146,9 +155,7 @@ export function StorageTab() {
146155
},
147156
},
148157
],
149-
// important to pass instance.runState because instance is not referentially
150-
// stable when we are polling when instance is in transition
151-
[detachDisk, instance.runState, instancePathQuery, createSnapshot, project]
158+
[detachDisk, instancePathQuery, createSnapshot, project]
152159
)
153160

154161
const attachDisk = useApiMutation('instanceDiskAttach', {
@@ -169,9 +176,14 @@ export function StorageTab() {
169176

170177
const { data: disks } = usePrefetchedApiQuery('instanceDiskList', instancePathQuery)
171178

179+
const rows = useMemo(
180+
() => disks.items.map((disk) => ({ ...disk, instanceState: instance.runState })),
181+
[disks.items, instance.runState]
182+
)
183+
172184
const table = useReactTable({
173185
columns: useColsWithActions(staticCols, makeActions),
174-
data: disks.items,
186+
data: rows,
175187
getCoreRowModel: getCoreRowModel(),
176188
})
177189

0 commit comments

Comments
 (0)