Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions app/pages/project/floating-ips/FloatingIpsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { Link, Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom'
import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom'

import {
apiQueryClient,
Expand All @@ -19,6 +19,7 @@ import {
} from '@oxide/api'
import { IpGlobal24Icon, Networking24Icon } from '@oxide/design-system/icons/react'

import { ExternalLink } from '~/components/ExternalLink'
import { HL } from '~/components/HL'
import { getProjectSelector, useProjectSelector } from '~/hooks'
import { confirmAction } from '~/stores/confirm-action'
Expand All @@ -27,13 +28,13 @@ import { addToast } from '~/stores/toast'
import { InstanceLinkCell } from '~/table/cells/InstanceLinkCell'
import type { MenuAction } from '~/table/columns/action-col'
import { useQueryTable } from '~/table/QueryTable'
import { buttonStyle } from '~/ui/lib/Button'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { Listbox } from '~/ui/lib/Listbox'
import { Message } from '~/ui/lib/Message'
import { Modal } from '~/ui/lib/Modal'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
import { TableActions } from '~/ui/lib/Table'
import { TableControls, TableControlsLink, TableControlsText } from '~/ui/lib/Table'
import { links } from '~/util/links'
import { pb } from '~/util/path-builder'

const EmptyState = () => (
Expand Down Expand Up @@ -161,11 +162,16 @@ export function FloatingIpsPage() {
<PageHeader>
<PageTitle icon={<IpGlobal24Icon />}>Floating IPs</PageTitle>
</PageHeader>
<TableActions>
<Link to={pb.floatingIpsNew({ project })} className={buttonStyle({ size: 'sm' })}>
<TableControls>
<TableControlsText>
Floating IPs are public IP addresses that can be attached to instances. They allow
your instances to be reachable from the internet. Find out more about{' '}
<ExternalLink href={links.floatingIpsDocs}>managing floating IPs</ExternalLink>.
</TableControlsText>
<TableControlsLink to={pb.floatingIpsNew({ project })}>
New Floating IP
</Link>
</TableActions>
</TableControlsLink>
</TableControls>
<Table emptyState={<EmptyState />} makeActions={makeActions}>
<Column accessor="name" />
<Column accessor="description" />
Expand Down
15 changes: 8 additions & 7 deletions app/pages/system/networking/IpPoolPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ import { LinkCell } from '~/table/cells/LinkCell'
import type { MenuAction } from '~/table/columns/action-col'
import { useQueryTable } from '~/table/QueryTable'
import { Badge } from '~/ui/lib/Badge'
import { Button, buttonStyle } from '~/ui/lib/Button'
import { buttonStyle } from '~/ui/lib/Button'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { Message } from '~/ui/lib/Message'
import { Modal } from '~/ui/lib/Modal'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
import { TableControls, TableControlsButton, TableControlsText } from '~/ui/lib/Table'
import { Tabs } from '~/ui/lib/Tabs'
import { links } from '~/util/links'
import { pb } from '~/util/path-builder'
Expand Down Expand Up @@ -216,18 +217,18 @@ function LinkedSilosTable() {

return (
<>
<div className="mb-4 flex items-end justify-between space-x-2">
<p className="mr-8 max-w-2xl text-sans-md text-secondary">
<TableControls>
<TableControlsText>
Users in linked silos can allocate external IPs from this pool for their
instances. A silo can have at most one default pool. IPs are allocated from the
default pool when users ask for one without specifying a pool. Read the docs to
learn more about{' '}
<ExternalLink href={links.ipPoolsDocs}>managing IP pools</ExternalLink>.
</p>
<Button onClick={() => setShowLinkModal(true)} size="sm" className="shrink-0">
</TableControlsText>
<TableControlsButton onClick={() => setShowLinkModal(true)}>
Link silo
</Button>
</div>
</TableControlsButton>
</TableControls>
<Table emptyState={emptyState} makeActions={makeActions}>
<Column accessor="siloId" id="Silo" cell={SiloNameFromId} />
<Column
Expand Down
14 changes: 7 additions & 7 deletions app/pages/system/silos/SiloIpPoolsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import { linkCell } from '~/table/cells/LinkCell'
import type { MenuAction } from '~/table/columns/action-col'
import { useQueryTable } from '~/table/QueryTable'
import { Badge } from '~/ui/lib/Badge'
import { Button } from '~/ui/lib/Button'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { Message } from '~/ui/lib/Message'
import { Modal } from '~/ui/lib/Modal'
import { TableControls, TableControlsButton, TableControlsText } from '~/ui/lib/Table'
import { links } from '~/util/links'
import { pb } from '~/util/path-builder'

Expand Down Expand Up @@ -144,17 +144,17 @@ export function SiloIpPoolsTab() {

return (
<>
<div className="mb-8 flex items-end justify-between space-x-2">
<p className="mr-8 max-w-2xl text-sans-md text-secondary">
<TableControls>
<TableControlsText>
Users in this silo can allocate external IPs from these pools for their instances.
A silo can have at most one default pool. IPs are allocated from the default pool
when users ask for one without specifying a pool. Read the docs to learn more
about <ExternalLink href={links.ipPoolsDocs}>managing IP pools</ExternalLink>.
</p>
<Button onClick={() => setShowLinkModal(true)} size="sm" className="shrink-0">
</TableControlsText>
<TableControlsButton onClick={() => setShowLinkModal(true)}>
Link pool
</Button>
</div>
</TableControlsButton>
</TableControls>
<Table emptyState={<EmptyState />} makeActions={makeActions}>
<Column accessor="name" cell={linkCell((pool) => pb.ipPool({ pool }))} />
<Column accessor="description" />
Expand Down
2 changes: 1 addition & 1 deletion app/ui/lib/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const buttonStyle = ({
variant = 'primary',
}: ButtonStyleProps = {}) => {
return cn(
'ox-button elevation-1 rounded inline-flex items-center justify-center align-top disabled:cursor-not-allowed',
'ox-button elevation-1 rounded inline-flex items-center justify-center align-top disabled:cursor-not-allowed shrink-0',
`btn-${variant}`,
sizeStyle[size],
variant === 'danger'
Expand Down
16 changes: 16 additions & 0 deletions app/ui/lib/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
*/
import cn from 'classnames'
import React, { useRef, type ReactElement } from 'react'
import { Link, type LinkProps } from 'react-router-dom'
import SimpleBar from 'simplebar-react'

import { useIsOverflow } from '~/hooks'
import { Button, buttonStyle, type ButtonProps } from '~/ui/lib/Button'
import { classed } from '~/util/classed'

export type TableProps = JSX.IntrinsicElements['table']
Expand Down Expand Up @@ -124,3 +126,17 @@ Table.Cell = ({ height = 'large', className, children, ...props }: TableCellProp
export const TableActions = classed.div`-mt-11 mb-3 flex justify-end space-x-2`

export const TableEmptyBox = classed.div`flex h-full max-h-[480px] items-center justify-center rounded-lg border border-secondary p-4`

/**
* Used _outside_ of the `Table`, this element includes a soon-to-be-removed description of the resource inside the table,
* along with a link to more info, and a button to take action on the resource listed in the table.
*/
export const TableControls = classed.div`mb-4 flex items-end justify-between space-x-8`
export const TableControlsText = classed.p`max-w-2xl text-sans-md text-secondary`

export const TableControlsButton = (props: ButtonProps) => (
<Button size="sm" className="shrink-0" {...props} />
)
export const TableControlsLink = (props: LinkProps) => (
<Link className={buttonStyle({ size: 'sm' })} {...props} />
)
1 change: 1 addition & 0 deletions app/util/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
export const links: Record<string, string> = {
cloudInitFormat: 'https://cloudinit.readthedocs.io/en/latest/explanation/format.html',
cloudInitExamples: 'https://cloudinit.readthedocs.io/en/latest/reference/examples.html',
floatingIpsDocs: 'https://docs.oxide.computer/guides/managing-floating-ips',
ipPoolsDocs: 'https://docs.oxide.computer/guides/operator/ip-pool-management',
}