Skip to content

Commit d7712f1

Browse files
authored
Add copy-to-clipboard to External IPs table on networking tab (#2313)
* Add IpLink component, use on Instance page * better import syntax * Move location of file * refactor, remove unneeded lines * Make configurable so link is optional
1 parent 81bd2ab commit d7712f1

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

app/components/ExternalIps.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { useApiQuery } from '@oxide/api'
1010

1111
import { EmptyCell, SkeletonCell } from '~/table/cells/EmptyCell'
12-
import { CopyToClipboard } from '~/ui/lib/CopyToClipboard'
12+
import { CopyableIp } from '~/ui/lib/CopyableIp'
1313
import { intersperse } from '~/util/array'
1414

1515
type InstanceSelector = { project: string; instance: string }
@@ -26,19 +26,7 @@ export function ExternalIps({ project, instance }: InstanceSelector) {
2626
return (
2727
<div className="flex items-center gap-1">
2828
{intersperse(
29-
ips.map((eip) => (
30-
<span className="flex items-center gap-1" key={eip.ip}>
31-
<a
32-
className="link-with-underline text-sans-semi-md"
33-
href={`https://${eip.ip}`}
34-
target="_blank"
35-
rel="noreferrer"
36-
>
37-
{eip.ip}
38-
</a>
39-
<CopyToClipboard text={eip.ip} />
40-
</span>
41-
)),
29+
ips.map((eip) => <CopyableIp ip={eip.ip} key={eip.ip} />),
4230
<span className="text-quinary"> / </span>
4331
)}
4432
</div>

app/pages/project/instances/instance/tabs/NetworkingTab.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
3636
import { Columns, DescriptionCell } from '~/table/columns/common'
3737
import { Table } from '~/table/Table'
3838
import { Badge } from '~/ui/lib/Badge'
39+
import { CopyableIp } from '~/ui/lib/CopyableIp'
3940
import { CreateButton } from '~/ui/lib/CreateButton'
4041
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
4142
import { TableControls, TableEmptyBox, TableTitle } from '~/ui/lib/Table'
@@ -115,7 +116,10 @@ const staticCols = [
115116
),
116117
}),
117118
colHelper.accessor('description', Columns.description),
118-
colHelper.accessor('ip', { header: 'Private IP' }),
119+
colHelper.accessor('ip', {
120+
header: 'Private IP',
121+
cell: (info) => <CopyableIp ip={info.getValue()} isLinked={false} />,
122+
}),
119123
colHelper.accessor('vpcId', {
120124
header: 'vpc',
121125
cell: (info) => <VpcNameFromId value={info.getValue()} />,
@@ -240,7 +244,9 @@ export function NetworkingTab() {
240244

241245
const ipColHelper = createColumnHelper<ExternalIp>()
242246
const staticIpCols = [
243-
ipColHelper.accessor('ip', {}),
247+
ipColHelper.accessor('ip', {
248+
cell: (info) => <CopyableIp ip={info.getValue()} />,
249+
}),
244250
ipColHelper.accessor('kind', {
245251
header: () => (
246252
<>

app/ui/lib/CopyableIp.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
import { CopyToClipboard } from '~/ui/lib/CopyToClipboard'
9+
10+
export const CopyableIp = ({ ip, isLinked = true }: { ip: string; isLinked?: boolean }) => (
11+
<span className="flex items-center gap-1">
12+
{isLinked ? (
13+
<a
14+
className="link-with-underline text-sans-semi-md"
15+
href={`https://${ip}`}
16+
target="_blank"
17+
rel="noreferrer"
18+
>
19+
{ip}
20+
</a>
21+
) : (
22+
ip
23+
)}
24+
<CopyToClipboard text={ip} />
25+
</span>
26+
)

0 commit comments

Comments
 (0)