diff --git a/app/pages/ProjectsPage.tsx b/app/pages/ProjectsPage.tsx index 2c2a55a9ff..b99f52b8c1 100644 --- a/app/pages/ProjectsPage.tsx +++ b/app/pages/ProjectsPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' -import { Link, Outlet, useNavigate } from 'react-router-dom' +import { Outlet, useNavigate } from 'react-router-dom' import { apiQueryClient, @@ -23,7 +23,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -123,9 +123,7 @@ export function ProjectsPage() { }>Projects - - New Project - + New Project } /> diff --git a/app/pages/SiloAccessPage.tsx b/app/pages/SiloAccessPage.tsx index 573cf9f590..9cc108ffdf 100644 --- a/app/pages/SiloAccessPage.tsx +++ b/app/pages/SiloAccessPage.tsx @@ -31,7 +31,7 @@ import { confirmDelete } from '~/stores/confirm-delete' import { getActionsCol } from '~/table/columns/action-col' import { Table } from '~/table/Table' import { Badge } from '~/ui/lib/Badge' -import { Button } from '~/ui/lib/Button' +import { CreateButton } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions, TableEmptyBox } from '~/ui/lib/Table' @@ -165,9 +165,7 @@ export function SiloAccessPage() { - + setAddModalOpen(true)}>Add user or group {siloPolicy && addModalOpen && ( - + setAddModalOpen(true)}>Add user or group {projectPolicy && addModalOpen && ( }>Disks - - New Disk - + New Disk
} /> diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index 360d0a0e9d..0353917e3b 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -30,12 +30,13 @@ import { InstanceLinkCell } from '~/table/cells/InstanceLinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' +import { CreateLink } from '~/ui/lib/CreateButton' 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 { TableControls, TableControlsLink, TableControlsText } from '~/ui/lib/Table' +import { TableControls, TableControlsText } from '~/ui/lib/Table' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -192,9 +193,7 @@ export function FloatingIpsPage() { your instances to be reachable from the internet. Learn more about{' '} managing floating IPs. - - New Floating IP - + New Floating IP
} /> diff --git a/app/pages/project/images/ImagesPage.tsx b/app/pages/project/images/ImagesPage.tsx index bd2bda08e2..f94efb5c6d 100644 --- a/app/pages/project/images/ImagesPage.tsx +++ b/app/pages/project/images/ImagesPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo, useState } from 'react' -import { Link, Outlet, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, useApiMutation, useApiQueryClient, type Image } from '@oxide/api' import { Images24Icon } from '@oxide/design-system/icons/react' @@ -19,7 +19,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { getActionsCol, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { Message } from '~/ui/lib/Message' import { Modal } from '~/ui/lib/Modal' @@ -100,9 +100,7 @@ export function ImagesPage() { }>Images - - Upload image - + Upload image
} /> {promoteImageName && ( diff --git a/app/pages/project/instances/InstancesPage.tsx b/app/pages/project/instances/InstancesPage.tsx index 141e2ef1df..6147e12dbd 100644 --- a/app/pages/project/instances/InstancesPage.tsx +++ b/app/pages/project/instances/InstancesPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useMemo } from 'react' -import { Link, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, @@ -25,7 +25,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { getActionsCol } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -127,9 +127,7 @@ export function InstancesPage() { - - New Instance - + New Instance
} rowHeight="large" /> diff --git a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx index a7cfde45b4..309f68b317 100644 --- a/app/pages/project/instances/instance/tabs/NetworkingTab.tsx +++ b/app/pages/project/instances/instance/tabs/NetworkingTab.tsx @@ -35,7 +35,7 @@ import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns, DescriptionCell } from '~/table/columns/common' import { Table } from '~/table/Table' import { Badge } from '~/ui/lib/Badge' -import { Button } from '~/ui/lib/Button' +import { CreateButton } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { TableControls, TableEmptyBox, TableTitle } from '~/ui/lib/Table' import { TipIcon } from '~/ui/lib/TipIcon' @@ -323,14 +323,13 @@ export function NetworkingTab() { <> External IPs - + {attachModalOpen && ( Network interfaces - + {createModalOpen && ( setCreateModalOpen(false)} diff --git a/app/pages/project/snapshots/SnapshotsPage.tsx b/app/pages/project/snapshots/SnapshotsPage.tsx index d8f905ce3d..424104fbed 100644 --- a/app/pages/project/snapshots/SnapshotsPage.tsx +++ b/app/pages/project/snapshots/SnapshotsPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback } from 'react' -import { Link, Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, @@ -26,7 +26,7 @@ import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' import { Badge } from '~/ui/lib/Badge' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -136,9 +136,7 @@ export function SnapshotsPage() { }>Snapshots - - New Snapshot - + New snapshot
} /> diff --git a/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx b/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx index 309e3c566a..33c77b5656 100644 --- a/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx +++ b/app/pages/project/vpcs/VpcPage/tabs/VpcFirewallRulesTab.tsx @@ -26,7 +26,7 @@ import { TypeValueCell } from '~/table/cells/TypeValueCell' import { getActionsCol } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { Table } from '~/table/Table' -import { Button } from '~/ui/lib/Button' +import { CreateButton } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { TableEmptyBox } from '~/ui/lib/Table' import { sortBy } from '~/util/array' @@ -134,9 +134,7 @@ export const VpcFirewallRulesTab = () => { return ( <>
- + setCreateModalOpen(true)}>New rule {createModalOpen && ( () @@ -77,9 +77,7 @@ export const VpcSubnetsTab = () => { return ( <>
- + setCreating(true)}>New subnet {creating && setCreating(false)} />} {editing && setEditing(null)} />}
diff --git a/app/pages/project/vpcs/VpcsPage.tsx b/app/pages/project/vpcs/VpcsPage.tsx index e15f65f0f2..5702634c58 100644 --- a/app/pages/project/vpcs/VpcsPage.tsx +++ b/app/pages/project/vpcs/VpcsPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' -import { Link, Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, @@ -24,7 +24,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { getActionsCol, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -122,9 +122,7 @@ export function VpcsPage() { }>VPCs - - New Vpc - + New Vpc
} /> diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx index e3602502ed..dc425e4fef 100644 --- a/app/pages/system/networking/IpPoolPage.tsx +++ b/app/pages/system/networking/IpPoolPage.tsx @@ -8,7 +8,7 @@ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo, useState } from 'react' -import { Link, Outlet, type LoaderFunctionArgs } from 'react-router-dom' +import { Outlet, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, @@ -36,12 +36,12 @@ import { LinkCell } from '~/table/cells/LinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateButton, CreateLink } from '~/ui/lib/CreateButton' 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 { TableControls, TableControlsText } from '~/ui/lib/Table' import { Tabs } from '~/ui/lib/Tabs' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -192,9 +192,7 @@ function IpRangesTable() { return ( <>
- - Add range - + Add range
@@ -286,9 +284,7 @@ function LinkedSilosTable() { learn more about{' '} managing IP pools. - setShowLinkModal(true)}> - Link silo - + setShowLinkModal(true)}>Link silo
{showLinkModal && setShowLinkModal(false)} />} diff --git a/app/pages/system/networking/IpPoolsPage.tsx b/app/pages/system/networking/IpPoolsPage.tsx index e83d5015d1..b7ae147deb 100644 --- a/app/pages/system/networking/IpPoolsPage.tsx +++ b/app/pages/system/networking/IpPoolsPage.tsx @@ -8,7 +8,7 @@ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' -import { Link, Outlet, useNavigate } from 'react-router-dom' +import { Outlet, useNavigate } from 'react-router-dom' import { apiQueryClient, @@ -27,7 +27,7 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -127,9 +127,7 @@ export function IpPoolsPage() { }>IP Pools - - New IP Pool - + New IP Pool
} /> diff --git a/app/pages/system/silos/SiloIdpsTab.tsx b/app/pages/system/silos/SiloIdpsTab.tsx index db7c897bca..2c6d90847f 100644 --- a/app/pages/system/silos/SiloIdpsTab.tsx +++ b/app/pages/system/silos/SiloIdpsTab.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useMemo } from 'react' -import { Link, Outlet } from 'react-router-dom' +import { Outlet } from 'react-router-dom' import { Cloud24Icon } from '@oxide/design-system/icons/react' @@ -17,7 +17,7 @@ import { LinkCell } from '~/table/cells/LinkCell' import { Columns } from '~/table/columns/common' import { useQueryTable } from '~/table/QueryTable' import { Badge } from '~/ui/lib/Badge' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { pb } from '~/util/path-builder' @@ -56,9 +56,7 @@ export function SiloIdpsTab() { return ( <>
- - New provider - + New provider
} columns={staticCols} /> diff --git a/app/pages/system/silos/SiloIpPoolsTab.tsx b/app/pages/system/silos/SiloIpPoolsTab.tsx index 025368ae0c..99f082b0f6 100644 --- a/app/pages/system/silos/SiloIpPoolsTab.tsx +++ b/app/pages/system/silos/SiloIpPoolsTab.tsx @@ -23,10 +23,11 @@ import { makeLinkCell } from '~/table/cells/LinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { useQueryTable } from '~/table/QueryTable' +import { CreateButton } from '~/ui/lib/CreateButton' 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 { TableControls, TableControlsText } from '~/ui/lib/Table' import { links } from '~/util/links' import { pb } from '~/util/path-builder' @@ -169,9 +170,7 @@ export function SiloIpPoolsTab() { when users ask for one without specifying a pool. Read the docs to learn more about managing IP pools. - setShowLinkModal(true)}> - Link pool - + setShowLinkModal(true)}>Link pool
} /> {showLinkModal && setShowLinkModal(false)} />} diff --git a/app/pages/system/silos/SilosPage.tsx b/app/pages/system/silos/SilosPage.tsx index d5e7a2030a..5986202205 100644 --- a/app/pages/system/silos/SilosPage.tsx +++ b/app/pages/system/silos/SilosPage.tsx @@ -7,7 +7,7 @@ */ import { createColumnHelper } from '@tanstack/react-table' import { useCallback, useMemo } from 'react' -import { Link, Outlet, useNavigate } from 'react-router-dom' +import { Outlet, useNavigate } from 'react-router-dom' import { apiQueryClient, @@ -26,7 +26,7 @@ import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' import { Badge } from '~/ui/lib/Badge' -import { buttonStyle } from '~/ui/lib/Button' +import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' @@ -114,9 +114,7 @@ export function SilosPage() { }>Silos - - New silo - + New silo
} /> diff --git a/app/ui/lib/CreateButton.tsx b/app/ui/lib/CreateButton.tsx new file mode 100644 index 0000000000..9d479aa790 --- /dev/null +++ b/app/ui/lib/CreateButton.tsx @@ -0,0 +1,27 @@ +/* + * 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, type LinkProps } from 'react-router-dom' + +import { AddRoundel12Icon } from '@oxide/design-system/icons/react' + +import { Button, buttonStyle, type ButtonProps } from '~/ui/lib/Button' + +export const CreateButton = ({ children, ...props }: ButtonProps) => ( + +) + +export const CreateLink = ({ children, ...rest }: LinkProps) => ( + + + {children} + +) diff --git a/app/ui/lib/Table.tsx b/app/ui/lib/Table.tsx index 3bfeb018b5..92c7ee114b 100644 --- a/app/ui/lib/Table.tsx +++ b/app/ui/lib/Table.tsx @@ -7,11 +7,9 @@ */ 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'] @@ -131,12 +129,4 @@ export const TableEmptyBox = classed.div`flex h-full max-h-[480px] items-center */ 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) => ( -