diff --git a/app/components/MoreActionsMenu.tsx b/app/components/MoreActionsMenu.tsx index 67a6955dd0..9c7ed5a06f 100644 --- a/app/components/MoreActionsMenu.tsx +++ b/app/components/MoreActionsMenu.tsx @@ -29,13 +29,19 @@ export const MoreActionsMenu = ({ actions, label }: MoreActionsMenuProps) => { {actions.map((a) => ( }> - - {a.label} - + {typeof a.onActivate === 'string' ? ( + + {a.label} + + ) : ( + + {a.label} + + )} ))} diff --git a/app/components/TopBarPicker.tsx b/app/components/TopBarPicker.tsx index 48ecfa4073..a6470c0e8d 100644 --- a/app/components/TopBarPicker.tsx +++ b/app/components/TopBarPicker.tsx @@ -115,14 +115,17 @@ const TopBarPicker = (props: TopBarPickerProps) => { props.items.map(({ label, to }) => { const isSelected = props.current === label return ( - - - - {label} - {isSelected && } - - - + + + {label} + {isSelected && } + + ) }) ) : ( diff --git a/app/pages/project/instances/actions.tsx b/app/pages/project/instances/actions.tsx index f0c91316fd..25a73d36b4 100644 --- a/app/pages/project/instances/actions.tsx +++ b/app/pages/project/instances/actions.tsx @@ -6,7 +6,6 @@ * Copyright Oxide Computer Company */ import { useCallback } from 'react' -import { useNavigate } from 'react-router-dom' import { instanceCan, useApiMutation, type Instance } from '@oxide/api' @@ -32,8 +31,6 @@ export const useMakeInstanceActions = ( projectSelector: { project: string }, options: Options = {} ): MakeActions => { - const navigate = useNavigate() - // if you also pass onSuccess to mutate(), this one is not overridden — this // one runs first, then the one passed to mutate() const opts = { onSuccess: options.onSuccess } @@ -109,9 +106,7 @@ export const useMakeInstanceActions = ( }, { label: 'View serial console', - onActivate() { - navigate(pb.serialConsole(instanceSelector)) - }, + onActivate: pb.serialConsole(instanceSelector), }, { label: 'Delete', @@ -132,6 +127,6 @@ export const useMakeInstanceActions = ( }, ] }, - [projectSelector, deleteInstance, navigate, rebootInstance, startInstance, stopInstance] + [projectSelector, deleteInstance, rebootInstance, startInstance, stopInstance] ) } diff --git a/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx b/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx index e4fab8bc61..ca4f18d6e4 100644 --- a/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx +++ b/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper, getCoreRowModel, useReactTable } from '@tanstack/react-table' import { useMemo } from 'react' -import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, type LoaderFunctionArgs } from 'react-router-dom' import * as R from 'remeda' import { @@ -112,8 +112,6 @@ export function VpcFirewallRulesTab() { }) const rules = useMemo(() => R.sortBy(data.rules, (r) => r.priority), [data]) - const navigate = useNavigate() - const updateRules = useApiMutation('vpcFirewallRulesUpdate', { onSuccess() { queryClient.invalidateQueries('vpcFirewallRulesView') @@ -135,15 +133,11 @@ export function VpcFirewallRulesTab() { getActionsCol((rule: VpcFirewallRule) => [ { label: 'Edit', - onActivate() { - navigate(pb.vpcFirewallRuleEdit({ ...vpcSelector, rule: rule.name })) - }, + onActivate: pb.vpcFirewallRuleEdit({ ...vpcSelector, rule: rule.name }), }, { label: 'Clone', - onActivate() { - navigate(pb.vpcFirewallRuleClone({ ...vpcSelector, rule: rule.name })) - }, + onActivate: pb.vpcFirewallRuleClone({ ...vpcSelector, rule: rule.name }), }, { label: 'Delete', @@ -160,7 +154,7 @@ export function VpcFirewallRulesTab() { }, ]), ] - }, [navigate, rules, updateRules, vpcSelector]) + }, [rules, updateRules, vpcSelector]) const table = useReactTable({ columns, data: rules, getCoreRowModel: getCoreRowModel() }) diff --git a/app/pages/project/vpcs/VpcPage/tabs/VpcSubnetsTab.tsx b/app/pages/project/vpcs/VpcPage/tabs/VpcSubnetsTab.tsx index 8c0a56dd51..ae2010f60f 100644 --- a/app/pages/project/vpcs/VpcPage/tabs/VpcSubnetsTab.tsx +++ b/app/pages/project/vpcs/VpcPage/tabs/VpcSubnetsTab.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' -import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, @@ -49,14 +49,11 @@ export function VpcSubnetsTab() { }, }) - const navigate = useNavigate() - const makeActions = useCallback( (subnet: VpcSubnet): MenuAction[] => [ { label: 'Edit', - onActivate: () => - navigate(pb.vpcSubnetsEdit({ ...vpcSelector, subnet: subnet.name })), + onActivate: pb.vpcSubnetsEdit({ ...vpcSelector, subnet: subnet.name }), }, // TODO: only show if you have permission to do this { @@ -67,7 +64,7 @@ export function VpcSubnetsTab() { }), }, ], - [navigate, deleteSubnet, vpcSelector] + [deleteSubnet, vpcSelector] ) const columns = useMemo( diff --git a/app/table/columns/action-col.tsx b/app/table/columns/action-col.tsx index a130f15fdf..9b81f390ec 100644 --- a/app/table/columns/action-col.tsx +++ b/app/table/columns/action-col.tsx @@ -20,7 +20,8 @@ export type MakeActions = (item: Item) => Array export type MenuAction = { label: string - onActivate: () => void + /** If it's a string, it's a URL and we should make it a LinkItem */ + onActivate: string | (() => void) disabled?: false | React.ReactNode className?: string } @@ -81,16 +82,28 @@ export const getActionsCol = >( with={} key={kebabCase(`action-${action.label}`)} > - - {action.label} - + {typeof action.onActivate === 'string' ? ( + + {action.label} + + ) : ( + + {action.label} + + )} ) })}