diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index 514401bc25..5bed62c366 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -59,6 +59,7 @@ export function VpcPage() { Firewall Rules Subnets + Routers ) diff --git a/app/pages/project/vpcs/VpcPage/tabs/VpcRoutersTab.tsx b/app/pages/project/vpcs/VpcPage/tabs/VpcRoutersTab.tsx new file mode 100644 index 0000000000..479290d95a --- /dev/null +++ b/app/pages/project/vpcs/VpcPage/tabs/VpcRoutersTab.tsx @@ -0,0 +1,54 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * Copyright Oxide Computer Company + */ +import { createColumnHelper } from '@tanstack/react-table' +import type { LoaderFunctionArgs } from 'react-router-dom' + +import { type VpcRouter } from '~/api' +import { apiQueryClient } from '~/api/client' +import { getVpcSelector, useVpcSelector } from '~/hooks/use-params' +import { Columns } from '~/table/columns/common' +import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' +import { Badge } from '~/ui/lib/Badge' +import { EmptyMessage } from '~/ui/lib/EmptyMessage' + +// import { pb } from '~/util/path-builder' + +VpcRoutersTab.loader = async ({ params }: LoaderFunctionArgs) => { + const { project, vpc } = getVpcSelector(params) + await apiQueryClient.prefetchQuery('vpcRouterList', { + query: { project, vpc, limit: PAGE_SIZE }, + }) + return null +} + +const colHelper = createColumnHelper() + +const columns = [ + colHelper.accessor('name', {}), + colHelper.accessor('kind', { + cell: (info) => {info.getValue()}, + }), + colHelper.accessor('description', Columns.description), + colHelper.accessor('timeCreated', Columns.timeCreated), +] + +export function VpcRoutersTab() { + const vpcSelector = useVpcSelector() + const { Table } = useQueryTable('vpcRouterList', { query: vpcSelector }) + + const emptyState = ( + + ) + + return +} diff --git a/app/routes.tsx b/app/routes.tsx index 6cdbd3c64f..a864f56fa9 100644 --- a/app/routes.tsx +++ b/app/routes.tsx @@ -63,6 +63,7 @@ import { StorageTab } from './pages/project/instances/instance/tabs/StorageTab' import { InstancesPage } from './pages/project/instances/InstancesPage' import { SnapshotsPage } from './pages/project/snapshots/SnapshotsPage' import { VpcFirewallRulesTab } from './pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab' +import { VpcRoutersTab } from './pages/project/vpcs/VpcPage/tabs/VpcRoutersTab' import { VpcSubnetsTab } from './pages/project/vpcs/VpcPage/tabs/VpcSubnetsTab' import { VpcPage } from './pages/project/vpcs/VpcPage/VpcPage' import { VpcsPage } from './pages/project/vpcs/VpcsPage' @@ -390,6 +391,9 @@ export const routes = createRoutesFromElements( handle={{ crumb: 'Edit Subnet' }} /> + } loader={VpcRoutersTab.loader}> + + diff --git a/app/util/path-builder.spec.ts b/app/util/path-builder.spec.ts index eb42d38935..6a37c8d060 100644 --- a/app/util/path-builder.spec.ts +++ b/app/util/path-builder.spec.ts @@ -91,6 +91,7 @@ test('path builder', () => { "vpcFirewallRuleEdit": "/projects/p/vpcs/v/firewall-rules/fr/edit", "vpcFirewallRules": "/projects/p/vpcs/v/firewall-rules", "vpcFirewallRulesNew": "/projects/p/vpcs/v/firewall-rules-new", + "vpcRouters": "/projects/p/vpcs/v/routers", "vpcSubnets": "/projects/p/vpcs/v/subnets", "vpcSubnetsEdit": "/projects/p/vpcs/v/subnets/su/edit", "vpcSubnetsNew": "/projects/p/vpcs/v/subnets-new", diff --git a/app/util/path-builder.ts b/app/util/path-builder.ts index 12e172018c..fcffd30253 100644 --- a/app/util/path-builder.ts +++ b/app/util/path-builder.ts @@ -83,6 +83,7 @@ export const pb = { vpcFirewallRuleEdit: (params: FirewallRule) => `${pb.vpcFirewallRules(params)}/${params.rule}/edit`, vpcSubnets: (params: Vpc) => `${vpcBase(params)}/subnets`, + vpcRouters: (params: Vpc) => `${vpcBase(params)}/routers`, vpcSubnetsNew: (params: Vpc) => `${vpcBase(params)}/subnets-new`, vpcSubnetsEdit: (params: VpcSubnet) => `${pb.vpcSubnets(params)}/${params.subnet}/edit`, diff --git a/mock-api/msw/db.ts b/mock-api/msw/db.ts index fa8d5b6c42..e0cc633ac3 100644 --- a/mock-api/msw/db.ts +++ b/mock-api/msw/db.ts @@ -327,6 +327,7 @@ const initDb = { users: [...mock.users], vpcFirewallRules: [...mock.firewallRules], vpcs: [...mock.vpcs], + vpcRouters: [...mock.vpcRouters], vpcSubnets: [mock.vpcSubnet], } diff --git a/mock-api/msw/handlers.ts b/mock-api/msw/handlers.ts index d88e250ad6..61df58218c 100644 --- a/mock-api/msw/handlers.ts +++ b/mock-api/msw/handlers.ts @@ -1301,6 +1301,15 @@ export const handlers = makeHandlers({ }, siloMetric: handleMetrics, + vpcRouterList({ query }) { + const vpc = lookup.vpc(query) + const routers = db.vpcRouters.filter((r) => r.vpc_id === vpc.id) + return paginated(query, routers) + }, + vpcRouterRouteList() { + return { items: [] } + }, + // Misc endpoints we're not using yet in the console certificateCreate: NotImplemented, certificateDelete: NotImplemented, @@ -1373,10 +1382,8 @@ export const handlers = makeHandlers({ userBuiltinView: NotImplemented, vpcRouterCreate: NotImplemented, vpcRouterDelete: NotImplemented, - vpcRouterList: NotImplemented, vpcRouterRouteCreate: NotImplemented, vpcRouterRouteDelete: NotImplemented, - vpcRouterRouteList: NotImplemented, vpcRouterRouteUpdate: NotImplemented, vpcRouterRouteView: NotImplemented, vpcRouterUpdate: NotImplemented, diff --git a/mock-api/vpc.ts b/mock-api/vpc.ts index 4d180daa97..3ee2b97a54 100644 --- a/mock-api/vpc.ts +++ b/mock-api/vpc.ts @@ -6,7 +6,7 @@ * Copyright Oxide Computer Company */ -import type { Vpc, VpcFirewallRule, VpcSubnet } from '@oxide/api' +import type { Vpc, VpcFirewallRule, VpcRouter, VpcSubnet } from '@oxide/api' import type { Json } from './json-type' import { project, project2 } from './project' @@ -174,3 +174,15 @@ export const firewallRules: Json = [ vpc_id: vpc2.id, }, ] + +export const vpcRouters: Json = [ + { + id: '9715d7cf-0e29-4c66-92dc-642961f9a3cb', + name: 'default', + kind: 'system', + description: '', + time_created, + time_modified, + vpc_id: vpc.id, + }, +]