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
17 changes: 16 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@ module.exports = {
'plugin:react/recommended',
'prettier',
'plugin:react-hook-form/recommended',
'plugin:import/recommended',
],
plugins: [
'@typescript-eslint',
'react-hooks',
'prettier',
'jsx-a11y',
'react-hook-form',
'import',
],
plugins: ['@typescript-eslint', 'react-hooks', 'prettier', 'jsx-a11y', 'react-hook-form'],
settings: {
react: {
version: 'detect',
Expand All @@ -35,6 +43,8 @@ module.exports = {
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
eqeqeq: ['error', 'always', { null: 'ignore' }],
'import/no-default-export': 'error',
'import/no-unresolved': 'off', // plugin doesn't know anything
'jsx-a11y/label-has-associated-control': [2, { controlComponents: ['button'] }],
'no-param-reassign': 'error',
'no-restricted-imports': [
Expand Down Expand Up @@ -64,6 +74,11 @@ module.exports = {
},
ignorePatterns: ['dist/'],
overrides: [
{
// default export is needed in config files
files: ['*.config.ts'],
rules: { 'import/no-default-export': 'off' },
},
{
files: ['*.js'],
rules: {
Expand Down
2 changes: 1 addition & 1 deletion app/components/EquivalentCliCommand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Success12Icon } from '@oxide/design-system/icons/react'

import { Button } from '~/ui/lib/Button'
import { Modal } from '~/ui/lib/Modal'
import useTimeout from '~/ui/lib/use-timeout'
import { useTimeout } from '~/ui/lib/use-timeout'

export function EquivalentCliCommand({ command }: { command: string }) {
const [isOpen, setIsOpen] = useState(false)
Expand Down
2 changes: 1 addition & 1 deletion app/components/RefetchIntervalPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Refresh16Icon, Time16Icon } from '@oxide/design-system/icons/react'

import { Listbox, type ListboxItem } from '~/ui/lib/Listbox'
import { SpinnerLoader } from '~/ui/lib/Spinner'
import useInterval from '~/ui/lib/use-interval'
import { useInterval } from '~/ui/lib/use-interval'

const intervalPresets = {
Off: undefined,
Expand Down
6 changes: 2 additions & 4 deletions app/components/RoundedSector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useEffect, useMemo, useState } from 'react'

import { useReducedMotion } from '~/hooks'

const RoundedSector = ({
export function RoundedSector({
angle,
size,
thickness,
Expand All @@ -19,7 +19,7 @@ const RoundedSector = ({
size: number
thickness: number
cornerRadius?: number
}) => {
}) {
const prefersReducedMotion = useReducedMotion()
const [interpolatedAngle, setInterpolatedAngle] = useState(0)

Expand Down Expand Up @@ -290,5 +290,3 @@ const polarToCartesian = (cx: number, cy: number, radius: number, angle: number)
x: cx + Math.cos((-Math.PI / 180) * angle) * radius,
y: cy + Math.sin((-Math.PI / 180) * angle) * radius,
})

export default RoundedSector
6 changes: 3 additions & 3 deletions app/components/Terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ interface TerminalProps {
ws: WebSocket
}

export const Terminal = ({ ws }: TerminalProps) => {
// default export is most convenient for dynamic import
// eslint-disable-next-line import/no-default-export
export default function Terminal({ ws }: TerminalProps) {
const [term, setTerm] = useState<XTerm | null>(null)
const terminalRef = useRef<HTMLDivElement>(null)

Expand Down Expand Up @@ -114,5 +116,3 @@ export const Terminal = ({ ws }: TerminalProps) => {
</>
)
}

export default Terminal
2 changes: 2 additions & 0 deletions app/components/TimeSeriesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ function roundUpToDivBy(value: number, divisor: number) {
return Math.ceil(value / divisor) * divisor
}

// default export is most convenient for dynamic import
// eslint-disable-next-line import/no-default-export
export default function TimeSeriesChart({
className,
data: rawData,
Expand Down
2 changes: 1 addition & 1 deletion app/components/form/fields/DisksTableField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useController, type Control } from 'react-hook-form'
import type { DiskCreate } from '@oxide/api'
import { Error16Icon } from '@oxide/design-system/icons/react'

import AttachDiskSideModalForm from '~/forms/disk-attach'
import { AttachDiskSideModalForm } from '~/forms/disk-attach'
import { CreateDiskSideModalForm } from '~/forms/disk-create'
import type { InstanceCreateInput } from '~/forms/instance-create'
import { Badge } from '~/ui/lib/Badge'
Expand Down
2 changes: 1 addition & 1 deletion app/components/form/fields/NetworkInterfaceField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
import { Error16Icon } from '@oxide/design-system/icons/react'

import type { InstanceCreateInput } from '~/forms/instance-create'
import CreateNetworkInterfaceForm from '~/forms/network-interface-create'
import { CreateNetworkInterfaceForm } from '~/forms/network-interface-create'
import { Button } from '~/ui/lib/Button'
import { FieldLabel } from '~/ui/lib/FieldLabel'
import * as MiniTable from '~/ui/lib/MiniTable'
Expand Down
2 changes: 0 additions & 2 deletions app/forms/disk-attach.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,3 @@ export function AttachDiskSideModalForm({
</SideModalForm>
)
}

export default AttachDiskSideModalForm
2 changes: 1 addition & 1 deletion app/forms/network-interface-create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type CreateNetworkInterfaceFormProps = {
* Can be used with either a `setState` or a real mutation as `onSubmit`, hence
* the optional `loading` and `submitError`
*/
export default function CreateNetworkInterfaceForm({
export function CreateNetworkInterfaceForm({
onSubmit,
onDismiss,
loading,
Expand Down
2 changes: 1 addition & 1 deletion app/forms/network-interface-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type EditNetworkInterfaceFormProps = {
onDismiss: () => void
}

export default function EditNetworkInterfaceForm({
export function EditNetworkInterfaceForm({
onDismiss,
editing,
}: EditNetworkInterfaceFormProps) {
Expand Down
32 changes: 14 additions & 18 deletions app/layouts/AuthLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,17 @@ import { Outlet } from 'react-router-dom'

import { OxideLogo } from '~/components/OxideLogo'

const AuthLayout = () => {
return (
<main
className="relative h-screen"
style={{
background:
'radial-gradient(200% 100% at 50% 100%, var(--surface-default) 0%, #161B1D 100%)',
}}
>
<OxideLogo className="absolute bottom-8 left-1/2 -translate-x-1/2" />
<div className="z-10 flex h-full items-center justify-center">
<Outlet />
</div>
</main>
)
}

export default AuthLayout
export const AuthLayout = () => (
<main
className="relative h-screen"
style={{
background:
'radial-gradient(200% 100% at 50% 100%, var(--surface-default) 0%, #161B1D 100%)',
}}
>
<OxideLogo className="absolute bottom-8 left-1/2 -translate-x-1/2" />
<div className="z-10 flex h-full items-center justify-center">
<Outlet />
</div>
</main>
)
4 changes: 1 addition & 3 deletions app/layouts/ProjectLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ ProjectLayout.loader = async ({ params }: LoaderFunctionArgs) => {
return null
}

function ProjectLayout({ overrideContentPane }: ProjectLayoutProps) {
export function ProjectLayout({ overrideContentPane }: ProjectLayoutProps) {
const navigate = useNavigate()
// project will always be there, instance may not
const projectSelector = useProjectSelector()
Expand Down Expand Up @@ -123,5 +123,3 @@ function ProjectLayout({ overrideContentPane }: ProjectLayoutProps) {
</PageContainer>
)
}

export default ProjectLayout
2 changes: 1 addition & 1 deletion app/layouts/RootLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useTitle } from '~/hooks/use-title'
* Root layout that applies to the entire app. Modify sparingly. It's rare for
* anything to actually belong here.
*/
export default function RootLayout() {
export function RootLayout() {
const title = useTitle()

return (
Expand Down
4 changes: 1 addition & 3 deletions app/layouts/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { pb } from '~/util/path-builder'
import { DocsLinkItem, NavLinkItem, Sidebar } from '../components/Sidebar'
import { ContentPane, PageContainer } from './helpers'

const SettingsLayout = () => {
export function SettingsLayout() {
const navigate = useNavigate()
const { pathname } = useLocation()

Expand Down Expand Up @@ -67,5 +67,3 @@ const SettingsLayout = () => {
</PageContainer>
)
}

export default SettingsLayout
2 changes: 1 addition & 1 deletion app/layouts/SystemLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ SystemLayout.loader = async () => {
return null
}

export default function SystemLayout() {
export function SystemLayout() {
// Only show silo picker if we are looking at a particular silo. The more
// robust way of doing this would be to make a separate layout for the
// silo-specific routes in the route config, but it's overkill considering
Expand Down
2 changes: 1 addition & 1 deletion app/pages/DeviceAuthSuccessPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Success12Icon } from '@oxide/design-system/icons/react'
/**
* Device authorization success page
*/
export default function DeviceAuthSuccessPage() {
export function DeviceAuthSuccessPage() {
return (
<div className="flex w-full max-w-[470px] flex-col items-center rounded-lg border p-9 text-center !bg-raise border-secondary elevation-3">
<div className="my-2 flex h-12 w-12 items-center justify-center">
Expand Down
2 changes: 1 addition & 1 deletion app/pages/DeviceAuthVerifyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function addDashes(dashAfterIdxs: number[], code: string) {
/**
* Device authorization verification page
*/
export default function DeviceAuthVerifyPage() {
export function DeviceAuthVerifyPage() {
const navigate = useNavigate()
const confirmPost = useApiMutation('deviceAuthConfirm', {
onSuccess: () => {
Expand Down
2 changes: 1 addition & 1 deletion app/pages/ProjectsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ProjectsPage.loader = async () => {
return null
}

export default function ProjectsPage() {
export function ProjectsPage() {
const navigate = useNavigate()

const queryClient = useApiQueryClient()
Expand Down
1 change: 0 additions & 1 deletion app/pages/project/access/ProjectAccessPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*
* Copyright Oxide Computer Company
*/
import '@tanstack/react-table'

import { createColumnHelper, getCoreRowModel, useReactTable } from '@tanstack/react-table'
import { useMemo, useState } from 'react'
Expand Down
4 changes: 2 additions & 2 deletions app/pages/project/instances/instance/tabs/NetworkingTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {
} from '@oxide/api'
import { Networking24Icon } from '@oxide/design-system/icons/react'

import CreateNetworkInterfaceForm from '~/forms/network-interface-create'
import EditNetworkInterfaceForm from '~/forms/network-interface-edit'
import { CreateNetworkInterfaceForm } from '~/forms/network-interface-create'
import { EditNetworkInterfaceForm } from '~/forms/network-interface-edit'
import {
getInstanceSelector,
useInstanceSelector,
Expand Down
2 changes: 1 addition & 1 deletion app/pages/project/instances/instance/tabs/StorageTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { Storage24Icon } from '@oxide/design-system/icons/react'

import { DiskStatusBadge } from '~/components/StatusBadge'
import AttachDiskSideModalForm from '~/forms/disk-attach'
import { AttachDiskSideModalForm } from '~/forms/disk-attach'
import { CreateDiskSideModalForm } from '~/forms/disk-create'
import { getInstanceSelector, useInstanceSelector } from '~/hooks'
import { addToast } from '~/stores/toast'
Expand Down
2 changes: 1 addition & 1 deletion app/pages/system/silos/SilosPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ SilosPage.loader = async () => {
return null
}

export default function SilosPage() {
export function SilosPage() {
const navigate = useNavigate()

const { Table, Column } = useQueryTable('siloList', {})
Expand Down
18 changes: 9 additions & 9 deletions app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ import { CreateVpcSideModalForm } from './forms/vpc-create'
import { EditVpcSideModalForm } from './forms/vpc-edit'
import type { CrumbFunc } from './hooks/use-title'
import { AuthenticatedLayout } from './layouts/AuthenticatedLayout'
import AuthLayout from './layouts/AuthLayout'
import { AuthLayout } from './layouts/AuthLayout'
import { SerialConsoleContentPane } from './layouts/helpers'
import { LoginLayout } from './layouts/LoginLayout'
import ProjectLayout from './layouts/ProjectLayout'
import RootLayout from './layouts/RootLayout'
import SettingsLayout from './layouts/SettingsLayout'
import { ProjectLayout } from './layouts/ProjectLayout'
import { RootLayout } from './layouts/RootLayout'
import { SettingsLayout } from './layouts/SettingsLayout'
import { SiloLayout } from './layouts/SiloLayout'
import SystemLayout from './layouts/SystemLayout'
import DeviceAuthSuccessPage from './pages/DeviceAuthSuccessPage'
import DeviceAuthVerifyPage from './pages/DeviceAuthVerifyPage'
import { SystemLayout } from './layouts/SystemLayout'
import { DeviceAuthSuccessPage } from './pages/DeviceAuthSuccessPage'
import { DeviceAuthVerifyPage } from './pages/DeviceAuthVerifyPage'
import { LoginPage } from './pages/LoginPage'
import { LoginPageSaml } from './pages/LoginPageSaml'
import { instanceLookupLoader } from './pages/lookups'
Expand All @@ -60,7 +60,7 @@ import { InstancesPage } from './pages/project/instances/InstancesPage'
import { SnapshotsPage } from './pages/project/snapshots/SnapshotsPage'
import { VpcPage } from './pages/project/vpcs/VpcPage/VpcPage'
import { VpcsPage } from './pages/project/vpcs/VpcsPage'
import ProjectsPage from './pages/ProjectsPage'
import { ProjectsPage } from './pages/ProjectsPage'
import { ProfilePage } from './pages/settings/ProfilePage'
import { SSHKeysPage } from './pages/settings/SSHKeysPage'
import { SiloAccessPage } from './pages/SiloAccessPage'
Expand All @@ -75,7 +75,7 @@ import { IpPoolsTab } from './pages/system/networking/IpPoolsTab'
import { NetworkingPage } from './pages/system/networking/NetworkingPage'
import { SiloImagesPage } from './pages/system/SiloImagesPage'
import { SiloPage } from './pages/system/silos/SiloPage'
import SilosPage from './pages/system/silos/SilosPage'
import { SilosPage } from './pages/system/silos/SilosPage'
import { SystemUtilizationPage } from './pages/system/UtilizationPage'
import { pb } from './util/path-builder'

Expand Down
2 changes: 1 addition & 1 deletion app/ui/lib/CopyToClipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useState } from 'react'

import { Copy12Icon, Success12Icon } from '@oxide/design-system/icons/react'

import useTimeout from './use-timeout'
import { useTimeout } from './use-timeout'

export const CopyToClipboard = ({
ariaLabel = 'Click to copy this text',
Expand Down
2 changes: 1 addition & 1 deletion app/ui/lib/TimeoutIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { animated, Globals, useTransition } from '@react-spring/web'
import cn from 'classnames'

import useTimeout from './use-timeout'
import { useTimeout } from './use-timeout'

export interface TimeoutIndicatorProps {
timeout: number
Expand Down
2 changes: 1 addition & 1 deletion app/ui/lib/use-interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface UseIntervalProps {
* force a render, which cleans up the currently set interval and possibly sets
* a new one.
*/
export default function useInterval({ fn, delay, key }: UseIntervalProps) {
export function useInterval({ fn, delay, key }: UseIntervalProps) {
const callbackRef = useRef<() => void>()

useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion app/ui/lib/use-timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { useEffect, useRef } from 'react'

// use null delay to prevent the timeout from firing
export default function useTimeout(callback: () => void, delay: number | null) {
export function useTimeout(callback: () => void, delay: number | null) {
const callbackRef = useRef<() => void>()

useEffect(() => {
Expand Down
Loading