Skip to content

Commit

Permalink
Add VPC, Subnet to NIC table (#1047)
Browse files Browse the repository at this point in the history
* WIP

* Slightly more correct types

* Fix indirect export issue

* Add ts-expect-errors for now

* Fix e2e tests

* Fix e2e take 2

* Remove table debug

* fix merge conflict I rudely introduced

* make vpc name a link, avoid dire type situation (#1063)

Co-authored-by: David Crespo <[email protected]>
Co-authored-by: David Crespo <[email protected]>
  • Loading branch information
3 people authored Jul 21, 2022
1 parent 1135044 commit 6b13fd1
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
14 changes: 12 additions & 2 deletions app/pages/__tests__/instance/networking.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test } from '@playwright/test'
import { expect, test } from '@playwright/test'

import { expectNotVisible, expectRowVisible, expectVisible } from 'app/util/e2e'

Expand All @@ -14,9 +14,17 @@ test('Instance networking tab', async ({ page }) => {
'my-nic',
'a network interface',
'172.30.0.10',
'mock-vpc',
'mock-subnet',
'primary',
])

// check VPC link in table points to the right page
await expect(page.locator('role=cell >> role=link[name="mock-vpc"]')).toHaveAttribute(
'href',
'/orgs/maze-war/projects/mock-project/vpcs/mock-vpc'
)

// Have to stop instance to edit NICs
await stopInstance(page)

Expand Down Expand Up @@ -52,9 +60,11 @@ test('Instance networking tab', async ({ page }) => {
'my-nic',
'a network interface',
'172.30.0.10',
'mock-vpc',
'mock-subnet',
'',
])
await expectRowVisible(page, 'nic-2', ['', 'nic-2', null, null, 'primary'])
await expectRowVisible(page, 'nic-2', ['', 'nic-2', null, null, null, null, 'primary'])

// Make an edit to the network interface
await page
Expand Down
23 changes: 23 additions & 0 deletions app/pages/project/instances/instance/tabs/NetworkingTab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState } from 'react'
import { Link } from 'react-router-dom'

import type { NetworkInterface, NetworkInterfaceUpdate } from '@oxide/api'
import { useApiMutation, useApiQuery, useApiQueryClient } from '@oxide/api'
Expand All @@ -18,6 +19,26 @@ import CreateNetworkInterfaceSideModalForm from 'app/forms/network-interface-cre
import EditNetworkInterfaceSideModalForm from 'app/forms/network-interface-edit'
import { useParams, useToast } from 'app/hooks'

const VpcNameFromId = ({ value }: { value: string }) => {
const { orgName, projectName } = useParams('orgName', 'projectName')
const { data: vpc } = useApiQuery('vpcViewById', { id: value })
if (!vpc) return null
return (
<Link
className="text-sans-semi-md text-accent hover:underline"
to={`/orgs/${orgName}/projects/${projectName}/vpcs/${vpc.name}`}
>
{vpc.name}
</Link>
)
}

const SubnetNameFromId = ({ value }: { value: string }) => (
<span className="text-default">
{useApiQuery('vpcSubnetViewById', { id: value }).data?.name}
</span>
)

export function NetworkingTab() {
const instanceParams = useParams('orgName', 'projectName', 'instanceName')
const queryClient = useApiQueryClient()
Expand Down Expand Up @@ -98,6 +119,8 @@ export function NetworkingTab() {
<Column accessor="description" />
{/* TODO: mark v4 or v6 explicitly? */}
<Column accessor="ip" />
<Column header="vpc" accessor="vpcId" cell={VpcNameFromId} />
<Column header="subnet" accessor="subnetId" cell={SubnetNameFromId} />
<Column
accessor="primary"
cell={({ value }) =>
Expand Down
13 changes: 0 additions & 13 deletions libs/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import type * as ApiTypes from './__generated__/Api'
import { Api } from './__generated__/Api'
import { handleErrors } from './errors'
import type { ResultItem } from './hooks'
import { getUseApiMutation, getUseApiQuery, getUseApiQueryClient } from './hooks'

const api = new Api({
Expand All @@ -11,18 +10,6 @@ const api = new Api({

export type ApiMethods = typeof api.methods

/**
* API methods that return a list of items.
*/
export type ApiListMethods = {
// Only never extends never. If ResultItem extends never, that means we
// couldn't pull out an item, which means it's not a list endpoint. If we can
// infer an item, that means it's a list endpoint, so include its M.
[M in keyof ApiMethods as ResultItem<ApiMethods[M]> extends never
? never
: M]: ApiMethods[M]
}

export const useApiQuery = getUseApiQuery(api.methods, handleErrors)
export const useApiMutation = getUseApiMutation(api.methods, handleErrors)
export const useApiQueryClient = getUseApiQueryClient<ApiMethods>()
Expand Down
2 changes: 1 addition & 1 deletion libs/table/QueryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const makeQueryTable = <Item,>(
manualPagination: true,
})

if (debug) console.table(data)
if (debug) console.table((data as { items?: any[] })?.items || data)

const paginationParams = useMemo(
() => ({
Expand Down

1 comment on commit 6b13fd1

@vercel
Copy link

@vercel vercel bot commented on 6b13fd1 Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.