Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix row actions on instance NICs table closing when polling #2460

Merged
merged 1 commit into from
Sep 20, 2024
Merged
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
34 changes: 25 additions & 9 deletions app/pages/project/instances/instance/tabs/NetworkingTab.tsx
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
usePrefetchedApiQuery, usePrefetchedApiQuery,
type ExternalIp, type ExternalIp,
type InstanceNetworkInterface, type InstanceNetworkInterface,
type InstanceState,
} from '@oxide/api' } from '@oxide/api'
import { IpGlobal24Icon, Networking24Icon } from '@oxide/design-system/icons/react' import { IpGlobal24Icon, Networking24Icon } from '@oxide/design-system/icons/react'


Expand Down Expand Up @@ -109,7 +110,15 @@ NetworkingTab.loader = async ({ params }: LoaderFunctionArgs) => {
return null return null
} }


const colHelper = createColumnHelper<InstanceNetworkInterface>() // Bit of a hack: by putting the instance state in the row data, we can avoid
// remaking the row actions callback whenever the instance state changes, which
// causes the whole table to get re-rendered, which jarringly closes any open
// row actions menus
type NicRow = InstanceNetworkInterface & {
instanceState: InstanceState
}

const colHelper = createColumnHelper<NicRow>()
const staticCols = [ const staticCols = [
colHelper.accessor('name', { colHelper.accessor('name', {
header: 'name', header: 'name',
Expand Down Expand Up @@ -202,10 +211,11 @@ export function NetworkingTab() {
path: { instance: instanceName }, path: { instance: instanceName },
query: { project }, query: { project },
}) })
const canUpdateNic = instanceCan.updateNic(instance)


const makeActions = useCallback( const makeActions = useCallback(
(nic: InstanceNetworkInterface): MenuAction[] => [ (nic: NicRow): MenuAction[] => {
const canUpdateNic = instanceCan.updateNic({ runState: nic.instanceState })
return [
{ {
label: 'Make primary', label: 'Make primary',
onActivate() { onActivate() {
Expand All @@ -231,8 +241,8 @@ export function NetworkingTab() {
}, },
disabled: !canUpdateNic && ( disabled: !canUpdateNic && (
<> <>
The instance must be {updateNicStates} before editing a network interface&apos;s The instance must be {updateNicStates} before editing a network
settings interface&apos;s settings
</> </>
), ),
}, },
Expand All @@ -250,8 +260,9 @@ export function NetworkingTab() {
<>The instance must be {updateNicStates} to delete a network interface</> <>The instance must be {updateNicStates} to delete a network interface</>
), ),
}, },
], ]
[canUpdateNic, deleteNic, editNic, instanceSelector] },
[deleteNic, editNic, instanceSelector]
) )


const columns = useColsWithActions(staticCols, makeActions) const columns = useColsWithActions(staticCols, makeActions)
Expand All @@ -260,9 +271,14 @@ export function NetworkingTab() {
query: { ...instanceSelector, limit: 1000 }, query: { ...instanceSelector, limit: 1000 },
}).data.items }).data.items


const nicRows = useMemo(
() => nics.map((nic) => ({ ...nic, instanceState: instance.runState })),
[nics, instance]
)

const tableInstance = useReactTable({ const tableInstance = useReactTable({
columns, columns,
data: nics || [], data: nicRows,
getCoreRowModel: getCoreRowModel(), getCoreRowModel: getCoreRowModel(),
}) })


Expand Down Expand Up @@ -414,7 +430,7 @@ export function NetworkingTab() {
<TableTitle id="nics-label">Network interfaces</TableTitle> <TableTitle id="nics-label">Network interfaces</TableTitle>
<CreateButton <CreateButton
onClick={() => setCreateModalOpen(true)} onClick={() => setCreateModalOpen(true)}
disabled={!canUpdateNic} disabled={!instanceCan.updateNic(instance)}
disabledReason={ disabledReason={
<> <>
A network interface cannot be created or edited unless the instance is{' '} A network interface cannot be created or edited unless the instance is{' '}
Expand Down
Loading