From 169e8cc530f06af5ce03199bc440f4fd3904b3fe Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 15 Mar 2024 10:43:53 -0700 Subject: [PATCH 1/9] Add TableResourceDescription --- app/components/TableResourceInformation.tsx | 11 +++++++++++ app/pages/project/floating-ips/FloatingIpsPage.tsx | 13 ++++++++++--- app/pages/system/networking/IpPoolPage.tsx | 5 +++-- app/pages/system/silos/SiloIpPoolsTab.tsx | 5 +++-- app/util/links.ts | 1 + 5 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 app/components/TableResourceInformation.tsx diff --git a/app/components/TableResourceInformation.tsx b/app/components/TableResourceInformation.tsx new file mode 100644 index 0000000000..70137dfd52 --- /dev/null +++ b/app/components/TableResourceInformation.tsx @@ -0,0 +1,11 @@ +/* + * 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 { classed } from '~/util/classed' + +// Used as a description of the resource detailed in the table. A bit different than a proper "table summary" as it's more about the resource than the table itself. +export const TableResourceInformation = classed.p`mr-8 max-w-2xl text-sans-md text-secondary` diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index c44efe44dc..782c2f1597 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -19,7 +19,9 @@ import { } from '@oxide/api' import { IpGlobal24Icon, Networking24Icon } from '@oxide/design-system/icons/react' +import { ExternalLink } from '~/components/ExternalLink' import { HL } from '~/components/HL' +import { TableResourceInformation } from '~/components/TableResourceInformation' import { getProjectSelector, useProjectSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { confirmDelete } from '~/stores/confirm-delete' @@ -33,7 +35,7 @@ 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 { links } from '~/util/links' import { pb } from '~/util/path-builder' const EmptyState = () => ( @@ -161,11 +163,16 @@ export function FloatingIpsPage() { }>Floating IPs - +
+ + 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{' '} + managing floating IPs. + New Floating IP - +
} makeActions={makeActions}> diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx index b64b777dcd..e619277451 100644 --- a/app/pages/system/networking/IpPoolPage.tsx +++ b/app/pages/system/networking/IpPoolPage.tsx @@ -24,6 +24,7 @@ import { ExternalLink } from '~/components/ExternalLink' import { ListboxField } from '~/components/form/fields/ListboxField' import { HL } from '~/components/HL' import { QueryParamTabs } from '~/components/QueryParamTabs' +import { TableResourceInformation } from '~/components/TableResourceInformation' import { getIpPoolSelector, useForm, useIpPoolSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { addToast } from '~/stores/toast' @@ -217,13 +218,13 @@ function LinkedSilosTable() { return ( <>
-

+ 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{' '} managing IP pools. -

+ diff --git a/app/pages/system/silos/SiloIpPoolsTab.tsx b/app/pages/system/silos/SiloIpPoolsTab.tsx index 8e703e4f5a..d2ae6caeb7 100644 --- a/app/pages/system/silos/SiloIpPoolsTab.tsx +++ b/app/pages/system/silos/SiloIpPoolsTab.tsx @@ -14,6 +14,7 @@ import { Networking24Icon, Success12Icon } from '@oxide/design-system/icons/reac import { ExternalLink } from '~/components/ExternalLink' import { ListboxField } from '~/components/form/fields/ListboxField' import { HL } from '~/components/HL' +import { TableResourceInformation } from '~/components/TableResourceInformation' import { useForm, useSiloSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { addToast } from '~/stores/toast' @@ -145,12 +146,12 @@ export function SiloIpPoolsTab() { return ( <>
-

+ 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 managing IP pools. -

+ diff --git a/app/util/links.ts b/app/util/links.ts index 4418c90a62..a729ba8977 100644 --- a/app/util/links.ts +++ b/app/util/links.ts @@ -8,5 +8,6 @@ export const links: Record = { 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', } From 79687315da403b6f5d62cea5d3d858476cf68b90 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 15 Mar 2024 15:34:58 -0700 Subject: [PATCH 2/9] Refactor --- app/components/TableResourceInformation.tsx | 11 ------ .../project/floating-ips/FloatingIpsPage.tsx | 27 ++++++------- app/pages/system/networking/IpPoolPage.tsx | 29 +++++++------- app/pages/system/silos/SiloIpPoolsTab.tsx | 27 ++++++------- app/ui/lib/Table.tsx | 39 +++++++++++++++++++ 5 files changed, 82 insertions(+), 51 deletions(-) delete mode 100644 app/components/TableResourceInformation.tsx diff --git a/app/components/TableResourceInformation.tsx b/app/components/TableResourceInformation.tsx deleted file mode 100644 index 70137dfd52..0000000000 --- a/app/components/TableResourceInformation.tsx +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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 { classed } from '~/util/classed' - -// Used as a description of the resource detailed in the table. A bit different than a proper "table summary" as it's more about the resource than the table itself. -export const TableResourceInformation = classed.p`mr-8 max-w-2xl text-sans-md text-secondary` diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index 782c2f1597..abfa28da32 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -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, @@ -21,7 +21,6 @@ import { IpGlobal24Icon, Networking24Icon } from '@oxide/design-system/icons/rea import { ExternalLink } from '~/components/ExternalLink' import { HL } from '~/components/HL' -import { TableResourceInformation } from '~/components/TableResourceInformation' import { getProjectSelector, useProjectSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { confirmDelete } from '~/stores/confirm-delete' @@ -29,12 +28,12 @@ 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 { TableInformationAndAction } from '~/ui/lib/Table' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -158,21 +157,23 @@ export function FloatingIpsPage() { } const { Table, Column } = useQueryTable('floatingIpList', { query: { project } }) + const resourceInformation = ( + <> + 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{' '} + managing floating IPs. + + ) return ( <> }>Floating IPs -
- - 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{' '} - managing floating IPs. - - - New Floating IP - -
+
} makeActions={makeActions}> diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx index e619277451..a081c81429 100644 --- a/app/pages/system/networking/IpPoolPage.tsx +++ b/app/pages/system/networking/IpPoolPage.tsx @@ -24,7 +24,6 @@ import { ExternalLink } from '~/components/ExternalLink' import { ListboxField } from '~/components/form/fields/ListboxField' import { HL } from '~/components/HL' import { QueryParamTabs } from '~/components/QueryParamTabs' -import { TableResourceInformation } from '~/components/TableResourceInformation' import { getIpPoolSelector, useForm, useIpPoolSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { addToast } from '~/stores/toast' @@ -34,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 { TableInformationAndAction } from '~/ui/lib/Table' import { Tabs } from '~/ui/lib/Tabs' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -215,20 +215,21 @@ function LinkedSilosTable() { /> ) + const resourceInformation = ( + <> + 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{' '} + managing IP pools. + + ) return ( <> -
- - 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{' '} - managing IP pools. - - -
+ setShowLinkModal(true)} + />
+ 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{' '} + managing IP pools. + + ) return ( <> -
- - 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 managing IP pools. - - -
+ setShowLinkModal(true)} + />
} makeActions={makeActions}> pb.ipPool({ pool }))} /> diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index 4f3014943d..8e27dadeb5 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -7,11 +7,14 @@ */ import cn from 'classnames' import React, { useRef, type ReactElement } from 'react' +import { Link } from 'react-router-dom' import SimpleBar from 'simplebar-react' import { useIsOverflow } from '~/hooks' import { classed } from '~/util/classed' +import { Button, buttonStyle } from './Button' + export type TableProps = JSX.IntrinsicElements['table'] export function Table({ className, ...props }: TableProps) { const overflowRef = useRef(null) @@ -123,4 +126,40 @@ Table.Cell = ({ height = 'large', className, children, ...props }: TableCellProp */ export const TableActions = classed.div`-mt-11 mb-3 flex justify-end space-x-2` +type TableInformationAndActionProps = { + resourceInformation: React.ReactNode + actionLabel?: string +} & ( + | { + linkTo?: never + onClick?: () => void + } + | { + linkTo?: string + onClick?: () => never + } +) +export const TableInformationAndAction = ({ + resourceInformation, + actionLabel, + linkTo, + onClick, +}: TableInformationAndActionProps) => { + const action = linkTo ? ( + + {actionLabel} + + ) : ( + + ) + return ( +
+

{resourceInformation}

+ {action} +
+ ) +} + export const TableEmptyBox = classed.div`flex h-full max-h-[480px] items-center justify-center rounded-lg border border-secondary p-4` From cc91a8abea45606a61946a6b8137585c9aab301b Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 15 Mar 2024 15:49:50 -0700 Subject: [PATCH 3/9] Fix collapsing flexbox button --- app/ui/lib/Button.tsx | 2 +- app/ui/lib/Table.tsx | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/ui/lib/Button.tsx b/app/ui/lib/Button.tsx index 6c7c627e4c..ae972219b0 100644 --- a/app/ui/lib/Button.tsx +++ b/app/ui/lib/Button.tsx @@ -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' diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index 8e27dadeb5..b44d1742b6 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -139,6 +139,11 @@ type TableInformationAndActionProps = { onClick?: () => never } ) + +/** + * Used _outside_ of the `Table`, this element displays information about the + * resource listed in the table (possibly inlcuding a docs link), and an action button. + */ export const TableInformationAndAction = ({ resourceInformation, actionLabel, @@ -155,8 +160,8 @@ export const TableInformationAndAction = ({ ) return ( -
-

{resourceInformation}

+
+

{resourceInformation}

{action}
) From 2fcb04c0ba321118ba8c3698bd1871379c83cbc8 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 15 Mar 2024 15:54:57 -0700 Subject: [PATCH 4/9] tighten vertical spacing to header --- app/ui/lib/Table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index b44d1742b6..ac85f80f36 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -160,7 +160,7 @@ export const TableInformationAndAction = ({ ) return ( -
+

{resourceInformation}

{action}
From 3b4aef0b0d3ae8fd657e3769fa4275808a9d0093 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 15 Mar 2024 16:48:34 -0700 Subject: [PATCH 5/9] Use Actions in case we need to submit multiple buttons for some reason --- .../project/floating-ips/FloatingIpsPage.tsx | 13 +++-- app/pages/system/networking/IpPoolPage.tsx | 10 ++-- app/pages/system/silos/SiloIpPoolsTab.tsx | 10 ++-- app/ui/lib/Table.tsx | 47 +++++-------------- app/ui/lib/TableActionButton.tsx | 29 ++++++++++++ 5 files changed, 61 insertions(+), 48 deletions(-) create mode 100644 app/ui/lib/TableActionButton.tsx diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index abfa28da32..ee31a29135 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -33,7 +33,8 @@ 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 { TableInformationAndAction } from '~/ui/lib/Table' +import { TableInformationAndActions } from '~/ui/lib/Table' +import { TableActionButton } from '~/ui/lib/TableActionButton' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -169,10 +170,14 @@ export function FloatingIpsPage() { }>Floating IPs - + } />
} makeActions={makeActions}> diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx index a081c81429..9658d17bdd 100644 --- a/app/pages/system/networking/IpPoolPage.tsx +++ b/app/pages/system/networking/IpPoolPage.tsx @@ -38,7 +38,8 @@ 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 { TableInformationAndAction } from '~/ui/lib/Table' +import { TableInformationAndActions } from '~/ui/lib/Table' +import { TableActionButton } from '~/ui/lib/TableActionButton' import { Tabs } from '~/ui/lib/Tabs' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -225,10 +226,11 @@ function LinkedSilosTable() { ) return ( <> - setShowLinkModal(true)} + actions={ + setShowLinkModal(true)} /> + } />
diff --git a/app/pages/system/silos/SiloIpPoolsTab.tsx b/app/pages/system/silos/SiloIpPoolsTab.tsx index 8ca455e8c9..a7fa9a8d03 100644 --- a/app/pages/system/silos/SiloIpPoolsTab.tsx +++ b/app/pages/system/silos/SiloIpPoolsTab.tsx @@ -24,7 +24,8 @@ import { Badge } from '~/ui/lib/Badge' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { Message } from '~/ui/lib/Message' import { Modal } from '~/ui/lib/Modal' -import { TableInformationAndAction } from '~/ui/lib/Table' +import { TableInformationAndActions } from '~/ui/lib/Table' +import { TableActionButton } from '~/ui/lib/TableActionButton' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -152,10 +153,11 @@ export function SiloIpPoolsTab() { ) return ( <> - setShowLinkModal(true)} + actions={ + setShowLinkModal(true)} /> + } />
} makeActions={makeActions}> pb.ipPool({ pool }))} /> diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index ac85f80f36..e963337fdd 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -7,14 +7,11 @@ */ import cn from 'classnames' import React, { useRef, type ReactElement } from 'react' -import { Link } from 'react-router-dom' import SimpleBar from 'simplebar-react' import { useIsOverflow } from '~/hooks' import { classed } from '~/util/classed' -import { Button, buttonStyle } from './Button' - export type TableProps = JSX.IntrinsicElements['table'] export function Table({ className, ...props }: TableProps) { const overflowRef = useRef(null) @@ -126,45 +123,23 @@ Table.Cell = ({ height = 'large', className, children, ...props }: TableCellProp */ export const TableActions = classed.div`-mt-11 mb-3 flex justify-end space-x-2` -type TableInformationAndActionProps = { +type TableInformationAndActionsProps = { resourceInformation: React.ReactNode - actionLabel?: string -} & ( - | { - linkTo?: never - onClick?: () => void - } - | { - linkTo?: string - onClick?: () => never - } -) + actions: React.ReactNode +} /** * Used _outside_ of the `Table`, this element displays information about the * resource listed in the table (possibly inlcuding a docs link), and an action button. */ -export const TableInformationAndAction = ({ +export const TableInformationAndActions = ({ resourceInformation, - actionLabel, - linkTo, - onClick, -}: TableInformationAndActionProps) => { - const action = linkTo ? ( - - {actionLabel} - - ) : ( - - ) - return ( -
-

{resourceInformation}

- {action} -
- ) -} + actions, +}: TableInformationAndActionsProps) => ( +
+

{resourceInformation}

+ {actions} +
+) export const TableEmptyBox = classed.div`flex h-full max-h-[480px] items-center justify-center rounded-lg border border-secondary p-4` diff --git a/app/ui/lib/TableActionButton.tsx b/app/ui/lib/TableActionButton.tsx new file mode 100644 index 0000000000..0e05043414 --- /dev/null +++ b/app/ui/lib/TableActionButton.tsx @@ -0,0 +1,29 @@ +/* + * 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 { Link } from 'react-router-dom' + +import { Button, buttonStyle } from './Button' + +/** + * Used _outside_ of the `Table`, this returns either a link or a button that allows the user to take the designated action + */ +type TableActionButtonProps = { label: string } & ( + | { linkTo?: never; onClick?: () => void } + | { linkTo: string; onClick?: never } +) +export const TableActionButton = ({ label, linkTo, onClick }: TableActionButtonProps) => + linkTo ? ( + + {label} + + ) : ( + + ) From a5683590bbb691ff9e4668e5706e6425a74cf521 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Mon, 18 Mar 2024 16:42:58 -0700 Subject: [PATCH 6/9] Refactoring / updates to simplify classed components --- .../project/floating-ips/FloatingIpsPage.tsx | 29 +++++++------------ app/pages/system/networking/IpPoolPage.tsx | 29 +++++++++---------- app/pages/system/silos/SiloIpPoolsTab.tsx | 28 ++++++++---------- app/ui/lib/Table.tsx | 29 +++++++++---------- 4 files changed, 49 insertions(+), 66 deletions(-) diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index ee31a29135..f9d2f4836d 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -33,8 +33,7 @@ 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 { TableInformationAndActions } from '~/ui/lib/Table' -import { TableActionButton } from '~/ui/lib/TableActionButton' +import { TableControls, TableControlsButton, TableControlsText } from '~/ui/lib/Table' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -158,27 +157,21 @@ export function FloatingIpsPage() { } const { Table, Column } = useQueryTable('floatingIpList', { query: { project } }) - const resourceInformation = ( - <> - 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{' '} - managing floating IPs. - - ) return ( <> }>Floating IPs - - } - /> + + + 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{' '} + managing floating IPs. + + navigate(pb.floatingIpsNew({ project }))}> + New floating IP + +
} makeActions={makeActions}> diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx index 9658d17bdd..292769dd3d 100644 --- a/app/pages/system/networking/IpPoolPage.tsx +++ b/app/pages/system/networking/IpPoolPage.tsx @@ -38,8 +38,7 @@ 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 { TableInformationAndActions } from '~/ui/lib/Table' -import { TableActionButton } from '~/ui/lib/TableActionButton' +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' @@ -216,22 +215,20 @@ function LinkedSilosTable() { /> ) - const resourceInformation = ( - <> - 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{' '} - managing IP pools. - - ) return ( <> - setShowLinkModal(true)} /> - } - /> + + + 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{' '} + managing IP pools. + + setShowLinkModal(true)}> + Link silo + +
- 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{' '} - managing IP pools. - - ) return ( <> - setShowLinkModal(true)} /> - } - /> + + + 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 managing IP pools. + + setShowLinkModal(true)}> + Link pool + +
} makeActions={makeActions}> pb.ipPool({ pool }))} /> diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index e963337fdd..08c88239e5 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -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'] @@ -123,23 +125,18 @@ Table.Cell = ({ height = 'large', className, children, ...props }: TableCellProp */ export const TableActions = classed.div`-mt-11 mb-3 flex justify-end space-x-2` -type TableInformationAndActionsProps = { - resourceInformation: React.ReactNode - actions: React.ReactNode -} +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 displays information about the - * resource listed in the table (possibly inlcuding a docs link), and an action button. + * 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 TableInformationAndActions = ({ - resourceInformation, - actions, -}: TableInformationAndActionsProps) => ( -
-

