Skip to content

Commit 2a5fc12

Browse files
committed
make instance list polling not do weirdo stuff to the row actions menu
1 parent 95399db commit 2a5fc12

File tree

2 files changed

+35
-28
lines changed

2 files changed

+35
-28
lines changed

app/pages/project/instances/InstancesPage.tsx

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,10 @@ import { createColumnHelper } from '@tanstack/react-table'
99
import { useMemo } from 'react'
1010
import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom'
1111

12-
import {
13-
apiQueryClient,
14-
useApiQueryClient,
15-
usePrefetchedApiQuery,
16-
type Instance,
17-
} from '@oxide/api'
12+
import { apiQueryClient, usePrefetchedApiQuery, type Instance } from '@oxide/api'
1813
import { Instances16Icon, Instances24Icon } from '@oxide/design-system/icons/react'
1914

20-
// import { instanceTransitioning } from '~/api/util'
15+
import { instanceTransitioning } from '~/api/util'
2116
import { DocsPopover } from '~/components/DocsPopover'
2217
import { RefreshButton } from '~/components/RefreshButton'
2318
import { getProjectSelector, useProjectSelector, useQuickActions } from '~/hooks'
@@ -31,7 +26,7 @@ import { CreateLink } from '~/ui/lib/CreateButton'
3126
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
3227
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
3328
import { TableActions } from '~/ui/lib/Table'
34-
// import { useInterval } from '~/ui/lib/use-interval'
29+
import { useInterval } from '~/ui/lib/use-interval'
3530
import { docLinks } from '~/util/links'
3631
import { pb } from '~/util/path-builder'
3732

@@ -57,12 +52,11 @@ InstancesPage.loader = async ({ params }: LoaderFunctionArgs) => {
5752
return null
5853
}
5954

55+
const refetchInstances = () => apiQueryClient.invalidateQueries('instanceList')
56+
6057
export function InstancesPage() {
6158
const { project } = useProjectSelector()
6259

63-
const queryClient = useApiQueryClient()
64-
const refetchInstances = () => queryClient.invalidateQueries('instanceList')
65-
6660
const makeActions = useMakeInstanceActions(
6761
{ project },
6862
{ onSuccess: refetchInstances, onDelete: refetchInstances }
@@ -75,10 +69,10 @@ export function InstancesPage() {
7569
// if any instance in the list is transitioning, poll
7670
// TODO: figure out this logic. polling requests have the horrible effect of close
7771
// any open row actions menus
78-
// useInterval({
79-
// fn: () => apiQueryClient.invalidateQueries('instanceList'),
80-
// delay: instances.items.some(instanceTransitioning) ? 1000 : null,
81-
// })
72+
useInterval({
73+
fn: () => apiQueryClient.invalidateQueries('instanceList'),
74+
delay: instances.items.some(instanceTransitioning) ? 1000 : null,
75+
})
8276

8377
const navigate = useNavigate()
8478
useQuickActions(

app/pages/project/instances/actions.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,35 @@ type Options = {
2929
}
3030

3131
export const useMakeInstanceActions = (
32-
projectSelector: { project: string },
32+
{ project }: { project: string },
3333
options: Options = {}
3434
): MakeActions<Instance> => {
3535
const navigate = useNavigate()
3636

3737
// if you also pass onSuccess to mutate(), this one is not overridden — this
38-
// one runs first, then the one passed to mutate()
38+
// one runs first, then the one passed to mutate().
39+
//
40+
// We pull out the mutate functions because they are referentially stable,
41+
// while the whole useMutation result object is not. The async ones are used
42+
// when we need to confirm because the confirm modals want that.
3943
const opts = { onSuccess: options.onSuccess }
40-
const startInstance = useApiMutation('instanceStart', opts)
41-
const stopInstance = useApiMutation('instanceStop', opts)
42-
const rebootInstance = useApiMutation('instanceReboot', opts)
44+
const { mutate: startInstance } = useApiMutation('instanceStart', opts)
45+
const { mutateAsync: stopInstanceAsync } = useApiMutation('instanceStop', opts)
46+
const { mutate: rebootInstance } = useApiMutation('instanceReboot', opts)
4347
// delete has its own
44-
const deleteInstance = useApiMutation('instanceDelete', { onSuccess: options.onDelete })
48+
const { mutateAsync: deleteInstanceAsync } = useApiMutation('instanceDelete', {
49+
onSuccess: options.onDelete,
50+
})
4551

4652
return useCallback(
4753
(instance) => {
48-
const instanceSelector = { ...projectSelector, instance: instance.name }
49-
const instanceParams = { path: { instance: instance.name }, query: projectSelector }
54+
const instanceSelector = { project, instance: instance.name }
55+
const instanceParams = { path: { instance: instance.name }, query: { project } }
5056
return [
5157
{
5258
label: 'Start',
5359
onActivate() {
54-
startInstance.mutate(instanceParams, {
60+
startInstance(instanceParams, {
5561
onSuccess: () => addToast({ title: `Starting instance '${instance.name}'` }),
5662
onError: (error) =>
5763
addToast({
@@ -71,7 +77,7 @@ export const useMakeInstanceActions = (
7177
confirmAction({
7278
actionType: 'danger',
7379
doAction: () =>
74-
stopInstance.mutateAsync(instanceParams, {
80+
stopInstanceAsync(instanceParams, {
7581
onSuccess: () =>
7682
addToast({ title: `Stopping instance '${instance.name}'` }),
7783
}),
@@ -93,7 +99,7 @@ export const useMakeInstanceActions = (
9399
{
94100
label: 'Reboot',
95101
onActivate() {
96-
rebootInstance.mutate(instanceParams, {
102+
rebootInstance(instanceParams, {
97103
onSuccess: () => addToast({ title: `Rebooting instance '${instance.name}'` }),
98104
onError: (error) =>
99105
addToast({
@@ -117,7 +123,7 @@ export const useMakeInstanceActions = (
117123
label: 'Delete',
118124
onActivate: confirmDelete({
119125
doDelete: () =>
120-
deleteInstance.mutateAsync(instanceParams, {
126+
deleteInstanceAsync(instanceParams, {
121127
onSuccess: () =>
122128
addToast({ title: `Deleting instance '${instance.name}'` }),
123129
}),
@@ -132,6 +138,13 @@ export const useMakeInstanceActions = (
132138
},
133139
]
134140
},
135-
[projectSelector, deleteInstance, navigate, rebootInstance, startInstance, stopInstance]
141+
[
142+
project,
143+
navigate,
144+
deleteInstanceAsync,
145+
rebootInstance,
146+
startInstance,
147+
stopInstanceAsync,
148+
]
136149
)
137150
}

0 commit comments

Comments
 (0)