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
6 changes: 3 additions & 3 deletions app/components/InstanceAutoRestartPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { Instance } from '~/api'
import { instanceAutoRestartingSoon } from '~/api/util'
import { useInstanceSelector } from '~/hooks/use-params'
import { Spinner } from '~/ui/lib/Spinner'
import { links } from '~/util/links'
import { docLinks } from '~/util/links'
import { pb } from '~/util/path-builder'

/**
Expand Down Expand Up @@ -101,15 +101,15 @@ export const InstanceAutoRestartPopover = ({ instance }: { instance: Instance })
: 'This instance will not automatically restart.'}
</p>
<a
href={links.instanceUpdateDocs}
href={docLinks.autoRestart.href}
className="group"
target="_blank"
rel="noreferrer"
>
<span className="inline-block max-w-300 truncate align-middle">
Learn about{' '}
<span className="group-hover:link-with-underline text-raise">
Instance Auto-Restart
{docLinks.autoRestart.linkText}
</span>
</span>
<OpenLink12Icon className="text-secondary ml-1 translate-y-px" />
Expand Down
4 changes: 2 additions & 2 deletions app/components/oxql-metrics/OxqlMetric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getInstanceSelector, useProjectSelector } from '~/hooks/use-params'
import { LearnMore } from '~/ui/lib/CardBlock'
import * as Dropdown from '~/ui/lib/DropdownMenu'
import { classed } from '~/util/classed'
import { links } from '~/util/links'
import { docLinks, links } from '~/util/links'

import { ChartContainer, ChartHeader, TimeSeriesChart } from '../TimeSeriesChart'
import { HighlightedOxqlQuery, toOxqlStr } from './HighlightedOxqlQuery'
Expand Down Expand Up @@ -101,7 +101,7 @@ export function OxqlMetric({ title, description, unit, ...queryObj }: OxqlMetric
code={query}
copyButtonText="Copy query"
modalTitle="OxQL query"
footer={<LearnMore href={links.oxqlDocs} text="OxQL" />}
footer={<LearnMore doc={docLinks.oxql} />}
>
<HighlightedOxqlQuery {...queryObj} />
</CopyCodeModal>
Expand Down
6 changes: 3 additions & 3 deletions app/forms/access-util.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { RadioFieldDyn } from '~/components/form/fields/RadioField'
import { type ListboxItem } from '~/ui/lib/Listbox'
import { Message } from '~/ui/lib/Message'
import { Radio } from '~/ui/lib/Radio'
import { links } from '~/util/links'
import { docLinks } from '~/util/links'
import { capitalize } from '~/util/str'

type AddUserValues = {
Expand Down Expand Up @@ -78,8 +78,8 @@ export type EditRoleModalProps = AddRoleModalProps & {
}

const AccessDocs = () => (
<a href={links.accessDocs} target="_blank" rel="noreferrer">
Access Control
<a href={docLinks.access.href} target="_blank" rel="noreferrer">
{docLinks.access.linkText}
</a>
)
export function RoleRadioField<
Expand Down
6 changes: 3 additions & 3 deletions app/forms/image-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { Spinner } from '~/ui/lib/Spinner'
import { anySignal } from '~/util/abort'
import { readBlobAsBase64 } from '~/util/file'
import { invariant } from '~/util/invariant'
import { links } from '~/util/links'
import { docLinks, links } from '~/util/links'
import { pb } from '~/util/path-builder'
import { isAllZeros } from '~/util/str'
import { GiB, KiB } from '~/util/units'
Expand Down Expand Up @@ -575,8 +575,8 @@ export default function ImageCreate() {
content={
<>
Read the{' '}
<a target="_blank" rel="noreferrer" href={links.imagesDocs}>
Images
<a target="_blank" rel="noreferrer" href={docLinks.images.href}>
{docLinks.images.linkText}
</a>{' '}
guide to learn more about image requirements.
</>
Expand Down
4 changes: 2 additions & 2 deletions app/pages/project/instances/AutoRestartCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { CardBlock, LearnMore } from '~/ui/lib/CardBlock'
import { type ListboxItem } from '~/ui/lib/Listbox'
import { TipIcon } from '~/ui/lib/TipIcon'
import { toLocaleDateTimeString } from '~/util/date'
import { links } from '~/util/links'
import { docLinks } from '~/util/links'

type FormPolicy = 'default' | 'never' | 'best_effort'

Expand Down Expand Up @@ -143,7 +143,7 @@ export function AutoRestartCard() {
</FormMeta>
</CardBlock.Body>
<CardBlock.Footer>
<LearnMore href={links.instanceUpdateDocs} text="Auto-Restart" />
<LearnMore doc={docLinks.autoRestart} />
<Button size="sm" type="submit" disabled={disableSubmit}>
Save
</Button>
Expand Down
6 changes: 3 additions & 3 deletions app/pages/project/instances/ConnectTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { getInstanceSelector, useInstanceSelector } from '~/hooks/use-params'
import { buttonStyle } from '~/ui/lib/Button'
import { CardBlock, LearnMore } from '~/ui/lib/CardBlock'
import { InlineCode } from '~/ui/lib/InlineCode'
import { links } from '~/util/links'
import { docLinks } from '~/util/links'
import { pb } from '~/util/path-builder'

export async function clientLoader({ params }: LoaderFunctionArgs) {
Expand Down Expand Up @@ -59,7 +59,7 @@ export default function ConnectTab() {
</Link>
</CardBlock.Header>
<CardBlock.Footer>
<LearnMore href={links.serialConsoleDocs} text="Serial Console" />
<LearnMore doc={docLinks.serialConsole} />
</CardBlock.Footer>
</CardBlock>

Expand Down Expand Up @@ -88,7 +88,7 @@ export default function ConnectTab() {
}
/>
<CardBlock.Footer>
<LearnMore href={links.sshDocs} text="SSH" />
<LearnMore doc={docLinks.ssh} />
</CardBlock.Footer>
</CardBlock>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/pages/system/silos/SiloScimTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { Message } from '~/ui/lib/Message'
import { Modal } from '~/ui/lib/Modal'
import { TableEmptyBox } from '~/ui/lib/Table'
import { Truncate } from '~/ui/lib/Truncate'
import { links } from '~/util/links'
import { docLinks } from '~/util/links'

export const handle = makeCrumb('SCIM')

Expand Down Expand Up @@ -123,7 +123,7 @@ export default function SiloScimTab() {
.exhaustive()}
</CardBlock.Body>
<CardBlock.Footer>
<LearnMore href={links.scimDocs} text="SCIM" />
<LearnMore doc={docLinks.scim} />
</CardBlock.Footer>
</CardBlock>

Expand Down
6 changes: 3 additions & 3 deletions app/ui/lib/CardBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ CardBlock.Body = classed.div`px-5 py-4 space-y-4 [&>*:last-child[data-simplebar]

CardBlock.Footer = classed.footer`flex items-center justify-between px-5 pt-4 text-secondary`

export const LearnMore = ({ href, text }: { href: string; text: React.ReactNode }) => (
export const LearnMore = ({ doc }: { doc: { href: string; linkText: string } }) => (
<div className="text-sans-md">
Learn more about{' '}
<a
href={href}
href={doc.href}
className="text-accent-secondary hover:text-accent inline-flex items-center"
target="_blank"
rel="noreferrer"
>
{text}
{doc.linkText}
<OpenLink12Icon className="ml-1 align-middle" />
</a>
</div>
Expand Down
112 changes: 47 additions & 65 deletions app/util/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,174 +8,156 @@

const remoteAccess = 'https://docs.oxide.computer/guides/remote-access'

// URLs used in inline prose links where the label is chosen to fit the
// surrounding sentence. For links with a canonical label, use docLinks instead.
export const links = {
accessDocs: 'https://docs.oxide.computer/guides/configuring-access',
affinityDocs:
'https://docs.oxide.computer/guides/deploying-workloads#_affinity_and_anti_affinity',
cloudInitFormat: 'https://cloudinit.readthedocs.io/en/latest/explanation/format.html',
cloudInitExamples: 'https://cloudinit.readthedocs.io/en/latest/reference/examples.html',
deviceTokenSetup:
'https://docs.oxide.computer/guides/working-with-api-and-sdk#_device_token_setup',
disksDocs: 'https://docs.oxide.computer/guides/managing-disks-and-snapshots',
firewallRulesDocs:
'https://docs.oxide.computer/guides/configuring-guest-networking#_firewall_rules',
floatingIpsDocs: 'https://docs.oxide.computer/guides/managing-floating-ips',
gatewaysDocs:
'https://docs.oxide.computer/guides/configuring-guest-networking#internet-gateway',
imagesDocs: 'https://docs.oxide.computer/guides/creating-and-sharing-images',
preparingImagesDocs:
'https://docs.oxide.computer/guides/creating-and-sharing-images#_preparing_images_for_import',
identityProvidersDocs: 'https://docs.oxide.computer/guides/operator/identity-providers',
instanceActionsDocs: 'https://docs.oxide.computer/guides/managing-instances',
// TODO: link to section
instanceBootDiskDocs: 'https://docs.oxide.computer/guides/deploying-workloads',
instanceUpdateDocs:
'https://docs.oxide.computer/guides/managing-instances#_update_instances',
keyConceptsIamPolicyDocs:
'https://docs.oxide.computer/guides/key-entities-and-concepts#iam-policy',
keyConceptsProjectsDocs:
'https://docs.oxide.computer/guides/key-entities-and-concepts#_projects',
oxqlDocs: 'https://docs.oxide.computer/guides/operator/system-metrics#_oxql_quickstart',
oxqlSchemaDocs: (metric: string) =>
`https://docs.oxide.computer/guides/metrics/timeseries-schemas#_${metric.replace(':', '')}`,
projectsDocs: 'https://docs.oxide.computer/guides/onboarding-projects',
quickStart: 'https://docs.oxide.computer/guides/quickstart',
routesDocs: 'https://docs.oxide.computer/guides/configuring-guest-networking#vpc-subnet',
customRoutersDocs:
'https://docs.oxide.computer/guides/configuring-guest-networking#_custom_routers',
scimDocs:
'https://docs.oxide.computer/guides/operator/identity-providers#_saml_authentication_scim_user_provisioning',
siloQuotasDocs:
'https://docs.oxide.computer/guides/operator/silo-management#_silo_resource_quota_management',
sledDocs:
'https://docs.oxide.computer/guides/architecture/service-processors#_server_sled',
snapshotsDocs:
'https://docs.oxide.computer/guides/managing-disks-and-snapshots#_snapshots',
serialConsoleDocs: remoteAccess + '#serial-console',
sshDocs: remoteAccess + '#ssh',
sshKeysDocs: 'https://docs.oxide.computer/guides/user-settings#_ssh_keys',
storageDocs:
'https://docs.oxide.computer/guides/architecture/os-hypervisor-storage#_storage',
systemIpPoolsDocs: 'https://docs.oxide.computer/guides/operator/ip-pool-management',
systemMetricsDocs: 'https://docs.oxide.computer/guides/operator/system-metrics',
systemSiloDocs: 'https://docs.oxide.computer/guides/operator/silo-management',
systemUpdateDocs: 'https://docs.oxide.computer/guides/operator/system-update',
transitIpsDocs:
'https://docs.oxide.computer/guides/configuring-guest-networking#_example_4_software_routing_tunnels',
troubleshootingAccess:
'https://docs.oxide.computer/guides/operator/faq#_how_do_i_fix_the_something_went_wrong_error',
instancesDocs: 'https://docs.oxide.computer/guides/deploying-workloads',
vpcsDocs: 'https://docs.oxide.computer/guides/configuring-guest-networking',
}

// These are links (and associated titles) to help documentation
// Links with a canonical label, used in DocsPopover and SideModalFormDocs.
export const docLinks = {
access: {
href: links.accessDocs,
href: 'https://docs.oxide.computer/guides/configuring-access',
linkText: 'Access Control',
},
affinity: {
href: links.affinityDocs,
href: 'https://docs.oxide.computer/guides/deploying-workloads#_affinity_and_anti_affinity',
linkText: 'Anti-Affinity Groups',
},
deviceTokens: {
href: links.deviceTokenSetup,
href: 'https://docs.oxide.computer/guides/working-with-api-and-sdk#_device_token_setup',
linkText: 'Access Tokens',
},
disks: {
href: links.disksDocs,
href: 'https://docs.oxide.computer/guides/managing-disks-and-snapshots',
linkText: 'Disks and Snapshots',
},
firewallRules: {
href: links.firewallRulesDocs,
linkText: 'Firewall Rules',
},
floatingIps: {
href: links.floatingIpsDocs,
href: 'https://docs.oxide.computer/guides/managing-floating-ips',
linkText: 'Floating IPs',
},
gateways: {
href: links.gatewaysDocs,
href: 'https://docs.oxide.computer/guides/configuring-guest-networking#internet-gateway',
linkText: 'Internet Gateways',
},
keyConceptsIam: {
href: links.keyConceptsIamPolicyDocs,
href: 'https://docs.oxide.computer/guides/key-entities-and-concepts#iam-policy',
linkText: 'Key Concepts',
},
identityProviders: {
href: links.identityProvidersDocs,
linkText: 'Identity Providers',
},
images: {
href: links.imagesDocs,
href: 'https://docs.oxide.computer/guides/creating-and-sharing-images',
linkText: 'Images',
},
autoRestart: {
href: 'https://docs.oxide.computer/guides/managing-instances#_update_instances',
linkText: 'Instance Auto-Restart',
},
instanceActions: {
href: links.instanceActionsDocs,
href: 'https://docs.oxide.computer/guides/managing-instances',
linkText: 'Instance Actions',
},
oxql: {
href: 'https://docs.oxide.computer/guides/operator/system-metrics#_oxql_quickstart',
linkText: 'OxQL',
},
keyConceptsProjects: {
href: links.keyConceptsProjectsDocs,
href: 'https://docs.oxide.computer/guides/key-entities-and-concepts#_projects',
linkText: 'Key Concepts',
},
projects: {
href: links.projectsDocs,
href: 'https://docs.oxide.computer/guides/onboarding-projects',
linkText: 'Projects',
},
quickStart: {
href: links.quickStart,
href: 'https://docs.oxide.computer/guides/quickstart',
linkText: 'Quick Start',
},
remoteAccess: {
href: remoteAccess,
linkText: 'Remote Access',
},
scim: {
href: 'https://docs.oxide.computer/guides/operator/identity-providers#_saml_authentication_scim_user_provisioning',
linkText: 'SCIM',
},
serialConsole: {
href: remoteAccess + '#serial-console',
linkText: 'Serial Console',
},
routers: {
href: links.customRoutersDocs,
href: 'https://docs.oxide.computer/guides/configuring-guest-networking#_custom_routers',
linkText: 'Custom Routers',
},
routes: {
href: links.routesDocs,
href: 'https://docs.oxide.computer/guides/configuring-guest-networking#vpc-subnet',
linkText: 'VPC Subnet Routing',
},
sleds: {
href: links.sledDocs,
href: 'https://docs.oxide.computer/guides/architecture/service-processors#_server_sled',
linkText: 'Server Sleds',
},
snapshots: {
href: links.snapshotsDocs,
href: 'https://docs.oxide.computer/guides/managing-disks-and-snapshots#_snapshots',
linkText: 'Disks and Snapshots',
},
ssh: {
href: remoteAccess + '#ssh',
linkText: 'SSH',
},
sshKeys: {
href: links.sshKeysDocs,
href: 'https://docs.oxide.computer/guides/user-settings#_ssh_keys',
linkText: 'SSH Keys',
},
storage: {
href: links.storageDocs,
href: 'https://docs.oxide.computer/guides/architecture/os-hypervisor-storage#_storage',
linkText: 'Storage',
},
systemIpPools: {
href: links.systemIpPoolsDocs,
href: 'https://docs.oxide.computer/guides/operator/ip-pool-management',
linkText: 'IP Pools',
},
systemMetrics: {
href: links.systemMetricsDocs,
href: 'https://docs.oxide.computer/guides/operator/system-metrics',
linkText: 'Metrics',
},
systemSilo: {
href: links.systemSiloDocs,
href: 'https://docs.oxide.computer/guides/operator/silo-management',
linkText: 'Silos',
},
systemUpdate: {
href: links.systemUpdateDocs,
href: 'https://docs.oxide.computer/guides/operator/system-update',
linkText: 'System Update',
},
instances: {
href: links.instancesDocs,
href: 'https://docs.oxide.computer/guides/deploying-workloads',
linkText: 'Instances',
},
vpcs: {
href: links.vpcsDocs,
href: 'https://docs.oxide.computer/guides/configuring-guest-networking',
linkText: 'Networking',
},
}
Loading