{resourceInformation}

- {actions} -
-) +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 TableEmptyBox = classed.div`flex h-full max-h-[480px] items-center justify-center rounded-lg border border-secondary p-4` +export const TableControlsButton = (props: ButtonProps) => ( + - ) From 9b51ad6450f7019ff23f22ad0b18295171764da0 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Mon, 18 Mar 2024 17:16:23 -0700 Subject: [PATCH 8/9] Capitalization for tests --- app/pages/project/floating-ips/FloatingIpsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index f9d2f4836d..2f841da0b6 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -169,7 +169,7 @@ export function FloatingIpsPage() { managing floating IPs. navigate(pb.floatingIpsNew({ project }))}> - New floating IP + New Floating IP
} makeActions={makeActions}> From c6dd729a17a049dd17c0af7a504beec8de2b9fcb Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Mon, 18 Mar 2024 17:48:39 -0700 Subject: [PATCH 9/9] Fix link --- app/pages/project/floating-ips/FloatingIpsPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index 2f841da0b6..8ec8c6716d 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -33,7 +33,7 @@ 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 { TableControls, TableControlsButton, TableControlsText } from '~/ui/lib/Table' +import { TableControls, TableControlsLink, TableControlsText } from '~/ui/lib/Table' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -168,9 +168,9 @@ export function FloatingIpsPage() { your instances to be reachable from the internet. Find out more about{' '} managing floating IPs. - navigate(pb.floatingIpsNew({ project }))}> + New Floating IP - +
} makeActions={makeActions}>