Skip to content

Commit a433d71

Browse files
charlieparkdavid-crespobenjaminleonard
authored
Networking tab enhancements (#2130)
* Change tab to networking * Move Add Network Interface button above table * Move to using useReactTable directly for Network Interfaces * Table and modal to attach / detach working * Add tests * refactor button * fix test * roll TableTitle into UI table file * change table title to text-sans-lg * tweak spacing * put external IPs on top * fix e2e tests * use non-hook version of addToast * simplify attach modal a bit * casing * extract FloatingIpLabel * use watch instead of getValue and ListboxField instead of setValue * fix mock floating IP update with empty description * leave off dash when there's no description * Table label tweaks * tweak data fetches, get rid of question marks * change disk name column header on storage tab to "disk" * move kind into its own column --------- Co-authored-by: David Crespo <[email protected]> Co-authored-by: Benjamin Leonard <[email protected]>
1 parent 83ace42 commit a433d71

File tree

13 files changed

+361
-87
lines changed

13 files changed

+361
-87
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
5+
*
6+
* Copyright Oxide Computer Company
7+
*/
8+
9+
import { useForm } from 'react-hook-form'
10+
11+
import { useApiMutation, useApiQueryClient, type FloatingIp, type Instance } from '~/api'
12+
import { ListboxField } from '~/components/form/fields/ListboxField'
13+
import { addToast } from '~/stores/toast'
14+
import { Message } from '~/ui/lib/Message'
15+
import { Modal } from '~/ui/lib/Modal'
16+
17+
function FloatingIpLabel({ fip }: { fip: FloatingIp }) {
18+
return (
19+
<div className="text-tertiary selected:text-accent-secondary">
20+
<div>{fip.name}</div>
21+
<div className="flex gap-0.5">
22+
<div>{fip.ip}</div>
23+
{fip.description && (
24+
<>
25+
<span className="mx-1 text-quinary selected:text-accent-disabled">/</span>
26+
<div className="flex-grow overflow-hidden overflow-ellipsis whitespace-pre text-left">
27+
{fip.description}
28+
</div>
29+
</>
30+
)}
31+
</div>
32+
</div>
33+
)
34+
}
35+
36+
export const AttachFloatingIpModal = ({
37+
floatingIps,
38+
instance,
39+
project,
40+
onDismiss,
41+
}: {
42+
floatingIps: Array<FloatingIp>
43+
instance: Instance
44+
project: string
45+
onDismiss: () => void
46+
}) => {
47+
const queryClient = useApiQueryClient()
48+
const floatingIpAttach = useApiMutation('floatingIpAttach', {
49+
onSuccess() {
50+
queryClient.invalidateQueries('floatingIpList')
51+
queryClient.invalidateQueries('instanceExternalIpList')
52+
addToast({ content: 'Your floating IP has been attached' })
53+
onDismiss()
54+
},
55+
onError: (err) => {
56+
addToast({ title: 'Error', content: err.message, variant: 'error' })
57+
},
58+
})
59+
const form = useForm({ defaultValues: { floatingIp: '' } })
60+
const floatingIp = form.watch('floatingIp')
61+
62+
return (
63+
<Modal isOpen title="Attach floating IP" onDismiss={onDismiss}>
64+
<Modal.Body>
65+
<Modal.Section>
66+
<Message
67+
variant="info"
68+
content={`Instance ‘${instance.name}’ will be reachable at the selected IP address`}
69+
/>
70+
<form>
71+
<ListboxField
72+
control={form.control}
73+
name="floatingIp"
74+
label="Floating IP"
75+
placeholder="Select floating IP"
76+
items={floatingIps.map((ip) => ({
77+
value: ip.id,
78+
label: <FloatingIpLabel fip={ip} />,
79+
labelString: ip.name,
80+
}))}
81+
required
82+
/>
83+
</form>
84+
</Modal.Section>
85+
</Modal.Body>
86+
<Modal.Footer
87+
actionText="Attach"
88+
disabled={!floatingIp}
89+
onAction={() =>
90+
floatingIpAttach.mutate({
91+
path: { floatingIp },
92+
query: { project },
93+
body: { kind: 'instance', parent: instance.id },
94+
})
95+
}
96+
onDismiss={onDismiss}
97+
></Modal.Footer>
98+
</Modal>
99+
)
100+
}

app/pages/project/floating-ips/FloatingIpsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ const AttachFloatingIpModal = ({
238238
const form = useForm({ defaultValues: { instanceId: '' } })
239239

240240
return (
241-
<Modal isOpen title="Attach Floating IP" onDismiss={onDismiss}>
241+
<Modal isOpen title="Attach floating IP" onDismiss={onDismiss}>
242242
<Modal.Body>
243243
<Modal.Section>
244244
<Message

app/pages/project/instances/instance/InstancePage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ export function InstancePage() {
192192
<RouteTabs fullWidth>
193193
<Tab to={pb.instanceStorage(instanceSelector)}>Storage</Tab>
194194
<Tab to={pb.instanceMetrics(instanceSelector)}>Metrics</Tab>
195-
<Tab to={pb.nics(instanceSelector)}>Network Interfaces</Tab>
195+
<Tab to={pb.nics(instanceSelector)}>Networking</Tab>
196196
<Tab to={pb.instanceConnect(instanceSelector)}>Connect</Tab>
197197
</RouteTabs>
198198
</>

0 commit comments

Comments
 (0)